From d37650e750990d3fd756af1a24c264b209bca96f Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Mon, 6 Feb 2023 21:49:21 +0100 Subject: [PATCH 001/936] Add ECS Panda 386V --- src/machine/m_at_386dx_486.c | 23 ++++++++++++++++++++++ src/machine/machine_table.c | 37 ++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 036eac550..73a8a98a6 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -225,6 +225,27 @@ machine_at_spc6000a_init(const machine_t *model) return ret; } +int +machine_at_ECS_386V_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ECS_386V/PANDA_386V.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&ali1429_device); + device_add(&keyboard_ps2_intel_ami_pci_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + int machine_at_rycleopardlx_init(const machine_t *model) { @@ -1810,3 +1831,5 @@ machine_at_tg486g_init(const machine_t *model) return ret; } + + diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index a5f51a8bf..1b8fcc712 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -4551,6 +4551,43 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has AMI Megakey P KBC firmware */ + { + .name = "[ALi M1429] ECS Panda 386V", + .internal_name = "ECS_386V", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_ALI_M1429, + .init = machine_at_ECS_386V_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_386DX, + .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_VLB, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024, + }, + .nvrmask = 127, + .kbc = KBC_UNKNOWN, + .kbc_p1 = 0, + .gpio = 0, + .device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Has AMIKey F KBC firmware. */ { .name = "[SiS 310] ASUS ISA-386C", From 03ba0bef5ccf0a24f04d42fad00c48e61897e7c6 Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Fri, 17 Mar 2023 22:00:50 +0100 Subject: [PATCH 002/936] Forgotten machine.h for ECS Panda 386V --- src/include/86box/machine.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 165e37cb2..64e550b8d 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -448,6 +448,7 @@ extern int machine_at_asus386_init(const machine_t *); extern int machine_at_ecs386_init(const machine_t *); extern int machine_at_spc6000a_init(const machine_t *); extern int machine_at_micronics386_init(const machine_t *); +extern int machine_at_ECS_386V_init(const machine_t *); extern int machine_at_rycleopardlx_init(const machine_t *); @@ -467,6 +468,7 @@ extern int machine_at_winbios1429_init(const machine_t *); extern int machine_at_opti495_init(const machine_t *); extern int machine_at_opti495_ami_init(const machine_t *); extern int machine_at_opti495_mr_init(const machine_t *); +extern int machine_at_INT_BDT486SX_init(const machine_t *); extern int machine_at_vect486vl_init(const machine_t *); extern int machine_at_d824_init(const machine_t *); From aee8d3a9ae8ce9f35cce490e54b74dc4b43360a3 Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Fri, 17 Mar 2023 22:08:21 +0100 Subject: [PATCH 003/936] Revert "Forgotten machine.h for ECS Panda 386V" This reverts commit 03ba0bef5ccf0a24f04d42fad00c48e61897e7c6. --- src/include/86box/machine.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 64e550b8d..165e37cb2 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -448,7 +448,6 @@ extern int machine_at_asus386_init(const machine_t *); extern int machine_at_ecs386_init(const machine_t *); extern int machine_at_spc6000a_init(const machine_t *); extern int machine_at_micronics386_init(const machine_t *); -extern int machine_at_ECS_386V_init(const machine_t *); extern int machine_at_rycleopardlx_init(const machine_t *); @@ -468,7 +467,6 @@ extern int machine_at_winbios1429_init(const machine_t *); extern int machine_at_opti495_init(const machine_t *); extern int machine_at_opti495_ami_init(const machine_t *); extern int machine_at_opti495_mr_init(const machine_t *); -extern int machine_at_INT_BDT486SX_init(const machine_t *); extern int machine_at_vect486vl_init(const machine_t *); extern int machine_at_d824_init(const machine_t *); From 3e3030d5a3b9b51e95ef7335451cf01f99eb59dc Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Fri, 17 Mar 2023 22:12:17 +0100 Subject: [PATCH 004/936] Properly update forgotten machine.h for ECS Panda 386V --- src/include/86box/machine.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 165e37cb2..339e9564a 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -448,6 +448,7 @@ extern int machine_at_asus386_init(const machine_t *); extern int machine_at_ecs386_init(const machine_t *); extern int machine_at_spc6000a_init(const machine_t *); extern int machine_at_micronics386_init(const machine_t *); +extern int machine_at_ECS_386V_init(const machine_t *); extern int machine_at_rycleopardlx_init(const machine_t *); From f480ca366856e1aa524eb676221dce6143888d85 Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Thu, 6 Jul 2023 00:51:57 +0200 Subject: [PATCH 005/936] Add the J-Bond PCI400C-A (note: PCI registers 00h - 03h get randomly zeroed out, needs fixing) --- src/include/86box/machine.h | 3 ++- src/machine/m_at_386dx_486.c | 35 ++++++++++++++++++++++++++++- src/machine/machine_table.c | 43 ++++++++++++++++++++++++++++++++++-- 3 files changed, 77 insertions(+), 4 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 3051e6685..d2ee8330a 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -457,7 +457,7 @@ extern int machine_at_asus386_init(const machine_t *); extern int machine_at_ecs386_init(const machine_t *); extern int machine_at_spc6000a_init(const machine_t *); extern int machine_at_micronics386_init(const machine_t *); -extern int machine_at_ECS_386V_init(const machine_t *); +extern int machine_at_ecs386v_init(const machine_t *); extern int machine_at_rycleopardlx_init(const machine_t *); @@ -497,6 +497,7 @@ extern int machine_at_ami471_init(const machine_t *); extern int machine_at_dtk486_init(const machine_t *); extern int machine_at_px471_init(const machine_t *); extern int machine_at_win471_init(const machine_t *); +extern int machine_at_pci400ca_init(const machine_t *); extern int machine_at_vi15g_init(const machine_t *); extern int machine_at_greenb_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 1df960fa8..ea1c7e1eb 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -226,7 +226,7 @@ machine_at_spc6000a_init(const machine_t *model) } int -machine_at_ECS_386V_init(const machine_t *model) +machine_at_ecs386v_init(const machine_t *model) { int ret; @@ -791,6 +791,39 @@ machine_at_win471_init(const machine_t *model) return ret; } +int +machine_at_pci400ca_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/JB_PCI400C_A/486-AA008851.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SCSI, 1, 2, 3, 4); + pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&keyboard_ps2_ami_device); + device_add(&sio_device); + device_add(&intel_flash_bxt_ami_device); + + device_add(&i420tx_device); + device_add(&ncr53c810_onboard_pci_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + int machine_at_vi15g_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 19b1c6b32..9371aeb5b 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -4793,7 +4793,7 @@ const machine_t machines[] = { .internal_name = "ECS_386V", .type = MACHINE_TYPE_386DX, .chipset = MACHINE_CHIPSET_ALI_M1429, - .init = machine_at_ECS_386V_init, + .init = machine_at_ecs386v_init, .pad = 0, .pad0 = 0, .pad1 = MACHINE_AVAILABLE, @@ -4816,7 +4816,7 @@ const machine_t machines[] = { .step = 1024, }, .nvrmask = 127, - .kbc = KBC_UNKNOWN, + .kbc_device = NULL, .kbc_p1 = 0, .gpio = 0, .device = NULL, @@ -5825,6 +5825,45 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* AMIKey-2 */ + { + .name = "[i420TX] J-Bond PCI400C-A", + .internal_name = "pci400ca", + .type = MACHINE_TYPE_486_S2, + .chipset = MACHINE_CHIPSET_INTEL_420TX, + .init = machine_at_pci400ca_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_SOCKET3, + .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_PS2_PCI, + .flags = MACHINE_SCSI, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = &keyboard_ps2_ami_device, + .kbc_p1 = 0, + .gpio = 0, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* 486 machines - Socket 3 */ /* 486 machines with just the ISA slot */ From 6334bd89934e1429a4ed911940ba9868669f5227 Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Thu, 6 Jul 2023 20:49:33 +0200 Subject: [PATCH 006/936] Add the ZEOS Martin (currently has memory related issues, to be fixed) --- src/include/86box/machine.h | 1 + src/machine/m_at_386dx_486.c | 21 ++++++++++++++++++- src/machine/machine_table.c | 39 ++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index d2ee8330a..c133c111b 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -498,6 +498,7 @@ extern int machine_at_dtk486_init(const machine_t *); extern int machine_at_px471_init(const machine_t *); extern int machine_at_win471_init(const machine_t *); extern int machine_at_pci400ca_init(const machine_t *); +extern int machine_at_zmartin_init(const machine_t *); extern int machine_at_vi15g_init(const machine_t *); extern int machine_at_greenb_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 19048f889..2e47c7112 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -796,7 +796,7 @@ machine_at_pci400ca_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/JB_PCI400C_A/486-AA008851.BIN", + ret = bios_load_linear("roms/machines/pci400ca/486-AA008851.BIN", 0x000e0000, 131072, 0); if (bios_only || !ret) @@ -824,6 +824,25 @@ machine_at_pci400ca_init(const machine_t *model) return ret; } +int +machine_at_zmartin_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/zeos_martin/rel11.bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&keyboard_at_device); + device_add(&intel_flash_bxt_ami_device); + device_add(&fdc37c651_device); + + return ret; +} + int machine_at_vi15g_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 9371aeb5b..b1db74bf8 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -5864,6 +5864,45 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* KBC?? Does the VLSI have On-Chip KBC? */ + { + .name = "[VLSI 82C480] ZEOS Martin", + .internal_name = "zmartin", + .type = MACHINE_TYPE_486_S2, + .chipset = MACHINE_CHIPSET_VLSI_VL82C480, + .init = machine_at_zmartin_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_SOCKET3, + .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_VLB, + .flags = MACHINE_SUPER_IO, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0, + .gpio = 0, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, //&fdc37c651_device, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* 486 machines - Socket 3 */ /* 486 machines with just the ISA slot */ From 1438e7f4e84434249d3e769117a8f1194d49d5dc Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Fri, 7 Jul 2023 23:33:57 +0200 Subject: [PATCH 007/936] Add the AMI Super Voyager PCI (S76) --- src/include/86box/machine.h | 1 + src/machine/m_at_386dx_486.c | 30 +++++++++++++++++++++++++++ src/machine/machine_table.c | 39 ++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index c133c111b..11095c75b 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -508,6 +508,7 @@ extern int machine_at_4dps_init(const machine_t *); extern int machine_at_4saw2_init(const machine_t *); extern int machine_at_m4li_init(const machine_t *); extern int machine_at_alfredo_init(const machine_t *); +extern int machine_at_amis76_init(const machine_t *); extern int machine_at_ninja_init(const machine_t *); extern int machine_at_486sp3_init(const machine_t *); extern int machine_at_486sp3c_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 2e47c7112..e95c913e8 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1157,6 +1157,36 @@ machine_at_486sp3_init(const machine_t *model) return ret; } +int +machine_at_amis76_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_inverted("roms/machines/s76p/s76p.rom", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + // pci_register_slot(0x01, PCI_CARD_IDE, 1, 2, 3 ,4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sio_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_ami_device); + + device_add(&i420tx_device); + // device_add(&ide_cmd640_pci_device); /* is this actually cmd640? is it single channel? */ + device_add(&ide_pci_device); + + return ret; +} + int machine_at_pci400cb_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index b1db74bf8..25cb27fdb 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -6736,6 +6736,45 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* According to another string seen on the UH19 website, this has AMI 'H' KBC. */ + { + .name = "[i420TX] AMI Super Voyager PCI", + .internal_name = "amis76", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_INTEL_420TX, + .init = machine_at_amis76_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_SOCKET3, + .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_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_SCSI | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0, + .gpio = 0, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* This has an AMIKey-2, which is an updated version of type 'H'. Also has a SST 29EE010 Flash chip. */ { From 69ff1c60f7f87756fe09f1801d23cac647fc9b96 Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Sun, 9 Jul 2023 15:55:58 +0200 Subject: [PATCH 008/936] Add Anigma BAT4IP3E (IDE needs work) --- src/include/86box/machine.h | 1 + src/machine/m_at_386dx_486.c | 29 +++++++++++++++++++++++++ src/machine/machine_table.c | 41 +++++++++++++++++++++++++++++++++++- 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 11095c75b..4f57a52dd 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -510,6 +510,7 @@ extern int machine_at_m4li_init(const machine_t *); extern int machine_at_alfredo_init(const machine_t *); extern int machine_at_amis76_init(const machine_t *); extern int machine_at_ninja_init(const machine_t *); +extern int machine_at_bat4ip3e_init(const machine_t *); extern int machine_at_486sp3_init(const machine_t *); extern int machine_at_486sp3c_init(const machine_t *); extern int machine_at_486sp3g_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 76d1d520b..49a005467 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1117,6 +1117,35 @@ machine_at_ninja_init(const machine_t *model) return ret; } +int +machine_at_bat4ip3e_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/bat4ip3e/404C.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1 | PCI_NO_IRQ_STEERING); + pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_IDE, 0xfe, 0xff, 0, 0); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 1, 2); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 1, 2, 1); + pci_register_slot(0x0a, PCI_CARD_NORMAL, 1, 2, 1, 2); + + device_add(&phoenix_486_jumper_pci_device); + device_add(&keyboard_ps2_pci_device); + device_add(&fdc37c665_device); + device_add(&i420ex_device); + device_add(&ide_cmd640_pci_device); + + return ret; +} + int machine_at_486sp3_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 25cb27fdb..c8ee7d7e1 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -6658,6 +6658,45 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has Phoenix Multikey/42 PS/2 KBC, but unknown version */ + { + .name = "[i420EX] Anigma BAT4IP3e", + .internal_name = "bat4ip3e", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_INTEL_420EX, + .init = machine_at_bat4ip3e_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_SOCKET3, + .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_PS2_PCI, + .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0, + .gpio = 0, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* I'm going to assume this as an AMIKey-2 like the other two 486SP3's. */ { .name = "[i420TX] ASUS PCI/I-486SP3", @@ -6758,7 +6797,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_SCSI | MACHINE_APM, + .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 1024, .max = 131072, From ea713a3374ffec52abbf4f586b4bbe1de5d27850 Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Tue, 11 Jul 2023 13:14:54 +0200 Subject: [PATCH 009/936] Add AIR 486PI --- src/include/86box/machine.h | 1 + src/machine/m_at_386dx_486.c | 26 ++++++++++++++++++++++++ src/machine/machine_table.c | 39 ++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 4f57a52dd..52cac6d8b 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -511,6 +511,7 @@ extern int machine_at_alfredo_init(const machine_t *); extern int machine_at_amis76_init(const machine_t *); extern int machine_at_ninja_init(const machine_t *); extern int machine_at_bat4ip3e_init(const machine_t *); +extern int machine_at_486pi_init(const machine_t *); extern int machine_at_486sp3_init(const machine_t *); extern int machine_at_486sp3c_init(const machine_t *); extern int machine_at_486sp3g_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 49a005467..cc4345db5 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1146,6 +1146,32 @@ machine_at_bat4ip3e_init(const machine_t *model) return ret; } +int +machine_at_486pi_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/486pi/486pi.bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1 | PCI_NO_IRQ_STEERING); + pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 1, 2); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 2, 1); + pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 1, 2); + + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c665_device); + device_add(&i420ex_device); + + return ret; +} + int machine_at_486sp3_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index c8ee7d7e1..1699094d8 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -6697,6 +6697,45 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[i420EX] Advanced Integration Research 486PI", + .internal_name = "486pi", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_INTEL_420EX, + .init = machine_at_486pi_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_SOCKET3, + .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_PCIV, + .flags = MACHINE_SUPER_IO | MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0, + .gpio = 0, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* I'm going to assume this as an AMIKey-2 like the other two 486SP3's. */ { .name = "[i420TX] ASUS PCI/I-486SP3", From e014dc4ee1a3b5ea97b63d079ce098faecf4d72d Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Tue, 11 Jul 2023 14:02:02 +0200 Subject: [PATCH 010/936] Add ECS AL486 --- src/include/86box/machine.h | 1 + src/machine/m_at_386dx_486.c | 22 ++++++++++++++++++- src/machine/machine_table.c | 41 +++++++++++++++++++++++++++++++++++- 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 52cac6d8b..7b372836c 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -542,6 +542,7 @@ extern int machine_at_spc7700plw_init(const machine_t *); extern int machine_at_ms4134_init(const machine_t *); extern int machine_at_tg486gp_init(const machine_t *); extern int machine_at_tg486g_init(const machine_t *); +extern int machine_at_ecsal486_init(const machine_t *); /* m_at_commodore.c */ extern int machine_at_cmdpc_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index cc4345db5..479f60194 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -230,7 +230,7 @@ machine_at_ecs386v_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/ECS_386V/PANDA_386V.BIN", + ret = bios_load_linear("roms/machines/ecs386v/PANDA_386V.BIN", 0x000f0000, 65536, 0); if (bios_only || !ret) @@ -1970,4 +1970,24 @@ machine_at_tg486g_init(const machine_t *model) return ret; } +int +machine_at_ecsal486_init(const machine_t *model) +{ + int ret; + ret = bios_load_linear("roms/machines/ecsal486/ECS_AL486.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&ali1429g_device); + device_add(&keyboard_ps2_ami_pci_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 1699094d8..122e54fc8 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -4790,7 +4790,7 @@ const machine_t machines[] = { /* Has AMI Megakey P KBC firmware */ { .name = "[ALi M1429] ECS Panda 386V", - .internal_name = "ECS_386V", + .internal_name = "ecs386v", .type = MACHINE_TYPE_386DX, .chipset = MACHINE_CHIPSET_ALI_M1429, .init = machine_at_ecs386v_init, @@ -6257,6 +6257,45 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[ALi M1429G] ECS AL486", + .internal_name = "ecsal486", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_ALI_M1429G, + .init = machine_at_ecsal486_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_SOCKET3, + .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_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 98304, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0, + .gpio = 0, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* 486 machines which utilize the PCI bus */ /* Machine with ALi M1429G chipset and M1435 southbridge */ From 75c2ef2347bbdacb4c4efc1ab7a66d7e69cd670a Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Tue, 11 Jul 2023 17:38:20 +0200 Subject: [PATCH 011/936] Add the Lanner Electronics AP-4100AA SBC. --- src/include/86box/machine.h | 1 + src/machine/m_at_386dx_486.c | 22 ++++++++++++++++++++ src/machine/machine_table.c | 39 ++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 7b372836c..b5306b0f6 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -543,6 +543,7 @@ extern int machine_at_ms4134_init(const machine_t *); extern int machine_at_tg486gp_init(const machine_t *); extern int machine_at_tg486g_init(const machine_t *); extern int machine_at_ecsal486_init(const machine_t *); +extern int machine_at_ap4100aa_init(const machine_t *); /* m_at_commodore.c */ extern int machine_at_cmdpc_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 479f60194..2cbb4be54 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1991,3 +1991,25 @@ machine_at_ecsal486_init(const machine_t *model) return ret; } + +int +machine_at_ap4100aa_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ap4100aa/M27C512DIP28.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + device_add(&ami_1994_nvr_device); + device_add(&ali1429g_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&ide_vlb_device); + device_add(&um8669f_device); // needs um8663 + + return ret; +} \ No newline at end of file diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 122e54fc8..f788eb29f 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -6296,6 +6296,45 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* This uses a VIA VT82C42N KBC, which is a clone of type 'F' with additional commands */ + { + .name = "[ALi M1429G] Lanner Electronics AP-4100AA", + .internal_name = "ap4100aa", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_ALI_M1429G, + .init = machine_at_ap4100aa_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_SOCKET3, + .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_AT, + .flags = MACHINE_SUPER_IO | MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0, + .gpio = 0, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* 486 machines which utilize the PCI bus */ /* Machine with ALi M1429G chipset and M1435 southbridge */ From 08f1004f41d01802d7256c2b611cfb2502bb9f88 Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Tue, 11 Jul 2023 21:06:40 +0200 Subject: [PATCH 012/936] Add the ICS SB486P --- src/include/86box/machine.h | 1 + src/machine/m_at_386dx_486.c | 25 +++++++++++++++++++++++ src/machine/machine_table.c | 39 ++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index b5306b0f6..8da1f77a1 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -512,6 +512,7 @@ extern int machine_at_amis76_init(const machine_t *); extern int machine_at_ninja_init(const machine_t *); extern int machine_at_bat4ip3e_init(const machine_t *); extern int machine_at_486pi_init(const machine_t *); +extern int machine_at_sb486p_init(const machine_t *); extern int machine_at_486sp3_init(const machine_t *); extern int machine_at_486sp3c_init(const machine_t *); extern int machine_at_486sp3g_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 2cbb4be54..52a50be29 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1172,6 +1172,31 @@ machine_at_486pi_init(const machine_t *model) return ret; } +int +machine_at_sb486p_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/sb486p/amiboot.rom", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1 | PCI_NO_IRQ_STEERING); + pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 1, 2); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 2, 1); + + device_add(&keyboard_ps2_ami_pci_device); + device_add(&i82091aa_device); + device_add(&i420ex_device); + + return ret; +} + int machine_at_486sp3_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index f788eb29f..3b557abfa 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -6814,6 +6814,45 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* absolutely no KBC info */ + { + .name = "[i420EX] ICS SB486P", + .internal_name = "sb486p", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_INTEL_420EX, + .init = machine_at_sb486p_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_SOCKET3, + .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_PCI, + .flags = MACHINE_SUPER_IO | MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0, + .gpio = 0, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* I'm going to assume this as an AMIKey-2 like the other two 486SP3's. */ { .name = "[i420TX] ASUS PCI/I-486SP3", From dd26f73896f91e06813b27e19aa35248b6d8760a Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Tue, 11 Jul 2023 21:34:39 +0200 Subject: [PATCH 013/936] Make the i420EX machines correctly have PCI IRQ steering. --- src/machine/m_at_386dx_486.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 52a50be29..71a84a449 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1103,7 +1103,7 @@ machine_at_ninja_init(const machine_t *model) machine_at_common_init(model); - pci_init(PCI_CONFIG_TYPE_1 | PCI_NO_IRQ_STEERING); + pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 1, 2); pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 2, 1); @@ -1130,7 +1130,7 @@ machine_at_bat4ip3e_init(const machine_t *model) machine_at_common_init(model); - pci_init(PCI_CONFIG_TYPE_1 | PCI_NO_IRQ_STEERING); + pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_IDE, 0xfe, 0xff, 0, 0); pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 1, 2); @@ -1159,7 +1159,7 @@ machine_at_486pi_init(const machine_t *model) machine_at_common_init(model); - pci_init(PCI_CONFIG_TYPE_1 | PCI_NO_IRQ_STEERING); + pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 1, 2); pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 2, 1); @@ -1185,7 +1185,7 @@ machine_at_sb486p_init(const machine_t *model) machine_at_common_init(model); - pci_init(PCI_CONFIG_TYPE_1 | PCI_NO_IRQ_STEERING); + pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 1, 2); pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 2, 1); @@ -1367,7 +1367,7 @@ machine_at_486ap4_init(const machine_t *model) machine_at_common_init(model); - pci_init(PCI_CONFIG_TYPE_1 | PCI_NO_IRQ_STEERING); + pci_init(PCI_CONFIG_TYPE_1); /* Excluded: 5, 6, 7, 8 */ pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 09 = Slot 1 */ From 7ff141ba995998b2346e30c2ebef31cb98663e41 Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Thu, 13 Jul 2023 00:50:02 +0200 Subject: [PATCH 014/936] Add the Olivetti M4-5xx. --- src/include/86box/machine.h | 1 + src/machine/m_at_386dx_486.c | 31 ++++++++++++++++++++++++++++ src/machine/machine_table.c | 39 ++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 8da1f77a1..f9d0459b2 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -485,6 +485,7 @@ extern int machine_at_403tg_init(const machine_t *); extern int machine_at_403tg_d_init(const machine_t *); extern int machine_at_403tg_d_mr_init(const machine_t *); extern int machine_at_pc330_6573_init(const machine_t *); +extern int machine_at_m45xx_init(const machine_t *); extern int machine_at_mvi486_init(const machine_t *); extern int machine_at_sis401_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 71a84a449..ebe122e66 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -670,6 +670,37 @@ machine_at_pc330_6573_init(const machine_t *model) /* doesn't like every CPU oth return ret; } +int +machine_at_m45xx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_inverted("roms/machines/m45xx/optoli_082594.rom", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + device_add(&ami_1994_nvr_device); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x15, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x16, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x12, PCI_CARD_IDE, 0xFF, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_VIDEO, 2, 0, 0, 0); + + device_add(&opti802g_pci_device); + device_add(&opti822_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c665_device); + device_add(&ide_vlb_device); + device_add(&intel_flash_bxt_device); // Just in case, no idea if it has it or not + + return ret; +} + int machine_at_mvi486_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 3b557abfa..93097f5fd 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -6658,6 +6658,45 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Absolutely no information. Anything here is guesswork. */ + { + .name = "[OPTi 802GP] Olivetti M4-5xx", + .internal_name = "m45xx", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_OPTI_895_802G, //OPTi 802GP + .init = machine_at_m45xx_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_SOCKET3, + .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_PS2_PCIV, + .flags = MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0, + .gpio = 0, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* This has an AMIKey-2, which is an updated version of type 'H'. */ { .name = "[i420EX] ASUS PVI-486AP4", From 04ded0492cff06b70b10a2f809df415984035bce Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Thu, 13 Jul 2023 12:24:54 +0200 Subject: [PATCH 015/936] Add the Epson ActionTower 8400. --- src/include/86box/machine.h | 1 + src/machine/m_at_386dx_486.c | 31 ++++++++++++++++++++++++++++ src/machine/machine_table.c | 40 ++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index f9d0459b2..b2fcdad76 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -539,6 +539,7 @@ extern int machine_at_ecs486_init(const machine_t *); extern int machine_at_hot433_init(const machine_t *); extern int machine_at_atc1415_init(const machine_t *); extern int machine_at_actionpc2600_init(const machine_t *); +extern int machine_at_actiontower8400_init(const machine_t *); extern int machine_at_m919_init(const machine_t *); extern int machine_at_spc7700plw_init(const machine_t *); extern int machine_at_ms4134_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index ebe122e66..b4122821a 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1874,6 +1874,37 @@ machine_at_actionpc2600_init(const machine_t *model) return ret; } +int +machine_at_actiontower8400_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/actiontower8400/V31C.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + if (gfxcard[0] == VID_INTERNAL) + pci_register_slot(0x15, PCI_CARD_VIDEO, 0, 0, 0, 0); + pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x14, PCI_CARD_NORMAL, 2, 3, 4, 1); + + device_add(&umc_hb4_device); + device_add(&umc_8886af_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_device); // The ActionPC 2600 has this so I'm gonna assume this does too. + device_add(&keyboard_ps2_ami_pci_device); + if (gfxcard[0] == VID_INTERNAL) + device_add(&gd5430_pci_device); // VBIOS not included in BIOS ROM + + return ret; +} + int machine_at_m919_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 93097f5fd..8981f1c4f 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -7480,6 +7480,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* This has the UMC 88xx on-chip KBC. All the copies of the BIOS string I can find, end in + in -H, so the UMC on-chip KBC likely emulates the AMI 'H' KBC firmware. */ + { + .name = "[UMC 8881] Epson ActionTower 8400", + .internal_name = "actiontower8400", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_UMC_UM8881, + .init = machine_at_actiontower8400_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_SOCKET3, + .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_PS2_PCI, + .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_VIDEO, + .ram = { + .min = 1024, + .max = 262144, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0, + .gpio = 0, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* This has the UMC 88xx on-chip KBC. All the copies of the BIOS string I can find, end in in -H, so the UMC on-chip KBC likely emulates the AMI 'H' KBC firmware. */ { From 635c00227dc95888e268325167b35d74e7009298 Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Thu, 13 Jul 2023 13:49:29 +0200 Subject: [PATCH 016/936] Add the Acrosser AR-B1476 --- src/include/86box/machine.h | 1 + src/machine/m_at_386dx_486.c | 23 +++++++++++++++++++++ src/machine/machine_table.c | 39 ++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index b2fcdad76..fc0cfd873 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -525,6 +525,7 @@ extern int machine_at_win486pci_init(const machine_t *); extern int machine_at_ms4145_init(const machine_t *); extern int machine_at_sbc490_init(const machine_t *); extern int machine_at_tf486_init(const machine_t *); +extern int machine_at_arb1476_init(const machine_t *); extern int machine_at_pci400cb_init(const machine_t *); extern int machine_at_g486ip_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index b4122821a..888b1bddc 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1613,6 +1613,29 @@ machine_at_tf486_init(const machine_t *model) return ret; } +int +machine_at_arb1476_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/arb1476/w1476b.v21", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + + device_add(&ali1489_device); + device_add(&fdc37c669_device); + device_add(&keyboard_ps2_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + int machine_at_itoxstar_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 8981f1c4f..e92ad21d2 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -6619,6 +6619,45 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has an ALi M5042 with phoenix firmware like the ESA TF-486. */ + { + .name = "[ALi M1489] Acrosser AR-B1476", + .internal_name = "arb1476", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_ALI_M1489, + .init = machine_at_arb1476_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_SOCKET3, + .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_PS2, + .flags = MACHINE_SUPER_IO | MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0, + .gpio = 0, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Has IBM PS/2 Type 1 KBC firmware. */ { .name = "[OPTi 802G] IBM PC 330 (type 6573)", From 0d8071ff77dc75e2fec28c3989f47ed382697905 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 21 Jul 2023 01:27:19 +0600 Subject: [PATCH 017/936] C&T 69000 (broken) --- src/include/86box/video.h | 3 + src/machine/m_at_socket370.c | 4 + src/machine/machine_table.c | 2 +- src/video/CMakeLists.txt | 3 +- src/video/vid_c&t_69000.c | 1353 ++++++++++++++++++++++++++++++++++ src/video/vid_table.c | 1 + 6 files changed, 1364 insertions(+), 2 deletions(-) create mode 100644 src/video/vid_c&t_69000.c diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 418423ea9..4c94fabfd 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -537,6 +537,9 @@ extern const device_t velocity_200_agp_device; /* Wyse 700 */ extern const device_t wy700_device; +/* Chips & Technologies */ +extern const device_t chips_69000_device; + #endif #endif /*EMU_VIDEO_H*/ diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index b8cc437a1..5e60885f3 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -312,6 +312,10 @@ machine_at_awo671r_init(const machine_t *model) device_add_inst(&w83977ef_device, 2); device_add(&keyboard_ps2_pci_device); device_add(&sst_flash_39sf020_device); + if (gfxcard[0] == VID_INTERNAL) { + extern const device_t chips_69000_onboard_device; + device_add(&chips_69000_onboard_device); + } spd_register(SPD_TYPE_SDRAM, 0x3, 256); return ret; diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index e73b74736..ea5d06a70 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -12478,7 +12478,7 @@ const machine_t machines[] = { .max_multi = 8.0 /* limits assumed */ }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_VIDEO, .ram = { .min = 8192, .max = 524288, diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index b37e81134..70ef72b7a 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -25,7 +25,8 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c vid_rtg310x.c vid_f82c425.c vid_ti_cf62011.c vid_tvga.c vid_tgui9440.c vid_tkd8001_ramdac.c vid_att20c49x_ramdac.c vid_s3.c vid_s3_virge.c vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_nga.c - vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c) + vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c + vid_c&t_69000.c) if(MGA) target_compile_definitions(vid PRIVATE USE_MGA) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c new file mode 100644 index 000000000..fe22985e0 --- /dev/null +++ b/src/video/vid_c&t_69000.c @@ -0,0 +1,1353 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * C&T 69000 emulation. + * + * + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/device.h> +#include <86box/timer.h> +#include <86box/video.h> +#include <86box/vid_svga.h> +#include <86box/vid_svga_render.h> +#include <86box/pci.h> +#include <86box/thread.h> +#include + +typedef struct chips_69000_t { + svga_t svga; + uint8_t pci_conf_status; + uint8_t pci_line_interrupt; + uint8_t pci_rom_enable; + uint8_t read_write_bank; + atomic_bool engine_active; + atomic_bool quit; + thread_t *accel_thread; + event_t *fifo_event, *fifo_data_event; + pc_timer_t decrement_timer; + uint16_t rom_addr; + mem_mapping_t linear_mapping; + uint8_t on_board; + + rgb_t cursor_palette[8]; + uint32_t cursor_pallook[8]; + + uint8_t mm_regs[256], mm_index; + uint8_t flat_panel_regs[256], flat_panel_index; + uint8_t ext_regs[256], ext_index; + + union { + uint32_t mem_regs[4]; + uint16_t mem_regs_w[4 * 2]; + uint8_t mem_regs_b[4 * 4]; + }; + union { + uint32_t bitblt_regs[16]; + uint16_t bitblt_regs_w[16 * 2]; + uint8_t bitblt_regs_b[16 * 4]; + }; + + union { + uint16_t subsys_vid; + uint8_t subsys_vid_b[2]; + }; + + union { + uint16_t subsys_pid; + uint8_t subsys_pid_b[2]; + }; + + rom_t bios_rom; +} chips_69000_t; + +static video_timings_t timing_sis = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 20, .read_w = 20, .read_l = 35 }; + +void +chips_69000_do_rop_8bpp(uint8_t *dst, uint8_t src, uint8_t rop) +{ + switch (rop) { + case 0x00: + *dst = 0; + break; + case 0x11: + *dst = ~(*dst) & ~src; + break; + case 0x22: + *dst &= ~src; + break; + case 0x33: + *dst = ~src; + break; + case 0x44: + *dst = src & ~(*dst); + break; + case 0x55: + *dst = ~*dst; + break; + case 0x66: + *dst ^= src; + break; + case 0x77: + *dst = ~src | ~(*dst); + break; + case 0x88: + *dst &= src; + break; + case 0x99: + *dst ^= ~src; + break; + case 0xAA: + break; /* No-op. */ + case 0xBB: + *dst |= ~src; + break; + case 0xCC: + *dst = src; + break; + case 0xDD: + *dst = src | ~(*dst); + break; + case 0xEE: + *dst |= src; + break; + case 0xFF: + *dst = 0xFF; + break; + } +} + +void +chips_69000_do_rop_15bpp(uint16_t *dst, uint16_t src, uint8_t rop) +{ + uint16_t orig_dst = *dst & 0x8000; + switch (rop) { + case 0x00: + *dst = 0; + break; + case 0x11: + *dst = ~(*dst) & ~src; + break; + case 0x22: + *dst &= ~src; + break; + case 0x33: + *dst = ~src; + break; + case 0x44: + *dst = src & ~(*dst); + break; + case 0x55: + *dst = ~*dst; + break; + case 0x66: + *dst ^= src; + break; + case 0x77: + *dst = ~src | ~(*dst); + break; + case 0x88: + *dst &= src; + break; + case 0x99: + *dst ^= ~src; + break; + case 0xAA: + break; /* No-op. */ + case 0xBB: + *dst |= ~src; + break; + case 0xCC: + *dst = src; + break; + case 0xDD: + *dst = src | ~(*dst); + break; + case 0xEE: + *dst |= src; + break; + case 0xFF: + *dst = ~0; + break; + } + *dst &= 0x7FFF; + *dst |= orig_dst; +} + +void +chips_69000_do_rop_16bpp(uint16_t *dst, uint16_t src, uint8_t rop) +{ + switch (rop) { + case 0x00: + *dst = 0; + break; + case 0x11: + *dst = ~(*dst) & ~src; + break; + case 0x22: + *dst &= ~src; + break; + case 0x33: + *dst = ~src; + break; + case 0x44: + *dst = src & ~(*dst); + break; + case 0x55: + *dst = ~*dst; + break; + case 0x66: + *dst ^= src; + break; + case 0x77: + *dst = ~src | ~(*dst); + break; + case 0x88: + *dst &= src; + break; + case 0x99: + *dst ^= ~src; + break; + case 0xAA: + break; /* No-op. */ + case 0xBB: + *dst |= ~src; + break; + case 0xCC: + *dst = src; + break; + case 0xDD: + *dst = src | ~(*dst); + break; + case 0xEE: + *dst |= src; + break; + case 0xFF: + *dst = 0xFF; + break; + } +} + +void +chips_69000_do_rop_24bpp(uint32_t *dst, uint32_t src, uint8_t rop) +{ + uint32_t orig_dst = *dst & 0xFF000000; + switch (rop) { + case 0x00: + *dst = 0; + break; + case 0x11: + *dst = ~(*dst) & ~src; + break; + case 0x22: + *dst &= ~src; + break; + case 0x33: + *dst = ~src; + break; + case 0x44: + *dst = src & ~(*dst); + break; + case 0x55: + *dst = ~*dst; + break; + case 0x66: + *dst ^= src; + break; + case 0x77: + *dst = ~src | ~(*dst); + break; + case 0x88: + *dst &= src; + break; + case 0x99: + *dst ^= ~src; + break; + case 0xAA: + break; /* No-op. */ + case 0xBB: + *dst |= ~src; + break; + case 0xCC: + *dst = src; + break; + case 0xDD: + *dst = src | ~(*dst); + break; + case 0xEE: + *dst |= src; + break; + case 0xFF: + *dst = 0xFF; + break; + } + *dst &= 0xFFFFFF; + *dst |= orig_dst; +} + +void +chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t src, uint8_t nonpattern_src, uint8_t rop) +{ + switch (rop) { + case 0x00: + *dst = 0; + break; + case 0x05: + *dst = ~(*dst) & ~src; + break; + case 0x0A: + *dst &= ~src; + break; + case 0x0F: + *dst = ~src; + break; + case 0x50: + *dst = src & ~(*dst); + break; + case 0x55: + *dst = ~*dst; + break; + case 0x5A: + *dst ^= src; + break; + case 0x5F: + *dst = ~src | ~(*dst); + break; + case 0xB8: + *dst = (((src ^ *dst) & nonpattern_src) ^ src); + break; + case 0xA0: + *dst &= src; + break; + case 0xA5: + *dst ^= ~src; + break; + case 0xAA: + break; /* No-op. */ + case 0xAF: + *dst |= ~src; + break; + case 0xF0: + *dst = src; + break; + case 0xF5: + *dst = src | ~(*dst); + break; + case 0xFA: + *dst |= src; + break; + case 0xFF: + *dst = 0xFF; + break; + } +} + +void +chips_69000_do_rop_15bpp_patterned(uint16_t *dst, uint16_t src, uint8_t nonpattern_src, uint8_t rop) +{ + uint16_t orig_dst = *dst & 0x8000; + switch (rop) { + case 0x00: + *dst = 0; + break; + case 0x05: + *dst = ~(*dst) & ~src; + break; + case 0x0A: + *dst &= ~src; + break; + case 0x0F: + *dst = ~src; + break; + case 0x50: + *dst = src & ~(*dst); + break; + case 0x55: + *dst = ~*dst; + break; + case 0x5A: + *dst ^= src; + break; + case 0x5F: + *dst = ~src | ~(*dst); + break; + case 0xB8: + *dst = (((src ^ *dst) & nonpattern_src) ^ src); + break; + case 0xA0: + *dst &= src; + break; + case 0xA5: + *dst ^= ~src; + break; + case 0xAA: + break; /* No-op. */ + case 0xAF: + *dst |= ~src; + break; + case 0xF0: + *dst = src; + break; + case 0xF5: + *dst = src | ~(*dst); + break; + case 0xFA: + *dst |= src; + break; + case 0xFF: + *dst = 0xFF; + break; + } + *dst &= 0x7FFF; + *dst |= orig_dst; +} + +void +chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint8_t nonpattern_src, uint8_t rop) +{ + switch (rop) { + case 0x00: + *dst = 0; + break; + case 0x05: + *dst = ~(*dst) & ~src; + break; + case 0x0A: + *dst &= ~src; + break; + case 0x0F: + *dst = ~src; + break; + case 0x50: + *dst = src & ~(*dst); + break; + case 0x55: + *dst = ~*dst; + break; + case 0x5A: + *dst ^= src; + break; + case 0x5F: + *dst = ~src | ~(*dst); + break; + case 0xB8: + *dst = (((src ^ *dst) & nonpattern_src) ^ src); + break; + case 0xA0: + *dst &= src; + break; + case 0xA5: + *dst ^= ~src; + break; + case 0xAA: + break; /* No-op. */ + case 0xAF: + *dst |= ~src; + break; + case 0xF0: + *dst = src; + break; + case 0xF5: + *dst = src | ~(*dst); + break; + case 0xFA: + *dst |= src; + break; + case 0xFF: + *dst = 0xFF; + break; + } +} + +void +chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t src, uint8_t nonpattern_src, uint8_t rop) +{ + uint32_t orig_dst = *dst & 0xFF000000; + switch (rop) { + case 0x00: + *dst = 0; + break; + case 0x05: + *dst = ~(*dst) & ~src; + break; + case 0x0A: + *dst &= ~src; + break; + case 0x0F: + *dst = ~src; + break; + case 0x50: + *dst = src & ~(*dst); + break; + case 0x55: + *dst = ~*dst; + break; + case 0x5A: + *dst ^= src; + break; + case 0x5F: + *dst = ~src | ~(*dst); + break; + case 0xB8: + *dst = (((src ^ *dst) & nonpattern_src) ^ src); + break; + case 0xA0: + *dst &= src; + break; + case 0xA5: + *dst ^= ~src; + break; + case 0xAA: + break; /* No-op. */ + case 0xAF: + *dst |= ~src; + break; + case 0xF0: + *dst = src; + break; + case 0xF5: + *dst = src | ~(*dst); + break; + case 0xFA: + *dst |= src; + break; + case 0xFF: + *dst = 0xFF; + break; + } + *dst &= 0xFFFFFF; + *dst |= orig_dst; +} + +void +chips_69000_recalctimings(svga_t *svga) +{ + chips_69000_t *chips = (chips_69000_t *) svga->p; + + if (chips->ext_regs[0x81] & 0x10) { + svga->htotal -= 5; + } + + if (chips->ext_regs[0x09] & 0x1) { + svga->vtotal -= 2; + svga->vtotal &= 0xFF; + svga->vtotal |= (svga->crtc[0x30] & 0xF) << 8; + svga->vtotal += 2; + + svga->dispend--; + svga->dispend &= 0xFF; + svga->dispend |= (svga->crtc[0x31] & 0xF) << 8; + svga->dispend++; + + svga->vsyncstart--; + svga->vsyncstart &= 0xFF; + svga->vsyncstart |= (svga->crtc[0x32] & 0xF) << 8; + svga->vsyncstart++; + + svga->vblankstart--; + svga->vblankstart &= 0xFF; + svga->vblankstart |= (svga->crtc[0x33] & 0xF) << 8; + svga->vblankstart++; + + if (!(chips->ext_regs[0x81] & 0x10)) + svga->htotal -= 5; + + svga->htotal |= (svga->crtc[0x38] & 0x1) << 8; + + if (!(chips->ext_regs[0x81] & 0x10)) + svga->htotal += 5; + + /* Let's care about horizontal blanking end later when it matters. */ + + svga->ma_latch |= (svga->crtc[0x40] & 0xF) << 16; + svga->rowoffset |= (svga->crtc[0x41] & 0xF) << 16; + } + + svga->interlace = !!(svga->crtc[0x70] & 0x80); + + switch (chips->ext_regs[0x81] & 0xF) { + case 0b0010: + svga->bpp = 8; + svga->render = svga_render_8bpp_highres; + svga->rowoffset <<= 2; + break; + + case 0b0100: + svga->bpp = 15; + svga->render = svga_render_15bpp_highres; + svga->rowoffset <<= 2; + break; + case 0b0101: + svga->bpp = 16; + svga->render = svga_render_16bpp_highres; + svga->rowoffset <<= 2; + break; + case 0b0110: + svga->bpp = 24; + svga->render = svga_render_24bpp_highres; + svga->rowoffset <<= 2; + break; + case 0b0111: + svga->bpp = 32; + svga->render = svga_render_32bpp_highres; + svga->rowoffset <<= 2; + break; + } +} + +void +chips_69000_decrement_timer(void* p) +{ + chips_69000_t *chips = (chips_69000_t*)p; + + chips->ext_regs[0xD2]--; + timer_on_auto(&chips->decrement_timer, 1000000. / 2000.); +} + +void +chips_69000_recalc_banking(chips_69000_t *chips) +{ + svga_t* svga = &chips->svga; + chips->svga.read_bank = chips->svga.write_bank = 0; + + svga->chain2_write = !(svga->seqregs[0x4] & 4); + svga->chain4 = (svga->seqregs[0x4] & 8) || (chips->ext_regs[0xA] & 0x4); + svga->packed_chain4 = !!(chips->ext_regs[0xA] & 0x4); + svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && !(svga->adv_flags & FLAG_ADDR_BY8); + + if (chips->ext_regs[0xA] & 1) { + chips->svga.read_bank = chips->svga.write_bank = 0x10000 * (chips->ext_regs[0xE] & 0x7f); + } + + /*if (chips->ext_regs[0x40] & 2) { + svga->decode_mask = (1 << 18) - 1; + } else { + svga->decode_mask = (1 << 21) - 1; + }*/ +} + +uint8_t +chips_69000_read_ext_reg(chips_69000_t* chips) +{ + uint8_t index = chips->ext_index; + switch (index) { + case 0x00: + return 0x2C; + case 0x01: + return 0x10; + case 0x02: + return 0xC0; + case 0x03: + return 0x00; + case 0x04: + return 0x62; + case 0x05: + case 0x06: + return 0x00; + case 0x08: + return 0x02; + case 0x0A: + return chips->ext_regs[index] & 0x37; + case 0x63: + return 0xFF; + case 0x70: + return 0x3; + case 0x71: + return 0x0; + } + return chips->ext_regs[index]; +} + +void +chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) +{ + switch (chips->ext_index) { + case 0xA: + chips->ext_regs[chips->ext_index] = val & 0x37; + chips_69000_recalc_banking(chips); + break; + case 0xB: + chips->ext_regs[chips->ext_index] = val & 0xD; + break; + case 0xE: + chips->ext_regs[chips->ext_index] = val & 0x7f; + chips_69000_recalc_banking(chips); + break; + case 0x9: + chips->ext_regs[chips->ext_index] = val & 0x3; + svga_recalctimings(&chips->svga); + break; + case 0x40: + chips->ext_regs[chips->ext_index] = val & 0x3; + chips_69000_recalc_banking(chips); + break; + case 0x60: + chips->ext_regs[chips->ext_index] = val & 0x43; + break; + case 0x20: + chips->ext_regs[chips->ext_index] = val & 0x3f; + break; + case 0x61: + chips->ext_regs[chips->ext_index] = val & 0x7f; + break; + case 0x62: + chips->ext_regs[chips->ext_index] = val & 0x9C; + break; + case 0x67: + chips->ext_regs[chips->ext_index] = val & 0x2; + break; + case 0x80: + chips->ext_regs[chips->ext_index] = val & 0xBF; + chips->svga.ramdac_type = (val & 0x80) ? RAMDAC_8BIT : RAMDAC_6BIT; + break; + case 0x81: + chips->ext_regs[chips->ext_index] = val & 0x1f; + svga_recalctimings(&chips->svga); + break; + default: + chips->ext_regs[chips->ext_index] = val; + break; + } +} + +void +chips_69000_out(uint16_t addr, uint8_t val, void *p) +{ + chips_69000_t *chips = (chips_69000_t *) p; + svga_t *svga = &chips->svga; + uint8_t old, index; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + // if (!(addr == 0x3CC || addr == 0x3C9)) pclog("SiS SVGA out: 0x%X, 0x%X\n", addr, val); + switch (addr) { + case 0x3c0: + if (!(chips->ext_regs[0x09] & 0x02)) + break; + svga->attraddr = val & 31; + if ((val & 0x20) != svga->attr_palette_enable) { + svga->fullchange = 3; + svga->attr_palette_enable = val & 0x20; + svga_recalctimings(svga); + } + return; + case 0x3c1: + if ((chips->ext_regs[0x09] & 0x02)) + { + svga->attrff = 1; + svga_out(addr, val, svga); + svga->attrff = 0; + return; + } + break; + case 0x3c9: + if (!(chips->ext_regs[0x09] & 0x01)) + break; + if (svga->adv_flags & FLAG_RAMDAC_SHIFT) + val <<= 2; + svga->fullchange = svga->monitor->mon_changeframecount; + switch (svga->dac_pos) { + case 2: + index = svga->dac_addr & 7; + chips->cursor_palette[index].r = svga->dac_r; + chips->cursor_palette[index].g = svga->dac_g; + chips->cursor_palette[index].b = val; + if (svga->ramdac_type == RAMDAC_8BIT) + chips->cursor_pallook[index] = makecol32(chips->cursor_palette[index].r, chips->cursor_palette[index].g, chips->cursor_palette[index].b); + else + chips->cursor_pallook[index] = makecol32(video_6to8[chips->cursor_palette[index].r & 0x3f], video_6to8[chips->cursor_palette[index].g & 0x3f], video_6to8[chips->cursor_palette[index].b & 0x3f]); + svga->dac_pos = 0; + svga->dac_addr = (svga->dac_addr + 1) & 255; + break; + } + return; + case 0x3c5: + svga_out(addr, val, svga); + chips_69000_recalc_banking(chips); + return; + case 0x3D4: + svga->crtcreg = val & 0xff; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + } + break; + case 0x3D6: + chips->ext_index = val; + return; + case 0x3D7: + return chips_69000_write_ext_reg(chips, val); + + } + svga_out(addr, val, svga); +} + +uint8_t +chips_69000_in(uint16_t addr, void *p) +{ + chips_69000_t *chips = (chips_69000_t *) p; + svga_t *svga = &chips->svga; + uint8_t temp, index; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + // if (!(addr == 0x3CC || addr == 0x3C9)) pclog("SiS SVGA in: 0x%X\n", addr); + switch (addr) { + case 0x3C5: + return svga->seqregs[svga->seqaddr]; + case 0x3c9: + if (!(chips->ext_regs[0x09] & 0x01)) { + temp = svga_in(addr, svga); + break; + } + index = (svga->dac_addr - 1) & 7; + switch (svga->dac_pos) { + case 0: + svga->dac_pos++; + if (svga->ramdac_type == RAMDAC_8BIT) + temp = chips->cursor_palette[index].r; + else + temp = chips->cursor_palette[index].r & 0x3f; + break; + case 1: + svga->dac_pos++; + if (svga->ramdac_type == RAMDAC_8BIT) + temp = chips->cursor_palette[index].g; + else + temp = chips->cursor_palette[index].g & 0x3f; + break; + case 2: + svga->dac_pos = 0; + svga->dac_addr = (svga->dac_addr + 1) & 255; + if (svga->ramdac_type == RAMDAC_8BIT) + temp = chips->cursor_palette[index].b; + else + temp = chips->cursor_palette[index].b & 0x3f; + break; + } + if (svga->adv_flags & FLAG_RAMDAC_SHIFT) + temp >>= 2; + break; + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + if (svga->crtcreg & 0x20) + temp = 0xff; + else + temp = svga->crtc[svga->crtcreg]; + break; + case 0x3D6: + temp = chips->ext_index; + break; + case 0x3D7: + temp = chips_69000_read_ext_reg(chips); + break; + default: + temp = svga_in(addr, svga); + break; + } + return temp; +} + +static uint8_t +chips_69000_pci_read(int func, int addr, void *p) +{ + chips_69000_t *chips = (chips_69000_t *) p; + + { + switch (addr) { + case 0x00: + case 0x01: + return (0x102C >> ((addr & 1) * 8)) & 0xFF; + case 0x02: + case 0x03: + return (0x00C0 >> ((addr & 1) * 8)) & 0xFF; + case 0x04: + return chips->pci_conf_status; + case 0x07: + return 0x02; + case 0x08: + case 0x09: + case 0x0a: + return 0x00; + case 0x0b: + return 0x03; + case 0x13: + return chips->linear_mapping.base >> 24; + case 0x30: + return chips->pci_rom_enable & 0x1; + case 0x31: + return 0x0; + case 0x32: + return chips->rom_addr & 0xFF; + case 0x33: + return (chips->rom_addr & 0xFF00) >> 8; + case 0x3c: + return chips->pci_line_interrupt; + case 0x3d: + return 0x01; + case 0x2C: + case 0x2D: + case 0x6C: + case 0x6D: + return (chips->subsys_vid >> ((addr & 1) * 8)) & 0xFF; + case 0x2E: + case 0x2F: + case 0x6E: + case 0x6F: + return (chips->subsys_pid >> ((addr & 1) * 8)) & 0xFF; + default: + return 0x00; + } + } +} + +static void +chips_69000_pci_write(int func, int addr, uint8_t val, void *p) +{ + chips_69000_t *chips = (chips_69000_t *) p; + + { + switch (addr) { + case 0x04: + { + chips->pci_conf_status = val; + io_removehandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips); + mem_mapping_disable(&chips->bios_rom.mapping); + mem_mapping_disable(&chips->linear_mapping); + mem_mapping_disable(&chips->svga.mapping); + if (chips->pci_conf_status & PCI_COMMAND_IO) { + io_sethandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips); + } + if (chips->pci_conf_status & PCI_COMMAND_MEM) { + if (!chips->on_board) mem_mapping_enable(&chips->bios_rom.mapping); + mem_mapping_enable(&chips->svga.mapping); + if (chips->linear_mapping.base) + mem_mapping_enable(&chips->linear_mapping); + } + break; + } + case 0x13: + { + mem_mapping_set_addr(&chips->linear_mapping, val << 24, (1 << 24) - 1); + break; + } + case 0x3c: + chips->pci_line_interrupt = val; + break; + case 0x30: + if (chips->on_board) break; + chips->pci_rom_enable = val & 0x1; + mem_mapping_disable(&chips->bios_rom.mapping); + if (chips->pci_rom_enable & 1) { + mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x40000); + } + break; + case 0x32: + if (chips->on_board) break; + chips->rom_addr &= ~0xFF; + chips->rom_addr |= val & 0xFC; + if (chips->pci_rom_enable & 1) { + mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x40000); + } + break; + case 0x33: + if (chips->on_board) break; + chips->rom_addr &= ~0xFF00; + chips->rom_addr |= (val << 8); + if (chips->pci_rom_enable & 1) { + mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x40000); + } + break; + case 0x6C: + case 0x6D: + chips->subsys_vid_b[addr & 1] = val; + break; + case 0x6E: + case 0x6F: + chips->subsys_pid_b[addr & 1] = val; + break; + } + } +} + +uint8_t +chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) +{ + switch (addr & 0xFFF) { + case 0x00 ... 0x28: + return chips->bitblt_regs_b[addr & 0xFF]; + case 0x600 ... 0x60F: + return chips->mem_regs_b[addr & 0xF]; + case 0x768: + return chips_69000_in(0x3b4, chips); + case 0x769: + return chips_69000_in(0x3b5, chips); + case 0x774: + return chips_69000_in(0x3ba, chips); + case 0x780: + return chips_69000_in(0x3c0, chips); + case 0x781: + return chips_69000_in(0x3c1, chips); + case 0x784: + return chips_69000_in(0x3c2, chips); + case 0x788: + return chips_69000_in(0x3c4, chips); + case 0x789: + return chips_69000_in(0x3c5, chips); + case 0x78C: + return chips_69000_in(0x3c6, chips); + case 0x78D: + return chips_69000_in(0x3c7, chips); + case 0x790: + return chips_69000_in(0x3c8, chips); + case 0x791: + return chips_69000_in(0x3c9, chips); + case 0x794: + return chips_69000_in(0x3ca, chips); + case 0x798: + return chips_69000_in(0x3cc, chips); + case 0x79C: + return chips_69000_in(0x3ce, chips); + case 0x79D: + return chips_69000_in(0x3cf, chips); + case 0x7A0: + return chips_69000_in(0x3d0, chips); + case 0x7A1: + return chips_69000_in(0x3d1, chips); + case 0x7A4: + return chips_69000_in(0x3d2, chips); + case 0x7A5: + return chips_69000_in(0x3d3, chips); + case 0x7A8: + return chips_69000_in(0x3d4, chips); + case 0x7A9: + return chips_69000_in(0x3d5, chips); + case 0x7AC: + return chips_69000_in(0x3d6, chips); + case 0x7AD: + return chips_69000_in(0x3d7, chips); + case 0x7B4: + return chips_69000_in(0x3da, chips); + } + return 0xFF; +} + +uint16_t +chips_69000_readw_mmio(uint32_t addr, chips_69000_t* chips) +{ + switch (addr & 0xFFF) { + default: + return chips_69000_readb_mmio(addr, chips) | (chips_69000_readb_mmio(addr + 1, chips) << 8); + } + return 0xFFFF; +} + +uint32_t +chips_69000_readl_mmio(uint32_t addr, chips_69000_t* chips) +{ + switch (addr & 0xFFF) { + default: + return chips_69000_readw_mmio(addr, chips) | (chips_69000_readw_mmio(addr + 2, chips) << 16); + } + return 0xFFFFFFFF; +} + +void +chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) +{ + switch (addr & 0xFFF) { + case 0x00 ... 0x28: + chips->bitblt_regs_b[addr & 0xFF] = val; + break; + case 0x600 ... 0x60F: + chips->mem_regs_b[addr & 0xF] = val; + break; + case 0x768: + chips_69000_out(0x3b4, val, chips); break; + case 0x769: + chips_69000_out(0x3b5, val, chips); break; + case 0x774: + chips_69000_out(0x3ba, val, chips); break; + case 0x780: + chips_69000_out(0x3c0, val, chips); break; + case 0x781: + chips_69000_out(0x3c1, val, chips); break; + case 0x784: + chips_69000_out(0x3c2, val, chips); break; + case 0x788: + chips_69000_out(0x3c4, val, chips); break; + case 0x789: + chips_69000_out(0x3c5, val, chips); break; + case 0x78C: + chips_69000_out(0x3c6, val, chips); break; + case 0x78D: + chips_69000_out(0x3c7, val, chips); break; + case 0x790: + chips_69000_out(0x3c8, val, chips); break; + case 0x791: + chips_69000_out(0x3c9, val, chips); break; + case 0x794: + chips_69000_out(0x3ca, val, chips); break; + case 0x798: + chips_69000_out(0x3cc, val, chips); break; + case 0x79C: + chips_69000_out(0x3ce, val, chips); break; + case 0x79D: + chips_69000_out(0x3cf, val, chips); break; + case 0x7A0: + chips_69000_out(0x3d0, val, chips); break; + case 0x7A1: + chips_69000_out(0x3d1, val, chips); break; + case 0x7A4: + chips_69000_out(0x3d2, val, chips); break; + case 0x7A5: + chips_69000_out(0x3d3, val, chips); break; + case 0x7A8: + chips_69000_out(0x3d4, val, chips); break; + case 0x7A9: + chips_69000_out(0x3d5, val, chips); break; + case 0x7AC: + chips_69000_out(0x3d6, val, chips); break; + case 0x7AD: + chips_69000_out(0x3d7, val, chips); break; + case 0x7B4: + chips_69000_out(0x3da, val, chips); break; + } +} + +void +chips_69000_writew_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) +{ + switch (addr & 0xFFF) { + default: + chips_69000_writeb_mmio(addr, val, chips); + chips_69000_writeb_mmio(addr + 1, val >> 8, chips); + break; + } +} + +void +chips_69000_writel_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) +{ + switch (addr & 0xFFF) { + default: + chips_69000_writew_mmio(addr, val, chips); + chips_69000_writew_mmio(addr + 2, val >> 16, chips); + break; + } +} + +uint8_t +chips_69000_readb_linear(uint32_t addr, void *p) +{ + svga_t *svga = (svga_t *) p; + chips_69000_t *chips = (chips_69000_t *) svga->p; + + if (addr & 0x400000) + return chips_69000_readb_mmio(addr, chips); + + return svga_readb_linear(addr & 0x1FFFFF, p); +} + +uint16_t +chips_69000_readw_linear(uint32_t addr, void *p) +{ + svga_t *svga = (svga_t *) p; + chips_69000_t *chips = (chips_69000_t *) svga->p; + + if (addr & 0x400000) + return chips_69000_readw_mmio(addr, chips); + + return svga_readw_linear(addr & 0x1FFFFF, p); +} + +uint32_t +chips_69000_readl_linear(uint32_t addr, void *p) +{ + svga_t *svga = (svga_t *) p; + chips_69000_t *chips = (chips_69000_t *) svga->p; + + if (addr & 0x400000) + return chips_69000_readl_mmio(addr, chips); + + return svga_readl_linear(addr & 0x1FFFFF, p); +} + +void +chips_69000_writeb_linear(uint32_t addr, uint8_t val, void *p) +{ + svga_t *svga = (svga_t *) p; + chips_69000_t *chips = (chips_69000_t *) svga->p; + + if (addr & 0x400000) + return chips_69000_writeb_mmio(addr, val, chips); + + svga_writeb_linear(addr & 0x1FFFFF, val, p); +} + +void +chips_69000_writew_linear(uint32_t addr, uint16_t val, void *p) +{ + svga_t *svga = (svga_t *) p; + chips_69000_t *chips = (chips_69000_t *) svga->p; + + if (addr & 0x400000) + return chips_69000_writew_mmio(addr, val, chips); + + svga_writew_linear(addr & 0x1FFFFF, val, p); +} + +void +chips_69000_writel_linear(uint32_t addr, uint32_t val, void *p) +{ + svga_t *svga = (svga_t *) p; + chips_69000_t *chips = (chips_69000_t *) svga->p; + + if (addr & 0x400000) + return chips_69000_writel_mmio(addr, val, chips); + + svga_writel_linear(addr & 0x1FFFFF, val, p); +} + +static void * +chips_69000_init(const device_t *info) +{ + chips_69000_t *chips = malloc(sizeof(chips_69000_t)); + memset(chips, 0, sizeof(chips_69000_t)); + + /* Appears to have an odd VBIOS size. */ + if (!info->local) { + rom_init(&chips->bios_rom, "roms/video/chips/69000.ROM", 0xc0000, 0x40000, 0x3ffff, 0x0000, MEM_MAPPING_EXTERNAL); + mem_mapping_disable(&chips->bios_rom.mapping); + } + + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_sis); + + svga_init(info, &chips->svga, chips, 1 << 21, /*2048kb*/ + NULL, + chips_69000_in, chips_69000_out, + NULL, + NULL); + + io_sethandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips); + + pci_add_card(PCI_ADD_VIDEO, chips_69000_pci_read, chips_69000_pci_write, chips); + + chips->svga.bpp = 8; + chips->svga.miscout = 1; + chips->svga.recalctimings_ex = chips_69000_recalctimings; + + mem_mapping_add(&chips->linear_mapping, 0, 0, chips_69000_readb_linear, chips_69000_readw_linear, chips_69000_readl_linear, chips_69000_writeb_linear, chips_69000_writew_linear, chips_69000_writel_linear, NULL, MEM_MAPPING_EXTERNAL, chips); + + chips->quit = 0; + chips->engine_active = 0; + chips->on_board = !!(info->local); + + timer_add(&chips->decrement_timer, chips_69000_decrement_timer, chips, 0); + timer_on_auto(&chips->decrement_timer, 1000000. / 2000.); + + return chips; +} + +static int +chips_69000_available(void) +{ + return rom_present("roms/video/chips/69000.ROM"); +} + +void +chips_69000_close(void *p) +{ + chips_69000_t *chips = (chips_69000_t *) p; + + chips->quit = 1; +// thread_set_event(chips->fifo_event); + // thread_wait(chips->accel_thread); + svga_close(&chips->svga); + + free(chips); +} + +void +chips_69000_speed_changed(void *p) +{ + chips_69000_t *chips = (chips_69000_t *) p; + + svga_recalctimings(&chips->svga); +} + +void +chips_69000_force_redraw(void *p) +{ + chips_69000_t *chips = (chips_69000_t *) p; + + chips->svga.fullchange = changeframecount; +} + +const device_t chips_69000_device = { + .name = "Chips & Technologies 69000", + .internal_name = "c&t_69000", + .flags = DEVICE_PCI, + .local = 0, + .init = chips_69000_init, + .close = chips_69000_close, + .reset = NULL, + { .available = chips_69000_available }, + .speed_changed = chips_69000_speed_changed, + .force_redraw = chips_69000_force_redraw, + .config = NULL +}; + +const device_t chips_69000_onboard_device = { + .name = "Chips & Technologies 69000 (onboard)", + .internal_name = "c&t_69000_onboard", + .flags = DEVICE_PCI, + .local = 1, + .init = chips_69000_init, + .close = chips_69000_close, + .reset = NULL, + { .available = chips_69000_available }, + .speed_changed = chips_69000_speed_changed, + .force_redraw = chips_69000_force_redraw, + .config = NULL +}; diff --git a/src/video/vid_table.c b/src/video/vid_table.c index a2cead1ec..d4915a056 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -198,6 +198,7 @@ video_cards[] = { { &s3_virge_357_pci_device }, { &s3_diamond_stealth_4000_pci_device }, { &s3_trio3d2x_pci_device }, + { &chips_69000_device }, #if defined(DEV_BRANCH) && defined(USE_MGA) { &millennium_device, VIDEO_FLAG_TYPE_SPECIAL }, { &mystique_device }, From 6fc8e3c83b5f571be21dae3cb7647e6d172056bb Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Sat, 22 Jul 2023 15:55:49 +0200 Subject: [PATCH 018/936] Add the A-Trend ATC-1762. --- src/include/86box/machine.h | 5 ++++- src/machine/m_at_386dx_486.c | 24 +++++++++++++++++++- src/machine/machine_table.c | 43 ++++++++++++++++++++++++++++++++++-- 3 files changed, 68 insertions(+), 4 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index c64dbe60d..a3ec1bd5d 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -484,6 +484,7 @@ extern int machine_at_d824_init(const machine_t *); extern int machine_at_403tg_init(const machine_t *); extern int machine_at_403tg_d_init(const machine_t *); extern int machine_at_403tg_d_mr_init(const machine_t *); +extern int machine_at_pb450_init(const machine_t *); extern int machine_at_pc330_6573_init(const machine_t *); extern int machine_at_m45xx_init(const machine_t *); extern int machine_at_mvi486_init(const machine_t *); @@ -506,6 +507,7 @@ extern int machine_at_greenb_init(const machine_t *); extern int machine_at_r418_init(const machine_t *); extern int machine_at_ls486e_init(const machine_t *); extern int machine_at_4dps_init(const machine_t *); +extern int machine_at_ms4144_init(const machine_t *); extern int machine_at_4saw2_init(const machine_t *); extern int machine_at_m4li_init(const machine_t *); extern int machine_at_alfredo_init(const machine_t *); @@ -537,7 +539,7 @@ extern int machine_at_pcm9340_init(const machine_t *); extern int machine_at_pcm5330_init(const machine_t *); extern int machine_at_ecs486_init(const machine_t *); -extern int machine_at_hot433_init(const machine_t *); +extern int machine_at_hot433a_init(const machine_t *); extern int machine_at_atc1415_init(const machine_t *); extern int machine_at_actionpc2600_init(const machine_t *); extern int machine_at_actiontower8400_init(const machine_t *); @@ -548,6 +550,7 @@ extern int machine_at_tg486gp_init(const machine_t *); extern int machine_at_tg486g_init(const machine_t *); extern int machine_at_ecsal486_init(const machine_t *); extern int machine_at_ap4100aa_init(const machine_t *); +extern int machine_at_atc1762_init(const machine_t *); /* m_at_commodore.c */ extern int machine_at_cmdpc_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 888b1bddc..25f3abb8f 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1807,7 +1807,7 @@ machine_at_ecs486_init(const machine_t *model) } int -machine_at_hot433_init(const machine_t *model) +machine_at_hot433a_init(const machine_t *model) { int ret; @@ -2121,5 +2121,27 @@ machine_at_ap4100aa_init(const machine_t *model) device_add(&ide_vlb_device); device_add(&um8669f_device); // needs um8663 + return ret; +} + +int +machine_at_atc1762_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/atc1762/atc1762.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&ali1429g_device); + device_add(&keyboard_ps2_ami_pci_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; } \ No newline at end of file diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index f7a78bb95..ac15601e8 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -6371,6 +6371,45 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* JETKey V5.0 */ + { + .name = "[ALi M1429G] A-Trend ATC-1762", + .internal_name = "atc1762", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_ALI_M1429G, + .init = machine_at_atc1762_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_SOCKET3, + .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_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 40960, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0, + .gpio = 0, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* 486 machines which utilize the PCI bus */ /* Machine with ALi M1429G chipset and M1435 southbridge */ @@ -7677,10 +7716,10 @@ const machine_t machines[] = { /* This has a Holtek KBC. */ { .name = "[UMC 8881] Shuttle HOT-433A", - .internal_name = "hot433", + .internal_name = "hot433a", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_UMC_UM8881, - .init = machine_at_hot433_init, + .init = machine_at_hot433a_init, .pad = 0, .pad0 = 0, .pad1 = MACHINE_AVAILABLE, From 590873f72f82fd0d7963aa2cc9b1f1a0fc6321d6 Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Sat, 22 Jul 2023 16:35:15 +0200 Subject: [PATCH 019/936] Add the MSI MS-4144. --- src/machine/m_at_386dx_486.c | 27 +++++++++++++++++++++++++ src/machine/machine_table.c | 39 ++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 25f3abb8f..ced1987ec 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1035,6 +1035,33 @@ machine_at_4dps_init(const machine_t *model) return ret; } +int +machine_at_ms4144_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ms4144/ms-4144-1.4.bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + machine_at_sis_85c496_common_init(model); + device_add(&sis_85c496_ls486e_device); + pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + + device_add(&w83787f_device); + device_add(&keyboard_at_ami_device); + + device_add(&sst_flash_29ee010_device); + + return ret; +} + int machine_at_486sp3c_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index ac15601e8..f30d77f5e 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -7477,6 +7477,45 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* AMIKEY-2 */ + { + .name = "[SiS 496] MSI MS-4144", + .internal_name = "ms4144", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_SIS_496, + .init = machine_at_ms4144_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_SOCKET3, + .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_PCI, + .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0, + .gpio = 0, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* This has the UMC 88xx on-chip KBC. */ { .name = "[UMC 8881] A-Trend ATC-1415", From c26327d9e27add68e596972778a5a8523842dd27 Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Sat, 22 Jul 2023 23:06:43 +0200 Subject: [PATCH 020/936] Add the DEC Venturis 4xx --- src/include/86box/machine.h | 1 + src/include/86box/video.h | 2 ++ src/machine/m_at_386dx_486.c | 23 +++++++++++++++++++++ src/machine/machine_table.c | 39 ++++++++++++++++++++++++++++++++++++ src/video/vid_s3.c | 38 +++++++++++++++++++++++++++++++++++ 5 files changed, 103 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index a3ec1bd5d..79ecf5ba4 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -548,6 +548,7 @@ extern int machine_at_spc7700plw_init(const machine_t *); extern int machine_at_ms4134_init(const machine_t *); extern int machine_at_tg486gp_init(const machine_t *); extern int machine_at_tg486g_init(const machine_t *); +extern int machine_at_dvent4xx_init(const machine_t *); extern int machine_at_ecsal486_init(const machine_t *); extern int machine_at_ap4100aa_init(const machine_t *); extern int machine_at_atc1762_init(const machine_t *); diff --git a/src/include/86box/video.h b/src/include/86box/video.h index b915fe35d..5bf6208ac 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -465,7 +465,9 @@ extern const device_t s3_bahamas64_vlb_device; extern const device_t s3_bahamas64_pci_device; extern const device_t s3_9fx_vlb_device; extern const device_t s3_9fx_pci_device; +extern const device_t s3_phoenix_trio32_onboard_vlb_device; extern const device_t s3_phoenix_trio32_vlb_device; +extern const device_t s3_phoenix_trio32_onboard_pci_device; extern const device_t s3_phoenix_trio32_pci_device; extern const device_t s3_diamond_stealth_se_vlb_device; extern const device_t s3_diamond_stealth_se_pci_device; diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index ced1987ec..29c862f2e 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -2107,6 +2107,29 @@ machine_at_tg486g_init(const machine_t *model) return ret; } +int +machine_at_dvent4xx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/dvent4xx/Venturis466_BIOS.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&sis_85c471_device); + device_add(&ide_cmd640_vlb_pri_device); + device_add(&fdc37c665_ide_device); + device_add(&keyboard_ps2_device); + + if (gfxcard[0] == VID_INTERNAL) + device_add(&s3_phoenix_trio32_onboard_vlb_device); + + return ret; +} + int machine_at_ecsal486_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index f30d77f5e..2779ac93d 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -6293,6 +6293,45 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Unknown revision phoenix 1993 multikey */ + { + .name = "[SiS 471] DEC Venturis 4xx", + .internal_name = "dvent4xx", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_SIS_471, + .init = machine_at_dvent4xx_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_SOCKET3, + .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_PS2, + .flags = MACHINE_IDE_DUAL | MACHINE_SUPER_IO | MACHINE_APM | MACHINE_VIDEO, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0, + .gpio = 0, + .device = &s3_phoenix_trio32_onboard_vlb_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* This has an AMIKey-2, which is an updated version of type 'H'. */ { .name = "[ALi M1429G] ECS AL486", diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 7f840d134..f9d80d2a5 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -77,6 +77,7 @@ enum { S3_PARADISE_BAHAMAS64, S3_DIAMOND_STEALTH64_964, S3_PHOENIX_TRIO32, + S3_PHOENIX_TRIO32_ONBOARD, S3_PHOENIX_TRIO64, S3_PHOENIX_TRIO64_ONBOARD, S3_PHOENIX_VISION864, @@ -7866,6 +7867,14 @@ s3_init(const device_t *info) else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio32_vlb); break; + case S3_PHOENIX_TRIO32_ONBOARD: + bios_fn = NULL; + chip = S3_TRIO32; + if (info->flags & DEVICE_PCI) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio32_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio32_vlb); + break; case S3_DIAMOND_STEALTH_SE: bios_fn = ROM_DIAMOND_STEALTH_SE; chip = S3_TRIO32; @@ -8298,6 +8307,7 @@ s3_init(const device_t *info) break; case S3_PHOENIX_TRIO32: + case S3_PHOENIX_TRIO32_ONBOARD: case S3_DIAMOND_STEALTH_SE: svga->decode_mask = (4 << 20) - 1; s3->id = 0xe1; /*Trio32*/ @@ -9057,6 +9067,20 @@ const device_t s3_9fx_pci_device = { .config = s3_9fx_config }; +const device_t s3_phoenix_trio32_onboard_vlb_device = { + .name = "S3 Trio32 VLB On-Board (Phoenix)", + .internal_name = "px_trio32_onboard_vlb", + .flags = DEVICE_VLB, + .local = S3_PHOENIX_TRIO32_ONBOARD, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + { .available = NULL }, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_phoenix_trio32_config +}; + const device_t s3_phoenix_trio32_vlb_device = { .name = "S3 Trio32 VLB (Phoenix)", .internal_name = "px_trio32_vlb", @@ -9071,6 +9095,20 @@ const device_t s3_phoenix_trio32_vlb_device = { .config = s3_phoenix_trio32_config }; +const device_t s3_phoenix_trio32_onboard_pci_device = { + .name = "S3 Trio32 PCI On-Board (Phoenix)", + .internal_name = "px_trio32_onboard_pci", + .flags = DEVICE_PCI, + .local = S3_PHOENIX_TRIO32_ONBOARD, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + { .available = NULL }, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_phoenix_trio32_config +}; + const device_t s3_phoenix_trio32_pci_device = { .name = "S3 Trio32 PCI (Phoenix)", .internal_name = "px_trio32_pci", From f9a6295a3cffb14d6b03583e6cd279b0b9dde68c Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Sun, 23 Jul 2023 16:50:12 +0200 Subject: [PATCH 021/936] Add the PB450 with MicroFirmware Phoenix 4.05 BIOS. The stock 1.0A BIOS... (which is the only stock BIOS we have for the PCI version of this board) is currently exhibiting setup utility issues and other POST issues. It will be added later as part of the BIOS switching feature. --- src/include/86box/machine.h | 1 + src/include/86box/sio.h | 2 ++ src/include/86box/video.h | 1 + src/machine/m_at_386dx_486.c | 33 ++++++++++++++++++++++++++++++ src/machine/machine_table.c | 39 ++++++++++++++++++++++++++++++++++++ src/sio/sio_fdc37c6xx.c | 15 ++++++++++++++ src/video/vid_cl54xx.c | 14 +++++++++++++ 7 files changed, 105 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 79ecf5ba4..8270c9e33 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -485,6 +485,7 @@ extern int machine_at_403tg_init(const machine_t *); extern int machine_at_403tg_d_init(const machine_t *); extern int machine_at_403tg_d_mr_init(const machine_t *); extern int machine_at_pb450_init(const machine_t *); +extern int machine_at_pb450_init(const machine_t *); extern int machine_at_pc330_6573_init(const machine_t *); extern int machine_at_m45xx_init(const machine_t *); extern int machine_at_mvi486_init(const machine_t *); diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index 8b95b55b5..2dea55a4c 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -25,6 +25,8 @@ extern const device_t f82c606_device; extern const device_t fdc37c651_device; extern const device_t fdc37c651_ide_device; extern const device_t fdc37c661_device; +extern const device_t fdc37c661_ide_device; +extern const device_t fdc37c661_ide_sec_device; extern const device_t fdc37c663_device; extern const device_t fdc37c663_ide_device; extern const device_t fdc37c665_device; diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 5bf6208ac..4a70f06cb 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -337,6 +337,7 @@ extern const device_t gd5426_diamond_speedstar_pro_a1_isa_device; extern const device_t gd5426_vlb_device; extern const device_t gd5426_onboard_device; extern const device_t gd5428_isa_device; +extern const device_t gd5428_vlb_onboard_device; extern const device_t gd5428_vlb_device; extern const device_t gd5428_diamond_speedstar_pro_b1_vlb_device; extern const device_t gd5428_boca_isa_device; diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 29c862f2e..c9caa553f 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -641,6 +641,39 @@ machine_at_403tg_d_mr_init(const machine_t *model) return ret; } +int +machine_at_pb450_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/pb450/OPTI802.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 5, 4, 3, 2); + pci_register_slot(0x12, PCI_CARD_NORMAL, 9, 8, 7, 6); + + device_add(&opti895_device); + device_add(&opti822_device); + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&fdc37c661_ide_device); + device_add(&ide_opti611_vlb_sec_device); + device_add(&ide_vlb_2ch_device); + device_add(&intel_flash_bxt_device); + device_add(&phoenix_486_jumper_pci_device); + + if (gfxcard[0] == VID_INTERNAL) + device_add(&gd5428_vlb_onboard_device); + + return ret; +} + int machine_at_pc330_6573_init(const machine_t *model) /* doesn't like every CPU other than the iDX4 and the Intel OverDrive, hangs without a PS/2 mouse */ { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 2779ac93d..279e9a388 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -6098,6 +6098,45 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* has a Phoenix PLCC Multikey copyrighted 1993, version unknown. */ + { + .name = "[OPTi 895] Packard Bell PB450", + .internal_name = "pb450", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_OPTI_895_802G, + .init = machine_at_pb450_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_SOCKET3, + .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_PS2_PCI, + .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_VIDEO, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0, + .gpio = 0, + .device = &gd5428_vlb_onboard_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Has AMIKey H keyboard BIOS. */ { .name = "[SiS 471] AOpen Vi15G", diff --git a/src/sio/sio_fdc37c6xx.c b/src/sio/sio_fdc37c6xx.c index 10eccf97c..bd5943d86 100644 --- a/src/sio/sio_fdc37c6xx.c +++ b/src/sio/sio_fdc37c6xx.c @@ -146,6 +146,7 @@ ide_handler(fdc37c6xx_t *dev) ide_sec_disable(); ide_set_base(1, (dev->regs[0x05] & 0x02) ? 0x170 : 0x1f0); ide_set_side(1, (dev->regs[0x05] & 0x02) ? 0x376 : 0x3f6); + pclog("\n0x%X | 0x%X\n", dev->regs[0x00], dev->regs[0x05]); if (dev->regs[0x00] & 0x01) ide_sec_enable(); } else if (dev->has_ide == 1) { @@ -396,6 +397,20 @@ const device_t fdc37c661_ide_device = { .config = NULL }; +const device_t fdc37c661_ide_sec_device = { + .name = "SMC FDC37C661 Super I/O (With Secondary IDE)", + .internal_name = "fdc37c661_ide", + .flags = 0, + .local = 0x261, + .init = fdc37c6xx_init, + .close = fdc37c6xx_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t fdc37c663_device = { .name = "SMC FDC37C663 Super I/O", .internal_name = "fdc37c663", diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 637598345..fe496917f 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -4752,6 +4752,20 @@ const device_t gd5428_onboard_device = { .config = gd5428_onboard_config }; +const device_t gd5428_vlb_onboard_device = { + .name = "Cirrus Logic GD5428 (VLB) (On-Board)", + .internal_name = "cl_gd5428_vlb_onboard", + .flags = DEVICE_VLB, + .local = CIRRUS_ID_CLGD5428, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, + { .available = NULL }, + .speed_changed = gd54xx_speed_changed, + .force_redraw = gd54xx_force_redraw, + .config = gd5428_onboard_config +}; + const device_t gd5429_isa_device = { .name = "Cirrus Logic GD5429 (ISA)", .internal_name = "cl_gd5429_isa", From 493ac6374171c08ccb3b6dd334ecd5d931fa713d Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Sun, 23 Jul 2023 17:26:14 +0200 Subject: [PATCH 022/936] Fix the Anigma BAT4IP3e's secondary IDE channel. --- src/include/86box/sio.h | 1 + src/machine/m_at_386dx_486.c | 5 +++-- src/sio/sio_fdc37c6xx.c | 15 ++++++++++++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index 2dea55a4c..d3bccca84 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -32,6 +32,7 @@ extern const device_t fdc37c663_ide_device; extern const device_t fdc37c665_device; extern const device_t fdc37c665_ide_device; extern const device_t fdc37c665_ide_pri_device; +extern const device_t fdc37c665_ide_sec_device; extern const device_t fdc37c666_device; extern const device_t fdc37c67x_device; extern const device_t fdc37c669_device; diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index c9caa553f..8271e753f 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1230,9 +1230,10 @@ machine_at_bat4ip3e_init(const machine_t *model) device_add(&phoenix_486_jumper_pci_device); device_add(&keyboard_ps2_pci_device); - device_add(&fdc37c665_device); + device_add(&ide_cmd640_pci_single_channel_device); + device_add(&fdc37c665_ide_sec_device); device_add(&i420ex_device); - device_add(&ide_cmd640_pci_device); + return ret; } diff --git a/src/sio/sio_fdc37c6xx.c b/src/sio/sio_fdc37c6xx.c index bd5943d86..95e0dfdd7 100644 --- a/src/sio/sio_fdc37c6xx.c +++ b/src/sio/sio_fdc37c6xx.c @@ -146,7 +146,6 @@ ide_handler(fdc37c6xx_t *dev) ide_sec_disable(); ide_set_base(1, (dev->regs[0x05] & 0x02) ? 0x170 : 0x1f0); ide_set_side(1, (dev->regs[0x05] & 0x02) ? 0x376 : 0x3f6); - pclog("\n0x%X | 0x%X\n", dev->regs[0x00], dev->regs[0x05]); if (dev->regs[0x00] & 0x01) ide_sec_enable(); } else if (dev->has_ide == 1) { @@ -481,6 +480,20 @@ const device_t fdc37c665_ide_pri_device = { .config = NULL }; +const device_t fdc37c665_ide_sec_device = { + .name = "SMC FDC37C665 Super I/O (With Secondary IDE)", + .internal_name = "fdc37c665_ide_sec", + .flags = 0, + .local = 0x265, + .init = fdc37c6xx_init, + .close = fdc37c6xx_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t fdc37c666_device = { .name = "SMC FDC37C666 Super I/O", .internal_name = "fdc37c666", From 908b9b1974cbce25600c931ac5caa02c0af97fb6 Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Sun, 23 Jul 2023 18:50:23 +0200 Subject: [PATCH 023/936] Add the Lanner Electronics IAC-H488. --- src/include/86box/machine.h | 1 + src/machine/m_at_386dx_486.c | 24 ++++++++++++++++++++++ src/machine/machine_table.c | 40 ++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 8270c9e33..0336723d5 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -536,6 +536,7 @@ extern int machine_at_g486ip_init(const machine_t *); extern int machine_at_itoxstar_init(const machine_t *); extern int machine_at_arb1423c_init(const machine_t *); extern int machine_at_arb1479_init(const machine_t *); +extern int machine_at_iach488_init(const machine_t *); extern int machine_at_pcm9340_init(const machine_t *); extern int machine_at_pcm5330_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 8271e753f..d158b5bd4 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1780,6 +1780,30 @@ machine_at_arb1479_init(const machine_t *model) return ret; } +int +machine_at_iach488_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/iach488/FH48800B.980", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x0B, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&w83977f_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&stpc_consumer2_device); + device_add(&sst_flash_29ee020_device); + + return ret; +} + int machine_at_pcm9340_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 279e9a388..d55817ca7 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -8070,6 +8070,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[STPC Consumer-II] Lanner Electronics IAC-H488", + .internal_name = "iach488", + .type = MACHINE_TYPE_486_MISC, + .chipset = MACHINE_CHIPSET_STPC_CONSUMER_II, + .init = machine_at_iach488_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_STPC, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 66666667, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 2.0, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 32768, + .max = 131072, + .step = 32768 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0, + .gpio = 0, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ { From 01ffb60df89a16544d7f6e894b1b0ec72abcbfc2 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sun, 6 Aug 2023 20:29:39 -0400 Subject: [PATCH 024/936] SVGA hskew --- src/video/vid_cl54xx.c | 22 ++++++ src/video/vid_et4000.c | 139 ++++++++++++++++++++++++++++++++---- src/video/vid_et4000w32.c | 8 +++ src/video/vid_s3.c | 34 +++++++-- src/video/vid_svga.c | 117 ++++++++++++++++++++++++++---- src/video/vid_svga_render.c | 17 ++++- src/video/vid_table.c | 1 + 7 files changed, 306 insertions(+), 32 deletions(-) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 225810974..74af8b4a1 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -1828,6 +1828,28 @@ gd54xx_recalctimings(svga_t *svga) } svga->vram_display_mask = (svga->crtc[0x1b] & 2) ? gd54xx->vram_mask : 0x3ffff; + + pclog("svga->crtc[0x1a] = %02X\n", svga->crtc[0x1a]); + pclog("svga->crtc[0x1b] = %02X\n", svga->crtc[0x1b]); + pclog("svga->crtc[0x1c] = %02X\n", svga->crtc[0x1c]); + + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5430) + svga->htotal += ((svga->crtc[0x1c] >> 3) & 0x07); + + if (svga->crtc[0x1b] & ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5424) ? 0xa0 : 0x20)) { + /* Special blanking mode: the blank start and end become components of the window generator, + and the actual blanking comes from the display enable signal. */ + /* Start blanking at the first character clock after the last active one. */ + svga->hblankstart = svga->crtc[1] + 1; + svga->hblank_end_val = (svga->htotal + 6) & 0x3f; + /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ + if (!svga->scrblank && svga->attr_palette_enable) + svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; + /* No overscan in this mode. */ + svga->hblank_overscan = 0; + /* Also make sure vertical blanking starts on display end. */ + svga->vblankstart = svga->dispend; + } } static void diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index a97d65cdb..b7362dd00 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -55,17 +55,19 @@ #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> +#define ET4000_TYPE_TC6058AF 0 /* ISA ET4000AX (TC6058AF) */ #define ET4000_TYPE_ISA 1 /* ISA ET4000AX */ #define ET4000_TYPE_MCA 2 /* MCA ET4000AX */ #define ET4000_TYPE_KOREAN 3 /* Korean ET4000 */ #define ET4000_TYPE_TRIGEM 4 /* Trigem 286M ET4000 */ #define ET4000_TYPE_KASAN 5 /* Kasan ET4000 */ -#define BIOS_ROM_PATH "roms/video/et4000/ET4000.BIN" -#define KOREAN_BIOS_ROM_PATH "roms/video/et4000/tgkorvga.bin" -#define KOREAN_FONT_ROM_PATH "roms/video/et4000/tg_ksc5601.rom" -#define KASAN_BIOS_ROM_PATH "roms/video/et4000/et4000_kasan16.bin" -#define KASAN_FONT_ROM_PATH "roms/video/et4000/kasan_ksc5601.rom" +#define BIOS_ROM_PATH "roms/video/et4000/ET4000.BIN" +#define TC6058AF_BIOS_ROM_PATH "roms/video/et4000/Tseng_Labs_VGA-4000_BIOS_V1.1.bin" +#define KOREAN_BIOS_ROM_PATH "roms/video/et4000/tgkorvga.bin" +#define KOREAN_FONT_ROM_PATH "roms/video/et4000/tg_ksc5601.rom" +#define KASAN_BIOS_ROM_PATH "roms/video/et4000/et4000_kasan16.bin" +#define KASAN_FONT_ROM_PATH "roms/video/et4000/kasan_ksc5601.rom" typedef struct { const char *name; @@ -115,6 +117,7 @@ et4000_in(uint16_t addr, void *priv) { et4000_t *dev = (et4000_t *) priv; svga_t *svga = &dev->svga; + uint8_t ret; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -138,7 +141,8 @@ et4000_in(uint16_t addr, void *priv) case 0x3c7: case 0x3c8: case 0x3c9: - return sc1502x_ramdac_in(addr, svga->ramdac, svga); + if (dev->type >= ET4000_TYPE_ISA) + return sc1502x_ramdac_in(addr, svga->ramdac, svga); case 0x3cd: /*Banking*/ return dev->banking; @@ -149,6 +153,26 @@ et4000_in(uint16_t addr, void *priv) case 0x3d5: return svga->crtc[svga->crtcreg]; + case 0x3da: + svga->attrff = 0; + + if (svga->cgastat & 0x01) + svga->cgastat &= ~0x30; + else + svga->cgastat ^= 0x30; + + ret = svga->cgastat; + + if ((svga->fcr & 0x08) && svga->dispon) + ret |= 0x08; + + if (ret & 0x08) + ret &= 0x7f; + else + ret |= 0x80; + + return ret; + default: break; } @@ -225,12 +249,33 @@ et4000_out(uint16_t addr, uint8_t val, void *priv) addr ^= 0x60; switch (addr) { + case 0x3c5: + if (svga->seqaddr == 4) { + svga->seqregs[4] = val; + + svga->chain2_write = !(val & 4); + svga->chain4 = (svga->chain4 & ~8) | (val & 8); + svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4 && !(svga->adv_flags & FLAG_ADDR_BY8); + return; + } else if (svga->seqaddr == 0x0e) { + svga->seqregs[0x0e] = val; + svga->chain4 &= ~0x02; + if (svga->gdcreg[5] & 0x40) + svga->chain4 |= (svga->seqregs[0x0e] & 0x02); + svga_recalctimings(svga); + return; + } + break; + case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: - sc1502x_ramdac_out(addr, val, svga->ramdac, svga); - return; + if (dev->type >= ET4000_TYPE_ISA) { + sc1502x_ramdac_out(addr, val, svga->ramdac, svga); + return; + } + break; case 0x3cd: /*Banking*/ if (!(svga->crtc[0x36] & 0x10) && !(svga->gdcreg[6] & 0x08)) { @@ -241,7 +286,11 @@ et4000_out(uint16_t addr, uint8_t val, void *priv) return; case 0x3cf: - if ((svga->gdcaddr & 15) == 6) { + if ((svga->gdcaddr & 15) == 5) { + svga->chain4 &= ~0x02; + if (val & 0x40) + svga->chain4 |= (svga->seqregs[0x0e] & 0x02); + } else if ((svga->gdcaddr & 15) == 6) { if (!(svga->crtc[0x36] & 0x10) && !(val & 0x08)) { svga->write_bank = (dev->banking & 0x0f) * 0x10000; svga->read_bank = ((dev->banking >> 4) & 0x0f) * 0x10000; @@ -418,7 +467,8 @@ et4000_kasan_out(uint16_t addr, uint8_t val, void *priv) break; case 1: case 2: - et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0] = val; + if ((et4000->kasan_cfg_index - 0xF0) <= 16) + et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0] = val; io_removehandler(et4000->kasan_access_addr, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000); et4000->kasan_access_addr = (et4000->kasan_cfg_regs[2] << 8) | et4000->kasan_cfg_regs[1]; io_sethandler(et4000->kasan_access_addr, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000); @@ -465,7 +515,8 @@ et4000_kasan_out(uint16_t addr, uint8_t val, void *priv) case 4: case 5: if (et4000->kasan_cfg_regs[0] & 1) { - et4000->kasan_font_data[addr - (((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1])) + 3)] = val; + if ((addr - (((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1])) + 3)) <= 4) + et4000->kasan_font_data[addr - (((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1])) + 3)] = val; } break; case 6: @@ -607,6 +658,19 @@ et4000_recalctimings(svga_t *svga) } } } + + if ((svga->seqregs[0x0e] & 0x02) && ((svga->gdcreg[5] & 0x60) >= 0x40)) { + svga->ma_latch <<= (1 << 0); + svga->rowoffset <<= (1 << 0); + svga->render = svga_render_8bpp_highres; + } + + if (dev->type == ET4000_TYPE_TC6058AF) { + if (svga->render == svga_render_8bpp_lowres) + svga->render = svga_render_8bpp_tseng_lowres; + else if (svga->render == svga_render_8bpp_highres) + svga->render = svga_render_8bpp_tseng_highres; + } } static void @@ -666,6 +730,7 @@ et4000_init(const device_t *info) fn = BIOS_ROM_PATH; switch (dev->type) { + case ET4000_TYPE_TC6058AF: /* ISA ET4000AX (TC6058AF) */ case ET4000_TYPE_ISA: /* ISA ET4000AX */ dev->vram_size = device_get_config_int("memory") << 10; video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et4000_isa); @@ -674,6 +739,8 @@ et4000_init(const device_t *info) NULL, NULL); io_sethandler(0x03c0, 32, et4000_in, NULL, NULL, et4000_out, NULL, NULL, dev); + if (dev->type == ET4000_TYPE_TC6058AF) + fn = TC6058AF_BIOS_ROM_PATH; break; case ET4000_TYPE_MCA: /* MCA ET4000AX */ @@ -750,7 +817,8 @@ et4000_init(const device_t *info) break; } - dev->svga.ramdac = device_add(&sc1502x_ramdac_device); + if (dev->type >= ET4000_TYPE_ISA) + dev->svga.ramdac = device_add(&sc1502x_ramdac_device); dev->vram_mask = dev->vram_size - 1; @@ -790,6 +858,12 @@ et4000_force_redraw(void *priv) dev->svga.fullchange = changeframecount; } +static int +et4000_tc6058af_available(void) +{ + return rom_present(TC6058AF_BIOS_ROM_PATH); +} + static int et4000_available(void) { @@ -808,6 +882,33 @@ et4000_kasan_available(void) return rom_present(KASAN_BIOS_ROM_PATH) && rom_present(KASAN_FONT_ROM_PATH); } +static const device_config_t et4000_tc6058af_config[] = { + // clang-format off + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 512, + .selection = { + { + .description = "256 KB", + .value = 256 + }, + { + .description = "512 KB", + .value = 512 + }, + { + .description = "" + } + } + }, + { + .type = CONFIG_END + } +// clang-format on +}; + static const device_config_t et4000_config[] = { // clang-format off { @@ -839,6 +940,20 @@ static const device_config_t et4000_config[] = { // clang-format on }; +const device_t et4000_tc6058af_isa_device = { + .name = "Tseng Labs ET4000AX (TC6058AF) (ISA)", + .internal_name = "et4000ax_tc6058af", + .flags = DEVICE_ISA, + .local = 0, + .init = et4000_init, + .close = et4000_close, + .reset = NULL, + { .available = et4000_tc6058af_available }, + .speed_changed = et4000_speed_changed, + .force_redraw = et4000_force_redraw, + .config = et4000_tc6058af_config +}; + const device_t et4000_isa_device = { .name = "Tseng Labs ET4000AX (ISA)", .internal_name = "et4000ax", diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index c2ce39778..bc23f224e 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -457,6 +457,7 @@ et4000w32p_recalctimings(svga_t *svga) } } +#if 0 if (svga->adv_flags & FLAG_NOSKEW) { /* On the Cardex ET4000/W32p-based cards, adjust text mode clocks by 1. */ if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /* Text mode */ @@ -480,6 +481,7 @@ et4000w32p_recalctimings(svga_t *svga) } } } +#endif if (et4000->type == ET4000W32) { if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { @@ -2561,6 +2563,9 @@ et4000w32p_pci_read(UNUSED(int func), int addr, void *priv) { et4000w32p_t *et4000 = (et4000w32p_t *) priv; + if (func > 0) + return 0xff; + addr &= 0xff; switch (addr) { @@ -2618,6 +2623,9 @@ et4000w32p_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) et4000w32p_t *et4000 = (et4000w32p_t *) priv; svga_t *svga = &et4000->svga; + if (func > 0) + return; + addr &= 0xff; switch (addr) { diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index bcdd64d40..48740d1ce 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3038,6 +3038,8 @@ s3_recalctimings(svga_t *svga) s3_t *s3 = (s3_t *) svga->priv; int clk_sel = (svga->miscout >> 2) & 3; + svga->hdisp = svga->hdisp_old; + if (!svga->scrblank && svga->attr_palette_enable) { if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { if (svga->crtc[0x3a] & 0x10) { /*256+ color register*/ @@ -3047,14 +3049,13 @@ s3_recalctimings(svga_t *svga) } svga->ma_latch |= (s3->ma_ext << 16); - if (s3->chip >= S3_86C928) { - svga->hdisp = svga->hdisp_old; + if (s3->chip >= S3_86C928) { if (svga->crtc[0x5d] & 0x01) svga->htotal |= 0x100; if (svga->crtc[0x5d] & 0x02) { svga->hdisp_time |= 0x100; - svga->hdisp |= 0x100 * ((svga->seqregs[1] & 8) ? 16 : 8); + svga->hdisp |= 0x100 * svga->dots_per_clock; } if (svga->crtc[0x5e] & 0x01) svga->vtotal |= 0x400; @@ -3072,7 +3073,8 @@ s3_recalctimings(svga_t *svga) svga->rowoffset |= (svga->crtc[0x51] & 0x30) << 4; else if (svga->crtc[0x43] & 0x04) svga->rowoffset |= 0x100; - } + } else if (svga->crtc[0x43] & 0x04) + svga->rowoffset |= 0x100; if (!svga->rowoffset) svga->rowoffset = 0x100; @@ -3341,6 +3343,30 @@ s3_recalctimings(svga_t *svga) } } } + + if (s3->chip >= S3_86C801) { + 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); + } + + if (svga->crtc[0x5d] & 0x04) + svga->hblankstart += 0x100; + if (s3->chip >= S3_VISION964) { + /* NOTE: The S3 Trio64V+ datasheet says this is bit 7, but then where is bit 6? + The datasheets for the pre-Trio64V+ cards say +64, which implies bit 6, + and, contrary to VGADOC, it also exists on Trio32, Trio64, Vision868, + and Vision968. */ +#if 0 + pclog("svga->crtc[0x5d] = %02X\n", svga->crtc[0x5d]); +#endif + if (svga->crtc[0x5d] & 0x08) + svga->hblank_ext = 0x40; + svga->hblank_end_len = 0x00000040; + } + } + + svga->hblank_overscan = !(svga->crtc[0x33] & 0x20); } static void diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 0e83c034a..3db97d3f1 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -202,7 +202,7 @@ svga_out(uint16_t addr, uint8_t val, void *priv) break; case 4: svga->chain2_write = !(val & 4); - svga->chain4 = val & 8; + svga->chain4 = (svga->chain4 & ~8) | (val & 8); svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && !(svga->adv_flags & FLAG_ADDR_BY8); break; @@ -307,6 +307,9 @@ svga_out(uint16_t addr, uint8_t val, void *priv) if (((svga->gdcaddr & 15) == 5 && (val ^ o) & 0x70) || ((svga->gdcaddr & 15) == 6 && (val ^ o) & 1)) svga_recalctimings(svga); break; + case 0x3da: + svga->fcr = val; + break; default: break; @@ -384,6 +387,9 @@ svga_in(uint16_t addr, void *priv) if (svga->adv_flags & FLAG_RAMDAC_SHIFT) ret >>= 2; break; + case 0x3ca: + ret = svga->fcr; + break; case 0x3cc: ret = svga->miscout; break; @@ -420,6 +426,8 @@ svga_in(uint16_t addr, void *priv) ret = svga->cgastat; + if ((svga->fcr & 0x08) && svga->dispon) + ret |= 0x08; break; default: @@ -453,6 +461,14 @@ svga_recalctimings(svga_t *svga) double _dispontime; double _dispofftime; double disptime; +#ifdef ENABLE_SVGA_LOG + int vsyncend; + int vblankend; + int hdispstart; + int hdispend; + int hsyncstart; + int hsyncend; +#endif svga->vtotal = svga->crtc[6]; svga->dispend = svga->crtc[0x12]; @@ -490,7 +506,7 @@ svga_recalctimings(svga_t *svga) svga->vblankstart |= 0x200; svga->vblankstart++; - svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5); + svga->hdisp = svga->crtc[1] - ((svga->crtc[3] & 0x60) >> 5); svga->hdisp++; svga->htotal = svga->crtc[0]; @@ -513,20 +529,20 @@ svga_recalctimings(svga_t *svga) svga->hdisp_time = svga->hdisp; svga->render = svga_render_blank; if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { + /* TODO: In case of bug reports, disable 9-dots-wide character clocks in graphics modes. */ + if (svga->seqregs[1] & 8) + svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; + else + svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ if (svga->seqregs[1] & 8) { /*40 column*/ svga->render = svga_render_text_40; - svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; - /* Character clock is off by 1 now in 40-line modes, on all cards. */ - svga->ma_latch--; - svga->hdisp += (svga->seqregs[1] & 1) ? 16 : 18; } else { svga->render = svga_render_text_80; - svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; } svga->hdisp_old = svga->hdisp; } else { - svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; svga->hdisp_old = svga->hdisp; switch (svga->gdcreg[5] & 0x60) { @@ -612,6 +628,26 @@ svga_recalctimings(svga_t *svga) } else svga->monitor->mon_overscan_x = 16; + svga->htotal = svga->crtc[0]; + svga->hblankstart = svga->crtc[4] + 1; + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00); +#if 0 + pclog("htotal = %i, hblankstart = %i, hblank_end_val = %02X\n", svga->htotal, svga->hblankstart, svga->hblank_end_val); +#endif + svga->hblank_end_len = 0x00000040; + svga->hblank_overscan = 1; + + if (!svga->scrblank && svga->attr_palette_enable) { + /* TODO: In case of bug reports, disable 9-dots-wide character clocks in graphics modes. */ + if (svga->seqregs[1] & 8) + svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18); + else + svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 8 : 9); + } else + svga->dots_per_clock = 1; + + /* Do svga->recalctimings_ex() here so that the above five variables can be + updated by said function. */ if (vga_on) { if (svga->recalctimings_ex) { svga->recalctimings_ex(svga); @@ -629,6 +665,20 @@ svga_recalctimings(svga_t *svga) xga_recalctimings(svga); } + svga->htotal += 6; /*+6 is required for Tyrian*/ + svga->hblankend = (svga->hblankstart & ~(svga->hblank_end_len - 1)) | svga->hblank_end_val; + if (svga->hblankend <= svga->hblankstart) + svga->hblankend += svga->hblank_end_len; + svga->hblankend += svga->hblank_ext; + + svga->hblank_sub = 0; + if (svga->hblankend > svga->htotal) { + svga->hblankend &= (svga->hblank_end_len - 1); + svga->hblank_sub = svga->hblankend + svga->hblank_overscan; + + svga->hdisp -= (svga->hblank_sub * svga->dots_per_clock); + } + if (svga->hdisp >= 2048) svga->monitor->mon_overscan_x = 0; @@ -640,6 +690,43 @@ svga_recalctimings(svga_t *svga) crtcconst = svga->clock * svga->char_width; +#ifdef ENABLE_SVGA_LOG + vsyncend = (svga->vsyncstart & 0xfffffff0) | (svga->crtc[0x11] & 0x0f); + if (vsyncend <= svga->vsyncstart) + vsyncend += 0x00000010; + vblankend = (svga->vblankstart & 0xffffff80) | (svga->crtc[0x16] & 0x7f); + if (vblankend <= svga->vblankstart) + vblankend += 0x00000080; + + hdispstart = ((svga->crtc[3] >> 5) & 3); + hdispend = svga->crtc[1] + 1; + hsyncstart = svga->crtc[4] + ((svga->crtc[5] >> 5) & 3) + 1; + hsyncend = (hsyncstart & 0xffffffe0) | (svga->crtc[5] & 0x1f); + if (hsyncend <= hsyncstart) + hsyncend += 0x00000020; +#endif + + svga_log("Last scanline in the vertical period: %i\n" + "First scanline after the last of active display: %i\n" + "First scanline with vertical retrace asserted: %i\n" + "First scanline after the last with vertical retrace asserted: %i\n" + "First scanline of blanking: %i\n" + "First scanline after the last of blanking: %i\n" + "\n" + "Last character in the horizontal period: %i\n" + "First character of active display: %i\n" + "First character after the last of active display: %i\n" + "First character with horizontal retrace asserted: %i\n" + "First character after the last with horizontal retrace asserted: %i\n" + "First character of blanking: %i\n" + "First character after the last of blanking: %i\n" + "\n" + "\n", + svga->vtotal, svga->dispend, svga->vsyncstart, vsyncend, + svga->vblankstart, vblankend, + svga->htotal, hdispstart, hdispend, hsyncstart, hsyncend, + svga->hblankstart, svga->hblankend); + if (ibm8514_on && !svga->dev8514.local) { disptime = svga->dev8514.h_total; _dispontime = svga->dev8514.h_disp; @@ -878,9 +965,9 @@ svga_poll(void *priv) if (ret) { if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5); + svga->ma = svga->maback = (svga->rowoffset << 1) + ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub; else - svga->ma = svga->maback = ((svga->crtc[5] & 0x60) >> 5); + svga->ma = svga->maback = ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub; svga->ma = (svga->ma << 2); svga->maback = (svga->maback << 2); @@ -951,9 +1038,9 @@ svga_poll(void *priv) if ((dev->local && vga_on) || !dev->local) { if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5); + svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub; else - svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[5] & 0x60) >> 5); + svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub; } else if (dev->local && ibm8514_on) { if (svga->interlace && svga->oddeven) svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1); @@ -968,6 +1055,9 @@ svga_poll(void *priv) if (svga->vsync_callback) svga->vsync_callback(svga); } +#if 0 + if (svga->vc == lines_num) { +#endif if (svga->vc == svga->vtotal) { svga->vc = 0; svga->sc = 0; @@ -1090,7 +1180,8 @@ svga_init(const device_t *info, svga_t *svga, void *priv, int memsize, svga->ramdac_type = RAMDAC_6BIT; - svga->map8 = svga->pallook; + svga->map8 = svga->pallook; + svga->hblank_overscan = 1; /* Do at least 1 character of overscan after horizontal blanking. */ return 0; } diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index c9369f09c..7ee263aa3 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -70,9 +70,20 @@ svga_render_blank(svga_t *svga) break; } +#if 0 + pclog("svga->displine = %i, svga->y_add = %i, svga->x_add = %i\n", svga->displine, svga->y_add, svga->x_add); +#endif uint32_t *line_ptr = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; +#if 0 + pclog("svga->hdisp = %i, svga->scrollcache = %i, char_width = %i, sizeof(uint32_t) = %i\n", svga->hdisp, svga->scrollcache, char_width, sizeof(uint32_t)); +#endif uint32_t line_width = (uint32_t) (svga->hdisp + svga->scrollcache) * char_width * sizeof(uint32_t); - memset(line_ptr, 0, line_width); + +#if 0 + pclog("line_width = %i\n", line_width); +#endif + if ((svga->hdisp + svga->scrollcache) > 0) + memset(line_ptr, 0, line_width); } void @@ -81,7 +92,7 @@ svga_render_overscan_left(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - if (svga->scrblank || (svga->hdisp == 0)) + if (svga->scrblank || (svga->hdisp <= 0)) return; uint32_t *line_ptr = svga->monitor->target_buffer->line[svga->displine + svga->y_add]; @@ -97,7 +108,7 @@ svga_render_overscan_right(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - if (svga->scrblank || (svga->hdisp == 0)) + if (svga->scrblank || (svga->hdisp <= 0)) return; uint32_t *line_ptr = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add + svga->hdisp]; diff --git a/src/video/vid_table.c b/src/video/vid_table.c index eb999eb3f..e8301e3ee 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -148,6 +148,7 @@ video_cards[] = { { &et4000k_isa_device }, { &et2000_device }, { &et3000_isa_device }, + { &et4000_tc6058af_isa_device }, { &et4000_isa_device }, { &et4000w32_device }, { &et4000w32i_isa_device }, From a947e49f5ef036c7303bc6208742d66d9f270727 Mon Sep 17 00:00:00 2001 From: redoste Date: Tue, 5 Sep 2023 19:01:33 +0200 Subject: [PATCH 025/936] Allow connection to a VDE switch run by the same user `libvdeplug` will only change the mode if the switch is run by another user that isn't root. If the switch is run by the same user as 86Box the socket will be chmoded to 000 and the switch, unable to connect back, will drop the connection. https://github.com/rd235/vdeplug4/blob/187256c528137036cc4e3228728b3f70a3342fa5/libvdeplug4/libvdeplug_vde.c#L261-L275 --- src/network/net_vde.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/net_vde.c b/src/network/net_vde.c index afeeaac9c..d783c9c9d 100644 --- a/src/network/net_vde.c +++ b/src/network/net_vde.c @@ -274,7 +274,7 @@ void *net_vde_init(const netcard_t *card, const uint8_t *mac_addr, void *priv, c vde_args.group = 0; vde_args.port = 0; - vde_args.mode = 0; + vde_args.mode = 0700; // Allow the switch to connect back to our socket if it is run by the same user // We are calling vde_open_real(), not the vde_open() macro... if ((vde->vdeconn = f_vde_open(socket_name, VDE_DESCRIPTION, From 3a0f1ace6062f9c430c95ff420cfb02692106689 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Thu, 7 Dec 2023 23:53:05 -0500 Subject: [PATCH 026/936] Update GHA to macos 12 --- .github/workflows/cmake.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index bde200b6b..4d446fd7a 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -381,10 +381,10 @@ jobs: name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-UbuntuJammy-x86_64-gha${{ github.run_number }}' path: build/artifacts/** - macos11: - name: "macOS 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)" + macos12: + name: "macOS 12 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)" - runs-on: macos-11 + runs-on: macos-12 env: BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed From 6c0bd91e4fd1ed77a035ba4742704600f1422d7b Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sun, 10 Dec 2023 01:48:08 -0500 Subject: [PATCH 027/936] Fix codeql runs --- .github/workflows/codeql.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 5c23961d5..53dde02ab 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -226,11 +226,11 @@ jobs: with: category: "/language:${{matrix.language}}" - analyze-macos11: + analyze-macos12: - name: "Analyze macOS 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)" + name: "Analyze macOS 12 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)" - runs-on: macos-11 + runs-on: macos-12 permissions: actions: read From 63ba53573a608c2b2901e72a38906ad8363f63b3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 11 Dec 2023 20:15:55 +0100 Subject: [PATCH 028/936] Made do_pause_ack also volatile, fixes hard freezes on 64-bit binaries. --- src/86box.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/86box.c b/src/86box.c index bf9be5086..7ccc3c96d 100644 --- a/src/86box.c +++ b/src/86box.c @@ -236,7 +236,7 @@ int efscrnsz_y = SCREEN_RES_Y; static wchar_t mouse_msg[3][200]; -static int do_pause_ack = 0; +static volatile int do_pause_ack = 0; static volatile int pause_ack = 0; #ifndef RELEASE_BUILD From 2a2432207a319cec4b2073e7abe9f43972c12e39 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 11 Dec 2023 20:32:51 +0100 Subject: [PATCH 029/936] More fixes, the hard freeze is truly gone now. --- src/86box.c | 22 ++++++++++++---------- src/qt/qt_main.cpp | 10 ++++++++-- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/86box.c b/src/86box.c index 7ccc3c96d..25b073fda 100644 --- a/src/86box.c +++ b/src/86box.c @@ -111,7 +111,7 @@ /* Stuff that used to be globally declared in plat.h but is now extern there and declared here instead. */ -int dopause; /* system is paused */ +int dopause = 1; /* system is paused */ atomic_flag doresize; /* screen resize requested */ volatile int is_quit; /* system exit requested */ uint64_t timer_freq; @@ -236,8 +236,8 @@ int efscrnsz_y = SCREEN_RES_Y; static wchar_t mouse_msg[3][200]; -static volatile int do_pause_ack = 0; -static volatile int pause_ack = 0; +static volatile atomic_int do_pause_ack = 0; +static volatile atomic_int pause_ack = 0; #ifndef RELEASE_BUILD static char buff[1024]; @@ -1359,9 +1359,9 @@ _ui_window_title(void *s) void ack_pause(void) { - if (do_pause_ack) { - do_pause_ack = 0; - pause_ack = 1; + if (atomic_load(&do_pause_ack)) { + atomic_store(&do_pause_ack, 0); + atomic_store(&pause_ack, 1); } } @@ -1579,12 +1579,14 @@ get_actual_size_y(void) void do_pause(int p) { - if (p) + int old_p = dopause; + + if (p && !old_p) do_pause_ack = p; dopause = p; - if (p) { - while (!pause_ack) + if (p && !old_p) { + while (!atomic_load(&pause_ack)) ; } - pause_ack = 0; + atomic_store(&pause_ack, 0); } diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 845ff705f..c859fe033 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -293,8 +293,6 @@ main(int argc, char *argv[]) // pc_reset_hard_init(); - /* Set the PAUSE mode depending on the renderer. */ - // plat_pause(0); QTimer onesec; QObject::connect(&onesec, &QTimer::timeout, &app, [] { pc_onesec(); @@ -323,6 +321,14 @@ main(int argc, char *argv[]) QTimer::singleShot(0, &app, [] { pc_reset_hard_init(); main_thread = new std::thread(main_thread_fn); + + /* Set the PAUSE mode depending on the renderer. */ +#ifdef USE_VNC + if (vnc_enabled && vid_api != 6) + plat_pause(1); + else +#endif + plat_pause(0); }); auto ret = app.exec(); From 5221a77dbfde0ccca76c965cffd34109abbb8639 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 14 Dec 2023 21:19:58 +0100 Subject: [PATCH 030/936] IDE/ATAPI SRST fixes - fixes ATAPI CD-ROM detection on the Nec PowerMate V. --- src/disk/hdc_ide.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 2bb83b4ab..725c31996 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -1389,7 +1389,13 @@ ide_write_devctl(UNUSED(uint16_t addr), uint8_t val, void *priv) } else { /* Currently active device is 1, simply reset the status and the active device. */ dev_reset(ide); - ide->tf->atastat = DRDY_STAT | DSC_STAT; + if (ide->type == IDE_ATAPI) { + /* Non-early ATAPI devices have DRDY clear after SRST. */ + ide->tf->atastat = 0; + if (IDE_ATAPI_IS_EARLY) + ide->tf->atastat |= DRDY_STAT; + } else + ide->tf->atastat = DRDY_STAT | DSC_STAT; ide->tf->error = 1; dev->cur_dev &= ~1; ch = dev->cur_dev; @@ -1788,7 +1794,7 @@ ide_read_data(ide_t *ide, int length) double xfer_us; #if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) - ide_log("ide_read_data(): ch = %i, board = %i, type = %i\n", ch, + ide_log("ide_read_data(): ch = %i, board = %i, type = %i\n", ide->channel, ide->board, ide->type); #endif @@ -1868,7 +1874,8 @@ ide_status(ide_t *ide, ide_t *ide_other, int ch) /* On real hardware, a slave with a present master always returns a status of 0x00. Confirmed by the ATA-3 and ATA-4 specifications. */ - ret = 0x00; + // ret = 0x00; + ret = 0x01; } else { ret = ide->tf->atastat; if (ide->type == IDE_ATAPI) @@ -1948,8 +1955,8 @@ ide_readb(uint16_t addr, void *priv) else ret = ide->tf->cylinder >> 8; #if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) - pclog("Cylinder high @ board %i, channel %i: ide->type = %i, " - "ret = %02X\n", ide->board, ide->channel, ide->type, ret); + ide_log("Cylinder high @ board %i, channel %i: ide->type = %i, " + "ret = %02X\n", ide->board, ide->channel, ide->type, ret); #endif break; @@ -2070,7 +2077,11 @@ ide_board_callback(void *priv) ide_log("ide_board_callback(%i)\n", dev->cur_dev >> 1); - for (uint8_t i = 0; i < 2; i++) { + dev->cur_dev &= ~1; + + /* Reset the devices in reverse so if there's a slave without a master, + its copy of the master's task file gets reset first. */ + for (int8_t i = 1; i >= 0; i--) { ide = dev->ide[i]; if (ide->type == IDE_ATAPI) { ide->tf->atastat = 0; @@ -2080,8 +2091,6 @@ ide_board_callback(void *priv) ide->tf->atastat = DRDY_STAT | DSC_STAT; } - dev->cur_dev &= ~1; - ide = dev->ide[0]; if (dev->diag) { dev->diag = 0; @@ -2287,6 +2296,9 @@ ide_callback(void *priv) case WIN_WRITE: case WIN_WRITE_NORETRY: +#ifdef ENABLE_IDE_LOG + off64_t s = ide_get_sector(ide); +#endif if (ide->type == IDE_ATAPI) err = ABRT_ERR; else if (!ide->tf->lba && (ide->cfg_spt == 0)) @@ -2305,6 +2317,7 @@ ide_callback(void *priv) ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); } } + ide_log("Write: %02X, %i, %08X, %" PRIi64 "\n", err, ide->hdd_num, ide->lba_addr, s); break; case WIN_WRITE_DMA: From 15c6d9e5fa974e97b36c71fe187ed900ee94dd97 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 14 Dec 2023 21:47:10 +0100 Subject: [PATCH 031/936] Mach8/32 fixes (again): 1. Fixed wrong setting of highres and lowres mode of 8bpp, makes Transport Tycoon run properly on these ATI cards again. 2. 32-bit (RGBA) True Color is actually supported on the Mach32, but barely used, and the original code was wrong. This fix makes 32-bit True Color render the right colors. --- src/video/vid_8514a.c | 6 +- src/video/vid_ati_mach8.c | 117 ++++++++++++++++++-------------------- 2 files changed, 57 insertions(+), 66 deletions(-) diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 955199970..7e476663c 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -4036,7 +4036,7 @@ ibm8514_render_ABGR8888(svga_t *svga) } void -ibm8514_render_RGBA8888(svga_t *svga) +ibm8514_render_32bpp(svga_t *svga) { ibm8514_t *dev = (ibm8514_t *) svga->dev8514; int x; @@ -4046,7 +4046,7 @@ ibm8514_render_RGBA8888(svga_t *svga) if ((dev->displine + svga->y_add) < 0) return; - if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { + if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || dev->changedvram[(dev->ma >> 12) + 2] || svga->fullchange) { p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; if (dev->firstline_draw == 2000) @@ -4055,7 +4055,7 @@ ibm8514_render_RGBA8888(svga_t *svga) for (x = 0; x <= dev->h_disp; x++) { dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 2)) & dev->vram_mask]); - *p++ = dat >> 8; + p[x] = dat & 0xffffff; } dev->ma += (x * 4); dev->ma &= dev->vram_mask; diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index dea8821e6..9b7c27649 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -87,6 +87,7 @@ typedef struct mach_t { uint16_t cursor_col_1_rg; uint16_t cursor_col_b; uint16_t cursor_offset_lo; + uint16_t cursor_offset_lo_reg; uint16_t cursor_offset_hi; uint16_t cursor_offset_hi_reg; uint16_t cursor_vh_offset; @@ -2583,13 +2584,10 @@ mach_recalctimings(svga_t *svga) svga->htotal <<= 1; svga->rowoffset <<= 1; svga->gdcreg[5] &= ~0x40; - svga->attrregs[0x10] &= ~0x40; } - if (mach->regs[0xb0] & 0x20) { + if (mach->regs[0xb0] & 0x20) svga->gdcreg[5] |= 0x40; - svga->attrregs[0x10] |= 0x40; - } mach_log("ON[0]=%d, ON[1]=%d, exton[0]=%d, exton[1]=%d, vendormode0=%d, vendormode1=%d.\n", dev->on[0], dev->on[1], mach->ext_on[0], mach->ext_on[1], dev->vendor_mode[0], dev->vendor_mode[1]); if (dev->on[0] || dev->on[1]) { @@ -2671,16 +2669,18 @@ mach_recalctimings(svga_t *svga) svga->render8514 = ibm8514_render_16bpp; break; case 24: + mach_log("GEConfig24bpp: %03x.\n", mach->accel.ext_ge_config & 0x600); if (mach->accel.ext_ge_config & 0x400) svga->render8514 = ibm8514_render_BGR; else svga->render8514 = ibm8514_render_24bpp; break; case 32: + mach_log("GEConfig32bpp: %03x.\n", mach->accel.ext_ge_config & 0x600); if (mach->accel.ext_ge_config & 0x400) svga->render8514 = ibm8514_render_ABGR8888; else - svga->render8514 = ibm8514_render_RGBA8888; + svga->render8514 = ibm8514_render_32bpp; break; default: @@ -2760,58 +2760,39 @@ mach_recalctimings(svga_t *svga) svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen); if (mach->regs[0xa7] & 0x80) svga->clock *= 3; - if (svga->bpp <= 8) { - if (svga->attrregs[0x10] & 0x40) { /*8bpp mode*/ - svga->map8 = svga->pallook; - if (svga->lowres) /*Low res (320)*/ - svga->render = svga_render_8bpp_lowres; - else { - svga->render = svga_render_8bpp_highres; - svga->ma_latch <<= 1; - svga->rowoffset <<= 1; - } - } else { - mach_log("4bpp.\n"); + switch (svga->gdcreg[5] & 0x60) { + case 0x00: if (svga->seqregs[1] & 8) /*Low res (320)*/ svga->render = svga_render_4bpp_lowres; else svga->render = svga_render_4bpp_highres; - } - } else { - switch (svga->gdcreg[5] & 0x60) { - case 0x00: - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_4bpp_lowres; - else - svga->render = svga_render_4bpp_highres; - break; - case 0x20: /*4 colours*/ - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_2bpp_lowres; - else - svga->render = svga_render_2bpp_highres; - break; - case 0x40: - case 0x60: /*256+ colours*/ - switch (svga->bpp) { - default: - case 8: - svga->map8 = svga->pallook; - if (svga->lowres) - svga->render = svga_render_8bpp_lowres; - else { - svga->render = svga_render_8bpp_highres; - svga->ma_latch <<= 1; - svga->rowoffset <<= 1; - } - break; + break; + case 0x20: /*4 colours*/ + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; + else + svga->render = svga_render_2bpp_highres; + break; + case 0x40: + case 0x60: /*256+ colours*/ + switch (svga->bpp) { + default: + case 8: + svga->map8 = svga->pallook; + mach_log("Lowres=%x, seqreg[1]bit3=%x.\n", svga->lowres, svga->seqregs[1] & 8); + if (svga->lowres) + svga->render = svga_render_8bpp_lowres; + else { + svga->render = svga_render_8bpp_highres; + svga->ma_latch <<= 1; + svga->rowoffset <<= 1; + } + break; + } + break; - } - break; - - default: - break; - } + default: + break; } } } @@ -3736,7 +3717,8 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0xaee: case 0xaef: - WRITE8(port, mach->cursor_offset_lo, val); + WRITE8(port, mach->cursor_offset_lo_reg, val); + mach->cursor_offset_lo = mach->cursor_offset_lo_reg; break; case 0xeee: @@ -3938,7 +3920,7 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) dev->vendor_mode[port & 1] = 1; mach32_updatemapping(mach); } - mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); + mach_log("ATI 8514/A: (0x%04x) val = %02x.\n", port, val); svga_recalctimings(svga); break; @@ -3947,7 +3929,6 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) WRITE8(port, mach->accel.eeprom_control, val); ati_eeprom_write(&mach->eeprom, mach->accel.eeprom_control & 4, mach->accel.eeprom_control & 2, mach->accel.eeprom_control & 1); mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); - svga_recalctimings(svga); break; default: @@ -4416,10 +4397,6 @@ mach_accel_in(uint16_t port, mach_t *mach) } break; - case 0x4ae8: - temp = dev->accel.advfunc_cntl; - break; - /*ATI Mach8/32 specific registers*/ case 0x12ee: case 0x12ef: @@ -4511,6 +4488,7 @@ mach_accel_in(uint16_t port, mach_t *mach) case 0x62ef: if (mach->force_busy) temp |= 0x20; + mach->force_busy = 0; if (ati_eeprom_read(&mach->eeprom)) temp |= 0x40; @@ -4701,6 +4679,7 @@ mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach) if (!(svga->gdcreg[6] & 1)) svga->fullchange = 2; + mach_log("WriteCommon chain4 = %x.\n", svga->chain4); if (((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && (svga->writemode < 4)) { writemask2 = 1 << (addr & 3); addr &= ~3; @@ -4865,6 +4844,7 @@ mach32_read_common(uint32_t addr, int linear, mach_t *mach) latch_addr = (addr << count) & svga->decode_mask; count = (1 << count); + mach_log("ReadCommon chain4 = %x.\n", svga->chain4); if ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) { addr &= svga->decode_mask; if (addr >= dev->vram_size) @@ -5209,7 +5189,11 @@ mach32_hwcursor_draw(svga_t *svga, int displine) int offset = dev->hwcursor_latch.x - dev->hwcursor_latch.xoff; uint32_t color0; uint32_t color1; + uint32_t *p; + int x_pos; + int y_pos; + mach_log("BPP=%d.\n", dev->accel_bpp); switch (dev->accel_bpp) { case 8: color0 = dev->pallook[mach->cursor_col_0]; @@ -5225,10 +5209,11 @@ mach32_hwcursor_draw(svga_t *svga, int displine) break; case 24: case 32: - default: color0 = ((mach->ext_cur_col_0_r << 16) | (mach->ext_cur_col_0_g << 8) | mach->cursor_col_0); color1 = ((mach->ext_cur_col_1_r << 16) | (mach->ext_cur_col_1_g << 8) | mach->cursor_col_1); break; + default: + break; } if (dev->interlace && dev->hwcursor_oddeven) @@ -5238,16 +5223,22 @@ mach32_hwcursor_draw(svga_t *svga, int displine) dat = dev->vram[dev->hwcursor_latch.addr & dev->vram_mask] | (dev->vram[(dev->hwcursor_latch.addr + 1) & dev->vram_mask] << 8); for (int xx = 0; xx < 8; xx++) { comb = (dat >> (xx << 1)) & 0x03; + + y_pos = displine; + x_pos = offset + svga->x_add; + p = buffer32->line[y_pos]; + if (offset >= dev->hwcursor_latch.x) { + mach_log("COMB=%d.\n", comb); switch (comb) { case 0: - (svga->monitor->target_buffer->line[displine])[offset + svga->x_add] = color0; + p[x_pos] = color0; break; case 1: - (svga->monitor->target_buffer->line[displine])[offset + svga->x_add] = color1; + p[x_pos] = color1; break; case 3: - (svga->monitor->target_buffer->line[displine])[offset + svga->x_add] ^= 0xffffff; + p[x_pos] ^= 0xffffff; break; default: From fc19a4698b4dba7088ad939ae9937c63c1426066 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Thu, 1 Jun 2023 01:57:41 -0400 Subject: [PATCH 032/936] Several fixes to compile with logging enabled --- src/chipset/neat.c | 3 ++- src/device/mouse_serial.c | 1 - src/disk/hdc_st506_xt.c | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/chipset/neat.c b/src/chipset/neat.c index a54fc312e..3b00b4ffd 100644 --- a/src/chipset/neat.c +++ b/src/chipset/neat.c @@ -673,13 +673,14 @@ neat_init(UNUSED(const device_t *info)) { neat_t *dev; uint8_t dram_mode = 0; + uint8_t i; /* Create an instance. */ dev = (neat_t *) malloc(sizeof(neat_t)); memset(dev, 0x00, sizeof(neat_t)); /* Initialize some of the registers to specific defaults. */ - for (uint8_t i = REG_RA0; i <= REG_RB11; i++) { + for (i = REG_RA0; i <= REG_RB11; i++) { dev->indx = i; neat_write(0x0023, 0x00, dev); } diff --git a/src/device/mouse_serial.c b/src/device/mouse_serial.c index 9e4556a88..e9531d78e 100644 --- a/src/device/mouse_serial.c +++ b/src/device/mouse_serial.c @@ -674,7 +674,6 @@ ltsermouse_process_data(mouse_t *dev) case 0x2a: switch (dev->ib) { default: - mouse_serial_log("Serial mouse: Invalid period %02X, using 1200 bps\n", data); fallthrough; case 0x6e: dev->bps = 1200; diff --git a/src/disk/hdc_st506_xt.c b/src/disk/hdc_st506_xt.c index 40709d307..79a5a8eba 100644 --- a/src/disk/hdc_st506_xt.c +++ b/src/disk/hdc_st506_xt.c @@ -1533,6 +1533,7 @@ static void set_switches(hdc_t *dev, hd_type_t *hdt, int num) { const drive_t *drive; + int c; int e; dev->switches = 0x00; @@ -1546,7 +1547,7 @@ set_switches(hdc_t *dev, hd_type_t *hdt, int num) continue; } - for (int c = 0; c < num; c++) { + for (c = 0; c < num; c++) { /* Does the Xebec also support more than 4 types? */ if ((drive->spt == hdt[c].spt) && (drive->hpc == hdt[c].hpc) && (drive->tracks == hdt[c].tracks)) { /* Olivetti M24/M240: Move the upper 2 bites up by 2 bits, as the From ea9348d104fdecf4bc65988179ef2381673c06f3 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 14 Dec 2023 21:56:17 +0100 Subject: [PATCH 033/936] Actually initialize the cursor color regs of the ATI Mach32 card. --- src/video/vid_ati_mach8.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 9b7c27649..872d41666 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -5195,6 +5195,7 @@ mach32_hwcursor_draw(svga_t *svga, int displine) mach_log("BPP=%d.\n", dev->accel_bpp); switch (dev->accel_bpp) { + default: case 8: color0 = dev->pallook[mach->cursor_col_0]; color1 = dev->pallook[mach->cursor_col_1]; @@ -5212,7 +5213,6 @@ mach32_hwcursor_draw(svga_t *svga, int displine) color0 = ((mach->ext_cur_col_0_r << 16) | (mach->ext_cur_col_0_g << 8) | mach->cursor_col_0); color1 = ((mach->ext_cur_col_1_r << 16) | (mach->ext_cur_col_1_g << 8) | mach->cursor_col_1); break; - default: break; } From 3c654af28675dae4cbc954e4df9311735722d45e Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 14 Dec 2023 21:57:48 +0100 Subject: [PATCH 034/936] dang it... --- src/video/vid_ati_mach8.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 872d41666..89abde977 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -5213,7 +5213,6 @@ mach32_hwcursor_draw(svga_t *svga, int displine) color0 = ((mach->ext_cur_col_0_r << 16) | (mach->ext_cur_col_0_g << 8) | mach->cursor_col_0); color1 = ((mach->ext_cur_col_1_r << 16) | (mach->ext_cur_col_1_g << 8) | mach->cursor_col_1); break; - break; } if (dev->interlace && dev->hwcursor_oddeven) From 61f83f2a3d396882be381c07f673051bad709401 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Thu, 14 Dec 2023 17:18:14 -0500 Subject: [PATCH 035/936] Better variable name in hdc_ide --- src/disk/hdc_ide.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 725c31996..522f1ee66 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -2297,7 +2297,7 @@ ide_callback(void *priv) case WIN_WRITE: case WIN_WRITE_NORETRY: #ifdef ENABLE_IDE_LOG - off64_t s = ide_get_sector(ide); + off64_t sector = ide_get_sector(ide); #endif if (ide->type == IDE_ATAPI) err = ABRT_ERR; @@ -2317,7 +2317,7 @@ ide_callback(void *priv) ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); } } - ide_log("Write: %02X, %i, %08X, %" PRIi64 "\n", err, ide->hdd_num, ide->lba_addr, s); + ide_log("Write: %02X, %i, %08X, %" PRIi64 "\n", err, ide->hdd_num, ide->lba_addr, sector); break; case WIN_WRITE_DMA: From 86e07aa598af975ec04e241c19943281b100d7a7 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Thu, 14 Dec 2023 20:42:52 -0500 Subject: [PATCH 036/936] Fix compile error with logging enabled in vid_compaq_cga --- src/video/vid_compaq_cga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_compaq_cga.c b/src/video/vid_compaq_cga.c index 4753ec223..430c7a64d 100644 --- a/src/video/vid_compaq_cga.c +++ b/src/video/vid_compaq_cga.c @@ -121,7 +121,7 @@ compaq_cga_poll(void *priv) if (self->cga.displine < self->cga.firstline) { self->cga.firstline = self->cga.displine; video_wait_for_buffer(); - compaq_cga_log("Firstline %i\n", firstline); + compaq_cga_log("Firstline %i\n", self->cga.firstline); } self->cga.lastline = self->cga.displine; From 9bc581d2f4aa5a11e98710b735e326473945a0b8 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 15 Dec 2023 17:45:19 -0500 Subject: [PATCH 037/936] Split cmake workflows into seperate files --- .github/workflows/cmake.yml | 483 ---------------------- .github/workflows/cmake_linux.yml | 122 ++++++ .github/workflows/cmake_macos.yml | 127 ++++++ .github/workflows/cmake_windows_llvm.yml | 163 ++++++++ .github/workflows/cmake_windows_msys2.yml | 149 +++++++ 5 files changed, 561 insertions(+), 483 deletions(-) delete mode 100644 .github/workflows/cmake.yml create mode 100644 .github/workflows/cmake_linux.yml create mode 100644 .github/workflows/cmake_macos.yml create mode 100644 .github/workflows/cmake_windows_llvm.yml create mode 100644 .github/workflows/cmake_windows_msys2.yml diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml deleted file mode 100644 index 4d446fd7a..000000000 --- a/.github/workflows/cmake.yml +++ /dev/null @@ -1,483 +0,0 @@ -name: CMake - -on: - - push: - paths: - - src/** - - cmake/** - - "**/CMakeLists.txt" - - "CMakePresets.json" - - .github/workflows/cmake.yml - - vcpkg.json - - "!**/Makefile*" - - pull_request: - paths: - - src/** - - cmake/** - - "**/CMakeLists.txt" - - "CMakePresets.json" - - .github/workflows/** - - .github/workflows/cmake.yml - - vcpkg.json - - "!**/Makefile*" - -jobs: - - msys2: - name: "Windows MSYS2 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }})" - - runs-on: windows-2022 - - env: - BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed - - defaults: - run: - shell: msys2 {0} - - strategy: - fail-fast: true - matrix: - build: -# - name: Regular -# preset: regular - - name: Debug - preset: debug - slug: -Debug - - name: Dev - preset: experimental - slug: -Dev - dynarec: - - name: ODR - new: off - slug: -ODR - - name: NDR - new: on - slug: -NDR - ui: - - name: Win32 GUI - qt: off - static: on - - name: Qt GUI - qt: on - static: on - slug: -Qt - packages: >- - qt5-static:p -# qt5-base:p -# qt5-tools:p - environment: -# - msystem: MSYS -# toolchain: ./cmake/flags-gcc-x86_64.cmake - - msystem: MINGW32 - prefix: mingw-w64-i686 - toolchain: ./cmake/flags-gcc-i686.cmake - - msystem: MINGW64 - prefix: mingw-w64-x86_64 - toolchain: ./cmake/flags-gcc-x86_64.cmake -# - msystem: CLANG32 -# prefix: mingw-w64-clang-i686 -# toolchain: ./cmake/llvm-win32-i686.cmake -# - msystem: CLANG64 -# prefix: mingw-w64-clang-x86_64 -# toolchain: ./cmake/llvm-win32-x86_64.cmake - - msystem: UCRT64 - prefix: mingw-w64-ucrt-x86_64 - toolchain: ./cmake/flags-gcc-x86_64.cmake - - steps: - - name: Prepare MSYS2 environment - uses: msys2/setup-msys2@v2 - with: - release: false - update: true - msystem: ${{ matrix.environment.msystem }} - pacboy: >- - ninja:p - cmake:p - gcc:p - pkgconf:p - freetype:p - SDL2:p - zlib:p - libpng:p - openal:p - rtmidi:p - libslirp:p - fluidsynth:p - libvncserver:p - ${{ matrix.ui.packages }} - - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - - name: Install sonar-scanner and build-wrapper - uses: SonarSource/sonarcloud-github-c-cpp@v2 - - - name: Configure CMake - run: >- - cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} - --toolchain ${{ matrix.environment.toolchain }} - -D NEW_DYNAREC=${{ matrix.dynarec.new }} - -D CMAKE_INSTALL_PREFIX=./build/artifacts - -D QT=${{ matrix.ui.qt }} - -D STATIC_BUILD=${{ matrix.ui.static }} - - - name: Build - run: | - .sonar/build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build - - - name: Run sonar-scanner - if: 0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: | - .sonar/sonar-scanner-5.0.1.3006-windows/bin/sonar-scanner.bat --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" - - - name: Generate package - run: cmake --install build - - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-${{ matrix.environment.msystem }}-gha${{ github.run_number }}' - path: build/artifacts/** - - llvm-windows: - name: "Windows vcpkg/LLVM (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.target.name }})" - if: 0 - - runs-on: windows-2022 - - env: - BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed - VCPKG_BINARY_SOURCES: 'clear;nuget,GitHub,readwrite' - - strategy: - fail-fast: true - matrix: - build: -# - name: Regular -# preset: regular - - name: Debug - preset: debug - slug: -Debug - - name: Dev - preset: experimental - slug: -Dev - dynarec: - - name: ODR - new: off - slug: -ODR - - name: NDR - new: on - slug: -NDR - ui: - - name: Win32 GUI - qt: off - - name: Qt GUI - qt: on - slug: -Qt - target: - - name: x86 - triplet: x86-windows-static - toolchain: ./cmake/llvm-win32-i686.cmake - vcvars: x64_x86 - - name: x64 - triplet: x64-windows-static - toolchain: ./cmake/llvm-win32-x86_64.cmake - vcvars: x64 -# - name: ARM -# triplet: arm-windows-static -# toolchain: ./cmake/llvm-win32-arm.cmake -# vcvars: x64_arm - - name: ARM64 - triplet: arm64-windows-static - toolchain: ./cmake/llvm-win32-aarch64.cmake - vcvars: x64_arm64 - exclude: - - dynarec: - new: off - target: - name: ARM64 - - steps: - - name: Prepare VS environment - uses: ilammy/msvc-dev-cmd@v1 - with: - arch: ${{ matrix.target.vcvars }} - - - name: Add LLVM to path - run: echo "C:/Program Files/LLVM/bin" >> $env:GITHUB_PATH - - - name: Download Ninja - run: > - Invoke-WebRequest https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-win.zip -OutFile ninja-win.zip && - Expand-Archive ninja-win.zip -DestinationPath . - - - name: Setup NuGet Credentials - run: > - & (C:/vcpkg/vcpkg --vcpkg-root "${{ env.VCPKG_ROOT }}" fetch nuget | tail -n 2) - sources add - -source "https://nuget.pkg.github.com/86Box/index.json" - -storepasswordincleartext - -name "GitHub" - -username "86Box" - -password "${{ secrets.GITHUB_TOKEN }}" - - - name: Fix MSVC atomic headers - run: dir "C:/Program Files/Microsoft Visual Studio/2022/*/VC/Tools/MSVC/*/include" -include stdatomic.h -recurse | del - - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - - name: Install sonar-scanner and build-wrapper - uses: SonarSource/sonarcloud-github-c-cpp@v2 - - - name: Configure CMake - run: > - cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} - --toolchain C:/vcpkg/scripts/buildsystems/vcpkg.cmake - -D NEW_DYNAREC=${{ matrix.dynarec.new }} -D QT=${{ matrix.ui.qt }} - -D CMAKE_INSTALL_PREFIX=./build/artifacts - -D VCPKG_CHAINLOAD_TOOLCHAIN_FILE=${{ github.workspace }}/${{ matrix.target.toolchain }} - -D VCPKG_TARGET_TRIPLET=${{ matrix.target.triplet }} - -D VCPKG_HOST_TRIPLET=x64-windows - -D VCPKG_USE_HOST_TOOLS=ON - - - name: Fix Qt - if: matrix.ui.qt == 'on' - run: | - $qtTargetsPath = "${{ github.workspace }}/build/vcpkg_installed/${{ matrix.target.triplet }}/share/Qt6/Qt6Targets.cmake" - (Get-Content $qtTargetsPath) -replace "^.*-Zc:__cplusplus;-permissive-.*$","#$&" | Set-Content $qtTargetsPath - - - name: Reconfigure CMake - if: matrix.ui.qt == 'on' - run: | - cmake clean build - - - name: Build - run: | - .sonar/build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build - - - name: Run sonar-scanner - if: 0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: | - .sonar/sonar-scanner-5.0.1.3006-windows/bin/sonar-scanner.bat --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" - - - name: Generate package - run: | - cmake --install build - - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-LLVM-${{ matrix.target.name }}-gha${{ github.run_number }}' - path: build/artifacts/** - - linux: - name: "Linux GCC 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)" - - runs-on: ubuntu-22.04 - - env: - BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed - - strategy: - fail-fast: true - matrix: - build: -# - name: Regular -# preset: regular - - name: Debug - preset: debug - slug: -Debug - - name: Dev - preset: experimental - slug: -Dev - dynarec: - - name: ODR - new: off - slug: -ODR - - name: NDR - new: on - slug: -NDR - ui: - - name: SDL GUI - qt: off - static: on - - name: Qt GUI - qt: on - slug: -Qt - packages: >- - qtbase5-dev - qtbase5-private-dev - qttools5-dev - libevdev-dev - libxkbcommon-x11-dev - - steps: - - name: Install dependencies - run: >- - sudo apt update && sudo apt install - build-essential - ninja-build - libfreetype-dev - libsdl2-dev - libpng-dev - libc6-dev - librtmidi-dev - libopenal-dev - libslirp-dev - libfluidsynth-dev - libvncserver-dev - ${{ matrix.ui.packages }} - - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - - name: Install sonar-scanner and build-wrapper - uses: SonarSource/sonarcloud-github-c-cpp@v2 - - - name: Configure CMake - run: >- - cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} - --toolchain ./cmake/flags-gcc-x86_64.cmake - -D NEW_DYNAREC=${{ matrix.dynarec.new }} - -D CMAKE_INSTALL_PREFIX=./build/artifacts - -D QT=${{ matrix.ui.qt }} - - - name: Build - run: | - build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build - - - name: Run sonar-scanner -# if: 0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: | - sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" - - - name: Generate package - run: | - cmake --install build - - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-UbuntuJammy-x86_64-gha${{ github.run_number }}' - path: build/artifacts/** - - macos12: - name: "macOS 12 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)" - - runs-on: macos-12 - - env: - BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed - - strategy: - fail-fast: true - matrix: - build: -# - name: Regular -# preset: regular - - name: Debug - preset: debug - slug: -Debug - - name: Dev - preset: experimental - slug: -Dev - dynarec: - - name: ODR - new: off - slug: -ODR - - name: NDR - new: on - slug: -NDR - ui: - - name: SDL GUI - qt: off - static: on - src-packages: >- - libsndfile - - name: Qt GUI - qt: on - slug: -Qt - packages: >- - qt@5 - src-packages: >- - libsndfile - - steps: - - name: Install source dependencies - run: >- - brew reinstall -s - ${{ matrix.ui.src-packages }} - - - name: Install dependencies - run: >- - brew install - ninja - freetype - sdl2 - libpng - rtmidi - openal-soft - fluidsynth - libvncserver - ${{ matrix.ui.packages }} - - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - - name: Install sonar-scanner and build-wrapper - uses: SonarSource/sonarcloud-github-c-cpp@v2 - - - name: Configure CMake - run: >- - cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} - --toolchain ./cmake/flags-gcc-x86_64.cmake - -D NEW_DYNAREC=${{ matrix.dynarec.new }} - -D CMAKE_INSTALL_PREFIX=./build/artifacts - -D QT=${{ matrix.ui.qt }} - -D Qt5_ROOT=$(brew --prefix qt@5) - -D Qt5LinguistTools_ROOT=$(brew --prefix qt@5) - -D OpenAL_ROOT=$(brew --prefix openal-soft) - - - name: Build - run: | - build-wrapper-macosx-x86 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build - - - name: Run sonar-scanner - if: 0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: | - sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" - - - name: Generate package - run: | - cmake --install build - - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-macOS-x86_64-gha${{ github.run_number }}' - path: build/artifacts/** diff --git a/.github/workflows/cmake_linux.yml b/.github/workflows/cmake_linux.yml new file mode 100644 index 000000000..c09789bfc --- /dev/null +++ b/.github/workflows/cmake_linux.yml @@ -0,0 +1,122 @@ +name: CMake (Linux) + +on: + + push: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/cmake.yml + - vcpkg.json + - "!**/Makefile*" + + pull_request: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/** + - .github/workflows/cmake.yml + - vcpkg.json + - "!**/Makefile*" + +jobs: + + linux: + name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64" + + runs-on: ubuntu-22.04 + + env: + BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed + + strategy: + fail-fast: true + matrix: + build: +# - name: Regular +# preset: regular + - name: Debug + preset: debug + slug: -Debug + - name: Dev + preset: experimental + slug: -Dev + dynarec: + - name: ODR + new: off + slug: -ODR + - name: NDR + new: on + slug: -NDR + ui: + - name: SDL GUI + qt: off + static: on + - name: Qt GUI + qt: on + slug: -Qt + packages: >- + qtbase5-dev + qtbase5-private-dev + qttools5-dev + libevdev-dev + libxkbcommon-x11-dev + + steps: + - name: Install dependencies + run: >- + sudo apt update && sudo apt install + build-essential + ninja-build + libfreetype-dev + libsdl2-dev + libpng-dev + libc6-dev + librtmidi-dev + libopenal-dev + libslirp-dev + libfluidsynth-dev + libvncserver-dev + ${{ matrix.ui.packages }} + + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + - name: Install sonar-scanner and build-wrapper + uses: SonarSource/sonarcloud-github-c-cpp@v2 + + - name: Configure CMake + run: >- + cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} + --toolchain ./cmake/flags-gcc-x86_64.cmake + -D NEW_DYNAREC=${{ matrix.dynarec.new }} + -D CMAKE_INSTALL_PREFIX=./build/artifacts + -D QT=${{ matrix.ui.qt }} + + - name: Build + run: | + build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build + + - name: Run sonar-scanner +# if: 0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: | + sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" + + - name: Generate package + run: | + cmake --install build + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-UbuntuJammy-x86_64-gha${{ github.run_number }}' + path: build/artifacts/** diff --git a/.github/workflows/cmake_macos.yml b/.github/workflows/cmake_macos.yml new file mode 100644 index 000000000..7a6edcde9 --- /dev/null +++ b/.github/workflows/cmake_macos.yml @@ -0,0 +1,127 @@ +name: CMake (macos) + +on: + + push: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/cmake.yml + - vcpkg.json + - "!**/Makefile*" + + pull_request: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/** + - .github/workflows/cmake.yml + - vcpkg.json + - "!**/Makefile*" + +jobs: + + macos12: + name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64" + + runs-on: macos-12 + + env: + BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed + + strategy: + fail-fast: true + matrix: + build: +# - name: Regular +# preset: regular + - name: Debug + preset: debug + slug: -Debug + - name: Dev + preset: experimental + slug: -Dev + dynarec: + - name: ODR + new: off + slug: -ODR + - name: NDR + new: on + slug: -NDR + ui: + - name: SDL GUI + qt: off + static: on + src-packages: >- + libsndfile + - name: Qt GUI + qt: on + slug: -Qt + packages: >- + qt@5 + src-packages: >- + libsndfile + + steps: + - name: Install source dependencies + run: >- + brew reinstall -s + ${{ matrix.ui.src-packages }} + + - name: Install dependencies + run: >- + brew install + ninja + freetype + sdl2 + libpng + rtmidi + openal-soft + fluidsynth + libvncserver + ${{ matrix.ui.packages }} + + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + - name: Install sonar-scanner and build-wrapper + uses: SonarSource/sonarcloud-github-c-cpp@v2 + + - name: Configure CMake + run: >- + cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} + --toolchain ./cmake/flags-gcc-x86_64.cmake + -D NEW_DYNAREC=${{ matrix.dynarec.new }} + -D CMAKE_INSTALL_PREFIX=./build/artifacts + -D QT=${{ matrix.ui.qt }} + -D Qt5_ROOT=$(brew --prefix qt@5) + -D Qt5LinguistTools_ROOT=$(brew --prefix qt@5) + -D OpenAL_ROOT=$(brew --prefix openal-soft) + + - name: Build + run: | + build-wrapper-macosx-x86 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build + + - name: Run sonar-scanner + if: 0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: | + sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" + + - name: Generate package + run: | + cmake --install build + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-macOS-x86_64-gha${{ github.run_number }}' + path: build/artifacts/** diff --git a/.github/workflows/cmake_windows_llvm.yml b/.github/workflows/cmake_windows_llvm.yml new file mode 100644 index 000000000..a49f9488a --- /dev/null +++ b/.github/workflows/cmake_windows_llvm.yml @@ -0,0 +1,163 @@ +name: CMake (Windows, vcpkg/LLVM) + +on: + + push: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/cmake.yml + - vcpkg.json + - "!**/Makefile*" + + pull_request: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/** + - .github/workflows/cmake.yml + - vcpkg.json + - "!**/Makefile*" + +jobs: + + llvm-windows: + name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.target.name }}" + if: 0 + + runs-on: windows-2022 + + env: + BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed + VCPKG_BINARY_SOURCES: 'clear;nuget,GitHub,readwrite' + + strategy: + fail-fast: true + matrix: + build: +# - name: Regular +# preset: regular + - name: Debug + preset: debug + slug: -Debug + - name: Dev + preset: experimental + slug: -Dev + dynarec: + - name: ODR + new: off + slug: -ODR + - name: NDR + new: on + slug: -NDR + ui: + - name: Win32 GUI + qt: off + - name: Qt GUI + qt: on + slug: -Qt + target: + - name: x86 + triplet: x86-windows-static + toolchain: ./cmake/llvm-win32-i686.cmake + vcvars: x64_x86 + - name: x64 + triplet: x64-windows-static + toolchain: ./cmake/llvm-win32-x86_64.cmake + vcvars: x64 +# - name: ARM +# triplet: arm-windows-static +# toolchain: ./cmake/llvm-win32-arm.cmake +# vcvars: x64_arm + - name: ARM64 + triplet: arm64-windows-static + toolchain: ./cmake/llvm-win32-aarch64.cmake + vcvars: x64_arm64 + exclude: + - dynarec: + new: off + target: + name: ARM64 + + steps: + - name: Prepare VS environment + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: ${{ matrix.target.vcvars }} + + - name: Add LLVM to path + run: echo "C:/Program Files/LLVM/bin" >> $env:GITHUB_PATH + + - name: Download Ninja + run: > + Invoke-WebRequest https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-win.zip -OutFile ninja-win.zip && + Expand-Archive ninja-win.zip -DestinationPath . + + - name: Setup NuGet Credentials + run: > + & (C:/vcpkg/vcpkg --vcpkg-root "${{ env.VCPKG_ROOT }}" fetch nuget | tail -n 2) + sources add + -source "https://nuget.pkg.github.com/86Box/index.json" + -storepasswordincleartext + -name "GitHub" + -username "86Box" + -password "${{ secrets.GITHUB_TOKEN }}" + + - name: Fix MSVC atomic headers + run: dir "C:/Program Files/Microsoft Visual Studio/2022/*/VC/Tools/MSVC/*/include" -include stdatomic.h -recurse | del + + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + - name: Install sonar-scanner and build-wrapper + uses: SonarSource/sonarcloud-github-c-cpp@v2 + + - name: Configure CMake + run: > + cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} + --toolchain C:/vcpkg/scripts/buildsystems/vcpkg.cmake + -D NEW_DYNAREC=${{ matrix.dynarec.new }} -D QT=${{ matrix.ui.qt }} + -D CMAKE_INSTALL_PREFIX=./build/artifacts + -D VCPKG_CHAINLOAD_TOOLCHAIN_FILE=${{ github.workspace }}/${{ matrix.target.toolchain }} + -D VCPKG_TARGET_TRIPLET=${{ matrix.target.triplet }} + -D VCPKG_HOST_TRIPLET=x64-windows + -D VCPKG_USE_HOST_TOOLS=ON + + - name: Fix Qt + if: matrix.ui.qt == 'on' + run: | + $qtTargetsPath = "${{ github.workspace }}/build/vcpkg_installed/${{ matrix.target.triplet }}/share/Qt6/Qt6Targets.cmake" + (Get-Content $qtTargetsPath) -replace "^.*-Zc:__cplusplus;-permissive-.*$","#$&" | Set-Content $qtTargetsPath + + - name: Reconfigure CMake + if: matrix.ui.qt == 'on' + run: | + cmake clean build + + - name: Build + run: | + .sonar/build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build + + - name: Run sonar-scanner + if: 0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: | + .sonar/sonar-scanner-5.0.1.3006-windows/bin/sonar-scanner.bat --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" + + - name: Generate package + run: | + cmake --install build + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-LLVM-${{ matrix.target.name }}-gha${{ github.run_number }}' + path: build/artifacts/** diff --git a/.github/workflows/cmake_windows_msys2.yml b/.github/workflows/cmake_windows_msys2.yml new file mode 100644 index 000000000..48503cc27 --- /dev/null +++ b/.github/workflows/cmake_windows_msys2.yml @@ -0,0 +1,149 @@ +name: CMake (Windows, msys2) + +on: + + push: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/cmake.yml + - vcpkg.json + - "!**/Makefile*" + + pull_request: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/** + - .github/workflows/cmake.yml + - vcpkg.json + - "!**/Makefile*" + +jobs: + + msys2: + name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}" + + runs-on: windows-2022 + + env: + BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed + + defaults: + run: + shell: msys2 {0} + + strategy: + fail-fast: true + matrix: + build: +# - name: Regular +# preset: regular + - name: Debug + preset: debug + slug: -Debug + - name: Dev + preset: experimental + slug: -Dev + dynarec: + - name: ODR + new: off + slug: -ODR + - name: NDR + new: on + slug: -NDR + ui: + - name: Win32 GUI + qt: off + static: on + - name: Qt GUI + qt: on + static: on + slug: -Qt + packages: >- + qt5-static:p +# qt5-base:p +# qt5-tools:p + environment: +# - msystem: MSYS +# toolchain: ./cmake/flags-gcc-x86_64.cmake + - msystem: MINGW32 + prefix: mingw-w64-i686 + toolchain: ./cmake/flags-gcc-i686.cmake + - msystem: MINGW64 + prefix: mingw-w64-x86_64 + toolchain: ./cmake/flags-gcc-x86_64.cmake +# - msystem: CLANG32 +# prefix: mingw-w64-clang-i686 +# toolchain: ./cmake/llvm-win32-i686.cmake +# - msystem: CLANG64 +# prefix: mingw-w64-clang-x86_64 +# toolchain: ./cmake/llvm-win32-x86_64.cmake + - msystem: UCRT64 + prefix: mingw-w64-ucrt-x86_64 + toolchain: ./cmake/flags-gcc-x86_64.cmake + + steps: + - name: Prepare MSYS2 environment + uses: msys2/setup-msys2@v2 + with: + release: false + update: true + msystem: ${{ matrix.environment.msystem }} + pacboy: >- + ninja:p + cmake:p + gcc:p + pkgconf:p + freetype:p + SDL2:p + zlib:p + libpng:p + openal:p + rtmidi:p + libslirp:p + fluidsynth:p + libvncserver:p + ${{ matrix.ui.packages }} + + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + - name: Install sonar-scanner and build-wrapper + uses: SonarSource/sonarcloud-github-c-cpp@v2 + + - name: Configure CMake + run: >- + cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} + --toolchain ${{ matrix.environment.toolchain }} + -D NEW_DYNAREC=${{ matrix.dynarec.new }} + -D CMAKE_INSTALL_PREFIX=./build/artifacts + -D QT=${{ matrix.ui.qt }} + -D STATIC_BUILD=${{ matrix.ui.static }} + + - name: Build + run: | + .sonar/build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build + + - name: Run sonar-scanner + if: 0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: | + .sonar/sonar-scanner-5.0.1.3006-windows/bin/sonar-scanner.bat --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" + + - name: Generate package + run: cmake --install build + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-${{ matrix.environment.msystem }}-gha${{ github.run_number }}' + path: build/artifacts/** From 420bd82dad80a1eb82b23893a4cb59e33319392e Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 15 Dec 2023 17:48:18 -0500 Subject: [PATCH 038/936] Split codeql workflows into seperate files --- .github/workflows/codeql.yml | 309 --------------------- .github/workflows/codeql_linux.yml | 112 ++++++++ .github/workflows/codeql_macos.yml | 108 +++++++ .github/workflows/codeql_windows_msys2.yml | 141 ++++++++++ 4 files changed, 361 insertions(+), 309 deletions(-) delete mode 100644 .github/workflows/codeql.yml create mode 100644 .github/workflows/codeql_linux.yml create mode 100644 .github/workflows/codeql_macos.yml create mode 100644 .github/workflows/codeql_windows_msys2.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index 53dde02ab..000000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,309 +0,0 @@ -name: CodeQL - -on: - - push: - paths: - - src/** - - cmake/** - - "**/CMakeLists.txt" - - "CMakePresets.json" - - .github/workflows/codeql.yml - - vcpkg.json - - "!**/Makefile*" - - pull_request: - paths: - - src/** - - cmake/** - - "**/CMakeLists.txt" - - "CMakePresets.json" - - .github/workflows/** - - .github/workflows/codeql.yml - - vcpkg.json - - "!**/Makefile*" - -jobs: - - analyze-msys2: - - name: "Analyze Windows MSYS2 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }})" - - runs-on: windows-2022 - - permissions: - actions: read - contents: read - security-events: write - - defaults: - run: - shell: msys2 {0} - - strategy: - fail-fast: true - matrix: - language: [ 'cpp' ] - build: -# - name: Regular -# preset: regular -# - name: Debug -# preset: debug -# slug: -Debug - - name: Dev - preset: experimental - slug: -Dev - dynarec: - - name: ODR - new: off - slug: -ODR - - name: NDR - new: on - slug: -NDR - ui: - - name: Win32 GUI - qt: off - static: on - - name: Qt GUI - qt: on - static: off - slug: -Qt - packages: >- - qt5-base:p - qt5-tools:p - environment: -# - msystem: MSYS -# toolchain: ./cmake/flags-gcc-x86_64.cmake - - msystem: MINGW32 - prefix: mingw-w64-i686 - toolchain: ./cmake/flags-gcc-i686.cmake - - msystem: MINGW64 - prefix: mingw-w64-x86_64 - toolchain: ./cmake/flags-gcc-x86_64.cmake -# - msystem: CLANG32 -# prefix: mingw-w64-clang-i686 -# toolchain: ./cmake/llvm-win32-i686.cmake -# - msystem: CLANG64 -# prefix: mingw-w64-clang-x86_64 -# toolchain: ./cmake/llvm-win32-x86_64.cmake - - msystem: UCRT64 - prefix: mingw-w64-ucrt-x86_64 - toolchain: ./cmake/flags-gcc-x86_64.cmake - - steps: - - name: Prepare MSYS2 environment - uses: msys2/setup-msys2@v2 - with: - release: false - update: true - msystem: ${{ matrix.environment.msystem }} - pacboy: >- - ninja:p - cmake:p - gcc:p - pkgconf:p - freetype:p - SDL2:p - zlib:p - libpng:p - openal:p - rtmidi:p - libslirp:p - fluidsynth:p - libvncserver:p - ${{ matrix.ui.packages }} - - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - config-file: ./.github/codeql/codeql-config.yml - - - name: Configure CMake - run: >- - cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} - --toolchain ${{ matrix.environment.toolchain }} - -D NEW_DYNAREC=${{ matrix.dynarec.new }} - -D CMAKE_INSTALL_PREFIX=./build/artifacts - -D QT=${{ matrix.ui.qt }} - -D STATIC_BUILD=${{ matrix.ui.static }} - - - name: Build - run: cmake --build build - - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{matrix.language}}" - - analyze-linux: - - name: "Analyze Linux GCC 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)" - - runs-on: ubuntu-22.04 - - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: true - matrix: - language: [ 'cpp' ] - build: -# - name: Regular -# preset: regular -# - name: Debug -# preset: debug -# slug: -Debug - - name: Dev - preset: experimental - slug: -Dev - dynarec: - - name: ODR - new: off - slug: -ODR - - name: NDR - new: on - slug: -NDR - ui: - - name: SDL GUI - qt: off - - name: Qt GUI - qt: on - slug: -Qt - packages: >- - qtbase5-dev - qtbase5-private-dev - qttools5-dev - libevdev-dev - libxkbcommon-x11-dev - - steps: - - name: Install dependencies - run: >- - sudo apt update && sudo apt install - build-essential - ninja-build - libfreetype-dev - libsdl2-dev - libpng-dev - libc6-dev - librtmidi-dev - libopenal-dev - libslirp-dev - libfluidsynth-dev - libvncserver-dev - ${{ matrix.ui.packages }} - - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - config-file: ./.github/codeql/codeql-config.yml - - - name: Configure CMake - run: >- - cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} - --toolchain ./cmake/flags-gcc-x86_64.cmake - -D NEW_DYNAREC=${{ matrix.dynarec.new }} - -D CMAKE_INSTALL_PREFIX=./build/artifacts - -D QT=${{ matrix.ui.qt }} - - - name: Build - run: cmake --build build - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{matrix.language}}" - - analyze-macos12: - - name: "Analyze macOS 12 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)" - - runs-on: macos-12 - - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: true - matrix: - language: [ 'cpp' ] - build: -# - name: Regular -# preset: regular -# - name: Debug -# preset: debug -# slug: -Debug - - name: Dev - preset: experimental - slug: -Dev - dynarec: - - name: ODR - new: off - slug: -ODR - - name: NDR - new: on - slug: -NDR - ui: - - name: SDL GUI - qt: off - - name: Qt GUI - qt: on - slug: -Qt - packages: >- - qt@5 - - steps: - - name: Install dependencies - run: >- - brew install - ninja - freetype - sdl2 - libpng - rtmidi - openal-soft - fluidsynth - libvncserver - ${{ matrix.ui.packages }} - - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - config-file: ./.github/codeql/codeql-config.yml - - - name: Configure CMake - run: >- - cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} - --toolchain ./cmake/flags-gcc-x86_64.cmake - -D NEW_DYNAREC=${{ matrix.dynarec.new }} - -D CMAKE_INSTALL_PREFIX=./build/artifacts - -D QT=${{ matrix.ui.qt }} - -D Qt5_ROOT=$(brew --prefix qt@5) - -D Qt5LinguistTools_ROOT=$(brew --prefix qt@5) - -D OpenAL_ROOT=$(brew --prefix openal-soft) - - - name: Build - run: cmake --build build - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{matrix.language}}" diff --git a/.github/workflows/codeql_linux.yml b/.github/workflows/codeql_linux.yml new file mode 100644 index 000000000..e1af413da --- /dev/null +++ b/.github/workflows/codeql_linux.yml @@ -0,0 +1,112 @@ +name: CodeQL Analasys (Linux) + +on: + + push: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/codeql.yml + - vcpkg.json + - "!**/Makefile*" + + pull_request: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/** + - .github/workflows/codeql.yml + - vcpkg.json + - "!**/Makefile*" + +jobs: + + analyze-linux: + + name: "Analyze Linux GCC 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)" + + runs-on: ubuntu-22.04 + + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: true + matrix: + language: [ 'cpp' ] + build: +# - name: Regular +# preset: regular +# - name: Debug +# preset: debug +# slug: -Debug + - name: Dev + preset: experimental + slug: -Dev + dynarec: + - name: ODR + new: off + slug: -ODR + - name: NDR + new: on + slug: -NDR + ui: + - name: SDL GUI + qt: off + - name: Qt GUI + qt: on + slug: -Qt + packages: >- + qtbase5-dev + qtbase5-private-dev + qttools5-dev + libevdev-dev + libxkbcommon-x11-dev + + steps: + - name: Install dependencies + run: >- + sudo apt update && sudo apt install + build-essential + ninja-build + libfreetype-dev + libsdl2-dev + libpng-dev + libc6-dev + librtmidi-dev + libopenal-dev + libslirp-dev + libfluidsynth-dev + libvncserver-dev + ${{ matrix.ui.packages }} + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + config-file: ./.github/codeql/codeql-config.yml + + - name: Configure CMake + run: >- + cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} + --toolchain ./cmake/flags-gcc-x86_64.cmake + -D NEW_DYNAREC=${{ matrix.dynarec.new }} + -D CMAKE_INSTALL_PREFIX=./build/artifacts + -D QT=${{ matrix.ui.qt }} + + - name: Build + run: cmake --build build + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/codeql_macos.yml b/.github/workflows/codeql_macos.yml new file mode 100644 index 000000000..9a4e672bc --- /dev/null +++ b/.github/workflows/codeql_macos.yml @@ -0,0 +1,108 @@ +name: CodeQL Analasys (macos) + +on: + + push: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/codeql.yml + - vcpkg.json + - "!**/Makefile*" + + pull_request: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/** + - .github/workflows/codeql.yml + - vcpkg.json + - "!**/Makefile*" + +jobs: + + analyze-macos12: + + name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64" + + runs-on: macos-12 + + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: true + matrix: + language: [ 'cpp' ] + build: +# - name: Regular +# preset: regular +# - name: Debug +# preset: debug +# slug: -Debug + - name: Dev + preset: experimental + slug: -Dev + dynarec: + - name: ODR + new: off + slug: -ODR + - name: NDR + new: on + slug: -NDR + ui: + - name: SDL GUI + qt: off + - name: Qt GUI + qt: on + slug: -Qt + packages: >- + qt@5 + + steps: + - name: Install dependencies + run: >- + brew install + ninja + freetype + sdl2 + libpng + rtmidi + openal-soft + fluidsynth + libvncserver + ${{ matrix.ui.packages }} + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + config-file: ./.github/codeql/codeql-config.yml + + - name: Configure CMake + run: >- + cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} + --toolchain ./cmake/flags-gcc-x86_64.cmake + -D NEW_DYNAREC=${{ matrix.dynarec.new }} + -D CMAKE_INSTALL_PREFIX=./build/artifacts + -D QT=${{ matrix.ui.qt }} + -D Qt5_ROOT=$(brew --prefix qt@5) + -D Qt5LinguistTools_ROOT=$(brew --prefix qt@5) + -D OpenAL_ROOT=$(brew --prefix openal-soft) + + - name: Build + run: cmake --build build + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/codeql_windows_msys2.yml b/.github/workflows/codeql_windows_msys2.yml new file mode 100644 index 000000000..472d36966 --- /dev/null +++ b/.github/workflows/codeql_windows_msys2.yml @@ -0,0 +1,141 @@ +name: CodeQL Analasys (Windows, msys2) + +on: + + push: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/codeql.yml + - vcpkg.json + - "!**/Makefile*" + + pull_request: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/** + - .github/workflows/codeql.yml + - vcpkg.json + - "!**/Makefile*" + +jobs: + + analyze-msys2: + + name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}" + + runs-on: windows-2022 + + permissions: + actions: read + contents: read + security-events: write + + defaults: + run: + shell: msys2 {0} + + strategy: + fail-fast: true + matrix: + language: [ 'cpp' ] + build: +# - name: Regular +# preset: regular +# - name: Debug +# preset: debug +# slug: -Debug + - name: Dev + preset: experimental + slug: -Dev + dynarec: + - name: ODR + new: off + slug: -ODR + - name: NDR + new: on + slug: -NDR + ui: + - name: Win32 GUI + qt: off + static: on + - name: Qt GUI + qt: on + static: off + slug: -Qt + packages: >- + qt5-base:p + qt5-tools:p + environment: +# - msystem: MSYS +# toolchain: ./cmake/flags-gcc-x86_64.cmake + - msystem: MINGW32 + prefix: mingw-w64-i686 + toolchain: ./cmake/flags-gcc-i686.cmake + - msystem: MINGW64 + prefix: mingw-w64-x86_64 + toolchain: ./cmake/flags-gcc-x86_64.cmake +# - msystem: CLANG32 +# prefix: mingw-w64-clang-i686 +# toolchain: ./cmake/llvm-win32-i686.cmake +# - msystem: CLANG64 +# prefix: mingw-w64-clang-x86_64 +# toolchain: ./cmake/llvm-win32-x86_64.cmake + - msystem: UCRT64 + prefix: mingw-w64-ucrt-x86_64 + toolchain: ./cmake/flags-gcc-x86_64.cmake + + steps: + - name: Prepare MSYS2 environment + uses: msys2/setup-msys2@v2 + with: + release: false + update: true + msystem: ${{ matrix.environment.msystem }} + pacboy: >- + ninja:p + cmake:p + gcc:p + pkgconf:p + freetype:p + SDL2:p + zlib:p + libpng:p + openal:p + rtmidi:p + libslirp:p + fluidsynth:p + libvncserver:p + ${{ matrix.ui.packages }} + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + config-file: ./.github/codeql/codeql-config.yml + + - name: Configure CMake + run: >- + cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} + --toolchain ${{ matrix.environment.toolchain }} + -D NEW_DYNAREC=${{ matrix.dynarec.new }} + -D CMAKE_INSTALL_PREFIX=./build/artifacts + -D QT=${{ matrix.ui.qt }} + -D STATIC_BUILD=${{ matrix.ui.static }} + + - name: Build + run: cmake --build build + + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" From be9ef9848dc080926d5d34898073214a591070bb Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 15 Dec 2023 17:56:05 -0500 Subject: [PATCH 039/936] Update name for makefile builds --- .github/workflows/c-cpp.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 79f350f4f..b76c2c260 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -1,4 +1,4 @@ -name: MSYS2 Makefile +name: MSYS2 Makefile (Windows, Legacy) on: @@ -16,7 +16,7 @@ on: jobs: msys2: - name: "Windows MSYS2 Makefile (Win32 GUI, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }})" + name: "Win32 GUI, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}" runs-on: windows-2022 From c88ae29a0e181397044a64775bb68629fd88a772 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 15 Dec 2023 18:07:42 -0500 Subject: [PATCH 040/936] Fix typos --- .github/workflows/codeql_linux.yml | 2 +- .github/workflows/codeql_macos.yml | 2 +- .github/workflows/codeql_windows_msys2.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql_linux.yml b/.github/workflows/codeql_linux.yml index e1af413da..04475f006 100644 --- a/.github/workflows/codeql_linux.yml +++ b/.github/workflows/codeql_linux.yml @@ -1,4 +1,4 @@ -name: CodeQL Analasys (Linux) +name: CodeQL Analasis (Linux) on: diff --git a/.github/workflows/codeql_macos.yml b/.github/workflows/codeql_macos.yml index 9a4e672bc..e4e536d18 100644 --- a/.github/workflows/codeql_macos.yml +++ b/.github/workflows/codeql_macos.yml @@ -1,4 +1,4 @@ -name: CodeQL Analasys (macos) +name: CodeQL Analasis (macos) on: diff --git a/.github/workflows/codeql_windows_msys2.yml b/.github/workflows/codeql_windows_msys2.yml index 472d36966..cff49f91c 100644 --- a/.github/workflows/codeql_windows_msys2.yml +++ b/.github/workflows/codeql_windows_msys2.yml @@ -1,4 +1,4 @@ -name: CodeQL Analasys (Windows, msys2) +name: CodeQL Analasis (Windows, msys2) on: From 73cd319d17070c2a71ed5011ddc0d5d8b9487254 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 15 Dec 2023 18:10:12 -0500 Subject: [PATCH 041/936] Yet more typo fixes --- .github/workflows/codeql_linux.yml | 2 +- .github/workflows/codeql_macos.yml | 2 +- .github/workflows/codeql_windows_msys2.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql_linux.yml b/.github/workflows/codeql_linux.yml index 04475f006..a97951abf 100644 --- a/.github/workflows/codeql_linux.yml +++ b/.github/workflows/codeql_linux.yml @@ -1,4 +1,4 @@ -name: CodeQL Analasis (Linux) +name: CodeQL Analysis (Linux) on: diff --git a/.github/workflows/codeql_macos.yml b/.github/workflows/codeql_macos.yml index e4e536d18..724bdc6f6 100644 --- a/.github/workflows/codeql_macos.yml +++ b/.github/workflows/codeql_macos.yml @@ -1,4 +1,4 @@ -name: CodeQL Analasis (macos) +name: CodeQL Analysis (macos) on: diff --git a/.github/workflows/codeql_windows_msys2.yml b/.github/workflows/codeql_windows_msys2.yml index cff49f91c..5b0c2485f 100644 --- a/.github/workflows/codeql_windows_msys2.yml +++ b/.github/workflows/codeql_windows_msys2.yml @@ -1,4 +1,4 @@ -name: CodeQL Analasis (Windows, msys2) +name: CodeQL Analysis (Windows, msys2) on: From ecd67950d460d7d525763e6a1254e83e7a1b3b1a Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 16 Dec 2023 14:03:42 +0100 Subject: [PATCH 042/936] SCSI CD-ROM Toshiba fixes. Data track is not audio, fixes anything that wants to play data track as audio. --- src/cdrom/cdrom.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 40686f14a..c5755709d 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -614,8 +614,14 @@ cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit) break; } - /* Unlike standard commands, if there's a data track on an Audio CD (mixed mode) - the playback continues with the audio muted (Toshiba CD-ROM SCSI-2 manual reference). */ + /* Do this at this point, since it's at this point that we know the + actual LBA position to start playing from. */ + if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) { + cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos); + cdrom_stop(dev); + return 0; + } + dev->cd_buflen = 0; dev->cd_status = playbit ? CD_STATUS_PLAYING : CD_STATUS_PAUSED; return 1; @@ -641,6 +647,14 @@ cdrom_audio_track_search_pioneer(cdrom_t *dev, uint32_t pos, uint8_t playbit) dev->seek_pos = pos; + /* Do this at this point, since it's at this point that we know the + actual LBA position to start playing from. */ + if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) { + cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos); + cdrom_stop(dev); + return 0; + } + dev->cd_buflen = 0; dev->cd_status = playbit ? CD_STATUS_PLAYING : CD_STATUS_PAUSED; return 1; @@ -705,8 +719,14 @@ cdrom_audio_play_toshiba(cdrom_t *dev, uint32_t pos, int type) cdrom_log("Toshiba/NEC Play Audio: MSF = %06x, type = %02x, cdstatus = %02x\n", pos, type, dev->cd_status); - /* Unlike standard commands, if there's a data track on an Audio CD (mixed mode) - the playback continues with the audio muted (Toshiba CD-ROM SCSI-2 manual reference). */ + /* Do this at this point, since it's at this point that we know the + actual LBA position to start playing from. */ + if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) { + cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos); + cdrom_stop(dev); + return 0; + } + dev->cd_buflen = 0; dev->cd_status = CD_STATUS_PLAYING; return 1; From e4696aa2e96f9a05fb87bd79646c35a914c74bbb Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 16 Dec 2023 20:17:55 +0100 Subject: [PATCH 043/936] Undev branch the Matrox Millennium since it is now mostly usable. --- src/include/86box/video.h | 2 +- src/video/CMakeLists.txt | 7 +- src/video/vid_mga.c | 228 ++++++++++++++++++++++++++------------ src/video/vid_table.c | 4 +- 4 files changed, 160 insertions(+), 81 deletions(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 1858fc246..0d435fd36 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -431,9 +431,9 @@ extern const device_t ht216_32_standalone_device; extern const device_t im1024_device; extern const device_t pgc_device; -# if defined(DEV_BRANCH) && defined(USE_MGA) /* Matrox MGA */ extern const device_t millennium_device; +# if defined(DEV_BRANCH) extern const device_t mystique_device; extern const device_t mystique_220_device; # endif diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index 59205f235..638837757 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -25,14 +25,9 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c vid_et4000w32.c vid_stg_ramdac.c vid_ht216.c vid_oak_oti.c vid_paradise.c vid_rtg310x.c vid_f82c425.c vid_ti_cf62011.c vid_tvga.c vid_tgui9440.c vid_tkd8001_ramdac.c vid_att20c49x_ramdac.c vid_s3.c vid_s3_virge.c - vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_nga.c + vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_mga.c vid_nga.c vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c) -if(MGA) - target_compile_definitions(vid PRIVATE USE_MGA) - target_sources(vid PRIVATE vid_mga.c) -endif() - if(VGAWONDER) target_compile_definitions(vid PRIVATE USE_VGAWONDER) endif() diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 74bb9d07a..86b3c3a92 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -856,23 +856,23 @@ mystique_recalctimings(svga_t *svga) svga->clock = (cpuclock * (float) (1ULL << 32)) / svga->getclock(clk_sel & 3, svga->clock_gen); if (mystique->crtcext_regs[1] & CRTCX_R1_HTOTAL8) - svga->htotal += 0x100; + svga->htotal |= 0x100; if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL10) - svga->vtotal += 0x400; + svga->vtotal |= 0x400; if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL11) - svga->vtotal += 0x800; + svga->vtotal |= 0x800; if (mystique->crtcext_regs[2] & CRTCX_R2_VDISPEND10) - svga->dispend += 0x400; + svga->dispend |= 0x400; if (mystique->crtcext_regs[2] & CRTCX_R2_VBLKSTR10) - svga->vblankstart += 0x400; + svga->vblankstart |= 0x400; if (mystique->crtcext_regs[2] & CRTCX_R2_VBLKSTR11) - svga->vblankstart += 0x800; + svga->vblankstart |= 0x800; if (mystique->crtcext_regs[2] & CRTCX_R2_VSYNCSTR10) - svga->vsyncstart += 0x400; + svga->vsyncstart |= 0x400; if (mystique->crtcext_regs[2] & CRTCX_R2_VSYNCSTR11) - svga->vsyncstart += 0x800; + svga->vsyncstart |= 0x800; if (mystique->crtcext_regs[2] & CRTCX_R2_LINECOMP10) - svga->split += 0x400; + svga->split |= 0x400; if (mystique->type == MGA_2064W) tvp3026_recalctimings(svga->ramdac, svga); @@ -935,7 +935,7 @@ mystique_recalctimings(svga_t *svga) } else { switch (svga->bpp) { case 8: - svga->render = svga_render_8bpp_highres; + svga->render = svga_render_8bpp_incompatible_highres; break; case 15: svga->render = svga_render_15bpp_highres; @@ -949,9 +949,6 @@ mystique_recalctimings(svga_t *svga) case 32: svga->render = svga_render_32bpp_highres; break; - - default: - break; } } svga->line_compare = mystique_line_compare; @@ -1381,7 +1378,7 @@ mystique_ctrl_read_b(uint32_t addr, void *priv) svga_t *svga = &mystique->svga; uint8_t ret = 0xff; int fifocount; - uint16_t addr_0x0f = 0; + uint8_t addr_0x0f = 0; uint16_t addr_0x03 = 0; int rs2 = 0; int rs3 = 0; @@ -1944,7 +1941,7 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) { mystique_t *mystique = (mystique_t *) priv; svga_t *svga = &mystique->svga; - uint16_t addr_0x0f = 0; + uint8_t addr_0x0f = 0; uint16_t addr_0x03 = 0; int rs2 = 0; int rs3 = 0; @@ -3944,7 +3941,7 @@ z_check(uint16_t z, uint16_t old_z, uint32_t z_mode) // mystique->dwgreg.dwgctrl } static void -blit_line(mystique_t *mystique, UNUSED(int closed)) +blit_line(mystique_t *mystique, int closed) { svga_t *svga = &mystique->svga; uint32_t src; @@ -3952,48 +3949,104 @@ blit_line(mystique_t *mystique, UNUSED(int closed)) uint32_t old_dst; int x; int z_write; + int pattern; + int funcnt = mystique->dwgreg.funcnt; switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { case DWGCTRL_ATYPE_RSTR: case DWGCTRL_ATYPE_RPL: x = mystique->dwgreg.xdst; - while (mystique->dwgreg.length > 0) { + while (mystique->dwgreg.length >= 0) { + pattern = mystique->dwgreg.src[0] & (1 << funcnt); + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { case MACCESS_PWIDTH_8: - src = mystique->dwgreg.fcol; + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_SOLID) + src = mystique->dwgreg.fcol; + else { + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { + if (pattern) + src = mystique->dwgreg.fcol; + } else + src = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + } dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + if (closed) { + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + } else if (!closed && mystique->dwgreg.length > 0) { + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + } break; case MACCESS_PWIDTH_16: - src = mystique->dwgreg.fcol; + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_SOLID) + src = mystique->dwgreg.fcol; + else { + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { + if (pattern) + src = mystique->dwgreg.fcol; + } else + src = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + } dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + if (closed) { + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + } else if (!closed && mystique->dwgreg.length > 0) { + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + } break; case MACCESS_PWIDTH_24: - src = mystique->dwgreg.fcol; + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_SOLID) + src = mystique->dwgreg.fcol; + else { + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { + if (pattern) + src = mystique->dwgreg.fcol; + } else + src = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + } old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); - *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); - svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + if (closed) { + *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + } else if (!closed && mystique->dwgreg.length > 0) { + *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + } break; case MACCESS_PWIDTH_32: - src = mystique->dwgreg.fcol; + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_SOLID) + src = mystique->dwgreg.fcol; + else { + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { + if (pattern) + src = mystique->dwgreg.fcol; + } else + src = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + } dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + if (closed) { + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + } else if (!closed && mystique->dwgreg.length > 0) { + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + } break; default: @@ -4016,6 +4069,9 @@ blit_line(mystique_t *mystique, UNUSED(int closed)) mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; mystique->dwgreg.length--; + funcnt = (funcnt - 1) & mystique->dwgreg.stylelen; + if (mystique->dwgreg.length == 0xffff) + break; } break; @@ -4186,25 +4242,25 @@ blit_trap(mystique_t *mystique) fatal("TRAP BLK/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); } } - x_l++; + if (x_l > x_r) + x_l--; + else + x_l++; + mystique->pixel_count++; } - if ((int32_t) mystique->dwgreg.ar[1] < 0) { - while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; - mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - } - } else - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; - if ((int32_t) mystique->dwgreg.ar[4] < 0) { - while ((int32_t) mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; - mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); - } - } else - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + while ((int32_t) mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); + } + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; mystique->dwgreg.ydst++; mystique->dwgreg.ydst &= 0x7fffff; @@ -4266,25 +4322,25 @@ blit_trap(mystique_t *mystique) fatal("TRAP RSTR PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); } } - x_l++; + if (x_l > x_r) + x_l--; + else + x_l++; + mystique->pixel_count++; } - if ((int32_t) mystique->dwgreg.ar[1] < 0) { - while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; - mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - } - } else - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; - if ((int32_t) mystique->dwgreg.ar[4] < 0) { - while ((int32_t) mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; - mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); - } - } else - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + while ((int32_t) mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); + } + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; mystique->dwgreg.ydst++; mystique->dwgreg.ydst &= 0x7fffff; @@ -4367,7 +4423,11 @@ blit_trap(mystique_t *mystique) mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; - x_l++; + if (x_l > x_r) + x_l--; + else + x_l++; + mystique->pixel_count++; } @@ -4403,7 +4463,10 @@ blit_trap(mystique_t *mystique) break; default: - fatal("Unknown atype %03x %08x TRAP\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); +#if 0 + pclog("Unknown atype %03x %08x TRAP\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); +#endif + break; } mystique->blitter_complete_refcount++; @@ -4615,7 +4678,11 @@ blit_texture_trap(mystique_t *mystique) } } skip_pixel: - x_l++; + if (x_l > x_r) + x_l--; + else + x_l++; + mystique->pixel_count++; mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; @@ -4747,9 +4814,14 @@ blit_bitblt(mystique_t *mystique) } else src_addr += x_dir; - if (x != x_end) - x += x_dir; - else + if (x != x_end) { + if ((x > x_end) && (x_dir == 1)) + x--; + else if ((x < x_end) && (x_dir == -1)) + x++; + else + x += x_dir; + } else break; } @@ -4854,9 +4926,14 @@ blit_bitblt(mystique_t *mystique) } else src_addr += x_dir; - if (x != x_end) - x += x_dir; - else + if (x != x_end) { + if ((x > x_end) && (x_dir == 1)) + x--; + else if ((x < x_end) && (x_dir == -1)) + x++; + else + x += x_dir; + } else break; } @@ -4937,9 +5014,14 @@ blit_bitblt(mystique_t *mystique) } else src_addr += x_dir; - if (x != x_end) - x += x_dir; - else + if (x != x_end) { + if ((x > x_end) && (x_dir == 1)) + x--; + else if ((x < x_end) && (x_dir == -1)) + x++; + else + x += x_dir; + } else break; } @@ -5024,7 +5106,9 @@ blit_idump(mystique_t *mystique) mystique->dwgreg.iload_rem_data = 0; mystique->dwgreg.idump_end_of_line = 0; mystique->busy = 1; - /* pclog("IDUMP ATYPE RPL busy\n"); */ +#if 0 + pclog("IDUMP ATYPE RPL busy\n"); +#endif break; default: diff --git a/src/video/vid_table.c b/src/video/vid_table.c index b4198eefd..04d48c9d9 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -204,8 +204,8 @@ video_cards[] = { { &s3_virge_357_pci_device }, { &s3_diamond_stealth_4000_pci_device }, { &s3_trio3d2x_pci_device }, -#if defined(DEV_BRANCH) && defined(USE_MGA) - { &millennium_device, VIDEO_FLAG_TYPE_SPECIAL }, + { &millennium_device }, +#if defined(DEV_BRANCH) { &mystique_device }, { &mystique_220_device }, #endif From 1df37c2440e2675efd4454f4e72b88f051bdafa4 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 16 Dec 2023 20:21:57 +0100 Subject: [PATCH 044/936] Temporarily added the older 8bpp highres render for the Matrox Millennium. --- src/include/86box/vid_svga_render.h | 1 + src/video/vid_svga_render.c | 83 +++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/src/include/86box/vid_svga_render.h b/src/include/86box/vid_svga_render.h index bc6894ca9..33bb13bbf 100644 --- a/src/include/86box/vid_svga_render.h +++ b/src/include/86box/vid_svga_render.h @@ -53,6 +53,7 @@ extern void svga_render_4bpp_lowres(svga_t *svga); extern void svga_render_4bpp_highres(svga_t *svga); extern void svga_render_8bpp_lowres(svga_t *svga); extern void svga_render_8bpp_highres(svga_t *svga); +extern void svga_render_8bpp_incompatible_highres(svga_t *svga); extern void svga_render_8bpp_tseng_lowres(svga_t *svga); extern void svga_render_8bpp_tseng_highres(svga_t *svga); extern void svga_render_8bpp_gs_lowres(svga_t *svga); diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 7cc0aafc3..f7bc36130 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -665,6 +665,89 @@ void svga_render_4bpp_highres(svga_t *svga) { svga_render_indexed_gfx(svga, true void svga_render_8bpp_lowres(svga_t *svga) { svga_render_indexed_gfx(svga, false, true); } void svga_render_8bpp_highres(svga_t *svga) { svga_render_indexed_gfx(svga, true, true); } +void +svga_render_8bpp_incompatible_highres(svga_t *svga) +{ + int x; + uint32_t *p; + uint32_t dat; + uint32_t changed_addr; + uint32_t addr; + + if ((svga->displine + svga->y_add) < 0) + return; + + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 8) { + dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); + p[0] = svga->map8[dat & 0xff]; + p[1] = svga->map8[(dat >> 8) & 0xff]; + p[2] = svga->map8[(dat >> 16) & 0xff]; + p[3] = svga->map8[(dat >> 24) & 0xff]; + + dat = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + p[4] = svga->map8[dat & 0xff]; + p[5] = svga->map8[(dat >> 8) & 0xff]; + p[6] = svga->map8[(dat >> 16) & 0xff]; + p[7] = svga->map8[(dat >> 24) & 0xff]; + + svga->ma += 8; + p += 8; + } + svga->ma &= svga->vram_display_mask; + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 8) { + dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); + p[0] = svga->map8[dat & 0xff]; + p[1] = svga->map8[(dat >> 8) & 0xff]; + p[2] = svga->map8[(dat >> 16) & 0xff]; + p[3] = svga->map8[(dat >> 24) & 0xff]; + + dat = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + p[4] = svga->map8[dat & 0xff]; + p[5] = svga->map8[(dat >> 8) & 0xff]; + p[6] = svga->map8[(dat >> 16) & 0xff]; + p[7] = svga->map8[(dat >> 24) & 0xff]; + + svga->ma += 8; + p += 8; + } + } else { + for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 4) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); + p[0] = svga->map8[dat & 0xff]; + p[1] = svga->map8[(dat >> 8) & 0xff]; + p[2] = svga->map8[(dat >> 16) & 0xff]; + p[3] = svga->map8[(dat >> 24) & 0xff]; + + svga->ma += 4; + p += 4; + } + } + svga->ma &= svga->vram_display_mask; + } + } +} + // TODO: Integrate more of this into the generic paletted renderer --GM #if 0 void From 7d9b10d5568b0f4202f3731bbf94f7efa7c2d76f Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 16 Dec 2023 14:35:52 -0500 Subject: [PATCH 045/936] Correct undevbranching of the Matrox Millenium --- src/include/86box/video.h | 2 +- src/video/CMakeLists.txt | 4 ++++ src/video/vid_table.c | 2 +- src/win/Makefile.mingw | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 0d435fd36..396b39124 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -433,7 +433,7 @@ extern const device_t pgc_device; /* Matrox MGA */ extern const device_t millennium_device; -# if defined(DEV_BRANCH) +# if defined(DEV_BRANCH) && defined(USE_MGA) extern const device_t mystique_device; extern const device_t mystique_220_device; # endif diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index 638837757..6635252a6 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -28,6 +28,10 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_mga.c vid_nga.c vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c) +if(MGA) + target_compile_definitions(vid PRIVATE USE_MGA) +endif() + if(VGAWONDER) target_compile_definitions(vid PRIVATE USE_VGAWONDER) endif() diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 04d48c9d9..6317fb5a3 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -205,7 +205,7 @@ video_cards[] = { { &s3_diamond_stealth_4000_pci_device }, { &s3_trio3d2x_pci_device }, { &millennium_device }, -#if defined(DEV_BRANCH) +#if defined(DEV_BRANCH) && defined(USE_MGA) { &mystique_device }, { &mystique_220_device }, #endif diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 022a639f2..13dbdcefe 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -498,7 +498,6 @@ ifeq ($(DEV_BRANCH), y) ifeq ($(MGA), y) OPTS += -DUSE_MGA - DEVBROBJ += vid_mga.o endif ifeq ($(OPEN_AT), y) @@ -765,6 +764,7 @@ VIDOBJ := agpgart.o video.o \ vid_s3.o vid_s3_virge.o \ vid_ibm_rgb528_ramdac.o vid_sdac_ramdac.o \ vid_ogc.o \ + vid_mga.o \ vid_nga.o \ vid_tvp3026_ramdac.o \ vid_xga.o From d3fbd93848ed717c5116284534740a166aae243c Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 16 Dec 2023 20:36:34 +0100 Subject: [PATCH 046/936] Fixed warning in vid_mga.c. --- src/video/vid_mga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 86b3c3a92..30d6b453a 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -3944,7 +3944,7 @@ static void blit_line(mystique_t *mystique, int closed) { svga_t *svga = &mystique->svga; - uint32_t src; + uint32_t src = 0; uint32_t dst; uint32_t old_dst; int x; From 48513fe6aa85d27f6a21770997328806a246bcf0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 16 Dec 2023 20:45:03 +0100 Subject: [PATCH 047/936] Fixed two warnings in codegen_new/codegen_backend_x86-64.c. --- src/codegen_new/codegen_backend_x86-64.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/codegen_new/codegen_backend_x86-64.c b/src/codegen_new/codegen_backend_x86-64.c index 67355539b..3cbca28f8 100644 --- a/src/codegen_new/codegen_backend_x86-64.c +++ b/src/codegen_new/codegen_backend_x86-64.c @@ -73,7 +73,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) { uint8_t *branch_offset; - uint8_t *misaligned_offset; + uint8_t *misaligned_offset = NULL; /*In - ESI = address Out - ECX = data, ESI = abrt*/ @@ -161,7 +161,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) { uint8_t *branch_offset; - uint8_t *misaligned_offset; + uint8_t *misaligned_offset = NULL; /*In - ECX = data, ESI = address Out - ESI = abrt From 0848f4a38e049e512db2eaee16ff184850cda3c2 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Sun, 17 Dec 2023 08:46:12 +1300 Subject: [PATCH 048/936] Disable blink in 8bpp modes on MGA; Re-instate main 8bpp hires renderer I don't actually know if 8bpp blink is a thing on a Matrox Millennium, but the video BIOS seems to act like it's not. --- src/include/86box/vid_svga.h | 5 +++++ src/video/vid_mga.c | 4 +++- src/video/vid_svga_render.c | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index f725996d8..cb914aca9 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -246,6 +246,11 @@ typedef struct svga_t { addresses are shifted to match*/ int packed_chain4; + /*Disable 8bpp blink mode - some cards support it, some don't, it's a weird mode + If mode 13h appears in a reddish-brown background (0x88) with dark green text (0x8F), + you should set this flag when entering that mode*/ + int disable_blink; + /*Force CRTC to dword mode, regardless of CR14/CR17. Required for S3 enhanced mode*/ int force_dword_mode; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 30d6b453a..320cd899a 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -935,7 +935,7 @@ mystique_recalctimings(svga_t *svga) } else { switch (svga->bpp) { case 8: - svga->render = svga_render_8bpp_incompatible_highres; + svga->render = svga_render_8bpp_highres; break; case 15: svga->render = svga_render_15bpp_highres; @@ -958,6 +958,8 @@ mystique_recalctimings(svga_t *svga) if (mystique->type >= MGA_1064SG) svga->bpp = 8; } + + svga->disable_blink = (svga->bpp > 4); } static void diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index f7bc36130..7a15dc1cf 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -457,7 +457,7 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) uint32_t changed_offset; const bool blinked = svga->blink & 0x10; - const bool attrblink = ((svga->attrregs[0x10] & 0x08) != 0); + const bool attrblink = (!svga->disable_blink) && ((svga->attrregs[0x10] & 0x08) != 0); /* The following is likely how it works on an IBM VGA - that is, it works with its BIOS. From e7f15d87e1b7838c5e2e29818cf40664a0133e7b Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 16 Dec 2023 20:47:11 +0100 Subject: [PATCH 049/936] And the warning in disk/zip.c. --- src/disk/zip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/disk/zip.c b/src/disk/zip.c index 7045b1e41..d4b644865 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -531,7 +531,7 @@ zip_load(zip_t *dev, char *fn) if (fseek(dev->drv->fp, dev->drv->base, SEEK_SET) == -1) fatal("zip_load(): Error seeking to the beginning of the file\n"); - strncpy(dev->drv->image_path, fn, sizeof(dev->drv->image_path) - 1); + strncpy(dev->drv->image_path, fn, strlen(dev->drv->image_path) + 1); return 1; } From c2a89f64b2298b9a2a533f84a2aabb0a676339d1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 16 Dec 2023 20:56:45 +0100 Subject: [PATCH 050/936] Fixed the warnings in sio/sio_it86x1f.c. --- src/sio/sio_it86x1f.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/sio/sio_it86x1f.c b/src/sio/sio_it86x1f.c index d53e78050..74e79bbed 100644 --- a/src/sio/sio_it86x1f.c +++ b/src/sio/sio_it86x1f.c @@ -14,9 +14,10 @@ * * Copyright 2023 RichardG. */ +#include #include -#include #include +#include #include #include #include @@ -805,10 +806,18 @@ it86x1f_init(UNUSED(const device_t *info)) break; } if (i >= (sizeof(it86x1f_models) / sizeof(it86x1f_models[0]))) { +#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) + fatal("IT86x1F: Unknown type %04" PRIX64 " selected\n", info->local); +#else fatal("IT86x1F: Unknown type %04X selected\n", info->local); +#endif return NULL; } +#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) + it86x1f_log("IT86x1F: init(%04" PRIX64 ")\n", info->local); +#else it86x1f_log("IT86x1F: init(%04X)\n", info->local); +#endif /* Let the resource data parser figure out the ROM size. */ dev->pnp_card = isapnp_add_card(it86x1f_models[i].pnp_rom, -1, it86x1f_models[i].pnp_config_changed, NULL, it86x1f_pnp_read_vendor_reg, it86x1f_pnp_write_vendor_reg, dev); From a76e3890b289f56200ee8c40f5eb5a08473113d6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 16 Dec 2023 20:57:58 +0100 Subject: [PATCH 051/936] And the one in sio/sio_um8669f.c. --- src/sio/sio_um8669f.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sio/sio_um8669f.c b/src/sio/sio_um8669f.c index 61e9abd97..136b1add6 100644 --- a/src/sio/sio_um8669f.c +++ b/src/sio/sio_um8669f.c @@ -222,7 +222,11 @@ um8669f_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *pri if (dev->ide < IDE_BUS_MAX) { config->io[1].base = config->io[0].base + 0x206; /* status port apparently fixed */ +#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) + ide_pnp_config_changed(0, config, (void *) (int64_t) dev->ide); +#else ide_pnp_config_changed(0, config, (void *) (int) dev->ide); +#endif } break; From 4b402c22cdb6634bbb5bb479253bc07ff216fbbd Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 16 Dec 2023 18:26:39 -0300 Subject: [PATCH 052/936] vid_mga: Implement DDC on the Millennium --- src/include/86box/vid_svga.h | 1 + src/video/vid_mga.c | 22 ++++++++++++++++++++ src/video/vid_tvp3026_ramdac.c | 37 ++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index cb914aca9..682a66111 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -398,6 +398,7 @@ extern uint8_t tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, sv extern void tvp3026_recalctimings(void *priv, svga_t *svga); extern void tvp3026_hwcursor_draw(svga_t *svga, int displine); extern float tvp3026_getclock(int clock, void *priv); +extern void tvp3026_gpio(uint8_t (*read)(uint8_t cntl, void *priv), void (*write)(uint8_t cntl, uint8_t data, void *priv), void *cb_priv, void *priv); # ifdef EMU_DEVICE_H extern const device_t ati68860_ramdac_device; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 320cd899a..2f701b33f 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5314,6 +5314,27 @@ mystique_hwcursor_draw(svga_t *svga, int displine) svga->hwcursor_latch.addr += 16; } +static uint8_t +mystique_tvp3026_gpio_read(uint8_t cntl, void *priv) +{ + mystique_t *mystique = (mystique_t *) priv; + + uint8_t ret = 0xff; + if (!i2c_gpio_get_scl(mystique->i2c_ddc)) + ret &= ~0x10; + if (!i2c_gpio_get_sda(mystique->i2c_ddc)) + ret &= ~0x04; + return ret; +} + +static void +mystique_tvp3026_gpio_write(uint8_t cntl, uint8_t data, void *priv) +{ + mystique_t *mystique = (mystique_t *) priv; + + i2c_gpio_set(mystique->i2c_ddc, !(cntl & 0x10) || (data & 0x10), !(cntl & 0x04) || (data & 0x04)); +} + static uint8_t mystique_pci_read(UNUSED(int func), int addr, void *priv) { @@ -5625,6 +5646,7 @@ mystique_init(const device_t *info) mystique->svga.ramdac = device_add(&tvp3026_ramdac_device); mystique->svga.clock_gen = mystique->svga.ramdac; mystique->svga.getclock = tvp3026_getclock; + tvp3026_gpio(mystique_tvp3026_gpio_read, mystique_tvp3026_gpio_write, mystique, mystique->svga.ramdac); } else { video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_mystique); svga_init(info, &mystique->svga, mystique, mystique->vram_size << 20, diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c index 15215c45d..611527a35 100644 --- a/src/video/vid_tvp3026_ramdac.c +++ b/src/video/vid_tvp3026_ramdac.c @@ -55,6 +55,11 @@ typedef struct tvp3026_ramdac_t { uint8_t n; uint8_t p; } pix, mem, loop; + uint8_t gpio_cntl; + uint8_t gpio_data; + uint8_t (*gpio_read)(uint8_t cntl, void *priv); + void (*gpio_write)(uint8_t cntl, uint8_t val, void *priv); + void *gpio_priv; } tvp3026_ramdac_t; static void @@ -211,6 +216,16 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svg ramdac->misc = val; svga->ramdac_type = (val & 0x08) ? RAMDAC_8BIT : RAMDAC_6BIT; break; + case 0x2a: /* General-Purpose I/O Control */ + ramdac->gpio_cntl = val; + if (ramdac->gpio_write) + ramdac->gpio_write(ramdac->gpio_cntl, ramdac->gpio_data, ramdac->gpio_priv); + break; + case 0x2b: /* General-Purpose I/O Data */ + ramdac->gpio_data = val; + if (ramdac->gpio_write) + ramdac->gpio_write(ramdac->gpio_cntl, ramdac->gpio_data, ramdac->gpio_priv); + break; case 0x2c: /* PLL Address */ ramdac->pll_addr = val; break; @@ -389,6 +404,16 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga) case 0x1e: /* Miscellaneous Control */ temp = ramdac->misc; break; + case 0x2a: /* General-Purpose I/O Control */ + temp = ramdac->gpio_cntl; + break; + case 0x2b: /* General-Purpose I/O Data */ + if (ramdac->gpio_read) { + temp = 0xe0 | (ramdac->gpio_cntl & 0x1f); /* keep upper bits untouched */ + ramdac->gpio_data = (ramdac->gpio_data & temp) | (ramdac->gpio_read(ramdac->gpio_cntl, ramdac->gpio_priv) & ~temp); + } + temp = ramdac->gpio_data; + break; case 0x2c: /* PLL Address */ temp = ramdac->pll_addr; break; @@ -630,6 +655,18 @@ tvp3026_getclock(int clock, void *priv) return f_pll; } +void +tvp3026_gpio(uint8_t (*read)(uint8_t cntl, void *priv), + void (*write)(uint8_t cntl, uint8_t val, void *priv), + void *cb_priv, void *priv) +{ + tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv; + + ramdac->gpio_read = read; + ramdac->gpio_write = write; + ramdac->gpio_priv = cb_priv; +} + void * tvp3026_ramdac_init(const device_t *info) { From aa0b4dfab7c34569aea26f8ab98520b16c9d4885 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 17 Dec 2023 12:43:07 +0100 Subject: [PATCH 053/936] ALi M1543(c) ACPI and SMBUS PCI BAR's now correctly return all 0x00's when locked, as documented by the M1543 datasheet, fixes the PCI error found by Dizzy on the ASUS P5A with Debian Lenny. --- src/chipset/ali1543.c | 107 +++++++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 47 deletions(-) diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index 4d8dea3ce..fb9fd70ce 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -984,7 +984,7 @@ static void ali7101_write(int func, int addr, uint8_t val, void *priv) { ali1543_t *dev = (ali1543_t *) priv; - ali1543_log("M7101: dev->pmu_conf[%02x] = %02x\n", addr, val); + ali1543_log("M7101: [W] dev->pmu_conf[%02x] = %02x\n", addr, val); if (func > 0) return; @@ -1408,65 +1408,78 @@ ali7101_read(int func, int addr, void *priv) uint8_t ret = 0xff; if (dev->pmu_dev_enable && (func == 0)) { - if ((dev->pmu_conf[0xc9] & 0x01) && (addr >= 0x40) && (addr != 0xc9)) - return 0xff; - - /* TODO: C4, C5 = GPIREG (masks: 0D, 0E) */ - switch (addr) { - default: - ret = dev->pmu_conf[addr]; - break; - case 0x42: - ret = (dev->pmu_conf[addr] & 0xf7) | (nvr_smi_status(dev->nvr) ? 0x08 : 0x00); - break; - case 0x43: - ret = acpi_ali_soft_smi_status_read(dev->acpi) ? 0x10 : 0x00; - break; - case 0x7f: - ret = 0x80; - break; - case 0xbc: - ret = inb(0x70); - break; - } - - if (dev->pmu_conf[0x77] & 0x10) { + if (!(dev->pmu_conf[0xc9] & 0x01) || (addr < 0x40) || (addr == 0xc9)) { + /* TODO: C4, C5 = GPIREG (masks: 0D, 0E) */ switch (addr) { + default: + ret = dev->pmu_conf[addr]; + break; + case 0x10 ... 0x13: + if (dev->pmu_conf[0x5b] & 0x02) + ret = 0x00; + else + ret = dev->pmu_conf[addr]; + break; + case 0x14 ... 0x17: + if (dev->pmu_conf[0x5b] & 0x04) + ret = 0x00; + else + ret = dev->pmu_conf[addr]; + break; case 0x42: - dev->pmu_conf[addr] &= 0xe0; + ret = (dev->pmu_conf[addr] & 0xf7) | (nvr_smi_status(dev->nvr) ? 0x08 : 0x00); break; case 0x43: - dev->pmu_conf[addr] &= 0xef; - acpi_ali_soft_smi_status_write(dev->acpi, 0); + ret = acpi_ali_soft_smi_status_read(dev->acpi) ? 0x10 : 0x00; break; + case 0x7f: + ret = 0x80; + break; + case 0xbc: + ret = inb(0x70); + break; + } - case 0x48: - dev->pmu_conf[addr] = 0x00; - break; - case 0x49: - dev->pmu_conf[addr] &= 0x60; - break; - case 0x4a: - dev->pmu_conf[addr] &= 0xc7; - break; + if (dev->pmu_conf[0x77] & 0x10) { + switch (addr) { + case 0x42: + dev->pmu_conf[addr] &= 0xe0; + break; + case 0x43: + dev->pmu_conf[addr] &= 0xef; + acpi_ali_soft_smi_status_write(dev->acpi, 0); + break; - case 0x4e: - dev->pmu_conf[addr] &= 0xfa; - break; - case 0x4f: - dev->pmu_conf[addr] &= 0xfe; - break; + case 0x48: + dev->pmu_conf[addr] = 0x00; + break; + case 0x49: + dev->pmu_conf[addr] &= 0x60; + break; + case 0x4a: + dev->pmu_conf[addr] &= 0xc7; + break; - case 0x74: - dev->pmu_conf[addr] &= 0xcc; - break; + case 0x4e: + dev->pmu_conf[addr] &= 0xfa; + break; + case 0x4f: + dev->pmu_conf[addr] &= 0xfe; + break; - default: - break; + case 0x74: + dev->pmu_conf[addr] &= 0xcc; + break; + + default: + break; + } } } } + ali1543_log("M7101: [R] dev->pmu_conf[%02x] = %02x\n", addr, ret); + return ret; } From 4c87164692f39af790c1a864eea82fb2d487c691 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sun, 17 Dec 2023 12:49:10 -0500 Subject: [PATCH 054/936] Fix remaining warnings in windows and linux builds --- src/config.c | 32 ++++++++++++++++---------------- src/include/86box/86box.h | 2 +- src/network/net_rtl8139.c | 2 +- src/unix/unix.c | 2 +- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/config.c b/src/config.c index b1ed7094f..8c4ad0de4 100644 --- a/src/config.c +++ b/src/config.c @@ -1104,13 +1104,13 @@ load_floppy_and_cdrom_drives(void) p = ini_section_get_string(cat, temp, NULL); if (p) { if (path_abs(p)) { - if (strlen(p) > 255) - fatal("load_floppy_and_cdrom_drives(): strlen(p) > 255 " + if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) + fatal("load_floppy_and_cdrom_drives(): strlen(p) > 2047 " "(fdd_image_history[%i][%i])\n", c, i); else - snprintf(fdd_image_history[c][i], 255, "%s", p); + snprintf(fdd_image_history[c][i], (MAX_IMAGE_PATH_LEN - 1), "%s", p); } else - snprintf(fdd_image_history[c][i], 255, "%s%s%s", usr_path, + snprintf(fdd_image_history[c][i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path, path_get_slash(usr_path), p); path_normalize(fdd_image_history[c][i]); } @@ -1220,13 +1220,13 @@ load_floppy_and_cdrom_drives(void) p = ini_section_get_string(cat, temp, NULL); if (p) { if (path_abs(p)) { - if (strlen(p) > 511) - fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 " + if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) + fatal("load_floppy_and_cdrom_drives(): strlen(p) > 2047 " "(cdrom[%i].image_history[%i])\n", c, i); else - snprintf(cdrom[c].image_history[i], 511, "%s", p); + snprintf(cdrom[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s", p); } else - snprintf(cdrom[c].image_history[i], 511, "%s%s%s", usr_path, + snprintf(cdrom[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path, path_get_slash(usr_path), p); path_normalize(cdrom[c].image_history[i]); } @@ -1353,13 +1353,13 @@ load_other_removable_devices(void) p = ini_section_get_string(cat, temp, NULL); if (p) { if (path_abs(p)) { - if (strlen(p) > 511) - fatal("load_other_removable_devices(): strlen(p) > 511 " + if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) + fatal("load_other_removable_devices(): strlen(p) > 2047 " "(zip_drives[%i].image_history[%i])\n", c, i); else - snprintf(zip_drives[c].image_history[i], 511, "%s", p); + snprintf(zip_drives[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s", p); } else - snprintf(zip_drives[c].image_history[i], 511, "%s%s%s", usr_path, + snprintf(zip_drives[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path, path_get_slash(usr_path), p); path_normalize(zip_drives[c].image_history[i]); } @@ -1469,13 +1469,13 @@ load_other_removable_devices(void) p = ini_section_get_string(cat, temp, NULL); if (p) { if (path_abs(p)) { - if (strlen(p) > 511) - fatal("load_other_removable_devices(): strlen(p) > 511 " + if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) + fatal("load_other_removable_devices(): strlen(p) > 2047 " "(mo_drives[%i].image_history[%i])\n", c, i); else - snprintf(mo_drives[c].image_history[i], 511, "%s", p); + snprintf(mo_drives[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s", p); } else - snprintf(mo_drives[c].image_history[i], 511, "%s%s%s", usr_path, + snprintf(mo_drives[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path, path_get_slash(usr_path), p); path_normalize(mo_drives[c].image_history[i]); } diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index ae2ea260c..c16cd5efb 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -33,7 +33,7 @@ /* Recently used images */ #define MAX_PREV_IMAGES 4 -#define MAX_IMAGE_PATH_LEN 256 +#define MAX_IMAGE_PATH_LEN 2048 /* Default language 0xFFFF = from system, 0x409 = en-US */ #define DEFAULT_LANGUAGE 0x0409 diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index d1e14fb12..6c86bdebf 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -3312,7 +3312,7 @@ nic_init(const device_t *info) fp = nvr_fopen(eeprom_filename, "rb"); if (fp) { - fread(s->eeprom.contents, 2, 64, fp); + (void) !fread(s->eeprom.contents, 2, 64, fp); fclose(fp); fp = NULL; } else { diff --git a/src/unix/unix.c b/src/unix/unix.c index ecd17cadb..bac84ead4 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -918,7 +918,7 @@ monitor_thread(void *param) line = f_readline("(86Box) "); else { printf("(86Box) "); - !getline(&line, &n, stdin); + (void) !getline(&line, &n, stdin); } if (line) { int cmdargc = 0; From c62182cd2e43f461952a74c60ead03022dae65db Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 18 Dec 2023 00:08:51 +0100 Subject: [PATCH 055/936] MGA Fixes: 1. LFB access is now done properly through the right svga_read/write linear calls. 2. Lowres 8bpp mode and Packed/Extended 8bpp+ mode don't mix together, fixes Debian Woody matroxfb module when testing the modes while keeping other compatibility intact (basically enable packed stuff only when gdcreg5 bits 5-6 are 0 when extended mode is set). 3. Small cleanup in the line accel stuff. --- src/video/vid_mga.c | 95 ++++++++++++++------------------------------- 1 file changed, 29 insertions(+), 66 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 2f701b33f..cadf64bb8 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -720,15 +720,10 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) if (mystique->crtcext_idx == 1) svga->dpms = !!(val & 0x30); if (mystique->crtcext_idx < 4) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - if (mystique->crtcext_idx == 3) { - if (val & CRTCX_R3_MGAMODE) - svga->fb_only = 1; - else - svga->fb_only = 0; - svga_recalctimings(svga); + if (mystique->crtcext_idx != 3) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } } if (mystique->crtcext_idx == 4) { if (svga->gdcreg[6] & 0xc) { @@ -880,7 +875,6 @@ mystique_recalctimings(svga_t *svga) svga->interlace = !!(mystique->crtcext_regs[0] & 0x80); if (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) { - svga->packed_chain4 = 1; svga->lowres = 0; svga->char_width = 8; svga->hdisp = (svga->crtc[1] + 1) * 8; @@ -891,6 +885,7 @@ mystique_recalctimings(svga_t *svga) svga->rowoffset <<= 1; svga->ma_latch <<= 1; } + if (mystique->type >= MGA_1064SG) { /*Mystique, unlike most SVGA cards, allows display start to take effect mid-screen*/ @@ -903,7 +898,6 @@ mystique_recalctimings(svga_t *svga) } svga->rowoffset <<= 1; - switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { case XMULCTRL_DEPTH_8: case XMULCTRL_DEPTH_2G8V16: @@ -952,6 +946,7 @@ mystique_recalctimings(svga_t *svga) } } svga->line_compare = mystique_line_compare; + svga->packed_chain4 = ((svga->gdcreg[5] & 0x60) == 0x00); } else { svga->packed_chain4 = 0; svga->line_compare = NULL; @@ -959,7 +954,11 @@ mystique_recalctimings(svga_t *svga) svga->bpp = 8; } + svga->fb_only = svga->packed_chain4; svga->disable_blink = (svga->bpp > 4); +#if 0 + pclog("PackedChain4=%d, chain4=%x, fast=%x, bit6 attrreg10=%02x, bits 5-6 gdcreg5=%02x.\n", svga->packed_chain4, svga->chain4, svga->fast, svga->attrregs[0x10] & 0x40, svga->gdcreg[5] & 0x60); +#endif } static void @@ -2563,6 +2562,7 @@ mystique_accel_iload_write_l(UNUSED(uint32_t addr), uint32_t val, void *priv) } } +#if 0 static uint8_t mystique_readb_linear(uint32_t addr, void *priv) { @@ -2616,7 +2616,7 @@ mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; svga->vram[addr] = val; } @@ -2631,7 +2631,7 @@ mystique_writew_linear(uint32_t addr, uint16_t val, void *priv) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; *(uint16_t *) &svga->vram[addr] = val; } @@ -2646,9 +2646,10 @@ mystique_writel_linear(uint32_t addr, uint32_t val, void *priv) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; *(uint32_t *) &svga->vram[addr] = val; } +#endif static void run_dma(mystique_t *mystique) @@ -3950,102 +3951,67 @@ blit_line(mystique_t *mystique, int closed) uint32_t dst; uint32_t old_dst; int x; + int len = 0; int z_write; - int pattern; - int funcnt = mystique->dwgreg.funcnt; switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { case DWGCTRL_ATYPE_RSTR: case DWGCTRL_ATYPE_RPL: x = mystique->dwgreg.xdst; - while (mystique->dwgreg.length >= 0) { - pattern = mystique->dwgreg.src[0] & (1 << funcnt); - + while (len <= mystique->dwgreg.length) { if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { case MACCESS_PWIDTH_8: - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_SOLID) - src = mystique->dwgreg.fcol; - else { - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { - if (pattern) - src = mystique->dwgreg.fcol; - } else - src = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - } + src = mystique->dwgreg.fcol; dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); if (closed) { svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; - } else if (!closed && mystique->dwgreg.length > 0) { + } else if (!closed && (len < mystique->dwgreg.length)) { svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; } break; case MACCESS_PWIDTH_16: - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_SOLID) - src = mystique->dwgreg.fcol; - else { - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { - if (pattern) - src = mystique->dwgreg.fcol; - } else - src = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - } + src = mystique->dwgreg.fcol; dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); if (closed) { ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; - } else if (!closed && mystique->dwgreg.length > 0) { + } else if (!closed && (len < mystique->dwgreg.length)) { ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; } break; case MACCESS_PWIDTH_24: - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_SOLID) - src = mystique->dwgreg.fcol; - else { - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { - if (pattern) - src = mystique->dwgreg.fcol; - } else - src = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - } + src = mystique->dwgreg.fcol; old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); if (closed) { *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; - } else if (!closed && mystique->dwgreg.length > 0) { + } else if (!closed && (len < mystique->dwgreg.length)) { *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; } break; case MACCESS_PWIDTH_32: - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_SOLID) - src = mystique->dwgreg.fcol; - else { - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { - if (pattern) - src = mystique->dwgreg.fcol; - } else - src = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - } + src = mystique->dwgreg.fcol; dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); if (closed) { ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; - } else if (!closed && mystique->dwgreg.length > 0) { + } else if (!closed && (len < mystique->dwgreg.length)) { ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; } @@ -4070,10 +4036,7 @@ blit_line(mystique_t *mystique, int closed) } else mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; - mystique->dwgreg.length--; - funcnt = (funcnt - 1) & mystique->dwgreg.stylelen; - if (mystique->dwgreg.length == 0xffff) - break; + len++; } break; @@ -5666,9 +5629,9 @@ mystique_init(const device_t *info) mem_mapping_disable(&mystique->ctrl_mapping); mem_mapping_add(&mystique->lfb_mapping, 0, 0, - mystique_readb_linear, mystique_readw_linear, mystique_readl_linear, - mystique_writeb_linear, mystique_writew_linear, mystique_writel_linear, - NULL, 0, mystique); + svga_read_linear, svga_readw_linear, svga_readl_linear, + svga_write_linear, svga_writew_linear, svga_writel_linear, + NULL, 0, &mystique->svga); mem_mapping_disable(&mystique->lfb_mapping); mem_mapping_add(&mystique->iload_mapping, 0, 0, From 8e74ee27267d877a1229db48ee392f6fb1299fb1 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sun, 17 Dec 2023 15:34:18 -0500 Subject: [PATCH 056/936] Fix most of the warnings in the macos builds --- src/chipset/ali1543.c | 2 -- src/qt/qt_renderercommon.cpp | 2 +- src/unix/unix.c | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index fb9fd70ce..fe3a0fda3 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -489,12 +489,10 @@ static void ali5229_ide_irq_handler(ali1543_t *dev) { int ctl = 0; - int ch = 0; int bit = 0; if (dev->ide_conf[0x52] & 0x10) { ctl ^= 1; - ch ^= 1; bit ^= 5; } diff --git a/src/qt/qt_renderercommon.cpp b/src/qt/qt_renderercommon.cpp index 983f14d26..05c35e09b 100644 --- a/src/qt/qt_renderercommon.cpp +++ b/src/qt/qt_renderercommon.cpp @@ -88,7 +88,7 @@ RendererCommon::onResize(int width, int height) if (video_fullscreen_scale == FULLSCR_SCALE_INT43) { gh = gw / r43; - gw = gw; +// gw = gw; gsr = r43; } diff --git a/src/unix/unix.c b/src/unix/unix.c index bac84ead4..cf69997b0 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -830,7 +830,7 @@ plat_init_rom_paths(void) rom_add_path("/usr/share/86Box/roms/"); } #else - char default_rom_path[1024] = { '\0 ' }; + char default_rom_path[1024] = { '\0' }; getDefaultROMPath(default_rom_path); rom_add_path(default_rom_path); #endif From c1ba150e3c5335a5bc3b2ba86ed96c980daff34f Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 18 Dec 2023 00:40:31 +0100 Subject: [PATCH 057/936] Oops, they actually can mix together, but not with plain (non-packed) chain4 stuff enabled, should fix more mode issues in the MGA Millennium card. --- src/video/vid_mga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index cadf64bb8..69d8de0f8 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -946,7 +946,7 @@ mystique_recalctimings(svga_t *svga) } } svga->line_compare = mystique_line_compare; - svga->packed_chain4 = ((svga->gdcreg[5] & 0x60) == 0x00); + svga->packed_chain4 = !svga->chain4; } else { svga->packed_chain4 = 0; svga->line_compare = NULL; From 9573d373643ae7e0532f41a974c5f62544f55fd3 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 18 Dec 2023 00:41:51 +0100 Subject: [PATCH 058/936] And warning fixes. --- src/video/vid_mga.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 69d8de0f8..c505b5cc2 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -634,12 +634,14 @@ static void wake_fifo_thread(mystique_t *mystique); static void wait_fifo_idle(mystique_t *mystique); static void mystique_queue(mystique_t *mystique, uint32_t addr, uint32_t val, uint32_t type); +#if 0 static uint8_t mystique_readb_linear(uint32_t addr, void *priv); static uint16_t mystique_readw_linear(uint32_t addr, void *priv); static uint32_t mystique_readl_linear(uint32_t addr, void *priv); static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv); static void mystique_writew_linear(uint32_t addr, uint16_t val, void *priv); static void mystique_writel_linear(uint32_t addr, uint32_t val, void *priv); +#endif static void mystique_recalc_mapping(mystique_t *mystique); static int mystique_line_compare(svga_t *svga); From 80e5c4f5ac0931bf5f5e7878921103488ab44343 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 18 Dec 2023 10:02:18 +0100 Subject: [PATCH 059/936] Temporarily reverted all the Matrox mode changes since they broke even standard SVGA modes. --- src/video/vid_mga.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index c505b5cc2..7b1db7cc8 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -634,14 +634,12 @@ static void wake_fifo_thread(mystique_t *mystique); static void wait_fifo_idle(mystique_t *mystique); static void mystique_queue(mystique_t *mystique, uint32_t addr, uint32_t val, uint32_t type); -#if 0 static uint8_t mystique_readb_linear(uint32_t addr, void *priv); static uint16_t mystique_readw_linear(uint32_t addr, void *priv); static uint32_t mystique_readl_linear(uint32_t addr, void *priv); static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv); static void mystique_writew_linear(uint32_t addr, uint16_t val, void *priv); static void mystique_writel_linear(uint32_t addr, uint32_t val, void *priv); -#endif static void mystique_recalc_mapping(mystique_t *mystique); static int mystique_line_compare(svga_t *svga); @@ -722,10 +720,15 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) if (mystique->crtcext_idx == 1) svga->dpms = !!(val & 0x30); if (mystique->crtcext_idx < 4) { - if (mystique->crtcext_idx != 3) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + if (mystique->crtcext_idx == 3) { + if (val & CRTCX_R3_MGAMODE) + svga->fb_only = 1; + else + svga->fb_only = 0; + svga_recalctimings(svga); } if (mystique->crtcext_idx == 4) { if (svga->gdcreg[6] & 0xc) { @@ -877,6 +880,7 @@ mystique_recalctimings(svga_t *svga) svga->interlace = !!(mystique->crtcext_regs[0] & 0x80); if (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) { + svga->packed_chain4 = 1; svga->lowres = 0; svga->char_width = 8; svga->hdisp = (svga->crtc[1] + 1) * 8; @@ -887,7 +891,6 @@ mystique_recalctimings(svga_t *svga) svga->rowoffset <<= 1; svga->ma_latch <<= 1; } - if (mystique->type >= MGA_1064SG) { /*Mystique, unlike most SVGA cards, allows display start to take effect mid-screen*/ @@ -900,6 +903,7 @@ mystique_recalctimings(svga_t *svga) } svga->rowoffset <<= 1; + switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { case XMULCTRL_DEPTH_8: case XMULCTRL_DEPTH_2G8V16: @@ -948,7 +952,6 @@ mystique_recalctimings(svga_t *svga) } } svga->line_compare = mystique_line_compare; - svga->packed_chain4 = !svga->chain4; } else { svga->packed_chain4 = 0; svga->line_compare = NULL; @@ -956,11 +959,7 @@ mystique_recalctimings(svga_t *svga) svga->bpp = 8; } - svga->fb_only = svga->packed_chain4; svga->disable_blink = (svga->bpp > 4); -#if 0 - pclog("PackedChain4=%d, chain4=%x, fast=%x, bit6 attrreg10=%02x, bits 5-6 gdcreg5=%02x.\n", svga->packed_chain4, svga->chain4, svga->fast, svga->attrregs[0x10] & 0x40, svga->gdcreg[5] & 0x60); -#endif } static void @@ -2564,7 +2563,6 @@ mystique_accel_iload_write_l(UNUSED(uint32_t addr), uint32_t val, void *priv) } } -#if 0 static uint8_t mystique_readb_linear(uint32_t addr, void *priv) { @@ -2618,7 +2616,7 @@ mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; + svga->changedvram[addr >> 12] = changeframecount; svga->vram[addr] = val; } @@ -2633,7 +2631,7 @@ mystique_writew_linear(uint32_t addr, uint16_t val, void *priv) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; + svga->changedvram[addr >> 12] = changeframecount; *(uint16_t *) &svga->vram[addr] = val; } @@ -2648,10 +2646,9 @@ mystique_writel_linear(uint32_t addr, uint32_t val, void *priv) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; + svga->changedvram[addr >> 12] = changeframecount; *(uint32_t *) &svga->vram[addr] = val; } -#endif static void run_dma(mystique_t *mystique) @@ -5631,9 +5628,9 @@ mystique_init(const device_t *info) mem_mapping_disable(&mystique->ctrl_mapping); mem_mapping_add(&mystique->lfb_mapping, 0, 0, - svga_read_linear, svga_readw_linear, svga_readl_linear, - svga_write_linear, svga_writew_linear, svga_writel_linear, - NULL, 0, &mystique->svga); + mystique_readb_linear, mystique_readw_linear, mystique_readl_linear, + mystique_writeb_linear, mystique_writew_linear, mystique_writel_linear, + NULL, 0, mystique); mem_mapping_disable(&mystique->lfb_mapping); mem_mapping_add(&mystique->iload_mapping, 0, 0, @@ -5804,6 +5801,7 @@ const device_t millennium_device = { .config = mystique_config }; +#if defined(DEV_BRANCH) && defined(USE_MGA) const device_t mystique_device = { .name = "Matrox Mystique", .internal_name = "mystique", @@ -5831,3 +5829,4 @@ const device_t mystique_220_device = { .force_redraw = mystique_force_redraw, .config = mystique_config }; +#endif From f5642ab1c3f10e40004f0945c3cffa37e413455c Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 18 Dec 2023 13:42:32 +0100 Subject: [PATCH 060/936] MGA fixes 2: 1. Reverted the packed chain4 and fb_only sides to 1 when extended mode is set, but with the call to svga_recalctimings removed from port 0x3df due to mode issues, this should fix all the MGA mode issues I know. 2. Cleaned up the rendering order in svga_recalctimings, especially 4bpp and 8bpp. --- src/video/vid_mga.c | 12 +++--------- src/video/vid_svga.c | 32 +++++++++----------------------- 2 files changed, 12 insertions(+), 32 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index c505b5cc2..9289c83ce 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -721,12 +721,6 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) mystique->crtcext_regs[mystique->crtcext_idx] = val; if (mystique->crtcext_idx == 1) svga->dpms = !!(val & 0x30); - if (mystique->crtcext_idx < 4) { - if (mystique->crtcext_idx != 3) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } if (mystique->crtcext_idx == 4) { if (svga->gdcreg[6] & 0xc) { /*64k banks*/ @@ -947,8 +941,8 @@ mystique_recalctimings(svga_t *svga) break; } } + svga->packed_chain4 = 1; svga->line_compare = mystique_line_compare; - svga->packed_chain4 = !svga->chain4; } else { svga->packed_chain4 = 0; svga->line_compare = NULL; @@ -958,8 +952,8 @@ mystique_recalctimings(svga_t *svga) svga->fb_only = svga->packed_chain4; svga->disable_blink = (svga->bpp > 4); -#if 0 - pclog("PackedChain4=%d, chain4=%x, fast=%x, bit6 attrreg10=%02x, bits 5-6 gdcreg5=%02x.\n", svga->packed_chain4, svga->chain4, svga->fast, svga->attrregs[0x10] & 0x40, svga->gdcreg[5] & 0x60); +#if 1 + pclog("PackedChain4=%d, chain4=%x, fast=%x, bit6 attrreg10=%02x, bits 5-6 gdcreg5=%02x, extmode=%02x.\n", svga->packed_chain4, svga->chain4, svga->fast, svga->attrregs[0x10] & 0x40, svga->gdcreg[5] & 0x60, mystique->pci_regs[0x41] & 1, mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE); #endif } diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 5f5efcd9e..1479ea718 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -639,27 +639,21 @@ svga_recalctimings(svga_t *svga) svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; svga->hdisp_old = svga->hdisp; - if (svga->bpp <= 8) { - if (svga->attrregs[0x10] & 0x40) { /*8bpp mode*/ - svga->map8 = svga->pallook; - if (svga->lowres) /*Low res (320)*/ - svga->render = svga_render_8bpp_lowres; - else - svga->render = svga_render_8bpp_highres; - } else { + if ((svga->bpp <= 8) || ((svga->gdcreg[5] & 0x60) == 0x00)) { + if ((svga->gdcreg[5] & 0x60) == 0x00) { if (svga->seqregs[1] & 8) /*Low res (320)*/ svga->render = svga_render_4bpp_lowres; else svga->render = svga_render_4bpp_highres; + } else { + svga->map8 = svga->pallook; + if (svga->attrregs[0x10] & 0x40) /*Low res (320)*/ + svga->render = svga_render_8bpp_lowres; + else + svga->render = svga_render_8bpp_highres; } } else { switch (svga->gdcreg[5] & 0x60) { - case 0x00: - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_4bpp_lowres; - else - svga->render = svga_render_4bpp_highres; - break; case 0x20: /*4 colours*/ if (svga->seqregs[1] & 8) /*Low res (320)*/ svga->render = svga_render_2bpp_lowres; @@ -669,13 +663,6 @@ svga_recalctimings(svga_t *svga) case 0x40: case 0x60: /*256+ colours*/ switch (svga->bpp) { - case 8: - svga->map8 = svga->pallook; - if (svga->lowres) - svga->render = svga_render_8bpp_lowres; - else - svga->render = svga_render_8bpp_highres; - break; case 15: if (svga->lowres) svga->render = svga_render_15bpp_lowres; @@ -1920,9 +1907,8 @@ svga_readl_common(uint32_t addr, uint8_t linear, void *priv) { svga_t *svga = (svga_t *) priv; - if (!svga->fast) { + if (!svga->fast) return svga_read_common(addr, linear, priv) | (svga_read_common(addr + 1, linear, priv) << 8) | (svga_read_common(addr + 2, linear, priv) << 16) | (svga_read_common(addr + 3, linear, priv) << 24); - } cycles -= svga->monitor->mon_video_timing_read_l; From 718fb759af92681644f354f68dccf9c5fe88e695 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 18 Dec 2023 13:47:23 +0100 Subject: [PATCH 061/936] There, log excess disabled. --- src/video/vid_mga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 9289c83ce..b2212d268 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -952,7 +952,7 @@ mystique_recalctimings(svga_t *svga) svga->fb_only = svga->packed_chain4; svga->disable_blink = (svga->bpp > 4); -#if 1 +#if 0 pclog("PackedChain4=%d, chain4=%x, fast=%x, bit6 attrreg10=%02x, bits 5-6 gdcreg5=%02x, extmode=%02x.\n", svga->packed_chain4, svga->chain4, svga->fast, svga->attrregs[0x10] & 0x40, svga->gdcreg[5] & 0x60, mystique->pci_regs[0x41] & 1, mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE); #endif } From c7f4e59e49d4233d7cf5c938540efb70db9b4810 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 18 Dec 2023 13:57:33 +0100 Subject: [PATCH 062/936] Restoring the old changes. --- src/video/vid_mga.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 7b1db7cc8..a1486cb27 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -634,12 +634,14 @@ static void wake_fifo_thread(mystique_t *mystique); static void wait_fifo_idle(mystique_t *mystique); static void mystique_queue(mystique_t *mystique, uint32_t addr, uint32_t val, uint32_t type); +#if 0 static uint8_t mystique_readb_linear(uint32_t addr, void *priv); static uint16_t mystique_readw_linear(uint32_t addr, void *priv); static uint32_t mystique_readl_linear(uint32_t addr, void *priv); static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv); static void mystique_writew_linear(uint32_t addr, uint16_t val, void *priv); static void mystique_writel_linear(uint32_t addr, uint32_t val, void *priv); +#endif static void mystique_recalc_mapping(mystique_t *mystique); static int mystique_line_compare(svga_t *svga); @@ -720,15 +722,10 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) if (mystique->crtcext_idx == 1) svga->dpms = !!(val & 0x30); if (mystique->crtcext_idx < 4) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - if (mystique->crtcext_idx == 3) { - if (val & CRTCX_R3_MGAMODE) - svga->fb_only = 1; - else - svga->fb_only = 0; - svga_recalctimings(svga); + if (mystique->crtcext_idx != 3) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } } if (mystique->crtcext_idx == 4) { if (svga->gdcreg[6] & 0xc) { @@ -880,7 +877,6 @@ mystique_recalctimings(svga_t *svga) svga->interlace = !!(mystique->crtcext_regs[0] & 0x80); if (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) { - svga->packed_chain4 = 1; svga->lowres = 0; svga->char_width = 8; svga->hdisp = (svga->crtc[1] + 1) * 8; @@ -891,6 +887,7 @@ mystique_recalctimings(svga_t *svga) svga->rowoffset <<= 1; svga->ma_latch <<= 1; } + if (mystique->type >= MGA_1064SG) { /*Mystique, unlike most SVGA cards, allows display start to take effect mid-screen*/ @@ -903,7 +900,6 @@ mystique_recalctimings(svga_t *svga) } svga->rowoffset <<= 1; - switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { case XMULCTRL_DEPTH_8: case XMULCTRL_DEPTH_2G8V16: @@ -952,6 +948,7 @@ mystique_recalctimings(svga_t *svga) } } svga->line_compare = mystique_line_compare; + svga->packed_chain4 = !svga->chain4; } else { svga->packed_chain4 = 0; svga->line_compare = NULL; @@ -959,7 +956,11 @@ mystique_recalctimings(svga_t *svga) svga->bpp = 8; } + svga->fb_only = svga->packed_chain4; svga->disable_blink = (svga->bpp > 4); +#if 0 + pclog("PackedChain4=%d, chain4=%x, fast=%x, bit6 attrreg10=%02x, bits 5-6 gdcreg5=%02x.\n", svga->packed_chain4, svga->chain4, svga->fast, svga->attrregs[0x10] & 0x40, svga->gdcreg[5] & 0x60); +#endif } static void @@ -2563,6 +2564,7 @@ mystique_accel_iload_write_l(UNUSED(uint32_t addr), uint32_t val, void *priv) } } +#if 0 static uint8_t mystique_readb_linear(uint32_t addr, void *priv) { @@ -2616,7 +2618,7 @@ mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; svga->vram[addr] = val; } @@ -2631,7 +2633,7 @@ mystique_writew_linear(uint32_t addr, uint16_t val, void *priv) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; *(uint16_t *) &svga->vram[addr] = val; } @@ -2646,9 +2648,10 @@ mystique_writel_linear(uint32_t addr, uint32_t val, void *priv) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; *(uint32_t *) &svga->vram[addr] = val; } +#endif static void run_dma(mystique_t *mystique) @@ -5628,9 +5631,9 @@ mystique_init(const device_t *info) mem_mapping_disable(&mystique->ctrl_mapping); mem_mapping_add(&mystique->lfb_mapping, 0, 0, - mystique_readb_linear, mystique_readw_linear, mystique_readl_linear, - mystique_writeb_linear, mystique_writew_linear, mystique_writel_linear, - NULL, 0, mystique); + svga_read_linear, svga_readw_linear, svga_readl_linear, + svga_write_linear, svga_writew_linear, svga_writel_linear, + NULL, 0, &mystique->svga); mem_mapping_disable(&mystique->lfb_mapping); mem_mapping_add(&mystique->iload_mapping, 0, 0, From 552740b2bd64d0bae1ce929017a2bedf5f6fc4b2 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 18 Dec 2023 14:01:38 +0100 Subject: [PATCH 063/936] S3 wraparound fix. Just a quick fix for Commander Keen 4 EGA's flickering. --- src/video/vid_s3.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index f35f729da..35e65cc18 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -2576,17 +2576,11 @@ s3_out(uint16_t addr, uint8_t val, void *priv) case 0x3C7: case 0x3C8: case 0x3C9: - if ((svga->crtc[0x55] & 0x03) == 0x00) - rs2 = !!(svga->crtc[0x43] & 0x02); - 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)) { - if (!(svga->crtc[0x45] & 0x20) || (s3->chip == S3_86C928)) - rs3 = !!(svga->crtc[0x55] & 0x02); - else - rs3 = 0; + 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_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) ibm_rgb528_ramdac_out(addr, rs2, val, svga->ramdac, svga); @@ -2633,10 +2627,7 @@ s3_out(uint16_t addr, uint8_t val, void *priv) svga->force_dword_mode = !!(val & 0x08); break; case 0x32: - if ((svga->crtc[0x31] & 0x30) && (svga->crtc[0x51] & 0x01) && (val & 0x40)) - svga->vram_display_mask = 0x3ffff; - else - svga->vram_display_mask = s3->vram_mask; + svga->vram_display_mask = (val & 0x40) ? 0x3ffff : s3->vram_mask; break; case 0x40: From 313bf84b04d8a53731aa8e4ac3b13f96d214e0a1 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 18 Dec 2023 15:42:24 -0300 Subject: [PATCH 064/936] i2c_eeprom: Random cleanups --- src/mem/i2c_eeprom.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/mem/i2c_eeprom.c b/src/mem/i2c_eeprom.c index 7d83bbe88..8e4a6cc14 100644 --- a/src/mem/i2c_eeprom.c +++ b/src/mem/i2c_eeprom.c @@ -60,7 +60,7 @@ i2c_eeprom_start(UNUSED(void *bus), uint8_t addr, uint8_t read, void *priv) { i2c_eeprom_t *dev = (i2c_eeprom_t *) priv; - i2c_eeprom_log("I2C EEPROM %s %02X: start()\n", i2c_getbusname(dev->i2c), dev->addr); + i2c_eeprom_log("I2C EEPROM %s %02X: start(%c)\n", i2c_getbusname(dev->i2c), dev->addr, read ? 'R' : 'W'); if (!read) { dev->addr_pos = 0; @@ -77,8 +77,7 @@ i2c_eeprom_read(UNUSED(void *bus), UNUSED(uint8_t addr), void *priv) uint8_t ret = dev->data[dev->addr_register]; i2c_eeprom_log("I2C EEPROM %s %02X: read(%06X) = %02X\n", i2c_getbusname(dev->i2c), dev->addr, dev->addr_register, ret); - dev->addr_register++; - dev->addr_register &= dev->addr_mask; /* roll-over */ + dev->addr_register = (dev->addr_register + 1) & dev->addr_mask; /* roll-over */ return ret; } @@ -100,8 +99,7 @@ i2c_eeprom_write(UNUSED(void *bus), uint8_t addr, uint8_t data, void *priv) i2c_eeprom_log("I2C EEPROM %s %02X: write(%06X, %02X) = %d\n", i2c_getbusname(dev->i2c), dev->addr, dev->addr_register, data, !!dev->writable); if (dev->writable) dev->data[dev->addr_register] = data; - dev->addr_register++; - dev->addr_register &= dev->addr_mask; /* roll-over */ + dev->addr_register = (dev->addr_register + 1) & dev->addr_mask; /* roll-over */ return dev->writable; } @@ -137,7 +135,8 @@ i2c_eeprom_init(void *i2c, uint8_t addr, uint8_t *data, uint32_t size, uint8_t w uint32_t pow_size = 1 << log2i(size); if (pow_size < size) size = pow_size << 1; - size &= 0x7fffff; /* address space limit of 8 MB = 7 bits from I2C address + 16 bits */ + if (size >= 8388608) + size = 8388608; /* address space limit of 8 MB = 7 bits from I2C address + 16 bits from command address */ i2c_eeprom_log("I2C EEPROM %s %02X: init(%d, %d)\n", i2c_getbusname(i2c), addr, size, writable); @@ -149,7 +148,8 @@ i2c_eeprom_init(void *i2c, uint8_t addr, uint8_t *data, uint32_t size, uint8_t w dev->addr_len = (size >= 4096) ? 16 : 8; /* use 16-bit addresses on 24C32 and above */ dev->addr_mask = size - 1; - i2c_sethandler(dev->i2c, dev->addr & ~(dev->addr_mask >> dev->addr_len), (dev->addr_mask >> dev->addr_len) + 1, i2c_eeprom_start, i2c_eeprom_read, i2c_eeprom_write, i2c_eeprom_stop, dev); + uint8_t i2c_mask = dev->addr_mask >> dev->addr_len; + i2c_sethandler(dev->i2c, dev->addr & ~i2c_mask, i2c_mask + 1, i2c_eeprom_start, i2c_eeprom_read, i2c_eeprom_write, i2c_eeprom_stop, dev); return dev; } @@ -161,7 +161,8 @@ i2c_eeprom_close(void *dev_handle) i2c_eeprom_log("I2C EEPROM %s %02X: close()\n", i2c_getbusname(dev->i2c), dev->addr); - i2c_removehandler(dev->i2c, dev->addr & ~(dev->addr_mask >> dev->addr_len), (dev->addr_mask >> dev->addr_len) + 1, i2c_eeprom_start, i2c_eeprom_read, i2c_eeprom_write, i2c_eeprom_stop, dev); + uint8_t i2c_mask = dev->addr_mask >> dev->addr_len; + i2c_removehandler(dev->i2c, dev->addr & ~i2c_mask, i2c_mask + 1, i2c_eeprom_start, i2c_eeprom_read, i2c_eeprom_write, i2c_eeprom_stop, dev); free(dev); } From 12d5d6c26085d8380b35a7b14c06dfea85845d48 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 19 Dec 2023 02:18:08 +0600 Subject: [PATCH 065/936] Matrox Mystique: Bus-mastering fixes * Make all bus-mastering-related variables atomic * Do not, under any circumstances, attempt to read beyond PRIMEND and SECEND This allows NT 4.0's Mystique drivers to work with busmastering enabled. --- src/video/vid_mga.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index d066adb73..0cf35bdd9 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -55,7 +55,7 @@ #define FIFO_ADDR 0x00ffffff #define DMA_POLL_TIME_US 100 /*100us*/ -#define DMA_MAX_WORDS 256 /*256 quad words per 100us poll*/ +#define DMA_MAX_WORDS (20 * 14) /*280 quad words per 100us poll*/ /*These registers are also mirrored into 0x1dxx, with the mirrored versions starting the blitter*/ @@ -505,10 +505,10 @@ typedef struct mystique_t { struct { - int pri_pos, sec_pos, iload_pos, + atomic_int pri_pos, sec_pos, iload_pos, pri_state, sec_state, iload_state, state; - uint32_t primaddress, primend, secaddress, secend, + atomic_uint primaddress, primend, secaddress, secend, pri_header, sec_header, iload_header; @@ -2660,21 +2660,23 @@ run_dma(mystique_t *mystique) } while (words_transferred < DMA_MAX_WORDS && mystique->dma.state != DMA_STATE_IDLE) { - switch (mystique->dma.state) { + switch (atomic_load(&mystique->dma.state)) { case DMA_STATE_PRI: switch (mystique->dma.primaddress & DMA_MODE_MASK) { case DMA_MODE_REG: if (mystique->dma.pri_state == 0) { dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.pri_header, 4, 4); mystique->dma.primaddress += 4; + words_transferred++; } - if ((mystique->dma.pri_header & 0xff) != 0x15) { + if ((mystique->dma.pri_header & 0xff) != 0x15 || (mystique->dma.primaddress & DMA_ADDR_MASK) < (mystique->dma.primend & DMA_ADDR_MASK)) { uint32_t val; uint32_t reg_addr; dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4); mystique->dma.primaddress += 4; + words_transferred++; reg_addr = (mystique->dma.pri_header & 0x7f) << 2; if (mystique->dma.pri_header & 0x80) @@ -2691,10 +2693,9 @@ run_dma(mystique_t *mystique) mystique->dma.pri_header >>= 8; mystique->dma.pri_state = (mystique->dma.pri_state + 1) & 3; - words_transferred++; if (mystique->dma.state == DMA_STATE_SEC) mystique->dma.pri_state = 0; - else if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { + else if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; } @@ -2711,6 +2712,7 @@ run_dma(mystique_t *mystique) if (mystique->dma.sec_state == 0) { dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.sec_header, 4, 4); mystique->dma.secaddress += 4; + words_transferred++; } uint32_t val; @@ -2734,8 +2736,8 @@ run_dma(mystique_t *mystique) mystique->dma.sec_state = (mystique->dma.sec_state + 1) & 3; words_transferred++; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { - if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; } else @@ -2754,8 +2756,8 @@ run_dma(mystique_t *mystique) blit_iload_write(mystique, val, 32); words_transferred++; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { - if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; } else From 111b6238110466a9b35ae9ff6c0670b06eb1da78 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 19 Dec 2023 03:00:54 +0600 Subject: [PATCH 066/936] Fix logical error --- src/video/vid_mga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 0cf35bdd9..2c9561b02 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -2670,7 +2670,7 @@ run_dma(mystique_t *mystique) words_transferred++; } - if ((mystique->dma.pri_header & 0xff) != 0x15 || (mystique->dma.primaddress & DMA_ADDR_MASK) < (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.pri_header & 0xff) != 0x15 && (mystique->dma.primaddress & DMA_ADDR_MASK) < (mystique->dma.primend & DMA_ADDR_MASK)) { uint32_t val; uint32_t reg_addr; From 46c5f9c0ccb053656dee94bf28b95f5b2e0ec8ed Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 18 Dec 2023 22:33:15 +0100 Subject: [PATCH 067/936] Added a missing sanity check to device/isapnp.c, fixes crash with ISA PnP sound cards on the PB520R. --- src/device/isapnp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/isapnp.c b/src/device/isapnp.c index 7b9d570bb..f9d10b380 100644 --- a/src/device/isapnp.c +++ b/src/device/isapnp.c @@ -124,7 +124,7 @@ static void isapnp_device_config_changed(isapnp_card_t *card, isapnp_device_t *ld) { /* Ignore card if it hasn't signed up for configuration changes. */ - if (!card->config_changed) + if ((card == NULL) || !card->config_changed) return; /* Populate config structure, performing endianness conversion as needed. */ From ff446fab9b6c2144417d73d058a08ed20fa77914 Mon Sep 17 00:00:00 2001 From: Alexander Babikov <2708460+lemondrops@users.noreply.github.com> Date: Mon, 18 Dec 2023 09:20:37 +0500 Subject: [PATCH 068/936] prt_escp.c: Fall back to roman.ttf instead of dotmatrix.ttf for unhandled typefaces --- src/printer/prt_escp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index 707590134..cd0279078 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -531,7 +531,7 @@ update_font(escp_t *dev) fn = FONT_FILE_OCRB; break; default: - fn = FONT_FILE_DOTMATRIX; + fn = FONT_FILE_ROMAN; } /* Create a full pathname for the ROM file. */ From bf1f4252672eb2607cd00da65b45c03a377c3193 Mon Sep 17 00:00:00 2001 From: Alexander Babikov <2708460+lemondrops@users.noreply.github.com> Date: Mon, 18 Dec 2023 09:20:48 +0500 Subject: [PATCH 069/936] prt_escp.c: Try to use courier.ttf if dotmatrix.ttf is missing --- src/printer/prt_escp.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index cd0279078..c11479786 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -545,6 +545,17 @@ update_font(escp_t *dev) if (FT_New_Face(ft_lib, path, 0, &dev->fontface)) { escp_log("ESC/P: unable to load font '%s'\n", path); dev->fontface = NULL; + + /* Try to fall back to Courier in case the dot matrix font is absent. */ + if (!strcmp(fn, FONT_FILE_DOTMATRIX)) { + strcpy(path, dev->fontpath); + path_slash(path); + strcat(path, FONT_FILE_COURIER); + if (FT_New_Face(ft_lib, path, 0, &dev->fontface)) { + escp_log("ESC/P: unable to load font '%s'\n", path); + dev->fontface = NULL; + } + } } if (!dev->multipoint_mode) { From 6eb05e14d5f0842e66838580a69337ed43970e3c Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 18 Dec 2023 23:43:37 +0100 Subject: [PATCH 070/936] ATI EGA Wonder 800+ and 18800 refactoring: 1. Proper cleanup of the code. 2. Migrate the card in question to the VGA class list as it's actually a rebadged VGA Edge (thus 18800). 3. Some VGA only features are not supported on this card and are documented in the recalctimings. --- src/include/86box/vid_ega.h | 3 - src/include/86box/video.h | 1 + src/video/vid_ati18800.c | 176 ++++++++++++++++++++++++++++-------- src/video/vid_ega.c | 105 +-------------------- src/video/vid_table.c | 2 +- 5 files changed, 142 insertions(+), 145 deletions(-) diff --git a/src/include/86box/vid_ega.h b/src/include/86box/vid_ega.h index 180803c8a..ec13de928 100644 --- a/src/include/86box/vid_ega.h +++ b/src/include/86box/vid_ega.h @@ -132,8 +132,6 @@ typedef struct ega_t { double dot_clock; - void * eeprom; - uint32_t (*remap_func)(struct ega_t *ega, uint32_t in_addr); void (*render)(struct ega_t *svga); } ega_t; @@ -143,7 +141,6 @@ typedef struct ega_t { extern const device_t ega_device; extern const device_t cpqega_device; extern const device_t sega_device; -extern const device_t atiega_device; extern const device_t iskra_ega_device; extern const device_t et2000_device; #endif diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 396b39124..de27fcbb1 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -322,6 +322,7 @@ extern const device_t ati18800_wonder_device; # endif extern const device_t ati18800_vga88_device; extern const device_t ati18800_device; +extern const device_t ati18800_egawonder800plus_device; /* ATi 28800 */ extern const device_t ati28800_device; diff --git a/src/video/vid_ati18800.c b/src/video/vid_ati18800.c index 5847faa39..fd658eacf 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -35,17 +35,20 @@ #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) # define BIOS_ROM_PATH_WONDER "roms/video/ati18800/VGA_Wonder_V3-1.02.bin" #endif -#define BIOS_ROM_PATH_VGA88 "roms/video/ati18800/vga88.bin" -#define BIOS_ROM_PATH_EDGE16 "roms/video/ati18800/vgaedge16.vbi" +#define BIOS_ROM_PATH_VGA88 "roms/video/ati18800/vga88.bin" +#define BIOS_ROM_PATH_EDGE16 "roms/video/ati18800/vgaedge16.vbi" +#define BIOS_ROM_PATH_ATIEGAPLUS "roms/video/ati18800/ATI EGA Wonder 800+ N1.00.BIN" enum { #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) ATI18800_WONDER = 0, ATI18800_VGA88, - ATI18800_EDGE16 + ATI18800_EDGE16, + ATI18800_EGAWONDER800PLUS #else ATI18800_VGA88 = 0, - ATI18800_EDGE16 + ATI18800_EDGE16, + ATI18800_EGAWONDER800PLUS #endif }; @@ -57,6 +60,8 @@ typedef struct ati18800_t { uint8_t regs[256]; int index; + int type; + uint32_t memory; } ati18800_t; static video_timings_t timing_ati18800 = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; @@ -76,19 +81,20 @@ ati18800_out(uint16_t addr, uint8_t val, void *priv) ati18800->index = val; break; case 0x1cf: + old = ati18800->regs[ati18800->index]; ati18800->regs[ati18800->index] = val; switch (ati18800->index) { case 0xb0: - svga_recalctimings(svga); + if ((old ^ val) & 6) + svga_recalctimings(svga); break; case 0xb2: case 0xbe: - if (ati18800->regs[0xbe] & 8) /*Read/write bank mode*/ - { - svga->read_bank = ((ati18800->regs[0xb2] >> 5) & 7) * 0x10000; - svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000; + if (ati18800->regs[0xbe] & 8) { /*Read/write bank mode*/ + svga->read_bank = ((ati18800->regs[0xb2] & 0xe0) >> 5) * 0x10000; + svga->write_bank = ((ati18800->regs[0xb2] & 0x0e) >> 1) * 0x10000; } else /*Single bank mode*/ - svga->read_bank = svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000; + svga->read_bank = svga->write_bank = ((ati18800->regs[0xb2] & 0x0e) >> 1) * 0x10000; break; case 0xb3: ati_eeprom_write(&ati18800->eeprom, val & 8, val & 2, val & 1); @@ -172,21 +178,91 @@ static void ati18800_recalctimings(svga_t *svga) { const ati18800_t *ati18800 = (ati18800_t *) svga->priv; + int clock_sel; - if (svga->crtc[0x17] & 4) { - svga->vtotal <<= 1; - svga->dispend <<= 1; - svga->vsyncstart <<= 1; - svga->split <<= 1; - svga->vblankstart <<= 1; + clock_sel = ((svga->miscout >> 2) & 3) | ((ati18800->regs[0xbe] & 0x10) >> 1) | ((ati18800->regs[0xb9] & 2) << 1); + + if (ati18800->type == ATI18800_EGAWONDER800PLUS) { + svga->crtc[5] &= ~0x60; /*Not supported by the EGA Wonder 800+*/ + svga->crtc[0x0b] &= ~0x60; /*Not supported by the EGA Wonder 800+*/ + + svga->hdisp_time = svga->hdisp; + + svga->hdisp = svga->crtc[1]; + svga->hdisp++; + + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]); + + svga->hdisp_time = svga->hdisp; + svga->render = svga_render_blank; + + if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ + if (svga->seqregs[1] & 8) { /*40 column*/ + svga->render = svga_render_text_40; + svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; + /* Character clock is off by 1 now in 40-line modes, on all cards. */ + svga->ma_latch--; + svga->hdisp += (svga->seqregs[1] & 1) ? 16 : 18; + } else { + svga->render = svga_render_text_80; + svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; + } + svga->hdisp_old = svga->hdisp; + } else { + svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; + svga->hdisp_old = svga->hdisp; + } + } } - if (!svga->scrblank && ((ati18800->regs[0xb0] & 0x02) || (ati18800->regs[0xb0] & 0x04))) /*Extended 256 colour modes*/ - { - svga->render = svga_render_8bpp_highres; - svga->bpp = 8; + if (ati18800->regs[0xb6] & 0x10) { + svga->hdisp <<= 1; + svga->htotal <<= 1; svga->rowoffset <<= 1; - svga->ma <<= 1; + svga->gdcreg[5] &= ~0x40; + } + + if (ati18800->regs[0xb0] & 6) + svga->gdcreg[5] |= 0x40; + + if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen); + switch (svga->gdcreg[5] & 0x60) { + case 0x00: + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_4bpp_lowres; + else + svga->render = svga_render_4bpp_highres; + break; + case 0x20: /*4 colours*/ + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; + else + svga->render = svga_render_2bpp_highres; + break; + case 0x40: + case 0x60: /*256+ colours*/ + switch (svga->bpp) { + default: + case 8: + svga->map8 = svga->pallook; + if (svga->lowres) + svga->render = svga_render_8bpp_lowres; + else { + svga->render = svga_render_8bpp_highres; + svga->ma_latch <<= 1; + svga->rowoffset <<= 1; + } + break; + } + break; + + default: + break; + } + } } } @@ -198,6 +274,8 @@ ati18800_init(const device_t *info) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ati18800); + ati18800->type = info->local; + switch (info->local) { default: #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) @@ -207,32 +285,36 @@ ati18800_init(const device_t *info) #endif case ATI18800_VGA88: rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_VGA88, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + ati18800->memory = 256; break; case ATI18800_EDGE16: rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_EDGE16, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + ati18800->memory = 512; + break; + case ATI18800_EGAWONDER800PLUS: + rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_ATIEGAPLUS, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + ati18800->memory = 256; break; } - if (info->local == ATI18800_EDGE16) { - svga_init(info, &ati18800->svga, ati18800, 1 << 18, /*256kb*/ - ati18800_recalctimings, - ati18800_in, ati18800_out, - NULL, - NULL); - } else { - svga_init(info, &ati18800->svga, ati18800, 1 << 19, /*512kb*/ - ati18800_recalctimings, - ati18800_in, ati18800_out, - NULL, - NULL); - } + svga_init(info, &ati18800->svga, ati18800, ati18800->memory << 10, + ati18800_recalctimings, + ati18800_in, ati18800_out, + NULL, + NULL); + ati18800->svga.clock_gen = device_add(&ati18810_device); + ati18800->svga.getclock = ics2494_getclock; io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); io_sethandler(0x03c0, 0x0020, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); ati18800->svga.miscout = 1; + ati18800->svga.bpp = 8; - ati_eeprom_load(&ati18800->eeprom, "ati18800.nvr", 0); + if (info->local == ATI18800_EGAWONDER800PLUS) + ati_eeprom_load(&ati18800->eeprom, "egawonder800.nvr", 0); + else + ati_eeprom_load(&ati18800->eeprom, "ati18800.nvr", 0); return ati18800; } @@ -257,6 +339,12 @@ ati18800_available(void) return rom_present(BIOS_ROM_PATH_EDGE16); } +static int +ati18800_egawonder800plus_available(void) +{ + return rom_present(BIOS_ROM_PATH_ATIEGAPLUS); +} + static void ati18800_close(void *priv) { @@ -300,7 +388,7 @@ const device_t ati18800_wonder_device = { #endif const device_t ati18800_vga88_device = { - .name = "ATI-18800-1", + .name = "ATI 18800-1", .internal_name = "ati18800v", .flags = DEVICE_ISA, .local = ATI18800_VGA88, @@ -314,7 +402,7 @@ const device_t ati18800_vga88_device = { }; const device_t ati18800_device = { - .name = "ATI-18800-5", + .name = "ATI VGA Edge 16", .internal_name = "ati18800", .flags = DEVICE_ISA, .local = ATI18800_EDGE16, @@ -326,3 +414,17 @@ const device_t ati18800_device = { .force_redraw = ati18800_force_redraw, .config = NULL }; + +const device_t ati18800_egawonder800plus_device = { + .name = "ATI EGA Wonder 800+", + .internal_name = "egawonder800", + .flags = DEVICE_ISA, + .local = ATI18800_EGAWONDER800PLUS, + .init = ati18800_init, + .close = ati18800_close, + .reset = NULL, + { .available = ati18800_egawonder800plus_available }, + .speed_changed = ati18800_speed_changed, + .force_redraw = ati18800_force_redraw, + .config = NULL +}; diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index d4abebb39..626ddeca9 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -41,7 +41,6 @@ void ega_doblit(int wx, int wy, ega_t *ega); #define BIOS_IBM_PATH "roms/video/ega/ibm_6277356_ega_card_u44_27128.bin" #define BIOS_CPQ_PATH "roms/video/ega/108281-001.bin" #define BIOS_SEGA_PATH "roms/video/ega/lega.vbi" -#define BIOS_ATIEGA_PATH "roms/video/ega/ATI EGA Wonder 800+ N1.00.BIN" #define BIOS_ISKRA_PATH "roms/video/ega/143-02.bin", "roms/video/ega/143-03.bin" #define BIOS_TSENG_PATH "roms/video/ega/EGA ET2000.BIN" @@ -49,7 +48,6 @@ enum { EGA_IBM = 0, EGA_COMPAQ, EGA_SUPEREGA, - EGA_ATI, EGA_ISKRA, EGA_TSENG }; @@ -80,34 +78,6 @@ ega_out(uint16_t addr, uint8_t val, void *priv) addr ^= 0x60; switch (addr) { - case 0x1ce: - ega->index = val; - break; - case 0x1cf: - ega->regs[ega->index] = val; - switch (ega->index) { - case 0xb0: - ega_recalctimings(ega); - break; - case 0xb2: - case 0xbe: -#if 0 - if (ega->regs[0xbe] & 8) { /*Read/write bank mode*/ - svga->read_bank = ((ega->regs[0xb2] >> 5) & 7) * 0x10000; - svga->write_bank = ((ega->regs[0xb2] >> 1) & 7) * 0x10000; - } else /*Single bank mode*/ - svga->read_bank = svga->write_bank = ((ega->regs[0xb2] >> 1) & 7) * 0x10000; -#endif - break; - case 0xb3: - ati_eeprom_write((ati_eeprom_t *) ega->eeprom, val & 8, val & 2, val & 1); - break; - - default: - break; - } - break; - case 0x3c0: case 0x3c1: if (!ega->attrff) { @@ -276,23 +246,6 @@ ega_in(uint16_t addr, void *priv) addr ^= 0x60; switch (addr) { - case 0x1ce: - ret = ega->index; - break; - case 0x1cf: - switch (ega->index) { - case 0xb7: - ret = ega->regs[ega->index] & ~8; - if (ati_eeprom_read((ati_eeprom_t *) ega->eeprom)) - ret |= 8; - break; - - default: - ret = ega->regs[ega->index]; - break; - } - break; - case 0x3c0: if (ega_type) ret = ega->attraddr | ega->attr_palette_enable; @@ -476,31 +429,6 @@ ega_recalctimings(ega_t *ega) crtcconst *= 9.0; else crtcconst *= 8.0; - } else if (ega->eeprom) { - clksel = ((ega->miscout & 0xc) >> 2) | ((ega->regs[0xbe] & 0x10) ? 4 : 0); - - switch (clksel) { - case 0: - crtcconst = (cpuclock / 25175000.0 * (double) (1ULL << 32)); - break; - case 1: - crtcconst = (cpuclock / 28322000.0 * (double) (1ULL << 32)); - break; - case 4: - crtcconst = (cpuclock / 14318181.0 * (double) (1ULL << 32)); - break; - case 5: - crtcconst = (cpuclock / 16257000.0 * (double) (1ULL << 32)); - break; - case 7: - default: - crtcconst = (cpuclock / 36000000.0 * (double) (1ULL << 32)); - break; - } - if (!(ega->seqregs[1] & 1)) - crtcconst *= 9.0; - else - crtcconst *= 8.0; } else { if (ega->vidclock) crtcconst = (ega->seqregs[1] & 1) ? MDACONST : (MDACONST * (9.0 / 8.0)); @@ -1414,10 +1342,6 @@ ega_standalone_init(const device_t *info) rom_init(&ega->bios_rom, BIOS_SEGA_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); break; - case EGA_ATI: - rom_init(&ega->bios_rom, BIOS_ATIEGA_PATH, - 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - break; case EGA_ISKRA: rom_init_interleaved(&ega->bios_rom, BIOS_ISKRA_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -1445,12 +1369,7 @@ ega_standalone_init(const device_t *info) mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); - if (info->local == EGA_ATI) { - io_sethandler(0x01ce, 0x0002, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); - ega->eeprom = malloc(sizeof(ati_eeprom_t)); - memset(ega->eeprom, 0, sizeof(ati_eeprom_t)); - ati_eeprom_load((ati_eeprom_t *) ega->eeprom, "egawonder800.nvr", 0); - } else if (info->local == EGA_COMPAQ) { + if (info->local == EGA_COMPAQ) { io_sethandler(0x0084, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); io_sethandler(0x07c6, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); io_sethandler(0x0bc6, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); @@ -1478,12 +1397,6 @@ sega_standalone_available(void) return rom_present(BIOS_SEGA_PATH); } -static int -atiega_standalone_available(void) -{ - return rom_present(BIOS_ATIEGA_PATH); -} - static int iskra_ega_standalone_available(void) { @@ -1501,8 +1414,6 @@ ega_close(void *priv) { ega_t *ega = (ega_t *) priv; - if (ega->eeprom) - free(ega->eeprom); free(ega->vram); free(ega); } @@ -1640,20 +1551,6 @@ const device_t sega_device = { .config = ega_config }; -const device_t atiega_device = { - .name = "ATI EGA Wonder 800+", - .internal_name = "egawonder800", - .flags = DEVICE_ISA, - .local = EGA_ATI, - .init = ega_standalone_init, - .close = ega_close, - .reset = NULL, - { .available = atiega_standalone_available }, - .speed_changed = ega_speed_changed, - .force_redraw = NULL, - .config = ega_config -}; - const device_t iskra_ega_device = { .name = "Iskra EGA (Cyrillic ROM)", .internal_name = "iskra_ega", diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 6317fb5a3..f7f377888 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -79,7 +79,7 @@ video_cards[] = { // clang-format off { &vid_none_device }, { &vid_internal_device }, - { &atiega_device }, + { &ati18800_egawonder800plus_device }, { &mach8_isa_device, VIDEO_FLAG_TYPE_8514 }, { &mach32_isa_device, VIDEO_FLAG_TYPE_8514 }, { &mach64gx_isa_device }, From 0bd67a1bc4517a1d1f5d8ab086cfe8fe672f8ab6 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Tue, 19 Dec 2023 13:11:01 +1300 Subject: [PATCH 071/936] Report correct S3 Trio64V2/DX revision ID Doesn't seem to affect much, but we might as well fix it. --- src/video/vid_s3.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 35e65cc18..9a56acdd7 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -2934,8 +2934,14 @@ s3_in(uint16_t addr, void *priv) return (s3->chip == S3_TRIO64V2) ? 0x89 : 0x88; /*Extended chip ID*/ case 0x2e: return s3->id_ext; /*New chip ID*/ - case 0x2f: - return (s3->chip == S3_TRIO64V) ? 0x40 : 0; /*Revision level*/ + case 0x2f: switch (s3->chip) { /*Revision level*/ + case S3_TRIO64V: + return 0x40; + case S3_TRIO64V2: + return 0x16; /*Confirmed on an onboard 64V2/DX*/ + default: + return 0x00; + } case 0x30: return s3->id; /*Chip ID*/ case 0x31: @@ -7558,8 +7564,14 @@ s3_pci_read(UNUSED(int func), int addr, void *priv) case 0x07: return (s3->chip == S3_TRIO64V2) ? (s3->pci_regs[0x07] & 0x36) : (1 << 1); /*Medium DEVSEL timing*/ - case 0x08: - return (s3->chip == S3_TRIO64V) ? 0x40 : 0; /*Revision ID*/ + case 0x08: switch (s3->chip) { /*Revision ID*/ + case S3_TRIO64V: + return 0x40; + case S3_TRIO64V2: + return 0x16; /*Confirmed on an onboard 64V2/DX*/ + default: + return 0x00; + } case 0x09: return 0; /*Programming interface*/ From efe9784aad8dfc742330ae20e95d550ecc3c2574 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 19 Dec 2023 11:42:01 +0600 Subject: [PATCH 072/936] MGA: Count for cases where DMA header data is not immediately available Fixes crashes on NT 4.0 --- src/video/vid_mga.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 2c9561b02..2d4d3be02 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -15,6 +15,7 @@ * Copyright 2008-2020 Sarah Walker. */ #include +#include #include #include #include @@ -512,6 +513,8 @@ typedef struct mystique_t { pri_header, sec_header, iload_header; + bool words_expected, sec_words_expected; + mutex_t *lock; } dma; @@ -2664,13 +2667,21 @@ run_dma(mystique_t *mystique) case DMA_STATE_PRI: switch (mystique->dma.primaddress & DMA_MODE_MASK) { case DMA_MODE_REG: - if (mystique->dma.pri_state == 0) { + if (mystique->dma.pri_state == 0 && !mystique->dma.words_expected) { dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.pri_header, 4, 4); mystique->dma.primaddress += 4; words_transferred++; } - if ((mystique->dma.pri_header & 0xff) != 0x15 && (mystique->dma.primaddress & DMA_ADDR_MASK) < (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK) && !mystique->dma.words_expected) + { + /* Wait until more data is available. */ + mystique->dma.words_expected = 1; + break; + } + + mystique->dma.words_expected = 0; + if ((mystique->dma.pri_header & 0xff) != 0x15) { uint32_t val; uint32_t reg_addr; @@ -2709,7 +2720,7 @@ run_dma(mystique_t *mystique) case DMA_STATE_SEC: switch (mystique->dma.secaddress & DMA_MODE_MASK) { case DMA_MODE_REG: - if (mystique->dma.sec_state == 0) { + if (mystique->dma.sec_state == 0 && !mystique->dma.sec_words_expected) { dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.sec_header, 4, 4); mystique->dma.secaddress += 4; words_transferred++; @@ -2718,6 +2729,14 @@ run_dma(mystique_t *mystique) uint32_t val; uint32_t reg_addr; + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK) && !mystique->dma.sec_words_expected) + { + /* Wait until more data is available. */ + mystique->dma.sec_words_expected = 1; + break; + } + + mystique->dma.sec_words_expected = 0; dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4); mystique->dma.secaddress += 4; From 3ba6e337c5cc0ca61357e9b97ceb867c1db67e5d Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 19 Dec 2023 12:02:58 +0600 Subject: [PATCH 073/936] Revert "MGA: Count for cases where DMA header data is not immediately available" This reverts commit efe9784aad8dfc742330ae20e95d550ecc3c2574. --- src/video/vid_mga.c | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 2d4d3be02..2c9561b02 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -15,7 +15,6 @@ * Copyright 2008-2020 Sarah Walker. */ #include -#include #include #include #include @@ -513,8 +512,6 @@ typedef struct mystique_t { pri_header, sec_header, iload_header; - bool words_expected, sec_words_expected; - mutex_t *lock; } dma; @@ -2667,21 +2664,13 @@ run_dma(mystique_t *mystique) case DMA_STATE_PRI: switch (mystique->dma.primaddress & DMA_MODE_MASK) { case DMA_MODE_REG: - if (mystique->dma.pri_state == 0 && !mystique->dma.words_expected) { + if (mystique->dma.pri_state == 0) { dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.pri_header, 4, 4); mystique->dma.primaddress += 4; words_transferred++; } - if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK) && !mystique->dma.words_expected) - { - /* Wait until more data is available. */ - mystique->dma.words_expected = 1; - break; - } - - mystique->dma.words_expected = 0; - if ((mystique->dma.pri_header & 0xff) != 0x15) { + if ((mystique->dma.pri_header & 0xff) != 0x15 && (mystique->dma.primaddress & DMA_ADDR_MASK) < (mystique->dma.primend & DMA_ADDR_MASK)) { uint32_t val; uint32_t reg_addr; @@ -2720,7 +2709,7 @@ run_dma(mystique_t *mystique) case DMA_STATE_SEC: switch (mystique->dma.secaddress & DMA_MODE_MASK) { case DMA_MODE_REG: - if (mystique->dma.sec_state == 0 && !mystique->dma.sec_words_expected) { + if (mystique->dma.sec_state == 0) { dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.sec_header, 4, 4); mystique->dma.secaddress += 4; words_transferred++; @@ -2729,14 +2718,6 @@ run_dma(mystique_t *mystique) uint32_t val; uint32_t reg_addr; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK) && !mystique->dma.sec_words_expected) - { - /* Wait until more data is available. */ - mystique->dma.sec_words_expected = 1; - break; - } - - mystique->dma.sec_words_expected = 0; dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4); mystique->dma.secaddress += 4; From 1f91c0e2ec22d0122f15cb12e754ccbbdd0f4eb1 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 19 Dec 2023 12:59:18 +0600 Subject: [PATCH 074/936] More work on busmastering NT 4.0 freezes as of now. No idea, although the data aren't filled with total nonsense anymore --- src/video/vid_mga.c | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 2c9561b02..1cba098ef 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -512,6 +512,8 @@ typedef struct mystique_t { pri_header, sec_header, iload_header; + atomic_uint words_expected; + mutex_t *lock; } dma; @@ -2435,7 +2437,7 @@ mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) mystique->status &= ~STATUS_ENDPRDMASTS; mystique->dma.state = DMA_STATE_PRI; - mystique->dma.pri_state = 0; + //mystique->dma.pri_state = 0; wake_fifo_thread(mystique); } thread_release_mutex(mystique->dma.lock); @@ -2664,19 +2666,32 @@ run_dma(mystique_t *mystique) case DMA_STATE_PRI: switch (mystique->dma.primaddress & DMA_MODE_MASK) { case DMA_MODE_REG: - if (mystique->dma.pri_state == 0) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + break; + } + if (mystique->dma.pri_state == 0 && !mystique->dma.words_expected) { dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.pri_header, 4, 4); mystique->dma.primaddress += 4; + pclog("DMA header: 0x%08X\n", mystique->dma.pri_header); + mystique->dma.words_expected = 4; words_transferred++; } - if ((mystique->dma.pri_header & 0xff) != 0x15 && (mystique->dma.primaddress & DMA_ADDR_MASK) < (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + break; + } + + if ((mystique->dma.pri_header & 0xff) != 0x15) { uint32_t val; uint32_t reg_addr; dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4); - mystique->dma.primaddress += 4; words_transferred++; + pclog("DMA val: 0x%08X\n", val); reg_addr = (mystique->dma.pri_header & 0x7f) << 2; if (mystique->dma.pri_header & 0x80) @@ -2690,6 +2705,10 @@ run_dma(mystique_t *mystique) mystique_accel_ctrl_write_l(reg_addr, val, mystique); } + if (mystique->dma.words_expected) + mystique->dma.words_expected--; + mystique->dma.primaddress += 4; + mystique->dma.pri_header >>= 8; mystique->dma.pri_state = (mystique->dma.pri_state + 1) & 3; @@ -2740,8 +2759,11 @@ run_dma(mystique_t *mystique) if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; - } else + } else{ mystique->dma.state = DMA_STATE_PRI; + mystique->dma.words_expected = 0; + mystique->dma.pri_state = 0; + } } break; @@ -2760,8 +2782,11 @@ run_dma(mystique_t *mystique) if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; - } else + } else { mystique->dma.state = DMA_STATE_PRI; + mystique->dma.words_expected = 0; + mystique->dma.pri_state = 0; + } } } break; From 3a5bbe9ad391bfb7647b863714fe6f25ae51ca1d Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 19 Dec 2023 13:46:27 +0600 Subject: [PATCH 075/936] vid_mga: Busmastering works properly now --- src/video/vid_mga.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 1cba098ef..bf73206dc 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -2674,7 +2674,6 @@ run_dma(mystique_t *mystique) if (mystique->dma.pri_state == 0 && !mystique->dma.words_expected) { dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.pri_header, 4, 4); mystique->dma.primaddress += 4; - pclog("DMA header: 0x%08X\n", mystique->dma.pri_header); mystique->dma.words_expected = 4; words_transferred++; } @@ -2685,13 +2684,12 @@ run_dma(mystique_t *mystique) break; } - if ((mystique->dma.pri_header & 0xff) != 0x15) { + { uint32_t val; uint32_t reg_addr; dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4); words_transferred++; - pclog("DMA val: 0x%08X\n", val); reg_addr = (mystique->dma.pri_header & 0x7f) << 2; if (mystique->dma.pri_header & 0x80) @@ -2712,8 +2710,10 @@ run_dma(mystique_t *mystique) mystique->dma.pri_header >>= 8; mystique->dma.pri_state = (mystique->dma.pri_state + 1) & 3; - if (mystique->dma.state == DMA_STATE_SEC) - mystique->dma.pri_state = 0; + if (mystique->dma.state == DMA_STATE_SEC) { + mystique->dma.pri_state = 0; + mystique->dma.words_expected = 0; + } else if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; From 8226a5e39c689a83449e2932b8c674cfb60859ff Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 19 Dec 2023 16:27:05 +0600 Subject: [PATCH 076/936] Matrox Mystique: Attempt fixing 3D busmastered drawing NT 4.0's OpenGL screensavers only display one frame before freezing the system --- src/video/vid_mga.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index bf73206dc..3fd143547 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -2064,6 +2064,12 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) mystique->blitter_complete_refcount = 0; mystique->dwgreg.iload_rem_count = 0; mystique->status = STATUS_ENDPRDMASTS; + thread_wait_mutex(mystique->dma.lock); + mystique->dma.pri_state = 0; + mystique->dma.sec_state = 0; + mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.words_expected = 0; + thread_release_mutex(mystique->dma.lock); break; case REG_ATTR_IDX: @@ -2393,6 +2399,8 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) case REG_SOFTRAP: mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.pri_state = 0; + mystique->dma.words_expected = 0; mystique->endprdmasts_pending = 1; mystique->softrap_pending_val = val; mystique->softrap_pending = 1; @@ -2713,6 +2721,7 @@ run_dma(mystique_t *mystique) if (mystique->dma.state == DMA_STATE_SEC) { mystique->dma.pri_state = 0; mystique->dma.words_expected = 0; + mystique->dma.sec_state = 0; } else if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; @@ -2728,6 +2737,18 @@ run_dma(mystique_t *mystique) case DMA_STATE_SEC: switch (mystique->dma.secaddress & DMA_MODE_MASK) { case DMA_MODE_REG: + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.pri_state = 0; + mystique->dma.words_expected = 0; + } else { + mystique->dma.state = DMA_STATE_PRI; + mystique->dma.words_expected = 0; + mystique->dma.pri_state = 0; + } + } if (mystique->dma.sec_state == 0) { dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.sec_header, 4, 4); mystique->dma.secaddress += 4; @@ -2759,7 +2780,9 @@ run_dma(mystique_t *mystique) if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; - } else{ + mystique->dma.pri_state = 0; + mystique->dma.words_expected = 0; + } else { mystique->dma.state = DMA_STATE_PRI; mystique->dma.words_expected = 0; mystique->dma.pri_state = 0; @@ -2770,6 +2793,18 @@ run_dma(mystique_t *mystique) case DMA_MODE_BLIT: { uint32_t val; + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.words_expected = 0; + mystique->dma.pri_state = 0; + } else { + mystique->dma.state = DMA_STATE_PRI; + mystique->dma.words_expected = 0; + mystique->dma.pri_state = 0; + } + } dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4); mystique->dma.secaddress += 4; @@ -2782,6 +2817,8 @@ run_dma(mystique_t *mystique) if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.words_expected = 0; + mystique->dma.pri_state = 0; } else { mystique->dma.state = DMA_STATE_PRI; mystique->dma.words_expected = 0; From 1e71efc5bb9d24c9c761614c98102a36a1d7cdc4 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 19 Dec 2023 18:48:49 +0100 Subject: [PATCH 077/936] More MGA fixes. Re-introduced the mystique read/write linear functions but with a check (!svga->fast) in the byte ones to make sure the generic svga linear functions are enabled when needed, this should keep compatibility stable while also fixing the amount of memory of NT 4.0's MGA Millennium drivers. --- src/video/vid_mga.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index bf73206dc..d6b07c68b 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -636,14 +636,12 @@ static void wake_fifo_thread(mystique_t *mystique); static void wait_fifo_idle(mystique_t *mystique); static void mystique_queue(mystique_t *mystique, uint32_t addr, uint32_t val, uint32_t type); -#if 0 static uint8_t mystique_readb_linear(uint32_t addr, void *priv); static uint16_t mystique_readw_linear(uint32_t addr, void *priv); static uint32_t mystique_readl_linear(uint32_t addr, void *priv); static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv); static void mystique_writew_linear(uint32_t addr, uint16_t val, void *priv); static void mystique_writel_linear(uint32_t addr, uint32_t val, void *priv); -#endif static void mystique_recalc_mapping(mystique_t *mystique); static int mystique_line_compare(svga_t *svga); @@ -994,7 +992,7 @@ mystique_recalc_mapping(mystique_t *mystique) if (mystique->pci_regs[0x41] & 1) { switch (svga->gdcreg[6] & 0x0C) { case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); svga->banked_mask = 0x1ffff; break; case 0x4: /*64k at A0000*/ @@ -2560,12 +2558,14 @@ mystique_accel_iload_write_l(UNUSED(uint32_t addr), uint32_t val, void *priv) } } -#if 0 static uint8_t mystique_readb_linear(uint32_t addr, void *priv) { const svga_t *svga = (svga_t *) priv; + if (!svga->fast) + return svga_read_linear(addr, priv); + cycles -= video_timing_read_b; addr &= svga->decode_mask; @@ -2608,6 +2608,11 @@ mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv) { svga_t *svga = (svga_t *) priv; + if (!svga->fast) { + svga_write_linear(addr, val, priv); + return; + } + cycles -= video_timing_write_b; addr &= svga->decode_mask; @@ -2647,7 +2652,6 @@ mystique_writel_linear(uint32_t addr, uint32_t val, void *priv) svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; *(uint32_t *) &svga->vram[addr] = val; } -#endif static void run_dma(mystique_t *mystique) @@ -2711,7 +2715,7 @@ run_dma(mystique_t *mystique) mystique->dma.pri_state = (mystique->dma.pri_state + 1) & 3; if (mystique->dma.state == DMA_STATE_SEC) { - mystique->dma.pri_state = 0; + mystique->dma.pri_state = 0; mystique->dma.words_expected = 0; } else if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { @@ -5652,8 +5656,8 @@ mystique_init(const device_t *info) mem_mapping_disable(&mystique->ctrl_mapping); mem_mapping_add(&mystique->lfb_mapping, 0, 0, - svga_read_linear, svga_readw_linear, svga_readl_linear, - svga_write_linear, svga_writew_linear, svga_writel_linear, + mystique_readb_linear, mystique_readw_linear, mystique_readl_linear, + mystique_writeb_linear, mystique_writew_linear, mystique_writel_linear, NULL, 0, &mystique->svga); mem_mapping_disable(&mystique->lfb_mapping); From d38ad2eb23fc2e9611933a7800239bb8f9b99878 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 19 Dec 2023 19:03:54 +0100 Subject: [PATCH 078/936] ATI EGA Wonder 800+ fixes. 1. Reverted the migration from ATI 18800 as the EGA code had the proper palette. 2. Add support for the 800x600 resolution required by said card. --- src/include/86box/vid_ega.h | 5 ++ src/include/86box/video.h | 1 - src/video/vid_ati18800.c | 71 +--------------- src/video/vid_ega.c | 158 +++++++++++++++++++++++++++++++++--- src/video/vid_table.c | 2 +- 5 files changed, 155 insertions(+), 82 deletions(-) diff --git a/src/include/86box/vid_ega.h b/src/include/86box/vid_ega.h index ec13de928..ec241d613 100644 --- a/src/include/86box/vid_ega.h +++ b/src/include/86box/vid_ega.h @@ -109,6 +109,8 @@ typedef struct ega_t { int bpp; int index; int remap_required; + int actual_type; + int chipset; uint32_t charseta; uint32_t charsetb; @@ -132,6 +134,8 @@ typedef struct ega_t { double dot_clock; + void * eeprom; + uint32_t (*remap_func)(struct ega_t *ega, uint32_t in_addr); void (*render)(struct ega_t *svga); } ega_t; @@ -141,6 +145,7 @@ typedef struct ega_t { extern const device_t ega_device; extern const device_t cpqega_device; extern const device_t sega_device; +extern const device_t atiega800p_device; extern const device_t iskra_ega_device; extern const device_t et2000_device; #endif diff --git a/src/include/86box/video.h b/src/include/86box/video.h index de27fcbb1..396b39124 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -322,7 +322,6 @@ extern const device_t ati18800_wonder_device; # endif extern const device_t ati18800_vga88_device; extern const device_t ati18800_device; -extern const device_t ati18800_egawonder800plus_device; /* ATi 28800 */ extern const device_t ati28800_device; diff --git a/src/video/vid_ati18800.c b/src/video/vid_ati18800.c index fd658eacf..f9dc8821e 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -37,18 +37,15 @@ #endif #define BIOS_ROM_PATH_VGA88 "roms/video/ati18800/vga88.bin" #define BIOS_ROM_PATH_EDGE16 "roms/video/ati18800/vgaedge16.vbi" -#define BIOS_ROM_PATH_ATIEGAPLUS "roms/video/ati18800/ATI EGA Wonder 800+ N1.00.BIN" enum { #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) ATI18800_WONDER = 0, ATI18800_VGA88, - ATI18800_EDGE16, - ATI18800_EGAWONDER800PLUS + ATI18800_EDGE16 #else ATI18800_VGA88 = 0, - ATI18800_EDGE16, - ATI18800_EGAWONDER800PLUS + ATI18800_EDGE16 #endif }; @@ -71,6 +68,7 @@ ati18800_out(uint16_t addr, uint8_t val, void *priv) { ati18800_t *ati18800 = (ati18800_t *) priv; svga_t *svga = &ati18800->svga; + uint8_t o; uint8_t old; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) @@ -182,40 +180,6 @@ ati18800_recalctimings(svga_t *svga) clock_sel = ((svga->miscout >> 2) & 3) | ((ati18800->regs[0xbe] & 0x10) >> 1) | ((ati18800->regs[0xb9] & 2) << 1); - if (ati18800->type == ATI18800_EGAWONDER800PLUS) { - svga->crtc[5] &= ~0x60; /*Not supported by the EGA Wonder 800+*/ - svga->crtc[0x0b] &= ~0x60; /*Not supported by the EGA Wonder 800+*/ - - svga->hdisp_time = svga->hdisp; - - svga->hdisp = svga->crtc[1]; - svga->hdisp++; - - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]); - - svga->hdisp_time = svga->hdisp; - svga->render = svga_render_blank; - - if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ - if (svga->seqregs[1] & 8) { /*40 column*/ - svga->render = svga_render_text_40; - svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; - /* Character clock is off by 1 now in 40-line modes, on all cards. */ - svga->ma_latch--; - svga->hdisp += (svga->seqregs[1] & 1) ? 16 : 18; - } else { - svga->render = svga_render_text_80; - svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; - } - svga->hdisp_old = svga->hdisp; - } else { - svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; - svga->hdisp_old = svga->hdisp; - } - } - } - if (ati18800->regs[0xb6] & 0x10) { svga->hdisp <<= 1; svga->htotal <<= 1; @@ -291,10 +255,6 @@ ati18800_init(const device_t *info) rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_EDGE16, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); ati18800->memory = 512; break; - case ATI18800_EGAWONDER800PLUS: - rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_ATIEGAPLUS, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - ati18800->memory = 256; - break; } svga_init(info, &ati18800->svga, ati18800, ati18800->memory << 10, @@ -311,10 +271,7 @@ ati18800_init(const device_t *info) ati18800->svga.miscout = 1; ati18800->svga.bpp = 8; - if (info->local == ATI18800_EGAWONDER800PLUS) - ati_eeprom_load(&ati18800->eeprom, "egawonder800.nvr", 0); - else - ati_eeprom_load(&ati18800->eeprom, "ati18800.nvr", 0); + ati_eeprom_load(&ati18800->eeprom, "ati18800.nvr", 0); return ati18800; } @@ -339,12 +296,6 @@ ati18800_available(void) return rom_present(BIOS_ROM_PATH_EDGE16); } -static int -ati18800_egawonder800plus_available(void) -{ - return rom_present(BIOS_ROM_PATH_ATIEGAPLUS); -} - static void ati18800_close(void *priv) { @@ -414,17 +365,3 @@ const device_t ati18800_device = { .force_redraw = ati18800_force_redraw, .config = NULL }; - -const device_t ati18800_egawonder800plus_device = { - .name = "ATI EGA Wonder 800+", - .internal_name = "egawonder800", - .flags = DEVICE_ISA, - .local = ATI18800_EGAWONDER800PLUS, - .init = ati18800_init, - .close = ati18800_close, - .reset = NULL, - { .available = ati18800_egawonder800plus_available }, - .speed_changed = ati18800_speed_changed, - .force_redraw = ati18800_force_redraw, - .config = NULL -}; diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 626ddeca9..da77449b0 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -41,6 +41,7 @@ void ega_doblit(int wx, int wy, ega_t *ega); #define BIOS_IBM_PATH "roms/video/ega/ibm_6277356_ega_card_u44_27128.bin" #define BIOS_CPQ_PATH "roms/video/ega/108281-001.bin" #define BIOS_SEGA_PATH "roms/video/ega/lega.vbi" +#define BIOS_ATIEGA800P_PATH "roms/video/ega/ATI EGA Wonder 800+ N1.00.BIN" #define BIOS_ISKRA_PATH "roms/video/ega/143-02.bin", "roms/video/ega/143-03.bin" #define BIOS_TSENG_PATH "roms/video/ega/EGA ET2000.BIN" @@ -48,6 +49,7 @@ enum { EGA_IBM = 0, EGA_COMPAQ, EGA_SUPEREGA, + EGA_ATI800P, EGA_ISKRA, EGA_TSENG }; @@ -78,6 +80,24 @@ ega_out(uint16_t addr, uint8_t val, void *priv) addr ^= 0x60; switch (addr) { + case 0x1ce: + ega->index = val; + break; + case 0x1cf: + ega->regs[ega->index] = val; + switch (ega->index) { + case 0xb0: + ega_recalctimings(ega); + break; + case 0xb3: + ati_eeprom_write((ati_eeprom_t *) ega->eeprom, val & 8, val & 2, val & 1); + break; + + default: + break; + } + break; + case 0x3c0: case 0x3c1: if (!ega->attrff) { @@ -126,8 +146,7 @@ ega_out(uint16_t addr, uint8_t val, void *priv) io_removehandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); if (!(val & 1)) io_sethandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); - if ((o ^ val) & 0x80) - ega_recalctimings(ega); + ega_recalctimings(ega); break; case 0x3c4: ega->seqaddr = val; @@ -208,14 +227,24 @@ ega_out(uint16_t addr, uint8_t val, void *priv) break; case 0x3d0: case 0x3d4: - ega->crtcreg = val & 31; + if (ega->chipset) + ega->crtcreg = val & 0x3f; + else + ega->crtcreg = val & 0x1f; return; case 0x3d1: case 0x3d5: - if ((ega->crtcreg < 7) && (ega->crtc[0x11] & 0x80)) - return; - if ((ega->crtcreg == 7) && (ega->crtc[0x11] & 0x80)) - val = (ega->crtc[7] & ~0x10) | (val & 0x10); + if (ega->chipset) { + if ((ega->crtcreg < 7) && (ega->crtc[0x11] & 0x80) && !(ega->regs[0xb4] & 0x80)) + return; + if ((ega->crtcreg == 7) && (ega->crtc[0x11] & 0x80) && !(ega->regs[0xb4] & 0x80)) + val = (ega->crtc[7] & ~0x10) | (val & 0x10); + } else { + if ((ega->crtcreg < 7) && (ega->crtc[0x11] & 0x80)) + return; + if ((ega->crtcreg == 7) && (ega->crtc[0x11] & 0x80)) + val = (ega->crtc[7] & ~0x10) | (val & 0x10); + } old = ega->crtc[ega->crtcreg]; ega->crtc[ega->crtcreg] = val; if (old != val) { @@ -246,6 +275,23 @@ ega_in(uint16_t addr, void *priv) addr ^= 0x60; switch (addr) { + case 0x1ce: + ret = ega->index; + break; + case 0x1cf: + switch (ega->index) { + case 0xb7: + ret = ega->regs[ega->index] & ~8; + if (ati_eeprom_read((ati_eeprom_t *) ega->eeprom)) + ret |= 8; + break; + + default: + ret = ega->regs[ega->index]; + break; + } + break; + case 0x3c0: if (ega_type) ret = ega->attraddr | ega->attr_palette_enable; @@ -255,8 +301,8 @@ ega_in(uint16_t addr, void *priv) ret = ega->attrregs[ega->attraddr]; break; case 0x3c2: - ret = (egaswitches & (8 >> egaswitchread)) ? 0x10 : 0x00; - break; + ret = (egaswitches & (8 >> egaswitchread)) ? 0x10 : 0x00; + break; case 0x3c4: if (ega_type) ret = ega->seqaddr; @@ -310,6 +356,7 @@ ega_in(uint16_t addr, void *priv) default: if (ega_type) ret = ega->crtc[ega->crtcreg]; + break; } break; case 0x3da: @@ -429,6 +476,31 @@ ega_recalctimings(ega_t *ega) crtcconst *= 9.0; else crtcconst *= 8.0; + } else if (ega->eeprom) { + clksel = ((ega->miscout & 0xc) >> 2) | ((ega->regs[0xbe] & 0x10) ? 4 : 0); + + switch (clksel) { + case 0: + crtcconst = (cpuclock / 25175000.0 * (double) (1ULL << 32)); + break; + case 1: + crtcconst = (cpuclock / 28322000.0 * (double) (1ULL << 32)); + break; + case 4: + crtcconst = (cpuclock / 14318181.0 * (double) (1ULL << 32)); + break; + case 5: + crtcconst = (cpuclock / 16257000.0 * (double) (1ULL << 32)); + break; + case 7: + default: + crtcconst = (cpuclock / 36000000.0 * (double) (1ULL << 32)); + break; + } + if (!(ega->seqregs[1] & 1)) + crtcconst *= 9.0; + else + crtcconst *= 8.0; } else { if (ega->vidclock) crtcconst = (ega->seqregs[1] & 1) ? MDACONST : (MDACONST * (9.0 / 8.0)); @@ -460,6 +532,15 @@ ega_recalctimings(ega_t *ega) } } + if (ega->chipset) { + if (ega->hdisp > 640) { + ega->dispend <<= 1; + ega->vtotal <<= 1; + ega->split <<= 1; + ega->vsyncstart <<= 1; + } + } + if (enable_overscan) { overscan_y = (ega->rowcount + 1) << 1; @@ -663,8 +744,18 @@ ega_poll(void *priv) if ((ega->stat & 8) && ((ega->displine & 15) == (ega->crtc[0x11] & 15)) && ega->vslines) ega->stat &= ~8; ega->vslines++; - if (ega->displine > 500) - ega->displine = 0; + if (ega->chipset) { + if (ega->hdisp > 640) { + if (ega->displine > 2000) + ega->displine = 0; + } else { + if (ega->displine > 500) + ega->displine = 0; + } + } else { + if (ega->displine > 500) + ega->displine = 0; + } } else { timer_advance_u64(&ega->timer, ega->dispontime); @@ -700,7 +791,13 @@ ega_poll(void *priv) } } ega->vc++; - ega->vc &= 511; + if (ega->chipset) { + if (ega->hdisp > 640) + ega->vc &= 1023; + else + ega->vc &= 511; + } else + ega->vc &= 511; if (ega->vc == ega->split) { // TODO: Implement the hardware bug where the first scanline is drawn twice when the split happens if (ega->interlace && ega->oddeven) @@ -1327,6 +1424,9 @@ ega_standalone_init(const device_t *info) else ega_type = 1; + ega->actual_type = info->local; + ega->chipset = 0; + switch (info->local) { default: case EGA_IBM: @@ -1342,6 +1442,11 @@ ega_standalone_init(const device_t *info) rom_init(&ega->bios_rom, BIOS_SEGA_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); break; + case EGA_ATI800P: + rom_init(&ega->bios_rom, BIOS_ATIEGA800P_PATH, + 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + ega->chipset = 1; + break; case EGA_ISKRA: rom_init_interleaved(&ega->bios_rom, BIOS_ISKRA_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -1369,7 +1474,12 @@ ega_standalone_init(const device_t *info) mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); - if (info->local == EGA_COMPAQ) { + if (ega->chipset) { + io_sethandler(0x01ce, 0x0002, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); + ega->eeprom = malloc(sizeof(ati_eeprom_t)); + memset(ega->eeprom, 0, sizeof(ati_eeprom_t)); + ati_eeprom_load((ati_eeprom_t *) ega->eeprom, "egawonder800p.nvr", 0); + } else if (info->local == EGA_COMPAQ) { io_sethandler(0x0084, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); io_sethandler(0x07c6, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); io_sethandler(0x0bc6, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); @@ -1397,6 +1507,12 @@ sega_standalone_available(void) return rom_present(BIOS_SEGA_PATH); } +static int +atiega800p_standalone_available(void) +{ + return rom_present(BIOS_ATIEGA800P_PATH); +} + static int iskra_ega_standalone_available(void) { @@ -1414,6 +1530,8 @@ ega_close(void *priv) { ega_t *ega = (ega_t *) priv; + if (ega->eeprom) + free(ega->eeprom); free(ega->vram); free(ega); } @@ -1551,6 +1669,20 @@ const device_t sega_device = { .config = ega_config }; +const device_t atiega800p_device = { + .name = "ATI EGA Wonder 800+", + .internal_name = "egawonder800p", + .flags = DEVICE_ISA, + .local = EGA_ATI800P, + .init = ega_standalone_init, + .close = ega_close, + .reset = NULL, + { .available = atiega800p_standalone_available }, + .speed_changed = ega_speed_changed, + .force_redraw = NULL, + .config = ega_config +}; + const device_t iskra_ega_device = { .name = "Iskra EGA (Cyrillic ROM)", .internal_name = "iskra_ega", diff --git a/src/video/vid_table.c b/src/video/vid_table.c index f7f377888..0131fa3a4 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -79,7 +79,7 @@ video_cards[] = { // clang-format off { &vid_none_device }, { &vid_internal_device }, - { &ati18800_egawonder800plus_device }, + { &atiega800p_device }, { &mach8_isa_device, VIDEO_FLAG_TYPE_8514 }, { &mach32_isa_device, VIDEO_FLAG_TYPE_8514 }, { &mach64gx_isa_device }, From 7495c2537b5fa4ce698aa471801ba621ca0efb2c Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 19 Dec 2023 19:32:23 +0100 Subject: [PATCH 079/936] Fixed a warning in video/vid_ati18800.c. --- src/video/vid_ati18800.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/vid_ati18800.c b/src/video/vid_ati18800.c index f9dc8821e..09e813bab 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -68,7 +68,6 @@ ati18800_out(uint16_t addr, uint8_t val, void *priv) { ati18800_t *ati18800 = (ati18800_t *) priv; svga_t *svga = &ati18800->svga; - uint8_t o; uint8_t old; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) From c64748ca6cf7a54e38be0617320898f07359bc79 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 19 Dec 2023 20:02:07 +0100 Subject: [PATCH 080/936] Slight RTL8139 mapping fixes, now Windows 2000 pings correctly, but still all 00's MAC address. --- src/network/net_rtl8139.c | 74 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index 6c86bdebf..942eb9be7 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -490,6 +490,8 @@ struct RTL8139State { int cplus_txbuffer_len; int cplus_txbuffer_offset; + uint32_t mem_base; + /* PCI interrupt timer */ pc_timer_t timer; @@ -3151,6 +3153,72 @@ rtl8139_io_writeb_ioport(uint16_t addr, uint8_t val, void *priv) return rtl8139_io_writeb(addr, val, priv); } +static uint32_t +rtl8139_io_readl_mem(uint32_t addr, void *priv) +{ + RTL8139State *s = (RTL8139State *) priv; + + if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) + return 0xffffffff; + + return rtl8139_io_readl(addr, priv); +} + +static uint16_t +rtl8139_io_readw_mem(uint32_t addr, void *priv) +{ + RTL8139State *s = (RTL8139State *) priv; + + if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) + return 0xffff; + + return rtl8139_io_readw(addr, priv); +} + +static uint8_t +rtl8139_io_readb_mem(uint32_t addr, void *priv) +{ + RTL8139State *s = (RTL8139State *) priv; + + if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) + return 0xff; + + return rtl8139_io_readb(addr, priv); +} + +static void +rtl8139_io_writel_mem(uint32_t addr, uint32_t val, void *priv) +{ + RTL8139State *s = (RTL8139State *) priv; + + if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) + return; + + return rtl8139_io_writel(addr, val, priv); +} + +static void +rtl8139_io_writew_mem(uint32_t addr, uint16_t val, void *priv) +{ + RTL8139State *s = (RTL8139State *) priv; + + if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) + return; + + return rtl8139_io_writew(addr, val, priv); +} + +static void +rtl8139_io_writeb_mem(uint32_t addr, uint8_t val, void *priv) +{ + RTL8139State *s = (RTL8139State *) priv; + + if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) + return; + + return rtl8139_io_writeb(addr, val, priv); +} + static int rtl8139_set_link_status(void *priv, uint32_t link_state) { @@ -3286,6 +3354,7 @@ rtl8139_pci_write(int func, int addr, uint8_t val, void *priv) case 0x16: case 0x17: s->pci_conf[addr & 0xFF] = val; + s->mem_base = (s->pci_conf[0x15] << 8) | (s->pci_conf[0x16] << 16) | (s->pci_conf[0x17] << 24); if (s->pci_conf[0x4] & PCI_COMMAND_MEM) mem_mapping_set_addr(&s->bar_mem, (s->pci_conf[0x15] << 8) | (s->pci_conf[0x16] << 16) | (s->pci_conf[0x17] << 24), 256); break; @@ -3304,7 +3373,10 @@ nic_init(const device_t *info) uint8_t *mac_bytes; uint32_t mac; - mem_mapping_add(&s->bar_mem, 0, 0, rtl8139_io_readb, rtl8139_io_readw, rtl8139_io_readl, rtl8139_io_writeb, rtl8139_io_writew, rtl8139_io_writel, NULL, MEM_MAPPING_EXTERNAL, s); + mem_mapping_add(&s->bar_mem, 0, 0, + rtl8139_io_readb_mem, rtl8139_io_readw_mem, rtl8139_io_readl_mem, + rtl8139_io_writeb_mem, rtl8139_io_writew_mem, rtl8139_io_writel_mem, + NULL, MEM_MAPPING_EXTERNAL, s); pci_add_card(PCI_ADD_NORMAL, rtl8139_pci_read, rtl8139_pci_write, s, &s->pci_slot); s->inst = device_get_instance(); From 1201b52890c5ef7ec78b270aaa3a252a66707b38 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 19 Dec 2023 20:09:00 +0100 Subject: [PATCH 081/936] Fixed the RTL8139 MAC address. --- src/network/net_rtl8139.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index 942eb9be7..afc73a0dd 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -3427,6 +3427,9 @@ nic_init(const device_t *info) mac_bytes[5] = (mac & 0xff); } + for (uint32_t i = 0; i < 6; i++) + s->phys[MAC0 + i] = mac_bytes[i]; + s->nic = network_attach(s, (uint8_t *) &s->eeprom.contents[7], rtl8139_do_receive, rtl8139_set_link_status); timer_add(&s->timer, rtl8139_timer, s, 0); timer_on_auto(&s->timer, 1000000.0 / cpu_pci_speed); From 1773ebfbf3dbc5b53be4662c4f9d6997b8d85c86 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 20 Dec 2023 01:30:09 +0600 Subject: [PATCH 082/936] Mystique: SOFTRAP register writes correctly reset the primary DMA channel --- src/video/vid_mga.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index a3838ea59..8600fac3e 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -2685,6 +2685,7 @@ run_dma(mystique_t *mystique) } if (mystique->dma.pri_state == 0 && !mystique->dma.words_expected) { dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.pri_header, 4, 4); + //pclog("DMA header: 0x%08X\n", mystique->dma.pri_header); mystique->dma.primaddress += 4; mystique->dma.words_expected = 4; words_transferred++; @@ -2712,7 +2713,12 @@ run_dma(mystique_t *mystique) if ((reg_addr & 0x300) == 0x100) mystique->blitter_submit_dma_refcount++; + //pclog("DMA value: 0x%08X to reg 0x%04X\n", val, reg_addr); mystique_accel_ctrl_write_l(reg_addr, val, mystique); + if (reg_addr == REG_SOFTRAP) { + mystique->dma.primaddress += 4; + break; + } } if (mystique->dma.words_expected) @@ -2723,8 +2729,6 @@ run_dma(mystique_t *mystique) mystique->dma.pri_state = (mystique->dma.pri_state + 1) & 3; if (mystique->dma.state == DMA_STATE_SEC) { - mystique->dma.pri_state = 0; - mystique->dma.words_expected = 0; mystique->dma.sec_state = 0; } else if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { @@ -2756,9 +2760,23 @@ run_dma(mystique_t *mystique) if (mystique->dma.sec_state == 0) { dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.sec_header, 4, 4); mystique->dma.secaddress += 4; + //pclog("DMA header (secondary): 0x%08X\n", mystique->dma.sec_header); words_transferred++; } + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.pri_state = 0; + mystique->dma.words_expected = 0; + } else { + mystique->dma.state = DMA_STATE_PRI; + mystique->dma.words_expected = 0; + mystique->dma.pri_state = 0; + } + } + uint32_t val; uint32_t reg_addr; @@ -2775,7 +2793,7 @@ run_dma(mystique_t *mystique) mystique->blitter_submit_dma_refcount++; mystique_accel_ctrl_write_l(reg_addr, val, mystique); - + //pclog("DMA value (secondary): 0x%08X\n", val); mystique->dma.sec_header >>= 8; mystique->dma.sec_state = (mystique->dma.sec_state + 1) & 3; From bf30678d5f48337db5125390d6a72754b436b750 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 20 Dec 2023 13:48:45 +0600 Subject: [PATCH 083/936] MGA: More Mystique busmastering fixes * Use mutex locking when reporting SOFTRAPEN * IEN register now correctly returns values it currently holds * Restore VLINEPEN interrupt --- src/video/vid_mga.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 8600fac3e..c00c7693b 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -1032,6 +1032,8 @@ mystique_update_irqs(mystique_t *mystique) if ((mystique->status & mystique->ien) & STATUS_SOFTRAPEN) irq = 1; + if ((mystique->status & mystique->ien) & STATUS_VLINEPEN) + irq = 1; if ((mystique->status & STATUS_VSYNCPEN) && (svga->crtc[0x11] & 0x30) == 0x10) irq = 1; @@ -1442,7 +1444,7 @@ mystique_ctrl_read_b(uint32_t addr, void *priv) break; case REG_IEN: - ret = mystique->ien & 0x64; + ret = mystique->ien & 0x65; break; case REG_IEN + 1: case REG_IEN + 2: @@ -1985,6 +1987,7 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) switch (addr & 0x3fff) { case REG_ICLEAR: if (val & ICLEAR_SOFTRAPICLR) { + //pclog("softrapiclr\n"); mystique->status &= ~STATUS_SOFTRAPEN; mystique_update_irqs(mystique); } @@ -2401,7 +2404,7 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) mystique->dma.words_expected = 0; mystique->endprdmasts_pending = 1; mystique->softrap_pending_val = val; - mystique->softrap_pending = 1; + mystique->softrap_pending += 1; break; default: @@ -2959,16 +2962,21 @@ mystique_softrap_pending_timer(void *priv) timer_advance_u64(&mystique->softrap_pending_timer, TIMER_USEC * 100); - if (mystique->endprdmasts_pending) { - mystique->endprdmasts_pending = 0; - mystique->status |= STATUS_ENDPRDMASTS; - } - if (mystique->softrap_pending) { - mystique->softrap_pending = 0; + if (thread_test_mutex(mystique->dma.lock)) + { + if (mystique->endprdmasts_pending) { + mystique->endprdmasts_pending = 0; + mystique->status |= STATUS_ENDPRDMASTS; + } + if (mystique->softrap_pending) { + mystique->softrap_pending--; - mystique->dma.secaddress = mystique->softrap_pending_val; - mystique->status |= STATUS_SOFTRAPEN; - mystique_update_irqs(mystique); + mystique->dma.secaddress = mystique->softrap_pending_val; + mystique->status |= STATUS_SOFTRAPEN; + //pclog("softrapen\n"); + mystique_update_irqs(mystique); + } + thread_release_mutex(mystique->dma.lock); } } From 7a8fe414c5f0196670945a1c1f0fa8da41fe1e18 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 20 Dec 2023 16:19:29 +0600 Subject: [PATCH 084/936] MGA: 3D busmastering now works (albeit slowly) --- src/video/vid_mga.c | 50 ++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index c00c7693b..d0ec17bff 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -2672,6 +2672,11 @@ run_dma(mystique_t *mystique) thread_wait_mutex(mystique->dma.lock); if (mystique->dma.state == DMA_STATE_IDLE) { + if (!(mystique->status & STATUS_ENDPRDMASTS)) + { + /* Force this to appear. */ + mystique->endprdmasts_pending = 1; + } thread_release_mutex(mystique->dma.lock); return; } @@ -2872,13 +2877,13 @@ fifo_thread(void *priv) mystique_t *mystique = (mystique_t *) priv; while (mystique->thread_run) { + int words_transferred = 0; thread_set_event(mystique->fifo_not_full_event); thread_wait_event(mystique->wake_fifo_thread, -1); thread_reset_event(mystique->wake_fifo_thread); while (!FIFO_EMPTY || mystique->dma.state != DMA_STATE_IDLE) { - int words_transferred = 0; - + words_transferred = 0; while (!FIFO_EMPTY && words_transferred < 100) { fifo_entry_t *fifo = &mystique->fifo[mystique->fifo_read_idx & FIFO_MASK]; @@ -2905,13 +2910,13 @@ fifo_thread(void *priv) words_transferred++; } - - /*Only run DMA once the FIFO is empty. Required by - Screamer 2 / Rally which will incorrectly clip an ILOAD - if DMA runs ahead*/ - if (!words_transferred) - run_dma(mystique); } + + /*Only run DMA once the FIFO is empty. Required by + Screamer 2 / Rally which will incorrectly clip an ILOAD + if DMA runs ahead*/ + if (!words_transferred) + run_dma(mystique); } } @@ -2962,22 +2967,21 @@ mystique_softrap_pending_timer(void *priv) timer_advance_u64(&mystique->softrap_pending_timer, TIMER_USEC * 100); - if (thread_test_mutex(mystique->dma.lock)) - { - if (mystique->endprdmasts_pending) { - mystique->endprdmasts_pending = 0; - mystique->status |= STATUS_ENDPRDMASTS; - } - if (mystique->softrap_pending) { - mystique->softrap_pending--; - - mystique->dma.secaddress = mystique->softrap_pending_val; - mystique->status |= STATUS_SOFTRAPEN; - //pclog("softrapen\n"); - mystique_update_irqs(mystique); - } - thread_release_mutex(mystique->dma.lock); + if (mystique->endprdmasts_pending) { + mystique->endprdmasts_pending = 0; + mystique->status |= STATUS_ENDPRDMASTS; } + if (mystique->softrap_pending) { + mystique->softrap_pending--; + + mystique->dma.secaddress = mystique->softrap_pending_val; + mystique->status |= STATUS_SOFTRAPEN; + //pclog("softrapen\n"); + mystique_update_irqs(mystique); + } + /* Force ENDPRDMASTS flag to be set. */ + if (mystique->dma.state == DMA_STATE_IDLE && !(mystique->status & STATUS_ENDPRDMASTS)) + wake_fifo_thread(mystique); } static void From aabbad31d86289f991068ad5c8fe389db7d1700d Mon Sep 17 00:00:00 2001 From: Alexander Babikov <2708460+lemondrops@users.noreply.github.com> Date: Wed, 20 Dec 2023 15:28:32 +0500 Subject: [PATCH 085/936] qt: Set the window icon per-application, instead of per-window --- src/qt/qt_main.cpp | 11 +++++++++++ src/qt/qt_mainwindow.cpp | 9 --------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index c859fe033..1d6526521 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -194,6 +194,17 @@ main(int argc, char *argv[]) QApplication::setFont(QFont(font_name, font_size.toInt())); SetCurrentProcessExplicitAppUserModelID(L"86Box.86Box"); #endif + +#ifdef RELEASE_BUILD + app.setWindowIcon(QIcon(":/settings/win/icons/86Box-green.ico")); +#elif defined ALPHA_BUILD + app.setWindowIcon(QIcon(":/settings/win/icons/86Box-red.ico")); +#elif defined BETA_BUILD + app.setWindowIcon(QIcon(":/settings/win/icons/86Box-yellow.ico")); +#else + app.setWindowIcon(QIcon(":/settings/win/icons/86Box-gray.ico")); +#endif + if (!pc_init_modules()) { ui_msgbox_header(MBX_FATAL, (void *) IDS_2121, (void *) IDS_2056); return 6; diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index f3503caeb..e0252dd7a 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -196,15 +196,6 @@ MainWindow::MainWindow(QWidget *parent) auto toolbar_label = new QLabel(); ui->toolBar->addWidget(toolbar_label); -#ifdef RELEASE_BUILD - this->setWindowIcon(QIcon(":/settings/win/icons/86Box-green.ico")); -#elif defined ALPHA_BUILD - this->setWindowIcon(QIcon(":/settings/win/icons/86Box-red.ico")); -#elif defined BETA_BUILD - this->setWindowIcon(QIcon(":/settings/win/icons/86Box-yellow.ico")); -#else - this->setWindowIcon(QIcon(":/settings/win/icons/86Box-gray.ico")); -#endif this->setWindowFlag(Qt::MSWindowsFixedSizeDialogHint, vid_resize != 1); this->setWindowFlag(Qt::WindowMaximizeButtonHint, vid_resize == 1); From fdae410884246cf81c0226f44554ac24087b35f3 Mon Sep 17 00:00:00 2001 From: Alexander Babikov <2708460+lemondrops@users.noreply.github.com> Date: Wed, 20 Dec 2023 20:15:31 +0500 Subject: [PATCH 086/936] qt: Set the .desktop file name on *nix May fix generic icon instead of 86Box's icon showing up on Wayland --- src/qt/qt_main.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 1d6526521..02a0026d8 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -205,6 +205,10 @@ main(int argc, char *argv[]) app.setWindowIcon(QIcon(":/settings/win/icons/86Box-gray.ico")); #endif +#if (!defined(Q_OS_WINDOWS) && !defined(__APPLE__)) + app.setDesktopFileName("net.86box.86Box"); +#endif + if (!pc_init_modules()) { ui_msgbox_header(MBX_FATAL, (void *) IDS_2121, (void *) IDS_2056); return 6; From 04103ee9b1ec15f371be58e0fedae78cd770a313 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 20 Dec 2023 20:49:51 +0100 Subject: [PATCH 087/936] Made the RTL8139 use the same 93x6 EEPROM implementation as the DEC Tulip's, also cleaned up the I/O and memory access handlers a bit. --- src/network/net_rtl8139.c | 390 ++++++++++---------------------------- 1 file changed, 101 insertions(+), 289 deletions(-) diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index afc73a0dd..74a1f90ff 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -39,6 +39,7 @@ #include <86box/device.h> #include <86box/thread.h> #include <86box/network.h> +#include <86box/net_eeprom_nmc93cxx.h> #include <86box/bswap.h> #include <86box/nvr.h> #include "cpu.h" @@ -351,44 +352,6 @@ enum chip_flags { #define RTL8139_PCI_REVID RTL8139_PCI_REVID_8139CPLUS -/* Size is 64 * 16bit words */ -#define EEPROM_9346_ADDR_BITS 6 -#define EEPROM_9346_SIZE (1 << EEPROM_9346_ADDR_BITS) -#define EEPROM_9346_ADDR_MASK (EEPROM_9346_SIZE - 1) - -enum Chip9346Operation { - Chip9346_op_mask = 0xc0, /* 10 zzzzzz */ - Chip9346_op_read = 0x80, /* 10 AAAAAA */ - Chip9346_op_write = 0x40, /* 01 AAAAAA D(15)..D(0) */ - Chip9346_op_ext_mask = 0xf0, /* 11 zzzzzz */ - Chip9346_op_write_enable = 0x30, /* 00 11zzzz */ - Chip9346_op_write_all = 0x10, /* 00 01zzzz */ - Chip9346_op_write_disable = 0x00, /* 00 00zzzz */ -}; - -enum Chip9346Mode { - Chip9346_none = 0, - Chip9346_enter_command_mode, - Chip9346_read_command, - Chip9346_data_read, /* from output register */ - Chip9346_data_write, /* to input register, then to contents at specified address */ - Chip9346_data_write_all, /* to input register, then filling contents */ -}; - -typedef struct EEprom9346 { - uint16_t contents[EEPROM_9346_SIZE]; - int mode; - uint32_t tick; - uint8_t address; - uint16_t input; - uint16_t output; - - uint8_t eecs; - uint8_t eesk; - uint8_t eedi; - uint8_t eedo; -} EEprom9346; - #pragma pack(push, 1) typedef struct RTL8139TallyCounters { /* Tally counters */ @@ -476,8 +439,6 @@ struct RTL8139State { uint32_t RxRingAddrLO; uint32_t RxRingAddrHI; - EEprom9346 eeprom; - uint32_t TCTR; uint32_t TimerInt; int64_t TCTR_base; @@ -499,190 +460,14 @@ struct RTL8139State { /* Support migration to/from old versions */ int rtl8139_mmio_io_addr_dummy; + + nmc93cxx_eeprom_t *eeprom; + uint8_t eeprom_data[128]; }; /* Writes tally counters to memory via DMA */ static void RTL8139TallyCounters_dma_write(RTL8139State *s, uint32_t tc_addr); -static void -prom9346_decode_command(EEprom9346 *eeprom, uint8_t command) -{ - rtl8139_log("eeprom command 0x%02x\n", command); - - switch (command & Chip9346_op_mask) { - case Chip9346_op_read: - { - eeprom->address = command & EEPROM_9346_ADDR_MASK; - eeprom->output = eeprom->contents[eeprom->address]; - eeprom->eedo = 0; - eeprom->tick = 0; - eeprom->mode = Chip9346_data_read; - rtl8139_log("eeprom read from address 0x%02x data=0x%04x\n", - eeprom->address, eeprom->output); - } - break; - - case Chip9346_op_write: - { - eeprom->address = command & EEPROM_9346_ADDR_MASK; - eeprom->input = 0; - eeprom->tick = 0; - eeprom->mode = Chip9346_none; /* Chip9346_data_write */ - rtl8139_log("eeprom begin write to address 0x%02x\n", - eeprom->address); - } - break; - default: - eeprom->mode = Chip9346_none; - switch (command & Chip9346_op_ext_mask) { - case Chip9346_op_write_enable: - rtl8139_log("eeprom write enabled\n"); - break; - case Chip9346_op_write_all: - rtl8139_log("eeprom begin write all\n"); - break; - case Chip9346_op_write_disable: - rtl8139_log("eeprom write disabled\n"); - break; - - default: - break; - } - break; - } -} - -static void -prom9346_shift_clock(EEprom9346 *eeprom) -{ - int bit = eeprom->eedi ? 1 : 0; - - ++eeprom->tick; - - rtl8139_log("eeprom: tick %d eedi=%d eedo=%d\n", eeprom->tick, eeprom->eedi, - eeprom->eedo); - - switch (eeprom->mode) { - case Chip9346_enter_command_mode: - if (bit) { - eeprom->mode = Chip9346_read_command; - eeprom->tick = 0; - eeprom->input = 0; - rtl8139_log("eeprom: +++ synchronized, begin command read\n"); - } - break; - - case Chip9346_read_command: - eeprom->input = (eeprom->input << 1) | (bit & 1); - if (eeprom->tick == 8) { - prom9346_decode_command(eeprom, eeprom->input & 0xff); - } - break; - - case Chip9346_data_read: - eeprom->eedo = (eeprom->output & 0x8000) ? 1 : 0; - eeprom->output <<= 1; - if (eeprom->tick == 16) { -#if 1 - // the FreeBSD drivers (rl and re) don't explicitly toggle - // CS between reads (or does setting Cfg9346 to 0 count too?), - // so we need to enter wait-for-command state here - eeprom->mode = Chip9346_enter_command_mode; - eeprom->input = 0; - eeprom->tick = 0; - - rtl8139_log("eeprom: +++ end of read, awaiting next command\n"); -#else - // original behaviour - ++eeprom->address; - eeprom->address &= EEPROM_9346_ADDR_MASK; - eeprom->output = eeprom->contents[eeprom->address]; - eeprom->tick = 0; - - rtl8139_log("eeprom: +++ read next address 0x%02x data=0x%04x\n", - eeprom->address, eeprom->output); -#endif - } - break; - - case Chip9346_data_write: - eeprom->input = (eeprom->input << 1) | (bit & 1); - if (eeprom->tick == 16) { - rtl8139_log("eeprom write to address 0x%02x data=0x%04x\n", - eeprom->address, eeprom->input); - - eeprom->contents[eeprom->address] = eeprom->input; - eeprom->mode = Chip9346_none; /* waiting for next command after CS cycle */ - eeprom->tick = 0; - eeprom->input = 0; - } - break; - - case Chip9346_data_write_all: - eeprom->input = (eeprom->input << 1) | (bit & 1); - if (eeprom->tick == 16) { - for (int i = 0; i < EEPROM_9346_SIZE; i++) { - eeprom->contents[i] = eeprom->input; - } - rtl8139_log("eeprom filled with data=0x%04x\n", eeprom->input); - - eeprom->mode = Chip9346_enter_command_mode; - eeprom->tick = 0; - eeprom->input = 0; - } - break; - - default: - break; - } -} - -static int -prom9346_get_wire(RTL8139State *s) -{ - const EEprom9346 *eeprom = &s->eeprom; - if (!eeprom->eecs) - return 0; - - return eeprom->eedo; -} - -/* FIXME: This should be merged into/replaced by eeprom93xx.c. */ -static void -prom9346_set_wire(RTL8139State *s, int eecs, int eesk, int eedi) -{ - EEprom9346 *eeprom = &s->eeprom; - uint8_t old_eecs = eeprom->eecs; - uint8_t old_eesk = eeprom->eesk; - - eeprom->eecs = eecs; - eeprom->eesk = eesk; - eeprom->eedi = eedi; - - rtl8139_log("eeprom: +++ wires CS=%d SK=%d DI=%d DO=%d\n", eeprom->eecs, - eeprom->eesk, eeprom->eedi, eeprom->eedo); - - if (!old_eecs && eecs) { - /* Synchronize start */ - eeprom->tick = 0; - eeprom->input = 0; - eeprom->output = 0; - eeprom->mode = Chip9346_enter_command_mode; - - rtl8139_log("=== eeprom: begin access, enter command mode\n"); - } - - if (!eecs) { - rtl8139_log("=== eeprom: end access\n"); - return; - } - - if (!old_eesk && eesk) { - /* SK front rules */ - prom9346_shift_clock(eeprom); - } -} - static void rtl8139_update_irq(RTL8139State *s) { @@ -1436,9 +1221,8 @@ rtl8139_IntrMitigate_read(UNUSED(RTL8139State *s)) static int rtl8139_config_writable(RTL8139State *s) { - if ((s->Cfg9346 & Chip9346_op_mask) == Cfg9346_ConfigWrite) { + if ((s->Cfg9346 & 0xc0) == 0xc0) return 1; - } rtl8139_log("Configuration registers are write-protected\n"); @@ -1520,10 +1304,10 @@ rtl8139_Cfg9346_write(RTL8139State *s, uint32_t val) if (opmode == 0x80) { /* eeprom access */ - int eecs = (eeprom_val & 0x08) ? 1 : 0; - int eesk = (eeprom_val & 0x04) ? 1 : 0; - int eedi = (eeprom_val & 0x02) ? 1 : 0; - prom9346_set_wire(s, eecs, eesk, eedi); + nmc93cxx_eeprom_write(s->eeprom, + !!(eeprom_val & 0x08), + !!(eeprom_val & 0x04), + !!(eeprom_val & 0x02)); } else if (opmode == 0x40) { /* Reset. */ val = 0; @@ -1541,13 +1325,10 @@ rtl8139_Cfg9346_read(RTL8139State *s) uint32_t opmode = ret & 0xc0; if (opmode == 0x80) { - /* eeprom access */ - int eedo = prom9346_get_wire(s); - if (eedo) { + if (nmc93cxx_eeprom_read(s->eeprom)) ret |= 0x01; - } else { + else ret &= ~0x01; - } } rtl8139_log("Cfg9346 read val=0x%02x\n", ret); @@ -3120,70 +2901,103 @@ rtl8139_io_readl(uint32_t addr, void *priv) static uint32_t rtl8139_io_readl_ioport(uint16_t addr, void *priv) { - return rtl8139_io_readl(addr, priv); + uint32_t ret = 0xffffffff; + + ret = rtl8139_io_readl(addr, priv); + + rtl8139_log("[%04X:%08X] [RLI] %04X = %08X\n", CS, cpu_state.pc, addr, ret); + + return ret; } static uint16_t rtl8139_io_readw_ioport(uint16_t addr, void *priv) { - return rtl8139_io_readw(addr, priv); + uint16_t ret = 0xffff; + + ret = rtl8139_io_readw(addr, priv); + + rtl8139_log("[%04X:%08X] [RWI] %04X = %04X\n", CS, cpu_state.pc, addr, ret); + + return ret; } static uint8_t rtl8139_io_readb_ioport(uint16_t addr, void *priv) { - return rtl8139_io_readb(addr, priv); + uint8_t ret = 0xff; + + ret = rtl8139_io_readb(addr, priv); + + rtl8139_log("[%04X:%08X] [RBI] %04X = %02X\n", CS, cpu_state.pc, addr, ret); + + return ret; } static void rtl8139_io_writel_ioport(uint16_t addr, uint32_t val, void *priv) { - return rtl8139_io_writel(addr, val, priv); + rtl8139_log("[%04X:%08X] [WLI] %04X = %08X\n", CS, cpu_state.pc, addr, val); + + rtl8139_io_writel(addr, val, priv); } static void rtl8139_io_writew_ioport(uint16_t addr, uint16_t val, void *priv) { - return rtl8139_io_writew(addr, val, priv); + rtl8139_log("[%04X:%08X] [WWI] %04X = %04X\n", CS, cpu_state.pc, addr, val); + + rtl8139_io_writew(addr, val, priv); } static void rtl8139_io_writeb_ioport(uint16_t addr, uint8_t val, void *priv) { - return rtl8139_io_writeb(addr, val, priv); + rtl8139_log("[%04X:%08X] [WBI] %04X = %02X\n", CS, cpu_state.pc, addr, val); + + rtl8139_io_writeb(addr, val, priv); } static uint32_t rtl8139_io_readl_mem(uint32_t addr, void *priv) { RTL8139State *s = (RTL8139State *) priv; + uint32_t ret = 0xffffffff; - if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) - return 0xffffffff; + if ((addr >= s->mem_base) && (addr < (s->mem_base + 0xff))) + ret = rtl8139_io_readl(addr, priv); - return rtl8139_io_readl(addr, priv); -} + rtl8139_log("[%04X:%08X] [RLM] %08X = %08X\n", CS, cpu_state.pc, addr, ret); + + return ret; + } static uint16_t rtl8139_io_readw_mem(uint32_t addr, void *priv) { RTL8139State *s = (RTL8139State *) priv; + uint16_t ret = 0xffff; - if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) - return 0xffff; + if ((addr >= s->mem_base) && (addr < (s->mem_base + 0xff))) + ret = rtl8139_io_readw(addr, priv); - return rtl8139_io_readw(addr, priv); + rtl8139_log("[%04X:%08X] [RWM] %08X = %04X\n", CS, cpu_state.pc, addr, ret); + + return ret; } static uint8_t rtl8139_io_readb_mem(uint32_t addr, void *priv) { RTL8139State *s = (RTL8139State *) priv; + uint8_t ret = 0xff; - if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) - return 0xff; + if ((addr >= s->mem_base) && (addr < (s->mem_base + 0xff))) + ret = rtl8139_io_readb(addr, priv); - return rtl8139_io_readb(addr, priv); + rtl8139_log("[%04X:%08X] [RBM] %08X = %02X\n", CS, cpu_state.pc, addr, ret); + + return ret; } static void @@ -3191,10 +3005,10 @@ rtl8139_io_writel_mem(uint32_t addr, uint32_t val, void *priv) { RTL8139State *s = (RTL8139State *) priv; - if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) - return; + rtl8139_log("[%04X:%08X] [WLM] %08X = %08X\n", CS, cpu_state.pc, addr, val); - return rtl8139_io_writel(addr, val, priv); + if ((addr >= s->mem_base) && (addr < (s->mem_base + 0xff))) + rtl8139_io_writel(addr, val, priv); } static void @@ -3202,10 +3016,10 @@ rtl8139_io_writew_mem(uint32_t addr, uint16_t val, void *priv) { RTL8139State *s = (RTL8139State *) priv; - if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) - return; + rtl8139_log("[%04X:%08X] [WWM] %08X = %04X\n", CS, cpu_state.pc, addr, val); - return rtl8139_io_writew(addr, val, priv); + if ((addr >= s->mem_base) && (addr < (s->mem_base + 0xff))) + rtl8139_io_writew(addr, val, priv); } static void @@ -3213,10 +3027,10 @@ rtl8139_io_writeb_mem(uint32_t addr, uint8_t val, void *priv) { RTL8139State *s = (RTL8139State *) priv; - if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) - return; + rtl8139_log("[%04X:%08X] [WBM] %08X = %02X\n", CS, cpu_state.pc, addr, val); - return rtl8139_io_writeb(addr, val, priv); + if ((addr >= s->mem_base) && (addr < (s->mem_base + 0xff))) + rtl8139_io_writeb(addr, val, priv); } static int @@ -3343,6 +3157,7 @@ rtl8139_pci_write(int func, int addr, uint8_t val, void *priv) rtl8139_io_writeb_ioport, rtl8139_io_writew_ioport, rtl8139_io_writel_ioport, priv); s->pci_conf[addr & 0xFF] = val; + rtl8139_log("New I/O base: %04X\n", s->pci_conf[0x11] << 8); if (s->pci_conf[0x4] & PCI_COMMAND_IO) io_sethandler((s->pci_conf[0x11] << 8), 256, rtl8139_io_readb_ioport, rtl8139_io_readw_ioport, rtl8139_io_readl_ioport, @@ -3355,6 +3170,7 @@ rtl8139_pci_write(int func, int addr, uint8_t val, void *priv) case 0x17: s->pci_conf[addr & 0xFF] = val; s->mem_base = (s->pci_conf[0x15] << 8) | (s->pci_conf[0x16] << 16) | (s->pci_conf[0x17] << 24); + rtl8139_log("New memory base: %08X\n", s->mem_base); if (s->pci_conf[0x4] & PCI_COMMAND_MEM) mem_mapping_set_addr(&s->bar_mem, (s->pci_conf[0x15] << 8) | (s->pci_conf[0x16] << 16) | (s->pci_conf[0x17] << 24), 256); break; @@ -3368,10 +3184,12 @@ static void * nic_init(const device_t *info) { RTL8139State *s = calloc(1, sizeof(RTL8139State)); - FILE *fp = NULL; + nmc93cxx_eeprom_params_t params; char eeprom_filename[1024] = { 0 }; - uint8_t *mac_bytes; - uint32_t mac; + char filename[1024] = { 0 }; + uint8_t *mac_bytes; + uint16_t *eep_data; + uint32_t mac; mem_mapping_add(&s->bar_mem, 0, 0, rtl8139_io_readb_mem, rtl8139_io_readw_mem, rtl8139_io_readl_mem, @@ -3382,31 +3200,26 @@ nic_init(const device_t *info) snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_rtl8139c_plus_%d.nvr", s->inst); - fp = nvr_fopen(eeprom_filename, "rb"); - if (fp) { - (void) !fread(s->eeprom.contents, 2, 64, fp); - fclose(fp); - fp = NULL; - } else { - /* prepare eeprom */ - s->eeprom.contents[0] = 0x8129; + eep_data = (uint16_t *) s->eeprom_data; - /* PCI vendor and device ID should be mirrored here */ - s->eeprom.contents[1] = 0x10EC; - s->eeprom.contents[2] = 0x8139; + /* prepare eeprom */ + eep_data[0] = 0x8129; - /* XXX: Get proper MAC addresses from real EEPROM dumps. OID taken from net_ne2000.c */ + /* PCI vendor and device ID should be mirrored here */ + eep_data[1] = 0x10EC; + eep_data[2] = 0x8139; + + /* XXX: Get proper MAC addresses from real EEPROM dumps. OID taken from net_ne2000.c */ #ifdef USE_REALTEK_OID - s->eeprom.contents[7] = 0xe000; - s->eeprom.contents[8] = 0x124c; + eep_data[7] = 0xe000; + eep_data[8] = 0x124c; #else - s->eeprom.contents[7] = 0x1400; - s->eeprom.contents[8] = 0x122a; + eep_data[7] = 0x1400; + eep_data[8] = 0x122a; #endif - s->eeprom.contents[9] = 0x1413; - } + eep_data[9] = 0x1413; - mac_bytes = (uint8_t *) &(s->eeprom.contents[7]); + mac_bytes = (uint8_t *) &(eep_data[7]); /* See if we have a local MAC address configured. */ mac = device_get_config_mac("mac", -1); @@ -3430,7 +3243,17 @@ nic_init(const device_t *info) for (uint32_t i = 0; i < 6; i++) s->phys[MAC0 + i] = mac_bytes[i]; - s->nic = network_attach(s, (uint8_t *) &s->eeprom.contents[7], rtl8139_do_receive, rtl8139_set_link_status); + params.nwords = 64; + params.default_content = (uint16_t *) s->eeprom_data; + params.filename = filename; + snprintf(filename, sizeof(filename), "nmc93cxx_eeprom_%s_%d.nvr", info->internal_name, device_get_instance()); + s->eeprom = device_add_parameters(&nmc93cxx_device, ¶ms); + if (!s->eeprom) { + free(s); + return NULL; + } + + s->nic = network_attach(s, (uint8_t *) &s->phys[MAC0], rtl8139_do_receive, rtl8139_set_link_status); timer_add(&s->timer, rtl8139_timer, s, 0); timer_on_auto(&s->timer, 1000000.0 / cpu_pci_speed); @@ -3444,17 +3267,6 @@ nic_init(const device_t *info) static void nic_close(void *priv) { - const RTL8139State *s = (RTL8139State *) priv; - FILE *fp = NULL; - char eeprom_filename[1024] = { 0 }; - - snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_rtl8139c_plus_%d.nvr", s->inst); - fp = nvr_fopen(eeprom_filename, "wb"); - if (fp) { - fwrite(s->eeprom.contents, 2, 64, fp); - fclose(fp); - fp = NULL; - } free(priv); } From 765a1f524ba4352c3b251b1ef84e63e0889b58ee Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 21 Dec 2023 02:03:27 +0600 Subject: [PATCH 088/936] Fix M3D programs --- src/video/vid_mga.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index d0ec17bff..498f2ff9c 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -2686,7 +2686,7 @@ run_dma(mystique_t *mystique) case DMA_STATE_PRI: switch (mystique->dma.primaddress & DMA_MODE_MASK) { case DMA_MODE_REG: - if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; break; @@ -2699,7 +2699,7 @@ run_dma(mystique_t *mystique) words_transferred++; } - if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; break; @@ -2739,7 +2739,7 @@ run_dma(mystique_t *mystique) if (mystique->dma.state == DMA_STATE_SEC) { mystique->dma.sec_state = 0; } - else if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + else if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; } @@ -2753,8 +2753,8 @@ run_dma(mystique_t *mystique) case DMA_STATE_SEC: switch (mystique->dma.secaddress & DMA_MODE_MASK) { case DMA_MODE_REG: - if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { - if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; mystique->dma.pri_state = 0; @@ -2772,8 +2772,8 @@ run_dma(mystique_t *mystique) words_transferred++; } - if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { - if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; mystique->dma.pri_state = 0; @@ -2806,8 +2806,8 @@ run_dma(mystique_t *mystique) mystique->dma.sec_state = (mystique->dma.sec_state + 1) & 3; words_transferred++; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { - if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; mystique->dma.pri_state = 0; @@ -2823,8 +2823,8 @@ run_dma(mystique_t *mystique) case DMA_MODE_BLIT: { uint32_t val; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { - if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; mystique->dma.words_expected = 0; @@ -2843,8 +2843,8 @@ run_dma(mystique_t *mystique) blit_iload_write(mystique, val, 32); words_transferred++; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { - if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; mystique->dma.words_expected = 0; @@ -2877,13 +2877,13 @@ fifo_thread(void *priv) mystique_t *mystique = (mystique_t *) priv; while (mystique->thread_run) { - int words_transferred = 0; thread_set_event(mystique->fifo_not_full_event); thread_wait_event(mystique->wake_fifo_thread, -1); thread_reset_event(mystique->wake_fifo_thread); while (!FIFO_EMPTY || mystique->dma.state != DMA_STATE_IDLE) { - words_transferred = 0; + int words_transferred = 0; + while (!FIFO_EMPTY && words_transferred < 100) { fifo_entry_t *fifo = &mystique->fifo[mystique->fifo_read_idx & FIFO_MASK]; @@ -2910,13 +2910,13 @@ fifo_thread(void *priv) words_transferred++; } - } - /*Only run DMA once the FIFO is empty. Required by - Screamer 2 / Rally which will incorrectly clip an ILOAD - if DMA runs ahead*/ - if (!words_transferred) - run_dma(mystique); + /*Only run DMA once the FIFO is empty. Required by + Screamer 2 / Rally which will incorrectly clip an ILOAD + if DMA runs ahead*/ + if (!words_transferred) + run_dma(mystique); + } } } @@ -2981,7 +2981,7 @@ mystique_softrap_pending_timer(void *priv) } /* Force ENDPRDMASTS flag to be set. */ if (mystique->dma.state == DMA_STATE_IDLE && !(mystique->status & STATUS_ENDPRDMASTS)) - wake_fifo_thread(mystique); + mystique->status |= STATUS_ENDPRDMASTS; } static void From 2d6ffe081e7c9f161e7414179bbaada40ef7f057 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 21 Dec 2023 14:40:32 +0600 Subject: [PATCH 089/936] Matrox Mystique: Force window resizing --- src/video/vid_mga.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 498f2ff9c..de6b1594f 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -717,10 +717,12 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) mystique->crtcext_idx = val; break; case 0x3df: - if (mystique->crtcext_idx < 6) - mystique->crtcext_regs[mystique->crtcext_idx] = val; if (mystique->crtcext_idx == 1) svga->dpms = !!(val & 0x30); + if (mystique->crtcext_idx < 6) { + mystique->crtcext_regs[mystique->crtcext_idx] = val; + svga_recalctimings(&mystique->svga); + } if (mystique->crtcext_idx == 4) { if (svga->gdcreg[6] & 0xc) { /*64k banks*/ @@ -952,6 +954,8 @@ mystique_recalctimings(svga_t *svga) svga->fb_only = svga->packed_chain4; svga->disable_blink = (svga->bpp > 4); + reset_screen_size(); + video_force_resize_set_monitor(1, svga->monitor_index); #if 0 pclog("PackedChain4=%d, chain4=%x, fast=%x, bit6 attrreg10=%02x, bits 5-6 gdcreg5=%02x, extmode=%02x.\n", svga->packed_chain4, svga->chain4, svga->fast, svga->attrregs[0x10] & 0x40, svga->gdcreg[5] & 0x60, mystique->pci_regs[0x41] & 1, mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE); #endif From 082337a381ff70441771b9c59372d9866177ce31 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 21 Dec 2023 13:36:46 +0100 Subject: [PATCH 090/936] Don't call svga_recalctimings() on MGA's port 0x3df, fixes Debian Woody's matroxfb screen test. --- src/video/vid_mga.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index de6b1594f..8ee6e1897 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -719,10 +719,9 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) case 0x3df: if (mystique->crtcext_idx == 1) svga->dpms = !!(val & 0x30); - if (mystique->crtcext_idx < 6) { + if (mystique->crtcext_idx < 6) mystique->crtcext_regs[mystique->crtcext_idx] = val; - svga_recalctimings(&mystique->svga); - } + if (mystique->crtcext_idx == 4) { if (svga->gdcreg[6] & 0xc) { /*64k banks*/ From 011d4b50ec33a8b790af93c42d3a33c4330e23bf Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 21 Dec 2023 15:05:15 +0100 Subject: [PATCH 091/936] Minor pause changes. --- src/86box.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/86box.c b/src/86box.c index 25b073fda..33914d017 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1581,10 +1581,10 @@ do_pause(int p) { int old_p = dopause; - if (p && !old_p) + if ((p == 1) && !old_p) do_pause_ack = p; - dopause = p; - if (p && !old_p) { + dopause = !!p; + if ((p == 1) && !old_p) { while (!atomic_load(&pause_ack)) ; } From 72cb0bedd044ba3ff6b27d6eaff2bdc3fc7aa9bd Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 21 Dec 2023 15:06:04 +0100 Subject: [PATCH 092/936] And QT. --- src/qt/qt_platform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index f306b6138..7ea28a4ce 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -371,7 +371,7 @@ plat_pause(int p) wchar_t title[1024]; wchar_t paused_msg[512]; - if (p == dopause) { + if ((!!p) == dopause) { #ifdef Q_OS_WINDOWS if (source_hwnd) PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSTATUS, (WPARAM) !!p, (LPARAM) (HWND) main_window->winId()); From e469861d2b0d58d315eacf3a78d8544bfc5ccf2d Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 21 Dec 2023 15:06:56 +0100 Subject: [PATCH 093/936] And finally, ACPI. --- src/acpi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/acpi.c b/src/acpi.c index 5672fb135..9521d5337 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -723,7 +723,8 @@ acpi_reg_write_common_regs(UNUSED(int size), uint16_t addr, uint8_t val, void *p /* Since the UI doesn't have a power button at the moment, pause emulation, then trigger a resume event so that the system resumes after unpausing. */ - plat_pause(1); + plat_pause(2); /* 2 means do not wait for pause as + we're already in the CPU thread. */ timer_set_delay_u64(&dev->resume_timer, 50 * TIMER_USEC); } } From 9ca9abebf482b56346f0f02eaaea055ded3e8018 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 22 Dec 2023 14:01:26 +0600 Subject: [PATCH 094/936] MGA: Don't reset screen size every recalctimings Fixes intense resizing. --- src/video/vid_mga.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 8ee6e1897..675abd474 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -953,7 +953,6 @@ mystique_recalctimings(svga_t *svga) svga->fb_only = svga->packed_chain4; svga->disable_blink = (svga->bpp > 4); - reset_screen_size(); video_force_resize_set_monitor(1, svga->monitor_index); #if 0 pclog("PackedChain4=%d, chain4=%x, fast=%x, bit6 attrreg10=%02x, bits 5-6 gdcreg5=%02x, extmode=%02x.\n", svga->packed_chain4, svga->chain4, svga->fast, svga->attrregs[0x10] & 0x40, svga->gdcreg[5] & 0x60, mystique->pci_regs[0x41] & 1, mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE); From 6b7cb3a0d42588bd8ce7715f1daf4e5de2e867b6 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 22 Dec 2023 15:14:53 +0600 Subject: [PATCH 095/936] mystique_line_compare: Return 1 Reduces glitches on M3D, although it doesn't eliminate it completely --- src/video/vid_mga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 8ee6e1897..07b0edfe8 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -805,7 +805,7 @@ mystique_line_compare(svga_t *svga) mystique->status |= STATUS_VLINEPEN; mystique_update_irqs(mystique); - return 0; + return 1; } static void From 816bc6f5598443b6d0220cf5818b3032ec5e5d70 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 22 Dec 2023 11:45:46 +0100 Subject: [PATCH 096/936] Mystique: Only update maback, the change will take place at the next retrace. --- src/video/vid_mga.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 3d6d28bd0..afd075035 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -886,6 +886,7 @@ mystique_recalctimings(svga_t *svga) if (mystique->type >= MGA_1064SG) { /*Mystique, unlike most SVGA cards, allows display start to take effect mid-screen*/ +#ifdef CHANGE_MA if (svga->ma_latch != mystique->ma_latch_old) { if (svga->interlace && svga->oddeven) svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); @@ -893,6 +894,17 @@ mystique_recalctimings(svga_t *svga) svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); mystique->ma_latch_old = svga->ma_latch; } +#else + /* Only change maback so the new display start will take effect on the next + horizontal retrace. */ + if (svga->ma_latch != mystique->ma_latch_old) { + if (svga->interlace && svga->oddeven) + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); + else + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); + mystique->ma_latch_old = svga->ma_latch; + } +#endif svga->rowoffset <<= 1; switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { From bf52c1172b1441a3e72568b8c6d7288ae5670907 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 22 Dec 2023 19:29:42 +0100 Subject: [PATCH 097/936] EGA: Implement PEL panning per hardware features. --- src/video/vid_ega.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index da77449b0..7cd6c6f17 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -108,6 +108,8 @@ ega_out(uint16_t addr, uint8_t val, void *priv) ega_recalctimings(ega); } } else { + if ((ega->attraddr == 0x13) && (ega->attrregs[0x13] != val)) + ega->fullchange = changeframecount; o = ega->attrregs[ega->attraddr & 31]; ega->attrregs[ega->attraddr & 31] = val; if (ega->attraddr < 16) From 524fd30c0c2d1d7e044562ee14e15b8132fa0cb9 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 22 Dec 2023 19:43:51 +0100 Subject: [PATCH 098/936] ATI Mach8/32 fixes regarding 1992 ATI Ultra drivers for Windows 3.1x: 1. For some reason, background colors were always black under those drivers in 8bpp mode, added a tweak to fix it (as well as Clock colors). 2. Likewise for the red scrolling in pbrush or write, added a tweak to its bitblt read mask. 3. Don't call svga_recalctimings in the hdisp/vdisp ports directly, fixes screen size on said drivers without affecting other stuff. --- src/video/vid_8514a.c | 8 +++++--- src/video/vid_ati_mach8.c | 10 +++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 7e476663c..469a4555e 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -2940,9 +2940,11 @@ rect_fill: } else { while (count-- && dev->accel.sy >= 0) { if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + switch (frgd_mix) { case 0: src_dat = bkgd_color; + if (!bkgd_mix && (dev->accel.cmd & 0x40) && ((dev->accel.frgd_mix & 0x1f) == 7) && ((dev->accel.bkgd_mix & 0x1f) == 3) && !dev->bpp && (bkgd_color == 0x00)) /*For some reason, the September 1992 Mach8/32 drivers for Win3.x don't set the background colors properly.*/ + src_dat = frgd_color; break; case 1: src_dat = frgd_color; @@ -2962,7 +2964,7 @@ rect_fill: if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); + MIX(1, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); WRITE(dev->accel.dest + dev->accel.cx, dest_dat); } @@ -3740,7 +3742,7 @@ bitblt: case 3: READ(dev->accel.src + dev->accel.cx, src_dat); if (pixcntl == 3) { - if (dev->accel.cmd & 0x10) { + if ((dev->accel.cmd & 0x10) && !(dev->accel.cmd & 0x40)) { src_dat = ((src_dat & rd_mask) == rd_mask); } } diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 89abde977..5b8dedfbe 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -3628,7 +3628,9 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x6e8: case 0x6e9: if (!(port & 1)) { - dev->hdisp = val; + if (!dev->on[0] || !dev->on[1]) + dev->hdisp = val; + mach_log("ATI 8514/A: H_DISP write 06E8 = %d\n", dev->hdisp + 1); } svga_recalctimings(svga); @@ -3653,8 +3655,10 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x16e8: case 0x16e9: - WRITE8(port, dev->vdisp, val); - dev->vdisp &= 0x1fff; + if (!dev->on[0] || !dev->on[1]) { + WRITE8(port, dev->vdisp, val); + dev->vdisp &= 0x1fff; + } svga_recalctimings(svga); break; From ad6ddfb31e157eb979a32157785a61abb6457fb3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 22 Dec 2023 23:11:24 +0100 Subject: [PATCH 099/936] Mystique and Millennium: Revert the ma change. --- src/video/vid_mga.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index afd075035..3d6d28bd0 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -886,7 +886,6 @@ mystique_recalctimings(svga_t *svga) if (mystique->type >= MGA_1064SG) { /*Mystique, unlike most SVGA cards, allows display start to take effect mid-screen*/ -#ifdef CHANGE_MA if (svga->ma_latch != mystique->ma_latch_old) { if (svga->interlace && svga->oddeven) svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); @@ -894,17 +893,6 @@ mystique_recalctimings(svga_t *svga) svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); mystique->ma_latch_old = svga->ma_latch; } -#else - /* Only change maback so the new display start will take effect on the next - horizontal retrace. */ - if (svga->ma_latch != mystique->ma_latch_old) { - if (svga->interlace && svga->oddeven) - svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); - else - svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); - mystique->ma_latch_old = svga->ma_latch; - } -#endif svga->rowoffset <<= 1; switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { From ede2ce91028a78641769303c38a21efc3ef566d9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 22 Dec 2023 23:12:25 +0100 Subject: [PATCH 100/936] And reverted it again. --- src/video/vid_mga.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 3d6d28bd0..afd075035 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -886,6 +886,7 @@ mystique_recalctimings(svga_t *svga) if (mystique->type >= MGA_1064SG) { /*Mystique, unlike most SVGA cards, allows display start to take effect mid-screen*/ +#ifdef CHANGE_MA if (svga->ma_latch != mystique->ma_latch_old) { if (svga->interlace && svga->oddeven) svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); @@ -893,6 +894,17 @@ mystique_recalctimings(svga_t *svga) svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); mystique->ma_latch_old = svga->ma_latch; } +#else + /* Only change maback so the new display start will take effect on the next + horizontal retrace. */ + if (svga->ma_latch != mystique->ma_latch_old) { + if (svga->interlace && svga->oddeven) + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); + else + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); + mystique->ma_latch_old = svga->ma_latch; + } +#endif svga->rowoffset <<= 1; switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { From 539f9a06a57e45b019c23f960bdca94ac42ca11a Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 22 Dec 2023 23:21:57 +0100 Subject: [PATCH 101/936] Mystique: Disable line compare, turns out it was disabled for a reason. --- src/video/vid_mga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index afd075035..eb3a28fc9 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -805,7 +805,7 @@ mystique_line_compare(svga_t *svga) mystique->status |= STATUS_VLINEPEN; mystique_update_irqs(mystique); - return 1; + return 0; } static void From 7bba9cee78894aab4497cc4c7243fb311ddc9737 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 23 Dec 2023 14:03:18 +0600 Subject: [PATCH 102/936] Matrox Mystique: Fix display flickering issues for real Direct3D tests under Windows 95 do not flicker anymore, and the MSICUBE sample program renders correctly. --- src/video/vid_mga.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index eb3a28fc9..7e077209a 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -722,6 +722,28 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) if (mystique->crtcext_idx < 6) mystique->crtcext_regs[mystique->crtcext_idx] = val; + if (mystique->crtcext_idx == 0 && (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE)) + { + svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); + if (mystique->type >= MGA_1064SG) + svga->rowoffset <<= 1; + svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; + if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { + svga->rowoffset <<= 1; + svga->ma_latch <<= 1; + } + if (mystique->type >= MGA_1064SG) { + svga->ma_latch <<= 1; + if (svga->ma_latch != mystique->ma_latch_old) { + if (svga->interlace && svga->oddeven) + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); + else + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); + mystique->ma_latch_old = svga->ma_latch; + } + } + } + if (mystique->crtcext_idx == 4) { if (svga->gdcreg[6] & 0xc) { /*64k banks*/ @@ -886,6 +908,7 @@ mystique_recalctimings(svga_t *svga) if (mystique->type >= MGA_1064SG) { /*Mystique, unlike most SVGA cards, allows display start to take effect mid-screen*/ + svga->ma_latch <<= 1; #ifdef CHANGE_MA if (svga->ma_latch != mystique->ma_latch_old) { if (svga->interlace && svga->oddeven) @@ -2767,7 +2790,7 @@ run_dma(mystique_t *mystique) case DMA_STATE_SEC: switch (mystique->dma.secaddress & DMA_MODE_MASK) { case DMA_MODE_REG: - if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; @@ -2786,7 +2809,7 @@ run_dma(mystique_t *mystique) words_transferred++; } - if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; @@ -2820,7 +2843,7 @@ run_dma(mystique_t *mystique) mystique->dma.sec_state = (mystique->dma.sec_state + 1) & 3; words_transferred++; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; @@ -2837,7 +2860,7 @@ run_dma(mystique_t *mystique) case DMA_MODE_BLIT: { uint32_t val; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; @@ -2857,7 +2880,7 @@ run_dma(mystique_t *mystique) blit_iload_write(mystique, val, 32); words_transferred++; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; From 94dfb353c0f5291f2f25abf8c53a2f8abd66c3dc Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 23 Dec 2023 14:21:50 +0600 Subject: [PATCH 103/936] Fix NASCAR Racing 1994 regression --- src/video/vid_mga.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 7e077209a..b69a65063 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -725,8 +725,7 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) if (mystique->crtcext_idx == 0 && (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE)) { svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); - if (mystique->type >= MGA_1064SG) - svga->rowoffset <<= 1; + svga->rowoffset <<= 1; svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { svga->rowoffset <<= 1; From 28775d2583af3b7bb6eba2b04ce1f3cc1ee846f6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 23 Dec 2023 14:11:46 +0100 Subject: [PATCH 104/936] Millennium: Do not ignore the interlace bit. --- src/video/vid_mga.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index b69a65063..2720bea68 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -887,9 +887,10 @@ mystique_recalctimings(svga_t *svga) if (mystique->crtcext_regs[2] & CRTCX_R2_LINECOMP10) svga->split |= 0x400; - if (mystique->type == MGA_2064W) + if (mystique->type == MGA_2064W) { tvp3026_recalctimings(svga->ramdac, svga); - else + svga->interlace |= !!(mystique->crtcext_regs[0] & 0x80); + } else svga->interlace = !!(mystique->crtcext_regs[0] & 0x80); if (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) { From 012527fc4e31f1970fca83dfc0d6687f03b2cd99 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 23 Dec 2023 15:02:15 +0100 Subject: [PATCH 105/936] MGA flicker fixes. It's time to end the flickers once and for all by making the start address correctly emulated in vblank_start when in power graphics mode. --- src/video/vid_mga.c | 81 ++++++++++++++++++--------------------------- 1 file changed, 32 insertions(+), 49 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 2720bea68..98e45fd2f 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -722,27 +722,6 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) if (mystique->crtcext_idx < 6) mystique->crtcext_regs[mystique->crtcext_idx] = val; - if (mystique->crtcext_idx == 0 && (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE)) - { - svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); - svga->rowoffset <<= 1; - svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; - if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { - svga->rowoffset <<= 1; - svga->ma_latch <<= 1; - } - if (mystique->type >= MGA_1064SG) { - svga->ma_latch <<= 1; - if (svga->ma_latch != mystique->ma_latch_old) { - if (svga->interlace && svga->oddeven) - svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); - else - svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); - mystique->ma_latch_old = svga->ma_latch; - } - } - } - if (mystique->crtcext_idx == 4) { if (svga->gdcreg[6] & 0xc) { /*64k banks*/ @@ -829,6 +808,33 @@ mystique_line_compare(svga_t *svga) return 0; } +static void +mystique_vblank_start(svga_t *svga) +{ + mystique_t *mystique = (mystique_t *) svga->priv; + + if (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) { + svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; + if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) + svga->ma_latch <<= 1; + + if (mystique->type >= MGA_1064SG) { + /*Mystique, unlike most SVGA cards, allows display start to take + effect mid-screen*/ + svga->ma_latch <<= 1; + /* Only change maback so the new display start will take effect on the next + horizontal retrace. */ + if (svga->ma_latch != mystique->ma_latch_old) { + if (svga->interlace && svga->oddeven) + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); + else + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); + mystique->ma_latch_old = svga->ma_latch; + } + } + } +} + static void mystique_vsync_callback(svga_t *svga) { @@ -896,39 +902,14 @@ mystique_recalctimings(svga_t *svga) if (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) { svga->lowres = 0; svga->char_width = 8; - svga->hdisp = (svga->crtc[1] + 1) * 8; + svga->hdisp = (svga->crtc[1] + 1) << 3; svga->hdisp_time = svga->hdisp; svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); - svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; - if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { + + if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) svga->rowoffset <<= 1; - svga->ma_latch <<= 1; - } if (mystique->type >= MGA_1064SG) { - /*Mystique, unlike most SVGA cards, allows display start to take - effect mid-screen*/ - svga->ma_latch <<= 1; -#ifdef CHANGE_MA - if (svga->ma_latch != mystique->ma_latch_old) { - if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); - else - svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); - mystique->ma_latch_old = svga->ma_latch; - } -#else - /* Only change maback so the new display start will take effect on the next - horizontal retrace. */ - if (svga->ma_latch != mystique->ma_latch_old) { - if (svga->interlace && svga->oddeven) - svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); - else - svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); - mystique->ma_latch_old = svga->ma_latch; - } -#endif - svga->rowoffset <<= 1; switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { case XMULCTRL_DEPTH_8: @@ -979,9 +960,11 @@ mystique_recalctimings(svga_t *svga) } svga->packed_chain4 = 1; svga->line_compare = mystique_line_compare; + svga->vblank_start = mystique_vblank_start; } else { svga->packed_chain4 = 0; svga->line_compare = NULL; + svga->vblank_start = NULL; if (mystique->type >= MGA_1064SG) svga->bpp = 8; } From 708a700abde20c8e438db4acb23ec1e5f5d68eba Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 23 Dec 2023 15:27:08 +0100 Subject: [PATCH 106/936] Mystique: Made the changes apply only to the Millennium. --- src/video/vid_mga.c | 67 ++++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 19 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 98e45fd2f..45ecd012f 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -722,7 +722,31 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) if (mystique->crtcext_idx < 6) mystique->crtcext_regs[mystique->crtcext_idx] = val; - if (mystique->crtcext_idx == 4) { + if ((mystique->type >= MGA_1064SG) && (mystique->crtcext_idx == 0) && + (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE)) { + svga->rowoffset = svga->crtc[0x13] | + ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); + svga->rowoffset <<= 1; + svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | + (svga->crtc[0xc] << 8) | svga->crtc[0xd]; + if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { + svga->rowoffset <<= 1; + svga->ma_latch <<= 1; + } + + svga->ma_latch <<= 1; + if (svga->ma_latch != mystique->ma_latch_old) { + if (svga->interlace && svga->oddeven) + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + + (svga->ma_latch << 2) + (svga->rowoffset << 1); + else + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + + (svga->ma_latch << 2); + mystique->ma_latch_old = svga->ma_latch; + } + } + + if (mystique->crtcext_idx == 4) { if (svga->gdcreg[6] & 0xc) { /*64k banks*/ svga->read_bank = (val & 0x7f) << 16; @@ -817,21 +841,6 @@ mystique_vblank_start(svga_t *svga) svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) svga->ma_latch <<= 1; - - if (mystique->type >= MGA_1064SG) { - /*Mystique, unlike most SVGA cards, allows display start to take - effect mid-screen*/ - svga->ma_latch <<= 1; - /* Only change maback so the new display start will take effect on the next - horizontal retrace. */ - if (svga->ma_latch != mystique->ma_latch_old) { - if (svga->interlace && svga->oddeven) - svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); - else - svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); - mystique->ma_latch_old = svga->ma_latch; - } - } } } @@ -906,10 +915,28 @@ mystique_recalctimings(svga_t *svga) svga->hdisp_time = svga->hdisp; svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); - if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) + if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { svga->rowoffset <<= 1; + if (mystique->type >= MGA_1064SG) + svga->ma_latch <<= 1; + } if (mystique->type >= MGA_1064SG) { + /*Mystique, unlike most SVGA cards, allows display start to take + effect mid-screen*/ + svga->ma_latch <<= 1; + /* Only change maback so the new display start will take effect on the next + horizontal retrace. */ + if (svga->ma_latch != mystique->ma_latch_old) { + if (svga->interlace && svga->oddeven) + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + + (svga->ma_latch << 2) + (svga->rowoffset << 1); + else + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + + (svga->ma_latch << 2); + mystique->ma_latch_old = svga->ma_latch; + } + svga->rowoffset <<= 1; switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { case XMULCTRL_DEPTH_8: @@ -960,13 +987,15 @@ mystique_recalctimings(svga_t *svga) } svga->packed_chain4 = 1; svga->line_compare = mystique_line_compare; - svga->vblank_start = mystique_vblank_start; + if (mystique->type < MGA_1064SG) + svga->vblank_start = mystique_vblank_start; } else { svga->packed_chain4 = 0; svga->line_compare = NULL; - svga->vblank_start = NULL; if (mystique->type >= MGA_1064SG) svga->bpp = 8; + else + svga->vblank_start = NULL; } svga->fb_only = svga->packed_chain4; From 933f402cc9aad4e41da5f1060dd6b19caea573c0 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 23 Dec 2023 13:27:25 -0500 Subject: [PATCH 107/936] Un-dev matrox mystique --- CMakeLists.txt | 1 - src/include/86box/video.h | 2 -- src/video/CMakeLists.txt | 4 ---- src/video/vid_mga.c | 2 -- src/video/vid_table.c | 2 -- src/win/Makefile.mingw | 10 ---------- 6 files changed, 21 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d9f92add3..4bc020f15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -153,7 +153,6 @@ cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF) cmake_dependent_option(LASERXT "VTech Laser XT" ON "DEV_BRANCH" OFF) -cmake_dependent_option(MGA "Matrox Mystique graphics adapters" ON "DEV_BRANCH" OFF) cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF) cmake_dependent_option(PAS16 "Pro Audio Spectrum 16" ON "DEV_BRANCH" OFF) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 396b39124..921b8e778 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -433,10 +433,8 @@ extern const device_t pgc_device; /* Matrox MGA */ extern const device_t millennium_device; -# if defined(DEV_BRANCH) && defined(USE_MGA) extern const device_t mystique_device; extern const device_t mystique_220_device; -# endif /* Oak OTI-0x7 */ extern const device_t oti037c_device; diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index 6635252a6..638837757 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -28,10 +28,6 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_mga.c vid_nga.c vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c) -if(MGA) - target_compile_definitions(vid PRIVATE USE_MGA) -endif() - if(VGAWONDER) target_compile_definitions(vid PRIVATE USE_VGAWONDER) endif() diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 45ecd012f..4a4d9169e 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5945,7 +5945,6 @@ const device_t millennium_device = { .config = mystique_config }; -#if defined(DEV_BRANCH) && defined(USE_MGA) const device_t mystique_device = { .name = "Matrox Mystique", .internal_name = "mystique", @@ -5973,4 +5972,3 @@ const device_t mystique_220_device = { .force_redraw = mystique_force_redraw, .config = mystique_config }; -#endif diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 0131fa3a4..ad6fca2c6 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -205,10 +205,8 @@ video_cards[] = { { &s3_diamond_stealth_4000_pci_device }, { &s3_trio3d2x_pci_device }, { &millennium_device }, -#if defined(DEV_BRANCH) && defined(USE_MGA) { &mystique_device }, { &mystique_220_device }, -#endif { &tgui9440_pci_device }, { &tgui9660_pci_device }, { &tgui9680_pci_device }, diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 13dbdcefe..8e4b99b56 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -64,9 +64,6 @@ ifeq ($(DEV_BUILD), y) ifndef LASERXT LASERXT := y endif - ifndef MGA - MGA := y - endif ifndef OLIVETTI OLIVETTI := y endif @@ -128,9 +125,6 @@ else ifndef LASERXT LASERXT := n endif - ifndef MGA - MGA := n - endif ifndef OLIVETTI OLIVETTI := n endif @@ -496,10 +490,6 @@ ifeq ($(DEV_BRANCH), y) DEVBROBJ += m_xt_laserxt.o endif - ifeq ($(MGA), y) - OPTS += -DUSE_MGA - endif - ifeq ($(OPEN_AT), y) OPTS += -DUSE_OPEN_AT endif From 70d6d5954bd65dd7123c9d2f0fd6c7a302f37396 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 24 Dec 2023 01:46:10 +0600 Subject: [PATCH 108/936] MGA: Implement gamma correction for 24+ bpp modes --- src/include/86box/vid_svga.h | 3 ++ src/include/86box/video.h | 3 ++ src/video/vid_mga.c | 2 + src/video/vid_svga_render.c | 80 +++++++++++++++++++++--------------- 4 files changed, 55 insertions(+), 33 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 682a66111..52a9c9b0a 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -268,6 +268,9 @@ typedef struct svga_t { /* Pointer to monitor */ monitor_t *monitor; + /* Enable LUT mapping of >= 24 bpp modes. */ + int lut_map; + void * dev8514; void * xga; } svga_t; diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 396b39124..4d8302982 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -32,6 +32,9 @@ using atomic_int = std::atomic_int; #define makecol(r, g, b) ((b) | ((g) << 8) | ((r) << 16)) #define makecol32(r, g, b) ((b) | ((g) << 8) | ((r) << 16)) +#define getcolr(color) (((color) >> 16) & 0xFF) +#define getcolg(color) (((color) >> 8) & 0xFF) +#define getcolb(color) ((color) & 0xFF) enum { VID_NONE = 0, diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 45ecd012f..1f93c339e 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -914,6 +914,7 @@ mystique_recalctimings(svga_t *svga) svga->hdisp = (svga->crtc[1] + 1) << 3; svga->hdisp_time = svga->hdisp; svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); + svga->lut_map = 1; if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { svga->rowoffset <<= 1; @@ -992,6 +993,7 @@ mystique_recalctimings(svga_t *svga) } else { svga->packed_chain4 = 0; svga->line_compare = NULL; + svga->lut_map = 0; if (mystique->type >= MGA_1064SG) svga->bpp = 8; else diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 7a15dc1cf..e94916fd5 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -30,6 +30,20 @@ #include <86box/vid_svga_render.h> #include <86box/vid_svga_render_remap.h> +static inline uint32_t +lookup_lut_ram(svga_t* svga, uint32_t val) +{ + if (!svga->lut_map) + return val; + + uint8_t r = getcolr(svga->pallook[getcolr(val)]); + uint8_t g = getcolg(svga->pallook[getcolg(val)]); + uint8_t b = getcolb(svga->pallook[getcolb(val)]); + return makecol32(r, g, b) | (val & 0xFF000000); +} + +#define lookup_lut(val) lookup_lut_ram(svga, val) + void svga_render_null(svga_t *svga) { @@ -1422,7 +1436,7 @@ svga_render_24bpp_lowres(svga_t *svga) fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); svga->ma += 3; svga->ma &= svga->vram_display_mask; - svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = fg; + svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = lookup_lut(fg); } } } else { @@ -1441,10 +1455,10 @@ svga_render_24bpp_lowres(svga_t *svga) dat1 = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); dat2 = *(uint32_t *) (&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); - p[0] = p[1] = dat0 & 0xffffff; - p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16); - p[6] = p[7] = dat2 >> 8; + p[0] = p[1] = lookup_lut(dat0 & 0xffffff); + p[2] = p[3] = lookup_lut((dat0 >> 24) | ((dat1 & 0xffff) << 8)); + p[4] = p[5] = lookup_lut((dat1 >> 16) | ((dat2 & 0xff) << 16)); + p[6] = p[7] = lookup_lut(dat2 >> 8); svga->ma += 12; } @@ -1457,10 +1471,10 @@ svga_render_24bpp_lowres(svga_t *svga) addr = svga->remap_func(svga, svga->ma + 8); dat2 = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - p[0] = p[1] = dat0 & 0xffffff; - p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16); - p[6] = p[7] = dat2 >> 8; + p[0] = p[1] = lookup_lut(dat0 & 0xffffff); + p[2] = p[3] = lookup_lut((dat0 >> 24) | ((dat1 & 0xffff) << 8)); + p[4] = p[5] = lookup_lut((dat1 >> 16) | ((dat2 & 0xff) << 16)); + p[6] = p[7] = lookup_lut(dat2 >> 8); svga->ma += 12; } @@ -1495,16 +1509,16 @@ svga_render_24bpp_highres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); - p[x] = dat & 0xffffff; + p[x] = lookup_lut(dat & 0xffffff); dat = *(uint32_t *) (&svga->vram[(svga->ma + 3) & svga->vram_display_mask]); - p[x + 1] = dat & 0xffffff; + p[x + 1] = lookup_lut(dat & 0xffffff); dat = *(uint32_t *) (&svga->vram[(svga->ma + 6) & svga->vram_display_mask]); - p[x + 2] = dat & 0xffffff; + p[x + 2] = lookup_lut(dat & 0xffffff); dat = *(uint32_t *) (&svga->vram[(svga->ma + 9) & svga->vram_display_mask]); - p[x + 3] = dat & 0xffffff; + p[x + 3] = lookup_lut(dat & 0xffffff); svga->ma += 12; } @@ -1526,10 +1540,10 @@ svga_render_24bpp_highres(svga_t *svga) dat1 = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); dat2 = *(uint32_t *) (&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); - *p++ = dat0 & 0xffffff; - *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); - *p++ = dat2 >> 8; + *p++ = lookup_lut(dat0 & 0xffffff); + *p++ = lookup_lut((dat0 >> 24) | ((dat1 & 0xffff) << 8)); + *p++ = lookup_lut((dat1 >> 16) | ((dat2 & 0xff) << 16)); + *p++ = lookup_lut(dat2 >> 8); svga->ma += 12; } @@ -1542,10 +1556,10 @@ svga_render_24bpp_highres(svga_t *svga) addr = svga->remap_func(svga, svga->ma + 8); dat2 = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = dat0 & 0xffffff; - *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); - *p++ = dat2 >> 8; + *p++ = lookup_lut(dat0 & 0xffffff); + *p++ = lookup_lut((dat0 >> 24) | ((dat1 & 0xffff) << 8)); + *p++ = lookup_lut((dat1 >> 16) | ((dat2 & 0xff) << 16)); + *p++ = lookup_lut(dat2 >> 8); svga->ma += 12; } @@ -1577,7 +1591,7 @@ svga_render_32bpp_lowres(svga_t *svga) dat = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); svga->ma += 4; svga->ma &= svga->vram_display_mask; - svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = dat; + svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = lookup_lut(dat); } } } else { @@ -1593,16 +1607,16 @@ svga_render_32bpp_lowres(svga_t *svga) if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - *p++ = dat & 0xffffff; - *p++ = dat & 0xffffff; + *p++ = lookup_lut(dat & 0xffffff); + *p++ = lookup_lut(dat & 0xffffff); } svga->ma += (x * 4); } else { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = dat & 0xffffff; - *p++ = dat & 0xffffff; + *p++ = lookup_lut(dat & 0xffffff); + *p++ = lookup_lut(dat & 0xffffff); svga->ma += 4; } svga->ma &= svga->vram_display_mask; @@ -1633,7 +1647,7 @@ svga_render_32bpp_highres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - p[x] = dat & 0xffffff; + p[x] = lookup_lut(dat & 0xffffff); } svga->ma += 4; svga->ma &= svga->vram_display_mask; @@ -1651,14 +1665,14 @@ svga_render_32bpp_highres(svga_t *svga) if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - *p++ = dat & 0xffffff; + *p++ = lookup_lut(dat & 0xffffff); } svga->ma += (x * 4); } else { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = dat & 0xffffff; + *p++ = lookup_lut(dat & 0xffffff); svga->ma += 4; } @@ -1692,14 +1706,14 @@ svga_render_ABGR8888_highres(svga_t *svga) if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + *p++ = lookup_lut(((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16)); } svga->ma += x * 4; } else { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + *p++ = lookup_lut(((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16)); svga->ma += 4; } @@ -1732,14 +1746,14 @@ svga_render_RGBA8888_highres(svga_t *svga) if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - *p++ = dat >> 8; + *p++ = lookup_lut(dat >> 8); } svga->ma += (x * 4); } else { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = dat >> 8; + *p++ = lookup_lut(dat >> 8); svga->ma += 4; } From 0a55e75b06fda425e493377d1487bd27905a770b Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 24 Dec 2023 02:16:51 +0600 Subject: [PATCH 109/936] MGA: Gamma-correct hardware cursor --- src/include/86box/vid_svga.h | 2 ++ src/video/vid_mga.c | 2 +- src/video/vid_svga_render.c | 6 +++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 52a9c9b0a..709641457 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -337,6 +337,8 @@ enum { RAMDAC_8BIT }; +uint32_t svga_lookup_lut_ram(svga_t* svga, uint32_t val); + /* We need a way to add a device with a pointer to a parent device so it can attach itself to it, and possibly also a second ATi 68860 RAM DAC type that auto-sets SVGA render on RAM DAC render change. */ extern void ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga); diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 1f93c339e..a04187fbe 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5404,7 +5404,7 @@ mystique_hwcursor_draw(svga_t *svga, int displine) case XCURCTRL_CURMODE_XGA: for (uint8_t x = 0; x < 64; x++) { if (!(dat[1] & (1ULL << 63))) - svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 63)) ? mystique->cursor.col[1] : mystique->cursor.col[0]; + svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, mystique->cursor.col[1]) : svga_lookup_lut_ram(svga, mystique->cursor.col[0]); else if (dat[0] & (1ULL << 63)) svga->monitor->target_buffer->line[displine][offset + svga->x_add] ^= 0xffffff; diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index e94916fd5..18e0438fd 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -30,8 +30,8 @@ #include <86box/vid_svga_render.h> #include <86box/vid_svga_render_remap.h> -static inline uint32_t -lookup_lut_ram(svga_t* svga, uint32_t val) +uint32_t +svga_lookup_lut_ram(svga_t* svga, uint32_t val) { if (!svga->lut_map) return val; @@ -42,7 +42,7 @@ lookup_lut_ram(svga_t* svga, uint32_t val) return makecol32(r, g, b) | (val & 0xFF000000); } -#define lookup_lut(val) lookup_lut_ram(svga, val) +#define lookup_lut(val) svga_lookup_lut_ram(svga, val) void svga_render_null(svga_t *svga) From 7701caf2312da6602cf6d13c5d03ca2d8a212a4e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 24 Dec 2023 14:18:55 +0600 Subject: [PATCH 110/936] Mystique: Fix flickering display on Direct3D --- src/video/vid_mga.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 74a81741b..119d3ad15 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -915,6 +915,7 @@ mystique_recalctimings(svga_t *svga) svga->hdisp_time = svga->hdisp; svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); svga->lut_map = 1; + svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { svga->rowoffset <<= 1; From 0eb2b2915e5541430b6ec7a34f67fbc0b8040d3a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 24 Dec 2023 14:22:23 +0600 Subject: [PATCH 111/936] Don't apply to Millennium --- src/video/vid_mga.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 119d3ad15..2eb129c07 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -915,7 +915,8 @@ mystique_recalctimings(svga_t *svga) svga->hdisp_time = svga->hdisp; svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); svga->lut_map = 1; - svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; + if (mystique->type >= MGA_1064SG) + svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { svga->rowoffset <<= 1; From c933b24f8b5853709196c9069cd8d0b9dc7bab14 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 24 Dec 2023 23:00:57 +0100 Subject: [PATCH 112/936] FDD: Return nothing on timeout, makes IBM PC and XT actually return Not ready instead of General failure when the drive is not ready. --- src/floppy/fdd.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 09e791c4e..ef489c445 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -563,8 +563,10 @@ fdd_poll(void *priv) if (fdd_notfound) { fdd_notfound--; +#ifdef RETURN_NOIDAM if (!fdd_notfound) fdc_noidam(fdd_fdc); +#endif } } @@ -606,6 +608,8 @@ fdd_reset(void) void fdd_readsector(int drive, int sector, int track, int side, int density, int sector_size) { + pclog("readsector = %08X\n", drives[drive].readsector); + if (drives[drive].readsector) drives[drive].readsector(drive, sector, track, side, density, sector_size); else From db788c6580f0d2d2a36f608fdfa4a9f83268133c Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 24 Dec 2023 23:01:55 +0100 Subject: [PATCH 113/936] Removed an excess logging line from floppy/fdd.c. --- src/floppy/fdd.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index ef489c445..845a6f35e 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -608,8 +608,6 @@ fdd_reset(void) void fdd_readsector(int drive, int sector, int track, int side, int density, int sector_size) { - pclog("readsector = %08X\n", drives[drive].readsector); - if (drives[drive].readsector) drives[drive].readsector(drive, sector, track, side, density, sector_size); else From 278661c41c2a85725e3ee36ef28e1da9a7713180 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 25 Dec 2023 14:05:07 +0600 Subject: [PATCH 114/936] Mystique: Don't do busmastering until SOFTRAP status is read MSICUBE sample for Windows 9x no longer freezes the entire VM after a while --- src/video/vid_mga.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 2eb129c07..4bc0f97f9 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -440,7 +440,10 @@ typedef struct mystique_t { uint32_t vram_mask, vram_mask_w, vram_mask_l, lfb_base, ctrl_base, iload_base, ma_latch_old, maccess, mctlwtst, maccess_running, - status, softrap_pending_val; + softrap_pending_val; + + atomic_uint status; + atomic_bool softrap_status_read; uint64_t blitter_time, status_time; @@ -1483,13 +1486,16 @@ mystique_ctrl_read_b(uint32_t addr, void *priv) ret = mystique->status & 0xff; if (svga->cgastat & 8) ret |= REG_STATUS_VSYNCSTS; + if (ret & 1) + mystique->softrap_status_read = 1; break; case REG_STATUS + 1: ret = (mystique->status >> 8) & 0xff; break; case REG_STATUS + 2: ret = (mystique->status >> 16) & 0xff; - if (mystique->busy || ((mystique->blitter_submit_refcount + mystique->blitter_submit_dma_refcount) != mystique->blitter_complete_refcount) || !FIFO_EMPTY) + if (mystique->busy || ((mystique->blitter_submit_refcount + mystique->blitter_submit_dma_refcount) != mystique->blitter_complete_refcount) || !FIFO_EMPTY + || mystique->dma.state != DMA_STATE_IDLE || mystique->softrap_pending || mystique->endprdmasts_pending) ret |= (STATUS_DWGENGSTS >> 16); break; case REG_STATUS + 3: @@ -2724,6 +2730,12 @@ run_dma(mystique_t *mystique) thread_wait_mutex(mystique->dma.lock); + if (mystique->softrap_pending || mystique->endprdmasts_pending || !mystique->softrap_status_read) + { + thread_release_mutex(mystique->dma.lock); + return; + } + if (mystique->dma.state == DMA_STATE_IDLE) { if (!(mystique->status & STATUS_ENDPRDMASTS)) { @@ -3025,16 +3037,14 @@ mystique_softrap_pending_timer(void *priv) mystique->status |= STATUS_ENDPRDMASTS; } if (mystique->softrap_pending) { - mystique->softrap_pending--; - mystique->dma.secaddress = mystique->softrap_pending_val; mystique->status |= STATUS_SOFTRAPEN; + mystique->softrap_status_read = 0; //pclog("softrapen\n"); mystique_update_irqs(mystique); + mystique->softrap_pending--; } - /* Force ENDPRDMASTS flag to be set. */ - if (mystique->dma.state == DMA_STATE_IDLE && !(mystique->status & STATUS_ENDPRDMASTS)) - mystique->status |= STATUS_ENDPRDMASTS; + } static void @@ -5838,6 +5848,8 @@ mystique_init(const device_t *info) timer_add(&mystique->softrap_pending_timer, mystique_softrap_pending_timer, (void *) mystique, 1); mystique->status = STATUS_ENDPRDMASTS; + + mystique->softrap_status_read = 1; mystique->svga.vsync_callback = mystique_vsync_callback; From 1bd4bbdfa1f7352b11f0b0f2b63ff8d9602b9d0a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 25 Dec 2023 15:24:52 +0600 Subject: [PATCH 115/936] MGA: Implement gamma-correction for <= 16 bpp modes --- src/include/86box/vid_svga.h | 3 + src/video/vid_mga.c | 26 +++++++ src/video/vid_svga.c | 7 ++ src/video/vid_svga_render.c | 136 +++++++++++++++++------------------ 4 files changed, 104 insertions(+), 68 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 709641457..fc6c02c20 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -271,6 +271,9 @@ typedef struct svga_t { /* Enable LUT mapping of >= 24 bpp modes. */ int lut_map; + /* Return a 32 bpp color from a 15/16 bpp color. */ + uint32_t (*conv_16to32)(struct svga_t *svga, uint16_t color, uint8_t bpp); + void * dev8514; void * xga; } svga_t; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 4bc0f97f9..f0cbad9eb 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5728,6 +5728,31 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) } } +static uint32_t +mystique_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) +{ + mystique_t *mystique = (mystique_t*)svga->priv; + + if (svga->lut_map) { + if (bpp == 15) { + if (mystique->xgenctrl & (1 << 2)) { + color &= 0x7FFF; + } + uint8_t b = getcolr(svga->pallook[(color & 0x1F) | (!!(color & 0x8000) >> 8)]); + uint8_t g = getcolg(svga->pallook[((color & 0x3E0) >> 5) | (!!(color & 0x8000) >> 8)]); + uint8_t r = getcolb(svga->pallook[((color & 0x7C00) >> 10) | (!!(color & 0x8000) >> 8)]); + return video_15to32[color] & 0xFF000000 | makecol(r, g, b); + } else { + uint8_t b = getcolr(svga->pallook[color & 0x1f]); + uint8_t g = getcolg(svga->pallook[(color & 0x7e0) >> 5]); + uint8_t r = getcolb(svga->pallook[(color & 0xf800) >> 11]); + return video_16to32[color] & 0xFF000000 | makecol(r, g, b); + } + } + + return (bpp == 15) ? video_15to32[color] : video_16to32[color]; +} + static void * mystique_init(const device_t *info) { @@ -5852,6 +5877,7 @@ mystique_init(const device_t *info) mystique->softrap_status_read = 1; mystique->svga.vsync_callback = mystique_vsync_callback; + mystique->svga.conv_16to32 = mystique_conv_16to32; mystique->i2c = i2c_gpio_init("i2c_mga"); mystique->i2c_ddc = i2c_gpio_init("ddc_mga"); diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 1479ea718..be53a0170 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1102,6 +1102,12 @@ svga_poll(void *priv) } } +uint32_t +svga_conv_16to32(struct svga_t *svga, uint16_t color, uint8_t bpp) +{ + return (bpp == 15) ? video_15to32[color] : video_16to32[color]; +} + int svga_init(const device_t *info, svga_t *svga, void *priv, int memsize, void (*recalctimings_ex)(struct svga_t *svga), @@ -1148,6 +1154,7 @@ svga_init(const device_t *info, svga_t *svga, void *priv, int memsize, svga->video_out = video_out; svga->hwcursor_draw = hwcursor_draw; svga->overlay_draw = overlay_draw; + svga->conv_16to32 = svga_conv_16to32; svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = 32; diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 18e0438fd..e3f4bff5e 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -1042,13 +1042,13 @@ svga_render_15bpp_lowres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x << 1] = p[(x << 1) + 1] = video_15to32[dat & 0xffff]; - p[(x << 1) + 2] = p[(x << 1) + 3] = video_15to32[dat >> 16]; + p[x << 1] = p[(x << 1) + 1] = svga->conv_16to32(svga, dat & 0xffff, 15); + p[(x << 1) + 2] = p[(x << 1) + 3] = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[(x << 1) + 4] = p[(x << 1) + 5] = video_15to32[dat & 0xffff]; - p[(x << 1) + 6] = p[(x << 1) + 7] = video_15to32[dat >> 16]; + p[(x << 1) + 4] = p[(x << 1) + 5] = svga->conv_16to32(svga, dat & 0xffff, 15); + p[(x << 1) + 6] = p[(x << 1) + 7] = svga->conv_16to32(svga, dat >> 16, 15); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -1067,13 +1067,13 @@ svga_render_15bpp_lowres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); } svga->ma += x << 1; } else { @@ -1081,8 +1081,8 @@ svga_render_15bpp_lowres(svga_t *svga) addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); svga->ma += 4; } } @@ -1113,20 +1113,20 @@ svga_render_15bpp_highres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = video_15to32[dat & 0xffff]; - p[x + 1] = video_15to32[dat >> 16]; + p[x] = svga->conv_16to32(svga, dat & 0xffff, 15); + p[x + 1] = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = video_15to32[dat & 0xffff]; - p[x + 3] = video_15to32[dat >> 16]; + p[x + 2] = svga->conv_16to32(svga, dat & 0xffff, 15); + p[x + 3] = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = video_15to32[dat & 0xffff]; - p[x + 5] = video_15to32[dat >> 16]; + p[x + 4] = svga->conv_16to32(svga, dat & 0xffff, 15); + p[x + 5] = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = video_15to32[dat & 0xffff]; - p[x + 7] = video_15to32[dat >> 16]; + p[x + 6] = svga->conv_16to32(svga, dat & 0xffff, 15); + p[x + 7] = svga->conv_16to32(svga, dat >> 16, 15); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -1144,20 +1144,20 @@ svga_render_15bpp_highres(svga_t *svga) if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); } svga->ma += x << 1; } else { @@ -1165,8 +1165,8 @@ svga_render_15bpp_highres(svga_t *svga) addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); svga->ma += 4; } } @@ -1194,16 +1194,16 @@ svga_render_15bpp_mix_lowres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x << 1] = p[(x << 1) + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x << 1] = p[(x << 1) + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat >>= 16; - p[(x << 1) + 2] = p[(x << 1) + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[(x << 1) + 2] = p[(x << 1) + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[(x << 1) + 4] = p[(x << 1) + 5] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[(x << 1) + 4] = p[(x << 1) + 5] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat >>= 16; - p[(x << 1) + 6] = p[(x << 1) + 7] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[(x << 1) + 6] = p[(x << 1) + 7] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -1229,24 +1229,24 @@ svga_render_15bpp_mix_highres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat >>= 16; - p[x + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x + 2] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat >>= 16; - p[x + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x + 4] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat >>= 16; - p[x + 5] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x + 5] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x + 6] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat >>= 16; - p[x + 7] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x + 7] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -1275,12 +1275,12 @@ svga_render_16bpp_lowres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x << 1] = p[(x << 1) + 1] = video_16to32[dat & 0xffff]; - p[(x << 1) + 2] = p[(x << 1) + 3] = video_16to32[dat >> 16]; + p[x << 1] = p[(x << 1) + 1] = svga->conv_16to32(svga, dat & 0xffff, 16); + p[(x << 1) + 2] = p[(x << 1) + 3] = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[(x << 1) + 4] = p[(x << 1) + 5] = video_16to32[dat & 0xffff]; - p[(x << 1) + 6] = p[(x << 1) + 7] = video_16to32[dat >> 16]; + p[(x << 1) + 4] = p[(x << 1) + 5] = svga->conv_16to32(svga, dat & 0xffff, 16); + p[(x << 1) + 6] = p[(x << 1) + 7] = svga->conv_16to32(svga, dat >> 16, 16); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -1299,13 +1299,13 @@ svga_render_16bpp_lowres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); } svga->ma += x << 1; } else { @@ -1313,8 +1313,8 @@ svga_render_16bpp_lowres(svga_t *svga) addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); } svga->ma += 4; } @@ -1345,20 +1345,20 @@ svga_render_16bpp_highres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { uint32_t dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = video_16to32[dat & 0xffff]; - p[x + 1] = video_16to32[dat >> 16]; + p[x] = svga->conv_16to32(svga, dat & 0xffff, 16); + p[x + 1] = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = video_16to32[dat & 0xffff]; - p[x + 3] = video_16to32[dat >> 16]; + p[x + 2] = svga->conv_16to32(svga, dat & 0xffff, 16); + p[x + 3] = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = video_16to32[dat & 0xffff]; - p[x + 5] = video_16to32[dat >> 16]; + p[x + 4] = svga->conv_16to32(svga, dat & 0xffff, 16); + p[x + 5] = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = video_16to32[dat & 0xffff]; - p[x + 7] = video_16to32[dat >> 16]; + p[x + 6] = svga->conv_16to32(svga, dat & 0xffff, 16); + p[x + 7] = svga->conv_16to32(svga, dat >> 16, 16); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -1376,20 +1376,20 @@ svga_render_16bpp_highres(svga_t *svga) if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); } svga->ma += x << 1; } else { @@ -1397,8 +1397,8 @@ svga_render_16bpp_highres(svga_t *svga) addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); svga->ma += 4; } From e812b3c3b1cd0db1a33d8fc0e5a0f5015b3adda0 Mon Sep 17 00:00:00 2001 From: Alexander Babikov <2708460+lemondrops@users.noreply.github.com> Date: Mon, 25 Dec 2023 07:05:02 +0500 Subject: [PATCH 116/936] ESC/P: Use the new dot matrix font Also remove the fallback to Courier as it's no longer needed --- src/include/86box/printer.h | 2 +- src/printer/prt_escp.c | 11 ----------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/src/include/86box/printer.h b/src/include/86box/printer.h index eb6eb4a75..8efba343e 100644 --- a/src/include/86box/printer.h +++ b/src/include/86box/printer.h @@ -46,7 +46,7 @@ #ifndef PRINTER_H #define PRINTER_H -#define FONT_FILE_DOTMATRIX "dotmatrix.ttf" +#define FONT_FILE_DOTMATRIX "dotmatrix.otf" #define FONT_FILE_ROMAN "roman.ttf" #define FONT_FILE_SANSSERIF "sansserif.ttf" diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index c11479786..cd0279078 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -545,17 +545,6 @@ update_font(escp_t *dev) if (FT_New_Face(ft_lib, path, 0, &dev->fontface)) { escp_log("ESC/P: unable to load font '%s'\n", path); dev->fontface = NULL; - - /* Try to fall back to Courier in case the dot matrix font is absent. */ - if (!strcmp(fn, FONT_FILE_DOTMATRIX)) { - strcpy(path, dev->fontpath); - path_slash(path); - strcat(path, FONT_FILE_COURIER); - if (FT_New_Face(ft_lib, path, 0, &dev->fontface)) { - escp_log("ESC/P: unable to load font '%s'\n", path); - dev->fontface = NULL; - } - } } if (!dev->multipoint_mode) { From a9d96371dcbbf8872900230b9e43958508d4067e Mon Sep 17 00:00:00 2001 From: Alexander Babikov <2708460+lemondrops@users.noreply.github.com> Date: Mon, 25 Dec 2023 07:06:39 +0500 Subject: [PATCH 117/936] ESC/P: Add workaround for glyphs with negative offsets Fixes characters disappearing when printed very close to the paper edges --- src/printer/prt_escp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index cd0279078..6ae706cc8 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -1578,8 +1578,8 @@ handle_char(escp_t *dev, uint8_t ch) FT_Render_Glyph(dev->fontface->glyph, FT_RENDER_MODE_NORMAL); } - pen_x = PIXX + dev->fontface->glyph->bitmap_left; - pen_y = (uint16_t) (PIXY - dev->fontface->glyph->bitmap_top + dev->fontface->size->metrics.ascender / 64); + pen_x = PIXX + fmax(0.0, dev->fontface->glyph->bitmap_left); + pen_y = (uint16_t) (PIXY + fmax(0.0, -dev->fontface->glyph->bitmap_top + dev->fontface->size->metrics.ascender / 64)); if (dev->font_style & STYLE_SUBSCRIPT) pen_y += dev->fontface->glyph->bitmap.rows / 2; From aab48daff79d2a35c6246a5f954d5e22208834b3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 25 Dec 2023 13:10:48 +0100 Subject: [PATCH 118/936] Fixed the two warnings in video/vid_mga.c. --- src/video/vid_mga.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index f0cbad9eb..19720f674 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5732,25 +5732,26 @@ static uint32_t mystique_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) { mystique_t *mystique = (mystique_t*)svga->priv; + uint32_t ret = 0x00000000; if (svga->lut_map) { if (bpp == 15) { - if (mystique->xgenctrl & (1 << 2)) { + if (mystique->xgenctrl & (1 << 2)) color &= 0x7FFF; - } uint8_t b = getcolr(svga->pallook[(color & 0x1F) | (!!(color & 0x8000) >> 8)]); uint8_t g = getcolg(svga->pallook[((color & 0x3E0) >> 5) | (!!(color & 0x8000) >> 8)]); uint8_t r = getcolb(svga->pallook[((color & 0x7C00) >> 10) | (!!(color & 0x8000) >> 8)]); - return video_15to32[color] & 0xFF000000 | makecol(r, g, b); + ret = (video_15to32[color] & 0xFF000000) | makecol(r, g, b); } else { uint8_t b = getcolr(svga->pallook[color & 0x1f]); uint8_t g = getcolg(svga->pallook[(color & 0x7e0) >> 5]); uint8_t r = getcolb(svga->pallook[(color & 0xf800) >> 11]); - return video_16to32[color] & 0xFF000000 | makecol(r, g, b); + ret = (video_16to32[color] & 0xFF000000) | makecol(r, g, b); } - } - - return (bpp == 15) ? video_15to32[color] : video_16to32[color]; + } else + ret = (bpp == 15) ? video_15to32[color] : video_16to32[color]; + + return ret; } static void * From 7ff4fd355fd0426bb2dd9e67ff85bd5382d00167 Mon Sep 17 00:00:00 2001 From: Alexander Babikov <2708460+lemondrops@users.noreply.github.com> Date: Mon, 25 Dec 2023 17:33:43 +0500 Subject: [PATCH 119/936] ESC/P: Add handling for a separate italic dot matrix font --- src/include/86box/printer.h | 3 ++- src/printer/prt_escp.c | 11 +++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/include/86box/printer.h b/src/include/86box/printer.h index 8efba343e..b576fbf27 100644 --- a/src/include/86box/printer.h +++ b/src/include/86box/printer.h @@ -46,7 +46,8 @@ #ifndef PRINTER_H #define PRINTER_H -#define FONT_FILE_DOTMATRIX "dotmatrix.otf" +#define FONT_FILE_DOTMATRIX "dotmatrix.otf" +#define FONT_FILE_DOTMATRIX_ITALIC "dotmatrix_italic.otf" #define FONT_FILE_ROMAN "roman.ttf" #define FONT_FILE_SANSSERIF "sansserif.ttf" diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index 6ae706cc8..2349c67a1 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -508,9 +508,12 @@ update_font(escp_t *dev) if (dev->fontface) FT_Done_Face(dev->fontface); - if (dev->print_quality == QUALITY_DRAFT) - fn = FONT_FILE_DOTMATRIX; - else + if (dev->print_quality == QUALITY_DRAFT) { + if (dev->font_style & STYLE_ITALICS) + fn = FONT_FILE_DOTMATRIX_ITALIC; + else + fn = FONT_FILE_DOTMATRIX; + } else switch (dev->lq_typeface) { case TYPEFACE_ROMAN: fn = FONT_FILE_ROMAN; @@ -592,7 +595,7 @@ update_font(escp_t *dev) (uint16_t) (hpoints * 64), (uint16_t) (vpoints * 64), dev->dpi, dev->dpi); - if ((dev->font_style & STYLE_ITALICS) || (dev->char_tables[dev->curr_char_table] == 0)) { + if ((dev->print_quality != QUALITY_DRAFT) && ((dev->font_style & STYLE_ITALICS) || (dev->char_tables[dev->curr_char_table] == 0))) { /* Italics transformation. */ matrix.xx = 0x10000L; matrix.xy = (FT_Fixed) (0.20 * 0x10000L); From 8b4c93fdfe031fbb11c5bbf83d850dd105b5e3d1 Mon Sep 17 00:00:00 2001 From: Alexander Babikov <2708460+lemondrops@users.noreply.github.com> Date: Mon, 25 Dec 2023 07:07:13 +0500 Subject: [PATCH 120/936] ESC/P: Set draft print quality by default --- src/printer/prt_escp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index 2349c67a1..8247ecfab 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -437,6 +437,7 @@ reset_printer(escp_t *dev) dev->cpi = PAGE_CPI; dev->curr_char_table = 1; dev->font_style = 0; + dev->print_quality = QUALITY_DRAFT; dev->extra_intra_space = 0.0; dev->print_upper_control = 1; dev->bg_remaining_bytes = 0; From 7678a86d6c55f7549acd9884f24e8a6499b5ec7d Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Dec 2023 02:21:48 +0100 Subject: [PATCH 121/936] MGA: LUT enable/disable and corrected 15bpp gamma correction. --- src/video/vid_mga.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 19720f674..49d44c06d 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -234,6 +234,7 @@ #define XREG_XPIXPLLSTAT 0x4f #define XMISCCTRL_VGA8DAC (1 << 3) +#define XMISCCTRL_RAMCS (1 << 4) #define XMULCTRL_DEPTH_MASK (7 << 0) #define XMULCTRL_DEPTH_8 (0 << 0) @@ -917,7 +918,7 @@ mystique_recalctimings(svga_t *svga) svga->hdisp = (svga->crtc[1] + 1) << 3; svga->hdisp_time = svga->hdisp; svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); - svga->lut_map = 1; + svga->lut_map = !!(mystique->xmiscctrl & XMISCCTRL_RAMCS); if (mystique->type >= MGA_1064SG) svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; @@ -1321,6 +1322,8 @@ mystique_write_xreg(mystique_t *mystique, int reg, uint8_t val) case XREG_XMISCCTRL: mystique->xmiscctrl = val; svga_set_ramdac_type(svga, (val & XMISCCTRL_VGA8DAC) ? RAMDAC_8BIT : RAMDAC_6BIT); + if (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) + svga->lut_map = !!(mystique->xmiscctrl & XMISCCTRL_RAMCS); break; case XREG_XGENCTRL: @@ -5738,15 +5741,21 @@ mystique_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) if (bpp == 15) { if (mystique->xgenctrl & (1 << 2)) color &= 0x7FFF; +#if 0 uint8_t b = getcolr(svga->pallook[(color & 0x1F) | (!!(color & 0x8000) >> 8)]); uint8_t g = getcolg(svga->pallook[((color & 0x3E0) >> 5) | (!!(color & 0x8000) >> 8)]); uint8_t r = getcolb(svga->pallook[((color & 0x7C00) >> 10) | (!!(color & 0x8000) >> 8)]); - ret = (video_15to32[color] & 0xFF000000) | makecol(r, g, b); +#else + uint8_t b = getcolr(svga->pallook[color & 0x1f]); + uint8_t g = getcolg(svga->pallook[(color & 0x3e0) >> 5]); + uint8_t r = getcolb(svga->pallook[(color & 0x7c00) >> 10]); +#endif + ret = video_15to32[color] & 0xFF000000 | makecol(r, g, b); } else { uint8_t b = getcolr(svga->pallook[color & 0x1f]); uint8_t g = getcolg(svga->pallook[(color & 0x7e0) >> 5]); uint8_t r = getcolb(svga->pallook[(color & 0xf800) >> 11]); - ret = (video_16to32[color] & 0xFF000000) | makecol(r, g, b); + ret = video_16to32[color] & 0xFF000000 | makecol(r, g, b); } } else ret = (bpp == 15) ? video_15to32[color] : video_16to32[color]; From f0f52279c45a917a7e5eaf93f1ff09ce047e40ff Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 27 Dec 2023 02:48:55 +0100 Subject: [PATCH 122/936] Restore correct CGA compatible mode behavior in (S)VGA. --- src/video/vid_svga.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index be53a0170..449c1b33c 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -618,7 +618,7 @@ svga_recalctimings(svga_t *svga) svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); svga->ca_adj = 0; - svga->rowcount = svga->crtc[9] & 31; + svga->rowcount = svga->crtc[9] & 0x1f; svga->hdisp_time = svga->hdisp; svga->render = svga_render_blank; @@ -639,27 +639,26 @@ svga_recalctimings(svga_t *svga) svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; svga->hdisp_old = svga->hdisp; - if ((svga->bpp <= 8) || ((svga->gdcreg[5] & 0x60) == 0x00)) { + if ((svga->bpp <= 8) || ((svga->gdcreg[5] & 0x60) <= 0x20)) { if ((svga->gdcreg[5] & 0x60) == 0x00) { if (svga->seqregs[1] & 8) /*Low res (320)*/ svga->render = svga_render_4bpp_lowres; else svga->render = svga_render_4bpp_highres; + } else if ((svga->gdcreg[5] & 0x60) == 0x20) { + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; + else + svga->render = svga_render_2bpp_highres; } else { svga->map8 = svga->pallook; - if (svga->attrregs[0x10] & 0x40) /*Low res (320)*/ + if (svga->lowres) /*Low res (320)*/ svga->render = svga_render_8bpp_lowres; else svga->render = svga_render_8bpp_highres; } } else { switch (svga->gdcreg[5] & 0x60) { - case 0x20: /*4 colours*/ - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_2bpp_lowres; - else - svga->render = svga_render_2bpp_highres; - break; case 0x40: case 0x60: /*256+ colours*/ switch (svga->bpp) { From c597a44c87587112bb755559da5400c24463bda1 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 27 Dec 2023 14:44:58 +0600 Subject: [PATCH 123/936] Mystique: Make sure dxdiag on D3D 9.0b doesn't crash the emulator on Win98SE --- src/video/vid_mga.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 49d44c06d..2b5c92ed3 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -2511,6 +2511,16 @@ mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) //mystique->dma.pri_state = 0; wake_fifo_thread(mystique); } + /* HACK: For DirectX 9.0b Direct3D testing on Windows 98 SE. + + The 4.12.013 drivers give an out-of-bounds busmastering range when dxdiag enumerates Direct3D, with exactly 16384 bytes of difference. + Don't attempt busmastering in such cases. This isn't ideal, but there are no more crashes faced in this case. */ + if ((mystique->dma.primend & DMA_ADDR_MASK) < (mystique->dma.primaddress & DMA_ADDR_MASK) && ((mystique->dma.primaddress & DMA_ADDR_MASK) - (mystique->dma.primend & DMA_ADDR_MASK)) == 0x4000) + { + mystique->dma.primaddress = mystique->dma.primend; + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + } thread_release_mutex(mystique->dma.lock); break; From d9a571c179611178dc5d2ed6142ad8f3b39a7a04 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Dec 2023 15:37:37 +0100 Subject: [PATCH 124/936] A small preparation in vid_svga. --- src/include/86box/vid_svga.h | 1 + src/video/vid_svga.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index fc6c02c20..f55ec930c 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -231,6 +231,7 @@ typedef struct svga_t { uint8_t dac_status; uint8_t dpms; uint8_t dpms_ui; + uint8_t color_4bpp; uint8_t ksc5601_sbyte_mask; uint8_t ksc5601_udc_area_msb[2]; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index be53a0170..ed93a6f3d 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -174,8 +174,10 @@ svga_out(uint16_t addr, uint8_t val, void *priv) svga->fullchange = svga->monitor->mon_changeframecount; o = svga->attrregs[svga->attraddr & 31]; svga->attrregs[svga->attraddr & 31] = val; - if (svga->attraddr < 16) + if (svga->attraddr < 16) { + svga->color_4bpp = (val >> 4) & 0x03; svga->fullchange = svga->monitor->mon_changeframecount; + } if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) { for (int c = 0; c < 16; c++) { if (svga->attrregs[0x10] & 0x80) { From 2002f8e34e1d1a679d9495cd5f8a25cbe6293b94 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Dec 2023 15:38:43 +0100 Subject: [PATCH 125/936] Fixed the variable's name. --- src/include/86box/vid_svga.h | 2 +- src/video/vid_svga.c | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index f55ec930c..b44f101cb 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -231,7 +231,7 @@ typedef struct svga_t { uint8_t dac_status; uint8_t dpms; uint8_t dpms_ui; - uint8_t color_4bpp; + uint8_t color_2bpp; uint8_t ksc5601_sbyte_mask; uint8_t ksc5601_udc_area_msb[2]; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 94759ae5d..c41624bf7 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -175,7 +175,7 @@ svga_out(uint16_t addr, uint8_t val, void *priv) o = svga->attrregs[svga->attraddr & 31]; svga->attrregs[svga->attraddr & 31] = val; if (svga->attraddr < 16) { - svga->color_4bpp = (val >> 4) & 0x03; + svga->color_2bpp = (val >> 4) & 0x03; svga->fullchange = svga->monitor->mon_changeframecount; } if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) { @@ -620,7 +620,7 @@ svga_recalctimings(svga_t *svga) svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); svga->ca_adj = 0; - svga->rowcount = svga->crtc[9] & 0x1f; + svga->rowcount = svga->crtc[9] & 31; svga->hdisp_time = svga->hdisp; svga->render = svga_render_blank; @@ -641,26 +641,27 @@ svga_recalctimings(svga_t *svga) svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; svga->hdisp_old = svga->hdisp; - if ((svga->bpp <= 8) || ((svga->gdcreg[5] & 0x60) <= 0x20)) { + if ((svga->bpp <= 8) || ((svga->gdcreg[5] & 0x60) == 0x00)) { if ((svga->gdcreg[5] & 0x60) == 0x00) { if (svga->seqregs[1] & 8) /*Low res (320)*/ svga->render = svga_render_4bpp_lowres; else svga->render = svga_render_4bpp_highres; - } else if ((svga->gdcreg[5] & 0x60) == 0x20) { - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_2bpp_lowres; - else - svga->render = svga_render_2bpp_highres; } else { svga->map8 = svga->pallook; - if (svga->lowres) /*Low res (320)*/ + if (svga->attrregs[0x10] & 0x40) /*Low res (320)*/ svga->render = svga_render_8bpp_lowres; else svga->render = svga_render_8bpp_highres; } } else { switch (svga->gdcreg[5] & 0x60) { + case 0x20: /*4 colours*/ + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; + else + svga->render = svga_render_2bpp_highres; + break; case 0x40: case 0x60: /*256+ colours*/ switch (svga->bpp) { From 35450fe632444f8b38d9edc0ae4c2447a2743843 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Dec 2023 15:47:42 +0100 Subject: [PATCH 126/936] Restored some previously reverted changes. --- src/video/vid_svga.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index c41624bf7..9f125fb72 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -620,7 +620,7 @@ svga_recalctimings(svga_t *svga) svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); svga->ca_adj = 0; - svga->rowcount = svga->crtc[9] & 31; + svga->rowcount = svga->crtc[9] & 0x1f; svga->hdisp_time = svga->hdisp; svga->render = svga_render_blank; @@ -641,27 +641,26 @@ svga_recalctimings(svga_t *svga) svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; svga->hdisp_old = svga->hdisp; - if ((svga->bpp <= 8) || ((svga->gdcreg[5] & 0x60) == 0x00)) { + if ((svga->bpp <= 8) || ((svga->gdcreg[5] & 0x60) <= 0x20)) { if ((svga->gdcreg[5] & 0x60) == 0x00) { if (svga->seqregs[1] & 8) /*Low res (320)*/ svga->render = svga_render_4bpp_lowres; else svga->render = svga_render_4bpp_highres; + } else if ((svga->gdcreg[5] & 0x60) == 0x20) { + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; + else + svga->render = svga_render_2bpp_highres; } else { svga->map8 = svga->pallook; - if (svga->attrregs[0x10] & 0x40) /*Low res (320)*/ + if (svga->lowres) /*Low res (320)*/ svga->render = svga_render_8bpp_lowres; else svga->render = svga_render_8bpp_highres; } } else { switch (svga->gdcreg[5] & 0x60) { - case 0x20: /*4 colours*/ - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_2bpp_lowres; - else - svga->render = svga_render_2bpp_highres; - break; case 0x40: case 0x60: /*256+ colours*/ switch (svga->bpp) { From c240db50ba58eb0862cb087301cfffd98c9a084a Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Dec 2023 15:49:13 +0100 Subject: [PATCH 127/936] Restored some accidentally reverted parentheses. --- src/video/vid_mga.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 2b5c92ed3..35354b2ad 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5760,12 +5760,12 @@ mystique_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) uint8_t g = getcolg(svga->pallook[(color & 0x3e0) >> 5]); uint8_t r = getcolb(svga->pallook[(color & 0x7c00) >> 10]); #endif - ret = video_15to32[color] & 0xFF000000 | makecol(r, g, b); + ret = (video_15to32[color] & 0xFF000000) | makecol(r, g, b); } else { uint8_t b = getcolr(svga->pallook[color & 0x1f]); uint8_t g = getcolg(svga->pallook[(color & 0x7e0) >> 5]); uint8_t r = getcolb(svga->pallook[(color & 0xf800) >> 11]); - ret = video_16to32[color] & 0xFF000000 | makecol(r, g, b); + ret = (video_16to32[color] & 0xFF000000) | makecol(r, g, b); } } else ret = (bpp == 15) ? video_15to32[color] : video_16to32[color]; From 1798b2e51ca2fd201ba22b6f40f890f8d70bcaa1 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 27 Dec 2023 16:07:03 +0100 Subject: [PATCH 128/936] ATI VGA mode fixes: 1. Fixed 4-bit packed modes. 2. Preparation of fixing the 2-bit modes. 3. Extra: fixed the accelerator mode switches again (Mach8/32 only). --- src/include/86box/vid_svga.h | 2 + src/video/vid_ati18800.c | 22 +++++++-- src/video/vid_ati28800.c | 91 ++++++++++++------------------------ src/video/vid_ati_mach8.c | 42 ++++++++++++----- 4 files changed, 82 insertions(+), 75 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index b44f101cb..3e7c6f3fe 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -128,6 +128,8 @@ typedef struct svga_t { int hblank_sub; int hblank_end_val; int hblank_end_len; + int packed_4bpp; + int ati_4color; /*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_ati18800.c b/src/video/vid_ati18800.c index 09e813bab..b54f6b89e 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -186,8 +186,22 @@ ati18800_recalctimings(svga_t *svga) svga->gdcreg[5] &= ~0x40; } - if (ati18800->regs[0xb0] & 6) + if (ati18800->regs[0xb0] & 6) { svga->gdcreg[5] |= 0x40; + if ((ati18800->regs[0xb6] & 0x18) >= 0x10) + svga->packed_4bpp = 1; + else + svga->packed_4bpp = 0; + } else + svga->packed_4bpp = 0; + + if ((ati18800->regs[0xb6] & 0x18) == 8) { + svga->hdisp <<= 1; + svga->htotal <<= 1; + svga->ati_4color = 1; + } else + svga->ati_4color = 0; + if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { @@ -215,8 +229,10 @@ ati18800_recalctimings(svga_t *svga) svga->render = svga_render_8bpp_lowres; else { svga->render = svga_render_8bpp_highres; - svga->ma_latch <<= 1; - svga->rowoffset <<= 1; + if (!svga->packed_4bpp) { + svga->ma_latch <<= 1; + svga->rowoffset <<= 1; + } } break; } diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index aa5800d1c..09d6279f4 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -400,7 +400,10 @@ ati28800k_in(uint16_t addr, void *priv) static void ati28800_recalctimings(svga_t *svga) { - const ati28800_t *ati28800 = (ati28800_t *) svga->priv; + ati28800_t *ati28800 = (ati28800_t *) svga->priv; + int clock_sel; + + clock_sel = ((svga->miscout >> 2) & 3) | ((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1); if (ati28800->regs[0xa3] & 0x10) svga->ma_latch |= 0x10000; @@ -408,66 +411,13 @@ ati28800_recalctimings(svga_t *svga) if (ati28800->regs[0xb0] & 0x40) svga->ma_latch |= 0x20000; - switch (((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1) | ((svga->miscout & 0x0C) >> 2)) { - case 0x00: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 42954000.0; - break; - case 0x01: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 48771000.0; - break; - case 0x02: - ati28800_log("clock 2\n"); - break; - case 0x03: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 36000000.0; - break; - case 0x04: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 50350000.0; - break; - case 0x05: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 56640000.0; - break; - case 0x06: - ati28800_log("clock 2\n"); - break; - case 0x07: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; - break; - case 0x08: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 30240000.0; - break; - case 0x09: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 32000000.0; - break; - case 0x0A: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 37500000.0; - break; - case 0x0B: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 39000000.0; - break; - case 0x0C: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 50350000.0; - break; - case 0x0D: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 56644000.0; - break; - case 0x0E: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 75000000.0; - break; - case 0x0F: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 65000000.0; - break; - default: - break; - } - if (ati28800->regs[0xb8] & 0x40) svga->clock *= 2; if (ati28800->regs[0xa7] & 0x80) svga->clock *= 3; - if (ati28800->regs[0xb6] & 0x10) { + if ((ati28800->regs[0xb6] & 0x18) >= 0x10) { svga->hdisp <<= 1; svga->htotal <<= 1; svga->rowoffset <<= 1; @@ -476,10 +426,24 @@ ati28800_recalctimings(svga_t *svga) if (ati28800->regs[0xb0] & 0x20) { svga->gdcreg[5] |= 0x40; - } + if ((ati28800->regs[0xb6] & 0x18) >= 0x10) + svga->packed_4bpp = 1; + else + svga->packed_4bpp = 0; + } else + svga->packed_4bpp = 0; - if (!svga->scrblank && svga->attr_palette_enable) { - if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + if ((ati28800->regs[0xb6] & 0x18) == 8) { + svga->hdisp <<= 1; + svga->htotal <<= 1; + svga->ati_4color = 1; + } else + svga->ati_4color = 0; + + if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen); + ati28800_log("SEQREG1 bit 3=%x. gdcreg5 bits 5-6=%02x, 4bit pel=%02x, planar 16color=%02x, apa mode=%02x, attregs10 bit 7=%02x.\n", svga->seqregs[1] & 8, svga->gdcreg[5] & 0x60, ati28800->regs[0xb3] & 0x40, ati28800->regs[0xac] & 0x40, ati28800->regs[0xb6] & 0x18, ati28800->svga.attrregs[0x10] & 0x80); switch (svga->gdcreg[5] & 0x60) { case 0x00: if (svga->seqregs[1] & 8) /*Low res (320)*/ @@ -502,8 +466,10 @@ ati28800_recalctimings(svga_t *svga) svga->render = svga_render_8bpp_lowres; else { svga->render = svga_render_8bpp_highres; - svga->rowoffset <<= 1; - svga->ma_latch <<= 1; + if (!svga->packed_4bpp) { + svga->ma_latch <<= 1; + svga->rowoffset <<= 1; + } } break; case 15: @@ -516,7 +482,6 @@ ati28800_recalctimings(svga_t *svga) svga->ma_latch <<= 1; } break; - default: break; } @@ -586,6 +551,8 @@ ati28800k_init(const device_t *info) ati28800k_in, ati28800k_out, NULL, NULL); + ati28800->svga.clock_gen = device_add(&ati18810_device); + ati28800->svga.getclock = ics2494_getclock; io_sethandler(0x01ce, 0x0002, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); io_sethandler(0x03c0, 0x0020, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); @@ -652,6 +619,8 @@ ati28800_init(const device_t *info) ati28800_in, ati28800_out, NULL, NULL); + ati28800->svga.clock_gen = device_add(&ati18810_device); + ati28800->svga.getclock = ics2494_getclock; io_sethandler(0x01ce, 2, ati28800_in, NULL, NULL, diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 5b8dedfbe..e9118bfbc 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2579,15 +2579,30 @@ mach_recalctimings(svga_t *svga) if (mach->regs[0xb0] & 0x40) svga->ma_latch |= 0x20000; - if (mach->regs[0xb6] & 0x10) { + if ((mach->regs[0xb6] & 0x18) >= 0x10) { svga->hdisp <<= 1; svga->htotal <<= 1; svga->rowoffset <<= 1; svga->gdcreg[5] &= ~0x40; } - if (mach->regs[0xb0] & 0x20) + if (mach->regs[0xb0] & 0x20) { svga->gdcreg[5] |= 0x40; + if ((mach->regs[0xb6] & 0x18) >= 0x10) + svga->packed_4bpp = 1; + else + svga->packed_4bpp = 0; + } else + svga->packed_4bpp = 0; + + if ((dev->local & 0xff) < 0x02) { + if ((mach->regs[0xb6] & 0x18) == 8) { + svga->hdisp <<= 1; + svga->htotal <<= 1; + svga->ati_4color = 1; + } else + svga->ati_4color = 0; + } mach_log("ON[0]=%d, ON[1]=%d, exton[0]=%d, exton[1]=%d, vendormode0=%d, vendormode1=%d.\n", dev->on[0], dev->on[1], mach->ext_on[0], mach->ext_on[1], dev->vendor_mode[0], dev->vendor_mode[1]); if (dev->on[0] || dev->on[1]) { @@ -2606,9 +2621,6 @@ mach_recalctimings(svga_t *svga) if (dev->dispend == 598) dev->dispend += 2; - if (dev->h_disp == 1024) - dev->accel.advfunc_cntl |= 4; /*Bit 2 means high resolution e.g.: 1024x768*/ - if (dev->accel.advfunc_cntl & 4) { if (mach->shadow_set & 2) { if (dev->h_disp == 8) { @@ -2784,8 +2796,10 @@ mach_recalctimings(svga_t *svga) svga->render = svga_render_8bpp_lowres; else { svga->render = svga_render_8bpp_highres; - svga->ma_latch <<= 1; - svga->rowoffset <<= 1; + if (!svga->packed_4bpp) { + svga->ma_latch <<= 1; + svga->rowoffset <<= 1; + } } break; } @@ -3628,7 +3642,9 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x6e8: case 0x6e9: if (!(port & 1)) { - if (!dev->on[0] || !dev->on[1]) + if ((dev->vendor_mode[0] || dev->vendor_mode[1]) && ((mach->shadow_set & 3) == 0)) + dev->hdisp = val; + else if (!dev->on[0] || !dev->on[1]) dev->hdisp = val; mach_log("ATI 8514/A: H_DISP write 06E8 = %d\n", dev->hdisp + 1); @@ -3655,10 +3671,13 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x16e8: case 0x16e9: - if (!dev->on[0] || !dev->on[1]) { + if ((dev->vendor_mode[0] || dev->vendor_mode[1]) && ((mach->shadow_set & 3) == 0)) { + WRITE8(port, dev->vdisp, val); + } else if (!dev->on[0] || !dev->on[1]) { WRITE8(port, dev->vdisp, val); - dev->vdisp &= 0x1fff; } + dev->vdisp &= 0x1fff; + mach_log("ATI 8514/A: V_DISP write 16E8 = %d\n", (dev->vdisp >> 1) + 1); svga_recalctimings(svga); break; @@ -3848,7 +3867,8 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x5aef: WRITE8(port, mach->shadow_set, val); mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); - svga_recalctimings(svga); + if (mach->shadow_set & 3) + svga_recalctimings(svga); break; case 0x5eee: From b38847915cbf712ec3980660ce248c6cdcebaad7 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 27 Dec 2023 13:54:01 -0300 Subject: [PATCH 129/936] Fix game port initialization order issue --- src/86box.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/86box.c b/src/86box.c index 25b073fda..022e84657 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1153,9 +1153,6 @@ pc_reset_hard_init(void) * that will be a call to device_reset_all() later ! */ - if (joystick_type) - gameport_update_joystick_type(); - /* Reset and reconfigure the Sound Card layer. */ sound_card_reset(); @@ -1199,10 +1196,13 @@ pc_reset_hard_init(void) /* Reset any ISA RTC cards. */ isartc_reset(); - /* Initialize the Voodoo cards here inorder to minmize + /* Initialize the Voodoo cards here inorder to minimize the chances of the SCSI controller ending up on the bridge. */ video_voodoo_init(); + if (joystick_type) + gameport_update_joystick_type(); /* installs game port if no device provides one, must be late */ + ui_sb_update_panes(); if (config_changed) { From db45cb8c0b3305af282139f2aa7ed5acc6c47326 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 27 Dec 2023 18:40:29 +0100 Subject: [PATCH 130/936] Forgot one file to commit in the branch. --- src/video/vid_svga_render.c | 50 +++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index e3f4bff5e..3b02110e3 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -35,7 +35,7 @@ svga_lookup_lut_ram(svga_t* svga, uint32_t val) { if (!svga->lut_map) return val; - + uint8_t r = getcolr(svga->pallook[getcolr(val)]); uint8_t g = getcolg(svga->pallook[getcolg(val)]); uint8_t b = getcolb(svga->pallook[getcolb(val)]); @@ -466,11 +466,12 @@ static void svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) { int x; + int xx = 0; uint32_t addr; uint32_t *p; uint32_t changed_offset; - const bool blinked = svga->blink & 0x10; + const bool blinked = !!(svga->blink & 0x10); const bool attrblink = (!svga->disable_blink) && ((svga->attrregs[0x10] & 0x08) != 0); /* @@ -499,11 +500,11 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) const uint32_t loadevery = forcepacked ? 1 : (dwordload ? 4 : wordload ? 2 : 1); const bool shift4bit = ((svga->gdcreg[0x05] & 0x40) == 0x40) || highres8bpp; - const bool shift2bit = ((svga->gdcreg[0x05] & 0x60) == 0x20) && !shift4bit; + const bool shift2bit = (((svga->gdcreg[0x05] & 0x60) == 0x20) && !shift4bit); const int dwshift = highres ? 0 : 1; const int dotwidth = 1 << dwshift; - const int charwidth = dotwidth * (combine8bits ? 4 : 8); + const int charwidth = dotwidth * ((combine8bits && !svga->packed_4bpp) ? 4 : 8); const uint32_t planemask = 0x11111111 * (uint32_t) (svga->plane_mask); const uint32_t blinkmask = (attrblink ? 0x88888888 : 0x0); const uint32_t blinkval = (attrblink && blinked ? 0x88888888 : 0x0); @@ -637,7 +638,7 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) */ out_edat = ((out_edat & planemask & ~blinkmask) | ((out_edat | ~planemask) & blinkmask & blinkval)) ^ blinkmask; - for (int i = 0; i < 8; i += 2) { + for (int i = 0; i < (8 + (svga->ati_4color ? 8 : 0)); i += (svga->ati_4color ? 4 : 2)) { /* c0 denotes the first 4bpp pixel shifted, while c1 denotes the second. For 8bpp modes, the first 4bpp pixel is the upper 4 bits. @@ -648,11 +649,37 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) current_shift >>= 3; if (combine8bits) { - uint32_t ccombined = (c0 << 4) | c1; - uint32_t p0 = svga->map8[ccombined]; - const int outoffs = (i >> 1) << dwshift; - for (int subx = 0; subx < dotwidth; subx++) - p[outoffs + subx] = p0; + if (svga->packed_4bpp) { + uint32_t p0 = svga->map8[c0]; + uint32_t p1 = svga->map8[c1]; + const int outoffs = i << dwshift; + for (int subx = 0; subx < dotwidth; subx++) + p[outoffs + subx] = p0; + for (int subx = 0; subx < dotwidth; subx++) + p[outoffs + subx + dotwidth] = p1; + } else { + uint32_t ccombined = (c0 << 4) | c1; + uint32_t p0 = svga->map8[ccombined]; + const int outoffs = (i >> 1) << dwshift; + for (int subx = 0; subx < dotwidth; subx++) + p[outoffs + subx] = p0; + } + } else if (svga->ati_4color) { + uint8_t pal4to16[16] = {0, 7, 8 | 0x30, 15 | 0x30, 0, 2, 4, 14 | 0x30, 0, 3, 4, 15 | 0x30, 0, 3, 5, 15 | 0x30}; + uint8_t *cur_pal = &(pal4to16[svga->color_2bpp << 2]); + uint32_t q[4]; + q[0] = svga->pallook[svga->egapal[cur_pal[(c0 & 0x0c) >> 2]]]; + q[1] = svga->pallook[svga->egapal[cur_pal[c0 & 0x03]]]; + q[2] = svga->pallook[svga->egapal[cur_pal[(c1 & 0x0c) >> 2]]]; + q[3] = svga->pallook[svga->egapal[cur_pal[c1 & 0x03]]]; + + const int outoffs = i << dwshift; + for (int ch = 0; ch < 4; ch++) { + for (int subx = 0; subx < (dotwidth + 1); subx++) + p[outoffs + subx] = q[ch]; + + p += (dotwidth + 1); + } } else { uint32_t p0 = svga->pallook[svga->egapal[c0]]; uint32_t p1 = svga->pallook[svga->egapal[c1]]; @@ -664,7 +691,8 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) } } - p += charwidth; + if (!svga->ati_4color) + p += charwidth; } } From 979198d5928b0e7f34207d88733e684feac414fe Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 27 Dec 2023 21:01:25 +0100 Subject: [PATCH 131/936] More ATI changes plus one IBM 8514/A fix: 1. Made the 4 color mode (67h) work properly now, including its 4 schemes on all ATI cards that support said mode. 2. Shadow set now has a true purpose for 8514/A compatibility on ATI Mach8/32. 3. Non-ATI 8514/A used to not work before because of the dev->local variable was not being set to 0 in the ibm8514_init() function, now it's fixed. --- src/include/86box/vid_svga.h | 2 +- src/video/vid_8514a.c | 9 +++++---- src/video/vid_svga.c | 23 +++++++++++---------- src/video/vid_svga_render.c | 39 ++++++++++++++++++------------------ 4 files changed, 37 insertions(+), 36 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 3e7c6f3fe..4d5539005 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -289,7 +289,7 @@ extern uint8_t ibm8514_ramdac_in(uint16_t port, void *priv); extern void ibm8514_ramdac_out(uint16_t port, uint8_t val, void *priv); extern int ibm8514_cpu_src(svga_t *svga); extern int ibm8514_cpu_dest(svga_t *svga); -extern void ibm8514_accel_out_pixtrans(svga_t *svga, uint16_t port, uint16_t val, int len); +extern void ibm8514_accel_out_pixtrans(svga_t *svga, uint16_t port, uint32_t val, int len); extern void ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, uint8_t ssv, int len); extern void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, int len); diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 469a4555e..e2a7da3ca 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -221,7 +221,7 @@ ibm8514_cpu_dest(svga_t *svga) } void -ibm8514_accel_out_pixtrans(svga_t *svga, UNUSED(uint16_t port), uint16_t val, int len) +ibm8514_accel_out_pixtrans(svga_t *svga, UNUSED(uint16_t port), uint32_t val, int len) { ibm8514_t *dev = (ibm8514_t *) svga->dev8514; uint8_t nibble = 0; @@ -1298,8 +1298,9 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat /*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled. When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on the NOP command)*/ - if (dev->accel.cmd == 0x53b1 && !cpu_dat) - ibm8514_log("CMD8514: CMD=%d, full=%04x, pixcntl=%x, count=%d, frgdmix = %02x, bkgdmix = %02x, polygon=%x, cpu=%08x, frgdmix=%02x, bkgdmix=%02x.\n", cmd, dev->accel.cmd, pixcntl, count, frgd_mix, bkgd_mix, dev->accel.multifunc[0x0a] & 6, cpu_dat, dev->accel.frgd_mix, dev->accel.bkgd_mix); + if (dev->accel.cmd == 0x43b3) { + ibm8514_log("CMD8514: CMD=%d, full=%04x, pixcntl=%x, count=%d, frcolor=%02x, bkcolor=%02x, polygon=%x, cpu=%08x, frgdmix=%02x, bkgdmix=%02x.\n", cmd, dev->accel.cmd, pixcntl, count, frgd_color, bkgd_color, dev->accel.multifunc[0x0a] & 6, cpu_dat, dev->accel.frgd_mix, dev->accel.bkgd_mix); + } switch (cmd) { case 0: /*NOP (Short Stroke Vectors)*/ @@ -3758,7 +3759,6 @@ bitblt: old_dest_dat = dest_dat; MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if (dev->accel.cmd & 4) { if (dev->accel.sx > 0) { WRITE(dev->accel.dest + dev->accel.dx, dest_dat); @@ -4356,6 +4356,7 @@ ibm8514_init(const device_t *info) dev->changedvram = calloc(dev->vram_size >> 12, 1); dev->vram_mask = dev->vram_size - 1; dev->map8 = dev->pallook; + dev->local = 0; dev->type = info->flags; dev->bpp = 0; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 9f125fb72..71109ce0e 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -116,6 +116,7 @@ svga_out(uint16_t addr, uint8_t val, void *priv) xga_t *xga = (xga_t *) svga->xga; uint8_t o; uint8_t index; + uint8_t pal4to16[16] = { 0, 7, 0x38, 0x3f, 0, 3, 4, 0x3f, 0, 2, 4, 0x3e, 0, 3, 5, 0x3f }; if (!dev && (addr >= 0x2ea) && (addr <= 0x2ed)) return; @@ -163,7 +164,7 @@ svga_out(uint16_t addr, uint8_t val, void *priv) case 0x3c0: case 0x3c1: if (!svga->attrff) { - svga->attraddr = val & 31; + svga->attraddr = val & 0x1f; if ((val & 0x20) != svga->attr_palette_enable) { svga->fullchange = 3; svga->attr_palette_enable = val & 0x20; @@ -172,19 +173,19 @@ svga_out(uint16_t addr, uint8_t val, void *priv) } else { if ((svga->attraddr == 0x13) && (svga->attrregs[0x13] != val)) svga->fullchange = svga->monitor->mon_changeframecount; - o = svga->attrregs[svga->attraddr & 31]; - svga->attrregs[svga->attraddr & 31] = val; - if (svga->attraddr < 16) { - svga->color_2bpp = (val >> 4) & 0x03; + o = svga->attrregs[svga->attraddr & 0x1f]; + svga->attrregs[svga->attraddr & 0x1f] = val; + if (svga->attraddr < 0x10) svga->fullchange = svga->monitor->mon_changeframecount; - } - if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) { - for (int c = 0; c < 16; c++) { - if (svga->attrregs[0x10] & 0x80) { + + if ((svga->attraddr == 0x10) || (svga->attraddr == 0x14) || (svga->attraddr < 0x10)) { + for (int c = 0; c < 0x10; c++) { + if (svga->attrregs[0x10] & 0x80) svga->egapal[c] = (svga->attrregs[c] & 0xf) | ((svga->attrregs[0x14] & 0xf) << 4); - } else { + else if (svga->ati_4color) + svga->egapal[c] = pal4to16[(c & 0x03) | ((val >> 2) & 0xc)]; + else svga->egapal[c] = (svga->attrregs[c] & 0x3f) | ((svga->attrregs[0x14] & 0xc) << 4); - } } svga->fullchange = svga->monitor->mon_changeframecount; } diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 3b02110e3..291a97f2b 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -586,8 +586,8 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) But 4bpp chunky is generally easier to deal with on a modern CPU. shift4bit is the native format for this renderer (4bpp chunky). */ - if (!shift4bit) { - if (shift2bit) { + if (svga->ati_4color || !shift4bit) { + if (shift2bit && !svga->ati_4color) { /* Group 2x 2bpp values into 4bpp values */ edat = (edat & 0xCCCC3333) | ((edat << 14) & 0x33330000) | ((edat >> 14) & 0x0000CCCC); } else { @@ -648,7 +648,19 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) uint32_t c1 = (out_edat >> (current_shift & 0x1C)) & 0xF; current_shift >>= 3; - if (combine8bits) { + if (svga->ati_4color) { + uint32_t q[4]; + q[0] = svga->pallook[svga->egapal[(c0 & 0x0c) >> 2]]; + q[1] = svga->pallook[svga->egapal[c0 & 0x03]]; + q[2] = svga->pallook[svga->egapal[(c1 & 0x0c) >> 2]]; + q[3] = svga->pallook[svga->egapal[c1 & 0x03]]; + + const int outoffs = i << dwshift; + for (int ch = 0; ch < 4; ch++) { + for (int subx = 0; subx < dotwidth; subx++) + p[outoffs + subx + (dotwidth * ch)] = q[ch]; + } + } else if (combine8bits) { if (svga->packed_4bpp) { uint32_t p0 = svga->map8[c0]; uint32_t p1 = svga->map8[c1]; @@ -664,22 +676,6 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) for (int subx = 0; subx < dotwidth; subx++) p[outoffs + subx] = p0; } - } else if (svga->ati_4color) { - uint8_t pal4to16[16] = {0, 7, 8 | 0x30, 15 | 0x30, 0, 2, 4, 14 | 0x30, 0, 3, 4, 15 | 0x30, 0, 3, 5, 15 | 0x30}; - uint8_t *cur_pal = &(pal4to16[svga->color_2bpp << 2]); - uint32_t q[4]; - q[0] = svga->pallook[svga->egapal[cur_pal[(c0 & 0x0c) >> 2]]]; - q[1] = svga->pallook[svga->egapal[cur_pal[c0 & 0x03]]]; - q[2] = svga->pallook[svga->egapal[cur_pal[(c1 & 0x0c) >> 2]]]; - q[3] = svga->pallook[svga->egapal[cur_pal[c1 & 0x03]]]; - - const int outoffs = i << dwshift; - for (int ch = 0; ch < 4; ch++) { - for (int subx = 0; subx < (dotwidth + 1); subx++) - p[outoffs + subx] = q[ch]; - - p += (dotwidth + 1); - } } else { uint32_t p0 = svga->pallook[svga->egapal[c0]]; uint32_t p1 = svga->pallook[svga->egapal[c1]]; @@ -691,7 +687,10 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) } } - if (!svga->ati_4color) + if (svga->ati_4color) + p += (charwidth << 1); + // p += charwidth; + else p += charwidth; } } From 87f5d01fda8bef85459c4942fcc7afb94abbc83e Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Dec 2023 21:13:55 +0100 Subject: [PATCH 132/936] Unix: Separate XDG_DATA_DIRS paths by colon instead of semicolon, fixes #3946. --- src/unix/unix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/unix/unix.c b/src/unix/unix.c index cf69997b0..0a71ac873 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -816,7 +816,7 @@ plat_init_rom_paths(void) while (xdg_rom_paths[strlen(xdg_rom_paths) - 1] == ':') { xdg_rom_paths[strlen(xdg_rom_paths) - 1] = '\0'; } - while ((cur_xdg_rom_path = local_strsep(&xdg_rom_paths, ";")) != NULL) { + while ((cur_xdg_rom_path = local_strsep(&xdg_rom_paths, ":")) != NULL) { char real_xdg_rom_path[1024] = { '\0' }; strcat(real_xdg_rom_path, cur_xdg_rom_path); path_slash(real_xdg_rom_path); From 3483cb02b36d4864c31920763f4dc6cd29b88c16 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Dec 2023 21:15:07 +0100 Subject: [PATCH 133/936] Removed an unused variable from video/vid_svga_render.c. --- 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 291a97f2b..20c1e6e5e 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -466,7 +466,6 @@ static void svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) { int x; - int xx = 0; uint32_t addr; uint32_t *p; uint32_t changed_offset; From dd005d74ea43d8f02e91d26a8d295f3494fa430a Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Dec 2023 21:30:47 +0100 Subject: [PATCH 134/936] Unix SDL: Fix plat_pause(). --- src/unix/unix.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/unix/unix.c b/src/unix/unix.c index 0a71ac873..1314db586 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -762,10 +762,13 @@ plat_pause(int p) static wchar_t oldtitle[512]; wchar_t title[512]; + if ((!!p) == dopause) + return; + if ((p == 0) && (time_sync & TIME_SYNC_ENABLED)) nvr_time_sync(); - dopause = p; + do_pause(p); if (p) { wcsncpy(oldtitle, ui_window_title(NULL), sizeof_w(oldtitle) - 1); wcscpy(title, oldtitle); From b239f4c102b09df2fda76b038795b3b7e8a4dbfd Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Dec 2023 21:35:39 +0100 Subject: [PATCH 135/936] Unix SDL: Actually honor the return value of pc_init(), fixes #3948. --- src/unix/unix.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/unix/unix.c b/src/unix/unix.c index 1314db586..3ca0a4e17 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -1163,9 +1163,12 @@ main(int argc, char **argv) { SDL_Event event; void *libedithandle; + int ret = 0; SDL_Init(0); - pc_init(argc, argv); + ret = pc_init(argc, argv); + if (ret == 0) + return 0; if (!pc_init_modules()) { ui_msgbox_header(MBX_FATAL, L"No ROMs found.", L"86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory."); SDL_Quit(); From 62917d5ef63701627eca0876cf5781399226a463 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Dec 2023 21:39:23 +0100 Subject: [PATCH 136/936] Unix SDL: Unpause the main window after initialization, fixes #3940. --- src/unix/unix.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/unix/unix.c b/src/unix/unix.c index 3ca0a4e17..b35820543 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -1212,6 +1212,7 @@ main(int argc, char **argv) thread_create(monitor_thread, NULL); #endif SDL_AddTimer(1000, timer_onesec, NULL); + plat_pause(1); while (!is_quit) { static int mouse_inside = 0; From 46d01e30da64ebab28c95f773edbc01e62d996c2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Dec 2023 21:39:51 +0100 Subject: [PATCH 137/936] Actually unpause it at the correct time. --- src/unix/unix.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/unix/unix.c b/src/unix/unix.c index b35820543..2e76ee5a9 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -1203,7 +1203,7 @@ main(int argc, char **argv) pc_reset_hard_init(); /* Set the PAUSE mode depending on the renderer. */ - // plat_pause(0); + plat_pause(0); /* Initialize the rendering window, or fullscreen. */ @@ -1212,7 +1212,6 @@ main(int argc, char **argv) thread_create(monitor_thread, NULL); #endif SDL_AddTimer(1000, timer_onesec, NULL); - plat_pause(1); while (!is_quit) { static int mouse_inside = 0; From d9dfa8d8d5116ab89b8134512103694e56f72509 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 28 Dec 2023 02:01:45 +0100 Subject: [PATCH 138/936] More ATI accel fixes and undocumented stuff. 1. Apparently some stuff uses read-only port 0x86ee and expects it to return 0 while port 0xf6ee is an alias to 0x82e8, this should fix hangs in Majong 8514 using ATI's DOS drivers. 2. 8514 data available bits are reset properly when new parameters for a new command are installed (port 0xCEEE), fixes remaining hangs with some stuff. --- src/video/vid_ati_mach8.c | 47 +++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index e9118bfbc..1fca83369 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -135,8 +135,9 @@ typedef struct mach_t { uint16_t scratch1; uint16_t test; uint16_t pattern; - uint8_t test2[2]; - uint8_t test3[2]; + uint16_t test2; + uint16_t test3; + uint16_t test4; int src_y_dir; int cmd_type; int block_write_mono_pattern_enable; @@ -1361,7 +1362,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 return; } if (dev->accel.sy >= mach->accel.height) { - if ((mono_src == 2) || (mono_src == 3) || (frgd_sel == 2) || (frgd_sel == 3) || (bkgd_sel == 2) || (bkgd_sel == 3)) + if ((mono_src == 2) || (mono_src == 3) || (frgd_sel == 3) || (bkgd_sel == 3)) return; if ((mono_src == 1) && (frgd_sel == 5) && (dev->accel_bpp == 24) && (mach->accel.patt_len_reg & 0x4000)) return; @@ -2623,7 +2624,7 @@ mach_recalctimings(svga_t *svga) if (dev->accel.advfunc_cntl & 4) { if (mach->shadow_set & 2) { - if (dev->h_disp == 8) { + if ((dev->h_disp == 8) && !dev->bpp) { dev->h_disp = 1024; dev->dispend = 768; dev->v_total = 1536; @@ -2634,7 +2635,7 @@ mach_recalctimings(svga_t *svga) } else svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); } else { - if (dev->h_disp == 1024) { + if ((dev->h_disp == 1024) && !dev->bpp) { dev->h_disp = 640; dev->dispend = 480; } @@ -2819,9 +2820,12 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u int bkgd_sel; int mono_src; + mach_log("[%04X:%08X]: Port FIFO OUT=%04x, val=%04x, len=%d.\n", CS, cpu_state.pc, port, val, len); + switch (port) { case 0x82e8: case 0xc2e8: + case 0xf6ee: if (len == 1) { dev->accel.cur_y = (dev->accel.cur_y & 0x700) | val; } else { @@ -2830,6 +2834,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u break; case 0x82e9: case 0xc2e9: + case 0xf6ef: if (len == 1) { dev->accel.cur_y = (dev->accel.cur_y & 0xff) | ((val & 0x07) << 8); } @@ -3497,6 +3502,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u if (len == 1) mach->accel.dp_config = (mach->accel.dp_config & 0xff00) | val; else { + dev->data_available = 0; + dev->data_available2 = 0; mach->accel.dp_config = val; } break; @@ -3631,7 +3638,7 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) svga_t *svga = &mach->svga; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; - mach_log("Port accel out = %04x, val = %04x.\n", port, val); + mach_log("[%04X:%08X]: Port NORMAL OUT=%04x, val=%04x.\n", CS, cpu_state.pc, port, val); switch (port) { case 0x2e8: @@ -3830,12 +3837,12 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x42ee: case 0x42ef: - mach->accel.test2[port & 1] = val; + WRITE8(port, mach->accel.test2, val); break; case 0x46ee: case 0x46ef: - mach->accel.test3[port & 1] = val; + WRITE8(port, mach->accel.test3, val); break; case 0x4aee: @@ -4183,6 +4190,11 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in temp = mach->accel.patt_data_idx; break; + case 0x86ee: + case 0x86ef: + temp = 0x0000; + break; + case 0x8eee: if (len == 1) temp = mach->accel.ext_ge_config & 0xff; @@ -4352,7 +4364,7 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in break; } - mach_log("Port FIFO IN=%04x, temp=%04x, len=%d.\n", port, temp, len); + mach_log("[%04X:%08X]: Port FIFO IN=%04x, temp=%04x, len=%d.\n", CS, cpu_state.pc, port, temp, len); return temp; } @@ -4362,8 +4374,8 @@ mach_accel_in(uint16_t port, mach_t *mach) svga_t *svga = &mach->svga; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; uint8_t temp = 0; - int vpos = 0; - int vblankend = svga->vblankstart + svga->crtc[0x16]; + uint16_t vpos = 0; + uint16_t vblankend = svga->vblankstart + svga->crtc[0x16]; switch (port) { case 0x2e8: @@ -4469,17 +4481,13 @@ mach_accel_in(uint16_t port, mach_t *mach) break; case 0x42ee: - temp = mach->accel.test2[0]; - break; case 0x42ef: - temp = mach->accel.test2[1]; + READ8(port, mach->accel.test2); break; case 0x46ee: - temp = mach->accel.test3[0]; - break; case 0x46ef: - temp = mach->accel.test3[1]; + READ8(port, mach->accel.test3); break; case 0x4aee: @@ -4547,7 +4555,7 @@ mach_accel_in(uint16_t port, mach_t *mach) default: break; } - mach_log("Port accel in = %04x, temp = %04x.\n", port, temp); + mach_log("[%04X:%08X]: Port NORMAL IN=%04x, temp=%04x.\n", CS, cpu_state.pc, port, temp); return temp; } @@ -5478,6 +5486,7 @@ mach_io_set(mach_t *mach) io_sethandler(0x7aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x7eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x82ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x86ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x8eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x92ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x96ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); @@ -5502,6 +5511,7 @@ mach_io_set(mach_t *mach) io_sethandler(0xe6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0xeeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0xf2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xf6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0xfaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0xfeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); } @@ -5781,7 +5791,6 @@ mach8_init(const device_t *info) else mach->config1 |= 0x06; mach->config1 |= 0x0400; - mach->config1 |= 0x1000; svga->clock_gen = device_add(&ati18811_1_device); } else if (mach->pci_bus) { video_inform(VIDEO_FLAG_TYPE_8514, &timing_mach32_pci); From e614103f04ef3fe9dbce1006f0ae5232f423bd29 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 28 Dec 2023 11:38:34 +0100 Subject: [PATCH 139/936] Unix: Temporarily disable the use of f_readline, fixes #3949. --- src/unix/unix.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/unix/unix.c b/src/unix/unix.c index 2e76ee5a9..e784df38e 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -917,12 +917,16 @@ monitor_thread(void *param) while (!exit_event) { if (feof(stdin)) break; +#ifdef ENABLE_READLINE if (f_readline) line = f_readline("(86Box) "); else { +#endif printf("(86Box) "); (void) !getline(&line, &n, stdin); +#ifdef ENABLE_READLINE } +#endif if (line) { int cmdargc = 0; char *linecpy; From b877c0c6396c0428c1070871a4425fd9df0522fd Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 28 Dec 2023 11:45:53 +0100 Subject: [PATCH 140/936] Disable --settings when using the SDL UI, closes #3950. --- src/86box.c | 4 ++++ src/CMakeLists.txt | 1 + 2 files changed, 5 insertions(+) diff --git a/src/86box.c b/src/86box.c index bf6e8d94a..2e9434b82 100644 --- a/src/86box.c +++ b/src/86box.c @@ -542,7 +542,9 @@ usage: printf("-N or --noconfirm - do not ask for confirmation on quit\n"); printf("-P or --vmpath path - set 'path' to be root for vm\n"); printf("-R or --rompath path - set 'path' to be ROM path\n"); +#ifndef USE_SDL_UI printf("-S or --settings - show only the settings dialog\n"); +#endif printf("-V or --vmname name - overrides the name of the running VM\n"); printf("-X or --clear what - clears the 'what' (cmos/flash/both)\n"); printf("-Y or --donothing - do not show any UI or run the emulation\n"); @@ -609,8 +611,10 @@ usage: goto usage; strcpy(vm_name, argv[++c]); +#ifndef USE_SDL_UI } else if (!strcasecmp(argv[c], "--settings") || !strcasecmp(argv[c], "-S")) { settings_only = 1; +#endif } else if (!strcasecmp(argv[c], "--noconfirm") || !strcasecmp(argv[c], "-N")) { confirm_exit_cmdl = 0; } else if (!strcasecmp(argv[c], "--missing") || !strcasecmp(argv[c], "-M")) { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bfa582e33..ec32d7548 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -229,5 +229,6 @@ if (QT) elseif(WIN32) add_subdirectory(win) else() + add_compile_definitions(USE_SDL_UI) add_subdirectory(unix) endif() From 8e50e88f7e4427c33f58b6a38ccbddbedf43acc9 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Thu, 28 Dec 2023 21:20:15 +0500 Subject: [PATCH 141/936] Joystick: Fix emulated POV hat configuration --- src/qt/qt_joystickconfiguration.cpp | 10 +--------- src/qt/qt_settingsinput.cpp | 4 ++-- src/win/win_jsconf.c | 2 +- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/qt/qt_joystickconfiguration.cpp b/src/qt/qt_joystickconfiguration.cpp index 8523a258d..c363cd544 100644 --- a/src/qt/qt_joystickconfiguration.cpp +++ b/src/qt/qt_joystickconfiguration.cpp @@ -186,7 +186,7 @@ JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) Models::AddEntry(model, plat_joystick_state[joystick].axis[d].name, 0); } - int mapping = joystick_state[joystick_nr].pov_mapping[c][0]; + int mapping = joystick_state[joystick_nr].pov_mapping[c / 2][c & 1]; int nr_povs = plat_joystick_state[joystick].nr_povs; if (mapping & POV_X) cbox->setCurrentIndex((mapping & 3) * 2); @@ -195,14 +195,6 @@ JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) else cbox->setCurrentIndex(mapping + nr_povs * 2); - mapping = joystick_state[joystick_nr].pov_mapping[c][1]; - if (mapping & POV_X) - cbox->setCurrentIndex((mapping & 3) * 2); - else if (mapping & POV_Y) - cbox->setCurrentIndex((mapping & 3) * 2 + 1); - else - cbox->setCurrentIndex(mapping + nr_povs * 2); - ui->ct->addWidget(label, row, 0); ui->ct->addWidget(cbox, row, 1); diff --git a/src/qt/qt_settingsinput.cpp b/src/qt/qt_settingsinput.cpp index 66d6e3de0..34d111e10 100644 --- a/src/qt/qt_settingsinput.cpp +++ b/src/qt/qt_settingsinput.cpp @@ -190,9 +190,9 @@ updateJoystickConfig(int type, int joystick_nr, QWidget *parent) for (int c = 0; c < joystick_get_button_count(type); c++) { joystick_state[joystick_nr].button_mapping[c] = jc.selectedButton(c); } - for (int c = 0; c < joystick_get_button_count(type); c++) { + for (int c = 0; c < joystick_get_pov_count(type) * 2; c += 2) { joystick_state[joystick_nr].pov_mapping[c][0] = get_pov(jc, c, joystick_nr); - joystick_state[joystick_nr].pov_mapping[c][1] = get_pov(jc, c, joystick_nr); + joystick_state[joystick_nr].pov_mapping[c][1] = get_pov(jc, c + 1, joystick_nr); } } } diff --git a/src/win/win_jsconf.c b/src/win/win_jsconf.c index 190338d3e..66ad60c73 100644 --- a/src/win/win_jsconf.c +++ b/src/win/win_jsconf.c @@ -247,7 +247,7 @@ joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lPa joystick_state[joystick_nr].button_mapping[c] = SendMessage(h, CB_GETCURSEL, 0, 0); id += 2; } - for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) { + for (c = 0; c < joystick_get_pov_count(joystick_config_type); c++) { h = GetDlgItem(hdlg, id); joystick_state[joystick_nr].pov_mapping[c][0] = get_pov(hdlg, id); id += 2; From c255bd51611cd392ae2e18df634ef1970e402a50 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 28 Dec 2023 18:34:35 +0100 Subject: [PATCH 142/936] Attempted fix for SCSI disk seek timings. --- src/include/86box/hdd.h | 4 ++-- src/scsi/scsi_disk.c | 18 ++++++++++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/include/86box/hdd.h b/src/include/86box/hdd.h index 8c82209c7..89a6cf1ff 100644 --- a/src/include/86box/hdd.h +++ b/src/include/86box/hdd.h @@ -159,8 +159,8 @@ typedef struct hard_disk_t { char fn[1024]; /* Name of current image file */ char vhd_parent[1041]; /* Differential VHD parent file */ - uint32_t res0; - uint32_t pad1; + uint32_t seek_pos; + uint32_t seek_len; uint32_t base; uint32_t spt; uint32_t hpc; /* Physical geometry parameters */ diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 837800eb0..39a69ea32 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -446,7 +446,7 @@ scsi_disk_command_common(scsi_disk_t *dev) case GPCMD_WRITE_AND_VERIFY_12: case GPCMD_WRITE_SAME_10: /* Seek time is in us. */ - period = hdd_timing_write(dev->drv, dev->sector_pos, dev->packet_len >> 9); + period = hdd_timing_write(dev->drv, dev->drv->seek_pos, dev->drv->seek_len); scsi_disk_log("SCSI HD %i: Seek period: %" PRIu64 " us\n", dev->id, (uint64_t) period); dev->callback += period; @@ -482,7 +482,7 @@ scsi_disk_command_common(scsi_disk_t *dev) case 0x28: case 0xa8: /* Seek time is in us. */ - period = hdd_timing_read(dev->drv, dev->sector_pos, dev->packet_len >> 9); + period = hdd_timing_read(dev->drv, dev->drv->seek_pos, dev->drv->seek_len); scsi_disk_log("SCSI HD %i: Seek period: %" PRIu64 " us\n", dev->id, (uint64_t) period); dev->callback += period; @@ -928,6 +928,10 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) case GPCMD_REZERO_UNIT: dev->sector_pos = dev->sector_len = 0; + + dev->drv->seek_pos = dev->sector_pos; + dev->drv->seek_len = dev->sector_len; + scsi_disk_seek(dev, 0); scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); break; @@ -1031,6 +1035,9 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) dev->packet_len = max_len * alloc_length; scsi_disk_buf_alloc(dev, dev->packet_len); + dev->drv->seek_pos = dev->sector_pos; + dev->drv->seek_len = dev->sector_len; + ret = scsi_disk_blocks(dev, &alloc_length, 1, 0); if (ret <= 0) { scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); @@ -1118,6 +1125,9 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) break; } + dev->drv->seek_pos = dev->sector_pos; + dev->drv->seek_len = dev->sector_len; + max_len = dev->sector_len; /* If we're writing all blocks in one go for DMA, why not also for @@ -1371,6 +1381,10 @@ atapi_out: default: break; } + + dev->drv->seek_pos = dev->sector_pos; + dev->drv->seek_len = 0; + scsi_disk_seek(dev, pos); scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); From 137581c0809336c41a0a872a6b930d92d9dd84a1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 28 Dec 2023 18:42:16 +0100 Subject: [PATCH 143/936] Fix for CD-ROM timings - seek times are no longer always calculated as if it was seeking from sector 0. --- src/scsi/scsi_cdrom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index fb52ca898..d2a6170a6 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -1751,7 +1751,7 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) int used_len; int alloc_length; int msf; - int pos = 0; + int pos = dev->drv->seek_pos; int size_idx; int idx = 0; uint32_t feature; From 277581daeaeb12a021ec8ca32a8f4c66b6c47a9f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 29 Dec 2023 02:13:40 +0600 Subject: [PATCH 144/936] Non-working Millennium II --- src/include/86box/video.h | 1 + src/video/vid_mga.c | 314 +++++++++++++++++++++++++++++++++----- src/video/vid_table.c | 1 + 3 files changed, 274 insertions(+), 42 deletions(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index fc739004f..3d1339f3b 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -438,6 +438,7 @@ extern const device_t pgc_device; extern const device_t millennium_device; extern const device_t mystique_device; extern const device_t mystique_220_device; +extern const device_t millennium_ii_device; /* Oak OTI-0x7 */ extern const device_t oti037c_device; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 35354b2ad..96b1d75ed 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -15,6 +15,7 @@ * Copyright 2008-2020 Sarah Walker. */ #include +#include #include #include #include @@ -36,9 +37,10 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> -#define ROM_MILLENNIUM "roms/video/matrox/matrox2064wr2.BIN" -#define ROM_MYSTIQUE "roms/video/matrox/MYSTIQUE.VBI" -#define ROM_MYSTIQUE_220 "roms/video/matrox/Myst220_66-99mhz.vbi" +#define ROM_MILLENNIUM "roms/video/matrox/matrox2064wr2.BIN" +#define ROM_MILLENNIUM_II "roms/video/matrox/matrox2164wpc.BIN" +#define ROM_MYSTIQUE "roms/video/matrox/MYSTIQUE.VBI" +#define ROM_MYSTIQUE_220 "roms/video/matrox/Myst220_66-99mhz.vbi" #define FIFO_SIZE 65536 #define FIFO_MASK (FIFO_SIZE - 1) @@ -111,6 +113,13 @@ #define REG_DR14 0x1cf8 #define REG_DR15 0x1cfc +#define REG_DR0_Z32LSB 0x2c50 +#define REG_DR0_Z32MSB 0x2c54 +#define REG_DR2_Z32LSB 0x2c60 +#define REG_DR2_Z32MSB 0x2c64 +#define REG_DR3_Z32LSB 0x2c68 +#define REG_DR3_Z32MSB 0x2c6c + #define REG_FIFOSTATUS 0x1e10 #define REG_STATUS 0x1e14 #define REG_ICLEAR 0x1e18 @@ -309,6 +318,7 @@ #define MACCESS_PWIDTH_16 (1 << 0) #define MACCESS_PWIDTH_32 (2 << 0) #define MACCESS_PWIDTH_24 (3 << 0) +#define MACCESS_ZWIDTH (1 << 3) #define MACCESS_TLUTLOAD (1 << 29) #define MACCESS_NODITHER (1 << 30) #define MACCESS_DIT555 (1 << 31) @@ -383,6 +393,7 @@ enum { MGA_2064W, /*Millennium*/ MGA_1064SG, /*Mystique*/ MGA_1164SG, /*Mystique 220*/ + MGA_2164W, /*Millennium II*/ }; enum { @@ -488,6 +499,8 @@ typedef struct mystique_t { uint32_t src[4], ar[7], dr[16], tmr[9]; + uint64_t extended_dr[4]; + struct { int sdydxl, scanleft, sdxl, sdy, @@ -675,7 +688,7 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) case 0x3c6: case 0x3c7: case 0x3c9: - if (mystique->type == MGA_2064W) { + if (mystique->type == MGA_2064W || mystique->type == MGA_2164W) { tvp3026_ramdac_out(addr, 0, 0, val, svga->ramdac, svga); return; } @@ -792,7 +805,7 @@ mystique_in(uint16_t addr, void *priv) case 0x3c7: case 0x3c8: case 0x3c9: - if (mystique->type == MGA_2064W) + if (mystique->type == MGA_2064W || mystique->type == MGA_2164W) temp = tvp3026_ramdac_in(addr, 0, 0, svga->ramdac, svga); else temp = svga_in(addr, svga); @@ -906,7 +919,7 @@ mystique_recalctimings(svga_t *svga) if (mystique->crtcext_regs[2] & CRTCX_R2_LINECOMP10) svga->split |= 0x400; - if (mystique->type == MGA_2064W) { + if (mystique->type == MGA_2064W || mystique->type == MGA_2164W) { tvp3026_recalctimings(svga->ramdac, svga); svga->interlace |= !!(mystique->crtcext_regs[0] & 0x80); } else @@ -1037,7 +1050,7 @@ mystique_recalc_mapping(mystique_t *mystique) mem_mapping_disable(&mystique->ctrl_mapping); if (mystique->lfb_base) - mem_mapping_set_addr(&mystique->lfb_mapping, mystique->lfb_base, 0x800000); + mem_mapping_set_addr(&mystique->lfb_mapping, mystique->lfb_base, (mystique->type >= MGA_2164W) ? 0x1000000 : 0x800000); else mem_mapping_disable(&mystique->lfb_mapping); @@ -1441,7 +1454,7 @@ mystique_ctrl_read_b(uint32_t addr, void *priv) int rs2 = 0; int rs3 = 0; - if ((mystique->type == MGA_2064W) && (addr & 0x3e00) == 0x3c00) { + if ((mystique->type == MGA_2064W || mystique->type == MGA_2164W) && (addr & 0x3e00) == 0x3c00) { /*RAMDAC*/ addr_0x0f = addr & 0x0f; @@ -1811,7 +1824,7 @@ mystique_accel_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) case REG_YDSTORG + 2: case REG_YDSTORG + 3: WRITE8(addr, mystique->dwgreg.ydstorg, val); - mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * 2 + mystique->dwgreg.zorg; + mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * ((mystique->maccess & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg; break; case REG_YTOP: case REG_YTOP + 1: @@ -2007,7 +2020,7 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) int rs2 = 0; int rs3 = 0; - if ((mystique->type == MGA_2064W) && (addr & 0x3e00) == 0x3c00) { + if ((mystique->type == MGA_2064W || mystique->type == MGA_2164W) && (addr & 0x3e00) == 0x3c00) { /*RAMDAC*/ addr_0x0f = addr & 0x0f; @@ -2290,7 +2303,7 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) case REG_ZORG: mystique->dwgreg.zorg = val; - mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * 2 + mystique->dwgreg.zorg; + mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * ((mystique->maccess & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg; break; case REG_PLNWT: @@ -2417,14 +2430,47 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) mystique->dwgreg.ar[6] = val; break; + case REG_DR0_Z32LSB: + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFFFFF) | val; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + break; + + case REG_DR0_Z32MSB: + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & 0xFFFFFFFF) | ((val & 0xFFFFull) << 32ull); + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + break; + + case REG_DR2_Z32LSB: + mystique->dwgreg.extended_dr[2] = (mystique->dwgreg.extended_dr[2] & ~0xFFFFFFFF) | val; + mystique->dwgreg.dr[2] = (mystique->dwgreg.extended_dr[2] >> 16) & 0xFFFFFFFF; + break; + + case REG_DR2_Z32MSB: + mystique->dwgreg.extended_dr[2] = (mystique->dwgreg.extended_dr[2] & 0xFFFFFFFF) | ((val & 0xFFFFull) << 32ull); + mystique->dwgreg.dr[2] = (mystique->dwgreg.extended_dr[2] >> 16) & 0xFFFFFFFF; + break; + + case REG_DR3_Z32LSB: + mystique->dwgreg.extended_dr[3] = (mystique->dwgreg.extended_dr[3] & ~0xFFFFFFFF) | val; + mystique->dwgreg.dr[3] = (mystique->dwgreg.extended_dr[3] >> 16) & 0xFFFFFFFF; + break; + + case REG_DR3_Z32MSB: + mystique->dwgreg.extended_dr[3] = (mystique->dwgreg.extended_dr[3] & 0xFFFFFFFF) | ((val & 0xFFFFull) << 32ull); + mystique->dwgreg.dr[3] = (mystique->dwgreg.extended_dr[3] >> 16) & 0xFFFFFFFF; + break; + case REG_DR0: mystique->dwgreg.dr[0] = val; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)val << 16ull); break; case REG_DR2: mystique->dwgreg.dr[2] = val; + mystique->dwgreg.extended_dr[2] = (mystique->dwgreg.extended_dr[2] & ~0xFFFFull) | ((uint64_t)val << 16ull); break; case REG_DR3: mystique->dwgreg.dr[3] = val; + mystique->dwgreg.extended_dr[3] = (mystique->dwgreg.extended_dr[3] & ~0xFFFFull) | ((uint64_t)val << 16ull); break; case REG_DR4: mystique->dwgreg.dr[4] = val; @@ -4113,6 +4159,29 @@ z_check(uint16_t z, uint16_t old_z, uint32_t z_mode) // mystique->dwgreg.dwgctrl } } +static int +z_check_32(uint32_t z, uint32_t old_z, uint32_t z_mode) // mystique->dwgreg.dwgctrl & DWGCTRL_ZMODE_MASK) +{ + switch (z_mode) { + case DWGCTRL_ZMODE_ZE: + return (z == old_z); + case DWGCTRL_ZMODE_ZNE: + return (z != old_z); + case DWGCTRL_ZMODE_ZLT: + return (z < old_z); + case DWGCTRL_ZMODE_ZLTE: + return (z <= old_z); + case DWGCTRL_ZMODE_ZGT: + return (z > old_z); + case DWGCTRL_ZMODE_ZGTE: + return (z >= old_z); + + case DWGCTRL_ZMODE_NOZCMP: + default: + return 1; + } +} + static void blit_line(mystique_t *mystique, int closed) { @@ -4216,18 +4285,30 @@ blit_line(mystique_t *mystique, int closed) x = mystique->dwgreg.xdst; while (mystique->dwgreg.length > 0) { if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { - uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); - uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask]; - uint16_t old_z = z_p[x]; + bool z_check_pass = false; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + uint32_t z = (mystique->dwgreg.extended_dr[0] & (1ull << 47ull)) ? 0 : (mystique->dwgreg.extended_dr[0] >> 15ull); + uint32_t *z_p = (uint32_t *) &svga->vram[(mystique->dwgreg.ydst_lin * 4 + mystique->dwgreg.zorg) & mystique->vram_mask]; + uint32_t old_z = z_p[x]; + z_check_pass = z_check_32(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK); + if (z_write && z_check_pass) { + z_p[x] = z; + } + } else { + uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask]; + uint16_t old_z = z_p[x]; + z_check_pass = z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK); + if (z_write && z_check_pass) { + z_p[x] = z; + } + } - if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { + if (z_check_pass) { int r = 0; int g = 0; int b = 0; - if (z_write) - z_p[x] = z; - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { case MACCESS_PWIDTH_16: if (!(mystique->dwgreg.dr[4] & (1 << 23))) @@ -4253,7 +4334,13 @@ blit_line(mystique_t *mystique, int closed) else mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); - mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] += mystique->dwgreg.extended_dr[2]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; @@ -4266,7 +4353,13 @@ blit_line(mystique_t *mystique, int closed) else x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - mystique->dwgreg.dr[0] += mystique->dwgreg.dr[3]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] += mystique->dwgreg.extended_dr[3]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[3]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } mystique->dwgreg.dr[4] += mystique->dwgreg.dr[7]; mystique->dwgreg.dr[8] += mystique->dwgreg.dr[11]; mystique->dwgreg.dr[12] += mystique->dwgreg.dr[15]; @@ -4326,6 +4419,7 @@ static void blit_trap(mystique_t *mystique) { svga_t *svga = &mystique->svga; + uint64_t z_back_32; uint32_t z_back; uint32_t r_back; uint32_t g_back; @@ -4491,12 +4585,14 @@ blit_trap(mystique_t *mystique) for (y = 0; y < mystique->dwgreg.length; y++) { uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask]; + uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * ((mystique->maccess_running & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg) & mystique->vram_mask]; int16_t x_l = mystique->dwgreg.fxleft & 0xffff; int16_t x_r = mystique->dwgreg.fxright & 0xffff; int16_t old_x_l = x_l; int dx; + z_back_32 = mystique->dwgreg.extended_dr[0]; + z_back = mystique->dwgreg.dr[0]; r_back = mystique->dwgreg.dr[4]; g_back = mystique->dwgreg.dr[8]; @@ -4504,10 +4600,18 @@ blit_trap(mystique_t *mystique) while (x_l != x_r) { if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) { - uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); - uint16_t old_z = z_p[x_l]; + bool z_check_pass = false; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + uint32_t z = (mystique->dwgreg.extended_dr[0] & (1ull << 47ull)) ? 0 : (mystique->dwgreg.extended_dr[0] >> 15ull); + uint32_t old_z = *(uint32_t*)&z_p[x_l * 2]; + z_check_pass = z_check_32(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK); + } else { + uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + uint16_t old_z = z_p[x_l]; + z_check_pass = z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK); + } - if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { + if (z_check_pass) { uint32_t dst = 0; uint32_t old_dst; int r = 0; @@ -4521,8 +4625,13 @@ blit_trap(mystique_t *mystique) if (!(mystique->dwgreg.dr[12] & (1 << 23))) b = (mystique->dwgreg.dr[12] >> 15) & 0xff; - if (z_write) - z_p[x_l] = z; + if (z_write) { + if (mystique->maccess_running & MACCESS_ZWIDTH) { + *(uint32_t*)(&z_p[x_l * 2]) = (mystique->dwgreg.extended_dr[0] & (1ull << 47ull)) ? 0 : (mystique->dwgreg.extended_dr[0] >> 15ull); + } + else + z_p[x_l] = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + } switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { case MACCESS_PWIDTH_8: @@ -4553,7 +4662,13 @@ blit_trap(mystique_t *mystique) } } - mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] += mystique->dwgreg.extended_dr[2]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; @@ -4566,7 +4681,13 @@ blit_trap(mystique_t *mystique) mystique->pixel_count++; } - mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] += z_back_32 + mystique->dwgreg.extended_dr[3]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] += z_back + mystique->dwgreg.dr[3]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; @@ -4584,7 +4705,13 @@ blit_trap(mystique_t *mystique) mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; dx = (int16_t) ((mystique->dwgreg.fxleft - old_x_l) & 0xffff); - mystique->dwgreg.dr[0] += dx * mystique->dwgreg.dr[2]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] += dx * mystique->dwgreg.extended_dr[2]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] += dx * mystique->dwgreg.dr[2]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } mystique->dwgreg.dr[4] += dx * mystique->dwgreg.dr[6]; mystique->dwgreg.dr[8] += dx * mystique->dwgreg.dr[10]; mystique->dwgreg.dr[12] += dx * mystique->dwgreg.dr[14]; @@ -4715,12 +4842,14 @@ blit_texture_trap(mystique_t *mystique) for (y = 0; y < mystique->dwgreg.length; y++) { uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask]; + uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * ((mystique->maccess_running & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg) & mystique->vram_mask]; int16_t x_l = mystique->dwgreg.fxleft & 0xffff; int16_t x_r = mystique->dwgreg.fxright & 0xffff; int16_t old_x_l = x_l; int dx; + uint64_t z_back_32 = mystique->dwgreg.extended_dr[0]; + uint32_t z_back = mystique->dwgreg.dr[0]; uint32_t r_back = mystique->dwgreg.dr[4]; uint32_t g_back = mystique->dwgreg.dr[8]; @@ -4731,10 +4860,18 @@ blit_texture_trap(mystique_t *mystique) while (x_l != x_r) { if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) { - uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); - uint16_t old_z = z_p[x_l]; + bool z_check_pass = false; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + uint32_t z = (mystique->dwgreg.extended_dr[0] & (1ull << 47ull)) ? 0 : (mystique->dwgreg.extended_dr[0] >> 15ull); + uint32_t old_z = *(uint32_t*)&z_p[x_l * 2]; + z_check_pass = z_check_32(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK); + } else { + uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + uint16_t old_z = z_p[x_l]; + z_check_pass = z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK); + } - if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { + if (z_check_pass) { int tex_r = 0; int tex_g = 0; int tex_b = 0; @@ -4808,8 +4945,13 @@ blit_texture_trap(mystique_t *mystique) ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = dither(mystique, tex_r, tex_g, tex_b, x_l & 1, mystique->dwgreg.selline & 1); svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount; } - if (z_write) - z_p[x_l] = z; + if (z_write) { + if (mystique->maccess_running & MACCESS_ZWIDTH) { + *(uint32_t*)(&z_p[x_l * 2]) = (mystique->dwgreg.extended_dr[0] & (1ull << 47ull)) ? 0 : (mystique->dwgreg.extended_dr[0] >> 15ull); + } + else + z_p[x_l] = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + } } } skip_pixel: @@ -4820,7 +4962,13 @@ skip_pixel: mystique->pixel_count++; - mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] += mystique->dwgreg.extended_dr[2]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; @@ -4829,7 +4977,13 @@ skip_pixel: mystique->dwgreg.tmr[8] += mystique->dwgreg.tmr[4]; } - mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] += z_back_32 + mystique->dwgreg.extended_dr[3]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] += z_back + mystique->dwgreg.dr[3]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; @@ -4850,7 +5004,13 @@ skip_pixel: mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; dx = (int16_t) ((mystique->dwgreg.fxleft - old_x_l) & 0xffff); - mystique->dwgreg.dr[0] += dx * mystique->dwgreg.dr[2]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] += dx * mystique->dwgreg.extended_dr[2]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] += dx * mystique->dwgreg.dr[2]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } mystique->dwgreg.dr[4] += dx * mystique->dwgreg.dr[6]; mystique->dwgreg.dr[8] += dx * mystique->dwgreg.dr[10]; mystique->dwgreg.dr[12] += dx * mystique->dwgreg.dr[14]; @@ -5474,6 +5634,15 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) mystique_t *mystique = (mystique_t *) priv; uint8_t ret = 0x00; + if (mystique->type >= MGA_2164W) + { + /* Millennium II and later Matrox cards swap MGABASE1 and 2. */ + if (addr >= 0x10 && addr <= 0x13) + addr += 0x4; + else if (addr >= 0x14 && addr <= 0x17) + addr -= 0x4; + } + if ((addr >= 0x30) && (addr <= 0x33) && !(mystique->pci_regs[0x43] & 0x40)) ret = 0x00; else @@ -5486,7 +5655,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) break; case 0x02: - ret = (mystique->type == MGA_2064W) ? 0x19 : 0x1a; + ret = (mystique->type == MGA_2164W) ? 0x1b : ((mystique->type == MGA_2064W) ? 0x19 : 0x1a); break; /*MGA*/ case 0x03: ret = 0x05; @@ -5537,7 +5706,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) ret = 0x00; break; /*Linear frame buffer*/ case 0x16: - ret = (mystique->lfb_base >> 16) & 0x80; + ret = (mystique->type >= MGA_2164W) ? 0x00 : ((mystique->lfb_base >> 16) & 0x80); break; case 0x17: ret = mystique->lfb_base >> 24; @@ -5626,6 +5795,15 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { mystique_t *mystique = (mystique_t *) priv; + if (mystique->type >= MGA_2164W) + { + /* Millennium II and later Matrox cards swap MGABASE1 and 2. */ + if (addr >= 0x10 && addr <= 0x13) + addr += 0x4; + else if (addr >= 0x14 && addr <= 0x17) + addr -= 0x4; + } + switch (addr) { case PCI_REG_COMMAND: mystique->pci_regs[PCI_REG_COMMAND] = (val & 0x27) | 0x80; @@ -5654,11 +5832,13 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) break; case 0x16: + if (mystique->type >= MGA_2164W) + break; mystique->lfb_base = (mystique->lfb_base & 0xff000000) | ((val & 0x80) << 16); mystique_recalc_mapping(mystique); break; case 0x17: - mystique->lfb_base = (mystique->lfb_base & 0x00800000) | (val << 24); + mystique->lfb_base = (mystique->lfb_base & ((mystique->type >= MGA_2164W) ? 0x00000000 : 0x00800000)) | (val << 24); mystique_recalc_mapping(mystique); break; @@ -5785,6 +5965,8 @@ mystique_init(const device_t *info) if (mystique->type == MGA_2064W) romfn = ROM_MILLENNIUM; + else if (mystique->type == MGA_2164W) + romfn = ROM_MILLENNIUM_II; else if (mystique->type == MGA_1064SG) romfn = ROM_MYSTIQUE; else @@ -5800,7 +5982,7 @@ mystique_init(const device_t *info) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_mystique); - if (mystique->type == MGA_2064W) { + if (mystique->type == MGA_2064W || mystique->type == MGA_2164W) { video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_millennium); svga_init(info, &mystique->svga, mystique, mystique->vram_size << 20, mystique_recalctimings, @@ -5945,6 +6127,12 @@ mystique_220_available(void) return rom_present(ROM_MYSTIQUE_220); } +static int +millennium_ii_available(void) +{ + return rom_present(ROM_MILLENNIUM_II); +} + static void mystique_speed_changed(void *priv) { @@ -5993,6 +6181,34 @@ static const device_config_t mystique_config[] = { // clang-format on }; +static const device_config_t millennium_ii_config[] = { + // clang-format off + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "4 MB", + .value = 4 + }, + { + .description = "8 MB", + .value = 8 + }, + { + .description = "" + } + }, + .default_int = 8 + }, + { + .type = CONFIG_END + } + // clang-format on +}; + const device_t millennium_device = { .name = "Matrox Millennium", .internal_name = "millennium", @@ -6034,3 +6250,17 @@ const device_t mystique_220_device = { .force_redraw = mystique_force_redraw, .config = mystique_config }; + +const device_t millennium_ii_device = { + .name = "Matrox Millennium II", + .internal_name = "millennium_ii", + .flags = DEVICE_PCI, + .local = MGA_2164W, + .init = mystique_init, + .close = mystique_close, + .reset = NULL, + { .available = millennium_ii_available }, + .speed_changed = mystique_speed_changed, + .force_redraw = mystique_force_redraw, + .config = mystique_config +}; diff --git a/src/video/vid_table.c b/src/video/vid_table.c index ad6fca2c6..0532a15a8 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -205,6 +205,7 @@ video_cards[] = { { &s3_diamond_stealth_4000_pci_device }, { &s3_trio3d2x_pci_device }, { &millennium_device }, + { &millennium_ii_device }, { &mystique_device }, { &mystique_220_device }, { &tgui9440_pci_device }, From 3d7923d9540bca71d3c7a8b26e0bfc92ef82065f Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 28 Dec 2023 22:12:21 +0100 Subject: [PATCH 145/936] Added the Dell Dimension XPS Pxxx, LG IBM 440FX (MS-6106), and NEC Mate NX MA30D/23D. --- src/device/CMakeLists.txt | 2 +- src/device/nec_mate_unk.c | 76 +++++++++++++++++++++++++++++++++++ src/include/86box/machine.h | 3 ++ src/machine/m_at_socket7_3v.c | 36 ++++++++++++++++- src/machine/m_at_socket8.c | 29 +++++++++++++ src/win/Makefile.mingw | 3 +- 6 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 src/device/nec_mate_unk.c diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index 2988152c1..9e2c2b53d 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -21,7 +21,7 @@ add_library(dev OBJECT bugger.c cassette.c cartridge.c hasp.c hwm.c hwm_lm75.c h smbus_piix4.c smbus_ali7101.c keyboard.c keyboard_xt.c kbc_at.c kbc_at_dev.c keyboard_at.c - mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c phoenix_486_jumper.c + mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c nec_mate_unk.c phoenix_486_jumper.c serial_passthrough.c) if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") diff --git a/src/device/nec_mate_unk.c b/src/device/nec_mate_unk.c new file mode 100644 index 000000000..d49805fc8 --- /dev/null +++ b/src/device/nec_mate_unk.c @@ -0,0 +1,76 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the NEC Mate NX MA30D/23D Unknown Readout. + * + * + * + * Authors: Miran Grca, + * + * Copyright 2020-2023 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/chipset.h> +#include <86box/plat_unused.h> + + if ((port == 0x6b) || (port == 0x3d6d)) + ret = 0x2a; + +static uint8_t +nec_mate_unk_read(UNUSED(uint16_t addr), void *priv) +{ + /* Expected by this NEC machine. + + It writes something on ports 3D6C, 3D6D, and 3D6E, then expects to read + 2Ah from port 3D6D. Then it repeats this with ports 6A, 6B, and 6C. + */ + return 0x2a; +} + +static void +nec_mate_unk_close(void *priv) +{ + free(dev); +} + +static void * +nec_mate_unk_init(const device_t *info) +{ + /* We have to return something non-NULL. */ + uint8_t *dev = (uint8_t *) calloc(1, sizeof(uint8_t)); + + io_sethandler(0x006b, 0x0001, nec_mate_unk_read, NULL, NULL, NULL, NULL, NULL, NULL); + io_sethandler(0x3d6d, 0x0001, nec_mate_unk_read, NULL, NULL, NULL, NULL, NULL, NULL); + + return dev; +} + +const device_t nec_mate_unk_device = { + .name = "NEC Mate NX MA30D/23D Unknown Readout", + .internal_name = "nec_mate_unk_jumper", + .flags = 0, + .local = 0, + .init = nec_mate_unk_jumper_init, + .close = nec_mate_unk_jumper_close, + .reset = nec_mate_unk_jumper_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 8560f0d3b..d75d65a01 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -638,6 +638,7 @@ extern int machine_at_8500tuc_init(const machine_t *); extern int machine_at_p55t2s_init(const machine_t *); extern int machine_at_p5vxb_init(const machine_t *); +extern int machine_at_dell_430vx_init(const machine_t *); extern int machine_at_gw2kte_init(const machine_t *); extern int machine_at_ap5s_init(const machine_t *); @@ -706,6 +707,7 @@ extern int machine_at_aurora_init(const machine_t *); extern int machine_at_686nx_init(const machine_t *); extern int machine_at_acerv60n_init(const machine_t *); +extern int machine_at_lgibm440fx_init(const machine_t *); extern int machine_at_vs440fx_init(const machine_t *); extern int machine_at_gw2kvenus_init(const machine_t *); extern int machine_at_ap440fx_init(const machine_t *); @@ -759,6 +761,7 @@ extern int machine_at_atc7020bxii_init(const machine_t *); extern int machine_at_m773_init(const machine_t *); extern int machine_at_ambx133_init(const machine_t *); extern int machine_at_awo671r_init(const machine_t *); +extern int machine_at_lc500j34dr_init(const machine_t *); extern int machine_at_63a1_init(const machine_t *); extern int machine_at_s370sba_init(const machine_t *); extern int machine_at_apas3_init(const machine_t *); diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index de87ec90d..a1b6de325 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -671,6 +671,40 @@ machine_at_p5vxb_init(const machine_t *model) return ret; } +int +machine_at_dell_430vx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined2("roms/machines/dell_430vx/1003DY0J.BIO", + "roms/machines/dell_430vx/1003DY0J.BI1", + "roms/machines/dell_430vx/1003DY0J.BI2", + "roms/machines/dell_430vx/1003DY0J.BI3", + "roms/machines/dell_430vx/1003DY0J.RCV", + 0x3a000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + 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(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); + device_add(&i430vx_device); + device_add(&piix3_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c932fr_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + int machine_at_gw2kte_init(const machine_t *model) { @@ -694,7 +728,7 @@ machine_at_gw2kte_init(const machine_t *model) pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x10, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); device_add(&i430vx_device); device_add(&piix3_device); diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index 628206a61..6e63af732 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -161,6 +161,35 @@ machine_at_acerv60n_init(const machine_t *model) return ret; } +int +machine_at_lgibm440fx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/lgibm440fx/bios.rom", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&i440fx_device); + device_add(&piix3_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83787f_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + int machine_at_vs440fx_init(const machine_t *model) { diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 8e4b99b56..ae850eee4 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -617,7 +617,8 @@ DEVOBJ := bugger.o cartridge.o cassette.o hasp.o hwm.o hwm_lm75.o hwm_lm78.o hwm mouse_bus.o \ mouse_serial.o mouse_ps2.o \ mouse_wacom_tablet.o \ - phoenix_486_jumper.o serial_passthrough.o + nec_mate_unk.o phoenix_486_jumper.o \ + serial_passthrough.o SIOOBJ := sio_acc3221.o sio_ali5123.o \ sio_f82c710.o sio_82091aa.o sio_fdc37c6xx.o \ From 6139c14245875bd0d25bc5550921f17d8f8c3210 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 28 Dec 2023 22:13:35 +0100 Subject: [PATCH 146/936] And chipset.h. --- src/include/86box/chipset.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 95440a172..4aa3ee3e9 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -174,6 +174,8 @@ extern const device_t vlsi_scamp_device; extern const device_t wd76c10_device; /* Miscellaneous Hardware */ +extern const device_t nec_mate_unk_device; + extern const device_t phoenix_486_jumper_device; extern const device_t phoenix_486_jumper_pci_device; From dbb53ce21a37d62e8319670749c3de7f0035efb1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 28 Dec 2023 22:27:35 +0100 Subject: [PATCH 147/936] Finishing touches. --- src/device/nec_mate_unk.c | 13 ++- src/include/86box/machine.h | 2 + src/machine/m_at_slot1.c | 57 ++++++++++-- src/machine/machine_table.c | 180 ++++++++++++++++++++++++++++++++++-- 4 files changed, 231 insertions(+), 21 deletions(-) diff --git a/src/device/nec_mate_unk.c b/src/device/nec_mate_unk.c index d49805fc8..165962f30 100644 --- a/src/device/nec_mate_unk.c +++ b/src/device/nec_mate_unk.c @@ -29,9 +29,6 @@ #include <86box/chipset.h> #include <86box/plat_unused.h> - if ((port == 0x6b) || (port == 0x3d6d)) - ret = 0x2a; - static uint8_t nec_mate_unk_read(UNUSED(uint16_t addr), void *priv) { @@ -46,6 +43,8 @@ nec_mate_unk_read(UNUSED(uint16_t addr), void *priv) static void nec_mate_unk_close(void *priv) { + uint8_t *dev = (uint8_t *) priv; + free(dev); } @@ -63,12 +62,12 @@ nec_mate_unk_init(const device_t *info) const device_t nec_mate_unk_device = { .name = "NEC Mate NX MA30D/23D Unknown Readout", - .internal_name = "nec_mate_unk_jumper", + .internal_name = "nec_mate_unk", .flags = 0, .local = 0, - .init = nec_mate_unk_jumper_init, - .close = nec_mate_unk_jumper_close, - .reset = nec_mate_unk_jumper_reset, + .init = nec_mate_unk_init, + .close = nec_mate_unk_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index d75d65a01..65e36959a 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -728,6 +728,8 @@ extern int machine_at_kn97_init(const machine_t *); extern int machine_at_lx6_init(const machine_t *); extern int machine_at_spitfire_init(const machine_t *); +extern int machine_at_mate_nx_ma30d_23d_init(const machine_t *); + extern int machine_at_p6i440e2_init(const machine_t *); extern int machine_at_p2bls_init(const machine_t *); diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 184cfc34d..d1e348ba4 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -152,6 +152,43 @@ machine_at_spitfire_init(const machine_t *model) return ret; } +int +machine_at_mate_nx_ma30d_23d_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/mate_nx_ma30d_23d/BIOS.ROM", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); +#ifdef UNKNOWN_SLOT + pci_register_slot(0x0A, PCI_CARD_NETWORK, 2, 3, 4, 1); /* ???? device - GPIO? */ +#endif + pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x10, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 3, 0, 0, 0); + device_add(&i440lx_device); + device_add(&piix4e_device); + device_add(&nec_mate_unk_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c67x_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 256); + device_add(&lm78_device); /* no reporting in BIOS */ + + return ret; +} + int machine_at_p6i440e2_init(const machine_t *model) { @@ -199,13 +236,21 @@ machine_at_p2bls_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x04, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x06, PCI_CARD_SCSI, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_NETWORK, 3, 4, 1, 2); + // pci_register_slot(0x04, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + // pci_register_slot(0x06, PCI_CARD_SCSI, 4, 1, 2, 3); + // pci_register_slot(0x07, PCI_CARD_NETWORK, 3, 4, 1, 2); +#if 0 pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); +#else + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); +#endif pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&piix4e_device); @@ -216,9 +261,9 @@ machine_at_p2bls_init(const machine_t *model) #endif device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); - device_add(&w83781d_device); /* fans: Chassis, CPU, Power; temperatures: MB, unused, CPU */ - hwm_values.temperatures[1] = 0; /* unused */ - hwm_values.temperatures[2] -= 3; /* CPU offset */ + // device_add(&w83781d_device); /* fans: Chassis, CPU, Power; temperatures: MB, unused, CPU */ + // hwm_values.temperatures[1] = 0; /* unused */ + // hwm_values.temperatures[2] -= 3; /* CPU offset */ return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 014417426..3a260d9ae 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -9524,6 +9524,48 @@ const machine_t machines[] = { }, /* 430VX */ + /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the + PC87306 Super I/O chip, command 0xA1 returns '5'. + Command 0xA0 copyright string: (C)1994 AMI . */ + { + .name = "[i430VX] Dell Hannibal+", + .internal_name = "dell_430vx", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430VX, + .init = machine_at_dell_430vx_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 = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Has AMIKey H KBC firmware (AMIKey-2). */ { .name = "[i430VX] ECS P5VX-B", @@ -11614,6 +11656,47 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* It's a Intel VS440FX with a Gateway 2000 OEM BIOS */ + { + .name = "[i440FX] Gateway 2000 Venus", + .internal_name = "gw2kvenus", + .type = MACHINE_TYPE_SOCKET8, + .chipset = MACHINE_CHIPSET_INTEL_440FX, + .init = machine_at_gw2kvenus_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET8, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2100, + .max_voltage = 3500, + .min_multi = 2.0, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the AMIKey-2 (updated 'H') KBC firmware. */ { .name = "[i440FX] Gigabyte GA-686NX", .internal_name = "686nx", @@ -11737,13 +11820,13 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* It's a Intel VS440FX with a Gateway 2000 OEM BIOS */ + /* Has the AMIKey-2 (updated 'H') KBC firmware. */ { - .name = "[i440FX] Gateway 2000 Venus", - .internal_name = "gw2kvenus", + .name = "[i440FX] LG IBM Multinet x61 (MSI MS-6106)", + .internal_name = "lgibm440fx", .type = MACHINE_TYPE_SOCKET8, .chipset = MACHINE_CHIPSET_INTEL_440FX, - .init = machine_at_gw2kvenus_init, + .init = machine_at_lgibm440fx_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, @@ -11753,15 +11836,15 @@ const machine_t machines[] = { .block = CPU_BLOCK_NONE, .min_bus = 60000000, .max_bus = 66666667, - .min_voltage = 2100, + .min_voltage = 2500, .max_voltage = 3500, - .min_multi = 2.0, - .max_multi = 3.5 + .min_multi = 1.5, + .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_PCI, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, .ram = { - .min = 8192, + .min = 40960, .max = 524288, .step = 8192 }, @@ -12069,6 +12152,47 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has a SM(S)C FDC37M60x Super I/O chip with on-chip KBC with Phoenix or + AMIKey-2 KBC firmware. */ + { + .name = "[i440LX] NEC Mate NX MA30D/23D", + .internal_name = "mate_nx_ma30d_23d", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440LX, + .init = machine_at_mate_nx_ma30d_23d_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 66666667, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .ram = { + .min = 8192, + .max = 1048576, + .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 = NULL, + .net_device = NULL + }, /* 440EX */ /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC @@ -13037,6 +13161,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has a Mitsubishi 38813 with AMIKey-3 KBC firmware. */ + { + .name = "[i440BX] NEC LaVie C PC-LC500J34DR", + .internal_name = "lc500j34dr", + .type = MACHINE_TYPE_SOCKET370, + .chipset = MACHINE_CHIPSET_INTEL_440BX, + .init = machine_at_lc500j34dr_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET370, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 133333333, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 /* limits assumed */ + }, + .bus_flags = MACHINE_PS2_AGP, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .ram = { + .min = 8192, + .max = 524288, + .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 = NULL, + .net_device = NULL + }, /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ { From 24993bca73b2c33c70c43ba8660bbbb6f904b91a Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 28 Dec 2023 22:29:19 +0100 Subject: [PATCH 148/936] Removed the leftovers of the locally added LC500J machine. --- src/include/86box/machine.h | 1 - src/machine/machine_table.c | 40 ------------------------------------- 2 files changed, 41 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 65e36959a..ddbce0ae4 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -763,7 +763,6 @@ extern int machine_at_atc7020bxii_init(const machine_t *); extern int machine_at_m773_init(const machine_t *); extern int machine_at_ambx133_init(const machine_t *); extern int machine_at_awo671r_init(const machine_t *); -extern int machine_at_lc500j34dr_init(const machine_t *); extern int machine_at_63a1_init(const machine_t *); extern int machine_at_s370sba_init(const machine_t *); extern int machine_at_apas3_init(const machine_t *); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 3a260d9ae..54b9258f4 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -13161,46 +13161,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has a Mitsubishi 38813 with AMIKey-3 KBC firmware. */ - { - .name = "[i440BX] NEC LaVie C PC-LC500J34DR", - .internal_name = "lc500j34dr", - .type = MACHINE_TYPE_SOCKET370, - .chipset = MACHINE_CHIPSET_INTEL_440BX, - .init = machine_at_lc500j34dr_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET370, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 133333333, - .min_voltage = 1300, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 /* limits assumed */ - }, - .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, - .ram = { - .min = 8192, - .max = 524288, - .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 = NULL, - .net_device = NULL - }, /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ { From 8ba35218faf4097fc35e4c8df9a6f008c269730f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 29 Dec 2023 12:24:20 +0600 Subject: [PATCH 149/936] Millennium II: Fix squished image on MGA modes --- src/video/vid_mga.c | 86 +++++++++++++++++++++++++++++---------------- 1 file changed, 56 insertions(+), 30 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 96b1d75ed..d8ca5a6a7 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -736,17 +736,22 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) case 0x3df: if (mystique->crtcext_idx == 1) svga->dpms = !!(val & 0x30); + old = mystique->crtcext_regs[mystique->crtcext_idx]; if (mystique->crtcext_idx < 6) mystique->crtcext_regs[mystique->crtcext_idx] = val; + + if (mystique->crtcext_idx == 6 && (old ^ val) == CRTCX_R3_MGAMODE && mystique->type >= MGA_2164W) + svga_recalctimings(svga); if ((mystique->type >= MGA_1064SG) && (mystique->crtcext_idx == 0) && (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE)) { svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); - svga->rowoffset <<= 1; + if (!(mystique->type >= MGA_2164W)) + svga->rowoffset <<= 1; svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; - if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { + if ((mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) && !(mystique->type >= MGA_2164W)) { svga->rowoffset <<= 1; svga->ma_latch <<= 1; } @@ -935,7 +940,7 @@ mystique_recalctimings(svga_t *svga) if (mystique->type >= MGA_1064SG) svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; - if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { + if ((mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) && !(mystique->type >= MGA_2164W)) { svga->rowoffset <<= 1; if (mystique->type >= MGA_1064SG) svga->ma_latch <<= 1; @@ -957,34 +962,55 @@ mystique_recalctimings(svga_t *svga) mystique->ma_latch_old = svga->ma_latch; } - svga->rowoffset <<= 1; - switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { - case XMULCTRL_DEPTH_8: - case XMULCTRL_DEPTH_2G8V16: - svga->render = svga_render_8bpp_highres; - svga->bpp = 8; - break; - case XMULCTRL_DEPTH_15: - case XMULCTRL_DEPTH_G16V16: - svga->render = svga_render_15bpp_highres; - svga->bpp = 15; - break; - case XMULCTRL_DEPTH_16: - svga->render = svga_render_16bpp_highres; - svga->bpp = 16; - break; - case XMULCTRL_DEPTH_24: - svga->render = svga_render_24bpp_highres; - svga->bpp = 24; - break; - case XMULCTRL_DEPTH_32: - case XMULCTRL_DEPTH_32_OVERLAYED: - svga->render = svga_render_32bpp_highres; - svga->bpp = 32; - break; + if (!(mystique->type >= MGA_2164W)) + svga->rowoffset <<= 1; + if (mystique->type != MGA_2164W) { + switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { + case XMULCTRL_DEPTH_8: + case XMULCTRL_DEPTH_2G8V16: + svga->render = svga_render_8bpp_highres; + svga->bpp = 8; + break; + case XMULCTRL_DEPTH_15: + case XMULCTRL_DEPTH_G16V16: + svga->render = svga_render_15bpp_highres; + svga->bpp = 15; + break; + case XMULCTRL_DEPTH_16: + svga->render = svga_render_16bpp_highres; + svga->bpp = 16; + break; + case XMULCTRL_DEPTH_24: + svga->render = svga_render_24bpp_highres; + svga->bpp = 24; + break; + case XMULCTRL_DEPTH_32: + case XMULCTRL_DEPTH_32_OVERLAYED: + svga->render = svga_render_32bpp_highres; + svga->bpp = 32; + break; - default: - break; + default: + break; + } + } else { + switch (svga->bpp) { + case 8: + svga->render = svga_render_8bpp_highres; + break; + case 15: + svga->render = svga_render_15bpp_highres; + break; + case 16: + svga->render = svga_render_16bpp_highres; + break; + case 24: + svga->render = svga_render_24bpp_highres; + break; + case 32: + svga->render = svga_render_32bpp_highres; + break; + } } } else { switch (svga->bpp) { From d1af2fe85dce8fec1732c653c721d6d9487670fe Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 29 Dec 2023 13:19:46 +0600 Subject: [PATCH 150/936] Millennnium II now working --- src/video/vid_mga.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index d8ca5a6a7..33be96fa6 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -756,7 +756,8 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) svga->ma_latch <<= 1; } - svga->ma_latch <<= 1; + if (!(mystique->type >= MGA_2164W)) + svga->ma_latch <<= 1; if (svga->ma_latch != mystique->ma_latch_old) { if (svga->interlace && svga->oddeven) svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + @@ -949,7 +950,8 @@ mystique_recalctimings(svga_t *svga) if (mystique->type >= MGA_1064SG) { /*Mystique, unlike most SVGA cards, allows display start to take effect mid-screen*/ - svga->ma_latch <<= 1; + if (!(mystique->type >= MGA_2164W)) + svga->ma_latch <<= 1; /* Only change maback so the new display start will take effect on the next horizontal retrace. */ if (svga->ma_latch != mystique->ma_latch_old) { @@ -1009,6 +1011,7 @@ mystique_recalctimings(svga_t *svga) break; case 32: svga->render = svga_render_32bpp_highres; + svga->rowoffset <<= 1; break; } } @@ -1714,6 +1717,7 @@ mystique_accel_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) case REG_MACCESS + 3: WRITE8(addr, mystique->maccess, val); mystique->dwgreg.dither = mystique->maccess >> 30; + mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * ((mystique->maccess & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg; break; case REG_MCTLWTST: @@ -2575,6 +2579,7 @@ mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) case REG_PRIMEND: thread_wait_mutex(mystique->dma.lock); mystique->dma.primend = val; + //pclog("PRIMADDRESS = 0x%08X, PRIMEND = 0x%08X\n", mystique->dma.primaddress, mystique->dma.primend); if (mystique->dma.state == DMA_STATE_IDLE && (mystique->dma.primaddress & DMA_ADDR_MASK) != (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 0; mystique->status &= ~STATUS_ENDPRDMASTS; @@ -5074,6 +5079,7 @@ blit_bitblt(mystique_t *mystique) case DWGCTRL_ATYPE_BLK: switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { case DWGCTRL_BLTMOD_BMONOLEF: + case DWGCTRL_BLTMOD_BMONOWF: src_addr = mystique->dwgreg.ar[3]; for (y = 0; y < mystique->dwgreg.length; y++) { @@ -5082,7 +5088,7 @@ blit_bitblt(mystique_t *mystique) while (1) { if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { uint32_t byte_addr = (src_addr >> 3) & mystique->vram_mask; - int bit_offset = src_addr & 7; + int bit_offset = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) == DWGCTRL_BLTMOD_BMONOWF) ? (7 - (src_addr & 7)) : (src_addr & 7); uint32_t old_dst; switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { @@ -5180,6 +5186,7 @@ blit_bitblt(mystique_t *mystique) case DWGCTRL_ATYPE_RSTR: switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { case DWGCTRL_BLTMOD_BMONOLEF: + case DWGCTRL_BLTMOD_BMONOWF: if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) fatal("BITBLT RPL/RSTR BMONOLEF with pattern\n"); @@ -5191,7 +5198,7 @@ blit_bitblt(mystique_t *mystique) while (1) { uint32_t byte_addr = (src_addr >> 3) & mystique->vram_mask; - int bit_offset = src_addr & 7; + int bit_offset = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) == DWGCTRL_BLTMOD_BMONOWF) ? (7 - (src_addr & 7)) : (src_addr & 7); if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && ((svga->vram[byte_addr] & (1 << bit_offset)) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && trans[x & 3]) { uint32_t src = (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; From 592229af947eb90861f4c13dae3f296f24462154 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 29 Dec 2023 14:59:09 +0600 Subject: [PATCH 151/936] 1. 16MB option 2. rowoffset fixes --- src/video/vid_mga.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 33be96fa6..d5ee42b30 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -772,12 +772,22 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) if (mystique->crtcext_idx == 4) { if (svga->gdcreg[6] & 0xc) { /*64k banks*/ - svga->read_bank = (val & 0x7f) << 16; - svga->write_bank = (val & 0x7f) << 16; + if (mystique->type >= MGA_2164W) { + svga->read_bank = val << 16; + svga->write_bank = val << 16; + } else { + svga->read_bank = (val & 0x7f) << 16; + svga->write_bank = (val & 0x7f) << 16; + } } else { /*128k banks*/ - svga->read_bank = (val & 0x7e) << 16; - svga->write_bank = (val & 0x7e) << 16; + if (mystique->type >= MGA_2164W) { + svga->read_bank = (val & 0xfe) << 16; + svga->write_bank = (val & 0xfe) << 16; + } else { + svga->read_bank = (val & 0x7e) << 16; + svga->write_bank = (val & 0x7e) << 16; + } } } break; @@ -1005,9 +1015,13 @@ mystique_recalctimings(svga_t *svga) break; case 16: svga->render = svga_render_16bpp_highres; + if (svga->hdisp >= 1024) + svga->rowoffset <<= 1; break; case 24: svga->render = svga_render_24bpp_highres; + if (svga->hdisp >= 1024) + svga->rowoffset <<= 1; break; case 32: svga->render = svga_render_32bpp_highres; @@ -6016,7 +6030,7 @@ mystique_init(const device_t *info) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_mystique); if (mystique->type == MGA_2064W || mystique->type == MGA_2164W) { - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_millennium); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, (mystique->type == MGA_2164W) ? &timing_matrox_mystique : &timing_matrox_millennium); svga_init(info, &mystique->svga, mystique, mystique->vram_size << 20, mystique_recalctimings, mystique_in, mystique_out, @@ -6026,6 +6040,8 @@ mystique_init(const device_t *info) mystique->svga.ramdac = device_add(&tvp3026_ramdac_device); mystique->svga.clock_gen = mystique->svga.ramdac; mystique->svga.getclock = tvp3026_getclock; + if (mystique->vram_size >= 16) + mystique->svga.decode_mask = mystique->svga.vram_mask; tvp3026_gpio(mystique_tvp3026_gpio_read, mystique_tvp3026_gpio_write, mystique, mystique->svga.ramdac); } else { video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_mystique); @@ -6230,6 +6246,10 @@ static const device_config_t millennium_ii_config[] = { .description = "8 MB", .value = 8 }, + { + .description = "16 MB", + .value = 16 + }, { .description = "" } @@ -6295,5 +6315,5 @@ const device_t millennium_ii_device = { { .available = millennium_ii_available }, .speed_changed = mystique_speed_changed, .force_redraw = mystique_force_redraw, - .config = mystique_config + .config = millennium_ii_config }; From a037b7618e8a52cba45c4e5bae00f1931ed59ad1 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 29 Dec 2023 15:45:26 +0600 Subject: [PATCH 152/936] MGA: Fix most remaining display problems with Millennium II --- src/video/vid_mga.c | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index d5ee42b30..2f524db5d 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -740,15 +740,14 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) if (mystique->crtcext_idx < 6) mystique->crtcext_regs[mystique->crtcext_idx] = val; - if (mystique->crtcext_idx == 6 && (old ^ val) == CRTCX_R3_MGAMODE && mystique->type >= MGA_2164W) - svga_recalctimings(svga); - if ((mystique->type >= MGA_1064SG) && (mystique->crtcext_idx == 0) && (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE)) { svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); + if (!(mystique->type >= MGA_2164W)) svga->rowoffset <<= 1; + svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; if ((mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) && !(mystique->type >= MGA_2164W)) { @@ -758,6 +757,36 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) if (!(mystique->type >= MGA_2164W)) svga->ma_latch <<= 1; + + if (mystique->type == MGA_2164W) + { + switch (svga->bpp) { + case 8: + svga->render = svga_render_8bpp_highres; + break; + case 15: + svga->render = svga_render_15bpp_highres; + break; + case 16: + svga->render = svga_render_16bpp_highres; + if (svga->dispend >= 1024) + svga->rowoffset <<= 1; + break; + case 24: + svga->render = svga_render_24bpp_highres; + if (svga->hdisp >= 1024) + svga->rowoffset <<= 1; + break; + case 32: + svga->render = svga_render_32bpp_highres; + svga->rowoffset <<= 1; + if (svga->hdisp >= 1024) { + svga->ma_latch <<= 1; + } + break; + } + } + if (svga->ma_latch != mystique->ma_latch_old) { if (svga->interlace && svga->oddeven) svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + @@ -1015,7 +1044,7 @@ mystique_recalctimings(svga_t *svga) break; case 16: svga->render = svga_render_16bpp_highres; - if (svga->hdisp >= 1024) + if (svga->dispend >= 1024) svga->rowoffset <<= 1; break; case 24: @@ -1026,6 +1055,9 @@ mystique_recalctimings(svga_t *svga) case 32: svga->render = svga_render_32bpp_highres; svga->rowoffset <<= 1; + if (svga->hdisp >= 1024) { + svga->ma_latch <<= 1; + } break; } } From f13a4a5723907ec6045fdc35e94b45827fcccb31 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 29 Dec 2023 11:10:15 +0100 Subject: [PATCH 153/936] PIIX3: Fixed USB legacy support register masks. --- src/chipset/intel_piix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index 2094eefcf..70035f6df 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -1006,11 +1006,11 @@ piix_write(int func, int addr, uint8_t val, void *priv) break; case 0xc0: if (dev->type <= 4) - fregs[0xc0] = (fregs[0xc0] & ~(val & 0xbf)) | (val & 0x20); + fregs[0xc0] = (fregs[0xc0] & 0x40) | (val & 0xbf); break; case 0xc1: if (dev->type <= 4) - fregs[0xc1] &= ~val; + fregs[0xc1] = (fregs[0xc0] & ~(val & 0x8f)) | (val & 0x20); break; case 0xff: if (dev->type == 4) { From b93b6d6f2beb5f92e2051319410a467d22e9ec5f Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 29 Dec 2023 11:12:45 +0100 Subject: [PATCH 154/936] Added the Cardex S3 Trio64V+. --- src/include/86box/video.h | 1 + src/video/vid_s3.c | 37 +++++++++++++++++++++++++++++++++++-- src/video/vid_table.c | 1 + 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 3d1339f3b..618819768 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -487,6 +487,7 @@ extern const device_t s3_phoenix_trio64_onboard_pci_device; extern const device_t s3_phoenix_trio64_pci_device; extern const device_t s3_phoenix_trio64vplus_pci_device; extern const device_t s3_phoenix_trio64vplus_onboard_pci_device; +extern const device_t s3_cardex_trio64vplus_pci_device; extern const device_t s3_mirocrystal_20sv_964_vlb_device; extern const device_t s3_mirocrystal_20sv_964_pci_device; extern const device_t s3_mirocrystal_20sd_864_vlb_device; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 9a56acdd7..94c251927 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -62,6 +62,7 @@ #define ROM_DIAMOND_STEALTH64_764 "roms/video/s3/stealt64.bin" #define ROM_TRIO64V2_DX_VBE20 "roms/video/s3/86c775_2.bin" #define ROM_PHOENIX_TRIO64VPLUS "roms/video/s3/64V1506.ROM" +#define ROM_CARDEX_TRIO64VPLUS "roms/video/s3/S3T64VP.VBI" #define ROM_DIAMOND_STEALTH_SE "roms/video/s3/DiamondStealthSE.VBI" #define ROM_ELSAWIN2KPROX_964 "roms/video/s3/elsaw20004m.BIN" #define ROM_ELSAWIN2KPROX "roms/video/s3/elsaw20008m.BIN" @@ -92,6 +93,7 @@ enum { S3_TRIO64V2_DX_ONBOARD, S3_PHOENIX_TRIO64VPLUS, S3_PHOENIX_TRIO64VPLUS_ONBOARD, + S3_CARDEX_TRIO64VPLUS, S3_DIAMOND_STEALTH_SE, S3_DIAMOND_STEALTH_VRAM, S3_ELSAWIN2KPROX_964, @@ -146,6 +148,7 @@ static video_timings_t timing_s3_trio32_vlb = { .type = VIDEO_BUS, .write_b = static video_timings_t timing_s3_trio32_pci = { .type = VIDEO_PCI, .write_b = 4, .write_w = 3, .write_l = 5, .read_b = 26, .read_w = 26, .read_l = 42 }; static video_timings_t timing_s3_trio64_vlb = { .type = VIDEO_BUS, .write_b = 3, .write_w = 2, .write_l = 4, .read_b = 25, .read_w = 25, .read_l = 40 }; static video_timings_t timing_s3_trio64_pci = { .type = VIDEO_PCI, .write_b = 3, .write_w = 2, .write_l = 4, .read_b = 25, .read_w = 25, .read_l = 40 }; +static video_timings_t timing_s3_trio64vp_cardex_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 3, .read_b = 19, .read_w = 19, .read_l = 30 }; enum { VRAM_4MB = 0, @@ -2894,7 +2897,8 @@ s3_in(uint16_t addr, void *priv) temp = svga->seqregs[svga->seqaddr]; /* This is needed for the Intel Advanced/ATX's built-in S3 Trio64V+ BIOS to not get stuck in an infinite loop. */ - if ((s3->card_type == S3_PHOENIX_TRIO64VPLUS_ONBOARD) && (svga->seqaddr == 0x17)) + if (((s3->card_type == S3_PHOENIX_TRIO64VPLUS_ONBOARD) || + (s3->card_type == S3_CARDEX_TRIO64VPLUS)) && (svga->seqaddr == 0x17)) svga->seqregs[svga->seqaddr] ^= 0x01; return temp; } @@ -7891,12 +7895,15 @@ s3_reset(void *priv) case S3_PHOENIX_TRIO64: case S3_PHOENIX_TRIO64_ONBOARD: + case S3_CARDEX_TRIO64VPLUS: case S3_PHOENIX_TRIO64VPLUS: case S3_PHOENIX_TRIO64VPLUS_ONBOARD: case S3_DIAMOND_STEALTH64_764: case S3_SPEA_MIRAGE_P64: case S3_NUMBER9_9FX: - if (s3->card_type == S3_PHOENIX_TRIO64VPLUS || s3->card_type == S3_PHOENIX_TRIO64VPLUS_ONBOARD) + if ((s3->card_type == S3_CARDEX_TRIO64VPLUS) || + (s3->card_type == S3_PHOENIX_TRIO64VPLUS) || + (s3->card_type == S3_PHOENIX_TRIO64VPLUS_ONBOARD)) svga->crtc[0x53] = 0x08; break; @@ -8141,6 +8148,11 @@ s3_init(const device_t *info) else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); break; + case S3_CARDEX_TRIO64VPLUS: + bios_fn = ROM_CARDEX_TRIO64VPLUS; + chip = S3_TRIO64V; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64vp_cardex_pci); + break; case S3_DIAMOND_STEALTH64_764: bios_fn = ROM_DIAMOND_STEALTH64_764; chip = S3_TRIO64; @@ -8543,6 +8555,7 @@ s3_init(const device_t *info) case S3_PHOENIX_TRIO64_ONBOARD: case S3_PHOENIX_TRIO64VPLUS: case S3_PHOENIX_TRIO64VPLUS_ONBOARD: + case S3_CARDEX_TRIO64VPLUS: case S3_DIAMOND_STEALTH64_764: case S3_SPEA_MIRAGE_P64: if (device_get_config_int("memory") == 1) @@ -8786,6 +8799,12 @@ s3_phoenix_trio64vplus_available(void) return rom_present(ROM_PHOENIX_TRIO64VPLUS); } +static int +s3_cardex_trio64vplus_available(void) +{ + return rom_present(ROM_PHOENIX_TRIO64VPLUS); +} + static int s3_diamond_stealth64_764_available(void) { @@ -9417,6 +9436,20 @@ const device_t s3_phoenix_trio64vplus_pci_device = { .config = s3_standard_config }; +const device_t s3_cardex_trio64vplus_pci_device = { + .name = "S3 Trio64V+ PCI (Cardex)", + .internal_name = "cardex_trio64vplus_pci", + .flags = DEVICE_PCI, + .local = S3_CARDEX_TRIO64VPLUS, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + { .available = s3_cardex_trio64vplus_available }, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_standard_config +}; + const device_t s3_phoenix_vision864_vlb_device = { .name = "S3 Vision864 VLB (Phoenix)", .internal_name = "px_vision864_vlb", diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 0532a15a8..37e399d22 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -192,6 +192,7 @@ video_cards[] = { { &s3_spea_mercury_p64v_pci_device }, { &s3_9fx_531_pci_device }, { &s3_phoenix_vision868_pci_device }, + { &s3_cardex_trio64vplus_pci_device }, { &s3_phoenix_trio64vplus_pci_device }, { &s3_trio64v2_dx_pci_device }, { &s3_virge_325_pci_device }, From 5663f9aa3b9d544bfaa37958a474bcbb9b56d813 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 30 Dec 2023 01:20:19 +0600 Subject: [PATCH 155/936] Millennium II: Don't ignore OPTION_INTERLEAVE Cleanups --- src/video/vid_mga.c | 43 +++---------------------------------------- 1 file changed, 3 insertions(+), 40 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 2f524db5d..6e85cfe5e 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -750,42 +750,13 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; - if ((mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) && !(mystique->type >= MGA_2164W)) { + if ((mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8))) { svga->rowoffset <<= 1; svga->ma_latch <<= 1; } if (!(mystique->type >= MGA_2164W)) svga->ma_latch <<= 1; - - if (mystique->type == MGA_2164W) - { - switch (svga->bpp) { - case 8: - svga->render = svga_render_8bpp_highres; - break; - case 15: - svga->render = svga_render_15bpp_highres; - break; - case 16: - svga->render = svga_render_16bpp_highres; - if (svga->dispend >= 1024) - svga->rowoffset <<= 1; - break; - case 24: - svga->render = svga_render_24bpp_highres; - if (svga->hdisp >= 1024) - svga->rowoffset <<= 1; - break; - case 32: - svga->render = svga_render_32bpp_highres; - svga->rowoffset <<= 1; - if (svga->hdisp >= 1024) { - svga->ma_latch <<= 1; - } - break; - } - } if (svga->ma_latch != mystique->ma_latch_old) { if (svga->interlace && svga->oddeven) @@ -980,14 +951,14 @@ mystique_recalctimings(svga_t *svga) if (mystique->type >= MGA_1064SG) svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; - if ((mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) && !(mystique->type >= MGA_2164W)) { + if ((mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8))) { svga->rowoffset <<= 1; if (mystique->type >= MGA_1064SG) svga->ma_latch <<= 1; } if (mystique->type >= MGA_1064SG) { - /*Mystique, unlike most SVGA cards, allows display start to take + /*Mystique and later, unlike most SVGA cards, allows display start to take effect mid-screen*/ if (!(mystique->type >= MGA_2164W)) svga->ma_latch <<= 1; @@ -1044,20 +1015,12 @@ mystique_recalctimings(svga_t *svga) break; case 16: svga->render = svga_render_16bpp_highres; - if (svga->dispend >= 1024) - svga->rowoffset <<= 1; break; case 24: svga->render = svga_render_24bpp_highres; - if (svga->hdisp >= 1024) - svga->rowoffset <<= 1; break; case 32: svga->render = svga_render_32bpp_highres; - svga->rowoffset <<= 1; - if (svga->hdisp >= 1024) { - svga->ma_latch <<= 1; - } break; } } From 148e466b807bb547a49891c6d691f98854157aeb Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 30 Dec 2023 01:27:04 +0600 Subject: [PATCH 156/936] Implement BAR swap for Matrox Mystique 220 Revision ID now properly indicates a Mystique 220 card --- src/video/vid_mga.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 6e85cfe5e..66a7dca71 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5676,9 +5676,9 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) mystique_t *mystique = (mystique_t *) priv; uint8_t ret = 0x00; - if (mystique->type >= MGA_2164W) + if (mystique->type >= MGA_1164SG) { - /* Millennium II and later Matrox cards swap MGABASE1 and 2. */ + /* Mystique 220, Millennium II and later Matrox cards swap MGABASE1 and 2. */ if (addr >= 0x10 && addr <= 0x13) addr += 0x4; else if (addr >= 0x14 && addr <= 0x17) @@ -5718,7 +5718,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) break; /*Fast DEVSEL timing*/ case 0x08: - ret = 0; + ret = (mystique->type == MGA_1164SG) ? 3 : 0; break; /*Revision ID*/ case 0x09: ret = 0; @@ -5837,9 +5837,9 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { mystique_t *mystique = (mystique_t *) priv; - if (mystique->type >= MGA_2164W) + if (mystique->type >= MGA_1164SG) { - /* Millennium II and later Matrox cards swap MGABASE1 and 2. */ + /* Mystique 220, Millennium II and later Matrox cards swap MGABASE1 and 2. */ if (addr >= 0x10 && addr <= 0x13) addr += 0x4; else if (addr >= 0x14 && addr <= 0x17) From 4d7fd68bbc5440d5bfb6f234e9afe7e9ec46b8e4 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 30 Dec 2023 02:10:45 +0600 Subject: [PATCH 157/936] Millennium and Millennium 2: Enable gamma correction only for 24+ bpp TVP3026 datasheet poorly or doesn't document at all gamma correction for 15/16 bpp --- src/video/vid_mga.c | 7 +++++-- src/video/vid_tvp3026_ramdac.c | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 66a7dca71..d30b2d681 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -947,9 +947,12 @@ mystique_recalctimings(svga_t *svga) svga->hdisp = (svga->crtc[1] + 1) << 3; svga->hdisp_time = svga->hdisp; svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); - svga->lut_map = !!(mystique->xmiscctrl & XMISCCTRL_RAMCS); + + if (mystique->type != MGA_2164W && mystique->type != MGA_2064W) + svga->lut_map = !!(mystique->xmiscctrl & XMISCCTRL_RAMCS); + if (mystique->type >= MGA_1064SG) - svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; + svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; if ((mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8))) { svga->rowoffset <<= 1; diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c index 611527a35..008f89a8b 100644 --- a/src/video/vid_tvp3026_ramdac.c +++ b/src/video/vid_tvp3026_ramdac.c @@ -515,6 +515,8 @@ tvp3026_recalctimings(void *priv, svga_t *svga) const tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv; svga->interlace = (ramdac->ccr & 0x40); + /* TODO: Figure out gamma correction for 15/16 bpp color. */ + svga->lut_map = !!(svga->bpp >= 24 && (ramdac->true_color & 0xf0) != 0x00); } void From dddf46f28a969d9ca38f19e4ec54dbee6e7652cf Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 30 Dec 2023 02:31:56 +0600 Subject: [PATCH 158/936] TVP3026: Implement gamma correction for 15/16 bpp modes --- src/include/86box/vid_svga.h | 13 +++++++------ src/video/vid_mga.c | 5 ++++- src/video/vid_s3.c | 7 ++++--- src/video/vid_tvp3026_ramdac.c | 26 +++++++++++++++++++++++++- 4 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 4d5539005..7ba637167 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -404,12 +404,13 @@ extern float stg_getclock(int clock, void *priv); extern void tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga); extern uint8_t tkd8001_ramdac_in(uint16_t addr, void *priv, svga_t *svga); -extern void tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_t *svga); -extern uint8_t tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga); -extern void tvp3026_recalctimings(void *priv, svga_t *svga); -extern void tvp3026_hwcursor_draw(svga_t *svga, int displine); -extern float tvp3026_getclock(int clock, void *priv); -extern void tvp3026_gpio(uint8_t (*read)(uint8_t cntl, void *priv), void (*write)(uint8_t cntl, uint8_t data, void *priv), void *cb_priv, void *priv); +extern void tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_t *svga); +extern uint8_t tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga); +extern uint32_t tvp3026_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp); +extern void tvp3026_recalctimings(void *priv, svga_t *svga); +extern void tvp3026_hwcursor_draw(svga_t *svga, int displine); +extern float tvp3026_getclock(int clock, void *priv); +extern void tvp3026_gpio(uint8_t (*read)(uint8_t cntl, void *priv), void (*write)(uint8_t cntl, uint8_t data, void *priv), void *cb_priv, void *priv); # ifdef EMU_DEVICE_H extern const device_t ati68860_ramdac_device; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index d30b2d681..521c561df 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -6038,6 +6038,7 @@ mystique_init(const device_t *info) mystique->svga.ramdac = device_add(&tvp3026_ramdac_device); mystique->svga.clock_gen = mystique->svga.ramdac; mystique->svga.getclock = tvp3026_getclock; + mystique->svga.conv_16to32 = tvp3026_conv_16to32; if (mystique->vram_size >= 16) mystique->svga.decode_mask = mystique->svga.vram_mask; tvp3026_gpio(mystique_tvp3026_gpio_read, mystique_tvp3026_gpio_write, mystique, mystique->svga.ramdac); @@ -6126,7 +6127,9 @@ mystique_init(const device_t *info) mystique->softrap_status_read = 1; mystique->svga.vsync_callback = mystique_vsync_callback; - mystique->svga.conv_16to32 = mystique_conv_16to32; + + if (mystique->type != MGA_2064W && mystique->type != MGA_2164W) + mystique->svga.conv_16to32 = mystique_conv_16to32; mystique->i2c = i2c_gpio_init("i2c_mga"); mystique->i2c_ddc = i2c_gpio_init("ddc_mga"); diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 9a56acdd7..3c11b90ee 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -8491,9 +8491,10 @@ s3_init(const device_t *info) svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; } else { - svga->ramdac = device_add(&tvp3026_ramdac_device); - svga->clock_gen = svga->ramdac; - svga->getclock = tvp3026_getclock; + svga->ramdac = device_add(&tvp3026_ramdac_device); + svga->clock_gen = svga->ramdac; + svga->getclock = tvp3026_getclock; + svga->conv_16to32 = tvp3026_conv_16to32; } break; diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c index 008f89a8b..2de3117b9 100644 --- a/src/video/vid_tvp3026_ramdac.c +++ b/src/video/vid_tvp3026_ramdac.c @@ -516,7 +516,31 @@ tvp3026_recalctimings(void *priv, svga_t *svga) svga->interlace = (ramdac->ccr & 0x40); /* TODO: Figure out gamma correction for 15/16 bpp color. */ - svga->lut_map = !!(svga->bpp >= 24 && (ramdac->true_color & 0xf0) != 0x00); + svga->lut_map = !!(svga->bpp >= 15 && (ramdac->true_color & 0xf0) != 0x00); +} + +uint32_t +tvp3026_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) +{ + tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t*)svga->ramdac; + uint32_t ret = 0x00000000; + + if (svga->lut_map) { + if (bpp == 15) { + uint8_t b = getcolr(svga->pallook[(color & 0x1f) << 3]); + uint8_t g = getcolg(svga->pallook[(color & 0x3e0) >> 2]); + uint8_t r = getcolb(svga->pallook[(color & 0x7c00) >> 7]); + ret = (video_15to32[color] & 0xFF000000) | makecol(r, g, b); + } else { + uint8_t b = getcolr(svga->pallook[(color & 0x1f) << 3]); + uint8_t g = getcolg(svga->pallook[(color & 0x7e0) >> 3]); + uint8_t r = getcolb(svga->pallook[(color & 0xf800) >> 8]); + ret = (video_16to32[color] & 0xFF000000) | makecol(r, g, b); + } + } else + ret = (bpp == 15) ? video_15to32[color] : video_16to32[color]; + + return ret; } void From 7701174b39ddd4eb20d1121a8d2dbfa9bcb7451b Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 30 Dec 2023 00:04:57 +0100 Subject: [PATCH 159/936] CL-GD 5446/5480: Implement missing byte swap behavior, fixes fonts with the Windows 3.1 CL-GD 5446 driver when cache is enabled. --- src/video/vid_cl54xx.c | 146 +++++++++++++++++++++++++---------------- 1 file changed, 90 insertions(+), 56 deletions(-) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 05e45b7d7..c6b3b725f 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -2074,18 +2074,49 @@ gd54xx_rop(gd54xx_t *gd54xx, uint8_t *res, uint8_t *dst, const uint8_t *src) } static uint8_t -gd54xx_mem_sys_dest_read(gd54xx_t *gd54xx) +gd54xx_get_aperture(uint32_t addr) { + uint32_t ap = addr >> 22; + return (uint8_t) (ap & 0x03); +} + +static uint32_t +gd54xx_mem_sys_pos_adj(gd54xx_t *gd54xx, uint8_t ap, uint32_t pos) +{ + uint32_t ret = pos; + + if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && + !(gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) { + switch (ap) { + case 1: + ret ^= 1; + break; + case 2: + ret ^= 3; + break; + } + } + + return ret; +} + +static uint8_t +gd54xx_mem_sys_dest_read(gd54xx_t *gd54xx, uint8_t ap) +{ + uint32_t adj_pos = gd54xx_mem_sys_pos_adj(gd54xx, ap, gd54xx->blt.msd_buf_pos); uint8_t ret = 0xff; if (gd54xx->blt.msd_buf_cnt != 0) { - ret = gd54xx->blt.msd_buf[gd54xx->blt.msd_buf_pos++]; + ret = gd54xx->blt.msd_buf[adj_pos]; + + gd54xx->blt.msd_buf_pos++; gd54xx->blt.msd_buf_cnt--; if (gd54xx->blt.msd_buf_cnt == 0) { if (gd54xx->countminusone == 1) { gd54xx->blt.msd_buf_pos = 0; - if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && !(gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) + if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && + !(gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) gd54xx_start_blit(0xff, 8, gd54xx, &gd54xx->svga); else gd54xx_start_blit(0xffffffff, 32, gd54xx, &gd54xx->svga); @@ -2098,14 +2129,17 @@ gd54xx_mem_sys_dest_read(gd54xx_t *gd54xx) } static void -gd54xx_mem_sys_src_write(gd54xx_t *gd54xx, uint8_t val) +gd54xx_mem_sys_src_write(gd54xx_t *gd54xx, uint8_t val, uint8_t ap) { - gd54xx->blt.sys_src32 &= ~(0xff << (gd54xx->blt.sys_cnt << 3)); - gd54xx->blt.sys_src32 |= (val << (gd54xx->blt.sys_cnt << 3)); + uint32_t adj_pos = gd54xx_mem_sys_pos_adj(gd54xx, ap, gd54xx->blt.sys_cnt); + + gd54xx->blt.sys_src32 &= ~(0xff << (adj_pos << 3)); + gd54xx->blt.sys_src32 |= (val << (adj_pos << 3)); gd54xx->blt.sys_cnt = (gd54xx->blt.sys_cnt + 1) & 3; if (gd54xx->blt.sys_cnt == 0) { - if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && !(gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) { + if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && + !(gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) { for (uint8_t i = 0; i < 32; i += 8) gd54xx_start_blit((gd54xx->blt.sys_src32 >> i) & 0xff, 8, gd54xx, &gd54xx->svga); } else @@ -2120,7 +2154,7 @@ gd54xx_write(uint32_t addr, uint8_t val, void *priv) svga_t *svga = &gd54xx->svga; if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd54xx_mem_sys_src_write(gd54xx, val); + gd54xx_mem_sys_src_write(gd54xx, val, 0); return; } @@ -2251,13 +2285,6 @@ gd54xx_write_modes45(svga_t *svga, uint8_t val, uint32_t addr) svga->changedvram[addr >> 12] = changeframecount; } -static uint8_t -gd54xx_get_aperture(uint32_t addr) -{ - uint32_t ap = addr >> 22; - return (uint8_t) (ap & 0x03); -} - static int gd54xx_aperture2_enabled(gd54xx_t *gd54xx) { @@ -2294,7 +2321,7 @@ gd54xx_readb_linear(uint32_t addr, void *priv) /* Do mem sys dest reads here if the blitter is neither paused, nor is there a second aperture. */ if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) - return gd54xx_mem_sys_dest_read(gd54xx); + return gd54xx_mem_sys_dest_read(gd54xx, ap); switch (ap) { default: @@ -2318,8 +2345,9 @@ gd54xx_readb_linear(uint32_t addr, void *priv) static uint16_t gd54xx_readw_linear(uint32_t addr, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) priv; - svga_t *svga = &gd54xx->svga; + gd54xx_t *gd54xx = (gd54xx_t *) priv; + svga_t *svga = &gd54xx->svga; + uint32_t old_addr = addr; uint8_t ap = gd54xx_get_aperture(addr); uint16_t temp; @@ -2338,8 +2366,8 @@ gd54xx_readw_linear(uint32_t addr, void *priv) /* Do mem sys dest reads here if the blitter is neither paused, nor is there a second aperture. */ if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - temp = gd54xx_readb_linear(addr, priv); - temp |= gd54xx_readb_linear(addr + 1, priv) << 8; + temp = gd54xx_readb_linear(old_addr, priv); + temp |= gd54xx_readb_linear(old_addr + 1, priv) << 8; return temp; } @@ -2367,8 +2395,9 @@ gd54xx_readw_linear(uint32_t addr, void *priv) static uint32_t gd54xx_readl_linear(uint32_t addr, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) priv; - svga_t *svga = &gd54xx->svga; + gd54xx_t *gd54xx = (gd54xx_t *) priv; + svga_t *svga = &gd54xx->svga; + uint32_t old_addr = addr; uint8_t ap = gd54xx_get_aperture(addr); uint32_t temp; @@ -2387,10 +2416,10 @@ gd54xx_readl_linear(uint32_t addr, void *priv) /* Do mem sys dest reads here if the blitter is neither paused, nor is there a second aperture. */ if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - temp = gd54xx_readb_linear(addr, priv); - temp |= gd54xx_readb_linear(addr + 1, priv) << 8; - temp |= gd54xx_readb_linear(addr + 2, priv) << 16; - temp |= gd54xx_readb_linear(addr + 3, priv) << 24; + temp = gd54xx_readb_linear(old_addr, priv); + temp |= gd54xx_readb_linear(old_addr + 1, priv) << 8; + temp |= gd54xx_readb_linear(old_addr + 2, priv) << 16; + temp |= gd54xx_readb_linear(old_addr + 3, priv) << 24; return temp; } @@ -2427,9 +2456,11 @@ static uint8_t gd5436_aperture2_readb(UNUSED(uint32_t addr), void *priv) { gd54xx_t *gd54xx = (gd54xx_t *) priv; + uint8_t ap = gd54xx_get_aperture(addr); - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) - return gd54xx_mem_sys_dest_read(gd54xx); + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && + gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) + return gd54xx_mem_sys_dest_read(gd54xx, ap); return 0xff; } @@ -2440,7 +2471,8 @@ gd5436_aperture2_readw(uint32_t addr, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) priv; uint16_t ret = 0xffff; - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && + gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { ret = gd5436_aperture2_readb(addr, priv); ret |= gd5436_aperture2_readb(addr + 1, priv) << 8; return ret; @@ -2455,7 +2487,8 @@ gd5436_aperture2_readl(uint32_t addr, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) priv; uint32_t ret = 0xffffffff; - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && + gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { ret = gd5436_aperture2_readb(addr, priv); ret |= gd5436_aperture2_readb(addr + 1, priv) << 8; ret |= gd5436_aperture2_readb(addr + 2, priv) << 16; @@ -2470,10 +2503,11 @@ static void gd5436_aperture2_writeb(UNUSED(uint32_t addr), uint8_t val, void *priv) { gd54xx_t *gd54xx = (gd54xx_t *) priv; + uint8_t ap = gd54xx_get_aperture(addr); - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest - && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) - gd54xx_mem_sys_src_write(gd54xx, val); + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && + gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) + gd54xx_mem_sys_src_write(gd54xx, val, ap); } static void @@ -2481,8 +2515,8 @@ gd5436_aperture2_writew(uint32_t addr, uint16_t val, void *priv) { gd54xx_t *gd54xx = (gd54xx_t *) priv; - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest - && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && + gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { gd5436_aperture2_writeb(addr, val, gd54xx); gd5436_aperture2_writeb(addr + 1, val >> 8, gd54xx); } @@ -2493,8 +2527,8 @@ gd5436_aperture2_writel(uint32_t addr, uint32_t val, void *priv) { gd54xx_t *gd54xx = (gd54xx_t *) priv; - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest - && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && + gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { gd5436_aperture2_writeb(addr, val, gd54xx); gd5436_aperture2_writeb(addr + 1, val >> 8, gd54xx); gd5436_aperture2_writeb(addr + 2, val >> 16, gd54xx); @@ -2508,7 +2542,7 @@ gd54xx_writeb_linear(uint32_t addr, uint8_t val, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; - uint8_t ap = gd54xx_get_aperture(addr); + uint8_t ap = gd54xx_get_aperture(addr); if ((svga->seqregs[0x07] & 0x01) == 0) { svga_write_linear(addr, val, svga); @@ -2526,7 +2560,7 @@ gd54xx_writeb_linear(uint32_t addr, uint8_t val, void *priv) /* Do mem sys src writes here if the blitter is neither paused, nor is there a second aperture. */ if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd54xx_mem_sys_src_write(gd54xx, val); + gd54xx_mem_sys_src_write(gd54xx, val, ap); return; } @@ -2552,10 +2586,10 @@ gd54xx_writeb_linear(uint32_t addr, uint8_t val, void *priv) static void gd54xx_writew_linear(uint32_t addr, uint16_t val, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) priv; - svga_t *svga = &gd54xx->svga; - - uint8_t ap = gd54xx_get_aperture(addr); + gd54xx_t *gd54xx = (gd54xx_t *) priv; + svga_t *svga = &gd54xx->svga; + uint32_t old_addr = addr; + uint8_t ap = gd54xx_get_aperture(addr); if ((svga->seqregs[0x07] & 0x01) == 0) { svga_writew_linear(addr, val, svga); @@ -2573,8 +2607,8 @@ gd54xx_writew_linear(uint32_t addr, uint16_t val, void *priv) /* Do mem sys src writes here if the blitter is neither paused, nor is there a second aperture. */ if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd54xx_writeb_linear(addr, val, gd54xx); - gd54xx_writeb_linear(addr + 1, val >> 8, gd54xx); + gd54xx_writeb_linear(old_addr, val, gd54xx); + gd54xx_writeb_linear(old_addr + 1, val >> 8, gd54xx); return; } @@ -2619,10 +2653,10 @@ gd54xx_writew_linear(uint32_t addr, uint16_t val, void *priv) static void gd54xx_writel_linear(uint32_t addr, uint32_t val, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) priv; - svga_t *svga = &gd54xx->svga; - - uint8_t ap = gd54xx_get_aperture(addr); + gd54xx_t *gd54xx = (gd54xx_t *) priv; + svga_t *svga = &gd54xx->svga; + uint32_t old_addr = addr; + uint8_t ap = gd54xx_get_aperture(addr); if ((svga->seqregs[0x07] & 0x01) == 0) { svga_writel_linear(addr, val, svga); @@ -2640,10 +2674,10 @@ gd54xx_writel_linear(uint32_t addr, uint32_t val, void *priv) /* Do mem sys src writes here if the blitter is neither paused, nor is there a second aperture. */ if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd54xx_writeb_linear(addr, val, gd54xx); - gd54xx_writeb_linear(addr + 1, val >> 8, gd54xx); - gd54xx_writeb_linear(addr + 2, val >> 16, gd54xx); - gd54xx_writeb_linear(addr + 3, val >> 24, gd54xx); + gd54xx_writeb_linear(old_addr, val, gd54xx); + gd54xx_writeb_linear(old_addr + 1, val >> 8, gd54xx); + gd54xx_writeb_linear(old_addr + 2, val >> 16, gd54xx); + gd54xx_writeb_linear(old_addr + 3, val >> 24, gd54xx); return; } @@ -2705,7 +2739,7 @@ gd54xx_read(uint32_t addr, void *priv) return svga_read(addr, svga); if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) - return gd54xx_mem_sys_dest_read(gd54xx); + return gd54xx_mem_sys_dest_read(gd54xx, 0); addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_read_linear(addr, svga); @@ -2938,7 +2972,7 @@ gd543x_mmio_writeb(uint32_t addr, uint8_t val, void *priv) svga_t *svga = &gd54xx->svga; if (!gd543x_do_mmio(svga, addr) && !gd54xx->blt.ms_is_dest && gd54xx->countminusone && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd54xx_mem_sys_src_write(gd54xx, val); + gd54xx_mem_sys_src_write(gd54xx, val, 0); return; } @@ -3127,7 +3161,7 @@ gd543x_mmio_read(uint32_t addr, void *priv) } else if (gd54xx->mmio_vram_overlap) ret = gd54xx_read(addr, gd54xx); else if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - ret = gd54xx_mem_sys_dest_read(gd54xx); + ret = gd54xx_mem_sys_dest_read(gd54xx, 0); } return ret; From bfee63da82b9b78fc6925c4d573a012db7137eab Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 30 Dec 2023 00:08:44 +0100 Subject: [PATCH 160/936] Fixes a warning in the TVP3026 RAM DAC code. --- src/video/vid_tvp3026_ramdac.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c index 2de3117b9..a28cc2aed 100644 --- a/src/video/vid_tvp3026_ramdac.c +++ b/src/video/vid_tvp3026_ramdac.c @@ -522,7 +522,6 @@ tvp3026_recalctimings(void *priv, svga_t *svga) uint32_t tvp3026_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) { - tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t*)svga->ramdac; uint32_t ret = 0x00000000; if (svga->lut_map) { From 4129c99cfe36d9ba21f93bd3f372c6c0f7d21b33 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 30 Dec 2023 05:54:27 +0500 Subject: [PATCH 161/936] Actually enable gameport on init on non-PnP SB16/AWE32 --- src/sound/snd_sb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 602c1c2a7..b2a629079 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -2141,6 +2141,7 @@ sb_16_init(UNUSED(const device_t *info)) sb->gameport = gameport_add(&gameport_pnp_device); sb->gameport_addr = 0x200; + gameport_remap(sb->gameport, sb->gameport_addr); return sb; } @@ -2352,6 +2353,7 @@ sb_16_compat_init(const device_t *info) sb->gameport = gameport_add(&gameport_pnp_device); sb->gameport_addr = 0x200; + gameport_remap(sb->gameport, sb->gameport_addr); return sb; } @@ -2455,6 +2457,7 @@ sb_awe32_init(UNUSED(const device_t *info)) sb->gameport = gameport_add(&gameport_pnp_device); sb->gameport_addr = 0x200; + gameport_remap(sb->gameport, sb->gameport_addr); return sb; } From ddb43a78c1d8da41e57d186349fd235a46d8c40a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 30 Dec 2023 12:52:21 +0600 Subject: [PATCH 162/936] vid_voodoo_banshee: Implement gamma correction for 16bpp --- src/video/vid_voodoo_banshee.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index d0fad5b95..23236be6f 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -219,7 +219,9 @@ enum { #define VIDPROCCFG_INTERLACE (1 << 3) #define VIDPROCCFG_HALF_MODE (1 << 4) #define VIDPROCCFG_OVERLAY_ENABLE (1 << 8) +#define VIDPROCCFG_DESKTOP_CLUT_BYPASS (1 << 10) #define VIDPROCCFG_OVERLAY_CLUT_BYPASS (1 << 11) +#define VIDPROCCFG_DESKTOP_CLUT_SEL (1 << 12) #define VIDPROCCFG_OVERLAY_CLUT_SEL (1 << 13) #define VIDPROCCFG_H_SCALE_ENABLE (1 << 14) #define VIDPROCCFG_V_SCALE_ENABLE (1 << 15) @@ -466,6 +468,32 @@ banshee_updatemapping(banshee_t *banshee) mem_mapping_set_addr(&banshee->reg_mapping_high, banshee->memBaseAddr0 + 0xc00000, 20 << 20); } +uint32_t +banshee_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) +{ + banshee_t *banshee = (banshee_t *) svga->priv; + uint32_t ret = 0x00000000; + uint16_t src_b = (color & 0x1f) << 3; + uint16_t src_g = (color & 0x7e0) >> 3; + uint16_t src_r = (color & 0xf800) >> 8; + + if (banshee->vidProcCfg & VIDPROCCFG_DESKTOP_CLUT_SEL) { + src_b += 256; + src_g += 256; + src_r += 256; + } + + if (svga->lut_map) { + uint8_t b = getcolr(svga->pallook[src_b]); + uint8_t g = getcolg(svga->pallook[src_g]); + uint8_t r = getcolb(svga->pallook[src_r]); + ret = (video_16to32[color] & 0xFF000000) | makecol(r, g, b); + } else + ret = video_16to32[color]; + + return ret; +} + static void banshee_render_16bpp_tiled(svga_t *svga) { @@ -489,7 +517,7 @@ banshee_render_16bpp_tiled(svga_t *svga) const uint16_t *vram_p = (uint16_t *) &svga->vram[addr & svga->vram_display_mask]; for (uint8_t xx = 0; xx < 64; xx++) - *p++ = video_16to32[*vram_p++]; + *p++ = banshee_conv_16to32(svga, *vram_p++, 16); drawn = 1; } else @@ -806,6 +834,7 @@ banshee_ext_outl(uint16_t addr, uint32_t val, void *priv) banshee->overlay_pix_fmt = (val & VIDPROCCFG_OVERLAY_PIX_FORMAT_MASK) >> VIDPROCCFG_OVERLAY_PIX_FORMAT_SHIFT; svga->hwcursor.ena = val & VIDPROCCFG_HWCURSOR_ENA; svga->fullchange = changeframecount; + svga->lut_map = !(val & VIDPROCCFG_DESKTOP_CLUT_BYPASS) && (svga->bpp < 24); svga_recalctimings(svga); break; @@ -3190,6 +3219,8 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int banshee->i2c_ddc = i2c_gpio_init("ddc_voodoo_banshee"); banshee->ddc = ddc_init(i2c_gpio_get_bus(banshee->i2c_ddc)); + banshee->svga.conv_16to32 = banshee_conv_16to32; + switch (type) { case TYPE_BANSHEE: if (has_sgram) { From 9854ccc7d2c028e92a24fab6633356a0f9aaa97a Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 30 Dec 2023 02:39:56 -0500 Subject: [PATCH 163/936] Fix debian package build --- debian/control | 11 ++++++++--- debian/copyright | 3 ++- debian/rules | 5 ++++- debian/source/format | 2 +- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/debian/control b/debian/control index 78a92bf8f..d67f5965b 100644 --- a/debian/control +++ b/debian/control @@ -1,18 +1,21 @@ Source: 86box Section: otherosfs Priority: optional -Maintainer: Mariusz Kurek +Maintainer: Jasmine Iwanek Build-Depends: cmake (>= 3.21), debhelper-compat (= 13), libevdev-dev, + libfluidsynth-dev, libfreetype-dev, libopenal-dev, libqt5opengl5-dev, librtmidi-dev, libsdl2-dev, libslirp-dev, + libxkbcommon-x11-dev, ninja-build, - qttools5-dev + qttools5-dev, + qtbase5-private-dev Standards-Version: 4.6.0 Homepage: https://86box.net/ #Vcs-Browser: https://salsa.debian.org/debian/86box @@ -26,4 +29,6 @@ Depends: ${shlibs:Depends}, sse2-support [i386] Recommends: libpcap0.8-dev Description: An emulator for classic IBM PC clones -#TODO: insert long description, indented with spaces + 86Box is a low level x86 emulator that runs older operating systems and software + designed for IBM PC systems and compatibles from 1981 through + fairly recent system designs based on the PCI bus. \ No newline at end of file diff --git a/debian/copyright b/debian/copyright index 22817edc5..9a71df3a0 100644 --- a/debian/copyright +++ b/debian/copyright @@ -8,7 +8,8 @@ Copyright: License: GPL-2.0+ Files: debian/* -Copyright: 2022 Mariusz Kurek +Copyright: 2023 Jasmine Iwanek + 2022 Mariusz Kurek License: GPL-2.0+ License: GPL-2.0+ diff --git a/debian/rules b/debian/rules index 7b0605e72..1ee4be4ed 100644 --- a/debian/rules +++ b/debian/rules @@ -25,7 +25,10 @@ endif dh $@ --buildsystem cmake+ninja override_dh_auto_configure: - dh_auto_configure --buildsystem cmake+ninja -- --preset regular --toolchain $(TOOLCHAIN) -DNEW_DYNAREC=$(NDR) + dh_auto_configure --buildsystem cmake+ninja -- --preset regular --toolchain $(TOOLCHAIN) -DNEW_DYNAREC=$(NDR) -B . + +override_dh_auto_build: + dh_auto_build --buildsystem cmake+ninja override_dh_auto_test: diff --git a/debian/source/format b/debian/source/format index 163aaf8d8..89ae9db8f 100644 --- a/debian/source/format +++ b/debian/source/format @@ -1 +1 @@ -3.0 (quilt) +3.0 (native) From fa7804e1c1c0035621ffed38e3473cf7a2a009fb Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 30 Dec 2023 03:30:44 -0500 Subject: [PATCH 164/936] Correct prior maintainer's name --- debian/copyright | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/copyright b/debian/copyright index 9a71df3a0..58c9077fa 100644 --- a/debian/copyright +++ b/debian/copyright @@ -9,7 +9,7 @@ License: GPL-2.0+ Files: debian/* Copyright: 2023 Jasmine Iwanek - 2022 Mariusz Kurek + 2022 Lili Kurek License: GPL-2.0+ License: GPL-2.0+ From 08428d497bab16500c6fa9996db462b7497d5bfc Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 30 Dec 2023 16:10:28 +0600 Subject: [PATCH 165/936] Disable 32-bit Z buffer on Mystique 220 and earlier --- src/video/vid_mga.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 521c561df..55f9cd243 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -1729,7 +1729,10 @@ mystique_accel_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) case REG_MACCESS + 3: WRITE8(addr, mystique->maccess, val); mystique->dwgreg.dither = mystique->maccess >> 30; - mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * ((mystique->maccess & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg; + if (mystique->type < MGA_2164W) + mystique->maccess &= ~MACCESS_ZWIDTH; + else + mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * ((mystique->maccess & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg; break; case REG_MCTLWTST: From bdae2ace60cae45039defd12f5e69016f09a77e8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 30 Dec 2023 18:03:26 +0600 Subject: [PATCH 166/936] Fix a dumb copy-paste mistake --- src/video/vid_mga.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 55f9cd243..33a3385d5 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -4728,10 +4728,10 @@ blit_trap(mystique_t *mystique) } if (mystique->maccess_running & MACCESS_ZWIDTH) { - mystique->dwgreg.extended_dr[0] += z_back_32 + mystique->dwgreg.extended_dr[3]; + mystique->dwgreg.extended_dr[0] = z_back_32 + mystique->dwgreg.extended_dr[3]; mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; } else { - mystique->dwgreg.dr[0] += z_back + mystique->dwgreg.dr[3]; + mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); } mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; From 69780ecc023174ed1574121aea518d0c5aef5e52 Mon Sep 17 00:00:00 2001 From: Conrad Kostecki Date: Sat, 30 Dec 2023 13:59:04 +0100 Subject: [PATCH 167/936] Intel Premiere/PCI ED: update bios to 1013AF2 This updates the filename to match the newer 1013AF2 BIOS. Signed-off-by: Conrad Kostecki --- src/machine/m_at_socket4.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index ad6d2c995..a32617de4 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -290,8 +290,8 @@ machine_at_revenge_init(const machine_t *model) { int ret; - ret = bios_load_linear_combined("roms/machines/revenge/1009af2_.bio", - "roms/machines/revenge/1009af2_.bi1", + ret = bios_load_linear_combined("roms/machines/revenge/1013af2_.bio", + "roms/machines/revenge/1013af2_.bi1", 0x1c000, 128); if (bios_only || !ret) From 26c1c77758dee5baf4050a99e1d50b09e43d9af5 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 30 Dec 2023 20:50:17 +0600 Subject: [PATCH 168/936] Fix yet another dumb copy-paste mistake --- src/video/vid_mga.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 33a3385d5..0a9df92ad 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5024,10 +5024,10 @@ skip_pixel: } if (mystique->maccess_running & MACCESS_ZWIDTH) { - mystique->dwgreg.extended_dr[0] += z_back_32 + mystique->dwgreg.extended_dr[3]; + mystique->dwgreg.extended_dr[0] = z_back_32 + mystique->dwgreg.extended_dr[3]; mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; } else { - mystique->dwgreg.dr[0] += z_back + mystique->dwgreg.dr[3]; + mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); } mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; From 0265b34384234dca2e41ef5823d9dac242e4bc6d Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 30 Dec 2023 19:40:05 +0100 Subject: [PATCH 169/936] 1x CD-ROM speed is 176400 bytes per second, not 176 * 1024 bytes per second. --- src/scsi/scsi_cdrom.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index d2a6170a6..65417ebe3 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -990,7 +990,8 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) if (dev->current_cdb[0] == 0x42) dev->callback += 40.0; /* Account for seek time. */ - bytes_per_second = 176.0 * 1024.0; + /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ + bytes_per_second = 176400.0; bytes_per_second *= (double) dev->drv->cur_speed; break; case 0xc6 ... 0xc7: @@ -1011,7 +1012,8 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) case CDROM_TYPE_SONY_CDU561_18k: case CDROM_TYPE_SONY_CDU76S_100: case CDROM_TYPE_TEXEL_DMXX24_100: - bytes_per_second = 176.0 * 1024.0; + /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ + bytes_per_second = 176400.0; bytes_per_second *= (double) dev->drv->cur_speed; break; } @@ -1023,7 +1025,8 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) case CDROM_TYPE_SONY_CDU76S_100: case CDROM_TYPE_PIONEER_DRM604X_2403: case CDROM_TYPE_TEXEL_DMXX24_100: - bytes_per_second = 176.0 * 1024.0; + /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ + bytes_per_second = 176400.0; bytes_per_second *= (double) dev->drv->cur_speed; break; } @@ -1037,7 +1040,8 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) case CDROM_TYPE_TEXEL_DMXX24_100: if (dev->current_cdb[0] == 0xc2) dev->callback += 40.0; - bytes_per_second = 176.0 * 1024.0; + /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ + bytes_per_second = 176400.0; bytes_per_second *= (double) dev->drv->cur_speed; break; } @@ -1049,7 +1053,8 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) case CDROM_TYPE_NEC_77_106: case CDROM_TYPE_NEC_211_100: case CDROM_TYPE_NEC_464_105: - bytes_per_second = 176.0 * 1024.0; + /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ + bytes_per_second = 176400.0; bytes_per_second *= (double) dev->drv->cur_speed; break; } From bd1a5e03b059897e55921dff4f9e520eef8c45fc Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 31 Dec 2023 02:19:11 +0600 Subject: [PATCH 170/936] Somewhat-working Matrox Productiva G100 --- src/include/86box/video.h | 1 + src/video/vid_mga.c | 287 +++++++++++++++++++++++++++++++++++--- src/video/vid_table.c | 1 + 3 files changed, 270 insertions(+), 19 deletions(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 618819768..0f0a13182 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -439,6 +439,7 @@ extern const device_t millennium_device; extern const device_t mystique_device; extern const device_t mystique_220_device; extern const device_t millennium_ii_device; +extern const device_t productiva_g100_device; /* Oak OTI-0x7 */ extern const device_t oti037c_device; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 0a9df92ad..f064b4d34 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -41,6 +41,7 @@ #define ROM_MILLENNIUM_II "roms/video/matrox/matrox2164wpc.BIN" #define ROM_MYSTIQUE "roms/video/matrox/MYSTIQUE.VBI" #define ROM_MYSTIQUE_220 "roms/video/matrox/Myst220_66-99mhz.vbi" +#define ROM_G100 "roms/video/matrox/productiva8mbsdr.BIN" #define FIFO_SIZE 65536 #define FIFO_MASK (FIFO_SIZE - 1) @@ -166,6 +167,14 @@ #define REG_SECADDRESS 0x2c40 #define REG_SECEND 0x2c44 #define REG_SOFTRAP 0x2c48 +#define REG_ALPHASTART 0x2c70 +#define REG_ALPHACTRL 0x2c7c +#define REG_ALPHAXINC 0x2c74 +#define REG_ALPHAYINC 0x2c78 +#define REG_FOGSTART 0x1cc4 +#define REG_FOGXINC 0x1cd4 +#define REG_FOGYINC 0x1ce4 +#define REG_FOGCOL 0x1cf4 /*Mystique only*/ #define REG_PALWTADD 0x3c00 @@ -319,6 +328,7 @@ #define MACCESS_PWIDTH_32 (2 << 0) #define MACCESS_PWIDTH_24 (3 << 0) #define MACCESS_ZWIDTH (1 << 3) +#define MACCESS_FOGEN (1 << 26) #define MACCESS_TLUTLOAD (1 << 29) #define MACCESS_NODITHER (1 << 30) #define MACCESS_DIT555 (1 << 31) @@ -359,7 +369,10 @@ #define TEXCTL_PALSEL_MASK (0xf << 4) #define TEXCTL_TPITCH_SHIFT (16) #define TEXCTL_TPITCH_MASK (7 << TEXCTL_TPITCH_SHIFT) +#define TEXCTL_TPITCHLIN (1 << 8) +#define TEXCTL_TPITCHEXT_MASK (0x7ff << 9) #define TEXCTL_NPCEN (1 << 21) +#define TEXCTL_AZEROEXTEND (1 << 23) #define TEXCTL_DECALCKEY (1 << 24) #define TEXCTL_TAKEY (1 << 25) #define TEXCTL_TAMASK (1 << 26) @@ -394,6 +407,7 @@ enum { MGA_1064SG, /*Mystique*/ MGA_1164SG, /*Mystique 220*/ MGA_2164W, /*Millennium II*/ + MGA_G100, /*Productiva G100*/ }; enum { @@ -494,7 +508,9 @@ typedef struct mystique_t { pitch, plnwt, ybot, ydstorg, ytop, texorg, texwidth, texheight, texctl, textrans, zorg, ydst_lin, - src_addr, z_base, iload_rem_data, highv_data; + src_addr, z_base, iload_rem_data, highv_data, + fogcol, fogxinc : 24, fogyinc : 24, fogstart : 24, + alphactrl, alphaxinc : 24, alphayinc : 24, alphastart : 24; uint32_t src[4], ar[7], dr[16], tmr[9]; @@ -2560,6 +2576,38 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) mystique->softrap_pending += 1; break; + case REG_ALPHACTRL: + mystique->dwgreg.alphactrl = val; + break; + + case REG_ALPHASTART: + mystique->dwgreg.alphastart = val; + break; + + case REG_ALPHAXINC: + mystique->dwgreg.alphaxinc = val; + break; + + case REG_ALPHAYINC: + mystique->dwgreg.alphayinc = val; + break; + + case REG_FOGCOL: + mystique->dwgreg.fogcol = val; + break; + + case REG_FOGSTART: + mystique->dwgreg.fogstart = val; + break; + + case REG_FOGXINC: + mystique->dwgreg.fogxinc = val; + break; + + case REG_FOGYINC: + mystique->dwgreg.fogyinc = val; + break; + default: mystique_accel_ctrl_write_b(addr, val & 0xff, priv); mystique_accel_ctrl_write_b(addr + 1, (val >> 8) & 0xff, priv); @@ -4781,7 +4829,7 @@ blit_trap(mystique_t *mystique) } static int -texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atransp) +texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atransp, int *tex_a) { svga_t *svga = &mystique->svga; @@ -4794,6 +4842,16 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra uint16_t src = 0; int s; int t; + int tex_pitch = 1 << tex_shift; + + *tex_a = 255; + + if (mystique->type >= MGA_G100 && (mystique->dwgreg.texctl & TEXCTL_TPITCHLIN)) + { + tex_pitch = (mystique->dwgreg.texctl & TEXCTL_TPITCHEXT_MASK) >> 9; + if (tex_pitch == 0) + tex_pitch = 2048; + } if (mystique->dwgreg.texctl & TEXCTL_NPCEN) { const int s_shift = 20 - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); @@ -4828,7 +4886,7 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra switch (mystique->dwgreg.texctl & TEXCTL_TEXFORMAT_MASK) { case TEXCTL_TEXFORMAT_TW4: - src = svga->vram[(mystique->dwgreg.texorg + (((t << tex_shift) + s) >> 1)) & mystique->vram_mask]; + src = svga->vram[(mystique->dwgreg.texorg + (((t * tex_pitch) + s) >> 1)) & mystique->vram_mask]; if (s & 1) src >>= 4; else @@ -4839,14 +4897,14 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra *atransp = 0; break; case TEXCTL_TEXFORMAT_TW8: - src = svga->vram[(mystique->dwgreg.texorg + (t << tex_shift) + s) & mystique->vram_mask]; + src = svga->vram[(mystique->dwgreg.texorg + (t * tex_pitch) + s) & mystique->vram_mask]; *tex_r = mystique->lut[src].r; *tex_g = mystique->lut[src].g; *tex_b = mystique->lut[src].b; *atransp = 0; break; case TEXCTL_TEXFORMAT_TW15: - src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t << tex_shift) + s) & mystique->vram_mask_w]; + src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t * tex_pitch) + s) & mystique->vram_mask_w]; *tex_r = ((src >> 10) & 0x1f) << 3; *tex_g = ((src >> 5) & 0x1f) << 3; *tex_b = (src & 0x1f) << 3; @@ -4855,8 +4913,22 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra else *atransp = 0; break; + case TEXCTL_TEXFORMAT_TW12: + src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t * tex_pitch) + s) & mystique->vram_mask_w]; + *tex_r = ((src >> 8) & 0xf) << 3; + *tex_g = ((src >> 4) & 0xf) << 3; + *tex_b = (src & 0xf) << 3; + *tex_a = ((src >> 12) & 0xf) << 3; + if (mystique->dwgreg.texctl & TEXCTL_AZEROEXTEND) { + *atransp = (((src >> 12) & 0xf) & mystique->dwgreg.ta_mask) == mystique->dwgreg.ta_key; + } else { + uint8_t ta_mask = mystique->dwgreg.ta_mask ? 0xf : 0x0; + uint8_t ta_key = mystique->dwgreg.ta_key ? 0xf : 0x0; + *atransp = (((src >> 12) & 0xf) & ta_mask) == ta_key; + } + break; case TEXCTL_TEXFORMAT_TW16: - src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t << tex_shift) + s) & mystique->vram_mask_w]; + src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t * tex_pitch) + s) & mystique->vram_mask_w]; *tex_r = (src >> 11) << 3; *tex_g = ((src >> 5) & 0x3f) << 2; *tex_b = (src & 0x1f) << 3; @@ -4903,6 +4975,8 @@ blit_texture_trap(mystique_t *mystique) uint32_t s_back = mystique->dwgreg.tmr[6]; uint32_t t_back = mystique->dwgreg.tmr[7]; uint32_t q_back = mystique->dwgreg.tmr[8]; + uint32_t a_back = mystique->dwgreg.alphastart; + uint32_t fog_back = mystique->dwgreg.fogstart; while (x_l != x_r) { if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) { @@ -4921,11 +4995,15 @@ blit_texture_trap(mystique_t *mystique) int tex_r = 0; int tex_g = 0; int tex_b = 0; + int tex_a = 0; int ctransp; int atransp = 0; int i_r = 0; int i_g = 0; int i_b = 0; + int i_a = 255; + int i_fog = 0; + uint8_t final_a = 255; if (!(mystique->dwgreg.dr[4] & (1 << 23))) i_r = (mystique->dwgreg.dr[4] >> 15) & 0xff; @@ -4934,7 +5012,43 @@ blit_texture_trap(mystique_t *mystique) if (!(mystique->dwgreg.dr[12] & (1 << 23))) i_b = (mystique->dwgreg.dr[12] >> 15) & 0xff; - ctransp = texture_read(mystique, &tex_r, &tex_g, &tex_b, &atransp); + if (mystique->type >= MGA_G100) + { + if (!(mystique->dwgreg.alphastart & (1 << 23))) + i_a = (mystique->dwgreg.alphastart >> 15) & 0xff; + else + i_a = 0; + + if (!(mystique->dwgreg.fogstart & (1 << 23))) + i_fog = (mystique->dwgreg.fogstart >> 15) & 0xff; + else + i_fog = 0; + } + + ctransp = texture_read(mystique, &tex_r, &tex_g, &tex_b, &atransp, &tex_a); + + if (mystique->type >= MGA_G100) + { + uint8_t alpha_sel = (mystique->dwgreg.alphactrl >> 24) & 3; + + switch (alpha_sel) + { + case 0x0: /* alpha from texture */ + final_a = tex_a; + break; + default: + case 0x1: /* interpolated alpha */ + if ((mystique->dwgreg.alphactrl & (1 << 11))) + final_a = i_a; + break; + case 0x2: /* modulated alpha */ + if (!(mystique->dwgreg.alphactrl & (1 << 11))) + final_a = tex_a; + else + final_a = ((i_a * tex_a) >> 8) & 0xFF; + break; + } + } switch (mystique->dwgreg.texctl & (TEXCTL_TMODULATE | TEXCTL_STRANS | TEXCTL_ITRANS | TEXCTL_DECALCKEY)) { case 0: @@ -4984,6 +5098,36 @@ blit_texture_trap(mystique_t *mystique) fatal("Bad TEXCTL %08x %08x\n", mystique->dwgreg.texctl, mystique->dwgreg.texctl & (TEXCTL_TMODULATE | TEXCTL_STRANS | TEXCTL_ITRANS | TEXCTL_DECALCKEY)); } + if (mystique->type >= MGA_G100 && (mystique->maccess_running & MACCESS_FOGEN)) + { + tex_r = (tex_r * ((255 - i_fog) / 255.)) + (mystique->dwgreg.fogcol >> 16) * (i_fog / 255.); + tex_g = (tex_g * ((255 - i_fog) / 255.)) + ((mystique->dwgreg.fogcol >> 8) & 0xFF) * (i_fog / 255.); + tex_b = (tex_b * ((255 - i_fog) / 255.)) + ((mystique->dwgreg.fogcol) & 0xFF) * (i_fog / 255.); + } + + if (final_a != 255) + { + if (dest32) { + uint32_t dst_col = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l]; + uint8_t dst_b = dst_col & 0xFF; + uint8_t dst_g = (dst_col >> 8) & 0xFF; + uint8_t dst_r = (dst_col >> 16) & 0xFF; + + tex_r = (tex_r * ((final_a) / 255.)) + dst_r * ((255 - final_a) / 255.); + tex_g = (tex_g * ((final_a) / 255.)) + dst_g * ((255 - final_a) / 255.); + tex_b = (tex_b * ((final_a) / 255.)) + dst_b * ((255 - final_a) / 255.); + } else { + uint16_t dst_col = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w]; + uint8_t dst_b = (dst_col & 0x1f) << 3; + uint8_t dst_g = (dst_col & 0x7e0) >> 3; + uint8_t dst_r = (dst_col & 0xf800) >> 8; + + tex_r = (tex_r * ((final_a) / 255.)) + dst_r * ((255 - final_a) / 255.); + tex_g = (tex_g * ((final_a) / 255.)) + dst_g * ((255 - final_a) / 255.); + tex_b = (tex_b * ((final_a) / 255.)) + dst_b * ((255 - final_a) / 255.); + } + } + if (dest32) { ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = tex_b | (tex_g << 8) | (tex_r << 16); svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; @@ -5021,6 +5165,10 @@ skip_pixel: mystique->dwgreg.tmr[6] += mystique->dwgreg.tmr[0]; mystique->dwgreg.tmr[7] += mystique->dwgreg.tmr[2]; mystique->dwgreg.tmr[8] += mystique->dwgreg.tmr[4]; + mystique->dwgreg.fogstart += mystique->dwgreg.fogxinc; + mystique->dwgreg.alphastart += mystique->dwgreg.alphaxinc; + mystique->dwgreg.fogstart &= 0xFFFFFF; + mystique->dwgreg.alphastart &= 0xFFFFFF; } if (mystique->maccess_running & MACCESS_ZWIDTH) { @@ -5030,12 +5178,16 @@ skip_pixel: mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); } - mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; - mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; - mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; - mystique->dwgreg.tmr[6] = s_back + mystique->dwgreg.tmr[1]; - mystique->dwgreg.tmr[7] = t_back + mystique->dwgreg.tmr[3]; - mystique->dwgreg.tmr[8] = q_back + mystique->dwgreg.tmr[5]; + mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; + mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; + mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; + mystique->dwgreg.tmr[6] = s_back + mystique->dwgreg.tmr[1]; + mystique->dwgreg.tmr[7] = t_back + mystique->dwgreg.tmr[3]; + mystique->dwgreg.tmr[8] = q_back + mystique->dwgreg.tmr[5]; + mystique->dwgreg.fogstart = fog_back + mystique->dwgreg.fogyinc; + mystique->dwgreg.alphastart = a_back + mystique->dwgreg.alphayinc; + mystique->dwgreg.fogstart &= 0xFFFFFF; + mystique->dwgreg.alphastart &= 0xFFFFFF; while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; @@ -5063,6 +5215,10 @@ skip_pixel: mystique->dwgreg.tmr[6] += dx * mystique->dwgreg.tmr[0]; mystique->dwgreg.tmr[7] += dx * mystique->dwgreg.tmr[2]; mystique->dwgreg.tmr[8] += dx * mystique->dwgreg.tmr[4]; + mystique->dwgreg.fogstart += dx * mystique->dwgreg.fogxinc; + mystique->dwgreg.alphastart += dx * mystique->dwgreg.alphaxinc; + mystique->dwgreg.fogstart &= 0xFFFFFF; + mystique->dwgreg.alphastart &= 0xFFFFFF; mystique->dwgreg.ydst++; mystique->dwgreg.ydst &= 0x7fffff; @@ -5703,10 +5859,16 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) break; case 0x02: - ret = (mystique->type == MGA_2164W) ? 0x1b : ((mystique->type == MGA_2064W) ? 0x19 : 0x1a); + if (mystique->type == MGA_G100) + ret = 0x01; + else + ret = (mystique->type == MGA_2164W) ? 0x1b : ((mystique->type == MGA_2064W) ? 0x19 : 0x1a); break; /*MGA*/ case 0x03: - ret = 0x05; + if (mystique->type == MGA_G100) + ret = 0x10; + else + ret = 0x05; break; case PCI_REG_COMMAND: @@ -5795,6 +5957,10 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) case 0x33: ret = mystique->pci_regs[0x33]; break; + + case 0x34: + ret = mystique->type == MGA_G100 ? 0xdc : 0x00; + break; case 0x3c: ret = mystique->int_line; @@ -5831,6 +5997,59 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) ret = mystique_ctrl_read_b(addr, mystique); break; + case 0xdc: + ret = 0x01; + break; + + case 0xdd: + ret = 0xf0; + break; + + case 0xde: + ret = 0x21; + break; + + /* No support for turning off the video adapter yet. */ + case 0xe0: + ret = 0x0; + break; + + case 0xf0: + ret = 0x02; + break; + + case 0xf1: + ret = 0x00; + break; + + case 0xf2: + ret = 0x10; + break; + + case 0xf4: + ret = 0x1; + break; + + case 0xf5: + ret = 0x2; + break; + + case 0xf7: + ret = 0x1; + break; + + case 0xf8: + ret = mystique->pci_regs[0xf8] & 0x7; + break; + + case 0xf9: + ret = mystique->pci_regs[0xf9] & 0x3; + break; + + case 0xfb: + ret = mystique->pci_regs[0xfb]; + break; + default: break; } @@ -5964,6 +6183,18 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) mystique_ctrl_write_b(addr, val, mystique); break; + case 0xf8: + mystique->pci_regs[0xf8] = val & 0x7; + break; + + case 0xf9: + mystique->pci_regs[0xf9] = val & 0x3; + break; + + case 0xfb: + mystique->pci_regs[0xfb] = val; + break; + default: break; } @@ -6017,6 +6248,8 @@ mystique_init(const device_t *info) romfn = ROM_MILLENNIUM_II; else if (mystique->type == MGA_1064SG) romfn = ROM_MYSTIQUE; + else if (mystique->type == MGA_G100) + romfn = ROM_G100; else romfn = ROM_MYSTIQUE_220; @@ -6186,6 +6419,12 @@ millennium_ii_available(void) return rom_present(ROM_MILLENNIUM_II); } +static int +matrox_g100_available(void) +{ + return rom_present(ROM_G100); +} + static void mystique_speed_changed(void *priv) { @@ -6242,10 +6481,6 @@ static const device_config_t millennium_ii_config[] = { .type = CONFIG_SELECTION, .selection = { - { - .description = "4 MB", - .value = 4 - }, { .description = "8 MB", .value = 8 @@ -6321,3 +6556,17 @@ const device_t millennium_ii_device = { .force_redraw = mystique_force_redraw, .config = millennium_ii_config }; + +const device_t productiva_g100_device = { + .name = "Matrox Productiva G100", + .internal_name = "productiva_g100", + .flags = DEVICE_AGP, + .local = MGA_G100, + .init = mystique_init, + .close = mystique_close, + .reset = NULL, + { .available = matrox_g100_available }, + .speed_changed = mystique_speed_changed, + .force_redraw = mystique_force_redraw, + .config = millennium_ii_config +}; diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 37e399d22..0b56f4d69 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -257,6 +257,7 @@ video_cards[] = { { &s3_virge_357_agp_device }, { &s3_diamond_stealth_4000_agp_device }, { &s3_trio3d2x_agp_device }, + { &productiva_g100_device }, { &velocity_100_agp_device }, { &velocity_200_agp_device }, { &voodoo_3_1000_agp_device }, From f96e25e10831572d97daa6ed2d94144a5e9f1a83 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 31 Dec 2023 05:23:17 +0500 Subject: [PATCH 171/936] Don't set the application icon in qt_main.c on Mac Should fix it overriding the bundle's icon --- src/qt/qt_main.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 02a0026d8..bc95ad1d1 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -195,18 +195,19 @@ main(int argc, char *argv[]) SetCurrentProcessExplicitAppUserModelID(L"86Box.86Box"); #endif -#ifdef RELEASE_BUILD +#ifndef Q_OS_APPLE +# ifdef RELEASE_BUILD app.setWindowIcon(QIcon(":/settings/win/icons/86Box-green.ico")); -#elif defined ALPHA_BUILD +# elif defined ALPHA_BUILD app.setWindowIcon(QIcon(":/settings/win/icons/86Box-red.ico")); -#elif defined BETA_BUILD +# elif defined BETA_BUILD app.setWindowIcon(QIcon(":/settings/win/icons/86Box-yellow.ico")); -#else +# else app.setWindowIcon(QIcon(":/settings/win/icons/86Box-gray.ico")); -#endif -#if (!defined(Q_OS_WINDOWS) && !defined(__APPLE__)) +# ifdef Q_OS_UNIX app.setDesktopFileName("net.86box.86Box"); +# endif #endif if (!pc_init_modules()) { From 1f6a5a8a957afe79a924f695539dc518e1af5ffc Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 31 Dec 2023 01:44:31 +0100 Subject: [PATCH 172/936] Added a missing #endif. --- src/qt/qt_main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index bc95ad1d1..a36130984 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -204,6 +204,7 @@ main(int argc, char *argv[]) app.setWindowIcon(QIcon(":/settings/win/icons/86Box-yellow.ico")); # else app.setWindowIcon(QIcon(":/settings/win/icons/86Box-gray.ico")); +# endif # ifdef Q_OS_UNIX app.setDesktopFileName("net.86box.86Box"); From 514212798294ad93f80f98cb16b31a4a4a762cda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Castell=C3=B3?= Date: Sat, 30 Dec 2023 23:25:20 -0300 Subject: [PATCH 173/936] fixes typo on mac icon fix --- src/qt/qt_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index a36130984..a83946ea3 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -195,7 +195,7 @@ main(int argc, char *argv[]) SetCurrentProcessExplicitAppUserModelID(L"86Box.86Box"); #endif -#ifndef Q_OS_APPLE +#ifndef __APPLE__ # ifdef RELEASE_BUILD app.setWindowIcon(QIcon(":/settings/win/icons/86Box-green.ico")); # elif defined ALPHA_BUILD From 5cb239103947a44dd774ffb6a9611626c7498d73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Castell=C3=B3?= Date: Sun, 31 Dec 2023 00:09:50 -0300 Subject: [PATCH 174/936] Update src/qt/qt_main.cpp Accepted changes Co-authored-by: Alexander Babikov --- src/qt/qt_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index a83946ea3..409a63248 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -195,7 +195,7 @@ main(int argc, char *argv[]) SetCurrentProcessExplicitAppUserModelID(L"86Box.86Box"); #endif -#ifndef __APPLE__ +#ifndef Q_OS_MACOS # ifdef RELEASE_BUILD app.setWindowIcon(QIcon(":/settings/win/icons/86Box-green.ico")); # elif defined ALPHA_BUILD From ca21ea528a0f3278406fb24e797d43e2a32c7647 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 31 Dec 2023 14:54:00 +0600 Subject: [PATCH 175/936] Matrox Productiva G100 working (expect maybe alpha stipple) --- src/video/vid_mga.c | 202 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 161 insertions(+), 41 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index f064b4d34..c2b405454 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -120,6 +120,7 @@ #define REG_DR2_Z32MSB 0x2c64 #define REG_DR3_Z32LSB 0x2c68 #define REG_DR3_Z32MSB 0x2c6c +#define REG_TEXFILTER 0x2c58 #define REG_FIFOSTATUS 0x1e10 #define REG_STATUS 0x1e14 @@ -510,7 +511,8 @@ typedef struct mystique_t { texctl, textrans, zorg, ydst_lin, src_addr, z_base, iload_rem_data, highv_data, fogcol, fogxinc : 24, fogyinc : 24, fogstart : 24, - alphactrl, alphaxinc : 24, alphayinc : 24, alphastart : 24; + alphactrl, alphaxinc : 24, alphayinc : 24, alphastart : 24, + texfilter; uint32_t src[4], ar[7], dr[16], tmr[9]; @@ -658,6 +660,15 @@ static const uint8_t trans_masks[16][16] = { static int8_t dither5[256][2][2]; static int8_t dither6[256][2][2]; +static double bayer_mat[4][4] = +{ + { 0.0, 8. / 16., 2. / 16., 10. / 16.}, + { 12. / 16., 4. / 16., 14. / 16., 6. / 16.}, + { 3. / 16., 11. / 16., 1. / 16., 9. / 16.}, + { 15. / 16., 7. / 16., 13. / 16., 5. / 16.}, +}; + +static const int grey_lut[16] = { 0, 16, 32, 48, 64, 80, 96, 112, 128, 143, 159, 175, 191, 207, 223, 239 }; static video_timings_t timing_matrox_millennium = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 10, .read_w = 10, .read_l = 10 }; static video_timings_t timing_matrox_mystique = { .type = VIDEO_PCI, .write_b = 4, .write_w = 4, .write_l = 4, .read_b = 10, .read_w = 10, .read_l = 10 }; @@ -2608,6 +2619,10 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) mystique->dwgreg.fogyinc = val; break; + case REG_TEXFILTER: + mystique->dwgreg.texfilter = val; + break; + default: mystique_accel_ctrl_write_b(addr, val & 0xff, priv); mystique_accel_ctrl_write_b(addr + 1, (val >> 8) & 0xff, priv); @@ -4828,45 +4843,18 @@ blit_trap(mystique_t *mystique) mystique->blitter_complete_refcount++; } -static int -texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atransp, int *tex_a) +static uint16_t texture_texel_fetch(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *tex_a, int *atransp, int s, int t, int tex_pitch) { - svga_t *svga = &mystique->svga; - - const int tex_shift = 3 + ((mystique->dwgreg.texctl & TEXCTL_TPITCH_MASK) >> TEXCTL_TPITCH_SHIFT); - const unsigned int palsel = mystique->dwgreg.texctl & TEXCTL_PALSEL_MASK; - const uint16_t tckey = mystique->dwgreg.textrans & TEXTRANS_TCKEY_MASK; - const uint16_t tkmask = (mystique->dwgreg.textrans & TEXTRANS_TKMASK_MASK) >> TEXTRANS_TKMASK_SHIFT; const unsigned int w_mask = (mystique->dwgreg.texwidth & TEXWIDTH_TWMASK_MASK) >> TEXWIDTH_TWMASK_SHIFT; const unsigned int h_mask = (mystique->dwgreg.texheight & TEXHEIGHT_THMASK_MASK) >> TEXHEIGHT_THMASK_SHIFT; - uint16_t src = 0; - int s; - int t; - int tex_pitch = 1 << tex_shift; + const unsigned int palsel = mystique->dwgreg.texctl & TEXCTL_PALSEL_MASK; + svga_t* svga = &mystique->svga; + uint16_t src = 0x0; - *tex_a = 255; + int atransp_dummy = 0; - if (mystique->type >= MGA_G100 && (mystique->dwgreg.texctl & TEXCTL_TPITCHLIN)) - { - tex_pitch = (mystique->dwgreg.texctl & TEXCTL_TPITCHEXT_MASK) >> 9; - if (tex_pitch == 0) - tex_pitch = 2048; - } - - if (mystique->dwgreg.texctl & TEXCTL_NPCEN) { - const int s_shift = 20 - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); - const int t_shift = 20 - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); - - s = (int32_t) mystique->dwgreg.tmr[6] >> s_shift; - t = (int32_t) mystique->dwgreg.tmr[7] >> t_shift; - } else { - const int s_shift = (20 + 16) - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); - const int t_shift = (20 + 16) - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); - int64_t q = mystique->dwgreg.tmr[8] ? (0x100000000LL / (int64_t) (int32_t) mystique->dwgreg.tmr[8] /*>> 16*/) : 0; - - s = ((int64_t) (int32_t) mystique->dwgreg.tmr[6] * q /*<< 8*/) >> s_shift; /*((16+20)-12);*/ - t = ((int64_t) (int32_t) mystique->dwgreg.tmr[7] * q /*<< 8*/) >> t_shift; /*((16+20)-9);*/ - } + if (!atransp) + atransp = &atransp_dummy; if (mystique->dwgreg.texctl & TEXCTL_CLAMPU) { if (s < 0) @@ -4915,10 +4903,11 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra break; case TEXCTL_TEXFORMAT_TW12: src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t * tex_pitch) + s) & mystique->vram_mask_w]; - *tex_r = ((src >> 8) & 0xf) << 3; - *tex_g = ((src >> 4) & 0xf) << 3; - *tex_b = (src & 0xf) << 3; - *tex_a = ((src >> 12) & 0xf) << 3; + *tex_r = ((src >> 8) & 0xf) << 4; + *tex_g = ((src >> 4) & 0xf) << 4; + *tex_b = (src & 0xf) << 4; + *tex_a = ((src >> 12) & 0xf) << 4; + pclog("TEXFORMAT_TW12\n"); if (mystique->dwgreg.texctl & TEXCTL_AZEROEXTEND) { *atransp = (((src >> 12) & 0xf) & mystique->dwgreg.ta_mask) == mystique->dwgreg.ta_key; } else { @@ -4938,6 +4927,114 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra fatal("Unknown texture format %i\n", mystique->dwgreg.texctl & TEXCTL_TEXFORMAT_MASK); break; } + return src; +} + +static double lerp(double v0, double v1, double t) { + return (1. - t) * v0 + t * v1; +} + +static int +texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atransp, int *tex_a) +{ + svga_t *svga = &mystique->svga; + + const int tex_shift = 3 + ((mystique->dwgreg.texctl & TEXCTL_TPITCH_MASK) >> TEXCTL_TPITCH_SHIFT); + const unsigned int palsel = mystique->dwgreg.texctl & TEXCTL_PALSEL_MASK; + const uint16_t tckey = mystique->dwgreg.textrans & TEXTRANS_TCKEY_MASK; + const uint16_t tkmask = (mystique->dwgreg.textrans & TEXTRANS_TKMASK_MASK) >> TEXTRANS_TKMASK_SHIFT; + const unsigned int w_mask = (mystique->dwgreg.texwidth & TEXWIDTH_TWMASK_MASK) >> TEXWIDTH_TWMASK_SHIFT; + const unsigned int h_mask = (mystique->dwgreg.texheight & TEXHEIGHT_THMASK_MASK) >> TEXHEIGHT_THMASK_SHIFT; + uint16_t src = 0; + int s; + int t; + int tex_pitch = 1 << tex_shift; + double s_frac = 0; + double t_frac = 0; + + *tex_a = 255; + + if (mystique->type >= MGA_G100 && (mystique->dwgreg.texctl & TEXCTL_TPITCHLIN)) + { + tex_pitch = (mystique->dwgreg.texctl & TEXCTL_TPITCHEXT_MASK) >> 9; + if (tex_pitch == 0) + tex_pitch = 2048; + } + + if (mystique->dwgreg.texctl & TEXCTL_NPCEN) { + const int s_shift = 20 - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); + const int t_shift = 20 - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); + + s = (int32_t) mystique->dwgreg.tmr[6] >> s_shift; + t = (int32_t) mystique->dwgreg.tmr[7] >> t_shift; + s_frac = (((int32_t) mystique->dwgreg.tmr[6] >> s_shift) & ((1 << s_shift) - 1)) / (double)(1 << s_shift); + t_frac = (((int32_t) mystique->dwgreg.tmr[7] >> t_shift) & ((1 << t_shift) - 1)) / (double)(1 << t_shift); + } else { + const int s_shift = (20 + 16) - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); + const int t_shift = (20 + 16) - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); + int64_t q = mystique->dwgreg.tmr[8] ? (0x100000000LL / (int64_t) (int32_t) mystique->dwgreg.tmr[8]) : 0; + + s = ((int64_t) (int32_t) mystique->dwgreg.tmr[6] * q) >> s_shift; + t = ((int64_t) (int32_t) mystique->dwgreg.tmr[7] * q) >> t_shift; + s_frac = (((int64_t) (int32_t) mystique->dwgreg.tmr[6] * q) & ((1 << s_shift) - 1)) / (double)(1 << s_shift); + t_frac = (((int64_t) (int32_t) mystique->dwgreg.tmr[6] * q) & ((1 << t_shift) - 1)) / (double)(1 << t_shift); + } + + if (mystique->dwgreg.texctl & TEXCTL_CLAMPU) { + if (s < 0) + s = 0; + else if (s > w_mask) + s = w_mask; + } else + s &= w_mask; + + if (mystique->dwgreg.texctl & TEXCTL_CLAMPV) { + if (t < 0) + t = 0; + else if (t > h_mask) + t = h_mask; + } else + t &= h_mask; + + src = texture_texel_fetch(mystique, tex_r, tex_g, tex_b, tex_a, atransp, s, t, tex_pitch); + switch (mystique->dwgreg.texfilter & 3) + { + case 0: + s_frac = t_frac = 0; + break; + case 1: + case 2: + break; + case 3: + s_frac = t_frac = .25; + break; + } + if (s_frac && s != w_mask) + { + int s_tex_r = 0, s_tex_g = 0, s_tex_b = 0, s_tex_a = 255; + texture_texel_fetch(mystique, &s_tex_r, &s_tex_g, &s_tex_b, &s_tex_a, NULL, s + 1, t, tex_pitch); + *tex_r = (int)lerp(*tex_r, s_tex_r, s_frac); + *tex_g = (int)lerp(*tex_g, s_tex_g, s_frac); + *tex_b = (int)lerp(*tex_b, s_tex_b, s_frac); + *tex_a = (int)lerp(*tex_a, s_tex_a, s_frac); + if (*tex_r > 255) *tex_r = 255; + if (*tex_g > 255) *tex_g = 255; + if (*tex_b > 255) *tex_b = 255; + if (*tex_a > 255) *tex_a = 255; + } + if (t_frac && t != h_mask) + { + int t_tex_r = 0, t_tex_g = 0, t_tex_b = 0, t_tex_a = 255; + texture_texel_fetch(mystique, &t_tex_r, &t_tex_g, &t_tex_b, &t_tex_a, NULL, s, t + 1, tex_pitch); + *tex_r = (int)lerp(*tex_r, t_tex_r, t_frac); + *tex_g = (int)lerp(*tex_g, t_tex_g, t_frac); + *tex_b = (int)lerp(*tex_b, t_tex_b, t_frac); + *tex_a = (int)lerp(*tex_a, t_tex_a, t_frac); + if (*tex_r > 255) *tex_r = 255; + if (*tex_g > 255) *tex_g = 255; + if (*tex_b > 255) *tex_b = 255; + if (*tex_a > 255) *tex_a = 255; + } return ((src & tkmask) == tckey); } @@ -4995,7 +5092,7 @@ blit_texture_trap(mystique_t *mystique) int tex_r = 0; int tex_g = 0; int tex_b = 0; - int tex_a = 0; + int tex_a = 255; int ctransp; int atransp = 0; int i_r = 0; @@ -5107,6 +5204,25 @@ blit_texture_trap(mystique_t *mystique) if (final_a != 255) { + /* Does this actually work? I'm not sure. */ + if (final_a & 0xf) { + double threshold = bayer_mat[mystique->dwgreg.selline & 3][x_l & 3]; + double final_a_frac = (final_a & 0xf) / 16.; + if (final_a_frac >= threshold) { + if ((final_a >> 4) == 0x0) + final_a = grey_lut[1]; + else if ((final_a >> 4) == 0xf) + final_a = 255; + else + final_a = grey_lut[final_a >> 4]; + } else { + if ((final_a >> 4) == 0x0) + final_a = 0; + else + final_a = grey_lut[(final_a >> 4) - 1]; + } + } + if (dest32) { uint32_t dst_col = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l]; uint8_t dst_b = dst_col & 0xFF; @@ -6480,7 +6596,11 @@ static const device_config_t millennium_ii_config[] = { .description = "Memory size", .type = CONFIG_SELECTION, .selection = - { + { + { + .description = "4 MB", + .value = 4 + }, { .description = "8 MB", .value = 8 From 6366e1c58c7b6bc48325cac3e088bdc8b6ece417 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 31 Dec 2023 16:43:01 +0600 Subject: [PATCH 176/936] Implement proper alpha stipple --- src/video/vid_mga.c | 39 ++++----------------------------------- 1 file changed, 4 insertions(+), 35 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index c2b405454..4f446cc62 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -668,8 +668,6 @@ static double bayer_mat[4][4] = { 15. / 16., 7. / 16., 13. / 16., 5. / 16.}, }; -static const int grey_lut[16] = { 0, 16, 32, 48, 64, 80, 96, 112, 128, 143, 159, 175, 191, 207, 223, 239 }; - static video_timings_t timing_matrox_millennium = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 10, .read_w = 10, .read_l = 10 }; static video_timings_t timing_matrox_mystique = { .type = VIDEO_PCI, .write_b = 4, .write_w = 4, .write_l = 4, .read_b = 10, .read_w = 10, .read_l = 10 }; @@ -5204,44 +5202,15 @@ blit_texture_trap(mystique_t *mystique) if (final_a != 255) { - /* Does this actually work? I'm not sure. */ - if (final_a & 0xf) { + { double threshold = bayer_mat[mystique->dwgreg.selline & 3][x_l & 3]; - double final_a_frac = (final_a & 0xf) / 16.; + double final_a_frac = (final_a) / 255.; if (final_a_frac >= threshold) { - if ((final_a >> 4) == 0x0) - final_a = grey_lut[1]; - else if ((final_a >> 4) == 0xf) - final_a = 255; - else - final_a = grey_lut[final_a >> 4]; + final_a = 255; } else { - if ((final_a >> 4) == 0x0) - final_a = 0; - else - final_a = grey_lut[(final_a >> 4) - 1]; + goto skip_pixel; } } - - if (dest32) { - uint32_t dst_col = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l]; - uint8_t dst_b = dst_col & 0xFF; - uint8_t dst_g = (dst_col >> 8) & 0xFF; - uint8_t dst_r = (dst_col >> 16) & 0xFF; - - tex_r = (tex_r * ((final_a) / 255.)) + dst_r * ((255 - final_a) / 255.); - tex_g = (tex_g * ((final_a) / 255.)) + dst_g * ((255 - final_a) / 255.); - tex_b = (tex_b * ((final_a) / 255.)) + dst_b * ((255 - final_a) / 255.); - } else { - uint16_t dst_col = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w]; - uint8_t dst_b = (dst_col & 0x1f) << 3; - uint8_t dst_g = (dst_col & 0x7e0) >> 3; - uint8_t dst_r = (dst_col & 0xf800) >> 8; - - tex_r = (tex_r * ((final_a) / 255.)) + dst_r * ((255 - final_a) / 255.); - tex_g = (tex_g * ((final_a) / 255.)) + dst_g * ((255 - final_a) / 255.); - tex_b = (tex_b * ((final_a) / 255.)) + dst_b * ((255 - final_a) / 255.); - } } if (dest32) { From b1cf6c865756a9f3292c9b54a36fc1a7a34bac6b Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 31 Dec 2023 16:44:54 +0600 Subject: [PATCH 177/936] Remove logging --- src/video/vid_mga.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 4f446cc62..ab93e95b5 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -4905,7 +4905,6 @@ static uint16_t texture_texel_fetch(mystique_t *mystique, int *tex_r, int *tex_g *tex_g = ((src >> 4) & 0xf) << 4; *tex_b = (src & 0xf) << 4; *tex_a = ((src >> 12) & 0xf) << 4; - pclog("TEXFORMAT_TW12\n"); if (mystique->dwgreg.texctl & TEXCTL_AZEROEXTEND) { *atransp = (((src >> 12) & 0xf) & mystique->dwgreg.ta_mask) == mystique->dwgreg.ta_key; } else { From 0ee66c4be8cd4750c566c382a0f05ad6c560ea51 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 31 Dec 2023 16:45:52 +0600 Subject: [PATCH 178/936] Whitespace removal --- src/video/vid_mga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index ab93e95b5..33250b8e2 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -6564,7 +6564,7 @@ static const device_config_t millennium_ii_config[] = { .description = "Memory size", .type = CONFIG_SELECTION, .selection = - { + { { .description = "4 MB", .value = 4 From 89f395ded1a5ae0e524417d7cbd8050e853e8007 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 31 Dec 2023 12:10:34 +0100 Subject: [PATCH 179/936] MGA: Fixed two warnings. --- src/video/vid_mga.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 33250b8e2..f815a2ead 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -4934,10 +4934,7 @@ static double lerp(double v0, double v1, double t) { static int texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atransp, int *tex_a) { - svga_t *svga = &mystique->svga; - const int tex_shift = 3 + ((mystique->dwgreg.texctl & TEXCTL_TPITCH_MASK) >> TEXCTL_TPITCH_SHIFT); - const unsigned int palsel = mystique->dwgreg.texctl & TEXCTL_PALSEL_MASK; const uint16_t tckey = mystique->dwgreg.textrans & TEXTRANS_TCKEY_MASK; const uint16_t tkmask = (mystique->dwgreg.textrans & TEXTRANS_TKMASK_MASK) >> TEXTRANS_TKMASK_SHIFT; const unsigned int w_mask = (mystique->dwgreg.texwidth & TEXWIDTH_TWMASK_MASK) >> TEXWIDTH_TWMASK_SHIFT; From 7b75d6f11d283526d03fceb31504b063c9ae4c3c Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 31 Dec 2023 19:18:20 +0600 Subject: [PATCH 180/936] Fix detection of MGA G100 video RAM when 16MB --- src/video/vid_mga.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 33250b8e2..f4b4ecf27 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -6371,6 +6371,8 @@ mystique_init(const device_t *info) NULL); mystique->svga.clock_gen = mystique; mystique->svga.getclock = mystique_getclock; + if (mystique->vram_size >= 16) + mystique->svga.decode_mask = mystique->svga.vram_mask; } io_sethandler(0x03c0, 0x0020, mystique_in, NULL, NULL, mystique_out, NULL, NULL, mystique); From f8e55d0edcd77115573869c1a177339e0af3eac8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 31 Dec 2023 19:47:25 +0600 Subject: [PATCH 181/936] MGA G100: Fix fog acceleration Minor variable cleanups --- src/video/vid_mga.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index f4b4ecf27..0767f8b3a 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -456,8 +456,7 @@ typedef struct mystique_t { uint8_t pci_regs[256], crtcext_regs[6], xreg_regs[256], dmamap[16]; - int vram_size, crtcext_idx, xreg_idx, xzoomctrl, - pixel_count, trap_count; + int vram_size, crtcext_idx, xreg_idx, xzoomctrl; atomic_int busy, blitter_submit_refcount, blitter_submit_dma_refcount, blitter_complete_refcount, @@ -540,8 +539,7 @@ typedef struct mystique_t { struct { - atomic_int pri_pos, sec_pos, iload_pos, - pri_state, sec_state, iload_state, state; + atomic_int pri_state, sec_state, iload_state, state; atomic_uint primaddress, primend, secaddress, secend, pri_header, sec_header, @@ -4535,8 +4533,6 @@ blit_trap(mystique_t *mystique) int y; const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; - mystique->trap_count++; - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { case DWGCTRL_ATYPE_BLK: case DWGCTRL_ATYPE_RPL: @@ -4583,7 +4579,6 @@ blit_trap(mystique_t *mystique) else x_l++; - mystique->pixel_count++; } while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { @@ -4662,8 +4657,6 @@ blit_trap(mystique_t *mystique) x_l--; else x_l++; - - mystique->pixel_count++; } while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { @@ -4784,8 +4777,6 @@ blit_trap(mystique_t *mystique) x_l--; else x_l++; - - mystique->pixel_count++; } if (mystique->maccess_running & MACCESS_ZWIDTH) { @@ -5045,8 +5036,6 @@ blit_texture_trap(mystique_t *mystique) const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; const int dest32 = ((mystique->maccess_running & MACCESS_PWIDTH_MASK) == MACCESS_PWIDTH_32); - mystique->trap_count++; - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { case DWGCTRL_ATYPE_I: case DWGCTRL_ATYPE_ZI: @@ -5194,9 +5183,9 @@ blit_texture_trap(mystique_t *mystique) if (mystique->type >= MGA_G100 && (mystique->maccess_running & MACCESS_FOGEN)) { - tex_r = (tex_r * ((255 - i_fog) / 255.)) + (mystique->dwgreg.fogcol >> 16) * (i_fog / 255.); - tex_g = (tex_g * ((255 - i_fog) / 255.)) + ((mystique->dwgreg.fogcol >> 8) & 0xFF) * (i_fog / 255.); - tex_b = (tex_b * ((255 - i_fog) / 255.)) + ((mystique->dwgreg.fogcol) & 0xFF) * (i_fog / 255.); + tex_r = (tex_r * ((i_fog) / 255.)) + (mystique->dwgreg.fogcol >> 16) * ((255 - i_fog) / 255.); + tex_g = (tex_g * ((i_fog) / 255.)) + ((mystique->dwgreg.fogcol >> 8) & 0xFF) * ((255 - i_fog) / 255.); + tex_b = (tex_b * ((i_fog) / 255.)) + ((mystique->dwgreg.fogcol) & 0xFF) * ((255 - i_fog) / 255.); } if (final_a != 255) @@ -5234,8 +5223,6 @@ skip_pixel: else x_l++; - mystique->pixel_count++; - if (mystique->maccess_running & MACCESS_ZWIDTH) { mystique->dwgreg.extended_dr[0] += mystique->dwgreg.extended_dr[2]; mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; From 941d5bfdf814836d285cce3d87eedbe6adb9d880 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 31 Dec 2023 22:46:21 +0600 Subject: [PATCH 182/936] Fix busmastering under Windows 2000 --- src/video/vid_mga.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 0767f8b3a..95a98521b 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -2175,6 +2175,7 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) thread_wait_mutex(mystique->dma.lock); WRITE8(addr, mystique->dma.primaddress, val); mystique->dma.pri_state = 0; + mystique->dma.words_expected = 0; thread_release_mutex(mystique->dma.lock); break; From 9966c6ced0e04309a9707e61e62415a0f0912411 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Jan 2024 16:51:31 +0500 Subject: [PATCH 183/936] Update the default copyright year --- CMakeLists.txt | 2 +- src/include_make/86box/version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4bc020f15..a6b50baf3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -196,7 +196,7 @@ if(NOT EMU_BUILD_NUM) set(EMU_BUILD_NUM 0) endif() if(NOT EMU_COPYRIGHT_YEAR) - set(EMU_COPYRIGHT_YEAR 2023) + set(EMU_COPYRIGHT_YEAR 2024) endif() add_subdirectory(src) diff --git a/src/include_make/86box/version.h b/src/include_make/86box/version.h index 9a175be24..4004f58b3 100644 --- a/src/include_make/86box/version.h +++ b/src/include_make/86box/version.h @@ -34,7 +34,7 @@ #define EMU_VERSION_FULL EMU_VERSION #define EMU_VERSION_FULL_W EMU_VERSION_W -#define COPYRIGHT_YEAR "2022" +#define COPYRIGHT_YEAR "2024" /* Web URL info. */ #define EMU_SITE "86box.net" From b63bf09db3e66841ad5f0c044b333d0ae157a998 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Jan 2024 16:53:17 +0500 Subject: [PATCH 184/936] Replace the hardcoded year with COPYRIGHT_YEAR Replace the hardcoded copyright year with the COPYRIGHT_YEAR macro in the emulated Logitech serial mouse's self-report --- src/device/mouse_serial.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/device/mouse_serial.c b/src/device/mouse_serial.c index e9531d78e..08aee09d8 100644 --- a/src/device/mouse_serial.c +++ b/src/device/mouse_serial.c @@ -28,6 +28,7 @@ #include <86box/serial.h> #include <86box/mouse.h> #include <86box/plat.h> +#include <86box/version.h> #define SERMOUSE_PORT 0 /* attach to Serial0 */ @@ -537,7 +538,7 @@ ltsermouse_process_command(mouse_t *dev) [FORMAT_HEX] = 0x04, [FORMAT_MS_4BYTE] = 0x08, /* Guess */ [FORMAT_MS_WHEEL] = 0x08 }; /* Guess */ - const char *copr = "\r\n(C) 2023 86Box, Revision 3.0"; + const char *copr = "\r\n(C) " COPYRIGHT_YEAR " 86Box, Revision 3.0"; mouse_serial_log("ltsermouse_process_command(): %02X\n", dev->ib); dev->command = dev->ib; From af5aafbc0ef9eb56e7eaa17da1d74c5a30c785a2 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 2 Jan 2024 13:49:22 +0600 Subject: [PATCH 185/936] Make Matrox Productiva G100 usable as secondary display Confirmed working in Windows 98 SE at least --- src/video/vid_mga.c | 28 ++-- src/video/vid_table.c | 376 +++++++++++++++++++++--------------------- 2 files changed, 205 insertions(+), 199 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 95a98521b..e4d4ef668 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -2797,11 +2797,14 @@ static uint8_t mystique_readb_linear(uint32_t addr, void *priv) { const svga_t *svga = (svga_t *) priv; + mystique_t *mystique = (mystique_t *) svga->priv; - if (!svga->fast) - return svga_read_linear(addr, priv); + if (mystique->type < MGA_1064SG) { + if (!svga->fast) + return svga_read_linear(addr, priv); + } - cycles -= video_timing_read_b; + cycles -= svga->monitor->mon_video_timing_read_b; addr &= svga->decode_mask; if (addr >= svga->vram_max) @@ -2815,7 +2818,7 @@ mystique_readw_linear(uint32_t addr, void *priv) { svga_t *svga = (svga_t *) priv; - cycles -= video_timing_read_w; + cycles -= svga->monitor->mon_video_timing_read_w; addr &= svga->decode_mask; if (addr >= svga->vram_max) @@ -2829,7 +2832,7 @@ mystique_readl_linear(uint32_t addr, void *priv) { svga_t *svga = (svga_t *) priv; - cycles -= video_timing_read_l; + cycles -= svga->monitor->mon_video_timing_read_l; addr &= svga->decode_mask; if (addr >= svga->vram_max) @@ -2842,13 +2845,16 @@ static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv) { svga_t *svga = (svga_t *) priv; + mystique_t *mystique = (mystique_t *) svga->priv; - if (!svga->fast) { - svga_write_linear(addr, val, priv); - return; + if (mystique->type < MGA_1064SG) { + if (!svga->fast) { + svga_write_linear(addr, val, priv); + return; + } } - cycles -= video_timing_write_b; + cycles -= svga->monitor->mon_video_timing_write_b; addr &= svga->decode_mask; if (addr >= svga->vram_max) @@ -2863,7 +2869,7 @@ mystique_writew_linear(uint32_t addr, uint16_t val, void *priv) { svga_t *svga = (svga_t *) priv; - cycles -= video_timing_write_w; + cycles -= svga->monitor->mon_video_timing_write_w; addr &= svga->decode_mask; if (addr >= svga->vram_max) @@ -2878,7 +2884,7 @@ mystique_writel_linear(uint32_t addr, uint32_t val, void *priv) { svga_t *svga = (svga_t *) priv; - cycles -= video_timing_write_l; + cycles -= svga->monitor->mon_video_timing_write_l; addr &= svga->decode_mask; if (addr >= svga->vram_max) diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 0b56f4d69..844baa97a 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -77,198 +77,198 @@ static const device_t vid_internal_device = { static const VIDEO_CARD video_cards[] = { // clang-format off - { &vid_none_device }, - { &vid_internal_device }, - { &atiega800p_device }, - { &mach8_isa_device, VIDEO_FLAG_TYPE_8514 }, - { &mach32_isa_device, VIDEO_FLAG_TYPE_8514 }, - { &mach64gx_isa_device }, - { &ati28800k_device }, - { &ati18800_vga88_device }, - { &ati28800_device }, - { &compaq_ati28800_device }, + { &vid_none_device }, + { &vid_internal_device }, + { &atiega800p_device }, + { &mach8_isa_device, VIDEO_FLAG_TYPE_8514 }, + { &mach32_isa_device, VIDEO_FLAG_TYPE_8514 }, + { &mach64gx_isa_device }, + { &ati28800k_device }, + { &ati18800_vga88_device }, + { &ati28800_device }, + { &compaq_ati28800_device }, #if defined(DEV_BRANCH) && defined(USE_XL24) - { &ati28800_wonderxl24_device }, + { &ati28800_wonderxl24_device }, #endif - { &ati18800_device }, + { &ati18800_device }, #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) - { &ati18800_wonder_device }, + { &ati18800_wonder_device }, #endif - { &cga_device }, - { &sega_device }, - { &gd5401_isa_device }, - { &gd5402_isa_device }, - { &gd5420_isa_device }, - { &gd5422_isa_device }, - { &gd5426_isa_device }, - { &gd5426_diamond_speedstar_pro_a1_isa_device }, - { &gd5428_boca_isa_device }, - { &gd5428_isa_device }, - { &gd5429_isa_device }, - { &gd5434_isa_device }, - { &gd5434_diamond_speedstar_64_a3_isa_device }, - { &compaq_cga_device }, - { &compaq_cga_2_device }, - { &cpqega_device }, - { &ega_device }, - { &g2_gc205_device }, - { &hercules_device, VIDEO_FLAG_TYPE_MDA }, - { &herculesplus_device, VIDEO_FLAG_TYPE_MDA }, - { &incolor_device }, - { &inmos_isa_device, VIDEO_FLAG_TYPE_XGA }, - { &im1024_device }, - { &iskra_ega_device }, - { &et4000_kasan_isa_device }, - { &mda_device, VIDEO_FLAG_TYPE_MDA }, - { &genius_device }, - { &nga_device }, - { &ogc_device }, - { &oti037c_device }, - { &oti067_device }, - { &oti077_device }, - { ¶dise_pvga1a_device }, - { ¶dise_wd90c11_device }, - { ¶dise_wd90c30_device }, - { &colorplus_device }, - { &pgc_device }, - { &cga_pravetz_device }, - { &radius_svga_multiview_isa_device }, - { &realtek_rtg3106_device }, - { &s3_diamond_stealth_vram_isa_device }, - { &s3_orchid_86c911_isa_device }, - { &s3_ami_86c924_isa_device }, - { &s3_metheus_86c928_isa_device }, - { &s3_phoenix_86c801_isa_device }, - { &s3_spea_mirage_86c801_isa_device }, - { &sigma_device }, - { &tvga8900b_device }, - { &tvga8900d_device }, - { &tvga9000b_device }, - { &nec_sv9000_device }, - { &et4000k_isa_device }, - { &et2000_device }, - { &et3000_isa_device }, - { &et4000_isa_device }, - { &et4000w32_device }, - { &et4000w32i_isa_device }, - { &vga_device }, - { &v7_vga_1024i_device }, - { &wy700_device }, - { &mach32_mca_device, VIDEO_FLAG_TYPE_8514 }, - { &gd5426_mca_device }, - { &gd5428_mca_device }, - { &et4000_mca_device }, - { &radius_svga_multiview_mca_device }, - { &mach32_pci_device, VIDEO_FLAG_TYPE_8514 }, - { &mach64gx_pci_device }, - { &mach64vt2_device }, - { &et4000w32p_videomagic_revb_pci_device }, - { &et4000w32p_revc_pci_device }, - { &et4000w32p_cardex_pci_device }, - { &et4000w32p_noncardex_pci_device }, - { &et4000w32p_pci_device }, - { &gd5430_pci_device, }, - { &gd5434_pci_device }, - { &gd5436_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, - { &gd5440_pci_device }, - { &gd5446_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, - { &gd5446_stb_pci_device,VIDEO_FLAG_TYPE_SPECIAL }, - { &gd5480_pci_device }, - { &s3_spea_mercury_lite_86c928_pci_device }, - { &s3_diamond_stealth64_964_pci_device }, - { &s3_elsa_winner2000_pro_x_964_pci_device }, - { &s3_mirocrystal_20sv_964_pci_device }, - { &s3_bahamas64_pci_device }, - { &s3_phoenix_vision864_pci_device }, - { &s3_diamond_stealth_se_pci_device }, - { &s3_phoenix_trio32_pci_device }, - { &s3_diamond_stealth64_pci_device }, - { &s3_9fx_pci_device }, - { &s3_phoenix_trio64_pci_device }, - { &s3_elsa_winner2000_pro_x_pci_device }, - { &s3_mirovideo_40sv_ergo_968_pci_device }, - { &s3_9fx_771_pci_device }, - { &s3_phoenix_vision968_pci_device }, - { &s3_spea_mercury_p64v_pci_device }, - { &s3_9fx_531_pci_device }, - { &s3_phoenix_vision868_pci_device }, - { &s3_cardex_trio64vplus_pci_device }, - { &s3_phoenix_trio64vplus_pci_device }, - { &s3_trio64v2_dx_pci_device }, - { &s3_virge_325_pci_device }, - { &s3_diamond_stealth_2000_pci_device }, - { &s3_diamond_stealth_3000_pci_device }, - { &s3_stb_velocity_3d_pci_device }, - { &s3_virge_375_pci_device }, - { &s3_diamond_stealth_2000pro_pci_device }, - { &s3_virge_385_pci_device }, - { &s3_virge_357_pci_device }, - { &s3_diamond_stealth_4000_pci_device }, - { &s3_trio3d2x_pci_device }, - { &millennium_device }, - { &millennium_ii_device }, - { &mystique_device }, - { &mystique_220_device }, - { &tgui9440_pci_device }, - { &tgui9660_pci_device }, - { &tgui9680_pci_device }, - { &voodoo_banshee_device }, - { &creative_voodoo_banshee_device }, - { &voodoo_3_1000_device }, - { &voodoo_3_2000_device }, - { &voodoo_3_3000_device }, - { &mach32_vlb_device, VIDEO_FLAG_TYPE_8514 }, - { &mach64gx_vlb_device }, - { &et4000w32i_vlb_device }, - { &et4000w32p_videomagic_revb_vlb_device }, - { &et4000w32p_revc_vlb_device }, - { &et4000w32p_cardex_vlb_device }, - { &et4000w32p_vlb_device }, - { &et4000w32p_noncardex_vlb_device }, - { &gd5424_vlb_device }, - { &gd5426_vlb_device }, - { &gd5428_vlb_device }, - { &gd5428_diamond_speedstar_pro_b1_vlb_device }, - { &gd5429_vlb_device }, - { &gd5430_diamond_speedstar_pro_se_a8_vlb_device }, - { &gd5430_vlb_device }, - { &gd5434_vlb_device }, - { &s3_metheus_86c928_vlb_device }, - { &s3_mirocrystal_8s_805_vlb_device }, - { &s3_mirocrystal_10sd_805_vlb_device }, - { &s3_phoenix_86c805_vlb_device }, - { &s3_spea_mirage_86c805_vlb_device }, - { &s3_diamond_stealth64_964_vlb_device }, - { &s3_mirocrystal_20sv_964_vlb_device }, - { &s3_mirocrystal_20sd_864_vlb_device }, - { &s3_bahamas64_vlb_device }, - { &s3_phoenix_vision864_vlb_device }, - { &s3_diamond_stealth_se_vlb_device }, - { &s3_phoenix_trio32_vlb_device }, - { &s3_diamond_stealth64_vlb_device }, - { &s3_9fx_vlb_device }, - { &s3_phoenix_trio64_vlb_device }, - { &s3_spea_mirage_p64_vlb_device }, - { &s3_phoenix_vision968_vlb_device }, - { &s3_phoenix_vision868_vlb_device }, - { &ht216_32_standalone_device }, - { &tgui9400cxi_device }, - { &tgui9440_vlb_device }, - { &s3_virge_357_agp_device }, - { &s3_diamond_stealth_4000_agp_device }, - { &s3_trio3d2x_agp_device }, - { &productiva_g100_device }, - { &velocity_100_agp_device }, - { &velocity_200_agp_device }, - { &voodoo_3_1000_agp_device }, - { &voodoo_3_2000_agp_device }, - { &voodoo_3_3000_agp_device }, - { &voodoo_3_3500_agp_ntsc_device }, - { &voodoo_3_3500_agp_pal_device }, - { &compaq_voodoo_3_3500_agp_device }, - { &voodoo_3_3500_se_agp_device }, - { &voodoo_3_3500_si_agp_device }, - { NULL } + { &cga_device }, + { &sega_device }, + { &gd5401_isa_device }, + { &gd5402_isa_device }, + { &gd5420_isa_device }, + { &gd5422_isa_device }, + { &gd5426_isa_device }, + { &gd5426_diamond_speedstar_pro_a1_isa_device }, + { &gd5428_boca_isa_device }, + { &gd5428_isa_device }, + { &gd5429_isa_device }, + { &gd5434_isa_device }, + { &gd5434_diamond_speedstar_64_a3_isa_device }, + { &compaq_cga_device }, + { &compaq_cga_2_device }, + { &cpqega_device }, + { &ega_device }, + { &g2_gc205_device }, + { &hercules_device, VIDEO_FLAG_TYPE_MDA }, + { &herculesplus_device, VIDEO_FLAG_TYPE_MDA }, + { &incolor_device }, + { &inmos_isa_device, VIDEO_FLAG_TYPE_XGA }, + { &im1024_device }, + { &iskra_ega_device }, + { &et4000_kasan_isa_device }, + { &mda_device, VIDEO_FLAG_TYPE_MDA }, + { &genius_device }, + { &nga_device }, + { &ogc_device }, + { &oti037c_device }, + { &oti067_device }, + { &oti077_device }, + { ¶dise_pvga1a_device }, + { ¶dise_wd90c11_device }, + { ¶dise_wd90c30_device }, + { &colorplus_device }, + { &pgc_device }, + { &cga_pravetz_device }, + { &radius_svga_multiview_isa_device }, + { &realtek_rtg3106_device }, + { &s3_diamond_stealth_vram_isa_device }, + { &s3_orchid_86c911_isa_device }, + { &s3_ami_86c924_isa_device }, + { &s3_metheus_86c928_isa_device }, + { &s3_phoenix_86c801_isa_device }, + { &s3_spea_mirage_86c801_isa_device }, + { &sigma_device }, + { &tvga8900b_device }, + { &tvga8900d_device }, + { &tvga9000b_device }, + { &nec_sv9000_device }, + { &et4000k_isa_device }, + { &et2000_device }, + { &et3000_isa_device }, + { &et4000_isa_device }, + { &et4000w32_device }, + { &et4000w32i_isa_device }, + { &vga_device }, + { &v7_vga_1024i_device }, + { &wy700_device }, + { &mach32_mca_device, VIDEO_FLAG_TYPE_8514 }, + { &gd5426_mca_device }, + { &gd5428_mca_device }, + { &et4000_mca_device }, + { &radius_svga_multiview_mca_device }, + { &mach32_pci_device, VIDEO_FLAG_TYPE_8514 }, + { &mach64gx_pci_device }, + { &mach64vt2_device }, + { &et4000w32p_videomagic_revb_pci_device }, + { &et4000w32p_revc_pci_device }, + { &et4000w32p_cardex_pci_device }, + { &et4000w32p_noncardex_pci_device }, + { &et4000w32p_pci_device }, + { &gd5430_pci_device, }, + { &gd5434_pci_device }, + { &gd5436_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, + { &gd5440_pci_device }, + { &gd5446_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, + { &gd5446_stb_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, + { &gd5480_pci_device }, + { &s3_spea_mercury_lite_86c928_pci_device }, + { &s3_diamond_stealth64_964_pci_device }, + { &s3_elsa_winner2000_pro_x_964_pci_device }, + { &s3_mirocrystal_20sv_964_pci_device }, + { &s3_bahamas64_pci_device }, + { &s3_phoenix_vision864_pci_device }, + { &s3_diamond_stealth_se_pci_device }, + { &s3_phoenix_trio32_pci_device }, + { &s3_diamond_stealth64_pci_device }, + { &s3_9fx_pci_device }, + { &s3_phoenix_trio64_pci_device }, + { &s3_elsa_winner2000_pro_x_pci_device }, + { &s3_mirovideo_40sv_ergo_968_pci_device }, + { &s3_9fx_771_pci_device }, + { &s3_phoenix_vision968_pci_device }, + { &s3_spea_mercury_p64v_pci_device }, + { &s3_9fx_531_pci_device }, + { &s3_phoenix_vision868_pci_device }, + { &s3_cardex_trio64vplus_pci_device }, + { &s3_phoenix_trio64vplus_pci_device }, + { &s3_trio64v2_dx_pci_device }, + { &s3_virge_325_pci_device }, + { &s3_diamond_stealth_2000_pci_device }, + { &s3_diamond_stealth_3000_pci_device }, + { &s3_stb_velocity_3d_pci_device }, + { &s3_virge_375_pci_device }, + { &s3_diamond_stealth_2000pro_pci_device }, + { &s3_virge_385_pci_device }, + { &s3_virge_357_pci_device }, + { &s3_diamond_stealth_4000_pci_device }, + { &s3_trio3d2x_pci_device }, + { &millennium_device }, + { &millennium_ii_device }, + { &mystique_device }, + { &mystique_220_device }, + { &tgui9440_pci_device }, + { &tgui9660_pci_device }, + { &tgui9680_pci_device }, + { &voodoo_banshee_device }, + { &creative_voodoo_banshee_device }, + { &voodoo_3_1000_device }, + { &voodoo_3_2000_device }, + { &voodoo_3_3000_device }, + { &mach32_vlb_device, VIDEO_FLAG_TYPE_8514 }, + { &mach64gx_vlb_device }, + { &et4000w32i_vlb_device }, + { &et4000w32p_videomagic_revb_vlb_device }, + { &et4000w32p_revc_vlb_device }, + { &et4000w32p_cardex_vlb_device }, + { &et4000w32p_vlb_device }, + { &et4000w32p_noncardex_vlb_device }, + { &gd5424_vlb_device }, + { &gd5426_vlb_device }, + { &gd5428_vlb_device }, + { &gd5428_diamond_speedstar_pro_b1_vlb_device }, + { &gd5429_vlb_device }, + { &gd5430_diamond_speedstar_pro_se_a8_vlb_device }, + { &gd5430_vlb_device }, + { &gd5434_vlb_device }, + { &s3_metheus_86c928_vlb_device }, + { &s3_mirocrystal_8s_805_vlb_device }, + { &s3_mirocrystal_10sd_805_vlb_device }, + { &s3_phoenix_86c805_vlb_device }, + { &s3_spea_mirage_86c805_vlb_device }, + { &s3_diamond_stealth64_964_vlb_device }, + { &s3_mirocrystal_20sv_964_vlb_device }, + { &s3_mirocrystal_20sd_864_vlb_device }, + { &s3_bahamas64_vlb_device }, + { &s3_phoenix_vision864_vlb_device }, + { &s3_diamond_stealth_se_vlb_device }, + { &s3_phoenix_trio32_vlb_device }, + { &s3_diamond_stealth64_vlb_device }, + { &s3_9fx_vlb_device }, + { &s3_phoenix_trio64_vlb_device }, + { &s3_spea_mirage_p64_vlb_device }, + { &s3_phoenix_vision968_vlb_device }, + { &s3_phoenix_vision868_vlb_device }, + { &ht216_32_standalone_device }, + { &tgui9400cxi_device }, + { &tgui9440_vlb_device }, + { &s3_virge_357_agp_device }, + { &s3_diamond_stealth_4000_agp_device }, + { &s3_trio3d2x_agp_device }, + { &productiva_g100_device, VIDEO_FLAG_TYPE_SPECIAL }, + { &velocity_100_agp_device }, + { &velocity_200_agp_device }, + { &voodoo_3_1000_agp_device }, + { &voodoo_3_2000_agp_device }, + { &voodoo_3_3000_agp_device }, + { &voodoo_3_3500_agp_ntsc_device }, + { &voodoo_3_3500_agp_pal_device }, + { &compaq_voodoo_3_3500_agp_device }, + { &voodoo_3_3500_se_agp_device }, + { &voodoo_3_3500_si_agp_device }, + { NULL } // clang-format on }; From 318403b133f08a0260ee3b7a861dc3418ca5fe76 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 2 Jan 2024 14:12:02 +0600 Subject: [PATCH 186/936] Fix G100 VBIOS mapping --- src/video/vid_mga.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index e4d4ef668..b4f84fb62 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -6202,9 +6202,11 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) if (!(mystique->pci_regs[0x43] & 0x40)) return; mystique->pci_regs[addr] = val; + if (addr == 0x30) + mystique->pci_regs[addr] &= 1; if (mystique->pci_regs[0x30] & 0x01) { uint32_t addr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); - mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, 0x8000); + mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, (mystique->type == MGA_G100) ? 0x10000 : 0x8000); } else mem_mapping_disable(&mystique->bios_rom.mapping); return; @@ -6228,11 +6230,11 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) if (val & 0x40) { if (mystique->pci_regs[0x30] & 0x01) { uint32_t addr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); - mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, 0x8000); + mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, (mystique->type == MGA_G100) ? 0x10000 : 0x8000); } else mem_mapping_disable(&mystique->bios_rom.mapping); } else - mem_mapping_set_addr(&mystique->bios_rom.mapping, 0x000c0000, 0x8000); + mem_mapping_set_addr(&mystique->bios_rom.mapping, 0x000c0000, (mystique->type == MGA_G100) ? 0x10000 : 0x8000); } break; @@ -6331,7 +6333,10 @@ mystique_init(const device_t *info) else romfn = ROM_MYSTIQUE_220; - rom_init(&mystique->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (mystique->type == MGA_G100) + rom_init(&mystique->bios_rom, romfn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + else + rom_init(&mystique->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); mem_mapping_disable(&mystique->bios_rom.mapping); mystique->vram_size = device_get_config_int("memory"); From 64c930f95feaf4b674fda5a78bc44b0913fc9b84 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 2 Jan 2024 14:34:12 +0600 Subject: [PATCH 187/936] G100 is now correctly added as AGP device --- src/video/vid_mga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index b4f84fb62..24a4e5835 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -6396,7 +6396,7 @@ mystique_init(const device_t *info) if (romfn == NULL) pci_add_card(PCI_ADD_VIDEO, mystique_pci_read, mystique_pci_write, mystique, &mystique->pci_slot); else - pci_add_card(PCI_ADD_NORMAL, mystique_pci_read, mystique_pci_write, mystique, &mystique->pci_slot); + pci_add_card((info->flags & DEVICE_AGP) ? PCI_ADD_AGP : PCI_ADD_NORMAL, mystique_pci_read, mystique_pci_write, mystique, &mystique->pci_slot); mystique->pci_regs[0x06] = 0x80; mystique->pci_regs[0x07] = 0 << 1; mystique->pci_regs[0x2c] = mystique->bios_rom.rom[0x7ff8]; From 413b6195924c0228afcd779a4623849c6e951745 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 2 Jan 2024 23:45:44 +0600 Subject: [PATCH 188/936] Rawinput now follows keyboard focus properly --- src/qt/qt_winrawinputfilter.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/qt/qt_winrawinputfilter.cpp b/src/qt/qt_winrawinputfilter.cpp index b8e7d1038..3ca091ae6 100644 --- a/src/qt/qt_winrawinputfilter.cpp +++ b/src/qt/qt_winrawinputfilter.cpp @@ -53,17 +53,15 @@ extern "C" void win_joystick_handle(PRAWINPUT); std::unique_ptr WindowsRawInputFilter::Register(MainWindow *window) { - HWND wnd = (HWND) window->winId(); - RAWINPUTDEVICE rid[2] = { {.usUsagePage = 0x01, .usUsage = 0x06, .dwFlags = RIDEV_NOHOTKEYS, - .hwndTarget = wnd}, + .hwndTarget = nullptr}, { .usUsagePage = 0x01, .usUsage = 0x02, .dwFlags = 0, - .hwndTarget = wnd} + .hwndTarget = nullptr} }; if (RegisterRawInputDevices(rid, 2, sizeof(rid[0])) == FALSE) From 6875cb08517953c57f6cab0bc7bba1dd93b8725a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 3 Jan 2024 00:10:41 +0600 Subject: [PATCH 189/936] Mouse capturing now works on secondary monitors --- src/qt/qt_rendererstack.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 1b1ed45c3..e5ed77ba7 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -144,7 +144,7 @@ int ignoreNextMouseEvent = 1; void RendererStack::mouseReleaseEvent(QMouseEvent *event) { - if (!dopause && this->geometry().contains(event->pos()) && + if (!dopause && this->geometry().contains(m_monitor_index >= 1 ? event->globalPos() : event->pos()) && (event->button() == Qt::LeftButton) && !mouse_capture && (isMouseDown & 1) && (kbd_req_capture || (mouse_get_buttons() != 0)) && (mouse_input_mode == 0)) { From b7a4fa2a7cfcfa66ead1c74fb45124e488b320c9 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 3 Jan 2024 22:58:18 +0100 Subject: [PATCH 190/936] S3 refactoring: 1. Made the 924 BIOS use the AT&T 491 ramdac since it supports such (tested). 2. Tweaks to the 928 Brooktree ID detection to make sure the cursor is shown correctly in 16bpp+ modes (it uses the BT485 ID detection so that it knows what BT is using to accommodate the cursor model). 3. Refactored the mode (CRTC50) and pitch timing stuff (moved to recalctimings for example) so that drivers/games/operating systems and what not can be used normally. (Warning, more stuff is to be tested due to a gazillion of combinations used by said stuff). 4. VRAM wraparound is now working as it should, fixes Commander Keen games. 5. Indentation fixes. 6. Attempt to fix 15/16bpp mode acceleration used by the 911/924 chips (not perfect and still has bugs). 7. Added the remaining missing stuff of the Sierra SC1502x RAMDAC including its 8BIT setting. 8. Some drivers use FIFO bits in non-FIFO configurations, should fix hang ups in some instances (namely the 928 S3 2.3 NT 3.1 drivers and possibly more). 9. Separated the 911/924 acceleration from the 80x/928+ one though the use of a function pointer. 10. Fixed the inverted colors in some instances using the S3 Trio64 driver in Win9x (mainly on soft reboots). 11. CX/CY (non-Blits) and DX/DY (Blits) wraparound correctly during their respective operations, fixes OS/2 software cursor once again while keeping existing stuff working. 12. Added some comments to keep track of some anomalies. 13. Fixed some badly formatted if's and switches. 14. Limited the SPEA Mercury Lite VRAM to 1MB per real world configurations. --- src/video/vid_s3.c | 2170 ++++++++++++++++++++++++++------ src/video/vid_sc1502x_ramdac.c | 192 ++- 2 files changed, 1909 insertions(+), 453 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 183066911..0fd939908 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -268,6 +268,18 @@ typedef struct s3_t { int ssv_len; uint8_t ssv_dir; uint8_t ssv_draw; + uint8_t dat_buf_16bit; + uint8_t frgd_color_actual[2]; + uint8_t bkgd_color_actual[2]; + uint8_t wrt_mask_actual[2]; + uint8_t rd_mask_actual[2]; + uint8_t *pix_trans_ptr; + int pix_trans_ptr_cnt; + int pix_trans_x_count; + int pix_trans_x_count2; + int color_16bit_check; + int color_16bit_check_rectfill; + uint16_t minus, srcminus; /*For non-threaded FIFO*/ int setup_fifo_slot; @@ -365,6 +377,8 @@ typedef struct s3_t { void *i2c, *ddc; int vram; + + void (*accel_start)(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, void *priv); } s3_t; #define INT_VSY (1 << 0) @@ -475,7 +489,7 @@ s3_update_irqs(s3_t *s3) } } -void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3); +void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, void *priv); void s3_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3, uint8_t ssv); static void s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3); @@ -496,7 +510,7 @@ static void s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3); } #define READ_PIXTRANS_BYTE_IO(n) \ - s3->accel.pix_trans[n] = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + n)) & s3->vram_mask]; + s3->accel.pix_trans[n] = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + n - s3->accel.minus)) & s3->vram_mask]; #define READ_PIXTRANS_BYTE_MM \ temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask]; @@ -506,7 +520,7 @@ static void s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3); temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask]; \ temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 1)) & s3->vram_mask] << 8); \ } else { \ - temp = vram_w[dword_remap_w(svga, (s3->accel.dest + s3->accel.cx)) & (s3->vram_mask >> 1)]; \ + temp = vram_w[dword_remap_w(svga, (s3->accel.dest + s3->accel.cx - s3->accel.minus)) & (s3->vram_mask >> 1)]; \ } #define READ_PIXTRANS_LONG \ @@ -567,20 +581,29 @@ s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) const svga_t *svga = &s3->svga; if (s3->accel.cmd & 0x100) { + //pclog("S3 PIXTRANS_W write: cmd=%03x, pixelcntl=%02x, frgdmix=%02x, bkgdmix=%02x, curx=%d, val=%04x.\n", s3->accel.cmd, s3->accel.multifunc[0x0a], s3->accel.frgd_mix, s3->accel.bkgd_mix, s3->accel.cur_x, val); switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) val = (val >> 8) | (val << 8); - s3_accel_start(8, 1, val | (val << 16), 0, s3); + s3->accel_start(8, 1, val | (val << 16), 0, s3); } else - s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); + s3->accel_start(1, 1, 0xffffffff, val | (val << 16), s3); } else { - if (s3->color_16bit) - s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); - else - s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); + if (s3->accel.color_16bit_check_rectfill) { + if (s3->accel.color_16bit_check) { + if (s3->accel.pix_trans_x_count < s3->accel.pix_trans_ptr_cnt) { + //pclog("Word: CPU data CMD=%04x, byte write=%02x, cnt=%d, check=%d.\n", s3->accel.cmd, val & 0xff, s3->accel.pix_trans_x_count, s3->accel.color_16bit_check); + s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count] = val & 0xff; + s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count + 1] = val >> 8; + s3->accel.pix_trans_x_count += 2; + } + } + break; + } + s3->accel_start(1, 1, 0xffffffff, val | (val << 16), s3); } break; case 0x200: @@ -588,11 +611,43 @@ s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) val = (val >> 8) | (val << 8); - s3_accel_start(16, 1, val | (val << 16), 0, s3); + s3->accel_start(16, 1, val | (val << 16), 0, s3); } else - s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + s3->accel_start(2, 1, 0xffffffff, val | (val << 16), s3); } else { - s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + if (s3->accel.color_16bit_check_rectfill) { + if (s3->accel.color_16bit_check) { + if (s3->accel.pix_trans_x_count < s3->accel.pix_trans_ptr_cnt) { + //pclog("Word: CPU data CMD=%04x, word write=%04x, cnt=%d, check=%d, totalptrcnt=%d.\n", s3->accel.cmd, val, s3->accel.pix_trans_x_count, s3->accel.color_16bit_check, s3->accel.pix_trans_ptr_cnt); + s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count] = val & 0xff; + s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count + 1] = val >> 8; + s3->accel.pix_trans_x_count += 2; + s3->accel.pix_trans_x_count2 = s3->accel.pix_trans_x_count; + } + } else { + if (s3->accel.pix_trans_x_count < s3->accel.pix_trans_ptr_cnt) { + //pclog("Word: CPU data CMD=%04x, word write=%04x, cnt=%d, check=%d, totalptrcnt=%d.\n", s3->accel.cmd, val, s3->accel.pix_trans_x_count, s3->accel.color_16bit_check, s3->accel.pix_trans_ptr_cnt); + s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count2] = val & 0xff; + s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count2 + 1] = val >> 8; + s3->accel.pix_trans_x_count += 2; + } + if (s3->accel.pix_trans_x_count2 == s3->accel.pix_trans_ptr_cnt) { + for (int i = 0; i < s3->accel.pix_trans_ptr_cnt; i += 2) { + //pclog("Transferring write count=%d, bytes=%08x.\n", i, s3->accel.pix_trans_ptr[i] | (s3->accel.pix_trans_ptr[i + 1] << 8) | (s3->accel.pix_trans_ptr[i + 2] << 16) | (s3->accel.pix_trans_ptr[i + 3] << 24)); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans_ptr[i] | (s3->accel.pix_trans_ptr[i + 1] << 8), s3); + } + + s3->accel.pix_trans_x_count2 = 0; + s3->accel.color_16bit_check_rectfill = 0; + if (s3->accel.pix_trans_ptr != NULL) { + free(s3->accel.pix_trans_ptr); + s3->accel.pix_trans_ptr = NULL; + } + } + } + break; + } + s3->accel_start(2, 1, 0xffffffff, val | (val << 16), s3); } break; case 0x400: @@ -601,21 +656,21 @@ s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) val = (val >> 8) | (val << 8); - s3_accel_start(32, 1, val | (val << 16), 0, s3); + s3->accel_start(32, 1, val | (val << 16), 0, s3); } else - s3_accel_start(4, 1, 0xffffffff, val | (val << 16), s3); + s3->accel_start(4, 1, 0xffffffff, val | (val << 16), s3); } else - s3_accel_start(4, 1, 0xffffffff, val | (val << 16), s3); + s3->accel_start(4, 1, 0xffffffff, val | (val << 16), s3); } else { if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) val = (val >> 8) | (val << 8); - s3_accel_start(16, 1, val | (val << 16), 0, s3); + s3->accel_start(16, 1, val | (val << 16), 0, s3); } else - s3_accel_start(4, 1, 0xffffffff, val | (val << 16), s3); + s3->accel_start(4, 1, 0xffffffff, val | (val << 16), s3); } else - s3_accel_start(4, 1, 0xffffffff, val | (val << 16), s3); + s3->accel_start(4, 1, 0xffffffff, val | (val << 16), s3); } break; case 0x600: @@ -624,8 +679,8 @@ s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) val = (val >> 8) | (val << 8); - s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); - s3_accel_start(8, 1, val & 0xff, 0, s3); + s3->accel_start(8, 1, (val >> 8) & 0xff, 0, s3); + s3->accel_start(8, 1, val & 0xff, 0, s3); } } } @@ -647,15 +702,15 @@ s3_accel_out_pixtrans_l(s3_t *s3, uint32_t val) if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); - s3_accel_start(8, 1, val, 0, s3); - s3_accel_start(8, 1, val >> 16, 0, s3); + s3->accel_start(8, 1, val, 0, s3); + s3->accel_start(8, 1, val >> 16, 0, s3); } else { - s3_accel_start(1, 1, 0xffffffff, val, s3); - s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); + s3->accel_start(1, 1, 0xffffffff, val, s3); + s3->accel_start(1, 1, 0xffffffff, val >> 16, s3); } } else { - s3_accel_start(1, 1, 0xffffffff, val, s3); - s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); + s3->accel_start(1, 1, 0xffffffff, val, s3); + s3->accel_start(1, 1, 0xffffffff, val >> 16, s3); } break; case 0x200: @@ -663,15 +718,15 @@ s3_accel_out_pixtrans_l(s3_t *s3, uint32_t val) if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); - s3_accel_start(16, 1, val, 0, s3); - s3_accel_start(16, 1, val >> 16, 0, s3); + s3->accel_start(16, 1, val, 0, s3); + s3->accel_start(16, 1, val >> 16, 0, s3); } else { - s3_accel_start(2, 1, 0xffffffff, val, s3); - s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); + s3->accel_start(2, 1, 0xffffffff, val, s3); + s3->accel_start(2, 1, 0xffffffff, val >> 16, s3); } } else { - s3_accel_start(2, 1, 0xffffffff, val, s3); - s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); + s3->accel_start(2, 1, 0xffffffff, val, s3); + s3->accel_start(2, 1, 0xffffffff, val >> 16, s3); } break; case 0x400: @@ -679,11 +734,11 @@ s3_accel_out_pixtrans_l(s3_t *s3, uint32_t val) if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); - s3_accel_start(32, 1, val, 0, s3); + s3->accel_start(32, 1, val, 0, s3); } else - s3_accel_start(4, 1, 0xffffffff, val, s3); + s3->accel_start(4, 1, 0xffffffff, val, s3); } else - s3_accel_start(4, 1, 0xffffffff, val, s3); + s3->accel_start(4, 1, 0xffffffff, val, s3); break; case 0x600: if (s3->chip == S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868 || s3->chip >= S3_TRIO64V) { @@ -691,10 +746,10 @@ s3_accel_out_pixtrans_l(s3_t *s3, uint32_t val) if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); - s3_accel_start(8, 1, (val >> 24) & 0xff, 0, s3); - s3_accel_start(8, 1, (val >> 16) & 0xff, 0, s3); - s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); - s3_accel_start(8, 1, val & 0xff, 0, s3); + s3->accel_start(8, 1, (val >> 24) & 0xff, 0, s3); + s3->accel_start(8, 1, (val >> 16) & 0xff, 0, s3); + s3->accel_start(8, 1, (val >> 8) & 0xff, 0, s3); + s3->accel_start(8, 1, val & 0xff, 0, s3); } } } @@ -854,7 +909,11 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x9ae9: s3->accel.cmd = (s3->accel.cmd & 0xff) | (val << 8); s3->accel.ssv_state = 0; - s3_accel_start(-1, 0, 0xffffffff, 0, s3); + s3->accel_start(-1, 0, 0xffffffff, 0, s3); + if (s3->bpp == 3) { + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] &= ~0x10; + } break; case 0x994a: @@ -902,6 +961,11 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xffff00ff) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; + + if (s3->accel.color_16bit_check) + s3->accel.bkgd_color_actual[1] = s3->accel.bkgd_color & 0xff; + else + s3->accel.bkgd_color_actual[0] = s3->accel.bkgd_color & 0xff; break; case 0xa14a: case 0xa2ea: @@ -935,6 +999,11 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.frgd_color = (s3->accel.frgd_color & 0xffff00ff) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; + + if (s3->accel.color_16bit_check) + s3->accel.frgd_color_actual[1] = s3->accel.frgd_color & 0xff; + else + s3->accel.frgd_color_actual[0] = s3->accel.frgd_color & 0xff; break; case 0xa54a: case 0xa6ea: @@ -968,6 +1037,11 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xffff00ff) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; + + if (s3->accel.color_16bit_check) + s3->accel.wrt_mask_actual[1] = s3->accel.wrt_mask & 0xff; + else + s3->accel.wrt_mask_actual[0] = s3->accel.wrt_mask & 0xff; break; case 0xa94a: case 0xaaea: @@ -1172,14 +1246,42 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); } else { - if (s3->color_16bit) - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0], s3); - else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + if (s3->accel.color_16bit_check_rectfill) { + if (s3->accel.color_16bit_check) { + if (s3->accel.pix_trans_x_count < s3->accel.pix_trans_ptr_cnt) { + //pclog("Byte: CPU data CMD=%04x, byte write=%02x, cnt=%d, check=%d.\n", s3->accel.cmd, val, s3->accel.pix_trans_x_count, s3->accel.color_16bit_check); + s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count] = val; + s3->accel.pix_trans_x_count++; + s3->accel.pix_trans_x_count2 = s3->accel.pix_trans_x_count; + } + } else { + if (s3->accel.pix_trans_x_count2 < s3->accel.pix_trans_ptr_cnt) { + //pclog("Byte: CPU data CMD=%04x, byte write=%02x, cnt=%d, check=%d.\n", s3->accel.cmd, val, s3->accel.pix_trans_x_count2, s3->accel.color_16bit_check); + s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count2] = val; + s3->accel.pix_trans_x_count2++; + } + //pclog("WriteCNT=%d, TotalCNT=%d.\n", s3->accel.pix_trans_x_count2, s3->accel.pix_trans_ptr_cnt); + if (s3->accel.pix_trans_x_count2 == s3->accel.pix_trans_ptr_cnt) { + for (int i = 0; i < s3->accel.pix_trans_ptr_cnt; i += 2) { + //pclog("Transferring write count=%d, bytes=%04x.\n", i, s3->accel.pix_trans_ptr[i] | (s3->accel.pix_trans_ptr[i + 1] << 8)); + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans_ptr[i] | (s3->accel.pix_trans_ptr[i + 1] << 8), s3); + } + + s3->accel.pix_trans_x_count2 = 0; + s3->accel.color_16bit_check_rectfill = 0; + if (s3->accel.pix_trans_ptr != NULL) { + free(s3->accel.pix_trans_ptr); + s3->accel.pix_trans_ptr = NULL; + } + } + } + break; + } + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); } break; @@ -1195,63 +1297,54 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; s3->accel.pix_trans[1] = val; if (s3->accel.cmd & 0x100) { + //pclog("S3 PIXTRANS_B write (E2E9): cmd=%03x, pixelcntl=%02x, frgdmix=%02x, bkgdmix=%02x, curx=%d, val=%04x.\n", s3->accel.cmd, s3->accel.multifunc[0x0a], s3->accel.frgd_mix, s3->accel.bkgd_mix, s3->accel.cur_x, val); switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); - } else { - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); - } + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + } else + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); break; case 0x200: - /*Windows 95's built-in driver expects this to be loaded regardless of the byte swap bit (0xE2E9) in the 86c928 ISA/VLB*/ if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) - s3_accel_start(16, 1, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), 0, s3); + s3->accel_start(16, 1, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), 0, s3); else - s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); - } else { - if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) { - s3_accel_out_pixtrans_w(s3, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8)); - } else { - if (s3->accel.cmd & 0x1000) - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); - else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); - } - } - } else { - if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) { - s3_accel_out_pixtrans_w(s3, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8)); + s3->accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); } else { if (s3->accel.cmd & 0x1000) - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); } + } else { + if (s3->accel.cmd & 0x1000) + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); + else + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); } break; case 0x400: if (svga->crtc[0x53] & 0x08) { if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(32, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); + s3->accel_start(32, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); else - s3_accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + s3->accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); } else - s3_accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + s3->accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); } break; case 0x600: if (s3->chip == S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868 || s3->chip >= S3_TRIO64V) { if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - s3_accel_start(8, 1, s3->accel.pix_trans[1], 0, s3); - s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[1], 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); } } } @@ -1279,58 +1372,49 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); } else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); break; case 0x200: - /*Windows 95's built-in driver expects the upper 16 bits to be loaded instead of the whole 32-bit one, regardless of the byte swap bit (0xE2EB) in the 86c928 ISA/VLB card*/ if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) - s3_accel_start(16, 1, s3->accel.pix_trans[3] | (s3->accel.pix_trans[2] << 8) | (s3->accel.pix_trans[1] << 16) | (s3->accel.pix_trans[0] << 24), 0, s3); + s3->accel_start(16, 1, s3->accel.pix_trans[3] | (s3->accel.pix_trans[2] << 8) | (s3->accel.pix_trans[1] << 16) | (s3->accel.pix_trans[0] << 24), 0, s3); else - s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); - } else { - if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) { - s3_accel_out_pixtrans_w(s3, s3->accel.pix_trans[2] | (s3->accel.pix_trans[3] << 8)); - } else { - if (s3->accel.cmd & 0x1000) - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[3] | (s3->accel.pix_trans[2] << 8) | (s3->accel.pix_trans[1] << 16) | (s3->accel.pix_trans[0] << 24), s3); - else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); - } - } - } else { - if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) { - s3_accel_out_pixtrans_w(s3, s3->accel.pix_trans[2] | (s3->accel.pix_trans[3] << 8)); + s3->accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); } else { if (s3->accel.cmd & 0x1000) - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[3] | (s3->accel.pix_trans[2] << 8) | (s3->accel.pix_trans[1] << 16) | (s3->accel.pix_trans[0] << 24), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[3] | (s3->accel.pix_trans[2] << 8) | (s3->accel.pix_trans[1] << 16) | (s3->accel.pix_trans[0] << 24), s3); else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); } + } else { + if (s3->accel.cmd & 0x1000) + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[3] | (s3->accel.pix_trans[2] << 8) | (s3->accel.pix_trans[1] << 16) | (s3->accel.pix_trans[0] << 24), s3); + else + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); } break; case 0x400: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(32, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); + s3->accel_start(32, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); else - s3_accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + s3->accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); } else - s3_accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + s3->accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); break; case 0x600: if (s3->chip == S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868 || s3->chip >= S3_TRIO64V) { if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - s3_accel_start(8, 1, s3->accel.pix_trans[3], 0, s3); - s3_accel_start(8, 1, s3->accel.pix_trans[2], 0, s3); - s3_accel_start(8, 1, s3->accel.pix_trans[1], 0, s3); - s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[3], 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[2], 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[1], 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); } } } @@ -1377,11 +1461,10 @@ s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) static void s3_accel_out_fifo_l(s3_t *s3, uint16_t port, uint32_t val) { - if (port == 0xb2e8 || port == 0xb148) { + if (port == 0xb2e8 || port == 0xb148) s3->accel.b2e8_pix = 1; - } else { + else s3->accel.b2e8_pix = 0; - } s3_accel_out_pixtrans_l(s3, val); } @@ -1552,11 +1635,11 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) if (s3->accel.cmd & 0x100) { if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); + s3->accel_start(8, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); else - s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); + s3->accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); } else - s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); + s3->accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); } } else { switch (addr & 0x1ffff) { @@ -1633,7 +1716,7 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) } } else { if (addr & 0x8000) { - if ((addr == 0xe2e8) || (addr == 0xe2e9)) { + if ((addr == 0xe2e8) || (addr == 0xe2e9) || (addr == 0xe2ea) || (addr == 0xe2eb)) { if ((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) goto mmio_byte_write; else @@ -1646,19 +1729,19 @@ mmio_byte_write: if ((s3->accel.cmd & 0x600) == 0x200) { if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(16, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); + s3->accel_start(16, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); else - s3_accel_start(2, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); + s3->accel_start(2, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); } else - s3_accel_start(2, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); + s3->accel_start(2, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); } else { if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); + s3->accel_start(8, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); else - s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); + s3->accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); } else - s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); + s3->accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); } } } @@ -1909,7 +1992,7 @@ s3_accel_write_fifo_l(s3_t *s3, uint32_t addr, uint32_t val) } else { if (addr & 0x8000) { if (addr == 0xe2e8) { - if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) + if ((s3->chip == S3_86C928) || (s3->chip == S3_86C928PCI)) s3_accel_out_pixtrans_l(s3, val); else { s3_accel_write_fifo(s3, addr, val); @@ -1984,7 +2067,7 @@ s3_hwcursor_draw(svga_t *svga, int displine) fg = video_16to32[s3->hwc_fg_col & 0xffff]; bg = video_16to32[s3->hwc_bg_col & 0xffff]; if (s3->chip >= S3_86C928 && s3->chip <= S3_86C805) { - if (s3->card_type != S3_MIROCRYSTAL10SD_805 && s3->card_type != S3_MIROCRYSTAL8S_805) { + if ((s3->card_type != S3_MIROCRYSTAL10SD_805) && (s3->card_type != S3_MIROCRYSTAL8S_805)) { if (!(svga->crtc[0x45] & 0x04)) { shift = 2; width = 8; @@ -1998,8 +2081,13 @@ s3_hwcursor_draw(svga_t *svga, int displine) break; case 24: - fg = s3->hwc_fg_col; - bg = s3->hwc_bg_col; + if (s3->chip <= S3_86C805) { + fg = svga->pallook[svga->crtc[0xe]]; + bg = svga->pallook[svga->crtc[0xf]]; + } else { + fg = s3->hwc_fg_col; + bg = s3->hwc_bg_col; + } break; case 32: @@ -2519,7 +2607,6 @@ s3_out(uint16_t addr, uint8_t val, void *priv) s3_t *s3 = (s3_t *) priv; svga_t *svga = &s3->svga; uint8_t old; - uint8_t mask; int rs2; int rs3; @@ -2590,9 +2677,10 @@ s3_out(uint16_t addr, uint8_t val, void *priv) 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)) + } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805) || (s3->chip == S3_86C924)) && + ((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) { + else if (s3->chip == S3_86C911) { 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); @@ -2631,6 +2719,8 @@ s3_out(uint16_t addr, uint8_t val, void *priv) break; case 0x32: svga->vram_display_mask = (val & 0x40) ? 0x3ffff : s3->vram_mask; + if (s3->color_16bit) + svga->vram_display_mask = s3->vram_mask; break; case 0x40: @@ -2638,32 +2728,6 @@ s3_out(uint16_t addr, uint8_t val, void *priv) break; case 0x50: - mask = 0xc0; - if (s3->chip != S3_86C801) - mask |= 0x01; - switch (svga->crtc[0x50] & mask) { - case 0x00: - s3->width = (svga->crtc[0x31] & 2) ? 2048 : 1024; - break; - case 0x01: - s3->width = 1152; - break; - case 0x40: - s3->width = 640; - break; - case 0x80: - s3->width = ((s3->chip > S3_86C805) && (s3->accel.advfunc_cntl & 4)) ? 1600 : 800; - break; - case 0x81: - s3->width = 1600; - break; - case 0xc0: - s3->width = 1280; - break; - - default: - break; - } s3->bpp = (svga->crtc[0x50] >> 4) & 3; break; @@ -2747,6 +2811,8 @@ s3_out(uint16_t addr, uint8_t val, void *priv) svga->hwcursor.x >>= 1; } else if ((s3->chip >= S3_86C928 && s3->chip <= S3_86C805) && (svga->bpp == 24)) svga->hwcursor.x /= 3; + else if ((s3->chip <= S3_86C805) && s3->color_16bit) + svga->hwcursor.x >>= 1; break; case 0x4a: @@ -2793,7 +2859,7 @@ s3_out(uint16_t addr, uint8_t val, void *priv) case 0x55: if (s3->chip == S3_86C928) { - if ((val & 0x08) || ((val & 0x20) == 0x20)) { + if (val & 0x28) { svga->hwcursor_draw = NULL; svga->dac_hwcursor_draw = bt48x_hwcursor_draw; } else { @@ -2812,6 +2878,21 @@ s3_out(uint16_t addr, uint8_t val, void *priv) case 0x43: if (s3->chip < S3_VISION964) { + if (s3->chip <= S3_86C805) { + s3->color_16bit = !!(val & 8); + if (s3->color_16bit) { + s3->width = 1024; + } else { + if (s3->chip <= S3_86C924) + s3->width = 1024; + else { + if (s3->accel.advfunc_cntl & 4) + s3->width = 1024; + else + s3->width = 640; + } + } + } s3_io_remove_alt(s3); s3->translate = !!(val & 0x10); s3_io_set_alt(s3); @@ -2912,16 +2993,21 @@ s3_in(uint16_t addr, void *priv) 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)) { - rs3 = !!(svga->crtc[0x55] & 0x02); - return bt48x_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); + 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); + return temp; } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (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)) + } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805) || (s3->chip == S3_86C924)) && + ((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) + else if (s3->chip == S3_86C911) 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); @@ -2945,7 +3031,8 @@ s3_in(uint16_t addr, void *priv) return 0x16; /*Confirmed on an onboard 64V2/DX*/ default: return 0x00; - } + } + break; case 0x30: return s3->id; /*Chip ID*/ case 0x31: @@ -2954,7 +3041,7 @@ s3_in(uint16_t addr, void *priv) return (svga->crtc[0x35] & 0xf0) | (s3->bank & 0xf); case 0x45: s3->hwc_col_stack_pos = 0; - break; + return svga->crtc[0x45]; case 0x51: return (svga->crtc[0x51] & 0xf0) | ((s3->bank >> 2) & 0xc) | ((s3->ma_ext >> 2) & 3); case 0x5c: /* General Output Port Register */ @@ -2985,6 +3072,7 @@ s3_in(uint16_t addr, void *priv) } } else return svga->crtc[0x6b]; + break; case 0x6c: if (s3->chip != S3_TRIO64V2) { if (svga->crtc[0x53] & 0x08) { @@ -2993,6 +3081,7 @@ s3_in(uint16_t addr, void *priv) return (svga->crtc[0x5a] & 0x80); } else return svga->crtc[0x6c]; + break; default: break; @@ -3010,11 +3099,13 @@ s3_recalctimings(svga_t *svga) { s3_t *s3 = (s3_t *) svga->priv; int clk_sel = (svga->miscout >> 2) & 3; + uint8_t mask = 0xc0; if (!svga->scrblank && svga->attr_palette_enable) { if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { if (svga->crtc[0x3a] & 0x10) { /*256+ color register*/ svga->gdcreg[5] |= 0x40; + svga->attrregs[0x10] |= 0x40; } } } @@ -3027,7 +3118,7 @@ s3_recalctimings(svga_t *svga) svga->htotal |= 0x100; if (svga->crtc[0x5d] & 0x02) { svga->hdisp_time |= 0x100; - svga->hdisp |= 0x100 * ((svga->seqregs[1] & 8) ? 16 : 8); + svga->hdisp |= (0x100 * ((svga->seqregs[1] & 8) ? 16 : 8)); } if (svga->crtc[0x5e] & 0x01) svga->vtotal |= 0x400; @@ -3035,6 +3126,8 @@ s3_recalctimings(svga_t *svga) svga->dispend |= 0x400; if (svga->crtc[0x5e] & 0x04) svga->vblankstart |= 0x400; + else + svga->vblankstart = svga->dispend; if (svga->crtc[0x5e] & 0x10) svga->vsyncstart |= 0x400; if (svga->crtc[0x5e] & 0x40) @@ -3052,17 +3145,19 @@ s3_recalctimings(svga_t *svga) if ((s3->chip == S3_VISION964) || (s3->chip == S3_86C928)) { if (s3->card_type == S3_ELSAWIN2KPROX_964) ibm_rgb528_recalctimings(svga->ramdac, svga); - else + else { 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) + if ((s3->card_type == S3_SPEA_MERCURY_P64V) || (s3->card_type == S3_MIROVIDEO40SV_ERGO_968)) tvp3026_recalctimings(svga->ramdac, svga); else ibm_rgb528_recalctimings(svga->ramdac, svga); } else svga->interlace = !!(svga->crtc[0x42] & 0x20); - if ((((svga->miscout >> 2) & 3) == 3) && s3->chip < S3_TRIO32) + if ((((svga->miscout >> 2) & 3) == 3) && (s3->chip < S3_TRIO32)) clk_sel = svga->crtc[0x42] & 0x0f; svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clk_sel, svga->clock_gen); @@ -3080,11 +3175,41 @@ s3_recalctimings(svga_t *svga) svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); + if (s3->chip != S3_86C801) + mask |= 0x01; + switch (svga->crtc[0x50] & mask) { + case 0x00: + if (s3->color_16bit) + s3->width = 1024; + else + s3->width = (svga->crtc[0x31] & 2) ? 2048 : 1024; + break; + case 0x01: + s3->width = 1152; + break; + case 0x40: + s3->width = 640; + break; + case 0x80: + s3->width = ((s3->chip > S3_86C805) && (s3->accel.advfunc_cntl & 4)) ? 1600 : 800; + break; + case 0x81: + s3->width = 1600; + break; + case 0xc0: + s3->width = 1280; + break; + + default: + break; + } + +#ifdef OLD_CODE_REFERENCE if (s3->card_type == S3_MIROCRYSTAL10SD_805 || s3->card_type == S3_MIROCRYSTAL20SD_864 || s3->card_type == S3_MIROCRYSTAL20SV_964 || s3->card_type == S3_SPEA_MIRAGE_86C801 || s3->card_type == S3_SPEA_MIRAGE_86C805 || s3->card_type == S3_MIROCRYSTAL8S_805 || s3->card_type == S3_NUMBER9_9FX_531 || s3->card_type == S3_SPEA_MERCURY_LITE_PCI) { if (!(svga->crtc[0x5e] & 0x04)) svga->vblankstart = svga->dispend; if (svga->bpp != 32) { - if (svga->crtc[0x31] & 2) /*This is needed if the pixel width gets set with delays*/ + if (svga->crtc[0x31] & 2) s3->width = 2048; else { if (s3->card_type == S3_MIROCRYSTAL10SD_805) { @@ -3105,24 +3230,96 @@ s3_recalctimings(svga_t *svga) s3->width = 1024; } } - - if ((svga->crtc[0x43] & 0x08) && !s3->color_16bit && (s3->chip <= S3_86C805)) { - s3->color_16bit = 1; - s3->width = 1024; - } else if (!(svga->crtc[0x43] & 0x08) && s3->color_16bit && (s3->chip <= S3_86C805)) { - s3->color_16bit = 0; - if (s3->chip <= S3_86C924) { - if (s3->accel.advfunc_cntl & 4) - s3->width = 1024; - else - s3->width = 640; - } - } +#endif if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { + //pclog("BPP=%d, pitch=%d, width=%02x, double?=%x, 16bit?=%d, highres?=%d, attr=%02x.\n", svga->bpp, s3->width, svga->crtc[0x50], svga->crtc[0x31] & 0x02, s3->color_16bit, s3->accel.advfunc_cntl & 4, svga->attrregs[0x10] & 0x40); switch (svga->bpp) { case 8: svga->render = svga_render_8bpp_highres; + switch (s3->chip) { + case S3_86C928: + switch (s3->card_type) { + case S3_METHEUS_86C928: + switch (s3->width) { + case 1280: + svga->hdisp <<= 1; + break; + case 2048: /*Account for the 1280x1024 resolution*/ + switch (svga->hdisp) { + case 320: + svga->hdisp <<= 2; + break; + case 640: + svga->hdisp <<= 1; + break; + default: + break; + } + break; + default: + break; + } + break; + + default: + break; + } + break; + case S3_86C928PCI: + switch (s3->card_type) { + case S3_SPEA_MERCURY_LITE_PCI: + switch (s3->width) { + case 640: + svga->hdisp >>= 1; + break; + default: + break; + } + break; + + default: + break; + } + break; + case S3_VISION964: + switch (s3->card_type) { + case S3_ELSAWIN2KPROX_964: + svga->hdisp <<= 1; + break; + + default: + break; + } + break; + case S3_VISION968: + switch (s3->card_type) { + case S3_NUMBER9_9FX_771: + case S3_SPEA_MERCURY_P64V: + case S3_ELSAWIN2KPROX: + case S3_PHOENIX_VISION968: + svga->hdisp <<= 1; + break; + case S3_MIROVIDEO40SV_ERGO_968: + switch (s3->width) { + case 1152: + case 1280: + svga->hdisp <<= 1; + break; + default: + break; + } + break; + + default: + break; + } + break; + + default: + break; + } +#ifdef OLD_CODE_REFERENCE if (s3->chip != S3_VISION868) { if (s3->chip == S3_86C928) { if (s3->width == 2048 || s3->width == 1280 || s3->width == 1600) { @@ -3142,55 +3339,128 @@ s3_recalctimings(svga_t *svga) svga->hdisp <<= 1; } else if (s3->card_type == S3_NUMBER9_9FX_771) svga->hdisp <<= 1; - - if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_MIROCRYSTAL20SD_864 || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_SPEA_MERCURY_P64V) { - if (svga->hdisp != 1408) - svga->hdisp = s3->width; - if (s3->card_type == S3_MIROCRYSTAL20SD_864) { - if (s3->width == 2048 || s3->width == 1600 || s3->width == 800) { - switch (svga->dispend) { - case 400: - case 480: - svga->hdisp = 640; - break; - - case 576: - svga->hdisp = 768; - break; - - case 600: - if (s3->width == 1600) - s3->width = 800; - svga->hdisp = 800; - break; - - case 768: - svga->hdisp = 1024; - break; - - case 864: - svga->hdisp = 1152; - break; - - case 1024: - if (svga->vtotal == 1066) - svga->hdisp = 1280; - break; - - default: - break; - } - } - } - } - if (s3->card_type == S3_MIROCRYSTAL10SD_805 || s3->card_type == S3_MIROCRYSTAL8S_805) { - if (svga->rowoffset == 256 && ((svga->crtc[0x51] & 0x30) == 0x00 && !(svga->crtc[0x43] & 0x04))) - svga->rowoffset >>= 1; - } } +#endif break; case 15: svga->render = svga_render_15bpp_highres; + switch (s3->chip) { + case S3_86C911: + case S3_86C924: + svga->hdisp >>= 1; + break; + + case S3_86C801: + switch (s3->card_type) { + case S3_PHOENIX_86C801: + svga->hdisp >>= 1; + break; + + default: + break; + } + break; + case S3_86C805: + switch (s3->card_type) { + case S3_MIROCRYSTAL8S_805: + case S3_MIROCRYSTAL10SD_805: + case S3_PHOENIX_86C805: + case S3_86C805_ONBOARD: + svga->hdisp >>= 1; + break; + + case S3_SPEA_MIRAGE_86C805: + svga->hdisp >>= 1; + switch (s3->width) { + case 800: + case 1024: + if (svga->hdisp == 400) /*SPEA specific drivers + its VBE RAM BIOS...*/ + svga->hdisp <<= 1; + break; + default: + break; + } + break; + + default: + break; + } + break; + case S3_86C928: + switch (s3->card_type) { + case S3_METHEUS_86C928: + if (!s3->color_16bit) + svga->hdisp <<= 1; + switch (svga->hdisp) { /*This might be a driver issue*/ + case 800: + s3->width = 1024; + break; + case 1280: + s3->width = 2048; + break; + default: + break; + } + break; + + default: + break; + } + break; + case S3_86C928PCI: + switch (s3->card_type) { + case S3_SPEA_MERCURY_LITE_PCI: + switch (s3->width) { + case 640: + svga->hdisp >>= 1; + break; + default: + break; + } + break; + + default: + break; + } + break; + case S3_VISION864: + switch (s3->card_type) { + case S3_MIROCRYSTAL20SD_864: + svga->hdisp >>= 1; + break; + + default: + break; + } + break; + case S3_VISION868: + switch (s3->card_type) { + case S3_PHOENIX_VISION868: + case S3_NUMBER9_9FX_531: + svga->hdisp >>= 1; + break; + + default: + break; + } + break; + case S3_VISION968: + switch (s3->card_type) { + case S3_NUMBER9_9FX_771: + case S3_PHOENIX_VISION968: + svga->hdisp <<= 1; + if (svga->hdisp == 832) + svga->hdisp -= 32; + break; + + default: + break; + } + break; + default: + break; + } +#ifdef OLD_CODE_REFERENCE if ((s3->chip != S3_VISION964) && (s3->card_type != S3_SPEA_MIRAGE_86C801) && (s3->card_type != S3_SPEA_MIRAGE_86C805)) { if (s3->chip == S3_86C928) svga->hdisp <<= 1; @@ -3212,9 +3482,127 @@ s3_recalctimings(svga_t *svga) if (s3->card_type == S3_SPEA_MIRAGE_86C801 || s3->card_type == S3_SPEA_MIRAGE_86C805 || s3->card_type == S3_SPEA_MERCURY_LITE_PCI) svga->hdisp = s3->width; +#endif break; case 16: svga->render = svga_render_16bpp_highres; + switch (s3->chip) { + case S3_86C911: + case S3_86C924: + svga->hdisp >>= 1; + break; + + case S3_86C801: + switch (s3->card_type) { + case S3_PHOENIX_86C801: + svga->hdisp >>= 1; + break; + + default: + break; + } + break; + case S3_86C805: + switch (s3->card_type) { + case S3_MIROCRYSTAL8S_805: + case S3_MIROCRYSTAL10SD_805: + case S3_PHOENIX_86C805: + case S3_86C805_ONBOARD: + svga->hdisp >>= 1; + break; + + case S3_SPEA_MIRAGE_86C805: + svga->hdisp >>= 1; + switch (s3->width) { + case 800: + case 1024: + if (svga->hdisp == 400) /*SPEA specific drivers + its VBE RAM BIOS...*/ + svga->hdisp <<= 1; + break; + default: + break; + } + break; + + default: + break; + } + break; + case S3_86C928: + switch (s3->card_type) { + case S3_METHEUS_86C928: + svga->hdisp <<= 1; + switch (svga->hdisp) { /*This might be a driver issue*/ + case 800: + s3->width = 1024; + break; + case 1280: + s3->width = 2048; + break; + default: + break; + } + break; + + default: + break; + } + break; + case S3_86C928PCI: + switch (s3->card_type) { + case S3_SPEA_MERCURY_LITE_PCI: + switch (s3->width) { + case 640: + svga->hdisp >>= 1; + break; + default: + break; + } + break; + + default: + break; + } + break; + case S3_VISION864: + switch (s3->card_type) { + case S3_MIROCRYSTAL20SD_864: + svga->hdisp >>= 1; + break; + + default: + break; + } + break; + case S3_VISION868: + switch (s3->card_type) { + case S3_PHOENIX_VISION868: + case S3_NUMBER9_9FX_531: + svga->hdisp >>= 1; + break; + + default: + break; + } + break; + case S3_VISION968: + switch (s3->card_type) { + case S3_NUMBER9_9FX_771: + case S3_PHOENIX_VISION968: + svga->hdisp <<= 1; + if (svga->hdisp == 832) + svga->hdisp -= 32; + break; + + default: + break; + } + break; + default: + break; + } + +#ifdef OLD_CODE_REFERENCE if ((s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->card_type == S3_ELSAWIN2KPROX)) { if (s3->width == 1280 || s3->width == 1600) svga->hdisp <<= 1; @@ -3233,7 +3621,7 @@ s3_recalctimings(svga_t *svga) svga->hdisp <<= 1; } if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_SPEA_MERCURY_P64V) { - if (svga->hdisp == (1408 * 2)) + if (svga->hdisp == (1408 << 1)) svga->hdisp >>= 1; else svga->hdisp = s3->width; @@ -3241,9 +3629,85 @@ s3_recalctimings(svga_t *svga) if (s3->card_type == S3_SPEA_MIRAGE_86C801 || s3->card_type == S3_SPEA_MIRAGE_86C805 || s3->card_type == S3_SPEA_MERCURY_LITE_PCI) svga->hdisp = s3->width; +#endif break; case 24: svga->render = svga_render_24bpp_highres; + switch (s3->chip) { + case S3_86C924: + switch (s3->card_type) { + case S3_AMI_86C924: + svga->hdisp = (svga->hdisp << 1) / 3; + if (svga->hdisp == 645) + svga->hdisp -= 5; + break; + default: + break; + } + break; + case S3_86C801: + switch (s3->card_type) { + case S3_PHOENIX_86C801: + case S3_SPEA_MIRAGE_86C801: + svga->hdisp = (svga->hdisp << 1) / 3; + break; + default: + break; + } + break; + case S3_86C805: + switch (s3->card_type) { + case S3_MIROCRYSTAL8S_805: + case S3_MIROCRYSTAL10SD_805: + case S3_PHOENIX_86C805: + case S3_SPEA_MIRAGE_86C805: + case S3_86C805_ONBOARD: + svga->hdisp = (svga->hdisp << 1) / 3; + break; + default: + break; + } + break; + case S3_86C928PCI: + switch (s3->card_type) { + case S3_SPEA_MERCURY_LITE_PCI: + svga->hdisp = (svga->hdisp << 1) / 3; + break; + default: + break; + } + break; + case S3_VISION864: + switch (s3->card_type) { + case S3_MIROCRYSTAL20SD_864: + svga->hdisp = (svga->hdisp << 1) / 3; + break; + default: + break; + } + break; + case S3_VISION968: + switch (s3->card_type) { + case S3_MIROVIDEO40SV_ERGO_968: + switch (s3->width) { + case 1280: + svga->hdisp = (svga->hdisp << 1) / 3; + svga->hdisp <<= 1; + break; + default: + break; + } + break; + + default: + break; + } + break; + + default: + break; + } +#ifdef OLD_CODE_REFERENCE if (s3->chip != S3_VISION968) { if (s3->chip != S3_86C928 && s3->chip != S3_86C801 && s3->chip != S3_86C805) svga->hdisp /= 3; @@ -3251,7 +3715,7 @@ s3_recalctimings(svga_t *svga) svga->hdisp = (svga->hdisp * 2) / 3; if (s3->card_type == S3_SPEA_MERCURY_LITE_PCI) { - if (s3->width == 2048) + if (s3->width == 2048) { switch (svga->dispend) { case 480: svga->hdisp = 640; @@ -3260,14 +3724,63 @@ s3_recalctimings(svga_t *svga) default: break; } + } + } else if (s3->chip == S3_86C924) { + if (svga->dispend == 480) + svga->hdisp = 640; } } else { if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_SPEA_MERCURY_P64V) svga->hdisp = s3->width; } +#endif break; case 32: svga->render = svga_render_32bpp_highres; + switch (s3->chip) { + case S3_VISION868: + switch (s3->card_type) { + case S3_PHOENIX_VISION868: + case S3_NUMBER9_9FX_531: + svga->hdisp >>= 1; + break; + default: + break; + } + break; + case S3_VISION964: + switch (s3->card_type) { + case S3_MIROCRYSTAL20SV_964: + switch (s3->width) { + case 800: + case 1024: + svga->hdisp >>= 1; + break; + default: + break; + } + break; + default: + break; + } + break; + case S3_VISION968: + switch (s3->card_type) { + case S3_NUMBER9_9FX_771: + case S3_PHOENIX_VISION968: + svga->hdisp <<= 1; + if (svga->hdisp == 832) + svga->hdisp -= 32; + break; + default: + break; + } + break; + + default: + break; + } +#ifdef OLD_CODE_REFERENCE if ((s3->chip < S3_TRIO32) && (s3->chip != S3_VISION964) && (s3->chip != S3_VISION968) && (s3->chip != S3_86C928)) { if (s3->chip == S3_VISION868) svga->hdisp >>= 1; @@ -3308,24 +3821,21 @@ s3_recalctimings(svga_t *svga) } } } +#endif break; default: break; } } else { - if (!svga->scrblank && svga->attr_palette_enable) { + if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { - if ((svga->crtc[0x31] & 0x08) && ((svga->gdcreg[5] & 0x60) == 0x00)) { + if ((svga->crtc[0x31] & 0x08) && (svga->attrregs[0x10] & 0x40) == 0x00) { if (svga->bpp == 8) { svga->render = svga_render_8bpp_highres; /*Enhanced 4bpp mode, just like the 8bpp mode per spec.*/ - if (svga->hdisp <= 1024) - s3->width = 1024; + svga->rowoffset <<= 1; } } - } else { - if (s3->chip <= S3_86C924) - s3->width = 1024; } } } @@ -3334,13 +3844,15 @@ s3_recalctimings(svga_t *svga) static void s3_trio64v_recalctimings(svga_t *svga) { - const s3_t *s3 = (s3_t *) svga->priv; + s3_t *s3 = (s3_t *) svga->priv; int clk_sel = (svga->miscout >> 2) & 3; if (!svga->scrblank && svga->attr_palette_enable) { if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { - if (svga->crtc[0x3a] & 0x10) /*256+ color register*/ + if (svga->crtc[0x3a] & 0x10) { /*256+ color register*/ svga->gdcreg[5] |= 0x40; + svga->attrregs[0x10] |= 0x40; + } } } svga->hdisp = svga->hdisp_old; @@ -3364,6 +3876,30 @@ s3_trio64v_recalctimings(svga_t *svga) svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clk_sel, svga->clock_gen); + switch (svga->crtc[0x50] & 0xc1) { + case 0x00: + s3->width = (svga->crtc[0x31] & 2) ? 2048 : 1024; + break; + case 0x01: + s3->width = 1152; + break; + case 0x40: + s3->width = 640; + break; + case 0x80: + s3->width = (s3->accel.advfunc_cntl & 4) ? 1600 : 800; + break; + case 0x81: + s3->width = 1600; + break; + case 0xc0: + s3->width = 1280; + break; + + default: + break; + } + if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ { svga->ma_latch |= (s3->ma_ext << 16); @@ -3542,11 +4078,10 @@ s3_updatemapping(s3_t *s3) svga->banked_mask = 0xffff; } } else { - if (s3->chip >= S3_TRIO64V) { + if (s3->chip >= S3_TRIO64V) s3->linear_base &= 0xfc000000; - } else if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868) { + else if ((s3->chip == S3_VISION968) || (s3->chip == S3_VISION868)) s3->linear_base &= 0xfe000000; - } mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size); } @@ -3640,8 +4175,7 @@ s3_accel_out(uint16_t port, uint8_t val, void *priv) svga->fullchange = svga->monitor->mon_changeframecount; svga_recalctimings(svga); } - if (s3->chip > S3_86C924) - s3_updatemapping(s3); + s3_updatemapping(s3); break; default: @@ -3802,6 +4336,7 @@ s3_accel_in(uint16_t port, void *priv) temp |= 0x02; /*Hardware busy*/ else temp |= 0x04; /*FIFO empty*/ + s3->force_busy = 0; if (s3->chip >= S3_VISION964) { @@ -3814,9 +4349,30 @@ s3_accel_in(uint16_t port, void *priv) s3->data_available = 0; } } else { - if (s3->force_busy) { + if (s3->force_busy) temp |= 0x02; /*Hardware busy*/ + else { + switch (s3->accel.cmd >> 13) { /*Some drivers may not set FIFO on but may still turn on FIFO empty bits!*/ + case 0: + if (!s3->accel.ssv_len) + temp |= 0x04; + break; + case 1: + if (!s3->accel.sy) + temp |= 0x04; + break; + case 2: + case 6: + case 7: + if (s3->accel.sy < 0) + temp |= 0x04; + break; + + default: + break; + } } + s3->force_busy = 0; if (s3->data_available) { temp |= 0x01; /*Read Data available*/ @@ -4330,21 +4886,20 @@ s3_accel_in(uint16_t port, void *priv) case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); } else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); break; case 0x200: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(16, 1, s3->accel.pix_trans[0], 0, s3); + s3->accel_start(16, 1, s3->accel.pix_trans[0], 0, s3); else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0], s3); - } else { - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0], s3); - } + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + } else + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0], s3); break; default: @@ -4363,30 +4918,30 @@ s3_accel_in(uint16_t port, void *priv) case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); } else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); break; case 0x200: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) - s3_accel_start(16, 1, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), 0, s3); + s3->accel_start(16, 1, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), 0, s3); else - s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); + s3->accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); } else { if (s3->accel.cmd & 0x1000) - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); } } else { if (s3->accel.cmd & 0x1000) - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); } break; @@ -4413,20 +4968,20 @@ s3_accel_in(uint16_t port, void *priv) case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); } else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); break; case 0x200: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); + s3->accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); } else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); break; default: @@ -4472,28 +5027,22 @@ s3_accel_in_w(uint16_t port, void *priv) if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) temp = (temp >> 8) | (temp << 8); - s3_accel_start(8, 1, temp | (temp << 16), 0, s3); - } else { - s3_accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); - } - } else { - if (s3->color_16bit) { - s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); - } else { - s3_accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); - } - } + s3->accel_start(8, 1, temp | (temp << 16), 0, s3); + } else + s3->accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); + } else + s3->accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); break; case 0x200: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) temp = (temp >> 8) | (temp << 8); - s3_accel_start(16, 1, temp | (temp << 16), 0, s3); + s3->accel_start(16, 1, temp | (temp << 16), 0, s3); } else - s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); + s3->accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); } else { - s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); + s3->accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); } break; @@ -4530,15 +5079,15 @@ s3_accel_in_l(UNUSED(uint16_t port), void *priv) if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) temp = ((temp & 0xff00ff00) >> 8) | ((temp & 0x00ff00ff) << 8); - s3_accel_start(8, 1, temp, 0, s3); - s3_accel_start(8, 1, temp >> 16, 0, s3); + s3->accel_start(8, 1, temp, 0, s3); + s3->accel_start(8, 1, temp >> 16, 0, s3); } else { - s3_accel_start(1, 1, 0xffffffff, temp, s3); - s3_accel_start(1, 1, 0xffffffff, temp >> 16, s3); + s3->accel_start(1, 1, 0xffffffff, temp, s3); + s3->accel_start(1, 1, 0xffffffff, temp >> 16, s3); } } else { - s3_accel_start(1, 1, 0xffffffff, temp, s3); - s3_accel_start(1, 1, 0xffffffff, temp >> 16, s3); + s3->accel_start(1, 1, 0xffffffff, temp, s3); + s3->accel_start(1, 1, 0xffffffff, temp >> 16, s3); } break; case 0x200: @@ -4546,15 +5095,15 @@ s3_accel_in_l(UNUSED(uint16_t port), void *priv) if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) temp = ((temp & 0xff00ff00) >> 8) | ((temp & 0x00ff00ff) << 8); - s3_accel_start(16, 1, temp, 0, s3); - s3_accel_start(16, 1, temp >> 16, 0, s3); + s3->accel_start(16, 1, temp, 0, s3); + s3->accel_start(16, 1, temp >> 16, 0, s3); } else { - s3_accel_start(2, 1, 0xffffffff, temp, s3); - s3_accel_start(2, 1, 0xffffffff, temp >> 16, s3); + s3->accel_start(2, 1, 0xffffffff, temp, s3); + s3->accel_start(2, 1, 0xffffffff, temp >> 16, s3); } } else { - s3_accel_start(2, 1, 0xffffffff, temp, s3); - s3_accel_start(2, 1, 0xffffffff, temp >> 16, s3); + s3->accel_start(2, 1, 0xffffffff, temp, s3); + s3->accel_start(2, 1, 0xffffffff, temp >> 16, s3); } break; @@ -4701,20 +5250,20 @@ s3_accel_read(uint32_t addr, void *priv) case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, temp | (temp << 8) | (temp << 16) | (temp << 24), 0, s3); + s3->accel_start(8, 1, temp | (temp << 8) | (temp << 16) | (temp << 24), 0, s3); else - s3_accel_start(1, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); + s3->accel_start(1, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); } else - s3_accel_start(1, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); + s3->accel_start(1, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); break; case 0x200: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(16, 1, temp | (temp << 8) | (temp << 16) | (temp << 24), 0, s3); + s3->accel_start(16, 1, temp | (temp << 8) | (temp << 16) | (temp << 24), 0, s3); else - s3_accel_start(2, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); + s3->accel_start(2, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); } else - s3_accel_start(2, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); + s3->accel_start(2, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); break; default: @@ -4765,20 +5314,20 @@ s3_accel_read_w(uint32_t addr, void *priv) case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, temp | (temp << 16), 0, s3); + s3->accel_start(8, 1, temp | (temp << 16), 0, s3); else - s3_accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); + s3->accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); } else - s3_accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); + s3->accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); break; case 0x200: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(16, 1, temp | (temp << 16), 0, s3); + s3->accel_start(16, 1, temp | (temp << 16), 0, s3); else - s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); + s3->accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); } else - s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); + s3->accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); break; default: @@ -4939,29 +5488,29 @@ s3_accel_read_l(uint32_t addr, void *priv) case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - s3_accel_start(8, 1, temp, 0, s3); - s3_accel_start(8, 1, temp >> 16, 0, s3); + s3->accel_start(8, 1, temp, 0, s3); + s3->accel_start(8, 1, temp >> 16, 0, s3); } else { - s3_accel_start(1, 1, 0xffffffff, temp, s3); - s3_accel_start(1, 1, 0xffffffff, temp >> 16, s3); + s3->accel_start(1, 1, 0xffffffff, temp, s3); + s3->accel_start(1, 1, 0xffffffff, temp >> 16, s3); } } else { - s3_accel_start(1, 1, 0xffffffff, temp, s3); - s3_accel_start(1, 1, 0xffffffff, temp >> 16, s3); + s3->accel_start(1, 1, 0xffffffff, temp, s3); + s3->accel_start(1, 1, 0xffffffff, temp >> 16, s3); } break; case 0x200: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - s3_accel_start(16, 1, temp, 0, s3); - s3_accel_start(16, 1, temp >> 16, 0, s3); + s3->accel_start(16, 1, temp, 0, s3); + s3->accel_start(16, 1, temp >> 16, 0, s3); } else { - s3_accel_start(2, 1, 0xffffffff, temp, s3); - s3_accel_start(2, 1, 0xffffffff, temp >> 16, s3); + s3->accel_start(2, 1, 0xffffffff, temp, s3); + s3->accel_start(2, 1, 0xffffffff, temp >> 16, s3); } } else { - s3_accel_start(2, 1, 0xffffffff, temp, s3); - s3_accel_start(2, 1, 0xffffffff, temp >> 16, s3); + s3->accel_start(2, 1, 0xffffffff, temp, s3); + s3->accel_start(2, 1, 0xffffffff, temp >> 16, s3); } break; @@ -5016,11 +5565,13 @@ polygon_setup(s3_t *s3) #define READ(addr, dat) \ if ((s3->bpp == 0) && !s3->color_16bit) \ dat = svga->vram[dword_remap(svga, addr) & s3->vram_mask]; \ - else if ((s3->bpp == 1) || s3->color_16bit) \ + else if ((s3->bpp == 1) || (s3->color_16bit && (svga->bpp < 24))) \ dat = vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)]; \ - else if (s3->bpp == 2) \ + else if (s3->bpp == 2) \ dat = svga->vram[dword_remap(svga, addr) & s3->vram_mask]; \ - else \ + else if (s3->color_16bit && (svga->bpp == 24)) { \ + dat = vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)]; \ + } else \ dat = vram_l[dword_remap_l(svga, addr) & (s3->vram_mask >> 2)]; #define MIX_READ \ @@ -5081,7 +5632,7 @@ polygon_setup(s3_t *s3) { \ old_dest_dat = dest_dat; \ MIX_READ \ - dest_dat = (dest_dat & s3->accel.wrt_mask) | (old_dest_dat & ~s3->accel.wrt_mask); \ + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); \ } #define ROPMIX_READ(D, P, S) \ @@ -5869,12 +6420,15 @@ polygon_setup(s3_t *s3) if ((s3->bpp == 0) && !s3->color_16bit) { \ svga->vram[dword_remap(svga, addr) & s3->vram_mask] = dat; \ svga->changedvram[(dword_remap(svga, addr) & s3->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ - } else if ((s3->bpp == 1) || s3->color_16bit) { \ + } else if ((s3->bpp == 1) || (s3->color_16bit && (svga->bpp < 24))) { \ vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)] = dat; \ svga->changedvram[(dword_remap_w(svga, addr) & (s3->vram_mask >> 1)) >> 11] = svga->monitor->mon_changeframecount; \ - } else if (s3->bpp == 2) { \ + } else if (s3->bpp == 2) { \ svga->vram[dword_remap(svga, addr) & s3->vram_mask] = dat; \ svga->changedvram[(dword_remap(svga, addr) & s3->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ + } else if (s3->color_16bit && (svga->bpp == 24)) { \ + vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)] = dat; \ + svga->changedvram[(dword_remap_w(svga, addr) & (s3->vram_mask >> 1)) >> 11] = svga->monitor->mon_changeframecount; \ } else { \ vram_l[dword_remap_l(svga, addr) & (s3->vram_mask >> 2)] = dat; \ svga->changedvram[(dword_remap_l(svga, addr) & (s3->vram_mask >> 2)) >> 10] = svga->monitor->mon_changeframecount; \ @@ -6261,6 +6815,782 @@ s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3) } } +void +s3_911_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, void *priv) +{ + s3_t *s3 = (s3_t *)priv; + svga_t *svga = &s3->svga; + uint32_t src_dat = 0; + uint32_t dest_dat; + uint32_t old_dest_dat; + int frgd_mix; + int bkgd_mix; + int clip_t = s3->accel.multifunc[1] & 0xfff; + int clip_l = s3->accel.multifunc[2] & 0xfff; + int clip_b = s3->accel.multifunc[3] & 0xfff; + int clip_r = s3->accel.multifunc[4] & 0xfff; + int vram_mask = (s3->accel.multifunc[0xa] & 0xc0) == 0xc0; + uint32_t mix_mask = (s3->accel.cmd & 0x200) ? 0x8000 : 0x80; + uint16_t *vram_w = (uint16_t *) svga->vram; + uint32_t *vram_l = (uint32_t *) svga->vram; + uint32_t rd_mask = s3->accel.rd_mask; + uint32_t wrt_mask = s3->accel.wrt_mask; + uint32_t frgd_color = s3->accel.frgd_color; + uint32_t bkgd_color = s3->accel.bkgd_color; + int cmd = s3->accel.cmd >> 13; + + if ((s3->accel.cmd & 0x100) && (s3_cpu_src(s3) || (s3_cpu_dest(s3))) && (!cpu_input || (s3_enable_fifo(s3) == 0))) + s3->force_busy = 1; + + if (cpu_input && (((s3->accel.multifunc[0xa] & 0xc0) != 0x80) || (!(s3->accel.cmd & 2)))) { + if (s3->color_16bit) { + if (count > 1) + count >>= 1; + } + } + + if (s3->color_16bit) + rd_mask &= 0xffff; + else + rd_mask &= 0xff; + + /*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled. + When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on + the NOP command)*/ + + switch (cmd) { + case 0: /*NOP (Short Stroke Vectors)*/ + if (s3->accel.ssv_state == 0) + break; + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + + if (s3->accel.cmd & 8) { /*Radial*/ + while (count-- && s3->accel.ssv_len >= 0) { + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; + + default: + break; + } + + READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + + MIX + + if (s3->accel.ssv_draw) { + WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + } + } + + mix_dat <<= 1; + mix_dat |= 1; + if (s3->bpp == 0) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + + if (!s3->accel.ssv_len) + break; + + switch (s3->accel.ssv_dir & 0xe0) { + case 0x00: + s3->accel.cx++; + break; + case 0x20: + s3->accel.cx++; + s3->accel.cy--; + break; + case 0x40: + s3->accel.cy--; + break; + case 0x60: + s3->accel.cx--; + s3->accel.cy--; + break; + case 0x80: + s3->accel.cx--; + break; + case 0xa0: + s3->accel.cx--; + s3->accel.cy++; + break; + case 0xc0: + s3->accel.cy++; + break; + case 0xe0: + s3->accel.cx++; + s3->accel.cy++; + break; + + default: + break; + } + + s3->accel.ssv_len--; + s3->accel.cx &= 0xfff; + s3->accel.cy &= 0xfff; + } + + s3->accel.cur_x = s3->accel.cx; + s3->accel.cur_y = s3->accel.cy; + } + break; + + case 1: /*Draw line*/ + if (!cpu_input) { + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; + s3->accel.sy = s3->accel.maj_axis_pcnt & 0x7ff; + + if (s3->color_16bit && (svga->bpp < 24)) { + if (s3->accel.wrt_mask != 0xffff) { + if (s3->accel.cur_x & 0x400) { + s3->accel.color_16bit_check = 0; + s3->accel.minus = 0x400; + } else { + s3->accel.color_16bit_check = 1; + s3->accel.minus = 0; + } + } else { + if (s3->accel.cur_x & 0x400) + s3->accel.color_16bit_check = 1; + else + s3->accel.color_16bit_check = 0; + + s3->accel.minus = 0; + } + } else { + s3->accel.color_16bit_check = 0; + s3->accel.minus = 0; + } + + if (s3_cpu_src(s3)) + return; /*Wait for data from CPU*/ + } + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + + if (s3->accel.cmd & 8) { /*Radial*/ + if (s3->color_16bit && (svga->bpp < 24)) { + if (s3->accel.color_16bit_check) + return; + if (s3->accel.wrt_mask != 0xffff) + wrt_mask = (s3->accel.wrt_mask_actual[0] | (s3->accel.wrt_mask_actual[1] << 8)); + } + + while (count-- && s3->accel.sy >= 0) { + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + if (s3->color_16bit && (svga->bpp < 24)) + src_dat = s3->accel.bkgd_color_actual[0] | (s3->accel.bkgd_color_actual[1] << 8); + break; + case 1: + src_dat = frgd_color; + if (s3->color_16bit && (svga->bpp < 24)) + src_dat = s3->accel.frgd_color_actual[0] | (s3->accel.frgd_color_actual[1] << 8); + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; + + default: + break; + } + + READ((s3->accel.cy * s3->width) + s3->accel.cx - s3->accel.minus, dest_dat); + + MIX + + WRITE((s3->accel.cy * s3->width) + s3->accel.cx - s3->accel.minus, dest_dat); + } + + mix_dat <<= 1; + mix_dat |= 1; + if ((s3->bpp == 0) && !s3->color_16bit) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + + if (!s3->accel.sy) + break; + + switch (s3->accel.cmd & 0xe0) { + case 0x00: + s3->accel.cx++; + break; + case 0x20: + s3->accel.cx++; + s3->accel.cy--; + break; + case 0x40: + s3->accel.cy--; + break; + case 0x60: + s3->accel.cx--; + s3->accel.cy--; + break; + case 0x80: + s3->accel.cx--; + break; + case 0xa0: + s3->accel.cx--; + s3->accel.cy++; + break; + case 0xc0: + s3->accel.cy++; + break; + case 0xe0: + s3->accel.cx++; + s3->accel.cy++; + break; + + default: + break; + } + s3->accel.sy--; + s3->accel.cx &= 0xfff; + s3->accel.cy &= 0xfff; + } + s3->accel.cur_x = s3->accel.cx; + s3->accel.cur_y = s3->accel.cy; + } else { /*Bresenham*/ + if (s3->accel.b2e8_pix && s3_cpu_src(s3) && (count == 16)) { /*Stupid undocumented 0xB2E8 on 911/924*/ + count = s3->accel.maj_axis_pcnt + 1; + s3->accel.temp_cnt = 16; + } + + if (s3->color_16bit && (svga->bpp < 24)) { + if (!s3->accel.b2e8_pix) { + if (!s3->accel.color_16bit_check) + wrt_mask = (s3->accel.wrt_mask_actual[0] | (s3->accel.wrt_mask_actual[1] << 8)); + else + return; + } + } + + //pclog("CMD=%04x, curx=%d, lwrtmask=%04x, actual wrtmask=%04x, frgdmix=%d, bkgdmix=%d, input=%d, cnt=%d.\n", s3->accel.cmd, s3->accel.cur_x, wrt_mask, s3->accel.wrt_mask, frgd_mix, bkgd_mix, cpu_input, count); + while (count-- && s3->accel.sy >= 0) { + if (s3->accel.b2e8_pix && s3_cpu_src(s3) && !s3->accel.temp_cnt) { + mix_dat >>= 16; + s3->accel.temp_cnt = 16; + } + + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + if (s3->color_16bit && (svga->bpp < 24) && !s3->accel.b2e8_pix) { + if (!s3->accel.color_16bit_check) + src_dat = s3->accel.bkgd_color_actual[0] | (s3->accel.bkgd_color_actual[1] << 8); + } + break; + case 1: + src_dat = frgd_color; + if (s3->color_16bit && (svga->bpp < 24) && !s3->accel.b2e8_pix) { + if (!s3->accel.color_16bit_check) + src_dat = s3->accel.frgd_color_actual[0] | (s3->accel.frgd_color_actual[1] << 8); + } + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; + + default: + break; + } + + READ((s3->accel.cy * s3->width) + s3->accel.cx - s3->accel.minus, dest_dat); + + MIX + + if (s3->accel.cmd & 0x10) { + WRITE((s3->accel.cy * s3->width) + s3->accel.cx - s3->accel.minus, dest_dat); + } + } + + if (s3->accel.b2e8_pix && s3_cpu_src(s3)) { + if (s3->accel.temp_cnt > 0) { + s3->accel.temp_cnt--; + mix_dat <<= 1; + mix_dat |= 1; + } + } else { + mix_dat <<= 1; + mix_dat |= 1; + } + + if (s3->color_16bit) + cpu_dat >>= 16; + else + cpu_dat >>= 8; + + if (!s3->accel.sy) + break; + + if (s3->accel.err_term >= s3->accel.maj_axis_pcnt) { + s3->accel.err_term += s3->accel.destx_distp; + /*Step minor axis*/ + switch (s3->accel.cmd & 0xe0) { + case 0x00: + s3->accel.cy--; + break; + case 0x20: + s3->accel.cy--; + break; + case 0x40: + s3->accel.cx--; + break; + case 0x60: + s3->accel.cx++; + break; + case 0x80: + s3->accel.cy++; + break; + case 0xa0: + s3->accel.cy++; + break; + case 0xc0: + s3->accel.cx--; + break; + case 0xe0: + s3->accel.cx++; + break; + + default: + break; + } + } else + s3->accel.err_term += s3->accel.desty_axstp; + + /*Step major axis*/ + switch (s3->accel.cmd & 0xe0) { + case 0x00: + s3->accel.cx--; + break; + case 0x20: + s3->accel.cx++; + break; + case 0x40: + s3->accel.cy--; + break; + case 0x60: + s3->accel.cy--; + break; + case 0x80: + s3->accel.cx--; + break; + case 0xa0: + s3->accel.cx++; + break; + case 0xc0: + s3->accel.cy++; + break; + case 0xe0: + s3->accel.cy++; + break; + + default: + break; + } + s3->accel.sy--; + s3->accel.cx &= 0xfff; + s3->accel.cy &= 0xfff; + } + s3->accel.cur_x = s3->accel.cx; + s3->accel.cur_y = s3->accel.cy; + } + break; + + case 2: /*Rectangle fill*/ + if (!cpu_input) { /*!cpu_input is trigger to start operation*/ + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + s3->accel.sy = s3->accel.multifunc[0] & 0xfff; + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; + s3->accel.pix_trans_x_count = 0; + + s3->accel.dest = s3->accel.cy * s3->width; + + if (s3->color_16bit && (svga->bpp < 24)) { + if (s3->accel.cur_x & 0x400) { + s3->accel.color_16bit_check = 0; + s3->accel.minus = 0x400; + } else { + s3->accel.color_16bit_check = 1; + s3->accel.minus = 0; + } + + if (s3->accel.color_16bit_check) { + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x00) && !(s3->accel.cmd & 2)) + s3->accel.color_16bit_check_rectfill = !!s3_cpu_src(s3); + else + s3->accel.color_16bit_check_rectfill = 0; + } + + if (s3->accel.color_16bit_check_rectfill) { + if (s3->accel.color_16bit_check) { + s3->accel.pix_trans_ptr = (uint8_t *) calloc(1, (s3->accel.sx + 1) << 1); + s3->accel.pix_trans_ptr_cnt = (s3->accel.sx + 1) << 1; + } + } else + s3->accel.pix_trans_x_count = 0; + } else { + s3->accel.pix_trans_x_count = 0; + s3->accel.color_16bit_check = 0; + s3->accel.color_16bit_check_rectfill = 0; + s3->accel.minus = 0; + } + + if (s3_cpu_src(s3)) { + s3->data_available = 0; + return; /*Wait for data from CPU*/ + } else if (s3_cpu_dest(s3)) { + s3->data_available = 1; + return; + } + } + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + + if (s3->accel.b2e8_pix && s3_cpu_src(s3) && count == 16) { /*Stupid undocumented 0xB2E8 on 911/924*/ + count = s3->accel.maj_axis_pcnt + 1; + s3->accel.temp_cnt = 16; + } + + if (s3->color_16bit && (svga->bpp < 24)) { + if (!s3->accel.b2e8_pix) { + if (!s3->accel.color_16bit_check) { + wrt_mask = (s3->accel.wrt_mask_actual[0] | (s3->accel.wrt_mask_actual[1] << 8)); + } else if (s3->accel.color_16bit_check && (s3->accel.cmd == 0x40f3)) + return; + } + } + + while (count-- && s3->accel.sy >= 0) { + if (s3->accel.b2e8_pix && s3_cpu_src(s3) && !s3->accel.temp_cnt) { + mix_dat >>= 16; + s3->accel.temp_cnt = 16; + } + + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { + if (s3_cpu_dest(s3) && ((s3->accel.multifunc[0xa] & 0xc0) == 0x00)) { + mix_dat = mix_mask; /* Mix data = forced to foreground register. */ + } else if (s3_cpu_dest(s3) && vram_mask) { + /* Mix data = current video memory value. */ + READ(s3->accel.dest + s3->accel.cx - s3->accel.minus, mix_dat); + mix_dat = ((mix_dat & rd_mask) == rd_mask); + mix_dat = mix_dat ? mix_mask : 0; + } + + if (s3_cpu_dest(s3)) { + READ(s3->accel.dest + s3->accel.cx - s3->accel.minus, src_dat); + if (vram_mask) + src_dat = ((src_dat & rd_mask) == rd_mask); + } else { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + if (s3->color_16bit && (svga->bpp < 24) && !s3->accel.b2e8_pix && (s3->accel.cmd != 0x41b3)) { + if (!s3->accel.color_16bit_check) + src_dat = s3->accel.bkgd_color_actual[0] | (s3->accel.bkgd_color_actual[1] << 8); + } + break; + case 1: + src_dat = frgd_color; + if (s3->color_16bit && (svga->bpp < 24) && !s3->accel.b2e8_pix && (s3->accel.cmd != 0x41b3)) { + if (!s3->accel.color_16bit_check) + src_dat = s3->accel.frgd_color_actual[0] | (s3->accel.frgd_color_actual[1] << 8); + } + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; + + default: + break; + } + } + + READ(s3->accel.dest + s3->accel.cx - s3->accel.minus, dest_dat); + + if (s3->accel.cmd == 0x41b1 || s3->accel.cmd == 0x41b0) { + uint16_t dest_dat2; + READ(s3->accel.dest + s3->accel.cx, dest_dat2); + //pclog("CMD=%04x, initialdest=%04x, c(%d,%d), cpu=%04x, minus=%d, len=%d.\n", s3->accel.cmd, dest_dat2, s3->accel.cx - s3->accel.minus, s3->accel.cy, cpu_dat & 0xffff, s3->accel.minus, s3->accel.maj_axis_pcnt); + } + + MIX + + if (s3->accel.cmd & 0x10) { + WRITE(s3->accel.dest + s3->accel.cx - s3->accel.minus, dest_dat); + } + } + + if (s3->accel.b2e8_pix && s3_cpu_src(s3)) { + if (s3->accel.temp_cnt > 0) { + s3->accel.temp_cnt--; + mix_dat <<= 1; + mix_dat |= 1; + } + } else { + mix_dat <<= 1; + mix_dat |= 1; + } + + if (s3->color_16bit) + cpu_dat >>= 16; + else + cpu_dat >>= 8; + + if (s3->accel.cmd & 0x20) + s3->accel.cx++; + else + s3->accel.cx--; + + s3->accel.cx &= 0xfff; + s3->accel.sx--; + if (s3->accel.sx < 0) { + if (s3->accel.cmd & 0x20) + s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + else + s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; + + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + if (s3->accel.cmd & 0x80) + s3->accel.cy++; + else + s3->accel.cy--; + + s3->accel.cy &= 0xfff; + s3->accel.dest = s3->accel.cy * s3->width; + s3->accel.sy--; + + if (cpu_input) { + if (s3->accel.b2e8_pix) { + s3->accel.cur_x = s3->accel.cx; + s3->accel.cur_y = s3->accel.cy; + } + return; + } + if (s3->accel.sy < 0) { + s3->accel.cur_x = s3->accel.cx; + s3->accel.cur_y = s3->accel.cy; + return; + } + } + } + break; + + case 6: /*BitBlt*/ + if (!cpu_input) { /*!cpu_input is trigger to start operation*/ + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + s3->accel.sy = s3->accel.multifunc[0] & 0xfff; + + s3->accel.dx = s3->accel.destx_distp & 0xfff; + s3->accel.dy = s3->accel.desty_axstp & 0xfff; + + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; + + s3->accel.src = s3->accel.cy * s3->width; + s3->accel.dest = s3->accel.dy * s3->width; + + if (s3->color_16bit && (svga->bpp < 24)) { + if (s3->accel.destx_distp & 0x400) { + s3->accel.color_16bit_check = 0; + s3->accel.minus = 0x400; + } else { + s3->accel.color_16bit_check = 1; + s3->accel.minus = 0; + } + s3->accel.srcminus = 0x400; + } else { + s3->accel.color_16bit_check = 0; + s3->accel.minus = 0; + s3->accel.srcminus = 0; + } + } + + if ((s3->accel.cmd & 0x100) && !cpu_input) { + return; /*Wait for data from CPU*/ + } + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + + if (s3->color_16bit && (svga->bpp < 24)) { + if (!s3->accel.color_16bit_check) + wrt_mask = (s3->accel.wrt_mask_actual[0] | (s3->accel.wrt_mask_actual[1] << 8)); + else + return; + } + + if (!cpu_input && (frgd_mix == 3) && !vram_mask && ((s3->accel.cmd & 0xa0) == 0xa0) && ((s3->accel.frgd_mix & 0xf) == 7) && ((s3->accel.bkgd_mix & 0xf) == 7)) { + while (1) { + 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) { + READ(s3->accel.src + s3->accel.cx - s3->accel.srcminus, src_dat); + READ(s3->accel.dest + s3->accel.dx - s3->accel.minus, dest_dat); + + dest_dat = (src_dat & wrt_mask) | (dest_dat & ~wrt_mask); + + WRITE(s3->accel.dest + s3->accel.dx - s3->accel.minus, dest_dat); + } + + s3->accel.cx++; + s3->accel.dx++; + s3->accel.sx--; + s3->accel.dx &= 0xfff; + if (s3->accel.sx < 0) { + s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + + s3->accel.cy++; + s3->accel.dy++; + + s3->accel.dy &= 0xfff; + s3->accel.src = s3->accel.cy * s3->width; + s3->accel.dest = s3->accel.dy * s3->width; + + s3->accel.sy--; + + if (s3->accel.sy < 0) { /*It's evident that this is a clear undocumented difference compared to later chips, per what NT 3.5+ does to DX/DY.*/ + s3->accel.destx_distp = s3->accel.dx; + s3->accel.desty_axstp = s3->accel.dy; + return; + } + } + } + } else { + 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 (vram_mask && (s3->accel.cmd & 0x10)) { + READ(s3->accel.src + s3->accel.cx - s3->accel.srcminus, mix_dat); + mix_dat = ((mix_dat & rd_mask) == rd_mask); + mix_dat = mix_dat ? mix_mask : 0; + } + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + if (s3->color_16bit && (svga->bpp < 24)) { + if (!s3->accel.color_16bit_check) + src_dat = s3->accel.bkgd_color_actual[0] | (s3->accel.bkgd_color_actual[1] << 8); + } + break; + case 1: + src_dat = frgd_color; + if (s3->color_16bit && (svga->bpp < 24)) { + if (!s3->accel.color_16bit_check) + src_dat = s3->accel.frgd_color_actual[0] | (s3->accel.frgd_color_actual[1] << 8); + } + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + READ(s3->accel.src + s3->accel.cx - s3->accel.srcminus, src_dat); + if (vram_mask && (s3->accel.cmd & 0x10)) + src_dat = ((src_dat & rd_mask) == rd_mask); + break; + + default: + break; + } + + READ(s3->accel.dest + s3->accel.dx - s3->accel.minus, dest_dat); + + MIX + + if ((!(s3->accel.cmd & 0x10) && vram_mask) || (s3->accel.cmd & 0x10)) { + WRITE(s3->accel.dest + s3->accel.dx - s3->accel.minus, dest_dat); + } + } + + mix_dat <<= 1; + mix_dat |= 1; + + if (s3->color_16bit) + cpu_dat >>= 16; + else + cpu_dat >>= 8; + + if (s3->accel.cmd & 0x20) { + s3->accel.cx++; + s3->accel.dx++; + } else { + s3->accel.cx--; + s3->accel.dx--; + } + s3->accel.dx &= 0xfff; + s3->accel.sx--; + if (s3->accel.sx < 0) { + if (s3->accel.cmd & 0x20) { + s3->accel.cx -= ((s3->accel.maj_axis_pcnt & 0xfff) + 1); + s3->accel.dx -= ((s3->accel.maj_axis_pcnt & 0xfff) + 1); + } else { + s3->accel.cx += ((s3->accel.maj_axis_pcnt & 0xfff) + 1); + s3->accel.dx += ((s3->accel.maj_axis_pcnt & 0xfff) + 1); + } + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + + if (s3->accel.cmd & 0x80) { + s3->accel.cy++; + s3->accel.dy++; + } else { + s3->accel.cy--; + s3->accel.dy--; + } + s3->accel.dy &= 0xfff; + s3->accel.src = s3->accel.cy * s3->width; + s3->accel.dest = s3->accel.dy * s3->width; + + s3->accel.sy--; + + if (cpu_input) + return; + + if (s3->accel.sy < 0) { /*It's evident that this is a clear undocumented difference compared to later chips, per what NT 3.5+ does to DX/DY.*/ + s3->accel.destx_distp = s3->accel.dx; + s3->accel.desty_axstp = s3->accel.dy; + return; + } + } + } + } + break; + + default: + break; + } +} + void s3_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3, uint8_t ssv) { @@ -6274,12 +7604,13 @@ s3_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_d } } - s3_accel_start(count, cpu_input, mix_dat, cpu_dat, s3); + s3->accel_start(count, cpu_input, mix_dat, cpu_dat, s3); } void -s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3) +s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, void *priv) { + s3_t *s3 = (s3_t *)priv; svga_t *svga = &s3->svga; uint32_t src_dat = 0; uint32_t dest_dat; @@ -6294,16 +7625,23 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ int clip_r = s3->accel.multifunc[4] & 0xfff; int vram_mask = (s3->accel.multifunc[0xa] & 0xc0) == 0xc0; uint32_t mix_mask = 0; + uint8_t *vram = (uint8_t *) svga->vram; uint16_t *vram_w = (uint16_t *) svga->vram; uint32_t *vram_l = (uint32_t *) svga->vram; uint32_t compare = s3->accel.color_cmp; uint8_t rop = s3->accel.ropmix & 0xff; int compare_mode = (s3->accel.multifunc[0xe] >> 7) & 3; uint32_t rd_mask = s3->accel.rd_mask; + uint32_t wrt_mask = s3->accel.wrt_mask; + uint32_t frgd_color = s3->accel.frgd_color; + uint32_t bkgd_color = s3->accel.bkgd_color; int cmd = s3->accel.cmd >> 13; uint32_t srcbase; uint32_t dstbase; + s3->accel.srcminus = 0; + s3->accel.minus = 0; + if ((s3->chip >= S3_TRIO64 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) && (s3->accel.cmd & (1 << 11))) cmd |= 8; @@ -6318,7 +7656,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ else dstbase = 0x100000 * ((s3->accel.multifunc[0xe] >> 0) & 3); - if (s3->bpp == 1) { + if ((s3->bpp == 1) || s3->color_16bit) { srcbase >>= 1; dstbase >>= 1; } else if (s3->bpp == 3) { @@ -6354,9 +7692,9 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ else if ((s3->bpp == 1) || s3->color_16bit) rd_mask &= 0xffff; - if ((s3->bpp == 0) && !s3->color_16bit) + if (s3->bpp == 0) compare &= 0xff; - else if ((s3->bpp == 1) || s3->color_16bit) + else if (s3->bpp == 1) compare &= 0xffff; switch (s3->accel.cmd & 0x600) { @@ -6394,10 +7732,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: - src_dat = s3->accel.bkgd_color; + src_dat = bkgd_color; break; case 1: - src_dat = s3->accel.frgd_color; + src_dat = frgd_color; break; case 2: src_dat = cpu_dat; @@ -6423,7 +7761,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ mix_dat <<= 1; mix_dat |= 1; - if (s3->bpp == 0) + if (s3->bpp == 0 && !s3->color_16bit) cpu_dat >>= 8; else cpu_dat >>= 16; @@ -6487,16 +7825,15 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ frgd_mix = (s3->accel.frgd_mix >> 5) & 3; bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - if (s3->accel.cmd & 8) /*Radial*/ - { + if (s3->accel.cmd & 8) { /*Radial*/ while (count-- && s3->accel.sy >= 0) { if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: - src_dat = s3->accel.bkgd_color; + src_dat = bkgd_color; break; case 1: - src_dat = s3->accel.frgd_color; + src_dat = frgd_color; break; case 2: src_dat = cpu_dat; @@ -6567,8 +7904,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ } s3->accel.cur_x = s3->accel.cx; s3->accel.cur_y = s3->accel.cy; - } else /*Bresenham*/ - { + } else { /*Bresenham*/ if (s3->accel.b2e8_pix && s3_cpu_src(s3) && (count == 16)) { /*Stupid undocumented 0xB2E8 on 911/924*/ count = s3->accel.maj_axis_pcnt + 1; s3->accel.temp_cnt = 16; @@ -6583,10 +7919,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: - src_dat = s3->accel.bkgd_color; + src_dat = bkgd_color; break; case 1: - src_dat = s3->accel.frgd_color; + src_dat = frgd_color; break; case 2: src_dat = cpu_dat; @@ -6618,11 +7954,11 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ mix_dat <<= 1; mix_dat |= 1; } + if (s3->bpp == 0 && !s3->color_16bit) cpu_dat >>= 8; - else { + else cpu_dat >>= 16; - } if (!s3->accel.sy) break; @@ -6659,9 +7995,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ default: break; } - } else { + } else s3->accel.err_term += s3->accel.desty_axstp; - } /*Step major axis*/ switch (s3->accel.cmd & 0xe0) { @@ -6749,13 +8084,13 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ READ(s3->accel.dest + s3->accel.cx, src_dat); if (vram_mask) src_dat = ((src_dat & rd_mask) == rd_mask); - } else + } else { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: - src_dat = s3->accel.bkgd_color; + src_dat = bkgd_color; break; case 1: - src_dat = s3->accel.frgd_color; + src_dat = frgd_color; break; case 2: src_dat = cpu_dat; @@ -6767,6 +8102,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ default: break; } + } if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { READ(s3->accel.dest + s3->accel.cx, dest_dat); @@ -6790,11 +8126,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ mix_dat |= 1; } - if ((s3->bpp == 0) && !s3->color_16bit) + if (s3->bpp == 0 && !s3->color_16bit) cpu_dat >>= 8; - else { + else cpu_dat >>= 16; - } if (s3->accel.cmd & 0x20) s3->accel.cx++; @@ -6808,8 +8143,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; else s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; if (s3->accel.cmd & 0x80) s3->accel.cy++; else @@ -6919,17 +8254,12 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ break; case 6: /*BitBlt*/ - if (!cpu_input) /*!cpu_input is trigger to start operation*/ - { + if (!cpu_input) { /*!cpu_input is trigger to start operation*/ s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - s3->accel.dx = s3->accel.destx_distp & 0x7ff; - if (s3->accel.destx_distp & 0x800) - s3->accel.dx |= ~0x7ff; - s3->accel.dy = s3->accel.desty_axstp & 0x7ff; - if (s3->accel.desty_axstp & 0x800) - s3->accel.dy |= ~0x7ff; + s3->accel.dx = s3->accel.destx_distp & 0xfff; + s3->accel.dy = s3->accel.desty_axstp & 0xfff; s3->accel.cx = s3->accel.cur_x & 0xfff; s3->accel.cy = s3->accel.cur_y & 0xfff; @@ -6951,16 +8281,15 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ READ(s3->accel.src + s3->accel.cx, src_dat); READ(s3->accel.dest + s3->accel.dx, dest_dat); - dest_dat = (src_dat & s3->accel.wrt_mask) | (dest_dat & ~s3->accel.wrt_mask); + dest_dat = (src_dat & wrt_mask) | (dest_dat & ~wrt_mask); - if (s3->accel.cmd & 0x10) { - WRITE(s3->accel.dest + s3->accel.dx, dest_dat); - } + WRITE(s3->accel.dest + s3->accel.dx, dest_dat); } s3->accel.cx++; s3->accel.dx++; s3->accel.sx--; + s3->accel.dx &= 0xfff; if (s3->accel.sx < 0) { s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; @@ -6969,12 +8298,15 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cy++; s3->accel.dy++; + s3->accel.dy &= 0xfff; s3->accel.src = srcbase + s3->accel.cy * s3->width; s3->accel.dest = dstbase + s3->accel.dy * s3->width; s3->accel.sy--; if (s3->accel.sy < 0) { + s3->accel.destx_distp = s3->accel.dx; + s3->accel.desty_axstp = s3->accel.dy; return; } } @@ -6989,10 +8321,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ } switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: - src_dat = s3->accel.bkgd_color; + src_dat = bkgd_color; break; case 1: - src_dat = s3->accel.frgd_color; + src_dat = frgd_color; break; case 2: src_dat = cpu_dat; @@ -7008,7 +8340,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ } if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { - READ(s3->accel.dest + s3->accel.dx, dest_dat); MIX @@ -7024,9 +8355,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (s3->bpp == 0 && !s3->color_16bit) cpu_dat >>= 8; - else { + else cpu_dat >>= 16; - } if (s3->accel.cmd & 0x20) { s3->accel.cx++; @@ -7035,6 +8365,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cx--; s3->accel.dx--; } + s3->accel.dx &= 0xfff; s3->accel.sx--; if (s3->accel.sx < 0) { if (s3->accel.cmd & 0x20) { @@ -7053,16 +8384,18 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cy--; s3->accel.dy--; } + s3->accel.dy &= 0xfff; s3->accel.src = srcbase + s3->accel.cy * s3->width; s3->accel.dest = dstbase + s3->accel.dy * s3->width; s3->accel.sy--; - if (cpu_input) { + if (cpu_input) return; - } if (s3->accel.sy < 0) { + s3->accel.destx_distp = s3->accel.dx; + s3->accel.desty_axstp = s3->accel.dy; return; } } @@ -7077,11 +8410,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ 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; @@ -7143,7 +8472,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ mix_dat <<= 1; mix_dat |= 1; - if (s3->bpp == 0) + if (s3->bpp == 0 && !s3->color_16bit) cpu_dat >>= 8; else cpu_dat >>= 16; @@ -7155,6 +8484,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cx = ((s3->accel.cx - 1) & 7) | (s3->accel.cx & ~7); s3->accel.dx--; } + s3->accel.dx &= 0xfff; s3->accel.sx--; if (s3->accel.sx < 0) { if (s3->accel.cmd & 0x20) { @@ -7174,6 +8504,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.dy--; } + s3->accel.dy &= 0xfff; s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width); s3->accel.dest = dstbase + s3->accel.dy * s3->width; @@ -7183,6 +8514,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ return; } if (s3->accel.sy < 0) { + s3->accel.destx_distp = s3->accel.dx; + s3->accel.desty_axstp = s3->accel.dy; return; } } @@ -7564,6 +8897,7 @@ s3_pci_read(UNUSED(int func), int addr, void *priv) return s3->pci_regs[PCI_REG_COMMAND] | 0x80; /*Respond to IO and memory accesses*/ else return s3->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ + break; case 0x07: return (s3->chip == S3_TRIO64V2) ? (s3->pci_regs[0x07] & 0x36) : (1 << 1); /*Medium DEVSEL timing*/ @@ -7575,7 +8909,8 @@ s3_pci_read(UNUSED(int func), int addr, void *priv) return 0x16; /*Confirmed on an onboard 64V2/DX*/ default: return 0x00; - } + } + break; case 0x09: return 0; /*Programming interface*/ @@ -7602,6 +8937,7 @@ s3_pci_read(UNUSED(int func), int addr, void *priv) return 0x00; else return (svga->crtc[0x5a] & 0x80); + break; case 0x13: if (svga->crtc[0x53] & 0x08) { @@ -7609,6 +8945,7 @@ s3_pci_read(UNUSED(int func), int addr, void *priv) } else { return svga->crtc[0x59]; } + break; case 0x30: return s3->has_bios ? (s3->pci_regs[0x30] & 0x01) : 0x00; /*BIOS ROM address*/ @@ -7826,6 +9163,11 @@ s3_reset(void *priv) s3->pci_regs[0x32] = 0x0c; s3->pci_regs[0x33] = 0x00; + if (s3->chip <= S3_86C924) + s3->accel_start = s3_911_accel_start; + else + s3->accel_start = s3_accel_start; + switch (s3->card_type) { case S3_MIROCRYSTAL8S_805: case S3_MIROCRYSTAL10SD_805: @@ -7901,9 +9243,7 @@ s3_reset(void *priv) case S3_DIAMOND_STEALTH64_764: case S3_SPEA_MIRAGE_P64: case S3_NUMBER9_9FX: - if ((s3->card_type == S3_CARDEX_TRIO64VPLUS) || - (s3->card_type == S3_PHOENIX_TRIO64VPLUS) || - (s3->card_type == S3_PHOENIX_TRIO64VPLUS_ONBOARD)) + if (s3->chip == S3_TRIO64V) svga->crtc[0x53] = 0x08; break; @@ -8251,12 +9591,34 @@ s3_init(const device_t *info) svga->hwcursor.cur_ysize = 64; - if (chip == S3_VISION964 && info->local != S3_ELSAWIN2KPROX_964) - svga->dac_hwcursor_draw = bt48x_hwcursor_draw; - else if ((chip == S3_VISION964 && info->local == S3_ELSAWIN2KPROX_964) || (chip == S3_VISION968 && (info->local == S3_ELSAWIN2KPROX || info->local == S3_PHOENIX_VISION968 || info->local == S3_NUMBER9_9FX_771))) - svga->dac_hwcursor_draw = ibm_rgb528_hwcursor_draw; - else if (chip == S3_VISION968 && (info->local == S3_SPEA_MERCURY_P64V || info->local == S3_MIROVIDEO40SV_ERGO_968)) - svga->dac_hwcursor_draw = tvp3026_hwcursor_draw; + switch (chip) { + case S3_VISION964: + switch (info->local) { + case S3_ELSAWIN2KPROX_964: + svga->dac_hwcursor_draw = ibm_rgb528_hwcursor_draw; + break; + default: + svga->dac_hwcursor_draw = bt48x_hwcursor_draw; + break; + } + break; + + case S3_VISION968: + switch (info->local) { + case S3_ELSAWIN2KPROX: + case S3_PHOENIX_VISION968: + case S3_NUMBER9_9FX_771: + svga->dac_hwcursor_draw = ibm_rgb528_hwcursor_draw; + break; + case S3_SPEA_MERCURY_P64V: + case S3_MIROVIDEO40SV_ERGO_968: + svga->dac_hwcursor_draw = tvp3026_hwcursor_draw; + break; + default: + break; + } + break; + } if (chip >= S3_VISION964) { switch (vram) { @@ -8326,6 +9688,11 @@ s3_init(const device_t *info) svga->force_old_addr = 1; + if (s3->chip <= S3_86C924) + s3->accel_start = s3_911_accel_start; + else + s3->accel_start = s3_accel_start; + switch (s3->card_type) { case S3_ORCHID_86C911: case S3_DIAMOND_STEALTH_VRAM: @@ -8351,7 +9718,7 @@ s3_init(const device_t *info) s3->packed_mmio = 0; s3->width = 1024; - svga->ramdac = device_add(&sc11487_ramdac_device); + svga->ramdac = device_add(&att490_ramdac_device); svga->clock_gen = device_add(&ics2494an_305_device); svga->getclock = ics2494_getclock; break; @@ -8417,7 +9784,7 @@ s3_init(const device_t *info) case S3_METHEUS_86C928: svga->decode_mask = (4 << 20) - 1; - stepping = 0x91; /*86C928*/ + stepping = 0x91; /*86C928D*/ s3->id = stepping; s3->id_ext = stepping; s3->id_ext_pci = 0; @@ -8445,7 +9812,7 @@ s3_init(const device_t *info) case S3_PHOENIX_VISION864: case S3_MIROCRYSTAL20SD_864: /*BIOS 3.xx has a SDAC ramdac.*/ svga->decode_mask = (8 << 20) - 1; - if (info->local == S3_PARADISE_BAHAMAS64 || info->local == S3_MIROCRYSTAL20SD_864) + if (info->local == S3_PARADISE_BAHAMAS64) stepping = 0xc0; /*Vision864*/ else stepping = 0xc1; /*Vision864P*/ @@ -8468,13 +9835,18 @@ s3_init(const device_t *info) s3->packed_mmio = 1; svga->crtc[0x5a] = 0x0a; - if (info->local == S3_ELSAWIN2KPROX_964) - svga->ramdac = device_add(&ibm_rgb528_ramdac_device); - else - svga->ramdac = device_add(&bt485_ramdac_device); - - svga->clock_gen = device_add(&icd2061_device); - svga->getclock = icd2061_getclock; + switch (info->local) { + case S3_ELSAWIN2KPROX_964: + svga->ramdac = device_add(&ibm_rgb528_ramdac_device); + svga->clock_gen = device_add(&icd2061_device); + svga->getclock = icd2061_getclock; + break; + default: + svga->ramdac = device_add(&bt485_ramdac_device); + svga->clock_gen = device_add(&icd2061_device); + svga->getclock = icd2061_getclock; + break; + } break; case S3_ELSAWIN2KPROX: @@ -8498,15 +9870,20 @@ s3_init(const device_t *info) svga->crtc[0x5a] = 0x0a; } - if (info->local == S3_ELSAWIN2KPROX || info->local == S3_PHOENIX_VISION968 || info->local == S3_NUMBER9_9FX_771) { - svga->ramdac = device_add(&ibm_rgb528_ramdac_device); - svga->clock_gen = device_add(&icd2061_device); - svga->getclock = icd2061_getclock; - } else { - svga->ramdac = device_add(&tvp3026_ramdac_device); - svga->clock_gen = svga->ramdac; - svga->getclock = tvp3026_getclock; - svga->conv_16to32 = tvp3026_conv_16to32; + switch (info->local) { + case S3_ELSAWIN2KPROX: + case S3_PHOENIX_VISION968: + case S3_NUMBER9_9FX_771: + svga->ramdac = device_add(&ibm_rgb528_ramdac_device); + svga->clock_gen = device_add(&icd2061_device); + svga->getclock = icd2061_getclock; + break; + default: + svga->ramdac = device_add(&tvp3026_ramdac_device); + svga->clock_gen = svga->ramdac; + svga->getclock = tvp3026_getclock; + svga->conv_16to32 = tvp3026_conv_16to32; + break; } break; @@ -8569,9 +9946,8 @@ s3_init(const device_t *info) s3->id_ext = s3->id_ext_pci = 0x11; s3->packed_mmio = 1; - if (info->local == S3_PHOENIX_TRIO64VPLUS || info->local == S3_PHOENIX_TRIO64VPLUS_ONBOARD) { + if (s3->chip == S3_TRIO64V) svga->crtc[0x53] = 0x08; - } svga->clock_gen = s3; svga->getclock = s3_trio64_getclock; @@ -9112,7 +10488,7 @@ const device_t s3_spea_mercury_lite_86c928_pci_device = { { .available = s3_spea_mercury_lite_pci_available }, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, - .config = s3_standard_config + .config = s3_orchid_86c911_config }; const device_t s3_mirocrystal_20sd_864_vlb_device = { diff --git a/src/video/vid_sc1502x_ramdac.c b/src/video/vid_sc1502x_ramdac.c index 7cbcaf05d..7315c65ad 100644 --- a/src/video/vid_sc1502x_ramdac.c +++ b/src/video/vid_sc1502x_ramdac.c @@ -34,84 +34,126 @@ typedef struct sc1502x_ramdac_t { int state; uint8_t ctrl; + uint8_t idx; + uint8_t regs[256]; + uint32_t pixel_mask; + uint8_t enable_ext; } sc1502x_ramdac_t; -void -sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga) +static void +sc1502x_ramdac_bpp(uint8_t val, sc1502x_ramdac_t *ramdac, svga_t *svga) { - sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) priv; - int oldbpp = 0; - - switch (addr) { - case 0x3C6: - if (ramdac->state == 4) { - ramdac->state = 0; - if (val == 0xFF) + 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; - 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; - } + default: + break; + } + break; + case 4: + case 5: + svga->bpp = 15; + break; + case 6: + svga->bpp = 16; + break; + case 7: + if (val & 4) { + switch (val & 0x20) { + case 0x00: + svga->bpp = 32; break; - case 4: - case 5: - svga->bpp = 15; - break; - case 6: - 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; - } + case 0x20: + svga->bpp = 24; break; default: break; } - if (oldbpp != svga->bpp) - svga_recalctimings(svga); + } else + svga->bpp = 16; + break; + + default: + break; + } + if (oldbpp != svga->bpp) + svga_recalctimings(svga); +} + +void +sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga) +{ + sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) priv; + + switch (addr) { + case 0x3C6: + if (ramdac->state == 0) + ramdac->enable_ext = (val == 0x10); + + if (ramdac->state == 4) { + ramdac->state = 0; + sc1502x_ramdac_bpp(val, ramdac, svga); return; } ramdac->state = 0; break; case 0x3C7: + if (ramdac->enable_ext) { + ramdac->idx = val; + return; + } + ramdac->state = 0; + break; case 0x3C8: + if (ramdac->enable_ext) { + switch (ramdac->idx) { + case 8: + ramdac->regs[ramdac->idx] = val; + svga_set_ramdac_type(svga, (ramdac->regs[ramdac->idx] & 1) ? 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; + default: + ramdac->regs[ramdac->idx] = val; + break; + } + return; + } + ramdac->state = 0; + break; case 0x3C9: + if (ramdac->enable_ext) + return; ramdac->state = 0; break; default: break; } - svga_out(addr, val, svga); } @@ -131,10 +173,45 @@ sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga) ramdac->state++; break; case 0x3C7: - case 0x3C8: - case 0x3C9: ramdac->state = 0; break; + case 0x3C8: + if (ramdac->enable_ext) { + 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; + } + } else + ramdac->state = 0; + break; + case 0x3C9: + if (ramdac->enable_ext) + temp = ramdac->idx; + else + ramdac->state = 0; + break; default: break; @@ -149,6 +226,9 @@ sc1502x_ramdac_init(UNUSED(const device_t *info)) sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) malloc(sizeof(sc1502x_ramdac_t)); memset(ramdac, 0, sizeof(sc1502x_ramdac_t)); + ramdac->ctrl = 0; + ramdac->pixel_mask = 0xffffff; + return ramdac; } From 127c00b22ebac1c1b7eaf9203448b9de64feb187 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 3 Jan 2024 23:22:05 +0100 Subject: [PATCH 191/936] NCR 53c9x MCA small improvements. 1. Changed the MCA ID of said adapter to one that is add-on based rather than integrated (still no bios though). 2. Fixed the DMA/IRQ stuff of the 86c01 DMA side of the card. --- src/include/86box/scsi_pcscsi.h | 2 +- src/scsi/scsi.c | 2 +- src/scsi/scsi_pcscsi.c | 98 +++++++++++++++++---------------- 3 files changed, 53 insertions(+), 49 deletions(-) diff --git a/src/include/86box/scsi_pcscsi.h b/src/include/86box/scsi_pcscsi.h index 0ce353d33..3acee78f9 100644 --- a/src/include/86box/scsi_pcscsi.h +++ b/src/include/86box/scsi_pcscsi.h @@ -26,6 +26,6 @@ #define SCSI_PCSCSI_H extern const device_t dc390_pci_device; -extern const device_t ncr53c90_mca_device; +extern const device_t ncr53c90a_mca_device; #endif /*SCSI_BUSLOGIC_H*/ diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index 238fa7cb3..94c9048ef 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -85,7 +85,7 @@ static SCSI_CARD scsi_cards[] = { { &scsi_t130b_device, }, { &aha1640_device, }, { &buslogic_640a_device, }, - { &ncr53c90_mca_device, }, + { &ncr53c90a_mca_device, }, { &spock_device, }, { &tribble_device, }, { &buslogic_958d_pci_device, }, diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index 7bf06b1c0..674bbdabf 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -238,12 +238,10 @@ esp_irq(esp_t *dev, int level) { if (dev->mca) { if (level) { - picint(1 << dev->irq); - dev->dma_86c01.status |= 0x01; + picintlevel(1 << dev->irq, &dev->irq_state); esp_log("Raising IRQ...\n"); } else { - picintc(1 << dev->irq); - dev->dma_86c01.status &= ~0x01; + picintclevel(1 << dev->irq, &dev->irq_state); esp_log("Lowering IRQ...\n"); } } else { @@ -465,7 +463,7 @@ esp_do_command_phase(esp_t *dev) scsi_device_identify(sd, SCSI_LUN_USE_CDB); - dev->rregs[ESP_RINTR] |= INTR_BS | INTR_FC; + dev->rregs[ESP_RINTR] |= (INTR_BS | INTR_FC); esp_raise_irq(dev); } @@ -518,7 +516,6 @@ esp_dma_enable(esp_t *dev, int level) if (level) { esp_log("ESP DMA Enabled\n"); dev->dma_enabled = 1; - dev->dma_86c01.status |= 0x02; timer_stop(&dev->timer); if (((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_TI) && ((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_PAD)) { timer_on_auto(&dev->timer, 40.0); @@ -529,7 +526,6 @@ esp_dma_enable(esp_t *dev, int level) } else { esp_log("ESP DMA Disabled\n"); dev->dma_enabled = 0; - dev->dma_86c01.status &= ~0x02; } } @@ -727,7 +723,7 @@ esp_do_dma(esp_t *dev, scsi_device_t *sd) dma_set_drq(dev->DmaChannel, 1); while (dev->dma_86c01.pos < count) { dma_channel_write(dev->DmaChannel, sd->sc->temp_buffer[dev->buffer_pos + dev->dma_86c01.pos]); - esp_log("ESP SCSI DMA read for 53C90: pos = %i, val = %02x\n", dev->dma_86c01.pos, sd->sc->temp_buffer[dev->buffer_pos + dev->dma_86c01.pos]); + esp_log("ESP SCSI DMA read for 53C9x: pos = %i, val = %02x\n", dev->dma_86c01.pos, sd->sc->temp_buffer[dev->buffer_pos + dev->dma_86c01.pos]); dev->dma_86c01.pos++; } dev->dma_86c01.pos = 0; @@ -741,7 +737,7 @@ esp_do_dma(esp_t *dev, scsi_device_t *sd) dma_set_drq(dev->DmaChannel, 1); while (dev->dma_86c01.pos < count) { int val = dma_channel_read(dev->DmaChannel); - esp_log("ESP SCSI DMA write for 53C90: pos = %i, val = %02x\n", dev->dma_86c01.pos, val & 0xff); + esp_log("ESP SCSI DMA write for 53C9x: pos = %i, val = %02x\n", dev->dma_86c01.pos, val & 0xff); sd->sc->temp_buffer[dev->buffer_pos + dev->dma_86c01.pos] = val & 0xff; dev->dma_86c01.pos++; } @@ -967,7 +963,7 @@ esp_callback(void *priv) } } - esp_log("ESP DMA activated = %d, CMD activated = %d\n", dev->dma_enabled, dev->do_cmd); + esp_log("ESP DMA activated = %d, CMD activated = %d, CMD = %02x\n", dev->dma_enabled, dev->do_cmd, (dev->rregs[ESP_CMD] & CMD_CMD)); } static uint32_t @@ -1060,14 +1056,13 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) dev->dma = 1; /* Reload DMA counter. */ esp_set_tc(dev, esp_get_stc(dev)); - if (dev->mca) - esp_dma_enable(dev, 1); } else { dev->dma = 0; esp_log("ESP Command not for DMA\n"); - if (dev->mca) - esp_dma_enable(dev, 0); } + if (dev->mca) + esp_dma_enable(dev, dev->dma); + esp_log("[%04X:%08X]: ESP Command = %02x, DMA ena1 = %d, DMA ena2 = %d\n", CS, cpu_state.pc, val & (CMD_CMD | CMD_DMA), dev->dma, dev->dma_enabled); switch (val & CMD_CMD) { case CMD_NOP: @@ -1094,7 +1089,7 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) } break; case CMD_TI: - esp_log("val = %02X\n", val); + esp_log("Transfer Information val = %02X\n", val); break; case CMD_SEL: handle_s_without_atn(dev); @@ -1876,10 +1871,10 @@ dc390_init(UNUSED(const device_t *info)) } static uint16_t -ncr53c90_in(uint16_t port, void *priv) +ncr53c9x_in(uint16_t port, void *priv) { esp_t *dev = (esp_t *) priv; - uint16_t ret = 0; + uint16_t ret = 0xffff; port &= 0x1f; @@ -1892,6 +1887,16 @@ ncr53c90_in(uint16_t port, void *priv) break; case 0x0c: + if (dev->rregs[ESP_RSTAT] & STAT_INT) + dev->dma_86c01.status |= 0x01; + else + dev->dma_86c01.status &= ~0x01; + + if ((dev->dma_86c01.mode & 0x40) || dev->dma_enabled) + dev->dma_86c01.status |= 0x02; + else + dev->dma_86c01.status &= ~0x02; + ret = dev->dma_86c01.status; break; @@ -1900,56 +1905,55 @@ ncr53c90_in(uint16_t port, void *priv) } } - esp_log("[%04X:%08X]: NCR53c90 DMA read port = %02x, ret = %02x\n", CS, cpu_state.pc, port, ret); + esp_log("[%04X:%08X]: NCR53c9x DMA read port = %02x, ret = %02x.\n\n", CS, cpu_state.pc, port, ret); return ret; } static uint8_t -ncr53c90_inb(uint16_t port, void *priv) +ncr53c9x_inb(uint16_t port, void *priv) { - return ncr53c90_in(port, priv); + return ncr53c9x_in(port, priv); } static uint16_t -ncr53c90_inw(uint16_t port, void *priv) +ncr53c9x_inw(uint16_t port, void *priv) { - return (ncr53c90_in(port, priv) & 0xff) | (ncr53c90_in(port + 1, priv) << 8); + return (ncr53c9x_in(port, priv) & 0xff) | (ncr53c9x_in(port + 1, priv) << 8); } static void -ncr53c90_out(uint16_t port, uint16_t val, void *priv) +ncr53c9x_out(uint16_t port, uint16_t val, void *priv) { esp_t *dev = (esp_t *) priv; port &= 0x1f; - esp_log("[%04X:%08X]: NCR53c90 DMA write port = %02x, val = %02x\n", CS, cpu_state.pc, port, val); + esp_log("[%04X:%08X]: NCR53c9x DMA write port = %02x, val = %02x\n", CS, cpu_state.pc, port, val); if (port >= 0x10) esp_reg_write(dev, port - 0x10, val); else { - if (port == 0x02) { - dev->dma_86c01.mode = (val & 0x40); - } + if (port == 0x02) + dev->dma_86c01.mode = val; } } static void -ncr53c90_outb(uint16_t port, uint8_t val, void *priv) +ncr53c9x_outb(uint16_t port, uint8_t val, void *priv) { - ncr53c90_out(port, val, priv); + ncr53c9x_out(port, val, priv); } static void -ncr53c90_outw(uint16_t port, uint16_t val, void *priv) +ncr53c9x_outw(uint16_t port, uint16_t val, void *priv) { - ncr53c90_out(port, val & 0xff, priv); - ncr53c90_out(port + 1, val >> 8, priv); + ncr53c9x_out(port, val & 0xff, priv); + ncr53c9x_out(port + 1, val >> 8, priv); } static uint8_t -ncr53c90_mca_read(int port, void *priv) +ncr53c9x_mca_read(int port, void *priv) { const esp_t *dev = (esp_t *) priv; @@ -1957,7 +1961,7 @@ ncr53c90_mca_read(int port, void *priv) } static void -ncr53c90_mca_write(int port, uint8_t val, void *priv) +ncr53c9x_mca_write(int port, uint8_t val, void *priv) { esp_t *dev = (esp_t *) priv; static const uint16_t ncrmca_iobase[] = { @@ -1974,8 +1978,8 @@ ncr53c90_mca_write(int port, uint8_t val, void *priv) /* This is always necessary so that the old handler doesn't remain. */ if (dev->Base != 0) { io_removehandler(dev->Base, 0x20, - ncr53c90_inb, ncr53c90_inw, NULL, - ncr53c90_outb, ncr53c90_outw, NULL, dev); + ncr53c9x_inb, ncr53c9x_inw, NULL, + ncr53c9x_outb, ncr53c9x_outw, NULL, dev); } /* Get the new assigned I/O base address. */ @@ -1999,20 +2003,20 @@ ncr53c90_mca_write(int port, uint8_t val, void *priv) if (dev->Base != 0) { /* Card enabled; register (new) I/O handler. */ io_sethandler(dev->Base, 0x20, - ncr53c90_inb, ncr53c90_inw, NULL, - ncr53c90_outb, ncr53c90_outw, NULL, dev); + ncr53c9x_inb, ncr53c9x_inw, NULL, + ncr53c9x_outb, ncr53c9x_outw, NULL, dev); esp_hard_reset(dev); } /* Say hello. */ - esp_log("NCR 53c90: I/O=%04x, IRQ=%d, DMA=%d, HOST ID %i\n", + esp_log("NCR 53c9x: I/O=%04x, IRQ=%d, DMA=%d, HOST ID %i\n", dev->Base, dev->irq, dev->DmaChannel, dev->HostID); } } static uint8_t -ncr53c90_mca_feedb(void *priv) +ncr53c9x_mca_feedb(void *priv) { const esp_t *dev = (esp_t *) priv; @@ -2020,7 +2024,7 @@ ncr53c90_mca_feedb(void *priv) } static void * -ncr53c90_mca_init(UNUSED(const device_t *info)) +ncr53c9x_mca_init(UNUSED(const device_t *info)) { esp_t *dev; @@ -2034,9 +2038,9 @@ ncr53c90_mca_init(UNUSED(const device_t *info)) fifo8_create(&dev->fifo, ESP_FIFO_SZ); fifo8_create(&dev->cmdfifo, ESP_CMDFIFO_SZ); - dev->pos_regs[0] = 0x4d; /* MCA board ID */ + dev->pos_regs[0] = 0x4f; /* MCA board ID */ dev->pos_regs[1] = 0x7f; - mca_add(ncr53c90_mca_read, ncr53c90_mca_write, ncr53c90_mca_feedb, NULL, dev); + mca_add(ncr53c9x_mca_read, ncr53c9x_mca_write, ncr53c9x_mca_feedb, NULL, dev); esp_hard_reset(dev); @@ -2088,12 +2092,12 @@ const device_t dc390_pci_device = { .config = bios_enable_config }; -const device_t ncr53c90_mca_device = { - .name = "NCR 53c90 MCA", - .internal_name = "ncr53c90", +const device_t ncr53c90a_mca_device = { + .name = "NCR 53c90a MCA", + .internal_name = "ncr53c90a", .flags = DEVICE_MCA, .local = 0, - .init = ncr53c90_mca_init, + .init = ncr53c9x_mca_init, .close = esp_close, .reset = NULL, { .available = NULL }, From a4dcd74216d470a8c0fa5db7d9a1321b45546e64 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 3 Jan 2024 23:42:24 +0100 Subject: [PATCH 192/936] Small 5380 SCSI improvements. 1. The chip in question now supports the right command length for vendor unique commands, fixes crashes that use said commands. 2. Made the CD speed of said chip even closer to the real thing. --- src/scsi/scsi_ncr5380.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index 285c65c80..f271df3ec 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -185,7 +185,7 @@ typedef struct ncr5380_t { #define DMA_SEND 1 #define DMA_INITIATOR_RECEIVE 2 -static int cmd_len[8] = { 6, 10, 10, 6, 16, 12, 6, 6 }; +static int cmd_len[8] = { 6, 10, 10, 6, 16, 12, 10, 6 }; #ifdef ENABLE_NCR5380_LOG int ncr5380_do_log = ENABLE_NCR5380_LOG; @@ -278,7 +278,7 @@ ncr_timer_on(ncr5380_t *ncr_dev, ncr_t *ncr, int callback) if (ncr_dev->type == 3) p *= 512.0; else - p *= 128.0; + p *= 144.0; } p += 1.0; From 2aa7c1f3debedaa153462dac0883af2974838698 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 3 Jan 2024 23:48:27 +0100 Subject: [PATCH 193/936] Added the LG IBM Multinet i x7G (MSI MS-6119), fixed the ASUS P2B-LS, and some SiS 551x fixes. --- src/chipset/sis_5511.c | 8 +++--- src/include/86box/machine.h | 1 + src/machine/m_at_slot1.c | 51 +++++++++++++++++++++++++++---------- src/machine/machine_table.c | 40 +++++++++++++++++++++++++++++ src/pit.c | 11 ++++---- 5 files changed, 88 insertions(+), 23 deletions(-) diff --git a/src/chipset/sis_5511.c b/src/chipset/sis_5511.c index f2ee01ebb..5699fa450 100644 --- a/src/chipset/sis_5511.c +++ b/src/chipset/sis_5511.c @@ -820,13 +820,13 @@ sis_5511_reset(void *priv) dev->pci_conf_sb[0][0x40] = 0x00; dev->pci_conf_sb[0][0x41] = dev->pci_conf_sb[0][0x42] = 0x80; dev->pci_conf_sb[0][0x43] = dev->pci_conf_sb[0][0x44] = 0x80; - dev->pci_conf_sb[0][0x48] = dev->pci_conf_sb[0][0x49] = 0x80; - dev->pci_conf_sb[0][0x4a] = dev->pci_conf_sb[0][0x4b] = 0x80; - dev->pci_conf_sb[0][0x60] = dev->pci_conf_sb[0][0x51] = 0x80; + dev->pci_conf_sb[0][0x48] = dev->pci_conf_sb[0][0x49] = 0x00; + dev->pci_conf_sb[0][0x4a] = dev->pci_conf_sb[0][0x4b] = 0x00; + dev->pci_conf_sb[0][0x60] = dev->pci_conf_sb[0][0x61] = 0x80; dev->pci_conf_sb[0][0x62] = 0x00; dev->pci_conf_sb[0][0x63] = 0x80; dev->pci_conf_sb[0][0x64] = 0x00; - dev->pci_conf_sb[0][0x65] = 0x80; + dev->pci_conf_sb[0][0x65] = 0x00; dev->pci_conf_sb[0][0x66] = dev->pci_conf_sb[0][0x67] = 0x00; dev->pci_conf_sb[0][0x68] = dev->pci_conf_sb[0][0x69] = 0x00; dev->pci_conf_sb[0][0x6a] = 0x04; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index ddbce0ae4..5d7a5204c 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -733,6 +733,7 @@ extern int machine_at_mate_nx_ma30d_23d_init(const machine_t *); extern int machine_at_p6i440e2_init(const machine_t *); extern int machine_at_p2bls_init(const machine_t *); +extern int machine_at_lgibm440bx_init(const machine_t *); extern int machine_at_p3bf_init(const machine_t *); extern int machine_at_bf6_init(const machine_t *); extern int machine_at_ax6bc_init(const machine_t *); diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index d1e348ba4..83e9b74a9 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -236,21 +236,13 @@ machine_at_p2bls_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - // pci_register_slot(0x04, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - // pci_register_slot(0x06, PCI_CARD_SCSI, 4, 1, 2, 3); - // pci_register_slot(0x07, PCI_CARD_NETWORK, 3, 4, 1, 2); -#if 0 + pci_register_slot(0x04, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x06, PCI_CARD_SCSI, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_NETWORK, 3, 4, 1, 2); pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); -#else - pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); -#endif pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&piix4e_device); @@ -261,9 +253,40 @@ machine_at_p2bls_init(const machine_t *model) #endif device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); - // device_add(&w83781d_device); /* fans: Chassis, CPU, Power; temperatures: MB, unused, CPU */ - // hwm_values.temperatures[1] = 0; /* unused */ - // hwm_values.temperatures[2] -= 3; /* CPU offset */ + device_add(&w83781d_device); /* fans: Chassis, CPU, Power; temperatures: MB, unused, CPU */ + hwm_values.temperatures[1] = 0; /* unused */ + hwm_values.temperatures[2] -= 3; /* CPU offset */ + + return ret; +} + +int +machine_at_lgibm440bx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/lgibm440bx/ms6119.331", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&i440bx_device); + device_add(&piix4e_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83977tf_device); + device_add(&winbond_flash_w29c020_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 54b9258f4..7bbd85cda 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -12484,6 +12484,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has the AMIKey-2 (updated 'H') KBC firmware. */ + { + .name = "[i440BX] LG IBM Multinet i x7G (MSI MS-6119)", + .internal_name = "lgibm440bx", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440BX, + .init = machine_at_lgibm440bx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 112121212, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .ram = { + .min = 8192, + .max = 1048576, + .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 = NULL, + .net_device = NULL + }, /* Has a National Semiconductors PC87309 Super I/O chip with on-chip KBC with most likely AMIKey-2 KBC firmware. */ { diff --git a/src/pit.c b/src/pit.c index f5816aaf5..a9099cfca 100644 --- a/src/pit.c +++ b/src/pit.c @@ -659,12 +659,13 @@ pit_read_reg(void *priv, uint8_t reg) break; case 0x07: /* The SiS 551x datasheet is unclear about how exactly - this register is structured. */ + this register is structured. + Update: But the SiS 5571 datasheet is clear. */ ret = (dev->counters[0].rm & 0x80) ? 0x01 : 0x00; - ret = (dev->counters[0].wm & 0x80) ? 0x02 : 0x00; - ret = (dev->counters[1].rm & 0x80) ? 0x04 : 0x00; - ret = (dev->counters[1].wm & 0x80) ? 0x08 : 0x00; - ret = (dev->counters[2].rm & 0x80) ? 0x10 : 0x00; + ret = (dev->counters[1].rm & 0x80) ? 0x02 : 0x00; + ret = (dev->counters[2].rm & 0x80) ? 0x04 : 0x00; + ret = (dev->counters[0].wm & 0x80) ? 0x08 : 0x00; + ret = (dev->counters[1].wm & 0x80) ? 0x10 : 0x00; ret = (dev->counters[2].wm & 0x80) ? 0x20 : 0x00; break; } From 356ac8acbe3770e13aa8976dc01004d0d335e2ce Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 3 Jan 2024 23:56:58 +0100 Subject: [PATCH 194/936] Fixed the two warnings in video/vid_s3.c. --- src/video/vid_s3.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 0fd939908..97a02b341 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -7340,12 +7340,6 @@ s3_911_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, READ(s3->accel.dest + s3->accel.cx - s3->accel.minus, dest_dat); - if (s3->accel.cmd == 0x41b1 || s3->accel.cmd == 0x41b0) { - uint16_t dest_dat2; - READ(s3->accel.dest + s3->accel.cx, dest_dat2); - //pclog("CMD=%04x, initialdest=%04x, c(%d,%d), cpu=%04x, minus=%d, len=%d.\n", s3->accel.cmd, dest_dat2, s3->accel.cx - s3->accel.minus, s3->accel.cy, cpu_dat & 0xffff, s3->accel.minus, s3->accel.maj_axis_pcnt); - } - MIX if (s3->accel.cmd & 0x10) { @@ -7625,7 +7619,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi int clip_r = s3->accel.multifunc[4] & 0xfff; int vram_mask = (s3->accel.multifunc[0xa] & 0xc0) == 0xc0; uint32_t mix_mask = 0; - uint8_t *vram = (uint8_t *) svga->vram; uint16_t *vram_w = (uint16_t *) svga->vram; uint32_t *vram_l = (uint32_t *) svga->vram; uint32_t compare = s3->accel.color_cmp; From 45df94c95483c8b3051929f3403e13e0f7b541b1 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 4 Jan 2024 00:22:47 +0100 Subject: [PATCH 195/936] S3 mode fixes (1): 1. Fixed the Elsa Winner 2000 Pro-X/8 (964 and 968) 15/16/32bpp modes at 1280x1024+. --- src/video/vid_s3.c | 78 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 3 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 97a02b341..18c4f587a 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3233,7 +3233,7 @@ s3_recalctimings(svga_t *svga) #endif if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { - //pclog("BPP=%d, pitch=%d, width=%02x, double?=%x, 16bit?=%d, highres?=%d, attr=%02x.\n", svga->bpp, s3->width, svga->crtc[0x50], svga->crtc[0x31] & 0x02, s3->color_16bit, s3->accel.advfunc_cntl & 4, svga->attrregs[0x10] & 0x40); + pclog("BPP=%d, pitch=%d, width=%02x, double?=%x, 16bit?=%d, highres?=%d, attr=%02x.\n", svga->bpp, s3->width, svga->crtc[0x50], svga->crtc[0x31] & 0x02, s3->color_16bit, s3->accel.advfunc_cntl & 4, svga->attrregs[0x10] & 0x40); switch (svga->bpp) { case 8: svga->render = svga_render_8bpp_highres; @@ -3433,6 +3433,23 @@ s3_recalctimings(svga_t *svga) break; } break; + case S3_VISION964: + switch (s3->card_type) { + case S3_ELSAWIN2KPROX_964: + switch (s3->width) { + case 1280: + case 1600: + svga->hdisp <<= 1; + break; + default: + break; + } + break; + + default: + break; + } + break; case S3_VISION868: switch (s3->card_type) { case S3_PHOENIX_VISION868: @@ -3452,7 +3469,16 @@ s3_recalctimings(svga_t *svga) if (svga->hdisp == 832) svga->hdisp -= 32; break; - + case S3_ELSAWIN2KPROX: + switch (s3->width) { + case 1280: + case 1600: + svga->hdisp <<= 1; + break; + default: + break; + } + break; default: break; } @@ -3585,6 +3611,23 @@ s3_recalctimings(svga_t *svga) break; } break; + case S3_VISION964: + switch (s3->card_type) { + case S3_ELSAWIN2KPROX_964: + switch (s3->width) { + case 1280: + case 1600: + svga->hdisp <<= 1; + break; + default: + break; + } + break; + + default: + break; + } + break; case S3_VISION968: switch (s3->card_type) { case S3_NUMBER9_9FX_771: @@ -3593,7 +3636,16 @@ s3_recalctimings(svga_t *svga) if (svga->hdisp == 832) svga->hdisp -= 32; break; - + case S3_ELSAWIN2KPROX: + switch (s3->width) { + case 1280: + case 1600: + svga->hdisp <<= 1; + break; + default: + break; + } + break; default: break; } @@ -3760,6 +3812,16 @@ s3_recalctimings(svga_t *svga) break; } break; + case S3_ELSAWIN2KPROX_964: + switch (s3->width) { + case 1280: + case 1600: + svga->hdisp <<= 1; + break; + default: + break; + } + break; default: break; } @@ -3772,6 +3834,16 @@ s3_recalctimings(svga_t *svga) if (svga->hdisp == 832) svga->hdisp -= 32; break; + case S3_ELSAWIN2KPROX_964: + switch (s3->width) { + case 1280: + case 1600: + svga->hdisp <<= 1; + break; + default: + break; + } + break; default: break; } From 4317155167dcd225f32793c293fa713c44a6c9d9 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 4 Jan 2024 00:27:50 +0100 Subject: [PATCH 196/936] S3 mode fixes (1.5): 1. Actually fix the one in 32bpp mode (968 only). --- src/video/vid_s3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 18c4f587a..ff28ffbfa 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3834,7 +3834,7 @@ s3_recalctimings(svga_t *svga) if (svga->hdisp == 832) svga->hdisp -= 32; break; - case S3_ELSAWIN2KPROX_964: + case S3_ELSAWIN2KPROX: switch (s3->width) { case 1280: case 1600: From 82b19477f46b570577903af758238c80afc7c3d7 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 4 Jan 2024 00:46:20 +0100 Subject: [PATCH 197/936] PCnet-based fixes: 1. Racal Etherblaster now has, on reset, the proper initialization values, fixes detection under various operating systems, especially NT. --- src/network/net_pcnet.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/network/net_pcnet.c b/src/network/net_pcnet.c index ab761acf3..02e3d32e7 100644 --- a/src/network/net_pcnet.c +++ b/src/network/net_pcnet.c @@ -866,7 +866,7 @@ pcnetSoftReset(nic_t *dev) case DEV_AM79C960_VLB: case DEV_AM79C961: dev->aCSR[88] = 0x3003; - dev->aCSR[89] = 0x0262; + dev->aCSR[89] = 0x0000; break; default: @@ -3101,9 +3101,12 @@ static const device_config_t pcnet_isa_config[] = { { .description = "IRQ 3", .value = 3 }, { .description = "IRQ 4", .value = 4 }, { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, { .description = "IRQ 9", .value = 9 }, { .description = "IRQ 10", .value = 10 }, { .description = "IRQ 11", .value = 11 }, + { .description = "IRQ 12", .value = 12 }, + { .description = "IRQ 15", .value = 15 }, { .description = "" } }, }, @@ -3116,6 +3119,7 @@ static const device_config_t pcnet_isa_config[] = { .file_filter = "", .spinner = { 0 }, .selection = { + { .description = "DMA 0", .value = 0 }, { .description = "DMA 3", .value = 3 }, { .description = "DMA 5", .value = 5 }, { .description = "DMA 6", .value = 6 }, @@ -3162,9 +3166,12 @@ static const device_config_t pcnet_vlb_config[] = { { .description = "IRQ 3", .value = 3 }, { .description = "IRQ 4", .value = 4 }, { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, { .description = "IRQ 9", .value = 9 }, { .description = "IRQ 10", .value = 10 }, { .description = "IRQ 11", .value = 11 }, + { .description = "IRQ 12", .value = 12 }, + { .description = "IRQ 15", .value = 15 }, { .description = "" } }, }, From 2722ae1d681d16fa060ecd203da33f479a7f6dcf Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 4 Jan 2024 09:00:29 +0100 Subject: [PATCH 198/936] PIT: Change assignments to OR's. --- src/pit.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pit.c b/src/pit.c index a9099cfca..6045fd842 100644 --- a/src/pit.c +++ b/src/pit.c @@ -662,11 +662,11 @@ pit_read_reg(void *priv, uint8_t reg) this register is structured. Update: But the SiS 5571 datasheet is clear. */ ret = (dev->counters[0].rm & 0x80) ? 0x01 : 0x00; - ret = (dev->counters[1].rm & 0x80) ? 0x02 : 0x00; - ret = (dev->counters[2].rm & 0x80) ? 0x04 : 0x00; - ret = (dev->counters[0].wm & 0x80) ? 0x08 : 0x00; - ret = (dev->counters[1].wm & 0x80) ? 0x10 : 0x00; - ret = (dev->counters[2].wm & 0x80) ? 0x20 : 0x00; + ret |= (dev->counters[1].rm & 0x80) ? 0x02 : 0x00; + ret |= (dev->counters[2].rm & 0x80) ? 0x04 : 0x00; + ret |= (dev->counters[0].wm & 0x80) ? 0x08 : 0x00; + ret |= (dev->counters[1].wm & 0x80) ? 0x10 : 0x00; + ret |= (dev->counters[2].wm & 0x80) ? 0x20 : 0x00; break; } From e64b7e837cf602599b6e66bb2cdf0f2fb7a96536 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 4 Jan 2024 09:02:59 +0100 Subject: [PATCH 199/936] Also applied the changes to pit_fast.c. --- src/pit_fast.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/pit_fast.c b/src/pit_fast.c index 1168cb3c5..f9d055375 100644 --- a/src/pit_fast.c +++ b/src/pit_fast.c @@ -522,13 +522,14 @@ pitf_read_reg(void *priv, uint8_t reg) break; case 0x07: /* The SiS 551x datasheet is unclear about how exactly - this register is structured. */ + this register is structured. + Update: But the SiS 5571 datasheet is clear. */ ret = (dev->counters[0].rm & 0x80) ? 0x01 : 0x00; - ret = (dev->counters[0].wm & 0x80) ? 0x02 : 0x00; - ret = (dev->counters[1].rm & 0x80) ? 0x04 : 0x00; - ret = (dev->counters[1].wm & 0x80) ? 0x08 : 0x00; - ret = (dev->counters[2].rm & 0x80) ? 0x10 : 0x00; - ret = (dev->counters[2].wm & 0x80) ? 0x20 : 0x00; + ret |= (dev->counters[1].rm & 0x80) ? 0x02 : 0x00; + ret |= (dev->counters[2].rm & 0x80) ? 0x04 : 0x00; + ret |= (dev->counters[0].wm & 0x80) ? 0x08 : 0x00; + ret |= (dev->counters[1].wm & 0x80) ? 0x10 : 0x00; + ret |= (dev->counters[2].wm & 0x80) ? 0x20 : 0x00; break; } From 13d582b56faf9caca114ec5625b34a7859ecb41f Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 5 Jan 2024 13:01:17 +0100 Subject: [PATCH 200/936] Unix: Use proper parentheses to cast the result, not the flags, fixes #3994. --- src/unix/unix.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/unix/unix.c b/src/unix/unix.c index e784df38e..cfa824313 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -644,10 +644,8 @@ ui_msgbox_header(int flags, void *header, void *message) SDL_MessageBoxData msgdata; SDL_MessageBoxButtonData msgbtn; -#if 0 if (!header) - header = (void *) (flags & MBX_ANSI) ? "86Box" : L"86Box"; -#endif + header = (void *) ((flags & MBX_ANSI) ? "86Box" : L"86Box"); if (header <= (void *) 7168) header = (void *) plat_get_string((uintptr_t) header); if (message <= (void *) 7168) From 6b1d0b9e88c9ca5bfd9e2274352441a2b72b2490 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 5 Jan 2024 21:11:49 +0100 Subject: [PATCH 201/936] S3 mode fixes 2 and one small accel cleanup: 1. Fixed 16bpp modes (including 15-bit) of the Trio32/64 that were doubling their horizontal resolution. 2. Made Bresenham Line easier to work with. --- src/video/vid_s3.c | 198 +++++++++++++++++---------------------------- 1 file changed, 74 insertions(+), 124 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index ff28ffbfa..4a7a76ed2 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3469,6 +3469,7 @@ s3_recalctimings(svga_t *svga) if (svga->hdisp == 832) svga->hdisp -= 32; break; + case S3_ELSAWIN2KPROX: switch (s3->width) { case 1280: @@ -3483,6 +3484,12 @@ s3_recalctimings(svga_t *svga) break; } break; + + case S3_TRIO64: + case S3_TRIO32: + svga->hdisp >>= 1; + break; + default: break; } @@ -3636,6 +3643,7 @@ s3_recalctimings(svga_t *svga) if (svga->hdisp == 832) svga->hdisp -= 32; break; + case S3_ELSAWIN2KPROX: switch (s3->width) { case 1280: @@ -3650,6 +3658,12 @@ s3_recalctimings(svga_t *svga) break; } break; + + case S3_TRIO64: + case S3_TRIO32: + svga->hdisp >>= 1; + break; + default: break; } @@ -3756,6 +3770,11 @@ s3_recalctimings(svga_t *svga) } break; + case S3_TRIO64: + case S3_TRIO32: + svga->hdisp /= 3; + break; + default: break; } @@ -3834,6 +3853,7 @@ s3_recalctimings(svga_t *svga) if (svga->hdisp == 832) svga->hdisp -= 32; break; + case S3_ELSAWIN2KPROX: switch (s3->width) { case 1280: @@ -7222,71 +7242,36 @@ s3_911_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, if (!s3->accel.sy) break; - if (s3->accel.err_term >= s3->accel.maj_axis_pcnt) { - s3->accel.err_term += s3->accel.destx_distp; - /*Step minor axis*/ - switch (s3->accel.cmd & 0xe0) { - case 0x00: - s3->accel.cy--; - break; - case 0x20: - s3->accel.cy--; - break; - case 0x40: - s3->accel.cx--; - break; - case 0x60: - s3->accel.cx++; - break; - case 0x80: - s3->accel.cy++; - break; - case 0xa0: - s3->accel.cy++; - break; - case 0xc0: - s3->accel.cx--; - break; - case 0xe0: - s3->accel.cx++; - break; - - default: - break; - } - } else - s3->accel.err_term += s3->accel.desty_axstp; - - /*Step major axis*/ - switch (s3->accel.cmd & 0xe0) { - case 0x00: - s3->accel.cx--; - break; - case 0x20: - s3->accel.cx++; - break; - case 0x40: - s3->accel.cy--; - break; - case 0x60: - s3->accel.cy--; - break; - case 0x80: - s3->accel.cx--; - break; - case 0xa0: - s3->accel.cx++; - break; - case 0xc0: + if (s3->accel.cmd & 0x40) { + if (s3->accel.cmd & 0x80) s3->accel.cy++; - break; - case 0xe0: - s3->accel.cy++; - break; + else + s3->accel.cy--; - default: - break; + if (s3->accel.err_term >= 0) { + s3->accel.err_term += s3->accel.destx_distp; + if (s3->accel.cmd & 0x20) + s3->accel.cx++; + else + s3->accel.cx--; + } else + s3->accel.err_term += s3->accel.desty_axstp; + } else { + if (s3->accel.cmd & 0x20) + s3->accel.cx++; + else + s3->accel.cx--; + + if (s3->accel.err_term >= 0) { + s3->accel.err_term += s3->accel.destx_distp; + if (s3->accel.cmd & 0x80) + s3->accel.cy++; + else + s3->accel.cy--; + } else + s3->accel.err_term += s3->accel.desty_axstp; } + s3->accel.sy--; s3->accel.cx &= 0xfff; s3->accel.cy &= 0xfff; @@ -8028,71 +8013,36 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if (!s3->accel.sy) break; - if (s3->accel.err_term >= s3->accel.maj_axis_pcnt) { - s3->accel.err_term += s3->accel.destx_distp; - /*Step minor axis*/ - switch (s3->accel.cmd & 0xe0) { - case 0x00: - s3->accel.cy--; - break; - case 0x20: - s3->accel.cy--; - break; - case 0x40: - s3->accel.cx--; - break; - case 0x60: - s3->accel.cx++; - break; - case 0x80: - s3->accel.cy++; - break; - case 0xa0: - s3->accel.cy++; - break; - case 0xc0: - s3->accel.cx--; - break; - case 0xe0: - s3->accel.cx++; - break; - - default: - break; - } - } else - s3->accel.err_term += s3->accel.desty_axstp; - - /*Step major axis*/ - switch (s3->accel.cmd & 0xe0) { - case 0x00: - s3->accel.cx--; - break; - case 0x20: - s3->accel.cx++; - break; - case 0x40: - s3->accel.cy--; - break; - case 0x60: - s3->accel.cy--; - break; - case 0x80: - s3->accel.cx--; - break; - case 0xa0: - s3->accel.cx++; - break; - case 0xc0: + if (s3->accel.cmd & 0x40) { + if (s3->accel.cmd & 0x80) s3->accel.cy++; - break; - case 0xe0: - s3->accel.cy++; - break; + else + s3->accel.cy--; - default: - break; + if (s3->accel.err_term >= 0) { + s3->accel.err_term += s3->accel.destx_distp; + if (s3->accel.cmd & 0x20) + s3->accel.cx++; + else + s3->accel.cx--; + } else + s3->accel.err_term += s3->accel.desty_axstp; + } else { + if (s3->accel.cmd & 0x20) + s3->accel.cx++; + else + s3->accel.cx--; + + if (s3->accel.err_term >= 0) { + s3->accel.err_term += s3->accel.destx_distp; + if (s3->accel.cmd & 0x80) + s3->accel.cy++; + else + s3->accel.cy--; + } else + s3->accel.err_term += s3->accel.desty_axstp; } + s3->accel.sy--; s3->accel.cx &= 0xfff; s3->accel.cy &= 0xfff; From 4b52a514bd4f6202cf5ba162ebcaee3a5d503b29 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 5 Jan 2024 21:22:01 +0100 Subject: [PATCH 202/936] Huge fixes to 8514/A compatibles: 1. Properly implemented polygon filling in the BitBLT side of the ATI 8514/A compatibles (Mach8/32), this allows games like Mj8514 and demos like HDIDEMO from IBM to run under ATI's hdiload 1.1 properly. 2. Finally figured out the polygon filling command in the IBM one about read and write masks (Command 5 and Command 2 with polygon filling bits on, currently only for the read mask one), this allows the above samples to render properly with IBM's original hdiload 1.0 from 1987. --- src/include/86box/vid_8514a.h | 8 +- src/video/vid_8514a.c | 764 +++++++++++++++++----------------- src/video/vid_ati_mach8.c | 551 +++++++++++++----------- 3 files changed, 703 insertions(+), 620 deletions(-) diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h index 49b4cb37d..4d7483f30 100644 --- a/src/include/86box/vid_8514a.h +++ b/src/include/86box/vid_8514a.h @@ -67,13 +67,14 @@ typedef struct ibm8514_t { uint16_t advfunc_cntl; uint8_t ext_advfunc_cntl; uint16_t cur_y; - uint16_t cur_y_bitres; uint16_t cur_x; - uint16_t cur_x_bitres; + int16_t destx; + int16_t desty; int16_t desty_axstp; int16_t destx_distp; int16_t err_term; int16_t maj_axis_pcnt; + int16_t maj_axis_pcnt_no_limit; uint16_t cmd; uint16_t cmd_back; uint16_t short_stroke; @@ -100,7 +101,9 @@ typedef struct ibm8514_t { int sys_cnt2; int temp_cnt; int16_t cx; + int16_t cx_back; int16_t cy; + int16_t oldcx; int16_t oldcy; int16_t sx; int16_t sy; @@ -133,6 +136,7 @@ typedef struct ibm8514_t { int fill_state; int xdir; int ydir; + int linedraw; uint32_t ge_offset; } accel; diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index e2a7da3ca..576562f23 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -447,14 +447,16 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) { ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + if (port != 0x9ae8 && port != 0xe2e8) + ibm8514_log("Port OUT FIFO=%04x, val=%04x, len=%d.\n", port, val, len); + switch (port) { case 0x82e8: case 0xc2e8: if (len == 1) { dev->accel.cur_y = (dev->accel.cur_y & 0x700) | val; - } else { + } else dev->accel.cur_y = val & 0x7ff; - } break; case 0x82e9: case 0xc2e9: @@ -465,11 +467,10 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) case 0x86e8: case 0xc6e8: - if (len == 1) { + if (len == 1) dev->accel.cur_x = (dev->accel.cur_x & 0x700) | val; - } else { + else dev->accel.cur_x = val & 0x7ff; - } break; case 0x86e9: case 0xc6e9: @@ -483,6 +484,7 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) if (len == 1) dev->accel.desty_axstp = (dev->accel.desty_axstp & 0x3f00) | val; else { + dev->accel.desty = val & 0x07ff; dev->accel.desty_axstp = val & 0x3fff; if (val & 0x2000) dev->accel.desty_axstp |= ~0x1fff; @@ -502,6 +504,7 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) if (len == 1) dev->accel.destx_distp = (dev->accel.destx_distp & 0x3f00) | val; else { + dev->accel.destx = val & 0x07ff; dev->accel.destx_distp = val & 0x3fff; if (val & 0x2000) dev->accel.destx_distp |= ~0x1fff; @@ -544,6 +547,7 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) dev->accel.maj_axis_pcnt = (dev->accel.maj_axis_pcnt & 0x700) | val; else { dev->accel.maj_axis_pcnt = val & 0x7ff; + dev->accel.maj_axis_pcnt_no_limit = val; } break; case 0x96e9: @@ -566,6 +570,7 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) if (dev->accel.cmd & 0x100) dev->accel.cmd_back = 0; } + ibm8514_log("8514/A CMD=%04x.\n", dev->accel.cmd); ibm8514_accel_start(-1, 0, -1, 0, svga, len); } break; @@ -848,6 +853,7 @@ static void ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) { ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint8_t old = 0; if (port & 0x8000) { ibm8514_accel_out_fifo(svga, port, val, len); @@ -947,16 +953,40 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) break; case 0x42e8: - if (len == 1) { - dev->subsys_stat &= ~val; - } else { - dev->subsys_stat &= ~(val & 0xff); + old = dev->subsys_stat; + if ((val & 0xff) & 1) + dev->subsys_stat &= ~1; + if ((val & 0xff) & 2) + dev->subsys_stat &= ~2; + if ((val & 0xff) & 4) + dev->subsys_stat &= ~4; + if ((val & 0xff) & 8) + dev->subsys_stat &= ~8; + if (len != 1) { + old = dev->subsys_cntl; dev->subsys_cntl = (val >> 8); + if ((old ^ dev->subsys_cntl) & 1) + dev->subsys_stat |= 1; + if ((old ^ dev->subsys_cntl) & 2) + dev->subsys_stat |= 2; + if ((old ^ dev->subsys_cntl) & 4) + dev->subsys_stat |= 4; + if ((old ^ dev->subsys_cntl) & 8) + dev->subsys_stat |= 8; } break; case 0x42e9: if (len == 1) { + old = dev->subsys_cntl; dev->subsys_cntl = val; + if ((old ^ val) & 1) + dev->subsys_stat |= 1; + if ((old ^ val) & 2) + dev->subsys_stat |= 2; + if ((old ^ val) & 4) + dev->subsys_stat |= 4; + if ((old ^ val) & 8) + dev->subsys_stat |= 8; } break; @@ -1038,6 +1068,7 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len) break; case 0x42e8: + cmd = dev->accel.cmd >> 13; vpos = dev->vc & 0x7ff; if (vblankend > dev->v_total) { vblankend -= dev->v_total; @@ -1058,6 +1089,20 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len) temp |= 0x80; break; + case 0x82e8: + case 0xc2e8: + if (len != 1) { + temp = dev->accel.cur_y; + } + break; + + case 0x86e8: + case 0xc6e8: + if (len != 1) { + temp = dev->accel.cur_x; + } + break; + case 0x92e8: if (len != 1) { temp = dev->test; @@ -1155,6 +1200,12 @@ ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t ibm8514_accel_start(count, cpu_input, mix_dat, cpu_dat, svga, len); } +#define CLAMP(x) \ + do { \ + if ((x) & ~0xff) \ + x = ((x) < 0) ? 0 : 0xff; \ + } while (0) + void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, UNUSED(int len)) { @@ -1173,13 +1224,15 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat int compare_mode = dev->accel.multifunc[0x0a] & 0x38; int cmd = dev->accel.cmd >> 13; uint16_t wrt_mask = dev->accel.wrt_mask; + uint16_t wrt_mask_polygon = dev->accel.wrt_mask; uint16_t rd_mask = dev->accel.rd_mask; uint16_t rd_mask_polygon = dev->accel.rd_mask; uint16_t frgd_color = dev->accel.frgd_color; uint16_t bkgd_color = dev->accel.bkgd_color; uint32_t old_mix_dat; - int and3 = dev->accel.cur_x & 3; - uint16_t poly_src = 0; + int and3 = dev->accel.cur_x & 3; + uint16_t poly_src = 0; + uint16_t old_poly_src = 0; if (!dev->bpp) { compare &= 0xff; @@ -1298,10 +1351,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat /*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled. When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on the NOP command)*/ - if (dev->accel.cmd == 0x43b3) { - ibm8514_log("CMD8514: CMD=%d, full=%04x, pixcntl=%x, count=%d, frcolor=%02x, bkcolor=%02x, polygon=%x, cpu=%08x, frgdmix=%02x, bkgdmix=%02x.\n", cmd, dev->accel.cmd, pixcntl, count, frgd_color, bkgd_color, dev->accel.multifunc[0x0a] & 6, cpu_dat, dev->accel.frgd_mix, dev->accel.bkgd_mix); - } - switch (cmd) { case 0: /*NOP (Short Stroke Vectors)*/ if (dev->accel.ssv_state == 0) @@ -1518,15 +1567,15 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.cx = dev->accel.cur_x; dev->accel.cy = dev->accel.cur_y; - if (dev->accel.cur_x >= 0x600) { + if (dev->accel.cur_x >= 0x600) dev->accel.cx |= ~0x5ff; - } - if (dev->accel.cur_y >= 0x600) { + + if (dev->accel.cur_y >= 0x600) dev->accel.cy |= ~0x5ff; - } dev->accel.sy = dev->accel.maj_axis_pcnt; + ibm8514_log("Line Draw 8514/A, frgdmix=%d, bkgdmix=%d, c(%d,%d), pixcntl=%d, sy=%d, polyfill=%x, selfrmix=%02x, selbkmix=%02x, bkgdcol=%02x, frgdcol=%02x, clipt=%d, clipb=%d.\n", frgd_mix, bkgd_mix, dev->accel.cx, dev->accel.cy, pixcntl, dev->accel.sy, dev->accel.multifunc[0x0a] & 6, dev->accel.frgd_mix & 0x1f, dev->accel.bkgd_mix & 0x1f, bkgd_color, frgd_color, dev->accel.clip_top, clip_b); if (ibm8514_cpu_src(svga)) { if (dev->accel.cmd & 2) { if (dev->accel.cmd & 8) { @@ -1586,7 +1635,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat READ((dev->accel.cy * dev->pitch) + dev->accel.cx, src_dat); if (pixcntl == 3) src_dat = ((src_dat & rd_mask) == rd_mask); - } else + } else { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: src_dat = bkgd_color; @@ -1604,6 +1653,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat default: break; } + } READ((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); @@ -1785,70 +1835,34 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat break; } - if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) { - dev->accel.err_term += dev->accel.destx_distp; - /*Step minor axis*/ - switch (dev->accel.cmd & 0xe0) { - case 0x00: - dev->accel.cy--; - break; - case 0x20: - dev->accel.cy--; - break; - case 0x40: - dev->accel.cx--; - break; - case 0x60: - dev->accel.cx++; - break; - case 0x80: - dev->accel.cy++; - break; - case 0xa0: - dev->accel.cy++; - break; - case 0xc0: - dev->accel.cx--; - break; - case 0xe0: - dev->accel.cx++; - break; - - default: - break; - } - } else - dev->accel.err_term += dev->accel.desty_axstp; - - /*Step major axis*/ - switch (dev->accel.cmd & 0xe0) { - case 0x00: - dev->accel.cx--; - break; - case 0x20: - dev->accel.cx++; - break; - case 0x40: - dev->accel.cy--; - break; - case 0x60: - dev->accel.cy--; - break; - case 0x80: - dev->accel.cx--; - break; - case 0xa0: - dev->accel.cx++; - break; - case 0xc0: + if (dev->accel.cmd & 0x40) { + if (dev->accel.cmd & 0x80) dev->accel.cy++; - break; - case 0xe0: - dev->accel.cy++; - break; + else + dev->accel.cy--; - default: - break; + if (dev->accel.err_term >= 0) { + dev->accel.err_term += dev->accel.destx_distp; + if (dev->accel.cmd & 0x20) + dev->accel.cx++; + else + dev->accel.cx--; + } else + dev->accel.err_term += dev->accel.desty_axstp; + } else { + if (dev->accel.cmd & 0x20) + dev->accel.cx++; + else + dev->accel.cx--; + + if (dev->accel.err_term >= 0) { + dev->accel.err_term += dev->accel.destx_distp; + if (dev->accel.cmd & 0x80) + dev->accel.cy++; + else + dev->accel.cy--; + } else + dev->accel.err_term += dev->accel.desty_axstp; } dev->accel.sy--; @@ -1909,74 +1923,37 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else cpu_dat >>= 8; - if (dev->accel.sy == 0) { + if (dev->accel.sy == 0) break; - } - if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) { - dev->accel.err_term += dev->accel.destx_distp; - /*Step minor axis*/ - switch (dev->accel.cmd & 0xe0) { - case 0x00: - dev->accel.cy--; - break; - case 0x20: - dev->accel.cy--; - break; - case 0x40: - dev->accel.cx--; - break; - case 0x60: - dev->accel.cx++; - break; - case 0x80: - dev->accel.cy++; - break; - case 0xa0: - dev->accel.cy++; - break; - case 0xc0: - dev->accel.cx--; - break; - case 0xe0: - dev->accel.cx++; - break; - - default: - break; - } - } else - dev->accel.err_term += dev->accel.desty_axstp; - - /*Step major axis*/ - switch (dev->accel.cmd & 0xe0) { - case 0x00: - dev->accel.cx--; - break; - case 0x20: - dev->accel.cx++; - break; - case 0x40: - dev->accel.cy--; - break; - case 0x60: - dev->accel.cy--; - break; - case 0x80: - dev->accel.cx--; - break; - case 0xa0: - dev->accel.cx++; - break; - case 0xc0: + if (dev->accel.cmd & 0x40) { + if (dev->accel.cmd & 0x80) dev->accel.cy++; - break; - case 0xe0: - dev->accel.cy++; - break; + else + dev->accel.cy--; - default: - break; + if (dev->accel.err_term >= 0) { + dev->accel.err_term += dev->accel.destx_distp; + if (dev->accel.cmd & 0x20) + dev->accel.cx++; + else + dev->accel.cx--; + } else + dev->accel.err_term += dev->accel.desty_axstp; + } else { + if (dev->accel.cmd & 0x20) + dev->accel.cx++; + else + dev->accel.cx--; + + if (dev->accel.err_term >= 0) { + dev->accel.err_term += dev->accel.destx_distp; + if (dev->accel.cmd & 0x80) + dev->accel.cy++; + else + dev->accel.cy--; + } else + dev->accel.err_term += dev->accel.desty_axstp; } dev->accel.sy--; @@ -2010,13 +1987,11 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (dev->accel.cur_y >= 0x600) dev->accel.cy |= ~0x5ff; - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24)) + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); else dev->accel.dest = dev->accel.cy * dev->pitch; - dev->accel.fill_state = 0; - if (cmd == 4) dev->accel.cmd |= 2; else if (cmd == 3) @@ -2062,7 +2037,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (!(dev->accel.cmd & 0x40) && (frgd_mix == 2) && (bkgd_mix == 2) && (pixcntl == 0) && (cmd == 2)) { if (!(dev->accel.sx & 1)) { dev->accel.output = 1; - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24)) + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) dev->accel.newdest_out = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch); else dev->accel.newdest_out = (dev->accel.cy + 1) * dev->pitch; @@ -2076,7 +2051,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (!(dev->accel.cmd & 2) && (frgd_mix == 2) && (pixcntl == 0) && (cmd == 2)) { if (!(dev->accel.sx & 1)) { dev->accel.input = 1; - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24)) + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) dev->accel.newdest_in = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch); else dev->accel.newdest_in = (dev->accel.cy + 1) * dev->pitch; @@ -2220,15 +2195,14 @@ rect_fill_pix: dev->accel.sx--; if (dev->accel.sx < 0) { dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - if (and3 == 1) { + if (and3 == 1) dev->accel.sx += 4; - } else if (and3 == 2) { + else if (and3 == 2) dev->accel.sx += 5; - } else if (and3 == 3) { + else if (and3 == 3) dev->accel.sx += 6; - } else { + else dev->accel.sx += 3; - } if (dev->accel.cmd & 0x20) dev->accel.cx -= (dev->accel.sx + 1); @@ -2259,10 +2233,11 @@ rect_fill_pix: break; } - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24)) + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); else dev->accel.dest = dev->accel.cy * dev->pitch; + dev->accel.sy--; return; } @@ -2344,7 +2319,7 @@ rect_fill_pix: else dev->accel.cy--; - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24)) + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); else dev->accel.dest = dev->accel.cy * dev->pitch; @@ -2436,7 +2411,7 @@ rect_fill_pix: else dev->accel.cy--; - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24)) + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); else dev->accel.dest = dev->accel.cy * dev->pitch; @@ -2495,7 +2470,7 @@ rect_fill_pix: else dev->accel.cy--; - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24)) { + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) { dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); dev->accel.newdest_in = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch); } else { @@ -2520,7 +2495,7 @@ rect_fill_pix: else dev->accel.cy--; - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24)) { + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) { dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); dev->accel.newdest_in = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch); } else { @@ -2576,7 +2551,7 @@ rect_fill_pix: else dev->accel.cy--; - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24)) { + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) { dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); dev->accel.newdest_out = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch); } else { @@ -2601,7 +2576,7 @@ rect_fill_pix: else dev->accel.cy--; - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24)) { + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) { dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); dev->accel.newdest_out = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch); } else { @@ -2691,7 +2666,7 @@ rect_fill_pix: else dev->accel.cy--; - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24)) + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); else dev->accel.dest = dev->accel.cy * dev->pitch; @@ -2768,7 +2743,7 @@ rect_fill: else dev->accel.cy--; - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24)) + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); else dev->accel.dest = dev->accel.cy * dev->pitch; @@ -2783,7 +2758,7 @@ rect_fill: } else { dev->accel.temp_cnt = 8; while (count-- && dev->accel.sy >= 0) { - if (dev->accel.temp_cnt == 0) { + if (!dev->accel.temp_cnt) { dev->accel.temp_cnt = 8; mix_dat = old_mix_dat; } @@ -2839,7 +2814,7 @@ rect_fill: else dev->accel.cy--; - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24)) + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); else dev->accel.dest = dev->accel.cy * dev->pitch; @@ -2855,93 +2830,74 @@ rect_fill: } } } else { - if (dev->accel.multifunc[0x0a] & 6) { - while (count-- && dev->accel.sy >= 0) { + if ((dev->accel.multifunc[0x0a] & 6) == 4) { + while (count-- && (dev->accel.sy >= 0)) { if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; - break; - case 1: - src_dat = frgd_color; - break; - case 2: - src_dat = 0; - break; - case 3: - src_dat = 0; - break; - - default: - break; - } - - READ(dev->accel.dest + dev->accel.cx, poly_src); - if (dev->accel.multifunc[0x0a] & 2) { - poly_src = ((poly_src & wrt_mask) == wrt_mask); - } else { - poly_src = ((poly_src & rd_mask_polygon) == rd_mask_polygon); - } - - if (poly_src) { - dev->accel.fill_state ^= 1; - } + READ(dev->accel.dest + dev->accel.cx, mix_dat); + if ((mix_dat & rd_mask_polygon) == rd_mask_polygon) + dev->accel.fill_state = !dev->accel.fill_state; + READ(dev->accel.dest + dev->accel.cx, dest_dat); + old_dest_dat = dest_dat; if (dev->accel.fill_state) { - READ(dev->accel.dest + dev->accel.cx, dest_dat); - - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + if (!(rd_mask_polygon & 1) && (wrt_mask & 1)) { + MIX(mix_dat ^ rd_mask_polygon, dest_dat, mix_dat); + ibm8514_log("Filling c(%d,%d) without bit 0 of rdmask=%02x, wrtmask=%02x, mixdat=%02x, dest=%02x, old=%02x.\n", dev->accel.cx, dev->accel.cy, rd_mask_polygon, wrt_mask, mix_dat, dest_dat, old_dest_dat); + dest_dat &= ~rd_mask_polygon; + } else if ((rd_mask_polygon & 1) && (wrt_mask & 1)) { + ibm8514_log("Filling c(%d,%d) with bit 0 of rdmask=%02x, wrtmask=%02x.\n", dev->accel.cx, dev->accel.cy, rd_mask_polygon, wrt_mask); + dest_dat &= ~(rd_mask_polygon & wrt_mask); } + } else { + if (!(rd_mask_polygon & 1) && (wrt_mask & 1)) + dest_dat &= ~rd_mask_polygon; + else if ((rd_mask_polygon & 1) && (wrt_mask & 1)) + dest_dat &= ~(rd_mask_polygon & wrt_mask); + } + + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + ibm8514_log("Results c(%d,%d):rdmask=%02x, wrtmask=%02x, mix=%02x, destdat=%02x, nowrite=%d.\n", dev->accel.cx, dev->accel.cy, rd_mask_polygon, wrt_mask, mix_dat, dest_dat, dev->accel.cx_back); + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); } } - mix_dat <<= 1; - mix_dat |= 1; - - if (dev->accel.cmd & 0x20) { + if (dev->accel.cmd & 0x20) dev->accel.cx++; - } else { + else dev->accel.cx--; - } dev->accel.sx--; if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; dev->accel.fill_state = 0; + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - if (dev->accel.cmd & 0x20) { + if (dev->accel.cmd & 0x20) dev->accel.cx -= (dev->accel.sx) + 1; - } else { + else dev->accel.cx += (dev->accel.sx) + 1; - } if (dev->accel.cmd & 0x80) dev->accel.cy++; else dev->accel.cy--; - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24)) - dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); - else - dev->accel.dest = dev->accel.cy * dev->pitch; + dev->accel.dest = dev->accel.cy * dev->pitch; dev->accel.sy--; if (dev->accel.sy < 0) { - dev->accel.cur_x = dev->accel.cx; - dev->accel.cur_y = dev->accel.cy; + ibm8514_log(".\n"); return; } } } } else { + ibm8514_log("Rectangle Fill Normal CMD=%04x, CURRENT(%d,%d), sx=%d, FR(%02x), linedraw=%d.\n", dev->accel.cmd, dev->accel.cx, dev->accel.cy, dev->accel.sx, frgd_color, dev->accel.linedraw); while (count-- && dev->accel.sy >= 0) { if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { - switch (frgd_mix) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: src_dat = bkgd_color; if (!bkgd_mix && (dev->accel.cmd & 0x40) && ((dev->accel.frgd_mix & 0x1f) == 7) && ((dev->accel.bkgd_mix & 0x1f) == 3) && !dev->bpp && (bkgd_color == 0x00)) /*For some reason, the September 1992 Mach8/32 drivers for Win3.x don't set the background colors properly.*/ @@ -2961,13 +2917,17 @@ rect_fill: break; } + READ(dev->accel.dest + dev->accel.cx, dest_dat); if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; - MIX(1, dest_dat, src_dat); + MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + + if (dev->accel.cmd & 0x10) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } } } @@ -2981,11 +2941,12 @@ rect_fill: dev->accel.sx--; if (dev->accel.sx < 0) { + dev->accel.fill_state = 0; dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - if (dev->accel.cmd & 0x20) { + if (dev->accel.cmd & 0x20) dev->accel.cx -= (dev->accel.sx) + 1; - } else + else dev->accel.cx += (dev->accel.sx) + 1; if (dev->accel.cmd & 0x80) @@ -2993,7 +2954,7 @@ rect_fill: else dev->accel.cy--; - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24)) + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); else dev->accel.dest = dev->accel.cy * dev->pitch; @@ -3013,17 +2974,25 @@ rect_fill: } break; - case 5: /*Draw Polygon Boundary Line*/ + case 5: /*Draw Polygon Boundary Line*/ { if (!cpu_input) { dev->accel.cx = dev->accel.cur_x; - dev->accel.cy = dev->accel.cur_y; if (dev->accel.cur_x >= 0x600) dev->accel.cx |= ~0x5ff; - + dev->accel.cy = dev->accel.cur_y; if (dev->accel.cur_y >= 0x600) dev->accel.cy |= ~0x5ff; - dev->accel.oldcy = dev->accel.cy; - dev->accel.sy = 0; + + dev->accel.sy = dev->accel.maj_axis_pcnt_no_limit; + + if (dev->accel.cmd & 0x80) + dev->accel.oldcy = dev->accel.cy + 1; + else + dev->accel.oldcy = dev->accel.cy - 1; + + dev->accel.oldcx = 0; + + ibm8514_log("Polygon Boundary activated=%04x, len=%d, cur(%d,%d), frgdmix=%02x, err=%d, clipping: l=%d, r=%d, t=%d, b=%d, pixcntl=%02x.\n", dev->accel.cmd, dev->accel.sy, dev->accel.cur_x_nolimit, dev->accel.cy, dev->accel.frgd_mix & 0x1f, dev->accel.err_term, dev->accel.clip_left, clip_r, dev->accel.clip_top, clip_b, compare_mode, dev->accel.multifunc[0x0a]); if (ibm8514_cpu_src(svga)) { dev->data_available = 0; @@ -3036,160 +3005,200 @@ rect_fill: } } - while (count-- && (dev->accel.sy >= 0)) { - if ((dev->accel.cx) >= dev->accel.clip_left && ((dev->accel.cx) <= clip_r) && (dev->accel.cy) >= dev->accel.clip_top && (dev->accel.cy) <= clip_b) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; + if (dev->accel.cmd & 8) { + while (count-- && (dev->accel.sy >= 0)) { + if (dev->accel.cx < 0) + dev->accel.cx = 0; + if (dev->accel.cy < 0) + dev->accel.cy = 0; + + if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; + + default: + break; + } + + + READ((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + MIX(mix_dat & mix_mask, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + if (dev->accel.cmd & 0x10) { + if (dev->accel.sy && (dev->accel.cmd & 4)) { + if (dev->accel.oldcy != dev->accel.cy) { + WRITE((dev->accel.cy * dev->pitch) + (dev->accel.cx), dest_dat); + } + } else if (!(dev->accel.cmd & 4)) { + if (dev->accel.oldcy != dev->accel.cy) { + WRITE((dev->accel.cy * dev->pitch) + (dev->accel.cx), dest_dat); + } + } + } + } + } + + mix_dat <<= 1; + mix_dat |= 1; + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; + + if (!dev->accel.sy) + break; + + switch (dev->accel.cmd & 0xe0) { + case 0x00: + dev->accel.cx++; break; - case 1: - src_dat = frgd_color; + case 0x20: + dev->accel.cx++; + dev->accel.oldcy = dev->accel.cy; + dev->accel.cy--; break; - case 2: - src_dat = cpu_dat; + case 0x40: + dev->accel.oldcy = dev->accel.cy; + dev->accel.cy--; break; - case 3: - src_dat = 0; + case 0x60: + dev->accel.cx--; + dev->accel.oldcy = dev->accel.cy; + dev->accel.cy--; + break; + case 0x80: + dev->accel.cx--; + break; + case 0xa0: + dev->accel.cx--; + dev->accel.oldcy = dev->accel.cy; + dev->accel.cy++; + break; + case 0xc0: + dev->accel.oldcy = dev->accel.cy; + dev->accel.cy++; + break; + case 0xe0: + dev->accel.cx++; + dev->accel.oldcy = dev->accel.cy; + dev->accel.cy++; break; default: break; } - READ((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + dev->accel.sy--; + } + } else { + while (count-- && (dev->accel.sy >= 0)) { + if (dev->accel.cx < 0) + dev->accel.cx = 0; + if (dev->accel.cy < 0) + dev->accel.cy = 0; - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if (dev->accel.cmd & 4) { - if (dev->accel.sy < dev->accel.maj_axis_pcnt) { - if (dev->accel.cmd & 0x40) { - WRITE((dev->accel.cy * dev->pitch) + (dev->accel.cx), dest_dat); - } else { - if (dev->accel.cy == (dev->accel.oldcy + 1)) { - if (dev->accel.cmd & 0x20) { - if (dev->accel.err_term < (dev->accel.destx_distp + dev->accel.desty_axstp)) { - WRITE((dev->accel.cy * dev->pitch) + (dev->accel.cx), dest_dat); - } - } else { - if (dev->accel.err_term >= 0) { - WRITE((dev->accel.cy * dev->pitch) + (dev->accel.cx), dest_dat); - } - } - } - } - } - } else { - if (dev->accel.cmd & 0x40) { - WRITE((dev->accel.cy * dev->pitch) + (dev->accel.cx), dest_dat); - } else { - if (dev->accel.cy == (dev->accel.oldcy + 1)) { - if (dev->accel.cmd & 0x20) { - if (dev->accel.err_term < (dev->accel.destx_distp + dev->accel.desty_axstp)) { - WRITE((dev->accel.cy * dev->pitch) + (dev->accel.cx), dest_dat); - } + if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; + + default: + break; + } + + READ((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + MIX(mix_dat & mix_mask, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + + if ((dev->accel.cmd & 0x14) == 0x14) { + if (dev->accel.sy) { + if (dev->accel.cmd & 0x40) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); } else { - if (dev->accel.err_term >= 0) { - WRITE((dev->accel.cy * dev->pitch) + (dev->accel.cx), dest_dat); + if (dev->accel.oldcy != dev->accel.cy) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); } } } } } } - } - mix_dat <<= 1; - mix_dat |= 1; - if (dev->bpp) - cpu_dat >>= 16; - else - cpu_dat >>= 8; + mix_dat <<= 1; + mix_dat |= 1; + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; - if (dev->accel.sy == dev->accel.maj_axis_pcnt) { - break; - } - - /*Step major axis*/ - switch (dev->accel.cmd & 0xe0) { - case 0x00: - dev->accel.cx--; - break; - case 0x20: - dev->accel.cx++; - break; - case 0x40: - dev->accel.oldcy = dev->accel.cy; - dev->accel.cy--; - break; - case 0x60: - dev->accel.oldcy = dev->accel.cy; - dev->accel.cy--; - break; - case 0x80: - dev->accel.cx--; - break; - case 0xa0: - dev->accel.cx++; - break; - case 0xc0: - dev->accel.oldcy = dev->accel.cy; - dev->accel.cy++; - break; - case 0xe0: - dev->accel.oldcy = dev->accel.cy; - dev->accel.cy++; + if (!dev->accel.sy) break; - default: - break; - } - - if (dev->accel.err_term >= 0) { - dev->accel.err_term += dev->accel.destx_distp; - /*Step minor axis*/ - switch (dev->accel.cmd & 0xe0) { - case 0x00: - dev->accel.oldcy = dev->accel.cy; - dev->accel.cy--; - break; - case 0x20: - dev->accel.oldcy = dev->accel.cy; - dev->accel.cy--; - break; - case 0x40: - dev->accel.cx--; - break; - case 0x60: - dev->accel.cx++; - break; - case 0x80: - dev->accel.oldcy = dev->accel.cy; + if (dev->accel.cmd & 0x40) { + if (dev->accel.cmd & 0x80) dev->accel.cy++; - break; - case 0xa0: - dev->accel.oldcy = dev->accel.cy; - dev->accel.cy++; - break; - case 0xc0: - dev->accel.cx--; - break; - case 0xe0: - dev->accel.cx++; - break; + else + dev->accel.cy--; - default: - break; + if (dev->accel.err_term >= 0) { + dev->accel.err_term += dev->accel.destx_distp; + if (dev->accel.cmd & 0x20) + dev->accel.cx++; + else + dev->accel.cx--; + } else + dev->accel.err_term += dev->accel.desty_axstp; + } else { + if (dev->accel.cmd & 0x20) + dev->accel.cx++; + else + dev->accel.cx--; + + dev->accel.oldcy = dev->accel.cy; + if (dev->accel.err_term >= 0) { + dev->accel.err_term += dev->accel.destx_distp; + if (dev->accel.cmd & 0x80) + dev->accel.cy++; + else + dev->accel.cy--; + } else + dev->accel.err_term += dev->accel.desty_axstp; } - } else - dev->accel.err_term += dev->accel.desty_axstp; - dev->accel.sy++; + dev->accel.sy--; + } } - break; + } + break; - case 6: /*BitBlt*/ + case 6: /*BitBlt*/ if (!cpu_input) /*!cpu_input is trigger to start operation*/ { dev->accel.x_count = 0; @@ -3198,12 +3207,12 @@ rect_fill: dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; dev->accel.sy = dev->accel.multifunc[0] & 0x7ff; - dev->accel.dx = dev->accel.destx_distp; - dev->accel.dy = dev->accel.desty_axstp; + dev->accel.dx = dev->accel.destx; + dev->accel.dy = dev->accel.desty; - if (dev->accel.destx_distp >= 0x600) + if (dev->accel.destx >= 0x600) dev->accel.dx |= ~0x5ff; - if (dev->accel.desty_axstp >= 0x600) + if (dev->accel.desty >= 0x600) dev->accel.dy |= ~0x5ff; dev->accel.cx = dev->accel.cur_x; @@ -3216,6 +3225,7 @@ rect_fill: dev->accel.src = dev->accel.cy * dev->pitch; dev->accel.dest = dev->accel.dy * dev->pitch; + dev->accel.fill_state = 0; if (ibm8514_cpu_src(svga)) { if (dev->accel.cmd & 2) { @@ -3280,6 +3290,7 @@ bitblt_pix: if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; + MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); WRITE(dev->accel.dest + dev->accel.dx, dest_dat); @@ -3413,8 +3424,8 @@ bitblt_pix: dev->accel.cx = dev->accel.cur_x; if (dev->accel.cur_x >= 0x600) dev->accel.cx |= ~0x5ff; - dev->accel.dx = dev->accel.destx_distp; - if (dev->accel.destx_distp >= 0x600) + dev->accel.dx = dev->accel.destx; + if (dev->accel.destx >= 0x600) dev->accel.dx |= ~0x5ff; } } @@ -3444,6 +3455,7 @@ bitblt_pix: } else { while (count-- && (dev->accel.sy >= 0)) { if (dev->accel.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b) { + if (pixcntl == 3) { if (!(dev->accel.cmd & 0x10) && ((frgd_mix != 3) || (bkgd_mix != 3))) { READ(dev->accel.src + dev->accel.cx, mix_dat); @@ -3698,6 +3710,7 @@ bitblt: while (1) { if ((dx >= (((int64_t)dev->accel.clip_left) * 3)) && (dx <= (((uint64_t)clip_r) * 3)) && (dev->accel.dy >= (dev->accel.clip_top << 1)) && (dev->accel.dy <= (clip_b << 1))) { + READ(dev->accel.src + (dev->accel.ge_offset << 2) + cx, src_dat); READ(dev->accel.dest + (dev->accel.ge_offset << 2) + dx, dest_dat); @@ -3716,6 +3729,7 @@ bitblt: return; } + ibm8514_log("BitBLT 8514/A=%04x, selfrmix=%d, selbkmix=%d, d(%d,%d), c(%d,%d), pixcntl=%d, sy=%d, frgdmix=%02x, bkgdmix=%02x, rdmask=%02x, wrtmask=%02x, linedraw=%d.\n", dev->accel.cmd, frgd_mix, bkgd_mix, dev->accel.dx, dev->accel.dy, dev->accel.cx, dev->accel.cy, pixcntl, dev->accel.sy, dev->accel.frgd_mix & 0x1f, dev->accel.bkgd_mix & 0x1f, dev->accel.rd_mask, wrt_mask, dev->accel.linedraw); while (count-- && dev->accel.sy >= 0) { if ((dev->accel.dx >= dev->accel.clip_left) && (dev->accel.dx <= clip_r) && (dev->accel.dy >= dev->accel.clip_top) && (dev->accel.dy <= clip_b)) { @@ -3781,15 +3795,18 @@ bitblt: dev->accel.sx--; if (dev->accel.sx < 0) { + dev->accel.fill_state = 0; dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - if (dev->accel.cmd & 0x20) { - dev->accel.dx -= (dev->accel.sx) + 1; - dev->accel.cx -= (dev->accel.sx) + 1; - } else { - dev->accel.dx += (dev->accel.sx) + 1; - dev->accel.cx += (dev->accel.sx) + 1; - } + dev->accel.dx = dev->accel.destx; + + if (dev->accel.destx >= 0x600) + dev->accel.dx |= ~0x5ff; + + dev->accel.cx = dev->accel.cur_x; + + if (dev->accel.cur_x >= 0x600) + dev->accel.cx |= ~0x5ff; if (dev->accel.cmd & 0x80) { dev->accel.dy++; @@ -3803,9 +3820,8 @@ bitblt: dev->accel.src = dev->accel.cy * dev->pitch; dev->accel.sy--; - if (dev->accel.sy < 0) { + if (dev->accel.sy < 0) return; - } } } } @@ -3818,6 +3834,8 @@ bitblt: } } +#undef CLAMP + void ibm8514_render_8bpp(svga_t *svga) { diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 1fca83369..be034c6d5 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -149,6 +149,7 @@ typedef struct mach_t { int16_t cy_end; int16_t dx; int16_t dx_end; + int16_t dy; int16_t dy_end; int16_t dx_start; int16_t dy_start; @@ -165,6 +166,7 @@ typedef struct mach_t { int16_t width; int16_t src_width; int16_t height; + int16_t bleft, bright, btop, bbottom; int poly_src; int temp_cnt; int stepx; @@ -413,7 +415,7 @@ static void mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint32_t cpu_dat, mach_t *mach, ibm8514_t *dev) { int compare_mode; - int poly_src = 0; + uint16_t poly_src = 0; uint16_t rd_mask = dev->accel.rd_mask; uint16_t wrt_mask = dev->accel.wrt_mask; uint16_t dest_cmp_clr = dev->accel.color_cmp; @@ -463,7 +465,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (dev->accel_bpp == 24) mach_log("24BPP: CMDType=%d, cwh(%d,%d,%d,%d), dpconfig=%04x\n", cmd_type, clip_l, clip_r, clip_t, clip_b, mach->accel.dp_config); else - mach_log("BPP=%d, CMDType = %d, offs=%08x, DPCONFIG = %04x, cnt = %d, input = %d, mono_src = %d, frgdsel = %d, dstx = %d, dstxend = %d, pitch = %d, extcrt = %d, rw = %x, monpattern = %x.\n", dev->accel_bpp, cmd_type, mach->accel.ge_offset, mach->accel.dp_config, count, cpu_input, mono_src, frgd_sel, dev->accel.cur_x, mach->accel.dest_x_end, dev->ext_pitch, dev->ext_crt_pitch, mach->accel.dp_config & 1, mach->accel.mono_pattern_enable); + mach_log("RdMask=%04x, Clipping: l=%d, r=%d, t=%d, b=%d, LineDrawOpt=%04x, BPP=%d, CMDType = %d, offs=%08x, DPCONFIG = %04x, cnt = %d, input = %d, mono_src = %d, frgdsel = %d, d(%d,%d), dstxend = %d, pitch = %d, extcrt = %d, rw = %x, monpattern = %x.\n", rd_mask, clip_l, clip_r, clip_t, clip_b, mach->accel.linedraw_opt, dev->accel_bpp, cmd_type, mach->accel.ge_offset, mach->accel.dp_config, count, cpu_input, mono_src, frgd_sel, dev->accel.cur_x, dev->accel.cur_y, mach->accel.dest_x_end, dev->ext_pitch, dev->ext_crt_pitch, mach->accel.dp_config & 1, mach->accel.mono_pattern_enable); } switch (cmd_type) { @@ -568,6 +570,41 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } if (((dev->accel.dx) >= clip_l) && ((dev->accel.dx) <= clip_r) && ((dev->accel.dy) >= clip_t) && ((dev->accel.dy) <= clip_b)) { + switch (mix ? frgd_sel : bkgd_sel) { + case 0: + src_dat = dev->accel.bkgd_color; + break; + case 1: + src_dat = dev->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + if (mach_pixel_read(mach)) + src_dat = cpu_dat; + else { + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), src_dat); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), src_dat); + } + if (mono_src == 3) { + src_dat = (src_dat & rd_mask) == rd_mask; + } + } + break; + case 5: + if (mix) { + src_dat = mach->accel.color_pattern[((dev->accel.dx) + ((dev->accel.dy) << 3)) & mach->accel.patt_len]; + } else + src_dat = 0; + break; + + default: + break; + } + if (mach->accel.linedraw_opt & 0x02) { if (dev->bpp) { READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src); @@ -579,99 +616,64 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mach->accel.poly_fill = !mach->accel.poly_fill; } - if (!mach->accel.poly_fill || !(mach->accel.linedraw_opt & 0x02)) { - switch (mix ? frgd_sel : bkgd_sel) { - case 0: - src_dat = dev->accel.bkgd_color; - break; + if (mach->accel.poly_fill || !(mach->accel.linedraw_opt & 0x02)) { + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); + } + + switch (compare_mode) { case 1: - src_dat = dev->accel.frgd_color; + compare = 1; break; case 2: - src_dat = cpu_dat; + compare = (dest_dat >= dest_cmp_clr) ? 0 : 1; break; case 3: - if (mach_pixel_read(mach)) - src_dat = cpu_dat; - else { - if (dev->bpp) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), src_dat); - } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), src_dat); - } - if (mono_src == 3) { - src_dat = (src_dat & rd_mask) == rd_mask; - } - } + compare = (dest_dat < dest_cmp_clr) ? 0 : 1; + break; + case 4: + compare = (dest_dat != dest_cmp_clr) ? 0 : 1; break; case 5: - if (mix) { - src_dat = mach->accel.color_pattern[((dev->accel.dx) + ((dev->accel.dy) << 3)) & mach->accel.patt_len]; - } else - src_dat = 0; + compare = (dest_dat == dest_cmp_clr) ? 0 : 1; + break; + case 6: + compare = (dest_dat <= dest_cmp_clr) ? 0 : 1; + break; + case 7: + compare = (dest_dat > dest_cmp_clr) ? 0 : 1; break; default: break; } - if (dev->bpp) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); - } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); + if (!compare) { + if (mach_pixel_write(mach)) { + old_dest_dat = dest_dat; + MIX(mix, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } } - } - switch (compare_mode) { - case 1: - compare = 1; - break; - case 2: - compare = (dest_dat >= dest_cmp_clr) ? 0 : 1; - break; - case 3: - compare = (dest_dat < dest_cmp_clr) ? 0 : 1; - break; - case 4: - compare = (dest_dat != dest_cmp_clr) ? 0 : 1; - break; - case 5: - compare = (dest_dat == dest_cmp_clr) ? 0 : 1; - break; - case 6: - compare = (dest_dat <= dest_cmp_clr) ? 0 : 1; - break; - case 7: - compare = (dest_dat > dest_cmp_clr) ? 0 : 1; - break; - - default: - break; - } - - if (!compare) { - if (mach_pixel_write(mach)) { - old_dest_dat = dest_dat; - MIX(mix, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - } - } - - if (mach->accel.dp_config & 0x10) { - if (mach->accel.linedraw_opt & 0x04) { - if (dev->accel.sx < mach->accel.width) { + if (mach->accel.dp_config & 0x10) { + if (mach->accel.linedraw_opt & 0x04) { + if (((mono_src != 1) && (dev->accel.sx < mach->accel.width)) || ((mono_src == 1) && count)) { + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); + } + } + } else { if (dev->bpp) { WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); } else { WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); } } - } else { - if (dev->bpp) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); - } else { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); - } } } } @@ -779,6 +781,41 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } if (((dev->accel.dx) >= clip_l) && ((dev->accel.dx) <= clip_r) && ((dev->accel.dy) >= clip_t) && ((dev->accel.dy) <= clip_b)) { + switch (mix ? frgd_sel : bkgd_sel) { + case 0: + src_dat = dev->accel.bkgd_color; + break; + case 1: + src_dat = dev->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + if (mach_pixel_read(mach)) + src_dat = cpu_dat; + else { + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), src_dat); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), src_dat); + } + if (mono_src == 3) { + src_dat = (src_dat & rd_mask) == rd_mask; + } + } + break; + case 5: + if (mix) { + src_dat = mach->accel.color_pattern[((dev->accel.dx) + ((dev->accel.dy) << 3)) & mach->accel.patt_len]; + } else + src_dat = 0; + break; + + default: + break; + } + if (mach->accel.linedraw_opt & 0x02) { if (dev->bpp) { READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src); @@ -790,99 +827,64 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mach->accel.poly_fill = !mach->accel.poly_fill; } - if (!mach->accel.poly_fill || !(mach->accel.linedraw_opt & 0x02)) { - switch (mix ? frgd_sel : bkgd_sel) { - case 0: - src_dat = dev->accel.bkgd_color; - break; + if (mach->accel.poly_fill || !(mach->accel.linedraw_opt & 0x02)) { + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); + } + + switch (compare_mode) { case 1: - src_dat = dev->accel.frgd_color; + compare = 1; break; case 2: - src_dat = cpu_dat; + compare = (dest_dat >= dest_cmp_clr) ? 0 : 1; break; case 3: - if (mach_pixel_read(mach)) - src_dat = cpu_dat; - else { - if (dev->bpp) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), src_dat); - } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), src_dat); - } - if (mono_src == 3) { - src_dat = (src_dat & rd_mask) == rd_mask; - } - } + compare = (dest_dat < dest_cmp_clr) ? 0 : 1; + break; + case 4: + compare = (dest_dat != dest_cmp_clr) ? 0 : 1; break; case 5: - if (mix) { - src_dat = mach->accel.color_pattern[((dev->accel.dx) + ((dev->accel.dy) << 3)) & mach->accel.patt_len]; - } else - src_dat = 0; + compare = (dest_dat == dest_cmp_clr) ? 0 : 1; + break; + case 6: + compare = (dest_dat <= dest_cmp_clr) ? 0 : 1; + break; + case 7: + compare = (dest_dat > dest_cmp_clr) ? 0 : 1; break; default: break; } - if (dev->bpp) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); - } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); + if (!compare) { + if (mach_pixel_write(mach)) { + old_dest_dat = dest_dat; + MIX(mix, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } } - } - switch (compare_mode) { - case 1: - compare = 1; - break; - case 2: - compare = (dest_dat >= dest_cmp_clr) ? 0 : 1; - break; - case 3: - compare = (dest_dat < dest_cmp_clr) ? 0 : 1; - break; - case 4: - compare = (dest_dat != dest_cmp_clr) ? 0 : 1; - break; - case 5: - compare = (dest_dat == dest_cmp_clr) ? 0 : 1; - break; - case 6: - compare = (dest_dat <= dest_cmp_clr) ? 0 : 1; - break; - case 7: - compare = (dest_dat > dest_cmp_clr) ? 0 : 1; - break; - - default: - break; - } - - if (!compare) { - if (mach_pixel_write(mach)) { - old_dest_dat = dest_dat; - MIX(mix, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - } - } - - if (mach->accel.dp_config & 0x10) { - if (mach->accel.linedraw_opt & 0x04) { - if (dev->accel.sx < mach->accel.width) { + if (mach->accel.dp_config & 0x10) { + if (mach->accel.linedraw_opt & 0x04) { + if (((mono_src != 1) && (dev->accel.sx < mach->accel.width)) || ((mono_src == 1) && count)) { + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); + } + } + } else { if (dev->bpp) { WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); } else { WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); } } - } else { - if (dev->bpp) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); - } else { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); - } } } } @@ -928,6 +930,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 dev->accel.sx++; } } + mach->accel.poly_fill = 0; dev->accel.cur_x = dev->accel.dx; dev->accel.cur_y = dev->accel.dy; break; @@ -1046,10 +1049,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 else dev->accel.src = (mach->accel.ge_offset << 2) + (dev->accel.cy * (dev->pitch)); - if ((dev->accel_bpp == 24) && (frgd_sel == 5)) { + if ((dev->accel_bpp == 24) && (frgd_sel == 5)) mach_log("BitBLT=%04x, WH(%d,%d), SRCWidth=%d, c(%d,%d), s(%d,%d).\n", mach->accel.dp_config, mach->accel.width, mach->accel.height, mach->accel.src_width, dev->accel.dx, dev->accel.dy, dev->accel.cx, dev->accel.cy); - } else - mach_log("BitBLT=%04x, Pitch=%d, C(%d,%d), SRCWidth=%d, WH(%d,%d), geoffset=%08x.\n", mach->accel.dp_config, dev->ext_pitch, dev->accel.cx, dev->accel.cy, mach->accel.src_width, mach->accel.width, mach->accel.height, (mach->accel.ge_offset << 2)); + else if (mach->accel.dp_config & 0x02) + mach_log("BitBLT=%04x, Pitch=%d, C(%d,%d), D(%d,%d), SRCWidth=%d, SRCXStep=%d, WH(%d,%d), clipt=%d, clipb=%d, geoffset=%08x.\n", mach->accel.dp_config, dev->ext_pitch, mach->accel.src_x, mach->accel.src_y, dev->accel.cur_x, dev->accel.cur_y, mach->accel.src_width, mach->accel.src_stepx, mach->accel.width, mach->accel.height, clip_t, clip_b, (mach->accel.ge_offset << 2)); if (mono_src == 1) { if ((mach->accel.mono_pattern_enable) && !(mach->accel.patt_len_reg & 0x4000)) { @@ -1183,14 +1186,14 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } if (((dev->accel.dx) >= clip_l) && ((dev->accel.dx) <= clip_r) && ((dev->accel.dy) >= clip_t) && ((dev->accel.dy) <= clip_b)) { - if (mach->accel.dp_config & 0x02) { - READ(dev->accel.src + (dev->accel.cx), poly_src); + if ((mach->accel.dp_config & 0x02) || (mach->accel.linedraw_opt & 0x02)) { + READ(dev->accel.src + dev->accel.cx, poly_src); poly_src = ((poly_src & rd_mask) == rd_mask); if (poly_src) - mach->accel.poly_fill = !mach->accel.poly_fill; + mach->accel.poly_fill ^= 1; } - if (!mach->accel.poly_fill || !(mach->accel.dp_config & 0x02)) { + if (mach->accel.poly_fill || !(mach->accel.dp_config & 0x02) || !(mach->accel.linedraw_opt & 0x02)) { switch (mix ? frgd_sel : bkgd_sel) { case 0: src_dat = dev->accel.bkgd_color; @@ -1205,7 +1208,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (mach_pixel_read(mach)) src_dat = cpu_dat; else { - READ(dev->accel.src + (dev->accel.cx), src_dat); + READ(dev->accel.src + dev->accel.cx, src_dat); if (mono_src == 3) src_dat = (src_dat & rd_mask) == rd_mask; } @@ -1223,62 +1226,62 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 default: break; } - } - if ((dev->accel_bpp == 24) && (mono_src == 1) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) { - if (dev->accel.sy & 1) { - READ(dev->accel.dest + dev->accel.dx - dev->ext_pitch, dest_dat); + if ((dev->accel_bpp == 24) && (mono_src == 1) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) { + if (dev->accel.sy & 1) { + READ(dev->accel.dest + dev->accel.dx - dev->ext_pitch, dest_dat); + } else { + READ(dev->accel.dest + dev->accel.dx, dest_dat); + } } else { READ(dev->accel.dest + dev->accel.dx, dest_dat); } - } else { - READ(dev->accel.dest + dev->accel.dx, dest_dat); - } - switch (compare_mode) { - case 1: - compare = 1; - break; - case 2: - compare = (dest_dat >= dest_cmp_clr) ? 0 : 1; - break; - case 3: - compare = (dest_dat < dest_cmp_clr) ? 0 : 1; - break; - case 4: - compare = (dest_dat != dest_cmp_clr) ? 0 : 1; - break; - case 5: - compare = (dest_dat == dest_cmp_clr) ? 0 : 1; - break; - case 6: - compare = (dest_dat <= dest_cmp_clr) ? 0 : 1; - break; - case 7: - compare = (dest_dat > dest_cmp_clr) ? 0 : 1; - break; + switch (compare_mode) { + case 1: + compare = 1; + break; + case 2: + compare = (dest_dat >= dest_cmp_clr) ? 0 : 1; + break; + case 3: + compare = (dest_dat < dest_cmp_clr) ? 0 : 1; + break; + case 4: + compare = (dest_dat != dest_cmp_clr) ? 0 : 1; + break; + case 5: + compare = (dest_dat == dest_cmp_clr) ? 0 : 1; + break; + case 6: + compare = (dest_dat <= dest_cmp_clr) ? 0 : 1; + break; + case 7: + compare = (dest_dat > dest_cmp_clr) ? 0 : 1; + break; - default: - break; - } - - if (!compare) { - if (mach_pixel_write(mach)) { - old_dest_dat = dest_dat; - MIX(mix, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + default: + break; } - } - if (mach->accel.dp_config & 0x10) { - if ((dev->accel_bpp == 24) && (mono_src == 1) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) { - if (dev->accel.sy & 1) { - WRITE(dev->accel.dest + dev->accel.dx - dev->ext_pitch, dest_dat); + if (!compare) { + if (mach_pixel_write(mach)) { + old_dest_dat = dest_dat; + MIX(mix, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } + } + + if (mach->accel.dp_config & 0x10) { + if ((dev->accel_bpp == 24) && (mono_src == 1) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) { + if (dev->accel.sy & 1) { + WRITE(dev->accel.dest + dev->accel.dx - dev->ext_pitch, dest_dat); + } else { + WRITE(dev->accel.dest + dev->accel.dx, dest_dat); + } } else { WRITE(dev->accel.dest + dev->accel.dx, dest_dat); } - } else { - WRITE(dev->accel.dest + dev->accel.dx, dest_dat); } } } @@ -1288,7 +1291,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 else cpu_dat >>= 8; - if ((mono_src == 3) || (frgd_sel == 3) || (bkgd_sel == 3)) { + if ((mono_src == 3) || (frgd_sel == 3) || (bkgd_sel == 3) || (mach->accel.dp_config & 0x02)) { dev->accel.cx += mach->accel.src_stepx; mach->accel.sx++; if (mach->accel.sx >= mach->accel.src_width) { @@ -1334,7 +1337,6 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 dev->accel.sx++; if (dev->accel.sx >= mach->accel.width) { - mach->accel.poly_fill = 0; dev->accel.sx = 0; if (mach->accel.stepx == -1) dev->accel.dx += mach->accel.width; @@ -1344,6 +1346,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 dev->accel.dy += mach->accel.stepy; dev->accel.sy++; + mach->accel.poly_fill = 0; if (dev->bpp) dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * (dev->pitch)); else @@ -1362,7 +1365,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 return; } if (dev->accel.sy >= mach->accel.height) { - if ((mono_src == 2) || (mono_src == 3) || (frgd_sel == 3) || (bkgd_sel == 3)) + if ((mono_src == 2) || (mono_src == 3) || (frgd_sel == 3) || (bkgd_sel == 3) || (mach->accel.dp_config & 0x02) || (mach->accel.linedraw_opt & 0x02)) return; if ((mono_src == 1) && (frgd_sel == 5) && (dev->accel_bpp == 24) && (mach->accel.patt_len_reg & 0x4000)) return; @@ -1397,7 +1400,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 dev->accel.sx = 0; - mach_log("Linedraw: c(%d,%d), d(%d,%d), cend(%d,%d).\n", dev->accel.cur_x, dev->accel.cur_y, dev->accel.dx, dev->accel.dy, mach->accel.cx_end_line, mach->accel.cy_end_line); + mach_log("Linedraw: c(%d,%d), d(%d,%d), cend(%d,%d), bounds: l=%d, r=%d, t=%d, b=%d.\n", dev->accel.cur_x, dev->accel.cur_y, dev->accel.dx, dev->accel.dy, mach->accel.cx_end_line, mach->accel.cy_end_line, mach->accel.bleft, mach->accel.bright, mach->accel.btop, mach->accel.bbottom); if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) { if (mach_pixel_write(mach)) { @@ -1439,7 +1442,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mix_dat <<= 1; mix_dat |= 1; - if (((dev->accel.cx) >= clip_l) && ((dev->accel.cx) <= clip_r) && ((dev->accel.cy) >= clip_t) && ((dev->accel.cy) <= clip_b)) { + if ((dev->accel.cx >= clip_l) && (dev->accel.cx <= clip_r) && (dev->accel.cy >= clip_t) && (dev->accel.cy <= clip_b)) { mach->accel.clip_overrun = 0; switch (mix ? frgd_sel : bkgd_sel) { case 0: @@ -1454,14 +1457,13 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 case 3: if (mach_pixel_read(mach)) src_dat = cpu_dat; - else { + else src_dat = 0; - } break; case 5: - if (mix) { + if (mix) src_dat = mach->accel.color_pattern[((dev->accel.cx) + ((dev->accel.cy) << 3)) & mach->accel.patt_len]; - } else + else src_dat = 0; break; @@ -1509,7 +1511,15 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); } } - if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) { + if (mach->accel.linedraw_opt & 0x04) { + if (count) { + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } + } + } else { if (dev->bpp) { WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } else { @@ -1561,8 +1571,14 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 break; } - if (((dev->accel.cx) >= clip_l) && ((dev->accel.cx) <= clip_r) && ((dev->accel.cy) >= clip_t) && ((dev->accel.cy) <= clip_b)) { + if ((dev->accel.cx >= clip_l) && (dev->accel.cx <= clip_r) && (dev->accel.cy >= clip_t) && (dev->accel.cy <= clip_b)) { mach->accel.clip_overrun = 0; + if (mach->accel.linedraw_opt & 0x02) { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src); + if (poly_src) + mach->accel.poly_fill = !mach->accel.poly_fill; + } + switch (mix ? frgd_sel : bkgd_sel) { case 0: src_dat = dev->accel.bkgd_color; @@ -1627,7 +1643,9 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (!compare) { if (mach_pixel_write(mach)) { old_dest_dat = dest_dat; - MIX(mix, dest_dat, src_dat); + if (mach->accel.poly_fill || !(mach->accel.linedraw_opt & 0x02)) { + MIX(mix, dest_dat, src_dat); + } dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); } } @@ -1683,7 +1701,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mix_dat <<= 1; mix_dat |= 1; - if (((dev->accel.cx) >= clip_l) && ((dev->accel.cx) <= clip_r) && ((dev->accel.cy) >= clip_t) && ((dev->accel.cy) <= clip_b)) { + if ((dev->accel.cx >= clip_l) && (dev->accel.cx <= clip_r) && (dev->accel.cy >= clip_t) && (dev->accel.cy <= clip_b)) { mach->accel.clip_overrun = 0; switch (mix ? frgd_sel : bkgd_sel) { case 0: @@ -1754,10 +1772,20 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) { - if (dev->bpp) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + if (mach->accel.linedraw_opt & 0x04) { + if (count) { + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } + } } else { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } } } } else @@ -1805,8 +1833,9 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 break; } - if (((dev->accel.cx) >= clip_l) && ((dev->accel.cx) <= clip_r) && ((dev->accel.cy) >= clip_t) && ((dev->accel.cy) <= clip_b)) { + if ((dev->accel.cx >= clip_l) && (dev->accel.cx <= clip_r) && (dev->accel.cy >= clip_t) && (dev->accel.cy <= clip_b)) { mach->accel.clip_overrun = 0; + switch (mix ? frgd_sel : bkgd_sel) { case 0: src_dat = dev->accel.bkgd_color; @@ -1915,6 +1944,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } } } + mach->accel.poly_fill = 0; mach->accel.line_array[(cmd_type == 4) ? 4 : 0] = dev->accel.cx; mach->accel.line_array[(cmd_type == 4) ? 5 : 1] = dev->accel.cy; dev->accel.cur_x = mach->accel.line_array[(cmd_type == 4) ? 4 : 0]; @@ -2828,9 +2858,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0xf6ee: if (len == 1) { dev->accel.cur_y = (dev->accel.cur_y & 0x700) | val; - } else { + } else dev->accel.cur_y = val & 0x7ff; - } break; case 0x82e9: case 0xc2e9: @@ -2844,9 +2873,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0xc6e8: if (len == 1) { dev->accel.cur_x = (dev->accel.cur_x & 0x700) | val; - } else { + } else dev->accel.cur_x = val & 0x7ff; - } break; case 0x86e9: case 0xc6e9: @@ -2861,6 +2889,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u dev->accel.desty_axstp = (dev->accel.desty_axstp & 0x3f00) | val; else { mach->accel.src_y = val; + dev->accel.desty = val & 0x07ff; dev->accel.desty_axstp = val & 0x3fff; if (val & 0x2000) dev->accel.desty_axstp |= ~0x1fff; @@ -2881,6 +2910,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u dev->accel.destx_distp = (dev->accel.destx_distp & 0x3f00) | val; else { mach->accel.src_x = val; + dev->accel.destx = val & 0x07ff; dev->accel.destx_distp = val & 0x3fff; if (val & 0x2000) dev->accel.destx_distp |= ~0x1fff; @@ -2901,7 +2931,6 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u fallthrough; case 0xd2e8: - mach_log("92E8 = %04x\n", val); if (len == 1) dev->accel.err_term = (dev->accel.err_term & 0x3f00) | val; else { @@ -2926,6 +2955,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u else { mach->accel.test = val & 0x1fff; dev->accel.maj_axis_pcnt = val & 0x07ff; + dev->accel.maj_axis_pcnt_no_limit = val; } break; case 0x96e9: @@ -2944,7 +2974,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u dev->data_available = 0; dev->data_available2 = 0; dev->accel.cmd = val; - mach_log("CMD8514 = %04x.\n", val); + mach_log("CMD8514=%04x, len=%d, pixcntl=%02x.\n", val, len, dev->accel.multifunc[0x0a]); mach->accel.cmd_type = -1; if (port == 0xdae8) { if (dev->accel.cmd & 0x100) @@ -3192,8 +3222,10 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0xeae8: if (len == 1) dev->accel.wrt_mask = (dev->accel.wrt_mask & 0x00ff) | val; - else + else { dev->accel.wrt_mask = val; + mach_log("WrtMask=%04x.\n", val); + } break; case 0xaae9: case 0xeae9: @@ -3205,8 +3237,10 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0xeee8: if (len == 1) dev->accel.rd_mask = (dev->accel.rd_mask & 0x00ff) | val; - else + else { dev->accel.rd_mask = val; + mach_log("ReadMask=%04x.\n", val); + } break; case 0xaee9: case 0xeee9: @@ -3344,7 +3378,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u mach->accel.bres_count = (mach->accel.bres_count & 0x700) | val; else { mach->accel.bres_count = val & 0x7ff; - mach_log("96EE line draw.\n"); + mach_log("BresenhamDraw = %04x.\n", mach->accel.dp_config); dev->data_available = 0; dev->data_available2 = 0; mach->accel.cmd_type = 1; @@ -3372,6 +3406,16 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u mach->accel.linedraw_opt = (mach->accel.linedraw_opt & 0xff00) | val; else { mach->accel.linedraw_opt = val; + mach->accel.bbottom = dev->accel.multifunc[3] & 0x7ff; + mach->accel.btop = dev->accel.clip_top & 0x7ff; + mach->accel.bleft = dev->accel.clip_left & 0x7ff; + mach->accel.bright = dev->accel.multifunc[4] & 0x7ff; + if (mach->accel.linedraw_opt & 0x100) { + mach->accel.bbottom = 2047; + mach->accel.btop = 0; + mach->accel.bleft = 0; + mach->accel.bright = 2047; + } } break; case 0xa2ef: @@ -3404,7 +3448,6 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u break; case 0xaeee: - mach_log("AEEE write val = %04x.\n", val); if (len == 1) mach->accel.dest_y_end = (mach->accel.dest_y_end & 0x700) | val; else { @@ -3471,7 +3514,6 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u break; case 0xcaee: - mach_log("CAEE write val = %04x.\n", val); if (len == 1) mach->accel.scan_to_x = (mach->accel.scan_to_x & 0x700) | val; else { @@ -3609,8 +3651,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u break; case 0xfeee: - if (mach->accel.dp_config == 0x2231 || mach->accel.dp_config == 0x2211) - mach_log("FEEE val = %d, lineidx = %d, DPCONFIG = %04x, CPUCX = %04x.\n", val, mach->accel.line_idx, mach->accel.dp_config, CX); + mach_log("LineDraw = %04x.\n", mach->accel.dp_config); if (len != 1) { mach->accel.line_array[mach->accel.line_idx] = val; dev->accel.cur_x = mach->accel.line_array[(mach->accel.line_idx == 4) ? 4 : 0]; @@ -3637,6 +3678,7 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) { svga_t *svga = &mach->svga; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint8_t old = 0; mach_log("[%04X:%08X]: Port NORMAL OUT=%04x, val=%04x.\n", CS, cpu_state.pc, port, val); @@ -3709,10 +3751,27 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) break; case 0x42e8: - dev->subsys_stat &= ~val; + old = dev->subsys_stat; + if (val & 1) + dev->subsys_stat &= ~1; + if (val & 2) + dev->subsys_stat &= ~2; + if (val & 4) + dev->subsys_stat &= ~4; + if (val & 8) + dev->subsys_stat &= ~8; break; case 0x42e9: + old = dev->subsys_cntl; dev->subsys_cntl = val; + if ((old ^ val) & 1) + dev->subsys_stat |= 1; + if ((old ^ val) & 2) + dev->subsys_stat |= 2; + if ((old ^ val) & 4) + dev->subsys_stat |= 4; + if ((old ^ val) & 8) + dev->subsys_stat |= 8; break; case 0x4ae8: @@ -3860,14 +3919,12 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x52ef: mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); WRITE8(port, mach->accel.scratch0, val); - mach->ext_on[port & 1] = 1; break; case 0x56ee: case 0x56ef: mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); WRITE8(port, mach->accel.scratch1, val); - mach->ext_on[port & 1] = 1; break; case 0x5aee: @@ -4376,16 +4433,17 @@ mach_accel_in(uint16_t port, mach_t *mach) uint8_t temp = 0; uint16_t vpos = 0; uint16_t vblankend = svga->vblankstart + svga->crtc[0x16]; + int cmd; switch (port) { case 0x2e8: vpos = dev->vc & 0x7ff; if (vblankend > dev->v_total) { vblankend -= dev->v_total; - if (vpos >= svga->vblankstart || vpos <= vblankend) + if ((vpos >= svga->vblankstart) || (vpos <= vblankend)) temp |= 2; } else { - if (vpos >= svga->vblankstart && vpos <= vblankend) + if ((vpos >= svga->vblankstart) && (vpos <= vblankend)) temp |= 2; } break; @@ -4412,14 +4470,17 @@ mach_accel_in(uint16_t port, mach_t *mach) case 0x42e8: case 0x42e9: + cmd = dev->accel.cmd >> 13; vpos = dev->vc & 0x7ff; - if (vblankend > dev->v_total) { - vblankend -= dev->v_total; - if (vpos >= svga->vblankstart || vpos <= vblankend) - dev->subsys_stat |= 1; - } else { - if (vpos >= svga->vblankstart && vpos <= vblankend) - dev->subsys_stat |= 1; + if (!(dev->subsys_stat & 1)) { + if (vblankend > dev->v_total) { + vblankend -= dev->v_total; + if ((vpos >= svga->vblankstart) || (vpos <= vblankend)) + dev->subsys_stat |= 1; + } else { + if ((vpos >= svga->vblankstart) && (vpos <= vblankend)) + dev->subsys_stat |= 1; + } } if (port & 1) { @@ -4534,22 +4595,22 @@ mach_accel_in(uint16_t port, mach_t *mach) case 0x72ee: case 0x72ef: - READ8(port, dev->accel.clip_left); + READ8(port, (mach->accel.bleft)); break; case 0x76ee: case 0x76ef: - READ8(port, dev->accel.clip_top); + READ8(port, (mach->accel.btop)); break; case 0x7aee: case 0x7aef: - READ8(port, dev->accel.multifunc[4]); + READ8(port, (mach->accel.bright)); break; case 0x7eee: case 0x7eef: - READ8(port, dev->accel.multifunc[3]); + READ8(port, (mach->accel.bbottom)); break; default: From a1ef3c47fcfd77faa245f56886950b1b5a7282b8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 6 Jan 2024 00:05:43 +0100 Subject: [PATCH 203/936] 8514/a and ATi Mach 8: Fix the recently introduced warnings. --- src/video/vid_8514a.c | 3 --- src/video/vid_ati_mach8.c | 2 -- 2 files changed, 5 deletions(-) diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 576562f23..864a88978 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -1224,15 +1224,12 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat int compare_mode = dev->accel.multifunc[0x0a] & 0x38; int cmd = dev->accel.cmd >> 13; uint16_t wrt_mask = dev->accel.wrt_mask; - uint16_t wrt_mask_polygon = dev->accel.wrt_mask; uint16_t rd_mask = dev->accel.rd_mask; uint16_t rd_mask_polygon = dev->accel.rd_mask; uint16_t frgd_color = dev->accel.frgd_color; uint16_t bkgd_color = dev->accel.bkgd_color; uint32_t old_mix_dat; int and3 = dev->accel.cur_x & 3; - uint16_t poly_src = 0; - uint16_t old_poly_src = 0; if (!dev->bpp) { compare &= 0xff; diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index be034c6d5..21f6abd29 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -4433,7 +4433,6 @@ mach_accel_in(uint16_t port, mach_t *mach) uint8_t temp = 0; uint16_t vpos = 0; uint16_t vblankend = svga->vblankstart + svga->crtc[0x16]; - int cmd; switch (port) { case 0x2e8: @@ -4470,7 +4469,6 @@ mach_accel_in(uint16_t port, mach_t *mach) case 0x42e8: case 0x42e9: - cmd = dev->accel.cmd >> 13; vpos = dev->vc & 0x7ff; if (!(dev->subsys_stat & 1)) { if (vblankend > dev->v_total) { From 937e2a52f8063584f4230ea01667c2fd69f03076 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 6 Jan 2024 01:51:20 +0100 Subject: [PATCH 204/936] SiS 5571, Daewoo Compaq, speed up AT / PS/2 KBC (does not appear to break anything from months of testing) and fix AT / PS/2 keyboard reset to fix the Samsung SPC7700LP-W soft reset. --- src/chipset/sis_5511.c | 42 +- src/chipset/sis_5571.c | 1605 +++++++++++++++++++++++------------ src/cpu/cpu.c | 9 + src/cpu/cpu.h | 8 +- src/cpu/x86.c | 2 + src/device/kbc_at.c | 49 +- src/device/keyboard_at.c | 20 +- src/include/86box/machine.h | 1 + src/machine/m_at_socket7.c | 35 +- src/machine/machine_table.c | 76 +- 10 files changed, 1241 insertions(+), 606 deletions(-) diff --git a/src/chipset/sis_5511.c b/src/chipset/sis_5511.c index 5699fa450..e58066c95 100644 --- a/src/chipset/sis_5511.c +++ b/src/chipset/sis_5511.c @@ -262,7 +262,7 @@ sis_5511_write(UNUSED(int func), int addr, uint8_t val, void *priv) case 0x7a: /* DRAM Bank Register 2-1 */ case 0x7c: /* DRAM Bank Register 3-0 */ case 0x7e: /* DRAM Bank Register 3-1 */ - spd_write_drbs(dev->regs, 0x70, 0x7e, 0x82); + spd_write_drbs(dev->pci_conf, 0x70, 0x7e, 0x82); break; case 0x71: /* DRAM Bank Register 0-0 */ @@ -579,16 +579,19 @@ sis_5513_ide_write(int addr, uint8_t val, sis_5511_t *dev) break; case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */ - case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */ case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */ - case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */ case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */ - case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */ case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */ - case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */ case 0x48: /* IDE Command Recovery Time Control */ + dev->pci_conf_sb[1][addr] = val & 0x0f; + break; + + case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */ + case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */ + case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */ + case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */ case 0x49: /* IDE Command Active Time Control */ - dev->pci_conf_sb[1][addr] = val; + dev->pci_conf_sb[1][addr] = val & 0x07; break; case 0x4a: /* IDE General Control Register 0 */ @@ -659,7 +662,11 @@ sis_5513_read(int func, int addr, void *priv) sis_5511_log("SiS 5513 P2I: [R] dev->pci_conf_sb[0][%02X] = %02X\n", addr, ret); } else if (func == 0x01) { - ret = dev->pci_conf_sb[func][addr]; + if (addr == 0x3d) + ret = (((dev->pci_conf_sb[0x01][0x4b] & 0xc0) == 0xc0) || + (dev->pci_conf_sb[0x01][0x09] & 0x05)) ? PCI_INTA : 0x00; + else + ret = dev->pci_conf_sb[func][addr]; sis_5511_log("SiS 5513 IDE: [R] dev->pci_conf_sb[1][%02X] = %02X\n", addr, ret); } @@ -785,7 +792,9 @@ sis_5511_reset(void *priv) dev->pci_conf[0x74] = dev->pci_conf[0x76] = 0x04; dev->pci_conf[0x78] = dev->pci_conf[0x7a] = 0x04; dev->pci_conf[0x7c] = dev->pci_conf[0x7e] = 0x04; + dev->pci_conf[0x71] = dev->pci_conf[0x75] = 0x00; dev->pci_conf[0x73] = dev->pci_conf[0x77] = 0x80; + dev->pci_conf[0x79] = dev->pci_conf[0x7d] = 0x00; dev->pci_conf[0x7b] = dev->pci_conf[0x7f] = 0x80; dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00; dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00; @@ -873,6 +882,23 @@ sis_5511_reset(void *priv) dev->pci_conf_sb[1][0x20] = 0x01; dev->pci_conf_sb[1][0x21] = 0xf0; dev->pci_conf_sb[1][0x22] = dev->pci_conf_sb[1][0x23] = 0x00; + dev->pci_conf_sb[1][0x24] = dev->pci_conf_sb[1][0x25] = 0x00; + dev->pci_conf_sb[1][0x26] = dev->pci_conf_sb[1][0x27] = 0x00; + dev->pci_conf_sb[1][0x28] = dev->pci_conf_sb[1][0x29] = 0x00; + dev->pci_conf_sb[1][0x2a] = dev->pci_conf_sb[1][0x2b] = 0x00; + dev->pci_conf_sb[1][0x2c] = dev->pci_conf_sb[1][0x2d] = 0x00; + dev->pci_conf_sb[1][0x2e] = dev->pci_conf_sb[1][0x2f] = 0x00; + dev->pci_conf_sb[1][0x30] = dev->pci_conf_sb[1][0x31] = 0x00; + dev->pci_conf_sb[1][0x32] = dev->pci_conf_sb[1][0x33] = 0x00; + dev->pci_conf_sb[1][0x40] = dev->pci_conf_sb[1][0x41] = 0x00; + dev->pci_conf_sb[1][0x42] = dev->pci_conf_sb[1][0x43] = 0x00; + dev->pci_conf_sb[1][0x44] = dev->pci_conf_sb[1][0x45] = 0x00; + dev->pci_conf_sb[1][0x46] = dev->pci_conf_sb[1][0x47] = 0x00; + dev->pci_conf_sb[1][0x48] = dev->pci_conf_sb[1][0x49] = 0x00; + dev->pci_conf_sb[1][0x4a] = 0x06; + dev->pci_conf_sb[1][0x4b] = 0x00; + dev->pci_conf_sb[1][0x4c] = dev->pci_conf_sb[1][0x4d] = 0x00; + dev->pci_conf_sb[1][0x4e] = dev->pci_conf_sb[1][0x4f] = 0x00; sis_5513_ide_irq_handler(dev); sis_5513_ide_handler(dev); @@ -896,8 +922,6 @@ sis_5511_init(UNUSED(const device_t *info)) sis_5511_t *dev = (sis_5511_t *) calloc(1, sizeof(sis_5511_t)); uint8_t pit_is_fast = (((pit_mode == -1) && is486) || (pit_mode == 1)); - memset(dev, 0, sizeof(sis_5511_t)); - /* Device 0: SiS 5511 */ pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5511_read, sis_5511_write, dev, &dev->nb_slot); /* Device 1: SiS 5513 */ diff --git a/src/chipset/sis_5571.c b/src/chipset/sis_5571.c index f130ecd8a..007a96178 100644 --- a/src/chipset/sis_5571.c +++ b/src/chipset/sis_5571.c @@ -6,13 +6,11 @@ * * This file is part of the 86Box distribution. * - * Implementation of the SiS 5571 Chipset. + * Implementation of the SiS 5571 Pentium PCI/ISA Chipset. * + * Authors: Miran Grca, * - * - * Authors: Tiseno100, - * - * Copyright 2021 Tiseno100. + * Copyright 2023-2024 Miran Grca. */ #include #include @@ -26,36 +24,26 @@ #include <86box/io.h> #include <86box/timer.h> -#include <86box/dma.h> +// #include <86box/dma.h> #include <86box/mem.h> -#include <86box/pci.h> -#include <86box/pic.h> -#include <86box/plat_unused.h> -#include <86box/port_92.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> #include <86box/smram.h> +#include <86box/spd.h> #include <86box/usb.h> #include <86box/chipset.h> -/* Shadow RAM */ -#define LSB_READ ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) -#define LSB_WRITE ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY) -#define MSB_READ ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) -#define MSB_WRITE ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY) -#define SYSTEM_READ ((dev->pci_conf[0x76] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) -#define SYSTEM_WRITE ((dev->pci_conf[0x76] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY) - -/* IDE Flags (1 Native / 0 Compatibility)*/ -#define PRIMARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 1) -#define SECONDARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 4) -#define PRIMARY_NATIVE_BASE (dev->pci_conf_sb[1][0x11] << 8) | (dev->pci_conf_sb[1][0x10] & 0xf8) -#define PRIMARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x15] << 8) | (dev->pci_conf_sb[1][0x14] & 0xfc)) + 2) -#define SECONDARY_NATIVE_BASE (dev->pci_conf_sb[1][0x19] << 8) | (dev->pci_conf_sb[1][0x18] & 0xf8) -#define SECONDARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x1d] << 8) | (dev->pci_conf_sb[1][0x1c] & 0xfc)) + 2) -#define BUS_MASTER_BASE ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) - #ifdef ENABLE_SIS_5571_LOG int sis_5571_do_log = ENABLE_SIS_5571_LOG; @@ -75,49 +63,87 @@ sis_5571_log(const char *fmt, ...) #endif typedef struct sis_5571_t { - uint8_t nb_slot; - uint8_t sb_slot; - uint8_t pad; - uint8_t usb_irq_state; + uint8_t index; + uint8_t nb_slot; + uint8_t sb_slot; + uint8_t pad; - uint8_t pci_conf[256]; - uint8_t pci_conf_sb[3][256]; + uint8_t regs[16]; + uint8_t states[7]; + uint8_t pad0; - port_92_t *port_92; - sff8038i_t *ide_drive[2]; + uint8_t usb_unk_regs[8]; + + uint8_t pci_conf[256]; + uint8_t pci_conf_sb[3][256]; + + uint16_t usb_unk_base; + + sff8038i_t *bm[2]; smram_t *smram; + port_92_t *port_92; + void *pit; + nvr_t *nvr; usb_t *usb; + + uint8_t (*pit_read_reg)(void *priv, uint8_t reg); } sis_5571_t; static void -sis_5571_shadow_recalc(int cur_reg, sis_5571_t *dev) +sis_5571_shadow_recalc(sis_5571_t *dev) { - if (cur_reg != 0x76) { - mem_set_mem_state_both(0xc0000 + (0x8000 * (cur_reg & 0x07)), 0x4000, LSB_READ | LSB_WRITE); - mem_set_mem_state_both(0xc4000 + (0x8000 * (cur_reg & 0x07)), 0x4000, MSB_READ | MSB_WRITE); - } else - mem_set_mem_state_both(0xf0000, 0x10000, SYSTEM_READ | SYSTEM_WRITE); + int state; + uint32_t base; + + for (uint8_t i = 0x70; i <= 0x76; i++) { + if (i == 0x76) { + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(0xf0000, 0x10000, state); + sis_5571_log("000F0000-000FFFFF\n"); + } + } else { + base = ((i & 0x07) << 15) + 0xc0000; + + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base, 0x4000, state); + sis_5571_log("%08X-%08X\n", base, base + 0x3fff); + } + + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) { + state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base + 0x4000, 0x4000, state); + sis_5571_log("%08X-%08X\n", base + 0x4000, base + 0x7fff); + } + } + + dev->states[i & 0x0f] = dev->pci_conf[i]; + } flushmmucache_nopc(); } static void -sis_5571_smm_recalc(sis_5571_t *dev) +sis_5571_smram_recalc(sis_5571_t *dev) { smram_disable_all(); - switch ((dev->pci_conf[0xa3] & 0xc0) >> 6) { - case 0x00: - smram_enable(dev->smram, 0xe0000, 0xe0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1); + switch (dev->pci_conf[0xa3] >> 6) { + case 0: + smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); break; - case 0x01: - smram_enable(dev->smram, 0xe0000, 0xa0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1); + case 1: + smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); break; - case 0x02: - smram_enable(dev->smram, 0xe0000, 0xb0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1); + case 2: + smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); break; - case 0x03: - smram_enable(dev->smram, 0xa0000, 0xa0000, 0x10000, (dev->pci_conf[0xa3] & 0x10), 1); + case 3: + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0xa3] & 0x10, 1); break; default: @@ -127,543 +153,1012 @@ sis_5571_smm_recalc(sis_5571_t *dev) flushmmucache(); } -void -sis_5571_ide_handler(sis_5571_t *dev) +static void +sis_5571_mem_to_pci_reset(sis_5571_t *dev) { - ide_pri_disable(); - ide_sec_disable(); - if (dev->pci_conf_sb[1][4] & 1) { - if (dev->pci_conf_sb[1][0x4a] & 4) { - ide_set_base(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_BASE : 0x1f0); - ide_set_side(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_SIDE : 0x3f6); - ide_pri_enable(); - } - if (dev->pci_conf_sb[1][0x4a] & 2) { - ide_set_base(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_BASE : 0x170); - ide_set_side(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_SIDE : 0x376); - ide_sec_enable(); + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x71; + dev->pci_conf[0x03] = 0x55; + dev->pci_conf[0x04] = 0x05; + dev->pci_conf[0x05] = 0x00; + dev->pci_conf[0x06] = 0x00; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = 0x00; + dev->pci_conf[0x09] = 0x00; + dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x0c] = 0x00; + dev->pci_conf[0x0d] = 0x00; + dev->pci_conf[0x0e] = 0x00; + dev->pci_conf[0x0f] = 0x00; + + dev->pci_conf[0x50] = 0x00; + dev->pci_conf[0x51] = 0x00; + dev->pci_conf[0x52] = 0x00; + dev->pci_conf[0x53] = 0x00; + dev->pci_conf[0x54] = 0x54; + dev->pci_conf[0x55] = 0x54; + dev->pci_conf[0x56] = 0x03; + dev->pci_conf[0x57] = 0x00; + dev->pci_conf[0x58] = 0x00; + dev->pci_conf[0x59] = 0x00; + dev->pci_conf[0x5a] = 0x00; + + /* Undocumented DRAM bank registers. */ + dev->pci_conf[0x60] = dev->pci_conf[0x62] = 0x04; + dev->pci_conf[0x64] = dev->pci_conf[0x66] = 0x04; + dev->pci_conf[0x68] = dev->pci_conf[0x6a] = 0x04; + dev->pci_conf[0x61] = dev->pci_conf[0x65] = 0x00; + dev->pci_conf[0x63] = dev->pci_conf[0x67] = 0x80; + dev->pci_conf[0x69] = 0x00; + dev->pci_conf[0x6b] = 0x80; + + dev->pci_conf[0x70] = 0x00; + dev->pci_conf[0x71] = 0x00; + dev->pci_conf[0x72] = 0x00; + dev->pci_conf[0x73] = 0x00; + dev->pci_conf[0x74] = 0x00; + dev->pci_conf[0x75] = 0x00; + dev->pci_conf[0x76] = 0x00; + + dev->pci_conf[0x77] = 0x00; + dev->pci_conf[0x78] = 0x00; + dev->pci_conf[0x79] = 0x00; + dev->pci_conf[0x7a] = 0x00; + dev->pci_conf[0x7b] = 0x00; + + dev->pci_conf[0x80] = 0x00; + dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x82] = 0x00; + dev->pci_conf[0x83] = 0x00; + dev->pci_conf[0x84] = 0x00; + dev->pci_conf[0x85] = 0x00; + dev->pci_conf[0x86] = 0x00; + dev->pci_conf[0x87] = 0x00; + + dev->pci_conf[0x8c] = 0x00; + dev->pci_conf[0x8d] = 0x00; + dev->pci_conf[0x8e] = 0x00; + dev->pci_conf[0x8f] = 0x00; + + dev->pci_conf[0x90] = 0x00; + dev->pci_conf[0x91] = 0x00; + dev->pci_conf[0x92] = 0x00; + dev->pci_conf[0x93] = 0x00; + dev->pci_conf[0x93] = 0x00; + dev->pci_conf[0x94] = 0x00; + dev->pci_conf[0x95] = 0x00; + dev->pci_conf[0x96] = 0x00; + dev->pci_conf[0x97] = 0x00; + dev->pci_conf[0x98] = 0x00; + dev->pci_conf[0x99] = 0x00; + dev->pci_conf[0x9a] = 0x00; + dev->pci_conf[0x9b] = 0x00; + dev->pci_conf[0x9c] = 0x00; + dev->pci_conf[0x9d] = 0x00; + dev->pci_conf[0x9e] = 0xff; + dev->pci_conf[0x9f] = 0xff; + + dev->pci_conf[0xa0] = 0xff; + dev->pci_conf[0xa1] = 0x00; + dev->pci_conf[0xa2] = 0xff; + dev->pci_conf[0xa3] = 0x00; + + cpu_cache_ext_enabled = 0; + cpu_update_waitstates(); + + sis_5571_smram_recalc(dev); + sis_5571_shadow_recalc(dev); + + flushmmucache(); +} + +static void +sis_5571_mem_to_pci_write(int func, int addr, uint8_t val, void *priv) +{ + sis_5571_t *dev = (sis_5571_t *) priv; + + if (func == 0) { + sis_5571_log("SiS 5571 M2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (addr) { + case 0x04: /* Command - low byte */ + case 0x05: /* Command - high byte */ + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xfd) | (val & 0x02); + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf[addr] &= ~(val & 0xb8); + break; + + case 0x0d: /* Master latency timer */ + dev->pci_conf[addr] = val; + break; + + case 0x50: /* Host Interface and DRAM arbiter */ + dev->pci_conf[addr] = val & 0xec; + break; + + case 0x51: /* CACHE */ + dev->pci_conf[addr] = val; + cpu_cache_ext_enabled = !!(val & 0x40); + cpu_update_waitstates(); + break; + + case 0x52: + dev->pci_conf[addr] = val & 0xd0; + break; + + case 0x53: /* DRAM */ + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x54: /* FP/EDO */ + dev->pci_conf[addr] = val; + break; + + case 0x55: + dev->pci_conf[addr] = val & 0xe0; + break; + + case 0x56: /* MDLE delay */ + dev->pci_conf[addr] = val & 0x07; + break; + + case 0x57: /* SDRAM */ + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x59: /* Buffer strength and current rating */ + dev->pci_conf[addr] = val; + break; + + case 0x5a: + dev->pci_conf[addr] = val & 0x03; + break; + + /* Undocumented - DRAM bank registers, the exact layout is currently unknown. */ + case 0x60 ... 0x6b: + dev->pci_conf[addr] = val; + break; + + case 0x70 ... 0x75: + dev->pci_conf[addr] = val & 0xee; + sis_5571_shadow_recalc(dev); + break; + case 0x76: + dev->pci_conf[addr] = val & 0xe8; + sis_5571_shadow_recalc(dev); + break; + + case 0x77: /* Characteristics of non-cacheable area */ + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x78: /* Allocation of Non-Cacheable area #1 */ + case 0x79: /* NCA1REG2 */ + case 0x7a: /* Allocation of Non-Cacheable area #2 */ + case 0x7b: /* NCA2REG2 */ + dev->pci_conf[addr] = val; + break; + + case 0x80: /* PCI master characteristics */ + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x81: + dev->pci_conf[addr] = val & 0xcc; + break; + + case 0x82: + dev->pci_conf[addr] = val; + break; + + case 0x83: /* CPU to PCI characteristics */ + dev->pci_conf[addr] = val; + /* TODO: Implement Fast A20 and Fast reset stuff on the KBC already! */ + break; + + case 0x84 ... 0x86: + dev->pci_conf[addr] = val; + break; + + case 0x87: /* Miscellanea */ + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x90: /* PMU control register */ + case 0x91: /* Address trap for green function */ + case 0x92: + dev->pci_conf[addr] = val; + break; + + case 0x93: /* STPCLK# and APM SMI control */ + dev->pci_conf[addr] = val; + + if ((dev->pci_conf[0x9b] & 0x01) && (val & 0x02)) { + smi_raise(); + dev->pci_conf[0x9d] |= 0x01; + } + break; + + case 0x94: /* 6x86 and Green function control */ + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x95: /* Test mode control */ + case 0x96: /* Time slot and Programmable 10-bit I/O port definition */ + dev->pci_conf[addr] = val & 0xfb; + break; + + case 0x97: /* programmable 10-bit I/O port address */ + case 0x98: /* Programmable 16-bit I/O port */ + case 0x99 ... 0x9c: + dev->pci_conf[addr] = val; + break; + + case 0x9d: + dev->pci_conf[addr] &= val; + break; + + case 0x9e: /* STPCLK# Assertion Timer */ + case 0x9f: /* STPCLK# De-assertion Timer */ + case 0xa0 ... 0xa2: + dev->pci_conf[addr] = val; + break; + + case 0xa3: /* SMRAM access control and Power supply control */ + dev->pci_conf[addr] = val & 0xd0; + sis_5571_smram_recalc(dev); + break; + + default: + break; } } } -void -sis_5571_bm_handler(sis_5571_t *dev) +static uint8_t +sis_5571_mem_to_pci_read(int func, int addr, void *priv) { - sff_bus_master_handler(dev->ide_drive[0], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE); - sff_bus_master_handler(dev->ide_drive[1], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE + 8); + const sis_5571_t *dev = (sis_5571_t *) priv; + uint8_t ret = 0xff; + + if (func == 0x00) { + ret = dev->pci_conf[addr]; + + sis_5571_log("SiS 5571 M2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + } + + return ret; } static void -memory_pci_bridge_write(UNUSED(int func), int addr, uint8_t val, void *priv) +sis_5571_pci_to_isa_reset(sis_5571_t *dev) +{ + /* PCI to ISA Bridge */ + dev->pci_conf_sb[0][0x00] = 0x39; + dev->pci_conf_sb[0][0x01] = 0x10; + dev->pci_conf_sb[0][0x02] = 0x08; + dev->pci_conf_sb[0][0x03] = 0x00; + dev->pci_conf_sb[0][0x04] = 0x07; + dev->pci_conf_sb[0][0x05] = 0x00; + dev->pci_conf_sb[0][0x06] = 0x00; + dev->pci_conf_sb[0][0x07] = 0x02; + dev->pci_conf_sb[0][0x08] = 0x01; + dev->pci_conf_sb[0][0x09] = 0x00; + dev->pci_conf_sb[0][0x0a] = 0x01; + dev->pci_conf_sb[0][0x0b] = 0x06; + dev->pci_conf_sb[0][0x0e] = 0x80; + + dev->pci_conf_sb[0][0x40] = 0x00; + dev->pci_conf_sb[0][0x41] = dev->pci_conf_sb[0][0x42] = 0x80; + dev->pci_conf_sb[0][0x43] = dev->pci_conf_sb[0][0x44] = 0x80; + dev->pci_conf_sb[0][0x45] = 0x00; + dev->pci_conf_sb[0][0x46] = 0x00; + dev->pci_conf_sb[0][0x47] = 0x00; + dev->pci_conf_sb[0][0x48] = dev->pci_conf_sb[0][0x49] = 0x00; + dev->pci_conf_sb[0][0x4a] = dev->pci_conf_sb[0][0x4b] = 0x00; + dev->pci_conf_sb[0][0x61] = 0x80; + dev->pci_conf_sb[0][0x62] = 0x00; + dev->pci_conf_sb[0][0x63] = 0x80; + dev->pci_conf_sb[0][0x64] = 0x00; + dev->pci_conf_sb[0][0x65] = 0x00; + dev->pci_conf_sb[0][0x66] = dev->pci_conf_sb[0][0x67] = 0x00; + dev->pci_conf_sb[0][0x68] = 0x80; + dev->pci_conf_sb[0][0x69] = dev->pci_conf_sb[0][0x6a] = 0x00; + dev->pci_conf_sb[0][0x6b] = 0x00; + dev->pci_conf_sb[0][0x6c] = 0x02; + dev->pci_conf_sb[0][0x6d] = 0x00; + dev->pci_conf_sb[0][0x6e] = dev->pci_conf_sb[0][0x6f] = 0x00; + dev->pci_conf_sb[0][0x70] = dev->pci_conf_sb[0][0x71] = 0x00; + dev->pci_conf_sb[0][0x72] = dev->pci_conf_sb[0][0x73] = 0x00; + dev->pci_conf_sb[0][0x74] = dev->pci_conf_sb[0][0x75] = 0x00; + dev->pci_conf_sb[0][0x76] = dev->pci_conf_sb[0][0x77] = 0x00; + + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + + pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); + + cpu_set_isa_speed(7159091); + nvr_bank_set(0, 0, dev->nvr); +} + +static void +sis_5571_pci_to_isa_write(int addr, uint8_t val, void *priv) { sis_5571_t *dev = (sis_5571_t *) priv; + uint8_t old; + + sis_5571_log("SiS 5571 P2I: [W] dev->pci_conf_sb[0][%02X] = %02X\n", addr, val); switch (addr) { - case 0x04: /* Command - low byte */ - case 0x05: /* Command - high byte */ - dev->pci_conf[addr] |= val; + default: break; - case 0x06: /* Status - Low Byte */ - dev->pci_conf[addr] &= val; + case 0x04: /* Command */ + // dev->pci_conf_sb[0][addr] = val & 0x0f; break; - case 0x07: /* Status - High Byte */ - dev->pci_conf[addr] &= val & 0xbe; + case 0x07: /* Status */ + dev->pci_conf_sb[0][addr] &= ~(val & 0x30); break; - case 0x0d: /* Master latency timer */ - dev->pci_conf[addr] = val; + case 0x40: /* BIOS Control Register */ + dev->pci_conf_sb[0][addr] = val & 0x3f; break; - case 0x50: /* Host Interface and DRAM arbiter */ - dev->pci_conf[addr] = val & 0xec; + case 0x41: /* INTA# Remapping Control Register */ + case 0x42: /* INTB# Remapping Control Register */ + case 0x43: /* INTC# Remapping Control Register */ + case 0x44: /* INTD# Remapping Control Register */ + dev->pci_conf_sb[0][addr] = val & 0x8f; + pci_set_irq_routing(addr & 0x07, (val & 0x80) ? PCI_IRQ_DISABLED : (val & 0x0f)); break; - case 0x51: /* CACHE */ - dev->pci_conf[addr] = val; - cpu_cache_ext_enabled = !!(val & 0x40); - cpu_update_waitstates(); + case 0x45: + dev->pci_conf_sb[0][addr] = val & 0xec; + switch (val >> 6) { + case 0: + cpu_set_isa_speed(7159091); + break; + case 1: + cpu_set_isa_pci_div(4); + break; + case 2: + cpu_set_isa_pci_div(3); + break; + + default: + break; + } + nvr_bank_set(0, !!(val & 0x08), dev->nvr); break; - case 0x52: - dev->pci_conf[addr] = val & 0xd0; + case 0x46: + dev->pci_conf_sb[0][addr] = val & 0xec; break; - case 0x53: /* DRAM */ - dev->pci_conf[addr] = val & 0xfe; + case 0x47: /* DMA Clock and Wait State Control Register */ + dev->pci_conf_sb[0][addr] = val & 0x3e; break; - case 0x54: /* FP/EDO */ - dev->pci_conf[addr] = val; + case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ + case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ + case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ + case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ + dev->pci_conf_sb[0][addr] = val; break; - case 0x55: - dev->pci_conf[addr] = val & 0xe0; + case 0x60: + outb(0x0070, val); break; - case 0x56: /* MDLE delay */ - case 0x57: /* SDRAM */ - dev->pci_conf[addr] = val & 0xf8; + /* Simply skip MIRQ0, so we can reuse the SiS 551x IDEIRQ infrastructure. */ + case 0x61: /* MIRQ Remapping Control Register */ + sis_5571_log("Set MIRQ routing: MIRQ%i -> %02X\n", addr & 0x01, val); + dev->pci_conf_sb[0][addr] = val & 0xcf; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf); break; - case 0x59: /* Buffer strength and current rating */ - dev->pci_conf[addr] = val; + case 0x62: /* On-board Device DMA Control Register */ + dev->pci_conf_sb[0][addr] = val; break; - case 0x5a: - dev->pci_conf[addr] = val & 0x03; + case 0x63: /* IDEIRQ Remapping Control Register */ + sis_5571_log("Set MIRQ routing: IDEIRQ -> %02X\n", val); + dev->pci_conf_sb[0][addr] = val & 0x8f; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ2, val & 0xf); break; - case 0x60: /* Undocumented */ - case 0x61: /* Undocumented */ - case 0x62: /* Undocumented */ - case 0x63: /* Undocumented */ - case 0x64: /* Undocumented */ - case 0x65: /* Undocumented */ - case 0x66: /* Undocumented */ - case 0x67: /* Undocumented */ - case 0x68: /* Undocumented */ - case 0x69: /* Undocumented */ - case 0x6a: /* Undocumented */ - case 0x6b: /* Undocumented */ - dev->pci_conf[addr] = val; + case 0x64: /* GPIO Control Register */ + dev->pci_conf_sb[0][addr] = val & 0xef; + break; + + case 0x65: + dev->pci_conf_sb[0][addr] = val & 0x1b; + break; + + case 0x66: /* GPIO Output Mode Control Register */ + case 0x67: /* GPIO Output Mode Control Register */ + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x68: /* USBIRQ Remapping Control Register */ + sis_5571_log("Set MIRQ routing: USBIRQ -> %02X\n", val); + dev->pci_conf_sb[0][addr] = val & 0xcf; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ3, val & 0xf); + break; + + case 0x69: + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x6a: + dev->pci_conf_sb[0][addr] = val & 0xfc; + break; + + case 0x6b: + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x6c: + dev->pci_conf_sb[0][addr] = val & 0x02; + break; + + case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */ + old = dev->pci_conf_sb[0][addr]; + picint((val ^ old) & val); + picintc((val ^ old) & ~val); + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */ + old = dev->pci_conf_sb[0][addr]; + picint(((val ^ old) & val) << 8); + picintc(((val ^ old) & ~val) << 8); + dev->pci_conf_sb[0][addr] = val; break; case 0x70: - case 0x71: - case 0x72: - case 0x73: - case 0x74: - case 0x75: - case 0x76: /* Attribute of shadow RAM for BIOS area */ - dev->pci_conf[addr] = val & ((addr != 0x76) ? 0xee : 0xe8); - sis_5571_shadow_recalc(addr, dev); - sis_5571_smm_recalc(dev); + dev->pci_conf_sb[0][addr] = (dev->pci_conf_sb[0][addr] & 0x02) | (val & 0xdc); break; - case 0x77: /* Characteristics of non-cacheable area */ - dev->pci_conf[addr] = val & 0x0f; + case 0x71: /* Type-F DMA Control Register */ + dev->pci_conf_sb[0][addr] = val & 0xef; break; - case 0x78: /* Allocation of Non-Cacheable area #1 */ - case 0x79: /* NCA1REG2 */ - case 0x7a: /* Allocation of Non-Cacheable area #2 */ - case 0x7b: /* NCA2REG2 */ - dev->pci_conf[addr] = val; + case 0x72: /* SMI Triggered By IRQ/GPIO Control */ + case 0x73: /* SMI Triggered By IRQ/GPIO Control */ + dev->pci_conf_sb[0][addr] = val; break; - case 0x80: /* PCI master characteristics */ - dev->pci_conf[addr] = val & 0xfe; - break; - - case 0x81: - dev->pci_conf[addr] = val & 0xcc; - break; - - case 0x82: - dev->pci_conf[addr] = val; - break; - - case 0x83: /* CPU to PCI characteristics */ - dev->pci_conf[addr] = val; - port_92_set_features(dev->port_92, !!(val & 0x40), !!(val & 0x80)); - break; - - case 0x84: - case 0x85: - case 0x86: - dev->pci_conf[addr] = val; - break; - - case 0x87: /* Miscellanea */ - dev->pci_conf[addr] = val & 0xf8; - break; - - case 0x90: /* PMU control register */ - case 0x91: /* Address trap for green function */ - case 0x92: - dev->pci_conf[addr] = val; - break; - - case 0x93: /* STPCLK# and APM SMI control */ - dev->pci_conf[addr] = val; - - if ((dev->pci_conf[0x9b] & 1) && !!(val & 2)) { - smi_raise(); - dev->pci_conf[0x9d] |= 1; - } - break; - - case 0x94: /* 6x86 and Green function control */ - dev->pci_conf[addr] = val & 0xf8; - break; - - case 0x95: /* Test mode control */ - case 0x96: /* Time slot and Programmable 10-bit I/O port definition */ - dev->pci_conf[addr] = val & 0xfb; - break; - - case 0x97: /* programmable 10-bit I/O port address */ - case 0x98: /* Programmable 16-bit I/O port */ - case 0x99: - case 0x9a: - case 0x9b: - case 0x9c: - dev->pci_conf[addr] = val; - break; - - case 0x9d: - dev->pci_conf[addr] &= val; - break; - - case 0x9e: /* STPCLK# Assertion Timer */ - case 0x9f: /* STPCLK# De-assertion Timer */ - case 0xa0: - case 0xa1: - case 0xa2: - dev->pci_conf[addr] = val; - break; - - case 0xa3: /* SMRAM access control and Power supply control */ - dev->pci_conf[addr] = val & 0xd0; - sis_5571_smm_recalc(dev); - break; - - default: + case 0x74: /* System Standby Timer Reload, + System Standby State Exit And Throttling State Exit Control */ + case 0x75: /* System Standby Timer Reload, + System Standby State Exit And Throttling State Exit Control */ + case 0x76: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */ + case 0x77: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */ + dev->pci_conf_sb[0][addr] = val; break; } - sis_5571_log("SiS5571: dev->pci_conf[%02x] = %02x\n", addr, val); } static uint8_t -memory_pci_bridge_read(UNUSED(int func), int addr, void *priv) +sis_5571_pci_to_isa_read(int addr, void *priv) { const sis_5571_t *dev = (sis_5571_t *) priv; + uint8_t ret = 0xff; - sis_5571_log("SiS5571: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf[addr]); - return dev->pci_conf[addr]; + switch (addr) { + default: + ret = dev->pci_conf_sb[0][addr]; + break; + case 0x4c ... 0x4f: + ret = pic_read_icw(0, addr & 0x03); + break; + case 0x50 ... 0x53: + ret = pic_read_icw(1, addr & 0x03); + break; + case 0x54 ... 0x55: + ret = pic_read_ocw(0, addr & 0x01); + break; + case 0x56 ... 0x57: + ret = pic_read_ocw(1, addr & 0x01); + break; + case 0x58 ... 0x5f: + ret = dev->pit_read_reg(dev->pit, addr & 0x07); + break; + case 0x60: + ret = inb(0x0070); + break; + } + + sis_5571_log("SiS 5571 P2I: [R] dev->pci_conf_sb[0][%02X] = %02X\n", addr, ret); + + return ret; } static void -pci_isa_bridge_write(int func, int addr, uint8_t val, void *priv) +sis_5571_ide_irq_handler(sis_5571_t *dev) +{ + if (dev->pci_conf_sb[1][0x09] & 0x01) { + /* Primary IDE is native. */ + sis_5571_log("Primary IDE IRQ mode: Native, Native\n"); + sff_set_irq_mode(dev->bm[0], IRQ_MODE_SIS_551X); + } else { + /* Primary IDE is legacy. */ + sis_5571_log("Primary IDE IRQ mode: IRQ14, IRQ15\n"); + sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); + } + + if (dev->pci_conf_sb[1][0x09] & 0x04) { + /* Secondary IDE is native. */ + sis_5571_log("Secondary IDE IRQ mode: Native, Native\n"); + sff_set_irq_mode(dev->bm[1], IRQ_MODE_SIS_551X); + } else { + /* Secondary IDE is legacy. */ + sis_5571_log("Secondary IDE IRQ mode: IRQ14, IRQ15\n"); + sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); + } +} + +static void +sis_5571_ide_handler(sis_5571_t *dev) +{ + uint8_t ide_io_on = dev->pci_conf_sb[1][0x04] & 0x01; + + uint16_t native_base_pri_addr = (dev->pci_conf_sb[1][0x11] | dev->pci_conf_sb[1][0x10] << 8) & 0xfffe; + uint16_t native_side_pri_addr = (dev->pci_conf_sb[1][0x15] | dev->pci_conf_sb[1][0x14] << 8) & 0xfffe; + uint16_t native_base_sec_addr = (dev->pci_conf_sb[1][0x19] | dev->pci_conf_sb[1][0x18] << 8) & 0xfffe; + uint16_t native_side_sec_addr = (dev->pci_conf_sb[1][0x1c] | dev->pci_conf_sb[1][0x1b] << 8) & 0xfffe; + + uint16_t current_pri_base; + uint16_t current_pri_side; + uint16_t current_sec_base; + uint16_t current_sec_side; + + /* Primary Channel Programming */ + current_pri_base = (!(dev->pci_conf_sb[1][0x09] & 1)) ? 0x01f0 : native_base_pri_addr; + current_pri_side = (!(dev->pci_conf_sb[1][0x09] & 1)) ? 0x03f6 : native_side_pri_addr; + + /* Secondary Channel Programming */ + current_sec_base = (!(dev->pci_conf_sb[1][0x09] & 4)) ? 0x0170 : native_base_sec_addr; + current_sec_side = (!(dev->pci_conf_sb[1][0x09] & 4)) ? 0x0376 : native_side_sec_addr; + + sis_5571_log("sis_5571_ide_handler(): Disabling primary IDE...\n"); + ide_pri_disable(); + sis_5571_log("sis_5571_ide_handler(): Disabling secondary IDE...\n"); + ide_sec_disable(); + + if (ide_io_on) { + /* Primary Channel Setup */ + if (dev->pci_conf_sb[1][0x4a] & 0x02) { + sis_5571_log("sis_5571_ide_handler(): Primary IDE base now %04X...\n", current_pri_base); + ide_set_base(0, current_pri_base); + sis_5571_log("sis_5571_ide_handler(): Primary IDE side now %04X...\n", current_pri_side); + ide_set_side(0, current_pri_side); + + sis_5571_log("sis_5571_ide_handler(): Enabling primary IDE...\n"); + ide_pri_enable(); + + sis_5571_log("SiS 5571 PRI: BASE %04x SIDE %04x\n", current_pri_base, current_pri_side); + } + + /* Secondary Channel Setup */ + if (dev->pci_conf_sb[1][0x4a] & 0x04) { + sis_5571_log("sis_5571_ide_handler(): Secondary IDE base now %04X...\n", current_sec_base); + ide_set_base(1, current_sec_base); + sis_5571_log("sis_5571_ide_handler(): Secondary IDE side now %04X...\n", current_sec_side); + ide_set_side(1, current_sec_side); + + sis_5571_log("sis_5571_ide_handler(): Enabling secondary IDE...\n"); + ide_sec_enable(); + + sis_5571_log("SiS 5571: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side); + } + } + + sff_bus_master_handler(dev->bm[0], ide_io_on, + ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + 0); + sff_bus_master_handler(dev->bm[1], ide_io_on, + ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + 8); +} + +static void +sis_5571_ide_reset(sis_5571_t *dev) +{ + /* PCI IDE */ + dev->pci_conf_sb[1][0x00] = 0x39; + dev->pci_conf_sb[1][0x01] = 0x10; + dev->pci_conf_sb[1][0x02] = 0x13; + dev->pci_conf_sb[1][0x03] = 0x55; + dev->pci_conf_sb[1][0x04] = dev->pci_conf_sb[1][0x05] = 0x00; + dev->pci_conf_sb[1][0x06] = dev->pci_conf_sb[1][0x07] = 0x00; + dev->pci_conf_sb[1][0x08] = 0xc0; + dev->pci_conf_sb[1][0x09] = 0x8a; + dev->pci_conf_sb[1][0x0a] = dev->pci_conf_sb[1][0x0b] = 0x01; + dev->pci_conf_sb[1][0x0c] = dev->pci_conf_sb[1][0x0d] = 0x00; + dev->pci_conf_sb[1][0x0e] = 0x80; + dev->pci_conf_sb[1][0x0f] = 0x00; + dev->pci_conf_sb[1][0x10] = 0xf1; + dev->pci_conf_sb[1][0x11] = 0x01; + dev->pci_conf_sb[1][0x14] = 0xf5; + dev->pci_conf_sb[1][0x15] = 0x03; + dev->pci_conf_sb[1][0x18] = 0x71; + dev->pci_conf_sb[1][0x19] = 0x01; + dev->pci_conf_sb[1][0x1c] = 0x75; + dev->pci_conf_sb[1][0x1d] = 0x03; + dev->pci_conf_sb[1][0x20] = 0x01; + dev->pci_conf_sb[1][0x21] = 0xf0; + dev->pci_conf_sb[1][0x22] = dev->pci_conf_sb[1][0x23] = 0x00; + dev->pci_conf_sb[1][0x24] = dev->pci_conf_sb[1][0x25] = 0x00; + dev->pci_conf_sb[1][0x26] = dev->pci_conf_sb[1][0x27] = 0x00; + dev->pci_conf_sb[1][0x28] = dev->pci_conf_sb[1][0x29] = 0x00; + dev->pci_conf_sb[1][0x2a] = dev->pci_conf_sb[1][0x2b] = 0x00; +#ifdef DATASHEET + dev->pci_conf_sb[1][0x2c] = dev->pci_conf_sb[1][0x2d] = 0x00; +#else + /* The only Linux lspci listing I could find of this chipset, + shows a subsystem of 0058:0000. */ + dev->pci_conf_sb[1][0x2c] = 0x58; + dev->pci_conf_sb[1][0x2d] = 0x00; +#endif + dev->pci_conf_sb[1][0x2e] = dev->pci_conf_sb[1][0x2f] = 0x00; + dev->pci_conf_sb[1][0x30] = dev->pci_conf_sb[1][0x31] = 0x00; + dev->pci_conf_sb[1][0x32] = dev->pci_conf_sb[1][0x33] = 0x00; + dev->pci_conf_sb[1][0x40] = dev->pci_conf_sb[1][0x41] = 0x00; + dev->pci_conf_sb[1][0x42] = dev->pci_conf_sb[1][0x43] = 0x00; + dev->pci_conf_sb[1][0x44] = dev->pci_conf_sb[1][0x45] = 0x00; + dev->pci_conf_sb[1][0x46] = dev->pci_conf_sb[1][0x47] = 0x00; + dev->pci_conf_sb[1][0x48] = dev->pci_conf_sb[1][0x49] = 0x00; + dev->pci_conf_sb[1][0x4a] = 0x06; + dev->pci_conf_sb[1][0x4b] = 0x00; + dev->pci_conf_sb[1][0x4c] = dev->pci_conf_sb[1][0x4d] = 0x00; + dev->pci_conf_sb[1][0x4e] = dev->pci_conf_sb[1][0x4f] = 0x00; + + sis_5571_ide_irq_handler(dev); + sis_5571_ide_handler(dev); + + sff_bus_master_reset(dev->bm[0]); + sff_bus_master_reset(dev->bm[1]); +} + +static void +sis_5571_ide_write(int addr, uint8_t val, void *priv) { sis_5571_t *dev = (sis_5571_t *) priv; - switch (func) { - case 0: /* Bridge */ - switch (addr) { - case 0x04: /* Command */ - dev->pci_conf_sb[0][addr] |= val & 0x0f; - break; - case 0x06: /* Status */ - dev->pci_conf_sb[0][addr] &= val; - break; - - case 0x40: /* BIOS Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x3f; - break; - - case 0x41: /* INTA# Remapping Control Register */ - case 0x42: /* INTB# Remapping Control Register */ - case 0x43: /* INTC# Remapping Control Register */ - case 0x44: /* INTD# Remapping Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x8f; - pci_set_irq_routing((addr & 0x07), !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); - break; - - case 0x45: - dev->pci_conf_sb[0][addr] = val & 0xec; - switch ((val & 0xc0) >> 6) { - case 0: - cpu_set_isa_speed(7159091); - break; - case 1: - cpu_set_isa_pci_div(4); - break; - case 2: - cpu_set_isa_pci_div(3); - break; - - default: - break; - } - break; - - case 0x46: - dev->pci_conf_sb[0][addr] = val & 0xec; - break; - - case 0x47: /* DMA Clock and Wait State Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x3e; - break; - - case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ - case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ - case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ - case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x4c: - case 0x4d: - case 0x4e: - case 0x4f: - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - case 0x58: - case 0x59: - case 0x5a: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x5e: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x5f: - dev->pci_conf_sb[0][addr] = val & 0x3f; - break; - - case 0x60: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x61: /* MIRQ Remapping Control Register */ - dev->pci_conf_sb[0][addr] = val; - pci_set_mirq_routing(PCI_MIRQ0, !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); - break; - - case 0x62: /* On-board Device DMA Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x0f; - dma_set_drq((val & 0x07), 1); - break; - - case 0x63: /* IDEIRQ Remapping Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x8f; - if (val & 0x80) { - sff_set_irq_line(dev->ide_drive[0], val & 0x0f); - sff_set_irq_line(dev->ide_drive[1], val & 0x0f); - } - break; - - case 0x64: /* GPIO Control Register */ - dev->pci_conf_sb[0][addr] = val & 0xef; - break; - - case 0x65: - dev->pci_conf_sb[0][addr] = val & 0x1b; - break; - - case 0x66: /* GPIO Output Mode Control Register */ - case 0x67: /* GPIO Output Mode Control Register */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x68: /* USBIRQ Remapping Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x1b; - break; - - case 0x69: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x6a: - dev->pci_conf_sb[0][addr] = val & 0xfc; - break; - - case 0x6b: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x6c: - dev->pci_conf_sb[0][addr] = val & 0x03; - break; - - case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */ - case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x70: - dev->pci_conf_sb[0][addr] = val & 0xde; - break; - - case 0x71: /* Type-F DMA Control Register */ - dev->pci_conf_sb[0][addr] = val & 0xfe; - break; - - case 0x72: /* SMI Triggered By IRQ/GPIO Control */ - case 0x73: /* SMI Triggered By IRQ/GPIO Control */ - dev->pci_conf_sb[0][addr] = (addr == 0x72) ? val & 0xfe : val; - break; - - case 0x74: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit Control */ - case 0x75: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit Control */ - case 0x76: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */ - case 0x77: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */ - dev->pci_conf_sb[0][addr] = val; - break; - - default: - break; - } - sis_5571_log("SiS5571-SB: dev->pci_conf[%02x] = %02x\n", addr, val); - break; - - case 1: /* IDE Controller */ - switch (addr) { - case 0x04: /* Command low byte */ - dev->pci_conf_sb[1][addr] = val & 0x05; - sis_5571_ide_handler(dev); - sis_5571_bm_handler(dev); - break; - - case 0x07: /* Status high byte */ - dev->pci_conf_sb[1][addr] &= val; - break; - - case 0x09: /* Programming Interface Byte */ - dev->pci_conf_sb[1][addr] = val & 0xcf; - sis_5571_ide_handler(dev); - break; - - case 0x0d: /* Latency Time */ - case 0x10: /* Primary Channel Base Address Register */ - case 0x11: /* Primary Channel Base Address Register */ - case 0x12: /* Primary Channel Base Address Register */ - case 0x13: /* Primary Channel Base Address Register */ - case 0x14: /* Primary Channel Base Address Register */ - case 0x15: /* Primary Channel Base Address Register */ - case 0x16: /* Primary Channel Base Address Register */ - case 0x17: /* Primary Channel Base Address Register */ - case 0x18: /* Secondary Channel Base Address Register */ - case 0x19: /* Secondary Channel Base Address Register */ - case 0x1a: /* Secondary Channel Base Address Register */ - case 0x1b: /* Secondary Channel Base Address Register */ - case 0x1c: /* Secondary Channel Base Address Register */ - case 0x1d: /* Secondary Channel Base Address Register */ - case 0x1e: /* Secondary Channel Base Address Register */ - case 0x1f: /* Secondary Channel Base Address Register */ - dev->pci_conf_sb[1][addr] = val; - sis_5571_ide_handler(dev); - break; - - case 0x20: /* Bus Master IDE Control Register Base Address */ - case 0x21: /* Bus Master IDE Control Register Base Address */ - case 0x22: /* Bus Master IDE Control Register Base Address */ - case 0x23: /* Bus Master IDE Control Register Base Address */ - dev->pci_conf_sb[1][addr] = val; - sis_5571_bm_handler(dev); - break; - - case 0x30: /* Expansion ROM Base Address */ - case 0x31: /* Expansion ROM Base Address */ - case 0x32: /* Expansion ROM Base Address */ - case 0x33: /* Expansion ROM Base Address */ - case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */ - case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */ - case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */ - case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */ - case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */ - case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */ - case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */ - case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */ - case 0x48: /* IDE Command Recovery Time Control */ - case 0x49: /* IDE Command Active Time Control */ - dev->pci_conf_sb[1][addr] = val; - break; - - case 0x4a: /* IDE General Control Register 0 */ - dev->pci_conf_sb[1][addr] = val & 0xaf; - sis_5571_ide_handler(dev); - break; - - case 0x4b: /* IDE General Control register 1 */ - case 0x4c: /* Prefetch Count of Primary Channel (Low Byte) */ - case 0x4d: /* Prefetch Count of Primary Channel (High Byte) */ - case 0x4e: /* Prefetch Count of Secondary Channel (Low Byte) */ - case 0x4f: /* Prefetch Count of Secondary Channel (High Byte) */ - dev->pci_conf_sb[1][addr] = val; - break; - - default: - break; - } - sis_5571_log("SiS5571-IDE: dev->pci_conf[%02x] = %02x\n", addr, val); - break; - - case 2: /* USB Controller */ - switch (addr) { - case 0x04: /* Command - Low Byte */ - dev->pci_conf_sb[2][addr] = val; - ohci_update_mem_mapping(dev->usb, dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 1); - break; - - case 0x05: /* Command - High Byte */ - dev->pci_conf_sb[2][addr] = val & 0x03; - break; - - case 0x06: /* Status - Low Byte */ - dev->pci_conf_sb[2][addr] &= val & 0xc0; - break; - - case 0x07: /* Status - High Byte */ - dev->pci_conf_sb[2][addr] &= val; - break; - - case 0x10: /* Memory Space Base Address Register */ - case 0x11: /* Memory Space Base Address Register */ - case 0x12: /* Memory Space Base Address Register */ - case 0x13: /* Memory Space Base Address Register */ - dev->pci_conf_sb[2][addr] = val & ((addr == 0x11) ? 0x0f : 0xff); - ohci_update_mem_mapping(dev->usb, dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 1); - break; - - case 0x14: /* IO Space Base Address Register */ - case 0x15: /* IO Space Base Address Register */ - case 0x16: /* IO Space Base Address Register */ - case 0x17: /* IO Space Base Address Register */ - case 0x3c: /* Interrupt Line */ - dev->pci_conf_sb[2][addr] = val; - break; - - default: - break; - } - sis_5571_log("SiS5571-USB: dev->pci_conf[%02x] = %02x\n", addr, val); - break; + sis_5571_log("SiS 5571 IDE: [W] dev->pci_conf_sb[1][%02X] = %02X\n", addr, val); + switch (addr) { default: break; + + case 0x04: /* Command low byte */ + dev->pci_conf_sb[1][addr] = val & 0x05; + sis_5571_ide_handler(dev); + break; + case 0x06: /* Status low byte */ + dev->pci_conf_sb[1][addr] = val & 0x20; + break; + case 0x07: /* Status high byte */ + dev->pci_conf_sb[1][addr] = (dev->pci_conf_sb[1][addr] & 0x06) & ~(val & 0x38); + break; + case 0x09: /* Programming Interface Byte */ + dev->pci_conf_sb[1][addr] = (dev->pci_conf_sb[1][addr] & 0x8a) | (val & 0x45); + sis_5571_ide_irq_handler(dev); + sis_5571_ide_handler(dev); + break; + case 0x0d: /* Latency Timer */ + dev->pci_conf_sb[1][addr] = val; + break; + + /* Primary Base Address */ + case 0x10: + case 0x11: + case 0x14: + case 0x15: + fallthrough; + + /* Secondary Base Address */ + case 0x18: + case 0x19: + case 0x1c: + case 0x1d: + fallthrough; + + /* Bus Mastering Base Address */ + case 0x20: + case 0x21: + if (addr == 0x20) + dev->pci_conf_sb[1][addr] = (val & 0xe0) | 0x01; + else + dev->pci_conf_sb[1][addr] = val; + sis_5571_ide_handler(dev); + break; + + /* The only Linux lspci listing I could find of this chipset, + does not show any BIOS bar, therefore writes to that are disabled. */ +#ifdef DATASHEET + case 0x30: /* Expansion ROM Base Address */ + case 0x31: /* Expansion ROM Base Address */ + case 0x32: /* Expansion ROM Base Address */ + case 0x33: /* Expansion ROM Base Address */ + dev->pci_conf_sb[1][addr] = val; + break; +#endif + + case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */ + case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */ + case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */ + case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */ + case 0x48: /* IDE Command Recovery Time Control */ + dev->pci_conf_sb[1][addr] = val & 0x0f; + break; + + case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */ + case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */ + case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */ + case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */ + case 0x49: /* IDE Command Active Time Control */ + dev->pci_conf_sb[1][addr] = val & 0x07; + break; + + case 0x4a: /* IDE General Control Register 0 */ + dev->pci_conf_sb[1][addr] = val & 0xaf; + sis_5571_ide_handler(dev); + break; + + case 0x4b: /* IDE General Control register 1 */ + dev->pci_conf_sb[1][addr] = val; + break; + + case 0x4c: /* Prefetch Count of Primary Channel (Low Byte) */ + case 0x4d: /* Prefetch Count of Primary Channel (High Byte) */ + case 0x4e: /* Prefetch Count of Secondary Channel (Low Byte) */ + case 0x4f: /* Prefetch Count of Secondary Channel (High Byte) */ + dev->pci_conf_sb[1][addr] = val; + break; } } static uint8_t -pci_isa_bridge_read(int func, int addr, void *priv) +sis_5571_ide_read(int addr, void *priv) { const sis_5571_t *dev = (sis_5571_t *) priv; + uint8_t ret = 0xff; + + switch (addr) { + default: + ret = dev->pci_conf_sb[1][addr]; + break; + + case 0x09: + ret = dev->pci_conf_sb[1][addr]; + if (dev->pci_conf_sb[1][0x09] & 0x40) + ret |= ((dev->pci_conf_sb[1][0x4a] & 0x06) << 3); + break; + + case 0x3d: + ret = (dev->pci_conf_sb[1][0x09] & 0x05) ? PCI_INTA : 0x00; + break; + } + + sis_5571_log("SiS 5571 IDE: [R] dev->pci_conf_sb[1][%02X] = %02X\n", addr, ret); + + return ret; +} + +/* SiS 5571 unknown I/O port (second USB PCI BAR). */ +static void +sis_5571_usb_unk_write(uint16_t addr, uint8_t val, void *priv) +{ + sis_5571_t *dev = (sis_5571_t *) priv; + + addr = (addr - dev->usb_unk_base) & 0x07; + + sis_5571_log("SiS 5571 USB UNK: [W] dev->usb_unk_regs[%02X] = %02X\n", addr, val); + + dev->usb_unk_regs[addr] = val; +} + +static uint8_t +sis_5571_usb_unk_read(uint16_t addr, void *priv) +{ + const sis_5571_t *dev = (sis_5571_t *) priv; + uint8_t ret = 0xff; + + addr = (addr - dev->usb_unk_base) & 0x07; + + ret = dev->usb_unk_regs[addr & 0x07]; + + sis_5571_log("SiS 5571 USB UNK: [R] dev->usb_unk_regs[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5571_usb_reset(sis_5571_t *dev) +{ + /* USB */ + dev->pci_conf_sb[2][0x00] = 0x39; + dev->pci_conf_sb[2][0x01] = 0x10; + dev->pci_conf_sb[2][0x02] = 0x01; + dev->pci_conf_sb[2][0x03] = 0x70; + dev->pci_conf_sb[2][0x04] = dev->pci_conf_sb[1][0x05] = 0x00; + dev->pci_conf_sb[2][0x06] = 0x00; + dev->pci_conf_sb[2][0x07] = 0x02; + dev->pci_conf_sb[2][0x08] = 0xb0; + dev->pci_conf_sb[2][0x09] = 0x10; + dev->pci_conf_sb[2][0x0a] = 0x03; + dev->pci_conf_sb[2][0x0b] = 0x0c; + dev->pci_conf_sb[2][0x0c] = dev->pci_conf_sb[1][0x0d] = 0x00; + dev->pci_conf_sb[2][0x0e] = 0x80 /* 0x10 - Datasheet erratum - header type 0x10 is invalid! */; + dev->pci_conf_sb[2][0x0f] = 0x00; + dev->pci_conf_sb[2][0x10] = 0x00; + dev->pci_conf_sb[2][0x11] = 0x00; + dev->pci_conf_sb[2][0x12] = 0x00; + dev->pci_conf_sb[2][0x13] = 0x00; + dev->pci_conf_sb[2][0x14] = 0x01; + dev->pci_conf_sb[2][0x15] = 0x00; + dev->pci_conf_sb[2][0x16] = 0x00; + dev->pci_conf_sb[2][0x17] = 0x00; + dev->pci_conf_sb[2][0x3c] = 0x00; + dev->pci_conf_sb[2][0x3d] = PCI_INTA; + dev->pci_conf_sb[2][0x3e] = 0x00; + dev->pci_conf_sb[2][0x3f] = 0x00; + + ohci_update_mem_mapping(dev->usb, + dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], + dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][0x04] & 0x02); + + if (dev->usb_unk_base != 0x0000) { + io_removehandler(dev->usb_unk_base, 0x0002, + sis_5571_usb_unk_read, NULL, NULL, + sis_5571_usb_unk_write, NULL, NULL, dev); + } + + dev->usb_unk_base = 0x0000; + + memset(dev->usb_unk_regs, 0x00, sizeof(dev->usb_unk_regs)); +} + +static void +sis_5571_usb_write(int addr, uint8_t val, void *priv) +{ + sis_5571_t *dev = (sis_5571_t *) priv; + + sis_5571_log("SiS 5571 USB: [W] dev->pci_conf_sb[2][%02X] = %02X\n", addr, val); + + if (dev->pci_conf_sb[0][0x68] & 0x40) switch (addr) { + default: + break; + + case 0x04: /* Command - Low Byte */ + dev->pci_conf_sb[2][addr] = val & 0x47; + if (dev->usb_unk_base != 0x0000) { + io_removehandler(dev->usb_unk_base, 0x0002, + sis_5571_usb_unk_read, NULL, NULL, + sis_5571_usb_unk_write, NULL, NULL, dev); + if (dev->pci_conf_sb[2][0x04] & 0x01) + io_sethandler(dev->usb_unk_base, 0x0002, + sis_5571_usb_unk_read, NULL, NULL, + sis_5571_usb_unk_write, NULL, NULL, dev); + } + ohci_update_mem_mapping(dev->usb, + dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], + dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][0x04] & 0x02); + break; + + case 0x05: /* Command - High Byte */ + dev->pci_conf_sb[2][addr] = val & 0x01; + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf_sb[2][addr] &= ~(val & 0xf9); + break; + + case 0x0d: /* Latency Timer */ + dev->pci_conf_sb[2][addr] = val; + break; + + case 0x11: /* Memory Space Base Address Register */ + case 0x12: /* Memory Space Base Address Register */ + case 0x13: /* Memory Space Base Address Register */ + dev->pci_conf_sb[2][addr] = val & ((addr == 0x11) ? 0xf0 : 0xff); + ohci_update_mem_mapping(dev->usb, + dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], + dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 0x02); + break; + + case 0x14: /* IO Space Base Address Register */ + case 0x15: /* IO Space Base Address Register */ + if (dev->usb_unk_base != 0x0000) { + io_removehandler(dev->usb_unk_base, 0x0002, + sis_5571_usb_unk_read, NULL, NULL, + sis_5571_usb_unk_write, NULL, NULL, dev); + } + dev->pci_conf_sb[2][addr] = val; + dev->usb_unk_base = (dev->pci_conf_sb[2][0x14] & 0xf8) | + (dev->pci_conf_sb[2][0x15] << 8); + if (dev->usb_unk_base != 0x0000) { + io_sethandler(dev->usb_unk_base, 0x0002, + sis_5571_usb_unk_read, NULL, NULL, + sis_5571_usb_unk_write, NULL, NULL, dev); + } + break; + + case 0x3c: /* Interrupt Line */ + dev->pci_conf_sb[2][addr] = val; + break; + } +} + +static uint8_t +sis_5571_usb_read(int addr, void *priv) +{ + const sis_5571_t *dev = (sis_5571_t *) priv; + uint8_t ret = 0xff; + + if (dev->pci_conf_sb[0][0x68] & 0x40) { + ret = dev->pci_conf_sb[2][addr]; + + sis_5571_log("SiS 5571 USB: [R] dev->pci_conf_sb[2][%02X] = %02X\n", addr, ret); + } + + return ret; +} + +static void +sis_5571_sb_write(int func, int addr, uint8_t val, void *priv) +{ + switch (func) { + case 0x00: + sis_5571_pci_to_isa_write(addr, val, priv); + break; + case 0x01: + sis_5571_ide_write(addr, val, priv); + break; + case 0x02: + sis_5571_usb_write(addr, val, priv); + break; + } +} + +static uint8_t +sis_5571_sb_read(int func, int addr, void *priv) +{ + uint8_t ret = 0xff; switch (func) { - case 0: - sis_5571_log("SiS5571-SB: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[0][addr]); - return dev->pci_conf_sb[0][addr]; - case 1: - sis_5571_log("SiS5571-IDE: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[1][addr]); - return dev->pci_conf_sb[1][addr]; - case 2: - sis_5571_log("SiS5571-USB: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[2][addr]); - return dev->pci_conf_sb[2][addr]; - - default: - return 0xff; + case 0x00: + ret = sis_5571_pci_to_isa_read(addr, priv); + break; + case 0x01: + ret = sis_5571_ide_read(addr, priv); + break; + case 0x02: + ret = sis_5571_usb_read(addr, priv); + break; } + + return ret; } static void @@ -672,52 +1167,16 @@ sis_5571_reset(void *priv) sis_5571_t *dev = (sis_5571_t *) priv; /* Memory/PCI Bridge */ - dev->pci_conf[0x00] = 0x39; - dev->pci_conf[0x01] = 0x10; - dev->pci_conf[0x02] = 0x71; - dev->pci_conf[0x03] = 0x55; - dev->pci_conf[0x04] = 0xfd; - dev->pci_conf[0x0b] = 0x06; - dev->pci_conf[0x9e] = 0xff; - dev->pci_conf[0x9f] = 0xff; - dev->pci_conf[0xa2] = 0xff; + sis_5571_mem_to_pci_reset(dev); /* PCI to ISA bridge */ - dev->pci_conf_sb[0][0x00] = 0x39; - dev->pci_conf_sb[0][0x01] = 0x10; - dev->pci_conf_sb[0][0x02] = 0x08; - dev->pci_conf_sb[0][0x04] = 0xfd; - dev->pci_conf_sb[0][0x08] = 0x01; - dev->pci_conf_sb[0][0x0a] = 0x01; - dev->pci_conf_sb[0][0x0b] = 0x06; + sis_5571_pci_to_isa_reset(dev); /* IDE Controller */ - dev->pci_conf_sb[1][0x00] = 0x39; - dev->pci_conf_sb[1][0x01] = 0x10; - dev->pci_conf_sb[1][0x02] = 0x13; - dev->pci_conf_sb[1][0x03] = 0x55; - dev->pci_conf_sb[1][0x08] = 0xc0; - dev->pci_conf_sb[1][0x0a] = 0x01; - dev->pci_conf_sb[1][0x0b] = 0x01; - dev->pci_conf_sb[1][0x0e] = 0x80; - dev->pci_conf_sb[1][0x4a] = 0x06; - sff_set_slot(dev->ide_drive[0], dev->sb_slot); - sff_set_slot(dev->ide_drive[1], dev->sb_slot); - sff_bus_master_reset(dev->ide_drive[0]); - sff_bus_master_reset(dev->ide_drive[1]); + sis_5571_ide_reset(dev); /* USB Controller */ - dev->pci_conf_sb[2][0x00] = 0x39; - dev->pci_conf_sb[2][0x01] = 0x10; - dev->pci_conf_sb[2][0x02] = 0x01; - dev->pci_conf_sb[2][0x03] = 0x70; - dev->pci_conf_sb[2][0x08] = 0xb0; - dev->pci_conf_sb[2][0x09] = 0x10; - dev->pci_conf_sb[2][0x0a] = 0x03; - dev->pci_conf_sb[2][0x0b] = 0xc0; - dev->pci_conf_sb[2][0x0e] = 0x80; - dev->pci_conf_sb[2][0x14] = 0x01; - dev->pci_conf_sb[2][0x3d] = 0x01; + sis_5571_usb_reset(dev); } static void @@ -732,22 +1191,40 @@ sis_5571_close(void *priv) static void * sis_5571_init(UNUSED(const device_t *info)) { - sis_5571_t *dev = (sis_5571_t *) malloc(sizeof(sis_5571_t)); - memset(dev, 0x00, sizeof(sis_5571_t)); + sis_5571_t *dev = (sis_5571_t *) calloc(1, sizeof(sis_5571_t)); + uint8_t pit_is_fast = (((pit_mode == -1) && is486) || (pit_mode == 1)); - pci_add_card(PCI_ADD_NORTHBRIDGE, memory_pci_bridge_read, memory_pci_bridge_write, dev, &dev->nb_slot); - pci_add_card(PCI_ADD_SOUTHBRIDGE, pci_isa_bridge_read, pci_isa_bridge_write, dev, &dev->sb_slot); + /* Device 0: Memory/PCI Bridge */ + pci_add_card(PCI_ADD_NORTHBRIDGE, + sis_5571_mem_to_pci_read, sis_5571_mem_to_pci_write, dev, &dev->nb_slot); + /* Device 1: Southbridge */ + pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5571_sb_read, sis_5571_sb_write, dev, &dev->sb_slot); /* MIRQ */ - pci_enable_mirq(0); + pci_enable_mirq(1); - /* Port 92 & SMRAM */ - dev->port_92 = device_add(&port_92_pci_device); - dev->smram = smram_add(); + /* IDEIRQ */ + pci_enable_mirq(2); + + /* USBIRQ */ + pci_enable_mirq(3); + + /* Port 92h */ + dev->port_92 = device_add(&port_92_device); /* SFF IDE */ - dev->ide_drive[0] = device_add_inst(&sff8038i_device, 1); - dev->ide_drive[1] = device_add_inst(&sff8038i_device, 2); + dev->bm[0] = device_add_inst(&sff8038i_device, 1); + dev->bm[1] = device_add_inst(&sff8038i_device, 2); + + /* SMRAM */ + dev->smram = smram_add(); + + /* PIT */ + dev->pit = device_find_first_priv(DEVICE_PIT); + dev->pit_read_reg = pit_is_fast ? pitf_read_reg : pit_read_reg; + + /* NVR */ + dev->nvr = device_add(&at_mb_nvr_device); /* USB */ dev->usb = device_add(&usb_device); diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 47e64a275..df6684baf 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -181,6 +181,7 @@ int cpu_multi; int cpu_16bitbus; int cpu_64bitbus; int cpu_cyrix_alignment; +int cpu_cpurst_on_sr; int CPUID; int is186; @@ -742,6 +743,7 @@ cpu_set(void) timing_misaligned = 0; cpu_cyrix_alignment = 0; + cpu_cpurst_on_sr = 0; cpu_CR4_mask = 0; switch (cpu_s->cpu_type) { @@ -3018,6 +3020,10 @@ amd_k_invalid_rdmsr: EAX = msr.ecx1002ff & 0xffffffff; EDX = msr.ecx1002ff >> 32; break; + case 0x40000020: + EAX = msr.ecx40000020 & 0xffffffff; + EDX = msr.ecx40000020 >> 32; + break; case 0xf0f00250: EAX = msr.ecxf0f00250 & 0xffffffff; EDX = msr.ecxf0f00250 >> 32; @@ -3453,6 +3459,9 @@ amd_k_invalid_wrmsr: case 0x1002ff: msr.ecx1002ff = EAX | ((uint64_t) EDX << 32); break; + case 0x40000020: + msr.ecx40000020 = EAX | ((uint64_t) EDX << 32); + break; case 0xf0f00250: msr.ecxf0f00250 = EAX | ((uint64_t) EDX << 32); break; diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 9bdcca84c..9aee59e60 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -339,6 +339,9 @@ typedef struct { /* K6-3, K6-2P, and K6-3P MSR's */ uint64_t amd_l2aar; /* 0xc0000089 */ + /* Weird long MSR's used by the Hyper-V BIOS. */ + uint64_t ecx40000020; /* 0x40000020 */ + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ uint64_t ecxf0f00250; /* 0xf0f00250 - Some weird long MSR's used by i686 AMI & some Phoenix BIOSes */ uint64_t ecxf0f00258; /* 0xf0f00258 */ @@ -544,8 +547,9 @@ extern int cpu_multi; extern double cpu_dmulti; extern double fpu_multi; extern double cpu_busspeed; -extern int cpu_cyrix_alignment; /*Cyrix 5x86/6x86 only has data misalignment - penalties when crossing 8-byte boundaries*/ +extern int cpu_cyrix_alignment; /* Cyrix 5x86/6x86 only has data misalignment + penalties when crossing 8-byte boundaries. */ +extern int cpu_cpurst_on_sr; /* SiS 551x and 5571: Issue CPURST on soft reset. */ extern int is8086; extern int is186; diff --git a/src/cpu/x86.c b/src/cpu/x86.c index 93674ae5c..64ff6be4c 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -342,6 +342,8 @@ reset_common(int hard) if (!is286) reset_808x(hard); + + cpu_cpurst_on_sr = 0; } /* Hard reset. */ diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 8045ea1df..fa7cdc304 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -44,6 +44,9 @@ #include <86box/video.h> #include <86box/keyboard.h> +#include <86box/dma.h> +#include <86box/pci.h> + #define STAT_PARITY 0x80 #define STAT_RTIMEOUT 0x40 #define STAT_TTIMEOUT 0x20 @@ -141,8 +144,9 @@ typedef struct atkbc_t { uint32_t flags; - /* Main timer. */ - pc_timer_t send_delay_timer; + /* Main timers. */ + pc_timer_t kbc_poll_timer; + pc_timer_t kbc_dev_poll_timer; /* P2 pulse callback timer. */ pc_timer_t pulse_cb; @@ -695,10 +699,18 @@ kbc_at_poll(void *priv) { atkbc_t *dev = (atkbc_t *) priv; - timer_advance_u64(&dev->send_delay_timer, (100ULL * TIMER_USEC)); + timer_advance_u64(&dev->kbc_poll_timer, (39ULL * TIMER_USEC)); /* TODO: Implement the password security state. */ kbc_at_do_poll(dev); +} + +static void +kbc_at_dev_poll(void *priv) +{ + atkbc_t *dev = (atkbc_t *) priv; + + timer_advance_u64(&dev->kbc_dev_poll_timer, (100ULL * TIMER_USEC)); if ((kbc_at_ports[0] != NULL) && (kbc_at_ports[0]->priv != NULL)) kbc_at_ports[0]->poll(kbc_at_ports[0]->priv); @@ -736,7 +748,7 @@ write_p2(atkbc_t *dev, uint8_t val) /* AT, PS/2: Handle reset. */ /* 0 holds the CPU in the RESET state, 1 releases it. To simplify this, we just do everything on release. */ - if ((old ^ val) & 0x01) { /*Reset*/ + if (!cpu_cpurst_on_sr && ((old ^ val) & 0x01)) { /*Reset*/ if (!(val & 0x01)) { /* Pin 0 selected. */ /* Pin 0 selected. */ kbc_at_log("write_p2(): Pulse reset!\n"); @@ -765,6 +777,28 @@ write_p2(atkbc_t *dev, uint8_t val) /* Do this here to avoid an infinite reset loop. */ dev->p2 = val; + + if (cpu_cpurst_on_sr && ((old ^ val) & 0x01)) { /*Reset*/ + if (!(val & 0x01)) { /* Pin 0 selected. */ + /* Pin 0 selected. */ + pclog("write_p2(): Pulse reset!\n"); + dma_reset(); + dma_set_at(1); + + device_reset_all(DEVICE_ALL); + + cpu_alt_reset = 0; + + pci_reset(); + + mem_a20_alt = 0; + mem_a20_recalc(); + + flushmmucache(); + + resetx86(); + } + } } static void @@ -1934,7 +1968,8 @@ kbc_at_close(void *priv) int max_ports = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) ? 2 : 1; /* Stop timers. */ - timer_disable(&dev->send_delay_timer); + timer_disable(&dev->kbc_dev_poll_timer); + timer_disable(&dev->kbc_poll_timer); for (int i = 0; i < max_ports; i++) { if (kbc_at_ports[i] != NULL) { @@ -1966,9 +2001,11 @@ kbc_at_init(const device_t *info) io_sethandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, dev); io_sethandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, dev); - timer_add(&dev->send_delay_timer, kbc_at_poll, dev, 1); + timer_add(&dev->kbc_poll_timer, kbc_at_poll, dev, 1); timer_add(&dev->pulse_cb, pulse_poll, dev, 0); + timer_add(&dev->kbc_dev_poll_timer, kbc_at_dev_poll, dev, 1); + dev->write60_ven = NULL; dev->write64_ven = NULL; diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 21c4884b7..f8eddb931 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -32,6 +32,8 @@ #define FIFO_SIZE 16 +#define BAT_COUNT 1000 + enum { KBD_84_KEY = 0, KBD_101_KEY, @@ -75,6 +77,8 @@ static atkbc_dev_t *SavedKbd = NULL; static uint8_t inv_cmd_response = 0xfa; +static uint16_t bat_counter = 0; + static const scancode scancode_set1[512] = { // clang-format off { { 0},{ 0} }, { { 0x01,0},{ 0x81,0} }, { { 0x02,0},{ 0x82,0} }, { { 0x03,0},{ 0x83,0} }, /*000*/ @@ -704,11 +708,16 @@ keyboard_at_bat(void *priv) { atkbc_dev_t *dev = (atkbc_dev_t *) priv; - keyboard_at_set_defaults(dev); + if (bat_counter == 0x0000) { + keyboard_at_set_defaults(dev); - keyboard_scan = 1; + keyboard_scan = 1; - kbc_at_dev_queue_add(dev, 0xaa, 0); + kbc_at_dev_queue_add(dev, 0xaa, 0); + } else { + bat_counter--; + dev->state = DEV_STATE_EXECUTE_BAT; + } } static void @@ -926,6 +935,7 @@ keyboard_at_write(void *priv) case 0xff: /* reset */ kbc_at_dev_reset(dev, 1); + bat_counter = 1000; break; default: @@ -965,8 +975,10 @@ keyboard_at_init(const device_t *info) dev->fifo_mask = FIFO_SIZE - 1; - if (dev->port != NULL) + if (dev->port != NULL) { kbc_at_dev_reset(dev, 0); + bat_counter = 0x0000; + } keyboard_send = add_data_kbd; SavedKbd = dev; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 5d7a5204c..4e80a7416 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -686,6 +686,7 @@ extern int machine_at_ficpa2012_init(const machine_t *); extern int machine_at_r534f_init(const machine_t *); extern int machine_at_ms5146_init(const machine_t *); +extern int machine_at_cb52x_si_init(const machine_t *); extern int machine_at_m560_init(const machine_t *); extern int machine_at_ms5164_init(const machine_t *); diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index fa81b40db..1e3b96a11 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -1087,7 +1087,7 @@ machine_at_r534f_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -1116,7 +1116,7 @@ machine_at_ms5146_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -1127,13 +1127,42 @@ machine_at_ms5146_init(const machine_t *model) pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&sis_5571_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&keyboard_ps2_ali_pci_device); device_add(&w83877f_device); device_add(&sst_flash_29ee010_device); return ret; } +int +machine_at_cb52x_si_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/cb52x_si/CD5205S.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); + + device_add(&sis_5571_device); + device_add(&keyboard_ps2_ali_pci_device); + device_add(&fdc37c669_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + int machine_at_m560_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 7bbd85cda..3584d8f1f 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -11000,11 +11000,11 @@ const machine_t machines[] = { /* SiS 5571 */ /* Has the SiS 5571 chipset with on-chip KBC. */ { - .name = "[SiS 5571] Rise R534F", - .internal_name = "r534f", + .name = "[SiS 5571] Daewoo CB52X-SI", + .internal_name = "cb52x_si", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_SIS_5571, - .init = machine_at_r534f_init, + .init = machine_at_cb52x_si_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, @@ -11012,9 +11012,9 @@ const machine_t machines[] = { .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, - .min_bus = 55000000, - .max_bus = 83333333, - .min_voltage = 2500, + .min_bus = 50000000, + .max_bus = 75000000, + .min_voltage = 2800, .max_voltage = 3520, .min_multi = 1.5, .max_multi = 3.0 @@ -11023,10 +11023,10 @@ const machine_t machines[] = { .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, .ram = { .min = 8192, - .max = 393216, + .max = 262144, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 255, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -11066,7 +11066,7 @@ const machine_t machines[] = { .max = 262144, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 255, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -11078,15 +11078,13 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - - /* ALi ALADDiN IV+ */ - /* Has the ALi M1543 southbridge with on-chip KBC. */ + /* Has the SiS 5571 chipset with on-chip KBC. */ { - .name = "[ALi ALADDiN IV+] PC Chips M560", - .internal_name = "m560", + .name = "[SiS 5571] Rise R534F", + .internal_name = "r534f", .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_ALI_ALADDIN_IV_PLUS, - .init = machine_at_m560_init, + .chipset = MACHINE_CHIPSET_SIS_5571, + .init = machine_at_r534f_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, @@ -11094,7 +11092,7 @@ const machine_t machines[] = { .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, - .min_bus = 50000000, + .min_bus = 55000000, .max_bus = 83333333, .min_voltage = 2500, .max_voltage = 3520, @@ -11105,7 +11103,7 @@ const machine_t machines[] = { .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, .ram = { .min = 8192, - .max = 786432, + .max = 393216, .step = 8192 }, .nvrmask = 255, @@ -11120,6 +11118,8 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + + /* ALi ALADDiN IV+ */ /* Has the ALi M1543 southbridge with on-chip KBC. */ { .name = "[ALi ALADDiN IV+] MSI MS-5164", @@ -11160,6 +11160,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has the ALi M1543 southbridge with on-chip KBC. */ + { + .name = "[ALi ALADDiN IV+] PC Chips M560", + .internal_name = "m560", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_ALI_ALADDIN_IV_PLUS, + .init = machine_at_m560_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 = 83333333, + .min_voltage = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .ram = { + .min = 8192, + .max = 786432, + .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 = NULL, + .net_device = NULL + }, /* Super Socket 7 machines */ /* ALi ALADDiN V */ From 41766a6a1d05e59f652f711f6b18a3ae645bd035 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 6 Jan 2024 01:55:38 +0100 Subject: [PATCH 205/936] PCI changes to accomodate the SiS TRC stuff. --- src/include/86box/pci.h | 1 + src/pci.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index 17f9f6687..f2a98a1b1 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -71,6 +71,7 @@ #define FLAG_CONFIG_M1_IO_ON 0x00000020 #define FLAG_NO_IRQ_STEERING 0x00000040 #define FLAG_NO_BRIDGES 0x00000080 +#define FLAG_TRC_CONTROLS_SRST 0x00000100 #define FLAG_MECHANISM_MASK FLAG_MECHANISM_1 | FLAG_MECHANISM_2 #define FLAG_MASK 0x0000007f diff --git a/src/pci.c b/src/pci.c index 7c61545b2..414370bdd 100644 --- a/src/pci.c +++ b/src/pci.c @@ -424,6 +424,9 @@ pci_write(uint16_t port, uint8_t val, UNUSED(void *priv)) } break; case 0xcf9: + if (pci_flags & FLAG_TRC_CONTROLS_SRST) + cpu_cpusrst_on_sr = !(val & 0x10); + if (!(pci_trc_reg & 4) && (val & 4)) pci_trc_reset(val); From 2fb04b63ecf4c24c15921455a21f58cf1ca58eb0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 6 Jan 2024 01:59:06 +0100 Subject: [PATCH 206/936] Some corrections. --- src/include/86box/pci.h | 2 +- src/machine/m_at_socket7.c | 6 +++--- src/machine/m_at_socket7_3v.c | 4 ++-- src/pci.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index f2a98a1b1..2bcb6b3b8 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -71,7 +71,7 @@ #define FLAG_CONFIG_M1_IO_ON 0x00000020 #define FLAG_NO_IRQ_STEERING 0x00000040 #define FLAG_NO_BRIDGES 0x00000080 -#define FLAG_TRC_CONTROLS_SRST 0x00000100 +#define FLAG_TRC_CONTROLS_CPURST 0x00000100 #define FLAG_MECHANISM_MASK FLAG_MECHANISM_1 | FLAG_MECHANISM_2 #define FLAG_MASK 0x0000007f diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 1e3b96a11..01459f144 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -1089,7 +1089,7 @@ machine_at_r534f_init(const machine_t *model) machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); @@ -1118,7 +1118,7 @@ machine_at_ms5146_init(const machine_t *model) machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); @@ -1147,7 +1147,7 @@ machine_at_cb52x_si_init(const machine_t *model) machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index a1b6de325..0e420aa3b 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -752,7 +752,7 @@ machine_at_ap5s_init(const machine_t *model) machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); @@ -781,7 +781,7 @@ machine_at_ms5124_init(const machine_t *model) machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0xFE, 0xFF, 0, 0); pci_register_slot(0x10, PCI_CARD_NORMAL, 1, 2, 3, 4); diff --git a/src/pci.c b/src/pci.c index 414370bdd..15a119cb7 100644 --- a/src/pci.c +++ b/src/pci.c @@ -424,8 +424,8 @@ pci_write(uint16_t port, uint8_t val, UNUSED(void *priv)) } break; case 0xcf9: - if (pci_flags & FLAG_TRC_CONTROLS_SRST) - cpu_cpusrst_on_sr = !(val & 0x10); + if (pci_flags & FLAG_TRC_CONTROLS_CPURST) + cpu_cpurst_on_sr = !(val & 0x10); if (!(pci_trc_reg & 4) && (val & 4)) pci_trc_reset(val); From 258c55dcd36e6c67f26997d0665de823538c1a5e Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Sun, 7 Jan 2024 09:04:25 +1300 Subject: [PATCH 207/936] EGA, (S)VGA: Fix vertical fine scroll behaviour Ref: GH-4001 --- src/video/vid_ega.c | 7 ++++--- src/video/vid_svga.c | 8 +++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 7cd6c6f17..d471247aa 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -555,7 +555,7 @@ ega_recalctimings(ega_t *ega) if (ega->seqregs[1] & 8) overscan_x <<= 1; - ega->y_add = (overscan_y >> 1) - (ega->crtc[8] & 0x1f); + ega->y_add = (overscan_y >> 1); ega->x_add = (overscan_x >> 1); if (ega->seqregs[1] & 8) { @@ -769,6 +769,7 @@ ega_poll(void *priv) if ((ega->sc == (ega->crtc[11] & 31)) || (ega->sc == ega->rowcount)) ega->con = 0; if (ega->dispon) { + /* TODO: Verify real hardware behaviour for out-of-range fine vertical scroll */ if (ega->linedbl && !ega->linecountff) { ega->linecountff = 1; ega->ma = ega->maback; @@ -881,7 +882,7 @@ ega_poll(void *priv) } if (ega->vc == ega->vtotal) { ega->vc = 0; - ega->sc = 0; + ega->sc = (ega->crtc[0x8] & 0x1f); ega->dispon = 1; ega->displine = (ega->interlace && ega->oddeven) ? 1 : 0; @@ -916,7 +917,7 @@ ega_doblit(int wx, int wy, ega_t *ega) int x_add = enable_overscan ? overscan_x : 0; int y_start = enable_overscan ? 0 : (overscan_y >> 1); int x_start = enable_overscan ? 0 : (overscan_x >> 1); - int bottom = (overscan_y >> 1) + (ega->crtc[8] & 0x1f); + int bottom = (overscan_y >> 1); uint32_t *p; int i; int j; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 71109ce0e..12c549765 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -741,7 +741,7 @@ svga_recalctimings(svga_t *svga) if (svga->hdisp >= 2048) svga->monitor->mon_overscan_x = 0; - svga->y_add = (svga->monitor->mon_overscan_y >> 1) - (svga->crtc[8] & 0x1f); + svga->y_add = (svga->monitor->mon_overscan_y >> 1); svga->x_add = (svga->monitor->mon_overscan_x >> 1); if (svga->vblankstart < svga->dispend) @@ -942,6 +942,8 @@ svga_poll(void *priv) if ((svga->sc == (svga->crtc[11] & 31)) || (svga->sc == svga->rowcount)) svga->con = 0; if (svga->dispon) { + /* TODO: Verify real hardware behaviour for out-of-range fine vertical scroll + - S3 Trio64V2/DX: sc == rowcount, wrapping 5-bit counter. */ if (svga->linedbl && !svga->linecountff) { svga->linecountff = 1; svga->ma = svga->maback; @@ -1065,7 +1067,7 @@ svga_poll(void *priv) } if (svga->vc == svga->vtotal) { svga->vc = 0; - svga->sc = 0; + svga->sc = (svga->crtc[0x8] & 0x1f); svga->dispon = 1; svga->displine = (svga->interlace && svga->oddeven) ? 1 : 0; @@ -1642,7 +1644,7 @@ svga_doblit(int wx, int wy, svga_t *svga) x_add = enable_overscan ? svga->monitor->mon_overscan_x : 0; y_start = enable_overscan ? 0 : (svga->monitor->mon_overscan_y >> 1); x_start = enable_overscan ? 0 : (svga->monitor->mon_overscan_x >> 1); - bottom = (svga->monitor->mon_overscan_y >> 1) + (svga->crtc[8] & 0x1f); + bottom = (svga->monitor->mon_overscan_y >> 1); if (svga->vertical_linedbl) { y_add <<= 1; From bf52ef7598a0b7243c776c59b16eade9edcf10a9 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Sun, 7 Jan 2024 11:21:38 +1300 Subject: [PATCH 208/936] Add "86Box unit tester" config option + Qt UI checkbox This is in preparation for making the device actually exist. --- src/86box.c | 1 + src/config.c | 10 ++++++++-- src/include/86box/86box.h | 1 + src/qt/qt_settingsotherperipherals.cpp | 8 +++++--- src/qt/qt_settingsotherperipherals.ui | 7 +++++++ 5 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/86box.c b/src/86box.c index 2e9434b82..31c0c0e09 100644 --- a/src/86box.c +++ b/src/86box.c @@ -173,6 +173,7 @@ bool serial_passthrough_enabled[SERIAL_MAX] = { 0, 0, 0, 0 }; /* (C) activat pass-through for serial ports */ int bugger_enabled = 0; /* (C) enable ISAbugger */ int postcard_enabled = 0; /* (C) enable POST card */ +int unittester_enabled = 0; /* (C) enable unit tester device */ int isamem_type[ISAMEM_MAX] = { 0, 0, 0, 0 }; /* (C) enable ISA mem cards */ int isartc_type = 0; /* (C) enable ISA RTC card */ int gfxcard[2] = { 0, 0 }; /* (C) graphics/video card */ diff --git a/src/config.c b/src/config.c index 8c4ad0de4..c973abf23 100644 --- a/src/config.c +++ b/src/config.c @@ -1514,8 +1514,9 @@ load_other_peripherals(void) char *p; char temp[512]; - bugger_enabled = !!ini_section_get_int(cat, "bugger_enabled", 0); - postcard_enabled = !!ini_section_get_int(cat, "postcard_enabled", 0); + bugger_enabled = !!ini_section_get_int(cat, "bugger_enabled", 0); + postcard_enabled = !!ini_section_get_int(cat, "postcard_enabled", 0); + unittester_enabled = !!ini_section_get_int(cat, "unittester_enabled", 0); for (uint8_t c = 0; c < ISAMEM_MAX; c++) { sprintf(temp, "isamem%d_type", c); @@ -2348,6 +2349,11 @@ save_other_peripherals(void) else ini_section_set_int(cat, "postcard_enabled", postcard_enabled); + if (unittester_enabled == 0) + ini_section_delete_var(cat, "unittester_enabled"); + else + ini_section_set_int(cat, "unittester_enabled", unittester_enabled); + for (uint8_t c = 0; c < ISAMEM_MAX; c++) { sprintf(temp, "isamem%d_type", c); if (isamem_type[c] == 0) diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index c16cd5efb..20f3fffcc 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -125,6 +125,7 @@ extern int gfxcard[2]; /* (C) graphics/video card */ extern char video_shader[512]; /* (C) video */ extern int bugger_enabled; /* (C) enable ISAbugger */ extern int postcard_enabled; /* (C) enable POST card */ +extern int unittester_enabled; /* (C) enable unit tester device */ extern int isamem_type[]; /* (C) enable ISA mem cards */ extern int isartc_type; /* (C) enable ISA RTC card */ extern int sound_is_float; /* (C) sound uses FP values */ diff --git a/src/qt/qt_settingsotherperipherals.cpp b/src/qt/qt_settingsotherperipherals.cpp index d168138a5..ad7a00bb4 100644 --- a/src/qt/qt_settingsotherperipherals.cpp +++ b/src/qt/qt_settingsotherperipherals.cpp @@ -44,6 +44,7 @@ SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) bool machineHasIsa = (machine_has_bus(machineId, MACHINE_BUS_ISA) > 0); ui->checkBoxISABugger->setChecked((machineHasIsa && (bugger_enabled > 0)) ? true : false); ui->checkBoxPOSTCard->setChecked(postcard_enabled > 0 ? true : false); + ui->checkBoxUnitTester->setChecked(unittester_enabled > 0 ? true : false); ui->checkBoxISABugger->setEnabled(machineHasIsa); ui->comboBoxRTC->setEnabled(machineHasIsa); ui->pushButtonConfigureRTC->setEnabled(machineHasIsa); @@ -112,9 +113,10 @@ void SettingsOtherPeripherals::save() { /* Other peripherals category */ - bugger_enabled = ui->checkBoxISABugger->isChecked() ? 1 : 0; - postcard_enabled = ui->checkBoxPOSTCard->isChecked() ? 1 : 0; - isartc_type = ui->comboBoxRTC->currentData().toInt(); + bugger_enabled = ui->checkBoxISABugger->isChecked() ? 1 : 0; + postcard_enabled = ui->checkBoxPOSTCard->isChecked() ? 1 : 0; + unittester_enabled = ui->checkBoxUnitTester->isChecked() ? 1 : 0; + isartc_type = ui->comboBoxRTC->currentData().toInt(); /* ISA memory boards. */ for (int i = 0; i < ISAMEM_MAX; i++) { diff --git a/src/qt/qt_settingsotherperipherals.ui b/src/qt/qt_settingsotherperipherals.ui index 01f5545f8..481d80ebe 100644 --- a/src/qt/qt_settingsotherperipherals.ui +++ b/src/qt/qt_settingsotherperipherals.ui @@ -190,6 +190,13 @@ + + + + 86Box unit tester + + + From 72b465e18126c02e9ddb04ad54696428d643f70e Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Sun, 7 Jan 2024 11:50:22 +1300 Subject: [PATCH 209/936] Add dummy 86Box Unit Tester device --- src/86box.c | 3 ++ src/device/CMakeLists.txt | 2 +- src/device/unittester.c | 79 ++++++++++++++++++++++++++++++++++ src/include/86box/unittester.h | 35 +++++++++++++++ 4 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 src/device/unittester.c create mode 100644 src/include/86box/unittester.h diff --git a/src/86box.c b/src/86box.c index 31c0c0e09..220d38dfa 100644 --- a/src/86box.c +++ b/src/86box.c @@ -65,6 +65,7 @@ #include <86box/machine.h> #include <86box/bugger.h> #include <86box/postcard.h> +#include <86box/unittester.h> #include <86box/isamem.h> #include <86box/isartc.h> #include <86box/lpt.h> @@ -1222,6 +1223,8 @@ pc_reset_hard_init(void) device_add(&bugger_device); if (postcard_enabled) device_add(&postcard_device); + if (unittester_enabled) + device_add(&unittester_device); if (IS_ARCH(machine, MACHINE_BUS_PCI)) { pci_register_cards(); diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index 9e2c2b53d..24a9d7ac4 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -17,7 +17,7 @@ add_library(dev OBJECT bugger.c cassette.c cartridge.c hasp.c hwm.c hwm_lm75.c hwm_lm78.c hwm_gl518sm.c hwm_vt82c686.c ibm_5161.c isamem.c isartc.c ../lpt.c pci_bridge.c - postcard.c serial.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c + postcard.c serial.c unittester.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c smbus_piix4.c smbus_ali7101.c keyboard.c keyboard_xt.c kbc_at.c kbc_at_dev.c keyboard_at.c diff --git a/src/device/unittester.c b/src/device/unittester.c new file mode 100644 index 000000000..8b4a0ca5b --- /dev/null +++ b/src/device/unittester.c @@ -0,0 +1,79 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Debug device for assisting in unit testing. + * + * + * + * Authors: GreaseMonkey, + * + * Copyright 2024 GreaseMonkey. + */ +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/plat.h> +#include <86box/unittester.h> + +static uint16_t unittester_trigger_port = 0x0080; +static uint16_t unittester_base_port = 0xFFFF; + +/* FIXME TEMPORARY --GM */ +#define ENABLE_UNITTESTER_LOG 1 + +#ifdef ENABLE_UNITTESTER_LOG +int unittester_do_log = ENABLE_UNITTESTER_LOG; + +static void +unittester_log(const char *fmt, ...) +{ + va_list ap; + + if (unittester_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define unittester_log(fmt, ...) +#endif + +static void * +unittester_init(UNUSED(const device_t *info)) +{ + //io_sethandler(unittester_trigger_port, 1, NULL, NULL, NULL, unittester_write, NULL, NULL, NULL); + unittester_log("[UT] 86Box Unit Tester initialised\n"); + + return &unittester_trigger_port; /* Dummy non-NULL value */ +} + +static void +unittester_close(UNUSED(void *priv)) +{ + //io_removehandler(unittester_trigger_port, 1, NULL, NULL, NULL, unittester_write, NULL, NULL, NULL); + unittester_log("[UT] 86Box Unit Tester closed\n"); +} + +const device_t unittester_device = { + .name = "86Box Unit Tester", + .internal_name = "unittester", + .flags = DEVICE_ISA, + .local = 0, + .init = unittester_init, + .close = unittester_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/include/86box/unittester.h b/src/include/86box/unittester.h new file mode 100644 index 000000000..1e1255f52 --- /dev/null +++ b/src/include/86box/unittester.h @@ -0,0 +1,35 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Debug device for assisting in unit testing. + * + * + * + * Authors: GreaseMonkey, + * + * Copyright 2024 GreaseMonkey. + */ + +#ifndef UNITTESTER_H +#define UNITTESTER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Global variables. */ +extern const device_t unittester_device; + +/* Functions. */ + +#ifdef __cplusplus +} +#endif + +#endif /*UNITTESTER_H*/ + From 130d4094e17de91978e7e399679b76e20d1f755b Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Sun, 7 Jan 2024 13:17:21 +1300 Subject: [PATCH 210/936] unittester: Implement basic activation + IOBASE-setting protocol Next up is the actual I/O ports! --- src/device/unittester.c | 106 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 101 insertions(+), 5 deletions(-) diff --git a/src/device/unittester.c b/src/device/unittester.c index 8b4a0ca5b..5c0932847 100644 --- a/src/device/unittester.c +++ b/src/device/unittester.c @@ -21,11 +21,42 @@ #include #define HAVE_STDARG_H #include <86box/86box.h> +#include <86box/io.h> #include <86box/plat.h> #include <86box/unittester.h> -static uint16_t unittester_trigger_port = 0x0080; -static uint16_t unittester_base_port = 0xFFFF; +enum fsm1_value { + UT_FSM1_WAIT_8, + UT_FSM1_WAIT_6, + UT_FSM1_WAIT_B, + UT_FSM1_WAIT_o, + UT_FSM1_WAIT_x, +}; +enum fsm2_value { + UT_FSM2_IDLE, + UT_FSM2_WAIT_IOBASE_0, + UT_FSM2_WAIT_IOBASE_1, +}; + +struct unittester_state { + /* I/O port settings */ + uint16_t trigger_port; + uint16_t iobase_port; + + /* Trigger port finite state machines */ + /* FSM1: "86Box" string detection */ + enum fsm1_value fsm1; + /* FSM2: IOBASE port selection, once trigger is activated */ + enum fsm2_value fsm2; + uint16_t fsm2_new_iobase; +}; +static struct unittester_state unittester; +static const struct unittester_state unittester_defaults = { + .trigger_port = 0x0080, + .iobase_port = 0xFFFF, + .fsm1 = UT_FSM1_WAIT_8, + .fsm2 = UT_FSM2_IDLE, +}; /* FIXME TEMPORARY --GM */ #define ENABLE_UNITTESTER_LOG 1 @@ -48,19 +79,84 @@ unittester_log(const char *fmt, ...) # define unittester_log(fmt, ...) #endif +static void +unittester_trigger_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv)) +{ + /* Update FSM2 */ + switch (unittester.fsm2) { + /* IDLE: Do nothing - FSM1 will put us in the right state. */ + case UT_FSM2_IDLE: + unittester.fsm2 = UT_FSM2_IDLE; + break; + + /* WAIT IOBASE 0: Set low byte of temporary IOBASE. */ + case UT_FSM2_WAIT_IOBASE_0: + unittester.fsm2_new_iobase = ((uint16_t)val); + unittester.fsm2 = UT_FSM2_WAIT_IOBASE_1; + break; + + /* WAIT IOBASE 0: Set high byte of temporary IOBASE and commit to the real IOBASE. */ + case UT_FSM2_WAIT_IOBASE_1: + unittester.fsm2_new_iobase |= ((uint16_t)val)<<8; + unittester.iobase_port = unittester.fsm2_new_iobase; + unittester.fsm2 = UT_FSM2_IDLE; + break; + } + + /* Update FSM1 */ + switch (val) { + case '8': + unittester.fsm1 = UT_FSM1_WAIT_6; + break; + case '6': + if (unittester.fsm1 == UT_FSM1_WAIT_6) + unittester.fsm1 = UT_FSM1_WAIT_B; + else + unittester.fsm1 = UT_FSM1_WAIT_8; + break; + case 'B': + if (unittester.fsm1 == UT_FSM1_WAIT_B) + unittester.fsm1 = UT_FSM1_WAIT_o; + else + unittester.fsm1 = UT_FSM1_WAIT_8; + break; + case 'o': + if (unittester.fsm1 == UT_FSM1_WAIT_o) + unittester.fsm1 = UT_FSM1_WAIT_x; + else + unittester.fsm1 = UT_FSM1_WAIT_8; + break; + case 'x': + if (unittester.fsm1 == UT_FSM1_WAIT_x) { + unittester.fsm2 = UT_FSM2_WAIT_IOBASE_0; + } + unittester.fsm1 = UT_FSM1_WAIT_8; + break; + + default: + unittester.fsm1 = UT_FSM1_WAIT_8; + break; + } + + unittester_log("[UT] Trigger value %02X -> FSM1 = %02X, FSM2 = %02X, IOBASE = %04X\n", val, unittester.fsm1, unittester.fsm2, unittester.iobase_port); +} + static void * unittester_init(UNUSED(const device_t *info)) { - //io_sethandler(unittester_trigger_port, 1, NULL, NULL, NULL, unittester_write, NULL, NULL, NULL); + unittester = (struct unittester_state)unittester_defaults; + io_sethandler(unittester.trigger_port, 1, NULL, NULL, NULL, unittester_trigger_write, NULL, NULL, NULL); + unittester_log("[UT] 86Box Unit Tester initialised\n"); - return &unittester_trigger_port; /* Dummy non-NULL value */ + return &unittester; /* Dummy non-NULL value */ } static void unittester_close(UNUSED(void *priv)) { - //io_removehandler(unittester_trigger_port, 1, NULL, NULL, NULL, unittester_write, NULL, NULL, NULL); + io_removehandler(unittester.trigger_port, 1, NULL, NULL, NULL, unittester_trigger_write, NULL, NULL, NULL); + unittester_log("[UT] 86Box Unit Tester closed\n"); } From 5279cd5d8d84f40f652a29175ae3b5857095e817 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Sun, 7 Jan 2024 13:31:45 +1300 Subject: [PATCH 211/936] unittester: Add dummy main ports Reads and writes mostly do nothing but log, although the status returns a dummy value of 0x04 (no command in flight, not waiting for anything, and no errors). --- src/device/unittester.c | 57 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/src/device/unittester.c b/src/device/unittester.c index 5c0932847..2f706c8e3 100644 --- a/src/device/unittester.c +++ b/src/device/unittester.c @@ -79,9 +79,46 @@ unittester_log(const char *fmt, ...) # define unittester_log(fmt, ...) #endif +static void +unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) +{ + if (port == unittester.iobase_port+0x00) { + /* Command port */ + /* TODO! --GM */ + unittester_log("[UT] W %02X Command\n", val); + } else if (port == unittester.iobase_port+0x01) { + /* Data port */ + /* TODO! --GM */ + unittester_log("[UT] W %02X Data\n", val); + } else { + /* Not handled here - possibly open bus! */ + } +} + +static uint8_t +unittester_read(uint16_t port, UNUSED(void *priv)) +{ + if (port == unittester.iobase_port+0x00) { + /* Status port */ + /* TODO! --GM */ + unittester_log("[UT] R -- Status\n"); + return 0x04; + } else if (port == unittester.iobase_port+0x01) { + /* Data port */ + /* TODO! --GM */ + unittester_log("[UT] R -- Data\n"); + return 0xFE; + } else { + /* Not handled here - possibly open bus! */ + return 0xFF; + } +} + static void unittester_trigger_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv)) { + unittester_log("[UT] Trigger value %02X -> FSM1 = %02X, FSM2 = %02X, IOBASE = %04X\n", val, unittester.fsm1, unittester.fsm2, unittester.iobase_port); + /* Update FSM2 */ switch (unittester.fsm2) { /* IDLE: Do nothing - FSM1 will put us in the right state. */ @@ -98,7 +135,20 @@ unittester_trigger_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv)) /* WAIT IOBASE 0: Set high byte of temporary IOBASE and commit to the real IOBASE. */ case UT_FSM2_WAIT_IOBASE_1: unittester.fsm2_new_iobase |= ((uint16_t)val)<<8; + + unittester_log("[UT] Remapping IOBASE: %04X -> %04X\n", val, unittester.iobase_port, unittester.fsm2_new_iobase); + + /* Unmap old IOBASE */ + if (unittester.iobase_port != 0xFFFF) + io_removehandler(unittester.iobase_port, 2, unittester_read, NULL, NULL, unittester_write, NULL, NULL, NULL); + unittester.iobase_port = 0xFFFF; + + /* Map new IOBASE */ unittester.iobase_port = unittester.fsm2_new_iobase; + if (unittester.iobase_port != 0xFFFF) + io_sethandler(unittester.iobase_port, 2, unittester_read, NULL, NULL, unittester_write, NULL, NULL, NULL); + + /* Reset FSM2 to IDLE */ unittester.fsm2 = UT_FSM2_IDLE; break; } @@ -128,6 +178,7 @@ unittester_trigger_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv)) break; case 'x': if (unittester.fsm1 == UT_FSM1_WAIT_x) { + unittester_log("[UT] Config activated, awaiting new IOBASE\n"); unittester.fsm2 = UT_FSM2_WAIT_IOBASE_0; } unittester.fsm1 = UT_FSM1_WAIT_8; @@ -137,8 +188,6 @@ unittester_trigger_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv)) unittester.fsm1 = UT_FSM1_WAIT_8; break; } - - unittester_log("[UT] Trigger value %02X -> FSM1 = %02X, FSM2 = %02X, IOBASE = %04X\n", val, unittester.fsm1, unittester.fsm2, unittester.iobase_port); } static void * @@ -157,6 +206,10 @@ unittester_close(UNUSED(void *priv)) { io_removehandler(unittester.trigger_port, 1, NULL, NULL, NULL, unittester_trigger_write, NULL, NULL, NULL); + if (unittester.iobase_port != 0xFFFF) + io_removehandler(unittester.iobase_port, 2, unittester_read, NULL, NULL, unittester_write, NULL, NULL, NULL); + unittester.iobase_port = 0xFFFF; + unittester_log("[UT] 86Box Unit Tester closed\n"); } From 4f392ca8e3592674eacbdc2db616b1f5e512c85b Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 7 Jan 2024 01:42:34 +0100 Subject: [PATCH 212/936] SM(S)C FDC37C669 Super I/O chip rewrite and proper FDC power down behavior, fixes floppy drive errors on the new Daeweoo machine. --- src/floppy/fdc.c | 149 +++++++-------- src/floppy/fdd_86f.c | 97 ++++++---- src/include/86box/fdc.h | 106 ++++++----- src/machine/m_at_socket7.c | 10 +- src/sio/sio_fdc37c669.c | 375 ++++++++++++++++++++----------------- 5 files changed, 397 insertions(+), 340 deletions(-) diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 88948aed9..f30d86168 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -212,6 +212,7 @@ fdc_ctrl_reset(void *priv) fdc->lock = 0; fdc->head = 0; fdc->step = 0; + fdc->power_down = 0; if (!(fdc->flags & FDC_FLAG_AT)) fdc->rate = 2; } @@ -257,7 +258,7 @@ fdc_set_wrong_am(fdc_t *fdc) int fdc_get_drive(fdc_t *fdc) { - return fdc->drive; + return (int) fdc->drive; } int fdc_get_bitcell_period(fdc_t *fdc); @@ -270,7 +271,7 @@ fdc_get_perp(fdc_t *fdc) if (!(fdc->flags & FDC_FLAG_AT) || (fdc->flags & FDC_FLAG_PCJR)) return 0; - return fdc->perp; + return (int) fdc->perp; } int @@ -292,7 +293,7 @@ fdc_get_gap2(fdc_t *fdc, int drive) int fdc_get_format_n(fdc_t *fdc) { - return fdc->format_n; + return (int) fdc->format_n; } int @@ -321,7 +322,7 @@ fdc_stop_id_request(fdc_t *fdc) int fdc_get_gap(fdc_t *fdc) { - return fdc->gap; + return (int) fdc->gap; } int @@ -333,7 +334,7 @@ fdc_get_dtl(fdc_t *fdc) int fdc_get_format_sectors(fdc_t *fdc) { - return fdc->format_sectors; + return (int) fdc->format_sectors; } static void @@ -418,6 +419,12 @@ fdc_update_rates(fdc_t *fdc) fdc_rate(fdc, 3); } +void +fdc_set_power_down(fdc_t *fdc, uint8_t power_down) +{ + fdc->power_down = power_down; +} + void fdc_update_max_track(fdc_t *fdc, int max_track) { @@ -427,7 +434,7 @@ fdc_update_max_track(fdc_t *fdc, int max_track) void fdc_update_enh_mode(fdc_t *fdc, int enh_mode) { - fdc->enh_mode = enh_mode; + fdc->enh_mode = !!enh_mode; fdc_update_rates(fdc); } @@ -490,7 +497,7 @@ fdc_update_drvrate(fdc_t *fdc, int drive, int drvrate) void fdc_update_drv2en(fdc_t *fdc, int drv2en) { - fdc->drv2en = drv2en; + fdc->drv2en = !!drv2en; } void @@ -500,37 +507,34 @@ fdc_update_rate(fdc_t *fdc, int drive) fdc->bit_rate = 500; else if ((fdc->rwc[drive] == 3) && fdc->enh_mode) fdc->bit_rate = 250; - else - switch (fdc->rate) { - case 0: /*High density*/ - fdc->bit_rate = 500; - break; - case 1: /*Double density (360 rpm)*/ - switch (fdc->drvrate[drive]) { - case 0: - fdc->bit_rate = 300; - break; - case 1: - fdc->bit_rate = 500; - break; - case 2: - fdc->bit_rate = 2000; - break; - - default: - break; - } - break; - case 2: /*Double density*/ - fdc->bit_rate = 250; - break; - case 3: /*Extended density*/ - fdc->bit_rate = 1000; - break; - - default: - break; - } + else switch (fdc->rate) { + default: + break; + case 0: /*High density*/ + fdc->bit_rate = 500; + break; + case 1: /*Double density (360 rpm)*/ + switch (fdc->drvrate[drive]) { + default: + break; + case 0: + fdc->bit_rate = 300; + break; + case 1: + fdc->bit_rate = 500; + break; + case 2: + fdc->bit_rate = 2000; + break; + } + break; + case 2: /*Double density*/ + fdc->bit_rate = 250; + break; + case 3: /*Extended density*/ + fdc->bit_rate = 1000; + break; + } fdc->bitcell_period = (1000000 / fdc->bit_rate) * 2; /*Bitcell period in ns*/ } @@ -688,10 +692,6 @@ fdc_io_command_phase1(fdc_t *fdc, int out) fdc->stat |= 0x20; else dma_set_drq(fdc->dma_ch, 1); - if (out) - fdc->pos = 0; - else - fdc->inread = 1; } static void @@ -741,7 +741,7 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) cycles -= ISA_CYCLES(8); - switch (addr & 7) { + if (!fdc->power_down || ((addr & 7) == 2) || ((addr & 7) == 4)) switch (addr & 7) { case 0: return; case 1: @@ -776,14 +776,20 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->pnum = fdc->ptot = 0; } if ((val & 4) && !(fdc->dor & 4)) { - timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC); - fdc->interrupt = -1; - fdc->perp &= 0xfc; + if (fdc->power_down) { + timer_set_delay_u64(&fdc->timer, 1000 * TIMER_USEC); + fdc->interrupt = -5; + } else { + timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC); + fdc->interrupt = -1; - for (i = 0; i < FDD_NUM; i++) - ui_sb_update_icon(SB_FLOPPY | i, 0); + fdc->perp &= 0xfc; - fdc_ctrl_reset(fdc); + for (i = 0; i < FDD_NUM; i++) + ui_sb_update_icon(SB_FLOPPY | i, 0); + + fdc_ctrl_reset(fdc); + } } /* We can now simplify this since each motor now spins separately. */ for (i = 0; i < FDD_NUM; i++) { @@ -854,7 +860,6 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->pnum = 0; fdc->ptot = 4; fdc->stat |= 0x90; - fdc->pos = 0; fdc->format_state = 0; } else fdc_bad_command(fdc); @@ -866,7 +871,6 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->pnum = 0; fdc->ptot = 8; fdc->stat |= 0x90; - fdc->pos = 0; fdc->mfm = (fdc->command & 0x40) ? 1 : 0; break; case 0x03: /*Specify*/ @@ -888,7 +892,6 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->pnum = 0; fdc->ptot = 8; fdc->stat |= 0x90; - fdc->pos = 0; fdc->mfm = (fdc->command & 0x40) ? 1 : 0; break; case 0x06: /*Read data*/ @@ -907,7 +910,6 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->pnum = 0; fdc->ptot = 8; fdc->stat |= 0x90; - fdc->pos = 0; fdc->mfm = (fdc->command & 0x40) ? 1 : 0; break; case 0x17: /*Powerdown mode*/ @@ -924,28 +926,24 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) case 0x08: /*Sense interrupt status*/ fdc_log("fdc->fintr = %i, fdc->reset_stat = %i\n", fdc->fintr, fdc->reset_stat); fdc->lastdrive = fdc->drive; - fdc->pos = 0; fdc_sis(fdc); break; case 0x0a: /*Read sector ID*/ fdc->pnum = 0; fdc->ptot = 1; fdc->stat |= 0x90; - fdc->pos = 0; fdc->mfm = (fdc->command & 0x40) ? 1 : 0; break; case 0x0d: /*Format track*/ fdc->pnum = 0; fdc->ptot = 5; fdc->stat |= 0x90; - fdc->pos = 0; fdc->mfm = (fdc->command & 0x40) ? 1 : 0; fdc->format_state = 0; break; case 0x0e: /*Dump registers*/ fdc->lastdrive = fdc->drive; fdc->interrupt = 0x0e; - fdc->pos = 0; fdc_callback(fdc); break; case 0x0f: /*Seek*/ @@ -964,7 +962,6 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) case 0x94: /*Lock*/ fdc->lastdrive = fdc->drive; fdc->interrupt = fdc->command; - fdc->pos = 0; fdc_callback(fdc); break; case 0x12: /*Set perpendicular mode*/ @@ -972,7 +969,6 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->pnum = 0; fdc->ptot = 1; fdc->stat |= 0x90; - fdc->pos = 0; } else fdc_bad_command(fdc); break; @@ -980,7 +976,6 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->pnum = 0; fdc->ptot = 3; fdc->stat |= 0x90; - fdc->pos = 0; break; default: fdc_bad_command(fdc); @@ -1151,7 +1146,6 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->format_sectors = fdc->params[2]; fdc->format_n = fdc->params[1]; fdc->format_state = 1; - fdc->pos = 0; fdc->stat = 0x10; break; case 0x0f: /* Seek */ @@ -1273,12 +1267,12 @@ uint8_t fdc_read(uint16_t addr, void *priv) { fdc_t *fdc = (fdc_t *) priv; - uint8_t ret; + uint8_t ret = 0xff; int drive = 0; cycles -= ISA_CYCLES(8); - switch (addr & 7) { + if (!fdc->power_down || ((addr & 7) == 2)) switch (addr & 7) { case 0: /* STA */ if (fdc->flags & FDC_FLAG_PS1) { drive = real_drive(fdc, fdc->dor & 3); @@ -1513,7 +1507,6 @@ fdc_poll_readwrite_finish(fdc_t *fdc, int compare) if ((fdc->interrupt == 5) || (fdc->interrupt == 9)) fdd_do_writeback(real_drive(fdc, fdc->drive)); - fdc->inread = 0; fdc->interrupt = -2; fdc_poll_common_finish(fdc, compare, 0); @@ -1544,10 +1537,21 @@ fdc_callback(void *priv) case -2: /*End of command*/ fdc->stat = (fdc->stat & 0xf) | 0x80; return; + case -5: /*Reset in power down mode */ + fdc->perp &= 0xfc; + + for (uint8_t i = 0; i < FDD_NUM; i++) + ui_sb_update_icon(SB_FLOPPY | i, 0); + + fdc_ctrl_reset(fdc); + + fdc->fintr = 0; + memset(fdc->pcn, 0x00, 4 * sizeof(uint16_t)); + return; case -1: /*Reset*/ fdc_int(fdc, 1); fdc->fintr = 0; - memset(fdc->pcn, 0, 4 * sizeof(int)); + memset(fdc->pcn, 0x00, 4 * sizeof(uint16_t)); fdc->reset_stat = 4; return; case 0x01: /* Mode */ @@ -1570,7 +1574,6 @@ fdc_callback(void *priv) fdc->stat = 0x50; } } - fdc->inread = 1; return; case 0x04: /* Sense drive status */ fdc->res[10] = (fdc->params[0] & 7) | 0x20; @@ -1715,7 +1718,6 @@ fdc_callback(void *priv) default: break; } - fdc->inread = 1; return; case 0x07: /* Recalibrate */ fdc->pcn[fdc->params[0] & 3] = 0; @@ -2004,18 +2006,11 @@ fdc_data(fdc_t *fdc, uint8_t data, int last) return 0; } -void -fdc_finishread(fdc_t *fdc) -{ - fdc->inread = 0; -} - void fdc_track_finishread(fdc_t *fdc, int condition) { fdc->stat = 0x10; fdc->satisfying_sectors |= condition; - fdc->inread = 0; fdc_callback(fdc); } @@ -2025,7 +2020,6 @@ fdc_sector_finishcompare(fdc_t *fdc, int satisfying) fdc->stat = 0x10; if (satisfying) fdc->satisfying_sectors++; - fdc->inread = 0; fdc_callback(fdc); } @@ -2033,7 +2027,6 @@ void fdc_sector_finishread(fdc_t *fdc) { fdc->stat = 0x10; - fdc->inread = 0; fdc_callback(fdc); } @@ -2356,6 +2349,8 @@ fdc_reset(void *priv) for (uint8_t i = 0; i < FDD_NUM; i++) ui_sb_update_icon(SB_FLOPPY | i, 0); + + fdc->power_down = 0; } static void @@ -2418,7 +2413,7 @@ fdc_init(const device_t *info) void fdc_3f1_enable(fdc_t *fdc, int enable) { - fdc->enable_3f1 = enable; + fdc->enable_3f1 = !!enable; } const device_t fdc_xt_device = { diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index 08e57c09b..fa1c070f1 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -1274,18 +1274,19 @@ d86f_find_address_mark_fm(int drive, int side, find_t *find, uint16_t req_am, ui if (dev->last_word[side] == req_am) { dev->calc_crc.word = 0xFFFF; fdd_calccrc(decodefm(drive, dev->last_word[side]), &(dev->calc_crc)); - find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; - find->sync_pos = 0xFFFFFFFF; - dev->preceding_bit[side] = dev->last_word[side] & 1; + find->sync_marks = find->bits_obtained = + find->bytes_obtained = 0; + find->sync_pos = 0xFFFFFFFF; + dev->preceding_bit[side] = dev->last_word[side] & 1; dev->state++; return; } if (wrong_am && (dev->last_word[side] == wrong_am)) { - dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; - dev->error_condition = 0; - dev->state = STATE_IDLE; - fdc_finishread(d86f_fdc); + dev->data_find.sync_marks = dev->data_find.bits_obtained = + dev->data_find.bytes_obtained = 0; + dev->error_condition = 0; + dev->state = STATE_IDLE; fdc_nodataam(d86f_fdc); return; } @@ -1328,8 +1329,9 @@ d86f_write_find_address_mark_fm(int drive, int side, find_t *find) /* If we hadn't found enough set bits but have found a clear bit, null the counter of set bits. */ if (!(dev->last_word[side] & 1)) { - find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; - find->sync_pos = 0xFFFFFFFF; + find->sync_marks = find->bits_obtained = + find->bytes_obtained = 0; + find->sync_pos = 0xFFFFFFFF; } } @@ -1347,10 +1349,10 @@ d86f_find_address_mark_mfm(int drive, int side, find_t *find, uint16_t req_am, u } if (wrong_am && (dev->last_word[side] == wrong_am) && (find->sync_marks >= 3)) { - dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; - dev->error_condition = 0; - dev->state = STATE_IDLE; - fdc_finishread(d86f_fdc); + dev->data_find.sync_marks = dev->data_find.bits_obtained = + dev->data_find.bytes_obtained = 0; + dev->error_condition = 0; + dev->state = STATE_IDLE; fdc_nodataam(d86f_fdc); return; } @@ -1433,22 +1435,26 @@ d86f_read_sector_id(int drive, int side, int match) if (!(dev->id_find.bits_obtained & 15)) { /* We've got a byte. */ if (dev->id_find.bytes_obtained < 4) { - dev->last_sector.byte_array[dev->id_find.bytes_obtained] = decodefm(drive, dev->last_word[side]); + dev->last_sector.byte_array[dev->id_find.bytes_obtained] = + decodefm(drive, dev->last_word[side]); fdd_calccrc(dev->last_sector.byte_array[dev->id_find.bytes_obtained], &(dev->calc_crc)); } else if ((dev->id_find.bytes_obtained >= 4) && (dev->id_find.bytes_obtained < 6)) { - dev->track_crc.bytes[(dev->id_find.bytes_obtained & 1) ^ 1] = decodefm(drive, dev->last_word[side]); + dev->track_crc.bytes[(dev->id_find.bytes_obtained & 1) ^ 1] = + decodefm(drive, dev->last_word[side]); } dev->id_find.bytes_obtained++; if (dev->id_find.bytes_obtained == 6) { /* We've got the ID. */ - if ((dev->calc_crc.word != dev->track_crc.word) && (dev->last_sector.dword == dev->req_sector.dword)) { - dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = 0; - d86f_log("86F: ID CRC error: %04X != %04X (%08X)\n", dev->track_crc.word, dev->calc_crc.word, dev->last_sector.dword); + if ((dev->calc_crc.word != dev->track_crc.word) && + (dev->last_sector.dword == dev->req_sector.dword)) { + dev->id_find.sync_marks = dev->id_find.bits_obtained = + dev->id_find.bytes_obtained = 0; + d86f_log("86F: ID CRC error: %04X != %04X (%08X)\n", dev->track_crc.word, + dev->calc_crc.word, dev->last_sector.dword); if ((dev->state != STATE_02_READ_ID) && (dev->state != STATE_0A_READ_ID)) { dev->error_condition = 0; dev->state = STATE_IDLE; - fdc_finishread(d86f_fdc); fdc_headercrcerror(d86f_fdc); } else if (dev->state == STATE_0A_READ_ID) dev->state--; @@ -1458,25 +1464,37 @@ d86f_read_sector_id(int drive, int side, int match) } } else if ((dev->calc_crc.word == dev->track_crc.word) && (dev->state == STATE_0A_READ_ID)) { /* CRC is valid and this is a read sector ID command. */ - dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = dev->error_condition = 0; - fdc_sectorid(d86f_fdc, dev->last_sector.id.c, dev->last_sector.id.h, dev->last_sector.id.r, dev->last_sector.id.n, 0, 0); + dev->id_find.sync_marks = dev->id_find.bits_obtained = + dev->id_find.bytes_obtained = dev->error_condition = 0; + fdc_sectorid(d86f_fdc, + dev->last_sector.id.c, dev->last_sector.id.h, + dev->last_sector.id.r, dev->last_sector.id.n, 0, 0); dev->state = STATE_IDLE; } else { /* CRC is valid. */ - dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = 0; + dev->id_find.sync_marks = dev->id_find.bits_obtained = + dev->id_find.bytes_obtained = 0; dev->id_found |= 1; if ((dev->last_sector.dword == dev->req_sector.dword) || !match) { - d86f_handler[drive].set_sector(drive, side, dev->last_sector.id.c, dev->last_sector.id.h, dev->last_sector.id.r, dev->last_sector.id.n); + d86f_handler[drive].set_sector(drive, side, + dev->last_sector.id.c, dev->last_sector.id.h, + dev->last_sector.id.r, dev->last_sector.id.n); if (dev->state == STATE_02_READ_ID) { /* READ TRACK command, we need some special handling here. */ - /* Code corrected: Only the C, H, and N portions of the sector ID are compared, the R portion (the sector number) is ignored. */ - if ((dev->last_sector.id.c != fdc_get_read_track_sector(d86f_fdc).id.c) || (dev->last_sector.id.h != fdc_get_read_track_sector(d86f_fdc).id.h) || (dev->last_sector.id.n != fdc_get_read_track_sector(d86f_fdc).id.n)) { - dev->error_condition |= 4; /* Mark that the sector ID is not the one expected by the FDC. */ + /* Code corrected: Only the C, H, and N portions of the + sector ID are compared, the R portion + (the sector number) is ignored. */ + if ((dev->last_sector.id.c != fdc_get_read_track_sector(d86f_fdc).id.c) || + (dev->last_sector.id.h != fdc_get_read_track_sector(d86f_fdc).id.h) || + (dev->last_sector.id.n != fdc_get_read_track_sector(d86f_fdc).id.n)) { + /* Mark that the sector ID is not the one expected by the FDC. */ + dev->error_condition |= 4; /* Make sure we use the sector size from the FDC. */ dev->last_sector.id.n = fdc_get_read_track_sector(d86f_fdc).id.n; } - /* If the two ID's are identical, then we do not need to do anything regarding the sector size. */ + /* If the two ID's are identical, then we do not need to do + anything regarding the sector size. */ } dev->state++; } else { @@ -1576,7 +1594,8 @@ d86f_read_sector_data(int drive, int side) data = d86f_handler[drive].read_data(drive, side, dev->data_find.bytes_obtained); else { #ifdef HACK_FOR_DBASE_III - if ((dev->last_sector.id.c == 39) && (dev->last_sector.id.h == 0) && (dev->last_sector.id.r == 5) && (dev->data_find.bytes_obtained >= 272)) + if ((dev->last_sector.id.c == 39) && (dev->last_sector.id.h == 0) && + (dev->last_sector.id.r == 5) && (dev->data_find.bytes_obtained >= 272)) data = (random_generate() & 0xff); else #endif @@ -1589,7 +1608,9 @@ d86f_read_sector_data(int drive, int side) } else { if (dev->data_find.bytes_obtained < d86f_get_data_len(drive)) { if (dev->state != STATE_16_VERIFY_DATA) { - read_status = fdc_data(d86f_fdc, data, dev->data_find.bytes_obtained == (d86f_get_data_len(drive) - 1)); + read_status = fdc_data(d86f_fdc, data, + dev->data_find.bytes_obtained == + (d86f_get_data_len(drive) - 1)); if (read_status == -1) dev->dma_over++; } @@ -1597,17 +1618,19 @@ d86f_read_sector_data(int drive, int side) } fdd_calccrc(data, &(dev->calc_crc)); } else if (dev->data_find.bytes_obtained < crc_pos) - dev->track_crc.bytes[(dev->data_find.bytes_obtained - sector_len) ^ 1] = decodefm(drive, dev->last_word[side]); + dev->track_crc.bytes[(dev->data_find.bytes_obtained - sector_len) ^ 1] = + decodefm(drive, dev->last_word[side]); dev->data_find.bytes_obtained++; if (dev->data_find.bytes_obtained == (crc_pos + fdc_get_gap(d86f_fdc))) { /* We've got the data. */ if ((dev->calc_crc.word != dev->track_crc.word) && (dev->state != STATE_02_READ_DATA)) { - d86f_log("86F: Data CRC error: %04X != %04X (%08X)\n", dev->track_crc.word, dev->calc_crc.word, dev->last_sector.dword); - dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; - dev->error_condition = 0; - dev->state = STATE_IDLE; - fdc_finishread(d86f_fdc); + d86f_log("86F: Data CRC error: %04X != %04X (%08X)\n", dev->track_crc.word, + dev->calc_crc.word, dev->last_sector.dword); + dev->data_find.sync_marks = dev->data_find.bits_obtained = + dev->data_find.bytes_obtained = 0; + dev->error_condition = 0; + dev->state = STATE_IDLE; fdc_datacrcerror(d86f_fdc); } else if ((dev->calc_crc.word != dev->track_crc.word) && (dev->state == STATE_02_READ_DATA)) { dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; @@ -2146,7 +2169,8 @@ d86f_turbo_read(int drive, int side) } else { if (dev->turbo_pos < (128UL << dev->req_sector.id.n)) { if (dev->state != STATE_16_VERIFY_DATA) { - read_status = fdc_data(d86f_fdc, dat, dev->turbo_pos == ((128UL << dev->req_sector.id.n) - 1)); + read_status = fdc_data(d86f_fdc, dat, + dev->turbo_pos == ((128UL << dev->req_sector.id.n) - 1)); if (read_status == -1) dev->dma_over++; } @@ -2163,7 +2187,6 @@ d86f_turbo_read(int drive, int side) #endif dev->error_condition = 0; dev->state = STATE_IDLE; - fdc_finishread(d86f_fdc); fdc_datacrcerror(d86f_fdc); } else if ((flags & SECTOR_CRC_ERROR) && (dev->state == STATE_02_READ_DATA)) { #ifdef ENABLE_D86F_LOG diff --git a/src/include/86box/fdc.h b/src/include/86box/fdc.h index 9441bdfc4..09c9c4578 100644 --- a/src/include/86box/fdc.h +++ b/src/include/86box/fdc.h @@ -65,76 +65,85 @@ typedef struct fdc_t { uint8_t st0; uint8_t swap; uint8_t dtl; + uint8_t swwp; uint8_t disable_write; uint8_t st5; uint8_t st6; uint8_t error; - uint8_t params[8]; - uint8_t res[11]; - uint8_t specify[2]; uint8_t config; uint8_t pretrk; + uint8_t power_down; + + uint8_t head; + uint8_t lastdrive; + uint8_t sector; + uint8_t drive; + uint8_t rate; + uint8_t tc; + uint8_t pnum; + uint8_t ptot; + + uint8_t reset_stat; + uint8_t seek_dir; + uint8_t perp; + uint8_t format_state; + uint8_t format_n; + uint8_t step; + uint8_t noprec; + uint8_t data_ready; + + uint8_t paramstogo; + uint8_t enh_mode; + uint8_t dma; + uint8_t densel_polarity; + uint8_t densel_force; + uint8_t fifo; + uint8_t tfifo; + uint8_t fifobufpos; + + uint8_t drv2en; + uint8_t gap; + uint8_t enable_3f1; + uint8_t format_sectors; + uint8_t mfm; + uint8_t deleted; + uint8_t wrong_am; + uint8_t sc; + + uint8_t fintr; + uint8_t rw_drive; + + uint8_t lock; + uint8_t specify[2]; + + uint8_t res[11]; + + uint8_t eot[4]; + uint8_t rwc[4]; + uint8_t params[8]; uint8_t fifobuf[16]; + uint16_t pcn[4]; + uint16_t base_address; + uint16_t rw_track; - int head; - int sector; - int drive; - int lastdrive; - int pcn[4]; - int eot[4]; - int rw_track; - int pos; - int pnum; - int ptot; - int rate; - int reset_stat; - int lock; - int perp; - int format_state; - int format_n; - int step; - int seek_dir; - int tc; - int noprec; + int bit_rate; /* Should be 250 at start. */ - int data_ready; - int inread; int bitcell_period; - int enh_mode; - int rwc[4]; - int drvrate[4]; int boot_drive; - int dma; - int densel_polarity; - int densel_force; - int fifo; - int tfifo; - int fifobufpos; - int drv2en; - int gap; - int enable_3f1; - int format_sectors; int max_track; - int mfm; - int deleted; - int wrong_am; - int sc; int satisfying_sectors; - int fintr; - int rw_drive; int flags; int interrupt; - int irq; /* Should be 6 by default. */ - int dma_ch; /* Should be 2 by default. */ + int irq; /* Should be 6 by default. */ + int dma_ch; /* Should be 2 by default. */ - int bit_rate; /* Should be 250 at start. */ - int paramstogo; + int drvrate[4]; sector_id_t read_track_sector; sector_id_t format_sector_id; @@ -183,6 +192,7 @@ extern int fdc_get_compare_condition(fdc_t *fdc); extern int fdc_is_deleted(fdc_t *fdc); extern int fdc_is_sk(fdc_t *fdc); extern void fdc_set_wrong_am(fdc_t *fdc); +extern void fdc_set_power_down(fdc_t *fdc, uint8_t power_down); extern int fdc_get_drive(fdc_t *fdc); extern int fdc_get_perp(fdc_t *fdc); extern int fdc_get_format_n(fdc_t *fdc); diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 01459f144..a3e777dbd 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -1127,7 +1127,7 @@ machine_at_ms5146_init(const machine_t *model) pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&sis_5571_device); - device_add(&keyboard_ps2_ali_pci_device); + device_add(&keyboard_ps2_ami_pci_device); device_add(&w83877f_device); device_add(&sst_flash_29ee010_device); @@ -1151,13 +1151,13 @@ machine_at_cb52x_si_init(const machine_t *model) pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&sis_5571_device); - device_add(&keyboard_ps2_ali_pci_device); - device_add(&fdc37c669_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c669_370_device); device_add(&sst_flash_29ee010_device); return ret; diff --git a/src/sio/sio_fdc37c669.c b/src/sio/sio_fdc37c669.c index b2c8933c6..cb678427c 100644 --- a/src/sio/sio_fdc37c669.c +++ b/src/sio/sio_fdc37c669.c @@ -12,13 +12,15 @@ * * Authors: Miran Grca, * - * Copyright 2016-2018 Miran Grca. + * Copyright 2016-2024 Miran Grca. */ +#include #include #include #include #include #include +#define HAVE_STDARG_H #include <86box/86box.h> #include <86box/io.h> #include <86box/timer.h> @@ -45,35 +47,67 @@ typedef struct fdc37c669_t { static int next_id = 0; -static uint16_t -make_port(fdc37c669_t *dev, uint8_t reg) +#ifdef ENABLE_FDC37C669_LOG +int fdc37c669_do_log = ENABLE_FDC37C669_LOG; + +static void +fdc37c669_log(const char *fmt, ...) { - uint16_t p = 0; - uint16_t mask = 0; + va_list ap; - switch (reg) { - case 0x20: - case 0x21: - case 0x22: - mask = 0xfc; - break; - case 0x23: - mask = 0xff; - break; - case 0x24: - case 0x25: - mask = 0xfe; - break; - - default: - break; + if (fdc37c669_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } +} +#else +# define fdc37c669_log(fmt, ...) +#endif - p = ((uint16_t) (dev->regs[reg] & mask)) << 2; - if (reg == 0x22) - p |= 6; +static void +fdc37c669_fdc_handler(fdc37c669_t *dev) +{ + fdc_remove(dev->fdc); + if (dev->regs[0x20] & 0xc0) + fdc_set_base(dev->fdc, ((uint16_t) dev->regs[0x20]) << 2); +} - return p; +static void +fdc37c669_uart_handler(fdc37c669_t *dev, uint8_t uart) +{ + uint8_t uart_reg = 0x24 + uart; + uint8_t pwrdn_mask = 0x08 << (uart << 2); + uint8_t uart_shift = ((uart ^ 1) << 2); + + serial_remove(dev->uart[uart]); + if ((dev->regs[0x02] & pwrdn_mask) && (dev->regs[uart_reg] & 0xc0)) + serial_setup(dev->uart[0], ((uint16_t) dev->regs[0x24]) << 2, + (dev->regs[0x28] >> uart_shift) & 0x0f); +} + +static double +fdc37c669_uart_get_clock_src(fdc37c669_t *dev, uint8_t uart) +{ + double clock_srcs[4] = { 24000000.0 / 13.0, 24000000.0 / 12.0, 24000000.0 / 3.0, 24000000.0 / 3.0 }; + double ret; + uint8_t clock_src_0 = !!(dev->regs[0x04] & (0x10 << uart)); + uint8_t clock_src_1 = !!(dev->regs[0x0c] & (0x40 << uart)); + uint8_t clock_src = clock_src_0 | (clock_src_1 << 1); + + ret = clock_srcs[clock_src]; + + return ret; +} + +static void +fdc37c669_lpt_handler(fdc37c669_t *dev) +{ + uint8_t mask = ~(dev->regs[0x04] & 0x01); + + lpt_port_remove(dev->id); + if ((dev->regs[0x01] & 0x04) && (dev->regs[0x23] >= 0x40)) + lpt_port_init(dev->id, ((uint16_t) (dev->regs[0x23] & mask)) << 2); } static void @@ -81,149 +115,153 @@ fdc37c669_write(uint16_t port, uint8_t val, void *priv) { fdc37c669_t *dev = (fdc37c669_t *) priv; uint8_t index = (port & 1) ? 0 : 1; - uint8_t valxor = 0; - uint8_t max = 42; + uint8_t valxor = val ^ dev->regs[dev->cur_reg]; + + fdc37c669_log("[%04X:%08X] [W] %04X = %02X (%i, %i)\n", CS, cpu_state.pc, port, val, + dev->tries, dev->locked); if (index) { if ((val == 0x55) && !dev->locked) { - if (dev->tries) { + dev->tries = (dev->tries + 1) & 1; + + if (!dev->tries) dev->locked = 1; - dev->tries = 0; - } else - dev->tries++; } else { if (dev->locked) { - if (val < max) - dev->cur_reg = val; if (val == 0xaa) dev->locked = 0; - } else { - if (dev->tries) - dev->tries = 0; - } + else + dev->cur_reg = val; + } else + dev->tries = 0; } - return; - } else { - if (dev->locked) { - if ((dev->cur_reg < 0x18) && (dev->rw_locked)) - return; - if ((dev->cur_reg >= 0x26) && (dev->cur_reg <= 0x27)) - return; - if (dev->cur_reg == 0x29) - return; - valxor = val ^ dev->regs[dev->cur_reg]; + } else if (!dev->rw_locked || (dev->cur_reg > 0x0f)) switch (dev->cur_reg) { + case 0x00: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x74) | (val & 0x8b); + if (!dev->id && (valxor & 8)) + fdc_set_power_down(dev->fdc, !(val & 0x08)); + break; + case 0x01: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x73) | (val & 0x8c); + if (valxor & 0x04) + fdc37c669_lpt_handler(dev); + if (valxor & 0x80) + dev->rw_locked = !(val & 0x80); + break; + case 0x02: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x77) | (val & 0x88); + if (valxor & 0x08) + fdc37c669_uart_handler(dev, 0); + if (valxor & 0x80) + fdc37c669_uart_handler(dev, 1); + break; + case 0x03: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x08) | (val & 0xf7); + if (!dev->id && (valxor & 0x02)) + fdc_update_enh_mode(dev->fdc, !!(val & 0x02)); + break; + case 0x04: dev->regs[dev->cur_reg] = val; - } else - return; - } - - switch (dev->cur_reg) { - case 0: - if (!dev->id && (valxor & 8)) { - fdc_remove(dev->fdc); - if ((dev->regs[0] & 8) && (dev->regs[0x20] & 0xc0)) - fdc_set_base(dev->fdc, make_port(dev, 0x20)); - } + if (valxor & 0x03) + fdc37c669_lpt_handler(dev); + if (valxor & 0x10) + serial_set_clock_src(dev->uart[0], fdc37c669_uart_get_clock_src(dev, 0)); + if (valxor & 0x20) + serial_set_clock_src(dev->uart[1], fdc37c669_uart_get_clock_src(dev, 1)); break; - case 1: - if (valxor & 4) { - if (dev->id) { - lpt2_remove(); - if ((dev->regs[1] & 4) && (dev->regs[0x23] >= 0x40)) - lpt2_init(make_port(dev, 0x23)); - } else { - lpt1_remove(); - if ((dev->regs[1] & 4) && (dev->regs[0x23] >= 0x40)) - lpt1_init(make_port(dev, 0x23)); - } - } - if (valxor & 7) - dev->rw_locked = (val & 8) ? 0 : 1; - break; - case 2: - if (valxor & 8) { - serial_remove(dev->uart[0]); - if ((dev->regs[2] & 8) && (dev->regs[0x24] >= 0x40)) - serial_setup(dev->uart[0], make_port(dev, 0x24), (dev->regs[0x28] & 0xf0) >> 4); - } - if (valxor & 0x80) { - serial_remove(dev->uart[1]); - if ((dev->regs[2] & 0x80) && (dev->regs[0x25] >= 0x40)) - serial_setup(dev->uart[1], make_port(dev, 0x25), dev->regs[0x28] & 0x0f); - } - break; - case 3: - if (!dev->id && (valxor & 2)) - fdc_update_enh_mode(dev->fdc, (val & 2) ? 1 : 0); - break; - case 5: + case 0x05: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x83) | (val & 0x7c); if (!dev->id && (valxor & 0x18)) fdc_update_densel_force(dev->fdc, (val & 0x18) >> 3); if (!dev->id && (valxor & 0x20)) fdc_set_swap(dev->fdc, (val & 0x20) >> 5); break; - case 0xB: - if (!dev->id && (valxor & 3)) - fdc_update_rwc(dev->fdc, 0, val & 3); - if (!dev->id && (valxor & 0xC)) - fdc_update_rwc(dev->fdc, 1, (val & 0xC) >> 2); + case 0x06: + dev->regs[dev->cur_reg] = val; + break; + case 0x07: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x06) | (val & 0xf9); + break; + case 0x08: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x0f) | (val & 0xf0); + break; + case 0x09: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x38) | (val & 0xc7); + break; + case 0x0a: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0xf0) | (val & 0x0f); + break; + case 0x0b: + dev->regs[dev->cur_reg] = val; + if (!dev->id && (valxor & 0x03)) + fdc_update_rwc(dev->fdc, 0, val & 0x03); + if (!dev->id && (valxor & 0x0c)) + fdc_update_rwc(dev->fdc, 1, (val & 0x0c) >> 2); + break; + case 0x0c: + dev->regs[dev->cur_reg] = val; + if (valxor & 0x40) + serial_set_clock_src(dev->uart[0], fdc37c669_uart_get_clock_src(dev, 0)); + if (valxor & 0x80) + serial_set_clock_src(dev->uart[1], fdc37c669_uart_get_clock_src(dev, 1)); + break; + case 0x0f: + case 0x12 ... 0x1f: + dev->regs[dev->cur_reg] = val; + break; + case 0x10: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x07) | (val & 0xf8); + break; + case 0x11: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0xfc) | (val & 0x03); break; case 0x20: - if (!dev->id && (valxor & 0xfc)) { - fdc_remove(dev->fdc); - if ((dev->regs[0] & 8) && (dev->regs[0x20] & 0xc0)) - fdc_set_base(dev->fdc, make_port(dev, 0x20)); - } + dev->regs[dev->cur_reg] = val & 0xfc; + if (!dev->id && (valxor & 0xfc)) + fdc37c669_fdc_handler(dev); + break; + case 0x21: + dev->regs[dev->cur_reg] = val & 0xfc; + break; + case 0x22: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x03) | (val & 0xfc); break; case 0x23: - if (valxor) { - if (dev->id) { - lpt2_remove(); - if ((dev->regs[1] & 4) && (dev->regs[0x23] >= 0x40)) - lpt2_init(make_port(dev, 0x23)); - } else { - lpt1_remove(); - if ((dev->regs[1] & 4) && (dev->regs[0x23] >= 0x40)) - lpt1_init(make_port(dev, 0x23)); - } - } + dev->regs[dev->cur_reg] = val; + if (valxor) + fdc37c669_lpt_handler(dev); break; case 0x24: - if (valxor & 0xfe) { - serial_remove(dev->uart[0]); - if ((dev->regs[2] & 8) && (dev->regs[0x24] >= 0x40)) - serial_setup(dev->uart[0], make_port(dev, 0x24), (dev->regs[0x28] & 0xf0) >> 4); - } + dev->regs[dev->cur_reg] = val & 0xfe; + if (valxor & 0xfe) + fdc37c669_uart_handler(dev, 0); break; case 0x25: - if (valxor & 0xfe) { - serial_remove(dev->uart[1]); - if ((dev->regs[2] & 0x80) && (dev->regs[0x25] >= 0x40)) - serial_setup(dev->uart[1], make_port(dev, 0x25), dev->regs[0x28] & 0x0f); - } + dev->regs[dev->cur_reg] = val & 0xfe; + if (valxor & 0xfe) + fdc37c669_uart_handler(dev, 1); + break; + case 0x26: + dev->regs[dev->cur_reg] = val; + if (valxor & 0xf0) + fdc_set_dma_ch(dev->fdc, val >> 4); break; case 0x27: - if (valxor & 0xf) { - if (dev->id) - lpt2_irq(val & 0xf); - else - lpt1_irq(val & 0xf); - } + dev->regs[dev->cur_reg] = val; + if (valxor & 0xf0) + fdc_set_irq(dev->fdc, val >> 4); + if (valxor & 0x0f) + lpt_port_irq(dev->id, val & 0x0f); break; case 0x28: - if (valxor & 0xf) { - serial_remove(dev->uart[1]); - if ((dev->regs[2] & 0x80) && (dev->regs[0x25] >= 0x40)) - serial_setup(dev->uart[1], make_port(dev, 0x25), dev->regs[0x28] & 0x0f); - } - if (valxor & 0xf0) { - serial_remove(dev->uart[0]); - if ((dev->regs[2] & 8) && (dev->regs[0x24] >= 0x40)) - serial_setup(dev->uart[0], make_port(dev, 0x24), (dev->regs[0x28] & 0xf0) >> 4); - } + dev->regs[dev->cur_reg] = val; + if (valxor & 0xf0) + fdc37c669_uart_handler(dev, 0); + if (valxor & 0x0f) + fdc37c669_uart_handler(dev, 1); break; - - default: + case 0x29: + dev->regs[dev->cur_reg] = val & 0x0f; break; } } @@ -238,23 +276,23 @@ fdc37c669_read(uint16_t port, void *priv) if (dev->locked) { if (index) ret = dev->cur_reg; - else if ((dev->cur_reg >= 0x18) || !dev->rw_locked) + else if (!dev->rw_locked || (dev->cur_reg > 0x0f)) ret = dev->regs[dev->cur_reg]; } + fdc37c669_log("[%04X:%08X] [R] %04X = %02X (%i, %i)\n", CS, cpu_state.pc, port, ret, + dev->tries, dev->locked); + return ret; } static void -fdc37c669_reset(fdc37c669_t *dev) +fdc37c669_reset(void *priv) { - serial_remove(dev->uart[0]); - serial_setup(dev->uart[0], COM1_ADDR, COM1_IRQ); + fdc37c669_t *dev = (fdc37c669_t *) priv; - serial_remove(dev->uart[1]); - serial_setup(dev->uart[1], COM2_ADDR, COM2_IRQ); + memset(dev->regs, 0x00, 42); - memset(dev->regs, 0, 42); dev->regs[0x00] = 0x28; dev->regs[0x01] = 0x9c; dev->regs[0x02] = 0x88; @@ -262,32 +300,23 @@ fdc37c669_reset(fdc37c669_t *dev) dev->regs[0x06] = 0xff; dev->regs[0x0d] = 0x03; dev->regs[0x0e] = 0x02; - dev->regs[0x1e] = 0x80; /* Gameport controller. */ - dev->regs[0x20] = (FDC_PRIMARY_ADDR >> 2) & 0xfc; - dev->regs[0x21] = (0x1f0 >> 2) & 0xfc; - dev->regs[0x22] = ((0x3f6 >> 2) & 0xfc) | 1; + dev->regs[0x1e] = 0x3c; /* Gameport controller. */ + dev->regs[0x20] = 0x3c; + dev->regs[0x21] = 0x3c; + dev->regs[0x22] = 0x3d; + if (dev->id == 1) { - dev->regs[0x23] = (LPT2_ADDR >> 2); - - lpt2_remove(); - lpt2_init(LPT2_ADDR); - - dev->regs[0x24] = (COM3_ADDR >> 2) & 0xfe; - dev->regs[0x25] = (COM4_ADDR >> 2) & 0xfe; - } else { fdc_reset(dev->fdc); - - lpt1_remove(); - lpt1_init(LPT1_ADDR); - - dev->regs[0x23] = (LPT1_ADDR >> 2); - - dev->regs[0x24] = (COM1_ADDR >> 2) & 0xfe; - dev->regs[0x25] = (COM2_ADDR >> 2) & 0xfe; + fdc37c669_fdc_handler(dev); } - dev->regs[0x26] = (2 << 4) | 3; - dev->regs[0x27] = (6 << 4) | (dev->id ? 5 : 7); - dev->regs[0x28] = (4 << 4) | 3; + + fdc37c669_uart_handler(dev, 0); + serial_set_clock_src(dev->uart[0], fdc37c669_uart_get_clock_src(dev, 0)); + + fdc37c669_uart_handler(dev, 1); + serial_set_clock_src(dev->uart[1], fdc37c669_uart_get_clock_src(dev, 1)); + + fdc37c669_lpt_handler(dev); dev->locked = 0; dev->rw_locked = 0; @@ -317,8 +346,8 @@ fdc37c669_init(const device_t *info) dev->uart[0] = device_add_inst(&ns16550_device, (next_id << 1) + 1); dev->uart[1] = device_add_inst(&ns16550_device, (next_id << 1) + 2); - io_sethandler(info->local ? FDC_SECONDARY_ADDR : (next_id ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR), 0x0002, - fdc37c669_read, NULL, NULL, fdc37c669_write, NULL, NULL, dev); + io_sethandler(info->local ? FDC_SECONDARY_ADDR : (next_id ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR), + 0x0002, fdc37c669_read, NULL, NULL, fdc37c669_write, NULL, NULL, dev); fdc37c669_reset(dev); @@ -334,7 +363,7 @@ const device_t fdc37c669_device = { .local = 0, .init = fdc37c669_init, .close = fdc37c669_close, - .reset = NULL, + .reset = fdc37c669_reset, { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, @@ -348,7 +377,7 @@ const device_t fdc37c669_370_device = { .local = 1, .init = fdc37c669_init, .close = fdc37c669_close, - .reset = NULL, + .reset = fdc37c669_reset, { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, From 04eb9ffc3e82418c5e45d1edb55a139e6b496bf7 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Sun, 7 Jan 2024 17:07:24 +1300 Subject: [PATCH 213/936] unittester: Add WIP specification document --- doc/specifications/86box-unit-tester.md | 240 ++++++++++++++++++++++++ src/device/unittester.c | 1 + src/include/86box/unittester.h | 1 + 3 files changed, 242 insertions(+) create mode 100644 doc/specifications/86box-unit-tester.md diff --git a/doc/specifications/86box-unit-tester.md b/doc/specifications/86box-unit-tester.md new file mode 100644 index 000000000..77279a3ee --- /dev/null +++ b/doc/specifications/86box-unit-tester.md @@ -0,0 +1,240 @@ +# 86Box Unit Tester device specification + +**TODO: DESCRIBE ME!** + +---------------------------------------------------------------------------- + +## Conventions + +### Integer types + +- `i8` denotes a signed 8-bit value. +- `u8` denotes an unsigned 8-bit value. +- `w8` denotes an 8-bit value which wraps around. +- `x8` denotes an 8-bit value where the signedness is irrelevant. +- `e8` ("either") denotes an 8-bit value where the most significant bit is clear - in effect, this is a 7-bit unsigned value. +- `u16L` denotes a little-endian unsigned 16-bit value. +- `u16B` would denote a big-endian unsigned 16-bit value if we had any big-endian values. +- `[N]T` denotes an array of `N` values of type `T`, whatever `N` and `T` are. + +---------------------------------------------------------------------------- + +## Usage + +### Accessing the device and configuring the I/O base address + +Find an area in I/O space where 2 addresses are confirmed (or assumed) to be unused. +There is no need for the 2 addresses to be 2-byte-aligned. + +Send the following sequence of bytes to port 0x80 with INTERRUPTS DISABLED: + + '8', '6', 'B', 'o', 'x', (IOBASE & 0xFF), (IOBASE >> 8) + +Alternatively denoted in hex: + + 38 36 42 6F 78 yy xx + +There are no timing constraints. This is an emulator, after all. + +To confirm that this has happened, read the status port at IOBASE+0x00. +If it's 0xFF, then the device is most likely not present. +Otherwise, one can potentially assume that it exists and has been configured successfully. +(You *did* make sure that the space was unused *before* doing this, right?) + +IOBASE is allowed to overlap the trigger port, but please don't do this! + +### Hiding the device + +Set the I/O base address to 0xFFFF using the above method. + +### Executing commands + +**TODO: IMPLEMENT ME!** + +The ports at IOBASE+0x00 and IOBASE+0x01 are all 8 bits wide. + +Writing to IOBASE+0x00 cancels any in-flight commands and sends a new command. + +Reading from IOBASE+0x00 reads the status: + +- bit 0: There is data to be read from this device + - If one reads with this bit clear, the returned data will be 0xFF. +- bit 1: The device is expecting data to be sent to it + - If one writes with this bit clear, the data will be ignored. +- bit 2: There is no command in flight + - If this is set, then bits 0 and 1 will be clear. +- bit 3: The previously-sent command does not exist. +- bits 4 .. 7: Reserved, should be 0. + +Writing to IOBASE+0x01 provides data to the device if said data is needed. + +Reading from IOBASE+0x01 fetches the next byte data to the device if said data is needed. + +### General flow of executing a command: + +This is how most commands will work. + +- Write the command to IOBASE+0x00. +- If data needs to be written or read: + - Read the status from IOBASE+0x00 and confirm that bit 2 is clear. + If it is set, then the command may not exist. + Check bit 3 if that's the case. +- If data needs to be written: + - Write all the data one needs to write. +- If data needs to be read: + - Read the status from IOBASE+0x00 and wait until bit 0 is set. + If it is set, then the command may not exist. + Check bit 3 if that's the case. + - Keep reading bytes until one is satisfied. +- Otherwise: + - Read the status from IOBASE+0x00 and wait until any of the bottom 3 bits are set. + +---------------------------------------------------------------------------- + +## Command reference + +### 0x00: No-op + +**TODO: IMPLEMENT ME!** + +This does nothing, takes no input, and gives no output. + +This is an easy way to reset the status to 0x04 (no command in flight, not waiting for reads or writes, and no errors). + +### 0x01: Capture Screen Snapshot + +**TODO: IMPLEMENT ME!** + +Captures a snapshot of the current screen state and stores it in the current snapshot buffer. + +The initial state of the screen snapshot buffer has an image area of 0x0, an overscanned area of 0x0, and an image start offset of (0,0). + +Input: + +* u8 monitor + - 0x00 = no monitor - clear the screen snapshot + - 0x01 = primary monitor + - 0x02 = secondary monitor + - Any monitor which is not available is treated as 0x00, and clears the screen snapshot. + +Output: + +* `e16L` image width in pixels +* `e16L` image height in pixels +* `e16L` overscanned width in pixels +* `e16L` overscanned height in pixels +* `e16L` X offset of image start +* `e16L` Y offset of image start + +If there is no screen snapshot, then all values will be 0 as per the initial screen snapshot buffer state. + +### 0x02: Read Screen Snapshot Rectangle + +**TODO: IMPLEMENT ME!** + +Returns a rectangular snapshot of the screen snapshot buffer. + +Input: + +* `e16L` w: rectangle width in pixels +* `e16L` h: rectangle height in pixels +* `i16L` x: X offset relative to image start +* `i16L` y: Y offset relative to image start + +Output: + +* `[h][w][4]u8`: image data + - `[y][x][0]` is the blue component, or 0x00 if the pixel is outside the snapshot area. + - `[y][x][1]` is the green component, or 0x00 if the pixel is outside the snapshot area. + - `[y][x][2]` is the red component, or 0x00 if the pixel is outside the snapshot area. + - `[y][x][3]` is 0x00, or 0xFF if the pixel is outside the snapshot area. + +### 0x03: Verify Screen Snapshot Rectangle + +**TODO: IMPLEMENT ME!** + +As per 0x02 "Read Screen Snapshot Rectangle", except instead of returning the pixel data, it returns a CRC-32 of the data. + +The CRC is as per zlib's `crc32()` function. Specifically, one uses a right-shifting Galois LFSR with a polynomial of 0xEDB88320, bytes XORed against the least significant byte, the initial seed is 0xFFFFFFFF, and all bits of the output are inverted. + +(Rationale: There are better CRCs, but this one is ubiquitous and still really good... and we don't need to protect against deliberate tampering.) + +Input: + +* `e16L` w: rectangle width in pixels +* `e16L` h: rectangle height in pixels +* `i16L` x: X offset relative to image start +* `i16L` y: Y offset relative to image start + +Output: + +* `u32L` crc: CRC-32 of rectangle data + +### 0x04: Exit 86Box + +**TODO: IMPLEMENT ME!** + +Exits 86Box, unless this command is disabled. + +- If the command is enabled, then program execution terminates immediately. +- If the command is disabled, it still counts as having executed correctly, but program execution continues. This makes it useful to show a "results" screen for a unit test. + +Input: + +* u8 exit code: + - The actual exit code is clamped to no greater than the maximum valid exit code. + - In practice, this is probably going to be 0x7F. + +---------------------------------------------------------------------------- + +## Implementation notes + +### Port 0x80 sequence detection + +In order to ensure that one can always trigger the activation sequence, there are effectively two finite state machines in action. + +FSM1: +- Wait for 8. +- Wait for 6. +- Wait for B. +- Wait for o. +- Wait for x. + Once received, set FSM2 to "Wait for low byte", + then go back to "Wait for 8". + +If at any point an 8 arrives, jump to the "Wait for 6" step. + +Otherwise, if any other unexpected byte arrives, jump to the "Wait for 8" step. + +FSM2: +- Idle. +- Wait for low byte. Once received, store this in a temporary location. +- Wait for high byte. + Once received, replace IOBASE with this byte in the high byte and the temporary value in the low byte, + then go back to "Idle". + +### Command processing state machine + +**TODO: IMPLEMENT ME!** + +**TODO: DOCUMENT ME!** + +---------------------------------------------------------------------------- + +## Extending the protocol + +### Adding new commands + +Commands 0x01 through 0x7F accept a single command byte. + +Command bytes 0x80 through 0xFB are reserved for 16-bit command IDs, to be written in a similar way to this: + +- Write the first command byte (0x80 through 0xFF) to the command register. +- If this block of commands does not exist, then the command is cancelled and the status is set to 0x0C. +- Otherwise, the status is set to 0x0 +- Write the next command byte (0x00 through 0xFF) to the data register. +- If this block of commands does not exist, then the command is cancelled and the status is set to 0x0C. +- Otherwise, the command exists and the status is set according to the command. + +Command bytes 0xFC through 0xFF are reserved for if we somehow need more than 16 bits worth of command ID. + diff --git a/src/device/unittester.c b/src/device/unittester.c index 2f706c8e3..ff605e119 100644 --- a/src/device/unittester.c +++ b/src/device/unittester.c @@ -7,6 +7,7 @@ * This file is part of the 86Box distribution. * * Debug device for assisting in unit testing. + * See doc/specifications/86box-unit-tester.md for more info. * * * diff --git a/src/include/86box/unittester.h b/src/include/86box/unittester.h index 1e1255f52..f6dedeae5 100644 --- a/src/include/86box/unittester.h +++ b/src/include/86box/unittester.h @@ -7,6 +7,7 @@ * This file is part of the 86Box distribution. * * Debug device for assisting in unit testing. + * See doc/specifications/86box-unit-tester.md for more info. * * * From d1133a7c7fdbd147caa8376c0c7347115bd24597 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Sun, 7 Jan 2024 17:20:19 +1300 Subject: [PATCH 214/936] unittester: Implement status register and 0x00 "No-op" command --- doc/specifications/86box-unit-tester.md | 2 -- src/device/unittester.c | 44 +++++++++++++++++++++---- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/doc/specifications/86box-unit-tester.md b/doc/specifications/86box-unit-tester.md index 77279a3ee..9100f59de 100644 --- a/doc/specifications/86box-unit-tester.md +++ b/doc/specifications/86box-unit-tester.md @@ -95,8 +95,6 @@ This is how most commands will work. ### 0x00: No-op -**TODO: IMPLEMENT ME!** - This does nothing, takes no input, and gives no output. This is an easy way to reset the status to 0x04 (no command in flight, not waiting for reads or writes, and no errors). diff --git a/src/device/unittester.c b/src/device/unittester.c index ff605e119..e6deb45bc 100644 --- a/src/device/unittester.c +++ b/src/device/unittester.c @@ -39,6 +39,20 @@ enum fsm2_value { UT_FSM2_WAIT_IOBASE_1, }; +/* Status bit mask */ +#define UT_STATUS_AWAITING_READ (1<<0) +#define UT_STATUS_AWAITING_WRITE (1<<1) +#define UT_STATUS_IDLE (1<<2) +#define UT_STATUS_UNSUPPORTED_CMD (1<<3) + +/* Command list */ +enum unittester_cmd { + UT_CMD_NOOP = 0x00, + UT_CMD_CAPTURE_SCREEN_SNAPSHOT = 0x01, + UT_CMD_READ_SCREEN_SNAPSHOT_RECTANGLE = 0x02, + UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE = 0x03, +}; + struct unittester_state { /* I/O port settings */ uint16_t trigger_port; @@ -50,6 +64,10 @@ struct unittester_state { /* FSM2: IOBASE port selection, once trigger is activated */ enum fsm2_value fsm2; uint16_t fsm2_new_iobase; + + /* Runtime state */ + uint8_t status; + enum unittester_cmd cmd_id; }; static struct unittester_state unittester; static const struct unittester_state unittester_defaults = { @@ -57,6 +75,7 @@ static const struct unittester_state unittester_defaults = { .iobase_port = 0xFFFF, .fsm1 = UT_FSM1_WAIT_8, .fsm2 = UT_FSM2_IDLE, + .status = UT_STATUS_IDLE, }; /* FIXME TEMPORARY --GM */ @@ -85,8 +104,22 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) { if (port == unittester.iobase_port+0x00) { /* Command port */ - /* TODO! --GM */ unittester_log("[UT] W %02X Command\n", val); + + switch (val) { + /* 0x00: No-op */ + case UT_CMD_NOOP: + unittester.cmd_id = UT_CMD_NOOP; + unittester.status = UT_STATUS_IDLE; + break; + + /* Unsupported command - terminate here */ + default: + unittester.cmd_id = UT_CMD_NOOP; + unittester.status = UT_STATUS_IDLE | UT_STATUS_UNSUPPORTED_CMD; + break; + } + } else if (port == unittester.iobase_port+0x01) { /* Data port */ /* TODO! --GM */ @@ -101,14 +134,13 @@ unittester_read(uint16_t port, UNUSED(void *priv)) { if (port == unittester.iobase_port+0x00) { /* Status port */ - /* TODO! --GM */ - unittester_log("[UT] R -- Status\n"); - return 0x04; + unittester_log("[UT] R -- Status = %02X\n", unittester.status); + return unittester.status; } else if (port == unittester.iobase_port+0x01) { /* Data port */ - /* TODO! --GM */ unittester_log("[UT] R -- Data\n"); - return 0xFE; + /* TODO! --GM */ + return 0xFF; } else { /* Not handled here - possibly open bus! */ return 0xFF; From ab7df4409b117b44f71362ce37252adb78386d63 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Sun, 7 Jan 2024 17:42:23 +1300 Subject: [PATCH 215/936] unittester: Implement 0x04 "Exit" --- doc/specifications/86box-unit-tester.md | 2 - src/device/unittester.c | 109 +++++++++++++++++++++++- 2 files changed, 106 insertions(+), 5 deletions(-) diff --git a/doc/specifications/86box-unit-tester.md b/doc/specifications/86box-unit-tester.md index 9100f59de..fe0203b46 100644 --- a/doc/specifications/86box-unit-tester.md +++ b/doc/specifications/86box-unit-tester.md @@ -170,8 +170,6 @@ Output: ### 0x04: Exit 86Box -**TODO: IMPLEMENT ME!** - Exits 86Box, unless this command is disabled. - If the command is enabled, then program execution terminates immediately. diff --git a/src/device/unittester.c b/src/device/unittester.c index e6deb45bc..8a6a81fdb 100644 --- a/src/device/unittester.c +++ b/src/device/unittester.c @@ -16,8 +16,10 @@ * Copyright 2024 GreaseMonkey. */ #include +#include #include #include +#include #include #include #define HAVE_STDARG_H @@ -51,6 +53,7 @@ enum unittester_cmd { UT_CMD_CAPTURE_SCREEN_SNAPSHOT = 0x01, UT_CMD_READ_SCREEN_SNAPSHOT_RECTANGLE = 0x02, UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE = 0x03, + UT_CMD_EXIT = 0x04, }; struct unittester_state { @@ -68,6 +71,14 @@ struct unittester_state { /* Runtime state */ uint8_t status; enum unittester_cmd cmd_id; + uint32_t write_offs; + uint32_t read_offs; + uint32_t write_len; + uint32_t read_len; + + /* Command-specific state */ + /* 0x04: Exit */ + uint8_t exit_code; }; static struct unittester_state unittester; static const struct unittester_state unittester_defaults = { @@ -76,8 +87,12 @@ static const struct unittester_state unittester_defaults = { .fsm1 = UT_FSM1_WAIT_8, .fsm2 = UT_FSM2_IDLE, .status = UT_STATUS_IDLE, + .cmd_id = UT_CMD_NOOP, }; +/* FIXME: This needs a config option! --GM */ +static bool unittester_exit_enabled = true; + /* FIXME TEMPORARY --GM */ #define ENABLE_UNITTESTER_LOG 1 @@ -106,6 +121,11 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) /* Command port */ unittester_log("[UT] W %02X Command\n", val); + unittester.write_offs = 0; + unittester.write_len = 0; + unittester.read_offs = 0; + unittester.read_len = 0; + switch (val) { /* 0x00: No-op */ case UT_CMD_NOOP: @@ -113,6 +133,13 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) unittester.status = UT_STATUS_IDLE; break; + /* 0x04: No-op */ + case UT_CMD_EXIT: + unittester.cmd_id = UT_CMD_EXIT; + unittester.status = UT_STATUS_AWAITING_WRITE; + unittester.write_len = 1; + break; + /* Unsupported command - terminate here */ default: unittester.cmd_id = UT_CMD_NOOP; @@ -122,8 +149,64 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) } else if (port == unittester.iobase_port+0x01) { /* Data port */ - /* TODO! --GM */ unittester_log("[UT] W %02X Data\n", val); + + /* Skip if not awaiting */ + if ((unittester.status & UT_STATUS_AWAITING_WRITE) == 0) + return; + + switch (unittester.cmd_id) { + case UT_CMD_EXIT: + switch(unittester.write_offs) { + case 0: + unittester.exit_code = val; + break; + default: + break; + } + break; + + /* This should not be reachable, but just in case... */ + default: + break; + } + + /* Advance write buffer */ + unittester.write_offs += 1; + if (unittester.write_offs >= unittester.write_len) { + unittester.status &= ~UT_STATUS_AWAITING_WRITE; + /* Determine what we're doing here based on the command. */ + switch (unittester.cmd_id) { + case UT_CMD_EXIT: + unittester_log("[UT] Exit received - code = %02X\n", unittester.exit_code); + + /* CHECK: Do we actually exit? */ + if (unittester_exit_enabled) { + /* Yes - call exit! */ + /* Clamp exit code */ + if (unittester.exit_code > 0x7F) + unittester.exit_code = 0x7F; + + /* Exit somewhat quickly! */ + unittester_log("[UT] Exit enabled, exiting with code %02X\n", unittester.exit_code); + exit(unittester.exit_code); + + } else { + /* No - report successful command completion and continue program execution */ + unittester_log("[UT] Exit disabled, continuing execution\n"); + unittester.cmd_id = UT_CMD_NOOP; + unittester.status = UT_STATUS_IDLE; + } + break; + + default: + /* Nothing to write? Stop here. */ + unittester.cmd_id = UT_CMD_NOOP; + unittester.status = UT_STATUS_IDLE; + break; + } + } + } else { /* Not handled here - possibly open bus! */ } @@ -132,6 +215,8 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) static uint8_t unittester_read(uint16_t port, UNUSED(void *priv)) { + uint8_t outval = 0xFF; + if (port == unittester.iobase_port+0x00) { /* Status port */ unittester_log("[UT] R -- Status = %02X\n", unittester.status); @@ -139,8 +224,26 @@ unittester_read(uint16_t port, UNUSED(void *priv)) } else if (port == unittester.iobase_port+0x01) { /* Data port */ unittester_log("[UT] R -- Data\n"); - /* TODO! --GM */ - return 0xFF; + + /* Skip if not awaiting */ + if ((unittester.status & UT_STATUS_AWAITING_READ) == 0) + return 0xFF; + + switch (unittester.cmd_id) { + /* This should not be reachable, but just in case... */ + default: + break; + } + + /* Advance read buffer */ + unittester.read_offs += 1; + if (unittester.read_offs >= unittester.read_len) { + /* Once fully read, we stop here. */ + unittester.cmd_id = UT_CMD_NOOP; + unittester.status = UT_STATUS_IDLE; + } + + return outval; } else { /* Not handled here - possibly open bus! */ return 0xFF; From 7dbbb0d12b1446c1238e1a29cad3ce26739745f8 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Sun, 7 Jan 2024 18:19:17 +1300 Subject: [PATCH 216/936] Fix a comment --- src/device/unittester.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/unittester.c b/src/device/unittester.c index 8a6a81fdb..b1f3efcc5 100644 --- a/src/device/unittester.c +++ b/src/device/unittester.c @@ -133,7 +133,7 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) unittester.status = UT_STATUS_IDLE; break; - /* 0x04: No-op */ + /* 0x04: Exit */ case UT_CMD_EXIT: unittester.cmd_id = UT_CMD_EXIT; unittester.status = UT_STATUS_AWAITING_WRITE; From ae3e40706f951008655d62d29a9d2ba09bb0ef65 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Sun, 7 Jan 2024 18:19:27 +1300 Subject: [PATCH 217/936] unittester: Remove the worst of the log spam --- src/device/unittester.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/device/unittester.c b/src/device/unittester.c index b1f3efcc5..8de09e295 100644 --- a/src/device/unittester.c +++ b/src/device/unittester.c @@ -253,7 +253,8 @@ unittester_read(uint16_t port, UNUSED(void *priv)) static void unittester_trigger_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv)) { - unittester_log("[UT] Trigger value %02X -> FSM1 = %02X, FSM2 = %02X, IOBASE = %04X\n", val, unittester.fsm1, unittester.fsm2, unittester.iobase_port); + /* This one gets quite spammy. */ + /* unittester_log("[UT] Trigger value %02X -> FSM1 = %02X, FSM2 = %02X, IOBASE = %04X\n", val, unittester.fsm1, unittester.fsm2, unittester.iobase_port); */ /* Update FSM2 */ switch (unittester.fsm2) { From 59e51939adfc8342f81629af1c1b3eea95ccef97 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Sun, 7 Jan 2024 20:09:06 +1300 Subject: [PATCH 218/936] unittester: Fix erroneous debug message --- src/device/unittester.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/unittester.c b/src/device/unittester.c index 8de09e295..01972ef67 100644 --- a/src/device/unittester.c +++ b/src/device/unittester.c @@ -273,7 +273,7 @@ unittester_trigger_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv)) case UT_FSM2_WAIT_IOBASE_1: unittester.fsm2_new_iobase |= ((uint16_t)val)<<8; - unittester_log("[UT] Remapping IOBASE: %04X -> %04X\n", val, unittester.iobase_port, unittester.fsm2_new_iobase); + unittester_log("[UT] Remapping IOBASE: %04X -> %04X\n", unittester.iobase_port, unittester.fsm2_new_iobase); /* Unmap old IOBASE */ if (unittester.iobase_port != 0xFFFF) From d44c439bd819ebaf9d44d055d08c153537c550c8 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Sun, 7 Jan 2024 21:26:14 +1300 Subject: [PATCH 219/936] unittester: Implement most of 0x01 "Capture Screen Snapshot" The thing that isn't implemented is the actual snapshot capture. But the dimensions should be correct. I am feeling a bit iffy about the overscan, though. --- src/device/unittester.c | 129 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 3 deletions(-) diff --git a/src/device/unittester.c b/src/device/unittester.c index 01972ef67..78086fd90 100644 --- a/src/device/unittester.c +++ b/src/device/unittester.c @@ -27,6 +27,7 @@ #include <86box/io.h> #include <86box/plat.h> #include <86box/unittester.h> +#include <86box/video.h> enum fsm1_value { UT_FSM1_WAIT_8, @@ -68,7 +69,7 @@ struct unittester_state { enum fsm2_value fsm2; uint16_t fsm2_new_iobase; - /* Runtime state */ + /* Command and data handling state */ uint8_t status; enum unittester_cmd cmd_id; uint32_t write_offs; @@ -76,6 +77,19 @@ struct unittester_state { uint32_t write_len; uint32_t read_len; + /* Screen snapshot state */ + /* Monitor to take snapshot on */ + uint8_t snap_monitor; + /* Main image width + height */ + uint16_t snap_img_width; + uint16_t snap_img_height; + /* Fully overscanned image width + height */ + uint16_t snap_overscan_width; + uint16_t snap_overscan_height; + /* Offset of actual image within overscanned area */ + uint16_t snap_img_xoffs; + uint16_t snap_img_yoffs; + /* Command-specific state */ /* 0x04: Exit */ uint8_t exit_code; @@ -90,6 +104,9 @@ static const struct unittester_state unittester_defaults = { .cmd_id = UT_CMD_NOOP, }; +/* Kept separate, as we will be reusing this object */ +static bitmap_t *unittester_screen_buffer = NULL; + /* FIXME: This needs a config option! --GM */ static bool unittester_exit_enabled = true; @@ -133,6 +150,13 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) unittester.status = UT_STATUS_IDLE; break; + /* 0x01: Capture Screen Snapshot */ + case UT_CMD_CAPTURE_SCREEN_SNAPSHOT: + unittester.cmd_id = UT_CMD_CAPTURE_SCREEN_SNAPSHOT; + unittester.status = UT_STATUS_AWAITING_WRITE; + unittester.write_len = 1; + break; + /* 0x04: Exit */ case UT_CMD_EXIT: unittester.cmd_id = UT_CMD_EXIT; @@ -166,6 +190,16 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) } break; + case UT_CMD_CAPTURE_SCREEN_SNAPSHOT: + switch(unittester.write_offs) { + case 0: + unittester.snap_monitor = val; + break; + default: + break; + } + break; + /* This should not be reachable, but just in case... */ default: break; @@ -194,9 +228,47 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) } else { /* No - report successful command completion and continue program execution */ unittester_log("[UT] Exit disabled, continuing execution\n"); - unittester.cmd_id = UT_CMD_NOOP; - unittester.status = UT_STATUS_IDLE; } + unittester.cmd_id = UT_CMD_NOOP; + unittester.status = UT_STATUS_IDLE; + break; + + case UT_CMD_CAPTURE_SCREEN_SNAPSHOT: + /* Recompute screen */ + unittester.snap_img_width = 0; + unittester.snap_img_height = 0; + unittester.snap_img_xoffs = 0; + unittester.snap_img_yoffs = 0; + unittester.snap_overscan_width = 0; + unittester.snap_overscan_height = 0; + if (unittester.snap_monitor < 0x01 || (unittester.snap_monitor - 1) > MONITORS_NUM) { + /* No monitor here - clear snapshot */ + unittester.snap_monitor = 0x00; + } else if (video_get_type_monitor(unittester.snap_monitor - 1) == VIDEO_FLAG_TYPE_NONE) { + /* Monitor disabled - clear snapshot */ + unittester.snap_monitor = 0x00; + } else { + /* Capture snapshot from monitor */ + const monitor_t *m = &monitors[unittester.snap_monitor - 1]; + unittester.snap_img_width = m->mon_xsize; + unittester.snap_img_height = m->mon_ysize; + unittester.snap_overscan_width = m->mon_xsize + m->mon_overscan_x; + unittester.snap_overscan_height = m->mon_ysize + m->mon_overscan_y; + unittester.snap_img_xoffs = (m->mon_overscan_x >> 1); + unittester.snap_img_yoffs = (m->mon_overscan_y >> 1); + /* TODO: Actually take snapshot! --GM */ + } + + /* We have 12 bytes to read. */ + unittester_log("[UT] Screen snapshot - image %d x %d @ (%d, %d) in overscan %d x %d\n", + unittester.snap_img_width, + unittester.snap_img_height, + unittester.snap_img_xoffs, + unittester.snap_img_yoffs, + unittester.snap_overscan_width, + unittester.snap_overscan_height); + unittester.status = UT_STATUS_AWAITING_READ; + unittester.read_len = 12; break; default: @@ -230,6 +302,49 @@ unittester_read(uint16_t port, UNUSED(void *priv)) return 0xFF; switch (unittester.cmd_id) { + case UT_CMD_CAPTURE_SCREEN_SNAPSHOT: + switch(unittester.read_offs) { + case 0: + outval = (uint8_t)(unittester.snap_img_width); + break; + case 1: + outval = (uint8_t)(unittester.snap_img_width>>8); + break; + case 2: + outval = (uint8_t)(unittester.snap_img_height); + break; + case 3: + outval = (uint8_t)(unittester.snap_img_height>>8); + break; + case 4: + outval = (uint8_t)(unittester.snap_overscan_width); + break; + case 5: + outval = (uint8_t)(unittester.snap_overscan_width>>8); + break; + case 6: + outval = (uint8_t)(unittester.snap_overscan_height); + break; + case 7: + outval = (uint8_t)(unittester.snap_overscan_height>>8); + break; + case 8: + outval = (uint8_t)(unittester.snap_img_xoffs); + break; + case 9: + outval = (uint8_t)(unittester.snap_img_xoffs>>8); + break; + case 10: + outval = (uint8_t)(unittester.snap_img_yoffs); + break; + case 11: + outval = (uint8_t)(unittester.snap_img_yoffs>>8); + break; + default: + break; + } + break; + /* This should not be reachable, but just in case... */ default: break; @@ -330,6 +445,9 @@ unittester_trigger_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv)) static void * unittester_init(UNUSED(const device_t *info)) { + if (unittester_screen_buffer == NULL) + unittester_screen_buffer = create_bitmap(2048, 2048); + unittester = (struct unittester_state)unittester_defaults; io_sethandler(unittester.trigger_port, 1, NULL, NULL, NULL, unittester_trigger_write, NULL, NULL, NULL); @@ -347,6 +465,11 @@ unittester_close(UNUSED(void *priv)) io_removehandler(unittester.iobase_port, 2, unittester_read, NULL, NULL, unittester_write, NULL, NULL, NULL); unittester.iobase_port = 0xFFFF; + if (unittester_screen_buffer != NULL) { + destroy_bitmap(unittester_screen_buffer); + unittester_screen_buffer = NULL; + } + unittester_log("[UT] 86Box Unit Tester closed\n"); } From 2e020584cf8bd87f37b161a1060379278992eeac Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Sun, 7 Jan 2024 21:32:59 +1300 Subject: [PATCH 220/936] unittester: Finish implementing 0x01 "Capture Screen Snapshot" And it's looking like the overscan bounds and offset calculation will need to be correct. Otherwise, things will break. Let's see what happens when I get command 0x02 working... --- doc/specifications/86box-unit-tester.md | 2 -- src/device/unittester.c | 9 +++++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/specifications/86box-unit-tester.md b/doc/specifications/86box-unit-tester.md index fe0203b46..c58b15960 100644 --- a/doc/specifications/86box-unit-tester.md +++ b/doc/specifications/86box-unit-tester.md @@ -101,8 +101,6 @@ This is an easy way to reset the status to 0x04 (no command in flight, not waiti ### 0x01: Capture Screen Snapshot -**TODO: IMPLEMENT ME!** - Captures a snapshot of the current screen state and stores it in the current snapshot buffer. The initial state of the screen snapshot buffer has an image area of 0x0, an overscanned area of 0x0, and an image start offset of (0,0). diff --git a/src/device/unittester.c b/src/device/unittester.c index 78086fd90..c020a81ee 100644 --- a/src/device/unittester.c +++ b/src/device/unittester.c @@ -248,7 +248,7 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) /* Monitor disabled - clear snapshot */ unittester.snap_monitor = 0x00; } else { - /* Capture snapshot from monitor */ + /* Compute bounds for snapshot */ const monitor_t *m = &monitors[unittester.snap_monitor - 1]; unittester.snap_img_width = m->mon_xsize; unittester.snap_img_height = m->mon_ysize; @@ -256,7 +256,12 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) unittester.snap_overscan_height = m->mon_ysize + m->mon_overscan_y; unittester.snap_img_xoffs = (m->mon_overscan_x >> 1); unittester.snap_img_yoffs = (m->mon_overscan_y >> 1); - /* TODO: Actually take snapshot! --GM */ + /* Take snapshot */ + for (size_t y = 0; y < unittester.snap_img_height; y++) { + for (size_t x = 0; x < unittester.snap_img_width; x++) { + unittester_screen_buffer->line[y][x] = m->target_buffer->line[y][x]; + } + } } /* We have 12 bytes to read. */ From 678874cd42289b5a873b4c9a7dd7c2b97adb26c9 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Sun, 7 Jan 2024 22:24:32 +1300 Subject: [PATCH 221/936] unittester: Implement 0x02 "Read Screen Snapshot Rectangle" This will need some extra testing but it does appear to be at least somewhat functional. --- doc/specifications/86box-unit-tester.md | 4 +- src/device/unittester.c | 94 ++++++++++++++++++++++++- 2 files changed, 93 insertions(+), 5 deletions(-) diff --git a/doc/specifications/86box-unit-tester.md b/doc/specifications/86box-unit-tester.md index c58b15960..ee77de8d4 100644 --- a/doc/specifications/86box-unit-tester.md +++ b/doc/specifications/86box-unit-tester.md @@ -126,9 +126,7 @@ If there is no screen snapshot, then all values will be 0 as per the initial scr ### 0x02: Read Screen Snapshot Rectangle -**TODO: IMPLEMENT ME!** - -Returns a rectangular snapshot of the screen snapshot buffer. +Returns a rectangular snapshot of the screen snapshot buffer as an array of 32bpp 8:8:8:8 B:G:R:X pixels. Input: diff --git a/src/device/unittester.c b/src/device/unittester.c index c020a81ee..fc864b965 100644 --- a/src/device/unittester.c +++ b/src/device/unittester.c @@ -91,6 +91,13 @@ struct unittester_state { uint16_t snap_img_yoffs; /* Command-specific state */ + /* 0x02: Read Screen Snapshot Rectangle */ + /* 0x03: Verify Screen Snapshot Rectangle */ + uint16_t read_snap_width; + uint16_t read_snap_height; + int16_t read_snap_xoffs; + int16_t read_snap_yoffs; + /* 0x04: Exit */ uint8_t exit_code; }; @@ -157,6 +164,13 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) unittester.write_len = 1; break; + /* 0x02: Read Screen Snapshot Rectangle */ + case UT_CMD_READ_SCREEN_SNAPSHOT_RECTANGLE: + unittester.cmd_id = UT_CMD_READ_SCREEN_SNAPSHOT_RECTANGLE; + unittester.status = UT_STATUS_AWAITING_WRITE; + unittester.write_len = 8; + break; + /* 0x04: Exit */ case UT_CMD_EXIT: unittester.cmd_id = UT_CMD_EXIT; @@ -200,6 +214,37 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) } break; + case UT_CMD_READ_SCREEN_SNAPSHOT_RECTANGLE: + switch(unittester.write_offs) { + case 0: + unittester.read_snap_width = (uint16_t)val; + break; + case 1: + unittester.read_snap_width |= ((uint16_t)val) << 8; + break; + case 2: + unittester.read_snap_height = (uint16_t)val; + break; + case 3: + unittester.read_snap_height |= ((uint16_t)val) << 8; + break; + case 4: + unittester.read_snap_xoffs = (uint16_t)val; + break; + case 5: + unittester.read_snap_xoffs |= ((uint16_t)val) << 8; + break; + case 6: + unittester.read_snap_yoffs = (uint16_t)val; + break; + case 7: + unittester.read_snap_yoffs |= ((uint16_t)val) << 8; + break; + default: + break; + } + break; + /* This should not be reachable, but just in case... */ default: break; @@ -257,8 +302,8 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) unittester.snap_img_xoffs = (m->mon_overscan_x >> 1); unittester.snap_img_yoffs = (m->mon_overscan_y >> 1); /* Take snapshot */ - for (size_t y = 0; y < unittester.snap_img_height; y++) { - for (size_t x = 0; x < unittester.snap_img_width; x++) { + for (size_t y = 0; y < unittester.snap_overscan_height; y++) { + for (size_t x = 0; x < unittester.snap_overscan_width; x++) { unittester_screen_buffer->line[y][x] = m->target_buffer->line[y][x]; } } @@ -276,6 +321,32 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) unittester.read_len = 12; break; + case UT_CMD_READ_SCREEN_SNAPSHOT_RECTANGLE: + /* Offset the X,Y offsets by the overscan offsets. */ + unittester.read_snap_xoffs += (int16_t)unittester.snap_img_xoffs; + unittester.read_snap_yoffs += (int16_t)unittester.snap_img_yoffs; + /*BUG: If the width and height are too large, this ends up with a multiplication overflow. + In practice, this means we end up sending less than we would want to. + However: + - A width and height of that size is obscene, and goes beyond what one would reasonably want. + - The consequences of triggering this bug are that one ends up with a bunch of FF FF FF FF pixels. + - Special-casing this would add unnecessary complexity. + So, this bug is kept here. + If there is any need to fix this bug... then go and make the variables 64-bit :P + */ + unittester.read_len = ((uint32_t)unittester.read_snap_width) * ((uint32_t)unittester.read_snap_height) * 4; + + /* Do we have anything to read? */ + if (unittester.read_len >= 1) { + /* Yes - start reads! */ + unittester.status = UT_STATUS_AWAITING_READ; + } else { + /* No - stop here. */ + unittester.cmd_id = UT_CMD_NOOP; + unittester.status = UT_STATUS_IDLE; + } + break; + default: /* Nothing to write? Stop here. */ unittester.cmd_id = UT_CMD_NOOP; @@ -350,6 +421,25 @@ unittester_read(uint16_t port, UNUSED(void *priv)) } break; + case UT_CMD_READ_SCREEN_SNAPSHOT_RECTANGLE: + /* WARNING: If the width is somehow 0 and wasn't caught earlier, you'll probably get a divide by zero crash. */ + { + uint32_t idx = unittester.read_offs & 0x3; + int32_t x = (unittester.read_offs >> 2) % unittester.read_snap_width; + int32_t y = (unittester.read_offs >> 2) / unittester.read_snap_width; + x += unittester.read_snap_xoffs; + y += unittester.read_snap_yoffs; + + if (x < 0 || y < 0 || x >= unittester.snap_overscan_width || y >= unittester.snap_overscan_height) { + /* Out of range! */ + outval = (idx == 3 ? 0xFF : 0x00); + } else { + /* In range */ + outval = (unittester_screen_buffer->line[y][x] & 0x00FFFFFF)>>(idx*8); + } + } + break; + /* This should not be reachable, but just in case... */ default: break; From c5e321ca923269e3002da1cf07d2f29c0d33ae71 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 7 Jan 2024 20:36:50 +0100 Subject: [PATCH 222/936] S3 changes again: 1. Moved the wraparound fix to the respective recalctimings, makes Commander Keen still playable without flickering and, at the same time, making Solaris work right in 640x480x8bpp+ mode (including 1024x768x8bpp). 2. The multifunction index 0x0e bit that can be toggled in 32bpp mode is now initialized properly, should fix the pinkness on Solaris' 32bpp mode. --- src/video/vid_s3.c | 43 ++++++++++++++----------------------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 4a7a76ed2..e8f5478a6 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -911,7 +911,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.ssv_state = 0; s3->accel_start(-1, 0, 0xffffffff, 0, s3); if (s3->bpp == 3) { - if (!(s3->accel.multifunc[0xe] & 0x200)) + if (!(s3->accel.multifunc[0xe] & 0x200) && !(svga->crtc[0x32] & 0x40)) s3->accel.multifunc[0xe] &= ~0x10; } break; @@ -2717,11 +2717,6 @@ s3_out(uint16_t addr, uint8_t val, void *priv) s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4); svga->force_dword_mode = !!(val & 0x08); break; - case 0x32: - svga->vram_display_mask = (val & 0x40) ? 0x3ffff : s3->vram_mask; - if (s3->color_16bit) - svga->vram_display_mask = s3->vram_mask; - break; case 0x40: s3->enable_8514 = (val & 0x01); @@ -3101,15 +3096,6 @@ s3_recalctimings(svga_t *svga) int clk_sel = (svga->miscout >> 2) & 3; uint8_t mask = 0xc0; - if (!svga->scrblank && svga->attr_palette_enable) { - if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { - if (svga->crtc[0x3a] & 0x10) { /*256+ color register*/ - svga->gdcreg[5] |= 0x40; - svga->attrregs[0x10] |= 0x40; - } - } - } - svga->ma_latch |= (s3->ma_ext << 16); if (s3->chip >= S3_86C928) { svga->hdisp = svga->hdisp_old; @@ -3173,7 +3159,7 @@ s3_recalctimings(svga_t *svga) break; } - svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); + svga->lowres = (!!(svga->attrregs[0x10] & 0x40) && !(svga->crtc[0x3a] & 0x10)); if (s3->chip != S3_86C801) mask |= 0x01; @@ -3232,7 +3218,8 @@ s3_recalctimings(svga_t *svga) } #endif - if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { + if ((svga->crtc[0x3a] & 0x10) && !svga->lowres) { + svga->vram_display_mask = s3->vram_mask; pclog("BPP=%d, pitch=%d, width=%02x, double?=%x, 16bit?=%d, highres?=%d, attr=%02x.\n", svga->bpp, s3->width, svga->crtc[0x50], svga->crtc[0x31] & 0x02, s3->color_16bit, s3->accel.advfunc_cntl & 4, svga->attrregs[0x10] & 0x40); switch (svga->bpp) { case 8: @@ -3920,9 +3907,11 @@ s3_recalctimings(svga_t *svga) break; } } else { + svga->vram_display_mask = (svga->crtc[0x32] & 0x40) ? 0x3ffff : s3->vram_mask; if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { - if ((svga->crtc[0x31] & 0x08) && (svga->attrregs[0x10] & 0x40) == 0x00) { + if (svga->crtc[0x31] & 0x08) { + svga->vram_display_mask = s3->vram_mask; if (svga->bpp == 8) { svga->render = svga_render_8bpp_highres; /*Enhanced 4bpp mode, just like the 8bpp mode per spec.*/ svga->rowoffset <<= 1; @@ -3939,14 +3928,6 @@ s3_trio64v_recalctimings(svga_t *svga) s3_t *s3 = (s3_t *) svga->priv; int clk_sel = (svga->miscout >> 2) & 3; - if (!svga->scrblank && svga->attr_palette_enable) { - if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { - if (svga->crtc[0x3a] & 0x10) { /*256+ color register*/ - svga->gdcreg[5] |= 0x40; - svga->attrregs[0x10] |= 0x40; - } - } - } svga->hdisp = svga->hdisp_old; if (svga->crtc[0x5d] & 0x01) svga->htotal |= 0x100; @@ -4002,9 +3983,10 @@ s3_trio64v_recalctimings(svga_t *svga) if (!svga->rowoffset) svga->rowoffset = 256; - svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); + svga->lowres = (!!(svga->attrregs[0x10] & 0x40) && !(svga->crtc[0x3a] & 0x10)); - if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { + if ((svga->crtc[0x3a] & 0x10) && !svga->lowres) { + svga->vram_display_mask = s3->vram_mask; switch (svga->bpp) { case 8: svga->render = svga_render_8bpp_highres; @@ -4028,7 +4010,9 @@ s3_trio64v_recalctimings(svga_t *svga) default: break; } - } + } else + svga->vram_display_mask = (svga->crtc[0x32] & 0x40) ? 0x3ffff : s3->vram_mask; + } else /*Streams mode*/ { if (s3->streams.buffer_ctrl & 1) @@ -4053,6 +4037,7 @@ s3_trio64v_recalctimings(svga_t *svga) svga->overlay.v_acc = s3->streams.dda_vert_accumulator; svga->rowoffset = s3->streams.pri_stride >> 3; + svga->vram_display_mask = s3->vram_mask; switch ((s3->streams.pri_ctrl >> 24) & 0x7) { case 0: /*RGB-8 (CLUT)*/ svga->render = svga_render_8bpp_highres; From 67d8ebba51c93cba801559f4de9734a56d44eeb0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 7 Jan 2024 20:54:48 +0100 Subject: [PATCH 223/936] S3: Correct line lengths and introduce s3_log(). --- src/video/vid_s3.c | 120 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 92 insertions(+), 28 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index e8f5478a6..49017e2ae 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -16,6 +16,7 @@ * Copyright 2008-2019 Sarah Walker. * Copyright 2016-2019 Miran Grca. */ +#include #include #include #include @@ -23,6 +24,7 @@ #include #include #include +#define HAVE_STDARG_H #include <86box/86box.h> #include <86box/device.h> #include <86box/io.h> @@ -413,6 +415,24 @@ static uint32_t s3_accel_in_l(uint16_t port, void *priv); static uint8_t s3_pci_read(int func, int addr, void *priv); static void s3_pci_write(int func, int addr, uint8_t val, void *priv); +#ifdef ENABLE_S3_LOG +int s3_do_log = ENABLE_S3_LOG; + +static void +s3_log(const char *fmt, ...) +{ + va_list ap; + + if (s3_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define s3_log(fmt, ...) +#endif + /*Remap address for chain-4/doubleword style layout. These will stay for convenience.*/ static __inline uint32_t @@ -581,7 +601,9 @@ s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) const svga_t *svga = &s3->svga; if (s3->accel.cmd & 0x100) { - //pclog("S3 PIXTRANS_W write: cmd=%03x, pixelcntl=%02x, frgdmix=%02x, bkgdmix=%02x, curx=%d, val=%04x.\n", s3->accel.cmd, s3->accel.multifunc[0x0a], s3->accel.frgd_mix, s3->accel.bkgd_mix, s3->accel.cur_x, val); + s3_log("S3 PIXTRANS_W write: cmd=%03x, pixelcntl=%02x, frgdmix=%02x, bkgdmix=%02x, " + "curx=%d, val=%04x.\n", s3->accel.cmd, s3->accel.multifunc[0x0a], + s3->accel.frgd_mix, s3->accel.bkgd_mix, s3->accel.cur_x, val); switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { @@ -595,7 +617,9 @@ s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) if (s3->accel.color_16bit_check_rectfill) { if (s3->accel.color_16bit_check) { if (s3->accel.pix_trans_x_count < s3->accel.pix_trans_ptr_cnt) { - //pclog("Word: CPU data CMD=%04x, byte write=%02x, cnt=%d, check=%d.\n", s3->accel.cmd, val & 0xff, s3->accel.pix_trans_x_count, s3->accel.color_16bit_check); + s3_log("Word: CPU data CMD=%04x, byte write=%02x, " + "cnt=%d, check=%d.\n", s3->accel.cmd, val & 0xff, + s3->accel.pix_trans_x_count, s3->accel.color_16bit_check); s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count] = val & 0xff; s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count + 1] = val >> 8; s3->accel.pix_trans_x_count += 2; @@ -618,7 +642,10 @@ s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) if (s3->accel.color_16bit_check_rectfill) { if (s3->accel.color_16bit_check) { if (s3->accel.pix_trans_x_count < s3->accel.pix_trans_ptr_cnt) { - //pclog("Word: CPU data CMD=%04x, word write=%04x, cnt=%d, check=%d, totalptrcnt=%d.\n", s3->accel.cmd, val, s3->accel.pix_trans_x_count, s3->accel.color_16bit_check, s3->accel.pix_trans_ptr_cnt); + s3_log("Word: CPU data CMD=%04x, word write=%04x, cnt=%d, check=%d, " + "totalptrcnt=%d.\n", s3->accel.cmd, val, + s3->accel.pix_trans_x_count, s3->accel.color_16bit_check, + s3->accel.pix_trans_ptr_cnt); s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count] = val & 0xff; s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count + 1] = val >> 8; s3->accel.pix_trans_x_count += 2; @@ -626,15 +653,23 @@ s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) } } else { if (s3->accel.pix_trans_x_count < s3->accel.pix_trans_ptr_cnt) { - //pclog("Word: CPU data CMD=%04x, word write=%04x, cnt=%d, check=%d, totalptrcnt=%d.\n", s3->accel.cmd, val, s3->accel.pix_trans_x_count, s3->accel.color_16bit_check, s3->accel.pix_trans_ptr_cnt); + s3_log("Word: CPU data CMD=%04x, word write=%04x, cnt=%d, check=%d, " + "totalptrcnt=%d.\n", s3->accel.cmd, val, + s3->accel.pix_trans_x_count, s3->accel.color_16bit_check, + s3->accel.pix_trans_ptr_cnt); s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count2] = val & 0xff; s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count2 + 1] = val >> 8; s3->accel.pix_trans_x_count += 2; } if (s3->accel.pix_trans_x_count2 == s3->accel.pix_trans_ptr_cnt) { for (int i = 0; i < s3->accel.pix_trans_ptr_cnt; i += 2) { - //pclog("Transferring write count=%d, bytes=%08x.\n", i, s3->accel.pix_trans_ptr[i] | (s3->accel.pix_trans_ptr[i + 1] << 8) | (s3->accel.pix_trans_ptr[i + 2] << 16) | (s3->accel.pix_trans_ptr[i + 3] << 24)); - s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans_ptr[i] | (s3->accel.pix_trans_ptr[i + 1] << 8), s3); + s3_log("Transferring write count=%d, bytes=%08x.\n", i, + s3->accel.pix_trans_ptr[i] | + (s3->accel.pix_trans_ptr[i + 1] << 8) | + (s3->accel.pix_trans_ptr[i + 2] << 16) | + (s3->accel.pix_trans_ptr[i + 3] << 24)); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans_ptr[i] | + (s3->accel.pix_trans_ptr[i + 1] << 8), s3); } s3->accel.pix_trans_x_count2 = 0; @@ -1253,22 +1288,30 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) if (s3->accel.color_16bit_check_rectfill) { if (s3->accel.color_16bit_check) { if (s3->accel.pix_trans_x_count < s3->accel.pix_trans_ptr_cnt) { - //pclog("Byte: CPU data CMD=%04x, byte write=%02x, cnt=%d, check=%d.\n", s3->accel.cmd, val, s3->accel.pix_trans_x_count, s3->accel.color_16bit_check); + s3_log("Byte: CPU data CMD=%04x, byte write=%02x, cnt=%d, " + "check=%d.\n", s3->accel.cmd, val, + s3->accel.pix_trans_x_count, s3->accel.color_16bit_check); s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count] = val; s3->accel.pix_trans_x_count++; s3->accel.pix_trans_x_count2 = s3->accel.pix_trans_x_count; } } else { if (s3->accel.pix_trans_x_count2 < s3->accel.pix_trans_ptr_cnt) { - //pclog("Byte: CPU data CMD=%04x, byte write=%02x, cnt=%d, check=%d.\n", s3->accel.cmd, val, s3->accel.pix_trans_x_count2, s3->accel.color_16bit_check); + s3_log("Byte: CPU data CMD=%04x, byte write=%02x, cnt=%d, " + "check=%d.\n", s3->accel.cmd, val, + s3->accel.pix_trans_x_count2, s3->accel.color_16bit_check); s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count2] = val; s3->accel.pix_trans_x_count2++; } - //pclog("WriteCNT=%d, TotalCNT=%d.\n", s3->accel.pix_trans_x_count2, s3->accel.pix_trans_ptr_cnt); + s3_log("WriteCNT=%d, TotalCNT=%d.\n", s3->accel.pix_trans_x_count2, + s3->accel.pix_trans_ptr_cnt); if (s3->accel.pix_trans_x_count2 == s3->accel.pix_trans_ptr_cnt) { for (int i = 0; i < s3->accel.pix_trans_ptr_cnt; i += 2) { - //pclog("Transferring write count=%d, bytes=%04x.\n", i, s3->accel.pix_trans_ptr[i] | (s3->accel.pix_trans_ptr[i + 1] << 8)); - s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans_ptr[i] | (s3->accel.pix_trans_ptr[i + 1] << 8), s3); + s3_log("Transferring write count=%d, bytes=%04x.\n", i, + s3->accel.pix_trans_ptr[i] | + (s3->accel.pix_trans_ptr[i + 1] << 8)); + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans_ptr[i] | + (s3->accel.pix_trans_ptr[i + 1] << 8), s3); } s3->accel.pix_trans_x_count2 = 0; @@ -1297,35 +1340,48 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; s3->accel.pix_trans[1] = val; if (s3->accel.cmd & 0x100) { - //pclog("S3 PIXTRANS_B write (E2E9): cmd=%03x, pixelcntl=%02x, frgdmix=%02x, bkgdmix=%02x, curx=%d, val=%04x.\n", s3->accel.cmd, s3->accel.multifunc[0x0a], s3->accel.frgd_mix, s3->accel.bkgd_mix, s3->accel.cur_x, val); + s3_log("S3 PIXTRANS_B write (E2E9): cmd=%03x, pixelcntl=%02x, frgdmix=%02x, " + "bkgdmix=%02x, curx=%d, val=%04x.\n", s3->accel.cmd, s3->accel.multifunc[0x0a], + s3->accel.frgd_mix, s3->accel.bkgd_mix, s3->accel.cur_x, val); switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3->accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); + if (((s3->accel.frgd_mix & 0x60) != 0x40) || + ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3->accel_start(8, 1, s3->accel.pix_trans[0] | + (s3->accel.pix_trans[1] << 8), 0, s3); else - s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | + (s3->accel.pix_trans[1] << 8), s3); } else - s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | + (s3->accel.pix_trans[1] << 8), s3); break; case 0x200: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || + ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) - s3->accel_start(16, 1, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), 0, s3); + s3->accel_start(16, 1, s3->accel.pix_trans[1] | + (s3->accel.pix_trans[0] << 8), 0, s3); else - s3->accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); + s3->accel_start(16, 1, s3->accel.pix_trans[0] | + (s3->accel.pix_trans[1] << 8), 0, s3); } else { if (s3->accel.cmd & 0x1000) - s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | + (s3->accel.pix_trans[0] << 8), s3); else - s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | + (s3->accel.pix_trans[1] << 8), s3); } } else { if (s3->accel.cmd & 0x1000) - s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | + (s3->accel.pix_trans[0] << 8), s3); else - s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | + (s3->accel.pix_trans[1] << 8), s3); } break; case 0x400: @@ -3220,7 +3276,10 @@ s3_recalctimings(svga_t *svga) if ((svga->crtc[0x3a] & 0x10) && !svga->lowres) { svga->vram_display_mask = s3->vram_mask; - pclog("BPP=%d, pitch=%d, width=%02x, double?=%x, 16bit?=%d, highres?=%d, attr=%02x.\n", svga->bpp, s3->width, svga->crtc[0x50], svga->crtc[0x31] & 0x02, s3->color_16bit, s3->accel.advfunc_cntl & 4, svga->attrregs[0x10] & 0x40); + s3_log("BPP=%d, pitch=%d, width=%02x, double?=%x, 16bit?=%d, highres?=%d, " + "attr=%02x.\n", svga->bpp, s3->width, svga->crtc[0x50], + svga->crtc[0x31] & 0x02, s3->color_16bit, s3->accel.advfunc_cntl & 4, + svga->attrregs[0x10] & 0x40); switch (svga->bpp) { case 8: svga->render = svga_render_8bpp_highres; @@ -7165,27 +7224,32 @@ s3_911_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, } } - //pclog("CMD=%04x, curx=%d, lwrtmask=%04x, actual wrtmask=%04x, frgdmix=%d, bkgdmix=%d, input=%d, cnt=%d.\n", s3->accel.cmd, s3->accel.cur_x, wrt_mask, s3->accel.wrt_mask, frgd_mix, bkgd_mix, cpu_input, count); + s3_log("CMD=%04x, curx=%d, lwrtmask=%04x, actual wrtmask=%04x, frgdmix=%d, " + "bkgdmix=%d, input=%d, cnt=%d.\n", s3->accel.cmd, s3->accel.cur_x, + wrt_mask, s3->accel.wrt_mask, frgd_mix, bkgd_mix, cpu_input, count); while (count-- && s3->accel.sy >= 0) { if (s3->accel.b2e8_pix && s3_cpu_src(s3) && !s3->accel.temp_cnt) { mix_dat >>= 16; s3->accel.temp_cnt = 16; } - if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && + (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: src_dat = bkgd_color; if (s3->color_16bit && (svga->bpp < 24) && !s3->accel.b2e8_pix) { if (!s3->accel.color_16bit_check) - src_dat = s3->accel.bkgd_color_actual[0] | (s3->accel.bkgd_color_actual[1] << 8); + src_dat = s3->accel.bkgd_color_actual[0] | + (s3->accel.bkgd_color_actual[1] << 8); } break; case 1: src_dat = frgd_color; if (s3->color_16bit && (svga->bpp < 24) && !s3->accel.b2e8_pix) { if (!s3->accel.color_16bit_check) - src_dat = s3->accel.frgd_color_actual[0] | (s3->accel.frgd_color_actual[1] << 8); + src_dat = s3->accel.frgd_color_actual[0] | + (s3->accel.frgd_color_actual[1] << 8); } break; case 2: From f35dd209745aaa09cf133c2f9adfbbcdd4b3e4f0 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Mon, 8 Jan 2024 10:45:13 +1300 Subject: [PATCH 224/936] unittester: Reduce spam --- src/device/unittester.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/unittester.c b/src/device/unittester.c index fc864b965..1736a70d8 100644 --- a/src/device/unittester.c +++ b/src/device/unittester.c @@ -371,7 +371,7 @@ unittester_read(uint16_t port, UNUSED(void *priv)) return unittester.status; } else if (port == unittester.iobase_port+0x01) { /* Data port */ - unittester_log("[UT] R -- Data\n"); + /* unittester_log("[UT] R -- Data\n"); */ /* Skip if not awaiting */ if ((unittester.status & UT_STATUS_AWAITING_READ) == 0) From 354c5374697e9d92bbb0b2bfb2d2384d1ca716ad Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 8 Jan 2024 00:07:00 +0100 Subject: [PATCH 225/936] Added 3 CGA line doubling types, in order from the lowest to the highest quality, and the IBM 5153 monitor (per VileR's colors) which is now default, closes #3105. --- src/video/vid_cga.c | 520 +++++++++++++++++++++++++++++++------------- src/video/video.c | 21 +- 2 files changed, 390 insertions(+), 151 deletions(-) diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index 3d806d95b..07a8dfcdb 100644 --- a/src/video/vid_cga.c +++ b/src/video/vid_cga.c @@ -43,11 +43,29 @@ #define COMPOSITE_OLD 0 #define COMPOSITE_NEW 1 +#define DOUBLE_NONE 0 +#define DOUBLE_SIMPLE 1 +#define DOUBLE_INTERPOLATE_SRGB 2 +#define DOUBLE_INTERPOLATE_LINEAR 3 + +typedef union +{ + uint32_t color; + struct { + uint8_t b; + uint8_t g; + uint8_t r; + uint8_t a; + }; +} color_t; + static uint8_t crtcmask[32] = { 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static uint8_t interp_lut[2][256][256]; + static video_timings_t timing_cga = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; void cga_recalctimings(cga_t *cga); @@ -201,24 +219,269 @@ cga_recalctimings(cga_t *cga) cga->dispofftime = (uint64_t) (_dispofftime); } -void -cga_poll(void *priv) +static void +cga_render(cga_t *cga, int line) { - cga_t *cga = (cga_t *) priv; uint16_t ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff; int drawcursor; int x; int c; - int xs_temp; - int ys_temp; - int oldvc; uint8_t chr; uint8_t attr; - uint8_t border; uint16_t dat; int cols[4]; int col; + + if ((cga->cgamode & 0x12) == 0x12) { + for (c = 0; c < 8; ++c) { + buffer32->line[line][c] = 0; + if (cga->cgamode & 1) + buffer32->line[line][c + (cga->crtc[1] << 3) + 8] = 0; + else + buffer32->line[line][c + (cga->crtc[1] << 4) + 8] = 0; + } + } else { + for (c = 0; c < 8; ++c) { + buffer32->line[line][c] = (cga->cgacol & 15) + 16; + if (cga->cgamode & 1) + buffer32->line[line][c + (cga->crtc[1] << 3) + 8] = (cga->cgacol & 15) + 16; + else + buffer32->line[line][c + (cga->crtc[1] << 4) + 8] = (cga->cgacol & 15) + 16; + } + } + if (cga->cgamode & 1) { + for (x = 0; x < cga->crtc[1]; x++) { + if (cga->cgamode & 8) { + chr = cga->charbuffer[x << 1]; + attr = cga->charbuffer[(x << 1) + 1]; + } else + chr = attr = 0; + drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); + cols[1] = (attr & 15) + 16; + if (cga->cgamode & 0x20) { + cols[0] = ((attr >> 4) & 7) + 16; + if ((cga->cgablink & 8) && (attr & 0x80) && !cga->drawcursor) + cols[1] = cols[0]; + } else + cols[0] = (attr >> 4) + 16; + if (drawcursor) { + for (c = 0; c < 8; c++) { + buffer32->line[line][(x << 3) + c + 8] + = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + } + } else { + for (c = 0; c < 8; c++) { + buffer32->line[line][(x << 3) + c + 8] + = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + } + } + cga->ma++; + } + } else if (!(cga->cgamode & 2)) { + for (x = 0; x < cga->crtc[1]; x++) { + if (cga->cgamode & 8) { + chr = cga->vram[(cga->ma << 1) & 0x3fff]; + attr = cga->vram[((cga->ma << 1) + 1) & 0x3fff]; + } else + chr = attr = 0; + drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); + cols[1] = (attr & 15) + 16; + if (cga->cgamode & 0x20) { + cols[0] = ((attr >> 4) & 7) + 16; + if ((cga->cgablink & 8) && (attr & 0x80)) + cols[1] = cols[0]; + } else + cols[0] = (attr >> 4) + 16; + cga->ma++; + if (drawcursor) { + for (c = 0; c < 8; c++) { + buffer32->line[line][(x << 4) + (c << 1) + 8] + = buffer32->line[line][(x << 4) + (c << 1) + 9] + = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + } + } else { + for (c = 0; c < 8; c++) { + buffer32->line[line][(x << 4) + (c << 1) + 8] + = buffer32->line[line][(x << 4) + (c << 1) + 9] + = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + } + } + } + } else if (!(cga->cgamode & 16)) { + cols[0] = (cga->cgacol & 15) | 16; + col = (cga->cgacol & 16) ? 24 : 16; + if (cga->cgamode & 4) { + cols[1] = col | 3; /* Cyan */ + cols[2] = col | 4; /* Red */ + cols[3] = col | 7; /* White */ + } else if (cga->cgacol & 32) { + cols[1] = col | 3; /* Cyan */ + cols[2] = col | 5; /* Magenta */ + cols[3] = col | 7; /* White */ + } else { + cols[1] = col | 2; /* Green */ + cols[2] = col | 4; /* Red */ + cols[3] = col | 6; /* Yellow */ + } + for (x = 0; x < cga->crtc[1]; x++) { + if (cga->cgamode & 8) + dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | + cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; + else + dat = 0; + cga->ma++; + for (c = 0; c < 8; c++) { + buffer32->line[line][(x << 4) + (c << 1) + 8] + = buffer32->line[line][(x << 4) + (c << 1) + 9] + = cols[dat >> 14]; + dat <<= 2; + } + } + } else { + cols[0] = 0; + cols[1] = (cga->cgacol & 15) + 16; + for (x = 0; x < cga->crtc[1]; x++) { + if (cga->cgamode & 8) + dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | + cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; + else + dat = 0; + cga->ma++; + for (c = 0; c < 16; c++) { + buffer32->line[line][(x << 4) + c + 8] = cols[dat >> 15]; + dat <<= 1; + } + } + } +} + +static void +cga_render_blank(cga_t *cga, int line) +{ + int col = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15) + 16; + + if (cga->cgamode & 1) + hline(buffer32, 0, line, (cga->crtc[1] << 3) + 16, col); + else + hline(buffer32, 0, line, (cga->crtc[1] << 4) + 16, col); +} + +static void +cga_render_process(cga_t *cga, int line) +{ + int x; + uint8_t border; + + if (cga->cgamode & 1) + x = (cga->crtc[1] << 3) + 16; + else + x = (cga->crtc[1] << 4) + 16; + + if (cga->composite) { + border = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15); + + Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[line]); + } else + video_process_8(x, line); +} + +static uint8_t +cga_interpolate_srgb(uint8_t co1, uint8_t co2, double fraction) +{ + uint8_t ret = ((co2 - co1) * fraction + co1); + + return ret; +} + +static uint8_t +cga_interpolate_linear(uint8_t co1, uint8_t co2, double fraction) +{ + double c1, c2; + double r1, r2; + uint8_t ret; + + c1 = ((double) co1) / 255.0; + c1 = pow((co1 >= 0) ? c1 : -c1, 2.19921875); + if (co1 <= 0) + c1 = -c1; + c2 = ((double) co2) / 255.0; + c2 = pow((co2 >= 0) ? c2 : -c2, 2.19921875); + if (co2 <= 0) + c2 = -c2; + r1 = ((c2 - c1) * fraction + c1); + r2 = pow((r1 >= 0.0) ? r1 : -r1, 1.0 / 2.19921875); + if (r1 <= 0.0) + r2 = -r2; + ret = (uint8_t) (r2 * 255.0); + + return ret; +} + +static color_t +cga_interpolate_lookup(cga_t *cga, color_t color1, color_t color2, double fraction) +{ + color_t ret; + uint8_t dt = cga->double_type - DOUBLE_INTERPOLATE_SRGB; + + ret.a = 0x00; + ret.r = interp_lut[dt][color1.r][color2.r]; + ret.g = interp_lut[dt][color1.g][color2.g]; + ret.b = interp_lut[dt][color1.b][color2.b]; + + return ret; +} + +static void +cga_interpolate(cga_t *cga, int x, int y, int w, int h) +{ + double quotient = 0.5; + + for (int i = y; i < (y + h); i++) { + if (i & 1) for (int j = x; j < (x + w); j++) { + int prev = i - 1; + int next = i + 1; + color_t prev_color, next_color; + color_t black; + color_t interim_1, interim_2; + color_t final; + + black.color = 0x00000000; + + prev_color.color = buffer32->line[prev][j]; + + if (next < (y + h)) + next_color.color = buffer32->line[next][j]; + else + next_color.color = 0x00000000; + + interim_1 = cga_interpolate_lookup(cga, prev_color, black, quotient); + interim_2 = cga_interpolate_lookup(cga, black, next_color, quotient); + final = cga_interpolate_lookup(cga, interim_1, interim_2, quotient); + + buffer32->line[i][j] = final.color; + } + } +} + +static void +cga_blit_memtoscreen(cga_t *cga, int x, int y, int w, int h) +{ + if (cga->double_type > DOUBLE_SIMPLE) + cga_interpolate(cga, x, y, w, h); + + video_blit_memtoscreen(x, y, w, h); +} + +void +cga_poll(void *priv) +{ + cga_t *cga = (cga_t *) priv; + int x; int oldsc; + int oldvc; + int xs_temp; + int ys_temp; + int old_ma; if (!cga->linepos) { timer_advance_u64(&cga->timer, cga->dispofftime); @@ -233,143 +496,44 @@ cga_poll(void *priv) video_wait_for_buffer(); } cga->lastline = cga->displine; - if ((cga->cgamode & 0x12) == 0x12) { - for (c = 0; c < 8; ++c) { - buffer32->line[cga->displine][c] = 0; - if (cga->cgamode & 1) - buffer32->line[cga->displine][c + (cga->crtc[1] << 3) + 8] = 0; - else - buffer32->line[cga->displine][c + (cga->crtc[1] << 4) + 8] = 0; - } - } else { - for (c = 0; c < 8; ++c) { - buffer32->line[cga->displine][c] = (cga->cgacol & 15) + 16; - if (cga->cgamode & 1) - buffer32->line[cga->displine][c + (cga->crtc[1] << 3) + 8] = (cga->cgacol & 15) + 16; - else - buffer32->line[cga->displine][c + (cga->crtc[1] << 4) + 8] = (cga->cgacol & 15) + 16; - } - } - if (cga->cgamode & 1) { - for (x = 0; x < cga->crtc[1]; x++) { - if (cga->cgamode & 8) { - chr = cga->charbuffer[x << 1]; - attr = cga->charbuffer[(x << 1) + 1]; - } else - chr = attr = 0; - drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); - cols[1] = (attr & 15) + 16; - if (cga->cgamode & 0x20) { - cols[0] = ((attr >> 4) & 7) + 16; - if ((cga->cgablink & 8) && (attr & 0x80) && !cga->drawcursor) - cols[1] = cols[0]; - } else - cols[0] = (attr >> 4) + 16; - if (drawcursor) { - for (c = 0; c < 8; c++) { - buffer32->line[cga->displine][(x << 3) + c + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; - } - } else { - for (c = 0; c < 8; c++) { - buffer32->line[cga->displine][(x << 3) + c + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - cga->ma++; - } - } else if (!(cga->cgamode & 2)) { - for (x = 0; x < cga->crtc[1]; x++) { - if (cga->cgamode & 8) { - chr = cga->vram[(cga->ma << 1) & 0x3fff]; - attr = cga->vram[((cga->ma << 1) + 1) & 0x3fff]; - } else - chr = attr = 0; - drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); - cols[1] = (attr & 15) + 16; - if (cga->cgamode & 0x20) { - cols[0] = ((attr >> 4) & 7) + 16; - if ((cga->cgablink & 8) && (attr & 0x80)) - cols[1] = cols[0]; - } else - cols[0] = (attr >> 4) + 16; - cga->ma++; - if (drawcursor) { - for (c = 0; c < 8; c++) { - buffer32->line[cga->displine][(x << 4) + (c << 1) + 8] - = buffer32->line[cga->displine][(x << 4) + (c << 1) + 9] - = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; - } - } else { - for (c = 0; c < 8; c++) { - buffer32->line[cga->displine][(x << 4) + (c << 1) + 8] - = buffer32->line[cga->displine][(x << 4) + (c << 1) + 9] - = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - } - } else if (!(cga->cgamode & 16)) { - cols[0] = (cga->cgacol & 15) | 16; - col = (cga->cgacol & 16) ? 24 : 16; - if (cga->cgamode & 4) { - cols[1] = col | 3; /* Cyan */ - cols[2] = col | 4; /* Red */ - cols[3] = col | 7; /* White */ - } else if (cga->cgacol & 32) { - cols[1] = col | 3; /* Cyan */ - cols[2] = col | 5; /* Magenta */ - cols[3] = col | 7; /* White */ - } else { - cols[1] = col | 2; /* Green */ - cols[2] = col | 4; /* Red */ - cols[3] = col | 6; /* Yellow */ - } - for (x = 0; x < cga->crtc[1]; x++) { - if (cga->cgamode & 8) - dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; - else - dat = 0; - cga->ma++; - for (c = 0; c < 8; c++) { - buffer32->line[cga->displine][(x << 4) + (c << 1) + 8] - = buffer32->line[cga->displine][(x << 4) + (c << 1) + 9] - = cols[dat >> 14]; - dat <<= 2; - } - } - } else { - cols[0] = 0; - cols[1] = (cga->cgacol & 15) + 16; - for (x = 0; x < cga->crtc[1]; x++) { - if (cga->cgamode & 8) - dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; - else - dat = 0; - cga->ma++; - for (c = 0; c < 16; c++) { - buffer32->line[cga->displine][(x << 4) + c + 8] = cols[dat >> 15]; - dat <<= 1; - } - } + switch (cga->double_type) { + default: + cga_render(cga, cga->displine << 1); + cga_render_blank(cga, (cga->displine << 1) + 1); + break; + case DOUBLE_NONE: + cga_render(cga, cga->displine); + break; + case DOUBLE_SIMPLE: + old_ma = cga->ma; + cga_render(cga, cga->displine << 1); + cga->ma = old_ma; + cga_render(cga, (cga->displine << 1) + 1); + break; } } else { - cols[0] = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15) + 16; - if (cga->cgamode & 1) { - hline(buffer32, 0, cga->displine, (cga->crtc[1] << 3) + 16, cols[0]); - } else { - hline(buffer32, 0, cga->displine, (cga->crtc[1] << 4) + 16, cols[0]); + switch (cga->double_type) { + default: + cga_render_blank(cga, cga->displine << 1); + break; + case DOUBLE_NONE: + cga_render_blank(cga, cga->displine); + break; + case DOUBLE_SIMPLE: + cga_render_blank(cga, cga->displine << 1); + cga_render_blank(cga, (cga->displine << 1) + 1); + break; } } - if (cga->cgamode & 1) - x = (cga->crtc[1] << 3) + 16; - else - x = (cga->crtc[1] << 4) + 16; - - if (cga->composite) { - border = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15); - - Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[cga->displine]); - } else { - video_process_8(x, cga->displine); + switch (cga->double_type) { + default: + cga_render_process(cga, cga->displine << 1); + cga_render_process(cga, (cga->displine << 1) + 1); + break; + case DOUBLE_NONE: + cga_render_process(cga, cga->displine); + break; } cga->sc = oldsc; @@ -386,7 +550,8 @@ cga_poll(void *priv) if (!cga->vsynctime) cga->cgastat &= ~8; } - if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[11] & 31) >> 1))) { + if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 && + cga->sc == ((cga->crtc[11] & 31) >> 1))) { cga->con = 0; cga->coff = 1; } @@ -445,6 +610,8 @@ cga_poll(void *priv) xs_temp = x; ys_temp = cga->lastline - cga->firstline; + if (cga->double_type > DOUBLE_NONE) + ys_temp <<= 1; if ((xs_temp > 0) && (ys_temp > 0)) { if (xs_temp < 64) @@ -454,21 +621,33 @@ cga_poll(void *priv) if (!enable_overscan) xs_temp -= 16; - if ((cga->cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { + if ((cga->cgamode & 8) && ((xs_temp != xsize) || + (ys_temp != ysize) || video_force_resize_get())) { xsize = xs_temp; ysize = ys_temp; - set_screen_size(xsize, ysize + (enable_overscan ? 8 : 0)); + if (cga->double_type > DOUBLE_NONE) + set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0)); + else + set_screen_size(xsize, ysize + (enable_overscan ? 8 : 0)); if (video_force_resize_get()) video_force_resize_set(0); } - if (enable_overscan) { - video_blit_memtoscreen(0, cga->firstline - 4, - xsize, (cga->lastline - cga->firstline) + 8); + if (cga->double_type > DOUBLE_NONE) { + if (enable_overscan) + cga_blit_memtoscreen(cga, 0, (cga->firstline - 4) << 1, + xsize, ((cga->lastline - cga->firstline) << 1) + 16); + else + cga_blit_memtoscreen(cga, 8, cga->firstline << 1, + xsize, (cga->lastline - cga->firstline) << 1); } else { - video_blit_memtoscreen(8, cga->firstline, - xsize, cga->lastline - cga->firstline); + if (enable_overscan) + video_blit_memtoscreen(0, cga->firstline - 4, + xsize, (cga->lastline - cga->firstline) + 8); + else + video_blit_memtoscreen(8, cga->firstline, + xsize, cga->lastline - cga->firstline); } } @@ -502,7 +681,8 @@ cga_poll(void *priv) } if (cga->cgadispon) cga->cgastat &= ~1; - if (cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1))) + if (cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && + cga->sc == ((cga->crtc[10] & 31) >> 1))) cga->con = 1; if (cga->cgadispon && (cga->cgamode & 1)) { for (x = 0; x < (cga->crtc[1] << 1); x++) @@ -546,6 +726,15 @@ cga_standalone_init(UNUSED(const device_t *info)) cgapal_rebuild(); update_cga16_color(cga->cgamode); + cga->double_type = device_get_config_int("double_type"); + + for (uint16_t i = 0; i < 256; i++) { + for (uint16_t j = 0; j < 256; j++) { + interp_lut[0][i][j] = cga_interpolate_srgb(i, j, 0.5); + interp_lut[1][i][j] = cga_interpolate_linear(i, j, 0.5); + } + } + return cga; } @@ -625,10 +814,10 @@ const device_config_t cga_config[] = { .name = "rgb_type", .description = "RGB type", .type = CONFIG_SELECTION, - .default_int = 0, + .default_int = 5, .selection = { { - .description = "Color", + .description = "Color (generic)", .value = 0 }, { @@ -647,6 +836,37 @@ const device_config_t cga_config[] = { .description = "Color (no brown)", .value = 4 }, + { + .description = "Color (IBM 5153)", + .value = 5 + }, + { + .description = "" + } + } + }, + { + .name = "double_type", + .description = "Line doubling type", + .type = CONFIG_SELECTION, + .default_int = DOUBLE_NONE, + .selection = { + { + .description = "None", + .value = DOUBLE_NONE + }, + { + .description = "Simple doubling", + .value = DOUBLE_SIMPLE + }, + { + .description = "sRGB interpolation", + .value = DOUBLE_INTERPOLATE_SRGB + }, + { + .description = "Linear interpolation", + .value = DOUBLE_INTERPOLATE_LINEAR + }, { .description = "" } diff --git a/src/video/video.c b/src/video/video.c index 4c561e229..710449746 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -601,8 +601,27 @@ cgapal_rebuild_monitor(int monitor_index) } } - if (cga_palette_monitor == 7) + if (cga_palette_monitor == 8) palette_lookup[0x16] = makecol(video_6to8[42], video_6to8[42], video_6to8[0]); + else if (cga_palette_monitor == 10) { + /* IBM 5153 CRT, colors by VileR */ + palette_lookup[0x10] = 0x00000000; + palette_lookup[0x11] = 0x000000c4; + palette_lookup[0x12] = 0x0000c400; + palette_lookup[0x13] = 0x0000c4c4; + palette_lookup[0x14] = 0x00c40000; + palette_lookup[0x15] = 0x00c400c4; + palette_lookup[0x16] = 0x00c47e00; + palette_lookup[0x17] = 0x00c4c4c4; + palette_lookup[0x18] = 0x004e4e4e; + palette_lookup[0x19] = 0x004e4edc; + palette_lookup[0x1a] = 0x004edc4e; + palette_lookup[0x1b] = 0x004ef3f3; + palette_lookup[0x1c] = 0x00dc4e4e; + palette_lookup[0x1d] = 0x00f34ef3; + palette_lookup[0x1e] = 0x00f3f34e; + palette_lookup[0x1f] = 0x00ffffff; + } } void From 30aacb2a1a7734e5ef8802869a318f32746f0791 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Mon, 8 Jan 2024 12:07:14 +1300 Subject: [PATCH 226/936] unittester: Implement 0x03 "Verify Screen Snapshot Rectangle" Basic quick tests show that this is probably consistent with command 0x02. --- doc/specifications/86box-unit-tester.md | 4 -- src/device/unittester.c | 79 ++++++++++++++++++------- 2 files changed, 58 insertions(+), 25 deletions(-) diff --git a/doc/specifications/86box-unit-tester.md b/doc/specifications/86box-unit-tester.md index ee77de8d4..8d8d5bbb6 100644 --- a/doc/specifications/86box-unit-tester.md +++ b/doc/specifications/86box-unit-tester.md @@ -49,8 +49,6 @@ Set the I/O base address to 0xFFFF using the above method. ### Executing commands -**TODO: IMPLEMENT ME!** - The ports at IOBASE+0x00 and IOBASE+0x01 are all 8 bits wide. Writing to IOBASE+0x00 cancels any in-flight commands and sends a new command. @@ -145,8 +143,6 @@ Output: ### 0x03: Verify Screen Snapshot Rectangle -**TODO: IMPLEMENT ME!** - As per 0x02 "Read Screen Snapshot Rectangle", except instead of returning the pixel data, it returns a CRC-32 of the data. The CRC is as per zlib's `crc32()` function. Specifically, one uses a right-shifting Galois LFSR with a polynomial of 0xEDB88320, bytes XORed against the least significant byte, the initial seed is 0xFFFFFFFF, and all bits of the output are inverted. diff --git a/src/device/unittester.c b/src/device/unittester.c index 1736a70d8..55bc270e9 100644 --- a/src/device/unittester.c +++ b/src/device/unittester.c @@ -97,6 +97,7 @@ struct unittester_state { uint16_t read_snap_height; int16_t read_snap_xoffs; int16_t read_snap_yoffs; + uint32_t read_snap_crc; /* 0x04: Exit */ uint8_t exit_code; @@ -138,6 +139,25 @@ unittester_log(const char *fmt, ...) # define unittester_log(fmt, ...) #endif +static uint8_t +unittester_read_snap_rect_idx(uint32_t offs) +{ + /* WARNING: If the width is somehow 0 and wasn't caught earlier, you'll probably get a divide by zero crash. */ + uint32_t idx = (offs & 0x3); + int32_t x = (offs >> 2) % unittester.read_snap_width; + int32_t y = (offs >> 2) / unittester.read_snap_width; + x += unittester.read_snap_xoffs; + y += unittester.read_snap_yoffs; + + if (x < 0 || y < 0 || x >= unittester.snap_overscan_width || y >= unittester.snap_overscan_height) { + /* Out of range! */ + return (idx == 3 ? 0xFF : 0x00); + } else { + /* In range */ + return (unittester_screen_buffer->line[y][x] & 0x00FFFFFF)>>(idx*8); + } +} + static void unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) { @@ -171,6 +191,13 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) unittester.write_len = 8; break; + /* 0x03: Verify Screen Snapshot Rectangle */ + case UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE: + unittester.cmd_id = UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE; + unittester.status = UT_STATUS_AWAITING_WRITE; + unittester.write_len = 8; + break; + /* 0x04: Exit */ case UT_CMD_EXIT: unittester.cmd_id = UT_CMD_EXIT; @@ -215,6 +242,7 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) break; case UT_CMD_READ_SCREEN_SNAPSHOT_RECTANGLE: + case UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE: switch(unittester.write_offs) { case 0: unittester.read_snap_width = (uint16_t)val; @@ -322,6 +350,7 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) break; case UT_CMD_READ_SCREEN_SNAPSHOT_RECTANGLE: + case UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE: /* Offset the X,Y offsets by the overscan offsets. */ unittester.read_snap_xoffs += (int16_t)unittester.snap_img_xoffs; unittester.read_snap_yoffs += (int16_t)unittester.snap_img_yoffs; @@ -335,15 +364,34 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) If there is any need to fix this bug... then go and make the variables 64-bit :P */ unittester.read_len = ((uint32_t)unittester.read_snap_width) * ((uint32_t)unittester.read_snap_height) * 4; + unittester.read_snap_crc = 0xFFFFFFFF; - /* Do we have anything to read? */ - if (unittester.read_len >= 1) { - /* Yes - start reads! */ + if (unittester.cmd_id == UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE) { + /* Read everything and compute CRC */ + uint32_t crc = 0xFFFFFFFF; + for (uint32_t i = 0; i < unittester.read_len; i++) { + crc ^= 0xFF & (uint32_t)unittester_read_snap_rect_idx(i); + /* Use some bit twiddling until we have a table-based fast CRC-32 implementation */ + for (uint32_t j = 0; j < 8; j++) { + crc = (crc >> 1) ^ ((-(crc&0x1)) & 0xEDB88320); + } + } + unittester.read_snap_crc = crc ^ 0xFFFFFFFF; + + /* Set actual read length for CRC result */ + unittester.read_len = 4; unittester.status = UT_STATUS_AWAITING_READ; + } else { - /* No - stop here. */ - unittester.cmd_id = UT_CMD_NOOP; - unittester.status = UT_STATUS_IDLE; + /* Do we have anything to read? */ + if (unittester.read_len >= 1) { + /* Yes - start reads! */ + unittester.status = UT_STATUS_AWAITING_READ; + } else { + /* No - stop here. */ + unittester.cmd_id = UT_CMD_NOOP; + unittester.status = UT_STATUS_IDLE; + } } break; @@ -422,22 +470,11 @@ unittester_read(uint16_t port, UNUSED(void *priv)) break; case UT_CMD_READ_SCREEN_SNAPSHOT_RECTANGLE: - /* WARNING: If the width is somehow 0 and wasn't caught earlier, you'll probably get a divide by zero crash. */ - { - uint32_t idx = unittester.read_offs & 0x3; - int32_t x = (unittester.read_offs >> 2) % unittester.read_snap_width; - int32_t y = (unittester.read_offs >> 2) / unittester.read_snap_width; - x += unittester.read_snap_xoffs; - y += unittester.read_snap_yoffs; + outval = unittester_read_snap_rect_idx(unittester.read_offs); + break; - if (x < 0 || y < 0 || x >= unittester.snap_overscan_width || y >= unittester.snap_overscan_height) { - /* Out of range! */ - outval = (idx == 3 ? 0xFF : 0x00); - } else { - /* In range */ - outval = (unittester_screen_buffer->line[y][x] & 0x00FFFFFF)>>(idx*8); - } - } + case UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE: + outval = (uint8_t)(unittester.read_snap_crc >> (8*unittester.read_offs)); break; /* This should not be reachable, but just in case... */ From 86d7c248f414e4910ac325d9d34682855b13e294 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 8 Jan 2024 00:09:35 +0100 Subject: [PATCH 227/936] The forgotten changes to vid_cga.h. --- src/include/86box/vid_cga.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/86box/vid_cga.h b/src/include/86box/vid_cga.h index f49fc73cc..5b6a2dea2 100644 --- a/src/include/86box/vid_cga.h +++ b/src/include/86box/vid_cga.h @@ -66,6 +66,7 @@ typedef struct cga_t { int composite; int snow_enabled; int rgb_type; + int double_type; } cga_t; void cga_init(cga_t *cga); From e5f467918ce791f1b391437ffffd2e32d6b30bc6 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Mon, 8 Jan 2024 12:54:31 +1300 Subject: [PATCH 228/936] unittester: Cleanups and specification v1.0.0 finalisation --- doc/specifications/86box-unit-tester.md | 57 +++++++++++++++++++++---- src/device/unittester.c | 5 +-- src/include/86box/unittester.h | 2 + 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/doc/specifications/86box-unit-tester.md b/doc/specifications/86box-unit-tester.md index 8d8d5bbb6..48817b27c 100644 --- a/doc/specifications/86box-unit-tester.md +++ b/doc/specifications/86box-unit-tester.md @@ -1,6 +1,51 @@ -# 86Box Unit Tester device specification +# 86Box Unit Tester device specification v1.0.0 -**TODO: DESCRIBE ME!** +By GreaseMonkey + other 86Box contributors, 2024. +This specification, including any code samples included, has been released into the Public Domain under the Creative Commons CC0 licence version 1.0 or later, as described here: + +The 86Box Unit Tester is a facility for allowing one to unit-test various parts of 86Box's emulation which would otherwise not be exposed to the emulated system. + +The original purpose of this was to make it possible to analyse and verify aspects of the monitor framebuffers in order to detect and prevent regressions in certain pieces of video hardware. + +---------------------------------------------------------------------------- + +## Versioning + +This specification follows the rules of Semantic Versioning 2.0.0 as documented here: + +The format is `major.minor.patch`. + +- Before you mess with this specification, talk to the other contributors first! +- Any changes need to be tracked in the Version History below, mostly in the event that this document escapes into the wild and doesn't have the Git history attached to it. +- If it clarifies something without introducing any behaviour changes (e.g. formatting changes, spelling fixes), increment the patch version. +- If it introduces a backwards-compatible change, increment the minor version and reset the patch version to 0. +- If it introduces a backwards-incompatible change, increment the major version and reset the minor and patch versions to 0. + - If you make a mistake and accidentally introduce a backward-incompatible change, fix the mistake and increment the minor version. + - To clarify, modifications to *this* section are to be classified as a *patch* version update. +- If you understand SemVer 2.0.0, you may also do other things to the version number according to the specification. + +And lastly, the 3 golden rules of protocol specifications: + +1. If it's not documented, it doesn't exist. +2. If it's not documented but somehow exists, it's a bug. +3. If it's a bug, it needs to be fixed. (Yes, I'm talking to you. You who introduced the bug. Go fix it.) + +The checklist: + +- Work out what kind of version number this document needs. +- Update the version number at the top of the file. +- Add an entry to the "Version History" section below describing roughly what was changed. + +---------------------------------------------------------------------------- + +## Version History + +Dates are based on what day it was in UTC at the time of publication. + +New entries are placed at the top. That is, immediately following this paragraph. + +### v1.0.0 (2024-01-08) +Initial release. Authored by GreaseMonkey. ---------------------------------------------------------------------------- @@ -12,7 +57,7 @@ - `u8` denotes an unsigned 8-bit value. - `w8` denotes an 8-bit value which wraps around. - `x8` denotes an 8-bit value where the signedness is irrelevant. -- `e8` ("either") denotes an 8-bit value where the most significant bit is clear - in effect, this is a 7-bit unsigned value. +- `e8` ("either") denotes an 8-bit value where the most significant bit is clear - in effect, this is a 7-bit unsigned value, and can be interepreted identically as a signed 8-bit value. - `u16L` denotes a little-endian unsigned 16-bit value. - `u16B` would denote a big-endian unsigned 16-bit value if we had any big-endian values. - `[N]T` denotes an array of `N` values of type `T`, whatever `N` and `T` are. @@ -201,12 +246,6 @@ FSM2: Once received, replace IOBASE with this byte in the high byte and the temporary value in the low byte, then go back to "Idle". -### Command processing state machine - -**TODO: IMPLEMENT ME!** - -**TODO: DOCUMENT ME!** - ---------------------------------------------------------------------------- ## Extending the protocol diff --git a/src/device/unittester.c b/src/device/unittester.c index 55bc270e9..047137752 100644 --- a/src/device/unittester.c +++ b/src/device/unittester.c @@ -8,6 +8,8 @@ * * Debug device for assisting in unit testing. * See doc/specifications/86box-unit-tester.md for more info. + * If modifying the protocol, you MUST modify the specification + * and increment the version number. * * * @@ -118,9 +120,6 @@ static bitmap_t *unittester_screen_buffer = NULL; /* FIXME: This needs a config option! --GM */ static bool unittester_exit_enabled = true; -/* FIXME TEMPORARY --GM */ -#define ENABLE_UNITTESTER_LOG 1 - #ifdef ENABLE_UNITTESTER_LOG int unittester_do_log = ENABLE_UNITTESTER_LOG; diff --git a/src/include/86box/unittester.h b/src/include/86box/unittester.h index f6dedeae5..e83add67f 100644 --- a/src/include/86box/unittester.h +++ b/src/include/86box/unittester.h @@ -8,6 +8,8 @@ * * Debug device for assisting in unit testing. * See doc/specifications/86box-unit-tester.md for more info. + * If modifying the protocol, you MUST modify the specification + * and increment the version number. * * * From 4648092b123bbafbdb484375ae45a77395d206ff Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Mon, 8 Jan 2024 12:59:02 +1300 Subject: [PATCH 229/936] unittester: Fix that one bug I wasn't going to fix I might as well not be a hypocrite here. --- src/device/unittester.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/device/unittester.c b/src/device/unittester.c index 047137752..ab948cb87 100644 --- a/src/device/unittester.c +++ b/src/device/unittester.c @@ -75,9 +75,9 @@ struct unittester_state { uint8_t status; enum unittester_cmd cmd_id; uint32_t write_offs; - uint32_t read_offs; uint32_t write_len; - uint32_t read_len; + uint64_t read_offs; + uint64_t read_len; /* Screen snapshot state */ /* Monitor to take snapshot on */ @@ -139,12 +139,12 @@ unittester_log(const char *fmt, ...) #endif static uint8_t -unittester_read_snap_rect_idx(uint32_t offs) +unittester_read_snap_rect_idx(uint64_t offs) { /* WARNING: If the width is somehow 0 and wasn't caught earlier, you'll probably get a divide by zero crash. */ uint32_t idx = (offs & 0x3); - int32_t x = (offs >> 2) % unittester.read_snap_width; - int32_t y = (offs >> 2) / unittester.read_snap_width; + int64_t x = (offs >> 2) % unittester.read_snap_width; + int64_t y = (offs >> 2) / unittester.read_snap_width; x += unittester.read_snap_xoffs; y += unittester.read_snap_yoffs; @@ -353,22 +353,18 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) /* Offset the X,Y offsets by the overscan offsets. */ unittester.read_snap_xoffs += (int16_t)unittester.snap_img_xoffs; unittester.read_snap_yoffs += (int16_t)unittester.snap_img_yoffs; - /*BUG: If the width and height are too large, this ends up with a multiplication overflow. - In practice, this means we end up sending less than we would want to. - However: - - A width and height of that size is obscene, and goes beyond what one would reasonably want. - - The consequences of triggering this bug are that one ends up with a bunch of FF FF FF FF pixels. - - Special-casing this would add unnecessary complexity. - So, this bug is kept here. - If there is any need to fix this bug... then go and make the variables 64-bit :P + /* NOTE: Width * Height * 4 can potentially exceed a 32-bit number. + So, we use 64-bit numbers instead. + In practice, this will only happen if someone decides to request e.g. a 65535 x 65535 image, + of which most of the pixels will be out of range anyway. */ - unittester.read_len = ((uint32_t)unittester.read_snap_width) * ((uint32_t)unittester.read_snap_height) * 4; + unittester.read_len = ((uint64_t)unittester.read_snap_width) * ((uint64_t)unittester.read_snap_height) * 4; unittester.read_snap_crc = 0xFFFFFFFF; if (unittester.cmd_id == UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE) { /* Read everything and compute CRC */ uint32_t crc = 0xFFFFFFFF; - for (uint32_t i = 0; i < unittester.read_len; i++) { + for (uint64_t i = 0; i < unittester.read_len; i++) { crc ^= 0xFF & (uint32_t)unittester_read_snap_rect_idx(i); /* Use some bit twiddling until we have a table-based fast CRC-32 implementation */ for (uint32_t j = 0; j < 8; j++) { From 5a2e3611d95468d9429c39c6e538edc03e8ee44b Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Mon, 8 Jan 2024 13:01:55 +1300 Subject: [PATCH 230/936] unittester: Apply clang-format --- src/device/unittester.c | 156 ++++++++++++++++----------------- src/include/86box/unittester.h | 1 - 2 files changed, 78 insertions(+), 79 deletions(-) diff --git a/src/device/unittester.c b/src/device/unittester.c index ab948cb87..f8f7fa56e 100644 --- a/src/device/unittester.c +++ b/src/device/unittester.c @@ -45,18 +45,18 @@ enum fsm2_value { }; /* Status bit mask */ -#define UT_STATUS_AWAITING_READ (1<<0) -#define UT_STATUS_AWAITING_WRITE (1<<1) -#define UT_STATUS_IDLE (1<<2) -#define UT_STATUS_UNSUPPORTED_CMD (1<<3) +#define UT_STATUS_AWAITING_READ (1 << 0) +#define UT_STATUS_AWAITING_WRITE (1 << 1) +#define UT_STATUS_IDLE (1 << 2) +#define UT_STATUS_UNSUPPORTED_CMD (1 << 3) /* Command list */ enum unittester_cmd { - UT_CMD_NOOP = 0x00, - UT_CMD_CAPTURE_SCREEN_SNAPSHOT = 0x01, - UT_CMD_READ_SCREEN_SNAPSHOT_RECTANGLE = 0x02, + UT_CMD_NOOP = 0x00, + UT_CMD_CAPTURE_SCREEN_SNAPSHOT = 0x01, + UT_CMD_READ_SCREEN_SNAPSHOT_RECTANGLE = 0x02, UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE = 0x03, - UT_CMD_EXIT = 0x04, + UT_CMD_EXIT = 0x04, }; struct unittester_state { @@ -81,7 +81,7 @@ struct unittester_state { /* Screen snapshot state */ /* Monitor to take snapshot on */ - uint8_t snap_monitor; + uint8_t snap_monitor; /* Main image width + height */ uint16_t snap_img_width; uint16_t snap_img_height; @@ -97,14 +97,14 @@ struct unittester_state { /* 0x03: Verify Screen Snapshot Rectangle */ uint16_t read_snap_width; uint16_t read_snap_height; - int16_t read_snap_xoffs; - int16_t read_snap_yoffs; + int16_t read_snap_xoffs; + int16_t read_snap_yoffs; uint32_t read_snap_crc; /* 0x04: Exit */ uint8_t exit_code; }; -static struct unittester_state unittester; +static struct unittester_state unittester; static const struct unittester_state unittester_defaults = { .trigger_port = 0x0080, .iobase_port = 0xFFFF, @@ -143,8 +143,8 @@ unittester_read_snap_rect_idx(uint64_t offs) { /* WARNING: If the width is somehow 0 and wasn't caught earlier, you'll probably get a divide by zero crash. */ uint32_t idx = (offs & 0x3); - int64_t x = (offs >> 2) % unittester.read_snap_width; - int64_t y = (offs >> 2) / unittester.read_snap_width; + int64_t x = (offs >> 2) % unittester.read_snap_width; + int64_t y = (offs >> 2) / unittester.read_snap_width; x += unittester.read_snap_xoffs; y += unittester.read_snap_yoffs; @@ -153,21 +153,21 @@ unittester_read_snap_rect_idx(uint64_t offs) return (idx == 3 ? 0xFF : 0x00); } else { /* In range */ - return (unittester_screen_buffer->line[y][x] & 0x00FFFFFF)>>(idx*8); + return (unittester_screen_buffer->line[y][x] & 0x00FFFFFF) >> (idx * 8); } } static void unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) { - if (port == unittester.iobase_port+0x00) { + if (port == unittester.iobase_port + 0x00) { /* Command port */ unittester_log("[UT] W %02X Command\n", val); unittester.write_offs = 0; - unittester.write_len = 0; - unittester.read_offs = 0; - unittester.read_len = 0; + unittester.write_len = 0; + unittester.read_offs = 0; + unittester.read_len = 0; switch (val) { /* 0x00: No-op */ @@ -178,29 +178,29 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) /* 0x01: Capture Screen Snapshot */ case UT_CMD_CAPTURE_SCREEN_SNAPSHOT: - unittester.cmd_id = UT_CMD_CAPTURE_SCREEN_SNAPSHOT; - unittester.status = UT_STATUS_AWAITING_WRITE; + unittester.cmd_id = UT_CMD_CAPTURE_SCREEN_SNAPSHOT; + unittester.status = UT_STATUS_AWAITING_WRITE; unittester.write_len = 1; break; /* 0x02: Read Screen Snapshot Rectangle */ case UT_CMD_READ_SCREEN_SNAPSHOT_RECTANGLE: - unittester.cmd_id = UT_CMD_READ_SCREEN_SNAPSHOT_RECTANGLE; - unittester.status = UT_STATUS_AWAITING_WRITE; + unittester.cmd_id = UT_CMD_READ_SCREEN_SNAPSHOT_RECTANGLE; + unittester.status = UT_STATUS_AWAITING_WRITE; unittester.write_len = 8; break; /* 0x03: Verify Screen Snapshot Rectangle */ case UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE: - unittester.cmd_id = UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE; - unittester.status = UT_STATUS_AWAITING_WRITE; + unittester.cmd_id = UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE; + unittester.status = UT_STATUS_AWAITING_WRITE; unittester.write_len = 8; break; /* 0x04: Exit */ case UT_CMD_EXIT: - unittester.cmd_id = UT_CMD_EXIT; - unittester.status = UT_STATUS_AWAITING_WRITE; + unittester.cmd_id = UT_CMD_EXIT; + unittester.status = UT_STATUS_AWAITING_WRITE; unittester.write_len = 1; break; @@ -211,7 +211,7 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) break; } - } else if (port == unittester.iobase_port+0x01) { + } else if (port == unittester.iobase_port + 0x01) { /* Data port */ unittester_log("[UT] W %02X Data\n", val); @@ -221,7 +221,7 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) switch (unittester.cmd_id) { case UT_CMD_EXIT: - switch(unittester.write_offs) { + switch (unittester.write_offs) { case 0: unittester.exit_code = val; break; @@ -231,7 +231,7 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) break; case UT_CMD_CAPTURE_SCREEN_SNAPSHOT: - switch(unittester.write_offs) { + switch (unittester.write_offs) { case 0: unittester.snap_monitor = val; break; @@ -242,30 +242,30 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) case UT_CMD_READ_SCREEN_SNAPSHOT_RECTANGLE: case UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE: - switch(unittester.write_offs) { + switch (unittester.write_offs) { case 0: - unittester.read_snap_width = (uint16_t)val; + unittester.read_snap_width = (uint16_t) val; break; case 1: - unittester.read_snap_width |= ((uint16_t)val) << 8; + unittester.read_snap_width |= ((uint16_t) val) << 8; break; case 2: - unittester.read_snap_height = (uint16_t)val; + unittester.read_snap_height = (uint16_t) val; break; case 3: - unittester.read_snap_height |= ((uint16_t)val) << 8; + unittester.read_snap_height |= ((uint16_t) val) << 8; break; case 4: - unittester.read_snap_xoffs = (uint16_t)val; + unittester.read_snap_xoffs = (uint16_t) val; break; case 5: - unittester.read_snap_xoffs |= ((uint16_t)val) << 8; + unittester.read_snap_xoffs |= ((uint16_t) val) << 8; break; case 6: - unittester.read_snap_yoffs = (uint16_t)val; + unittester.read_snap_yoffs = (uint16_t) val; break; case 7: - unittester.read_snap_yoffs |= ((uint16_t)val) << 8; + unittester.read_snap_yoffs |= ((uint16_t) val) << 8; break; default: break; @@ -307,11 +307,11 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) case UT_CMD_CAPTURE_SCREEN_SNAPSHOT: /* Recompute screen */ - unittester.snap_img_width = 0; - unittester.snap_img_height = 0; - unittester.snap_img_xoffs = 0; - unittester.snap_img_yoffs = 0; - unittester.snap_overscan_width = 0; + unittester.snap_img_width = 0; + unittester.snap_img_height = 0; + unittester.snap_img_xoffs = 0; + unittester.snap_img_yoffs = 0; + unittester.snap_overscan_width = 0; unittester.snap_overscan_height = 0; if (unittester.snap_monitor < 0x01 || (unittester.snap_monitor - 1) > MONITORS_NUM) { /* No monitor here - clear snapshot */ @@ -321,13 +321,13 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) unittester.snap_monitor = 0x00; } else { /* Compute bounds for snapshot */ - const monitor_t *m = &monitors[unittester.snap_monitor - 1]; - unittester.snap_img_width = m->mon_xsize; - unittester.snap_img_height = m->mon_ysize; - unittester.snap_overscan_width = m->mon_xsize + m->mon_overscan_x; + const monitor_t *m = &monitors[unittester.snap_monitor - 1]; + unittester.snap_img_width = m->mon_xsize; + unittester.snap_img_height = m->mon_ysize; + unittester.snap_overscan_width = m->mon_xsize + m->mon_overscan_x; unittester.snap_overscan_height = m->mon_ysize + m->mon_overscan_y; - unittester.snap_img_xoffs = (m->mon_overscan_x >> 1); - unittester.snap_img_yoffs = (m->mon_overscan_y >> 1); + unittester.snap_img_xoffs = (m->mon_overscan_x >> 1); + unittester.snap_img_yoffs = (m->mon_overscan_y >> 1); /* Take snapshot */ for (size_t y = 0; y < unittester.snap_overscan_height; y++) { for (size_t x = 0; x < unittester.snap_overscan_width; x++) { @@ -344,38 +344,38 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) unittester.snap_img_yoffs, unittester.snap_overscan_width, unittester.snap_overscan_height); - unittester.status = UT_STATUS_AWAITING_READ; + unittester.status = UT_STATUS_AWAITING_READ; unittester.read_len = 12; break; case UT_CMD_READ_SCREEN_SNAPSHOT_RECTANGLE: case UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE: /* Offset the X,Y offsets by the overscan offsets. */ - unittester.read_snap_xoffs += (int16_t)unittester.snap_img_xoffs; - unittester.read_snap_yoffs += (int16_t)unittester.snap_img_yoffs; + unittester.read_snap_xoffs += (int16_t) unittester.snap_img_xoffs; + unittester.read_snap_yoffs += (int16_t) unittester.snap_img_yoffs; /* NOTE: Width * Height * 4 can potentially exceed a 32-bit number. So, we use 64-bit numbers instead. In practice, this will only happen if someone decides to request e.g. a 65535 x 65535 image, of which most of the pixels will be out of range anyway. */ - unittester.read_len = ((uint64_t)unittester.read_snap_width) * ((uint64_t)unittester.read_snap_height) * 4; + unittester.read_len = ((uint64_t) unittester.read_snap_width) * ((uint64_t) unittester.read_snap_height) * 4; unittester.read_snap_crc = 0xFFFFFFFF; if (unittester.cmd_id == UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE) { /* Read everything and compute CRC */ uint32_t crc = 0xFFFFFFFF; for (uint64_t i = 0; i < unittester.read_len; i++) { - crc ^= 0xFF & (uint32_t)unittester_read_snap_rect_idx(i); + crc ^= 0xFF & (uint32_t) unittester_read_snap_rect_idx(i); /* Use some bit twiddling until we have a table-based fast CRC-32 implementation */ for (uint32_t j = 0; j < 8; j++) { - crc = (crc >> 1) ^ ((-(crc&0x1)) & 0xEDB88320); + crc = (crc >> 1) ^ ((-(crc & 0x1)) & 0xEDB88320); } } unittester.read_snap_crc = crc ^ 0xFFFFFFFF; /* Set actual read length for CRC result */ unittester.read_len = 4; - unittester.status = UT_STATUS_AWAITING_READ; + unittester.status = UT_STATUS_AWAITING_READ; } else { /* Do we have anything to read? */ @@ -408,11 +408,11 @@ unittester_read(uint16_t port, UNUSED(void *priv)) { uint8_t outval = 0xFF; - if (port == unittester.iobase_port+0x00) { + if (port == unittester.iobase_port + 0x00) { /* Status port */ unittester_log("[UT] R -- Status = %02X\n", unittester.status); return unittester.status; - } else if (port == unittester.iobase_port+0x01) { + } else if (port == unittester.iobase_port + 0x01) { /* Data port */ /* unittester_log("[UT] R -- Data\n"); */ @@ -422,42 +422,42 @@ unittester_read(uint16_t port, UNUSED(void *priv)) switch (unittester.cmd_id) { case UT_CMD_CAPTURE_SCREEN_SNAPSHOT: - switch(unittester.read_offs) { + switch (unittester.read_offs) { case 0: - outval = (uint8_t)(unittester.snap_img_width); + outval = (uint8_t) (unittester.snap_img_width); break; case 1: - outval = (uint8_t)(unittester.snap_img_width>>8); + outval = (uint8_t) (unittester.snap_img_width >> 8); break; case 2: - outval = (uint8_t)(unittester.snap_img_height); + outval = (uint8_t) (unittester.snap_img_height); break; case 3: - outval = (uint8_t)(unittester.snap_img_height>>8); + outval = (uint8_t) (unittester.snap_img_height >> 8); break; case 4: - outval = (uint8_t)(unittester.snap_overscan_width); + outval = (uint8_t) (unittester.snap_overscan_width); break; case 5: - outval = (uint8_t)(unittester.snap_overscan_width>>8); + outval = (uint8_t) (unittester.snap_overscan_width >> 8); break; case 6: - outval = (uint8_t)(unittester.snap_overscan_height); + outval = (uint8_t) (unittester.snap_overscan_height); break; case 7: - outval = (uint8_t)(unittester.snap_overscan_height>>8); + outval = (uint8_t) (unittester.snap_overscan_height >> 8); break; case 8: - outval = (uint8_t)(unittester.snap_img_xoffs); + outval = (uint8_t) (unittester.snap_img_xoffs); break; case 9: - outval = (uint8_t)(unittester.snap_img_xoffs>>8); + outval = (uint8_t) (unittester.snap_img_xoffs >> 8); break; case 10: - outval = (uint8_t)(unittester.snap_img_yoffs); + outval = (uint8_t) (unittester.snap_img_yoffs); break; case 11: - outval = (uint8_t)(unittester.snap_img_yoffs>>8); + outval = (uint8_t) (unittester.snap_img_yoffs >> 8); break; default: break; @@ -469,7 +469,7 @@ unittester_read(uint16_t port, UNUSED(void *priv)) break; case UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE: - outval = (uint8_t)(unittester.read_snap_crc >> (8*unittester.read_offs)); + outval = (uint8_t) (unittester.read_snap_crc >> (8 * unittester.read_offs)); break; /* This should not be reachable, but just in case... */ @@ -507,13 +507,13 @@ unittester_trigger_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv)) /* WAIT IOBASE 0: Set low byte of temporary IOBASE. */ case UT_FSM2_WAIT_IOBASE_0: - unittester.fsm2_new_iobase = ((uint16_t)val); - unittester.fsm2 = UT_FSM2_WAIT_IOBASE_1; + unittester.fsm2_new_iobase = ((uint16_t) val); + unittester.fsm2 = UT_FSM2_WAIT_IOBASE_1; break; /* WAIT IOBASE 0: Set high byte of temporary IOBASE and commit to the real IOBASE. */ case UT_FSM2_WAIT_IOBASE_1: - unittester.fsm2_new_iobase |= ((uint16_t)val)<<8; + unittester.fsm2_new_iobase |= ((uint16_t) val) << 8; unittester_log("[UT] Remapping IOBASE: %04X -> %04X\n", unittester.iobase_port, unittester.fsm2_new_iobase); @@ -575,12 +575,12 @@ unittester_init(UNUSED(const device_t *info)) if (unittester_screen_buffer == NULL) unittester_screen_buffer = create_bitmap(2048, 2048); - unittester = (struct unittester_state)unittester_defaults; + unittester = (struct unittester_state) unittester_defaults; io_sethandler(unittester.trigger_port, 1, NULL, NULL, NULL, unittester_trigger_write, NULL, NULL, NULL); unittester_log("[UT] 86Box Unit Tester initialised\n"); - return &unittester; /* Dummy non-NULL value */ + return &unittester; /* Dummy non-NULL value */ } static void diff --git a/src/include/86box/unittester.h b/src/include/86box/unittester.h index e83add67f..00abed3ff 100644 --- a/src/include/86box/unittester.h +++ b/src/include/86box/unittester.h @@ -35,4 +35,3 @@ extern const device_t unittester_device; #endif #endif /*UNITTESTER_H*/ - From 276e43428e11a869b53a2792df822a5e0191c7c0 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Mon, 8 Jan 2024 13:48:33 +1300 Subject: [PATCH 231/936] Allow one to enable/disable unit tester exit Memo to self: Hardware renderers often exit in a silent segfault. Look into this at some point. --- src/device/unittester.c | 17 ++++++++++++++--- src/qt/qt_settingsotherperipherals.cpp | 7 +++++++ src/qt/qt_settingsotherperipherals.hpp | 1 + src/qt/qt_settingsotherperipherals.ui | 19 ++++++++++++++++++- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/device/unittester.c b/src/device/unittester.c index f8f7fa56e..0442d0695 100644 --- a/src/device/unittester.c +++ b/src/device/unittester.c @@ -114,10 +114,18 @@ static const struct unittester_state unittester_defaults = { .cmd_id = UT_CMD_NOOP, }; +static const device_config_t unittester_config[] = { + { .name = "exit_enabled", + .description = "Enable 0x04 \"Exit 86Box\" command", + .type = CONFIG_BINARY, + .default_int = 1, + .default_string = "" }, + { .type = CONFIG_END } +}; + /* Kept separate, as we will be reusing this object */ static bitmap_t *unittester_screen_buffer = NULL; -/* FIXME: This needs a config option! --GM */ static bool unittester_exit_enabled = true; #ifdef ENABLE_UNITTESTER_LOG @@ -572,10 +580,13 @@ unittester_trigger_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv)) static void * unittester_init(UNUSED(const device_t *info)) { + unittester = (struct unittester_state) unittester_defaults; + + unittester_exit_enabled = !!device_get_config_int("exit_enabled"); + if (unittester_screen_buffer == NULL) unittester_screen_buffer = create_bitmap(2048, 2048); - unittester = (struct unittester_state) unittester_defaults; io_sethandler(unittester.trigger_port, 1, NULL, NULL, NULL, unittester_trigger_write, NULL, NULL, NULL); unittester_log("[UT] 86Box Unit Tester initialised\n"); @@ -611,5 +622,5 @@ const device_t unittester_device = { { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, - .config = NULL + .config = unittester_config, }; diff --git a/src/qt/qt_settingsotherperipherals.cpp b/src/qt/qt_settingsotherperipherals.cpp index ad7a00bb4..beb484848 100644 --- a/src/qt/qt_settingsotherperipherals.cpp +++ b/src/qt/qt_settingsotherperipherals.cpp @@ -23,6 +23,7 @@ extern "C" { #include <86box/machine.h> #include <86box/isamem.h> #include <86box/isartc.h> +#include <86box/unittester.h> } #include "qt_deviceconfig.hpp" @@ -199,3 +200,9 @@ SettingsOtherPeripherals::on_pushButtonConfigureCard4_clicked() { DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard4->currentData().toInt()), 4, qobject_cast(Settings::settings)); } + +void +SettingsOtherPeripherals::on_pushButtonConfigureUT_clicked() +{ + DeviceConfig::ConfigureDevice(&unittester_device); +} diff --git a/src/qt/qt_settingsotherperipherals.hpp b/src/qt/qt_settingsotherperipherals.hpp index 97e47c90e..b521e7829 100644 --- a/src/qt/qt_settingsotherperipherals.hpp +++ b/src/qt/qt_settingsotherperipherals.hpp @@ -30,6 +30,7 @@ private slots: void on_comboBoxCard1_currentIndexChanged(int index); void on_pushButtonConfigureRTC_clicked(); void on_comboBoxRTC_currentIndexChanged(int index); + void on_pushButtonConfigureUT_clicked(); private: Ui::SettingsOtherPeripherals *ui; diff --git a/src/qt/qt_settingsotherperipherals.ui b/src/qt/qt_settingsotherperipherals.ui index 481d80ebe..af953a984 100644 --- a/src/qt/qt_settingsotherperipherals.ui +++ b/src/qt/qt_settingsotherperipherals.ui @@ -190,10 +190,27 @@ + + + + - 86Box unit tester + 86Box Unit Tester + + + + 0 + 0 + + + + + + + + Configure From 9448fc044f28e12c762ff6b50d2f89fc78ed361f Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Mon, 8 Jan 2024 13:53:13 +1300 Subject: [PATCH 232/936] Enable and disable "configure" button for unit tester Now ready for review! --- src/qt/qt_settingsotherperipherals.cpp | 7 +++++++ src/qt/qt_settingsotherperipherals.hpp | 1 + 2 files changed, 8 insertions(+) diff --git a/src/qt/qt_settingsotherperipherals.cpp b/src/qt/qt_settingsotherperipherals.cpp index beb484848..f662b644c 100644 --- a/src/qt/qt_settingsotherperipherals.cpp +++ b/src/qt/qt_settingsotherperipherals.cpp @@ -47,6 +47,7 @@ SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) ui->checkBoxPOSTCard->setChecked(postcard_enabled > 0 ? true : false); ui->checkBoxUnitTester->setChecked(unittester_enabled > 0 ? true : false); ui->checkBoxISABugger->setEnabled(machineHasIsa); + ui->pushButtonConfigureUT->setEnabled(unittester_enabled > 0); ui->comboBoxRTC->setEnabled(machineHasIsa); ui->pushButtonConfigureRTC->setEnabled(machineHasIsa); @@ -201,6 +202,12 @@ SettingsOtherPeripherals::on_pushButtonConfigureCard4_clicked() DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard4->currentData().toInt()), 4, qobject_cast(Settings::settings)); } +void +SettingsOtherPeripherals::on_checkBoxUnitTester_stateChanged(int arg1) +{ + ui->pushButtonConfigureUT->setEnabled(arg1 != 0); +} + void SettingsOtherPeripherals::on_pushButtonConfigureUT_clicked() { diff --git a/src/qt/qt_settingsotherperipherals.hpp b/src/qt/qt_settingsotherperipherals.hpp index b521e7829..feaa7a001 100644 --- a/src/qt/qt_settingsotherperipherals.hpp +++ b/src/qt/qt_settingsotherperipherals.hpp @@ -30,6 +30,7 @@ private slots: void on_comboBoxCard1_currentIndexChanged(int index); void on_pushButtonConfigureRTC_clicked(); void on_comboBoxRTC_currentIndexChanged(int index); + void on_checkBoxUnitTester_stateChanged(int arg1); void on_pushButtonConfigureUT_clicked(); private: From 215c507634d288a438e2335e4912568452067da7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 8 Jan 2024 02:35:03 +0100 Subject: [PATCH 233/936] Soft reset on IDE device 1 causes the assertion of PDIAG- which causes the error register of device 0 to also be set to 1, indicating diagnostics passed successfully (+ a PIIX3 fix), fixes #4002. --- src/chipset/intel_piix.c | 6 ++++++ src/disk/hdc_ide.c | 6 +++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index 70035f6df..49d720d8b 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -597,6 +597,12 @@ piix_write(int func, int addr, uint8_t val, void *priv) pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), PCI_IRQ_DISABLED); else pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf); + if (dev->type == 3) { + if (val & 0x20) + sff_set_irq_mode(dev->bm[1], IRQ_MODE_MIRQ_0); + else + sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); + } piix_log("MIRQ%i is %s\n", addr & 0x01, (val & 0x20) ? "disabled" : "enabled"); } break; diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 522f1ee66..4041b9ff6 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -1397,6 +1397,7 @@ ide_write_devctl(UNUSED(uint16_t addr), uint8_t val, void *priv) } else ide->tf->atastat = DRDY_STAT | DSC_STAT; ide->tf->error = 1; + ide_other->tf->error = 1; /* Assert PDIAG-. */ dev->cur_dev &= ~1; ch = dev->cur_dev; @@ -1410,7 +1411,8 @@ ide_write_devctl(UNUSED(uint16_t addr), uint8_t val, void *priv) old = dev->devctl; dev->devctl = val; - if (!(val & 0x02) && (old & 0x02)) + // if (!(val & 0x02) && (old & 0x02)) + if ((old ^ val) & 0x02) ide_irq_update(ide_boards[ide->board], 1); } @@ -1566,6 +1568,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) if ((ide->type == IDE_NONE) || ((ide->type & IDE_SHADOW) && (val != WIN_DRIVE_DIAGNOSTICS))) break; + pclog("IRQ lower\n"); ide_irq_lower(ide); ide->command = val; @@ -2459,6 +2462,7 @@ ide_callback(void *priv) else { ide->blocksize = ide->tf->secount; ide->tf->atastat = DRDY_STAT | DSC_STAT; + pclog("IRQ raise\n"); ide_irq_raise(ide); } break; From 7f92d71bf1810023325d5104b4741a73ab5b1308 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 8 Jan 2024 02:40:45 +0100 Subject: [PATCH 234/936] Removed some accidentally excess logging from disk/hdc_ide.c. --- src/disk/hdc_ide.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 4041b9ff6..06aa87395 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -1568,7 +1568,6 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) if ((ide->type == IDE_NONE) || ((ide->type & IDE_SHADOW) && (val != WIN_DRIVE_DIAGNOSTICS))) break; - pclog("IRQ lower\n"); ide_irq_lower(ide); ide->command = val; @@ -2462,7 +2461,7 @@ ide_callback(void *priv) else { ide->blocksize = ide->tf->secount; ide->tf->atastat = DRDY_STAT | DSC_STAT; - pclog("IRQ raise\n"); + ide_irq_raise(ide); } break; From 1e5aa1352998d919c735af97b533e40dcba355c2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 8 Jan 2024 13:23:48 +0100 Subject: [PATCH 235/936] Default the previous pixel to black if prev < 0. --- src/video/vid_cga.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index 07a8dfcdb..f61b85e10 100644 --- a/src/video/vid_cga.c +++ b/src/video/vid_cga.c @@ -447,7 +447,10 @@ cga_interpolate(cga_t *cga, int x, int y, int w, int h) black.color = 0x00000000; - prev_color.color = buffer32->line[prev][j]; + if (prev >= 0) + prev_color.color = buffer32->line[prev][j]; + else + prev_color.color = 0x00000000; if (next < (y + h)) next_color.color = buffer32->line[next][j]; From 39258ecdeb042cc30120f8043e602e6b7c046c71 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 8 Jan 2024 13:27:24 +0100 Subject: [PATCH 236/936] And added even more sanity checks. --- src/video/vid_cga.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index f61b85e10..2ba4323f3 100644 --- a/src/video/vid_cga.c +++ b/src/video/vid_cga.c @@ -445,14 +445,17 @@ cga_interpolate(cga_t *cga, int x, int y, int w, int h) color_t interim_1, interim_2; color_t final; + if (i < 0) + continue; + black.color = 0x00000000; - if (prev >= 0) + if ((prev >= 0) && (prev < (y + h))) prev_color.color = buffer32->line[prev][j]; else prev_color.color = 0x00000000; - if (next < (y + h)) + if ((next >= 0) && (next < (y + h))) next_color.color = buffer32->line[next][j]; else next_color.color = 0x00000000; From 3a62aa4ea760334edab4329f6a8e49600e4708f7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 8 Jan 2024 22:27:09 +0100 Subject: [PATCH 237/936] First batch of Acer A1G fixes, fixes #3992. --- src/86box.c | 4 + src/disk/hdc_ide.c | 16 +++ src/include/86box/hdc_ide.h | 2 + src/include/86box/sio.h | 1 + src/machine/m_at_386dx_486.c | 5 +- src/sio/sio_pc87310.c | 252 +++++++++++++++++++++-------------- 6 files changed, 178 insertions(+), 102 deletions(-) diff --git a/src/86box.c b/src/86box.c index 220d38dfa..f72b066a5 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1231,6 +1231,10 @@ pc_reset_hard_init(void) device_reset_all(DEVICE_PCI); } + /* Mark IDE shadow drives (slaves with a present master) as such in case + the IDE controllers present are not some form of PCI. */ + ide_drives_set_shadow(); + /* Reset the CPU module. */ resetx86(); dma_reset(); diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 06aa87395..299c5c487 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -2977,6 +2977,22 @@ ide_board_reset(int board) ide_drive_reset(d); } +void +ide_drives_set_shadow(void) +{ + for (uint8_t d = 0; d < IDE_NUM; d++) { + if (ide_drives[d] == NULL) + continue; + + if ((d & 1) && (ide_drives[d]->type == IDE_NONE) && (ide_drives[d ^ 1]->type != IDE_NONE)) { + ide_drives[d]->type = ide_drives[d ^ 1]->type | IDE_SHADOW; + if (ide_drives[d]->tf != NULL) + free(ide_drives[d]->tf); + ide_drives[d]->tf = ide_drives[d ^ 1]->tf; + } + } +} + /* Reset a standalone IDE unit. */ static void ide_reset(UNUSED(void *priv)) diff --git a/src/include/86box/hdc_ide.h b/src/include/86box/hdc_ide.h index 291dec303..1f7a78c9f 100644 --- a/src/include/86box/hdc_ide.h +++ b/src/include/86box/hdc_ide.h @@ -188,6 +188,8 @@ extern void ide_atapi_attach(ide_t *dev); extern void *ide_xtide_init(void); extern void ide_xtide_close(void); +extern void ide_drives_set_shadow(void); + extern void ide_writew(uint16_t addr, uint16_t val, void *priv); extern void ide_write_devctl(uint16_t addr, uint8_t val, void *priv); extern void ide_writeb(uint16_t addr, uint8_t val, void *priv); diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index 6ec9eceb9..0f74d899f 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -19,6 +19,7 @@ extern void vt82c686_sio_write(uint8_t addr, uint8_t val, void *priv); extern const device_t acc3221_device; +extern const device_t ali5105_device; extern const device_t ali5123_device; extern const device_t f82c710_device; extern const device_t f82c606_device; diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 10f82e4ed..a695073e2 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -381,10 +381,9 @@ machine_at_acera1g_init(const machine_t *model) device_add(&gd5428_onboard_device); device_add(&keyboard_ps2_acer_pci_device); - device_add(&ide_isa_2ch_device); + device_add(&ide_vlb_2ch_device); - if (fdc_type == FDC_INTERNAL) - device_add(&fdc_at_device); + device_add(&ali5105_device); return ret; } diff --git a/src/sio/sio_pc87310.c b/src/sio/sio_pc87310.c index d567bd4d5..f9626214c 100644 --- a/src/sio/sio_pc87310.c +++ b/src/sio/sio_pc87310.c @@ -8,15 +8,13 @@ * * Emulation of the NatSemi PC87310 Super I/O chip. * - * - * * Authors: Miran Grca, - * Tiseno100 - * EngiNerd + * EngiNerd, + * Tiseno100, * - * Copyright 2020 Miran Grca. - * Copyright 2020 Tiseno100 + * Copyright 2020-2024 Miran Grca. * Copyright 2021 EngiNerd. + * Copyright 2020 Tiseno100. */ #include #include @@ -42,7 +40,8 @@ #include <86box/sio.h> #include <86box/plat_unused.h> -#define HAS_IDE_FUNCTIONALITY dev->ide_function +#define FLAG_IDE 0x00000001 +#define FLAG_ALI 0x00000002 #ifdef ENABLE_PC87310_LOG int pc87310_do_log = ENABLE_PC87310_LOG; @@ -64,8 +63,8 @@ pc87310_log(const char *fmt, ...) typedef struct pc87310_t { uint8_t tries; - uint8_t ide_function; - uint8_t reg; + uint8_t flags; + uint8_t regs[2]; fdc_t *fdc; serial_t *uart[2]; } pc87310_t; @@ -83,7 +82,9 @@ lpt1_handler(pc87310_t *dev) * 10 278h * 11 disabled */ - temp = dev->reg & 3; + temp = dev->regs[1] & 0x03; + + lpt1_remove(); switch (temp) { case 0: @@ -111,23 +112,59 @@ lpt1_handler(pc87310_t *dev) } static void -serial_handler(pc87310_t *dev, int uart) +serial_handler(pc87310_t *dev) { - int temp; - /* bit 2: disable serial port 1 - * bit 3: disable serial port 2 - * bit 4: swap serial ports + uint8_t temp, temp2 = 0x00; + uint16_t base1 = 0x0000, base2 = 0x0000; + uint8_t irq1, irq2; + /* - Bit 2: Disable serial port 1; + * - Bit 3: Disable serial port 2; + * - Bit 4: Swap serial ports. */ - temp = (dev->reg >> (2 + uart)) & 1; + temp = (dev->regs[1] >> 2) & 0x07; - // current serial port is enabled - if (!temp) { - // configure serial port as COM2 - if (((dev->reg >> 4) & 1) ^ uart) - serial_setup(dev->uart[uart], COM2_ADDR, COM2_IRQ); - // configure serial port as COM1 - else - serial_setup(dev->uart[uart], COM1_ADDR, COM1_IRQ); + /* - Bits 1, 0: 0, 0 = Normal (3F8 and 2F8); + * 0, 1 = 2E8 instead of 2F8; + * 1, 0 = 3E8 instead of 3F8 and 2E8 instead of 2F8; + * 1, 1 = 3E8 instead of 3F8. + * + * If we XOR bit 0 with bit 1, we get this: + * 0, 0 = Normal (3F8 and 2F8); + * 0, 1 = 2E8 instead of 2F8; + * 1, 0 = 3E8 instead of 3F8; + * 1, 1 = 3E8 instead of 3F8 and 2E8 instead of 2F8. + * + * Then they become simple toggle bits. + * Therefore, we do this for easier operation. + */ + if (dev->flags & FLAG_ALI) { + temp2 = dev->regs[0] & 0x03; + temp2 ^= ((temp2 & 0x02) >> 1); + } + + serial_remove(dev->uart[0]); + serial_remove(dev->uart[1]); + + if (!(temp & 0x01)) { + base1 = (temp & 0x04) ? COM2_ADDR : COM1_ADDR; + if ((base1 == COM1_ADDR) && (temp2 & 0x02)) + base1 = 0x03e8; + else if ((base1 == COM2_ADDR) && (temp2 & 0x01)) + base1 = 0x02e8; + irq1 = (temp & 0x04) ? COM2_IRQ : COM1_IRQ; + serial_setup(dev->uart[0], base1, irq1); + pc87310_log("UART 1 at %04X, IRQ %i\n", base1, irq1); + } + + if (!(temp & 0x02)) { + base2 = (temp & 0x04) ? COM1_ADDR : COM2_ADDR; + if ((base2 == COM1_ADDR) && (temp2 & 0x02)) + base2 = 0x03e8; + else if ((base2 == COM2_ADDR) && (temp2 & 0x01)) + base2 = 0x02e8; + irq2 = (temp & 0x04) ? COM1_IRQ : COM2_IRQ; + serial_setup(dev->uart[1], base2, irq2); + pc87310_log("UART 2 at %04X, IRQ %i\n", base2, irq2); } } @@ -136,61 +173,63 @@ pc87310_write(UNUSED(uint16_t port), uint8_t val, void *priv) { pc87310_t *dev = (pc87310_t *) priv; uint8_t valxor; + uint8_t idx = (uint8_t) ((port & 0x0002) >> 1); + + pc87310_log("[%04X:%08X] [W] %02X = %02X (%i)\n", CS, cpu_state.pc, port, val, dev->tries); - // second write to config register if (dev->tries) { - valxor = val ^ dev->reg; - dev->tries = 0; - dev->reg = val; - // first write to config register - } else { + /* Second write to config register. */ + valxor = val ^ dev->regs[idx]; + dev->tries = 0; + dev->regs[idx] = val; + + if (idx) { + /* Register, common to both PC87310 and ALi M5105. */ + pc87310_log("SIO: Common register written %02X\n", val); + + /* Reconfigure parallel port. */ + if (valxor & 0x03) + /* Bits 1, 0: 1, 1 = Disable parallel port. */ + lpt1_handler(dev); + + /* Reconfigure serial ports. */ + if (valxor & 0x1c) + serial_handler(dev); + + /* Reconfigure IDE controller. */ + if ((dev->flags & FLAG_IDE) && (valxor & 0x20)) { + pc87310_log("SIO: HDC disabled\n"); + ide_pri_disable(); + /* Bit 5: 1 = Disable IDE controller. */ + if (!(val & 0x20)) { + pc87310_log("SIO: HDC enabled\n"); + ide_set_base(0, 0x1f0); + ide_set_side(0, 0x3f6); + ide_pri_enable(); + } + } + + /* Reconfigure floppy disk controller. */ + if (valxor & 0x40) { + pc87310_log("SIO: FDC disabled\n"); + fdc_remove(dev->fdc); + /* Bit 6: 1 = Disable FDC. */ + if (!(val & 0x40)) { + pc87310_log("SIO: FDC enabled\n"); + fdc_set_base(dev->fdc, FDC_PRIMARY_ADDR); + } + } + } else { + /* ALi M5105 extension register. */ + pc87310_log("SIO: M5105 extension register written %02X\n", val); + + /* Reconfigure serial ports. */ + if (valxor & 0x03) + serial_handler(dev); + } + } else + /* First write to config register. */ dev->tries++; - return; - } - - pc87310_log("SIO: written %01X\n", val); - - /* reconfigure parallel port */ - if (valxor & 0x03) { - lpt1_remove(); - /* bits 0-1: 11 disable parallel port */ - if (!((val & 1) && (val & 2))) - lpt1_handler(dev); - } - /* reconfigure serial ports */ - if (valxor & 0x1c) { - serial_remove(dev->uart[0]); - serial_remove(dev->uart[1]); - /* bit 2: 1 disable first serial port */ - if (!(val & 4)) - serial_handler(dev, 0); - /* bit 3: 1 disable second serial port */ - if (!(val & 8)) - serial_handler(dev, 1); - } - /* reconfigure IDE controller */ - if (valxor & 0x20) { - pc87310_log("SIO: HDC disabled\n"); - ide_pri_disable(); - /* bit 5: 1 disable ide controller */ - if (!(val & 0x20) && HAS_IDE_FUNCTIONALITY) { - pc87310_log("SIO: HDC enabled\n"); - ide_set_base(0, 0x1f0); - ide_set_side(0, 0x3f6); - ide_pri_enable(); - } - } - /* reconfigure floppy disk controller */ - if (valxor & 0x40) { - pc87310_log("SIO: FDC disabled\n"); - fdc_remove(dev->fdc); - /* bit 6: 1 disable fdc */ - if (!(val & 0x40)) { - pc87310_log("SIO: FDC enabled\n"); - fdc_set_base(dev->fdc, FDC_PRIMARY_ADDR); - } - } - return; } uint8_t @@ -198,11 +237,13 @@ pc87310_read(UNUSED(uint16_t port), void *priv) { pc87310_t *dev = (pc87310_t *) priv; uint8_t ret = 0xff; + uint8_t idx = (uint8_t) ((port & 0x0002) >> 1); dev->tries = 0; - ret = dev->reg; + ret = dev->regs[idx]; + pc87310_log("[%04X:%08X] [R] %02X = %02X\n", CS, cpu_state.pc, port, ret); pc87310_log("SIO: read %01X\n", ret); return ret; @@ -211,22 +252,18 @@ pc87310_read(UNUSED(uint16_t port), void *priv) void pc87310_reset(pc87310_t *dev) { - dev->reg = 0x0; - dev->tries = 0; - /* - 0 = 360 rpm @ 500 kbps for 3.5" - 1 = Default, 300 rpm @ 500, 300, 250, 1000 kbps for 3.5" - */ - lpt1_remove(); + dev->regs[0] = 0x00; + dev->regs[1] = 0x00; + + dev->tries = 0; + lpt1_handler(dev); - serial_remove(dev->uart[0]); - serial_remove(dev->uart[1]); - serial_handler(dev, 0); - serial_handler(dev, 1); + serial_handler(dev); + if (dev->flags & FLAG_IDE) { + ide_pri_disable(); + ide_pri_enable(); + } fdc_reset(dev->fdc); -#if 0 - ide_pri_enable(); -#endif } static void @@ -240,25 +277,28 @@ pc87310_close(void *priv) static void * pc87310_init(const device_t *info) { - pc87310_t *dev = (pc87310_t *) malloc(sizeof(pc87310_t)); - memset(dev, 0, sizeof(pc87310_t)); + pc87310_t *dev = (pc87310_t *) calloc(1, sizeof(pc87310_t)); /* Avoid conflicting with machines that make no use of the PC87310 Internal IDE */ - HAS_IDE_FUNCTIONALITY = info->local; + dev->flags = info->local; dev->fdc = device_add(&fdc_at_nsc_device); - dev->uart[0] = device_add_inst(&ns16550_device, 1); - dev->uart[1] = device_add_inst(&ns16550_device, 2); + dev->uart[0] = device_add_inst(&ns16450_device, 1); + dev->uart[1] = device_add_inst(&ns16450_device, 2); - if (HAS_IDE_FUNCTIONALITY) - device_add(&ide_isa_device); + if (dev->flags & FLAG_IDE) + device_add((dev->flags & FLAG_ALI) ? &ide_vlb_device : &ide_isa_device); pc87310_reset(dev); io_sethandler(0x3f3, 0x0001, pc87310_read, NULL, NULL, pc87310_write, NULL, NULL, dev); + if (dev->flags & FLAG_ALI) + io_sethandler(0x3f1, 0x0001, + pc87310_read, NULL, NULL, pc87310_write, NULL, NULL, dev); + return dev; } @@ -280,7 +320,21 @@ const device_t pc87310_ide_device = { .name = "National Semiconductor PC87310 Super I/O with IDE functionality", .internal_name = "pc87310_ide", .flags = 0, - .local = 1, + .local = FLAG_IDE, + .init = pc87310_init, + .close = pc87310_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ali5105_device = { + .name = "ALi M5105 Super I/O", + .internal_name = "ali5105", + .flags = 0, + .local = FLAG_ALI, .init = pc87310_init, .close = pc87310_close, .reset = NULL, From 1d15d48ee7c98a7c1d65e0e17340734f763ca46b Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 8 Jan 2024 23:58:30 +0100 Subject: [PATCH 238/936] Broke out the ALi M5213 IDE from the ALi M1489 code (it turns out the ALi M1489 on-chip IDE is for all intents and purposes identical to the M5213) and made the Acer A1G use it. --- src/chipset/ali1489.c | 161 ++------------------- src/disk/CMakeLists.txt | 3 +- src/disk/hdc_ide_ali5213.c | 267 +++++++++++++++++++++++++++++++++++ src/include/86box/hdc.h | 3 + src/machine/m_at_386dx_486.c | 2 +- src/sio/sio_pc87310.c | 1 - 6 files changed, 282 insertions(+), 155 deletions(-) create mode 100644 src/disk/hdc_ide_ali5213.c diff --git a/src/chipset/ali1489.c b/src/chipset/ali1489.c index 822ab7baf..3550f1da6 100644 --- a/src/chipset/ali1489.c +++ b/src/chipset/ali1489.c @@ -41,7 +41,8 @@ #include <86box/chipset.h> -#define DEFINE_SHADOW_PROCEDURE (((dev->regs[0x14] & 0x10) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x14] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)) +#define DEFINE_SHADOW_PROCEDURE (((dev->regs[0x14] & 0x10) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | \ + ((dev->regs[0x14] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)) #define DISABLED_SHADOW (MEM_READ_EXTANY | MEM_WRITE_EXTANY) #ifdef ENABLE_ALI1489_LOG @@ -64,19 +65,14 @@ ali1489_log(const char *fmt, ...) typedef struct ali1489_t { uint8_t index; - uint8_t ide_index; - uint8_t ide_chip_id; uint8_t pci_slot; uint8_t regs[256]; uint8_t pci_conf[256]; - uint8_t ide_regs[256]; port_92_t *port_92; smram_t *smram; } ali1489_t; -static void ali1489_ide_handler(ali1489_t *dev); - static void ali1489_shadow_recalc(ali1489_t *dev) { @@ -85,7 +81,8 @@ ali1489_shadow_recalc(ali1489_t *dev) for (uint8_t i = 0; i < 8; i++) { if (dev->regs[0x13] & (1 << i)) { ali1489_log("%06Xh-%06Xh region shadow enabled: read = %i, write = %i\n", - 0xc0000 + (i << 14), 0xc3fff + (i << 14), !!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20)); + 0xc0000 + (i << 14), 0xc3fff + (i << 14), + !!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20)); mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, DEFINE_SHADOW_PROCEDURE); } else { ali1489_log("%06Xh-%06Xh region shadow disabled\n", 0xc0000 + (i << 14), 0xc3fff + (i << 14)); @@ -96,7 +93,8 @@ ali1489_shadow_recalc(ali1489_t *dev) for (uint8_t i = 0; i < 4; i++) { if (dev->regs[0x14] & (1 << i)) { ali1489_log("%06Xh-%06Xh region shadow enabled: read = %i, write = %i\n", - 0xe0000 + (i << 15), 0xe7fff + (i << 15), !!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20)); + 0xe0000 + (i << 15), 0xe7fff + (i << 15), + !!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20)); mem_set_mem_state_both(0xe0000 + (i << 15), 0x8000, DEFINE_SHADOW_PROCEDURE); shadowbios |= !!(dev->regs[0x14] & 0x10); shadowbios_write |= !!(dev->regs[0x14] & 0x20); @@ -142,25 +140,9 @@ ali1489_smram_recalc(ali1489_t *dev) static void ali1489_defaults(ali1489_t *dev) { - memset(dev->ide_regs, 0x00, 256); memset(dev->pci_conf, 0x00, 256); memset(dev->regs, 0x00, 256); - ide_pri_disable(); - ide_sec_disable(); - - /* IDE registers */ - dev->ide_regs[0x00] = 0x57; - dev->ide_regs[0x01] = 0x02; - dev->ide_regs[0x08] = 0xff; - dev->ide_regs[0x09] = 0x41; - dev->ide_regs[0x0c] = 0x02; - dev->ide_regs[0x0e] = 0x02; - dev->ide_regs[0x10] = 0x02; - dev->ide_regs[0x12] = 0x02; - dev->ide_regs[0x34] = 0xff; - dev->ide_regs[0x35] = 0x01; - /* PCI registers */ dev->pci_conf[0x00] = 0xb9; dev->pci_conf[0x01] = 0x10; @@ -203,8 +185,6 @@ ali1489_defaults(ali1489_t *dev) pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); - - ali1489_ide_handler(dev); } static void @@ -385,7 +365,8 @@ ali1489_write(uint16_t addr, uint8_t val, void *priv) break; case 0x44: /* PCI INTx Sensitivity Register */ - /* TODO: When doing the IRQ and PCI IRQ rewrite, bits 0 to 3 toggle edge/level output. */ + /* TODO: When doing the IRQ and PCI IRQ rewrite, + bits 0 to 3 toggle edge/level output. */ dev->regs[dev->index] = val; break; default: @@ -464,121 +445,6 @@ ali1489_pci_read(UNUSED(int func), int addr, void *priv) return ret; } -static void -ali1489_ide_handler(ali1489_t *dev) -{ - ide_pri_disable(); - ide_sec_disable(); - if (dev->ide_regs[0x01] & 0x01) { - ide_pri_enable(); - if (!(dev->ide_regs[0x35] & 0x40)) - ide_sec_enable(); - } -} - -static void -ali1489_ide_write(uint16_t addr, uint8_t val, void *priv) -{ - ali1489_t *dev = (ali1489_t *) priv; - - switch (addr) { - case 0xf4: /* Usually it writes 30h here */ - dev->ide_chip_id = val; - break; - - case 0xf8: - dev->ide_index = val; - break; - - case 0xfc: - if (dev->ide_chip_id != 0x30) - break; - - switch (dev->ide_index) { - case 0x01: /* IDE Configuration Register */ - dev->ide_regs[dev->ide_index] = val & 0x8f; - ali1489_ide_handler(dev); - break; - case 0x02: /* DBA Data Byte Cative Count for IDE-1 */ - case 0x03: /* D0RA Disk 0 Read Active Count for IDE-1 */ - case 0x04: /* D0WA Disk 0 Write Active Count for IDE-1 */ - case 0x05: /* D1RA Disk 1 Read Active Count for IDE-1 */ - case 0x06: /* D1WA Disk 1 Write Active Count for IDE-1 */ - case 0x25: /* DBR Data Byte Recovery Count for IDE-1 */ - case 0x26: /* D0RR Disk 0 Read Byte Recovery Count for IDE-1 */ - case 0x27: /* D0WR Disk 0 Write Byte Recovery Count for IDE-1 */ - case 0x28: /* D1RR Disk 1 Read Byte Recovery Count for IDE-1 */ - case 0x29: /* D1WR Disk 1 Write Byte Recovery Count for IDE-1 */ - case 0x2a: /* DBA Data Byte Cative Count for IDE-2 */ - case 0x2b: /* D0RA Disk 0 Read Active Count for IDE-2 */ - case 0x2c: /* D0WA Disk 0 Write Active Count for IDE-2 */ - case 0x2d: /* D1RA Disk 1 Read Active Count for IDE-2 */ - case 0x2e: /* D1WA Disk 1 Write Active Count for IDE-2 */ - case 0x2f: /* DBR Data Byte Recovery Count for IDE-2 */ - case 0x30: /* D0RR Disk 0 Read Byte Recovery Count for IDE-2 */ - case 0x31: /* D0WR Disk 0 Write Byte Recovery Count for IDE-2 */ - case 0x32: /* D1RR Disk 1 Read Byte Recovery Count for IDE-2 */ - case 0x33: /* D1WR Disk 1 Write Byte Recovery Count for IDE-2 */ - dev->ide_regs[dev->ide_index] = val & 0x1f; - break; - case 0x07: /* Buffer Mode Register 1 */ - dev->ide_regs[dev->ide_index] = val; - break; - case 0x09: /* IDEPE1 IDE Port Enable Register 1 */ - dev->ide_regs[dev->ide_index] = val & 0xc3; - break; - case 0x0a: /* Buffer Mode Register 2 */ - dev->ide_regs[dev->ide_index] = val & 0x4f; - break; - case 0x0b: /* IDE Channel 1 Disk 0 Sector Byte Count Register 1 */ - case 0x0d: /* IDE Channel 1 Disk 1 Sector Byte Count Register 1 */ - case 0x0f: /* IDE Channel 2 Disk 0 Sector Byte Count Register 1 */ - case 0x11: /* IDE Channel 2 Disk 1 Sector Byte Count Register 1 */ - dev->ide_regs[dev->ide_index] = val & 0x03; - break; - case 0x0c: /* IDE Channel 1 Disk 0 Sector Byte Count Register 2 */ - case 0x0e: /* IDE Channel 1 Disk 1 Sector Byte Count Register 2 */ - case 0x10: /* IDE Channel 2 Disk 1 Sector Byte Count Register 2 */ - case 0x12: /* IDE Channel 2 Disk 1 Sector Byte Count Register 2 */ - dev->ide_regs[dev->ide_index] = val & 0x1f; - break; - case 0x35: /* IDEPE3 IDE Port Enable Register 3 */ - dev->ide_regs[dev->ide_index] = val; - ali1489_ide_handler(dev); - break; - - default: - break; - } - break; - - default: - break; - } -} - -static uint8_t -ali1489_ide_read(uint16_t addr, void *priv) -{ - const ali1489_t *dev = (ali1489_t *) priv; - uint8_t ret = 0xff; - - switch (addr) { - case 0xf4: - ret = dev->ide_chip_id; - break; - case 0xfc: - ret = dev->ide_regs[dev->ide_index]; - ali1489_log("M1489-IDE: dev->regs[%02x] (%02x)\n", dev->ide_index, ret); - break; - - default: - break; - } - - return ret; -} - static void ali1489_reset(void *priv) { @@ -612,19 +478,10 @@ ali1489_init(UNUSED(const device_t *info)) 23h Data Port */ io_sethandler(0x0022, 0x0002, ali1489_read, NULL, NULL, ali1489_write, NULL, NULL, dev); - /* M1489 IDE controller - F4h Chip ID we write always 30h onto it - F8h Index Port - FCh Data Port - */ - io_sethandler(0x0f4, 0x0001, ali1489_ide_read, NULL, NULL, ali1489_ide_write, NULL, NULL, dev); - io_sethandler(0x0f8, 0x0001, ali1489_ide_read, NULL, NULL, ali1489_ide_write, NULL, NULL, dev); - io_sethandler(0x0fc, 0x0001, ali1489_ide_read, NULL, NULL, ali1489_ide_write, NULL, NULL, dev); - /* Dummy M1489 PCI device */ pci_add_card(PCI_ADD_NORTHBRIDGE, ali1489_pci_read, ali1489_pci_write, dev, &dev->pci_slot); - device_add(&ide_pci_2ch_device); + device_add(&ide_ali1489_device); dev->port_92 = device_add(&port_92_pci_device); dev->smram = smram_add(); diff --git a/src/disk/CMakeLists.txt b/src/disk/CMakeLists.txt index 7771a0b72..00da385d4 100644 --- a/src/disk/CMakeLists.txt +++ b/src/disk/CMakeLists.txt @@ -15,7 +15,8 @@ add_library(hdd OBJECT hdd.c hdd_image.c hdd_table.c hdc.c hdc_st506_xt.c hdc_st506_at.c hdc_xta.c hdc_esdi_at.c hdc_esdi_mca.c hdc_xtide.c - hdc_ide.c hdc_ide_opti611.c hdc_ide_cmd640.c hdc_ide_cmd646.c hdc_ide_sff8038i.c) + hdc_ide.c hdc_ide_ali5213.c hdc_ide_opti611.c hdc_ide_cmd640.c hdc_ide_cmd646.c + hdc_ide_sff8038i.c) add_library(zip OBJECT zip.c) diff --git a/src/disk/hdc_ide_ali5213.c b/src/disk/hdc_ide_ali5213.c new file mode 100644 index 000000000..eee3844c4 --- /dev/null +++ b/src/disk/hdc_ide_ali5213.c @@ -0,0 +1,267 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the ALi M1489 chipset. + * + * + * + * Authors: Tiseno100, + * Miran Grca, + * + * Copyright 2020-2021 Tiseno100. + * Copyright 2020-2021 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> + +#include <86box/hdc_ide.h> +#include <86box/hdc.h> +#include <86box/mem.h> +#include <86box/nmi.h> +#include <86box/pic.h> +#include <86box/pci.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> + +#include <86box/chipset.h> + +#ifdef ENABLE_ALI5213_LOG +int ali5213_do_log = ENABLE_ALI5213_LOG; + +static void +ali5213_log(const char *fmt, ...) +{ + va_list ap; + + if (ali5213_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define ali5213_log(fmt, ...) +#endif + +typedef struct ali5213_t { + uint8_t index; + uint8_t chip_id; + + uint8_t regs[256]; +} ali5213_t; + +static void +ali5213_ide_handler(ali5213_t *dev) +{ + ide_pri_disable(); + ide_sec_disable(); + if (dev->regs[0x01] & 0x01) { + ide_pri_enable(); + if (!(dev->regs[0x35] & 0x40)) + ide_sec_enable(); + } +} + +static void +ali5213_write(uint16_t addr, uint8_t val, void *priv) +{ + ali5213_t *dev = (ali5213_t *) priv; + + ali5213_log("[%04X:%08X] [W] %02X = %02X (%i)\n", CS, cpu_state.pc, port, val, dev->tries); + + switch (addr) { + case 0xf4: /* Usually it writes 30h here */ + dev->chip_id = val; + break; + + case 0xf8: + dev->index = val; + break; + + case 0xfc: + if (dev->chip_id != 0x30) + break; + + switch (dev->index) { + case 0x01: /* IDE Configuration Register */ + dev->regs[dev->index] = val & 0x8f; + ali5213_ide_handler(dev); + break; + case 0x02: /* DBA Data Byte Cative Count for IDE-1 */ + case 0x03: /* D0RA Disk 0 Read Active Count for IDE-1 */ + case 0x04: /* D0WA Disk 0 Write Active Count for IDE-1 */ + case 0x05: /* D1RA Disk 1 Read Active Count for IDE-1 */ + case 0x06: /* D1WA Disk 1 Write Active Count for IDE-1 */ + case 0x25: /* DBR Data Byte Recovery Count for IDE-1 */ + case 0x26: /* D0RR Disk 0 Read Byte Recovery Count for IDE-1 */ + case 0x27: /* D0WR Disk 0 Write Byte Recovery Count for IDE-1 */ + case 0x28: /* D1RR Disk 1 Read Byte Recovery Count for IDE-1 */ + case 0x29: /* D1WR Disk 1 Write Byte Recovery Count for IDE-1 */ + case 0x2a: /* DBA Data Byte Cative Count for IDE-2 */ + case 0x2b: /* D0RA Disk 0 Read Active Count for IDE-2 */ + case 0x2c: /* D0WA Disk 0 Write Active Count for IDE-2 */ + case 0x2d: /* D1RA Disk 1 Read Active Count for IDE-2 */ + case 0x2e: /* D1WA Disk 1 Write Active Count for IDE-2 */ + case 0x2f: /* DBR Data Byte Recovery Count for IDE-2 */ + case 0x30: /* D0RR Disk 0 Read Byte Recovery Count for IDE-2 */ + case 0x31: /* D0WR Disk 0 Write Byte Recovery Count for IDE-2 */ + case 0x32: /* D1RR Disk 1 Read Byte Recovery Count for IDE-2 */ + case 0x33: /* D1WR Disk 1 Write Byte Recovery Count for IDE-2 */ + dev->regs[dev->index] = val & 0x1f; + break; + case 0x07: /* Buffer Mode Register 1 */ + dev->regs[dev->index] = val; + break; + case 0x09: /* IDEPE1 IDE Port Enable Register 1 */ + dev->regs[dev->index] = val & 0xc3; + break; + case 0x0a: /* Buffer Mode Register 2 */ + dev->regs[dev->index] = val & 0x4f; + break; + case 0x0b: /* IDE Channel 1 Disk 0 Sector Byte Count Register 1 */ + case 0x0d: /* IDE Channel 1 Disk 1 Sector Byte Count Register 1 */ + case 0x0f: /* IDE Channel 2 Disk 0 Sector Byte Count Register 1 */ + case 0x11: /* IDE Channel 2 Disk 1 Sector Byte Count Register 1 */ + dev->regs[dev->index] = val & 0x03; + break; + case 0x0c: /* IDE Channel 1 Disk 0 Sector Byte Count Register 2 */ + case 0x0e: /* IDE Channel 1 Disk 1 Sector Byte Count Register 2 */ + case 0x10: /* IDE Channel 2 Disk 1 Sector Byte Count Register 2 */ + case 0x12: /* IDE Channel 2 Disk 1 Sector Byte Count Register 2 */ + dev->regs[dev->index] = val & 0x1f; + break; + case 0x35: /* IDEPE3 IDE Port Enable Register 3 */ + dev->regs[dev->index] = val; + ali5213_ide_handler(dev); + break; + + default: + break; + } + break; + + default: + break; + } +} + +static uint8_t +ali5213_read(uint16_t addr, void *priv) +{ + const ali5213_t *dev = (ali5213_t *) priv; + uint8_t ret = 0xff; + + switch (addr) { + case 0xf4: + ret = dev->chip_id; + break; + case 0xfc: + ret = dev->regs[dev->index]; + break; + + default: + break; + } + + ali5213_log("[%04X:%08X] [R] %02X = %02X\n", CS, cpu_state.pc, port, ret); + + return ret; +} + +static void +ali5213_reset(void *priv) +{ + ali5213_t *dev = (ali5213_t *) priv; + + memset(dev->regs, 0x00, 256); + + ide_pri_disable(); + ide_sec_disable(); + + /* IDE registers */ + dev->regs[0x00] = 0x57; + dev->regs[0x01] = 0x02; + dev->regs[0x08] = 0xff; + dev->regs[0x09] = 0x41; + dev->regs[0x0c] = 0x02; + dev->regs[0x0e] = 0x02; + dev->regs[0x10] = 0x02; + dev->regs[0x12] = 0x02; + dev->regs[0x34] = 0xff; + dev->regs[0x35] = 0x01; + + ali5213_ide_handler(dev); +} + +static void +ali5213_close(void *priv) +{ + ali5213_t *dev = (ali5213_t *) priv; + + free(dev); +} + +static void * +ali5213_init(UNUSED(const device_t *info)) +{ + ali5213_t *dev = (ali5213_t *) calloc(1, sizeof(ali5213_t)); + + /* M5213/M1489 IDE controller + F4h Chip ID we write always 30h onto it + F8h Index Port + FCh Data Port + */ + io_sethandler(0x0f4, 0x0001, ali5213_read, NULL, NULL, ali5213_write, NULL, NULL, dev); + io_sethandler(0x0f8, 0x0001, ali5213_read, NULL, NULL, ali5213_write, NULL, NULL, dev); + io_sethandler(0x0fc, 0x0001, ali5213_read, NULL, NULL, ali5213_write, NULL, NULL, dev); + + device_add(info->local ? &ide_pci_2ch_device : &ide_vlb_2ch_device); + + ali5213_reset(dev); + + return dev; +} + +const device_t ide_ali1489_device = { + .name = "ALi M1489 IDE", + .internal_name = "ali1489_ide", + .flags = 0, + .local = 1, + .init = ali5213_init, + .close = ali5213_close, + .reset = ali5213_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_ali5213_device = { + .name = "ALi M5213", + .internal_name = "ali5213", + .flags = 0, + .local = 0, + .init = ali5213_init, + .close = ali5213_close, + .reset = ali5213_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h index 8ede3e786..b0e775886 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -60,6 +60,9 @@ extern const device_t ide_vlb_2ch_device; /* vlb_ide_2ch */ extern const device_t ide_pci_device; /* pci_ide */ extern const device_t ide_pci_2ch_device; /* pci_ide_2ch */ +extern const device_t ide_ali1489_device; /* ALi M1489 */ +extern const device_t ide_ali5213_device; /* ALi M5213 */ + extern const device_t ide_cmd640_vlb_device; /* CMD PCI-640B VLB */ extern const device_t ide_cmd640_vlb_178_device; /* CMD PCI-640B VLB (Port 178h) */ extern const device_t ide_cmd640_vlb_pri_device; /* CMD PCI-640B VLB (Only primary channel) */ diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index a695073e2..2f92676c9 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -381,9 +381,9 @@ machine_at_acera1g_init(const machine_t *model) device_add(&gd5428_onboard_device); device_add(&keyboard_ps2_acer_pci_device); - device_add(&ide_vlb_2ch_device); device_add(&ali5105_device); + device_add(&ide_ali5213_device); return ret; } diff --git a/src/sio/sio_pc87310.c b/src/sio/sio_pc87310.c index f9626214c..075b819ff 100644 --- a/src/sio/sio_pc87310.c +++ b/src/sio/sio_pc87310.c @@ -244,7 +244,6 @@ pc87310_read(UNUSED(uint16_t port), void *priv) ret = dev->regs[idx]; pc87310_log("[%04X:%08X] [R] %02X = %02X\n", CS, cpu_state.pc, port, ret); - pc87310_log("SIO: read %01X\n", ret); return ret; } From 9df44e60b5d4135ecc4e6cd40b0b1d9cfbb79041 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Tue, 9 Jan 2024 13:08:25 +1300 Subject: [PATCH 239/936] unittester: Make the log more usable --- src/device/unittester.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/device/unittester.c b/src/device/unittester.c index 0442d0695..e52f3b56f 100644 --- a/src/device/unittester.c +++ b/src/device/unittester.c @@ -170,7 +170,7 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) { if (port == unittester.iobase_port + 0x00) { /* Command port */ - unittester_log("[UT] W %02X Command\n", val); + /* unittester_log("[UT] W %02X Command\n", val); */ unittester.write_offs = 0; unittester.write_len = 0; @@ -221,7 +221,7 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) } else if (port == unittester.iobase_port + 0x01) { /* Data port */ - unittester_log("[UT] W %02X Data\n", val); + /* unittester_log("[UT] W %02X Data\n", val); */ /* Skip if not awaiting */ if ((unittester.status & UT_STATUS_AWAITING_WRITE) == 0) @@ -369,6 +369,12 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) unittester.read_len = ((uint64_t) unittester.read_snap_width) * ((uint64_t) unittester.read_snap_height) * 4; unittester.read_snap_crc = 0xFFFFFFFF; + unittester_log("[UT] Screen rectangle analysis - %d x %d @ (%d, %d)\n", + unittester.read_snap_width, + unittester.read_snap_height, + unittester.read_snap_xoffs - (int16_t) unittester.snap_img_xoffs, + unittester.read_snap_yoffs - (int16_t) unittester.snap_img_yoffs); + if (unittester.cmd_id == UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE) { /* Read everything and compute CRC */ uint32_t crc = 0xFFFFFFFF; @@ -381,6 +387,9 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) } unittester.read_snap_crc = crc ^ 0xFFFFFFFF; + unittester_log("[UT] Screen rectangle analysis CRC = %08X\n", + unittester.read_snap_crc); + /* Set actual read length for CRC result */ unittester.read_len = 4; unittester.status = UT_STATUS_AWAITING_READ; @@ -418,7 +427,7 @@ unittester_read(uint16_t port, UNUSED(void *priv)) if (port == unittester.iobase_port + 0x00) { /* Status port */ - unittester_log("[UT] R -- Status = %02X\n", unittester.status); + /* unittester_log("[UT] R -- Status = %02X\n", unittester.status); */ return unittester.status; } else if (port == unittester.iobase_port + 0x01) { /* Data port */ From c29d51b41985ad456a323165a3f79fd386e1a8fb Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 9 Jan 2024 02:40:00 +0100 Subject: [PATCH 240/936] Slowed down the keyboard controller back to the old speed, fixes #4013. --- src/device/kbc_at.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index fa7cdc304..d2e6cf364 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -699,7 +699,7 @@ kbc_at_poll(void *priv) { atkbc_t *dev = (atkbc_t *) priv; - timer_advance_u64(&dev->kbc_poll_timer, (39ULL * TIMER_USEC)); + timer_advance_u64(&dev->kbc_poll_timer, (100ULL * TIMER_USEC)); /* TODO: Implement the password security state. */ kbc_at_do_poll(dev); From 22ead81b809189916032267d49434c21b80dfa6e Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Tue, 9 Jan 2024 17:20:31 +1300 Subject: [PATCH 241/936] Fixes for EGA scrolling --- src/video/vid_ega.c | 51 +++++++++++++------------------------- src/video/vid_ega_render.c | 8 ++++++ 2 files changed, 25 insertions(+), 34 deletions(-) diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index d471247aa..1017e25b2 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -684,7 +684,7 @@ void ega_poll(void *priv) { ega_t *ega = (ega_t *) priv; - int x; + int x, y; int old_ma; int wx = 640; int wy = 350; @@ -704,37 +704,26 @@ ega_poll(void *priv) video_wait_for_buffer(); } - if (ega->vres) { - old_ma = ega->ma; - - ega->displine <<= 1; - ega->y_add <<= 1; - + old_ma = ega->ma; + ega->displine *= ega->vres + 1; + ega->y_add *= ega->vres + 1; + for (y = 0; y <= ega->vres; y++) { + /* Render scanline */ ega->render(ega); + /* Render overscan */ ega->x_add = (overscan_x >> 1); ega_render_overscan_left(ega); ega_render_overscan_right(ega); ega->x_add = (overscan_x >> 1) - ega->scrollcache; - ega->displine++; - - ega->ma = old_ma; - - ega->render(ega); - - ega->x_add = (overscan_x >> 1); - ega_render_overscan_left(ega); - ega_render_overscan_right(ega); - ega->x_add = (overscan_x >> 1) - ega->scrollcache; - - ega->y_add >>= 1; - ega->displine >>= 1; - } else { - ega_render_overscan_left(ega); - ega->render(ega); - ega_render_overscan_right(ega); + if (y != ega->vres) { + ega->ma = old_ma; + ega->displine++; + } } + ega->displine /= ega->vres + 1; + ega->y_add /= ega->vres + 1; if (ega->lastline < ega->displine) ega->lastline = ega->displine; @@ -887,16 +876,10 @@ ega_poll(void *priv) ega->displine = (ega->interlace && ega->oddeven) ? 1 : 0; ega->scrollcache = (ega->attrregs[0x13] & 0x0f); - if (!(ega->gdcreg[6] & 1) && !(ega->attrregs[0x10] & 1)) { /*Text mode*/ - if (ega->seqregs[1] & 1) - ega->scrollcache &= 0x07; - else { - ega->scrollcache++; - if (ega->scrollcache > 8) - ega->scrollcache = 0; - } - } else - ega->scrollcache &= 0x07; + if (ega->scrollcache >= 0x8) + ega->scrollcache = 0; + else + ega->scrollcache++; if (ega->seqregs[1] & 8) ega->scrollcache <<= 1; diff --git a/src/video/vid_ega_render.c b/src/video/vid_ega_render.c index 2d15d6dc5..98905e0c8 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -126,6 +126,14 @@ ega_render_text(ega_t *ega) const bool blinked = ega->blink & 0x10; uint32_t *p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; + /* Compensate for 8dot scroll */ + if (!seq9dot) { + for (int x = 0; x < dotwidth; x++) { + p[x] = ega->overscan_color; + } + p += dotwidth; + } + for (int x = 0; x < (ega->hdisp + ega->scrollcache); x += charwidth) { uint32_t addr = ega->remap_func(ega, ega->ma) & ega->vrammask; From bad7c6490e8cec7cb73529c55f2203186f021d9b Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Tue, 9 Jan 2024 17:31:19 +1300 Subject: [PATCH 242/936] Rework EGA overscan to be compatible with the unit tester By the way, text mode scrolling at least seems to be correct now --- src/video/vid_ega.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 1017e25b2..9aa2574d9 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -552,12 +552,18 @@ ega_recalctimings(ega_t *ega) overscan_x = (ega->seqregs[1] & 1) ? 16 : 18; + if (ega->vres) + overscan_y <<= 1; + if (ega->seqregs[1] & 8) overscan_x <<= 1; ega->y_add = (overscan_y >> 1); ega->x_add = (overscan_x >> 1); + if (ega->vres) + ega->y_add >>= 1; + if (ega->seqregs[1] & 8) { disptime = (double) ((ega->crtc[0] + 2) << 1); _dispontime = (double) ((ega->crtc[1] + 1) << 1); @@ -896,11 +902,12 @@ ega_poll(void *priv) void ega_doblit(int wx, int wy, ega_t *ega) { - int y_add = enable_overscan ? overscan_y : 0; + int unscaled_overscan_y = ega->vres ? overscan_y >> 1 : overscan_y; + int y_add = enable_overscan ? unscaled_overscan_y : 0; int x_add = enable_overscan ? overscan_x : 0; - int y_start = enable_overscan ? 0 : (overscan_y >> 1); + int y_start = enable_overscan ? 0 : (unscaled_overscan_y >> 1); int x_start = enable_overscan ? 0 : (overscan_x >> 1); - int bottom = (overscan_y >> 1); + int bottom = (unscaled_overscan_y >> 1); uint32_t *p; int i; int j; From 143b8be92fe34bc792a275d65b6bbcbf4d09045f Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 9 Jan 2024 17:10:47 +0100 Subject: [PATCH 243/936] The forgotten changes to win/Makefile.mingw. --- src/win/Makefile.mingw | 1 + 1 file changed, 1 insertion(+) diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index ae850eee4..28c93702d 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -648,6 +648,7 @@ HDDOBJ := hdd.o \ hdc_xta.o \ hdc_esdi_at.o hdc_esdi_mca.o \ hdc_xtide.o hdc_ide.o \ + hdc_ide_ali5213.o \ hdc_ide_opti611.o \ hdc_ide_cmd640.o hdc_ide_cmd646.o \ hdc_ide_sff8038i.o From 79874ad3d5967827d2c6e527d0734c4fd811bdbe Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 9 Jan 2024 17:38:54 +0100 Subject: [PATCH 244/936] EGA and (S)VGA: Removed a leftover if block around overscan Y, fixes garbage overscan Y values causing crashes. --- src/video/vid_ega.c | 8 +++----- src/video/vid_svga.c | 16 ++++++---------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 9aa2574d9..670d88e61 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -543,12 +543,10 @@ ega_recalctimings(ega_t *ega) } } - if (enable_overscan) { - overscan_y = (ega->rowcount + 1) << 1; + overscan_y = (ega->rowcount + 1) << 1; - if (overscan_y < 16) - overscan_y = 16; - } + if (overscan_y < 16) + overscan_y = 16; overscan_x = (ega->seqregs[1] & 1) ? 16 : 18; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 12c549765..f90c3f74e 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -92,12 +92,10 @@ svga_set_override(svga_t *svga, int val) if (!val) { /* Override turned off, restore overscan X and Y per the CRTC. */ - if (enable_overscan) { - svga->monitor->mon_overscan_y = (svga->rowcount + 1) << 1; + svga->monitor->mon_overscan_y = (svga->rowcount + 1) << 1; - if (svga->monitor->mon_overscan_y < 16) - svga->monitor->mon_overscan_y = 16; - } + if (svga->monitor->mon_overscan_y < 16) + svga->monitor->mon_overscan_y = 16; svga->monitor->mon_overscan_x = (svga->seqregs[1] & 1) ? 16 : 18; @@ -711,12 +709,10 @@ svga_recalctimings(svga_t *svga) svga->linedbl = svga->crtc[9] & 0x80; svga->char_width = (svga->seqregs[1] & 1) ? 8 : 9; - if (enable_overscan) { - svga->monitor->mon_overscan_y = (svga->rowcount + 1) << 1; + svga->monitor->mon_overscan_y = (svga->rowcount + 1) << 1; - if (svga->monitor->mon_overscan_y < 16) - svga->monitor->mon_overscan_y = 16; - } + if (svga->monitor->mon_overscan_y < 16) + svga->monitor->mon_overscan_y = 16; if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { svga->monitor->mon_overscan_x = (svga->seqregs[1] & 1) ? 16 : 18; From fbc1341e58bc3a79ac9410dee0acdc952acb8a5e Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 9 Jan 2024 18:35:53 +0100 Subject: [PATCH 245/936] Added unit tester to the MingW makefile. --- src/win/Makefile.mingw | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 28c93702d..0cf34d6c6 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -618,7 +618,8 @@ DEVOBJ := bugger.o cartridge.o cassette.o hasp.o hwm.o hwm_lm75.o hwm_lm78.o hwm mouse_serial.o mouse_ps2.o \ mouse_wacom_tablet.o \ nec_mate_unk.o phoenix_486_jumper.o \ - serial_passthrough.o + serial_passthrough.o \ + unittester.o SIOOBJ := sio_acc3221.o sio_ali5123.o \ sio_f82c710.o sio_82091aa.o sio_fdc37c6xx.o \ From eb200030e375c880cb9f424f3925a91e5fecf8f3 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 10 Jan 2024 01:26:50 +0600 Subject: [PATCH 246/936] IBM PS/1 Model 2011: Add language ROMs --- src/device.c | 6 ++ src/include/86box/device.h | 2 + src/machine/m_ps1.c | 110 +++++++++++++++++++++++++++++++++--- src/machine/machine_table.c | 3 +- 4 files changed, 113 insertions(+), 8 deletions(-) diff --git a/src/device.c b/src/device.c index c517f98e9..6125674db 100644 --- a/src/device.c +++ b/src/device.c @@ -849,3 +849,9 @@ machine_get_config_string(char *s) return NULL; } + +const device_t* +device_context_get_device(void) +{ + return device_current.dev; +} diff --git a/src/include/86box/device.h b/src/include/86box/device.h index b2d7a05ed..f5efb5dbb 100644 --- a/src/include/86box/device.h +++ b/src/include/86box/device.h @@ -202,6 +202,8 @@ extern const char *device_get_bios_file(const device_t *dev, const char *interna extern int device_is_valid(const device_t *, int m); +extern const device_t* device_context_get_device(void); + extern int device_get_config_int(const char *name); extern int device_get_config_int_ex(const char *s, int dflt_int); extern int device_get_config_hex16(const char *name); diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c index d2c9f80ba..e0a15126e 100644 --- a/src/machine/m_ps1.c +++ b/src/machine/m_ps1.c @@ -63,6 +63,7 @@ #include <86box/video.h> #include <86box/machine.h> #include <86box/sound.h> +#include <86box/plat_unused.h> typedef struct { int model; @@ -242,6 +243,56 @@ ps1_read(uint16_t port, void *priv) return ret; } +static const device_config_t ps1_2011_config[] = { + // clang-format off + { + .name = "bios_language", + .description = "BIOS Language", + .type = CONFIG_BIOS, + .default_string = "english_us", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, /*W1*/ + .bios = { + { .name = "English (US)", .internal_name = "english_us", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 262144, .files = { "roms/machines/ibmps1es/FC0000_US.BIN", "" } }, + { .name = "English (UK)", .internal_name = "english_uk", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 262144, .files = { "roms/machines/ibmps1es/F80000_UK.BIN", "roms/machines/ibmps1es/FC0000_UK.BIN", "" } }, + { .name = "English (Canada)", .internal_name = "english_ca", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 262144, .files = { "roms/machines/ibmps1es/F80000_CA.BIN", "roms/machines/ibmps1es/FC0000_CA.BIN", "" } }, + { .name = "Portuguese", .internal_name = "portuguese", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 262144, .files = { "roms/machines/ibmps1es/F80000_PT.BIN", "roms/machines/ibmps1es/FC0000_PT.BIN", "" } }, + { .name = "German", .internal_name = "german", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 262144, .files = { "roms/machines/ibmps1es/F80000_DE.BIN", "roms/machines/ibmps1es/FC0000_DE.BIN", "" } }, + { .name = "Swedish", .internal_name = "swedish", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 262144, .files = { "roms/machines/ibmps1es/F80000_SE.BIN", "roms/machines/ibmps1es/FC0000_SE.BIN", "" } }, + { .name = "French", .internal_name = "french", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 262144, .files = { "roms/machines/ibmps1es/F80000_FR.BIN", "roms/machines/ibmps1es/FC0000_FR.BIN", "" } }, + { .name = "Italian", .internal_name = "italian", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 524288, .files = { "roms/machines/ibmps1es/f80000.bin", "" } }, + { .name = "Spanish", .internal_name = "spanish", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 524288, .files = { "roms/machines/ibmps1es/F80000_ES.bin", "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ps1_2011_device = { + .name = "PS/1 2011", + .internal_name = "ps/1_2011", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = &ps1_2011_config[0] +}; + static void ps1_setup(int model) { @@ -273,9 +324,27 @@ ps1_setup(int model) device_add(&ps_nvr_device); if (model == 2011) { - rom_init(&ps->high_rom, - "roms/machines/ibmps1es/f80000.bin", - 0xf80000, 0x80000, 0x7ffff, 0, MEM_MAPPING_EXTERNAL); + if (!strcmp("english_us", device_get_config_bios("bios_language"))) { + /* US English */ + rom_init(&ps->high_rom, + device_get_bios_file(device_context_get_device(), device_get_config_bios("bios_language"), 0), + 0xfc0000, 0x40000, 0x3ffff, 0, MEM_MAPPING_EXTERNAL); + + } else if ((device_get_bios_file(device_context_get_device(), device_get_config_bios("bios_language"), 1)) == NULL) { + /* Combined ROM. */ + rom_init(&ps->high_rom, + device_get_bios_file(device_context_get_device(), device_get_config_bios("bios_language"), 0), + 0xf80000, 0x80000, 0x7ffff, 0, MEM_MAPPING_EXTERNAL); + } else { + /* Split ROM. */ + rom_init(&ps->mid_rom, + device_get_bios_file(device_context_get_device(), device_get_config_bios("bios_language"), 0), + 0xf80000, 0x40000, 0x3ffff, 0, MEM_MAPPING_EXTERNAL); + + rom_init(&ps->high_rom, + device_get_bios_file(device_context_get_device(), device_get_config_bios("bios_language"), 1), + 0xfc0000, 0x40000, 0x3ffff, 0, MEM_MAPPING_EXTERNAL); + } lpt2_remove(); @@ -339,16 +408,43 @@ int machine_ps1_m2011_init(const machine_t *model) { int ret; + const char* fn; + uint32_t offset; - ret = bios_load_linear("roms/machines/ibmps1es/f80000.bin", - 0x000e0000, 131072, 0x60000); + if (!device_available(model->device)) { + /* No ROMs available. */ + return 0; + } - if (bios_only || !ret) + device_context(model->device); + if ((fn = device_get_bios_file(model->device, device_get_config_bios("bios_language"), 1)) == NULL) { + /* Combined ROM or US English. */ + fn = device_get_bios_file(model->device, device_get_config_bios("bios_language"), 0); + offset = (!strcmp("english_us", device_get_config_bios("bios_language"))) ? 0x20000 : 0x60000; + } else { + /* Separated ROM. */ + offset = 0x20000; + } + + if (!fn) { + fn = device_get_bios_file(model->device, "us_english", 0); + offset = 0x20000; + } + + ret = bios_load_linear(fn, 0x000e0000, 131072, offset); + device_context_restore(); + + if (bios_only || !ret) { return ret; + } ps1_common_init(model); - ps1_setup(2011); + device_context(model->device); + + ps1_setup(2011); + + device_context_restore(); return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 3584d8f1f..462379a7c 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -51,6 +51,7 @@ extern const device_t vid_ppc512_device; extern const device_t vid_device_sl; extern const device_t t1200_video_device; extern const device_t compaq_plasma_device; +extern const device_t ps1_2011_device; const machine_filter_t machine_types[] = { { "None", MACHINE_TYPE_NONE }, @@ -2546,7 +2547,7 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &ps1_2011_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, From 115a0b1c555cf537f5adf5d28666e426258400ae Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Tue, 9 Jan 2024 21:27:58 +0100 Subject: [PATCH 247/936] Add GLaBIOS machine. --- src/include/86box/machine.h | 1 + src/machine/m_xt.c | 16 +++++++++++++++ src/machine/machine_table.c | 39 +++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 4e80a7416..b02b64882 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -852,6 +852,7 @@ extern int machine_xt_pc700_init(const machine_t *); extern int machine_xt_pc500_init(const machine_t *); extern int machine_xt_vendex_init(const machine_t *); extern int machine_xt_znic_init(const machine_t *); +extern int machine_xt_glabios_init(const machine_t *); extern int machine_xt_super16t_init(const machine_t *); extern int machine_xt_super16te_init(const machine_t *); extern int machine_xt_top88_init(const machine_t *); diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index a374b58f3..20a7da6ae 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -640,3 +640,19 @@ machine_xt_pb8810_init(const machine_t *model) return ret; } + +int +machine_xt_glabios_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/glabios/GLABIOS_0.2.5_8E.ROM", + 0x000fe000, 8192, 0); + + if (bios_only || !ret) + return ret; + + machine_xt_init_ex(model); + + return ret; +} \ No newline at end of file diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 3584d8f1f..2e99f7f6f 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -1802,6 +1802,45 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + { + .name = "[8088] GLaBIOS", + .internal_name = "glabios", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_glabios_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 = 64, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc_device = &keyboard_xt_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, { .name = "[GC100A] Philips P3120", .internal_name = "p3120", From ce342400eb2dd1ed87b61bdb1aa033d09a383902 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 9 Jan 2024 23:49:09 +0100 Subject: [PATCH 248/936] Fixed IDE sector advancement, fixes #4012. --- src/disk/hdc_ide.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 299c5c487..b47bfaf70 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -734,19 +734,25 @@ ide_get_sector(ide_t *ide) static void ide_next_sector(ide_t *ide) { + uint32_t sector = ide->tf->sector; + uint32_t head = ide->tf->head; + if (ide->tf->lba) ide->lba_addr++; else { - ide->tf->sector++; - if ((ide->tf->sector == 0) || (ide->tf->sector == (ide->cfg_spt + 1))) { - ide->tf->sector = 1; - ide->tf->head++; - if ((ide->tf->head == 0) || (ide->head == ide->cfg_hpc)) { - ide->tf->head = 0; + sector++; + if ((sector == 0) || (sector == (ide->cfg_spt + 1))) { + sector = 1; + head++; + if (head == ide->cfg_hpc) { + head = 0; ide->tf->cylinder++; } } } + + ide->tf->sector = sector & 0xff; + ide->tf->head = head & 0x0f; } static void @@ -1411,8 +1417,7 @@ ide_write_devctl(UNUSED(uint16_t addr), uint8_t val, void *priv) old = dev->devctl; dev->devctl = val; - // if (!(val & 0x02) && (old & 0x02)) - if ((old ^ val) & 0x02) + if (!(val & 0x02) && (old & 0x02)) ide_irq_update(ide_boards[ide->board], 1); } From 67c84f1ae6726a7a8615a69222e5279e2db8d31a Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 9 Jan 2024 20:13:16 -0300 Subject: [PATCH 249/936] Add automatically-generated names to threads --- src/include/86box/plat.h | 1 + src/include/86box/thread.h | 5 +++-- src/qt/qt_main.cpp | 1 + src/qt/qt_platform.cpp | 45 ++++++++++++++++++++++++++++++++++++++ src/thread.cpp | 5 +++-- src/unix/unix.c | 20 +++++++++++++++++ src/unix/unix_thread.c | 3 ++- src/win/win.c | 30 +++++++++++++++++++++++++ src/win/win_thread.c | 3 ++- 9 files changed, 107 insertions(+), 6 deletions(-) diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index 0d5b17a3c..1f5f2b695 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -149,6 +149,7 @@ extern uint32_t plat_language_code(char *langcode); extern void plat_language_code_r(uint32_t lcid, char *outbuf, int len); extern void plat_get_cpu_string(char *outbuf, uint8_t len); extern double plat_get_dpi(void); +extern void plat_set_thread_name(void *thread, const char *name); /* Resource management. */ extern void set_language(uint32_t id); diff --git a/src/include/86box/thread.h b/src/include/86box/thread.h index 4d5584787..a71d03913 100644 --- a/src/include/86box/thread.h +++ b/src/include/86box/thread.h @@ -28,7 +28,7 @@ extern "C" { # define event_t plat_event_t # define mutex_t plat_mutex_t -# define thread_create plat_thread_create +# define thread_create_named plat_thread_create_named # define thread_wait plat_thread_wait # define thread_create_event plat_thread_create_event # define thread_set_event plat_thread_set_event @@ -48,7 +48,8 @@ typedef void thread_t; typedef void event_t; typedef void mutex_t; -extern thread_t *thread_create(void (*thread_func)(void *param), void *param); +#define thread_create(thread_func, param) thread_create_named((thread_func), (param), #thread_func) +extern thread_t *thread_create_named(void (*thread_func)(void *param), void *param, const char *name); extern int thread_wait(thread_t *arg); extern event_t *thread_create_event(void); extern void thread_set_event(event_t *arg); diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 409a63248..4d02e2601 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -94,6 +94,7 @@ main_thread_fn() int frames; QThread::currentThread()->setPriority(QThread::HighestPriority); + plat_set_thread_name(NULL, "main_thread_fn"); framecountx = 0; // title_update = 1; old_time = elapsed_timer.elapsed(); diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 7ea28a4ce..62325e780 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -50,6 +50,7 @@ #include "qt_util.hpp" #ifdef Q_OS_UNIX +# include # include #endif @@ -742,3 +743,47 @@ plat_get_dpi(void) { return util::screenOfWidget(main_window)->devicePixelRatio(); } + +void +plat_set_thread_name(void *thread, const char *name) +{ +#ifdef Q_OS_WINDOWS + /* SetThreadDescription was added in 14393. Revisit if we ever start requiring 10. */ + static void *kernel32_handle = NULL; + static HRESULT(WINAPI *pSetThreadDescription)(HANDLE hThread, PCWSTR lpThreadDescription) = NULL; + static dllimp_t kernel32_imports[] = { + // clang-format off + { "SetThreadDescription", &pSetThreadDescription }, + { NULL, NULL } + // clang-format on + }; + + if (!kernel32_handle) { + kernel32_handle = dynld_module("kernel32.dll", kernel32_imports); + if (!kernel32_handle) { + kernel32_handle = kernel32_imports; /* dummy pointer to store that we tried */ + pSetThreadDescription = NULL; + } + } + + if (pSetThreadDescription) { + size_t len = strlen(name) + 1; + wchar_t wname[len]; + mbstowcs(wname, name, len); + pSetThreadDescription(thread ? (HANDLE) thread : GetCurrentThread(), wname); + } +#else +# ifdef Q_OS_DARWIN + char truncated[64]; +# else + char truncated[16]; +# endif + strncpy(truncated, name, sizeof(truncated) - 1); +# ifdef Q_OS_DARWIN + if (!thread) + pthread_setname_np(truncated); +# else + pthread_setname_np(thread ? (pthread_t) thread : pthread_self(), truncated); +# endif +#endif +} diff --git a/src/thread.cpp b/src/thread.cpp index 1b4311f37..f2a0ceaf0 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -14,9 +14,10 @@ struct event_cpp11_t { extern "C" { thread_t * -thread_create(void (*thread_rout)(void *param), void *param) +thread_create_named(void (*thread_rout)(void *param), void *param, const char *name) { - auto thread = new std::thread([thread_rout, param] { + auto thread = new std::thread([thread_rout, param, name] { + plat_set_thread_name(NULL, name); thread_rout(param); }); return thread; diff --git a/src/unix/unix.c b/src/unix/unix.c index cfa824313..bbf7556ba 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -45,6 +45,9 @@ #include <86box/ui.h> #include <86box/gdbstub.h> +#define __USE_GNU 1 /* shouldn't be done, yet it is */ +#include + static int first_use = 1; static uint64_t StartingTime; static uint64_t Frequency; @@ -1379,6 +1382,23 @@ plat_get_cpu_string(char *outbuf, uint8_t len) { strncpy(outbuf, cpu_string, len); } +void +plat_set_thread_name(void *thread, const char *name) +{ +#ifdef __APPLE__ + char truncated[64]; +#else + char truncated[16]; +#endif + strncpy(truncated, name, sizeof(truncated) - 1); +#ifdef __APPLE__ + if (!thread) + pthread_setname_np(truncated); +#else + pthread_setname_np(thread ? (pthread_t) thread : pthread_self(), truncated); +#endif +} + /* Converts back the language code to LCID */ void plat_language_code_r(uint32_t lcid, char *outbuf, int len) diff --git a/src/unix/unix_thread.c b/src/unix/unix_thread.c index 0c2e9bf6b..a73d23225 100644 --- a/src/unix/unix_thread.c +++ b/src/unix/unix_thread.c @@ -32,7 +32,7 @@ thread_run_wrapper(thread_param *arg) } thread_t * -thread_create(void (*thread_rout)(void *param), void *param) +thread_create(void (*thread_rout)(void *param), void *param, const char *name) { pthread_t *thread = malloc(sizeof(pthread_t)); thread_param *thrparam = malloc(sizeof(thread_param)); @@ -40,6 +40,7 @@ thread_create(void (*thread_rout)(void *param), void *param) thrparam->param = param; pthread_create(thread, NULL, (void *(*) (void *) ) thread_run_wrapper, thrparam); + plat_set_thread_name(thread, name); return thread; } diff --git a/src/win/win.c b/src/win/win.c index 21ff6646c..7e752f90f 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -51,6 +51,7 @@ #include <86box/path.h> #define GLOBAL #include <86box/plat.h> +#include <86box/plat_dynld.h> #include <86box/thread.h> #include <86box/ui.h> #ifdef USE_VNC @@ -1276,6 +1277,35 @@ plat_get_cpu_string(char *outbuf, uint8_t len) { strncpy(outbuf, cpu_string, len); } +void +plat_set_thread_name(void *thread, const char *name) +{ + /* SetThreadDescription was added in 14393. Revisit if we ever start requiring 10. */ + static void *kernel32_handle = NULL; + static HRESULT(WINAPI *pSetThreadDescription)(HANDLE hThread, PCWSTR lpThreadDescription) = NULL; + static dllimp_t kernel32_imports[] = { + // clang-format off + { "SetThreadDescription", &pSetThreadDescription }, + { NULL, NULL } + // clang-format on + }; + + if (!kernel32_handle) { + kernel32_handle = dynld_module("kernel32.dll", kernel32_imports); + if (!kernel32_handle) { + kernel32_handle = kernel32_imports; /* dummy pointer to store that we tried */ + pSetThreadDescription = NULL; + } + } + + if (pSetThreadDescription) { + size_t len = strlen(name) + 1; + wchar_t wname[len]; + mbstowcs(wname, name, len); + pSetThreadDescription(thread ? (HANDLE) thread : GetCurrentThread(), wname); + } +} + void take_screenshot(void) { diff --git a/src/win/win_thread.c b/src/win/win_thread.c index faacca74f..db86e9204 100644 --- a/src/win/win_thread.c +++ b/src/win/win_thread.c @@ -37,9 +37,10 @@ typedef struct { } win_event_t; thread_t * -thread_create(void (*func)(void *param), void *param) +thread_create(void (*func)(void *param), void *param, const char *name) { uintptr_t bt = _beginthread(func, 0, param); + plat_set_thread_name(bt, name); return ((thread_t *) bt); } From 30043d7b00f9bc98839a44bbb115fe060fc80136 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 9 Jan 2024 20:20:18 -0300 Subject: [PATCH 250/936] Fix unix and win32 build without C++ threads --- src/unix/unix_thread.c | 2 +- src/win/win_thread.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/unix/unix_thread.c b/src/unix/unix_thread.c index a73d23225..9d989fb91 100644 --- a/src/unix/unix_thread.c +++ b/src/unix/unix_thread.c @@ -32,7 +32,7 @@ thread_run_wrapper(thread_param *arg) } thread_t * -thread_create(void (*thread_rout)(void *param), void *param, const char *name) +thread_create_named(void (*thread_rout)(void *param), void *param, const char *name) { pthread_t *thread = malloc(sizeof(pthread_t)); thread_param *thrparam = malloc(sizeof(thread_param)); diff --git a/src/win/win_thread.c b/src/win/win_thread.c index db86e9204..3136c029c 100644 --- a/src/win/win_thread.c +++ b/src/win/win_thread.c @@ -37,7 +37,7 @@ typedef struct { } win_event_t; thread_t * -thread_create(void (*func)(void *param), void *param, const char *name) +thread_create_named(void (*func)(void *param), void *param, const char *name) { uintptr_t bt = _beginthread(func, 0, param); plat_set_thread_name(bt, name); From 02a1a8ec1bd6a9b6ef34588a88a8d2c9e360f37a Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 9 Jan 2024 20:28:10 -0300 Subject: [PATCH 251/936] More non-cppthreads build fixes --- src/qt/qt_platform.cpp | 2 +- src/unix/unix.c | 2 +- src/unix/unix_thread.c | 2 +- src/win/win_thread.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 62325e780..09feb5f5e 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -783,7 +783,7 @@ plat_set_thread_name(void *thread, const char *name) if (!thread) pthread_setname_np(truncated); # else - pthread_setname_np(thread ? (pthread_t) thread : pthread_self(), truncated); + pthread_setname_np(thread ? *((pthread_t *) thread) : pthread_self(), truncated); # endif #endif } diff --git a/src/unix/unix.c b/src/unix/unix.c index bbf7556ba..62d3bd36d 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -1395,7 +1395,7 @@ plat_set_thread_name(void *thread, const char *name) if (!thread) pthread_setname_np(truncated); #else - pthread_setname_np(thread ? (pthread_t) thread : pthread_self(), truncated); + pthread_setname_np(thread ? *((pthread_t *) thread) : pthread_self(), truncated); #endif } diff --git a/src/unix/unix_thread.c b/src/unix/unix_thread.c index 9d989fb91..88ce01456 100644 --- a/src/unix/unix_thread.c +++ b/src/unix/unix_thread.c @@ -52,7 +52,7 @@ thread_wait(thread_t *arg) } event_t * -thread_create_event() +thread_create_event(void) { event_pthread_t *event = malloc(sizeof(event_pthread_t)); diff --git a/src/win/win_thread.c b/src/win/win_thread.c index 3136c029c..e874c4941 100644 --- a/src/win/win_thread.c +++ b/src/win/win_thread.c @@ -40,7 +40,7 @@ thread_t * thread_create_named(void (*func)(void *param), void *param, const char *name) { uintptr_t bt = _beginthread(func, 0, param); - plat_set_thread_name(bt, name); + plat_set_thread_name((void *) bt, name); return ((thread_t *) bt); } From 009139c9023c90e8e00c31a2f467f64a2f39b755 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 10 Jan 2024 00:43:17 +0100 Subject: [PATCH 252/936] IDE: Reset the reset flag to 0 for all affected devices in ide_board_callback(), fixes #4014. --- src/disk/hdc_ide.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index b47bfaf70..39031138f 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -1784,7 +1784,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ide->tf->error = ABRT_ERR; ide_irq_raise(ide); } - return; + break; default: break; @@ -2096,6 +2096,8 @@ ide_board_callback(void *priv) ide->tf->atastat |= DRDY_STAT | DSC_STAT; } else ide->tf->atastat = DRDY_STAT | DSC_STAT; + + ide->reset = 0; } ide = dev->ide[0]; From d125caf776c837fd2e9da46a4d19d68b8b6ab068 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 10 Jan 2024 09:27:07 +0100 Subject: [PATCH 253/936] Applied the blanking extensions to S3 Trio64V+ and V2/DX. --- src/video/vid_s3.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index dcb251f02..3b3cebe8d 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -4018,7 +4018,7 @@ s3_trio64v_recalctimings(svga_t *svga) svga->htotal |= 0x100; if (svga->crtc[0x5d] & 0x02) { svga->hdisp_time |= 0x100; - svga->hdisp |= 0x100 * ((svga->seqregs[1] & 8) ? 16 : 8); + svga->hdisp |= 0x100 * svga->dots_per_clock; } if (svga->crtc[0x5e] & 0x01) svga->vtotal |= 0x400; @@ -4146,6 +4146,24 @@ s3_trio64v_recalctimings(svga_t *svga) break; } } + + 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); + } + + if (svga->crtc[0x5d] & 0x04) + svga->hblankstart += 0x100; + + /* NOTE: The S3 Trio64V+ datasheet says this is bit 7, but then where is bit 6? + The datasheets for the pre-Trio64V+ cards say +64, which implies bit 6, + and, contrary to VGADOC, it also exists on Trio32, Trio64, Vision868, + and Vision968. */ + if (svga->crtc[0x5d] & 0x08) + svga->hblank_ext = 0x40; + svga->hblank_end_len = 0x00000040; + + svga->hblank_overscan = !(svga->crtc[0x33] & 0x20); } static void From 23039a35b49f1fc98ea65d1d05e9127e8fbd0aba Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 10 Jan 2024 10:27:11 -0300 Subject: [PATCH 254/936] More thread name clean-ups --- src/qt/qt_platform.cpp | 9 +++++---- src/unix/unix.c | 5 +++-- src/win/win.c | 4 ++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 09feb5f5e..6890bd407 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -761,27 +761,28 @@ plat_set_thread_name(void *thread, const char *name) if (!kernel32_handle) { kernel32_handle = dynld_module("kernel32.dll", kernel32_imports); if (!kernel32_handle) { - kernel32_handle = kernel32_imports; /* dummy pointer to store that we tried */ + kernel32_handle = kernel32_imports; /* store dummy pointer to avoid trying again */ pSetThreadDescription = NULL; } } if (pSetThreadDescription) { size_t len = strlen(name) + 1; - wchar_t wname[len]; + wchar_t wname[len + 1]; mbstowcs(wname, name, len); pSetThreadDescription(thread ? (HANDLE) thread : GetCurrentThread(), wname); } #else # ifdef Q_OS_DARWIN + if (thread) /* Apple pthread can only set self's name */ + return; char truncated[64]; # else char truncated[16]; # endif strncpy(truncated, name, sizeof(truncated) - 1); # ifdef Q_OS_DARWIN - if (!thread) - pthread_setname_np(truncated); + pthread_setname_np(truncated); # else pthread_setname_np(thread ? *((pthread_t *) thread) : pthread_self(), truncated); # endif diff --git a/src/unix/unix.c b/src/unix/unix.c index 62d3bd36d..4f21ddd53 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -1386,14 +1386,15 @@ void plat_set_thread_name(void *thread, const char *name) { #ifdef __APPLE__ + if (thread) /* Apple pthread can only set self's name */ + return; char truncated[64]; #else char truncated[16]; #endif strncpy(truncated, name, sizeof(truncated) - 1); #ifdef __APPLE__ - if (!thread) - pthread_setname_np(truncated); + pthread_setname_np(truncated); #else pthread_setname_np(thread ? *((pthread_t *) thread) : pthread_self(), truncated); #endif diff --git a/src/win/win.c b/src/win/win.c index 7e752f90f..d77ab32fd 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -1293,14 +1293,14 @@ plat_set_thread_name(void *thread, const char *name) if (!kernel32_handle) { kernel32_handle = dynld_module("kernel32.dll", kernel32_imports); if (!kernel32_handle) { - kernel32_handle = kernel32_imports; /* dummy pointer to store that we tried */ + kernel32_handle = kernel32_imports; /* store dummy pointer to avoid trying again */ pSetThreadDescription = NULL; } } if (pSetThreadDescription) { size_t len = strlen(name) + 1; - wchar_t wname[len]; + wchar_t wname[len + 1]; mbstowcs(wname, name, len); pSetThreadDescription(thread ? (HANDLE) thread : GetCurrentThread(), wname); } From 8e9a2e0b79168e85fa6080ceb473e6658671d8ce Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 11 Jan 2024 01:48:49 +0600 Subject: [PATCH 255/936] Apply blanking extensions to more SVGA cards. * Fix duplicated logic in vid_svga.c * Voodoo 3/Banshee emulation now has blanking extensions applied * S3 ViRGE and Matrox video cards as well * Tseng ET4000-series cards as well * Fix off-by-one error in vid_cl54xx.c Trident cards are yet to be investigated. XGA and 8514/A are yet to be made blanking extensions compliant. Mach64, Paradise/WDC and OAK OTI cards remain as-is for now. --- src/video/vid_cl54xx.c | 6 +++++- src/video/vid_et4000.c | 2 ++ src/video/vid_et4000w32.c | 2 ++ src/video/vid_mga.c | 9 +++++++++ src/video/vid_s3.c | 10 +++++----- src/video/vid_s3_virge.c | 16 +++++++++++++++- src/video/vid_svga.c | 2 -- src/video/vid_voodoo_banshee.c | 6 ++++++ 8 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index caac05fc7..738e67607 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -1950,7 +1950,7 @@ gd54xx_recalctimings(svga_t *svga) and the actual blanking comes from the display enable signal. */ /* Start blanking at the first character clock after the last active one. */ svga->hblankstart = svga->crtc[1] + 1; - svga->hblank_end_val = (svga->htotal + 6) & 0x3f; + svga->hblank_end_val = (svga->htotal + 5) & 0xff; /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ if (!svga->scrblank && svga->attr_palette_enable) svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; @@ -1958,6 +1958,10 @@ gd54xx_recalctimings(svga_t *svga) svga->hblank_overscan = 0; /* Also make sure vertical blanking starts on display end. */ svga->vblankstart = svga->dispend; + + /* Account for horizontal overflow bits. */ + svga->hblank_end_val += (svga->crtc[0x1a] & 0x30) << 2; + svga->hblank_end_len = 0x100; } if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index faf977d7c..882a3e12e 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -613,6 +613,8 @@ et4000_recalctimings(svga_t *svga) svga->rowoffset = 0x100; if (svga->crtc[0x3f] & 1) svga->htotal += 256; + if (svga->crtc[0x3f] & 0x04) + svga->hblankstart += 0x100; if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1; diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index b9c146d89..0133b728b 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -445,6 +445,8 @@ et4000w32p_recalctimings(svga_t *svga) svga->rowoffset += 0x100; if (svga->crtc[0x3F] & 0x01) svga->htotal += 256; + if (svga->crtc[0x3F] & 0x04) + svga->hblankstart += 0x100; if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index ccbf1c1b3..9fa9e9389 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -192,6 +192,8 @@ #define CRTCX_R0_OFFSET_MASK (3 << 4) #define CRTCX_R1_HTOTAL8 (1 << 0) +#define CRTCX_R1_HBLKSTRT8 (1 << 1) +#define CRTCX_R1_HBLKEND6 (1 << 6) #define CRTCX_R2_VTOTAL10 (1 << 0) #define CRTCX_R2_VTOTAL11 (1 << 1) @@ -941,6 +943,8 @@ mystique_recalctimings(svga_t *svga) if (mystique->crtcext_regs[1] & CRTCX_R1_HTOTAL8) svga->htotal |= 0x100; + if (mystique->crtcext_regs[1] & CRTCX_R1_HBLKSTRT8) + svga->hblankstart += 0x100; if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL10) svga->vtotal |= 0x400; if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL11) @@ -971,6 +975,11 @@ mystique_recalctimings(svga_t *svga) svga->hdisp_time = svga->hdisp; svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); + svga->hblank_end_len = 0x80; + svga->hblank_end_val += mystique->crtcext_regs[1] & CRTCX_R1_HBLKEND6; + + svga->hblank_overscan = 0; + if (mystique->type != MGA_2164W && mystique->type != MGA_2064W) svga->lut_map = !!(mystique->xmiscctrl & XMISCCTRL_RAMCS); diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 3b3cebe8d..6f648f628 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -4013,6 +4013,11 @@ s3_trio64v_recalctimings(svga_t *svga) s3_t *s3 = (s3_t *) svga->priv; int clk_sel = (svga->miscout >> 2) & 3; + 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); + } + svga->hdisp = svga->hdisp_old; if (svga->crtc[0x5d] & 0x01) svga->htotal |= 0x100; @@ -4147,11 +4152,6 @@ s3_trio64v_recalctimings(svga_t *svga) } } - 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); - } - if (svga->crtc[0x5d] & 0x04) svga->hblankstart += 0x100; diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index ce9dda100..76195189f 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -778,11 +778,16 @@ s3_virge_recalctimings(svga_t *svga) svga->hdisp = svga->hdisp_old; + 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); + } + if (svga->crtc[0x5d] & 0x01) svga->htotal += 0x100; if (svga->crtc[0x5d] & 0x02) { svga->hdisp_time += 0x100; - svga->hdisp += 0x100 * ((svga->seqregs[1] & 8) ? 16 : 8); + svga->hdisp += 0x100 * svga->dots_per_clock; } if (svga->crtc[0x5e] & 0x01) svga->vtotal += 0x400; @@ -906,6 +911,15 @@ s3_virge_recalctimings(svga_t *svga) } svga->vram_display_mask = virge->vram_mask; } + + if (svga->crtc[0x5d] & 0x04) + svga->hblankstart += 0x100; + + if (svga->crtc[0x5d] & 0x08) + svga->hblank_ext = 0x40; + svga->hblank_end_len = 0x00000040; + + svga->hblank_overscan = !(svga->crtc[0x33] & 0x20); } static void diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 975296e08..a350b6d28 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -738,7 +738,6 @@ svga_recalctimings(svga_t *svga) } else svga->monitor->mon_overscan_x = 16; - svga->htotal = svga->crtc[0]; svga->hblankstart = svga->crtc[4] + 1; svga->hblank_end_val = (svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00); #if 0 @@ -767,7 +766,6 @@ svga_recalctimings(svga_t *svga) if (xga_active && (svga->xga != NULL)) xga_recalctimings(svga); - svga->htotal += 6; /*+6 is required for Tyrian*/ svga->hblankend = (svga->hblankstart & ~(svga->hblank_end_len - 1)) | svga->hblank_end_val; if (svga->hblankend <= svga->hblankstart) svga->hblankend += svga->hblank_end_len; diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 23236be6f..e10337928 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -552,6 +552,10 @@ banshee_recalctimings(svga_t *svga) svga->htotal += 0x100; if (svga->crtc[0x1a] & 0x04) svga->hdisp += 0x100; + if (svga->crtc[0x1a] & 0x10) + svga->hblankstart += 0x100; + if (svga->crtc[0x1a] & 0x20) + svga->hblank_end_val += 0x40; /*6 R/W Vertical Retrace Start bit 10 0x10 5 R/W Reserved. - 4 R/W Vertical Blank Start bit 10. 0x15 @@ -611,6 +615,8 @@ banshee_recalctimings(svga_t *svga) svga->char_width = 8; svga->split = 99999; + svga->hblank_end_len = 0x80; + if (banshee->vidProcCfg & VIDPROCCFG_2X_MODE) { svga->hdisp *= 2; svga->htotal *= 2; From 03a1f783f2234fad6c35e0d7ea199043736f3d3e Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 10 Jan 2024 22:41:13 +0100 Subject: [PATCH 256/936] ATi Mach64: Override (S)VGA horizontal blanking calculation in accelerator CRTC mode. --- src/video/vid_ati_mach64.c | 2 ++ src/video/vid_svga.c | 20 +++++++++++--------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index da1b5d556..587341538 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -510,6 +510,7 @@ mach64_recalctimings(svga_t *svga) const mach64_t *mach64 = (mach64_t *) svga->priv; if (((mach64->crtc_gen_cntl >> 24) & 3) == 3) { + svga->hoverride = 1; svga->vtotal = (mach64->crtc_v_total_disp & 2047) + 1; svga->dispend = ((mach64->crtc_v_total_disp >> 16) & 2047) + 1; svga->htotal = (mach64->crtc_h_total_disp & 255) + 1; @@ -566,6 +567,7 @@ mach64_recalctimings(svga_t *svga) svga->vram_display_mask = mach64->vram_mask; } else { + svga->hoverride = 0; svga->vram_display_mask = (mach64->regs[0x36] & 0x01) ? mach64->vram_mask : 0x3ffff; } } diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index a350b6d28..ff8dbbbea 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -766,17 +766,19 @@ svga_recalctimings(svga_t *svga) if (xga_active && (svga->xga != NULL)) xga_recalctimings(svga); - svga->hblankend = (svga->hblankstart & ~(svga->hblank_end_len - 1)) | svga->hblank_end_val; - if (svga->hblankend <= svga->hblankstart) - svga->hblankend += svga->hblank_end_len; - svga->hblankend += svga->hblank_ext; + if (!svga->hoverride) { + svga->hblankend = (svga->hblankstart & ~(svga->hblank_end_len - 1)) | svga->hblank_end_val; + if (svga->hblankend <= svga->hblankstart) + svga->hblankend += svga->hblank_end_len; + svga->hblankend += svga->hblank_ext; - svga->hblank_sub = 0; - if (svga->hblankend > svga->htotal) { - svga->hblankend &= (svga->hblank_end_len - 1); - svga->hblank_sub = svga->hblankend + svga->hblank_overscan; + svga->hblank_sub = 0; + if (svga->hblankend > svga->htotal) { + svga->hblankend &= (svga->hblank_end_len - 1); + svga->hblank_sub = svga->hblankend + svga->hblank_overscan; - svga->hdisp -= (svga->hblank_sub * svga->dots_per_clock); + svga->hdisp -= (svga->hblank_sub * svga->dots_per_clock); + } } if (svga->hdisp >= 2048) From 0090000f850d15a6259d79a51ff10f3eeed8f81d Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 10 Jan 2024 23:25:16 +0100 Subject: [PATCH 257/936] HT216-32: Apply the blanking calculation. --- src/video/vid_ht216.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index 9cd68e4ee..803d5658c 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -312,6 +312,10 @@ ht216_out(uint16_t addr, uint8_t val, void *priv) ht216_remap(ht216); break; + case 0xca: + svga_recalctimings(svga); + break; + case 0xc9: case 0xcf: ht216_remap(ht216); @@ -321,6 +325,7 @@ ht216_out(uint16_t addr, uint8_t val, void *priv) svga->adv_flags &= ~FLAG_RAMDAC_SHIFT; if (val & 0x04) svga->adv_flags |= FLAG_RAMDAC_SHIFT; + svga_recalctimings(svga); fallthrough; /*Bank registers*/ case 0xe8: @@ -688,7 +693,7 @@ ht216_recalctimings(svga_t *svga) if (!(svga->crtc[1] & 1)) svga->hdisp--; svga->hdisp++; - svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; + svga->hdisp *= svga->dots_per_clock; svga->rowoffset <<= 1; if ((svga->crtc[0x17] & 0x60) == 0x20) /*Would result in a garbled screen with trailing cursor glitches*/ svga->crtc[0x17] |= 0x40; @@ -711,6 +716,9 @@ ht216_recalctimings(svga_t *svga) svga->vram_display_mask = 0x7ffff; else svga->vram_display_mask = (ht216->ht_regs[0xf6] & 0x40) ? ht216->vram_mask : 0x3ffff; + + if (ht216->ht_regs[0xe0] & 0x20) + svga->hblankstart = ((ht216->ht_regs[0xca] >> 2) << 8) + svga->crtc[4] + 1; } static void @@ -1466,9 +1474,8 @@ radius_mca_feedb(UNUSED(void *priv)) return 1; } -void - * - ht216_init(const device_t *info, uint32_t mem_size, int has_rom) +void * +ht216_init(const device_t *info, uint32_t mem_size, int has_rom) { ht216_t *ht216 = malloc(sizeof(ht216_t)); svga_t *svga; From d00dafcf16cc8416901f9a9a1612750afb5ba0d1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 10 Jan 2024 23:30:48 +0100 Subject: [PATCH 258/936] Apply it to ATi 28800 and Mach 8 as well. --- src/video/vid_ati28800.c | 7 +++++++ src/video/vid_ati_mach8.c | 3 +++ 2 files changed, 10 insertions(+) diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index 09d6279f4..aed95b243 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -136,6 +136,10 @@ ati28800_out(uint16_t addr, uint8_t val, void *priv) if ((old ^ val) & 0x80) svga_recalctimings(svga); break; + case 0xad: + if ((old ^ val) & 0x0c) + svga_recalctimings(svga); + break; case 0xb0: if ((old ^ val) & 0x60) svga_recalctimings(svga); @@ -492,6 +496,9 @@ ati28800_recalctimings(svga_t *svga) } } } + + if (ati28800->regs[0xad] & 0x08) + svga->hblankstart = ((ati28800->regs[0x0d] >> 2) << 8) + svga->crtc[4] + 1; } static void diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 21f6abd29..92ee59e19 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2841,6 +2841,9 @@ mach_recalctimings(svga_t *svga) } } } + + if (ati28800->regs[0xad] & 0x08) + svga->hblankstart = ((ati28800->regs[0x0d] >> 2) << 8) + svga->crtc[4] + 1; } static void From b159ec07bf4e12601460ec9563a4f19d3272f045 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 10 Jan 2024 23:33:08 +0100 Subject: [PATCH 259/936] And vid_svga.h. --- src/include/86box/vid_svga.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 7ba637167..880f79003 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -274,6 +274,9 @@ typedef struct svga_t { /* Enable LUT mapping of >= 24 bpp modes. */ int lut_map; + /* Override the horizontal blanking stuff. */ + int hoverride; + /* Return a 32 bpp color from a 15/16 bpp color. */ uint32_t (*conv_16to32)(struct svga_t *svga, uint16_t color, uint8_t bpp); From fe52ecc3da8f0f6dbcaee7e006b7013e168ad628 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 10 Jan 2024 23:44:27 +0100 Subject: [PATCH 260/936] GreaseMonkey's comments in vid_svga.c. --- src/video/vid_svga.c | 67 +++++++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 20 deletions(-) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index ff8dbbbea..d092c849e 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -640,11 +640,20 @@ svga_recalctimings(svga_t *svga) svga->hdisp_time = svga->hdisp; svga->render = svga_render_blank; if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { - /* TODO: In case of bug reports, disable 9-dots-wide character clocks in graphics modes. */ - if (svga->seqregs[1] & 8) - svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ + if (svga->seqregs[1] & 8) + svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; + else + svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; else - svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; + /*RESEARCH TOPIC: Which chipsets honour 9-dot mode in graphics mode? + One still gets an 8-dot input, but is likely to get some weird chaining through the graphics controller. + Chipsets which honour it, and do an extra pixel (or two, or four) of chaining through the GC pixel shift registers: + - (none found so far) + Chipsets which treat it like it's in 8-dot mode, and affect the monitor timings in the process: + - S3 Trio64V2/DX + */ + svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ if (svga->seqregs[1] & 8) { /*40 column*/ @@ -747,11 +756,20 @@ svga_recalctimings(svga_t *svga) svga->hblank_overscan = 1; if (!svga->scrblank && svga->attr_palette_enable) { - /* TODO: In case of bug reports, disable 9-dots-wide character clocks in graphics modes. */ - if (svga->seqregs[1] & 8) - svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18); + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ + if (svga->seqregs[1] & 8) + svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18); + else + svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 8 : 9); else - svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 8 : 9); + /*RESEARCH TOPIC: Which chipsets honour 9-dot mode in graphics mode? + One still gets an 8-dot input, but is likely to get some weird chaining through the graphics controller. + Chipsets which honour it, and do an extra pixel (or two, or four) of chaining through the GC pixel shift registers: + - (none found so far) + Chipsets which treat it like it's in 8-dot mode, and affect the monitor timings in the process: + - S3 Trio64V2/DX + */ + svga->dots_per_clock = ((svga->seqregs[1] & 8) ? 16 : 8); } else svga->dots_per_clock = 1; @@ -766,19 +784,17 @@ svga_recalctimings(svga_t *svga) if (xga_active && (svga->xga != NULL)) xga_recalctimings(svga); - if (!svga->hoverride) { - svga->hblankend = (svga->hblankstart & ~(svga->hblank_end_len - 1)) | svga->hblank_end_val; - if (svga->hblankend <= svga->hblankstart) - svga->hblankend += svga->hblank_end_len; - svga->hblankend += svga->hblank_ext; + svga->hblankend = (svga->hblankstart & ~(svga->hblank_end_len - 1)) | svga->hblank_end_val; + if (svga->hblankend <= svga->hblankstart) + svga->hblankend += svga->hblank_end_len; + svga->hblankend += svga->hblank_ext; - svga->hblank_sub = 0; - if (svga->hblankend > svga->htotal) { - svga->hblankend &= (svga->hblank_end_len - 1); - svga->hblank_sub = svga->hblankend + svga->hblank_overscan; + svga->hblank_sub = 0; + if (svga->hblankend > svga->htotal) { + svga->hblankend &= (svga->hblank_end_len - 1); + svga->hblank_sub = svga->hblankend + svga->hblank_overscan; - svga->hdisp -= (svga->hblank_sub * svga->dots_per_clock); - } + svga->hdisp -= (svga->hblank_sub * svga->dots_per_clock); } if (svga->hdisp >= 2048) @@ -1060,6 +1076,17 @@ svga_poll(void *priv) ret = svga->line_compare(svga); if (ret) { + /*NOTE ON CHARACTER SKEW VALUES: + - CR03 delays the start and end of active video, while continuing to clock things as usual. + This effectively hides N character clocks on the left, and reveals N character clocks on the right. + - CR05 delays the horizontal retrace (HSYNC) signal. It affects the position of the displayed image on the monitor. + Since 86Box at the time of writing (2024-01-10) does not support overscan for anything other than showing the border, + there should be no effect. + - CR0B delays the position of the cursor by a number of character clocks. + So how do the INT 0x10 modes work? + - EGA has some rather interesting values for all of this which can make for interesting research. + - VGA and all of a few SVGA chipsets sampled uses 0 for everything except CR05 in the two 40x25 text modes where it uses 1. + */ if (svga->interlace && svga->oddeven) svga->ma = svga->maback = (svga->rowoffset << 1) + ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub; else @@ -1133,7 +1160,7 @@ svga_poll(void *priv) svga->vslines = 0; if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + + svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub; else svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub; From c4aa4e888995054aef852d441bfc9d16bb3ab105 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 11 Jan 2024 01:56:32 +0100 Subject: [PATCH 261/936] A minor change to video/vid_svga.c. --- src/video/vid_svga.c | 74 ++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 50 deletions(-) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index d092c849e..142037696 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -640,20 +640,11 @@ svga_recalctimings(svga_t *svga) svga->hdisp_time = svga->hdisp; svga->render = svga_render_blank; if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ - if (svga->seqregs[1] & 8) - svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; - else - svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; + /* TODO: In case of bug reports, disable 9-dots-wide character clocks in graphics modes. */ + if (svga->seqregs[1] & 8) + svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; else - /*RESEARCH TOPIC: Which chipsets honour 9-dot mode in graphics mode? - One still gets an 8-dot input, but is likely to get some weird chaining through the graphics controller. - Chipsets which honour it, and do an extra pixel (or two, or four) of chaining through the GC pixel shift registers: - - (none found so far) - Chipsets which treat it like it's in 8-dot mode, and affect the monitor timings in the process: - - S3 Trio64V2/DX - */ - svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; + svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ if (svga->seqregs[1] & 8) { /*40 column*/ @@ -749,27 +740,19 @@ svga_recalctimings(svga_t *svga) svga->hblankstart = svga->crtc[4] + 1; svga->hblank_end_val = (svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00); -#if 0 - pclog("htotal = %i, hblankstart = %i, hblank_end_val = %02X\n", svga->htotal, svga->hblankstart, svga->hblank_end_val); -#endif + + svga_log("htotal = %i, hblankstart = %i, hblank_end_val = %02X\n", + svga->htotal, svga->hblankstart, svga->hblank_end_val); + svga->hblank_end_len = 0x00000040; svga->hblank_overscan = 1; if (!svga->scrblank && svga->attr_palette_enable) { - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ - if (svga->seqregs[1] & 8) - svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18); - else - svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 8 : 9); + /* TODO: In case of bug reports, disable 9-dots-wide character clocks in graphics modes. */ + if (svga->seqregs[1] & 8) + svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18); else - /*RESEARCH TOPIC: Which chipsets honour 9-dot mode in graphics mode? - One still gets an 8-dot input, but is likely to get some weird chaining through the graphics controller. - Chipsets which honour it, and do an extra pixel (or two, or four) of chaining through the GC pixel shift registers: - - (none found so far) - Chipsets which treat it like it's in 8-dot mode, and affect the monitor timings in the process: - - S3 Trio64V2/DX - */ - svga->dots_per_clock = ((svga->seqregs[1] & 8) ? 16 : 8); + svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 8 : 9); } else svga->dots_per_clock = 1; @@ -784,17 +767,19 @@ svga_recalctimings(svga_t *svga) if (xga_active && (svga->xga != NULL)) xga_recalctimings(svga); - svga->hblankend = (svga->hblankstart & ~(svga->hblank_end_len - 1)) | svga->hblank_end_val; - if (svga->hblankend <= svga->hblankstart) - svga->hblankend += svga->hblank_end_len; - svga->hblankend += svga->hblank_ext; + if (!svga->hoverride) { + svga->hblankend = (svga->hblankstart & ~(svga->hblank_end_len - 1)) | svga->hblank_end_val; + if (svga->hblankend <= svga->hblankstart) + svga->hblankend += svga->hblank_end_len; + svga->hblankend += svga->hblank_ext; - svga->hblank_sub = 0; - if (svga->hblankend > svga->htotal) { - svga->hblankend &= (svga->hblank_end_len - 1); - svga->hblank_sub = svga->hblankend + svga->hblank_overscan; + svga->hblank_sub = 0; + if (svga->hblankend > svga->htotal) { + svga->hblankend &= (svga->hblank_end_len - 1); + svga->hblank_sub = svga->hblankend + svga->hblank_overscan; - svga->hdisp -= (svga->hblank_sub * svga->dots_per_clock); + svga->hdisp -= (svga->hblank_sub * svga->dots_per_clock); + } } if (svga->hdisp >= 2048) @@ -1076,17 +1061,6 @@ svga_poll(void *priv) ret = svga->line_compare(svga); if (ret) { - /*NOTE ON CHARACTER SKEW VALUES: - - CR03 delays the start and end of active video, while continuing to clock things as usual. - This effectively hides N character clocks on the left, and reveals N character clocks on the right. - - CR05 delays the horizontal retrace (HSYNC) signal. It affects the position of the displayed image on the monitor. - Since 86Box at the time of writing (2024-01-10) does not support overscan for anything other than showing the border, - there should be no effect. - - CR0B delays the position of the cursor by a number of character clocks. - So how do the INT 0x10 modes work? - - EGA has some rather interesting values for all of this which can make for interesting research. - - VGA and all of a few SVGA chipsets sampled uses 0 for everything except CR05 in the two 40x25 text modes where it uses 1. - */ if (svga->interlace && svga->oddeven) svga->ma = svga->maback = (svga->rowoffset << 1) + ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub; else @@ -1160,7 +1134,7 @@ svga_poll(void *priv) svga->vslines = 0; if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + + svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub; else svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub; From 3010ce4f8ab7e1a06dfa6d9b211d793ae1fcd426 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 11 Jan 2024 02:07:21 +0100 Subject: [PATCH 262/936] Minor ATi fixes. --- src/video/vid_ati28800.c | 9 +++++++-- src/video/vid_ati_mach8.c | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index aed95b243..c2ede4d45 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -407,7 +407,8 @@ ati28800_recalctimings(svga_t *svga) ati28800_t *ati28800 = (ati28800_t *) svga->priv; int clock_sel; - clock_sel = ((svga->miscout >> 2) & 3) | ((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1); + clock_sel = ((svga->miscout >> 2) & 3) | ((ati28800->regs[0xbe] & 0x10) >> 1) | + ((ati28800->regs[0xb9] & 2) << 1); if (ati28800->regs[0xa3] & 0x10) svga->ma_latch |= 0x10000; @@ -447,7 +448,11 @@ ati28800_recalctimings(svga_t *svga) if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen); - ati28800_log("SEQREG1 bit 3=%x. gdcreg5 bits 5-6=%02x, 4bit pel=%02x, planar 16color=%02x, apa mode=%02x, attregs10 bit 7=%02x.\n", svga->seqregs[1] & 8, svga->gdcreg[5] & 0x60, ati28800->regs[0xb3] & 0x40, ati28800->regs[0xac] & 0x40, ati28800->regs[0xb6] & 0x18, ati28800->svga.attrregs[0x10] & 0x80); + ati28800_log("SEQREG1 bit 3=%x. gdcreg5 bits 5-6=%02x, 4bit pel=%02x, " + "planar 16color=%02x, apa mode=%02x, attregs10 bit 7=%02x.\n", + svga->seqregs[1] & 8, svga->gdcreg[5] & 0x60, + ati28800->regs[0xb3] & 0x40, ati28800->regs[0xac] & 0x40, + ati28800->regs[0xb6] & 0x18, ati28800->svga.attrregs[0x10] & 0x80); switch (svga->gdcreg[5] & 0x60) { case 0x00: if (svga->seqregs[1] & 8) /*Low res (320)*/ diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 92ee59e19..365a03cee 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2842,8 +2842,8 @@ mach_recalctimings(svga_t *svga) } } - if (ati28800->regs[0xad] & 0x08) - svga->hblankstart = ((ati28800->regs[0x0d] >> 2) << 8) + svga->crtc[4] + 1; + if (mach->regs[0xad] & 0x08) + svga->hblankstart = ((mach->regs[0x0d] >> 2) << 8) + svga->crtc[4] + 1; } static void From 553e58f8efb399f96164e9de7f218606656ca644 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 11 Jan 2024 02:11:23 +0100 Subject: [PATCH 263/936] Remove an unnecessary subtraction proven to be wrong by the S3 and IBM documentation and that was a result of VGADOC being vague. --- src/video/vid_svga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 142037696..39d6a2e22 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -617,7 +617,7 @@ svga_recalctimings(svga_t *svga) svga->vblankstart |= 0x200; svga->vblankstart++; - svga->hdisp = svga->crtc[1] - ((svga->crtc[3] & 0x60) >> 5); + svga->hdisp = svga->crtc[1]; svga->hdisp++; svga->htotal = svga->crtc[0]; From 2b3ebf9101347640235470f32b2ff8de75f8e07c Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 11 Jan 2024 11:08:11 +0600 Subject: [PATCH 264/936] vid_cl54xx: Revert changes made to special blanking mode --- src/video/vid_cl54xx.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 738e67607..e960e631c 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -1950,7 +1950,7 @@ gd54xx_recalctimings(svga_t *svga) and the actual blanking comes from the display enable signal. */ /* Start blanking at the first character clock after the last active one. */ svga->hblankstart = svga->crtc[1] + 1; - svga->hblank_end_val = (svga->htotal + 5) & 0xff; + svga->hblank_end_val = (svga->htotal + 5) & 0x3f; /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ if (!svga->scrblank && svga->attr_palette_enable) svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; @@ -1958,10 +1958,6 @@ gd54xx_recalctimings(svga_t *svga) svga->hblank_overscan = 0; /* Also make sure vertical blanking starts on display end. */ svga->vblankstart = svga->dispend; - - /* Account for horizontal overflow bits. */ - svga->hblank_end_val += (svga->crtc[0x1a] & 0x30) << 2; - svga->hblank_end_len = 0x100; } if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ From cd0636ee0434b8f6068b5962f825d5f79777e694 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 11 Jan 2024 14:42:54 +0100 Subject: [PATCH 265/936] Fixed horizontal retrace start and end extensions on almost every applicable card, fixes #4025. --- src/video/vid_et4000.c | 4 +- src/video/vid_et4000w32.c | 4 +- src/video/vid_mga.c | 9 +++-- src/video/vid_s3.c | 18 ++++----- src/video/vid_s3_virge.c | 12 +++--- src/video/vid_voodoo_banshee.c | 68 +++++++++++++++++----------------- 6 files changed, 56 insertions(+), 59 deletions(-) diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 882a3e12e..1b868ecd7 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -613,11 +613,11 @@ et4000_recalctimings(svga_t *svga) svga->rowoffset = 0x100; if (svga->crtc[0x3f] & 1) svga->htotal += 256; - if (svga->crtc[0x3f] & 0x04) - svga->hblankstart += 0x100; if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1; + svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[4] + 1; + switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x34] << 1) & 4)) { case 0: case 1: diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 0133b728b..3ba134342 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -445,11 +445,11 @@ et4000w32p_recalctimings(svga_t *svga) svga->rowoffset += 0x100; if (svga->crtc[0x3F] & 0x01) svga->htotal += 256; - if (svga->crtc[0x3F] & 0x04) - svga->hblankstart += 0x100; if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1; + svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[4] + 1; + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((svga->miscout >> 2) & 3, svga->clock_gen); if (et4000->type != ET4000W32P_DIAMOND) { diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 9fa9e9389..d386bdb71 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -943,8 +943,9 @@ mystique_recalctimings(svga_t *svga) if (mystique->crtcext_regs[1] & CRTCX_R1_HTOTAL8) svga->htotal |= 0x100; - if (mystique->crtcext_regs[1] & CRTCX_R1_HBLKSTRT8) - svga->hblankstart += 0x100; + + svga->hblankstart = (((mystique->crtcext_regs[1] & 0x04) >> 2) << 8) + svga->crtc[4] + 1; + if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL10) svga->vtotal |= 0x400; if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL11) @@ -975,8 +976,8 @@ mystique_recalctimings(svga_t *svga) svga->hdisp_time = svga->hdisp; svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); - svga->hblank_end_len = 0x80; - svga->hblank_end_val += mystique->crtcext_regs[1] & CRTCX_R1_HBLKEND6; + svga->hblank_end_val = (mystique->crtcext_regs[1] & 0x40) | (svga->crtc[3] & 0x1f) | + ((svga->crtc[5] & 0x80) ? 0x20 : 0x00); svga->hblank_overscan = 0; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 6f648f628..073b8523f 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3988,6 +3988,8 @@ s3_recalctimings(svga_t *svga) svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18); } + svga->hblankstart = (((svga->crtc[0x5d] & 0x10) >> 4) << 8) + svga->crtc[4] + 1; + if (svga->crtc[0x5d] & 0x04) svga->hblankstart += 0x100; if (s3->chip >= S3_VISION964) { @@ -3995,12 +3997,8 @@ s3_recalctimings(svga_t *svga) The datasheets for the pre-Trio64V+ cards say +64, which implies bit 6, and, contrary to VGADOC, it also exists on Trio32, Trio64, Vision868, and Vision968. */ -#if 0 - pclog("svga->crtc[0x5d] = %02X\n", svga->crtc[0x5d]); -#endif - if (svga->crtc[0x5d] & 0x08) - svga->hblank_ext = 0x40; - svga->hblank_end_len = 0x00000040; + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | + (((svga->crtc[0x5d] & 0x08) >> 3) << 6); } } @@ -4152,16 +4150,14 @@ s3_trio64v_recalctimings(svga_t *svga) } } - if (svga->crtc[0x5d] & 0x04) - svga->hblankstart += 0x100; + svga->hblankstart = (((svga->crtc[0x5d] & 0x10) >> 4) << 8) + svga->crtc[4] + 1; /* NOTE: The S3 Trio64V+ datasheet says this is bit 7, but then where is bit 6? The datasheets for the pre-Trio64V+ cards say +64, which implies bit 6, and, contrary to VGADOC, it also exists on Trio32, Trio64, Vision868, and Vision968. */ - if (svga->crtc[0x5d] & 0x08) - svga->hblank_ext = 0x40; - svga->hblank_end_len = 0x00000040; + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | + (((svga->crtc[0x5d] & 0x08) >> 3) << 6); svga->hblank_overscan = !(svga->crtc[0x33] & 0x20); } diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 76195189f..f398aa80b 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -911,13 +911,11 @@ s3_virge_recalctimings(svga_t *svga) } svga->vram_display_mask = virge->vram_mask; } - - if (svga->crtc[0x5d] & 0x04) - svga->hblankstart += 0x100; - - if (svga->crtc[0x5d] & 0x08) - svga->hblank_ext = 0x40; - svga->hblank_end_len = 0x00000040; + + svga->hblankstart = (((svga->crtc[0x5d] & 0x10) >> 4) << 8) + svga->crtc[4] + 1; + + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | + (((svga->crtc[0x5d] & 0x08) >> 3) << 6); svga->hblank_overscan = !(svga->crtc[0x33] & 0x20); } diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index e10337928..31e0d34d4 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -540,37 +540,40 @@ banshee_recalctimings(svga_t *svga) banshee_t *banshee = (banshee_t *) svga->priv; const voodoo_t *voodoo = banshee->voodoo; - /*7 R/W Horizontal Retrace End bit 5. - - 6 R/W Horizontal Retrace Start bit 8 0x4 - 5 R/W Horizontal Blank End bit 6. - - 4 R/W Horizontal Blank Start bit 8. 0x3 - 3 R/W Reserved. - - 2 R/W Horizontal Display Enable End bit 8. 0x1 - 1 R/W Reserved. - - 0 R/W Horizontal Total bit 8. 0x0*/ - if (svga->crtc[0x1a] & 0x01) - svga->htotal += 0x100; - if (svga->crtc[0x1a] & 0x04) - svga->hdisp += 0x100; - if (svga->crtc[0x1a] & 0x10) - svga->hblankstart += 0x100; - if (svga->crtc[0x1a] & 0x20) - svga->hblank_end_val += 0x40; - /*6 R/W Vertical Retrace Start bit 10 0x10 - 5 R/W Reserved. - - 4 R/W Vertical Blank Start bit 10. 0x15 - 3 R/W Reserved. - - 2 R/W Vertical Display Enable End bit 10 0x12 - 1 R/W Reserved. - - 0 R/W Vertical Total bit 10. 0x6*/ - if (svga->crtc[0x1b] & 0x01) - svga->vtotal += 0x400; - if (svga->crtc[0x1b] & 0x04) - svga->dispend += 0x400; - if (svga->crtc[0x1b] & 0x10) - svga->vblankstart += 0x400; - if (svga->crtc[0x1b] & 0x40) - svga->vsyncstart += 0x400; + if (banshee->vgaInit0 & 0x40) { + /*7 R/W Horizontal Retrace End bit 5. - + 6 R/W Horizontal Retrace Start bit 8 0x4 + 5 R/W Horizontal Blank End bit 6. - + 4 R/W Horizontal Blank Start bit 8. 0x3 ---- Erratum: Actually, 0x02! + 3 R/W Reserved. - + 2 R/W Horizontal Display Enable End bit 8. 0x1 + 1 R/W Reserved. - + 0 R/W Horizontal Total bit 8. 0x0*/ + if (svga->crtc[0x1a] & 0x01) + svga->htotal += 0x100; + if (svga->crtc[0x1a] & 0x04) + svga->hdisp += 0x100; + + svga->hblankstart = (((svga->crtc[0x1a] & 0x40) >> 6) << 8) + svga->crtc[4] + 1; + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | + (((svga->crtc[0x1a] & 0x20) >> 5) << 6); + + /*6 R/W Vertical Retrace Start bit 10 0x10 + 5 R/W Reserved. - + 4 R/W Vertical Blank Start bit 10. 0x15 + 3 R/W Reserved. - + 2 R/W Vertical Display Enable End bit 10 0x12 + 1 R/W Reserved. - + 0 R/W Vertical Total bit 10. 0x6*/ + if (svga->crtc[0x1b] & 0x01) + svga->vtotal += 0x400; + if (svga->crtc[0x1b] & 0x04) + svga->dispend += 0x400; + if (svga->crtc[0x1b] & 0x10) + svga->vblankstart += 0x400; + if (svga->crtc[0x1b] & 0x40) + svga->vsyncstart += 0x400; + } #if 0 banshee_log("svga->hdisp=%i\n", svga->hdisp); #endif @@ -615,8 +618,6 @@ banshee_recalctimings(svga_t *svga) svga->char_width = 8; svga->split = 99999; - svga->hblank_end_len = 0x80; - if (banshee->vidProcCfg & VIDPROCCFG_2X_MODE) { svga->hdisp *= 2; svga->htotal *= 2; @@ -801,6 +802,7 @@ banshee_ext_outl(uint16_t addr, uint32_t val, void *priv) case Init_vgaInit0: banshee->vgaInit0 = val; svga_set_ramdac_type(svga, (val & VGAINIT0_RAMDAC_8BIT ? RAMDAC_8BIT : RAMDAC_6BIT)); + svga_recalctimings(svga); break; case Init_vgaInit1: banshee->vgaInit1 = val; From 1f569f233814eaa10d98229bad059152b166c8f6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 11 Jan 2024 22:11:23 +0100 Subject: [PATCH 266/936] NukedOPL: Fast track updates to the new mode flag (register 105h), fixes #4026. --- src/sound/snd_opl_nuked.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/sound/snd_opl_nuked.c b/src/sound/snd_opl_nuked.c index e4131f1fe..d8281ba1d 100644 --- a/src/sound/snd_opl_nuked.c +++ b/src/sound/snd_opl_nuked.c @@ -1581,17 +1581,17 @@ nuked_drv_write(uint16_t port, uint8_t val, void *priv) nuked_write_reg_buffered(&dev->opl, dev->port, val); switch (dev->port) { - case 0x02: /* Timer 1 */ + case 0x002: /* Timer 1 */ dev->timer_count[0] = val; nuked_log("Timer 0 count now: %i\n", dev->timer_count[0]); break; - case 0x03: /* Timer 2 */ + case 0x003: /* Timer 2 */ dev->timer_count[1] = val; nuked_log("Timer 1 count now: %i\n", dev->timer_count[1]); break; - case 0x04: /* Timer control */ + case 0x004: /* Timer control */ if (val & CTRL_RESET) { nuked_log("Resetting timer status...\n"); dev->status &= ~STAT_TMR_OVER; @@ -1603,6 +1603,10 @@ nuked_drv_write(uint16_t port, uint8_t val, void *priv) } break; + case 0x105: + dev->opl.newm = val & 0x01; + break; + default: break; } From 6e546bbbdcbc4942392f920024f5a48abb3098b1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 12 Jan 2024 02:06:30 +0100 Subject: [PATCH 267/936] Reverted to the old behavior, fixes #4019. --- src/floppy/fdd.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 845a6f35e..09e791c4e 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -563,10 +563,8 @@ fdd_poll(void *priv) if (fdd_notfound) { fdd_notfound--; -#ifdef RETURN_NOIDAM if (!fdd_notfound) fdc_noidam(fdd_fdc); -#endif } } From d2674c8dbbcc095a3241e9a1a71fe8c6c90917aa Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 12 Jan 2024 21:07:21 +0100 Subject: [PATCH 268/936] Fixed the Cirrus horizontal blanking calculation, fixes #4029. --- src/video/vid_cl54xx.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index e960e631c..638413ac7 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -1943,21 +1943,32 @@ gd54xx_recalctimings(svga_t *svga) svga->vram_display_mask = (svga->crtc[0x1b] & 2) ? gd54xx->vram_mask : 0x3ffff; if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5430) - svga->htotal += ((svga->crtc[0x1c] >> 3) & 0x07); + svga->htotal += ((svga->crtc[0x1c] >> 3) & 0x07); + + svga->hblankstart = svga->crtc[2] + 1; if (svga->crtc[0x1b] & ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5424) ? 0xa0 : 0x20)) { - /* Special blanking mode: the blank start and end become components of the window generator, - and the actual blanking comes from the display enable signal. */ - /* Start blanking at the first character clock after the last active one. */ - svga->hblankstart = svga->crtc[1] + 1; - svga->hblank_end_val = (svga->htotal + 5) & 0x3f; - /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ - if (!svga->scrblank && svga->attr_palette_enable) - svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; - /* No overscan in this mode. */ - svga->hblank_overscan = 0; - /* Also make sure vertical blanking starts on display end. */ - svga->vblankstart = svga->dispend; + /* Special blanking mode: the blank start and end become components of the window generator, + and the actual blanking comes from the display enable signal. */ + /* This means blanking during overscan, we already calculate it that way, so just use the + same calculation and force otvercan to 0. */ + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00) | + (((svga->crtc[0x1a] >> 4) & 3) << 6); + + if (svga->crtc[0x1b] & 0x20) { + /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ + if (!svga->scrblank && svga->attr_palette_enable) + svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; + + /* No overscan in this mode. */ + svga->hblank_overscan = 0; + + svga->monitor->mon_overscan_y = 0; + svga->monitor->mon_overscan_x = 0; + + /* Also make sure vertical blanking starts on display end. */ + svga->vblankstart = svga->dispend; + } } if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ From 38ef7fa1c3f09288de0539eff8e2f0451dbbf918 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 12 Jan 2024 23:20:01 +0100 Subject: [PATCH 269/936] CL-GD 54xx: Actually use display start and end for horizontal blanking timings in the special blanking mode. --- src/video/vid_cl54xx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 638413ac7..f87e8b87e 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -1956,6 +1956,9 @@ gd54xx_recalctimings(svga_t *svga) (((svga->crtc[0x1a] >> 4) & 3) << 6); if (svga->crtc[0x1b] & 0x20) { + svga->hblankstart = svga->crtc[1] + ((svga->crtc[3] >> 5) & 3) + 1; + svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); + /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ if (!svga->scrblank && svga->attr_palette_enable) svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; From ca4f5bad1332cbb07697e085fbdcb083d8b6fb73 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 13 Jan 2024 00:41:45 +0100 Subject: [PATCH 270/936] More horizontal blanking calculation fixes (and actually use blank start, not retrace start), fixes graphics cut-off on Voodoo on Windows 98 SE. --- src/video/vid_ati28800.c | 2 +- src/video/vid_ati_mach64.c | 19 +++++++++ src/video/vid_ati_mach8.c | 2 +- src/video/vid_et4000.c | 2 +- src/video/vid_et4000w32.c | 2 +- src/video/vid_mga.c | 4 +- src/video/vid_s3.c | 4 +- src/video/vid_s3_virge.c | 2 +- src/video/vid_svga.c | 2 +- src/video/vid_voodoo_banshee.c | 76 ++++++++++++++++++++-------------- 10 files changed, 76 insertions(+), 39 deletions(-) diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index c2ede4d45..8ac7e0292 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -503,7 +503,7 @@ ati28800_recalctimings(svga_t *svga) } if (ati28800->regs[0xad] & 0x08) - svga->hblankstart = ((ati28800->regs[0x0d] >> 2) << 8) + svga->crtc[4] + 1; + svga->hblankstart = ((ati28800->regs[0x0d] >> 2) << 8) + svga->crtc[2] + 1; } static void diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 587341538..9704a432c 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -113,6 +113,7 @@ typedef struct mach64_t { uint32_t crtc_gen_cntl; uint8_t crtc_int_cntl; + uint32_t crtc_h_sync_strt_wid; uint32_t crtc_h_total_disp; uint32_t crtc_v_sync_strt_wid; uint32_t crtc_v_total_disp; @@ -515,6 +516,10 @@ mach64_recalctimings(svga_t *svga) svga->dispend = ((mach64->crtc_v_total_disp >> 16) & 2047) + 1; svga->htotal = (mach64->crtc_h_total_disp & 255) + 1; svga->hdisp_time = svga->hdisp = ((mach64->crtc_h_total_disp >> 16) & 255) + 1; + svga->hblankstart = (mach64->crtc_h_sync_strt_wid & 255) + + ((mach64->crtc_h_sync_strt_wid >> 8) & 7) + 1; + svga->hblank_end_val = (svga->hblankstart + + ((mach64->crtc_h_sync_strt_wid >> 16) & 31) - 1) & 63; svga->vsyncstart = (mach64->crtc_v_sync_strt_wid & 2047) + 1; svga->rowoffset = (mach64->crtc_off_pitch >> 22); svga->clock = (cpuclock * (double) (1ULL << 32)) / ics2595_getclock(svga->clock_gen); @@ -2350,6 +2355,12 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x03: READ8(addr, mach64->crtc_h_total_disp); break; + case 0x04: + case 0x05: + case 0x06: + case 0x07: + READ8(addr, mach64->crtc_h_sync_strt_wid); + break; case 0x08: case 0x09: case 0x0a: @@ -3052,6 +3063,14 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv) svga_recalctimings(&mach64->svga); svga->fullchange = svga->monitor->mon_changeframecount; break; + case 0x04: + case 0x05: + case 0x06: + case 0x07: + WRITE8(addr, mach64->crtc_h_sync_strt_wid, val); + svga_recalctimings(&mach64->svga); + svga->fullchange = svga->monitor->mon_changeframecount; + break; case 0x08: case 0x09: case 0x0a: diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 365a03cee..f24ca9c4c 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2843,7 +2843,7 @@ mach_recalctimings(svga_t *svga) } if (mach->regs[0xad] & 0x08) - svga->hblankstart = ((mach->regs[0x0d] >> 2) << 8) + svga->crtc[4] + 1; + svga->hblankstart = ((mach->regs[0x0d] >> 2) << 8) + svga->crtc[2] + 1; } static void diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 1b868ecd7..cb44e9383 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -616,7 +616,7 @@ et4000_recalctimings(svga_t *svga) if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1; - svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[4] + 1; + svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x34] << 1) & 4)) { case 0: diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 3ba134342..69a995208 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -448,7 +448,7 @@ et4000w32p_recalctimings(svga_t *svga) if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1; - svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[4] + 1; + svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((svga->miscout >> 2) & 3, svga->clock_gen); diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index d386bdb71..c101b272c 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -944,7 +944,9 @@ mystique_recalctimings(svga_t *svga) if (mystique->crtcext_regs[1] & CRTCX_R1_HTOTAL8) svga->htotal |= 0x100; - svga->hblankstart = (((mystique->crtcext_regs[1] & 0x04) >> 2) << 8) + svga->crtc[4] + 1; + svga->hblankstart = (((mystique->crtcext_regs[1] & 0x02) >> 2) << 8) + svga->crtc[2] + 1; + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | + (((mystique->crtcext_regs[1] & 0x40) >> 6) << 6); if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL10) svga->vtotal |= 0x400; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 073b8523f..5242652e8 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3988,7 +3988,7 @@ s3_recalctimings(svga_t *svga) svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18); } - svga->hblankstart = (((svga->crtc[0x5d] & 0x10) >> 4) << 8) + svga->crtc[4] + 1; + svga->hblankstart = (((svga->crtc[0x5d] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; if (svga->crtc[0x5d] & 0x04) svga->hblankstart += 0x100; @@ -4150,7 +4150,7 @@ s3_trio64v_recalctimings(svga_t *svga) } } - svga->hblankstart = (((svga->crtc[0x5d] & 0x10) >> 4) << 8) + svga->crtc[4] + 1; + svga->hblankstart = (((svga->crtc[0x5d] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; /* NOTE: The S3 Trio64V+ datasheet says this is bit 7, but then where is bit 6? The datasheets for the pre-Trio64V+ cards say +64, which implies bit 6, diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index f398aa80b..fdac95bac 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -912,7 +912,7 @@ s3_virge_recalctimings(svga_t *svga) svga->vram_display_mask = virge->vram_mask; } - svga->hblankstart = (((svga->crtc[0x5d] & 0x10) >> 4) << 8) + svga->crtc[4] + 1; + svga->hblankstart = (((svga->crtc[0x5d] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | (((svga->crtc[0x5d] & 0x08) >> 3) << 6); diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 39d6a2e22..692bfef27 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -738,7 +738,7 @@ svga_recalctimings(svga_t *svga) } else svga->monitor->mon_overscan_x = 16; - svga->hblankstart = svga->crtc[4] + 1; + svga->hblankstart = svga->crtc[2] + 1; svga->hblank_end_val = (svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00); svga_log("htotal = %i, hblankstart = %i, hblank_end_val = %02X\n", diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 31e0d34d4..03db89d2e 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -540,44 +540,60 @@ banshee_recalctimings(svga_t *svga) banshee_t *banshee = (banshee_t *) svga->priv; const voodoo_t *voodoo = banshee->voodoo; - if (banshee->vgaInit0 & 0x40) { - /*7 R/W Horizontal Retrace End bit 5. - - 6 R/W Horizontal Retrace Start bit 8 0x4 - 5 R/W Horizontal Blank End bit 6. - - 4 R/W Horizontal Blank Start bit 8. 0x3 ---- Erratum: Actually, 0x02! - 3 R/W Reserved. - - 2 R/W Horizontal Display Enable End bit 8. 0x1 - 1 R/W Reserved. - - 0 R/W Horizontal Total bit 8. 0x0*/ - if (svga->crtc[0x1a] & 0x01) - svga->htotal += 0x100; - if (svga->crtc[0x1a] & 0x04) - svga->hdisp += 0x100; + /*7 R/W Horizontal Retrace End bit 5. - + 6 R/W Horizontal Retrace Start bit 8 0x4 + 5 R/W Horizontal Blank End bit 6. - + 4 R/W Horizontal Blank Start bit 8. 0x3 ---- Erratum: Actually, 0x02! + 3 R/W Reserved. - + 2 R/W Horizontal Display Enable End bit 8. 0x1 + 1 R/W Reserved. - + 0 R/W Horizontal Total bit 8. 0x0*/ + if (svga->crtc[0x1a] & 0x01) + svga->htotal += 0x100; + if (svga->crtc[0x1a] & 0x04) + svga->hdisp += 0x100; - svga->hblankstart = (((svga->crtc[0x1a] & 0x40) >> 6) << 8) + svga->crtc[4] + 1; + if (banshee->vidProcCfg & VIDPROCCFG_VIDPROC_ENABLE) { + /* Video processing mode - assume timings akin to Cirrus' special blanking mode, + that is, no overscan and relying on display end to blank. */ + svga->hblankstart = svga->crtc[1] + ((svga->crtc[3] >> 5) & 3) + + (((svga->crtc[0x1a] & 0x04) >> 2) << 8) + 1; + svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); + + /* No overscan in this mode. */ + svga->hblank_overscan = 0; + + svga->monitor->mon_overscan_y = 0; + svga->monitor->mon_overscan_x = 0; + } else { + svga->hblankstart = (((svga->crtc[0x1a] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | (((svga->crtc[0x1a] & 0x20) >> 5) << 6); - - /*6 R/W Vertical Retrace Start bit 10 0x10 - 5 R/W Reserved. - - 4 R/W Vertical Blank Start bit 10. 0x15 - 3 R/W Reserved. - - 2 R/W Vertical Display Enable End bit 10 0x12 - 1 R/W Reserved. - - 0 R/W Vertical Total bit 10. 0x6*/ - if (svga->crtc[0x1b] & 0x01) - svga->vtotal += 0x400; - if (svga->crtc[0x1b] & 0x04) - svga->dispend += 0x400; - if (svga->crtc[0x1b] & 0x10) - svga->vblankstart += 0x400; - if (svga->crtc[0x1b] & 0x40) - svga->vsyncstart += 0x400; } + + /*6 R/W Vertical Retrace Start bit 10 0x10 + 5 R/W Reserved. - + 4 R/W Vertical Blank Start bit 10. 0x15 + 3 R/W Reserved. - + 2 R/W Vertical Display Enable End bit 10 0x12 + 1 R/W Reserved. - + 0 R/W Vertical Total bit 10. 0x6*/ + if (svga->crtc[0x1b] & 0x01) + svga->vtotal += 0x400; + if (svga->crtc[0x1b] & 0x04) + svga->dispend += 0x400; + if (svga->crtc[0x1b] & 0x10) + svga->vblankstart += 0x400; + if (svga->crtc[0x1b] & 0x40) + svga->vsyncstart += 0x400; + #if 0 banshee_log("svga->hdisp=%i\n", svga->hdisp); #endif + if (banshee->vidProcCfg & VIDPROCCFG_2X_MODE) + svga->dots_per_clock *= 2; + svga->interlace = 0; if (banshee->vgaInit0 & VGAINIT0_EXTENDED_SHIFT_OUT) { From 8552558cfd4d166d167554b9985420527bfa9a82 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 13 Jan 2024 01:55:30 +0100 Subject: [PATCH 271/936] CT1745 mixer: Speak volume is only in bits 7 and 6, 2 bits total, fixes #4027. --- src/sound/snd_sb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index b2a629079..3aa152b8f 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -796,7 +796,9 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->regs[0x36] = mixer->regs[0x37] = 0xf8; mixer->regs[0x38] = mixer->regs[0x39] = 0x00; - mixer->regs[0x3a] = mixer->regs[0x3b] = 0x00; + mixer->regs[0x3a] = 0x00; + /* Speaker control - it appears to be in steps of 64. */ + mixer->regs[0x3b] = 0x80; mixer->regs[0x3c] = (OUTPUT_MIC | OUTPUT_CD_R | OUTPUT_CD_L | OUTPUT_LINE_R | OUTPUT_LINE_L); mixer->regs[0x3d] = (INPUT_MIC | INPUT_CD_L | INPUT_LINE_L | INPUT_MIDI_L); @@ -980,7 +982,7 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->line_r = (mixer->output_selector & OUTPUT_LINE_R) ? (sb_att_2dbstep_5bits[mixer->regs[0x39] >> 3] / 32768.0) : 0.0; mixer->mic = sb_att_2dbstep_5bits[mixer->regs[0x3a] >> 3] / 32768.0; - mixer->speaker = sb_att_2dbstep_5bits[mixer->regs[0x3b] * 3 + 22] / 32768.0; + mixer->speaker = sb_att_7dbstep_2bits[(mixer->regs[0x3b] >> 6) & 0x3] / 32768.0; mixer->input_gain_L = (mixer->regs[0x3f] >> 6); mixer->input_gain_R = (mixer->regs[0x40] >> 6); From 996530a94e7deae0e0254b5165a786cb0d5f54fe Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 13 Jan 2024 03:54:56 +0100 Subject: [PATCH 272/936] Horizontal blanking calculation now takes into account horizontal timings multiplications and divisions, fixes a lot of S3 (and ViRGE) modes. --- src/video/vid_ati28800.c | 12 +- src/video/vid_ati_mach64.c | 5 +- src/video/vid_ati_mach8.c | 9 +- src/video/vid_cl54xx.c | 63 +++++----- src/video/vid_mga.c | 7 +- src/video/vid_s3.c | 215 +++++++++++++++++++++++++++------ src/video/vid_s3_virge.c | 41 +++++-- src/video/vid_voodoo_banshee.c | 12 +- 8 files changed, 271 insertions(+), 93 deletions(-) diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index 8ac7e0292..b3f138dc7 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -407,6 +407,9 @@ ati28800_recalctimings(svga_t *svga) ati28800_t *ati28800 = (ati28800_t *) svga->priv; int clock_sel; + if (ati28800->regs[0xad] & 0x08) + svga->hblankstart = ((ati28800->regs[0x0d] >> 2) << 8) + svga->crtc[2] + 1; + clock_sel = ((svga->miscout >> 2) & 3) | ((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1); @@ -426,6 +429,8 @@ ati28800_recalctimings(svga_t *svga) svga->hdisp <<= 1; svga->htotal <<= 1; svga->rowoffset <<= 1; + svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblank_end_val <<= 1; svga->gdcreg[5] &= ~0x40; } @@ -441,6 +446,8 @@ ati28800_recalctimings(svga_t *svga) if ((ati28800->regs[0xb6] & 0x18) == 8) { svga->hdisp <<= 1; svga->htotal <<= 1; + svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblank_end_val <<= 1; svga->ati_4color = 1; } else svga->ati_4color = 0; @@ -487,6 +494,8 @@ ati28800_recalctimings(svga_t *svga) else { svga->render = svga_render_15bpp_highres; svga->hdisp >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; svga->rowoffset <<= 1; svga->ma_latch <<= 1; } @@ -501,9 +510,6 @@ ati28800_recalctimings(svga_t *svga) } } } - - if (ati28800->regs[0xad] & 0x08) - svga->hblankstart = ((ati28800->regs[0x0d] >> 2) << 8) + svga->crtc[2] + 1; } static void diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 9704a432c..cdd906067 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -511,7 +511,6 @@ mach64_recalctimings(svga_t *svga) const mach64_t *mach64 = (mach64_t *) svga->priv; if (((mach64->crtc_gen_cntl >> 24) & 3) == 3) { - svga->hoverride = 1; svga->vtotal = (mach64->crtc_v_total_disp & 2047) + 1; svga->dispend = ((mach64->crtc_v_total_disp >> 16) & 2047) + 1; svga->htotal = (mach64->crtc_h_total_disp & 255) + 1; @@ -571,10 +570,8 @@ mach64_recalctimings(svga_t *svga) } svga->vram_display_mask = mach64->vram_mask; - } else { - svga->hoverride = 0; + } else svga->vram_display_mask = (mach64->regs[0x36] & 0x01) ? mach64->vram_mask : 0x3ffff; - } } void diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index f24ca9c4c..34cd8b11b 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2594,6 +2594,8 @@ mach_recalctimings(svga_t *svga) ibm8514_t *dev = (ibm8514_t *) svga->dev8514; int clock_sel; + if (mach->regs[0xad] & 0x08) + svga->hblankstart = ((mach->regs[0x0d] >> 2) << 8) + svga->crtc[2] + 1; clock_sel = ((svga->miscout >> 2) & 3) | ((mach->regs[0xbe] & 0x10) >> 1) | ((mach->regs[0xb9] & 2) << 1); if ((dev->local & 0xff) >= 0x02) { @@ -2613,6 +2615,8 @@ mach_recalctimings(svga_t *svga) if ((mach->regs[0xb6] & 0x18) >= 0x10) { svga->hdisp <<= 1; svga->htotal <<= 1; + svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblank_end_val <<= 1; svga->rowoffset <<= 1; svga->gdcreg[5] &= ~0x40; } @@ -2630,6 +2634,8 @@ mach_recalctimings(svga_t *svga) if ((mach->regs[0xb6] & 0x18) == 8) { svga->hdisp <<= 1; svga->htotal <<= 1; + svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblank_end_val <<= 1; svga->ati_4color = 1; } else svga->ati_4color = 0; @@ -2841,9 +2847,6 @@ mach_recalctimings(svga_t *svga) } } } - - if (mach->regs[0xad] & 0x08) - svga->hblankstart = ((mach->regs[0x0d] >> 2) << 8) + svga->crtc[2] + 1; } static void diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index f87e8b87e..c1d622ac5 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -1751,6 +1751,35 @@ gd54xx_recalctimings(svga_t *svga) uint8_t rdmask; uint8_t linedbl = svga->dispend * 9 / 10 >= svga->hdisp; + svga->hblankstart = svga->crtc[2] + 1; + + if (svga->crtc[0x1b] & ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5424) ? 0xa0 : 0x20)) { + /* Special blanking mode: the blank start and end become components of the window generator, + and the actual blanking comes from the display enable signal. */ + /* This means blanking during overscan, we already calculate it that way, so just use the + same calculation and force otvercan to 0. */ + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00) | + (((svga->crtc[0x1a] >> 4) & 3) << 6); + + if (svga->crtc[0x1b] & 0x20) { + svga->hblankstart = svga->crtc[1] + ((svga->crtc[3] >> 5) & 3) + 1; + svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); + + /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ + if (!svga->scrblank && svga->attr_palette_enable) + svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; + + /* No overscan in this mode. */ + svga->hblank_overscan = 0; + + svga->monitor->mon_overscan_y = 0; + svga->monitor->mon_overscan_x = 0; + + /* Also make sure vertical blanking starts on display end. */ + svga->vblankstart = svga->dispend; + } + } + svga->rowoffset = (svga->crtc[0x13]) | (((int) (uint32_t) (svga->crtc[0x1b] & 0x10)) << 4); svga->interlace = (svga->crtc[0x1a] & 0x01); @@ -1765,8 +1794,11 @@ gd54xx_recalctimings(svga_t *svga) svga->render = svga_render_8bpp_lowres; else { svga->render = svga_render_8bpp_highres; - if ((svga->dispend == 512) && !svga->interlace && gd54xx_is_5434(svga)) + if ((svga->dispend == 512) && !svga->interlace && gd54xx_is_5434(svga)) { svga->hdisp <<= 1; + svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblank_end_val <<= 1; + } } } else if (svga->gdcreg[5] & 0x40) svga->render = svga_render_8bpp_lowres; @@ -1945,35 +1977,6 @@ gd54xx_recalctimings(svga_t *svga) if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5430) svga->htotal += ((svga->crtc[0x1c] >> 3) & 0x07); - svga->hblankstart = svga->crtc[2] + 1; - - if (svga->crtc[0x1b] & ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5424) ? 0xa0 : 0x20)) { - /* Special blanking mode: the blank start and end become components of the window generator, - and the actual blanking comes from the display enable signal. */ - /* This means blanking during overscan, we already calculate it that way, so just use the - same calculation and force otvercan to 0. */ - svga->hblank_end_val = (svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00) | - (((svga->crtc[0x1a] >> 4) & 3) << 6); - - if (svga->crtc[0x1b] & 0x20) { - svga->hblankstart = svga->crtc[1] + ((svga->crtc[3] >> 5) & 3) + 1; - svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); - - /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ - if (!svga->scrblank && svga->attr_palette_enable) - svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; - - /* No overscan in this mode. */ - svga->hblank_overscan = 0; - - svga->monitor->mon_overscan_y = 0; - svga->monitor->mon_overscan_x = 0; - - /* Also make sure vertical blanking starts on display end. */ - svga->vblankstart = svga->dispend; - } - } - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ if (svga->seqregs[1] & 8) { svga->render = svga_render_text_40; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index c101b272c..f84464bc1 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -945,8 +945,6 @@ mystique_recalctimings(svga_t *svga) svga->htotal |= 0x100; svga->hblankstart = (((mystique->crtcext_regs[1] & 0x02) >> 2) << 8) + svga->crtc[2] + 1; - svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | - (((mystique->crtcext_regs[1] & 0x40) >> 6) << 6); if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL10) svga->vtotal |= 0x400; @@ -978,8 +976,9 @@ mystique_recalctimings(svga_t *svga) svga->hdisp_time = svga->hdisp; svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); - svga->hblank_end_val = (mystique->crtcext_regs[1] & 0x40) | (svga->crtc[3] & 0x1f) | - ((svga->crtc[5] & 0x80) ? 0x20 : 0x00); + svga->dots_per_clock = 8; + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | + (((mystique->crtcext_regs[1] & 0x40) >> 6) << 6); svga->hblank_overscan = 0; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 5242652e8..6a6b949f8 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3248,6 +3248,44 @@ s3_recalctimings(svga_t *svga) break; } + if (svga->crtc[0x33] & 0x20) { + /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ + svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1] + + ((svga->crtc[3] >> 5) & 3) + 1; + svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); + + /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ + if (!svga->scrblank && svga->attr_palette_enable) + svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; + + /* No overscan in this mode. */ + svga->hblank_overscan = 0; + + svga->monitor->mon_overscan_y = 0; + svga->monitor->mon_overscan_x = 0; + + /* Also make sure vertical blanking starts on display end. */ + svga->vblankstart = svga->dispend; + } else if (s3->chip >= S3_86C801) { + 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); + } + + svga->hblankstart = (((svga->crtc[0x5d] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; + + if (svga->crtc[0x5d] & 0x04) + svga->hblankstart += 0x100; + if (s3->chip >= S3_VISION964) { + /* NOTE: The S3 Trio64V+ datasheet says this is bit 7, but then where is bit 6? + The datasheets for the pre-Trio64V+ cards say +64, which implies bit 6, + and, contrary to VGADOC, it also exists on Trio32, Trio64, Vision868, + and Vision968. */ + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | + (((svga->crtc[0x5d] & 0x08) >> 3) << 6); + } + } + #ifdef OLD_CODE_REFERENCE if (s3->card_type == S3_MIROCRYSTAL10SD_805 || s3->card_type == S3_MIROCRYSTAL20SD_864 || s3->card_type == S3_MIROCRYSTAL20SV_964 || s3->card_type == S3_SPEA_MIRAGE_86C801 || s3->card_type == S3_SPEA_MIRAGE_86C805 || s3->card_type == S3_MIROCRYSTAL8S_805 || s3->card_type == S3_NUMBER9_9FX_531 || s3->card_type == S3_SPEA_MERCURY_LITE_PCI) { if (!(svga->crtc[0x5e] & 0x04)) @@ -3292,14 +3330,20 @@ s3_recalctimings(svga_t *svga) switch (s3->width) { case 1280: svga->hdisp <<= 1; + svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblank_end_val <<= 1; break; case 2048: /*Account for the 1280x1024 resolution*/ switch (svga->hdisp) { case 320: svga->hdisp <<= 2; + svga->hblankstart = ((svga->hblankstart - 1) << 2) + 1; + svga->hblank_end_val <<= 2; break; case 640: svga->hdisp <<= 1; + svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblank_end_val <<= 1; break; default: break; @@ -3320,6 +3364,8 @@ s3_recalctimings(svga_t *svga) switch (s3->width) { case 640: svga->hdisp >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; break; default: break; @@ -3334,6 +3380,8 @@ s3_recalctimings(svga_t *svga) switch (s3->card_type) { case S3_ELSAWIN2KPROX_964: svga->hdisp <<= 1; + svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblank_end_val <<= 1; break; default: @@ -3347,12 +3395,16 @@ s3_recalctimings(svga_t *svga) case S3_ELSAWIN2KPROX: case S3_PHOENIX_VISION968: svga->hdisp <<= 1; + svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblank_end_val <<= 1; break; case S3_MIROVIDEO40SV_ERGO_968: switch (s3->width) { case 1152: case 1280: svga->hdisp <<= 1; + svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblank_end_val <<= 1; break; default: break; @@ -3385,6 +3437,7 @@ s3_recalctimings(svga_t *svga) } else if (s3->card_type == S3_SPEA_MERCURY_P64V) { if (s3->width == 1280 || s3->width == 1600) svga->hdisp <<= 1; + } } else if (s3->card_type == S3_NUMBER9_9FX_771) svga->hdisp <<= 1; } @@ -3402,6 +3455,8 @@ s3_recalctimings(svga_t *svga) switch (s3->card_type) { case S3_PHOENIX_86C801: svga->hdisp >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; break; default: @@ -3415,6 +3470,8 @@ s3_recalctimings(svga_t *svga) case S3_PHOENIX_86C805: case S3_86C805_ONBOARD: svga->hdisp >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; break; case S3_SPEA_MIRAGE_86C805: @@ -3422,8 +3479,12 @@ s3_recalctimings(svga_t *svga) switch (s3->width) { case 800: case 1024: - if (svga->hdisp == 400) /*SPEA specific drivers + its VBE RAM BIOS...*/ + if (svga->hdisp == 400) { + /*SPEA specific drivers + its VBE RAM BIOS...*/ svga->hdisp <<= 1; + svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblank_end_val <<= 1; + } break; default: break; @@ -3437,8 +3498,11 @@ s3_recalctimings(svga_t *svga) case S3_86C928: switch (s3->card_type) { case S3_METHEUS_86C928: - if (!s3->color_16bit) + if (!s3->color_16bit) { svga->hdisp <<= 1; + svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblank_end_val <<= 1; + } switch (svga->hdisp) { /*This might be a driver issue*/ case 800: s3->width = 1024; @@ -3461,6 +3525,8 @@ s3_recalctimings(svga_t *svga) switch (s3->width) { case 640: svga->hdisp >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; break; default: break; @@ -3475,6 +3541,8 @@ s3_recalctimings(svga_t *svga) switch (s3->card_type) { case S3_MIROCRYSTAL20SD_864: svga->hdisp >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; break; default: @@ -3488,6 +3556,8 @@ s3_recalctimings(svga_t *svga) case 1280: case 1600: svga->hdisp <<= 1; + svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblank_end_val <<= 1; break; default: break; @@ -3503,6 +3573,8 @@ s3_recalctimings(svga_t *svga) case S3_PHOENIX_VISION868: case S3_NUMBER9_9FX_531: svga->hdisp >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; break; default: @@ -3514,6 +3586,9 @@ s3_recalctimings(svga_t *svga) case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: svga->hdisp <<= 1; + svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblank_end_val <<= 1; + /* TODO: Is this still needed? */ if (svga->hdisp == 832) svga->hdisp -= 32; break; @@ -3523,6 +3598,8 @@ s3_recalctimings(svga_t *svga) case 1280: case 1600: svga->hdisp <<= 1; + svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblank_end_val <<= 1; break; default: break; @@ -3536,6 +3613,8 @@ s3_recalctimings(svga_t *svga) case S3_TRIO64: case S3_TRIO32: svga->hdisp >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; break; default: @@ -3571,12 +3650,16 @@ s3_recalctimings(svga_t *svga) case S3_86C911: case S3_86C924: svga->hdisp >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; break; case S3_86C801: switch (s3->card_type) { case S3_PHOENIX_86C801: svga->hdisp >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; break; default: @@ -3590,6 +3673,8 @@ s3_recalctimings(svga_t *svga) case S3_PHOENIX_86C805: case S3_86C805_ONBOARD: svga->hdisp >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; break; case S3_SPEA_MIRAGE_86C805: @@ -3597,8 +3682,12 @@ s3_recalctimings(svga_t *svga) switch (s3->width) { case 800: case 1024: - if (svga->hdisp == 400) /*SPEA specific drivers + its VBE RAM BIOS...*/ + if (svga->hdisp == 400) { + /*SPEA specific drivers + its VBE RAM BIOS...*/ svga->hdisp <<= 1; + svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblank_end_val <<= 1; + } break; default: break; @@ -3613,6 +3702,8 @@ s3_recalctimings(svga_t *svga) switch (s3->card_type) { case S3_METHEUS_86C928: svga->hdisp <<= 1; + svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblank_end_val <<= 1; switch (svga->hdisp) { /*This might be a driver issue*/ case 800: s3->width = 1024; @@ -3635,7 +3726,9 @@ s3_recalctimings(svga_t *svga) switch (s3->width) { case 640: svga->hdisp >>= 1; - break; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; + break; default: break; } @@ -3649,6 +3742,8 @@ s3_recalctimings(svga_t *svga) switch (s3->card_type) { case S3_MIROCRYSTAL20SD_864: svga->hdisp >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; break; default: @@ -3660,6 +3755,8 @@ s3_recalctimings(svga_t *svga) case S3_PHOENIX_VISION868: case S3_NUMBER9_9FX_531: svga->hdisp >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; break; default: @@ -3673,6 +3770,8 @@ s3_recalctimings(svga_t *svga) case 1280: case 1600: svga->hdisp <<= 1; + svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblank_end_val <<= 1; break; default: break; @@ -3688,6 +3787,9 @@ s3_recalctimings(svga_t *svga) case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: svga->hdisp <<= 1; + svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblank_end_val <<= 1; + /* TODO: Is this still needed? */ if (svga->hdisp == 832) svga->hdisp -= 32; break; @@ -3697,6 +3799,8 @@ s3_recalctimings(svga_t *svga) case 1280: case 1600: svga->hdisp <<= 1; + svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblank_end_val <<= 1; break; default: break; @@ -3710,6 +3814,8 @@ s3_recalctimings(svga_t *svga) case S3_TRIO64: case S3_TRIO32: svga->hdisp >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; break; default: @@ -3752,6 +3858,9 @@ s3_recalctimings(svga_t *svga) switch (s3->card_type) { case S3_AMI_86C924: svga->hdisp = (svga->hdisp << 1) / 3; + svga->hblankstart = (((svga->hblankstart - 1) << 1) / 3) + 1; + svga->hblank_end_val = (svga->hblank_end_val << 1) / 3; + /* TODO: Is this still needed? */ if (svga->hdisp == 645) svga->hdisp -= 5; break; @@ -3764,6 +3873,8 @@ s3_recalctimings(svga_t *svga) case S3_PHOENIX_86C801: case S3_SPEA_MIRAGE_86C801: svga->hdisp = (svga->hdisp << 1) / 3; + svga->hblankstart = (((svga->hblankstart - 1) << 1) / 3) + 1; + svga->hblank_end_val = (svga->hblank_end_val << 1) / 3; break; default: break; @@ -3777,6 +3888,8 @@ s3_recalctimings(svga_t *svga) case S3_SPEA_MIRAGE_86C805: case S3_86C805_ONBOARD: svga->hdisp = (svga->hdisp << 1) / 3; + svga->hblankstart = (((svga->hblankstart - 1) << 1) / 3) + 1; + svga->hblank_end_val = (svga->hblank_end_val << 1) / 3; break; default: break; @@ -3786,6 +3899,8 @@ s3_recalctimings(svga_t *svga) switch (s3->card_type) { case S3_SPEA_MERCURY_LITE_PCI: svga->hdisp = (svga->hdisp << 1) / 3; + svga->hblankstart = (((svga->hblankstart - 1) << 1) / 3) + 1; + svga->hblank_end_val = (svga->hblank_end_val << 1) / 3; break; default: break; @@ -3795,6 +3910,8 @@ s3_recalctimings(svga_t *svga) switch (s3->card_type) { case S3_MIROCRYSTAL20SD_864: svga->hdisp = (svga->hdisp << 1) / 3; + svga->hblankstart = (((svga->hblankstart - 1) << 1) / 3) + 1; + svga->hblank_end_val = (svga->hblank_end_val << 1) / 3; break; default: break; @@ -3805,8 +3922,9 @@ s3_recalctimings(svga_t *svga) case S3_MIROVIDEO40SV_ERGO_968: switch (s3->width) { case 1280: - svga->hdisp = (svga->hdisp << 1) / 3; - svga->hdisp <<= 1; + svga->hdisp = ((svga->hdisp << 1) / 3) << 1; + svga->hblankstart = ((((svga->hblankstart - 1) << 1) / 3) << 1) + 1; + svga->hblank_end_val = ((svga->hblank_end_val << 1) / 3) << 1; break; default: break; @@ -3821,6 +3939,8 @@ s3_recalctimings(svga_t *svga) case S3_TRIO64: case S3_TRIO32: svga->hdisp /= 3; + svga->hblankstart = ((svga->hblankstart - 1) / 3) + 1; + svga->hblank_end_val /= 3; break; default: @@ -3862,6 +3982,8 @@ s3_recalctimings(svga_t *svga) case S3_PHOENIX_VISION868: case S3_NUMBER9_9FX_531: svga->hdisp >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; break; default: break; @@ -3874,6 +3996,8 @@ s3_recalctimings(svga_t *svga) case 800: case 1024: svga->hdisp >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; break; default: break; @@ -3884,6 +4008,8 @@ s3_recalctimings(svga_t *svga) case 1280: case 1600: svga->hdisp <<= 1; + svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblank_end_val <<= 1; break; default: break; @@ -3898,6 +4024,9 @@ s3_recalctimings(svga_t *svga) case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: svga->hdisp <<= 1; + svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblank_end_val <<= 1; + /* TODO: Is this still needed? */ if (svga->hdisp == 832) svga->hdisp -= 32; break; @@ -3907,6 +4036,8 @@ s3_recalctimings(svga_t *svga) case 1280: case 1600: svga->hdisp <<= 1; + svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblank_end_val <<= 1; break; default: break; @@ -3981,28 +4112,6 @@ s3_recalctimings(svga_t *svga) } } } - - if (s3->chip >= S3_86C801) { - 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); - } - - svga->hblankstart = (((svga->crtc[0x5d] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; - - if (svga->crtc[0x5d] & 0x04) - svga->hblankstart += 0x100; - if (s3->chip >= S3_VISION964) { - /* NOTE: The S3 Trio64V+ datasheet says this is bit 7, but then where is bit 6? - The datasheets for the pre-Trio64V+ cards say +64, which implies bit 6, - and, contrary to VGADOC, it also exists on Trio32, Trio64, Vision868, - and Vision968. */ - svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | - (((svga->crtc[0x5d] & 0x08) >> 3) << 6); - } - } - - svga->hblank_overscan = !(svga->crtc[0x33] & 0x20); } static void @@ -4061,6 +4170,35 @@ s3_trio64v_recalctimings(svga_t *svga) break; } + if ((svga->crtc[0x33] & 0x20) ||((svga->crtc[0x67] & 0xc) == 0xc)) { + /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ + svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1] + + ((svga->crtc[3] >> 5) & 3) + 1; + svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); + + /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ + if (!svga->scrblank && svga->attr_palette_enable) + svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; + + /* No overscan in this mode. */ + svga->hblank_overscan = 0; + + svga->monitor->mon_overscan_y = 0; + svga->monitor->mon_overscan_x = 0; + + /* Also make sure vertical blanking starts on display end. */ + svga->vblankstart = svga->dispend; + } else { + svga->hblankstart = (((svga->crtc[0x5d] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; + + /* NOTE: The S3 Trio64V+ datasheet says this is bit 7, but then where is bit 6? + The datasheets for the pre-Trio64V+ cards say +64, which implies bit 6, + and, contrary to VGADOC, it also exists on Trio32, Trio64, Vision868, + and Vision968. */ + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | + (((svga->crtc[0x5d] & 0x08) >> 3) << 6); + } + if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ { svga->ma_latch |= (s3->ma_ext << 16); @@ -4082,14 +4220,20 @@ s3_trio64v_recalctimings(svga_t *svga) case 15: svga->render = svga_render_15bpp_highres; svga->hdisp >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; break; case 16: svga->render = svga_render_16bpp_highres; svga->hdisp >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; break; case 24: svga->render = svga_render_24bpp_highres; svga->hdisp /= 3; + svga->hblankstart = ((svga->hblankstart - 1) / 3) + 1; + svga->hblank_end_val /= 3; break; case 32: svga->render = svga_render_32bpp_highres; @@ -4132,10 +4276,14 @@ s3_trio64v_recalctimings(svga_t *svga) break; case 3: /*KRGB-16 (1.5.5.5)*/ svga->htotal >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; svga->render = svga_render_15bpp_highres; break; case 5: /*RGB-16 (5.6.5)*/ svga->htotal >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; svga->render = svga_render_16bpp_highres; break; case 6: /*RGB-24 (8.8.8)*/ @@ -4149,17 +4297,6 @@ s3_trio64v_recalctimings(svga_t *svga) break; } } - - svga->hblankstart = (((svga->crtc[0x5d] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; - - /* NOTE: The S3 Trio64V+ datasheet says this is bit 7, but then where is bit 6? - The datasheets for the pre-Trio64V+ cards say +64, which implies bit 6, - and, contrary to VGADOC, it also exists on Trio32, Trio64, Vision868, - and Vision968. */ - svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | - (((svga->crtc[0x5d] & 0x08) >> 3) << 6); - - svga->hblank_overscan = !(svga->crtc[0x33] & 0x20); } static void diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index fdac95bac..8f05552c3 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -818,6 +818,31 @@ s3_virge_recalctimings(svga_t *svga) svga->clock = (cpuclock * (float) (1ULL << 32)) / freq; } + if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) { + /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ + svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1] + + ((svga->crtc[3] >> 5) & 3) + 1; + svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); + + /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ + if (!svga->scrblank && svga->attr_palette_enable) + svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; + + /* No overscan in this mode. */ + svga->hblank_overscan = 0; + + svga->monitor->mon_overscan_y = 0; + svga->monitor->mon_overscan_x = 0; + + /* Also make sure vertical blanking starts on display end. */ + svga->vblankstart = svga->dispend; + } else { + svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2] + 1; + + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | + (((svga->crtc[0x5d] & 0x08) >> 3) << 6); + } + if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ { svga->ma_latch |= (virge->ma_ext << 16); @@ -839,6 +864,9 @@ s3_virge_recalctimings(svga_t *svga) if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) { svga->htotal >>= 1; svga->hdisp >>= 1; + svga->hoverride = 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; } break; case 16: @@ -846,6 +874,8 @@ s3_virge_recalctimings(svga_t *svga) if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) { svga->htotal >>= 1; svga->hdisp >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; } break; case 24: @@ -893,10 +923,14 @@ s3_virge_recalctimings(svga_t *svga) break; case 3: /*KRGB-16 (1.5.5.5)*/ svga->htotal >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; svga->render = svga_render_15bpp_highres; break; case 5: /*RGB-16 (5.6.5)*/ svga->htotal >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; svga->render = svga_render_16bpp_highres; break; case 6: /*RGB-24 (8.8.8)*/ @@ -911,13 +945,6 @@ s3_virge_recalctimings(svga_t *svga) } svga->vram_display_mask = virge->vram_mask; } - - svga->hblankstart = (((svga->crtc[0x5d] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; - - svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | - (((svga->crtc[0x5d] & 0x08) >> 3) << 6); - - svga->hblank_overscan = !(svga->crtc[0x33] & 0x20); } static void diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 03db89d2e..d013ec2e5 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -560,11 +560,18 @@ banshee_recalctimings(svga_t *svga) (((svga->crtc[0x1a] & 0x04) >> 2) << 8) + 1; svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); + /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ + if (!svga->scrblank && svga->attr_palette_enable) + svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; + /* No overscan in this mode. */ svga->hblank_overscan = 0; svga->monitor->mon_overscan_y = 0; svga->monitor->mon_overscan_x = 0; + + /* Also make sure vertical blanking starts on display end. */ + svga->vblankstart = svga->dispend; } else { svga->hblankstart = (((svga->crtc[0x1a] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | @@ -591,9 +598,6 @@ banshee_recalctimings(svga_t *svga) banshee_log("svga->hdisp=%i\n", svga->hdisp); #endif - if (banshee->vidProcCfg & VIDPROCCFG_2X_MODE) - svga->dots_per_clock *= 2; - svga->interlace = 0; if (banshee->vgaInit0 & VGAINIT0_EXTENDED_SHIFT_OUT) { @@ -637,6 +641,8 @@ banshee_recalctimings(svga_t *svga) if (banshee->vidProcCfg & VIDPROCCFG_2X_MODE) { svga->hdisp *= 2; svga->htotal *= 2; + svga->hblankstart = ((svga->hblankstart - 1) * 2) + 1; + svga->hblank_end_val *= 2; } svga->interlace = !!(banshee->vidProcCfg & VIDPROCCFG_INTERLACE); From 2390d2d2aed44378db78d4334028d29caee0b4ff Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 13 Jan 2024 13:38:19 +0600 Subject: [PATCH 273/936] MGA: Do not reset DWORD expected counter while SOFTRAP read is still pending Fixes Matrox Simple Interface games without breaking Windows 2000 drivers --- src/video/vid_mga.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index f84464bc1..44a33db2e 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -2186,7 +2186,10 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) thread_wait_mutex(mystique->dma.lock); WRITE8(addr, mystique->dma.primaddress, val); mystique->dma.pri_state = 0; - mystique->dma.words_expected = 0; + if (mystique->dma.state == DMA_STATE_IDLE && !(mystique->softrap_pending || mystique->endprdmasts_pending || !mystique->softrap_status_read)) { + mystique->dma.words_expected = 0; + } + mystique->dma.state = DMA_STATE_IDLE; thread_release_mutex(mystique->dma.lock); break; From de1e98d3ece1e7576d49b34eaaece9a189c0da0d Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 13 Jan 2024 17:10:00 +0100 Subject: [PATCH 274/936] Corrected S3 864 horizontal display. --- src/video/vid_s3.c | 38 +++++++++----------------------------- 1 file changed, 9 insertions(+), 29 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 6a6b949f8..25c0ea98c 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3538,16 +3538,9 @@ s3_recalctimings(svga_t *svga) } break; case S3_VISION864: - switch (s3->card_type) { - case S3_MIROCRYSTAL20SD_864: - svga->hdisp >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; - svga->hblank_end_val >>= 1; - break; - - default: - break; - } + svga->hdisp >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; break; case S3_VISION964: switch (s3->card_type) { @@ -3739,16 +3732,9 @@ s3_recalctimings(svga_t *svga) } break; case S3_VISION864: - switch (s3->card_type) { - case S3_MIROCRYSTAL20SD_864: - svga->hdisp >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; - svga->hblank_end_val >>= 1; - break; - - default: - break; - } + svga->hdisp >>= 1; + svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblank_end_val >>= 1; break; case S3_VISION868: switch (s3->card_type) { @@ -3907,15 +3893,9 @@ s3_recalctimings(svga_t *svga) } break; case S3_VISION864: - switch (s3->card_type) { - case S3_MIROCRYSTAL20SD_864: - svga->hdisp = (svga->hdisp << 1) / 3; - svga->hblankstart = (((svga->hblankstart - 1) << 1) / 3) + 1; - svga->hblank_end_val = (svga->hblank_end_val << 1) / 3; - break; - default: - break; - } + svga->hdisp = (svga->hdisp << 1) / 3; + svga->hblankstart = (((svga->hblankstart - 1) << 1) / 3) + 1; + svga->hblank_end_val = (svga->hblank_end_val << 1) / 3; break; case S3_VISION968: switch (s3->card_type) { From b1c292a9e9833e0dfed17ef6c9113abd5be6d4bf Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 13 Jan 2024 22:04:20 +0100 Subject: [PATCH 275/936] Sanitized the horizontal blanking adjustments a bit and fixed 640x480x8bpp on some S3 cards. --- src/video/vid_ati28800.c | 4 +- src/video/vid_ati_mach8.c | 4 +- src/video/vid_cl54xx.c | 2 +- src/video/vid_s3.c | 123 +++++++++++++++++++-------------- src/video/vid_s3_virge.c | 9 ++- src/video/vid_voodoo_banshee.c | 2 +- 6 files changed, 81 insertions(+), 63 deletions(-) diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index b3f138dc7..1f2b69e25 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -429,7 +429,7 @@ ati28800_recalctimings(svga_t *svga) svga->hdisp <<= 1; svga->htotal <<= 1; svga->rowoffset <<= 1; - svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; svga->gdcreg[5] &= ~0x40; } @@ -446,7 +446,7 @@ ati28800_recalctimings(svga_t *svga) if ((ati28800->regs[0xb6] & 0x18) == 8) { svga->hdisp <<= 1; svga->htotal <<= 1; - svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; svga->ati_4color = 1; } else diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 34cd8b11b..b19f1e3d6 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2615,7 +2615,7 @@ mach_recalctimings(svga_t *svga) if ((mach->regs[0xb6] & 0x18) >= 0x10) { svga->hdisp <<= 1; svga->htotal <<= 1; - svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; svga->rowoffset <<= 1; svga->gdcreg[5] &= ~0x40; @@ -2634,7 +2634,7 @@ mach_recalctimings(svga_t *svga) if ((mach->regs[0xb6] & 0x18) == 8) { svga->hdisp <<= 1; svga->htotal <<= 1; - svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; svga->ati_4color = 1; } else diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index c1d622ac5..168912e9d 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -1796,7 +1796,7 @@ gd54xx_recalctimings(svga_t *svga) svga->render = svga_render_8bpp_highres; if ((svga->dispend == 512) && !svga->interlace && gd54xx_is_5434(svga)) { svga->hdisp <<= 1; - svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; } } diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 25c0ea98c..48e55e02e 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3330,19 +3330,19 @@ s3_recalctimings(svga_t *svga) switch (s3->width) { case 1280: svga->hdisp <<= 1; - svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; break; case 2048: /*Account for the 1280x1024 resolution*/ switch (svga->hdisp) { case 320: svga->hdisp <<= 2; - svga->hblankstart = ((svga->hblankstart - 1) << 2) + 1; + svga->hblankstart <<= 2; svga->hblank_end_val <<= 2; break; case 640: svga->hdisp <<= 1; - svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; break; default: @@ -3364,7 +3364,7 @@ s3_recalctimings(svga_t *svga) switch (s3->width) { case 640: svga->hdisp >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; break; default: @@ -3379,9 +3379,15 @@ s3_recalctimings(svga_t *svga) case S3_VISION964: switch (s3->card_type) { case S3_ELSAWIN2KPROX_964: - svga->hdisp <<= 1; - svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; - svga->hblank_end_val <<= 1; + switch (s3->width) { + case 1280: + case 1600: + svga->hdisp <<= 1; + svga->hblankstart <<= 1; + svga->hblank_end_val <<= 1; + default: + break; + } break; default: @@ -3391,19 +3397,28 @@ s3_recalctimings(svga_t *svga) case S3_VISION968: switch (s3->card_type) { case S3_NUMBER9_9FX_771: + svga->hdisp <<= 1; + svga->hblankstart <<= 1; + svga->hblank_end_val <<= 1; + break; case S3_SPEA_MERCURY_P64V: case S3_ELSAWIN2KPROX: - case S3_PHOENIX_VISION968: - svga->hdisp <<= 1; - svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; - svga->hblank_end_val <<= 1; + switch (s3->width) { + case 1280: + case 1600: + svga->hdisp <<= 1; + svga->hblankstart <<= 1; + svga->hblank_end_val <<= 1; + default: + break; + } break; case S3_MIROVIDEO40SV_ERGO_968: switch (s3->width) { case 1152: case 1280: svga->hdisp <<= 1; - svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; break; default: @@ -3449,13 +3464,15 @@ s3_recalctimings(svga_t *svga) case S3_86C911: case S3_86C924: svga->hdisp >>= 1; + svga->hblankstart >>= 1; + svga->hblank_end_val >>= 1; break; case S3_86C801: switch (s3->card_type) { case S3_PHOENIX_86C801: svga->hdisp >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; break; @@ -3470,19 +3487,21 @@ s3_recalctimings(svga_t *svga) case S3_PHOENIX_86C805: case S3_86C805_ONBOARD: svga->hdisp >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; break; case S3_SPEA_MIRAGE_86C805: svga->hdisp >>= 1; + svga->hblankstart >>= 1; + svga->hblank_end_val >>= 1; switch (s3->width) { case 800: case 1024: if (svga->hdisp == 400) { /*SPEA specific drivers + its VBE RAM BIOS...*/ svga->hdisp <<= 1; - svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; } break; @@ -3500,7 +3519,7 @@ s3_recalctimings(svga_t *svga) case S3_METHEUS_86C928: if (!s3->color_16bit) { svga->hdisp <<= 1; - svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; } switch (svga->hdisp) { /*This might be a driver issue*/ @@ -3525,7 +3544,7 @@ s3_recalctimings(svga_t *svga) switch (s3->width) { case 640: svga->hdisp >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; break; default: @@ -3539,7 +3558,7 @@ s3_recalctimings(svga_t *svga) break; case S3_VISION864: svga->hdisp >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; break; case S3_VISION964: @@ -3549,7 +3568,7 @@ s3_recalctimings(svga_t *svga) case 1280: case 1600: svga->hdisp <<= 1; - svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; break; default: @@ -3566,7 +3585,7 @@ s3_recalctimings(svga_t *svga) case S3_PHOENIX_VISION868: case S3_NUMBER9_9FX_531: svga->hdisp >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; break; @@ -3579,7 +3598,7 @@ s3_recalctimings(svga_t *svga) case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: svga->hdisp <<= 1; - svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; /* TODO: Is this still needed? */ if (svga->hdisp == 832) @@ -3591,7 +3610,7 @@ s3_recalctimings(svga_t *svga) case 1280: case 1600: svga->hdisp <<= 1; - svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; break; default: @@ -3606,7 +3625,7 @@ s3_recalctimings(svga_t *svga) case S3_TRIO64: case S3_TRIO32: svga->hdisp >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; break; @@ -3643,7 +3662,7 @@ s3_recalctimings(svga_t *svga) case S3_86C911: case S3_86C924: svga->hdisp >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; break; @@ -3651,7 +3670,7 @@ s3_recalctimings(svga_t *svga) switch (s3->card_type) { case S3_PHOENIX_86C801: svga->hdisp >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; break; @@ -3666,7 +3685,7 @@ s3_recalctimings(svga_t *svga) case S3_PHOENIX_86C805: case S3_86C805_ONBOARD: svga->hdisp >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; break; @@ -3678,7 +3697,7 @@ s3_recalctimings(svga_t *svga) if (svga->hdisp == 400) { /*SPEA specific drivers + its VBE RAM BIOS...*/ svga->hdisp <<= 1; - svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; } break; @@ -3695,7 +3714,7 @@ s3_recalctimings(svga_t *svga) switch (s3->card_type) { case S3_METHEUS_86C928: svga->hdisp <<= 1; - svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; switch (svga->hdisp) { /*This might be a driver issue*/ case 800: @@ -3719,7 +3738,7 @@ s3_recalctimings(svga_t *svga) switch (s3->width) { case 640: svga->hdisp >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; break; default: @@ -3733,7 +3752,7 @@ s3_recalctimings(svga_t *svga) break; case S3_VISION864: svga->hdisp >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; break; case S3_VISION868: @@ -3741,7 +3760,7 @@ s3_recalctimings(svga_t *svga) case S3_PHOENIX_VISION868: case S3_NUMBER9_9FX_531: svga->hdisp >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; break; @@ -3756,7 +3775,7 @@ s3_recalctimings(svga_t *svga) case 1280: case 1600: svga->hdisp <<= 1; - svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; break; default: @@ -3773,7 +3792,7 @@ s3_recalctimings(svga_t *svga) case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: svga->hdisp <<= 1; - svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; /* TODO: Is this still needed? */ if (svga->hdisp == 832) @@ -3785,7 +3804,7 @@ s3_recalctimings(svga_t *svga) case 1280: case 1600: svga->hdisp <<= 1; - svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; break; default: @@ -3800,7 +3819,7 @@ s3_recalctimings(svga_t *svga) case S3_TRIO64: case S3_TRIO32: svga->hdisp >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; break; @@ -3844,7 +3863,7 @@ s3_recalctimings(svga_t *svga) switch (s3->card_type) { case S3_AMI_86C924: svga->hdisp = (svga->hdisp << 1) / 3; - svga->hblankstart = (((svga->hblankstart - 1) << 1) / 3) + 1; + svga->hblankstart = (svga->hblankstart << 1) / 3; svga->hblank_end_val = (svga->hblank_end_val << 1) / 3; /* TODO: Is this still needed? */ if (svga->hdisp == 645) @@ -3859,7 +3878,7 @@ s3_recalctimings(svga_t *svga) case S3_PHOENIX_86C801: case S3_SPEA_MIRAGE_86C801: svga->hdisp = (svga->hdisp << 1) / 3; - svga->hblankstart = (((svga->hblankstart - 1) << 1) / 3) + 1; + svga->hblankstart = (svga->hblankstart << 1) / 3; svga->hblank_end_val = (svga->hblank_end_val << 1) / 3; break; default: @@ -3874,7 +3893,7 @@ s3_recalctimings(svga_t *svga) case S3_SPEA_MIRAGE_86C805: case S3_86C805_ONBOARD: svga->hdisp = (svga->hdisp << 1) / 3; - svga->hblankstart = (((svga->hblankstart - 1) << 1) / 3) + 1; + svga->hblankstart = (svga->hblankstart << 1) / 3; svga->hblank_end_val = (svga->hblank_end_val << 1) / 3; break; default: @@ -3885,7 +3904,7 @@ s3_recalctimings(svga_t *svga) switch (s3->card_type) { case S3_SPEA_MERCURY_LITE_PCI: svga->hdisp = (svga->hdisp << 1) / 3; - svga->hblankstart = (((svga->hblankstart - 1) << 1) / 3) + 1; + svga->hblankstart = (svga->hblankstart << 1) / 3; svga->hblank_end_val = (svga->hblank_end_val << 1) / 3; break; default: @@ -3894,7 +3913,7 @@ s3_recalctimings(svga_t *svga) break; case S3_VISION864: svga->hdisp = (svga->hdisp << 1) / 3; - svga->hblankstart = (((svga->hblankstart - 1) << 1) / 3) + 1; + svga->hblankstart = (svga->hblankstart << 1) / 3; svga->hblank_end_val = (svga->hblank_end_val << 1) / 3; break; case S3_VISION968: @@ -3903,7 +3922,7 @@ s3_recalctimings(svga_t *svga) switch (s3->width) { case 1280: svga->hdisp = ((svga->hdisp << 1) / 3) << 1; - svga->hblankstart = ((((svga->hblankstart - 1) << 1) / 3) << 1) + 1; + svga->hblankstart = (svga->hblankstart << 1) / 3; svga->hblank_end_val = ((svga->hblank_end_val << 1) / 3) << 1; break; default: @@ -3919,7 +3938,7 @@ s3_recalctimings(svga_t *svga) case S3_TRIO64: case S3_TRIO32: svga->hdisp /= 3; - svga->hblankstart = ((svga->hblankstart - 1) / 3) + 1; + svga->hblankstart /= 3; svga->hblank_end_val /= 3; break; @@ -3962,7 +3981,7 @@ s3_recalctimings(svga_t *svga) case S3_PHOENIX_VISION868: case S3_NUMBER9_9FX_531: svga->hdisp >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; break; default: @@ -3976,7 +3995,7 @@ s3_recalctimings(svga_t *svga) case 800: case 1024: svga->hdisp >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; break; default: @@ -3988,7 +4007,7 @@ s3_recalctimings(svga_t *svga) case 1280: case 1600: svga->hdisp <<= 1; - svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; break; default: @@ -4004,7 +4023,7 @@ s3_recalctimings(svga_t *svga) case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: svga->hdisp <<= 1; - svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; /* TODO: Is this still needed? */ if (svga->hdisp == 832) @@ -4016,7 +4035,7 @@ s3_recalctimings(svga_t *svga) case 1280: case 1600: svga->hdisp <<= 1; - svga->hblankstart = ((svga->hblankstart - 1) << 1) + 1; + svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; break; default: @@ -4200,19 +4219,19 @@ s3_trio64v_recalctimings(svga_t *svga) case 15: svga->render = svga_render_15bpp_highres; svga->hdisp >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; break; case 16: svga->render = svga_render_16bpp_highres; svga->hdisp >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; break; case 24: svga->render = svga_render_24bpp_highres; svga->hdisp /= 3; - svga->hblankstart = ((svga->hblankstart - 1) / 3) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val /= 3; break; case 32: @@ -4256,13 +4275,13 @@ s3_trio64v_recalctimings(svga_t *svga) break; case 3: /*KRGB-16 (1.5.5.5)*/ svga->htotal >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; svga->render = svga_render_15bpp_highres; break; case 5: /*RGB-16 (5.6.5)*/ svga->htotal >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; svga->render = svga_render_16bpp_highres; break; diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 8f05552c3..a0bf98815 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -864,8 +864,7 @@ s3_virge_recalctimings(svga_t *svga) if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) { svga->htotal >>= 1; svga->hdisp >>= 1; - svga->hoverride = 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; } break; @@ -874,7 +873,7 @@ s3_virge_recalctimings(svga_t *svga) if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) { svga->htotal >>= 1; svga->hdisp >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; } break; @@ -923,13 +922,13 @@ s3_virge_recalctimings(svga_t *svga) break; case 3: /*KRGB-16 (1.5.5.5)*/ svga->htotal >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; svga->render = svga_render_15bpp_highres; break; case 5: /*RGB-16 (5.6.5)*/ svga->htotal >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; + svga->hblankstart >>= 1; svga->hblank_end_val >>= 1; svga->render = svga_render_16bpp_highres; break; diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index d013ec2e5..5e28e763c 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -641,7 +641,7 @@ banshee_recalctimings(svga_t *svga) if (banshee->vidProcCfg & VIDPROCCFG_2X_MODE) { svga->hdisp *= 2; svga->htotal *= 2; - svga->hblankstart = ((svga->hblankstart - 1) * 2) + 1; + svga->hblankstart *= 2; svga->hblank_end_val *= 2; } From a13a8efb390dbecc8fd67b5a1842090eda46bb8b Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 14 Jan 2024 04:04:04 +0600 Subject: [PATCH 276/936] Implement TSS debug trap bit --- src/cpu/386.c | 2 +- src/cpu/386_dynarec.c | 11 +++++++++-- src/cpu/x86seg.c | 13 +++++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/cpu/386.c b/src/cpu/386.c index f89a8dc96..295f94056 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -311,12 +311,12 @@ exec386_2386(int32_t cycs) } } else if (trap) { flags_rebuild(); + dr[6] |= (trap == 2) ? 0x8000 : 0x4000; trap = 0; #ifndef USE_NEW_DYNAREC oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; - dr[6] |= 0x4000; x86_int(1); } diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index e4caa8a1b..e132c0300 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -268,6 +268,12 @@ exec386_dynarec_int(void) cpu_block_end = 0; x86_was_reset = 0; + if (trap == 2) { + /* Handle the T bit in the new TSS first. */ + CPU_BLOCK_END(); + goto block_ended; + } + while (!cpu_block_end) { # ifndef USE_NEW_DYNAREC oldcs = CS; @@ -321,13 +327,14 @@ exec386_dynarec_int(void) CPU_BLOCK_END(); } +block_ended: if (!cpu_state.abrt && trap) { + dr[6] |= (trap == 2) ? 0x8000 : 0x4000; trap = 0; # ifndef USE_NEW_DYNAREC oldcs = CS; # endif cpu_state.oldpc = cpu_state.pc; - dr[6] |= 0x4000; x86_int(1); } @@ -542,7 +549,7 @@ exec386_dynarec_dyn(void) # endif CPU_BLOCK_END(); - if (cpu_state.flags & T_FLAG) + if ((cpu_state.flags & T_FLAG) || (trap == 2)) CPU_BLOCK_END(); if (smi_line) CPU_BLOCK_END(); diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 96061d3fa..feaad5913 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -78,6 +78,10 @@ x86seg_log(const char *fmt, ...) # define x86seg_log(fmt, ...) #endif +#ifdef USE_DYNAREC +extern int cpu_block_end; +#endif + void #ifdef OPS_286_386 x86_doabrt_2386(int x86_abrt) @@ -2088,6 +2092,7 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) uint32_t new_edi; uint32_t new_pc; uint32_t new_flags; + uint32_t t_bit; uint32_t addr; uint32_t *segdat232 = (uint32_t *) segdat2; const x86seg *dt; @@ -2189,6 +2194,7 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) new_fs = readmemw(base, 0x58); new_gs = readmemw(base, 0x5C); new_ldt = readmemw(base, 0x60); + t_bit = readmemb(base, 0x64) & 1; cr0 |= 8; @@ -2279,6 +2285,13 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) op_loadseg(new_ds, &cpu_state.seg_ds); op_loadseg(new_fs, &cpu_state.seg_fs); op_loadseg(new_gs, &cpu_state.seg_gs); + + if (t_bit) { + trap = 2; +#ifdef USE_DYNAREC + cpu_block_end = 1; +#endif + } } else { if (limit < 43) { x86ts(NULL, seg); From 780f74bca0d8230f79250161e494fe3454d502b9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 14 Jan 2024 01:40:24 +0100 Subject: [PATCH 277/936] S3: Fix 256-color modes on the Phoenix S3 Vision 968. --- src/video/vid_s3.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 48e55e02e..6de3ffce7 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3396,6 +3396,7 @@ s3_recalctimings(svga_t *svga) break; case S3_VISION968: switch (s3->card_type) { + case S3_PHOENIX_VISION968: case S3_NUMBER9_9FX_771: svga->hdisp <<= 1; svga->hblankstart <<= 1; From f4f252c0b72e8451bfed1c238d2cae76ac48d5ee Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 14 Jan 2024 15:26:40 +0600 Subject: [PATCH 278/936] Implement x86 debug registers --- src/cpu/386.c | 15 ++++- src/cpu/386_common.c | 33 +++++++++++ src/cpu/386_common.h | 117 +++++++++++++++++++------------------ src/cpu/386_dynarec.c | 18 +++++- src/cpu/x86_ops_flag.h | 4 ++ src/cpu/x86_ops_mov_ctrl.h | 32 ++++++++++ src/cpu/x86_ops_ret.h | 4 ++ src/cpu/x86seg.c | 2 + src/cpu/x86seg_common.c | 6 ++ src/cpu/x86seg_common.h | 1 + src/include/86box/mem.h | 2 + src/io.c | 65 +++++++++++++++++++++ src/mem/mem.c | 77 ++++++++++++++++++++++-- src/mem/mmu_2386.c | 63 ++++++++++++-------- 14 files changed, 352 insertions(+), 87 deletions(-) diff --git a/src/cpu/386.c b/src/cpu/386.c index 295f94056..c1e7b9285 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -240,6 +240,7 @@ exec386_2386(int32_t cycs) cycdiff = 0; oldcyc = cycles; while (cycdiff < cycle_period) { + int ins_fetch_fault = 0; ins_cycles = cycles; #ifndef USE_NEW_DYNAREC @@ -259,6 +260,14 @@ exec386_2386(int32_t cycs) fetchdat = fastreadl_fetch(cs + cpu_state.pc); ol = opcode_length[fetchdat & 0xff]; CHECK_READ_CS(MIN(ol, 4)); + ins_fetch_fault = cpu_386_check_instruction_fault(); + + if (!cpu_state.abrt && ins_fetch_fault) { + x86gen(); + ins_fetch_fault = 0; + /* No instructions executed at this point. */ + goto block_ended; + } if (!cpu_state.abrt) { #ifdef ENABLE_386_LOG @@ -287,6 +296,7 @@ exec386_2386(int32_t cycs) if (cpu_end_block_after_ins) cpu_end_block_after_ins--; +block_ended: if (cpu_state.abrt) { flags_rebuild(); tempi = cpu_state.abrt & ABRT_MASK; @@ -309,9 +319,12 @@ exec386_2386(int32_t cycs) #endif } } + if (!x86_was_reset && ins_fetch_fault) + x86gen(); /* This is supposed to be the first one serviced by the processor according to the manual. */ } else if (trap) { flags_rebuild(); - dr[6] |= (trap == 2) ? 0x8000 : 0x4000; + if (trap != 4) + dr[6] |= (trap == 2) ? 0x8000 : 0x4000; trap = 0; #ifndef USE_NEW_DYNAREC oldcs = CS; diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 60ecd8954..b80716142 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -80,6 +80,7 @@ int smm_in_hlt = 0; int smi_block = 0; int prefetch_prefixes = 0; +int rf_flag_no_clear = 0; int tempc; int oldcpl; @@ -1655,6 +1656,38 @@ cpu_386_flags_rebuild(void) flags_rebuild(); } +int +cpu_386_check_instruction_fault(void) +{ + int i = 0; + int fault = 0; + /* Report no fault if RF is set. */ + if (cpu_state.eflags & RF_FLAG) + return 0; + + /* Make sure breakpoints are enabled. */ + if (!(dr[7] & 0xFF)) + return 0; + + for (i = 0; i < 4; i++) { + int breakpoint_enabled = !!(dr[7] & (0x3 << (2 * i))) && !(dr[7] & (0x30000 << (4 * i))); + uint64_t translated_addr = 0xffffffffffffffffULL; + if (!breakpoint_enabled) + continue; + if (!(cr0 >> 31)) + translated_addr = dr[i]; + else + translated_addr = mmutranslate_noabrt(dr[i], 0); + + if ((cs + cpu_state.pc) == translated_addr) { + dr[6] |= (1 << i); + fault = 1; + } + } + + return fault; +} + int sysenter(uint32_t fetchdat) { diff --git a/src/cpu/386_common.h b/src/cpu/386_common.h index 22fbd4bff..0478fe5c6 100644 --- a/src/cpu/386_common.h +++ b/src/cpu/386_common.h @@ -50,80 +50,80 @@ # define do_mmut_ww(s, a, b) do_mmutranslate_2386((s) + (a), b, 2, 1) # define do_mmut_wl(s, a, b) do_mmutranslate_2386((s) + (a), b, 4, 1) #else -# define readmemb_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl_no_mmut((s) + (a), b) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) -# define readmemw_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl_no_mmut((s) + (a), b) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) -# define readmeml_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll_no_mmut((s) + (a), b) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) -# define readmemb(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl((s) + (a)) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) -# define readmemw(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl((s) + (a)) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) -# define readmeml(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll((s) + (a)) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) -# define readmemq(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) ? readmemql((s) + (a)) : *(uint64_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) +# define readmemb_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) ? readmembl_no_mmut((s) + (a), b) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) +# define readmemw_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF) || (((s) + (a)) & 1)) ? readmemwl_no_mmut((s) + (a), b) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +# define readmeml_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF) || (((s) + (a)) & 3)) ? readmemll_no_mmut((s) + (a), b) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +# define readmemb(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) ? readmembl((s) + (a)) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) +# define readmemw(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF) || (((s) + (a)) & 1)) ? readmemwl((s) + (a)) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +# define readmeml(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF) || (((s) + (a)) & 3)) ? readmemll((s) + (a)) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +# define readmemq(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF) || (((s) + (a)) & 7)) ? readmemql((s) + (a)) : *(uint64_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) -# define writememb_n(s, a, b, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ - writemembl_no_mmut((s) + (a), b, v); \ - else \ +# define writememb_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) \ + writemembl_no_mmut((s) + (a), b, v); \ + else \ *(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -# define writememw_n(s, a, b, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ - writememwl_no_mmut((s) + (a), b, v); \ - else \ +# define writememw_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1) || (dr[7] & 0xFF)) \ + writememwl_no_mmut((s) + (a), b, v); \ + else \ *(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -# define writememl_n(s, a, b, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ - writememll_no_mmut((s) + (a), b, v); \ - else \ +# define writememl_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3) || (dr[7] & 0xFF)) \ + writememll_no_mmut((s) + (a), b, v); \ + else \ *(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -# define writememb(s, a, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ - writemembl((s) + (a), v); \ - else \ +# define writememb(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) \ + writemembl((s) + (a), v); \ + else \ *(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -# define writememw(s, a, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ - writememwl((s) + (a), v); \ - else \ +# define writememw(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1) || (dr[7] & 0xFF)) \ + writememwl((s) + (a), v); \ + else \ *(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -# define writememl(s, a, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ - writememll((s) + (a), v); \ - else \ +# define writememl(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3) || (dr[7] & 0xFF)) \ + writememll((s) + (a), v); \ + else \ *(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -# define writememq(s, a, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) \ - writememql((s) + (a), v); \ - else \ +# define writememq(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7) || (dr[7] & 0xFF)) \ + writememql((s) + (a), v); \ + else \ *(uint64_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -# define do_mmut_rb(s, a, b) \ - if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ +# define do_mmut_rb(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) \ do_mmutranslate((s) + (a), b, 1, 0) -# define do_mmut_rw(s, a, b) \ - if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ +# define do_mmut_rw(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1) || (dr[7] & 0xFF)) \ do_mmutranslate((s) + (a), b, 2, 0) -# define do_mmut_rl(s, a, b) \ - if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ +# define do_mmut_rl(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3) || (dr[7] & 0xFF)) \ do_mmutranslate((s) + (a), b, 4, 0) -# define do_mmut_rb2(s, a, b) \ - old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ - if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ +# define do_mmut_rb2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) \ do_mmutranslate((s) + (a), b, 1, 0) -# define do_mmut_rw2(s, a, b) \ - old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ - if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ +# define do_mmut_rw2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1) || (dr[7] & 0xFF)) \ do_mmutranslate((s) + (a), b, 2, 0) -# define do_mmut_rl2(s, a, b) \ - old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ - if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ +# define do_mmut_rl2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3) || (dr[7] & 0xFF)) \ do_mmutranslate((s) + (a), b, 4, 0) -# define do_mmut_wb(s, a, b) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ +# define do_mmut_wb(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) \ do_mmutranslate((s) + (a), b, 1, 1) -# define do_mmut_ww(s, a, b) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ +# define do_mmut_ww(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1) || (dr[7] & 0xFF)) \ do_mmutranslate((s) + (a), b, 2, 1) -# define do_mmut_wl(s, a, b) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ +# define do_mmut_wl(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3) || (dr[7] & 0xFF)) \ do_mmutranslate((s) + (a), b, 4, 1) #endif @@ -674,3 +674,8 @@ seteaq(uint64_t v) cpu_state.pc += 2 #endif + +/* Resume Flag handling. */ +extern int rf_flag_no_clear; + +int cpu_386_check_instruction_fault(void); \ No newline at end of file diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index e132c0300..16759634d 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -223,7 +223,7 @@ fetch_ea_16_long(uint32_t rmdat) #include "386_ops.h" -#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) +#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG) && !(dr[7] & 0xFF)) #ifdef USE_DYNAREC int32_t cycles_main = 0; @@ -285,6 +285,11 @@ exec386_dynarec_int(void) cpu_state.ea_seg = &cpu_state.seg_ds; cpu_state.ssegs = 0; + if (UNLIKELY(cpu_386_check_instruction_fault())) { + x86gen(); + goto block_ended; + } + fetchdat = fastreadl_fetch(cs + cpu_state.pc); # ifdef ENABLE_386_DYNAREC_LOG if (in_smm) @@ -306,6 +311,14 @@ exec386_dynarec_int(void) cpu_state.pc &= 0xffff; # endif + if (!cpu_state.abrt) { + if (!rf_flag_no_clear) { + cpu_state.eflags &= ~RF_FLAG; + } + + rf_flag_no_clear = 0; + } + if (((cs + cpu_state.pc) >> 12) != pccache) CPU_BLOCK_END(); @@ -329,7 +342,8 @@ exec386_dynarec_int(void) block_ended: if (!cpu_state.abrt && trap) { - dr[6] |= (trap == 2) ? 0x8000 : 0x4000; + if (trap != 4) + dr[6] |= (trap == 2) ? 0x8000 : 0x4000; trap = 0; # ifndef USE_NEW_DYNAREC oldcs = CS; diff --git a/src/cpu/x86_ops_flag.h b/src/cpu/x86_ops_flag.h index f08b30fce..ba34ae5e7 100644 --- a/src/cpu/x86_ops_flag.h +++ b/src/cpu/x86_ops_flag.h @@ -178,6 +178,7 @@ opPOPF_186(uint32_t fetchdat) else cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; flags_extract(); + rf_flag_no_clear = 1; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); @@ -211,6 +212,7 @@ opPOPF_286(uint32_t fetchdat) else cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; flags_extract(); + rf_flag_no_clear = 1; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); @@ -264,6 +266,7 @@ opPOPF(uint32_t fetchdat) cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; } flags_extract(); + rf_flag_no_clear = 1; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); @@ -307,6 +310,7 @@ opPOPFD(uint32_t fetchdat) cpu_state.eflags = (templ >> 16) & 3; flags_extract(); + rf_flag_no_clear = 1; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 0); diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h index b0c841f83..c57dc8226 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu/x86_ops_mov_ctrl.h @@ -87,6 +87,12 @@ opMOV_r_DRx_a16(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); + if (cpu_reg == 4 || cpu_reg == 5) { + if (cr4 & 0x8) + x86illegal(); + else + cpu_reg += 2; + } cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); CLOCK_CYCLES(6); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); @@ -100,6 +106,12 @@ opMOV_r_DRx_a32(uint32_t fetchdat) return 1; } fetch_ea_32(fetchdat); + if (cpu_reg == 4 || cpu_reg == 5) { + if (cr4 & 0x8) + x86illegal(); + else + cpu_reg += 2; + } cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); CLOCK_CYCLES(6); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); @@ -228,10 +240,23 @@ opMOV_DRx_r_a16(uint32_t fetchdat) x86gpf(NULL, 0); return 1; } + if ((dr[6] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) { + dr[7] |= 0x2000; + dr[6] &= ~0x2000; + x86gen(); + return 1; + } fetch_ea_16(fetchdat); + if (cpu_reg == 4 || cpu_reg == 5) { + if (cr4 & 0x8) + x86illegal(); + else + cpu_reg += 2; + } dr[cpu_reg] = cpu_state.regs[cpu_rm].l; CLOCK_CYCLES(6); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + CPU_BLOCK_END(); return 0; } static int @@ -242,9 +267,16 @@ opMOV_DRx_r_a32(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); + if (cpu_reg == 4 || cpu_reg == 5) { + if (cr4 & 0x8) + x86illegal(); + else + cpu_reg += 2; + } dr[cpu_reg] = cpu_state.regs[cpu_rm].l; CLOCK_CYCLES(6); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + CPU_BLOCK_END(); return 0; } diff --git a/src/cpu/x86_ops_ret.h b/src/cpu/x86_ops_ret.h index 0d9a6370b..ca85bf2b0 100644 --- a/src/cpu/x86_ops_ret.h +++ b/src/cpu/x86_ops_ret.h @@ -135,6 +135,7 @@ opIRET_186(uint32_t fetchdat) } flags_extract(); nmi_enable = 1; + rf_flag_no_clear = 1; CPU_BLOCK_END(); PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); @@ -175,6 +176,7 @@ opIRET_286(uint32_t fetchdat) } flags_extract(); nmi_enable = 1; + rf_flag_no_clear = 1; CPU_BLOCK_END(); PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); @@ -243,6 +245,7 @@ opIRET(uint32_t fetchdat) } flags_extract(); nmi_enable = 1; + rf_flag_no_clear = 1; CPU_BLOCK_END(); PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); @@ -285,6 +288,7 @@ opIRETD(uint32_t fetchdat) } flags_extract(); nmi_enable = 1; + rf_flag_no_clear = 1; CPU_BLOCK_END(); PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1); diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index feaad5913..553e3dbc4 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -2286,6 +2286,8 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) op_loadseg(new_fs, &cpu_state.seg_fs); op_loadseg(new_gs, &cpu_state.seg_gs); + rf_flag_no_clear = 1; + if (t_bit) { trap = 2; #ifdef USE_DYNAREC diff --git a/src/cpu/x86seg_common.c b/src/cpu/x86seg_common.c index 8926af0d7..12b698b1a 100644 --- a/src/cpu/x86seg_common.c +++ b/src/cpu/x86seg_common.c @@ -87,6 +87,12 @@ x86de(UNUSED(char *s), UNUSED(uint16_t error)) #endif } +void +x86gen(void) +{ + x86_int(1); +} + void x86gpf(UNUSED(char *s), uint16_t error) { diff --git a/src/cpu/x86seg_common.h b/src/cpu/x86seg_common.h index f4bffed40..9f9049322 100644 --- a/src/cpu/x86seg_common.h +++ b/src/cpu/x86seg_common.h @@ -41,6 +41,7 @@ extern int cgate32; extern int intgatesize; extern void x86seg_reset(void); +extern void x86gen(void); extern void x86de(char *s, uint16_t error); extern void x86gpf(char *s, uint16_t error); extern void x86gpf_expected(char *s, uint16_t error); diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index 69a2b5de8..db95d3f7b 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -439,6 +439,8 @@ extern void mem_reset_page_blocks(void); extern void flushmmucache(void); extern void flushmmucache_nopc(void); +extern void mem_debug_check_addr(uint32_t addr, int write); + extern void mem_a20_init(void); extern void mem_a20_recalc(void); diff --git a/src/io.c b/src/io.c index 0e68049c3..e6ab88453 100644 --- a/src/io.c +++ b/src/io.c @@ -279,6 +279,59 @@ io_handler_interleaved(int set, uint16_t base, int size, io_handler_common(set, base, size, inb, inw, inl, outb, outw, outl, priv, 2); } +extern int trap; +/* Set trap for I/O address breakpoints. */ +void +io_debug_check_addr(uint16_t addr) +{ + int i = 0; + int set_trap = 0; + + if (trap == 4) + return; /* Debug trap already pending. */ + + if (!(dr[7] & 0xFF)) + return; + + if (!(cr4 & 0x8)) + return; /* No I/O debug trap. */ + + for (i = 0; i < 4; i++) { + uint16_t dr_addr = dr[i] & 0xFFFF; + int breakpoint_enabled = !!(dr[7] & (0x3 << (2 * i))); + int len_type_pair = ((dr[7] >> 16) & (0xF << (4 * i))) >> (4 * i); + if (!breakpoint_enabled) + continue; + if ((len_type_pair & 3) != 2) + continue; + + switch ((len_type_pair >> 2) & 3) + { + case 0x00: + if (dr_addr == addr) { + set_trap = 1; + dr[6] |= (1 << i); + } + break; + case 0x01: + if ((dr_addr & ~1) == addr || ((dr_addr & ~1) + 1) == (addr + 1)) { + set_trap = 1; + dr[6] |= (1 << i); + } + break; + case 0x03: + dr_addr &= ~3; + if (addr >= dr_addr && addr < (dr_addr + 4)) { + set_trap = 1; + dr[6] |= (1 << i); + } + break; + } + } + if (set_trap) + trap = 4; +} + uint8_t inb(uint16_t port) { @@ -290,6 +343,8 @@ inb(uint16_t port) int qfound = 0; #endif + io_debug_check_addr(port); + if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { ret = pci_read(port, NULL); found = 1; @@ -350,6 +405,8 @@ outb(uint16_t port, uint8_t val) int qfound = 0; #endif + io_debug_check_addr(port); + if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { pci_write(port, val, NULL); found = 1; @@ -402,6 +459,8 @@ inw(uint16_t port) #endif uint8_t ret8[2]; + io_debug_check_addr(port); + if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { ret = pci_readw(port, NULL); found = 2; @@ -474,6 +533,8 @@ outw(uint16_t port, uint16_t val) int qfound = 0; #endif + io_debug_check_addr(port); + if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { pci_writew(port, val, NULL); found = 2; @@ -542,6 +603,8 @@ inl(uint16_t port) int qfound = 0; #endif + io_debug_check_addr(port); + if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { ret = pci_readl(port, NULL); found = 4; @@ -646,6 +709,8 @@ outl(uint16_t port, uint32_t val) #endif int i = 0; + io_debug_check_addr(port); + if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { pci_writel(port, val, NULL); found = 4; diff --git a/src/mem/mem.c b/src/mem/mem.c index 0b002b302..887720d3d 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -161,6 +161,57 @@ mem_log(const char *fmt, ...) # define mem_log(fmt, ...) #endif +/* Set trap for data address breakpoints. */ +void +mem_debug_check_addr(uint32_t addr, int write) +{ + int i = 0; + int set_trap = 0; + + if (trap == 4) + return; /* Debug trap already pending. */ + + if (!(dr[7] & 0xFF)) + return; + + for (i = 0; i < 4; i++) { + uint32_t dr_addr = dr[i]; + int breakpoint_enabled = !!(dr[7] & (0x3 << (2 * i))); + int len_type_pair = ((dr[7] >> 16) & (0xF << (4 * i))) >> (4 * i); + if (!breakpoint_enabled) + continue; + if (!write && (len_type_pair & 3) != 3) + continue; + if ((len_type_pair & 3) != 1) + continue; + + switch ((len_type_pair >> 2) & 3) + { + case 0x00: + if (dr_addr == addr) { + set_trap = 1; + dr[6] |= (1 << i); + } + break; + case 0x01: + if ((dr_addr & ~1) == addr || ((dr_addr & ~1) + 1) == (addr + 1)) { + set_trap = 1; + dr[6] |= (1 << i); + } + break; + case 0x03: + dr_addr &= ~3; + if (addr >= dr_addr && addr < (dr_addr + 4)) { + set_trap = 1; + dr[6] |= (1 << i); + } + break; + } + } + if (set_trap) + trap = 4; +} + int mem_addr_is_ram(uint32_t addr) { @@ -790,6 +841,7 @@ readmembl(uint32_t addr) uint64_t a; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1); + mem_debug_check_addr(addr, 0); addr64 = (uint64_t) addr; mem_logical_addr = addr; @@ -819,6 +871,7 @@ writemembl(uint32_t addr, uint8_t val) uint64_t a; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1); + mem_debug_check_addr(addr, 1); addr64 = (uint64_t) addr; mem_logical_addr = addr; @@ -905,6 +958,8 @@ readmemwl(uint32_t addr) addr64a[0] = addr; addr64a[1] = addr + 1; + mem_debug_check_addr(addr, 0); + mem_debug_check_addr(addr + 1, 0); GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 2); mem_logical_addr = addr; @@ -963,6 +1018,8 @@ writememwl(uint32_t addr, uint16_t val) addr64a[0] = addr; addr64a[1] = addr + 1; + mem_debug_check_addr(addr, 1); + mem_debug_check_addr(addr + 1, 1); GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 2); mem_logical_addr = addr; @@ -1139,8 +1196,10 @@ readmemll(uint32_t addr) int i; uint64_t a = 0x0000000000000000ULL; - for (i = 0; i < 4; i++) + for (i = 0; i < 4; i++) { addr64a[i] = (uint64_t) (addr + i); + mem_debug_check_addr(addr + i, 0); + } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 4); mem_logical_addr = addr; @@ -1213,8 +1272,10 @@ writememll(uint32_t addr, uint32_t val) int i; uint64_t a = 0x0000000000000000ULL; - for (i = 0; i < 4; i++) + for (i = 0; i < 4; i++) { addr64a[i] = (uint64_t) (addr + i); + mem_debug_check_addr(addr + i, 1); + } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 4); mem_logical_addr = addr; @@ -1417,8 +1478,10 @@ readmemql(uint32_t addr) int i; uint64_t a = 0x0000000000000000ULL; - for (i = 0; i < 8; i++) + for (i = 0; i < 8; i++) { addr64a[i] = (uint64_t) (addr + i); + mem_debug_check_addr(addr + i, 0); + } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 8); mem_logical_addr = addr; @@ -1483,8 +1546,10 @@ writememql(uint32_t addr, uint64_t val) int i; uint64_t a = 0x0000000000000000ULL; - for (i = 0; i < 8; i++) + for (i = 0; i < 8; i++) { addr64a[i] = (uint64_t) (addr + i); + mem_debug_check_addr(addr + i, 1); + } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 8); mem_logical_addr = addr; @@ -1582,8 +1647,10 @@ do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write) uint32_t last_addr = addr + (num - 1); uint64_t a = 0x0000000000000000ULL; - for (i = 0; i < num; i++) + mem_debug_check_addr(addr, write); + for (i = 0; i < num; i++) { a64[i] = (uint64_t) addr; + } for (i = 0; i < num; i++) { if (cr0 >> 31) { diff --git a/src/mem/mmu_2386.c b/src/mem/mmu_2386.c index 21c62b833..fc2237bec 100644 --- a/src/mem/mmu_2386.c +++ b/src/mem/mmu_2386.c @@ -243,6 +243,7 @@ readmembl_2386(uint32_t addr) GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1); + mem_debug_check_addr(addr, 0); addr64 = (uint64_t) addr; mem_logical_addr = addr; @@ -270,6 +271,7 @@ writemembl_2386(uint32_t addr, uint8_t val) mem_mapping_t *map; uint64_t a; + mem_debug_check_addr(addr, 1); GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1); addr64 = (uint64_t) addr; @@ -347,6 +349,8 @@ readmemwl_2386(uint32_t addr) addr64a[0] = addr; addr64a[1] = addr + 1; + mem_debug_check_addr(addr, 0); + mem_debug_check_addr(addr + 1, 0); GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 2); mem_logical_addr = addr; @@ -402,6 +406,8 @@ writememwl_2386(uint32_t addr, uint16_t val) addr64a[0] = addr; addr64a[1] = addr + 1; + mem_debug_check_addr(addr, 1); + mem_debug_check_addr(addr + 1, 1); GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 2); mem_logical_addr = addr; @@ -555,8 +561,10 @@ readmemll_2386(uint32_t addr) int i; uint64_t a = 0x0000000000000000ULL; - for (i = 0; i < 4; i++) + for (i = 0; i < 4; i++) { addr64a[i] = (uint64_t) (addr + i); + mem_debug_check_addr(addr + i, 0); + } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 4); mem_logical_addr = addr; @@ -626,8 +634,10 @@ writememll_2386(uint32_t addr, uint32_t val) int i; uint64_t a = 0x0000000000000000ULL; - for (i = 0; i < 4; i++) + for (i = 0; i < 4; i++) { addr64a[i] = (uint64_t) (addr + i); + mem_debug_check_addr(addr + i, 1); + } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 4); mem_logical_addr = addr; @@ -807,8 +817,10 @@ readmemql_2386(uint32_t addr) int i; uint64_t a = 0x0000000000000000ULL; - for (i = 0; i < 8; i++) + for (i = 0; i < 8; i++) { addr64a[i] = (uint64_t) (addr + i); + mem_debug_check_addr(addr + i, 0); + } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 8); mem_logical_addr = addr; @@ -870,8 +882,10 @@ writememql_2386(uint32_t addr, uint64_t val) int i; uint64_t a = 0x0000000000000000ULL; - for (i = 0; i < 8; i++) + for (i = 0; i < 8; i++) { addr64a[i] = (uint64_t) (addr + i); + mem_debug_check_addr(addr + i, 1); + } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 8); mem_logical_addr = addr; @@ -957,32 +971,35 @@ do_mmutranslate_2386(uint32_t addr, uint32_t *a64, int num, int write) uint32_t last_addr = addr + (num - 1); uint64_t a = 0x0000000000000000ULL; + mem_debug_check_addr(addr, write); + for (i = 0; i < num; i++) a64[i] = (uint64_t) addr; - for (i = 0; i < num; i++) { - if (cr0 >> 31) { - /* If we have encountered at least one page fault, mark all subsequent addresses as - having page faulted, prevents false negatives in readmem*l_no_mmut. */ - if ((i > 0) && cpu_state.abrt && !high_page) - a64[i] = a64[i - 1]; - /* If we are on the same page, there is no need to translate again, as we can just - reuse the previous result. */ - else if (i == 0) { - a = mmutranslatereal_2386(addr, write); - a64[i] = (uint32_t) a; - } else if (!(addr & 0xfff)) { - a = mmutranslatereal_2386(last_addr, write); - a64[i] = (uint32_t) a; + if (!(cr0 >> 31)) + return; - if (!cpu_state.abrt) { - a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); - a64[i] = (uint32_t) a; - } - } else { + for (i = 0; i < num; i++) { + /* If we have encountered at least one page fault, mark all subsequent addresses as + having page faulted, prevents false negatives in readmem*l_no_mmut. */ + if ((i > 0) && cpu_state.abrt && !high_page) + a64[i] = a64[i - 1]; + /* If we are on the same page, there is no need to translate again, as we can just + reuse the previous result. */ + else if (i == 0) { + a = mmutranslatereal_2386(addr, write); + a64[i] = (uint32_t) a; + } else if (!(addr & 0xfff)) { + a = mmutranslatereal_2386(last_addr, write); + a64[i] = (uint32_t) a; + + if (!cpu_state.abrt) { a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); a64[i] = (uint32_t) a; } + } else { + a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); + a64[i] = (uint32_t) a; } addr++; From 3cf747d93e31f903e8345d54f27326717c1a8fa8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 14 Jan 2024 15:33:35 +0600 Subject: [PATCH 279/936] Forgot taskswitch DR7 clearing --- src/cpu/x86seg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 553e3dbc4..51045e68d 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -2469,6 +2469,7 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) tr.limit = limit; tr.access = segdat[2] >> 8; tr.ar_high = segdat[3] & 0xff; + dr[7] &= 0xFFFFFFAA; } void From 55f03f63e5a5a70fef96528d0c415b01d799bc48 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 14 Jan 2024 20:12:53 +0600 Subject: [PATCH 280/936] More oversight fixing --- src/cpu/386_common.c | 4 ++-- src/cpu/386_dynarec.c | 14 +++++++++----- src/cpu/x86seg.c | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index b80716142..d7a64b7b4 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -1492,7 +1492,7 @@ x86_int_sw(int num) } } - trap = 0; + trap &= ~1; CPU_BLOCK_END(); } @@ -1535,7 +1535,7 @@ x86_int_sw_rm(int num) #endif cycles -= timing_int_rm; - trap = 0; + trap &= ~1; CPU_BLOCK_END(); return 0; diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index 16759634d..c4afbb431 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -300,7 +300,7 @@ exec386_dynarec_int(void) opcode = fetchdat & 0xFF; fetchdat >>= 8; - trap = cpu_state.flags & T_FLAG; + trap |= cpu_state.flags & T_FLAG; cpu_state.pc++; x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); @@ -342,8 +342,9 @@ exec386_dynarec_int(void) block_ended: if (!cpu_state.abrt && trap) { - if (trap != 4) - dr[6] |= (trap == 2) ? 0x8000 : 0x4000; + if (trap & 2) dr[6] |= 0x8000; + if (trap & 1) dr[6] |= 0x4000; + trap = 0; # ifndef USE_NEW_DYNAREC oldcs = CS; @@ -864,7 +865,7 @@ exec386(int32_t cycs) #endif opcode = fetchdat & 0xFF; fetchdat >>= 8; - trap = cpu_state.flags & T_FLAG; + trap |= cpu_state.flags & T_FLAG; cpu_state.pc++; x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); @@ -908,12 +909,15 @@ exec386(int32_t cycs) } } else if (trap) { flags_rebuild(); + if (trap & 1) + dr[6] |= 0x4000; + if (trap & 2) + dr[6] |= 0x8000; trap = 0; #ifndef USE_NEW_DYNAREC oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; - dr[6] |= 0x4000; x86_int(1); } diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 51045e68d..245f3fa65 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -2289,7 +2289,7 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) rf_flag_no_clear = 1; if (t_bit) { - trap = 2; + trap |= 2; #ifdef USE_DYNAREC cpu_block_end = 1; #endif From b884ef825c11696dd039a4ac5838a2db261ef213 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 14 Jan 2024 20:58:29 +0600 Subject: [PATCH 281/936] And 386.c --- src/cpu/386.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/386.c b/src/cpu/386.c index c1e7b9285..0eae622e9 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -323,8 +323,8 @@ block_ended: x86gen(); /* This is supposed to be the first one serviced by the processor according to the manual. */ } else if (trap) { flags_rebuild(); - if (trap != 4) - dr[6] |= (trap == 2) ? 0x8000 : 0x4000; + if (trap & 2) dr[6] |= 0x8000; + if (trap & 1) dr[6] |= 0x4000; trap = 0; #ifndef USE_NEW_DYNAREC oldcs = CS; From 128a2f2b5d02471b8dd1f3445b01510a31cedc3d Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 14 Jan 2024 21:21:02 +0600 Subject: [PATCH 282/936] And finally exec386 --- src/cpu/386_dynarec.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index c4afbb431..73441a346 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -856,6 +856,11 @@ exec386(int32_t cycs) cpu_state.ea_seg = &cpu_state.seg_ds; cpu_state.ssegs = 0; + if (UNLIKELY(cpu_386_check_instruction_fault())) { + x86gen(); + goto block_ended; + } + fetchdat = fastreadl_fetch(cs + cpu_state.pc); if (!cpu_state.abrt) { @@ -885,6 +890,7 @@ exec386(int32_t cycs) if (cpu_end_block_after_ins) cpu_end_block_after_ins--; +block_ended: if (cpu_state.abrt) { flags_rebuild(); tempi = cpu_state.abrt & ABRT_MASK; From c3fa0fc18b124ca45e4b832565586f072ab7f88b Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 14 Jan 2024 21:32:43 +0600 Subject: [PATCH 283/936] Also account for data address breakpoints --- src/io.c | 2 +- src/mem/mem.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/io.c b/src/io.c index e6ab88453..3df413f9b 100644 --- a/src/io.c +++ b/src/io.c @@ -329,7 +329,7 @@ io_debug_check_addr(uint16_t addr) } } if (set_trap) - trap = 4; + trap |= 4; } uint8_t diff --git a/src/mem/mem.c b/src/mem/mem.c index 887720d3d..567c17634 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -209,7 +209,7 @@ mem_debug_check_addr(uint32_t addr, int write) } } if (set_trap) - trap = 4; + trap |= 4; } int From 8c6fc11bb216a5ef2521a1267f455d33c141df71 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 15 Jan 2024 00:05:48 +0600 Subject: [PATCH 284/936] Fix TSS trap-bit handling --- src/cpu/386_dynarec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index 73441a346..dcdb3c151 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -268,7 +268,7 @@ exec386_dynarec_int(void) cpu_block_end = 0; x86_was_reset = 0; - if (trap == 2) { + if (trap & 2) { /* Handle the T bit in the new TSS first. */ CPU_BLOCK_END(); goto block_ended; @@ -342,6 +342,7 @@ exec386_dynarec_int(void) block_ended: if (!cpu_state.abrt && trap) { + //pclog("Debug trap 0x%X\n", trap); if (trap & 2) dr[6] |= 0x8000; if (trap & 1) dr[6] |= 0x4000; From 911deeab1a4b38be978fe0609a384b9a6e7517ea Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 15 Jan 2024 01:09:52 +0600 Subject: [PATCH 285/936] Fix single-step trap flag setting --- src/cpu/386.c | 2 +- src/cpu/386_dynarec.c | 4 ++-- src/io.c | 3 --- src/mem/mem.c | 3 --- 4 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/cpu/386.c b/src/cpu/386.c index 0eae622e9..b5a1e61e3 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -276,7 +276,7 @@ exec386_2386(int32_t cycs) #endif opcode = fetchdat & 0xFF; fetchdat >>= 8; - trap = cpu_state.flags & T_FLAG; + trap |= !!(cpu_state.flags & T_FLAG); cpu_state.pc++; x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index dcdb3c151..ca2e60aea 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -300,7 +300,7 @@ exec386_dynarec_int(void) opcode = fetchdat & 0xFF; fetchdat >>= 8; - trap |= cpu_state.flags & T_FLAG; + trap |= !!(cpu_state.flags & T_FLAG); cpu_state.pc++; x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); @@ -871,7 +871,7 @@ exec386(int32_t cycs) #endif opcode = fetchdat & 0xFF; fetchdat >>= 8; - trap |= cpu_state.flags & T_FLAG; + trap |= !!(cpu_state.flags & T_FLAG); cpu_state.pc++; x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); diff --git a/src/io.c b/src/io.c index 3df413f9b..d09b9c10f 100644 --- a/src/io.c +++ b/src/io.c @@ -287,9 +287,6 @@ io_debug_check_addr(uint16_t addr) int i = 0; int set_trap = 0; - if (trap == 4) - return; /* Debug trap already pending. */ - if (!(dr[7] & 0xFF)) return; diff --git a/src/mem/mem.c b/src/mem/mem.c index 567c17634..1ed1e8118 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -168,9 +168,6 @@ mem_debug_check_addr(uint32_t addr, int write) int i = 0; int set_trap = 0; - if (trap == 4) - return; /* Debug trap already pending. */ - if (!(dr[7] & 0xFF)) return; From 2eb39a8c5c67b262d276ef8a803905759d3a4dbf Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 15 Jan 2024 01:19:21 +0600 Subject: [PATCH 286/936] Add more missing memory checking --- src/mem/mem.c | 14 ++++++++++++++ src/mem/mmu_2386.c | 15 +++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/mem/mem.c b/src/mem/mem.c index 1ed1e8118..8f9a883d7 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -901,6 +901,7 @@ readmembl_no_mmut(uint32_t addr, uint32_t a64) mem_mapping_t *map; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1); + mem_debug_check_addr(addr, 0); mem_logical_addr = addr; @@ -928,6 +929,7 @@ writemembl_no_mmut(uint32_t addr, uint32_t a64, uint8_t val) GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1); mem_logical_addr = addr; + mem_debug_check_addr(addr, 1); if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_b) { page_lookup[addr >> 12]->write_b(addr, val, page_lookup[addr >> 12]); @@ -1092,6 +1094,8 @@ readmemwl_no_mmut(uint32_t addr, uint32_t *a64) GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 2); mem_logical_addr = addr; + mem_debug_check_addr(addr, 0); + mem_debug_check_addr(addr + 1, 0); if (addr & 1) { if (!cpu_cyrix_alignment || (addr & 7) == 7) @@ -1138,6 +1142,8 @@ writememwl_no_mmut(uint32_t addr, uint32_t *a64, uint16_t val) GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 2); mem_logical_addr = addr; + mem_debug_check_addr(addr, 1); + mem_debug_check_addr(addr + 1, 1); if (addr & 1) { if (!cpu_cyrix_alignment || (addr & 7) == 7) @@ -1366,6 +1372,10 @@ readmemll_no_mmut(uint32_t addr, uint32_t *a64) GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 4); mem_logical_addr = addr; + mem_debug_check_addr(addr, 0); + mem_debug_check_addr(addr + 1, 0); + mem_debug_check_addr(addr + 2, 0); + mem_debug_check_addr(addr + 3, 0); if (addr & 3) { if (!cpu_cyrix_alignment || (addr & 7) > 4) @@ -1414,6 +1424,10 @@ writememll_no_mmut(uint32_t addr, uint32_t *a64, uint32_t val) GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 4); mem_logical_addr = addr; + mem_debug_check_addr(addr, 1); + mem_debug_check_addr(addr + 1, 1); + mem_debug_check_addr(addr + 2, 1); + mem_debug_check_addr(addr + 3, 1); if (addr & 3) { if (!cpu_cyrix_alignment || (addr & 7) > 4) diff --git a/src/mem/mmu_2386.c b/src/mem/mmu_2386.c index fc2237bec..e6fc5ab36 100644 --- a/src/mem/mmu_2386.c +++ b/src/mem/mmu_2386.c @@ -300,6 +300,7 @@ readmembl_no_mmut_2386(uint32_t addr, uint32_t a64) mem_mapping_t *map; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1); + mem_debug_check_addr(addr, 0); mem_logical_addr = addr; @@ -325,6 +326,7 @@ writemembl_no_mmut_2386(uint32_t addr, uint32_t a64, uint8_t val) mem_mapping_t *map; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1); + mem_debug_check_addr(addr, 1); mem_logical_addr = addr; @@ -473,6 +475,8 @@ readmemwl_no_mmut_2386(uint32_t addr, uint32_t *a64) GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 2); mem_logical_addr = addr; + mem_debug_check_addr(addr, 0); + mem_debug_check_addr(addr + 1, 0); if (addr & 1) { if (!cpu_cyrix_alignment || (addr & 7) == 7) @@ -514,6 +518,8 @@ writememwl_no_mmut_2386(uint32_t addr, uint32_t *a64, uint16_t val) mem_mapping_t *map; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 2); + mem_debug_check_addr(addr, 1); + mem_debug_check_addr(addr + 1, 1); mem_logical_addr = addr; @@ -719,6 +725,11 @@ readmemll_no_mmut_2386(uint32_t addr, uint32_t *a64) mem_mapping_t *map; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 4); + + mem_debug_check_addr(addr, 0); + mem_debug_check_addr(addr + 1, 0); + mem_debug_check_addr(addr + 2, 0); + mem_debug_check_addr(addr + 3, 0); mem_logical_addr = addr; @@ -766,6 +777,10 @@ writememll_no_mmut_2386(uint32_t addr, uint32_t *a64, uint32_t val) GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 4); mem_logical_addr = addr; + mem_debug_check_addr(addr, 1); + mem_debug_check_addr(addr + 1, 1); + mem_debug_check_addr(addr + 2, 2); + mem_debug_check_addr(addr + 3, 3); if (addr & 3) { if (!cpu_cyrix_alignment || (addr & 7) > 4) From a7be107e9ba2d7fae1dfa7fc829a9d43db9f7b0e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 15 Jan 2024 01:22:50 +0600 Subject: [PATCH 287/936] Fix address compare --- src/cpu/386_common.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index d7a64b7b4..6f2f47912 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -1656,6 +1656,7 @@ cpu_386_flags_rebuild(void) flags_rebuild(); } +extern uint64_t mmutranslate_noabrt_2386(uint32_t addr, int rw); int cpu_386_check_instruction_fault(void) { @@ -1677,9 +1678,9 @@ cpu_386_check_instruction_fault(void) if (!(cr0 >> 31)) translated_addr = dr[i]; else - translated_addr = mmutranslate_noabrt(dr[i], 0); + translated_addr = cpu_exec == exec386_2386 ? mmutranslate_noabrt_2386(dr[i], 0) : mmutranslate_noabrt(dr[i], 0); - if ((cs + cpu_state.pc) == translated_addr) { + if ((cs + cpu_state.pc) == (uint32_t)translated_addr) { dr[6] |= (1 << i); fault = 1; } From ea5729c8021fe694ec21c24c9fb2bd43846d5d4e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 15 Jan 2024 02:07:13 +0600 Subject: [PATCH 288/936] Revert "Add more missing memory checking" This reverts commit 2eb39a8c5c67b262d276ef8a803905759d3a4dbf. Likely unneeded --- src/mem/mem.c | 14 -------------- src/mem/mmu_2386.c | 15 --------------- 2 files changed, 29 deletions(-) diff --git a/src/mem/mem.c b/src/mem/mem.c index 8f9a883d7..1ed1e8118 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -901,7 +901,6 @@ readmembl_no_mmut(uint32_t addr, uint32_t a64) mem_mapping_t *map; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1); - mem_debug_check_addr(addr, 0); mem_logical_addr = addr; @@ -929,7 +928,6 @@ writemembl_no_mmut(uint32_t addr, uint32_t a64, uint8_t val) GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1); mem_logical_addr = addr; - mem_debug_check_addr(addr, 1); if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_b) { page_lookup[addr >> 12]->write_b(addr, val, page_lookup[addr >> 12]); @@ -1094,8 +1092,6 @@ readmemwl_no_mmut(uint32_t addr, uint32_t *a64) GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 2); mem_logical_addr = addr; - mem_debug_check_addr(addr, 0); - mem_debug_check_addr(addr + 1, 0); if (addr & 1) { if (!cpu_cyrix_alignment || (addr & 7) == 7) @@ -1142,8 +1138,6 @@ writememwl_no_mmut(uint32_t addr, uint32_t *a64, uint16_t val) GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 2); mem_logical_addr = addr; - mem_debug_check_addr(addr, 1); - mem_debug_check_addr(addr + 1, 1); if (addr & 1) { if (!cpu_cyrix_alignment || (addr & 7) == 7) @@ -1372,10 +1366,6 @@ readmemll_no_mmut(uint32_t addr, uint32_t *a64) GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 4); mem_logical_addr = addr; - mem_debug_check_addr(addr, 0); - mem_debug_check_addr(addr + 1, 0); - mem_debug_check_addr(addr + 2, 0); - mem_debug_check_addr(addr + 3, 0); if (addr & 3) { if (!cpu_cyrix_alignment || (addr & 7) > 4) @@ -1424,10 +1414,6 @@ writememll_no_mmut(uint32_t addr, uint32_t *a64, uint32_t val) GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 4); mem_logical_addr = addr; - mem_debug_check_addr(addr, 1); - mem_debug_check_addr(addr + 1, 1); - mem_debug_check_addr(addr + 2, 1); - mem_debug_check_addr(addr + 3, 1); if (addr & 3) { if (!cpu_cyrix_alignment || (addr & 7) > 4) diff --git a/src/mem/mmu_2386.c b/src/mem/mmu_2386.c index e6fc5ab36..fc2237bec 100644 --- a/src/mem/mmu_2386.c +++ b/src/mem/mmu_2386.c @@ -300,7 +300,6 @@ readmembl_no_mmut_2386(uint32_t addr, uint32_t a64) mem_mapping_t *map; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1); - mem_debug_check_addr(addr, 0); mem_logical_addr = addr; @@ -326,7 +325,6 @@ writemembl_no_mmut_2386(uint32_t addr, uint32_t a64, uint8_t val) mem_mapping_t *map; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1); - mem_debug_check_addr(addr, 1); mem_logical_addr = addr; @@ -475,8 +473,6 @@ readmemwl_no_mmut_2386(uint32_t addr, uint32_t *a64) GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 2); mem_logical_addr = addr; - mem_debug_check_addr(addr, 0); - mem_debug_check_addr(addr + 1, 0); if (addr & 1) { if (!cpu_cyrix_alignment || (addr & 7) == 7) @@ -518,8 +514,6 @@ writememwl_no_mmut_2386(uint32_t addr, uint32_t *a64, uint16_t val) mem_mapping_t *map; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 2); - mem_debug_check_addr(addr, 1); - mem_debug_check_addr(addr + 1, 1); mem_logical_addr = addr; @@ -725,11 +719,6 @@ readmemll_no_mmut_2386(uint32_t addr, uint32_t *a64) mem_mapping_t *map; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 4); - - mem_debug_check_addr(addr, 0); - mem_debug_check_addr(addr + 1, 0); - mem_debug_check_addr(addr + 2, 0); - mem_debug_check_addr(addr + 3, 0); mem_logical_addr = addr; @@ -777,10 +766,6 @@ writememll_no_mmut_2386(uint32_t addr, uint32_t *a64, uint32_t val) GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 4); mem_logical_addr = addr; - mem_debug_check_addr(addr, 1); - mem_debug_check_addr(addr + 1, 1); - mem_debug_check_addr(addr + 2, 2); - mem_debug_check_addr(addr + 3, 3); if (addr & 3) { if (!cpu_cyrix_alignment || (addr & 7) > 4) From d8330a0c46b7416d76e6781568ba5193ba50174a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 15 Jan 2024 02:14:00 +0600 Subject: [PATCH 289/936] No need to translate EIP --- src/cpu/386_common.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 6f2f47912..4b4037207 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -1672,14 +1672,12 @@ cpu_386_check_instruction_fault(void) for (i = 0; i < 4; i++) { int breakpoint_enabled = !!(dr[7] & (0x3 << (2 * i))) && !(dr[7] & (0x30000 << (4 * i))); - uint64_t translated_addr = 0xffffffffffffffffULL; + uint32_t translated_addr = 0xffffffff; if (!breakpoint_enabled) continue; - if (!(cr0 >> 31)) - translated_addr = dr[i]; - else - translated_addr = cpu_exec == exec386_2386 ? mmutranslate_noabrt_2386(dr[i], 0) : mmutranslate_noabrt(dr[i], 0); - + + translated_addr = dr[i]; + if ((cs + cpu_state.pc) == (uint32_t)translated_addr) { dr[6] |= (1 << i); fault = 1; From 5c15da4a174a44fc4f29e74a254762c860aec2e5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 14 Jan 2024 21:31:46 +0100 Subject: [PATCH 290/936] CD-ROM: Converted the wrong kind of trailing slash, fixes #4038. --- src/cdrom/cdrom.c | 21 ++++++++++++++++++++- src/qt/qt_mediamenu.cpp | 7 +++++++ src/unix/unix_cdrom.c | 2 ++ src/win/win_cdrom.c | 2 ++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index c5755709d..897083708 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -1952,8 +1952,18 @@ cdrom_hard_reset(void) dev->cd_status = CD_STATUS_EMPTY; - if (dev->host_drive == 200) + if (dev->host_drive == 200) { +#ifdef _WIN32 + if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '/')) + dev->image_path[strlen(dev->image_path) - 1] = '\\'; +#else + if ((strlen(dev->image_path) >= 1) && + (dev->image_path[strlen(dev->image_path) - 1] == '\\')) + dev->image_path[strlen(dev->image_path) - 1] = '/'; +#endif + cdrom_image_open(dev, dev->image_path); + } } } @@ -2042,6 +2052,15 @@ cdrom_reload(uint8_t id) if (dev->prev_host_drive == 200) { /* Reload a previous image. */ strcpy(dev->image_path, dev->prev_image_path); + +#ifdef _WIN32 + if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '/')) + dev->image_path[strlen(dev->image_path) - 1] = '\\'; +#else + if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '\\')) + dev->image_path[strlen(dev->image_path) - 1] = '/'; +#endif + cdrom_image_open(dev, dev->image_path); cdrom_insert(id); diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index 26169b0d0..541e31190 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -456,6 +456,13 @@ MediaMenu::cdromMount(int i, const QString &filename) cdrom[i].ops = nullptr; memset(cdrom[i].image_path, 0, sizeof(cdrom[i].image_path)); +#ifdef _WIN32 + if ((fn.data() != NULL) && (strlen(fn.data()) >= 1) && (fn.data()[strlen(fn.data()) - 1] == '/')) + fn.data()[strlen(fn.data()) - 1] = '\\'; +#else + if ((fn.data() != NULL) && (strlen(fn.data()) >= 1) && (fn.data()[strlen(fn.data()) - 1] == '\\')) + fn.data()[strlen(fn.data()) - 1] = '/'; +#endif cdrom_image_open(&(cdrom[i]), fn.data()); /* Signal media change to the emulated machine. */ if (cdrom[i].insert) diff --git a/src/unix/unix_cdrom.c b/src/unix/unix_cdrom.c index 424f1a9a3..6b167fac5 100644 --- a/src/unix/unix_cdrom.c +++ b/src/unix/unix_cdrom.c @@ -145,6 +145,8 @@ cdrom_mount(uint8_t id, char *fn) cdrom[id].ops->exit(&(cdrom[id])); cdrom[id].ops = NULL; memset(cdrom[id].image_path, 0, sizeof(cdrom[id].image_path)); + if ((fn != NULL) && (strlen(fn) >= 1) && ((fn[strlen(fn) - 1] == '\\')) + fn[strlen(fn) - 1] = '/'; cdrom_image_open(&(cdrom[id]), fn); /* Signal media change to the emulated machine. */ if (cdrom[id].insert) diff --git a/src/win/win_cdrom.c b/src/win/win_cdrom.c index 37b741c29..1ab6947bb 100644 --- a/src/win/win_cdrom.c +++ b/src/win/win_cdrom.c @@ -136,6 +136,8 @@ cdrom_mount(uint8_t id, char *fn) cdrom[id].ops->exit(&(cdrom[id])); cdrom[id].ops = NULL; memset(cdrom[id].image_path, 0, sizeof(cdrom[id].image_path)); + if ((fn != NULL) && (strlen(fn) >= 1) && ((fn[strlen(fn) - 1] == '/')) + fn[strlen(fn) - 1] = '\\'; cdrom_image_open(&(cdrom[id]), fn); /* Signal media change to the emulated machine. */ if (cdrom[id].insert) From f2971a132f7c6e565ff752109e15231be67eca72 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 14 Jan 2024 21:47:52 +0100 Subject: [PATCH 291/936] Disable the debug registers on 486+. --- src/cpu/386_common.h | 112 ++++----- src/cpu/386_dynarec.c | 37 +-- src/cpu/386_ops.h | 18 +- src/cpu/x86_ops_flag.h | 4 - src/cpu/x86_ops_flag_2386.h | 323 +++++++++++++++++++++++++ src/cpu/x86_ops_mov_ctrl.h | 32 --- src/cpu/x86_ops_mov_ctrl_2386.h | 414 ++++++++++++++++++++++++++++++++ src/cpu/x86_ops_ret.h | 4 - src/cpu/x86_ops_ret_2386.h | 297 +++++++++++++++++++++++ src/mem/mem.c | 74 +----- src/mem/mmu_2386.c | 48 ++++ 11 files changed, 1164 insertions(+), 199 deletions(-) create mode 100644 src/cpu/x86_ops_flag_2386.h create mode 100644 src/cpu/x86_ops_mov_ctrl_2386.h create mode 100644 src/cpu/x86_ops_ret_2386.h diff --git a/src/cpu/386_common.h b/src/cpu/386_common.h index 0478fe5c6..35d4f7cc8 100644 --- a/src/cpu/386_common.h +++ b/src/cpu/386_common.h @@ -50,80 +50,80 @@ # define do_mmut_ww(s, a, b) do_mmutranslate_2386((s) + (a), b, 2, 1) # define do_mmut_wl(s, a, b) do_mmutranslate_2386((s) + (a), b, 4, 1) #else -# define readmemb_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) ? readmembl_no_mmut((s) + (a), b) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) -# define readmemw_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF) || (((s) + (a)) & 1)) ? readmemwl_no_mmut((s) + (a), b) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) -# define readmeml_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF) || (((s) + (a)) & 3)) ? readmemll_no_mmut((s) + (a), b) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) -# define readmemb(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) ? readmembl((s) + (a)) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) -# define readmemw(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF) || (((s) + (a)) & 1)) ? readmemwl((s) + (a)) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) -# define readmeml(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF) || (((s) + (a)) & 3)) ? readmemll((s) + (a)) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) -# define readmemq(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF) || (((s) + (a)) & 7)) ? readmemql((s) + (a)) : *(uint64_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) +# define readmemb_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl_no_mmut((s) + (a), b) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) +# define readmemw_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl_no_mmut((s) + (a), b) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +# define readmeml_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll_no_mmut((s) + (a), b) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +# define readmemb(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl((s) + (a)) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) +# define readmemw(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl((s) + (a)) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +# define readmeml(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll((s) + (a)) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +# define readmemq(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) ? readmemql((s) + (a)) : *(uint64_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) -# define writememb_n(s, a, b, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) \ - writemembl_no_mmut((s) + (a), b, v); \ - else \ +# define writememb_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + writemembl_no_mmut((s) + (a), b, v); \ + else \ *(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -# define writememw_n(s, a, b, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1) || (dr[7] & 0xFF)) \ - writememwl_no_mmut((s) + (a), b, v); \ - else \ +# define writememw_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + writememwl_no_mmut((s) + (a), b, v); \ + else \ *(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -# define writememl_n(s, a, b, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3) || (dr[7] & 0xFF)) \ - writememll_no_mmut((s) + (a), b, v); \ - else \ +# define writememl_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + writememll_no_mmut((s) + (a), b, v); \ + else \ *(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -# define writememb(s, a, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) \ - writemembl((s) + (a), v); \ - else \ +# define writememb(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + writemembl((s) + (a), v); \ + else \ *(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -# define writememw(s, a, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1) || (dr[7] & 0xFF)) \ - writememwl((s) + (a), v); \ - else \ +# define writememw(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + writememwl((s) + (a), v); \ + else \ *(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -# define writememl(s, a, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3) || (dr[7] & 0xFF)) \ - writememll((s) + (a), v); \ - else \ +# define writememl(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + writememll((s) + (a), v); \ + else \ *(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -# define writememq(s, a, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7) || (dr[7] & 0xFF)) \ - writememql((s) + (a), v); \ - else \ +# define writememq(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) \ + writememql((s) + (a), v); \ + else \ *(uint64_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -# define do_mmut_rb(s, a, b) \ - if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) \ +# define do_mmut_rb(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ do_mmutranslate((s) + (a), b, 1, 0) -# define do_mmut_rw(s, a, b) \ - if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1) || (dr[7] & 0xFF)) \ +# define do_mmut_rw(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ do_mmutranslate((s) + (a), b, 2, 0) -# define do_mmut_rl(s, a, b) \ - if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3) || (dr[7] & 0xFF)) \ +# define do_mmut_rl(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ do_mmutranslate((s) + (a), b, 4, 0) -# define do_mmut_rb2(s, a, b) \ - old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ - if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) \ +# define do_mmut_rb2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ do_mmutranslate((s) + (a), b, 1, 0) -# define do_mmut_rw2(s, a, b) \ - old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ - if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1) || (dr[7] & 0xFF)) \ +# define do_mmut_rw2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ do_mmutranslate((s) + (a), b, 2, 0) -# define do_mmut_rl2(s, a, b) \ - old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ - if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3) || (dr[7] & 0xFF)) \ +# define do_mmut_rl2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ do_mmutranslate((s) + (a), b, 4, 0) -# define do_mmut_wb(s, a, b) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) \ +# define do_mmut_wb(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ do_mmutranslate((s) + (a), b, 1, 1) -# define do_mmut_ww(s, a, b) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1) || (dr[7] & 0xFF)) \ +# define do_mmut_ww(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ do_mmutranslate((s) + (a), b, 2, 1) -# define do_mmut_wl(s, a, b) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3) || (dr[7] & 0xFF)) \ +# define do_mmut_wl(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ do_mmutranslate((s) + (a), b, 4, 1) #endif diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index ca2e60aea..e132c0300 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -223,7 +223,7 @@ fetch_ea_16_long(uint32_t rmdat) #include "386_ops.h" -#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG) && !(dr[7] & 0xFF)) +#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) #ifdef USE_DYNAREC int32_t cycles_main = 0; @@ -268,7 +268,7 @@ exec386_dynarec_int(void) cpu_block_end = 0; x86_was_reset = 0; - if (trap & 2) { + if (trap == 2) { /* Handle the T bit in the new TSS first. */ CPU_BLOCK_END(); goto block_ended; @@ -285,11 +285,6 @@ exec386_dynarec_int(void) cpu_state.ea_seg = &cpu_state.seg_ds; cpu_state.ssegs = 0; - if (UNLIKELY(cpu_386_check_instruction_fault())) { - x86gen(); - goto block_ended; - } - fetchdat = fastreadl_fetch(cs + cpu_state.pc); # ifdef ENABLE_386_DYNAREC_LOG if (in_smm) @@ -300,7 +295,7 @@ exec386_dynarec_int(void) opcode = fetchdat & 0xFF; fetchdat >>= 8; - trap |= !!(cpu_state.flags & T_FLAG); + trap = cpu_state.flags & T_FLAG; cpu_state.pc++; x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); @@ -311,14 +306,6 @@ exec386_dynarec_int(void) cpu_state.pc &= 0xffff; # endif - if (!cpu_state.abrt) { - if (!rf_flag_no_clear) { - cpu_state.eflags &= ~RF_FLAG; - } - - rf_flag_no_clear = 0; - } - if (((cs + cpu_state.pc) >> 12) != pccache) CPU_BLOCK_END(); @@ -342,10 +329,7 @@ exec386_dynarec_int(void) block_ended: if (!cpu_state.abrt && trap) { - //pclog("Debug trap 0x%X\n", trap); - if (trap & 2) dr[6] |= 0x8000; - if (trap & 1) dr[6] |= 0x4000; - + dr[6] |= (trap == 2) ? 0x8000 : 0x4000; trap = 0; # ifndef USE_NEW_DYNAREC oldcs = CS; @@ -857,11 +841,6 @@ exec386(int32_t cycs) cpu_state.ea_seg = &cpu_state.seg_ds; cpu_state.ssegs = 0; - if (UNLIKELY(cpu_386_check_instruction_fault())) { - x86gen(); - goto block_ended; - } - fetchdat = fastreadl_fetch(cs + cpu_state.pc); if (!cpu_state.abrt) { @@ -871,7 +850,7 @@ exec386(int32_t cycs) #endif opcode = fetchdat & 0xFF; fetchdat >>= 8; - trap |= !!(cpu_state.flags & T_FLAG); + trap = cpu_state.flags & T_FLAG; cpu_state.pc++; x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); @@ -891,7 +870,6 @@ exec386(int32_t cycs) if (cpu_end_block_after_ins) cpu_end_block_after_ins--; -block_ended: if (cpu_state.abrt) { flags_rebuild(); tempi = cpu_state.abrt & ABRT_MASK; @@ -916,15 +894,12 @@ block_ended: } } else if (trap) { flags_rebuild(); - if (trap & 1) - dr[6] |= 0x4000; - if (trap & 2) - dr[6] |= 0x8000; trap = 0; #ifndef USE_NEW_DYNAREC oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; + dr[6] |= 0x4000; x86_int(1); } diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index 8a0f4cd5a..710031ef1 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -181,7 +181,11 @@ extern void x386_dynarec_log(const char *fmt, ...); #ifndef OPS_286_386 # include "x86_ops_cyrix.h" #endif -#include "x86_ops_flag.h" +#ifdef OPS_286_386 +# include "x86_ops_flag_2386.h" +#else +# include "x86_ops_flag.h" +#endif #include "x86_ops_fpu.h" #include "x86_ops_inc_dec.h" #include "x86_ops_int.h" @@ -200,7 +204,11 @@ extern void x386_dynarec_log(const char *fmt, ...); # include "x86_ops_mmx_shift.h" #endif #include "x86_ops_mov.h" -#include "x86_ops_mov_ctrl.h" +#ifdef OPS_286_386 +# include "x86_ops_mov_ctrl_2386.h" +#else +# include "x86_ops_mov_ctrl.h" +#endif #include "x86_ops_mov_seg.h" #include "x86_ops_movx.h" #ifndef OPS_286_386 @@ -218,7 +226,11 @@ extern void x386_dynarec_log(const char *fmt, ...); # include "x86_ops_rep.h" # endif #endif -#include "x86_ops_ret.h" +#ifdef OPS_286_386 +# include "x86_ops_ret_2386.h" +#else +# include "x86_ops_ret.h" +#endif #include "x86_ops_set.h" #include "x86_ops_stack.h" #ifdef OPS_286_386 diff --git a/src/cpu/x86_ops_flag.h b/src/cpu/x86_ops_flag.h index ba34ae5e7..f08b30fce 100644 --- a/src/cpu/x86_ops_flag.h +++ b/src/cpu/x86_ops_flag.h @@ -178,7 +178,6 @@ opPOPF_186(uint32_t fetchdat) else cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; flags_extract(); - rf_flag_no_clear = 1; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); @@ -212,7 +211,6 @@ opPOPF_286(uint32_t fetchdat) else cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; flags_extract(); - rf_flag_no_clear = 1; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); @@ -266,7 +264,6 @@ opPOPF(uint32_t fetchdat) cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; } flags_extract(); - rf_flag_no_clear = 1; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); @@ -310,7 +307,6 @@ opPOPFD(uint32_t fetchdat) cpu_state.eflags = (templ >> 16) & 3; flags_extract(); - rf_flag_no_clear = 1; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 0); diff --git a/src/cpu/x86_ops_flag_2386.h b/src/cpu/x86_ops_flag_2386.h new file mode 100644 index 000000000..ba34ae5e7 --- /dev/null +++ b/src/cpu/x86_ops_flag_2386.h @@ -0,0 +1,323 @@ +static int +opCMC(uint32_t fetchdat) +{ + flags_rebuild(); + cpu_state.flags ^= C_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; +} + +static int +opCLC(uint32_t fetchdat) +{ + flags_rebuild(); + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; +} +static int +opCLD(uint32_t fetchdat) +{ + cpu_state.flags &= ~D_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; +} +static int +opCLI(uint32_t fetchdat) +{ + if (!IOPLp) { + if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) { + cpu_state.eflags &= ~VIF_FLAG; + } else { + x86gpf(NULL, 0); + return 1; + } + } else + cpu_state.flags &= ~I_FLAG; + + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; +} + +static int +opSTC(uint32_t fetchdat) +{ + flags_rebuild(); + cpu_state.flags |= C_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; +} +static int +opSTD(uint32_t fetchdat) +{ + cpu_state.flags |= D_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; +} +static int +opSTI(uint32_t fetchdat) +{ + if (!IOPLp) { + if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) { + if (cpu_state.eflags & VIP_FLAG) { + x86gpf(NULL, 0); + return 1; + } else + cpu_state.eflags |= VIF_FLAG; + } else { + x86gpf(NULL, 0); + return 1; + } + } else + cpu_state.flags |= I_FLAG; + + /*First instruction after STI will always execute, regardless of whether + there is a pending interrupt*/ + cpu_end_block_after_ins = 2; + + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; +} + +static int +opSAHF(uint32_t fetchdat) +{ + flags_rebuild(); + cpu_state.flags = (cpu_state.flags & 0xff00) | (AH & 0xd5) | 2; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) + codegen_flags_changed = 0; +#endif + + return 0; +} +static int +opLAHF(uint32_t fetchdat) +{ + flags_rebuild(); + AH = cpu_state.flags & 0xff; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; +} + +static int +opPUSHF(uint32_t fetchdat) +{ + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + if (cr4 & CR4_VME) { + uint16_t temp; + + flags_rebuild(); + temp = (cpu_state.flags & ~I_FLAG) | 0x3000; + if (cpu_state.eflags & VIF_FLAG) + temp |= I_FLAG; + PUSH_W(temp); + } else { + x86gpf(NULL, 0); + return 1; + } + } else { + flags_rebuild(); + PUSH_W(cpu_state.flags); + } + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0); + return cpu_state.abrt; +} +static int +opPUSHFD(uint32_t fetchdat) +{ + uint16_t tempw; + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + x86gpf(NULL, 0); + return 1; + } + if (cpu_CR4_mask & CR4_VME) + tempw = cpu_state.eflags & 0x3c; + else if (CPUID) + tempw = cpu_state.eflags & 0x24; + else + tempw = cpu_state.eflags & 4; + flags_rebuild(); + PUSH_L(cpu_state.flags | (tempw << 16)); + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0); + return cpu_state.abrt; +} + +static int +opPOPF_186(uint32_t fetchdat) +{ + uint16_t tempw; + + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + x86gpf(NULL, 0); + return 1; + } + + tempw = POP_W(); + if (cpu_state.abrt) + return 1; + + if (!(msw & 1)) + cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2; + else if (!(CPL)) + cpu_state.flags = (tempw & 0x7fd5) | 2; + else if (IOPLp) + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; + else + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + flags_extract(); + rf_flag_no_clear = 1; + + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) + codegen_flags_changed = 0; +#endif + + return 0; +} +static int +opPOPF_286(uint32_t fetchdat) +{ + uint16_t tempw; + + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + x86gpf(NULL, 0); + return 1; + } + + tempw = POP_W(); + if (cpu_state.abrt) + return 1; + + if (!(msw & 1)) + cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2; + else if (!(CPL)) + cpu_state.flags = (tempw & 0x7fd5) | 2; + else if (IOPLp) + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; + else + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + flags_extract(); + rf_flag_no_clear = 1; + + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) + codegen_flags_changed = 0; +#endif + + return 0; +} +static int +opPOPF(uint32_t fetchdat) +{ + uint16_t tempw; + + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + if (cr4 & CR4_VME) { + uint32_t old_esp = ESP; + + tempw = POP_W(); + if (cpu_state.abrt) { + + ESP = old_esp; + return 1; + } + + if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) { + ESP = old_esp; + x86gpf(NULL, 0); + return 1; + } + if (tempw & I_FLAG) + cpu_state.eflags |= VIF_FLAG; + else + cpu_state.eflags &= ~VIF_FLAG; + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + } else { + x86gpf(NULL, 0); + return 1; + } + } else { + tempw = POP_W(); + if (cpu_state.abrt) + return 1; + + if (!(CPL) || !(msw & 1)) + cpu_state.flags = (tempw & 0x7fd5) | 2; + else if (IOPLp) + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; + else + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + } + flags_extract(); + rf_flag_no_clear = 1; + + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) + codegen_flags_changed = 0; +#endif + + return 0; +} +static int +opPOPFD(uint32_t fetchdat) +{ + uint32_t templ; + + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + x86gpf(NULL, 0); + return 1; + } + + templ = POP_L(); + if (cpu_state.abrt) + return 1; + + if (!(CPL) || !(msw & 1)) + cpu_state.flags = (templ & 0x7fd5) | 2; + else if (IOPLp) + cpu_state.flags = (cpu_state.flags & 0x3000) | (templ & 0x4fd5) | 2; + else + cpu_state.flags = (cpu_state.flags & 0x3200) | (templ & 0x4dd5) | 2; + + templ &= (is486 || isibm486) ? 0x3c0000 : 0; + templ |= ((cpu_state.eflags & 3) << 16); + if (cpu_CR4_mask & CR4_VME) + cpu_state.eflags = (templ >> 16) & 0x3f; + else if (CPUID) + cpu_state.eflags = (templ >> 16) & 0x27; + else if (is486 || isibm486) + cpu_state.eflags = (templ >> 16) & 7; + else + cpu_state.eflags = (templ >> 16) & 3; + + flags_extract(); + rf_flag_no_clear = 1; + + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 0); + +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) + codegen_flags_changed = 0; +#endif + + return 0; +} diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h index c57dc8226..b0c841f83 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu/x86_ops_mov_ctrl.h @@ -87,12 +87,6 @@ opMOV_r_DRx_a16(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); - if (cpu_reg == 4 || cpu_reg == 5) { - if (cr4 & 0x8) - x86illegal(); - else - cpu_reg += 2; - } cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); CLOCK_CYCLES(6); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); @@ -106,12 +100,6 @@ opMOV_r_DRx_a32(uint32_t fetchdat) return 1; } fetch_ea_32(fetchdat); - if (cpu_reg == 4 || cpu_reg == 5) { - if (cr4 & 0x8) - x86illegal(); - else - cpu_reg += 2; - } cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); CLOCK_CYCLES(6); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); @@ -240,23 +228,10 @@ opMOV_DRx_r_a16(uint32_t fetchdat) x86gpf(NULL, 0); return 1; } - if ((dr[6] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) { - dr[7] |= 0x2000; - dr[6] &= ~0x2000; - x86gen(); - return 1; - } fetch_ea_16(fetchdat); - if (cpu_reg == 4 || cpu_reg == 5) { - if (cr4 & 0x8) - x86illegal(); - else - cpu_reg += 2; - } dr[cpu_reg] = cpu_state.regs[cpu_rm].l; CLOCK_CYCLES(6); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); - CPU_BLOCK_END(); return 0; } static int @@ -267,16 +242,9 @@ opMOV_DRx_r_a32(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); - if (cpu_reg == 4 || cpu_reg == 5) { - if (cr4 & 0x8) - x86illegal(); - else - cpu_reg += 2; - } dr[cpu_reg] = cpu_state.regs[cpu_rm].l; CLOCK_CYCLES(6); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); - CPU_BLOCK_END(); return 0; } diff --git a/src/cpu/x86_ops_mov_ctrl_2386.h b/src/cpu/x86_ops_mov_ctrl_2386.h new file mode 100644 index 000000000..c57dc8226 --- /dev/null +++ b/src/cpu/x86_ops_mov_ctrl_2386.h @@ -0,0 +1,414 @@ +static int +opMOV_r_CRx_a16(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + switch (cpu_reg) { + case 0: + cpu_state.regs[cpu_rm].l = cr0; + if (is486 || isibm486) + cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/ + else { + if (is386) + cpu_state.regs[cpu_rm].l |= 0x7fffffe0; + else + cpu_state.regs[cpu_rm].l |= 0x7ffffff0; + } + break; + case 2: + cpu_state.regs[cpu_rm].l = cr2; + break; + case 3: + cpu_state.regs[cpu_rm].l = cr3; + break; + case 4: + if (cpu_has_feature(CPU_FEATURE_CR4)) { + cpu_state.regs[cpu_rm].l = cr4; + break; + } + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opMOV_r_CRx_a32(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + switch (cpu_reg) { + case 0: + cpu_state.regs[cpu_rm].l = cr0; + if (is486 || isibm486) + cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/ + else { + if (is386) + cpu_state.regs[cpu_rm].l |= 0x7fffffe0; + else + cpu_state.regs[cpu_rm].l |= 0x7ffffff0; + } + break; + case 2: + cpu_state.regs[cpu_rm].l = cr2; + break; + case 3: + cpu_state.regs[cpu_rm].l = cr3; + break; + case 4: + if (cpu_has_feature(CPU_FEATURE_CR4)) { + cpu_state.regs[cpu_rm].l = cr4; + break; + } + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static int +opMOV_r_DRx_a16(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + if (cpu_reg == 4 || cpu_reg == 5) { + if (cr4 & 0x8) + x86illegal(); + else + cpu_reg += 2; + } + cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opMOV_r_DRx_a32(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + if (cpu_reg == 4 || cpu_reg == 5) { + if (cr4 & 0x8) + x86illegal(); + else + cpu_reg += 2; + } + cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static int +opMOV_CRx_r_a16(uint32_t fetchdat) +{ + uint32_t old_cr0 = cr0; + + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + switch (cpu_reg) { + case 0: + if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) + flushmmucache(); + /* Make sure CPL = 0 when switching from real mode to protected mode. */ + if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) + cpu_state.seg_cs.access &= 0x9f; + cr0 = cpu_state.regs[cpu_rm].l; + if (cpu_16bitbus) + cr0 |= 0x10; + if (!(cr0 & 0x80000000)) + mmu_perm = 4; + if (hascache && !(cr0 & (1 << 30))) + cpu_cache_int_enabled = 1; + else + cpu_cache_int_enabled = 0; + if (hascache && ((cr0 ^ old_cr0) & (1 << 30))) + cpu_update_waitstates(); + if (cr0 & 1) + cpu_cur_status |= CPU_STATUS_PMODE; + else + cpu_cur_status &= ~CPU_STATUS_PMODE; + break; + case 2: + cr2 = cpu_state.regs[cpu_rm].l; + break; + case 3: + cr3 = cpu_state.regs[cpu_rm].l; + flushmmucache(); + break; + case 4: + if (cpu_has_feature(CPU_FEATURE_CR4)) { + if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PAE | CR4_PGE)) + flushmmucache(); + cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; + break; + } + + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + CLOCK_CYCLES(10); + PREFETCH_RUN(10, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opMOV_CRx_r_a32(uint32_t fetchdat) +{ + uint32_t old_cr0 = cr0; + + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + switch (cpu_reg) { + case 0: + if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) + flushmmucache(); + /* Make sure CPL = 0 when switching from real mode to protected mode. */ + if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) + cpu_state.seg_cs.access &= 0x9f; + cr0 = cpu_state.regs[cpu_rm].l; + if (cpu_16bitbus) + cr0 |= 0x10; + if (!(cr0 & 0x80000000)) + mmu_perm = 4; + if (hascache && !(cr0 & (1 << 30))) + cpu_cache_int_enabled = 1; + else + cpu_cache_int_enabled = 0; + if (hascache && ((cr0 ^ old_cr0) & (1 << 30))) + cpu_update_waitstates(); + if (cr0 & 1) + cpu_cur_status |= CPU_STATUS_PMODE; + else + cpu_cur_status &= ~CPU_STATUS_PMODE; + break; + case 2: + cr2 = cpu_state.regs[cpu_rm].l; + break; + case 3: + cr3 = cpu_state.regs[cpu_rm].l; + flushmmucache(); + break; + case 4: + if (cpu_has_feature(CPU_FEATURE_CR4)) { + if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PAE | CR4_PGE)) + flushmmucache(); + cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; + break; + } + + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + CLOCK_CYCLES(10); + PREFETCH_RUN(10, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static int +opMOV_DRx_r_a16(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + if ((dr[6] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) { + dr[7] |= 0x2000; + dr[6] &= ~0x2000; + x86gen(); + return 1; + } + fetch_ea_16(fetchdat); + if (cpu_reg == 4 || cpu_reg == 5) { + if (cr4 & 0x8) + x86illegal(); + else + cpu_reg += 2; + } + dr[cpu_reg] = cpu_state.regs[cpu_rm].l; + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + CPU_BLOCK_END(); + return 0; +} +static int +opMOV_DRx_r_a32(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + if (cpu_reg == 4 || cpu_reg == 5) { + if (cr4 & 0x8) + x86illegal(); + else + cpu_reg += 2; + } + dr[cpu_reg] = cpu_state.regs[cpu_rm].l; + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + CPU_BLOCK_END(); + return 0; +} + +static void +opMOV_r_TRx(void) +{ +#if 0 + uint32_t base; + + base = _tr[4] & 0xfffff800; +#endif + + switch (cpu_reg) { + case 3: +#if 0 + pclog("[R] %08X cache = %08X\n", base + cache_index, _tr[3]); +#endif + _tr[3] = *(uint32_t *) &(_cache[cache_index]); + cache_index = (cache_index + 4) & 0xf; + break; + } + cpu_state.regs[cpu_rm].l = _tr[cpu_reg]; + CLOCK_CYCLES(6); +} +static int +opMOV_r_TRx_a16(uint32_t fetchdat) +{ + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + opMOV_r_TRx(); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opMOV_r_TRx_a32(uint32_t fetchdat) +{ + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + opMOV_r_TRx(); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static void +opMOV_TRx_r(void) +{ + uint32_t base; + int i; + int ctl; + + _tr[cpu_reg] = cpu_state.regs[cpu_rm].l; + base = _tr[4] & 0xfffff800; + ctl = _tr[5] & 3; + switch (cpu_reg) { + case 3: +#if 0 + pclog("[W] %08X cache = %08X\n", base + cache_index, _tr[3]); +#endif + *(uint32_t *) &(_cache[cache_index]) = _tr[3]; + cache_index = (cache_index + 4) & 0xf; + break; + case 4: +#if 0 + if (!(cr0 & 1) && !(_tr[5] & (1 << 19))) + pclog("TAG = %08X, DEST = %08X\n", base, base + cache_index - 16); +#endif + break; + case 5: +#if 0 + pclog("[16] EXT = %i (%i), SET = %04X\n", !!(_tr[5] & (1 << 19)), _tr[5] & 0x03, _tr[5] & 0x7f0); +#endif + if (!(_tr[5] & (1 << 19))) { + switch (ctl) { + case 0: +#if 0 + pclog(" Cache fill or read...\n", base); +#endif + break; + case 1: + base += (_tr[5] & 0x7f0); +#if 0 + pclog(" Writing 16 bytes to %08X...\n", base); +#endif + for (i = 0; i < 16; i += 4) + mem_writel_phys(base + i, *(uint32_t *) &(_cache[i])); + break; + case 2: + base += (_tr[5] & 0x7f0); +#if 0 + pclog(" Reading 16 bytes from %08X...\n", base); +#endif + for (i = 0; i < 16; i += 4) + *(uint32_t *) &(_cache[i]) = mem_readl_phys(base + i); + break; + case 3: +#if 0 + pclog(" Cache invalidate/flush...\n", base); +#endif + break; + } + } + break; + } + CLOCK_CYCLES(6); +} +static int +opMOV_TRx_r_a16(uint32_t fetchdat) +{ + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + opMOV_TRx_r(); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opMOV_TRx_r_a32(uint32_t fetchdat) +{ + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + opMOV_TRx_r(); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} diff --git a/src/cpu/x86_ops_ret.h b/src/cpu/x86_ops_ret.h index ca85bf2b0..0d9a6370b 100644 --- a/src/cpu/x86_ops_ret.h +++ b/src/cpu/x86_ops_ret.h @@ -135,7 +135,6 @@ opIRET_186(uint32_t fetchdat) } flags_extract(); nmi_enable = 1; - rf_flag_no_clear = 1; CPU_BLOCK_END(); PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); @@ -176,7 +175,6 @@ opIRET_286(uint32_t fetchdat) } flags_extract(); nmi_enable = 1; - rf_flag_no_clear = 1; CPU_BLOCK_END(); PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); @@ -245,7 +243,6 @@ opIRET(uint32_t fetchdat) } flags_extract(); nmi_enable = 1; - rf_flag_no_clear = 1; CPU_BLOCK_END(); PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); @@ -288,7 +285,6 @@ opIRETD(uint32_t fetchdat) } flags_extract(); nmi_enable = 1; - rf_flag_no_clear = 1; CPU_BLOCK_END(); PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1); diff --git a/src/cpu/x86_ops_ret_2386.h b/src/cpu/x86_ops_ret_2386.h new file mode 100644 index 000000000..ca85bf2b0 --- /dev/null +++ b/src/cpu/x86_ops_ret_2386.h @@ -0,0 +1,297 @@ +#ifdef USE_NEW_DYNAREC +# define CPU_SET_OXPC +#else +# define CPU_SET_OXPC oxpc = cpu_state.pc; +#endif + +#define RETF_a16(stack_offset) \ + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \ + op_pmoderetf(0, stack_offset); \ + return 1; \ + } \ + CPU_SET_OXPC \ + if (stack32) { \ + cpu_state.pc = readmemw(ss, ESP); \ + op_loadcs(readmemw(ss, ESP + 2)); \ + } else { \ + cpu_state.pc = readmemw(ss, SP); \ + op_loadcs(readmemw(ss, SP + 2)); \ + } \ + if (cpu_state.abrt) \ + return 1; \ + if (stack32) \ + ESP += 4 + stack_offset; \ + else \ + SP += 4 + stack_offset; \ + cycles -= timing_retf_rm; + +#define RETF_a32(stack_offset) \ + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \ + op_pmoderetf(1, stack_offset); \ + return 1; \ + } \ + CPU_SET_OXPC \ + if (stack32) { \ + cpu_state.pc = readmeml(ss, ESP); \ + op_loadcs(readmeml(ss, ESP + 4) & 0xffff); \ + } else { \ + cpu_state.pc = readmeml(ss, SP); \ + op_loadcs(readmeml(ss, SP + 4) & 0xffff); \ + } \ + if (cpu_state.abrt) \ + return 1; \ + if (stack32) \ + ESP += 8 + stack_offset; \ + else \ + SP += 8 + stack_offset; \ + cycles -= timing_retf_rm; + +static int +opRETF_a16(uint32_t fetchdat) +{ + int cycles_old = cycles; + UN_USED(cycles_old); + + CPU_BLOCK_END(); + RETF_a16(0); + + PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; +} +static int +opRETF_a32(uint32_t fetchdat) +{ + int cycles_old = cycles; + UN_USED(cycles_old); + + CPU_BLOCK_END(); + RETF_a32(0); + + PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1); + PREFETCH_FLUSH(); + return 0; +} + +static int +opRETF_a16_imm(uint32_t fetchdat) +{ + uint16_t offset = getwordf(); + int cycles_old = cycles; + UN_USED(cycles_old); + + CPU_BLOCK_END(); + RETF_a16(offset); + + PREFETCH_RUN(cycles_old - cycles, 3, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; +} +static int +opRETF_a32_imm(uint32_t fetchdat) +{ + uint16_t offset = getwordf(); + int cycles_old = cycles; + UN_USED(cycles_old); + + CPU_BLOCK_END(); + RETF_a32(offset); + + PREFETCH_RUN(cycles_old - cycles, 3, -1, 0, 2, 0, 0, 1); + PREFETCH_FLUSH(); + return 0; +} + +static int +opIRET_186(uint32_t fetchdat) +{ + int cycles_old = cycles; + UN_USED(cycles_old); + + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf(NULL, 0); + return 1; + } + if (msw & 1) { + optype = IRET; + op_pmodeiret(0); + optype = 0; + } else { + uint16_t new_cs; + CPU_SET_OXPC + if (stack32) { + cpu_state.pc = readmemw(ss, ESP); + new_cs = readmemw(ss, ESP + 2); + cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2; + ESP += 6; + } else { + cpu_state.pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2; + SP += 6; + } + op_loadcs(new_cs); + cycles -= timing_iret_rm; + } + flags_extract(); + nmi_enable = 1; + rf_flag_no_clear = 1; + CPU_BLOCK_END(); + + PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return cpu_state.abrt; +} + +static int +opIRET_286(uint32_t fetchdat) +{ + int cycles_old = cycles; + UN_USED(cycles_old); + + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf(NULL, 0); + return 1; + } + if (msw & 1) { + optype = IRET; + op_pmodeiret(0); + optype = 0; + } else { + uint16_t new_cs; + CPU_SET_OXPC + if (stack32) { + cpu_state.pc = readmemw(ss, ESP); + new_cs = readmemw(ss, ESP + 2); + cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2; + ESP += 6; + } else { + cpu_state.pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2; + SP += 6; + } + op_loadcs(new_cs); + cycles -= timing_iret_rm; + } + flags_extract(); + nmi_enable = 1; + rf_flag_no_clear = 1; + CPU_BLOCK_END(); + + PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return cpu_state.abrt; +} + +static int +opIRET(uint32_t fetchdat) +{ + int cycles_old = cycles; + UN_USED(cycles_old); + + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + if (cr4 & CR4_VME) { + uint16_t new_pc; + uint16_t new_cs; + uint16_t new_flags; + + new_pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + new_flags = readmemw(ss, ((SP + 4) & 0xffff)); + if (cpu_state.abrt) + return 1; + + if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) { + x86gpf(NULL, 0); + return 1; + } + SP += 6; + if (new_flags & I_FLAG) + cpu_state.eflags |= VIF_FLAG; + else + cpu_state.eflags &= ~VIF_FLAG; + cpu_state.flags = (cpu_state.flags & 0x3300) | (new_flags & 0x4cd5) | 2; + op_loadcs(new_cs); + cpu_state.pc = new_pc; + + cycles -= timing_iret_rm; + } else { + x86gpf_expected(NULL, 0); + return 1; + } + } else { + if (msw & 1) { + optype = IRET; + op_pmodeiret(0); + optype = 0; + } else { + uint16_t new_cs; + CPU_SET_OXPC + if (stack32) { + cpu_state.pc = readmemw(ss, ESP); + new_cs = readmemw(ss, ESP + 2); + cpu_state.flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2; + ESP += 6; + } else { + cpu_state.pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + cpu_state.flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2; + SP += 6; + } + op_loadcs(new_cs); + cycles -= timing_iret_rm; + } + } + flags_extract(); + nmi_enable = 1; + rf_flag_no_clear = 1; + CPU_BLOCK_END(); + + PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return cpu_state.abrt; +} + +static int +opIRETD(uint32_t fetchdat) +{ + int cycles_old = cycles; + UN_USED(cycles_old); + + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf_expected(NULL, 0); + return 1; + } + if (msw & 1) { + optype = IRET; + op_pmodeiret(1); + optype = 0; + } else { + uint16_t new_cs; + CPU_SET_OXPC + if (stack32) { + cpu_state.pc = readmeml(ss, ESP); + new_cs = readmemw(ss, ESP + 4); + cpu_state.flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2; + cpu_state.eflags = readmemw(ss, ESP + 10); + ESP += 12; + } else { + cpu_state.pc = readmeml(ss, SP); + new_cs = readmemw(ss, ((SP + 4) & 0xffff)); + cpu_state.flags = (readmemw(ss, (SP + 8) & 0xffff) & 0xffd5) | 2; + cpu_state.eflags = readmemw(ss, (SP + 10) & 0xffff); + SP += 12; + } + op_loadcs(new_cs); + cycles -= timing_iret_rm; + } + flags_extract(); + nmi_enable = 1; + rf_flag_no_clear = 1; + CPU_BLOCK_END(); + + PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1); + PREFETCH_FLUSH(); + return cpu_state.abrt; +} diff --git a/src/mem/mem.c b/src/mem/mem.c index 1ed1e8118..0b002b302 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -161,54 +161,6 @@ mem_log(const char *fmt, ...) # define mem_log(fmt, ...) #endif -/* Set trap for data address breakpoints. */ -void -mem_debug_check_addr(uint32_t addr, int write) -{ - int i = 0; - int set_trap = 0; - - if (!(dr[7] & 0xFF)) - return; - - for (i = 0; i < 4; i++) { - uint32_t dr_addr = dr[i]; - int breakpoint_enabled = !!(dr[7] & (0x3 << (2 * i))); - int len_type_pair = ((dr[7] >> 16) & (0xF << (4 * i))) >> (4 * i); - if (!breakpoint_enabled) - continue; - if (!write && (len_type_pair & 3) != 3) - continue; - if ((len_type_pair & 3) != 1) - continue; - - switch ((len_type_pair >> 2) & 3) - { - case 0x00: - if (dr_addr == addr) { - set_trap = 1; - dr[6] |= (1 << i); - } - break; - case 0x01: - if ((dr_addr & ~1) == addr || ((dr_addr & ~1) + 1) == (addr + 1)) { - set_trap = 1; - dr[6] |= (1 << i); - } - break; - case 0x03: - dr_addr &= ~3; - if (addr >= dr_addr && addr < (dr_addr + 4)) { - set_trap = 1; - dr[6] |= (1 << i); - } - break; - } - } - if (set_trap) - trap |= 4; -} - int mem_addr_is_ram(uint32_t addr) { @@ -838,7 +790,6 @@ readmembl(uint32_t addr) uint64_t a; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1); - mem_debug_check_addr(addr, 0); addr64 = (uint64_t) addr; mem_logical_addr = addr; @@ -868,7 +819,6 @@ writemembl(uint32_t addr, uint8_t val) uint64_t a; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1); - mem_debug_check_addr(addr, 1); addr64 = (uint64_t) addr; mem_logical_addr = addr; @@ -955,8 +905,6 @@ readmemwl(uint32_t addr) addr64a[0] = addr; addr64a[1] = addr + 1; - mem_debug_check_addr(addr, 0); - mem_debug_check_addr(addr + 1, 0); GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 2); mem_logical_addr = addr; @@ -1015,8 +963,6 @@ writememwl(uint32_t addr, uint16_t val) addr64a[0] = addr; addr64a[1] = addr + 1; - mem_debug_check_addr(addr, 1); - mem_debug_check_addr(addr + 1, 1); GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 2); mem_logical_addr = addr; @@ -1193,10 +1139,8 @@ readmemll(uint32_t addr) int i; uint64_t a = 0x0000000000000000ULL; - for (i = 0; i < 4; i++) { + for (i = 0; i < 4; i++) addr64a[i] = (uint64_t) (addr + i); - mem_debug_check_addr(addr + i, 0); - } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 4); mem_logical_addr = addr; @@ -1269,10 +1213,8 @@ writememll(uint32_t addr, uint32_t val) int i; uint64_t a = 0x0000000000000000ULL; - for (i = 0; i < 4; i++) { + for (i = 0; i < 4; i++) addr64a[i] = (uint64_t) (addr + i); - mem_debug_check_addr(addr + i, 1); - } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 4); mem_logical_addr = addr; @@ -1475,10 +1417,8 @@ readmemql(uint32_t addr) int i; uint64_t a = 0x0000000000000000ULL; - for (i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) addr64a[i] = (uint64_t) (addr + i); - mem_debug_check_addr(addr + i, 0); - } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 8); mem_logical_addr = addr; @@ -1543,10 +1483,8 @@ writememql(uint32_t addr, uint64_t val) int i; uint64_t a = 0x0000000000000000ULL; - for (i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) addr64a[i] = (uint64_t) (addr + i); - mem_debug_check_addr(addr + i, 1); - } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 8); mem_logical_addr = addr; @@ -1644,10 +1582,8 @@ do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write) uint32_t last_addr = addr + (num - 1); uint64_t a = 0x0000000000000000ULL; - mem_debug_check_addr(addr, write); - for (i = 0; i < num; i++) { + for (i = 0; i < num; i++) a64[i] = (uint64_t) addr; - } for (i = 0; i < num; i++) { if (cr0 >> 31) { diff --git a/src/mem/mmu_2386.c b/src/mem/mmu_2386.c index fc2237bec..9ed26edfa 100644 --- a/src/mem/mmu_2386.c +++ b/src/mem/mmu_2386.c @@ -39,6 +39,54 @@ #include <86box/rom.h> #include <86box/gdbstub.h> +/* Set trap for data address breakpoints. */ +void +mem_debug_check_addr(uint32_t addr, int write) +{ + int i = 0; + int set_trap = 0; + + if (!(dr[7] & 0xFF)) + return; + + for (i = 0; i < 4; i++) { + uint32_t dr_addr = dr[i]; + int breakpoint_enabled = !!(dr[7] & (0x3 << (2 * i))); + int len_type_pair = ((dr[7] >> 16) & (0xF << (4 * i))) >> (4 * i); + if (!breakpoint_enabled) + continue; + if (!write && (len_type_pair & 3) != 3) + continue; + if ((len_type_pair & 3) != 1) + continue; + + switch ((len_type_pair >> 2) & 3) + { + case 0x00: + if (dr_addr == addr) { + set_trap = 1; + dr[6] |= (1 << i); + } + break; + case 0x01: + if ((dr_addr & ~1) == addr || ((dr_addr & ~1) + 1) == (addr + 1)) { + set_trap = 1; + dr[6] |= (1 << i); + } + break; + case 0x03: + dr_addr &= ~3; + if (addr >= dr_addr && addr < (dr_addr + 4)) { + set_trap = 1; + dr[6] |= (1 << i); + } + break; + } + } + if (set_trap) + trap |= 4; +} + uint8_t mem_readb_map(uint32_t addr) { From 00e38ed0bccfec0189560ef50af7880dbbb54f06 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 14 Jan 2024 21:49:30 +0100 Subject: [PATCH 292/936] Disable I/O port debug checking on 486+. --- src/io.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/io.c b/src/io.c index d09b9c10f..6e4f190e5 100644 --- a/src/io.c +++ b/src/io.c @@ -287,6 +287,10 @@ io_debug_check_addr(uint16_t addr) int i = 0; int set_trap = 0; + /* Do nothing on 486+. */ + if (is486) + return; + if (!(dr[7] & 0xFF)) return; From 540273b23af1ba660daac4ebe1a7651b4b4fea35 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 14 Jan 2024 21:55:24 +0100 Subject: [PATCH 293/936] And reverted io.c, since the stuff was Pentium-only anyway, so pointless. --- src/io.c | 66 -------------------------------------------------------- 1 file changed, 66 deletions(-) diff --git a/src/io.c b/src/io.c index 6e4f190e5..0e68049c3 100644 --- a/src/io.c +++ b/src/io.c @@ -279,60 +279,6 @@ io_handler_interleaved(int set, uint16_t base, int size, io_handler_common(set, base, size, inb, inw, inl, outb, outw, outl, priv, 2); } -extern int trap; -/* Set trap for I/O address breakpoints. */ -void -io_debug_check_addr(uint16_t addr) -{ - int i = 0; - int set_trap = 0; - - /* Do nothing on 486+. */ - if (is486) - return; - - if (!(dr[7] & 0xFF)) - return; - - if (!(cr4 & 0x8)) - return; /* No I/O debug trap. */ - - for (i = 0; i < 4; i++) { - uint16_t dr_addr = dr[i] & 0xFFFF; - int breakpoint_enabled = !!(dr[7] & (0x3 << (2 * i))); - int len_type_pair = ((dr[7] >> 16) & (0xF << (4 * i))) >> (4 * i); - if (!breakpoint_enabled) - continue; - if ((len_type_pair & 3) != 2) - continue; - - switch ((len_type_pair >> 2) & 3) - { - case 0x00: - if (dr_addr == addr) { - set_trap = 1; - dr[6] |= (1 << i); - } - break; - case 0x01: - if ((dr_addr & ~1) == addr || ((dr_addr & ~1) + 1) == (addr + 1)) { - set_trap = 1; - dr[6] |= (1 << i); - } - break; - case 0x03: - dr_addr &= ~3; - if (addr >= dr_addr && addr < (dr_addr + 4)) { - set_trap = 1; - dr[6] |= (1 << i); - } - break; - } - } - if (set_trap) - trap |= 4; -} - uint8_t inb(uint16_t port) { @@ -344,8 +290,6 @@ inb(uint16_t port) int qfound = 0; #endif - io_debug_check_addr(port); - if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { ret = pci_read(port, NULL); found = 1; @@ -406,8 +350,6 @@ outb(uint16_t port, uint8_t val) int qfound = 0; #endif - io_debug_check_addr(port); - if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { pci_write(port, val, NULL); found = 1; @@ -460,8 +402,6 @@ inw(uint16_t port) #endif uint8_t ret8[2]; - io_debug_check_addr(port); - if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { ret = pci_readw(port, NULL); found = 2; @@ -534,8 +474,6 @@ outw(uint16_t port, uint16_t val) int qfound = 0; #endif - io_debug_check_addr(port); - if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { pci_writew(port, val, NULL); found = 2; @@ -604,8 +542,6 @@ inl(uint16_t port) int qfound = 0; #endif - io_debug_check_addr(port); - if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { ret = pci_readl(port, NULL); found = 4; @@ -710,8 +646,6 @@ outl(uint16_t port, uint32_t val) #endif int i = 0; - io_debug_check_addr(port); - if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { pci_writel(port, val, NULL); found = 4; From a9082f418a1ffc856d75a4557ad52abe0aa77886 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 15 Jan 2024 03:14:43 +0600 Subject: [PATCH 294/936] Use Toshiba T1200's HDC in Epson Equity LT --- src/machine/m_elt.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/machine/m_elt.c b/src/machine/m_elt.c index 95ca52a3e..560113ba0 100644 --- a/src/machine/m_elt.c +++ b/src/machine/m_elt.c @@ -50,6 +50,7 @@ #include <86box/rom.h> #include <86box/video.h> #include <86box/vid_cga.h> +#include <86box/hdc.h> #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> @@ -193,6 +194,9 @@ machine_elt_init(const machine_t *model) device_add(&elt_nvr_device); + if (hdc_current <= 1) + device_add(&st506_xt_toshiba_t1200_device); + io_sethandler(0x11b8, 1, sysstat_in, NULL, NULL, sysstat_out, NULL, NULL, cga); return ret; From 8b9e5201010c6a5847907dabcf4cb408499a7419 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 14 Jan 2024 22:25:00 +0100 Subject: [PATCH 295/936] The Epson Equity LT now has a MFM hard disk controller. --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index ac7e767b5..b1ca4cbac 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -2216,7 +2216,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PC, - .flags = MACHINE_VIDEO, + .flags = MACHINE_VIDEO | MACHINE_MFM, .ram = { .min = 640, .max = 640, From eb7464eced6f43458783388f74fe68b43723f9e6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 14 Jan 2024 23:26:03 +0100 Subject: [PATCH 296/936] Removed the Equity LT hard disk controller, the ports are standard (320-323), but it requires a ROM which is not dumped. --- src/machine/m_elt.c | 3 --- src/machine/machine_table.c | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/machine/m_elt.c b/src/machine/m_elt.c index 560113ba0..a69b62184 100644 --- a/src/machine/m_elt.c +++ b/src/machine/m_elt.c @@ -194,9 +194,6 @@ machine_elt_init(const machine_t *model) device_add(&elt_nvr_device); - if (hdc_current <= 1) - device_add(&st506_xt_toshiba_t1200_device); - io_sethandler(0x11b8, 1, sysstat_in, NULL, NULL, sysstat_out, NULL, NULL, cga); return ret; diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index b1ca4cbac..ac7e767b5 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -2216,7 +2216,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PC, - .flags = MACHINE_VIDEO | MACHINE_MFM, + .flags = MACHINE_VIDEO, .ram = { .min = 640, .max = 640, From 974150357b0229be4c8f655c988492fe5da164fd Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 15 Jan 2024 03:16:22 +0100 Subject: [PATCH 297/936] QT: Apply maximized window handling on start-up, fixes #2921. --- src/qt/qt_mainwindow.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index e0252dd7a..eb4634dee 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -808,6 +808,14 @@ MainWindow::initRendererMonitorSlot(int monitor_index) } secondaryRenderer->switchRenderer((RendererStack::Renderer) vid_api); secondaryRenderer->setMouseTracking(true); + + if (monitor_settings[monitor_index].mon_window_maximized) { + if (renderers[monitor_index]) + renderers[monitor_index]->onResize(renderers[monitor_index]->width(), + renderers[monitor_index]->height()); + + device_force_redraw(); + } } } } @@ -1379,12 +1387,12 @@ MainWindow::on_actionResizable_window_triggered(bool checked) { if (checked) { vid_resize = 1; - setWindowFlag(Qt::WindowMaximizeButtonHint); + setWindowFlag(Qt::WindowMaximizeButtonHint, true); setWindowFlag(Qt::MSWindowsFixedSizeDialogHint, false); setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); for (int i = 1; i < MONITORS_NUM; i++) { if (monitors[i].target_buffer) { - renderers[i]->setWindowFlag(Qt::WindowMaximizeButtonHint); + renderers[i]->setWindowFlag(Qt::WindowMaximizeButtonHint, true); renderers[i]->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); } } From 2354a252310055dd5a16e20344440f4394e1e40e Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 15 Jan 2024 03:55:06 +0100 Subject: [PATCH 298/936] Voodoo 3/Banshee: Disable SVGA line doubling in video processing modes, fixes #2629. --- src/video/vid_voodoo_banshee.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 5e28e763c..460a0dcb1 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -572,6 +572,8 @@ banshee_recalctimings(svga_t *svga) /* Also make sure vertical blanking starts on display end. */ svga->vblankstart = svga->dispend; + + svga->linedbl = 0; } else { svga->hblankstart = (((svga->crtc[0x1a] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | From 2cbfc8e04747c4b59cd1735ab3096757f57ff09f Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 15 Jan 2024 04:32:52 +0100 Subject: [PATCH 299/936] 808x: Clear prefetch queue on soft reset, fixes the CTRL+ALT+DEL hang on Amstrad 808x machines, fixes #408. --- src/cpu/808x.c | 3 ++- src/machine/m_amstrad.c | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/808x.c b/src/cpu/808x.c index 3572f2c9f..0b6bd66b5 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -563,9 +563,10 @@ reset_808x(int hard) _opseg[3] = &cpu_state.seg_ds; pfq_size = (is8086) ? 6 : 4; - pfq_clear(); } + pfq_clear(); + load_cs(0xFFFF); cpu_state.pc = 0; if (is_nec) diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index 4bc53c9b4..dfeb1fa0f 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -2124,7 +2124,6 @@ kbd_write(uint16_t port, uint8_t val, void *priv) case 0x66: softresetx86(); - cpu_set_edx(); break; default: From 441b2422d98ed95cd6978eaa1bee165bcaf183b0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 15 Jan 2024 14:00:27 +0100 Subject: [PATCH 300/936] Unix SDL and Win32: Remove excess parenthesis from the recent CD-ROM change, fixes compile. --- src/unix/unix_cdrom.c | 2 +- src/win/win_cdrom.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/unix/unix_cdrom.c b/src/unix/unix_cdrom.c index 6b167fac5..61813a754 100644 --- a/src/unix/unix_cdrom.c +++ b/src/unix/unix_cdrom.c @@ -145,7 +145,7 @@ cdrom_mount(uint8_t id, char *fn) cdrom[id].ops->exit(&(cdrom[id])); cdrom[id].ops = NULL; memset(cdrom[id].image_path, 0, sizeof(cdrom[id].image_path)); - if ((fn != NULL) && (strlen(fn) >= 1) && ((fn[strlen(fn) - 1] == '\\')) + if ((fn != NULL) && (strlen(fn) >= 1) && (fn[strlen(fn) - 1] == '\\')) fn[strlen(fn) - 1] = '/'; cdrom_image_open(&(cdrom[id]), fn); /* Signal media change to the emulated machine. */ diff --git a/src/win/win_cdrom.c b/src/win/win_cdrom.c index 1ab6947bb..58bd85c65 100644 --- a/src/win/win_cdrom.c +++ b/src/win/win_cdrom.c @@ -136,7 +136,7 @@ cdrom_mount(uint8_t id, char *fn) cdrom[id].ops->exit(&(cdrom[id])); cdrom[id].ops = NULL; memset(cdrom[id].image_path, 0, sizeof(cdrom[id].image_path)); - if ((fn != NULL) && (strlen(fn) >= 1) && ((fn[strlen(fn) - 1] == '/')) + if ((fn != NULL) && (strlen(fn) >= 1) && (fn[strlen(fn) - 1] == '/')) fn[strlen(fn) - 1] = '\\'; cdrom_image_open(&(cdrom[id]), fn); /* Signal media change to the emulated machine. */ From 9143302587abf78266d92759bf082ed38e253ffe Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 15 Jan 2024 18:14:04 +0100 Subject: [PATCH 301/936] The two Compaq Presarios no longer allow PCI bridges, fixes #4046. --- src/machine/m_at_socket7.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index a3e777dbd..d61e4ba6e 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -532,7 +532,7 @@ machine_at_presario2240_init(const machine_t *model) machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_NO_BRIDGES); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); pci_register_slot(0x14, PCI_CARD_VIDEO, 3, 0, 0, 0); @@ -563,7 +563,7 @@ machine_at_presario4500_init(const machine_t *model) machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_NO_BRIDGES); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); pci_register_slot(0x14, PCI_CARD_VIDEO, 3, 0, 0, 0); From 481b8c8b2234121353c7b2c0fe42840be790d147 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 15 Jan 2024 18:42:32 +0100 Subject: [PATCH 302/936] Tseng improvements. --- src/video/vid_et4000.c | 17 +++++++++---- src/video/vid_et4000w32.c | 50 ++++++++++----------------------------- 2 files changed, 26 insertions(+), 41 deletions(-) diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index cb44e9383..c5e2772f2 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -599,6 +599,9 @@ et4000_recalctimings(svga_t *svga) const et4000_t *dev = (et4000_t *) svga->priv; svga->ma_latch |= (svga->crtc[0x33] & 3) << 16; + + svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; + if (svga->crtc[0x35] & 1) svga->vblankstart += 0x400; if (svga->crtc[0x35] & 2) @@ -613,10 +616,11 @@ et4000_recalctimings(svga_t *svga) svga->rowoffset = 0x100; if (svga->crtc[0x3f] & 1) svga->htotal += 256; - if (svga->attrregs[0x16] & 0x20) + if (svga->attrregs[0x16] & 0x20) { svga->hdisp <<= 1; - - svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; + svga->hblankstart <<= 1; + svga->hblank_end_val <<= 1; + } switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x34] << 1) & 4)) { case 0: @@ -637,10 +641,14 @@ et4000_recalctimings(svga_t *svga) case 15: case 16: svga->hdisp /= 2; + svga->hblankstart /= 2; + svga->hblank_end_val /= 2; break; case 24: svga->hdisp /= 3; + svga->hblankstart /= 3; + svga->hblank_end_val /= 3; break; default: @@ -689,7 +697,8 @@ et4000_kasan_recalctimings(svga_t *svga) et4000_recalctimings(svga); if (svga->render == svga_render_text_80 && (et4000->kasan_cfg_regs[0] & 8)) { - svga->ma_latch -= 3; + svga->hdisp += svga->dots_per_clock; + svga->ma_latch -= 5; svga->ca_adj = (et4000->kasan_cfg_regs[0] >> 6) - 3; svga->ksc5601_sbyte_mask = (et4000->kasan_cfg_regs[0] & 4) << 5; if ((et4000->kasan_cfg_regs[0] & 0x23) == 0x20 && (et4000->kasan_cfg_regs[4] & 0x80) && ((svga->crtc[0x37] & 0x0B) == 0x0A)) diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 69a995208..f3cac960b 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -431,6 +431,9 @@ et4000w32p_recalctimings(svga_t *svga) et4000w32p_t *et4000 = (et4000w32p_t *) svga->priv; svga->ma_latch |= (svga->crtc[0x33] & 0x7) << 16; + + svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; + if (svga->crtc[0x35] & 0x01) svga->vblankstart += 0x400; if (svga->crtc[0x35] & 0x02) @@ -445,10 +448,11 @@ et4000w32p_recalctimings(svga_t *svga) svga->rowoffset += 0x100; if (svga->crtc[0x3F] & 0x01) svga->htotal += 256; - if (svga->attrregs[0x16] & 0x20) + if (svga->attrregs[0x16] & 0x20) { svga->hdisp <<= 1; - - svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; + svga->hblankstart <<= 1; + svga->hblank_end_val <<= 1; + } svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((svga->miscout >> 2) & 3, svga->clock_gen); @@ -474,32 +478,6 @@ et4000w32p_recalctimings(svga_t *svga) } } -#if 0 - if (svga->adv_flags & FLAG_NOSKEW) { - /* On the Cardex ET4000/W32p-based cards, adjust text mode clocks by 1. */ - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /* Text mode */ - svga->ma_latch--; - - if (svga->seqregs[1] & 8) /*40 column*/ - svga->hdisp += (svga->seqregs[1] & 1) ? 16 : 18; - else - svga->hdisp += (svga->seqregs[1] & 1) ? 8 : 9; - } else { - /* Also adjust the graphics mode clocks in some cases. */ - if ((svga->gdcreg[5] & 0x40) && (svga->bpp != 32)) { - if ((svga->bpp == 15) || (svga->bpp == 16) || (svga->bpp == 24)) - svga->hdisp += (svga->seqregs[1] & 1) ? 16 : 18; - else - svga->hdisp += (svga->seqregs[1] & 1) ? 8 : 9; - } else if ((svga->gdcreg[5] & 0x40) == 0) { - svga->hdisp += (svga->seqregs[1] & 1) ? 8 : 9; - if (svga->hdisp == 648 || svga->hdisp == 808 || svga->hdisp == 1032) - svga->hdisp -= 8; - } - } - } -#endif - if (et4000->type == ET4000W32) { if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { if (svga->gdcreg[5] & 0x40) { @@ -522,8 +500,11 @@ et4000w32p_recalctimings(svga_t *svga) switch (svga->bpp) { case 15: case 16: - if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { svga->hdisp >>= 1; + svga->hblankstart >>= 1; + svga->hblank_end_val >>= 1; + } if (et4000->type <= ET4000W32P_REVC) { if (et4000->type == ET4000W32P_REVC) { if (svga->hdisp != 1024) @@ -534,6 +515,8 @@ et4000w32p_recalctimings(svga_t *svga) break; case 24: svga->hdisp /= 3; + svga->hblankstart /= 3; + svga->hblank_end_val /= 3; if (et4000->type <= ET4000W32P_REVC) et4000->adjust_cursor = 2; if ((et4000->type == ET4000W32P_DIAMOND) && ((svga->hdisp == (640 / 2)) || (svga->hdisp == 1232))) { @@ -553,10 +536,6 @@ et4000w32p_recalctimings(svga_t *svga) else svga->render = svga_render_text_80; } else { - if (svga->adv_flags & FLAG_NOSKEW) { - svga->ma_latch--; - } - switch (svga->gdcreg[5] & 0x60) { case 0x00: if (et4000->rev == 5) @@ -2809,7 +2788,6 @@ et4000w32p_init(const device_t *info) et4000->svga.ramdac = device_add(&stg_ramdac_device); et4000->svga.clock_gen = et4000->svga.ramdac; et4000->svga.getclock = stg_getclock; - et4000->svga.adv_flags |= FLAG_NOSKEW; break; case ET4000W32P_REVC: @@ -2834,7 +2812,6 @@ et4000w32p_init(const device_t *info) et4000->svga.ramdac = device_add(&stg_ramdac_device); et4000->svga.clock_gen = et4000->svga.ramdac; et4000->svga.getclock = stg_getclock; - et4000->svga.adv_flags |= FLAG_NOSKEW; break; case ET4000W32P_CARDEX: @@ -2847,7 +2824,6 @@ et4000w32p_init(const device_t *info) et4000->svga.ramdac = device_add(&stg_ramdac_device); et4000->svga.clock_gen = et4000->svga.ramdac; et4000->svga.getclock = stg_getclock; - et4000->svga.adv_flags |= FLAG_NOSKEW; break; case ET4000W32P_DIAMOND: From d17d13e3b842d74c62639bc85315509a44bfb75e Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 15 Jan 2024 21:43:33 +0100 Subject: [PATCH 303/936] ATI Mach8/32 mode changes and cleanup: 1. Cleanups and moving the mach8/32 struct to a dedicated header so that would allow for future 8514/A add-on clones (in paper). 2. Mach8/32's port 0x4ae8/9 and shadow set ports (0x5aee and 0x46ee) now account to the mode changes seriously, should fix most of the horizontal/vertical coordinates while entering GUI modes of various stuff. 3. Horizontal/Vertical window coordinates can only be modified if the display enable bit of port 0x22e8 is set as well as bit 0 of port 0x4aee, fixes most problems noted above. 4. Implemented horizontal blanking stuff a la VGA but actually for 8514/A and clones (like ATI). 5. Added some comments regarding the current situation. 6. The Mach8 was actually a 8514/A clone co-processor, not a single solution card of its own. The ATI Graphics Ultra was a single solution card that is actually a Mach8 + ATI 28800-6 in one, so renaming it accordingly. 7. Fixed garbled/distorted acceleration when device bitmap acceleration is enabled in the ATI Mach8 3.0 Win3.1 drivers. --- src/include/86box/vid_8514a.h | 25 +- src/include/86box/vid_ati_mach8.h | 162 +++++ src/include/86box/vid_svga.h | 8 + src/include/86box/video.h | 2 +- src/video/vid_8514a.c | 433 +++++++----- src/video/vid_ati68860_ramdac.c | 1 + src/video/vid_ati_mach8.c | 1099 +++++++++++++++++------------ src/video/vid_table.c | 2 +- 8 files changed, 1075 insertions(+), 657 deletions(-) create mode 100644 src/include/86box/vid_ati_mach8.h diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h index 4d7483f30..dcfdf6045 100644 --- a/src/include/86box/vid_8514a.h +++ b/src/include/86box/vid_8514a.h @@ -33,6 +33,8 @@ typedef struct hwcursor8514_t { } hwcursor8514_t; typedef struct ibm8514_t { + rom_t bios_rom; + rom_t bios_rom2; hwcursor8514_t hwcursor; hwcursor8514_t hwcursor_latch; uint8_t pos_regs[8]; @@ -60,12 +62,12 @@ typedef struct ibm8514_t { int dac_b; int internal_pitch; int hwcursor_on; + int modechange; struct { uint16_t subsys_cntl; uint16_t setup_md; uint16_t advfunc_cntl; - uint8_t ext_advfunc_cntl; uint16_t cur_y; uint16_t cur_x; int16_t destx; @@ -142,14 +144,21 @@ typedef struct ibm8514_t { uint16_t test; int vendor_mode[2]; + int h_blankstart; + int h_blank_end_val; + int hblankstart; + int hblank_end_val; + int hblankend; + int hblank_ext; + int hblank_sub; int v_total; int dispend; int v_syncstart; int split; int h_disp; - int h_disp_old; int h_total; + int h_sync_width; int h_disp_time; int rowoffset; int dispon; @@ -176,20 +185,17 @@ typedef struct ibm8514_t { uint8_t data_available; uint8_t data_available2; - uint8_t scanmodulos; uint8_t rowcount; + int hsync_start; + int hsync_width; int htotal; int hdisp; - int vtadj; - int vdadj; - int vsadj; + int hdisped; int sc; - int vtb; - int vdb; - int vsb; int vsyncstart; int vsyncwidth; int vtotal; + int v_disp; int vdisp; int disp_cntl; int interlace; @@ -205,6 +211,7 @@ typedef struct ibm8514_t { int pitch; int ext_pitch; int ext_crt_pitch; + int extensions; } ibm8514_t; #endif /*VIDEO_8514A_H*/ diff --git a/src/include/86box/vid_ati_mach8.h b/src/include/86box/vid_ati_mach8.h new file mode 100644 index 000000000..7b5862f35 --- /dev/null +++ b/src/include/86box/vid_ati_mach8.h @@ -0,0 +1,162 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the 8514/A-compatible Mach8 and Mach32 graphics + * chips from ATI for the ISA/VLB/MCA/PCI buses. + * + * + * + * Authors: TheCollector1995. + * + * Copyright 2022-2024 TheCollector1995. + */ +#ifndef VIDEO_ATI_MACH8_H +#define VIDEO_ATI_MACH8_H + +typedef struct mach_t { + ati_eeprom_t eeprom; + svga_t svga; + + rom_t bios_rom; + rom_t bios_rom2; + mem_mapping_t mmio_linear_mapping; + + int mca_bus; + int pci_bus; + int vlb_bus; + int has_bios; + + uint8_t regs[256]; + uint8_t pci_regs[256]; + uint8_t int_line; + uint8_t pci_slot; + uint8_t irq_state; + + int index; + int ramdac_type; + int old_mode; + + uint32_t memory; + + uint16_t config1; + uint16_t config2; + + uint8_t pos_regs[8]; + uint8_t pci_cntl_reg; + uint8_t cursor_col_0; + uint8_t cursor_col_1; + uint8_t ext_cur_col_0_r; + uint8_t ext_cur_col_1_r; + uint8_t ext_cur_col_0_g; + uint8_t ext_cur_col_1_g; + uint16_t cursor_col_0_rg; + uint16_t cursor_col_1_rg; + uint16_t cursor_col_b; + uint16_t cursor_offset_lo; + uint16_t cursor_offset_lo_reg; + uint16_t cursor_offset_hi; + uint16_t cursor_offset_hi_reg; + uint16_t cursor_vh_offset; + uint16_t cursor_x; + uint16_t cursor_y; + uint16_t misc; + uint16_t memory_aperture; + uint16_t local_cntl; + uint32_t linear_base; + uint8_t ap_size; + uint8_t bank_w; + uint8_t bank_r; + uint16_t shadow_set; + uint16_t shadow_cntl; + int ext_on[2]; + int compat_mode; + + struct { + uint8_t line_idx; + int16_t line_array[6]; + uint8_t patt_idx; + uint8_t patt_len; + uint8_t pix_trans[2]; + uint8_t eeprom_control; + uint16_t dest_x_end; + uint16_t dest_x_start; + uint16_t dest_y_end; + uint16_t src_x_end; + uint16_t src_x_start; + uint16_t src_x; + uint16_t src_y; + int16_t bres_count; + uint16_t clock_sel; + uint16_t crt_pitch; + uint16_t ge_pitch; + uint16_t dest_cmp_fn; + uint16_t dp_config; + uint16_t ext_ge_config; + uint16_t ge_offset_lo; + uint16_t ge_offset_hi; + uint16_t linedraw_opt; + uint16_t max_waitstates; + uint8_t patt_data_idx; + uint8_t patt_data[0x18]; + uint16_t scan_to_x; + uint16_t scratch0; + uint16_t scratch1; + uint16_t test; + uint16_t pattern; + uint16_t test2; + int src_y_dir; + int cmd_type; + int block_write_mono_pattern_enable; + int mono_pattern_enable; + int16_t cx_end_line; + int16_t cy_end_line; + int16_t cx; + int16_t cx_end; + int16_t cy_end; + int16_t dx; + int16_t dx_end; + int16_t dy; + int16_t dy_end; + int16_t dx_start; + int16_t dy_start; + int16_t cy; + int16_t sx_start; + int16_t sx_end; + int16_t sx; + int16_t x_count; + int16_t xx_count; + int16_t xxx_count; + int16_t sy; + int16_t y_count; + int16_t err; + int16_t width; + int16_t src_width; + int16_t height; + int16_t bleft, bright, btop, bbottom; + int poly_src; + int temp_cnt; + int stepx; + int stepy; + int src_stepx; + uint8_t color_pattern[16]; + uint8_t color_pattern_full[32]; + uint16_t color_pattern_word[8]; + int mono_pattern[8][8]; + uint32_t ge_offset; + uint32_t crt_offset; + uint32_t patt_len_reg; + int poly_fill; + uint16_t dst_clr_cmp_mask; + int clip_overrun; + int color_pattern_idx; + } accel; + + atomic_int force_busy; +} mach_t; + +#endif /*VIDEO_ATI_MACH8_H*/ diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 880f79003..f644c2b63 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -281,6 +281,7 @@ typedef struct svga_t { uint32_t (*conv_16to32)(struct svga_t *svga, uint16_t color, uint8_t bpp); void * dev8514; + void * ext8514; void * xga; } svga_t; @@ -296,6 +297,13 @@ extern void ibm8514_accel_out_pixtrans(svga_t *svga, uint16_t port, uint32_t extern void ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, uint8_t ssv, int len); extern void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, int len); +#ifdef ATI_8514_ULTRA +extern void ati8514_recalctimings(svga_t *svga); +extern uint8_t ati8514_mca_read(int port, void *priv); +extern void ati8514_mca_write(int port, uint8_t val, void *priv); +extern void ati8514_init(svga_t *svga, void *ext8514, void *dev8514); +#endif + extern void xga_poll(void *priv, svga_t *svga); extern void xga_recalctimings(svga_t *svga); diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 0f0a13182..2dfc6e6c1 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -306,7 +306,7 @@ extern void xga_device_add(void); /* IBM 8514/A and clones*/ extern void ibm8514_device_add(void); -extern const device_t mach8_isa_device; +extern const device_t mach8_vga_isa_device; extern const device_t mach32_isa_device; extern const device_t mach32_vlb_device; extern const device_t mach32_mca_device; diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 864a88978..bb61e3c47 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -13,7 +13,7 @@ * * Authors: TheCollector1995. * - * Copyright 2022-2023 TheCollector1995. + * Copyright 2022-2024 TheCollector1995. */ #include #include @@ -38,8 +38,14 @@ #include <86box/vid_xga.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> +#include <86box/vid_ati_eeprom.h> +#include <86box/vid_ati_mach8.h> #include "cpu.h" +#ifdef ATI_8514_ULTRA +#define BIOS_MACH8_ROM_PATH "roms/video/mach8/11301113140.BIN" +#endif + static void ibm8514_accel_outb(uint16_t port, uint8_t val, void *priv); static void ibm8514_accel_outw(uint16_t port, uint16_t val, void *priv); static uint8_t ibm8514_accel_inb(uint16_t port, void *priv); @@ -63,6 +69,27 @@ ibm8514_log(const char *fmt, ...) # define ibm8514_log(fmt, ...) #endif +#define WRITE8(addr, var, val) \ + switch ((addr) & 1) { \ + case 0: \ + var = (var & 0xff00) | (val); \ + break; \ + case 1: \ + var = (var & 0x00ff) | ((val) << 8); \ + break; \ + } + +#define READ8(addr, var) \ + switch ((addr) & 1) { \ + case 0: \ + temp = (var) & 0xff; \ + break; \ + case 1: \ + temp = ((var) >> 8) & 0xff; \ + break; \ + } + + #define READ_PIXTRANS_WORD(cx, n) \ if ((cmd <= 1) || (cmd == 5)) { \ temp = dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & dev->vram_mask]; \ @@ -453,16 +480,15 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) switch (port) { case 0x82e8: case 0xc2e8: - if (len == 1) { + if (len == 1) dev->accel.cur_y = (dev->accel.cur_y & 0x700) | val; - } else + else dev->accel.cur_y = val & 0x7ff; break; case 0x82e9: case 0xc2e9: - if (len == 1) { + if (len == 1) dev->accel.cur_y = (dev->accel.cur_y & 0xff) | ((val & 0x07) << 8); - } break; case 0x86e8: @@ -474,9 +500,8 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) break; case 0x86e9: case 0xc6e9: - if (len == 1) { + if (len == 1) dev->accel.cur_x = (dev->accel.cur_x & 0xff) | ((val & 0x07) << 8); - } break; case 0x8ae8: @@ -742,16 +767,19 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) else { dev->accel.multifunc_cntl = val; dev->accel.multifunc[dev->accel.multifunc_cntl >> 12] = dev->accel.multifunc_cntl & 0xfff; - if ((dev->accel.multifunc_cntl >> 12) == 1) { + if ((dev->accel.multifunc_cntl >> 12) == 1) dev->accel.clip_top = val & 0x7ff; - if (val & 0x400) - dev->accel.clip_top |= ~0x3ff; - } - if ((dev->accel.multifunc_cntl >> 12) == 2) { + + if ((dev->accel.multifunc_cntl >> 12) == 2) dev->accel.clip_left = val & 0x7ff; - if (val & 0x400) - dev->accel.clip_left |= ~0x3ff; - } + + if ((dev->accel.multifunc_cntl >> 12) == 3) + dev->accel.multifunc[3] = val & 0x7ff; + + if ((dev->accel.multifunc_cntl >> 12) == 4) + dev->accel.multifunc[4] = val & 0x7ff; + + ibm8514_log("CLIPBOTTOM=%d, CLIPRIGHT=%d, bpp=%d, pitch=%d.\n", dev->accel.multifunc[3], dev->accel.multifunc[4], dev->accel_bpp, dev->pitch); if (port == 0xfee8) dev->accel.cmd_back = 1; else @@ -763,6 +791,12 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) if (len == 1) { dev->accel.multifunc_cntl = (dev->accel.multifunc_cntl & 0xff) | (val << 8); dev->accel.multifunc[dev->accel.multifunc_cntl >> 12] = dev->accel.multifunc_cntl & 0xfff; + if ((dev->accel.multifunc_cntl >> 12) == 1) + dev->accel.clip_top = dev->accel.multifunc_cntl & 0x7ff; + + if ((dev->accel.multifunc_cntl >> 12) == 2) + dev->accel.clip_left = dev->accel.multifunc_cntl & 0x7ff; + if (port == 0xfee9) dev->accel.cmd_back = 1; else @@ -855,151 +889,118 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) ibm8514_t *dev = (ibm8514_t *) svga->dev8514; uint8_t old = 0; - if (port & 0x8000) { + if (port & 0x8000) ibm8514_accel_out_fifo(svga, port, val, len); - } else { + else { switch (port) { case 0x2e8: - if (len == 1) - dev->htotal = (dev->htotal & 0xff00) | val; - else { - dev->htotal = val; - svga_recalctimings(svga); - } - break; case 0x2e9: - if (len != 1) { - dev->htotal = (dev->htotal & 0xff) | (val << 8); - ibm8514_log("IBM 8514/A: H_TOTAL write 02E8 = %d\n", dev->htotal + 1); - svga_recalctimings(svga); - } + WRITE8(port, dev->htotal, val); break; case 0x6e8: - dev->hdisp = val; - ibm8514_log("IBM 8514/A: H_DISP write 06E8 = %d\n", dev->hdisp + 1); - svga_recalctimings(svga); + case 0x6e9: + if (!(port & 1)) { + dev->hdisped = val; + dev->hdisp = (dev->hdisped + 1) << 3; + } + ibm8514_log("IBM 8514/A: H_DISP write 06E8 = %d, advfunc=%x.\n", dev->hdisp, dev->accel.advfunc_cntl & 4); break; case 0xae8: + case 0xae9: + if (!(port & 1)) { + dev->hsync_start = val; + dev->hblankstart = (dev->hsync_start & 0x07) + 1; + } ibm8514_log("IBM 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); - svga_recalctimings(svga); break; case 0xee8: + case 0xee9: + if (!(port & 1)) { + dev->hsync_width = val; + dev->hblank_end_val = (dev->hblankstart + (dev->hsync_start & 0x1f) - 1) & 0x3f; + } ibm8514_log("IBM 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); - svga_recalctimings(svga); break; case 0x12e8: - if (len == 1) - dev->vtotal = (dev->vtotal & 0x1f00) | val; - else { - dev->vtotal = val & 0x1fff; - svga_recalctimings(svga); - } - break; case 0x12e9: - if (len == 1) { - dev->vtotal = (dev->vtotal & 0xff) | ((val & 0x1f) << 8); - ibm8514_log("IBM 8514/A: V_TOTAL write 12E8 = %d\n", dev->vtotal); - svga_recalctimings(svga); - } + WRITE8(port, dev->vtotal, val); + dev->vtotal &= 0x1fff; break; case 0x16e8: - if (len == 1) - dev->vdisp = (dev->vdisp & 0x1f00) | val; - else { - dev->vdisp = val & 0x1fff; - svga_recalctimings(svga); - } - break; case 0x16e9: - if (len == 1) { - dev->vdisp = (dev->vdisp & 0xff) | ((val & 0x1f) << 8); - ibm8514_log("IBM 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp); - svga_recalctimings(svga); - } + WRITE8(port, dev->v_disp, val); + dev->v_disp &= 0x1fff; + dev->vdisp = dev->v_disp; + dev->vdisp >>= 1; + dev->vdisp++; + ibm8514_log("IBM 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp); break; case 0x1ae8: - if (len == 1) - dev->vsyncstart = (dev->vsyncstart & 0x1f00) | val; - else { - dev->vsyncstart = val & 0x1fff; - svga_recalctimings(svga); - } - break; case 0x1ae9: - if (len == 1) { - dev->vsyncstart = (dev->vsyncstart & 0xff) | ((val & 0x1f) << 8); - ibm8514_log("IBM 8514/A: V_SYNC_STRT write 1AE8 = %d\n", dev->vsyncstart); - svga_recalctimings(svga); - } + WRITE8(port, dev->vsyncstart, val); + dev->vsyncstart &= 0x1fff; break; case 0x1ee8: - dev->vsyncwidth = val; + case 0x1ee9: ibm8514_log("IBM 8514/A: V_SYNC_WID write 1EE8 = %02x\n", val); - svga_recalctimings(svga); break; case 0x22e8: dev->disp_cntl = val & 0x7e; dev->interlace = !!(val & 0x10); - ibm8514_log("IBM 8514/A: DISP_CNTL write 22E8 = %02x, SCANMODULOS = %d\n", dev->disp_cntl, dev->scanmodulos); - svga_recalctimings(svga); + ibm8514_log("IBM 8514/A: DISP_CNTL write 22E8 = %02x, interlace = %d\n", dev->disp_cntl, dev->interlace); break; case 0x42e8: old = dev->subsys_stat; - if ((val & 0xff) & 1) + if (val & 1) dev->subsys_stat &= ~1; - if ((val & 0xff) & 2) + if (val & 2) dev->subsys_stat &= ~2; - if ((val & 0xff) & 4) + if (val & 4) dev->subsys_stat &= ~4; - if ((val & 0xff) & 8) + if (val & 8) dev->subsys_stat &= ~8; - if (len != 1) { - old = dev->subsys_cntl; - dev->subsys_cntl = (val >> 8); - if ((old ^ dev->subsys_cntl) & 1) - dev->subsys_stat |= 1; - if ((old ^ dev->subsys_cntl) & 2) - dev->subsys_stat |= 2; - if ((old ^ dev->subsys_cntl) & 4) - dev->subsys_stat |= 4; - if ((old ^ dev->subsys_cntl) & 8) - dev->subsys_stat |= 8; - } break; case 0x42e9: - if (len == 1) { - old = dev->subsys_cntl; - dev->subsys_cntl = val; - if ((old ^ val) & 1) - dev->subsys_stat |= 1; - if ((old ^ val) & 2) - dev->subsys_stat |= 2; - if ((old ^ val) & 4) - dev->subsys_stat |= 4; - if ((old ^ val) & 8) - dev->subsys_stat |= 8; - } + old = dev->subsys_cntl; + dev->subsys_cntl = val; + if ((old ^ val) & 1) + dev->subsys_stat |= 1; + if ((old ^ val) & 2) + dev->subsys_stat |= 2; + if ((old ^ val) & 4) + dev->subsys_stat |= 4; + if ((old ^ val) & 8) + dev->subsys_stat |= 8; break; case 0x4ae8: - if (!val) - break; - dev->accel.advfunc_cntl = val & 0x0f; - dev->on[0] = val & 0x01; - vga_on = !dev->on[0]; - ibm8514_log("IBM 8514/A: VGA ON = %i, val = %02x\n", vga_on, val); + case 0x4ae9: + WRITE8(port, dev->accel.advfunc_cntl, val); + dev->on[port & 1] = dev->accel.advfunc_cntl & 0x01; + vga_on = !dev->on[port & 1]; + dev->vendor_mode[port & 1] = 0; + if (dev->on[0] || dev->on[1]) { + if (!(dev->accel.advfunc_cntl & 4)) { + if (dev->disp_cntl & 0x60) { + dev->hdisp = 640; + dev->vdisp = 480; + } + } + } + ibm8514_log("IBM 8514/A: (0x%04x): ON=%d, shadow crt=%x.\n", port, dev->on[port & 1], dev->accel.advfunc_cntl & 4); svga_recalctimings(svga); break; + default: break; } @@ -1036,16 +1037,16 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len) vpos = dev->vc & 0x7ff; if (vblankend > dev->v_total) { vblankend -= dev->v_total; - if (vpos >= svga->vblankstart || vpos <= vblankend) + if ((vpos >= svga->vblankstart) || (vpos <= vblankend)) temp |= 2; } else { - if (vpos >= svga->vblankstart && vpos <= vblankend) + if ((vpos >= svga->vblankstart) && (vpos <= vblankend)) temp |= 2; } break; case 0x6e8: - temp = dev->hdisp; + temp = dev->hdisped; break; case 0x22e8: @@ -1091,22 +1092,19 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len) case 0x82e8: case 0xc2e8: - if (len != 1) { + if (len != 1) temp = dev->accel.cur_y; - } break; case 0x86e8: case 0xc6e8: - if (len != 1) { + if (len != 1) temp = dev->accel.cur_x; - } break; case 0x92e8: - if (len != 1) { + if (len != 1) temp = dev->test; - } break; case 0x9ae8: @@ -1200,12 +1198,6 @@ ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t ibm8514_accel_start(count, cpu_input, mix_dat, cpu_dat, svga, len); } -#define CLAMP(x) \ - do { \ - if ((x) & ~0xff) \ - x = ((x) < 0) ? 0 : 0xff; \ - } while (0) - void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, UNUSED(int len)) { @@ -3831,8 +3823,6 @@ bitblt: } } -#undef CLAMP - void ibm8514_render_8bpp(svga_t *svga) { @@ -3840,9 +3830,8 @@ ibm8514_render_8bpp(svga_t *svga) uint32_t *p; uint32_t dat; - if ((dev->displine + svga->y_add) < 0) { + if ((dev->displine + svga->y_add) < 0) return; - } if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; @@ -4184,6 +4173,7 @@ ibm8514_poll(void *priv, svga_t *svga) dev->maback += (dev->rowoffset << 3); if (dev->interlace) dev->maback += (dev->rowoffset << 3); + dev->maback &= dev->vram_mask; dev->ma = dev->maback; } else { @@ -4260,65 +4250,66 @@ ibm8514_recalctimings(svga_t *svga) { ibm8514_t *dev = (ibm8514_t *) svga->dev8514; - if (dev->on[0]) { - dev->h_disp = (dev->hdisp + 1) << 3; - dev->pitch = (dev->accel.advfunc_cntl & 4) ? 1024 : 640; - dev->h_total = (dev->htotal + 1); - dev->v_total = (dev->vtotal + 1); - dev->v_syncstart = (dev->vsyncstart + 1); - dev->rowcount = !!(dev->disp_cntl & 0x08); - dev->dispend = ((dev->vdisp >> 1) + 1); - if (dev->dispend == 766) - dev->dispend += 2; +#ifdef ATI_8514_ULTRA + if (dev->extensions) { + if (svga->ext8514 != NULL) + ati8514_recalctimings(svga); + } else +#endif + { + if (dev->on[0] || dev->on[1]) { + dev->h_disp = dev->hdisp; + dev->h_total = dev->htotal + 1; + dev->h_blankstart = dev->hblankstart; + dev->h_blank_end_val = dev->hblank_end_val; + dev->v_total = dev->vtotal + 1; + dev->v_syncstart = dev->vsyncstart + 1; + dev->rowcount = !!(dev->disp_cntl & 0x08); + dev->dispend = dev->vdisp; - if (dev->dispend == 598) - dev->dispend += 2; - - if (dev->accel.advfunc_cntl & 4) { - if (dev->h_disp == 8) { - dev->h_disp = 1024; - dev->dispend = 768; - dev->v_total = 1536; - dev->v_syncstart = 1536; - } + if (dev->dispend == 766) + dev->dispend += 2; if (dev->dispend == 598) - dev->dispend = 600; + dev->dispend += 2; - if (dev->interlace) { - dev->dispend >>= 1; - dev->v_syncstart >>= 2; - dev->v_total >>= 2; + if (dev->accel.advfunc_cntl & 4) { + dev->pitch = 1024; + if (!dev->h_disp) { + dev->h_disp = 1024; + dev->dispend = 768; + } + svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; } else { - dev->v_syncstart >>= 1; - dev->v_total >>= 1; + dev->pitch = 640; + if (!dev->h_disp) { + dev->h_disp = 640; + dev->dispend = 480; + } + svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; } + if (dev->interlace) + dev->dispend >>= 1; + dev->rowoffset = 0x80; + svga->map8 = dev->pallook; + svga->render8514 = ibm8514_render_8bpp; - ibm8514_log("1024x768 clock mode, hdisp = %d, htotal = %d, vtotal = %d, vsyncstart = %d, interlace = %02x\n", dev->h_disp, dev->h_total, dev->v_total, dev->v_syncstart, dev->interlace); - svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; - } else { - if (dev->h_disp == 1024) { - dev->h_disp = 640; - dev->dispend = 480; + dev->hblankend = (dev->h_blankstart & ~0x3f) | dev->h_blank_end_val; + if (dev->hblankend <= dev->h_blankstart) + dev->hblankend += 0x40; + dev->hblankend += dev->hblank_ext; + + dev->hblank_sub = 0; + if (dev->hblankend > dev->h_total) { + dev->hblankend &= 0x3f; + dev->hblank_sub = dev->hblankend + 1; + + dev->h_disp -= dev->hblank_sub; } - - if (dev->interlace) { - dev->dispend >>= 1; - dev->v_syncstart >>= 2; - dev->v_total >>= 2; - } else { - dev->v_syncstart >>= 1; - dev->v_total >>= 1; - } - - dev->rowoffset = 0x80; - - svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + ibm8514_log("BPP=%d, Pitch = %d, rowoffset = %d, crtc13 = %02x, highres bit = %02x, has_vga? = %d.\n", dev->bpp, dev->pitch, dev->rowoffset, svga->crtc[0x13], dev->accel.advfunc_cntl & 4, !ibm8514_standalone_enabled); } - svga->render8514 = ibm8514_render_8bpp; - ibm8514_log("BPP=%d, Pitch = %d, rowoffset = %d, crtc13 = %02x, mode = %d, highres bit = %02x, has_vga? = %d.\n", dev->bpp, dev->pitch, dev->rowoffset, svga->crtc[0x13], dev->ibm_mode, dev->accel.advfunc_cntl & 4, !ibm8514_standalone_enabled); } ibm8514_log("8514 enabled, hdisp=%d, vtotal=%d, htotal=%d, dispend=%d, rowoffset=%d, split=%d, vsyncstart=%d, split=%08x\n", dev->hdisp, dev->vtotal, dev->htotal, dev->dispend, dev->rowoffset, dev->split, dev->vsyncstart, dev->split); } @@ -4355,6 +4346,19 @@ ibm8514_mca_feedb(void *priv) return dev->pos_regs[2] & 1; } +static void +ibm8514_mca_reset(void *priv) +{ + svga_t *svga = (svga_t *) priv; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + ibm8514_log("MCA reset.\n"); + dev->on[0] = 0; + dev->on[1] = 0; + vga_on = 1; + ibm8514_mca_write(0x102, 0, svga); +} + static void * ibm8514_init(const device_t *info) { @@ -4363,8 +4367,10 @@ ibm8514_init(const device_t *info) svga_t *svga = svga_get_pri(); ibm8514_t *dev = (ibm8514_t *) calloc(1, sizeof(ibm8514_t)); + mach_t *mach = NULL; svga->dev8514 = dev; + svga->ext8514 = NULL; dev->vram_size = 1024 << 10; dev->vram = calloc(dev->vram_size, 1); @@ -4376,13 +4382,56 @@ ibm8514_init(const device_t *info) dev->type = info->flags; dev->bpp = 0; +#ifdef ATI_8514_ULTRA + dev->extensions = device_get_config_int("extensions"); + + switch (dev->extensions) { + case 1: + if (rom_present(BIOS_MACH8_ROM_PATH)) { + mach = (mach_t *) calloc(1, sizeof(mach_t)); + svga->ext8514 = mach; + ati8514_init(svga, svga->ext8514, svga->dev8514); + + if (dev->type & DEVICE_MCA) { + rom_init(&dev->bios_rom, + BIOS_MACH8_ROM_PATH, + 0xc6800, 0x1000, 0x0fff, + 0x0800, MEM_MAPPING_EXTERNAL); + mem_mapping_disable(&dev->bios_rom.mapping); + dev->pos_regs[0] = 0x88; + dev->pos_regs[1] = 0x80; + mca_add(ati8514_mca_read, ati8514_mca_write, ibm8514_mca_feedb, ibm8514_mca_reset, svga); + ati_eeprom_load(&mach->eeprom, "ati8514_mca.nvr", 0); + } else { + rom_init(&dev->bios_rom, + BIOS_MACH8_ROM_PATH, + 0xd0000, 0x1000, 0x0fff, + 0x0800, MEM_MAPPING_EXTERNAL); + ati_eeprom_load(&mach->eeprom, "ati8514.nvr", 0); + } + break; + } + fallthrough; + + default: + ibm8514_io_set(svga); + + if (dev->type & DEVICE_MCA) { + dev->pos_regs[0] = 0x7f; + dev->pos_regs[1] = 0xef; + mca_add(ibm8514_mca_read, ibm8514_mca_write, ibm8514_mca_feedb, ibm8514_mca_reset, svga); + } + break; + } +#else ibm8514_io_set(svga); if (dev->type & DEVICE_MCA) { dev->pos_regs[0] = 0x7f; dev->pos_regs[1] = 0xef; - mca_add(ibm8514_mca_read, ibm8514_mca_write, ibm8514_mca_feedb, NULL, svga); + mca_add(ibm8514_mca_read, ibm8514_mca_write, ibm8514_mca_feedb, ibm8514_mca_reset, svga); } +#endif return svga; } @@ -4392,6 +4441,10 @@ ibm8514_close(void *priv) { svga_t *svga = (svga_t *) priv; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + mach_t *mach = (mach_t *) svga->ext8514; + + if (mach) + free(mach); if (dev) { free(dev->vram); @@ -4417,6 +4470,34 @@ ibm8514_force_redraw(void *priv) svga->fullchange = changeframecount; } +#ifdef ATI_8514_ULTRA +// clang-format off +static const device_config_t ext8514_config[] = { + { + .name = "extensions", + .description = "Vendor", + .type = CONFIG_SELECTION, + .default_int = 0, + .selection = { + { + .description = "IBM", + .value = 0 + }, + { + .description = "ATI", + .value = 1 + }, + { + .description = "" + } + } + }, + { + .type = CONFIG_END + } +}; +#endif + // clang-format off const device_t gen8514_isa_device = { .name = "Generic 8514/A clone (ISA)", diff --git a/src/video/vid_ati68860_ramdac.c b/src/video/vid_ati68860_ramdac.c index 7cdd18019..2cb0c4c98 100644 --- a/src/video/vid_ati68860_ramdac.c +++ b/src/video/vid_ati68860_ramdac.c @@ -44,6 +44,7 @@ #include <86box/86box.h> #include <86box/device.h> #include <86box/mem.h> +#include <86box/rom.h> #include <86box/timer.h> #include <86box/video.h> #include <86box/vid_8514a.h> diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index b19f1e3d6..fb07d1548 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -13,7 +13,7 @@ * * Authors: TheCollector1995. * - * Copyright 2022-2023 TheCollector1995. + * Copyright 2022-2024 TheCollector1995. */ #include #include @@ -40,154 +40,14 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> #include <86box/vid_ati_eeprom.h> +#include <86box/vid_ati_mach8.h> -#define BIOS_MACH8_ROM_PATH "roms/video/mach8/BIOS.BIN" +#define BIOS_MACH8_VGA_ROM_PATH "roms/video/mach8/BIOS.BIN" #define BIOS_MACH32_ISA_ROM_PATH "roms/video/mach32/ATi Mach32 Graphics Pro ISA.BIN" #define BIOS_MACH32_VLB_ROM_PATH "roms/video/mach32/MACH32VLB.VBI" #define BIOS_MACH32_MCA_ROM_PATH "roms/video/mach32/MACH32MCA_Olivetti.BIN" #define BIOS_MACH32_PCI_ROM_PATH "roms/video/mach32/intelopt_00000.rom" -typedef struct mach_t { - ati_eeprom_t eeprom; - svga_t svga; - - rom_t bios_rom; - rom_t bios_rom2; - mem_mapping_t mmio_linear_mapping; - - int mca_bus; - int pci_bus; - int vlb_bus; - int has_bios; - - uint8_t regs[256]; - uint8_t pci_regs[256]; - uint8_t int_line; - uint8_t pci_slot; - uint8_t irq_state; - - int index; - int ramdac_type; - int old_mode; - - uint32_t memory; - - uint16_t config1; - uint16_t config2; - - uint8_t pos_regs[8]; - uint8_t pci_cntl_reg; - uint8_t cursor_col_0; - uint8_t cursor_col_1; - uint8_t ext_cur_col_0_r; - uint8_t ext_cur_col_1_r; - uint8_t ext_cur_col_0_g; - uint8_t ext_cur_col_1_g; - uint16_t cursor_col_0_rg; - uint16_t cursor_col_1_rg; - uint16_t cursor_col_b; - uint16_t cursor_offset_lo; - uint16_t cursor_offset_lo_reg; - uint16_t cursor_offset_hi; - uint16_t cursor_offset_hi_reg; - uint16_t cursor_vh_offset; - uint16_t cursor_x; - uint16_t cursor_y; - uint16_t misc; - uint16_t memory_aperture; - uint16_t local_cntl; - uint32_t linear_base; - uint8_t ap_size; - uint8_t bank_w; - uint8_t bank_r; - uint16_t shadow_set; - int ext_on[2]; - - struct { - uint8_t line_idx; - int16_t line_array[6]; - uint8_t patt_idx; - uint8_t patt_len; - uint8_t pix_trans[2]; - uint8_t eeprom_control; - uint16_t dest_x_end; - uint16_t dest_x_start; - uint16_t dest_y_end; - uint16_t src_x_end; - uint16_t src_x_start; - uint16_t src_x; - uint16_t src_y; - int16_t bres_count; - uint16_t clock_sel; - uint16_t crt_pitch; - uint16_t ge_pitch; - uint16_t dest_cmp_fn; - uint16_t dp_config; - uint16_t ext_ge_config; - uint16_t ge_offset_lo; - uint16_t ge_offset_hi; - uint16_t linedraw_opt; - uint16_t max_waitstates; - uint8_t patt_data_idx; - uint8_t patt_data[0x18]; - uint16_t scan_to_x; - uint16_t scratch0; - uint16_t scratch1; - uint16_t test; - uint16_t pattern; - uint16_t test2; - uint16_t test3; - uint16_t test4; - int src_y_dir; - int cmd_type; - int block_write_mono_pattern_enable; - int mono_pattern_enable; - int16_t cx_end_line; - int16_t cy_end_line; - int16_t cx; - int16_t cx_end; - int16_t cy_end; - int16_t dx; - int16_t dx_end; - int16_t dy; - int16_t dy_end; - int16_t dx_start; - int16_t dy_start; - int16_t cy; - int16_t sx_start; - int16_t sx_end; - int16_t sx; - int16_t x_count; - int16_t xx_count; - int16_t xxx_count; - int16_t sy; - int16_t y_count; - int16_t err; - int16_t width; - int16_t src_width; - int16_t height; - int16_t bleft, bright, btop, bbottom; - int poly_src; - int temp_cnt; - int stepx; - int stepy; - int src_stepx; - uint8_t color_pattern[16]; - uint8_t color_pattern_full[32]; - uint16_t color_pattern_word[8]; - int mono_pattern[8][8]; - uint32_t ge_offset; - uint32_t crt_offset; - uint32_t patt_len_reg; - int poly_fill; - uint16_t dst_clr_cmp_mask; - int clip_overrun; - int color_pattern_idx; - } accel; - - atomic_int force_busy; -} mach_t; - static video_timings_t timing_gfxultra_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 }; static video_timings_t timing_mach32_vlb = { .type = VIDEO_BUS, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; static video_timings_t timing_mach32_mca = { .type = VIDEO_MCA, .write_b = 4, .write_w = 5, .write_l = 10, .read_b = 5, .read_w = 5, .read_l = 10 }; @@ -199,7 +59,15 @@ static uint8_t mach_accel_inb(uint16_t port, void *priv); static uint16_t mach_accel_inw(uint16_t port, void *priv); static uint8_t mach_in(uint16_t addr, void *priv); -static void mach32_updatemapping(mach_t *mach); +static void ati8514_accel_outb(uint16_t port, uint8_t val, void *priv); +static void ati8514_accel_outw(uint16_t port, uint16_t val, void *priv); +static void ati8514_accel_outl(uint16_t port, uint32_t val, void *priv); +static uint8_t ati8514_accel_inb(uint16_t port, void *priv); +static uint16_t ati8514_accel_inw(uint16_t port, void *priv); +static uint32_t ati8514_accel_inl(uint16_t port, void *priv); + + +static void mach32_updatemapping(mach_t *mach, svga_t *svga); #ifdef ENABLE_MACH_LOG int mach_do_log = ENABLE_MACH_LOG; @@ -462,10 +330,8 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } if ((dev->accel_bpp == 8) || (dev->accel_bpp == 15) || (dev->accel_bpp == 16) || (dev->accel_bpp == 24)) { - if (dev->accel_bpp == 24) - mach_log("24BPP: CMDType=%d, cwh(%d,%d,%d,%d), dpconfig=%04x\n", cmd_type, clip_l, clip_r, clip_t, clip_b, mach->accel.dp_config); - else - mach_log("RdMask=%04x, Clipping: l=%d, r=%d, t=%d, b=%d, LineDrawOpt=%04x, BPP=%d, CMDType = %d, offs=%08x, DPCONFIG = %04x, cnt = %d, input = %d, mono_src = %d, frgdsel = %d, d(%d,%d), dstxend = %d, pitch = %d, extcrt = %d, rw = %x, monpattern = %x.\n", rd_mask, clip_l, clip_r, clip_t, clip_b, mach->accel.linedraw_opt, dev->accel_bpp, cmd_type, mach->accel.ge_offset, mach->accel.dp_config, count, cpu_input, mono_src, frgd_sel, dev->accel.cur_x, dev->accel.cur_y, mach->accel.dest_x_end, dev->ext_pitch, dev->ext_crt_pitch, mach->accel.dp_config & 1, mach->accel.mono_pattern_enable); + if (cpu_input && (cmd_type == 2)) + mach_log("RdMask=%04x, DPCONFIG=%04x, Clipping: l=%d, r=%d, t=%d, b=%d, LineDrawOpt=%04x, BPP=%d, CMDType = %d, offs=%08x, cnt = %d, input = %d, mono_src = %d, frgdsel = %d, d(%d,%d), dstxend = %d, pitch = %d, extcrt = %d, rw = %x, monpattern = %x.\n", rd_mask, mach->accel.dp_config, clip_l, clip_r, clip_t, clip_b, mach->accel.linedraw_opt, dev->accel_bpp, cmd_type, mach->accel.ge_offset, count, cpu_input, mono_src, frgd_sel, dev->accel.cur_x, dev->accel.cur_y, mach->accel.dest_x_end, dev->ext_pitch, dev->ext_crt_pitch, mach->accel.dp_config & 1, mach->accel.mono_pattern_enable); } switch (cmd_type) { @@ -948,10 +814,16 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (dev->accel.cur_y >= 0x600) dev->accel.dy |= ~0x5ff; + if (mach->accel.dp_config == 0x5211) { + if (mach->accel.dest_x_end == 1024) { + goto skip_dx; + } + } /*Destination Width*/ if (mach->accel.dest_x_start != dev->accel.dx) mach->accel.dest_x_start = dev->accel.dx; +skip_dx: mach->accel.dx_start = mach->accel.dest_x_start; if (mach->accel.dest_x_start >= 0x600) mach->accel.dx_start |= ~0x5ff; @@ -1336,7 +1208,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } dev->accel.sx++; - if (dev->accel.sx >= mach->accel.width) { + if ((dev->accel.sx >= mach->accel.width) || (dev->accel.dx >= 0x600)) { dev->accel.sx = 0; if (mach->accel.stepx == -1) dev->accel.dx += mach->accel.width; @@ -2156,10 +2028,9 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (mach_pixel_read(mach)) src_dat = cpu_dat; else { - READ(dev->accel.src + (dev->accel.cx), src_dat); - if (mono_src == 3) { + READ(dev->accel.src + dev->accel.cx, src_dat); + if (mono_src == 3) src_dat = (src_dat & rd_mask) == rd_mask; - } } break; case 5: @@ -2179,7 +2050,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 break; } - READ(dev->accel.dest + (dev->accel.dx), dest_dat); + READ(dev->accel.dest + dev->accel.dx, dest_dat); switch (compare_mode) { case 1: @@ -2299,7 +2170,7 @@ mach_accel_out_pixtrans(mach_t *mach, ibm8514_t *dev, uint16_t val) case 0x000: /*8-bit size*/ if (mono_src == 2) { if ((frgd_sel != 2) && (bkgd_sel != 2)) { - if ((mach->accel.dp_config & 0x1000) && ((dev->local & 0xff) >= 0x02)) + if (mach->accel.dp_config & 0x1000) val = (val >> 8) | (val << 8); mach_accel_start(mach->accel.cmd_type, 1, 8, val | (val << 16), 0, mach, dev); } else @@ -2313,12 +2184,10 @@ mach_accel_out_pixtrans(mach_t *mach, ibm8514_t *dev, uint16_t val) if (mach->accel.dp_config & 0x1000) val = (val >> 8) | (val << 8); mach_accel_start(mach->accel.cmd_type, 1, 16, val | (val << 16), 0, mach, dev); - } else { + } else mach_accel_start(mach->accel.cmd_type, 1, 2, -1, val | (val << 16), mach, dev); - } - } else { + } else mach_accel_start(mach->accel.cmd_type, 1, 2, -1, val | (val << 16), mach, dev); - } break; default: @@ -2398,7 +2267,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv) break; case 0xbd: if ((old ^ val) & 4) { - mach32_updatemapping(mach); + mach32_updatemapping(mach, svga); } break; case 0xb3: @@ -2508,6 +2377,9 @@ mach_in(uint16_t addr, void *priv) break; case 0x1cf: switch (mach->index) { + case 0xa0: + temp = mach->regs[0xa0] | 0x10; + break; case 0xa8: temp = (svga->vc >> 8) & 3; break; @@ -2516,11 +2388,10 @@ mach_in(uint16_t addr, void *priv) break; case 0xb0: temp = mach->regs[0xb0] | 0x80; + temp &= ~0x18; if ((dev->local & 0xff) >= 0x02) { /*Mach32 VGA 1MB memory*/ temp |= 0x08; - temp &= ~0x10; } else { /*ATI 28800 VGA 512kB memory*/ - temp &= ~0x08; temp |= 0x10; } break; @@ -2587,15 +2458,109 @@ mach_in(uint16_t addr, void *priv) return temp; } + +#ifdef ATI_8514_ULTRA +static void +ati8514_out(uint16_t addr, uint8_t val, void *priv) +{ + mach_log("ADDON OUT addr=%03x, val=%02x.\n", addr, val); + svga_out(addr, val, priv); +} + +static uint8_t +ati8514_in(uint16_t addr, void *priv) +{ + uint8_t temp = 0xff; + + temp = svga_in(addr, priv); + + mach_log("ADDON IN addr=%03x, temp=%02x.\n", addr, temp); + return temp; +} + +void +ati8514_recalctimings(svga_t *svga) +{ + const mach_t *mach = (mach_t *) svga->ext8514; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + mach_log("ON0=%d, ON1=%d, vgahdisp=%d.\n", dev->on[0], dev->on[1], svga->hdisp); + if (dev->on[0] || dev->on[1]) { + dev->h_disp = dev->hdisp; + dev->h_total = dev->htotal + 1; + dev->h_blankstart = dev->hblankstart; + dev->h_blank_end_val = dev->hblank_end_val; + dev->v_total = dev->vtotal + 1; + dev->v_syncstart = dev->vsyncstart + 1; + dev->rowcount = !!(dev->disp_cntl & 0x08); + dev->dispend = dev->vdisp; + + if (dev->dispend == 766) + dev->dispend += 2; + + if (dev->dispend == 598) + dev->dispend += 2; + + if (dev->accel.advfunc_cntl & 4) { + if (dev->h_disp != 800) { + dev->h_disp = 1024; + dev->dispend = 768; + } + svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; + } else { + svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + } + + if (dev->interlace) { + dev->dispend >>= 1; + dev->v_syncstart >>= 2; + dev->v_total >>= 2; + } else { + dev->v_syncstart >>= 1; + dev->v_total >>= 1; + } + + dev->pitch = dev->ext_pitch; + dev->rowoffset = dev->ext_crt_pitch; + mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, advfunc_cntl=%x, shadow=%x.\n", dev->accel.advfunc_cntl & 4, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, dev->accel.advfunc_cntl & 4, mach->shadow_set & 3); + svga->map8 = dev->pallook; + svga->render8514 = ibm8514_render_8bpp; + + dev->hblankend = (dev->h_blankstart & ~0x3f) | dev->h_blank_end_val; + if (dev->hblankend <= dev->h_blankstart) + dev->hblankend += 0x40; + + dev->hblankend += dev->hblank_ext; + + dev->hblank_sub = 0; + if (dev->hblankend > dev->h_total) { + dev->hblankend &= 0x3f; + dev->hblank_sub = dev->hblankend + 1; + + dev->h_disp -= dev->hblank_sub; + } + } else { + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ + if (svga->seqregs[1] & 8) { /*40 column*/ + svga->render = svga_render_text_40; + } else { + svga->render = svga_render_text_80; + } + } + } +} +#endif + static void mach_recalctimings(svga_t *svga) { - const mach_t *mach = (mach_t *) svga->priv; + mach_t *mach = (mach_t *) svga->priv; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; int clock_sel; if (mach->regs[0xad] & 0x08) svga->hblankstart = ((mach->regs[0x0d] >> 2) << 8) + svga->crtc[2] + 1; + clock_sel = ((svga->miscout >> 2) & 3) | ((mach->regs[0xbe] & 0x10) >> 1) | ((mach->regs[0xb9] & 2) << 1); if ((dev->local & 0xff) >= 0x02) { @@ -2640,46 +2605,35 @@ mach_recalctimings(svga_t *svga) } else svga->ati_4color = 0; } - mach_log("ON[0]=%d, ON[1]=%d, exton[0]=%d, exton[1]=%d, vendormode0=%d, vendormode1=%d.\n", dev->on[0], dev->on[1], mach->ext_on[0], mach->ext_on[1], dev->vendor_mode[0], dev->vendor_mode[1]); if (dev->on[0] || dev->on[1]) { mach_log("8514/A ON.\n"); + dev->h_disp = dev->hdisp; + dev->h_total = dev->htotal + 1; + dev->h_blankstart = dev->hblankstart; + dev->h_blank_end_val = dev->hblank_end_val; + dev->v_total = dev->vtotal + 1; + dev->v_syncstart = dev->vsyncstart + 1; + dev->dispend = dev->vdisp; + dev->rowcount = !!(dev->disp_cntl & 0x08); + + if (dev->dispend == 766) + dev->dispend += 2; + + if (dev->dispend == 598) + dev->dispend += 2; + if ((dev->local & 0xff) >= 0x02) { - dev->h_disp = (dev->hdisp + 1) << 3; - dev->h_total = (dev->htotal + 1); - dev->v_total = (dev->vtotal + 1); - dev->v_syncstart = (dev->vsyncstart + 1); - dev->dispend = ((dev->vdisp >> 1) + 1); - dev->rowcount = !!(dev->disp_cntl & 0x08); - - if (dev->dispend == 766) - dev->dispend += 2; - - if (dev->dispend == 598) - dev->dispend += 2; - - if (dev->accel.advfunc_cntl & 4) { - if (mach->shadow_set & 2) { - if ((dev->h_disp == 8) && !dev->bpp) { - dev->h_disp = 1024; - dev->dispend = 768; - dev->v_total = 1536; - dev->v_syncstart = 1536; - } - mach_log("Shadow set 2.\n"); + if ((dev->accel.advfunc_cntl ^ dev->modechange) & 0x04) { + if ((mach->shadow_set ^ mach->compat_mode) & 0x03) + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + else svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; - } else - svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); } else { - if ((dev->h_disp == 1024) && !dev->bpp) { - dev->h_disp = 640; - dev->dispend = 480; - } - if (mach->shadow_set & 1) { - mach_log("Shadow set 1.\n"); - svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; - } else + if ((mach->shadow_set ^ mach->compat_mode) & 0x03) svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + else + svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; } if (dev->interlace) { @@ -2690,6 +2644,7 @@ mach_recalctimings(svga_t *svga) dev->v_syncstart >>= 1; dev->v_total >>= 1; } + dev->pitch = dev->ext_pitch; dev->rowoffset = dev->ext_crt_pitch; if ((mach->accel.ext_ge_config & 0x800) || (!(mach->accel.ext_ge_config & 0x8000) && !(mach->accel.ext_ge_config & 0x800))) { @@ -2706,7 +2661,7 @@ mach_recalctimings(svga_t *svga) } else dev->accel_bpp = 8; - mach_log("hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, bpp=%d.\n", dev->h_disp, dev->dispend, dev->pitch, dev->ext_crt_pitch, mach->accel.ext_ge_config & 0xcec0, dev->accel_bpp); + mach_log("hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, bpp=%d, shadow=%x, vgahdisp=%d.\n", dev->h_disp, dev->dispend, dev->pitch, dev->ext_crt_pitch, mach->accel.ext_ge_config & 0xcec0, dev->accel_bpp, mach->shadow_set & 3, svga->hdisp); switch (dev->accel_bpp) { case 8: svga->render8514 = ibm8514_render_8bpp; @@ -2751,40 +2706,23 @@ mach_recalctimings(svga_t *svga) break; } } else { - dev->h_disp = (dev->hdisp + 1) << 3; - dev->h_total = (dev->htotal + 1); - dev->v_total = (dev->vtotal + 1); - dev->v_syncstart = (dev->vsyncstart + 1); - dev->rowcount = !!(dev->disp_cntl & 0x08); - dev->dispend = ((dev->vdisp >> 1) + 1); - - if (dev->dispend == 766) - dev->dispend += 2; - - if (dev->dispend == 598) - dev->dispend += 2; - - if (dev->accel.advfunc_cntl & 4) { - if (mach->shadow_set & 2) { - if (dev->h_disp == 8) { - dev->h_disp = 1024; - dev->dispend = 768; - dev->v_total = 1536; - dev->v_syncstart = 1536; - } - svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; - } else + if ((dev->accel.advfunc_cntl ^ dev->modechange) & 0x04) { + if ((mach->shadow_set ^ mach->compat_mode) & 0x03) svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + else + svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; } else { - if (dev->h_disp == 1024) { + if ((mach->shadow_set ^ mach->compat_mode) & 0x03) + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + else + svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + + if (((mach->shadow_set & 0x03) != 0x02) || !(dev->accel.advfunc_cntl & 0x04)) { /*Shadow set of 2 and bit 2 of port 0x4ae8 mean 1024x768+*/ dev->h_disp = 640; dev->dispend = 480; } - if (mach->shadow_set & 1) { - svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; - } else - svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); } + if (dev->interlace) { dev->dispend >>= 1; dev->v_syncstart >>= 2; @@ -2793,14 +2731,29 @@ mach_recalctimings(svga_t *svga) dev->v_syncstart >>= 1; dev->v_total >>= 1; } + dev->pitch = dev->ext_pitch; dev->rowoffset = dev->ext_crt_pitch; - mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x.\n", dev->accel.advfunc_cntl & 4, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0); + mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x.\n", dev->accel.advfunc_cntl & 4, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3); svga->map8 = dev->pallook; svga->render8514 = ibm8514_render_8bpp; if (mach->regs[0xb8] & 0x40) svga->clock *= 2; } + + dev->hblankend = (dev->h_blankstart & ~0x3f) | dev->h_blank_end_val; + if (dev->hblankend <= dev->h_blankstart) + dev->hblankend += 0x40; + + dev->hblankend += dev->hblank_ext; + + dev->hblank_sub = 0; + if (dev->hblankend > dev->h_total) { + dev->hblankend &= 0x3f; + dev->hblank_sub = dev->hblankend + 1; + + dev->h_disp -= dev->hblank_sub; + } } if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { @@ -2862,24 +2815,23 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0x82e8: case 0xc2e8: case 0xf6ee: - if (len == 1) { + if (len == 1) dev->accel.cur_y = (dev->accel.cur_y & 0x700) | val; - } else + else dev->accel.cur_y = val & 0x7ff; break; case 0x82e9: case 0xc2e9: case 0xf6ef: - if (len == 1) { + if (len == 1) dev->accel.cur_y = (dev->accel.cur_y & 0xff) | ((val & 0x07) << 8); - } break; case 0x86e8: case 0xc6e8: - if (len == 1) { + if (len == 1) dev->accel.cur_x = (dev->accel.cur_x & 0x700) | val; - } else + else dev->accel.cur_x = val & 0x7ff; break; case 0x86e9: @@ -3284,24 +3236,22 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u else { dev->accel.multifunc_cntl = val; dev->accel.multifunc[dev->accel.multifunc_cntl >> 12] = dev->accel.multifunc_cntl & 0xfff; - if ((dev->accel.multifunc_cntl >> 12) == 1) { + if ((dev->accel.multifunc_cntl >> 12) == 1) dev->accel.clip_top = val & 0x7ff; - } - if ((dev->accel.multifunc_cntl >> 12) == 2) { + + if ((dev->accel.multifunc_cntl >> 12) == 2) dev->accel.clip_left = val & 0x7ff; - } - if ((dev->accel.multifunc_cntl >> 12) == 3) { + + if ((dev->accel.multifunc_cntl >> 12) == 3) dev->accel.multifunc[3] = val & 0x7ff; - } - if ((dev->accel.multifunc_cntl >> 12) == 4) { + + if ((dev->accel.multifunc_cntl >> 12) == 4) dev->accel.multifunc[4] = val & 0x7ff; - } + mach_log("CLIPBOTTOM=%d, CLIPRIGHT=%d, bpp=%d, pitch=%d.\n", dev->accel.multifunc[3], dev->accel.multifunc[4], dev->accel_bpp, dev->pitch); if ((dev->accel.multifunc_cntl >> 12) == 5) { - if (dev->local < 2) + if ((dev->local & 0xff) < 0x02) dev->ext_crt_pitch = 128; - - svga_recalctimings(svga); } if (port == 0xfee8) dev->accel.cmd_back = 1; @@ -3314,17 +3264,15 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u if (len == 1) { dev->accel.multifunc_cntl = (dev->accel.multifunc_cntl & 0xff) | (val << 8); dev->accel.multifunc[dev->accel.multifunc_cntl >> 12] = dev->accel.multifunc_cntl & 0xfff; - if ((dev->accel.multifunc_cntl >> 12) == 1) { + if ((dev->accel.multifunc_cntl >> 12) == 1) dev->accel.clip_top = dev->accel.multifunc_cntl & 0x7ff; - } - if ((dev->accel.multifunc_cntl >> 12) == 2) { - dev->accel.clip_left = dev->accel.multifunc_cntl & 0x7ff; - } - if ((dev->accel.multifunc_cntl >> 12) == 5) { - if (dev->local < 2) - dev->ext_crt_pitch = 128; - svga_recalctimings(svga); + if ((dev->accel.multifunc_cntl >> 12) == 2) + dev->accel.clip_left = dev->accel.multifunc_cntl & 0x7ff; + + if ((dev->accel.multifunc_cntl >> 12) == 5) { + if ((dev->local & 0xff) < 0x02) + dev->ext_crt_pitch = 128; } if (port == 0xfee9) dev->accel.cmd_back = 1; @@ -3680,80 +3628,83 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u } static void -mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) +mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8514_t *dev) { - svga_t *svga = &mach->svga; - ibm8514_t *dev = (ibm8514_t *) svga->dev8514; uint8_t old = 0; - mach_log("[%04X:%08X]: Port NORMAL OUT=%04x, val=%04x.\n", CS, cpu_state.pc, port, val); + if (port != 0x7aee && port != 0x7aef && port != 0x42e8 && port != 0x42e9 && port != 0x46e8 && port != 0x46e9) + mach_log("[%04X:%08X]: Port CALL OUT=%04x, val=%02x.\n", CS, cpu_state.pc, port, val); switch (port) { case 0x2e8: case 0x2e9: WRITE8(port, dev->htotal, val); - svga_recalctimings(svga); break; + case 0x6e8: case 0x6e9: if (!(port & 1)) { - if ((dev->vendor_mode[0] || dev->vendor_mode[1]) && ((mach->shadow_set & 3) == 0)) - dev->hdisp = val; - else if (!dev->on[0] || !dev->on[1]) - dev->hdisp = val; - - mach_log("ATI 8514/A: H_DISP write 06E8 = %d\n", dev->hdisp + 1); + if (((dev->disp_cntl & 0x60) == 0x20) || (mach->accel.clock_sel & 0x01)) { + dev->hdisped = val; + dev->hdisp = (dev->hdisped + 1) << 3; + } } - svga_recalctimings(svga); + mach_log("[%04X:%08X]: ATI 8514/A: H_DISP write 06E8 = %d, actual val=%d, set lock=%x, shadow set=%x, advfunc=%x, dispcntl=%02x.\n", CS, cpu_state.pc, dev->hdisp, ((val + 1) << 3), mach->shadow_cntl, mach->shadow_set, dev->accel.advfunc_cntl & 4, dev->disp_cntl & 0x60); break; case 0xae8: + case 0xae9: + if (!(port & 1)) { + dev->hsync_start = val; + dev->hblankstart = (dev->hsync_start & 0x07) + 1; + } mach_log("ATI 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); - svga_recalctimings(svga); break; case 0xee8: + case 0xee9: + if (!(port & 1)) { + dev->hsync_width = val; + dev->hblank_end_val = (dev->hblankstart + (dev->hsync_start & 0x1f) - 1) & 0x3f; + } mach_log("ATI 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); - svga_recalctimings(svga); break; case 0x12e8: case 0x12e9: WRITE8(port, dev->vtotal, val); dev->vtotal &= 0x1fff; - svga_recalctimings(svga); break; case 0x16e8: case 0x16e9: - if ((dev->vendor_mode[0] || dev->vendor_mode[1]) && ((mach->shadow_set & 3) == 0)) { - WRITE8(port, dev->vdisp, val); - } else if (!dev->on[0] || !dev->on[1]) { - WRITE8(port, dev->vdisp, val); + if (((dev->disp_cntl & 0x60) == 0x20) || (mach->accel.clock_sel & 0x01)) { + WRITE8(port, dev->v_disp, val); + dev->v_disp &= 0x1fff; + dev->vdisp = dev->v_disp; + dev->vdisp >>= 1; + dev->vdisp++; } - dev->vdisp &= 0x1fff; - mach_log("ATI 8514/A: V_DISP write 16E8 = %d\n", (dev->vdisp >> 1) + 1); - svga_recalctimings(svga); + dev->modechange = dev->accel.advfunc_cntl & 4; + mach->compat_mode = mach->shadow_set & 3; + mach_log("ATI 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp); break; case 0x1ae8: case 0x1ae9: WRITE8(port, dev->vsyncstart, val); dev->vsyncstart &= 0x1fff; - svga_recalctimings(svga); break; case 0x1ee8: case 0x1ee9: mach_log("ATI 8514/A: V_SYNC_WID write 1EE8 = %02x\n", val); - svga_recalctimings(svga); break; case 0x22e8: dev->disp_cntl = val & 0x7e; dev->interlace = !!(val & 0x10); - svga_recalctimings(svga); - mach_log("ATI 8514/A: DISP_CNTL write 22E8 = %02x, SCANMODULOS = %d\n", dev->disp_cntl, dev->scanmodulos); + mach_log("ATI 8514/A: DISP_CNTL write 22E8 = %02x, interlace = %d\n", dev->disp_cntl, dev->interlace); break; case 0x42e8: @@ -3782,16 +3733,16 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x4ae8: case 0x4ae9: - if (dev->local < 2) + WRITE8(port, dev->accel.advfunc_cntl, val); + dev->on[port & 1] = dev->accel.advfunc_cntl & 0x01; + if ((dev->local & 0xff) < 0x02) dev->ext_crt_pitch = 128; - WRITE8(port, dev->accel.advfunc_cntl, val); - dev->on[port & 1] = (dev->accel.advfunc_cntl & 0x01); - mach_log("ATI 8514/A: (0x%04x): ON=%d.\n", port, dev->on[port & 1]); vga_on = !dev->on[port & 1]; mach->ext_on[port & 1] = dev->on[port & 1]; - mach32_updatemapping(mach); + mach32_updatemapping(mach, svga); dev->vendor_mode[port & 1] = 0; + mach_log("ATI 8514/A: (0x%04x): ON=%d, shadow crt=%x.\n", port, dev->on[port & 1], dev->accel.advfunc_cntl & 4); svga_recalctimings(svga); break; @@ -3853,7 +3804,7 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x22ee: if (mach->pci_bus) { mach->pci_cntl_reg = val; - mach32_updatemapping(mach); + mach32_updatemapping(mach, svga); } break; @@ -3876,7 +3827,7 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x32ee: case 0x32ef: WRITE8(port, mach->local_cntl, val); - mach32_updatemapping(mach); + mach32_updatemapping(mach, svga); break; case 0x36ee: @@ -3902,12 +3853,14 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x42ee: case 0x42ef: + mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); WRITE8(port, mach->accel.test2, val); break; case 0x46ee: case 0x46ef: - WRITE8(port, mach->accel.test3, val); + mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); + WRITE8(port, mach->shadow_cntl, val); break; case 0x4aee: @@ -3935,10 +3888,10 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x5aee: case 0x5aef: - WRITE8(port, mach->shadow_set, val); - mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); - if (mach->shadow_set & 3) - svga_recalctimings(svga); + if (!(mach->shadow_cntl & 0x3f)) { + WRITE8(port, mach->shadow_set, val); + mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); + } break; case 0x5eee: @@ -3948,7 +3901,7 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) if (!mach->pci_bus) mach->linear_base = (mach->memory_aperture & 0xff00) << 12; - mach32_updatemapping(mach); + mach32_updatemapping(mach, svga); break; case 0x62ee: @@ -3980,7 +3933,7 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x76ef: WRITE8(port, mach->accel.ge_pitch, val); dev->ext_pitch = ((mach->accel.ge_pitch & 0xff) << 3); - mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); + mach_log("ATI 8514/A: (0x%04x) val = %04x, extpitch = %d.\n", port, val, dev->ext_pitch); svga_recalctimings(svga); break; @@ -4012,16 +3965,19 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) } svga_set_ramdac_type(svga, !!(mach->accel.ext_ge_config & 0x4000)); dev->vendor_mode[port & 1] = 1; - mach32_updatemapping(mach); + mach32_updatemapping(mach, svga); + mach_log("ATI 8514/A: (0x%04x) val = %02x.\n", port, val); + svga_recalctimings(svga); + } else { + if (mach->accel.ext_ge_config & 0x8080) + ati_eeprom_write(&mach->eeprom, mach->accel.ext_ge_config & 0x4040, mach->accel.ext_ge_config & 0x2020, mach->accel.ext_ge_config & 0x1010); } - mach_log("ATI 8514/A: (0x%04x) val = %02x.\n", port, val); - svga_recalctimings(svga); break; case 0x7eee: case 0x7eef: WRITE8(port, mach->accel.eeprom_control, val); - ati_eeprom_write(&mach->eeprom, mach->accel.eeprom_control & 4, mach->accel.eeprom_control & 2, mach->accel.eeprom_control & 1); + ati_eeprom_write(&mach->eeprom, mach->accel.eeprom_control & 8, mach->accel.eeprom_control & 2, mach->accel.eeprom_control & 1); mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); break; @@ -4030,6 +3986,17 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) } } +static void +mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) +{ + svga_t *svga = &mach->svga; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + mach_log("[%04X:%08X]: Port NORMAL OUT=%04x, val=%04x.\n", CS, cpu_state.pc, port, val); + + mach_accel_out_call(port, val, mach, svga, (ibm8514_t *) svga->dev8514); +} + static uint16_t mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, int len) { @@ -4043,28 +4010,24 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in switch (port) { case 0x82e8: case 0xc2e8: - if (len != 1) { + if (len != 1) temp = dev->accel.cur_y; - } break; case 0x86e8: case 0xc6e8: - if (len != 1) { + if (len != 1) temp = dev->accel.cur_x; - } break; case 0x92e8: - if (len != 1) { + if (len != 1) temp = dev->test; - } break; case 0x96e8: - if (len != 1) { + if (len != 1) temp = dev->accel.maj_axis_pcnt; - } break; case 0x9ae8: @@ -4287,9 +4250,9 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in break; case 0x96ee: - if (len == 1) { + if (len == 1) temp = dev->accel.maj_axis_pcnt & 0xff; - } else { + else { temp = dev->accel.maj_axis_pcnt; if ((mach->accel.test == 0x1555) || (mach->accel.test == 0x0aaa)) temp = mach->accel.test; @@ -4303,9 +4266,8 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in case 0xa2ee: if (len == 1) temp = mach->accel.linedraw_opt & 0xff; - else { + else temp = mach->accel.linedraw_opt; - } break; case 0xa2ef: if (len == 1) @@ -4314,17 +4276,23 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in case 0xb2ee: if (len == 1) - temp = dev->hdisp; + temp = dev->hdisped; else { - temp = dev->hdisp & 0xff; + temp = dev->hdisped & 0xff; temp |= (dev->htotal << 8); - mach_log("HDISP read=%d, HTOTAL read=%d.\n", temp & 0xff, temp >> 8); } break; case 0xb2ef: - if (len == 1) { + if (len == 1) temp = dev->htotal; - } + break; + + case 0xb6ee: + temp = dev->hsync_start; + break; + + case 0xbaee: + temp = dev->hsync_width; break; case 0xc2ee: @@ -4342,15 +4310,15 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in case 0xc6ee: if (len == 1) - temp = dev->vdisp & 0xff; + temp = dev->v_disp & 0xff; else { - temp = dev->vdisp; + temp = dev->v_disp; mach_log("VDISP read=%d.\n", temp); } break; case 0xc6ef: if (len == 1) - temp = dev->vdisp >> 8; + temp = dev->v_disp >> 8; break; case 0xcaee: @@ -4428,15 +4396,14 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in } mach_log("[%04X:%08X]: Port FIFO IN=%04x, temp=%04x, len=%d.\n", CS, cpu_state.pc, port, temp, len); + return temp; } static uint8_t -mach_accel_in(uint16_t port, mach_t *mach) +mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) { - svga_t *svga = &mach->svga; - ibm8514_t *dev = (ibm8514_t *) svga->dev8514; - uint8_t temp = 0; + uint8_t temp = 0; uint16_t vpos = 0; uint16_t vblankend = svga->vblankstart + svga->crtc[0x16]; @@ -4448,13 +4415,13 @@ mach_accel_in(uint16_t port, mach_t *mach) if ((vpos >= svga->vblankstart) || (vpos <= vblankend)) temp |= 2; } else { - if ((vpos >= svga->vblankstart) && (vpos <= vblankend)) + if ((vpos >= svga->vblankstart) && (vpos <= vblankend)) temp |= 2; } break; case 0x6e8: - temp = dev->hdisp; + temp = dev->hdisped; break; case 0x22e8: @@ -4476,26 +4443,25 @@ mach_accel_in(uint16_t port, mach_t *mach) case 0x42e8: case 0x42e9: vpos = dev->vc & 0x7ff; - if (!(dev->subsys_stat & 1)) { - if (vblankend > dev->v_total) { - vblankend -= dev->v_total; - if ((vpos >= svga->vblankstart) || (vpos <= vblankend)) - dev->subsys_stat |= 1; - } else { - if ((vpos >= svga->vblankstart) && (vpos <= vblankend)) - dev->subsys_stat |= 1; - } + if (vblankend > dev->v_total) { + vblankend -= dev->v_total; + if ((vpos >= svga->vblankstart) || (vpos <= vblankend)) + dev->subsys_stat |= 1; + } else { + if ((vpos >= svga->vblankstart) && (vpos <= vblankend)) + dev->subsys_stat |= 1; } - if (port & 1) { + if (port & 1) temp = 0x80; - } else { + else { temp = dev->subsys_stat | 0x80; - if (mach->accel.ext_ge_config & 0x08) { + if (mach->accel.ext_ge_config & 0x08) temp |= ((mach->accel.ext_ge_config & 0x07) << 4); - } else + else temp |= 0x20; } + mach_log("Subsystem Status=%04x, 4ae8 shadow set=%02x.\n", temp, dev->accel.advfunc_cntl & 4); break; /*ATI Mach8/32 specific registers*/ @@ -4510,9 +4476,8 @@ mach_accel_in(uint16_t port, mach_t *mach) break; case 0x22ee: - if (mach->pci_bus) { + if (mach->pci_bus) temp = mach->pci_cntl_reg; - } break; case 0x32ee: @@ -4525,10 +4490,8 @@ mach_accel_in(uint16_t port, mach_t *mach) READ8(port, mach->misc); if (!(port & 1)) { + temp &= ~0x0c; switch (mach->memory) { - case 512: - temp &= ~0x0c; - break; case 1024: temp |= 0x04; break; @@ -4540,6 +4503,8 @@ mach_accel_in(uint16_t port, mach_t *mach) break; default: + if ((dev->local & 0xff) < 0x02) + temp |= 0x04; break; } } @@ -4552,7 +4517,7 @@ mach_accel_in(uint16_t port, mach_t *mach) case 0x46ee: case 0x46ef: - READ8(port, mach->accel.test3); + READ8(port, mach->shadow_cntl); break; case 0x4aee: @@ -4563,6 +4528,23 @@ mach_accel_in(uint16_t port, mach_t *mach) case 0x52ee: case 0x52ef: READ8(port, mach->accel.scratch0); +#ifdef ATI_8514_ULTRA + if (mach->mca_bus) { + if (!(port & 1)) { + if (svga->ext8514 != NULL) + temp = dev->pos_regs[4]; + } else { + if (svga->ext8514 != NULL) + temp = dev->pos_regs[5]; + } + } else { + if (!(port & 1)) { + if (svga->ext8514 != NULL) { + temp = 0x20 | 0x80; + } + } + } +#endif break; case 0x56ee: @@ -4620,10 +4602,65 @@ mach_accel_in(uint16_t port, mach_t *mach) default: break; } - mach_log("[%04X:%08X]: Port NORMAL IN=%04x, temp=%04x.\n", CS, cpu_state.pc, port, temp); + if (port != 0x62ee && port != 0x62ef && port != 0x42e8 && port != 0x42e9) + mach_log("[%04X:%08X]: Port NORMAL IN=%04x, temp=%04x.\n", CS, cpu_state.pc, port, temp); + return temp; } +#ifdef ATI_8514_ULTRA +static void +ati8514_accel_out(uint16_t port, uint8_t val, svga_t *svga) +{ + mach_log("[%04X:%08X]: Port NORMAL OUT=%04x, val=%04x.\n", CS, cpu_state.pc, port, val); + + mach_accel_out_call(port, val, (mach_t *)svga->ext8514, svga, (ibm8514_t *) svga->dev8514); +} + +static void +ati8514_accel_outb(uint16_t port, uint8_t val, void *priv) +{ + svga_t *svga = (svga_t *)priv; + mach_t *mach = (mach_t *)svga->ext8514; + + if (port & 0x8000) + mach_accel_out_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port, val, 1); + else + ati8514_accel_out(port, val, svga); +} + +static void +ati8514_accel_outw(uint16_t port, uint16_t val, void *priv) +{ + svga_t *svga = (svga_t *)priv; + mach_t *mach = (mach_t *)svga->ext8514; + + if (port & 0x8000) + mach_accel_out_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port, val, 2); + else { + ati8514_accel_out(port, val, svga); + ati8514_accel_out(port + 1, (val >> 8), svga); + } +} + +static void +ati8514_accel_outl(uint16_t port, uint32_t val, void *priv) +{ + svga_t *svga = (svga_t *)priv; + mach_t *mach = (mach_t *)svga->ext8514; + + if (port & 0x8000) { + mach_accel_out_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port, val & 0xffff, 2); + mach_accel_out_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port + 2, val >> 16, 2); + } else { + ati8514_accel_out(port, val, svga); + ati8514_accel_out(port + 1, (val >> 8), svga); + ati8514_accel_out(port + 2, (val >> 16), svga); + ati8514_accel_out(port + 3, (val >> 24), svga); + } +} +#endif + static void mach_accel_outb(uint16_t port, uint8_t val, void *priv) { @@ -4666,6 +4703,72 @@ mach_accel_outl(uint16_t port, uint32_t val, void *priv) mach_accel_out(port + 3, (val >> 24), mach); } } + +#ifdef ATI_8514_ULTRA +static uint8_t +ati8514_accel_in(uint16_t port, svga_t *svga) +{ + return mach_accel_in_call(port, (mach_t *) svga->ext8514, svga, (ibm8514_t *) svga->dev8514); +} + +static uint8_t +ati8514_accel_inb(uint16_t port, void *priv) +{ + svga_t *svga = (svga_t *)priv; + mach_t *mach = (mach_t *)svga->ext8514; + uint8_t temp; + + if (port & 0x8000) + temp = mach_accel_in_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port, 1); + else + temp = ati8514_accel_in(port, svga); + + return temp; +} + +static uint16_t +ati8514_accel_inw(uint16_t port, void *priv) +{ + svga_t *svga = (svga_t *)priv; + mach_t *mach = (mach_t *)svga->ext8514; + uint16_t temp; + + if (port & 0x8000) + temp = mach_accel_in_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port, 2); + else { + temp = ati8514_accel_in(port, svga); + temp |= (ati8514_accel_in(port + 1, svga) << 8); + } + return temp; +} + +static uint32_t +ati8514_accel_inl(uint16_t port, void *priv) +{ + svga_t *svga = (svga_t *)priv; + mach_t *mach = (mach_t *)svga->ext8514; + uint32_t temp; + + if (port & 0x8000) { + temp = mach_accel_in_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port, 2); + temp = (mach_accel_in_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port + 2, 2) << 16); + } else { + temp = ati8514_accel_in(port, svga); + temp |= (ati8514_accel_in(port + 1, svga) << 8); + temp |= (ati8514_accel_in(port + 2, svga) << 16); + temp |= (ati8514_accel_in(port + 3, svga) << 24); + } + return temp; +} +#endif + +static uint8_t +mach_accel_in(uint16_t port, mach_t *mach) +{ + svga_t *svga = &mach->svga; + return mach_accel_in_call(port, mach, svga, (ibm8514_t *) svga->dev8514); +} + static uint8_t mach_accel_inb(uint16_t port, void *priv) { @@ -5212,9 +5315,8 @@ mach32_ap_readl(uint32_t addr, void *priv) } static void -mach32_updatemapping(mach_t *mach) +mach32_updatemapping(mach_t *mach, svga_t *svga) { - svga_t *svga = &mach->svga; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; if (mach->pci_bus && (!(mach->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))) { @@ -5349,119 +5451,120 @@ mach32_hwcursor_draw(svga_t *svga, int displine) dev->hwcursor_latch.addr += 16; } -#if 0 +#ifdef ATI_8514_ULTRA static void -mach_io_remove(mach_t *mach) +ati8514_io_set(svga_t *svga) { - io_removehandler(0x2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x12e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x16e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x1ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x1ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x22e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x26e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x2ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x42e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x4ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x52e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x56e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x5ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x5ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x82e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x86e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x8ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x8ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x92e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x96e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x9ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x9ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xa2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xa6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xaae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xaee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xb2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xb6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xbae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xbee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xe2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x2e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x6e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x12e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x16e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x1ae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x1ee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x22e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x26e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x2ee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x42e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x4ae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x52e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x56e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x5ae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x5ee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x82e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x86e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x8ae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x8ee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x92e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x96e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x9ae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x9ee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xa2e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xa6e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xaae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xaee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xb2e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xb6e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xbae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xbee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xe2e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); - io_removehandler(0xc2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xc6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xcae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xcee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xd2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xd6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xdae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xdee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xe6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xeae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xeee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xf2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xf6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xfae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xfee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xc2e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xc6e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xcae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xcee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xd2e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xd6e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xdae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xdee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xe6e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xeae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xeee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xf2e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xf6e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xfae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xfee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); - io_removehandler(0x02ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x06ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x0aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x0eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x12ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x16ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x1aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x1eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x22ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x26ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x2aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x2eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x32ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x36ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x3aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x3eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x42ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x46ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x4aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x52ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x56ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x5aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x5eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x62ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x66ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x6aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x6eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x72ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x76ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x7aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x7eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x82ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x8eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x92ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x96ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x9aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xa2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xa6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xaaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xaeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xb2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xb6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xbaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xbeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xc2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xc6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xcaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xceee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xd2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xd6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xdaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xdeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xe2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xe6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xeeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xf2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xfaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xfeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x02ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x06ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x0aee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x0eee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x12ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x16ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x1aee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x1eee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x22ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x26ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x2aee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x2eee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x32ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x36ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x3aee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x3eee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x42ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x46ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x4aee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x52ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x56ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x5aee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x5eee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x62ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x66ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x6aee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x6eee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x72ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x76ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x7aee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x7eee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x82ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x86ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x8eee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x92ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x96ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x9aee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xa2ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xa6ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xaaee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xaeee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xb2ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xb6ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xbaee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xbeee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xc2ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xc6ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xcaee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xceee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xd2ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xd6ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xdaee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xdeee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xe2ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xe6ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xeeee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xf2ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xf6ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xfeee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); } #endif @@ -5577,7 +5680,6 @@ mach_io_set(mach_t *mach) io_sethandler(0xeeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0xf2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0xf6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_sethandler(0xfaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0xfeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); } @@ -5633,6 +5735,34 @@ mach_mca_reset(void *priv) mach_mca_write(0x102, 0, mach); } +#ifdef ATI_8514_ULTRA +uint8_t +ati8514_mca_read(int port, void *priv) +{ + const svga_t *svga = (svga_t *) priv; + const ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + return (dev->pos_regs[port & 7]); +} + +void +ati8514_mca_write(int port, uint8_t val, void *priv) +{ + svga_t *svga = (svga_t *) priv; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + if (port < 0x102) + return; + + dev->pos_regs[port & 7] = val; + mach_log("[%04X]: MCA write port = %x, val = %02x, biosaddr = %05x.\n", CS, port & 7, dev->pos_regs[port & 7], (((dev->pos_regs[3] & 0x3e) << 0x0c) >> 1) + 0xc0000); + mem_mapping_disable(&dev->bios_rom.mapping); + + if (dev->pos_regs[2] & 0x01) + mem_mapping_enable(&dev->bios_rom.mapping); +} +#endif + static uint8_t mach32_pci_read(UNUSED(int func), int addr, void *priv) { @@ -5728,19 +5858,19 @@ mach32_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) io_sethandler(0x02ea, 4, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); io_sethandler(0x03c0, 32, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); } else { - io_removehandler(0x03c0, 32, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); io_removehandler(0x02ea, 4, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + io_removehandler(0x03c0, 32, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); } - mach32_updatemapping(mach); + mach32_updatemapping(mach, &mach->svga); break; case 0x12: mach->linear_base = (mach->linear_base & 0xff000000) | ((val & 0xc0) << 16); - mach32_updatemapping(mach); + mach32_updatemapping(mach, &mach->svga); break; case 0x13: mach->linear_base = (mach->linear_base & 0xc00000) | (val << 24); - mach32_updatemapping(mach); + mach32_updatemapping(mach, &mach->svga); break; case 0x30: @@ -5818,12 +5948,11 @@ mach8_init(const device_t *info) 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); } - } else { + } else rom_init(&mach->bios_rom, - BIOS_MACH8_ROM_PATH, + BIOS_MACH8_VGA_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - } if ((dev->local & 0xff) >= 0x02) { svga_init(info, svga, mach, mach->memory << 10, /*default: 2MB for Mach32*/ @@ -5884,7 +6013,7 @@ mach8_init(const device_t *info) dev->changedvram = calloc(dev->vram_size >> 12, 1); dev->vram_mask = dev->vram_size - 1; video_inform(VIDEO_FLAG_TYPE_8514, &timing_gfxultra_isa); - mach->config1 = 0x02 | 0x20 | 0x80; + mach->config1 = 0x01 | 0x02 | 0x20 | 0x08 | 0x80; mach->config2 = 0x02; svga->clock_gen = device_add(&ati18810_device); } @@ -5911,6 +6040,7 @@ mach8_init(const device_t *info) mach->cursor_col_1 = 0xff; mach->ext_cur_col_1_r = 0xff; mach->ext_cur_col_1_g = 0xff; + io_sethandler(0xfaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); if (mach->vlb_bus) ati_eeprom_load(&mach->eeprom, "mach32_vlb.nvr", 1); else if (mach->mca_bus) { @@ -5927,23 +6057,52 @@ mach8_init(const device_t *info) pci_add_card(PCI_ADD_NORMAL, mach32_pci_read, mach32_pci_write, mach, &mach->pci_slot); } else pci_add_card(PCI_ADD_VIDEO, mach32_pci_read, mach32_pci_write, mach, &mach->pci_slot); + mach->pci_regs[PCI_REG_COMMAND] = 0x83; mach->pci_regs[0x30] = 0x00; mach->pci_regs[0x32] = 0x0c; mach->pci_regs[0x33] = 0x00; } else ati_eeprom_load(&mach->eeprom, "mach32.nvr", 1); - } else { + } else ati_eeprom_load_mach8(&mach->eeprom, "mach8.nvr"); - } return mach; } -static int -mach8_available(void) +#ifdef ATI_8514_ULTRA +void +ati8514_init(svga_t *svga, void *ext8514, void *dev8514) { - return rom_present(BIOS_MACH8_ROM_PATH); + mach_t *mach = (mach_t *)ext8514; + ibm8514_t *dev = (ibm8514_t *)dev8514; + + dev->on[0] = 0; + dev->on[1] = 0; + dev->ext_pitch = 1024; + dev->ext_crt_pitch = 0x80; + dev->accel_bpp = 8; + dev->rowoffset = 0x80; + dev->hdisp = 1024; + dev->vdisp = 768; + + io_sethandler(0x02ea, 4, ati8514_in, NULL, NULL, ati8514_out, NULL, NULL, svga); + ati8514_io_set(svga); + mach->mca_bus = !!(dev->type & DEVICE_MCA); + + if (mach->mca_bus) + mach->config1 = 0x02 | 0x04 | 0x08 | 0x20 | 0x80; + else + mach->config1 = 0x02 | 0x08 | 0x20 | 0x80; + + mach->config2 = 0x01 | 0x02; +} +#endif + +static int +mach8_vga_available(void) +{ + return rom_present(BIOS_MACH8_VGA_ROM_PATH); } static int @@ -6093,15 +6252,15 @@ static const device_config_t mach32_pci_config[] = { } }; -const device_t mach8_isa_device = { - .name = "ATI Mach8 (ISA)", - .internal_name = "mach8_isa", +const device_t mach8_vga_isa_device = { + .name = "ATI Mach8 (ATI Graphics Ultra) (ISA)", + .internal_name = "mach8_vga_isa", .flags = DEVICE_ISA, .local = 1, .init = mach8_init, .close = mach_close, .reset = NULL, - { .available = mach8_available }, + { .available = mach8_vga_available }, .speed_changed = mach_speed_changed, .force_redraw = mach_force_redraw, .config = NULL diff --git a/src/video/vid_table.c b/src/video/vid_table.c index cec106373..bb30fa685 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -80,7 +80,7 @@ video_cards[] = { { &vid_none_device }, { &vid_internal_device }, { &atiega800p_device }, - { &mach8_isa_device, VIDEO_FLAG_TYPE_8514 }, + { &mach8_vga_isa_device, VIDEO_FLAG_TYPE_8514 }, { &mach32_isa_device, VIDEO_FLAG_TYPE_8514 }, { &mach64gx_isa_device }, { &ati28800k_device }, From 3599d2bed167369e0bb4ee48d20e9148ab13e8a0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 15 Jan 2024 21:46:12 +0100 Subject: [PATCH 304/936] Make sure all CPU's with 16-bit bus default to slow PIT. --- src/machine/machine.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/machine/machine.c b/src/machine/machine.c index 1684f312a..9e530eb3b 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -169,6 +169,7 @@ void machine_common_init(UNUSED(const machine_t *model)) { uint8_t cpu_requires_fast_pit = is486 || (!is286 && is8086 && (cpu_s->rspeed >= 8000000)); + cpu_requires_fast_pit = cpu_requires_fast_pit && !cpu_16bitbus; /* System devices first. */ pic_init(); From 69572283f3fe8e397dd8ac2447dd1b4561457e2c Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 15 Jan 2024 21:52:39 +0100 Subject: [PATCH 305/936] TGUI9440AGi/96xx changes: If the chips are PCI-based, assume linear addressing is always enabled when the linear base is on valid value (e.g.: not 0). Should fix a regression when linear addressing is used by almost everything in the PCI world (e.g.: Win95's drivers). --- src/video/vid_tgui9440.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index 7bed43ac2..d54cc8fe7 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -891,7 +891,6 @@ tgui_recalcmapping(tgui_t *tgui) } } else { mem_mapping_disable(&tgui->linear_mapping); - mem_mapping_disable(&tgui->accel_mapping); switch (svga->gdcreg[6] & 0xC) { case 0x0: /*128k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); @@ -899,12 +898,6 @@ tgui_recalcmapping(tgui_t *tgui) break; case 0x4: /*64k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - if ((svga->crtc[0x36] & 0x03) == 0x01) - mem_mapping_set_addr(&tgui->accel_mapping, 0xb4000, 0x4000); - else if ((svga->crtc[0x36] & 0x03) == 0x02) - mem_mapping_set_addr(&tgui->accel_mapping, 0xbc000, 0x4000); - else if ((svga->crtc[0x36] & 0x03) == 0x03) - mem_mapping_set_addr(&tgui->accel_mapping, tgui->ge_base, 0x4000); svga->banked_mask = 0xffff; break; case 0x8: /*32k at B0000*/ @@ -919,6 +912,18 @@ tgui_recalcmapping(tgui_t *tgui) default: break; } + + if (tgui->pci && tgui->linear_base) /*Assume that, with PCI, linear addressing is always enabled.*/ + mem_mapping_set_addr(&tgui->linear_mapping, tgui->linear_base, tgui->linear_size); + + if ((svga->crtc[0x36] & 0x03) == 0x01) + mem_mapping_set_addr(&tgui->accel_mapping, 0xb4000, 0x4000); + else if ((svga->crtc[0x36] & 0x03) == 0x02) + mem_mapping_set_addr(&tgui->accel_mapping, 0xbc000, 0x4000); + else if ((svga->crtc[0x36] & 0x03) == 0x03) + mem_mapping_set_addr(&tgui->accel_mapping, tgui->ge_base, 0x4000); + else + mem_mapping_disable(&tgui->accel_mapping); } if (tgui->type >= TGUI_9440) { @@ -982,7 +987,7 @@ tgui_pci_read(UNUSED(int func), int addr, void *priv) return (tgui->type == TGUI_9440) ? 0x94 : 0x96; case PCI_REG_COMMAND: - return tgui->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ + return tgui->pci_regs[PCI_REG_COMMAND] | 0x80; /*Respond to IO and memory accesses*/ case 0x07: return 1 << 1; /*Medium DEVSEL timing*/ @@ -1043,11 +1048,12 @@ tgui_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) switch (addr) { case PCI_REG_COMMAND: - tgui->pci_regs[PCI_REG_COMMAND] = (val & 0x23); - if (val & PCI_COMMAND_IO) { + tgui->pci_regs[PCI_REG_COMMAND] = val & 0x23; + if (val & PCI_COMMAND_IO) tgui_set_io(tgui); - } else + else tgui_remove_io(tgui); + tgui_recalcmapping(tgui); break; @@ -3193,7 +3199,7 @@ tgui_init(const device_t *info) pci_add_card(PCI_ADD_VIDEO | PCI_ADD_STRICT, tgui_pci_read, tgui_pci_write, tgui, &tgui->pci_slot); } - tgui->pci_regs[PCI_REG_COMMAND] = 7; + tgui->pci_regs[PCI_REG_COMMAND] = 0x83; if (tgui->has_bios) { tgui->pci_regs[0x30] = 0x00; From a74c1e907d8e1cad405e6901a712dae7e2abb4b2 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 15 Jan 2024 22:10:07 +0100 Subject: [PATCH 306/936] Added the RTG3105 video card and fixed some wrong stuff in the RTG3106 as well. --- src/include/86box/video.h | 1 + src/video/vid_rtg310x.c | 130 ++++++++++++++++++++++---------------- src/video/vid_table.c | 1 + 3 files changed, 77 insertions(+), 55 deletions(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 2dfc6e6c1..78b83be0f 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -458,6 +458,7 @@ extern const device_t paradise_wd90c11_device; extern const device_t paradise_wd90c30_device; /* Realtek (S)VGA */ +extern const device_t realtek_rtg3105_device; extern const device_t realtek_rtg3106_device; /* S3 9XX/8XX/Vision/Trio */ diff --git a/src/video/vid_rtg310x.c b/src/video/vid_rtg310x.c index eef95a910..e84696a65 100644 --- a/src/video/vid_rtg310x.c +++ b/src/video/vid_rtg310x.c @@ -29,7 +29,8 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> -#define BIOS_ROM_PATH "roms/video/rtg/realtekrtg3106.BIN" +#define RTG_3105_BIOS_ROM_PATH "roms/video/rtg/RTG3105I.VBI" +#define RTG_3106_BIOS_ROM_PATH "roms/video/rtg/realtekrtg3106.BIN" typedef struct { const char *name; @@ -86,18 +87,18 @@ rtg_in(uint16_t addr, void *priv) return svga->crtcreg; case 0x3d5: - if (!(svga->crtc[0x1e] & 0x80) && (svga->crtcreg > 0x18)) - return 0xff; if (svga->crtcreg == 0x1a) return dev->type << 6; if (svga->crtcreg == 0x1e) { + ret = svga->crtc[0x1e]; + ret &= ~3; if (dev->vram_size == 1024) ret = 2; else if (dev->vram_size == 512) ret = 1; else ret = 0; - return svga->crtc[0x1e] | ret; + return ret; } return svga->crtc[svga->crtcreg]; @@ -208,13 +209,10 @@ rtg_out(uint16_t addr, uint8_t val, void *priv) static void rtg_recalctimings(svga_t *svga) { - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); svga->ma_latch |= ((svga->crtc[0x19] & 0x10) << 16) | ((svga->crtc[0x19] & 0x40) << 17); svga->interlace = (svga->crtc[0x19] & 1); - svga->lowres = svga->attrregs[0x10] & 0x40; - /*Clock table not available, currently a guesswork*/ switch (((svga->miscout >> 2) & 3) | ((svga->gdcreg[0x0c] & 0x20) >> 3)) { case 0: @@ -258,50 +256,41 @@ rtg_recalctimings(svga_t *svga) break; } - if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { - switch (svga->gdcreg[5] & 0x60) { - case 0x00: - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_4bpp_lowres; - else { - svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5); - svga->hdisp++; - svga->hdisp *= 8; + if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + switch (svga->gdcreg[5] & 0x60) { + case 0x00: + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_4bpp_lowres; + else { + if (svga->hdisp == 1280) + svga->rowoffset >>= 1; - if (svga->hdisp == 1280) - svga->rowoffset >>= 1; - - svga->render = svga_render_4bpp_highres; - } - break; - case 0x20: /*4 colours*/ - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_2bpp_lowres; - else - svga->render = svga_render_2bpp_highres; - break; - case 0x40: - case 0x60: - svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5); - svga->hdisp++; - svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; - if (svga->crtc[0x19] & 2) { - if (svga->hdisp == 1280) { - svga->hdisp >>= 1; - } else - svga->rowoffset <<= 1; - - svga->render = svga_render_8bpp_highres; - } else { - if (svga->lowres) - svga->render = svga_render_8bpp_lowres; + svga->render = svga_render_4bpp_highres; + } + break; + case 0x20: /*4 colours*/ + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; else - svga->render = svga_render_8bpp_highres; - } - break; + svga->render = svga_render_2bpp_highres; + break; + case 0x40: + case 0x60: + if (svga->crtc[0x19] & 2) { + if (svga->hdisp == 1280) + svga->hdisp >>= 1; + else + svga->rowoffset <<= 1; - default: - break; + svga->render = svga_render_8bpp_highres; + } else + svga->render = svga_render_8bpp_lowres; + break; + + default: + break; + } } } } @@ -316,13 +305,24 @@ rtg_init(const device_t *info) memset(dev, 0x00, sizeof(rtg_t)); dev->name = info->name; dev->type = info->local; - fn = BIOS_ROM_PATH; + fn = NULL; switch (dev->type) { - case 2: /* ISA RTG3106 */ - dev->vram_size = device_get_config_int("memory") << 10; + case 1: /* ISA RTG3105 */ + fn = RTG_3105_BIOS_ROM_PATH; + dev->vram_size = device_get_config_int("memory"); video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_rtg_isa); - svga_init(info, &dev->svga, dev, dev->vram_size, + svga_init(info, &dev->svga, dev, dev->vram_size << 10, + rtg_recalctimings, rtg_in, rtg_out, + NULL, NULL); + io_sethandler(0x03c0, 32, + rtg_in, NULL, NULL, rtg_out, NULL, NULL, dev); + break; + case 2: /* ISA RTG3106 */ + fn = RTG_3106_BIOS_ROM_PATH; + dev->vram_size = device_get_config_int("memory"); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_rtg_isa); + svga_init(info, &dev->svga, dev, dev->vram_size << 10, rtg_recalctimings, rtg_in, rtg_out, NULL, NULL); io_sethandler(0x03c0, 32, @@ -371,9 +371,15 @@ rtg_force_redraw(void *priv) } static int -rtg_available(void) +rtg3105_available(void) { - return rom_present(BIOS_ROM_PATH); + return rom_present(RTG_3105_BIOS_ROM_PATH); +} + +static int +rtg3106_available(void) +{ + return rom_present(RTG_3106_BIOS_ROM_PATH); } static const device_config_t rtg_config[] = { @@ -407,6 +413,20 @@ static const device_config_t rtg_config[] = { // clang-format on }; +const device_t realtek_rtg3105_device = { + .name = "Realtek RTG3105 (ISA)", + .internal_name = "rtg3105", + .flags = DEVICE_ISA | DEVICE_AT, + .local = 1, + .init = rtg_init, + .close = rtg_close, + .reset = NULL, + { .available = rtg3105_available }, + .speed_changed = rtg_speed_changed, + .force_redraw = rtg_force_redraw, + .config = rtg_config +}; + const device_t realtek_rtg3106_device = { .name = "Realtek RTG3106 (ISA)", .internal_name = "rtg3106", @@ -415,7 +435,7 @@ const device_t realtek_rtg3106_device = { .init = rtg_init, .close = rtg_close, .reset = NULL, - { .available = rtg_available }, + { .available = rtg3106_available }, .speed_changed = rtg_speed_changed, .force_redraw = rtg_force_redraw, .config = rtg_config diff --git a/src/video/vid_table.c b/src/video/vid_table.c index bb30fa685..d40f00e13 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -133,6 +133,7 @@ video_cards[] = { { &pgc_device }, { &cga_pravetz_device }, { &radius_svga_multiview_isa_device }, + { &realtek_rtg3105_device }, { &realtek_rtg3106_device }, { &s3_diamond_stealth_vram_isa_device }, { &s3_orchid_86c911_isa_device }, From 82311551d21a65baf380e7e978e0a0bf014c9ca5 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 15 Jan 2024 22:35:41 +0100 Subject: [PATCH 307/936] XGA changes: Cleanup the area fill side. --- src/video/vid_xga.c | 307 +++++++++++++++++++++++--------------------- 1 file changed, 162 insertions(+), 145 deletions(-) diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 17b6dfdb5..822bb3b6d 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -803,7 +803,7 @@ xga_ext_inb(uint16_t addr, void *priv) break; } - xga_log("[%04X:%08X]: EXT INB = %02x, ret = %02x\n", CS, cpu_state.pc, addr, ret); + xga_log("[%04X:%08X]: EXT INB = %02x, ret = %02x.\n\n", CS, cpu_state.pc, addr, ret); return ret; } @@ -1233,9 +1233,8 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) } } - if (!y) { + if (!y) break; - } dx += dirx; dy += diry; @@ -1249,11 +1248,6 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) xga->accel.dst_map_y = dy; } -#define SWAP(a, b) \ - tmpswap = a; \ - a = b; \ - b = tmpswap; - static void xga_line_draw_write(svga_t *svga) { @@ -1269,10 +1263,6 @@ xga_line_draw_write(svga_t *svga) int destxtmp; int dmajor; int err; - int tmpswap; - int steep = 1; - int xdir = (xga->accel.octant & 0x04) ? -1 : 1; - int ydir = (xga->accel.octant & 0x02) ? -1 : 1; int y = xga->accel.blt_width; int x = 0; int16_t dx; @@ -1282,6 +1272,7 @@ xga_line_draw_write(svga_t *svga) dminor = xga->accel.bres_k1; if (xga->accel.bres_k1 & 0x2000) dminor |= ~0x1fff; + dminor >>= 1; destxtmp = xga->accel.bres_k2; @@ -1305,17 +1296,119 @@ xga_line_draw_write(svga_t *svga) if ((xga->accel.command & 0x30) == 0x30) xga_log("Line Draw Write: BLTWIDTH=%d, BLTHEIGHT=%d, FRGDCOLOR=%04x, XDIR=%i, YDIR=%i, steep=%s, ERR=%04x.\n", xga->accel.blt_width, xga->accel.blt_height, xga->accel.frgd_color & 0xffff, xdir, ydir, (xga->accel.octant & 0x01) ? "0" : "1", err); - if (xga->accel.octant & 0x01) { - steep = 0; - SWAP(dx, dy); - SWAP(xdir, ydir); - } if (xga->accel.pat_src == 8) { - while (y >= 0) { - draw_pixel = 1; - if (xga->accel.command & 0xc0) { - if (steep) { + if ((xga->accel.command & 0x30) == 0x30) { + while (y >= 0) { + draw_pixel = 1; + + if (xga->accel.command & 0xc0) { + if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); + + if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { + ROP(1, dest_dat, src_dat); + dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); + if (xga->accel.octant & 0x01) { /*Y Major*/ + if (xga->accel.octant & 0x02) { /*Bottom-to-Top*/ + if (!x) + draw_pixel = 0; + } else { /*Top-to-Bottom*/ + if (!y) + draw_pixel = 0; + } + } else { + if (err >= 0) { + if (xga->accel.octant & 0x02) { /*Bottom-to-Top*/ + if (!x) + draw_pixel = 0; + } else { /*Top-to-Bottom*/ + if (!y) + draw_pixel = 0; + } + } else + draw_pixel = 0; + } + + if (draw_pixel) + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + } + } + } else { + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); + + if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { + ROP(1, dest_dat, src_dat); + dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); + if (xga->accel.octant & 0x01) { /*Y Major*/ + if (xga->accel.octant & 0x02) { /*Bottom-to-Top*/ + if (!x) + draw_pixel = 0; + } else { /*Top-to-Bottom*/ + if (!y) + draw_pixel = 0; + } + } else { + if (err >= 0) { + if (xga->accel.octant & 0x02) { /*Bottom-to-Top*/ + if (!x) + draw_pixel = 0; + } else { /*Top-to-Bottom*/ + if (!y) + draw_pixel = 0; + } + } else + draw_pixel = 0; + } + + if (draw_pixel) + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + } + } + + if (!y) + break; + + if (xga->accel.octant & 0x01) { + if (xga->accel.octant & 0x02) + dy--; + else + dy++; + + while (err >= 0) { + err -= (dmajor << 1); + if (xga->accel.octant & 0x04) + dx--; + else + dx++; + } + + err += (dminor << 1); + } else { + if (xga->accel.octant & 0x04) + dx--; + else + dx++; + + while (err >= 0) { + err -= (dmajor << 1); + if (xga->accel.octant & 0x02) + dy--; + else + dy++; + } + + err += (dminor << 1); + } + + y--; + x++; + } + } else { + while (y >= 0) { + if (xga->accel.command & 0xc0) { if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); @@ -1330,54 +1423,9 @@ xga_line_draw_write(svga_t *svga) xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x20) && y) xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); - else if ((xga->accel.command & 0x30) == 0x30) { - if (err < 0) - draw_pixel = 0; - else { - if (ydir == -1) { /*Bottom-to-Top*/ - if (!x) - draw_pixel = 0; - } else { /*Top-to-Bottom*/ - if (!y) - draw_pixel = 0; - } - } - if (draw_pixel) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); - } } } } else { - if ((dy >= xga->accel.mask_map_origin_x_off) && (dy <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dx >= xga->accel.mask_map_origin_y_off) && (dx <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); - - if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { - old_dest_dat = dest_dat; - ROP(1, dest_dat, src_dat); - dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - if ((xga->accel.command & 0x30) == 0) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); - else if (((xga->accel.command & 0x30) == 0x10) && x) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); - else if (((xga->accel.command & 0x30) == 0x20) && y) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); - else if ((xga->accel.command & 0x30) == 0x30) { - if (xdir == -1) { /*Bottom-to-Top*/ - if (!x) - draw_pixel = 0; - } else { /*Top-to-Bottom*/ - if (!y) - draw_pixel = 0; - } - if (draw_pixel) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); - } - } - } - } - } else { - if (steep) { src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); @@ -1391,79 +1439,54 @@ xga_line_draw_write(svga_t *svga) xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x20) && y) xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); - else if ((xga->accel.command & 0x30) == 0x30) { - if (err < 0) - draw_pixel = 0; - else { - if (ydir == -1) { /*Bottom-to-Top*/ - if (!x) - draw_pixel = 0; - } else { /*Top-to-Bottom*/ - if (!y) - draw_pixel = 0; - } - } - if (draw_pixel) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); - } - } - } else { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); - - if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { - old_dest_dat = dest_dat; - ROP(1, dest_dat, src_dat); - dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - if ((xga->accel.command & 0x30) == 0) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); - else if (((xga->accel.command & 0x30) == 0x10) && x) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); - else if (((xga->accel.command & 0x30) == 0x20) && y) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); - else if ((xga->accel.command & 0x30) == 0x30) { - if (xdir == -1) { /*Bottom-to-Top*/ - if (!x) - draw_pixel = 0; - } else { /*Top-to-Bottom*/ - if (!y) - draw_pixel = 0; - } - if (draw_pixel) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); - } } } + + if (!y) + break; + + if (xga->accel.octant & 0x01) { + if (xga->accel.octant & 0x02) + dy--; + else + dy++; + + while (err >= 0) { + err -= (dmajor << 1); + if (xga->accel.octant & 0x04) + dx--; + else + dx++; + } + + err += (dminor << 1); + } else { + if (xga->accel.octant & 0x04) + dx--; + else + dx++; + + while (err >= 0) { + err -= (dmajor << 1); + if (xga->accel.octant & 0x02) + dy--; + else + dy++; + } + + err += (dminor << 1); + } + + y--; + x++; } - - if (!y) { - break; - } - - while (err >= 0) { - dy += ydir; - err -= (dmajor << 1); - } - - dx += xdir; - err += (dminor << 1); - - x++; - y--; } } - if (steep) { - xga->accel.dst_map_x = dx; - xga->accel.dst_map_y = dy; - } else { - xga->accel.dst_map_x = dy; - xga->accel.dst_map_y = dx; - } + xga->accel.dst_map_x = dx; + xga->accel.dst_map_y = dy; } -#undef SWAP - static void xga_bitblt(svga_t *svga) { @@ -1641,7 +1664,7 @@ xga_bitblt(svga_t *svga) while (xga->accel.y >= 0) { mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, xga->accel.pat_src, patbase, patwidth + 1); if (mix) - area_state ^= 1; + area_state = !area_state; if (xga->accel.command & 0xc0) { if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { @@ -1650,9 +1673,6 @@ xga_bitblt(svga_t *svga) else src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol; - if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) <= 3) - src_dat &= 0xff; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; @@ -1669,9 +1689,6 @@ xga_bitblt(svga_t *svga) else src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol; - if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) <= 3) - src_dat &= 0xff; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; @@ -1715,11 +1732,11 @@ xga_bitblt(svga_t *svga) if (xga->accel.command & 0xc0) { if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - if (mix) { + if (mix) src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol; - } else { + else src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol; - } + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; @@ -1730,11 +1747,11 @@ xga_bitblt(svga_t *svga) } } else { if ((dx >= 0) && (dx <= dstwidth) && (dy >= 0) && (dy <= dstheight)) { - if (mix) { + if (mix) src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol; - } else { + else src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol; - } + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; @@ -2422,7 +2439,7 @@ xga_memio_readl(uint32_t addr, void *priv) temp |= (xga_mem_read(addr + 2, xga, svga) << 16); temp |= (xga_mem_read(addr + 3, xga, svga) << 24); - xga_log("Read MEMIOL = %04x, temp = %08x\n", addr, temp); + xga_log("[%04X:%08X]: Read MEMIOL = %04x, temp = %08x\n", CS, cpu_state.pc, addr, temp); return temp; } From e25fadc138fa3e3d0965bbcf0503d8f59d77ffeb Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 15 Jan 2024 23:04:36 +0100 Subject: [PATCH 308/936] S3 true color update. Reset bit 4 of the Misc Index register (from port 0xbee8) on mode changes. --- src/video/vid_s3.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 6de3ffce7..54f9047e8 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -945,10 +945,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.cmd = (s3->accel.cmd & 0xff) | (val << 8); s3->accel.ssv_state = 0; s3->accel_start(-1, 0, 0xffffffff, 0, s3); - if (s3->bpp == 3) { - if (!(s3->accel.multifunc[0xe] & 0x200) && !(svga->crtc[0x32] & 0x40)) - s3->accel.multifunc[0xe] &= ~0x10; - } break; case 0x994a: @@ -2780,6 +2776,10 @@ s3_out(uint16_t addr, uint8_t val, void *priv) case 0x50: s3->bpp = (svga->crtc[0x50] >> 4) & 3; + if (s3->bpp == 3) { + if (!(s3->accel.multifunc[0xe] & 0x200)) /*On True Color mode change, reset bit 4 of Misc Index register*/ + s3->accel.multifunc[0xe] &= ~0x10; + } break; case 0x5c: From 56631fac30a5f5e7c22284bcb7b1a856689d3322 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 16 Jan 2024 19:03:54 +0100 Subject: [PATCH 309/936] More fixes to the RTG series: 1. Make the RTG VGA series work on XT's. 2. The RTG3105 is limited to up to 512K of memory, not 1M. 3. Fixed rowoffset in 8bpp mode used by the RTG3105. --- src/video/vid_rtg310x.c | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/video/vid_rtg310x.c b/src/video/vid_rtg310x.c index e84696a65..e82763d15 100644 --- a/src/video/vid_rtg310x.c +++ b/src/video/vid_rtg310x.c @@ -209,6 +209,8 @@ rtg_out(uint16_t addr, uint8_t val, void *priv) static void rtg_recalctimings(svga_t *svga) { + const rtg_t *dev = (rtg_t *) svga->priv; + svga->ma_latch |= ((svga->crtc[0x19] & 0x10) << 16) | ((svga->crtc[0x19] & 0x40) << 17); svga->interlace = (svga->crtc[0x19] & 1); @@ -280,7 +282,7 @@ rtg_recalctimings(svga_t *svga) if (svga->crtc[0x19] & 2) { if (svga->hdisp == 1280) svga->hdisp >>= 1; - else + else if (dev->type == 2) svga->rowoffset <<= 1; svga->render = svga_render_8bpp_highres; @@ -382,7 +384,34 @@ rtg3106_available(void) return rom_present(RTG_3106_BIOS_ROM_PATH); } -static const device_config_t rtg_config[] = { +static const device_config_t rtg3105_config[] = { + // clang-format off + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 512, + .selection = { + { + .description = "256 KB", + .value = 256 + }, + { + .description = "512 KB", + .value = 512 + }, + { + .description = "" + } + } + }, + { + .type = CONFIG_END + } + // clang-format on +}; + +static const device_config_t rtg3106_config[] = { // clang-format off { .name = "memory", @@ -416,7 +445,7 @@ static const device_config_t rtg_config[] = { const device_t realtek_rtg3105_device = { .name = "Realtek RTG3105 (ISA)", .internal_name = "rtg3105", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA, .local = 1, .init = rtg_init, .close = rtg_close, @@ -424,13 +453,13 @@ const device_t realtek_rtg3105_device = { { .available = rtg3105_available }, .speed_changed = rtg_speed_changed, .force_redraw = rtg_force_redraw, - .config = rtg_config + .config = rtg3105_config }; const device_t realtek_rtg3106_device = { .name = "Realtek RTG3106 (ISA)", .internal_name = "rtg3106", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA, .local = 2, .init = rtg_init, .close = rtg_close, @@ -438,5 +467,5 @@ const device_t realtek_rtg3106_device = { { .available = rtg3106_available }, .speed_changed = rtg_speed_changed, .force_redraw = rtg_force_redraw, - .config = rtg_config + .config = rtg3106_config }; From 958c2be839ad0a63e3f7d0e5bec7334f65cf64bd Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 16 Jan 2024 23:42:12 +0100 Subject: [PATCH 310/936] Added a proper VLB variant to the TGUI9440AGi See above. --- src/video/vid_tgui9440.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index d54cc8fe7..86159ed0a 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -76,7 +76,8 @@ #include <86box/vid_svga_render.h> #define ROM_TGUI_9400CXI "roms/video/tgui9440/9400CXI.VBI" -#define ROM_TGUI_9440 "roms/video/tgui9440/BIOS.BIN" +#define ROM_TGUI_9440_VLB "roms/video/tgui9440/trident_9440_vlb.bin" +#define ROM_TGUI_9440_PCI "roms/video/tgui9440/BIOS.BIN" #define ROM_TGUI_96xx "roms/video/tgui9660/Union.VBI" #define EXT_CTRL_16BIT 0x01 @@ -3147,7 +3148,10 @@ tgui_init(const device_t *info) bios_fn = ROM_TGUI_9400CXI; break; case TGUI_9440: - bios_fn = (info->local & ONBOARD) ? NULL : ROM_TGUI_9440; + if (tgui->pci) + bios_fn = (info->local & ONBOARD) ? NULL : ROM_TGUI_9440_PCI; + else + bios_fn = ROM_TGUI_9440_VLB; break; case TGUI_9660: case TGUI_9680: @@ -3224,9 +3228,15 @@ tgui9400cxi_available(void) } static int -tgui9440_available(void) +tgui9440_vlb_available(void) { - return rom_present(ROM_TGUI_9440); + return rom_present(ROM_TGUI_9440_VLB); +} + +static int +tgui9440_pci_available(void) +{ + return rom_present(ROM_TGUI_9440_PCI); } static int @@ -3344,7 +3354,7 @@ const device_t tgui9440_vlb_device = { .init = tgui_init, .close = tgui_close, .reset = NULL, - { .available = tgui9440_available }, + { .available = tgui9440_vlb_available }, .speed_changed = tgui_speed_changed, .force_redraw = tgui_force_redraw, .config = tgui9440_config @@ -3358,7 +3368,7 @@ const device_t tgui9440_pci_device = { .init = tgui_init, .close = tgui_close, .reset = NULL, - { .available = tgui9440_available }, + { .available = tgui9440_pci_available }, .speed_changed = tgui_speed_changed, .force_redraw = tgui_force_redraw, .config = tgui9440_config From 19af46a8c20936385fd0a6586350057bd58a57ea Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 17 Jan 2024 03:59:56 +0100 Subject: [PATCH 311/936] Some more mouse helper functions and fixed the video warnings. --- src/device/mouse.c | 9 +++++++++ src/include/86box/mouse.h | 1 + src/video/vid_8514a.c | 1 - src/video/vid_ati_mach8.c | 11 +---------- src/video/vid_xga.c | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/device/mouse.c b/src/device/mouse.c index 193149bc8..da4ed1c04 100644 --- a/src/device/mouse.c +++ b/src/device/mouse.c @@ -454,6 +454,15 @@ mouse_scale(int x, int y) mouse_scale_y(y); } +void +mouse_scale_axis(int axis, int val) +{ + if (axis == 1) + mouse_scale_y(val); + else if (axis == 0) + mouse_scale_x(val); +} + void mouse_set_z(int z) { diff --git a/src/include/86box/mouse.h b/src/include/86box/mouse.h index 3ed6b2126..786b86f41 100644 --- a/src/include/86box/mouse.h +++ b/src/include/86box/mouse.h @@ -93,6 +93,7 @@ extern void mouse_scale_x(int x); extern void mouse_scale_y(int y); extern void mouse_scalef(double x, double y); extern void mouse_scale(int x, int y); +extern void mouse_scale_axis(int axis, int val); extern void mouse_set_z(int z); extern void mouse_clear_z(void); extern void mouse_subtract_z(int *delta_z, int min, int max, int invert); diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index bb61e3c47..9f2b1316a 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -4367,7 +4367,6 @@ ibm8514_init(const device_t *info) svga_t *svga = svga_get_pri(); ibm8514_t *dev = (ibm8514_t *) calloc(1, sizeof(ibm8514_t)); - mach_t *mach = NULL; svga->dev8514 = dev; svga->ext8514 = NULL; diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index fb07d1548..d710b2bcf 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -59,15 +59,7 @@ static uint8_t mach_accel_inb(uint16_t port, void *priv); static uint16_t mach_accel_inw(uint16_t port, void *priv); static uint8_t mach_in(uint16_t addr, void *priv); -static void ati8514_accel_outb(uint16_t port, uint8_t val, void *priv); -static void ati8514_accel_outw(uint16_t port, uint16_t val, void *priv); -static void ati8514_accel_outl(uint16_t port, uint32_t val, void *priv); -static uint8_t ati8514_accel_inb(uint16_t port, void *priv); -static uint16_t ati8514_accel_inw(uint16_t port, void *priv); -static uint32_t ati8514_accel_inl(uint16_t port, void *priv); - - -static void mach32_updatemapping(mach_t *mach, svga_t *svga); +static void mach32_updatemapping(mach_t *mach, svga_t *svga); #ifdef ENABLE_MACH_LOG int mach_do_log = ENABLE_MACH_LOG; @@ -3990,7 +3982,6 @@ static void mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) { svga_t *svga = &mach->svga; - ibm8514_t *dev = (ibm8514_t *) svga->dev8514; mach_log("[%04X:%08X]: Port NORMAL OUT=%04x, val=%04x.\n", CS, cpu_state.pc, port, val); diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 822bb3b6d..44e8aa6c3 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -1254,7 +1254,7 @@ xga_line_draw_write(svga_t *svga) xga_t *xga = (xga_t *) svga->xga; uint32_t src_dat; uint32_t dest_dat; - uint32_t old_dest_dat; + uint32_t old_dest_dat = 0x00000000; uint32_t color_cmp = xga->accel.color_cmp; uint32_t plane_mask = xga->accel.plane_mask; uint32_t dstbase = xga->accel.px_map_base[xga->accel.dst_map]; From 079cf6782c388c503dcb09e88bb2b1dd2375ae30 Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Thu, 18 Jan 2024 14:12:07 +0100 Subject: [PATCH 312/936] Add DataExpert EXP4349 (PhoenixBIOS 4.03 for ALi M1429G and 386DX/Socket 3 combo board.) --- src/include/86box/machine.h | 1 + src/machine/m_at_386dx_486.c | 21 ++ src/machine/machine_table.c | 361 ++++++++++++++++------------------- 3 files changed, 183 insertions(+), 200 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index dac5cbe54..f730bbdd7 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -505,6 +505,7 @@ extern int machine_at_winbios1429_init(const machine_t *); extern int machine_at_opti495_init(const machine_t *); extern int machine_at_opti495_ami_init(const machine_t *); extern int machine_at_opti495_mr_init(const machine_t *); +extern int machine_at_exp4349_init(const machine_t *); extern int machine_at_vect486vl_init(const machine_t *); extern int machine_at_d824_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 8c06fc815..9ca59577d 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -574,6 +574,27 @@ machine_at_opti495_mr_init(const machine_t *model) return ret; } +int +machine_at_exp4349_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/exp4349/biosdump.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&ali1429g_device); + device_add(&keyboard_at_ami_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + return ret; +} + static void machine_at_403tg_common_init(const machine_t *model, int nvr_hack) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 37df5b3e3..099ef62ea 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -5027,10 +5027,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386DX, .chipset = MACHINE_CHIPSET_ALI_M1429, .init = machine_at_ecs386v_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386DX, .block = CPU_BLOCK_NONE, @@ -5050,8 +5050,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .vid_device = NULL, .snd_device = NULL, @@ -5262,6 +5263,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Winbond W83C42 with unknown firmware. */ + { + .name = "[ALi M1429G] DataExpert EXP4349", + .internal_name = "exp4349", + .type = MACHINE_TYPE_386DX_486, + .chipset = MACHINE_CHIPSET_ALI_M1429G, + .init = machine_at_exp4349_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX | CPU_PKG_SOCKET3, + .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_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 49152, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Has IBM PS/2 Type 1 KBC firmware. */ { .name = "[MCA] IBM PS/2 model 70 (type 3)", @@ -6090,10 +6131,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S2, .chipset = MACHINE_CHIPSET_INTEL_420TX, .init = machine_at_pci400ca_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6113,8 +6154,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = &keyboard_ps2_ami_device, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6129,10 +6171,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S2, .chipset = MACHINE_CHIPSET_VLSI_VL82C480, .init = machine_at_zmartin_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6152,8 +6194,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, //&fdc37c651_device, @@ -6331,10 +6374,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_OPTI_895_802G, .init = machine_at_pb450_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6354,8 +6397,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = &gd5428_vlb_onboard_device, .fdc_device = NULL, .sio_device = NULL, @@ -6568,21 +6612,12 @@ const machine_t machines[] = { .name = "[SiS 471] DEC Venturis 4xx", .internal_name = "dvent4xx", .type = MACHINE_TYPE_486_S3, -<<<<<<< HEAD .chipset = MACHINE_CHIPSET_SIS_471, .init = machine_at_dvent4xx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, -======= - .chipset = MACHINE_CHIPSET_ALI_M1429G, - .init = machine_at_ms4134_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, ->>>>>>> origin/master .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6602,16 +6637,10 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, -<<<<<<< HEAD - .kbc_p1 = 0, - .gpio = 0, - .device = &s3_phoenix_trio32_onboard_vlb_device, -======= .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, ->>>>>>> origin/master + .device = &s3_phoenix_trio32_onboard_vlb_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, @@ -6624,19 +6653,11 @@ const machine_t machines[] = { .internal_name = "ecsal486", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_ALI_M1429G, -<<<<<<< HEAD .init = machine_at_ecsal486_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, -======= - .init = machine_at_tg486gp_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, ->>>>>>> origin/master .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6671,21 +6692,12 @@ const machine_t machines[] = { .name = "[ALi M1429G] Lanner Electronics AP-4100AA", .internal_name = "ap4100aa", .type = MACHINE_TYPE_486_S3, -<<<<<<< HEAD .chipset = MACHINE_CHIPSET_ALI_M1429G, .init = machine_at_ap4100aa_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, -======= - .chipset = MACHINE_CHIPSET_ALI_M1489, - .init = machine_at_sbc490_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, ->>>>>>> origin/master .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6705,14 +6717,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, -<<<<<<< HEAD - .kbc_p1 = 0, - .gpio = 0, -======= .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, ->>>>>>> origin/master .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6725,21 +6732,12 @@ const machine_t machines[] = { .name = "[ALi M1429G] A-Trend ATC-1762", .internal_name = "atc1762", .type = MACHINE_TYPE_486_S3, -<<<<<<< HEAD .chipset = MACHINE_CHIPSET_ALI_M1429G, .init = machine_at_atc1762_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, -======= - .chipset = MACHINE_CHIPSET_ALI_M1489, - .init = machine_at_abpb4_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, ->>>>>>> origin/master .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6776,21 +6774,12 @@ const machine_t machines[] = { .name = "[ALi M1429G] MSI MS-4134", .internal_name = "ms4134", .type = MACHINE_TYPE_486_S3, -<<<<<<< HEAD .chipset = MACHINE_CHIPSET_ALI_M1429G, .init = machine_at_ms4134_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, -======= - .chipset = MACHINE_CHIPSET_ALI_M1489, - .init = machine_at_win486pci_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, ->>>>>>> origin/master .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6825,21 +6814,12 @@ const machine_t machines[] = { .name = "[ALi M1429G] TriGem 486GP", .internal_name = "tg486gp", .type = MACHINE_TYPE_486_S3, -<<<<<<< HEAD .chipset = MACHINE_CHIPSET_ALI_M1429G, .init = machine_at_tg486gp_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, -======= - .chipset = MACHINE_CHIPSET_ALI_M1489, - .init = machine_at_ms4145_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, ->>>>>>> origin/master .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6875,19 +6855,11 @@ const machine_t machines[] = { .internal_name = "sbc490", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_ALI_M1489, -<<<<<<< HEAD .init = machine_at_sbc490_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, -======= - .init = machine_at_tf486_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, ->>>>>>> origin/master .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6907,16 +6879,10 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, -<<<<<<< HEAD - .kbc_p1 = 0, - .gpio = 0, - .device = &tgui9440_onboard_pci_device, -======= .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, ->>>>>>> origin/master + .device = &tgui9440_onboard_pci_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, @@ -6929,21 +6895,12 @@ const machine_t machines[] = { .name = "[ALi M1489] ABIT AB-PB4", .internal_name = "abpb4", .type = MACHINE_TYPE_486_S3, -<<<<<<< HEAD .chipset = MACHINE_CHIPSET_ALI_M1489, .init = machine_at_abpb4_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, -======= - .chipset = MACHINE_CHIPSET_OPTI_895_802G, - .init = machine_at_pc330_6573_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, ->>>>>>> origin/master .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6963,8 +6920,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6983,10 +6941,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_ALI_M1489, .init = machine_at_win486pci_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -7006,8 +6964,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7026,10 +6985,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_ALI_M1489, .init = machine_at_ms4145_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -7049,8 +7008,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7065,10 +7025,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_ALI_M1489, .init = machine_at_tf486_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -7088,8 +7048,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7104,10 +7065,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_ALI_M1489, .init = machine_at_arb1476_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -7127,8 +7088,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7143,10 +7105,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_OPTI_895_802G, .init = machine_at_pc330_6573_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3_PC330, .block = CPU_BLOCK_NONE, @@ -7183,10 +7145,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_OPTI_895_802G, //OPTi 802GP .init = machine_at_m45xx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -7206,8 +7168,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7302,10 +7265,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_INTEL_420EX, .init = machine_at_bat4ip3e_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -7325,8 +7288,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7341,10 +7305,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_INTEL_420EX, .init = machine_at_486pi_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -7364,8 +7328,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7380,10 +7345,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_INTEL_420EX, .init = machine_at_sb486p_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -7403,8 +7368,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7499,10 +7465,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_INTEL_420TX, .init = machine_at_amis76_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -7522,8 +7488,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7901,10 +7868,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_SIS_496, .init = machine_at_ms4144_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -7924,8 +7891,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -8061,10 +8029,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_UMC_UM8881, .init = machine_at_actiontower8400_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -8084,8 +8052,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -8180,19 +8149,11 @@ const machine_t machines[] = { .internal_name = "hot433a", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_UMC_UM8881, -<<<<<<< HEAD .init = machine_at_hot433a_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, -======= - .init = machine_at_hot433_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, ->>>>>>> origin/master .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -8436,10 +8397,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_MISC, .chipset = MACHINE_CHIPSET_STPC_CONSUMER_II, .init = machine_at_iach488_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_STPC, .block = CPU_BLOCK_NONE, @@ -8459,8 +8420,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -9087,7 +9049,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Socket 5 machines */ /* 430NX */ /* This has the Phoenix MultiKey KBC firmware. */ From 3857fede38cf3b1eaca5994b18fdd2f1cae3809a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 19 Jan 2024 16:30:51 +0600 Subject: [PATCH 313/936] DECchip 21040 emulation (only tested on Linux) --- src/include/86box/net_tulip.h | 1 + src/network/net_tulip.c | 315 ++++++++++++++++++++-------------- src/network/network.c | 1 + 3 files changed, 190 insertions(+), 127 deletions(-) diff --git a/src/include/86box/net_tulip.h b/src/include/86box/net_tulip.h index 3e14deeea..2ee7ec3c1 100644 --- a/src/include/86box/net_tulip.h +++ b/src/include/86box/net_tulip.h @@ -1,3 +1,4 @@ extern const device_t dec_tulip_device; extern const device_t dec_tulip_21140_device; extern const device_t dec_tulip_21140_vpc_device; +extern const device_t dec_tulip_21040_device; diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index b74b345bc..c81fbc3f9 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -323,6 +323,9 @@ struct TULIPState { uint32_t mii_word; uint32_t mii_bitcnt; + /* 21040 ROM read address. */ + uint32_t rom_read_addr; + uint32_t current_rx_desc; uint32_t current_tx_desc; @@ -666,6 +669,9 @@ tulip_mii(TULIPState *s) static uint32_t tulip_csr9_read(TULIPState *s) { + if (s->device_info->local == 3) { + return ((uint8_t*)nmc93cxx_eeprom_data(s->eeprom))[s->rom_read_addr++]; + } if (s->csr[9] & CSR9_SR) { if (nmc93cxx_eeprom_read(s->eeprom)) { s->csr[9] |= CSR9_SR_DO; @@ -698,6 +704,10 @@ tulip_read(uint32_t addr, void *opaque) break; case CSR(12): + if (s->device_info->local == 3) { + data = 0; + break; + } /* Fake autocompletion complete until we have PHY emulation */ data = 5 << CSR12_ANS_SHIFT; break; @@ -884,8 +894,10 @@ tulip_reset(void *priv) s->csr[13] = 0xffff0000; s->csr[14] = 0xffffffff; s->csr[15] = 0x8ff00000; - s->subsys_id = eeprom_data[1]; - s->subsys_ven_id = eeprom_data[0]; + if (s->device_info->local != 3) { + s->subsys_id = eeprom_data[1]; + s->subsys_ven_id = eeprom_data[0]; + } } static void @@ -955,12 +967,16 @@ tulip_write(uint32_t addr, uint32_t data, void *opaque) break; case CSR(9): - tulip_csr9_write(s, s->csr[9], data); - /* don't clear MII read data */ - s->csr[9] &= CSR9_MDI; - s->csr[9] |= (data & ~CSR9_MDI); - tulip_mii(s); - s->old_csr9 = s->csr[9]; + if (s->device_info->local != 3) { + tulip_csr9_write(s, s->csr[9], data); + /* don't clear MII read data */ + s->csr[9] &= CSR9_MDI; + s->csr[9] |= (data & ~CSR9_MDI); + tulip_mii(s); + s->old_csr9 = s->csr[9]; + } else { + s->rom_read_addr = 0; + } break; case CSR(10): @@ -978,6 +994,11 @@ tulip_write(uint32_t addr, uint32_t data, void *opaque) case CSR(13): s->csr[13] = data; + if (s->device_info->local == 3 && (data & 0x4)) { + s->csr[13] = 0x8f01; + s->csr[14] = 0xfffd; + s->csr[15] = 0; + } break; case CSR(14): @@ -1141,7 +1162,9 @@ tulip_pci_read(UNUSED(int func), int addr, void *priv) ret = 0x10; break; case 0x02: - if (s->device_info->local) + if (s->device_info->local == 3) + ret = 0x02; + else if (s->device_info->local) ret = 0x09; else ret = 0x19; @@ -1229,6 +1252,7 @@ tulip_pci_read(UNUSED(int func), int addr, void *priv) break; case 0x3E: case 0x3F: + case 0x41: ret = s->pci_conf[addr & 0xff]; break; } @@ -1319,6 +1343,7 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) return; case 0x3E: case 0x3F: + case 0x41: s->pci_conf[addr & 0xff] = val; return; } @@ -1336,7 +1361,7 @@ nic_init(const device_t *info) if (!s) return NULL; - if (info->local) { + if (info->local && info->local != 3) { s->bios_addr = 0xD0000; s->has_bios = device_get_config_int("bios"); } else { @@ -1349,139 +1374,161 @@ nic_init(const device_t *info) s->device_info = info; - /*Subsystem Vendor ID*/ - s->eeprom_data[0] = info->local ? 0x25 : 0x11; - s->eeprom_data[1] = 0x10; + if (info->local != 3) { + /*Subsystem Vendor ID*/ + s->eeprom_data[0] = info->local ? 0x25 : 0x11; + s->eeprom_data[1] = 0x10; - /*Subsystem ID*/ - s->eeprom_data[2] = info->local ? 0x10 : 0x0a; - s->eeprom_data[3] = info->local ? 0x03 : 0x50; + /*Subsystem ID*/ + s->eeprom_data[2] = info->local ? 0x10 : 0x0a; + s->eeprom_data[3] = info->local ? 0x03 : 0x50; - /*Cardbus CIS Pointer low*/ - s->eeprom_data[4] = 0x00; - s->eeprom_data[5] = 0x00; + /*Cardbus CIS Pointer low*/ + s->eeprom_data[4] = 0x00; + s->eeprom_data[5] = 0x00; - /*Cardbus CIS Pointer high*/ - s->eeprom_data[6] = 0x00; - s->eeprom_data[7] = 0x00; + /*Cardbus CIS Pointer high*/ + s->eeprom_data[6] = 0x00; + s->eeprom_data[7] = 0x00; - /*ID Reserved1*/ - for (int i = 0; i < 7; i++) - s->eeprom_data[8 + i] = 0x00; + /*ID Reserved1*/ + for (int i = 0; i < 7; i++) + s->eeprom_data[8 + i] = 0x00; - /*MiscHwOptions*/ - s->eeprom_data[15] = 0x00; + /*MiscHwOptions*/ + s->eeprom_data[15] = 0x00; - /*ID_BLOCK_CRC*/ - tulip_idblock_crc((uint16_t *) s->eeprom_data); + /*ID_BLOCK_CRC*/ + tulip_idblock_crc((uint16_t *) s->eeprom_data); - /*Func0_HwOptions*/ - s->eeprom_data[17] = 0x00; + /*Func0_HwOptions*/ + s->eeprom_data[17] = 0x00; - /*SROM Format Version 1, compatible with older guests*/ - s->eeprom_data[18] = 0x01; + /*SROM Format Version 1, compatible with older guests*/ + s->eeprom_data[18] = 0x01; - /*Controller Count*/ - s->eeprom_data[19] = 0x01; + /*Controller Count*/ + s->eeprom_data[19] = 0x01; - /*DEC OID*/ - s->eeprom_data[20] = 0x00; - s->eeprom_data[21] = 0x00; - s->eeprom_data[22] = 0xf8; - - if (info->local == 2) { - /* Microsoft VPC DEC Tulip. */ + /*DEC OID*/ s->eeprom_data[20] = 0x00; - s->eeprom_data[21] = 0x03; - s->eeprom_data[22] = 0x0f; - } + s->eeprom_data[21] = 0x00; + s->eeprom_data[22] = 0xf8; - /* See if we have a local MAC address configured. */ - mac = device_get_config_mac("mac", -1); + if (info->local == 2) { + /* Microsoft VPC DEC Tulip. */ + s->eeprom_data[20] = 0x00; + s->eeprom_data[21] = 0x03; + s->eeprom_data[22] = 0x0f; + } - /* Set up our BIA. */ - if (mac & 0xff000000) { - /* Generate new local MAC. */ - s->eeprom_data[23] = random_generate(); - s->eeprom_data[24] = random_generate(); - s->eeprom_data[25] = random_generate(); - mac = (((int) s->eeprom_data[23]) << 16); - mac |= (((int) s->eeprom_data[24]) << 8); - mac |= ((int) s->eeprom_data[25]); - device_set_config_mac("mac", mac); + /* See if we have a local MAC address configured. */ + mac = device_get_config_mac("mac", -1); + + /* Set up our BIA. */ + if (mac & 0xff000000) { + /* Generate new local MAC. */ + s->eeprom_data[23] = random_generate(); + s->eeprom_data[24] = random_generate(); + s->eeprom_data[25] = random_generate(); + mac = (((int) s->eeprom_data[23]) << 16); + mac |= (((int) s->eeprom_data[24]) << 8); + mac |= ((int) s->eeprom_data[25]); + device_set_config_mac("mac", mac); + } else { + s->eeprom_data[23] = (mac >> 16) & 0xff; + s->eeprom_data[24] = (mac >> 8) & 0xff; + s->eeprom_data[25] = (mac & 0xff); + } + + /*Controller_0 Device_Number*/ + s->eeprom_data[26] = 0x00; + + /*Controller_0 Info Leaf_Offset*/ + s->eeprom_data[27] = 0x1e; + s->eeprom_data[28] = 0x00; + + /*Selected Connection Type, Powerup AutoSense and Dynamic AutoSense if the board supports it*/ + s->eeprom_data[30] = 0x00; + s->eeprom_data[31] = 0x08; + + if (info->local) { + /*General Purpose Control*/ + s->eeprom_data[32] = 0xff; + + /*Block Count*/ + s->eeprom_data[33] = 0x01; + + /*Extended Format (first part)*/ + /*Length (0:6) and Format Indicator (7)*/ + s->eeprom_data[34] = 0x81; + + /*Block Type (first part)*/ + s->eeprom_data[35] = 0x01; + + /*Extended Format (second part) - Block Type 0 for 21140*/ + /*Length (0:6) and Format Indicator (7)*/ + s->eeprom_data[36] = 0x85; + + /*Block Type (second part)*/ + s->eeprom_data[37] = 0x00; + + /*Media Code (0:5), EXT (6), Reserved (7)*/ + s->eeprom_data[38] = 0x01; + + /*General Purpose Data*/ + s->eeprom_data[39] = 0x00; + + /*Command*/ + s->eeprom_data[40] = 0x00; + s->eeprom_data[41] = 0x00; + } else { + /*Block Count*/ + s->eeprom_data[32] = 0x01; + + /*Extended Format - Block Type 2 for 21142/21143*/ + /*Length (0:6) and Format Indicator (7)*/ + s->eeprom_data[33] = 0x86; + + /*Block Type*/ + s->eeprom_data[34] = 0x02; + + /*Media Code (0:5), EXT (6), Reserved (7)*/ + s->eeprom_data[35] = 0x01; + + /*General Purpose Control*/ + s->eeprom_data[36] = 0xff; + s->eeprom_data[37] = 0xff; + + /*General Purpose Data*/ + s->eeprom_data[38] = 0x00; + s->eeprom_data[39] = 0x00; + } + + s->eeprom_data[126] = tulip_srom_crc(s->eeprom_data) & 0xff; + s->eeprom_data[127] = tulip_srom_crc(s->eeprom_data) >> 8; } else { - s->eeprom_data[23] = (mac >> 16) & 0xff; - s->eeprom_data[24] = (mac >> 8) & 0xff; - s->eeprom_data[25] = (mac & 0xff); + /* 21040 is supposed to only have MAC address in its serial ROM if Linux is correct. */ + memset(s->eeprom_data, 0, sizeof(s->eeprom_data)); + s->eeprom_data[0] = 0x00; + s->eeprom_data[1] = 0x00; + s->eeprom_data[2] = 0xF8; + if (mac & 0xff000000) { + /* Generate new local MAC. */ + s->eeprom_data[3] = random_generate(); + s->eeprom_data[4] = random_generate(); + s->eeprom_data[5] = random_generate(); + mac = (((int) s->eeprom_data[3]) << 16); + mac |= (((int) s->eeprom_data[4]) << 8); + mac |= ((int) s->eeprom_data[5]); + device_set_config_mac("mac", mac); + } else { + s->eeprom_data[3] = (mac >> 16) & 0xff; + s->eeprom_data[4] = (mac >> 8) & 0xff; + s->eeprom_data[5] = (mac & 0xff); + } } - /*Controller_0 Device_Number*/ - s->eeprom_data[26] = 0x00; - - /*Controller_0 Info Leaf_Offset*/ - s->eeprom_data[27] = 0x1e; - s->eeprom_data[28] = 0x00; - - /*Selected Connection Type, Powerup AutoSense and Dynamic AutoSense if the board supports it*/ - s->eeprom_data[30] = 0x00; - s->eeprom_data[31] = 0x08; - - if (info->local) { - /*General Purpose Control*/ - s->eeprom_data[32] = 0xff; - - /*Block Count*/ - s->eeprom_data[33] = 0x01; - - /*Extended Format (first part)*/ - /*Length (0:6) and Format Indicator (7)*/ - s->eeprom_data[34] = 0x81; - - /*Block Type (first part)*/ - s->eeprom_data[35] = 0x01; - - /*Extended Format (second part) - Block Type 0 for 21140*/ - /*Length (0:6) and Format Indicator (7)*/ - s->eeprom_data[36] = 0x85; - - /*Block Type (second part)*/ - s->eeprom_data[37] = 0x00; - - /*Media Code (0:5), EXT (6), Reserved (7)*/ - s->eeprom_data[38] = 0x01; - - /*General Purpose Data*/ - s->eeprom_data[39] = 0x00; - - /*Command*/ - s->eeprom_data[40] = 0x00; - s->eeprom_data[41] = 0x00; - } else { - /*Block Count*/ - s->eeprom_data[32] = 0x01; - - /*Extended Format - Block Type 2 for 21142/21143*/ - /*Length (0:6) and Format Indicator (7)*/ - s->eeprom_data[33] = 0x86; - - /*Block Type*/ - s->eeprom_data[34] = 0x02; - - /*Media Code (0:5), EXT (6), Reserved (7)*/ - s->eeprom_data[35] = 0x01; - - /*General Purpose Control*/ - s->eeprom_data[36] = 0xff; - s->eeprom_data[37] = 0xff; - - /*General Purpose Data*/ - s->eeprom_data[38] = 0x00; - s->eeprom_data[39] = 0x00; - } - - s->eeprom_data[126] = tulip_srom_crc(s->eeprom_data) & 0xff; - s->eeprom_data[127] = tulip_srom_crc(s->eeprom_data) >> 8; - params.nwords = 64; params.default_content = (uint16_t *) s->eeprom_data; params.filename = filename; @@ -1592,3 +1639,17 @@ const device_t dec_tulip_21140_vpc_device = { .force_redraw = NULL, .config = dec_tulip_21140_config }; + +const device_t dec_tulip_21040_device = { + .name = "DEC DE-435 EtherWorks Turbo (DECchip 21040 \"Tulip\")", + .internal_name = "dec_21040_tulip", + .flags = DEVICE_PCI, + .local = 3, + .init = nic_init, + .close = nic_close, + .reset = tulip_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = dec_tulip_21143_config +}; diff --git a/src/network/network.c b/src/network/network.c index 38af502b2..4d11ba955 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -136,6 +136,7 @@ static const device_t *net_cards[] = { &rtl8139c_plus_device, &dec_tulip_21140_device, &dec_tulip_21140_vpc_device, + &dec_tulip_21040_device, &pcnet_am79c960_vlb_device, NULL }; From 4621e6b8a49902071dc34d2195a230384f1fc4a8 Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Fri, 19 Jan 2024 12:34:56 +0100 Subject: [PATCH 314/936] Add Northgate Computer Systems ELEGANCE PENTIUM 90 --- src/include/86box/machine.h | 1 + src/machine/m_at_socket5.c | 30 ++++++++++++++++++++++++++++ src/machine/machine_table.c | 39 +++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index f730bbdd7..358a7af07 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -632,6 +632,7 @@ extern int machine_at_hawk_init(const machine_t *); extern int machine_at_pat54pv_init(const machine_t *); extern int machine_at_hot543_init(const machine_t *); +extern int machine_at_ncselp90_init(const machine_t *); extern int machine_at_p54sp4_init(const machine_t *); extern int machine_at_sq588_init(const machine_t *); diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 0b67976af..f8cda984d 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -349,6 +349,36 @@ machine_at_hot543_init(const machine_t *model) return ret; } +int +machine_at_ncselp90_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ncselp90/elegancep90.bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); + + device_add(&opti5x7_pci_device); + device_add(&opti822_device); + device_add(&sst_flash_29ee010_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&ide_opti611_vlb_device); + device_add(&fdc37c665_ide_sec_device); + device_add(&ide_vlb_2ch_device); + + return ret; +} + int machine_at_p54sp4_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 099ef62ea..f2ac6e818 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -9501,6 +9501,45 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + { + .name = "[OPTi 597] Northgate Computer Systems Elegance Pentium 90", + .internal_name = "ncselp90", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_OPTI_547_597, + .init = machine_at_ncselp90_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 = 3520, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PCIV | MACHINE_PS2, + .flags = MACHINE_APM | MACHINE_IDE_DUAL | MACHINE_SUPER_IO, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* SiS 85C50x */ /* This has an AMIKey-2, which is an updated version of type 'H'. */ From c9dab454b7d168db297e59f945947a1ee65d5234 Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Fri, 19 Jan 2024 13:37:24 +0100 Subject: [PATCH 315/936] Fix Anigma BAT4ip3e IDE --- src/machine/m_at_386dx_486.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 9ca59577d..707c9c0c0 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1258,10 +1258,9 @@ machine_at_bat4ip3e_init(const machine_t *model) device_add(&phoenix_486_jumper_pci_device); device_add(&keyboard_ps2_pci_device); - device_add(&ide_cmd640_pci_single_channel_device); - device_add(&fdc37c665_ide_sec_device); device_add(&i420ex_device); - + device_add(&ide_cmd640_pci_device); + device_add(&fdc37c665_device); return ret; } From 9eff65a6f74e6c63cdf409ddba7941a5be905004 Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Fri, 19 Jan 2024 14:30:59 +0100 Subject: [PATCH 316/936] Olivetti M4-5xx fixes. --- src/machine/m_at_386dx_486.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 707c9c0c0..f5d31b0c2 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -749,14 +749,12 @@ machine_at_m45xx_init(const machine_t *model) pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x15, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x16, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x12, PCI_CARD_IDE, 0xFF, 0, 0, 0); - pci_register_slot(0x11, PCI_CARD_VIDEO, 2, 0, 0, 0); device_add(&opti802g_pci_device); device_add(&opti822_device); device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c665_device); - device_add(&ide_vlb_device); + device_add(&ide_vlb_2ch_device); device_add(&intel_flash_bxt_device); // Just in case, no idea if it has it or not return ret; From d3bcd9646be27ea491307cec3a8799cde8cee6e3 Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Fri, 19 Jan 2024 14:57:51 +0100 Subject: [PATCH 317/936] Add Teknor TEK-932. --- src/include/86box/machine.h | 1 + src/machine/m_at_socket5.c | 30 ++++++++++++++++++++++++++++ src/machine/machine_table.c | 40 +++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 358a7af07..7a640e8a3 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -622,6 +622,7 @@ extern int machine_at_plato_init(const machine_t *); extern int machine_at_dellplato_init(const machine_t *); extern int machine_at_ambradp90_init(const machine_t *); extern int machine_at_430nx_init(const machine_t *); +extern int machine_at_tek932_init(const machine_t *); extern int machine_at_acerv30_init(const machine_t *); extern int machine_at_apollo_init(const machine_t *); diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index f8cda984d..cb4818cc0 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -117,6 +117,36 @@ machine_at_430nx_init(const machine_t *model) return ret; } +int +machine_at_tek932_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/tek932/B932_019.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_2 | PCI_CAN_SWITCH_TYPE); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&i430nx_device); + device_add(&sio_zb_device); + device_add(&fdc37c665_ide_device); + device_add(&ide_vlb_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + int machine_at_acerv30_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index f2ac6e818..46d5a5be3 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -9212,6 +9212,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has AMI MegaKey KBC firmware. */ + { + .name = "[i430NX] Teknor TEK-932", + .internal_name = "tek932", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_INTEL_430NX, + .init = machine_at_tek932_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 = 60000000, + .max_bus = 66666667, + .min_voltage = 3520, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 1.5 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_IDE | MACHINE_APM | MACHINE_ACPI, + .ram = { + .min = 2048, + .max = 262144, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* 430FX */ /* Uses an ACER/NEC 90M002A (UPD82C42C, 8042 clone) with unknown firmware (V5.0). */ From 3a75b395ce12a957bafd7905e0903441c13ebdde Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Fri, 19 Jan 2024 17:53:36 +0100 Subject: [PATCH 318/936] Add FIC PT-2000. (Please note that the contributed ROM for this machine is not the latest BIOS, because the sole reason this machine was chosen for addition was its unique 4.50GP AwardBIOS, even though later it got updates to the more common 4.50PG AwardBIOS.) --- src/include/86box/machine.h | 1 + src/machine/m_at_socket5.c | 29 +++++++++++++++++++++++++++ src/machine/machine_table.c | 40 +++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 7a640e8a3..fc51ba629 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -629,6 +629,7 @@ extern int machine_at_apollo_init(const machine_t *); extern int machine_at_zappa_init(const machine_t *); extern int machine_at_powermatev_init(const machine_t *); extern int machine_at_hawk_init(const machine_t *); +extern int machine_at_pt2000_init(const machine_t *); extern int machine_at_pat54pv_init(const machine_t *); diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index cb4818cc0..4a6d00f76 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -327,6 +327,35 @@ machine_at_hawk_init(const machine_t *model) return ret; } +int +machine_at_pt2000_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ficpt2000/PT2000_v1.01.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&i430fx_device); + device_add(&piix_device); + device_add(&pc87332_398_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + int machine_at_pat54pv_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 46d5a5be3..38e498f6e 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -9456,6 +9456,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* KBC On-Chip the VT82C406MV. */ + { + .name = "[i430FX] FIC PT-2000", + .internal_name = "pt2000", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_pt2000_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 = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* OPTi 596/597 */ /* This uses an AMI KBC firmware in PS/2 mode (it sends command A5 with the From aa77a484c0254c4a0a13545c80f8605defa23a06 Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Fri, 19 Jan 2024 20:35:50 +0100 Subject: [PATCH 319/936] Add AMI Atlas PCI-II. --- src/include/86box/machine.h | 1 + src/machine/m_at_socket7_3v.c | 29 +++++++++++++++++++++++++ src/machine/machine_table.c | 40 +++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index fc51ba629..3bb697888 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -665,6 +665,7 @@ extern int machine_at_gw2kte_init(const machine_t *); extern int machine_at_ap5s_init(const machine_t *); extern int machine_at_ms5124_init(const machine_t *); +extern int machine_at_amis727_init(const machine_t *); extern int machine_at_vectra54_init(const machine_t *); /* m_at_socket7.c */ diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index 0e420aa3b..9410b656d 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -797,6 +797,35 @@ machine_at_ms5124_init(const machine_t *model) return ret; } +int +machine_at_amis727_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/amis727/S727p.rom", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0xFE, 0xFF, 0, 0); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); + + device_add(&sis_5511_device); + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + int machine_at_vectra54_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 38e498f6e..dd737593a 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -10608,6 +10608,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has Megakey 'R' KBC */ + { + .name = "[SiS 5511] AMI Atlas PCI-II", + .internal_name = "AMIS727", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_SIS_5511, + .init = machine_at_amis727_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 = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Socket 7 (Dual Voltage) machines */ /* 430HX */ From e986047c2c38748b6a8a50ebb2a5999c769f3651 Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Fri, 19 Jan 2024 22:06:00 +0100 Subject: [PATCH 320/936] Add Radisys EPC-2102 --- src/include/86box/machine.h | 1 + src/machine/m_at_socket7.c | 29 +++++++++++++++++++++++++++ src/machine/machine_table.c | 40 +++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 3bb697888..ac1aa14a7 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -678,6 +678,7 @@ 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 *); +extern int machine_at_epc2102_init(const machine_t *); extern int machine_at_ap5vm_init(const machine_t *); extern int machine_at_p55tvp4_init(const machine_t *); diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index d61e4ba6e..a51d767cb 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -433,6 +433,35 @@ machine_at_p65up5_cp55t2d_init(const machine_t *model) return ret; } +int +machine_at_epc2102_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/epc2102/P5000HX.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&i430hx_device); + device_add(&piix3_device); + device_add(&keyboard_ps2_pci_device); + device_add(&i82091aa_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + int machine_at_p55tvp4_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index dd737593a..b799204d8 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -11016,6 +11016,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Unknown PS/2 KBC. */ + { + .name = "[i430HX] Radisys EPC-2102", + .internal_name = "epc2102", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430HX, + .init = machine_at_epc2102_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 = 83333333, + .min_voltage = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* 430VX */ /* This has the VIA VT82C42N KBC. */ From 7b387580724ff165486d82430dc997f4e1a8ef2a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 20 Jan 2024 17:06:46 +0600 Subject: [PATCH 321/936] Fix EEPROM reading in DECchip 21040 --- src/network/net_eeprom_nmc93cxx.c | 2 ++ src/network/net_tulip.c | 43 +++++++++++++++++-------------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/network/net_eeprom_nmc93cxx.c b/src/network/net_eeprom_nmc93cxx.c index 1e2fd1645..681263717 100644 --- a/src/network/net_eeprom_nmc93cxx.c +++ b/src/network/net_eeprom_nmc93cxx.c @@ -263,6 +263,8 @@ nmc93cxx_eeprom_close(void *priv) uint16_t * nmc93cxx_eeprom_data(nmc93cxx_eeprom_t *eeprom) { + if (UNLIKELY(!eeprom)) + return NULL; /* Get EEPROM data array. */ return &eeprom->dev.data[0]; } diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index c81fbc3f9..3dab8d915 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -324,7 +324,7 @@ struct TULIPState { uint32_t mii_bitcnt; /* 21040 ROM read address. */ - uint32_t rom_read_addr; + uint8_t rom_read_addr; uint32_t current_rx_desc; uint32_t current_tx_desc; @@ -670,7 +670,7 @@ static uint32_t tulip_csr9_read(TULIPState *s) { if (s->device_info->local == 3) { - return ((uint8_t*)nmc93cxx_eeprom_data(s->eeprom))[s->rom_read_addr++]; + return s->eeprom_data[s->rom_read_addr++]; } if (s->csr[9] & CSR9_SR) { if (nmc93cxx_eeprom_read(s->eeprom)) { @@ -717,7 +717,7 @@ tulip_read(uint32_t addr, void *opaque) data = s->csr[addr >> 3]; break; } - //pclog("[%04X:%08X]: CSR9 read %02x, data = %08x.\n", CS, cpu_state.pc, addr, data); + pclog("[%04X:%08X]: CSR9 read %02x, data = %08x.\n", CS, cpu_state.pc, addr, data); return data; } @@ -906,7 +906,7 @@ tulip_write(uint32_t addr, uint32_t data, void *opaque) TULIPState *s = opaque; addr &= 127; - //pclog("[%04X:%08X]: Tulip Write >> 3: %02x, val=%08x.\n", CS, cpu_state.pc, addr >> 3, data); + pclog("[%04X:%08X]: Tulip Write >> 3: %02x, val=%08x.\n", CS, cpu_state.pc, addr >> 3, data); switch (addr) { case CSR(0): s->csr[0] = data; @@ -1266,11 +1266,11 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { TULIPState *s = (TULIPState *) priv; - //pclog("PCI write=%02x, ret=%02x.\n", addr, val); + pclog("PCI write=%02x, ret=%02x.\n", addr, val); switch (addr) { case 0x04: s->pci_conf[0x04] = val & 0x07; - //pclog("PCI write cmd: IOBase=%04x, MMIOBase=%08x, val=%02x.\n", s->PCIBase, s->MMIOBase, s->pci_conf[0x04]); + pclog("PCI write cmd: IOBase=%04x, MMIOBase=%08x, val=%02x.\n", s->PCIBase, s->MMIOBase, s->pci_conf[0x04]); io_removehandler(s->PCIBase, 128, tulip_readb_io, tulip_readw_io, tulip_readl_io, tulip_writeb_io, tulip_writew_io, tulip_writel_io, @@ -1280,7 +1280,7 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) tulip_readb_io, tulip_readw_io, tulip_readl_io, tulip_writeb_io, tulip_writew_io, tulip_writel_io, priv); - //pclog("PCI write cmd: IOBase=%04x, MMIOBase=%08x, val=%02x.\n", s->PCIBase, s->MMIOBase, s->pci_conf[0x04]); + pclog("PCI write cmd: IOBase=%04x, MMIOBase=%08x, val=%02x.\n", s->PCIBase, s->MMIOBase, s->pci_conf[0x04]); mem_mapping_disable(&s->memory); if ((s->MMIOBase != 0) && (val & PCI_COMMAND_MEM)) mem_mapping_set_addr(&s->memory, s->MMIOBase, 128); @@ -1300,7 +1300,7 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) tulip_pci_bar[0].addr &= 0xffffff80; s->PCIBase = tulip_pci_bar[0].addr; if (s->pci_conf[0x4] & PCI_COMMAND_IO) { - //pclog("PCI write=%02x, base=%04x, io?=%x.\n", addr, s->PCIBase, s->pci_conf[0x4] & PCI_COMMAND_IO); + pclog("PCI write=%02x, base=%04x, io?=%x.\n", addr, s->PCIBase, s->pci_conf[0x4] & PCI_COMMAND_IO); if (s->PCIBase != 0) io_sethandler(s->PCIBase, 128, tulip_readb_io, tulip_readw_io, tulip_readl_io, @@ -1317,7 +1317,7 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) tulip_pci_bar[1].addr &= 0xffffff80; s->MMIOBase = tulip_pci_bar[1].addr; if (s->pci_conf[0x4] & PCI_COMMAND_MEM) { - //pclog("PCI write=%02x, mmiobase=%08x, mmio?=%x.\n", addr, s->PCIBase, s->pci_conf[0x4] & PCI_COMMAND_MEM); + pclog("PCI write=%02x, mmiobase=%08x, mmio?=%x.\n", addr, s->PCIBase, s->pci_conf[0x4] & PCI_COMMAND_MEM); if (s->MMIOBase != 0) mem_mapping_set_addr(&s->memory, s->MMIOBase, 128); } @@ -1510,6 +1510,9 @@ nic_init(const device_t *info) } else { /* 21040 is supposed to only have MAC address in its serial ROM if Linux is correct. */ memset(s->eeprom_data, 0, sizeof(s->eeprom_data)); + /* See if we have a local MAC address configured. */ + mac = device_get_config_mac("mac", -1); + /*DEC OID*/ s->eeprom_data[0] = 0x00; s->eeprom_data[1] = 0x00; s->eeprom_data[2] = 0xF8; @@ -1529,14 +1532,16 @@ nic_init(const device_t *info) } } - params.nwords = 64; - params.default_content = (uint16_t *) s->eeprom_data; - params.filename = filename; - snprintf(filename, sizeof(filename), "nmc93cxx_eeprom_%s_%d.nvr", info->internal_name, device_get_instance()); - s->eeprom = device_add_parameters(&nmc93cxx_device, ¶ms); - if (!s->eeprom) { - free(s); - return NULL; + if (info->local != 3) { + params.nwords = 64; + params.default_content = (uint16_t *) s->eeprom_data; + params.filename = filename; + snprintf(filename, sizeof(filename), "nmc93cxx_eeprom_%s_%d.nvr", info->internal_name, device_get_instance()); + s->eeprom = device_add_parameters(&nmc93cxx_device, ¶ms); + if (!s->eeprom) { + free(s); + return NULL; + } } tulip_pci_bar[0].addr_regs[0] = 1; @@ -1551,11 +1556,11 @@ nic_init(const device_t *info) tulip_pci_bar[2].addr = 0; mem_mapping_disable(&s->bios_rom.mapping); - eeprom_data = (uint8_t *) &nmc93cxx_eeprom_data(s->eeprom)[0]; + eeprom_data = (info->local == 3) ? s->eeprom_data : (uint8_t *) &nmc93cxx_eeprom_data(s->eeprom)[0]; //pclog("EEPROM Data Format=%02x, Count=%02x, MAC=%02x:%02x:%02x:%02x:%02x:%02x.\n", eeprom_data[0x12], eeprom_data[0x13], eeprom_data[0x14], eeprom_data[0x15], eeprom_data[0x16], eeprom_data[0x17], eeprom_data[0x18], eeprom_data[0x19]); memcpy(s->mii_regs, tulip_mdi_default, sizeof(tulip_mdi_default)); - s->nic = network_attach(s, &eeprom_data[20], tulip_receive, NULL); + s->nic = network_attach(s, &eeprom_data[(info->local == 3) ? 0 : 20], tulip_receive, NULL); pci_add_card(PCI_ADD_NORMAL, tulip_pci_read, tulip_pci_write, s, &s->pci_slot); tulip_reset(s); return s; From 530fafe78a8d9e46cddaf71c7439cbcd51891a35 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 20 Jan 2024 17:27:24 +0100 Subject: [PATCH 322/936] Minor keyboard-related fixes. --- src/86box.c | 3 ++- src/device/kbc_at_dev.c | 8 ++++---- src/device/keyboard_at.c | 21 +++++++++++++++++++-- src/include/86box/keyboard.h | 1 + 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/86box.c b/src/86box.c index f72b066a5..8218c208c 100644 --- a/src/86box.c +++ b/src/86box.c @@ -30,10 +30,10 @@ #include #include #include +#include #ifndef _WIN32 # include -# include #endif #ifdef __APPLE__ # include @@ -1048,6 +1048,7 @@ pc_send_ca(uint16_t sc) keyboard_input(1, 0x1D); /* Ctrl key pressed */ keyboard_input(1, 0x38); /* Alt key pressed */ keyboard_input(1, sc); + usleep(50000); keyboard_input(0, sc); keyboard_input(0, 0x38); /* Alt key released */ keyboard_input(0, 0x1D); /* Ctrl key released */ diff --git a/src/device/kbc_at_dev.c b/src/device/kbc_at_dev.c index 1c1a0e91a..c1041e6e1 100644 --- a/src/device/kbc_at_dev.c +++ b/src/device/kbc_at_dev.c @@ -119,12 +119,13 @@ kbc_at_dev_poll(void *priv) break; case DEV_STATE_MAIN_2: /* Output from scan queue if needed and then return to main loop #1. */ - if (*dev->scan && (dev->port->out_new == -1) && (dev->queue_start != dev->queue_end)) { + if (!dev->ignore && *dev->scan && (dev->port->out_new == -1) && + (dev->queue_start != dev->queue_end)) { kbc_at_dev_log("%s: %02X (DATA) on channel 1\n", dev->name, dev->queue[dev->queue_start]); dev->port->out_new = dev->queue[dev->queue_start]; dev->queue_start = (dev->queue_start + 1) & dev->fifo_mask; } - if (!(*dev->scan) || dev->port->wantcmd) + if (dev->ignore || !(*dev->scan) || dev->port->wantcmd) dev->state = DEV_STATE_MAIN_1; break; case DEV_STATE_MAIN_OUT: @@ -199,8 +200,7 @@ kbc_at_dev_init(uint8_t inst) { atkbc_dev_t *dev; - dev = (atkbc_dev_t *) malloc(sizeof(atkbc_dev_t)); - memset(dev, 0x00, sizeof(atkbc_dev_t)); + dev = (atkbc_dev_t *) calloc(1, sizeof(atkbc_dev_t)); dev->port = kbc_at_ports[inst]; diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index f8eddb931..7accb2fd6 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -523,10 +523,12 @@ static void add_data_kbd(uint16_t val) { atkbc_dev_t *dev = SavedKbd; - uint8_t fake_shift[4]; + uint8_t fake_shift[4] = { 0 }; uint8_t num_lock = 0; uint8_t shift_states = 0; + dev->ignore = 1; + keyboard_get_states(NULL, &num_lock, NULL); shift_states = keyboard_get_shift() & STATE_SHIFT_MASK; @@ -541,12 +543,14 @@ add_data_kbd(uint16_t val) /* Num lock on and no shifts are pressed, send non-inverted fake shift. */ switch (keyboard_mode & 0x02) { case 1: + keyboard_at_log("E0 2A\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0x2a; add_data_vals(dev, fake_shift, 2); break; case 2: + keyboard_at_log("E0 12\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0x12; add_data_vals(dev, fake_shift, 2); @@ -562,12 +566,14 @@ add_data_kbd(uint16_t val) /* Num lock off and left shift pressed. */ switch (keyboard_mode & 0x02) { case 1: + keyboard_at_log("E0 AA\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0xaa; add_data_vals(dev, fake_shift, 2); break; case 2: + keyboard_at_log("E0 F0 12\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0xf0; fake_shift[2] = 0x12; @@ -583,12 +589,14 @@ add_data_kbd(uint16_t val) /* Num lock off and right shift pressed. */ switch (keyboard_mode & 0x02) { case 1: + keyboard_at_log("E0 B6\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0xb6; add_data_vals(dev, fake_shift, 2); break; case 2: + keyboard_at_log("E0 F0 59\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0xf0; fake_shift[2] = 0x59; @@ -614,12 +622,14 @@ add_data_kbd(uint16_t val) /* Num lock on and no shifts are pressed, send non-inverted fake shift. */ switch (keyboard_mode & 0x02) { case 1: + keyboard_at_log("E0 AA\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0xaa; add_data_vals(dev, fake_shift, 2); break; case 2: + keyboard_at_log("E0 F0 12\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0xf0; fake_shift[2] = 0x12; @@ -636,12 +646,14 @@ add_data_kbd(uint16_t val) /* Num lock off and left shift pressed. */ switch (keyboard_mode & 0x02) { case 1: + keyboard_at_log("E0 2A\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0x2a; add_data_vals(dev, fake_shift, 2); break; case 2: + keyboard_at_log("E0 12\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0x12; add_data_vals(dev, fake_shift, 2); @@ -656,12 +668,14 @@ add_data_kbd(uint16_t val) /* Num lock off and right shift pressed. */ switch (keyboard_mode & 0x02) { case 1: + keyboard_at_log("E0 36\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0x36; add_data_vals(dev, fake_shift, 2); break; case 2: + keyboard_at_log("E0 59\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0x59; add_data_vals(dev, fake_shift, 2); @@ -680,6 +694,8 @@ add_data_kbd(uint16_t val) kbc_at_dev_queue_add(dev, val, 1); break; } + + dev->ignore = 0; } void @@ -860,7 +876,8 @@ keyboard_at_write(void *priv) case 0xf5: /* set defaults and disable keyboard */ case 0xf6: /* set defaults */ - keyboard_at_log("%s: set defaults%s\n", (val == 0xf6) ? "" : " and disable keyboard"); + keyboard_at_log("%s: set defaults%s\n", + dev->name, (val == 0xf6) ? "" : " and disable keyboard"); keyboard_scan = !(val & 0x01); keyboard_at_log("%s: val = %02X, keyboard_scan = %i\n", dev->name, val, keyboard_scan); diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index a4b079760..759fad714 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -79,6 +79,7 @@ typedef struct atkbc_dev_t { int y; int z; int b; + int ignore; int *scan; From f59bb3373389d8ce196bed8f5843249a8216d024 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 20 Jan 2024 18:11:21 +0100 Subject: [PATCH 323/936] Added the TriGem Richmond. --- src/chipset/intel_piix.c | 11 +++++++++- src/include/86box/machine.h | 1 + src/machine/m_at_socket7.c | 32 +++++++++++++++++++++++++++++ src/machine/machine_table.c | 40 +++++++++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index 49d720d8b..1f95c28b3 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -1578,7 +1578,16 @@ piix_init(const device_t *info) dev->acpi = device_add(&acpi_intel_device); acpi_set_slot(dev->acpi, dev->pci_slot); acpi_set_nvr(dev->acpi, dev->nvr); - acpi_set_gpireg2_default(dev->acpi, (dev->type > 4) ? 0xf1 : 0xdd); + /* + TriGem Richmond: + - Bit 5: Manufacturing jumper, must be set; + - Bit 4: CMOS clear jumper, must be clear; + - Bit 0: Password switch, must be clear. + */ + if (!strcmp(machine_get_internal_name(), "richmond")) + acpi_set_gpireg2_default(dev->acpi, 0xee); + else + acpi_set_gpireg2_default(dev->acpi, (dev->type > 4) ? 0xf1 : 0xdd); acpi_set_trap_update(dev->acpi, piix_trap_update, dev); dev->ddma = device_add(&ddma_device); diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index b02b64882..9ca9a84be 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -679,6 +679,7 @@ extern int machine_at_thunderbolt_init(const machine_t *); extern int machine_at_mb540n_init(const machine_t *); extern int machine_at_56a5_init(const machine_t *); extern int machine_at_p5mms98_init(const machine_t *); +extern int machine_at_richmond_init(const machine_t *); extern int machine_at_ficva502_init(const machine_t *); diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index d61e4ba6e..c26ad3889 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -1014,6 +1014,38 @@ machine_at_p5mms98_init(const machine_t *model) return ret; } +int +machine_at_richmond_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/richmond/RICHMOND.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); /* PIIX4 */ + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&i430tx_device); + device_add(&piix4_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&it8671f_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); + device_add(&lm78_device); /* fans: Thermal, CPU, Chassis; temperature: unused */ + device_add(&lm75_1_4a_device); /* temperature: CPU */ + + return ret; +} + int machine_at_ficva502_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index ac7e767b5..8a8e1b2ff 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -10950,6 +10950,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* [TEST] Has AMIKey 'H' KBC firmware. */ + { + .name = "[i430TX] TriGem Richmond", + .internal_name = "richmond", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_richmond_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 = 2100, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .ram = { + .min = 8192, + .max = 262144, + .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 = NULL, + .net_device = NULL + }, /* Apollo VPX */ /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA From 485e73d4da7e2182739fb35ee0edb9da86e786bb Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 21 Jan 2024 01:55:05 +0100 Subject: [PATCH 324/936] Added the Gateway Tomahawk (430TX machine). --- src/acpi.c | 4 ++ src/chipset/intel_4x0.c | 2 + src/include/86box/flash.h | 2 + src/include/86box/machine.h | 1 + src/include/86box/net_pcnet.h | 1 + src/machine/m_at_socket7.c | 44 ++++++++++++++++++++ src/machine/machine_table.c | 41 +++++++++++++++++++ src/mem/sst_flash.c | 75 ++++++++++++++++++++++++++++++----- src/network/net_pcnet.c | 21 +++++++++- 9 files changed, 179 insertions(+), 12 deletions(-) diff --git a/src/acpi.c b/src/acpi.c index 9521d5337..ddd2ffbe7 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -1669,6 +1669,10 @@ acpi_reset(void *priv) acpi_power_on = 0; } + /* The Gateway Tomahawk requires the LID polarity bit to be set. */ + if (!strcmp(machine_get_internal_name(), "tomahawk")) + dev->regs.glbctl |= 0x02000000; + acpi_rtc_status = 0; acpi_update_irq(dev); diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index 1e4158b94..a1f923e49 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -1522,6 +1522,8 @@ i4x0_read(int func, int addr, void *priv) with the addition of bits 3 and 0. */ if ((func == 0) && (addr == 0x93) && ((dev->type == INTEL_440FX) || (dev->type == INTEL_440LX) || (dev->type == INTEL_440EX))) ret = (ret & 0xf9) | (pci_read(0x0cf9, NULL) & 0x06); + else if ((func == 0) && (addr == 0x52) && (dev->type == INTEL_430TX) && !strcmp(machine_get_internal_name(), "tomahawk")) + ret = 0xb2; } return ret; diff --git a/src/include/86box/flash.h b/src/include/86box/flash.h index d161d416b..6f0e1ff15 100644 --- a/src/include/86box/flash.h +++ b/src/include/86box/flash.h @@ -60,4 +60,6 @@ extern const device_t sst_flash_49lf080_device; extern const device_t sst_flash_49lf016_device; extern const device_t sst_flash_49lf160_device; +extern const device_t amd_flash_29f020a_device; + #endif /*EMU_FLASH_H*/ diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 9ca9a84be..faed59dae 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -680,6 +680,7 @@ extern int machine_at_mb540n_init(const machine_t *); extern int machine_at_56a5_init(const machine_t *); extern int machine_at_p5mms98_init(const machine_t *); extern int machine_at_richmond_init(const machine_t *); +extern int machine_at_tomahawk_init(const machine_t *); extern int machine_at_ficva502_init(const machine_t *); diff --git a/src/include/86box/net_pcnet.h b/src/include/86box/net_pcnet.h index ccdc7e832..23ee643ed 100644 --- a/src/include/86box/net_pcnet.h +++ b/src/include/86box/net_pcnet.h @@ -36,5 +36,6 @@ extern const device_t pcnet_am79c960_vlb_device; extern const device_t pcnet_am79c961_device; extern const device_t pcnet_am79c970a_device; extern const device_t pcnet_am79c973_device; +extern const device_t pcnet_am79c973_onboard_device; #endif /*NET_PCNET_H*/ diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index c26ad3889..46b95ce76 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -43,6 +43,8 @@ #include <86box/fdc.h> #include <86box/nvr.h> #include <86box/scsi_ncr53c8xx.h> +#include <86box/thread.h> +#include <86box/network.h> int machine_at_acerv35n_init(const machine_t *model) @@ -1046,6 +1048,48 @@ machine_at_richmond_init(const machine_t *model) return ret; } +int +machine_at_tomahawk_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/tomahawk/0AAGT046.ROM", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); /* PIIX4 */ + pci_register_slot(0x0D, PCI_CARD_VIDEO, 3, 0, 0, 0); + pci_register_slot(0x0E, PCI_CARD_NETWORK, 4, 0, 0, 0); + pci_register_slot(0x06, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x07, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x08, PCI_CARD_NORMAL, 3, 4, 1, 2); + device_add(&i430tx_device); + device_add(&piix4_device); + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&fdc37c67x_device); + device_add(&amd_flash_29f020a_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); + device_add(&lm78_device); /* fans: Thermal, CPU, Chassis; temperature: unused */ + device_add(&lm75_1_4a_device); /* temperature: CPU */ + + if ((gfxcard[0] == VID_INTERNAL) && machine_get_vid_device(machine)) + device_add(machine_get_vid_device(machine)); + + if ((sound_card_current[0] == SOUND_INTERNAL) && machine_get_snd_device(machine)) + device_add(machine_get_snd_device(machine)); + + if ((net_cards_conf[0].device_num == NET_INTERNAL) && machine_get_net_device(machine)) + device_add(machine_get_net_device(machine)); + + return ret; +} + int machine_at_ficva502_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 8a8e1b2ff..7406cce30 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -33,6 +33,7 @@ #include <86box/sound.h> #include <86box/video.h> #include <86box/plat_unused.h> +#include <86box/net_pcnet.h> // Temporarily here till we move everything out into the right files extern const device_t pcjr_device; @@ -10708,6 +10709,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* [TEST] Has AMI Megakey '5' KBC firmware on the SM(S)C FDC37C67x Super I/O chip. */ + { + .name = "[i430TX] Gateway Tomahawk", + .internal_name = "tomahawk", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_tomahawk_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 = 2100, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_NIC, + .ram = { + .min = 8192, + .max = 262144, + .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 = &s3_trio64v2_dx_onboard_pci_device, + .snd_device = &cs4236b_device, + .net_device = &pcnet_am79c973_onboard_device + }, #if defined(DEV_BRANCH) && defined(USE_AN430TX) /* This has the Phoenix MultiKey KBC firmware. */ { diff --git a/src/mem/sst_flash.c b/src/mem/sst_flash.c index 472a042d1..cd6ec7cd9 100644 --- a/src/mem/sst_flash.c +++ b/src/mem/sst_flash.c @@ -131,6 +131,9 @@ static char flash_path[1024]; #define W29C020 0x4500 #define W29C040 0x4600 +#define AMD 0x01 /* AMD Manufacturer's ID */ +#define AMD29F020A 0xb000 + #define SIZE_512K 0x010000 #define SIZE_1M 0x020000 #define SIZE_2M 0x040000 @@ -144,12 +147,32 @@ sst_sector_erase(sst_t *dev, uint32_t addr) { uint32_t base = addr & (dev->mask & ~0xfff); - if ((base < 0x2000) && (dev->bbp_first_8k & 0x01)) - return; - else if ((base >= (dev->size - 0x2000)) && (dev->bbp_last_8k & 0x01)) - return; + if (dev->manufacturer == AMD) { + base = addr & biosmask; + + if ((base >= 0x00000) && (base <= 0x0ffff)) + memset(&dev->array[0x00000], 0xff, 65536); + else if ((base >= 0x10000) && (base <= 0x1ffff)) + memset(&dev->array[0x10000], 0xff, 65536); + else if ((base >= 0x20000) && (base <= 0x2ffff)) + memset(&dev->array[0x20000], 0xff, 65536); + else if ((base >= 0x30000) && (base <= 0x37fff)) + memset(&dev->array[0x30000], 0xff, 32768); + else if ((base >= 0x38000) && (base <= 0x39fff)) + memset(&dev->array[0x38000], 0xff, 8192); + else if ((base >= 0x3a000) && (base <= 0x3bfff)) + memset(&dev->array[0x3a000], 0xff, 8192); + else if ((base >= 0x3c000) && (base <= 0x3ffff)) + memset(&dev->array[0x3c000], 0xff, 16384); + } else { + if ((base < 0x2000) && (dev->bbp_first_8k & 0x01)) + return; + else if ((base >= (dev->size - 0x2000)) && (dev->bbp_last_8k & 0x01)) + return; + + memset(&dev->array[base], 0xff, 4096); + } - memset(&dev->array[base], 0xff, 4096); dev->dirty = 1; } @@ -262,10 +285,14 @@ sst_read_id(uint32_t addr, void *priv) { const sst_t *dev = (sst_t *) priv; uint8_t ret = 0x00; + uint32_t mask = 0xffff; - if ((addr & 0xffff) == 0) + if (dev->manufacturer == AMD) + mask >>= 8; + + if ((addr & mask) == 0) ret = dev->manufacturer; - else if ((addr & 0xffff) == 1) + else if ((addr & mask) == 1) ret = dev->id; #ifdef UNKNOWN_FLASH else if ((addr & 0xffff) == 0x100) @@ -278,6 +305,9 @@ sst_read_id(uint32_t addr, void *priv) ret = dev->bbp_first_8k; else if (addr == 0x3fff2) ret = dev->bbp_last_8k; + } else if (dev->manufacturer == AMD) { + if ((addr & mask) == 2) + ret = 0x00; } return ret; @@ -300,6 +330,15 @@ static void sst_write(uint32_t addr, uint8_t val, void *priv) { sst_t *dev = (sst_t *) priv; + uint32_t mask = 0x7fff; + uint32_t addr0 = 0x5555; + uint32_t addr1 = 0x2aaa; + + if (dev->manufacturer == AMD) { + mask >>= 4; + addr0 >>= 4; + addr1 >>= 4; + } switch (dev->command_state) { case 0: @@ -309,7 +348,7 @@ sst_write(uint32_t addr, uint8_t val, void *priv) if (dev->id_mode) dev->id_mode = 0; dev->command_state = 0; - } else if (((addr & 0x7fff) == 0x5555) && (val == 0xaa)) + } else if (((addr & mask) == addr0) && (val == 0xaa)) dev->command_state++; else { if (!dev->is_39 && !dev->sdp && (dev->command_state == 0)) { @@ -326,7 +365,7 @@ sst_write(uint32_t addr, uint8_t val, void *priv) case 1: case 4: /* 2nd and 5th Bus Write Cycle */ - if (((addr & 0x7fff) == 0x2aaa) && (val == 0x55)) + if (((addr & mask) == addr1) && (val == 0x55)) dev->command_state++; else dev->command_state = 0; @@ -337,7 +376,7 @@ sst_write(uint32_t addr, uint8_t val, void *priv) if ((dev->command_state == 5) && (val == SST_SECTOR_ERASE)) { /* Sector erase - can be on any address. */ sst_new_command(dev, addr, val); - } else if ((addr & 0x7fff) == 0x5555) + } else if ((addr & mask) == addr0) sst_new_command(dev, addr, val); else dev->command_state = 0; @@ -481,6 +520,8 @@ sst_init(const device_t *info) dev->id = (info->local >> 8) & 0xff; dev->has_bbp = (dev->manufacturer == WINBOND) && ((info->local & 0xff00) >= W29C020); dev->is_39 = (dev->manufacturer == SST) && ((info->local & 0xff00) >= SST39SF512); + if (dev->manufacturer == AMD) + dev->is_39 = 1; dev->size = info->local & 0xffff0000; if ((dev->size == 0x20000) && (strstr(machine_get_internal_name_ex(machine), "xi8088")) && !xi8088_bios_128kb()) @@ -941,3 +982,17 @@ const device_t sst_flash_49lf160_device = { .force_redraw = NULL, .config = NULL }; + +const device_t amd_flash_29f020a_device = { + .name = "AMD 29F020a Flash BIOS", + .internal_name = "amd_flash_29f020a", + .flags = 0, + .local = AMD | AMD29F020A | SIZE_2M, + .init = sst_init, + .close = sst_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/network/net_pcnet.c b/src/network/net_pcnet.c index 02e3d32e7..9ddcfe29d 100644 --- a/src/network/net_pcnet.c +++ b/src/network/net_pcnet.c @@ -2896,7 +2896,7 @@ pcnet_init(const device_t *info) dev = malloc(sizeof(nic_t)); memset(dev, 0x00, sizeof(nic_t)); dev->name = info->name; - dev->board = info->local; + dev->board = info->local & 0xff; dev->is_pci = !!(info->flags & DEVICE_PCI); dev->is_vlb = !!(info->flags & DEVICE_VLB); @@ -2997,7 +2997,10 @@ pcnet_init(const device_t *info) pcnet_pci_regs[0x04] = 3; /* Add device to the PCI bus, keep its slot number. */ - pci_add_card(PCI_ADD_NORMAL, pcnet_pci_read, pcnet_pci_write, dev, &dev->pci_slot); + if (info->local & 0x0100) + pci_add_card(PCI_ADD_NETWORK, pcnet_pci_read, pcnet_pci_write, dev, &dev->pci_slot); + else + pci_add_card(PCI_ADD_NORMAL, pcnet_pci_read, pcnet_pci_write, dev, &dev->pci_slot); } else if (dev->board == DEV_AM79C961) { dev->dma_channel = -1; @@ -3269,3 +3272,17 @@ const device_t pcnet_am79c973_device = { .force_redraw = NULL, .config = pcnet_pci_config }; + +const device_t pcnet_am79c973_onboard_device = { + .name = "AMD PCnet-FAST III", + .internal_name = "pcnetfast_onboard", + .flags = DEVICE_PCI, + .local = DEV_AM79C973 | 0x0100, + .init = pcnet_init, + .close = pcnet_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = pcnet_pci_config +}; From 0da14beb397efa443bdf454760c6158bcd18a0fc Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 21 Jan 2024 13:28:29 +0600 Subject: [PATCH 325/936] Implement 21040 checksum algorithm --- src/network/net_tulip.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index 3dab8d915..6c01f58ee 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -717,7 +717,7 @@ tulip_read(uint32_t addr, void *opaque) data = s->csr[addr >> 3]; break; } - pclog("[%04X:%08X]: CSR9 read %02x, data = %08x.\n", CS, cpu_state.pc, addr, data); + //pclog("[%04X:%08X]: CSR9 read %02x, data = %08x.\n", CS, cpu_state.pc, addr, data); return data; } @@ -906,7 +906,7 @@ tulip_write(uint32_t addr, uint32_t data, void *opaque) TULIPState *s = opaque; addr &= 127; - pclog("[%04X:%08X]: Tulip Write >> 3: %02x, val=%08x.\n", CS, cpu_state.pc, addr >> 3, data); + //pclog("[%04X:%08X]: Tulip Write >> 3: %02x, val=%08x.\n", CS, cpu_state.pc, addr >> 3, data); switch (addr) { case CSR(0): s->csr[0] = data; @@ -1266,7 +1266,7 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { TULIPState *s = (TULIPState *) priv; - pclog("PCI write=%02x, ret=%02x.\n", addr, val); + //pclog("PCI write=%02x, ret=%02x.\n", addr, val); switch (addr) { case 0x04: s->pci_conf[0x04] = val & 0x07; @@ -1508,6 +1508,7 @@ nic_init(const device_t *info) s->eeprom_data[126] = tulip_srom_crc(s->eeprom_data) & 0xff; s->eeprom_data[127] = tulip_srom_crc(s->eeprom_data) >> 8; } else { + uint32_t checksum = 0; /* 21040 is supposed to only have MAC address in its serial ROM if Linux is correct. */ memset(s->eeprom_data, 0, sizeof(s->eeprom_data)); /* See if we have a local MAC address configured. */ @@ -1530,6 +1531,31 @@ nic_init(const device_t *info) s->eeprom_data[4] = (mac >> 8) & 0xff; s->eeprom_data[5] = (mac & 0xff); } + + /* Generate checksum. */ + checksum = (s->eeprom_data[0] * 256) | s->eeprom_data[1]; + checksum *= 2; + if (checksum > 65535) + checksum = checksum % 65535; + + /* 2nd pair. */ + checksum += (s->eeprom_data[2] * 256) | s->eeprom_data[3]; + if (checksum > 65535) + checksum = checksum % 65535; + checksum *= 2; + if (checksum > 65535) + checksum = checksum % 65535; + + /* 3rd pair. */ + checksum += (s->eeprom_data[4] * 256) | s->eeprom_data[5]; + if (checksum > 65535) + checksum = checksum % 65535; + + if (checksum >= 65535) + checksum = 0; + + s->eeprom_data[6] = (checksum >> 8) & 0xFF; + s->eeprom_data[7] = checksum & 0xFF; } if (info->local != 3) { From b241817c7b0a8bf35be6fb92b249c4bfbfc4602f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 21 Jan 2024 13:45:36 +0600 Subject: [PATCH 326/936] Disable more logging --- src/network/net_tulip.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index 6c01f58ee..a350d6662 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -1270,7 +1270,7 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) switch (addr) { case 0x04: s->pci_conf[0x04] = val & 0x07; - pclog("PCI write cmd: IOBase=%04x, MMIOBase=%08x, val=%02x.\n", s->PCIBase, s->MMIOBase, s->pci_conf[0x04]); + //pclog("PCI write cmd: IOBase=%04x, MMIOBase=%08x, val=%02x.\n", s->PCIBase, s->MMIOBase, s->pci_conf[0x04]); io_removehandler(s->PCIBase, 128, tulip_readb_io, tulip_readw_io, tulip_readl_io, tulip_writeb_io, tulip_writew_io, tulip_writel_io, @@ -1280,7 +1280,7 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) tulip_readb_io, tulip_readw_io, tulip_readl_io, tulip_writeb_io, tulip_writew_io, tulip_writel_io, priv); - pclog("PCI write cmd: IOBase=%04x, MMIOBase=%08x, val=%02x.\n", s->PCIBase, s->MMIOBase, s->pci_conf[0x04]); + //pclog("PCI write cmd: IOBase=%04x, MMIOBase=%08x, val=%02x.\n", s->PCIBase, s->MMIOBase, s->pci_conf[0x04]); mem_mapping_disable(&s->memory); if ((s->MMIOBase != 0) && (val & PCI_COMMAND_MEM)) mem_mapping_set_addr(&s->memory, s->MMIOBase, 128); @@ -1300,7 +1300,7 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) tulip_pci_bar[0].addr &= 0xffffff80; s->PCIBase = tulip_pci_bar[0].addr; if (s->pci_conf[0x4] & PCI_COMMAND_IO) { - pclog("PCI write=%02x, base=%04x, io?=%x.\n", addr, s->PCIBase, s->pci_conf[0x4] & PCI_COMMAND_IO); + //pclog("PCI write=%02x, base=%04x, io?=%x.\n", addr, s->PCIBase, s->pci_conf[0x4] & PCI_COMMAND_IO); if (s->PCIBase != 0) io_sethandler(s->PCIBase, 128, tulip_readb_io, tulip_readw_io, tulip_readl_io, @@ -1317,7 +1317,7 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) tulip_pci_bar[1].addr &= 0xffffff80; s->MMIOBase = tulip_pci_bar[1].addr; if (s->pci_conf[0x4] & PCI_COMMAND_MEM) { - pclog("PCI write=%02x, mmiobase=%08x, mmio?=%x.\n", addr, s->PCIBase, s->pci_conf[0x4] & PCI_COMMAND_MEM); + //pclog("PCI write=%02x, mmiobase=%08x, mmio?=%x.\n", addr, s->PCIBase, s->pci_conf[0x4] & PCI_COMMAND_MEM); if (s->MMIOBase != 0) mem_mapping_set_addr(&s->memory, s->MMIOBase, 128); } From 958f253b4718ac6d00e0b123a24f623031baa681 Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Sun, 21 Jan 2024 19:34:21 +0100 Subject: [PATCH 327/936] Add Gateway Lucas --- src/include/86box/machine.h | 60 +++++++++++++++++++------------------ src/machine/m_at_sockets7.c | 32 ++++++++++++++++++++ src/machine/machine_table.c | 40 +++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 29 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index a4c6a4d1f..d63c45aee 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -49,37 +49,38 @@ #define MACHINE_BUS_AGP 0x00080000 /* sys has AGP bus */ #define MACHINE_BUS_AC97 0x00100000 /* sys has AC97 bus (ACR/AMR/CNR slot) */ /* Aliases. */ -#define MACHINE_CASSETTE (MACHINE_BUS_CASSETTE) /* sys has cassette port */ -#define MACHINE_CARTRIDGE (MACHINE_BUS_CARTRIDGE) /* sys has two cartridge bays */ +#define MACHINE_CASSETTE (MACHINE_BUS_CASSETTE) /* sys has cassette port */ +#define MACHINE_CARTRIDGE (MACHINE_BUS_CARTRIDGE) /* sys has two cartridge bays */ /* Combined flags. */ -#define MACHINE_PC (MACHINE_BUS_ISA) /* sys is PC/XT-compatible (ISA) */ -#define MACHINE_AT (MACHINE_BUS_ISA | MACHINE_BUS_ISA16) /* sys is AT-compatible (ISA + ISA16) */ -#define MACHINE_PC98 (MACHINE_BUS_CBUS) /* sys is NEC PC-98x1 series */ -#define MACHINE_EISA (MACHINE_BUS_EISA | MACHINE_AT) /* sys is AT-compatible with EISA */ -#define MACHINE_VLB (MACHINE_BUS_VLB | MACHINE_AT) /* sys is AT-compatible with VLB */ -#define MACHINE_VLB98 (MACHINE_BUS_VLB | MACHINE_PC98) /* sys is NEC PC-98x1 series with VLB (did that even exist?) */ -#define MACHINE_VLBE (MACHINE_BUS_VLB | MACHINE_EISA) /* sys is AT-compatible with EISA and VLB */ -#define MACHINE_MCA (MACHINE_BUS_MCA) /* sys is MCA */ -#define MACHINE_PCI (MACHINE_BUS_PCI | MACHINE_AT) /* sys is AT-compatible with PCI */ -#define MACHINE_PCI98 (MACHINE_BUS_PCI | MACHINE_PC98) /* sys is NEC PC-98x1 series with PCI */ -#define MACHINE_PCIE (MACHINE_BUS_PCI | MACHINE_EISA) /* sys is AT-compatible with PCI, and EISA */ -#define MACHINE_PCIV (MACHINE_BUS_PCI | MACHINE_VLB) /* sys is AT-compatible with PCI and VLB */ -#define MACHINE_PCIVE (MACHINE_BUS_PCI | MACHINE_VLBE) /* sys is AT-compatible with PCI, VLB, and EISA */ -#define MACHINE_PCMCIA (MACHINE_BUS_PCMCIA | MACHINE_AT) /* sys is AT-compatible laptop with PCMCIA */ -#define MACHINE_AGP (MACHINE_BUS_AGP | MACHINE_PCI) /* sys is AT-compatible with AGP */ -#define MACHINE_AGP98 (MACHINE_BUS_AGP | MACHINE_PCI98) /* sys is NEC PC-98x1 series with AGP (did that even exist?) */ +#define MACHINE_PC (MACHINE_BUS_ISA) /* sys is PC/XT-compatible (ISA) */ +#define MACHINE_AT (MACHINE_BUS_ISA | MACHINE_BUS_ISA16) /* sys is AT-compatible (ISA + ISA16) */ +#define MACHINE_PC98 (MACHINE_BUS_CBUS) /* sys is NEC PC-98x1 series */ +#define MACHINE_EISA (MACHINE_BUS_EISA | MACHINE_AT) /* sys is AT-compatible with EISA */ +#define MACHINE_VLB (MACHINE_BUS_VLB | MACHINE_AT) /* sys is AT-compatible with VLB */ +#define MACHINE_VLB98 (MACHINE_BUS_VLB | MACHINE_PC98) /* sys is NEC PC-98x1 series with VLB (did that even exist?) */ +#define MACHINE_VLBE (MACHINE_BUS_VLB | MACHINE_EISA) /* sys is AT-compatible with EISA and VLB */ +#define MACHINE_MCA (MACHINE_BUS_MCA) /* sys is MCA */ +#define MACHINE_PCI (MACHINE_BUS_PCI | MACHINE_AT) /* sys is AT-compatible with PCI */ +#define MACHINE_PCI98 (MACHINE_BUS_PCI | MACHINE_PC98) /* sys is NEC PC-98x1 series with PCI */ +#define MACHINE_PCIE (MACHINE_BUS_PCI | MACHINE_EISA) /* sys is AT-compatible with PCI, and EISA */ +#define MACHINE_PCIV (MACHINE_BUS_PCI | MACHINE_VLB) /* sys is AT-compatible with PCI and VLB */ +#define MACHINE_PCIVE (MACHINE_BUS_PCI | MACHINE_VLBE) /* sys is AT-compatible with PCI, VLB, and EISA */ +#define MACHINE_PCMCIA (MACHINE_BUS_PCMCIA | MACHINE_AT) /* sys is AT-compatible laptop with PCMCIA */ +#define MACHINE_AGP (MACHINE_BUS_AGP | MACHINE_PCI) /* sys is AT-compatible with AGP */ +#define MACHINE_AGP98 (MACHINE_BUS_AGP | MACHINE_PCI98) /* sys is NEC PC-98x1 series with AGP (did that even exist?) */ -#define MACHINE_PC5150 (MACHINE_PC | MACHINE_CASSETTE) /* sys is IBM PC 5150 */ -#define MACHINE_PCJR (MACHINE_PC | MACHINE_CASSETTE | MACHINE_CARTRIDGE) /* sys is PCjr */ -#define MACHINE_PS2 (MACHINE_AT | MACHINE_BUS_PS2) /* sys is PS/2 */ -#define MACHINE_PS2_MCA (MACHINE_MCA | MACHINE_BUS_PS2) /* sys is MCA PS/2 */ -#define MACHINE_PS2_VLB (MACHINE_VLB | MACHINE_BUS_PS2) /* sys is VLB PS/2 */ -#define MACHINE_PS2_PCI (MACHINE_PCI | MACHINE_BUS_PS2) /* sys is PCI PS/2 */ -#define MACHINE_PS2_PCIV (MACHINE_PCIV | MACHINE_BUS_PS2) /* sys is VLB/PCI PS/2 */ -#define MACHINE_PS2_AGP (MACHINE_AGP | MACHINE_BUS_PS2) /* sys is AGP PS/2 */ -#define MACHINE_PS2_A97 (MACHINE_PS2_AGP | MACHINE_BUS_AC97) /* sys is AGP/AC97 PS/2 */ -#define MACHINE_PS2_NOISA (MACHINE_PS2_AGP & ~MACHINE_AT) /* sys is AGP PS/2 without ISA */ -#define MACHINE_PS2_NOI97 (MACHINE_PS2_A97 & ~MACHINE_AT) /* sys is AGP/AC97 PS/2 without ISA */ +#define MACHINE_PC5150 (MACHINE_PC | MACHINE_CASSETTE) /* sys is IBM PC 5150 */ +#define MACHINE_PCJR (MACHINE_PC | MACHINE_CASSETTE | MACHINE_CARTRIDGE) /* sys is PCjr */ +#define MACHINE_PS2 (MACHINE_AT | MACHINE_BUS_PS2) /* sys is PS/2 */ +#define MACHINE_PS2_MCA (MACHINE_MCA | MACHINE_BUS_PS2) /* sys is MCA PS/2 */ +#define MACHINE_PS2_VLB (MACHINE_VLB | MACHINE_BUS_PS2) /* sys is VLB PS/2 */ +#define MACHINE_PS2_PCI (MACHINE_PCI | MACHINE_BUS_PS2) /* sys is PCI PS/2 */ +#define MACHINE_PS2_PCIV (MACHINE_PCIV | MACHINE_BUS_PS2) /* sys is VLB/PCI PS/2 */ +#define MACHINE_PS2_AGP (MACHINE_AGP | MACHINE_BUS_PS2) /* sys is AGP PS/2 */ +#define MACHINE_PS2_A97 (MACHINE_PS2_AGP | MACHINE_BUS_AC97) /* sys is AGP/AC97 PS/2 */ +#define MACHINE_PS2_NOISA (MACHINE_PS2_AGP & ~MACHINE_AT) /* sys is AGP PS/2 without ISA */ +#define MACHINE_PS2_PCIONLY (MACHINE_PS2_NOISA & ~MACHINE_BUS_AGP) /* sys is PCI PS/2 without ISA */ +#define MACHINE_PS2_NOI97 (MACHINE_PS2_A97 & ~MACHINE_AT) /* sys is AGP/AC97 PS/2 without ISA */ /* Feature flags for miscellaneous internal devices. */ #define MACHINE_FLAGS_NONE 0x00000000 /* sys has no int devices */ #define MACHINE_SOFTFLOAT_ONLY 0x00000001 /* sys requires SoftFloat FPU */ @@ -720,6 +721,7 @@ extern int machine_at_ms5164_init(const machine_t *); /* m_at_sockets7.c */ extern int machine_at_p5a_init(const machine_t *); extern int machine_at_m579_init(const machine_t *); +extern int machine_at_gwlucas_init(const machine_t *); extern int machine_at_5aa_init(const machine_t *); extern int machine_at_5ax_init(const machine_t *); diff --git a/src/machine/m_at_sockets7.c b/src/machine/m_at_sockets7.c index 382a4f327..8ff1a367d 100644 --- a/src/machine/m_at_sockets7.c +++ b/src/machine/m_at_sockets7.c @@ -106,6 +106,38 @@ machine_at_m579_init(const machine_t *model) return ret; } +int +machine_at_gwlucas_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/gwlucas/gw2kboot.rom", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_SOUTHBRIDGE_IDE, 1, 2, 3, 4); + pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE_PMU, 1, 2, 3, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE_USB, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_SOUND, 1, 2, 3, 4); // ES1373 + pci_register_slot(0x14, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&ali1541_device); + device_add(&ali1543c_device); /* +0 */ + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 512); + + return ret; +} + int machine_at_5aa_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index af12a6df9..a63d6391f 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -12323,6 +12323,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* M1534c kbc */ + { + .name = "[ALi ALADDiN V] Gateway Lucas", + .internal_name = "gwlucas", + .type = MACHINE_TYPE_SOCKETS7, + .chipset = MACHINE_CHIPSET_ALI_ALADDIN_V, + .init = machine_at_gwlucas_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 = 66666667, + .max_bus = 100000000, + .min_voltage = 2000, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_PCIONLY, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .ram = { + .min = 8192, + .max = 262144, + .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, // rage + .snd_device = NULL, // es1373 + .net_device = NULL + }, /* Has the ALi M1543C southbridge with on-chip KBC. */ { .name = "[ALi ALADDiN V] Gigabyte GA-5AA", From bd2ef6855a100403cfebb4a21ff0bfaa08669a17 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 21 Jan 2024 20:21:52 +0100 Subject: [PATCH 328/936] A CPU change in preparation for the AOpen AP61. --- src/cpu/cpu.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index df6684baf..b6cd6f9ad 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -2372,14 +2372,20 @@ cpu_CPUID(void) EBX = ECX = 0; EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_CMOV; } else if (EAX == 2) { - EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries - Instruction TLB: 4 MB pages, fully associative, 2 entries - Data TLB: 4 KB pages, 4-way set associative, 64 entries */ + if (!strcmp(machine_get_internal_name(), "ap61")) { + EAX = 0x00000001; + EDX = 0x00000000; + } else { + EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries + Instruction TLB: 4 MB pages, fully associative, 2 entries + Data TLB: 4 KB pages, 4-way set associative, 64 entries */ + EDX = 0x06040a42; /* 2nd-level cache: 256 KB, 4-way set associative, 32-byte line size + 1st-level data cache: 8 KB, 2-way set associative, 32-byte line size + Data TLB: 4 MB pages, 4-way set associative, 8 entries + 1st-level instruction cache:8 KB, 4-way set associative, 32-byte line size */ + } + EBX = ECX = 0; - EDX = 0x06040a42; /* 2nd-level cache: 256 KB, 4-way set associative, 32-byte line size - 1st-level data cache: 8 KB, 2-way set associative, 32-byte line size - Data TLB: 4 MB pages, 4-way set associative, 8 entries - 1st-level instruction cache:8 KB, 4-way set associative, 32-byte line size */ } else EAX = EBX = ECX = EDX = 0; break; From b607d191f4b4ba55fd4a1b1aa1260fe76483875c Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 22 Jan 2024 15:35:32 +0100 Subject: [PATCH 329/936] Fix the WD1004A-WX1 BIOS and jumpers. --- src/disk/hdc_st506_xt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/disk/hdc_st506_xt.c b/src/disk/hdc_st506_xt.c index 79a5a8eba..fc20350b0 100644 --- a/src/disk/hdc_st506_xt.c +++ b/src/disk/hdc_st506_xt.c @@ -107,7 +107,7 @@ #define ST11_BIOS_FILE_OLD "roms/hdd/st506/st11_bios_vers_1.7.bin" #define ST11_BIOS_FILE_NEW "roms/hdd/st506/st11_bios_vers_2.0.bin" #define WD1002A_WX1_BIOS_FILE "roms/hdd/st506/wd1002a_wx1-62-000094-032.bin" -#define WD1004A_WX1_BIOS_FILE "roms/hdd/st506/wd1002a_wx1-62-000094-032.bin" +#define WD1004A_WX1_BIOS_FILE "roms/hdd/st506/western_digital_WD1004A-27X.bin" /* SuperBIOS was for both the WX1 and 27X, users jumpers readout to determine if to use 26 sectors per track, 26 -> 17 sectors per track translation, or 17 sectors per track. */ @@ -1667,7 +1667,7 @@ st506_init(const device_t *info) fn = WD1004A_WX1_BIOS_FILE; /* The switches are read in reverse: 0 = closed, 1 = open. Both open means MFM, 17 sectors per track. */ - dev->switches = 0x10; /* autobios */ + dev->switches = 0x30; /* autobios */ dev->base = device_get_config_hex16("base"); dev->irq = device_get_config_int("irq"); if (dev->irq == 2) From 9844cbc2459cc33d18ae17253e431547e5504579 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Tue, 23 Jan 2024 16:02:32 +1300 Subject: [PATCH 330/936] Add 8-dot hscroll compensation to EGA graphics modes This is in lieu of whatever the correct emulation would be (as per the text modes). Somehow I forgot to add this when reworking the fine scroll implementations. --- src/video/vid_ega_render.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/video/vid_ega_render.c b/src/video/vid_ega_render.c index 98905e0c8..0cb1216ad 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -199,6 +199,7 @@ ega_render_graphics(ega_t *ega) const bool attrblink = ((ega->attrregs[0x10] & 8) != 0); const bool blinked = ega->blink & 0x10; const bool crtcreset = ((ega->crtc[0x17] & 0x80) == 0); + const bool seq9dot = ((ega->seqregs[1] & 1) == 0); const bool seqoddeven = ((ega->seqregs[1] & 4) != 0); const uint8_t blinkmask = (attrblink && blinked ? 0x8 : 0x0); uint32_t *p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; @@ -206,6 +207,15 @@ ega_render_graphics(ega_t *ega) const int dotwidth = 1 << dwshift; const int charwidth = dotwidth * 8; int secondcclk = 0; + + /* Compensate for 8dot scroll */ + if (!seq9dot) { + for (int x = 0; x < dotwidth; x++) { + p[x] = ega->overscan_color; + } + p += dotwidth; + } + for (int x = 0; x <= (ega->hdisp + ega->scrollcache); x += charwidth) { uint32_t addr = ega->remap_func(ega, ega->ma) & ega->vrammask; From e5000f7419d1020c4e657b4168f91658d3b1c746 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Tue, 23 Jan 2024 17:03:33 +1300 Subject: [PATCH 331/936] Fix fine scroll wobbling in EGA when calling `ega_recalctimings` Closes: GH-4072 --- src/video/vid_ega.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 670d88e61..282fde656 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -557,7 +557,7 @@ ega_recalctimings(ega_t *ega) overscan_x <<= 1; ega->y_add = (overscan_y >> 1); - ega->x_add = (overscan_x >> 1); + ega->x_add = (overscan_x >> 1) - ega->scrollcache; if (ega->vres) ega->y_add >>= 1; From 257cf0d1a2cb18bfd28cf5230a9a8bf27198a492 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Tue, 23 Jan 2024 17:06:39 +1300 Subject: [PATCH 332/936] Remove the "reset horizontal fine scroll on split screen" VGAism from EGA --- src/video/vid_ega.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 282fde656..7979cd958 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -804,10 +804,6 @@ ega_poll(void *priv) ega->cca = ega->ma; ega->maback <<= 2; ega->sc = 0; - if (ega->attrregs[0x10] & 0x20) { - ega->scrollcache = 0; - ega->x_add = (overscan_x >> 1); - } } if (ega->vc == ega->dispend) { ega->dispon = 0; From a21b8d865dad4cc229739ca1bf215452f6cc0a62 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 23 Jan 2024 19:15:50 +0100 Subject: [PATCH 333/936] MGA: Line draw rework/fixes by TC1995, fixes the Setup bug reported by Luennix. --- src/video/vid_mga.c | 215 +++++++++++++++++++++++++------------------- 1 file changed, 124 insertions(+), 91 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 44a33db2e..bc335fc9c 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -469,7 +469,7 @@ typedef struct mystique_t { lfb_base, ctrl_base, iload_base, ma_latch_old, maccess, mctlwtst, maccess_running, softrap_pending_val; - + atomic_uint status; atomic_bool softrap_status_read; @@ -502,7 +502,7 @@ typedef struct mystique_t { int xoff, yoff, selline, ydst, length_cur, iload_rem_count, idump_end_of_line, words, ta_key, ta_mask, lastpix_r, lastpix_g, - lastpix_b, highv_line, beta, dither; + lastpix_b, highv_line, beta, dither, err, k1, k2; int pattern[8][16]; @@ -764,13 +764,13 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) old = mystique->crtcext_regs[mystique->crtcext_idx]; if (mystique->crtcext_idx < 6) mystique->crtcext_regs[mystique->crtcext_idx] = val; - + if ((mystique->type >= MGA_1064SG) && (mystique->crtcext_idx == 0) && (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE)) { svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); - if (!(mystique->type >= MGA_2164W)) + if (!(mystique->type >= MGA_2164W)) svga->rowoffset <<= 1; svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | @@ -2394,10 +2394,10 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) break; case REG_SHIFT: - mystique->dwgreg.funcnt = val & 0xff; + mystique->dwgreg.funcnt = val & 0x7f; mystique->dwgreg.xoff = val & 7; mystique->dwgreg.yoff = (val >> 4) & 7; - mystique->dwgreg.stylelen = (val >> 16) & 0xff; + mystique->dwgreg.stylelen = (val >> 16) & 0x7f; break; case REG_PITCH: @@ -2601,7 +2601,7 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) case REG_ALPHACTRL: mystique->dwgreg.alphactrl = val; break; - + case REG_ALPHASTART: mystique->dwgreg.alphastart = val; break; @@ -2617,7 +2617,7 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) case REG_FOGCOL: mystique->dwgreg.fogcol = val; break; - + case REG_FOGSTART: mystique->dwgreg.fogstart = val; break; @@ -2678,7 +2678,7 @@ mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) wake_fifo_thread(mystique); } /* HACK: For DirectX 9.0b Direct3D testing on Windows 98 SE. - + The 4.12.013 drivers give an out-of-bounds busmastering range when dxdiag enumerates Direct3D, with exactly 16384 bytes of difference. Don't attempt busmastering in such cases. This isn't ideal, but there are no more crashes faced in this case. */ if ((mystique->dma.primend & DMA_ADDR_MASK) < (mystique->dma.primaddress & DMA_ADDR_MASK) && ((mystique->dma.primaddress & DMA_ADDR_MASK) - (mystique->dma.primend & DMA_ADDR_MASK)) == 0x4000) @@ -3229,7 +3229,7 @@ mystique_softrap_pending_timer(void *priv) mystique_update_irqs(mystique); mystique->softrap_pending--; } - + } static void @@ -4309,21 +4309,19 @@ z_check_32(uint32_t z, uint32_t old_z, uint32_t z_mode) // mystique->dwgreg.dwgc } static void -blit_line(mystique_t *mystique, int closed) +blit_line(mystique_t *mystique, int closed, int autoline) { svga_t *svga = &mystique->svga; uint32_t src = 0; uint32_t dst; uint32_t old_dst; - int x; - int len = 0; + int x = mystique->dwgreg.xdst; int z_write; switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { case DWGCTRL_ATYPE_RSTR: case DWGCTRL_ATYPE_RPL: - x = mystique->dwgreg.xdst; - while (len <= mystique->dwgreg.length) { + while (mystique->dwgreg.length >= 0) { if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { case MACCESS_PWIDTH_8: @@ -4334,7 +4332,10 @@ blit_line(mystique_t *mystique, int closed) if (closed) { svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; - } else if (!closed && (len < mystique->dwgreg.length)) { + } else if (!closed && (mystique->dwgreg.length > 0) && ((mystique->dwgreg.err > 0) || (mystique->dwgreg.err < 0)) && !autoline) { + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + } else if (!closed && (mystique->dwgreg.length > 0) && autoline) { svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; } @@ -4348,7 +4349,10 @@ blit_line(mystique_t *mystique, int closed) if (closed) { ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; - } else if (!closed && (len < mystique->dwgreg.length)) { + } else if (!closed && (mystique->dwgreg.length > 0) && ((mystique->dwgreg.err > 0) || (mystique->dwgreg.err < 0)) && !autoline) { + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + } else if (!closed && (mystique->dwgreg.length > 0) && autoline) { ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; } @@ -4362,7 +4366,10 @@ blit_line(mystique_t *mystique, int closed) if (closed) { *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; - } else if (!closed && (len < mystique->dwgreg.length)) { + } else if (!closed && (mystique->dwgreg.length > 0) && ((mystique->dwgreg.err > 0) || (mystique->dwgreg.err < 0)) && !autoline) { + *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + } else if (!closed && (mystique->dwgreg.length > 0) && autoline) { *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; } @@ -4376,7 +4383,10 @@ blit_line(mystique_t *mystique, int closed) if (closed) { ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; - } else if (!closed && (len < mystique->dwgreg.length)) { + } else if (!closed && (mystique->dwgreg.length > 0) && ((mystique->dwgreg.err > 0) || (mystique->dwgreg.err < 0)) && !autoline) { + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + } else if (!closed && (mystique->dwgreg.length > 0) && autoline) { ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; } @@ -4387,28 +4397,34 @@ blit_line(mystique_t *mystique, int closed) } } + if (!mystique->dwgreg.length) + break; + if (mystique->dwgreg.sgn.sdydxl) x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - else + else { + mystique->dwgreg.ydst += (mystique->dwgreg.sgn.sdy ? -1 : 1); + mystique->dwgreg.ydst &= 0x7fffff; mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); - - if ((int32_t) mystique->dwgreg.ar[1] >= 0) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; - if (mystique->dwgreg.sgn.sdydxl) + } + if (mystique->dwgreg.err >= 0) { + mystique->dwgreg.err += mystique->dwgreg.k2; + if (mystique->dwgreg.sgn.sdydxl) { + mystique->dwgreg.ydst += (mystique->dwgreg.sgn.sdy ? -1 : 1); + mystique->dwgreg.ydst &= 0x7fffff; mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); - else + } else x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); } else - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.err += mystique->dwgreg.k1; - len++; + mystique->dwgreg.length--; } break; case DWGCTRL_ATYPE_I: case DWGCTRL_ATYPE_ZI: z_write = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) == DWGCTRL_ATYPE_ZI); - x = mystique->dwgreg.xdst; while (mystique->dwgreg.length > 0) { if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { bool z_check_pass = false; @@ -4471,8 +4487,8 @@ blit_line(mystique_t *mystique, int closed) mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; - if ((int32_t) mystique->dwgreg.ar[1] >= 0) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + if (mystique->dwgreg.err >= 0) { + mystique->dwgreg.err += mystique->dwgreg.k2; if (mystique->dwgreg.sgn.sdydxl) mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); @@ -4490,7 +4506,7 @@ blit_line(mystique_t *mystique, int closed) mystique->dwgreg.dr[8] += mystique->dwgreg.dr[11]; mystique->dwgreg.dr[12] += mystique->dwgreg.dr[15]; } else - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.err += mystique->dwgreg.k1; mystique->dwgreg.length--; } @@ -4507,7 +4523,7 @@ blit_line(mystique_t *mystique, int closed) } static void -blit_autoline(mystique_t *mystique, int closed) +blit_line_start(mystique_t *mystique, int closed, int autoline) { int start_x = (int32_t) mystique->dwgreg.ar[5]; int start_y = (int32_t) mystique->dwgreg.ar[6]; @@ -4516,29 +4532,37 @@ blit_autoline(mystique_t *mystique, int closed) int dx = end_x - start_x; int dy = end_y - start_y; - if (ABS(dx) > ABS(dy)) { - mystique->dwgreg.sgn.sdydxl = 1; - mystique->dwgreg.ar[0] = 2 * ABS(dy); - mystique->dwgreg.ar[1] = 2 * ABS(dy) - ABS(dx) - ((start_y > end_y) ? 1 : 0); - mystique->dwgreg.ar[2] = 2 * ABS(dy) - 2 * ABS(dx); - mystique->dwgreg.length = ABS(end_x - start_x); + if (autoline) { + if (ABS(dx) > ABS(dy)) { + mystique->dwgreg.sgn.sdydxl = 1; + mystique->dwgreg.k1 = 2 * ABS(dy); + mystique->dwgreg.err = 2 * ABS(dy) - ABS(dx) - ((start_y > end_y) ? 1 : 0); + mystique->dwgreg.k2 = 2 * ABS(dy) - 2 * ABS(dx); + mystique->dwgreg.length = ABS(end_x - start_x); + } else { + mystique->dwgreg.sgn.sdydxl = 0; + mystique->dwgreg.k1 = 2 * ABS(dx); + mystique->dwgreg.err = 2 * ABS(dx) - ABS(dy) - ((start_y > end_y) ? 1 : 0); + mystique->dwgreg.k2 = 2 * ABS(dx) - 2 * ABS(dy); + mystique->dwgreg.length = ABS(end_y - start_y); + } + mystique->dwgreg.sgn.sdxl = (start_x > end_x) ? 1 : 0; + mystique->dwgreg.sgn.sdy = (start_y > end_y) ? 1 : 0; } else { - mystique->dwgreg.sgn.sdydxl = 0; - mystique->dwgreg.ar[0] = 2 * ABS(dx); - mystique->dwgreg.ar[1] = 2 * ABS(dx) - ABS(dy) - ((start_y > end_y) ? 1 : 0); - mystique->dwgreg.ar[2] = 2 * ABS(dx) - 2 * ABS(dy); - mystique->dwgreg.length = ABS(end_y - start_y); + mystique->dwgreg.k1 = (int32_t) mystique->dwgreg.ar[0]; + mystique->dwgreg.err = (int32_t) mystique->dwgreg.ar[1]; + mystique->dwgreg.k2 = (int32_t) mystique->dwgreg.ar[2]; } - mystique->dwgreg.sgn.sdxl = (start_x > end_x) ? 1 : 0; - mystique->dwgreg.sgn.sdy = (start_y > end_y) ? 1 : 0; - blit_line(mystique, closed); + blit_line(mystique, closed, autoline); - mystique->dwgreg.ar[5] = end_x; - mystique->dwgreg.xdst = end_x; - mystique->dwgreg.ar[6] = end_y; - mystique->dwgreg.ydst = end_y; - mystique->dwgreg.ydst_lin = ((int32_t) (int16_t) mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; + if (autoline) { + mystique->dwgreg.ar[5] = end_x; + mystique->dwgreg.xdst = end_x; + mystique->dwgreg.ar[6] = end_y; + mystique->dwgreg.ydst = end_y; + mystique->dwgreg.ydst_lin = ((int32_t) (int16_t) mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; + } } static void @@ -4552,6 +4576,8 @@ blit_trap(mystique_t *mystique) uint32_t b_back; int z_write; int y; + int err_l = (int32_t)mystique->dwgreg.ar[1]; + int err_r = (int32_t)mystique->dwgreg.ar[4]; const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { @@ -4562,8 +4588,14 @@ blit_trap(mystique_t *mystique) int16_t x_l = mystique->dwgreg.fxleft & 0xffff; int16_t x_r = mystique->dwgreg.fxright & 0xffff; int yoff = (mystique->dwgreg.yoff + mystique->dwgreg.ydst) & 7; + int len; - while (x_l != x_r) { + if (x_l > x_r) + len = x_l - x_r; + else + len = x_r - x_l; + + while (len > 0) { if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) { int xoff = (mystique->dwgreg.xoff + (x_l & 7)) & 15; int pattern = mystique->dwgreg.pattern[yoff][xoff]; @@ -4595,24 +4627,21 @@ blit_trap(mystique_t *mystique) fatal("TRAP BLK/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); } } - if (x_l > x_r) - x_l--; - else - x_l++; - + len--; + x_l++; } - while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + while ((err_l < 0) && mystique->dwgreg.ar[0]) { + err_l += mystique->dwgreg.ar[0]; mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); } - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + err_l += mystique->dwgreg.ar[2]; - while ((int32_t) mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + while ((err_r < 0) && mystique->dwgreg.ar[6]) { + err_r += mystique->dwgreg.ar[6]; mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); } - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + err_r += mystique->dwgreg.ar[5]; mystique->dwgreg.ydst++; mystique->dwgreg.ydst &= 0x7fffff; @@ -4628,8 +4657,14 @@ blit_trap(mystique_t *mystique) int16_t x_l = mystique->dwgreg.fxleft & 0xffff; int16_t x_r = mystique->dwgreg.fxright & 0xffff; int yoff = (mystique->dwgreg.yoff + mystique->dwgreg.ydst) & 7; + int len; - while (x_l != x_r) { + if (x_l > x_r) + len = x_l - x_r; + else + len = x_r - x_l; + + while (len > 0) { if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) { int xoff = (mystique->dwgreg.xoff + (x_l & 7)) & 15; int pattern = mystique->dwgreg.pattern[yoff][xoff]; @@ -4674,23 +4709,21 @@ blit_trap(mystique_t *mystique) fatal("TRAP RSTR PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); } } - if (x_l > x_r) - x_l--; - else - x_l++; + x_l++; + len--; } - while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + while ((err_l < 0) && mystique->dwgreg.ar[0]) { + err_l += mystique->dwgreg.ar[0]; mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); } - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + err_l += mystique->dwgreg.ar[2]; - while ((int32_t) mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + while ((err_r < 0) && mystique->dwgreg.ar[6]) { + err_r += mystique->dwgreg.ar[6]; mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); } - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + err_r += mystique->dwgreg.ar[5]; mystique->dwgreg.ydst++; mystique->dwgreg.ydst &= 0x7fffff; @@ -5801,19 +5834,19 @@ mystique_start_blit(mystique_t *mystique) switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) { case DWGCTRL_OPCODE_LINE_OPEN: - blit_line(mystique, 0); + blit_line_start(mystique, 0, 0); break; case DWGCTRL_OPCODE_AUTOLINE_OPEN: - blit_autoline(mystique, 0); + blit_line_start(mystique, 0, 1); break; case DWGCTRL_OPCODE_LINE_CLOSE: - blit_line(mystique, 1); + blit_line_start(mystique, 1, 0); break; case DWGCTRL_OPCODE_AUTOLINE_CLOSE: - blit_autoline(mystique, 1); + blit_line_start(mystique, 1, 1); break; case DWGCTRL_OPCODE_TRAP: @@ -6046,7 +6079,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) case 0x33: ret = mystique->pci_regs[0x33]; break; - + case 0x34: ret = mystique->type == MGA_G100 ? 0xdc : 0x00; break; @@ -6089,7 +6122,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) case 0xdc: ret = 0x01; break; - + case 0xdd: ret = 0xf0; break; @@ -6097,7 +6130,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) case 0xde: ret = 0x21; break; - + /* No support for turning off the video adapter yet. */ case 0xe0: ret = 0x0; @@ -6106,19 +6139,19 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) case 0xf0: ret = 0x02; break; - + case 0xf1: ret = 0x00; break; - + case 0xf2: ret = 0x10; break; - + case 0xf4: ret = 0x1; break; - + case 0xf5: ret = 0x2; break; @@ -6126,15 +6159,15 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) case 0xf7: ret = 0x1; break; - + case 0xf8: ret = mystique->pci_regs[0xf8] & 0x7; break; - + case 0xf9: ret = mystique->pci_regs[0xf9] & 0x3; break; - + case 0xfb: ret = mystique->pci_regs[0xfb]; break; @@ -6277,11 +6310,11 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) case 0xf8: mystique->pci_regs[0xf8] = val & 0x7; break; - + case 0xf9: mystique->pci_regs[0xf9] = val & 0x3; break; - + case 0xfb: mystique->pci_regs[0xfb] = val; break; @@ -6455,7 +6488,7 @@ mystique_init(const device_t *info) timer_add(&mystique->softrap_pending_timer, mystique_softrap_pending_timer, (void *) mystique, 1); mystique->status = STATUS_ENDPRDMASTS; - + mystique->softrap_status_read = 1; mystique->svga.vsync_callback = mystique_vsync_callback; From 9107c2fa257df891fbc4be8c8c47c0e14096ec5c Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 24 Jan 2024 04:56:31 +0100 Subject: [PATCH 334/936] Added the AOpen AP61 and fixed floppies on the LG IBM 440 FX. --- src/chipset/intel_i450kx.c | 56 +++++++++++++++++-------------------- src/cpu/cpu.c | 56 +++++++++++-------------------------- src/cpu/cpu.h | 17 ++++------- src/include/86box/machine.h | 2 +- src/machine/m_at_socket8.c | 39 ++++++++++++++++++++++++-- src/machine/machine_table.c | 40 ++++++++++++++++++++++++++ src/sio/sio_w83787f.c | 10 ++++--- src/sio/sio_w83877f.c | 11 ++++---- 8 files changed, 139 insertions(+), 92 deletions(-) diff --git a/src/chipset/intel_i450kx.c b/src/chipset/intel_i450kx.c index 90b807a6d..2f6547309 100644 --- a/src/chipset/intel_i450kx.c +++ b/src/chipset/intel_i450kx.c @@ -8,19 +8,14 @@ * * Implementation of the Intel 450KX Mars Chipset. * + * i450GX is way more popular of an option but needs more stuff. * + * Authors: Miran Grca, + * Tiseno100, * - * Authors: Tiseno100 - * + * Copyright 2021-2024 Miran Grca. * Copyright 2021 Tiseno100. */ - -/* -Note: i450KX PB manages PCI memory access with MC manages DRAM memory access. -Due to 86Box limitations we can't manage them seperately thus it is dev branch till then. - -i450GX is way more popular of an option but needs more stuff. -*/ #include #include #include @@ -97,17 +92,18 @@ i450kx_smram_recalc(i450kx_t *dev, int bus) const uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf; uint32_t addr; uint32_t size; + int enable = bus ? !(regs[0x57] & 0x08) : (regs[0x57] & 0x08); smram_disable(dev->smram[bus]); addr = ((uint32_t) regs[0xb8] << 16) | ((uint32_t) regs[0xb9] << 24); size = (((uint32_t) ((regs[0xbb] >> 4) & 0x0f)) << 16) + 0x00010000; - if ((addr != 0x00000000) && !!(regs[0x57] & 0x08)) { + if ((addr != 0x00000000) && enable) { if (bus) - smram_enable_ex(dev->smram[bus], addr, addr, size, 0, !!(regs[0x57] & 8), 0, 1); + smram_enable_ex(dev->smram[bus], addr, addr, size, 0, 0, 0, enable); else - smram_enable_ex(dev->smram[bus], addr, addr, size, !!(regs[0x57] & 8), 0, 1, 0); + smram_enable_ex(dev->smram[bus], addr, addr, size, 0, 0, enable, 0); } flushmmucache(); @@ -118,10 +114,8 @@ i450kx_vid_buf_recalc(i450kx_t *dev, int bus) { const uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf; -#if 0 - // int state = (regs[0x58] & 0x02) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_DISABLED | MEM_WRITE_DISABLED); -#endif - int state = (regs[0x58] & 0x02) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + int state = (regs[0x58] & 0x02) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : + (MEM_READ_EXTANY | MEM_WRITE_EXTANY); if (bus) mem_set_mem_state_bus_both(0x000a0000, 0x00020000, state); @@ -136,10 +130,10 @@ pb_write(int func, int addr, uint8_t val, void *priv) { i450kx_t *dev = (i450kx_t *) priv; - // pclog("i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); - i450kx_log("i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); + if (func == 0) { + i450kx_log("[%04X:%08X] i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X\n", CS, cpu_state.pc, + addr, val); - if (func == 0) switch (addr) { case 0x04: dev->pb_pci_conf[addr] = (dev->pb_pci_conf[addr] & 0x04) | (val & 0x53); @@ -373,6 +367,7 @@ pb_write(int func, int addr, uint8_t val, void *priv) default: break; } + } } static uint8_t @@ -381,10 +376,12 @@ pb_read(int func, int addr, void *priv) const i450kx_t *dev = (i450kx_t *) priv; uint8_t ret = 0xff; - if (func == 0) + if (func == 0) { ret = dev->pb_pci_conf[addr]; - // pclog("i450KX-PB: [R] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, ret, inb(0x80)); + i450kx_log("[%04X:%08X] i450KX-PB: [R] dev->pb_pci_conf[%02X] = %02X\n", CS, cpu_state.pc, + addr, ret); + } return ret; } @@ -407,10 +404,10 @@ mc_write(int func, int addr, uint8_t val, void *priv) { i450kx_t *dev = (i450kx_t *) priv; - // pclog("i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); - i450kx_log("i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); + if (func == 0) { + i450kx_log("[%04X:%08X] i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X\n", CS, cpu_state.pc, + addr, val); - if (func == 0) switch (addr) { case 0x4c: dev->mc_pci_conf[addr] = val & 0xdf; @@ -600,6 +597,7 @@ mc_write(int func, int addr, uint8_t val, void *priv) default: break; } + } } static uint8_t @@ -608,10 +606,12 @@ mc_read(int func, int addr, void *priv) const i450kx_t *dev = (i450kx_t *) priv; uint8_t ret = 0xff; - if (func == 0) + if (func == 0) { ret = dev->mc_pci_conf[addr]; - // pclog("i450KX-MC: [R] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, ret, inb(0x80)); + i450kx_log("[%04X:%08X] i450KX-MC: [R] dev->mc_pci_conf[%02X] = %02X\n", CS, cpu_state.pc, + addr, ret); + } return ret; } @@ -622,10 +622,6 @@ i450kx_reset(void *priv) i450kx_t *dev = (i450kx_t *) priv; uint32_t i; -#if 0 - // pclog("i450KX: i450kx_reset()\n"); -#endif - /* Defaults PB */ dev->pb_pci_conf[0x00] = 0x86; dev->pb_pci_conf[0x01] = 0x80; diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index b6cd6f9ad..c3e3c39d4 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -2372,10 +2372,10 @@ cpu_CPUID(void) EBX = ECX = 0; EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_CMOV; } else if (EAX == 2) { - if (!strcmp(machine_get_internal_name(), "ap61")) { + /* if (!strcmp(machine_get_internal_name(), "ap61")) { EAX = 0x00000001; EDX = 0x00000000; - } else { + } else */ { EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries Instruction TLB: 4 MB pages, fully associative, 2 entries Data TLB: 4 KB pages, 4-way set associative, 64 entries */ @@ -2799,7 +2799,9 @@ amd_k_invalid_rdmsr: case CPU_PENTIUM2: case CPU_PENTIUM2D: EAX = EDX = 0; - switch (ECX) { + /* Per RichardG's probing of a real Deschutes using my RDMSR tool, + we have discovered that the top 18 bits are filtered out. */ + switch (ECX & 0x00003fff) { case 0x00: case 0x01: break; @@ -2821,6 +2823,11 @@ amd_k_invalid_rdmsr: EDX = msr.apic_base >> 32; cpu_log("APIC_BASE read : %08X%08X\n", EDX, EAX); break; + /* Unknown (undocumented?) MSR used by the Hyper-V BIOS. */ + case 0x20: + EAX = msr.ecx20 & 0xffffffff; + EDX = msr.ecx20 >> 32; + break; case 0x2a: EAX = 0xc4000000; EDX = 0; @@ -3022,26 +3029,6 @@ amd_k_invalid_rdmsr: EAX = msr.ecx570 & 0xffffffff; EDX = msr.ecx570 >> 32; break; - case 0x1002ff: - EAX = msr.ecx1002ff & 0xffffffff; - EDX = msr.ecx1002ff >> 32; - break; - case 0x40000020: - EAX = msr.ecx40000020 & 0xffffffff; - EDX = msr.ecx40000020 >> 32; - break; - case 0xf0f00250: - EAX = msr.ecxf0f00250 & 0xffffffff; - EDX = msr.ecxf0f00250 >> 32; - break; - case 0xf0f00258: - EAX = msr.ecxf0f00258 & 0xffffffff; - EDX = msr.ecxf0f00258 >> 32; - break; - case 0xf0f00259: - EAX = msr.ecxf0f00259 & 0xffffffff; - EDX = msr.ecxf0f00259 >> 32; - break; default: i686_invalid_rdmsr: cpu_log("RDMSR: Invalid MSR: %08X\n", ECX); @@ -3303,7 +3290,9 @@ amd_k_invalid_wrmsr: case CPU_PENTIUMPRO: case CPU_PENTIUM2: case CPU_PENTIUM2D: - switch (ECX) { + /* Per RichardG's probing of a real Deschutes using my RDMSR tool, + we have discovered that the top 18 bits are filtered out. */ + switch (ECX & 0x00003fff) { case 0x00: case 0x01: if (EAX || EDX) @@ -3318,6 +3307,10 @@ amd_k_invalid_wrmsr: msr.apic_base = EAX | ((uint64_t) EDX << 32); #endif break; + /* Unknown (undocumented?) MSR used by the Hyper-V BIOS. */ + case 0x20: + msr.ecx20 = EAX | ((uint64_t) EDX << 32); + break; case 0x2a: break; case 0x79: @@ -3462,21 +3455,6 @@ amd_k_invalid_wrmsr: case 0x570: msr.ecx570 = EAX | ((uint64_t) EDX << 32); break; - case 0x1002ff: - msr.ecx1002ff = EAX | ((uint64_t) EDX << 32); - break; - case 0x40000020: - msr.ecx40000020 = EAX | ((uint64_t) EDX << 32); - break; - case 0xf0f00250: - msr.ecxf0f00250 = EAX | ((uint64_t) EDX << 32); - break; - case 0xf0f00258: - msr.ecxf0f00258 = EAX | ((uint64_t) EDX << 32); - break; - case 0xf0f00259: - msr.ecxf0f00259 = EAX | ((uint64_t) EDX << 32); - break; default: i686_invalid_wrmsr: cpu_log("WRMSR: Invalid MSR: %08X\n", ECX); diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 9aee59e60..e185f2e4a 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -253,6 +253,12 @@ typedef struct { /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ uint64_t apic_base; /* 0x0000001b - Should the Pentium not also have this? */ + + /* Weird long MSR's used by the Hyper-V BIOS. */ + uint64_t ecx20; /* 0x00000020, really 0x40000020, but we filter out the top 18 bits + like a real Deschutes does. */ + + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ uint64_t ecx79; /* 0x00000079 */ /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ @@ -314,9 +320,6 @@ typedef struct { /* IBM 486SLC and 486BL MSR's */ uint64_t ibm_por2; /* 0x00001002 - Processor Operation Register */ - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecx1002ff; /* 0x001002ff - MSR used by some Intel AMI boards */ - /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ uint64_t amd_efer; /* 0xc0000080 */ @@ -338,14 +341,6 @@ typedef struct { /* K6-3, K6-2P, and K6-3P MSR's */ uint64_t amd_l2aar; /* 0xc0000089 */ - - /* Weird long MSR's used by the Hyper-V BIOS. */ - uint64_t ecx40000020; /* 0x40000020 */ - - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecxf0f00250; /* 0xf0f00250 - Some weird long MSR's used by i686 AMI & some Phoenix BIOSes */ - uint64_t ecxf0f00258; /* 0xf0f00258 */ - uint64_t ecxf0f00259; /* 0xf0f00259 */ } msr_t; typedef struct { diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index faed59dae..73b27afbf 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -705,8 +705,8 @@ extern int machine_at_ficva503a_init(const machine_t *); extern int machine_at_5emapro_init(const machine_t *); /* m_at_socket8.c */ +extern int machine_at_ap61_init(const machine_t *); extern int machine_at_p6rp4_init(const machine_t *); -extern int machine_at_aurora_init(const machine_t *); extern int machine_at_686nx_init(const machine_t *); extern int machine_at_acerv60n_init(const machine_t *); diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index 6e63af732..7ce9d5095 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -39,6 +39,39 @@ #include "cpu.h" #include <86box/machine.h> +int +machine_at_ap61_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ap61/ap61r120.bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x19, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x14, PCI_CARD_NORTHBRIDGE_SEC, 0, 0, 0, 0); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_IDE, 0xFE, 0xFF, 0, 0); + pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&i450kx_device); + device_add(&sio_zb_device); + device_add(&ide_cmd646_device); + device_add(&keyboard_ps2_acer_pci_device); + device_add(&fdc37c665_device); + device_add(&sst_flash_29ee010_device); + // device_add(&intel_flash_bxt_device); + + return ret; +} + int machine_at_p6rp4_init(const machine_t *model) { @@ -183,8 +216,10 @@ machine_at_lgibm440fx_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&i440fx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&w83787f_device); + // device_add(&keyboard_ps2_ami_pci_device); + device_add(&keyboard_ps2_ami_device); + // device_add(&w83787f_device); + device_add(&w83877f_president_device); device_add(&sst_flash_29ee010_device); return ret; diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 7406cce30..101052f4e 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -11655,6 +11655,46 @@ const machine_t machines[] = { /* Socket 8 machines */ /* 450KX */ /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[i450KX] AOpen AP61", + .internal_name = "ap61", + .type = MACHINE_TYPE_SOCKET8, + .chipset = MACHINE_CHIPSET_INTEL_450KX, + .init = machine_at_ap61_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET8, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2100, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ { .name = "[i450KX] ASUS P/I-P6RP4", .internal_name = "p6rp4", diff --git a/src/sio/sio_w83787f.c b/src/sio/sio_w83787f.c index 33cfc6311..2e4b82059 100644 --- a/src/sio/sio_w83787f.c +++ b/src/sio/sio_w83787f.c @@ -215,8 +215,9 @@ static void w83787f_fdc_handler(w83787f_t *dev) { fdc_remove(dev->fdc); - if (!(dev->regs[0] & 0x20) && !(dev->regs[6] & 0x08)) + if (!(dev->regs[0] & 0x20)) fdc_set_base(dev->fdc, (dev->regs[0] & 0x10) ? FDC_PRIMARY_ADDR : FDC_SECONDARY_ADDR); + fdc_set_power_down(dev->fdc, !!(dev->regs[6] & 0x08)); } static void @@ -258,10 +259,10 @@ w83787f_write(uint16_t port, uint8_t val, void *priv) return; } else { if (dev->locked) { - if (dev->rw_locked) + if (dev->rw_locked && (dev->cur_reg <= 0x0b)) return; if (dev->cur_reg == 6) - val &= 0xF3; + val &= 0xFB; valxor = val ^ dev->regs[dev->cur_reg]; dev->regs[dev->cur_reg] = val; } else @@ -363,7 +364,7 @@ w83787f_read(uint16_t port, void *priv) else if (port == 0x252) { if (dev->cur_reg == 7) ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2)); - else if (!dev->rw_locked) + else if (!dev->rw_locked || (dev->cur_reg > 0x0b)) ret = dev->regs[dev->cur_reg]; } } @@ -406,6 +407,7 @@ w83787f_reset(w83787f_t *dev) dev->regs[0x00] = 0xd0; fdc_reset(dev->fdc); + w83787f_fdc_handler(dev); dev->regs[0x01] = 0x2C; dev->regs[0x03] = 0x70; diff --git a/src/sio/sio_w83877f.c b/src/sio/sio_w83877f.c index 8cbb82876..c9a437630 100644 --- a/src/sio/sio_w83877f.c +++ b/src/sio/sio_w83877f.c @@ -78,12 +78,12 @@ w83877f_remap(w83877f_t *dev) { uint8_t hefras = HEFRAS; - io_removehandler(0x250, 0x0002, + io_removehandler(0x250, 0x0003, w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev); io_removehandler(FDC_PRIMARY_ADDR, 0x0002, w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev); dev->base_address = (hefras ? FDC_PRIMARY_ADDR : 0x250); - io_sethandler(dev->base_address, 0x0002, + io_sethandler(dev->base_address, hefras ? 0x0002 : 0x0003, w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev); dev->key_times = hefras + 1; dev->key = (hefras ? 0x86 : 0x88) | HEFERE; @@ -155,8 +155,9 @@ static void w83877f_fdc_handler(w83877f_t *dev) { fdc_remove(dev->fdc); - if (!(dev->regs[6] & 0x08) && (dev->regs[0x20] & 0xc0)) - fdc_set_base(dev->fdc, FDC_PRIMARY_ADDR); + if (dev->regs[0x20] & 0xc0) + fdc_set_base(dev->fdc, make_port(dev, 0x20)); + fdc_set_power_down(dev->fdc, !!(dev->regs[6] & 0x08)); } static void @@ -252,7 +253,7 @@ w83877f_write(uint16_t port, uint8_t val, void *priv) if (dev->cur_reg == 0x29) return; if (dev->cur_reg == 6) - val &= 0xF3; + val &= 0xFB; valxor = val ^ dev->regs[dev->cur_reg]; dev->regs[dev->cur_reg] = val; } else From 555cba7b8ae56a478410dc3024bffad9d63cb797 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 24 Jan 2024 05:22:22 +0100 Subject: [PATCH 335/936] RTL8139 changes: The PCI memory BAR is now 4096 bytes instead of 256 in order to fit into 86Box's memory mapping granularity, and implemented the undocumented CSCR reads discovered by RichardG when probing the real hardware. --- src/network/net_rtl8139.c | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index 74a1f90ff..a07becff0 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -308,6 +308,8 @@ enum CSCRBits { #endif enum CSCRBits { CSCR_Testfun = 1 << 15, /* 1 = Auto-neg speeds up internal timer, WO, def 0 */ + CSCR_Cable_Changed = 1 << 11, /* Undocumented: 1 = Cable status changed, 0 = No change */ + CSCR_Cable = 1 << 10, /* Undocumented: 1 = Cable connected, 0 = Cable disconnected */ CSCR_LD = 1 << 9, /* Active low TPI link disable signal. When low, TPI still transmits link pulses and TPI stays in good link state. def 1*/ CSCR_HEART_BIT = 1 << 8, /* 1 = HEART BEAT enable, 0 = HEART BEAT disable. HEART BEAT function is only valid in 10Mbps mode. def 1*/ CSCR_JBEN = 1 << 7, /* 1 = enable jabber function. 0 = disable jabber function, def 1*/ @@ -2285,7 +2287,17 @@ rtl8139_TSAD_read(RTL8139State *s) static uint16_t rtl8139_CSCR_read(RTL8139State *s) { - uint16_t ret = s->CSCR; + static uint16_t old_ret = 0xffff; + uint16_t ret = s->CSCR | + ((net_cards_conf[s->nic->card_num].link_state & NET_LINK_DOWN) ? 0 : CSCR_Cable); + + if (old_ret != 0xffff) { + ret &= ~CSCR_Cable_Changed; + if ((ret ^ old_ret) & CSCR_Cable) + ret |= CSCR_Cable_Changed; + } + + old_ret = ret; rtl8139_log("CSCR read val=0x%04x\n", ret); @@ -2736,6 +2748,13 @@ rtl8139_io_readb(uint32_t addr, void *priv) rtl8139_log("RTL8139C TxConfig at 0x43 read(b) val=0x%02x\n", ret); break; + case CSCR: + ret = rtl8139_CSCR_read(s) & 0xff; + break; + case CSCR + 1: + ret = rtl8139_CSCR_read(s) >> 8; + break; + default: rtl8139_log("not implemented read(b) addr=0x%x\n", addr); ret = 0; @@ -3105,6 +3124,10 @@ rtl8139_pci_read(UNUSED(int func), int addr, void *priv) return 1; case 0x14: return 0; +#ifndef USE_256_BYTE_BAR + case 0x15: + return s->pci_conf[addr & 0xFF] & 0xf0; +#endif case 0x2c: return 0xEC; case 0x2d: @@ -3169,10 +3192,20 @@ rtl8139_pci_write(int func, int addr, uint8_t val, void *priv) case 0x16: case 0x17: s->pci_conf[addr & 0xFF] = val; - s->mem_base = (s->pci_conf[0x15] << 8) | (s->pci_conf[0x16] << 16) | (s->pci_conf[0x17] << 24); + s->mem_base = (s->pci_conf[0x15] << 8) | (s->pci_conf[0x16] << 16) | + (s->pci_conf[0x17] << 24); +#ifndef USE_256_BYTE_BAR + s->mem_base &= 0xfffff000; +#endif rtl8139_log("New memory base: %08X\n", s->mem_base); if (s->pci_conf[0x4] & PCI_COMMAND_MEM) - mem_mapping_set_addr(&s->bar_mem, (s->pci_conf[0x15] << 8) | (s->pci_conf[0x16] << 16) | (s->pci_conf[0x17] << 24), 256); +#ifdef USE_256_BYTE_BAR + mem_mapping_set_addr(&s->bar_mem, (s->pci_conf[0x15] << 8) | (s->pci_conf[0x16] << 16) | + (s->pci_conf[0x17] << 24), 256); +#else + mem_mapping_set_addr(&s->bar_mem, ((s->pci_conf[0x15] & 0xf0) << 8) | + (s->pci_conf[0x16] << 16) | (s->pci_conf[0x17] << 24), 4096); +#endif break; case 0x3c: s->pci_conf[addr & 0xFF] = val; From ecafaa7daf4ddc2e52ce74d7efe0e55cb3ac7f59 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 24 Jan 2024 05:30:08 +0100 Subject: [PATCH 336/936] Update the GLaBIOS version to latest nightly, fixes #4074. --- src/machine/m_xt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 20a7da6ae..9a0b39a89 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -646,7 +646,7 @@ machine_xt_glabios_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/glabios/GLABIOS_0.2.5_8E.ROM", + ret = bios_load_linear("roms/machines/glabios/GLABIOS_0.2.6_8X_012324.ROM", 0x000fe000, 8192, 0); if (bios_only || !ret) @@ -655,4 +655,4 @@ machine_xt_glabios_init(const machine_t *model) machine_xt_init_ex(model); return ret; -} \ No newline at end of file +} From 13330322b491280f342f823c99e22e16626b5aa6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 24 Jan 2024 05:56:50 +0100 Subject: [PATCH 337/936] Interim mem.c/h code and a slight optimization to do_mmutranslate(). --- src/include/86box/mem.h | 2 + src/mem/mem.c | 81 +++++++++++++++++++++++++++-------------- 2 files changed, 56 insertions(+), 27 deletions(-) diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index db95d3f7b..8832ad7f9 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -449,6 +449,8 @@ extern void mem_close(void); extern void mem_reset(void); extern void mem_remap_top(int kb); +extern void umc_smram_recalc(uint32_t start, int set); + extern mem_mapping_t *read_mapping[MEM_MAPPINGS_NO]; extern mem_mapping_t *write_mapping[MEM_MAPPINGS_NO]; diff --git a/src/mem/mem.c b/src/mem/mem.c index 0b002b302..145202260 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -1585,40 +1585,38 @@ do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write) for (i = 0; i < num; i++) a64[i] = (uint64_t) addr; - for (i = 0; i < num; i++) { - if (cr0 >> 31) { - if (write && ((i == 0) || !(addr & 0xfff))) - cond = (!page_lookup[addr >> 12] || !page_lookup[addr >> 12]->write_b); + if (cr0 >> 31) for (i = 0; i < num; i++) { + if (write && ((i == 0) || !(addr & 0xfff))) + cond = (!page_lookup[addr >> 12] || !page_lookup[addr >> 12]->write_b); - if (cond) { - /* If we have encountered at least one page fault, mark all subsequent addresses as - having page faulted, prevents false negatives in readmem*l_no_mmut. */ - if ((i > 0) && cpu_state.abrt && !high_page) - a64[i] = a64[i - 1]; - /* If we are on the same page, there is no need to translate again, as we can just - reuse the previous result. */ - else if (i == 0) { - a = mmutranslatereal(addr, write); - a64[i] = (uint32_t) a; + if (cond) { + /* If we have encountered at least one page fault, mark all subsequent addresses as + having page faulted, prevents false negatives in readmem*l_no_mmut. */ + if ((i > 0) && cpu_state.abrt && !high_page) + a64[i] = a64[i - 1]; + /* If we are on the same page, there is no need to translate again, as we can just + reuse the previous result. */ + else if (i == 0) { + a = mmutranslatereal(addr, write); + a64[i] = (uint32_t) a; - high_page = high_page || (!cpu_state.abrt && (a > 0xffffffffULL)); - } else if (!(addr & 0xfff)) { - a = mmutranslatereal(last_addr, write); - a64[i] = (uint32_t) a; + high_page = high_page || (!cpu_state.abrt && (a > 0xffffffffULL)); + } else if (!(addr & 0xfff)) { + a = mmutranslatereal(last_addr, write); + a64[i] = (uint32_t) a; - high_page = high_page || (!cpu_state.abrt && (a64[i] > 0xffffffffULL)); + high_page = high_page || (!cpu_state.abrt && (a64[i] > 0xffffffffULL)); - if (!cpu_state.abrt) { - a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); - a64[i] = (uint32_t) a; - } - } else { + if (!cpu_state.abrt) { a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); a64[i] = (uint32_t) a; } - } else - mmu_perm = page_lookupp[addr >> 12]; - } + } else { + a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); + a64[i] = (uint32_t) a; + } + } else + mmu_perm = page_lookupp[addr >> 12]; addr++; } @@ -2871,6 +2869,35 @@ mem_init(void) writelookupp = malloc((1 << 20) * sizeof(uint8_t)); } +static void +umc_page_recalc(uint32_t c, int set) +{ + if (set) { + pages[c].mem = &ram[(c & 0xff) << 12]; + pages[c].write_b = mem_write_ramb_page; + pages[c].write_w = mem_write_ramw_page; + pages[c].write_l = mem_write_raml_page; + } else { + pages[c].mem = page_ff; + pages[c].write_b = NULL; + pages[c].write_w = NULL; + pages[c].write_l = NULL; + } + +#ifdef USE_NEW_DYNAREC + pages[c].evict_prev = EVICT_NOT_IN_LIST; + pages[c].byte_dirty_mask = &byte_dirty_mask[(c & 0xff) * 64]; + pages[c].byte_code_present_mask = &byte_code_present_mask[(c & 0xff) * 64]; +#endif +} + +void +umc_smram_recalc(uint32_t start, int set) +{ + for (uint32_t c = start; c < (start + 0x0020); c++) + umc_page_recalc(c, set); +} + void mem_remap_top(int kb) { From 95bb3ae33397de68ade0791e2602f56c025a815f Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 24 Jan 2024 06:00:56 +0100 Subject: [PATCH 338/936] IBM 5161: Set switches according to the total memory installed (on-board + any expansion cards), fixes #4070. --- src/device/ibm_5161.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/device/ibm_5161.c b/src/device/ibm_5161.c index 07083873e..762a379a1 100644 --- a/src/device/ibm_5161.c +++ b/src/device/ibm_5161.c @@ -73,8 +73,8 @@ ibm_5161_in(uint16_t port, void *priv) 02-03 = not used 04-07 = switch position 1 = Off - 0 =On */ - ret = dev->regs[3] & 0x01; + 0 = On */ + ret = (dev->regs[3] & 0x01) | (((~(0xf - ((mem_size + isa_mem_size) >> 6))) & 0xf) << 4); break; default: @@ -95,8 +95,7 @@ ibm_5161_close(void *priv) static void * ibm_5161_init(UNUSED(const device_t *info)) { - ibm_5161_t *dev = (ibm_5161_t *) malloc(sizeof(ibm_5161_t)); - memset(dev, 0, sizeof(ibm_5161_t)); + ibm_5161_t *dev = (ibm_5161_t *) calloc(1, sizeof(ibm_5161_t)); /* Extender Card Registers */ io_sethandler(0x0210, 0x0004, From 3e7ad13e36a006cdf4972151d78fd9edbb3f719c Mon Sep 17 00:00:00 2001 From: 640-KB <640kb@glabios.org> Date: Wed, 24 Jan 2024 10:33:04 -0500 Subject: [PATCH 339/936] Alphabetize XT machine_table list --- src/machine/machine_table.c | 78 ++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 101052f4e..860c68b61 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -709,6 +709,45 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + { + .name = "[8088] GLaBIOS", + .internal_name = "glabios", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_glabios_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 = 64, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc_device = &keyboard_xt_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, { .name = "[8088] Hyosung Topstar 88T", .internal_name = "top88", @@ -1804,45 +1843,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - { - .name = "[8088] GLaBIOS", - .internal_name = "glabios", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_glabios_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 = 64, - .max = 640, - .step = 64 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xt_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, { .name = "[GC100A] Philips P3120", .internal_name = "p3120", From ac78275cb831d8cf4ffb3e0dc49142862e794200 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 24 Jan 2024 20:45:44 +0100 Subject: [PATCH 340/936] EGA: Correct register (non-)readability on the Compaq EGA and light pen registers. --- src/include/86box/vid_ega.h | 2 ++ src/video/vid_ega.c | 33 ++++++++++++++++++++------------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/include/86box/vid_ega.h b/src/include/86box/vid_ega.h index ec241d613..0bccd607e 100644 --- a/src/include/86box/vid_ega.h +++ b/src/include/86box/vid_ega.h @@ -56,6 +56,8 @@ typedef struct ega_t { uint8_t *vram; + uint16_t light_pen; + int vidclock; int fast; int extvram; diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 7979cd958..dd84074e6 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -295,22 +295,22 @@ ega_in(uint16_t addr, void *priv) break; case 0x3c0: - if (ega_type) + if (ega_type == 1) ret = ega->attraddr | ega->attr_palette_enable; break; case 0x3c1: - if (ega_type) + if (ega_type == 1) ret = ega->attrregs[ega->attraddr]; break; case 0x3c2: ret = (egaswitches & (8 >> egaswitchread)) ? 0x10 : 0x00; break; case 0x3c4: - if (ega_type) + if (ega_type == 1) ret = ega->seqaddr; break; case 0x3c5: - if (ega_type) + if (ega_type == 1) ret = ega->seqregs[ega->seqaddr & 0xf]; break; case 0x3c6: @@ -318,24 +318,24 @@ ega_in(uint16_t addr, void *priv) ret = ega->ctl_mode; break; case 0x3c8: - if (ega_type) + if (ega_type == 1) ret = 2; break; case 0x3cc: - if (ega_type) + if (ega_type == 1) ret = ega->miscout; break; case 0x3ce: - if (ega_type) + if (ega_type == 1) ret = ega->gdcaddr; break; case 0x3cf: - if (ega_type) + if (ega_type == 1) ret = ega->gdcreg[ega->gdcaddr & 0xf]; break; case 0x3d0: case 0x3d4: - if (ega_type) + if (ega_type == 1) ret = ega->crtcreg; break; case 0x3d1: @@ -349,14 +349,21 @@ ega_in(uint16_t addr, void *priv) break; case 0x10: - case 0x11: - /* TODO: Return light pen address once implemented. */ - if (ega_type) + if (ega_type == 1) ret = ega->crtc[ega->crtcreg]; + else + ret = ega->light_pen >> 8; + break; + + case 0x11: + if (ega_type == 1) + ret = ega->crtc[ega->crtcreg]; + else + ret = ega->light_pen & 0xff; break; default: - if (ega_type) + if (ega_type == 1) ret = ega->crtc[ega->crtcreg]; break; } From cd03b6a31c57ddbdbd2b7fd71d5058f548db208c Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 25 Jan 2024 21:47:15 +0100 Subject: [PATCH 341/936] Packard Bell machines: PS/2 mouse commands now suspend dynamic recompilation until the response byte is read, fixes #552. --- src/cpu/386_dynarec.c | 3 ++- src/cpu/cpu.h | 3 +++ src/device/kbc_at.c | 5 +++++ src/device/mouse_ps2.c | 2 ++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index e132c0300..c96e3420d 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -48,6 +48,7 @@ #define CPU_BLOCK_END() cpu_block_end = 1 +int cpu_override_dynarec = 0; int inrecomp = 0; int cpu_block_end = 0; int cpu_end_block_after_ins = 0; @@ -718,7 +719,7 @@ exec386_dynarec(int32_t cycs) cycles_old = cycles; oldtsc = tsc; tsc_old = tsc; - if (!CACHE_ON()) /*Interpret block*/ + if ((!CACHE_ON()) || cpu_override_dynarec) /*Interpret block*/ { exec386_dynarec_int(); } else { diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index e185f2e4a..95625df55 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -833,6 +833,9 @@ extern void nmi_raise(void); extern MMX_REG *MMP[8]; extern uint16_t *MMEP[8]; +extern int cpu_block_end; +extern int cpu_override_dynarec; + extern void mmx_init(void); extern void prefetch_flush(void); diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index d2e6cf364..bc4a1f366 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -1787,6 +1787,9 @@ kbc_at_process_cmd(void *priv) if (dev->ib == 0xbb) break; + if (strstr(machine_get_internal_name(), "pb") != NULL) + cpu_override_dynarec = 1; + if (dev->misc_flags & FLAG_PS2) { set_enable_aux(dev, 1); if ((dev->ports[1] != NULL) && (dev->ports[1]->priv != NULL)) { @@ -1891,6 +1894,8 @@ kbc_at_read(uint16_t port, void *priv) This also means that in AT mode, the IRQ is level-triggered. */ if (!(dev->misc_flags & FLAG_PS2)) picintclevel(1 << 1, &dev->irq_state); + if ((strstr(machine_get_internal_name(), "pb") != NULL) && (cpu_override_dynarec == 1)) + cpu_override_dynarec = 0; break; case 0x64: diff --git a/src/device/mouse_ps2.c b/src/device/mouse_ps2.c index 35f0cd9e8..c3a7310f0 100644 --- a/src/device/mouse_ps2.c +++ b/src/device/mouse_ps2.c @@ -21,6 +21,7 @@ #include #define HAVE_STDARG_H #include <86box/86box.h> +#include "cpu.h" #include <86box/device.h> #include <86box/keyboard.h> #include <86box/mouse.h> @@ -276,6 +277,7 @@ ps2_write(void *priv) break; default: + mouse_ps2_log("%s: Bad command: %02X\n", dev->name, val); kbc_at_dev_queue_add(dev, 0xfe, 0); } } From 26ea0c822504e46d47ea3332dda82bd98ca3684f Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 25 Jan 2024 22:05:31 +0100 Subject: [PATCH 342/936] XGA update/slight fixes: 1. Remove some useless parentheses and correct some identation. 2. The reversed linear mapping activation and a5 vram test are reset properly now. 3. More correct Area Fill emulation, especially in 640x480 mode, (800x600 and 1024x768 too). --- src/video/vid_xga.c | 329 +++++++++++++++++++++----------------------- 1 file changed, 156 insertions(+), 173 deletions(-) diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 44e8aa6c3..fad5e4124 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -178,8 +178,8 @@ xga_updatemapping(svga_t *svga) } } - xga_log("XGA opmode (extended) = %d, disp mode = %d, aperture = %d.\n", xga->op_mode & 7, - xga->disp_cntl_2 & 7, xga->aperture_cntl); + xga_log("XGA opmode (extended) = %d, disp mode = %d, aperture = %d, on = %d, linear endian reverse = %d.\n", xga->op_mode & 7, + xga->disp_cntl_2 & 7, xga->aperture_cntl, xga->on, xga->linear_endian_reverse); } xga_log("VGA on = %d, map = %02x.\n", vga_on, svga->gdcreg[6] & 0x0c); } @@ -198,7 +198,7 @@ xga_recalctimings(svga_t *svga) xga->h_disp = (xga->hdisp + 1) << 3; - xga->rowoffset = (xga->hdisp + 1); + xga->rowoffset = xga->hdisp + 1; xga->interlace = !!(xga->disp_cntl_1 & 0x08); xga->rowcount = (xga->disp_cntl_2 & 0xc0) >> 6; @@ -213,6 +213,11 @@ xga_recalctimings(svga_t *svga) xga->ma_latch = xga->disp_start_addr; + if ((xga->disp_cntl_2 & 7) == 2) + xga->rowoffset >>= 1; + else if ((xga->disp_cntl_2 & 7) == 4) + xga->rowoffset <<= 1; + xga_log("XGA ClkSel1 = %d, ClkSel2 = %02x.\n", (xga->clk_sel_1 >> 2) & 3, xga->clk_sel_2 & 0x80); switch ((xga->clk_sel_1 >> 2) & 3) { case 0: @@ -410,7 +415,7 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) xga->cursor_data_on = 1; else if ((xga->sprite_pos >= 1) || (((xga->disp_cntl_2 & 7) == 2) || (xga->disp_cntl_2 & 7) == 4)) xga->cursor_data_on = 1; - else if (xga->aperture_cntl == 0) { + else if (!xga->aperture_cntl) { if (xga->linear_endian_reverse && !(xga->access_mode & 8)) xga->cursor_data_on = 0; } @@ -422,10 +427,11 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) xga->cursor_data_on = 1; else xga->cursor_data_on = 0; - } else { + } else xga->cursor_data_on = 0; - } - } + } else if (!xga->sprite_pos && xga->cursor_data_on && !xga->aperture_cntl && xga->linear_endian_reverse) + xga->cursor_data_on = 0; + xga_log("Sprite POS = %d, data on = %d, idx = %d, apcntl = %d\n", xga->sprite_pos, xga->cursor_data_on, xga->sprite_pal_addr_idx, xga->aperture_cntl); @@ -998,9 +1004,9 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int addr += x; if (!skip) { READ(addr, byte); - } else { + } else byte = mem_readb_phys(addr); - } + return byte; case 4: /*16-bit*/ addr += (y * (width << 1)); @@ -1082,6 +1088,7 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui } else { byte = mem_readb_phys(addr); } + if (xga->linear_endian_reverse) mask = 0x0f << ((1 - (x & 1)) << 2); else { @@ -1259,31 +1266,17 @@ xga_line_draw_write(svga_t *svga) uint32_t plane_mask = xga->accel.plane_mask; uint32_t dstbase = xga->accel.px_map_base[xga->accel.dst_map]; uint32_t srcbase = xga->accel.px_map_base[xga->accel.src_map]; - int dminor; - int destxtmp; - int dmajor; - int err; int y = xga->accel.blt_width; int x = 0; int16_t dx; int16_t dy; - int draw_pixel; + int16_t cx; + int16_t cy; + int err = xga->accel.bres_err_term; + int draw_pixel = 0; - dminor = xga->accel.bres_k1; - if (xga->accel.bres_k1 & 0x2000) - dminor |= ~0x1fff; - - dminor >>= 1; - - destxtmp = xga->accel.bres_k2; - if (xga->accel.bres_k2 & 0x2000) - destxtmp |= ~0x1fff; - - dmajor = -(destxtmp - (dminor << 1)) >> 1; - - err = xga->accel.bres_err_term; - if (xga->accel.bres_err_term & 0x2000) - err |= ~0x1fff; + cx = xga->accel.src_map_x & 0xfff; + cy = xga->accel.src_map_y & 0xfff; dx = xga->accel.dst_map_x & 0x1fff; if (xga->accel.dst_map_x >= 0x1800) @@ -1300,75 +1293,46 @@ xga_line_draw_write(svga_t *svga) if (xga->accel.pat_src == 8) { if ((xga->accel.command & 0x30) == 0x30) { while (y >= 0) { - draw_pixel = 1; + draw_pixel = 0; + + if (xga->accel.octant & 0x01) { + if (xga->accel.octant & 0x02) { /*Bottom-to-Top*/ + if (x) + draw_pixel = 1; + } else { /*Top-to-Bottom*/ + if (y) + draw_pixel = 1; + } + } else if (!(xga->accel.octant & 0x04) && (err < (xga->accel.bres_k2 + xga->accel.bres_k1))) /*X+*/ + draw_pixel = 1; + else if ((xga->accel.octant & 0x04) && (err >= 0)) /*X-*/ + draw_pixel = 1; if (xga->accel.command & 0xc0) { if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; + if (draw_pixel) { + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); + + if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { + ROP(1, dest_dat, src_dat); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + } + } + } + } else { + if (draw_pixel) { + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { ROP(1, dest_dat, src_dat); - dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - if (xga->accel.octant & 0x01) { /*Y Major*/ - if (xga->accel.octant & 0x02) { /*Bottom-to-Top*/ - if (!x) - draw_pixel = 0; - } else { /*Top-to-Bottom*/ - if (!y) - draw_pixel = 0; - } - } else { - if (err >= 0) { - if (xga->accel.octant & 0x02) { /*Bottom-to-Top*/ - if (!x) - draw_pixel = 0; - } else { /*Top-to-Bottom*/ - if (!y) - draw_pixel = 0; - } - } else - draw_pixel = 0; - } - - if (draw_pixel) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); - } - } - } else { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); - - if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { - ROP(1, dest_dat, src_dat); - dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - if (xga->accel.octant & 0x01) { /*Y Major*/ - if (xga->accel.octant & 0x02) { /*Bottom-to-Top*/ - if (!x) - draw_pixel = 0; - } else { /*Top-to-Bottom*/ - if (!y) - draw_pixel = 0; - } - } else { - if (err >= 0) { - if (xga->accel.octant & 0x02) { /*Bottom-to-Top*/ - if (!x) - draw_pixel = 0; - } else { /*Top-to-Bottom*/ - if (!y) - draw_pixel = 0; - } - } else - draw_pixel = 0; - } - - if (draw_pixel) xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + } } } - if (!y) + if (x == xga->accel.blt_width) break; if (xga->accel.octant & 0x01) { @@ -1377,34 +1341,31 @@ xga_line_draw_write(svga_t *svga) else dy++; - while (err >= 0) { - err -= (dmajor << 1); + if (err >= 0) { + err += xga->accel.bres_k2; if (xga->accel.octant & 0x04) dx--; else dx++; - } - - err += (dminor << 1); + } else + err += xga->accel.bres_k1; } else { if (xga->accel.octant & 0x04) dx--; else dx++; - while (err >= 0) { - err -= (dmajor << 1); + if (err >= 0) { + err += xga->accel.bres_k2; if (xga->accel.octant & 0x02) dy--; else dy++; - } - - err += (dminor << 1); + } else + err += xga->accel.bres_k1; } - - y--; x++; + y--; } } else { while (y >= 0) { @@ -1451,47 +1412,40 @@ xga_line_draw_write(svga_t *svga) else dy++; - while (err >= 0) { - err -= (dmajor << 1); + if (err >= 0) { + err += xga->accel.bres_k2; if (xga->accel.octant & 0x04) dx--; else dx++; - } - - err += (dminor << 1); + } else + err += xga->accel.bres_k1; } else { if (xga->accel.octant & 0x04) dx--; else dx++; - while (err >= 0) { - err -= (dmajor << 1); + if (err >= 0) { + err += xga->accel.bres_k2; if (xga->accel.octant & 0x02) dy--; else dy++; - } - - err += (dminor << 1); + } else + err += xga->accel.bres_k1; } - y--; x++; } } } - - xga->accel.dst_map_x = dx; - xga->accel.dst_map_y = dy; } static void xga_bitblt(svga_t *svga) { xga_t *xga = (xga_t *) svga->xga; - uint8_t area_state = 0; uint32_t src_dat; uint32_t dest_dat; uint32_t old_dest_dat; @@ -1530,6 +1484,7 @@ xga_bitblt(svga_t *svga) xga_log("D(%d,%d), SWH(%d,%d), BLT(%d,%d), dstwidth=%d.\n", dx, dy, xga->accel.x, xga->accel.y, srcwidth, srcheight, dstwidth); xga->accel.pattern = 0; + xga->accel.filling = 0; xga_log("XGA bitblt linear endian reverse=%d, access_mode=%x, octanty=%d, src command = %08x, " "pxsrcmap=%x, pxpatmap=%x, pxdstmap=%x, srcmap=%d, patmap=%d, dstmap=%d, " @@ -1660,70 +1615,66 @@ xga_bitblt(svga_t *svga) xga->accel.px_map_width[0], xga->accel.px_map_width[1], xga->accel.px_map_width[2], xga->accel.px_map_width[3], bkgdcol); - if (((xga->accel.command >> 24) & 0x0f) == 0x0a) { + if ((((xga->accel.command >> 24) & 0x0f) == 0x0a) && ((xga->accel.bkgd_mix & 0x1f) == 5)) { while (xga->accel.y >= 0) { mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, xga->accel.pat_src, patbase, patwidth + 1); if (mix) - area_state = !area_state; + xga->accel.filling = !xga->accel.filling; if (xga->accel.command & 0xc0) { if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - if (area_state) - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol; - else - src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol; - - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); - if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { - old_dest_dat = dest_dat; - ROP(area_state, dest_dat, src_dat); - dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_log("1SRCDat=%02x, DSTDat=%02x, Old=%02x, MIX=%d.\n", src_dat, dest_dat, old_dest_dat, area_state); - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol; + if (xga->accel.filling) { + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, 1024, 0); + if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { + old_dest_dat = dest_dat; + ROP(1, dest_dat, src_dat); + dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); + xga_log("1SRCDat=%02x, DSTDat=%02x, Old=%02x, MIX=%d.\n", src_dat, dest_dat, old_dest_dat, area_state); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + } } } } else { if ((dx >= 0) && (dx <= dstwidth) && (dy >= 0) && (dy <= dstheight)) { - if (area_state) - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol; - else - src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol; - - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); - if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { - old_dest_dat = dest_dat; - ROP(area_state, dest_dat, src_dat); - dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_log("2Fill: NumXY(%d,%d): DXY(%d,%d): SRCDat=%02x, DSTDat=%02x, Old=%02x, frgdcol=%02x, bkgdcol=%02x, MIX=%d, frgdmix=%02x, bkgdmix=%02x, dstmapfmt=%02x, srcmapfmt=%02x, srcmapnum=%d.\n", x, y, dx, dy, src_dat, dest_dat, old_dest_dat, frgdcol, bkgdcol, area_state, xga->accel.frgd_mix & 0x1f, xga->accel.bkgd_mix & 0x1f, xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, xga->accel.px_map_format[xga->accel.src_map] & 0x0f, xga->accel.src_map); - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol; + if (xga->accel.filling) { + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); + if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { + old_dest_dat = dest_dat; + ROP(1, dest_dat, src_dat); + dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); + xga_log("2Fill: NumXY(%d,%d): DXY(%d,%d): SRCDat=%02x, DSTDat=%02x, Old=%02x, frgdcol=%02x, bkgdcol=%02x, MIX=%d, frgdmix=%02x, bkgdmix=%02x, dstmapfmt=%02x, srcmapfmt=%02x, srcmapnum=%d.\n", x, y, dx, dy, src_dat, dest_dat, old_dest_dat, frgdcol, bkgdcol, area_state, xga->accel.frgd_mix & 0x1f, xga->accel.bkgd_mix & 0x1f, xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, xga->accel.px_map_format[xga->accel.src_map] & 0x0f, xga->accel.src_map); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + } } } } - xga->accel.sx = ((xga->accel.sx + 1) & srcwidth) | (xga->accel.sx & ~srcwidth); - xga->accel.px = ((xga->accel.px + 1) & patwidth) | (xga->accel.px & ~patwidth); + xga->accel.sx = ((xga->accel.sx + xdir) & srcwidth) | (xga->accel.sx & ~srcwidth); + xga->accel.px++; + dx++; xga->accel.x--; if (xga->accel.x < 0) { - area_state = 0; xga->accel.y--; xga->accel.x = xga->accel.blt_width & 0xfff; dx = xga->accel.dst_map_x & 0x1fff; if (xga->accel.dst_map_x >= 0x1800) dx |= ~0x17ff; + xga->accel.sx = xga->accel.src_map_x & 0xfff; xga->accel.px = xga->accel.pat_map_x & 0xfff; xga->accel.sy = ((xga->accel.sy + ydir) & srcheight) | (xga->accel.sy & ~srcheight); - xga->accel.py += ydir; - dy += ydir; + xga->accel.py++; - if (xga->accel.y < 0) { - xga->accel.dst_map_x = dx; - xga->accel.dst_map_y = dy; + dy++; + xga->accel.filling = 0; + + if (xga->accel.y < 0) return; - } } } } else { @@ -1777,6 +1728,7 @@ xga_bitblt(svga_t *svga) dx = xga->accel.dst_map_x & 0x1fff; if (xga->accel.dst_map_x >= 0x1800) dx |= ~0x17ff; + xga->accel.sx = xga->accel.src_map_x & 0xfff; xga->accel.px = xga->accel.pat_map_x & 0xfff; @@ -1870,7 +1822,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) if (len >= 2) { xga->accel.bres_err_term = val & 0x3fff; if (val & 0x2000) - xga->accel.bres_err_term |= ~0x3fff; + xga->accel.bres_err_term |= ~0x1fff; } else xga->accel.bres_err_term = (xga->accel.bres_err_term & 0x3f00) | val; break; @@ -1878,7 +1830,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) if (len == 1) { xga->accel.bres_err_term = (xga->accel.bres_err_term & 0xff) | ((val & 0x3f) << 8); if (val & 0x20) - xga->accel.bres_err_term |= ~0x3fff; + xga->accel.bres_err_term |= ~0x1fff; } break; @@ -1886,7 +1838,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) if (len >= 2) { xga->accel.bres_k1 = val & 0x3fff; if (val & 0x2000) - xga->accel.bres_k1 |= ~0x3fff; + xga->accel.bres_k1 |= ~0x1fff; } else xga->accel.bres_k1 = (xga->accel.bres_k1 & 0x3f00) | val; break; @@ -1894,7 +1846,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) if (len == 1) { xga->accel.bres_k1 = (xga->accel.bres_k1 & 0xff) | ((val & 0x3f) << 8); if (val & 0x20) - xga->accel.bres_k1 |= ~0x3fff; + xga->accel.bres_k1 |= ~0x1fff; } break; @@ -1902,7 +1854,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) if (len >= 2) { xga->accel.bres_k2 = val & 0x3fff; if (val & 0x2000) - xga->accel.bres_k2 |= ~0x3fff; + xga->accel.bres_k2 |= ~0x1fff; } else xga->accel.bres_k2 = (xga->accel.bres_k2 & 0x3f00) | val; break; @@ -1910,7 +1862,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) if (len == 1) { xga->accel.bres_k2 = (xga->accel.bres_k2 & 0xff) | ((val & 0x3f) << 8); if (val & 0x20) - xga->accel.bres_k2 |= ~0x3fff; + xga->accel.bres_k2 |= ~0x1fff; } break; @@ -2015,6 +1967,30 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) xga->accel.plane_mask = (xga->accel.plane_mask & 0x00ffffff) | (val << 24); break; + case 0x54: + if (len == 4) + xga->accel.carry_chain = val; + else if (len == 2) + xga->accel.carry_chain = (xga->accel.carry_chain & 0xffff0000) | val; + else + xga->accel.carry_chain = (xga->accel.carry_chain & 0xffffff00) | val; + break; + case 0x55: + if (len == 1) + xga->accel.carry_chain = (xga->accel.carry_chain & 0xffff00ff) | (val << 8); + break; + case 0x56: + if (len == 2) + xga->accel.carry_chain = (xga->accel.carry_chain & 0x0000ffff) | (val << 16); + else + xga->accel.carry_chain = (xga->accel.carry_chain & 0xff00ffff) | (val << 16); + break; + case 0x57: + if (len == 1) + xga->accel.carry_chain = (xga->accel.carry_chain & 0x00ffffff) | (val << 24); + break; + + case 0x58: if (len == 4) xga->accel.frgd_color = val; @@ -2454,7 +2430,7 @@ xga_hwcursor_draw(svga_t *svga, int displine) int y_pos; int comb = 0; uint32_t *p; - int idx = (xga->cursor_data_on) ? 32 : 0; + int idx = xga->cursor_data_on ? 32 : 0; if (xga->interlace && xga->hwcursor_oddeven) xga->hwcursor_latch.addr += 16; @@ -2549,20 +2525,24 @@ xga_render_4bpp(svga_t *svga) for (int x = 0; x <= xga->h_disp; x += 16) { dat = *(uint32_t *) (&xga->vram[xga->ma & xga->vram_mask]); - p[0] = xga->pallook[(dat >> 4) & 0x0f]; - p[1] = xga->pallook[dat & 0x0f]; - p[2] = xga->pallook[(dat >> 12) & 0x0f]; - p[3] = xga->pallook[(dat >> 8) & 0x0f]; - p[4] = xga->pallook[(dat >> 20) & 0x0f]; - p[5] = xga->pallook[(dat >> 16) & 0x0f]; - p[6] = xga->pallook[(dat >> 28) & 0x0f]; - p[7] = xga->pallook[(dat >> 24) & 0x0f]; + p[0] = xga->pallook[dat & 0x0f]; + p[1] = xga->pallook[(dat >> 4) & 0x0f]; + p[2] = xga->pallook[(dat >> 8) & 0x0f]; + p[3] = xga->pallook[(dat >> 12) & 0x0f]; + p[4] = xga->pallook[(dat >> 16) & 0x0f]; + p[5] = xga->pallook[(dat >> 20) & 0x0f]; + p[6] = xga->pallook[(dat >> 24) & 0x0f]; + p[7] = xga->pallook[(dat >> 28) & 0x0f]; dat = *(uint32_t *) (&xga->vram[(xga->ma + 4) & xga->vram_mask]); - p[9] = xga->pallook[dat & 0x0f]; - p[11] = xga->pallook[(dat >> 8) & 0x0f]; - p[13] = xga->pallook[(dat >> 16) & 0x0f]; - p[15] = xga->pallook[(dat >> 24) & 0x0f]; + p[8] = xga->pallook[dat & 0x0f]; + p[9] = xga->pallook[(dat >> 4) & 0x0f]; + p[10] = xga->pallook[(dat >> 8) & 0x0f]; + p[11] = xga->pallook[(dat >> 12) & 0x0f]; + p[12] = xga->pallook[(dat >> 16) & 0x0f]; + p[13] = xga->pallook[(dat >> 20) & 0x0f]; + p[14] = xga->pallook[(dat >> 24) & 0x0f]; + p[15] = xga->pallook[(dat >> 28) & 0x0f]; xga->ma += 8; p += 16; @@ -2626,7 +2606,7 @@ xga_render_16bpp(svga_t *svga) xga->firstline_draw = xga->displine; xga->lastline_draw = xga->displine; - for (x = 0; x <= (xga->h_disp); x += 8) { + for (x = 0; x <= xga->h_disp; x += 8) { dat = *(uint32_t *) (&xga->vram[(xga->ma + (x << 1)) & xga->vram_mask]); p[x] = video_16to32[dat & 0xffff]; p[x + 1] = video_16to32[dat >> 16]; @@ -2969,9 +2949,8 @@ xga_poll(void *priv, svga_t *svga) video_wait_for_buffer_monitor(svga->monitor_index); } - if (xga->hwcursor_on) { + if (xga->hwcursor_on) xga->changedvram[xga->ma >> 12] = xga->changedvram[(xga->ma >> 12) + 1] = xga->interlace ? 3 : 2; - } xga_do_render(svga); @@ -2993,9 +2972,10 @@ xga_poll(void *priv, svga_t *svga) if (xga->sc == xga->rowcount) { xga->sc = 0; - xga->maback += (xga->rowoffset << (xga->disp_cntl_2 & 7)); + xga->maback += (xga->rowoffset << 3); if (xga->interlace) - xga->maback += (xga->rowoffset << (xga->disp_cntl_2 & 7)); + xga->maback += (xga->rowoffset << 3); + xga->maback &= xga->vram_mask; xga->ma = xga->maback; } else { @@ -3013,6 +2993,7 @@ xga_poll(void *priv, svga_t *svga) xga->ma = xga->maback = (xga->rowoffset << 1); else xga->ma = xga->maback = 0; + xga->ma = (xga->ma << 2); xga->maback = (xga->maback << 2); @@ -3152,6 +3133,8 @@ xga_mca_reset(void *priv) xga->on = 0; vga_on = 1; xga_mca_write(0x102, 0, svga); + xga->linear_endian_reverse = 0; + xga->a5_test = 0; } static void From 40dc25466c96eef30935c374092cfa5d5e2bfd7b Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 25 Jan 2024 23:42:26 +0100 Subject: [PATCH 343/936] Updated CPU clock selection on Compaq 286/386 based machines. Per their manuals, see above and below (manuals only) --- src/cpu/cpu.h | 58 +++++++++++----------- src/cpu/cpu_table.c | 95 +++++++++++++++++++++++++++++++++++++ src/machine/machine_table.c | 10 ++-- 3 files changed, 131 insertions(+), 32 deletions(-) diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 95625df55..6a03fc328 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -86,33 +86,37 @@ enum { }; enum { - CPU_PKG_8088 = (1 << 0), - CPU_PKG_8088_EUROPC = (1 << 1), - CPU_PKG_8086 = (1 << 2), - CPU_PKG_188 = (1 << 3), - CPU_PKG_186 = (1 << 4), - CPU_PKG_286 = (1 << 5), - CPU_PKG_386SX = (1 << 6), - CPU_PKG_386DX = (1 << 7), - CPU_PKG_M6117 = (1 << 8), - CPU_PKG_386SLC_IBM = (1 << 9), - CPU_PKG_486SLC = (1 << 10), - CPU_PKG_486SLC_IBM = (1 << 11), - CPU_PKG_486BL = (1 << 12), - CPU_PKG_486DLC = (1 << 13), - CPU_PKG_SOCKET1 = (1 << 14), - CPU_PKG_SOCKET3 = (1 << 15), - CPU_PKG_SOCKET3_PC330 = (1 << 16), - CPU_PKG_STPC = (1 << 17), - CPU_PKG_SOCKET4 = (1 << 18), - CPU_PKG_SOCKET5_7 = (1 << 19), - CPU_PKG_SOCKET8 = (1 << 20), - CPU_PKG_SLOT1 = (1 << 21), - CPU_PKG_SLOT2 = (1 << 22), - CPU_PKG_SLOTA = (1 << 23), - CPU_PKG_SOCKET370 = (1 << 24), - CPU_PKG_SOCKETA = (1 << 25), - CPU_PKG_EBGA368 = (1 << 26) + CPU_PKG_8088 = (1 << 0), + CPU_PKG_8088_EUROPC = (1 << 1), + CPU_PKG_8086 = (1 << 2), + CPU_PKG_188 = (1 << 3), + CPU_PKG_186 = (1 << 4), + CPU_PKG_286 = (1 << 5), + CPU_PKG_286_CPQ_PORTABLE_II = (1 << 6), + CPU_PKG_386SX = (1 << 7), + CPU_PKG_386DX = (1 << 8), + CPU_PKG_386DX_CPQ_09_1986 = (1 << 9), + CPU_PKG_386DX_CPQ_1987 = (1 << 10), + CPU_PKG_386DX_CPQ_05_1988 = (1 << 11), + CPU_PKG_M6117 = (1 << 12), + CPU_PKG_386SLC_IBM = (1 << 13), + CPU_PKG_486SLC = (1 << 14), + CPU_PKG_486SLC_IBM = (1 << 15), + CPU_PKG_486BL = (1 << 16), + CPU_PKG_486DLC = (1 << 17), + CPU_PKG_SOCKET1 = (1 << 18), + CPU_PKG_SOCKET3 = (1 << 19), + CPU_PKG_SOCKET3_PC330 = (1 << 20), + CPU_PKG_STPC = (1 << 21), + CPU_PKG_SOCKET4 = (1 << 22), + CPU_PKG_SOCKET5_7 = (1 << 23), + CPU_PKG_SOCKET8 = (1 << 24), + CPU_PKG_SLOT1 = (1 << 25), + CPU_PKG_SLOT2 = (1 << 26), + CPU_PKG_SLOTA = (1 << 27), + CPU_PKG_SOCKET370 = (1 << 28), + CPU_PKG_SOCKETA = (1 << 29), + CPU_PKG_EBGA368 = (1 << 30) }; #define MANU_INTEL 0 diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 947804014..89b25e152 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -1004,6 +1004,65 @@ const cpu_family_t cpu_families[] = { { .name = "", 0 } } }, { + .package = CPU_PKG_286_CPQ_PORTABLE_II, + .manufacturer = "Intel", + .name = "80286", + .internal_name = "286", + .cpus = (const CPU[]) { + { + .name = "6", + .cpu_type = CPU_286, + .fpus = fpus_80286, + .rspeed = 6000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 2, + .mem_write_cycles = 2, + .cache_read_cycles = 2, + .cache_write_cycles = 2, + .atclk_div = 1 + }, + { + .name = "8", + .cpu_type = CPU_286, + .fpus = fpus_80286, + .rspeed = 8000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 2, + .mem_write_cycles = 2, + .cache_read_cycles = 2, + .cache_write_cycles = 2, + .atclk_div = 1 + }, + { + .name = "16", + .cpu_type = CPU_286, + .fpus = fpus_80286, + .rspeed = 16000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 3, + .mem_write_cycles = 3, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 2 + }, + { .name = "", 0 } + } + }, { .package = CPU_PKG_386SX, .manufacturer = "Intel", .name = "i386SX", @@ -1030,6 +1089,33 @@ const cpu_family_t cpu_families[] = { {"", 0} } }, { + .package = CPU_PKG_386DX_CPQ_09_1986, + .manufacturer = "Intel", + .name = "i386DX", + .internal_name = "i386dx", + .cpus = (const CPU[]) { + {"16", CPU_386DX, fpus_80286, 16000000, 1, 5000, 0x0308, 0, 0, 0, 3,3,3,3, 2}, + {"", 0} + } + }, { + .package = CPU_PKG_386DX_CPQ_1987, + .manufacturer = "Intel", + .name = "i386DX", + .internal_name = "i386dx", + .cpus = (const CPU[]) { + {"20", CPU_386DX, fpus_80386, 20000000, 1, 5000, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"", 0} + } + }, { + .package = CPU_PKG_386DX_CPQ_05_1988, + .manufacturer = "Intel", + .name = "i386DX", + .internal_name = "i386dx", + .cpus = (const CPU[]) { + {"25", CPU_386DX, fpus_80386, 25000000, 1, 5000, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"", 0} + } + }, { .package = CPU_PKG_386DX, .manufacturer = "Intel", .name = "i386DX", @@ -1170,6 +1256,15 @@ const cpu_family_t cpu_families[] = { {"", 0} } }, { + .package = CPU_PKG_386DX_CPQ_1987, + .manufacturer = "Cyrix", + .name = "Cx486DRx2", + .internal_name = "cx486drx2", + .cpus = (const CPU[]) { + {"40", CPU_486DLC, fpus_80386, 40000000, 2, 5000, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6}, + {"", 0} + } + }, { .package = CPU_PKG_386DX, .manufacturer = "Cyrix", .name = "Cx486DRx2", diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 860c68b61..2066b125b 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -2767,7 +2767,7 @@ const machine_t machines[] = { .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_286, + .package = CPU_PKG_286_CPQ_PORTABLE_II, .block = CPU_BLOCK_NONE, .min_bus = 0, .max_bus = 0, @@ -2807,7 +2807,7 @@ const machine_t machines[] = { .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_286, + .package = CPU_PKG_286_CPQ_PORTABLE_II, .block = CPU_BLOCK_NONE, .min_bus = 0, .max_bus = 0, @@ -4875,7 +4875,7 @@ const machine_t machines[] = { .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_386DX, + .package = CPU_PKG_386DX_CPQ_09_1986, .block = CPU_BLOCK_NONE, .min_bus = 0, .max_bus = 0, @@ -4914,7 +4914,7 @@ const machine_t machines[] = { .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_386DX, + .package = CPU_PKG_386DX_CPQ_05_1988, .block = CPU_BLOCK_NONE, .min_bus = 0, .max_bus = 0, @@ -4953,7 +4953,7 @@ const machine_t machines[] = { .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_386DX, + .package = CPU_PKG_386DX_CPQ_1987, .block = CPU_BLOCK_NONE, .min_bus = 0, .max_bus = 0, From e779ea5902e4b0d40d96c42ec22cf32076c69018 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 25 Jan 2024 21:17:05 -0300 Subject: [PATCH 344/936] Fix the Compaq CPU selection mess --- src/cpu/cpu.h | 58 +++++++++++----------- src/cpu/cpu_table.c | 95 ------------------------------------- src/machine/machine_table.c | 34 ++++++------- 3 files changed, 44 insertions(+), 143 deletions(-) diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 6a03fc328..95625df55 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -86,37 +86,33 @@ enum { }; enum { - CPU_PKG_8088 = (1 << 0), - CPU_PKG_8088_EUROPC = (1 << 1), - CPU_PKG_8086 = (1 << 2), - CPU_PKG_188 = (1 << 3), - CPU_PKG_186 = (1 << 4), - CPU_PKG_286 = (1 << 5), - CPU_PKG_286_CPQ_PORTABLE_II = (1 << 6), - CPU_PKG_386SX = (1 << 7), - CPU_PKG_386DX = (1 << 8), - CPU_PKG_386DX_CPQ_09_1986 = (1 << 9), - CPU_PKG_386DX_CPQ_1987 = (1 << 10), - CPU_PKG_386DX_CPQ_05_1988 = (1 << 11), - CPU_PKG_M6117 = (1 << 12), - CPU_PKG_386SLC_IBM = (1 << 13), - CPU_PKG_486SLC = (1 << 14), - CPU_PKG_486SLC_IBM = (1 << 15), - CPU_PKG_486BL = (1 << 16), - CPU_PKG_486DLC = (1 << 17), - CPU_PKG_SOCKET1 = (1 << 18), - CPU_PKG_SOCKET3 = (1 << 19), - CPU_PKG_SOCKET3_PC330 = (1 << 20), - CPU_PKG_STPC = (1 << 21), - CPU_PKG_SOCKET4 = (1 << 22), - CPU_PKG_SOCKET5_7 = (1 << 23), - CPU_PKG_SOCKET8 = (1 << 24), - CPU_PKG_SLOT1 = (1 << 25), - CPU_PKG_SLOT2 = (1 << 26), - CPU_PKG_SLOTA = (1 << 27), - CPU_PKG_SOCKET370 = (1 << 28), - CPU_PKG_SOCKETA = (1 << 29), - CPU_PKG_EBGA368 = (1 << 30) + CPU_PKG_8088 = (1 << 0), + CPU_PKG_8088_EUROPC = (1 << 1), + CPU_PKG_8086 = (1 << 2), + CPU_PKG_188 = (1 << 3), + CPU_PKG_186 = (1 << 4), + CPU_PKG_286 = (1 << 5), + CPU_PKG_386SX = (1 << 6), + CPU_PKG_386DX = (1 << 7), + CPU_PKG_M6117 = (1 << 8), + CPU_PKG_386SLC_IBM = (1 << 9), + CPU_PKG_486SLC = (1 << 10), + CPU_PKG_486SLC_IBM = (1 << 11), + CPU_PKG_486BL = (1 << 12), + CPU_PKG_486DLC = (1 << 13), + CPU_PKG_SOCKET1 = (1 << 14), + CPU_PKG_SOCKET3 = (1 << 15), + CPU_PKG_SOCKET3_PC330 = (1 << 16), + CPU_PKG_STPC = (1 << 17), + CPU_PKG_SOCKET4 = (1 << 18), + CPU_PKG_SOCKET5_7 = (1 << 19), + CPU_PKG_SOCKET8 = (1 << 20), + CPU_PKG_SLOT1 = (1 << 21), + CPU_PKG_SLOT2 = (1 << 22), + CPU_PKG_SLOTA = (1 << 23), + CPU_PKG_SOCKET370 = (1 << 24), + CPU_PKG_SOCKETA = (1 << 25), + CPU_PKG_EBGA368 = (1 << 26) }; #define MANU_INTEL 0 diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 89b25e152..947804014 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -1004,65 +1004,6 @@ const cpu_family_t cpu_families[] = { { .name = "", 0 } } }, { - .package = CPU_PKG_286_CPQ_PORTABLE_II, - .manufacturer = "Intel", - .name = "80286", - .internal_name = "286", - .cpus = (const CPU[]) { - { - .name = "6", - .cpu_type = CPU_286, - .fpus = fpus_80286, - .rspeed = 6000000, - .multi = 1, - .voltage = 5000, - .edx_reset = 0, - .cpuid_model = 0, - .cyrix_id = 0, - .cpu_flags = 0, - .mem_read_cycles = 2, - .mem_write_cycles = 2, - .cache_read_cycles = 2, - .cache_write_cycles = 2, - .atclk_div = 1 - }, - { - .name = "8", - .cpu_type = CPU_286, - .fpus = fpus_80286, - .rspeed = 8000000, - .multi = 1, - .voltage = 5000, - .edx_reset = 0, - .cpuid_model = 0, - .cyrix_id = 0, - .cpu_flags = 0, - .mem_read_cycles = 2, - .mem_write_cycles = 2, - .cache_read_cycles = 2, - .cache_write_cycles = 2, - .atclk_div = 1 - }, - { - .name = "16", - .cpu_type = CPU_286, - .fpus = fpus_80286, - .rspeed = 16000000, - .multi = 1, - .voltage = 5000, - .edx_reset = 0, - .cpuid_model = 0, - .cyrix_id = 0, - .cpu_flags = 0, - .mem_read_cycles = 3, - .mem_write_cycles = 3, - .cache_read_cycles = 3, - .cache_write_cycles = 3, - .atclk_div = 2 - }, - { .name = "", 0 } - } - }, { .package = CPU_PKG_386SX, .manufacturer = "Intel", .name = "i386SX", @@ -1089,33 +1030,6 @@ const cpu_family_t cpu_families[] = { {"", 0} } }, { - .package = CPU_PKG_386DX_CPQ_09_1986, - .manufacturer = "Intel", - .name = "i386DX", - .internal_name = "i386dx", - .cpus = (const CPU[]) { - {"16", CPU_386DX, fpus_80286, 16000000, 1, 5000, 0x0308, 0, 0, 0, 3,3,3,3, 2}, - {"", 0} - } - }, { - .package = CPU_PKG_386DX_CPQ_1987, - .manufacturer = "Intel", - .name = "i386DX", - .internal_name = "i386dx", - .cpus = (const CPU[]) { - {"20", CPU_386DX, fpus_80386, 20000000, 1, 5000, 0x0308, 0, 0, 0, 4,4,3,3, 3}, - {"", 0} - } - }, { - .package = CPU_PKG_386DX_CPQ_05_1988, - .manufacturer = "Intel", - .name = "i386DX", - .internal_name = "i386dx", - .cpus = (const CPU[]) { - {"25", CPU_386DX, fpus_80386, 25000000, 1, 5000, 0x0308, 0, 0, 0, 4,4,3,3, 3}, - {"", 0} - } - }, { .package = CPU_PKG_386DX, .manufacturer = "Intel", .name = "i386DX", @@ -1256,15 +1170,6 @@ const cpu_family_t cpu_families[] = { {"", 0} } }, { - .package = CPU_PKG_386DX_CPQ_1987, - .manufacturer = "Cyrix", - .name = "Cx486DRx2", - .internal_name = "cx486drx2", - .cpus = (const CPU[]) { - {"40", CPU_486DLC, fpus_80386, 40000000, 2, 5000, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6}, - {"", 0} - } - }, { .package = CPU_PKG_386DX, .manufacturer = "Cyrix", .name = "Cx486DRx2", diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 2066b125b..06069eed0 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -2767,10 +2767,10 @@ const machine_t machines[] = { .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_286_CPQ_PORTABLE_II, + .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, + .min_bus = 6000000, + .max_bus = 16000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -2807,10 +2807,10 @@ const machine_t machines[] = { .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_286_CPQ_PORTABLE_II, + .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, + .min_bus = 6000000, + .max_bus = 16000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -4875,10 +4875,10 @@ const machine_t machines[] = { .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_386DX_CPQ_09_1986, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, + .package = CPU_PKG_386DX, + .block = CPU_BLOCK(CPU_486DLC, CPU_RAPIDCAD), + .min_bus = 16000000, + .max_bus = 16000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -4914,10 +4914,10 @@ const machine_t machines[] = { .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_386DX_CPQ_05_1988, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, + .package = CPU_PKG_386DX, + .block = CPU_BLOCK(CPU_486DLC, CPU_RAPIDCAD), + .min_bus = 25000000, + .max_bus = 25000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -4953,10 +4953,10 @@ const machine_t machines[] = { .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_386DX_CPQ_1987, + .package = CPU_PKG_386DX, .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, + .min_bus = 20000000, + .max_bus = 20000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, From c996f69e8c8924d1d2f47a2a8af4529a6a023ed3 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 25 Jan 2024 21:27:39 -0300 Subject: [PATCH 345/936] Fix new machine names --- src/include/86box/machine.h | 10 +++++----- src/machine/m_at_slot1.c | 8 ++++---- src/machine/m_at_socket7.c | 4 ++-- src/machine/m_at_socket7_3v.c | 12 ++++++------ src/machine/m_at_socket8.c | 4 ++-- src/machine/machine_table.c | 20 ++++++++++---------- 6 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 73b27afbf..06443e101 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -638,7 +638,7 @@ extern int machine_at_8500tuc_init(const machine_t *); extern int machine_at_p55t2s_init(const machine_t *); extern int machine_at_p5vxb_init(const machine_t *); -extern int machine_at_dell_430vx_init(const machine_t *); +extern int machine_at_dellhannibalp_init(const machine_t *); extern int machine_at_gw2kte_init(const machine_t *); extern int machine_at_ap5s_init(const machine_t *); @@ -688,7 +688,7 @@ extern int machine_at_ficpa2012_init(const machine_t *); extern int machine_at_r534f_init(const machine_t *); extern int machine_at_ms5146_init(const machine_t *); -extern int machine_at_cb52x_si_init(const machine_t *); +extern int machine_at_cb52xsi_init(const machine_t *); extern int machine_at_m560_init(const machine_t *); extern int machine_at_ms5164_init(const machine_t *); @@ -710,7 +710,7 @@ extern int machine_at_p6rp4_init(const machine_t *); extern int machine_at_686nx_init(const machine_t *); extern int machine_at_acerv60n_init(const machine_t *); -extern int machine_at_lgibm440fx_init(const machine_t *); +extern int machine_at_lgibmx61_init(const machine_t *); extern int machine_at_vs440fx_init(const machine_t *); extern int machine_at_gw2kvenus_init(const machine_t *); extern int machine_at_ap440fx_init(const machine_t *); @@ -731,12 +731,12 @@ extern int machine_at_kn97_init(const machine_t *); extern int machine_at_lx6_init(const machine_t *); extern int machine_at_spitfire_init(const machine_t *); -extern int machine_at_mate_nx_ma30d_23d_init(const machine_t *); +extern int machine_at_ma30d_init(const machine_t *); extern int machine_at_p6i440e2_init(const machine_t *); extern int machine_at_p2bls_init(const machine_t *); -extern int machine_at_lgibm440bx_init(const machine_t *); +extern int machine_at_lgibmx7g_init(const machine_t *); extern int machine_at_p3bf_init(const machine_t *); extern int machine_at_bf6_init(const machine_t *); extern int machine_at_ax6bc_init(const machine_t *); diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 83e9b74a9..25cbde004 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -153,11 +153,11 @@ machine_at_spitfire_init(const machine_t *model) } int -machine_at_mate_nx_ma30d_23d_init(const machine_t *model) +machine_at_ma30d_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/mate_nx_ma30d_23d/BIOS.ROM", + ret = bios_load_linear("roms/machines/ma30d/BIOS.ROM", 0x000c0000, 262144, 0); if (bios_only || !ret) @@ -261,11 +261,11 @@ machine_at_p2bls_init(const machine_t *model) } int -machine_at_lgibm440bx_init(const machine_t *model) +machine_at_lgibmx7g_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/lgibm440bx/ms6119.331", + ret = bios_load_linear("roms/machines/lgibmx7g/ms6119.331", 0x000c0000, 262144, 0); if (bios_only || !ret) diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 46b95ce76..d06129b84 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -1211,11 +1211,11 @@ machine_at_ms5146_init(const machine_t *model) } int -machine_at_cb52x_si_init(const machine_t *model) +machine_at_cb52xsi_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/cb52x_si/CD5205S.ROM", + ret = bios_load_linear("roms/machines/cb52xsi/CD5205S.ROM", 0x000e0000, 131072, 0); if (bios_only || !ret) diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index 0e420aa3b..6b3df3c83 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -672,15 +672,15 @@ machine_at_p5vxb_init(const machine_t *model) } int -machine_at_dell_430vx_init(const machine_t *model) +machine_at_dellhannibalp_init(const machine_t *model) { int ret; - ret = bios_load_linear_combined2("roms/machines/dell_430vx/1003DY0J.BIO", - "roms/machines/dell_430vx/1003DY0J.BI1", - "roms/machines/dell_430vx/1003DY0J.BI2", - "roms/machines/dell_430vx/1003DY0J.BI3", - "roms/machines/dell_430vx/1003DY0J.RCV", + ret = bios_load_linear_combined2("roms/machines/dellhannibalp/1003DY0J.BIO", + "roms/machines/dellhannibalp/1003DY0J.BI1", + "roms/machines/dellhannibalp/1003DY0J.BI2", + "roms/machines/dellhannibalp/1003DY0J.BI3", + "roms/machines/dellhannibalp/1003DY0J.RCV", 0x3a000, 128); if (bios_only || !ret) diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index 7ce9d5095..e1dad68e7 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -195,11 +195,11 @@ machine_at_acerv60n_init(const machine_t *model) } int -machine_at_lgibm440fx_init(const machine_t *model) +machine_at_lgibmx61_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/lgibm440fx/bios.rom", + ret = bios_load_linear("roms/machines/lgibmx61/bios.rom", 0x000e0000, 131072, 0); if (bios_only || !ret) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 06069eed0..ed99ad076 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -9570,10 +9570,10 @@ const machine_t machines[] = { Command 0xA0 copyright string: (C)1994 AMI . */ { .name = "[i430VX] Dell Hannibal+", - .internal_name = "dell_430vx", + .internal_name = "dellhannibalp", .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430VX, - .init = machine_at_dell_430vx_init, + .init = machine_at_dellhannibalp_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, @@ -11122,10 +11122,10 @@ const machine_t machines[] = { /* Has the SiS 5571 chipset with on-chip KBC. */ { .name = "[SiS 5571] Daewoo CB52X-SI", - .internal_name = "cb52x_si", + .internal_name = "cb52xsi", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_SIS_5571, - .init = machine_at_cb52x_si_init, + .init = machine_at_cb52xsi_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, @@ -12024,10 +12024,10 @@ const machine_t machines[] = { /* Has the AMIKey-2 (updated 'H') KBC firmware. */ { .name = "[i440FX] LG IBM Multinet x61 (MSI MS-6106)", - .internal_name = "lgibm440fx", + .internal_name = "lgibmx61", .type = MACHINE_TYPE_SOCKET8, .chipset = MACHINE_CHIPSET_INTEL_440FX, - .init = machine_at_lgibm440fx_init, + .init = machine_at_lgibmx61_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, @@ -12357,10 +12357,10 @@ const machine_t machines[] = { AMIKey-2 KBC firmware. */ { .name = "[i440LX] NEC Mate NX MA30D/23D", - .internal_name = "mate_nx_ma30d_23d", + .internal_name = "ma30d", .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440LX, - .init = machine_at_mate_nx_ma30d_23d_init, + .init = machine_at_ma30d_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, @@ -12688,10 +12688,10 @@ const machine_t machines[] = { /* Has the AMIKey-2 (updated 'H') KBC firmware. */ { .name = "[i440BX] LG IBM Multinet i x7G (MSI MS-6119)", - .internal_name = "lgibm440bx", + .internal_name = "lgibmx7g", .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440BX, - .init = machine_at_lgibm440bx_init, + .init = machine_at_lgibmx7g_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, From aa28d7789ebbf6c79ef5fe4ad1840e1113b826e3 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 25 Jan 2024 21:43:14 -0300 Subject: [PATCH 346/936] Fix NEC MA30D parameters per a located spec sheet --- src/machine/m_at_slot1.c | 3 +-- src/machine/machine_table.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 25cbde004..12c84ffdf 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -183,8 +183,7 @@ machine_at_ma30d_init(const machine_t *model) device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c67x_device); device_add(&intel_flash_bxt_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 256); - device_add(&lm78_device); /* no reporting in BIOS */ + spd_register(SPD_TYPE_SDRAM, 0x7, 256); return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index ed99ad076..84a55eb75 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -12379,7 +12379,7 @@ const machine_t machines[] = { .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, .ram = { .min = 8192, - .max = 1048576, + .max = 786432, .step = 8192 }, .nvrmask = 255, From ce24961846b70cb88a0ea2bd7e87c9b3077e5da0 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 25 Jan 2024 21:50:33 -0300 Subject: [PATCH 347/936] Fix parameters for the MS-6119 machine --- src/machine/machine_table.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 84a55eb75..5a799cdb4 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -12699,9 +12699,9 @@ const machine_t machines[] = { .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 112121212, - .min_voltage = 1300, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1800, .max_voltage = 3500, .min_multi = 1.5, .max_multi = 8.0 @@ -12710,7 +12710,7 @@ const machine_t machines[] = { .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, .ram = { .min = 8192, - .max = 1048576, + .max = 786432, .step = 8192 }, .nvrmask = 255, From 0c8f03effa7f134ace159b1d562d3a1212f3ecce Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 26 Jan 2024 15:32:09 +0100 Subject: [PATCH 348/936] DEC 21140: Fix subsystem ID for the VPC Tulip, fixes #4081. --- src/network/net_tulip.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index a350d6662..00026deac 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -1375,13 +1375,23 @@ nic_init(const device_t *info) s->device_info = info; if (info->local != 3) { - /*Subsystem Vendor ID*/ - s->eeprom_data[0] = info->local ? 0x25 : 0x11; - s->eeprom_data[1] = 0x10; + if (info->local == 2) { + /*Subsystem Vendor ID*/ + s->eeprom_data[0] = 0x00; + s->eeprom_data[1] = 0x0a; - /*Subsystem ID*/ - s->eeprom_data[2] = info->local ? 0x10 : 0x0a; - s->eeprom_data[3] = info->local ? 0x03 : 0x50; + /*Subsystem ID*/ + s->eeprom_data[2] = 0x14; + s->eeprom_data[3] = 0x21; + } else { + /*Subsystem Vendor ID*/ + s->eeprom_data[0] = info->local ? 0x25 : 0x11; + s->eeprom_data[1] = 0x10; + + /*Subsystem ID*/ + s->eeprom_data[2] = info->local ? 0x10 : 0x0a; + s->eeprom_data[3] = info->local ? 0x03 : 0x50; + } /*Cardbus CIS Pointer low*/ s->eeprom_data[4] = 0x00; From 6d3e9642cecc33bdf0b995e3fe85608c047ac880 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 26 Jan 2024 16:23:53 +0100 Subject: [PATCH 349/936] SPEA Mercury P64V: Correctly caulculate the width at 1280x1024x24bpp. --- src/video/vid_s3.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 54f9047e8..d78dd03c7 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3920,6 +3920,7 @@ s3_recalctimings(svga_t *svga) case S3_VISION968: switch (s3->card_type) { case S3_MIROVIDEO40SV_ERGO_968: + case S3_SPEA_MERCURY_P64V: switch (s3->width) { case 1280: svga->hdisp = ((svga->hdisp << 1) / 3) << 1; From cfd8ec8088e85f16fb7428dda278053423e3a215 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 26 Jan 2024 19:03:43 +0100 Subject: [PATCH 350/936] Slight cleanup of the 8514/A compatible chips. Hopefully fix various modes altogether in all three chips (640x480, 800x600, 1024x768 and 1280x1024). --- src/include/86box/vid_8514a.h | 2 + src/video/vid_8514a.c | 88 ++++++++++++++++---------------- src/video/vid_ati_mach8.c | 94 ++++++++++++++++++++--------------- 3 files changed, 100 insertions(+), 84 deletions(-) diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h index dcfdf6045..ce346e84d 100644 --- a/src/include/86box/vid_8514a.h +++ b/src/include/86box/vid_8514a.h @@ -152,8 +152,10 @@ typedef struct ibm8514_t { int hblank_ext; int hblank_sub; + int v_total_reg; int v_total; int dispend; + int v_sync_start; int v_syncstart; int split; int h_disp; diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 9f2b1316a..fdbd39979 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -901,8 +901,10 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) case 0x6e8: case 0x6e9: if (!(port & 1)) { - dev->hdisped = val; - dev->hdisp = (dev->hdisped + 1) << 3; + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { + dev->hdisped = val; + dev->hdisp = (dev->hdisped + 1) << 3; + } } ibm8514_log("IBM 8514/A: H_DISP write 06E8 = %d, advfunc=%x.\n", dev->hdisp, dev->accel.advfunc_cntl & 4); break; @@ -910,8 +912,10 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) case 0xae8: case 0xae9: if (!(port & 1)) { - dev->hsync_start = val; - dev->hblankstart = (dev->hsync_start & 0x07) + 1; + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { + dev->hsync_start = val; + dev->hblankstart = (dev->hsync_start & 0x07) + 1; + } } ibm8514_log("IBM 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); break; @@ -919,32 +923,44 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) case 0xee8: case 0xee9: if (!(port & 1)) { - dev->hsync_width = val; - dev->hblank_end_val = (dev->hblankstart + (dev->hsync_start & 0x1f) - 1) & 0x3f; + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { + dev->hsync_width = val; + dev->hblank_end_val = (dev->hblankstart + (dev->hsync_start & 0x1f) - 1) & 0x3f; + } } ibm8514_log("IBM 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); break; case 0x12e8: case 0x12e9: - WRITE8(port, dev->vtotal, val); - dev->vtotal &= 0x1fff; + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { + WRITE8(port, dev->v_total_reg, val); + dev->v_total_reg &= 0x1fff; + dev->vtotal = dev->v_total_reg; + dev->vtotal++; + } break; case 0x16e8: case 0x16e9: - WRITE8(port, dev->v_disp, val); - dev->v_disp &= 0x1fff; - dev->vdisp = dev->v_disp; - dev->vdisp >>= 1; - dev->vdisp++; + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { + WRITE8(port, dev->v_disp, val); + dev->v_disp &= 0x1fff; + dev->vdisp = dev->v_disp; + dev->vdisp >>= 1; + dev->vdisp++; + } ibm8514_log("IBM 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp); break; case 0x1ae8: case 0x1ae9: - WRITE8(port, dev->vsyncstart, val); - dev->vsyncstart &= 0x1fff; + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { + WRITE8(port, dev->v_sync_start, val); + dev->v_sync_start &= 0x1fff; + dev->vsyncstart = dev->v_sync_start; + dev->vsyncstart++; + } break; case 0x1ee8: @@ -988,14 +1004,6 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) dev->on[port & 1] = dev->accel.advfunc_cntl & 0x01; vga_on = !dev->on[port & 1]; dev->vendor_mode[port & 1] = 0; - if (dev->on[0] || dev->on[1]) { - if (!(dev->accel.advfunc_cntl & 4)) { - if (dev->disp_cntl & 0x60) { - dev->hdisp = 640; - dev->vdisp = 480; - } - } - } ibm8514_log("IBM 8514/A: (0x%04x): ON=%d, shadow crt=%x.\n", port, dev->on[port & 1], dev->accel.advfunc_cntl & 4); svga_recalctimings(svga); break; @@ -4208,7 +4216,6 @@ ibm8514_poll(void *priv, svga_t *svga) dev->firstline--; wx = x; - wy = dev->lastline - dev->firstline; svga_doblit(wx, wy, svga); @@ -4262,17 +4269,14 @@ ibm8514_recalctimings(svga_t *svga) dev->h_total = dev->htotal + 1; dev->h_blankstart = dev->hblankstart; dev->h_blank_end_val = dev->hblank_end_val; - dev->v_total = dev->vtotal + 1; - dev->v_syncstart = dev->vsyncstart + 1; - dev->rowcount = !!(dev->disp_cntl & 0x08); + dev->v_total = dev->vtotal; + dev->v_syncstart = dev->vsyncstart; dev->dispend = dev->vdisp; + dev->rowcount = !!(dev->disp_cntl & 0x08); if (dev->dispend == 766) dev->dispend += 2; - if (dev->dispend == 598) - dev->dispend += 2; - if (dev->accel.advfunc_cntl & 4) { dev->pitch = 1024; if (!dev->h_disp) { @@ -4289,25 +4293,18 @@ ibm8514_recalctimings(svga_t *svga) svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; } - if (dev->interlace) + if (dev->interlace) { dev->dispend >>= 1; + dev->v_syncstart >>= 2; + dev->v_total >>= 2; + } else { + dev->v_syncstart >>= 1; + dev->v_total >>= 1; + } dev->rowoffset = 0x80; svga->map8 = dev->pallook; svga->render8514 = ibm8514_render_8bpp; - - dev->hblankend = (dev->h_blankstart & ~0x3f) | dev->h_blank_end_val; - if (dev->hblankend <= dev->h_blankstart) - dev->hblankend += 0x40; - dev->hblankend += dev->hblank_ext; - - dev->hblank_sub = 0; - if (dev->hblankend > dev->h_total) { - dev->hblankend &= 0x3f; - dev->hblank_sub = dev->hblankend + 1; - - dev->h_disp -= dev->hblank_sub; - } ibm8514_log("BPP=%d, Pitch = %d, rowoffset = %d, crtc13 = %02x, highres bit = %02x, has_vga? = %d.\n", dev->bpp, dev->pitch, dev->rowoffset, svga->crtc[0x13], dev->accel.advfunc_cntl & 4, !ibm8514_standalone_enabled); } } @@ -4440,10 +4437,13 @@ ibm8514_close(void *priv) { svga_t *svga = (svga_t *) priv; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + +#ifdef ATI_8514_ULTRA mach_t *mach = (mach_t *) svga->ext8514; if (mach) free(mach); +#endif if (dev) { free(dev->vram); diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index d710b2bcf..de40dc24e 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -59,7 +59,17 @@ static uint8_t mach_accel_inb(uint16_t port, void *priv); static uint16_t mach_accel_inw(uint16_t port, void *priv); static uint8_t mach_in(uint16_t addr, void *priv); -static void mach32_updatemapping(mach_t *mach, svga_t *svga); +#ifdef ATI_8514_ULTRA +static void ati8514_accel_outb(uint16_t port, uint8_t val, void *priv); +static void ati8514_accel_outw(uint16_t port, uint16_t val, void *priv); +static void ati8514_accel_outl(uint16_t port, uint32_t val, void *priv); +static uint8_t ati8514_accel_inb(uint16_t port, void *priv); +static uint16_t ati8514_accel_inw(uint16_t port, void *priv); +static uint32_t ati8514_accel_inl(uint16_t port, void *priv); +#endif + + +static void mach32_updatemapping(mach_t *mach, svga_t *svga); #ifdef ENABLE_MACH_LOG int mach_do_log = ENABLE_MACH_LOG; @@ -113,9 +123,9 @@ mach_log(const char *fmt, ...) #define READ_PIXTRANS_WORD(cx, n) \ if ((cmd == 0) || (cmd == 1) || (cmd == 5) || (mach->accel.cmd_type == -1)) { \ - if (dev->bpp) { \ + if (dev->bpp) \ temp = vram_w[((dev->accel.cy * dev->pitch) + (cx) + (n)) & (dev->vram_mask >> 1)]; \ - } else { \ + else { \ temp = dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & dev->vram_mask]; \ temp |= (dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ } \ @@ -2482,8 +2492,8 @@ ati8514_recalctimings(svga_t *svga) dev->h_total = dev->htotal + 1; dev->h_blankstart = dev->hblankstart; dev->h_blank_end_val = dev->hblank_end_val; - dev->v_total = dev->vtotal + 1; - dev->v_syncstart = dev->vsyncstart + 1; + dev->v_total = dev->vtotal; + dev->v_syncstart = dev->vsyncstart; dev->rowcount = !!(dev->disp_cntl & 0x08); dev->dispend = dev->vdisp; @@ -2604,8 +2614,8 @@ mach_recalctimings(svga_t *svga) dev->h_total = dev->htotal + 1; dev->h_blankstart = dev->hblankstart; dev->h_blank_end_val = dev->hblank_end_val; - dev->v_total = dev->vtotal + 1; - dev->v_syncstart = dev->vsyncstart + 1; + dev->v_total = dev->vtotal; + dev->v_syncstart = dev->vsyncstart; dev->dispend = dev->vdisp; dev->rowcount = !!(dev->disp_cntl & 0x08); @@ -2615,6 +2625,9 @@ mach_recalctimings(svga_t *svga) if (dev->dispend == 598) dev->dispend += 2; + if (dev->dispend == 478) + dev->dispend += 2; + if ((dev->local & 0xff) >= 0x02) { if ((dev->accel.advfunc_cntl ^ dev->modechange) & 0x04) { if ((mach->shadow_set ^ mach->compat_mode) & 0x03) @@ -2710,8 +2723,11 @@ mach_recalctimings(svga_t *svga) svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; if (((mach->shadow_set & 0x03) != 0x02) || !(dev->accel.advfunc_cntl & 0x04)) { /*Shadow set of 2 and bit 2 of port 0x4ae8 mean 1024x768+*/ - dev->h_disp = 640; - dev->dispend = 480; + if (!(mach->accel.clock_sel & 0x01)) { + dev->h_disp = 640; + dev->dispend = 480; + } + dev->interlace = 0; } } @@ -2726,26 +2742,12 @@ mach_recalctimings(svga_t *svga) dev->pitch = dev->ext_pitch; dev->rowoffset = dev->ext_crt_pitch; - mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x.\n", dev->accel.advfunc_cntl & 4, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3); + mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x interlace=%d.\n", dev->accel.advfunc_cntl & 4, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3, dev->interlace); svga->map8 = dev->pallook; svga->render8514 = ibm8514_render_8bpp; if (mach->regs[0xb8] & 0x40) svga->clock *= 2; } - - dev->hblankend = (dev->h_blankstart & ~0x3f) | dev->h_blank_end_val; - if (dev->hblankend <= dev->h_blankstart) - dev->hblankend += 0x40; - - dev->hblankend += dev->hblank_ext; - - dev->hblank_sub = 0; - if (dev->hblankend > dev->h_total) { - dev->hblankend &= 0x3f; - dev->hblank_sub = dev->hblankend + 1; - - dev->h_disp -= dev->hblank_sub; - } } if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { @@ -3636,7 +3638,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0x6e8: case 0x6e9: if (!(port & 1)) { - if (((dev->disp_cntl & 0x60) == 0x20) || (mach->accel.clock_sel & 0x01)) { + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { dev->hdisped = val; dev->hdisp = (dev->hdisped + 1) << 3; } @@ -3647,8 +3649,10 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0xae8: case 0xae9: if (!(port & 1)) { - dev->hsync_start = val; - dev->hblankstart = (dev->hsync_start & 0x07) + 1; + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { + dev->hsync_start = val; + dev->hblankstart = (dev->hsync_start & 0x07) + 1; + } } mach_log("ATI 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); break; @@ -3656,36 +3660,46 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0xee8: case 0xee9: if (!(port & 1)) { - dev->hsync_width = val; - dev->hblank_end_val = (dev->hblankstart + (dev->hsync_start & 0x1f) - 1) & 0x3f; + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { + dev->hsync_width = val; + dev->hblank_end_val = (dev->hblankstart + (dev->hsync_start & 0x1f) - 1) & 0x3f; + } } mach_log("ATI 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); break; case 0x12e8: case 0x12e9: - WRITE8(port, dev->vtotal, val); - dev->vtotal &= 0x1fff; + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { + WRITE8(port, dev->v_total_reg, val); + dev->v_total_reg &= 0x1fff; + dev->vtotal = dev->v_total_reg; + dev->vtotal++; + } break; case 0x16e8: case 0x16e9: - if (((dev->disp_cntl & 0x60) == 0x20) || (mach->accel.clock_sel & 0x01)) { + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { WRITE8(port, dev->v_disp, val); dev->v_disp &= 0x1fff; dev->vdisp = dev->v_disp; dev->vdisp >>= 1; dev->vdisp++; } - dev->modechange = dev->accel.advfunc_cntl & 4; - mach->compat_mode = mach->shadow_set & 3; + dev->modechange = dev->accel.advfunc_cntl & 0x04; + mach->compat_mode = mach->shadow_set & 0x03; mach_log("ATI 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp); break; case 0x1ae8: case 0x1ae9: - WRITE8(port, dev->vsyncstart, val); - dev->vsyncstart &= 0x1fff; + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { + WRITE8(port, dev->v_sync_start, val); + dev->v_sync_start &= 0x1fff; + dev->vsyncstart = dev->v_sync_start; + dev->vsyncstart++; + } break; case 0x1ee8: @@ -3694,7 +3708,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 break; case 0x22e8: - dev->disp_cntl = val & 0x7e; + dev->disp_cntl = val; dev->interlace = !!(val & 0x10); mach_log("ATI 8514/A: DISP_CNTL write 22E8 = %02x, interlace = %d\n", dev->disp_cntl, dev->interlace); break; @@ -4314,13 +4328,13 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in case 0xcaee: if (len == 1) - temp = dev->vsyncstart & 0xff; + temp = dev->v_sync_start & 0xff; else - temp = dev->vsyncstart; + temp = dev->v_sync_start; break; case 0xcaef: if (len == 1) - temp = dev->vsyncstart >> 8; + temp = dev->v_sync_start >> 8; break; case 0xceee: From 3f2a61ae70617e442d4f14a290ddfb25d8462828 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 27 Jan 2024 02:15:59 +0100 Subject: [PATCH 351/936] DEC Tulip: Make the memory BAR 4096 bytes in order to fit within 86Box's memory mapping granularity. --- src/network/net_rtl8139.c | 6 ++++- src/network/net_tulip.c | 52 +++++++++++++++++++++++++++++++++------ 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index a07becff0..8afb7b4b8 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -3124,8 +3124,10 @@ rtl8139_pci_read(UNUSED(int func), int addr, void *priv) return 1; case 0x14: return 0; -#ifndef USE_256_BYTE_BAR case 0x15: +#ifdef USE_256_BYTE_BAR + return s->pci_conf[addr & 0xFF]; +#else return s->pci_conf[addr & 0xFF] & 0xf0; #endif case 0x2c: @@ -3187,7 +3189,9 @@ rtl8139_pci_write(int func, int addr, uint8_t val, void *priv) rtl8139_io_writeb_ioport, rtl8139_io_writew_ioport, rtl8139_io_writel_ioport, priv); break; +#ifndef USE_256_BYTE_BAR case 0x14: +#endif case 0x15: case 0x16: case 0x17: diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index 00026deac..5fed7f1d1 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -1038,37 +1038,55 @@ tulip_writel_io(uint16_t addr, uint32_t data, void *opaque) static void tulip_mem_writeb(uint32_t addr, uint8_t data, void *opaque) { - return tulip_write(addr, data, opaque); + if ((addr & 0xfff) < 0x100) + tulip_write(addr, data, opaque); } static void tulip_mem_writew(uint32_t addr, uint16_t data, void *opaque) { - return tulip_write(addr, data, opaque); + if ((addr & 0xfff) < 0x100) + tulip_write(addr, data, opaque); } static void tulip_mem_writel(uint32_t addr, uint32_t data, void *opaque) { - return tulip_write(addr, data, opaque); + if ((addr & 0xfff) < 0x100) + tulip_write(addr, data, opaque); } static uint8_t tulip_mem_readb(uint32_t addr, void *opaque) { - return tulip_read(addr, opaque); + uint8_t ret = 0xff; + + if ((addr & 0xfff) < 0x100) + ret = tulip_read(addr, opaque); + + return ret; } static uint16_t tulip_mem_readw(uint32_t addr, void *opaque) { - return tulip_read(addr, opaque); + uint16_t ret = 0xffff; + + if ((addr & 0xfff) < 0x100) + ret = tulip_read(addr, opaque); + + return ret; } static uint32_t tulip_mem_readl(uint32_t addr, void *opaque) { - return tulip_read(addr, opaque); + uint32_t ret = 0xffffffff; + + if ((addr & 0xfff) < 0x100) + ret = tulip_read(addr, opaque); + + return ret; } static uint8_t @@ -1208,11 +1226,17 @@ tulip_pci_read(UNUSED(int func), int addr, void *priv) case 0x13: ret = tulip_pci_bar[0].addr_regs[3]; break; +#ifdef USE_128_BYTE_BAR case 0x14: ret = (tulip_pci_bar[1].addr_regs[0] & 0x80); break; +#endif case 0x15: +#ifdef USE_128_BYTE_BAR ret = tulip_pci_bar[1].addr_regs[1]; +#else + ret = tulip_pci_bar[1].addr_regs[1] & 0xf0; +#endif break; case 0x16: ret = tulip_pci_bar[1].addr_regs[2]; @@ -1283,7 +1307,7 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) //pclog("PCI write cmd: IOBase=%04x, MMIOBase=%08x, val=%02x.\n", s->PCIBase, s->MMIOBase, s->pci_conf[0x04]); mem_mapping_disable(&s->memory); if ((s->MMIOBase != 0) && (val & PCI_COMMAND_MEM)) - mem_mapping_set_addr(&s->memory, s->MMIOBase, 128); + mem_mapping_enable(&s->memory); break; case 0x05: s->pci_conf[0x05] = val & 1; @@ -1308,18 +1332,28 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) priv); } break; +#ifndef USE_128_BYTE_BAR case 0x14: +#endif case 0x15: case 0x16: case 0x17: mem_mapping_disable(&s->memory); tulip_pci_bar[1].addr_regs[addr & 3] = val; +#ifdef USE_128_BYTE_BAR tulip_pci_bar[1].addr &= 0xffffff80; +#else + tulip_pci_bar[1].addr &= 0xfffff000; +#endif s->MMIOBase = tulip_pci_bar[1].addr; if (s->pci_conf[0x4] & PCI_COMMAND_MEM) { //pclog("PCI write=%02x, mmiobase=%08x, mmio?=%x.\n", addr, s->PCIBase, s->pci_conf[0x4] & PCI_COMMAND_MEM); if (s->MMIOBase != 0) +#ifdef USE_128_BYTE_BAR mem_mapping_set_addr(&s->memory, s->MMIOBase, 128); +#else + mem_mapping_set_addr(&s->memory, s->MMIOBase, 4096); +#endif } break; case 0x30: /* PCI_ROMBAR */ @@ -1369,7 +1403,11 @@ nic_init(const device_t *info) s->has_bios = 0; } +#ifdef USE_128_BYTE_BAR mem_mapping_add(&s->memory, 0x0fffff00, 128, tulip_mem_readb, tulip_mem_readw, tulip_mem_readl, tulip_mem_writeb, tulip_mem_writew, tulip_mem_writel, NULL, MEM_MAPPING_EXTERNAL, s); +#else + mem_mapping_add(&s->memory, 0x0ffff000, 4096, tulip_mem_readb, tulip_mem_readw, tulip_mem_readl, tulip_mem_writeb, tulip_mem_writew, tulip_mem_writel, NULL, MEM_MAPPING_EXTERNAL, s); +#endif mem_mapping_disable(&s->memory); s->device_info = info; From 64d7fbc18668d6f97f81facbeafb3bf52f2f2080 Mon Sep 17 00:00:00 2001 From: BurnedPinguin Date: Sat, 27 Jan 2024 09:40:24 +0100 Subject: [PATCH 352/936] Temporarily remove machines ZEOS Martin and Olivetti M4-5xx because of A20 issues. --- src/include/86box/machine.h | 2 - src/machine/m_at_386dx_486.c | 48 --------------------- src/machine/machine_table.c | 81 +----------------------------------- 3 files changed, 1 insertion(+), 130 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 9d225d35d..5dd95b673 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -517,7 +517,6 @@ extern int machine_at_403tg_d_mr_init(const machine_t *); extern int machine_at_pb450_init(const machine_t *); extern int machine_at_pb450_init(const machine_t *); extern int machine_at_pc330_6573_init(const machine_t *); -extern int machine_at_m45xx_init(const machine_t *); extern int machine_at_mvi486_init(const machine_t *); extern int machine_at_sis401_init(const machine_t *); @@ -531,7 +530,6 @@ extern int machine_at_dtk486_init(const machine_t *); extern int machine_at_px471_init(const machine_t *); extern int machine_at_win471_init(const machine_t *); extern int machine_at_pci400ca_init(const machine_t *); -extern int machine_at_zmartin_init(const machine_t *); extern int machine_at_vi15g_init(const machine_t *); extern int machine_at_greenb_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index f5d31b0c2..b8d4c2e48 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -731,35 +731,6 @@ machine_at_pc330_6573_init(const machine_t *model) /* doesn't like every CPU oth return ret; } -int -machine_at_m45xx_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear_inverted("roms/machines/m45xx/optoli_082594.rom", - 0x000e0000, 131072, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - device_add(&ami_1994_nvr_device); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x15, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x16, PCI_CARD_NORMAL, 3, 4, 1, 2); - - device_add(&opti802g_pci_device); - device_add(&opti822_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&fdc37c665_device); - device_add(&ide_vlb_2ch_device); - device_add(&intel_flash_bxt_device); // Just in case, no idea if it has it or not - - return ret; -} - int machine_at_mvi486_init(const machine_t *model) { @@ -914,25 +885,6 @@ machine_at_pci400ca_init(const machine_t *model) return ret; } -int -machine_at_zmartin_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/zeos_martin/rel11.bin", - 0x000e0000, 131072, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init(model); - device_add(&keyboard_at_device); - device_add(&intel_flash_bxt_ami_device); - device_add(&fdc37c651_device); - - return ret; -} - int machine_at_vi15g_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index e46434e56..4e7dfb2c9 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -6165,46 +6165,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* KBC?? Does the VLSI have On-Chip KBC? */ - { - .name = "[VLSI 82C480] ZEOS Martin", - .internal_name = "zmartin", - .type = MACHINE_TYPE_486_S2, - .chipset = MACHINE_CHIPSET_VLSI_VL82C480, - .init = machine_at_zmartin_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .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_VLB, - .flags = MACHINE_SUPER_IO, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, //&fdc37c651_device, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, + /* 486 machines - Socket 3 */ /* 486 machines with just the ISA slot */ @@ -7139,46 +7100,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Absolutely no information. Anything here is guesswork. */ - { - .name = "[OPTi 802GP] Olivetti M4-5xx", - .internal_name = "m45xx", - .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_OPTI_895_802G, //OPTi 802GP - .init = machine_at_m45xx_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .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_PS2_PCIV, - .flags = MACHINE_IDE | MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, /* This has an AMIKey-2, which is an updated version of type 'H'. */ { .name = "[i420EX] ASUS PVI-486AP4", From f4fadfe22ef162a010115d896fcc2952e00a52c2 Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Sat, 27 Jan 2024 18:34:04 +0300 Subject: [PATCH 353/936] Move MSI MS-4144 into dev branch --- CMakeLists.txt | 1 + src/include/86box/machine.h | 2 ++ src/machine/CMakeLists.txt | 4 ++++ src/machine/m_at_386dx_486.c | 4 ++-- src/machine/machine_table.c | 2 ++ 5 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a6b50baf3..06a6be389 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -159,6 +159,7 @@ cmake_dependent_option(PAS16 "Pro Audio Spectrum 16" cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF) cmake_dependent_option(VGAWONDER "ATI VGA Wonder (ATI-18800)" ON "DEV_BRANCH" OFF) cmake_dependent_option(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF) +cmake_dependent_option(MS4144 "MSI MS-4144" ON "DEV_BRANCH" OFF) # Ditto but for Qt if(QT) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 5dd95b673..f55644b87 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -536,7 +536,9 @@ extern int machine_at_greenb_init(const machine_t *); extern int machine_at_r418_init(const machine_t *); extern int machine_at_ls486e_init(const machine_t *); extern int machine_at_4dps_init(const machine_t *); +#if defined(DEV_BRANCH) && defined(USE_MS4144) extern int machine_at_ms4144_init(const machine_t *); +#endif extern int machine_at_4saw2_init(const machine_t *); extern int machine_at_m4li_init(const machine_t *); extern int machine_at_alfredo_init(const machine_t *); diff --git a/src/machine/CMakeLists.txt b/src/machine/CMakeLists.txt index e88631044..b90f92100 100644 --- a/src/machine/CMakeLists.txt +++ b/src/machine/CMakeLists.txt @@ -40,3 +40,7 @@ endif() if(OPEN_AT) target_compile_definitions(mch PRIVATE USE_OPEN_AT) endif() + +if(MS4144) + target_compile_definitions(mch PRIVATE USE_MS4144) +endif() \ No newline at end of file diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index b8d4c2e48..ebd8728d9 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1045,7 +1045,7 @@ machine_at_4dps_init(const machine_t *model) return ret; } - +#if defined(DEV_BRANCH) && defined(USE_MS4144) int machine_at_ms4144_init(const machine_t *model) { @@ -1072,7 +1072,7 @@ machine_at_ms4144_init(const machine_t *model) return ret; } - +#endif int machine_at_486sp3c_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 4e7dfb2c9..bbcfc80cc 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -7783,6 +7783,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, +#if defined(DEV_BRANCH) && defined(USE_MS4144) /* AMIKEY-2 */ { .name = "[SiS 496] MSI MS-4144", @@ -7823,6 +7824,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, +#endif /* This has the UMC 88xx on-chip KBC. */ { .name = "[UMC 8881] A-Trend ATC-1415", From bc4f09d5a95c837088ef5d41d5afd1be125f9abc Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Sat, 27 Jan 2024 21:12:27 +0300 Subject: [PATCH 354/936] Revert "Move MSI MS-4144 into dev branch" This reverts commit f4fadfe22ef162a010115d896fcc2952e00a52c2. --- CMakeLists.txt | 1 - src/include/86box/machine.h | 2 -- src/machine/CMakeLists.txt | 4 ---- src/machine/m_at_386dx_486.c | 4 ++-- src/machine/machine_table.c | 2 -- 5 files changed, 2 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 06a6be389..a6b50baf3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -159,7 +159,6 @@ cmake_dependent_option(PAS16 "Pro Audio Spectrum 16" cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF) cmake_dependent_option(VGAWONDER "ATI VGA Wonder (ATI-18800)" ON "DEV_BRANCH" OFF) cmake_dependent_option(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF) -cmake_dependent_option(MS4144 "MSI MS-4144" ON "DEV_BRANCH" OFF) # Ditto but for Qt if(QT) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index f55644b87..5dd95b673 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -536,9 +536,7 @@ extern int machine_at_greenb_init(const machine_t *); extern int machine_at_r418_init(const machine_t *); extern int machine_at_ls486e_init(const machine_t *); extern int machine_at_4dps_init(const machine_t *); -#if defined(DEV_BRANCH) && defined(USE_MS4144) extern int machine_at_ms4144_init(const machine_t *); -#endif extern int machine_at_4saw2_init(const machine_t *); extern int machine_at_m4li_init(const machine_t *); extern int machine_at_alfredo_init(const machine_t *); diff --git a/src/machine/CMakeLists.txt b/src/machine/CMakeLists.txt index b90f92100..e88631044 100644 --- a/src/machine/CMakeLists.txt +++ b/src/machine/CMakeLists.txt @@ -40,7 +40,3 @@ endif() if(OPEN_AT) target_compile_definitions(mch PRIVATE USE_OPEN_AT) endif() - -if(MS4144) - target_compile_definitions(mch PRIVATE USE_MS4144) -endif() \ No newline at end of file diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index ebd8728d9..b8d4c2e48 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1045,7 +1045,7 @@ machine_at_4dps_init(const machine_t *model) return ret; } -#if defined(DEV_BRANCH) && defined(USE_MS4144) + int machine_at_ms4144_init(const machine_t *model) { @@ -1072,7 +1072,7 @@ machine_at_ms4144_init(const machine_t *model) return ret; } -#endif + int machine_at_486sp3c_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index bbcfc80cc..4e7dfb2c9 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -7783,7 +7783,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, -#if defined(DEV_BRANCH) && defined(USE_MS4144) /* AMIKEY-2 */ { .name = "[SiS 496] MSI MS-4144", @@ -7824,7 +7823,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, -#endif /* This has the UMC 88xx on-chip KBC. */ { .name = "[UMC 8881] A-Trend ATC-1415", From 301819b6b558155b7fa9ad18ed537ce87bc488de Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Sat, 27 Jan 2024 21:13:54 +0300 Subject: [PATCH 355/936] Raise minimum RAM for MSI MS-4144 to 5 MB --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 4e7dfb2c9..45f3f77df 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -7807,7 +7807,7 @@ const machine_t machines[] = { .bus_flags = MACHINE_PCI, .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_APM, .ram = { - .min = 1024, + .min = 5120, /* Hack: machine seems to break with less than 5 MBs of RAM */ .max = 131072, .step = 1024 }, From afe0627177bb9c6e52629d7a0d22f3465a13a582 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 28 Jan 2024 05:06:42 +0100 Subject: [PATCH 356/936] J-Bond PCI400C-B: Correct the bus flag - the machine in fact supports VLB but not PS/2 mice. --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 45f3f77df..302fe8409 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -7482,7 +7482,7 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PCIV, .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 2048, From 72a3c67ec1b485f142615e05e41c20a0dd418ca6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 28 Jan 2024 05:10:23 +0100 Subject: [PATCH 357/936] ABit AB-AH4: Machine is actually Socket 3. --- src/machine/machine_table.c | 84 ++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 302fe8409..9adfde6e6 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -6083,48 +6083,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* The BIOS string ends in -U, unless command 0xA1 (AMIKey get version) returns an - 'F', in which case, it ends in -F, so it has an AMIKey F KBC firmware. - The photo of the board shows an AMIKey KBC which is indeed F. */ - { - .name = "[SiS 471] ABit AB-AH4", - .internal_name = "win471", - .type = MACHINE_TYPE_486_S2, - .chipset = MACHINE_CHIPSET_SIS_471, - .init = machine_at_win471_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .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_VLB, - .flags = MACHINE_IDE | MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, /* AMIKey-2 */ { .name = "[i420TX] J-Bond PCI400C-A", @@ -6369,6 +6327,48 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* The BIOS string ends in -U, unless command 0xA1 (AMIKey get version) returns an + 'F', in which case, it ends in -F, so it has an AMIKey F KBC firmware. + The photo of the board shows an AMIKey KBC which is indeed F. */ + { + .name = "[SiS 471] ABit AB-AH4", + .internal_name = "win471", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_SIS_471, + .init = machine_at_win471_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .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_VLB, + .flags = MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Has AMIKey H keyboard BIOS. */ { .name = "[SiS 471] AOpen Vi15G", From 3390aa8d03e1e0d8a2ae67c64547a78d666a5d1d Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Sun, 28 Jan 2024 09:19:12 +0300 Subject: [PATCH 358/936] Rename 586MC1 to GA-586IS --- src/machine/m_at_socket4.c | 1 - src/machine/machine_table.c | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index a32617de4..c06388547 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -317,7 +317,6 @@ machine_at_586mc1_init(const machine_t *model) machine_at_award_common_init(model); - device_add(&sio_device); device_add(&intel_flash_bxt_device); device_add(&i430lx_device); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 45f3f77df..8cb270b25 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -8725,7 +8725,7 @@ const machine_t machines[] = { }, /* Has AMI MegaKey KBC firmware. */ { - .name = "[i430LX] Micro Star 586MC1", + .name = "[i430LX] Gigabyte GA-586IS", .internal_name = "586mc1", .type = MACHINE_TYPE_SOCKET4, .chipset = MACHINE_CHIPSET_INTEL_430LX, @@ -8744,8 +8744,8 @@ const machine_t machines[] = { .min_multi = MACHINE_MULTIPLIER_FIXED, .max_multi = MACHINE_MULTIPLIER_FIXED }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_APM | MACHINE_ACPI, .ram = { .min = 2048, .max = 131072, From e5862a9ec771b73ba53010fa08ca2fa1125af376 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Sun, 28 Jan 2024 12:11:40 -0500 Subject: [PATCH 359/936] Block incompatible cyrix CPUs from 4saw2 --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 9adfde6e6..827610be8 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -7715,7 +7715,7 @@ const machine_t machines[] = { .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK(CPU_i486SX, CPU_i486DX, CPU_Am486SX, CPU_Am486DX), + .block = CPU_BLOCK(CPU_i486SX, CPU_i486DX, CPU_Am486SX, CPU_Am486DX, CPU_Cx486S, CPU_Cx486DX, CPU_Cx5x86), .min_bus = 0, .max_bus = 0, .min_voltage = 0, From f4aeaeeaba9d2b34633bc04654b8beaeec98d892 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Sun, 28 Jan 2024 12:33:03 -0500 Subject: [PATCH 360/936] Disable win32 and makefile jobs --- .github/workflows/c-cpp.yml | 2 ++ .github/workflows/cmake_windows_msys2.yml | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index b76c2c260..2a22a19cf 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -16,6 +16,8 @@ on: jobs: msys2: + # Negative condition disables the job + if: false name: "Win32 GUI, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}" runs-on: windows-2022 diff --git a/.github/workflows/cmake_windows_msys2.yml b/.github/workflows/cmake_windows_msys2.yml index 48503cc27..46fc25b67 100644 --- a/.github/workflows/cmake_windows_msys2.yml +++ b/.github/workflows/cmake_windows_msys2.yml @@ -57,9 +57,6 @@ jobs: new: on slug: -NDR ui: - - name: Win32 GUI - qt: off - static: on - name: Qt GUI qt: on static: on From c8bdb4cfcd2ffcfe50904e36dce38c1b66ac9205 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 28 Jan 2024 01:35:12 +0500 Subject: [PATCH 361/936] Add manufacturer name to IBM video adapters --- src/video/vid_cga.c | 2 +- src/video/vid_ega.c | 2 +- src/video/vid_mda.c | 2 +- src/video/vid_pgc.c | 2 +- src/video/vid_vga.c | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index 2ba4323f3..2ea07c346 100644 --- a/src/video/vid_cga.c +++ b/src/video/vid_cga.c @@ -891,7 +891,7 @@ const device_config_t cga_config[] = { // clang-format on const device_t cga_device = { - .name = "CGA", + .name = "IBM CGA", .internal_name = "cga", .flags = DEVICE_ISA, .local = 0, diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index dd84074e6..8f995117c 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -1622,7 +1622,7 @@ static const device_config_t ega_config[] = { }; const device_t ega_device = { - .name = "EGA", + .name = "IBM EGA", .internal_name = "ega", .flags = DEVICE_ISA, .local = EGA_IBM, diff --git a/src/video/vid_mda.c b/src/video/vid_mda.c index a53199324..702fb7e32 100644 --- a/src/video/vid_mda.c +++ b/src/video/vid_mda.c @@ -386,7 +386,7 @@ static const device_config_t mda_config[] = { }; const device_t mda_device = { - .name = "MDA", + .name = "IBM MDA", .internal_name = "mda", .flags = DEVICE_ISA, .local = 0, diff --git a/src/video/vid_pgc.c b/src/video/vid_pgc.c index aa1517ddf..354c7e265 100644 --- a/src/video/vid_pgc.c +++ b/src/video/vid_pgc.c @@ -2736,7 +2736,7 @@ pgc_standalone_init(const device_t *info) } const device_t pgc_device = { - .name = "PGC", + .name = "IBM PGC", .internal_name = "pgc", .flags = DEVICE_ISA, .local = 0, diff --git a/src/video/vid_vga.c b/src/video/vid_vga.c index 43b8a2750..8b2e761a3 100644 --- a/src/video/vid_vga.c +++ b/src/video/vid_vga.c @@ -186,7 +186,7 @@ vga_force_redraw(void *priv) } const device_t vga_device = { - .name = "VGA", + .name = "IBM VGA", .internal_name = "vga", .flags = DEVICE_ISA, .local = 0, @@ -200,7 +200,7 @@ const device_t vga_device = { }; const device_t ps1vga_device = { - .name = "PS/1 VGA", + .name = "IBM PS/1 VGA", .internal_name = "ps1vga", .flags = DEVICE_ISA, .local = 0, @@ -214,7 +214,7 @@ const device_t ps1vga_device = { }; const device_t ps1vga_mca_device = { - .name = "PS/1 VGA", + .name = "IBM PS/1 VGA", .internal_name = "ps1vga_mca", .flags = DEVICE_MCA, .local = 0, From 249e097b6b0f3ee03a580b9b9ee423db74ff1a8f Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 28 Jan 2024 01:43:53 +0500 Subject: [PATCH 362/936] Correct capitalization for ABIT AB-AH4 --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 9adfde6e6..92baa66eb 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -6331,7 +6331,7 @@ const machine_t machines[] = { 'F', in which case, it ends in -F, so it has an AMIKey F KBC firmware. The photo of the board shows an AMIKey KBC which is indeed F. */ { - .name = "[SiS 471] ABit AB-AH4", + .name = "[SiS 471] ABIT AB-AH4", .internal_name = "win471", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_SIS_471, From 712cf761756a6a9d4e0255e968401c5dba98b7d4 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 28 Jan 2024 01:51:43 +0500 Subject: [PATCH 363/936] Expand text for IBM 8514/A and XGA Also capitalize the A in IBM 8514/A --- src/qt/languages/ca-ES.po | 4 ++-- src/qt/languages/cs-CZ.po | 4 ++-- src/qt/languages/de-DE.po | 4 ++-- src/qt/languages/en-GB.po | 4 ++-- src/qt/languages/en-US.po | 4 ++-- src/qt/languages/es-ES.po | 4 ++-- src/qt/languages/fi-FI.po | 4 ++-- src/qt/languages/fr-FR.po | 4 ++-- src/qt/languages/hr-HR.po | 4 ++-- src/qt/languages/hu-HU.po | 4 ++-- src/qt/languages/it-IT.po | 4 ++-- src/qt/languages/ja-JP.po | 4 ++-- src/qt/languages/ko-KR.po | 4 ++-- src/qt/languages/pl-PL.po | 4 ++-- src/qt/languages/pt-BR.po | 4 ++-- src/qt/languages/pt-PT.po | 4 ++-- src/qt/languages/ru-RU.po | 4 ++-- src/qt/languages/sk-SK.po | 4 ++-- src/qt/languages/sl-SI.po | 4 ++-- src/qt/languages/tr-TR.po | 4 ++-- src/qt/languages/uk-UA.po | 4 ++-- src/qt/languages/zh-CN.po | 4 ++-- src/qt/languages/zh-TW.po | 4 ++-- src/qt/qt_settingsdisplay.ui | 4 ++-- src/win/languages/cs-CZ.rc | 2 +- src/win/languages/de-DE.rc | 2 +- src/win/languages/en-GB.rc | 2 +- src/win/languages/en-US.rc | 2 +- src/win/languages/es-ES.rc | 2 +- src/win/languages/fi-FI.rc | 2 +- src/win/languages/fr-FR.rc | 2 +- src/win/languages/hr-HR.rc | 2 +- src/win/languages/hu-HU.rc | 2 +- src/win/languages/it-IT.rc | 2 +- src/win/languages/ja-JP.rc | 2 +- src/win/languages/ko-KR.rc | 2 +- src/win/languages/pl-PL.rc | 2 +- src/win/languages/pt-BR.rc | 2 +- src/win/languages/pt-PT.rc | 2 +- src/win/languages/ru-RU.rc | 2 +- src/win/languages/sl-SI.rc | 2 +- src/win/languages/tr-TR.rc | 2 +- src/win/languages/uk-UA.rc | 2 +- src/win/languages/zh-CN.rc | 2 +- src/win/languages/zh-TW.rc | 2 +- 45 files changed, 69 insertions(+), 69 deletions(-) diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po index 371781b7a..b250178bf 100644 --- a/src/qt/languages/ca-ES.po +++ b/src/qt/languages/ca-ES.po @@ -385,8 +385,8 @@ msgstr "Vídeo:" msgid "Voodoo Graphics" msgstr "Gràfics Voodoo" -msgid "IBM 8514/a Graphics" -msgstr "Gràfics IBM 8514/a" +msgid "IBM 8514/A Graphics" +msgstr "Gràfics IBM 8514/A" msgid "XGA Graphics" msgstr "Gràfics XGA" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index d86f5b635..1ee5452c8 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -385,8 +385,8 @@ msgstr "Grafika:" msgid "Voodoo Graphics" msgstr "Použít grafický akcelerátor Voodoo" -msgid "IBM 8514/a Graphics" -msgstr "Grafika IBM 8514/a" +msgid "IBM 8514/A Graphics" +msgstr "Grafika IBM 8514/A" msgid "XGA Graphics" msgstr "Grafika XGA" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index 9c985d871..6d5cc4146 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -385,8 +385,8 @@ msgstr "Videokarte:" msgid "Voodoo Graphics" msgstr "Voodoo-Grafik" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a-Grafik" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A-Grafik" msgid "XGA Graphics" msgstr "XGA-Grafik" diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index 4a6a58db6..e2d3909ec 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -385,8 +385,8 @@ msgstr "Video:" msgid "Voodoo Graphics" msgstr "Voodoo Graphics" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a Graphics" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A Graphics" msgid "XGA Graphics" msgstr "XGA Graphics" diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index ce7ceb149..ec524f5e1 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -385,8 +385,8 @@ msgstr "Video:" msgid "Voodoo Graphics" msgstr "Voodoo Graphics" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a Graphics" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A Graphics" msgid "XGA Graphics" msgstr "XGA Graphics" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index d8d648691..be1e7514c 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -385,8 +385,8 @@ msgstr "Vídeo:" msgid "Voodoo Graphics" msgstr "Voodoo Graphics" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a Graphics" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A Graphics" msgid "XGA Graphics" msgstr "XGA Graphics" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index 217827f74..6fe3020f9 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -385,8 +385,8 @@ msgstr "Näytönohjain:" msgid "Voodoo Graphics" msgstr "Voodoo-grafiikkasuoritin" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a-grafiikkasuoritin" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A-grafiikkasuoritin" msgid "XGA Graphics" msgstr "XGA-grafiikkasuoritin" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index be66e5924..2328b0bc6 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -385,8 +385,8 @@ msgstr "Vidéo:" msgid "Voodoo Graphics" msgstr "Graphique Voodoo" -msgid "IBM 8514/a Graphics" -msgstr "Graphique IBM 8514/a" +msgid "IBM 8514/A Graphics" +msgstr "Graphique IBM 8514/A" msgid "XGA Graphics" msgstr "Graphique XGA" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index b2aa40d28..74d2c497c 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -385,8 +385,8 @@ msgstr "Video:" msgid "Voodoo Graphics" msgstr "Voodoo grafika" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a grafika" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A grafika" msgid "XGA Graphics" msgstr "XGA grafika" diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index 352a64749..d2df6d547 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -385,8 +385,8 @@ msgstr "Videokártya:" msgid "Voodoo Graphics" msgstr "Voodoo-gyorsítókártya" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a-gyorsítókártya" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A-gyorsítókártya" msgid "XGA Graphics" msgstr "XGA-gyorsítókártya" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index df71d148b..1d5d4f5b8 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -385,8 +385,8 @@ msgstr "Video:" msgid "Voodoo Graphics" msgstr "Grafica Voodoo" -msgid "IBM 8514/a Graphics" -msgstr "Grafica IBM 8514/a" +msgid "IBM 8514/A Graphics" +msgstr "Grafica IBM 8514/A" msgid "XGA Graphics" msgstr "Grafica XGA" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index 7ea47bc1a..3f5ea5083 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -385,8 +385,8 @@ msgstr "ビデオカード:" msgid "Voodoo Graphics" msgstr "Voodooグラフィック" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/aグラフィック" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/Aグラフィック" msgid "XGA Graphics" msgstr "XGAグラフィック" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index ac4476ca8..33424c40c 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -385,8 +385,8 @@ msgstr "비디오 카드:" msgid "Voodoo Graphics" msgstr "Voodoo 그래픽" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a 그래픽" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A 그래픽" msgid "XGA Graphics" msgstr "XGA 그래픽" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index b24e338f4..8288fb385 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -385,8 +385,8 @@ msgstr "Wideo:" msgid "Voodoo Graphics" msgstr "Grafika Voodoo" -msgid "IBM 8514/a Graphics" -msgstr "Grafika IBM 8514/a" +msgid "IBM 8514/A Graphics" +msgstr "Grafika IBM 8514/A" msgid "XGA Graphics" msgstr "Grafika XGA" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 0db661b4f..34fe953b5 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -385,8 +385,8 @@ msgstr "Vídeo:" msgid "Voodoo Graphics" msgstr "3DFX Voodoo" -msgid "IBM 8514/a Graphics" -msgstr "Gráficos IBM 8514/a" +msgid "IBM 8514/A Graphics" +msgstr "Gráficos IBM 8514/A" msgid "XGA Graphics" msgstr "Gráficos XGA" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index 8f080e423..939aceab8 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -385,8 +385,8 @@ msgstr "Vídeo:" msgid "Voodoo Graphics" msgstr "Gráficos Voodoo" -msgid "IBM 8514/a Graphics" -msgstr "Gráficos IBM 8514/a" +msgid "IBM 8514/A Graphics" +msgstr "Gráficos IBM 8514/A" msgid "XGA Graphics" msgstr "Gráficos XGA" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index b0bcc0e1e..c0204b508 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -385,8 +385,8 @@ msgstr "Видеокарта:" msgid "Voodoo Graphics" msgstr "Ускоритель Voodoo" -msgid "IBM 8514/a Graphics" -msgstr "Ускоритель IBM 8514/a" +msgid "IBM 8514/A Graphics" +msgstr "Ускоритель IBM 8514/A" msgid "XGA Graphics" msgstr "Ускоритель XGA" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index a8f60b861..37a7c050a 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -385,8 +385,8 @@ msgstr "Grafika:" msgid "Voodoo Graphics" msgstr "Použiť grafický akcelerátor Voodoo" -msgid "IBM 8514/a Graphics" -msgstr "Grafika IBM 8514/a" +msgid "IBM 8514/A Graphics" +msgstr "Grafika IBM 8514/A" msgid "XGA Graphics" msgstr "Grafika XGA" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index 98a51d863..5d83d8e28 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -385,8 +385,8 @@ msgstr "Video:" msgid "Voodoo Graphics" msgstr "Voodoo grafika" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a grafika" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A grafika" msgid "XGA Graphics" msgstr "XGA grafika" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index 0d6875eb8..c15694953 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -385,8 +385,8 @@ msgstr "Ekran kartı:" msgid "Voodoo Graphics" msgstr "Voodoo Grafikleri" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a Grafikleri" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A Grafikleri" msgid "XGA Graphics" msgstr "XGA Grafikleri" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index 6f8ecac52..8641388c2 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -385,8 +385,8 @@ msgstr "Відеокарта:" msgid "Voodoo Graphics" msgstr "Прискорювач Voodoo" -msgid "IBM 8514/a Graphics" -msgstr "Прискорювач IBM 8514/a" +msgid "IBM 8514/A Graphics" +msgstr "Прискорювач IBM 8514/A" msgid "XGA Graphics" msgstr "Прискорювач XGA" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index 3d045b74e..2b8167670 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -385,8 +385,8 @@ msgstr "显卡:" msgid "Voodoo Graphics" msgstr "Voodoo Graphics" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a Graphics" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A Graphics" msgid "XGA Graphics" msgstr "XGA Graphics" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 2d2ea473e..2f0e5c4f2 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -385,8 +385,8 @@ msgstr "顯示卡:" msgid "Voodoo Graphics" msgstr "Voodoo Graphics" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a Graphics" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A Graphics" msgid "XGA Graphics" msgstr "XGA Graphics" diff --git a/src/qt/qt_settingsdisplay.ui b/src/qt/qt_settingsdisplay.ui index dfda43c40..5dd76287f 100644 --- a/src/qt/qt_settingsdisplay.ui +++ b/src/qt/qt_settingsdisplay.ui @@ -42,7 +42,7 @@ - XGA + XGA Graphics @@ -95,7 +95,7 @@ - 8514/A + IBM 8514/A Graphics diff --git a/src/win/languages/cs-CZ.rc b/src/win/languages/cs-CZ.rc index 6c0982c5c..353ea55b6 100644 --- a/src/win/languages/cs-CZ.rc +++ b/src/win/languages/cs-CZ.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Grafika:" #define STR_VIDEO_2 "Grafika 2:" #define STR_VOODOO "Použít grafický akcelerátor Voodoo" -#define STR_IBM8514 "Grafika IBM 8514/a" +#define STR_IBM8514 "Grafika IBM 8514/A" #define STR_XGA "Grafika XGA" #define STR_MOUSE "Myš:" diff --git a/src/win/languages/de-DE.rc b/src/win/languages/de-DE.rc index 031f935cd..0fe48b0ef 100644 --- a/src/win/languages/de-DE.rc +++ b/src/win/languages/de-DE.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Videokarte:" #define STR_VIDEO_2 "Videokarte 2:" #define STR_VOODOO "Voodoo-Grafik" -#define STR_IBM8514 "IBM 8514/a-Grafik" +#define STR_IBM8514 "IBM 8514/A-Grafik" #define STR_XGA "XGA-Grafik" #define STR_MOUSE "Maus:" diff --git a/src/win/languages/en-GB.rc b/src/win/languages/en-GB.rc index 01e18f71a..98af74409 100644 --- a/src/win/languages/en-GB.rc +++ b/src/win/languages/en-GB.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Video:" #define STR_VIDEO_2 "Video 2:" #define STR_VOODOO "Voodoo Graphics" -#define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_IBM8514 "IBM 8514/A Graphics" #define STR_XGA "XGA Graphics" #define STR_MOUSE "Mouse:" diff --git a/src/win/languages/en-US.rc b/src/win/languages/en-US.rc index 6ca6945d6..7971a7948 100644 --- a/src/win/languages/en-US.rc +++ b/src/win/languages/en-US.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Video:" #define STR_VIDEO_2 "Video 2:" #define STR_VOODOO "Voodoo Graphics" -#define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_IBM8514 "IBM 8514/A Graphics" #define STR_XGA "XGA Graphics" #define STR_MOUSE "Mouse:" diff --git a/src/win/languages/es-ES.rc b/src/win/languages/es-ES.rc index 1fd0bceff..e9fef50d4 100644 --- a/src/win/languages/es-ES.rc +++ b/src/win/languages/es-ES.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Vídeo:" #define STR_VIDEO_2 "Vídeo 2:" #define STR_VOODOO "Voodoo Graphics" -#define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_IBM8514 "IBM 8514/A Graphics" #define STR_XGA "XGA Graphics" #define STR_MOUSE "Ratón:" diff --git a/src/win/languages/fi-FI.rc b/src/win/languages/fi-FI.rc index 3f875cb3d..1b958cc82 100644 --- a/src/win/languages/fi-FI.rc +++ b/src/win/languages/fi-FI.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Näytönohjain:" #define STR_VIDEO_2 "Näytönohjain 2:" #define STR_VOODOO "Voodoo-grafiikkasuoritin" -#define STR_IBM8514 "IBM 8514/a-grafiikkasuoritin" +#define STR_IBM8514 "IBM 8514/A-grafiikkasuoritin" #define STR_XGA "XGA-grafiikkasuoritin" #define STR_MOUSE "Hiiri:" diff --git a/src/win/languages/fr-FR.rc b/src/win/languages/fr-FR.rc index 1ad5a4da1..8c77979ef 100644 --- a/src/win/languages/fr-FR.rc +++ b/src/win/languages/fr-FR.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Vidéo:" #define STR_VIDEO_2 "Vidéo 2:" #define STR_VOODOO "Graphique Voodoo" -#define STR_IBM8514 "Graphique IBM 8514/a" +#define STR_IBM8514 "Graphique IBM 8514/A" #define STR_XGA "Graphique XGA" #define STR_MOUSE "Souris:" diff --git a/src/win/languages/hr-HR.rc b/src/win/languages/hr-HR.rc index 9497a7b0d..2e6caea43 100644 --- a/src/win/languages/hr-HR.rc +++ b/src/win/languages/hr-HR.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Video:" #define STR_VIDEO_2 "Video 2:" #define STR_VOODOO "Voodoo grafika" -#define STR_IBM8514 "IBM 8514/a grafika" +#define STR_IBM8514 "IBM 8514/A grafika" #define STR_XGA "XGA grafika" #define STR_MOUSE "Miš:" diff --git a/src/win/languages/hu-HU.rc b/src/win/languages/hu-HU.rc index ab91d43f5..34bf512c1 100644 --- a/src/win/languages/hu-HU.rc +++ b/src/win/languages/hu-HU.rc @@ -288,7 +288,7 @@ END #define STR_VIDEO "Videokártya:" #define STR_VIDEO_2 "Videokártya 2:" #define STR_VOODOO "Voodoo-gyorsítókártya" -#define STR_IBM8514 "IBM 8514/a-gyorsítókártya" +#define STR_IBM8514 "IBM 8514/A-gyorsítókártya" #define STR_XGA "XGA-gyorsítókártya" #define STR_MOUSE "Egér:" diff --git a/src/win/languages/it-IT.rc b/src/win/languages/it-IT.rc index cb6e7afa1..6f5b67201 100644 --- a/src/win/languages/it-IT.rc +++ b/src/win/languages/it-IT.rc @@ -284,7 +284,7 @@ END #define STR_VIDEO "Video:" #define STR_VIDEO_2 "Video 2:" #define STR_VOODOO "Grafica Voodoo" -#define STR_IBM8514 "Grafica IBM 8514/a" +#define STR_IBM8514 "Grafica IBM 8514/A" #define STR_XGA "Grafica XGA" #define STR_MOUSE "Mouse:" diff --git a/src/win/languages/ja-JP.rc b/src/win/languages/ja-JP.rc index bf9509453..a8e90d062 100644 --- a/src/win/languages/ja-JP.rc +++ b/src/win/languages/ja-JP.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "ビデオカード:" #define STR_VIDEO_2 "ビデオカード2:" #define STR_VOODOO "Voodooグラフィック" -#define STR_IBM8514 "IBM 8514/aグラフィック" +#define STR_IBM8514 "IBM 8514/Aグラフィック" #define STR_XGA "XGAグラフィック" #define STR_MOUSE "マウス:" diff --git a/src/win/languages/ko-KR.rc b/src/win/languages/ko-KR.rc index 360d6e36b..535ff1df4 100644 --- a/src/win/languages/ko-KR.rc +++ b/src/win/languages/ko-KR.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "비디오 카드:" #define STR_VIDEO_2 "비디오 카드 2:" #define STR_VOODOO "Voodoo 그래픽" -#define STR_IBM8514 "IBM 8514/a 그래픽" +#define STR_IBM8514 "IBM 8514/A 그래픽" #define STR_XGA "XGA 그래픽" #define STR_MOUSE "마우스:" diff --git a/src/win/languages/pl-PL.rc b/src/win/languages/pl-PL.rc index f835ad9eb..bdd73f6cf 100644 --- a/src/win/languages/pl-PL.rc +++ b/src/win/languages/pl-PL.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Wideo:" #define STR_VIDEO_2 "Wideo 2:" #define STR_VOODOO "Grafika Voodoo" -#define STR_IBM8514 "Grafika IBM 8514/a" +#define STR_IBM8514 "Grafika IBM 8514/A" #define STR_XGA "Grafika XGA" #define STR_MOUSE "Mysz:" diff --git a/src/win/languages/pt-BR.rc b/src/win/languages/pt-BR.rc index 00e9c243d..48cbba111 100644 --- a/src/win/languages/pt-BR.rc +++ b/src/win/languages/pt-BR.rc @@ -286,7 +286,7 @@ END #define STR_VIDEO "Vídeo:" #define STR_VIDEO_2 "Vídeo 2:" #define STR_VOODOO "3DFX Voodoo" -#define STR_IBM8514 "Gráficos IBM 8514/a" +#define STR_IBM8514 "Gráficos IBM 8514/A" #define STR_XGA "Gráficos XGA" #define STR_MOUSE "Mouse:" diff --git a/src/win/languages/pt-PT.rc b/src/win/languages/pt-PT.rc index 88db4f18c..e4394b0cb 100644 --- a/src/win/languages/pt-PT.rc +++ b/src/win/languages/pt-PT.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Vídeo:" #define STR_VIDEO_2 "Vídeo 2:" #define STR_VOODOO "Gráficos Voodoo" -#define STR_IBM8514 "Gráficos IBM 8514/a" +#define STR_IBM8514 "Gráficos IBM 8514/A" #define STR_XGA "Gráficos XGA" #define STR_MOUSE "Rato:" diff --git a/src/win/languages/ru-RU.rc b/src/win/languages/ru-RU.rc index 647b43d44..01562063a 100644 --- a/src/win/languages/ru-RU.rc +++ b/src/win/languages/ru-RU.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Видеокарта:" #define STR_VIDEO_2 "Видеокарта 2:" #define STR_VOODOO "Ускоритель Voodoo" -#define STR_IBM8514 "Ускоритель IBM 8514/a" +#define STR_IBM8514 "Ускоритель IBM 8514/A" #define STR_XGA "Ускоритель XGA" #define STR_MOUSE "Мышь:" diff --git a/src/win/languages/sl-SI.rc b/src/win/languages/sl-SI.rc index b3a00c9de..80da82276 100644 --- a/src/win/languages/sl-SI.rc +++ b/src/win/languages/sl-SI.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Video:" #define STR_VIDEO_2 "Video 2:" #define STR_VOODOO "Voodoo grafika" -#define STR_IBM8514 "IBM 8514/a grafika" +#define STR_IBM8514 "IBM 8514/A grafika" #define STR_XGA "XGA grafika" #define STR_MOUSE "Miška:" diff --git a/src/win/languages/tr-TR.rc b/src/win/languages/tr-TR.rc index 78e7b4b87..d7285bdf7 100644 --- a/src/win/languages/tr-TR.rc +++ b/src/win/languages/tr-TR.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Ekran kartı:" #define STR_VIDEO_2 "Ekran kartı 2:" #define STR_VOODOO "Voodoo Grafikleri" -#define STR_IBM8514 "IBM 8514/a Grafikleri" +#define STR_IBM8514 "IBM 8514/A Grafikleri" #define STR_XGA "XGA Grafikleri" #define STR_MOUSE "Fare:" diff --git a/src/win/languages/uk-UA.rc b/src/win/languages/uk-UA.rc index 41bf85f1a..d9674260c 100644 --- a/src/win/languages/uk-UA.rc +++ b/src/win/languages/uk-UA.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Відеокарта:" #define STR_VIDEO_2 "Відеокарта 2:" #define STR_VOODOO "Прискорювач Voodoo" -#define STR_IBM8514 "Прискорювач IBM 8514/a" +#define STR_IBM8514 "Прискорювач IBM 8514/A" #define STR_XGA "Прискорювач XGA" #define STR_MOUSE "Миша:" diff --git a/src/win/languages/zh-CN.rc b/src/win/languages/zh-CN.rc index 92afaf86d..1be833eb3 100644 --- a/src/win/languages/zh-CN.rc +++ b/src/win/languages/zh-CN.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "显卡:" #define STR_VIDEO_2 "显卡 2:" #define STR_VOODOO "Voodoo 显卡" -#define STR_IBM8514 "IBM 8514/a 显卡" +#define STR_IBM8514 "IBM 8514/A 显卡" #define STR_XGA "XGA 显卡" #define STR_MOUSE "鼠标:" diff --git a/src/win/languages/zh-TW.rc b/src/win/languages/zh-TW.rc index 039993e5d..fbd4fa998 100644 --- a/src/win/languages/zh-TW.rc +++ b/src/win/languages/zh-TW.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "顯示卡:" #define STR_VIDEO_2 "顯示卡 2:" #define STR_VOODOO "Voodoo Graphics" -#define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_IBM8514 "IBM 8514/A Graphics" #define STR_XGA "XGA Graphics" #define STR_MOUSE "滑鼠:" From e82d9d0c2934c6679c6a23e9ce937ca4d318cc3c Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 28 Jan 2024 01:53:31 +0500 Subject: [PATCH 364/936] Fix "Sound card #" translations --- src/include/86box/resource.h | 8 ++++---- src/qt/languages/ca-ES.po | 8 ++++---- src/qt/languages/cs-CZ.po | 8 ++++---- src/qt/languages/de-DE.po | 8 ++++---- src/qt/languages/en-GB.po | 16 ++++++++-------- src/qt/languages/en-US.po | 16 ++++++++-------- src/qt/languages/es-ES.po | 8 ++++---- src/qt/languages/fi-FI.po | 8 ++++---- src/qt/languages/fr-FR.po | 8 ++++---- src/qt/languages/hr-HR.po | 8 ++++---- src/qt/languages/hu-HU.po | 8 ++++---- src/qt/languages/it-IT.po | 8 ++++---- src/qt/languages/ja-JP.po | 8 ++++---- src/qt/languages/ko-KR.po | 8 ++++---- src/qt/languages/pl-PL.po | 8 ++++---- src/qt/languages/pt-BR.po | 8 ++++---- src/qt/languages/pt-PT.po | 8 ++++---- src/qt/languages/ru-RU.po | 8 ++++---- src/qt/languages/sk-SK.po | 8 ++++---- src/qt/languages/sl-SI.po | 8 ++++---- src/qt/languages/tr-TR.po | 8 ++++---- src/qt/languages/uk-UA.po | 8 ++++---- src/qt/languages/zh-CN.po | 8 ++++---- src/qt/languages/zh-TW.po | 8 ++++---- src/win/languages/en-GB.rc | 8 ++++---- src/win/languages/en-US.rc | 8 ++++---- 26 files changed, 112 insertions(+), 112 deletions(-) diff --git a/src/include/86box/resource.h b/src/include/86box/resource.h index 20067aa40..2e6628c77 100644 --- a/src/include/86box/resource.h +++ b/src/include/86box/resource.h @@ -79,10 +79,10 @@ #define IDT_JOYSTICK 1718 /* Joystick: */ /* DLG_CFG_SOUND */ -#define IDT_SOUND1 1719 /* Sound card 1: */ -#define IDT_SOUND2 1720 /* Sound card 2: */ -#define IDT_SOUND3 1721 /* Sound card 3: */ -#define IDT_SOUND4 1722 /* Sound card 4: */ +#define IDT_SOUND1 1719 /* Sound card #1: */ +#define IDT_SOUND2 1720 /* Sound card #2: */ +#define IDT_SOUND3 1721 /* Sound card #3: */ +#define IDT_SOUND4 1722 /* Sound card #4: */ #define IDT_MIDI_OUT 1723 /* MIDI Out Device: */ #define IDT_MIDI_IN 1724 /* MIDI In Device: */ diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po index b250178bf..372475099 100644 --- a/src/qt/languages/ca-ES.po +++ b/src/qt/languages/ca-ES.po @@ -409,16 +409,16 @@ msgstr "Joystick 3..." msgid "Joystick 4..." msgstr "Joystick 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Targeta de so 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Targeta de so 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Targeta de so 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Targeta de so 4:" msgid "MIDI Out Device:" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index 1ee5452c8..b8a68ce7d 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -409,16 +409,16 @@ msgstr "Joystick 3..." msgid "Joystick 4..." msgstr "Joystick 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Zvuková karta 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Zvuková karta 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Zvuková karta 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Zvuková karta 4:" msgid "MIDI Out Device:" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index 6d5cc4146..25e708f1b 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -409,16 +409,16 @@ msgstr "Joystick 3..." msgid "Joystick 4..." msgstr "Joystick 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Soundkarte 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Soundkarte 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Soundkarte 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Soundkarte 4:" msgid "MIDI Out Device:" diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index e2d3909ec..2c262aeaa 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -409,17 +409,17 @@ msgstr "Joystick 3..." msgid "Joystick 4..." msgstr "Joystick 4..." -msgid "Sound card 1:" -msgstr "Sound card 1:" +msgid "Sound card #1:" +msgstr "Sound card #1:" -msgid "Sound card 2:" -msgstr "Sound card 2:" +msgid "Sound card #2:" +msgstr "Sound card #2:" -msgid "Sound card 3:" -msgstr "Sound card 3:" +msgid "Sound card #3:" +msgstr "Sound card #3:" -msgid "Sound card 4:" -msgstr "Sound card 4:" +msgid "Sound card #4:" +msgstr "Sound card #4:" msgid "MIDI Out Device:" msgstr "MIDI Out Device:" diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index ec524f5e1..cb251f661 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -409,17 +409,17 @@ msgstr "Joystick 3..." msgid "Joystick 4..." msgstr "Joystick 4..." -msgid "Sound card 1:" -msgstr "Sound card 1:" +msgid "Sound card #1:" +msgstr "Sound card #1:" -msgid "Sound card 2:" -msgstr "Sound card 2:" +msgid "Sound card #2:" +msgstr "Sound card #2:" -msgid "Sound card 3:" -msgstr "Sound card 3:" +msgid "Sound card #3:" +msgstr "Sound card #3:" -msgid "Sound card 4:" -msgstr "Sound card 4:" +msgid "Sound card #4:" +msgstr "Sound card #4:" msgid "MIDI Out Device:" msgstr "MIDI Out Device:" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index be1e7514c..7e2ae7aa9 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -409,16 +409,16 @@ msgstr "Mando 3..." msgid "Joystick 4..." msgstr "Mando 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Tarjeta de sonido 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Tarjeta de sonido 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Tarjeta de sonido 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Tarjeta de sonido 4:" msgid "MIDI Out Device:" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index 6fe3020f9..c8bced530 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -409,16 +409,16 @@ msgstr "Peliohjain 3..." msgid "Joystick 4..." msgstr "Peliohjain 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Äänikortti 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Äänikortti 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Äänikortti 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Äänikortti 4:" msgid "MIDI Out Device:" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index 2328b0bc6..5a044c217 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -409,16 +409,16 @@ msgstr "Manette 3..." msgid "Joystick 4..." msgstr "Manette 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Carte son 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Carte son 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Carte son 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Carte son 4:" msgid "MIDI Out Device:" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index 74d2c497c..a42a94bb1 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -409,16 +409,16 @@ msgstr "Palica za igru 3..." msgid "Joystick 4..." msgstr "Palica za igru 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Zvučna kartica 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Zvučna kartica 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Zvučna kartica 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Zvučna kartica 4:" msgid "MIDI Out Device:" diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index d2df6d547..4d0dbd01e 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -409,16 +409,16 @@ msgstr "Játékvez. 3..." msgid "Joystick 4..." msgstr "Játékvez. 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Hangkártya 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Hangkártya 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Hangkártya 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Hangkártya 4:" msgid "MIDI Out Device:" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index 1d5d4f5b8..9ba78ed43 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -409,16 +409,16 @@ msgstr "Joystick 3..." msgid "Joystick 4..." msgstr "Joystick 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Scheda audio 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Scheda audio 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Scheda audio 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Scheda audio 4:" msgid "MIDI Out Device:" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index 3f5ea5083..ee70f5c71 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -409,16 +409,16 @@ msgstr "ジョイスティック3..." msgid "Joystick 4..." msgstr "ジョイスティック4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "サウンドカード1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "サウンドカード2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "サウンドカード3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "サウンドカード4:" msgid "MIDI Out Device:" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index 33424c40c..598a9e2c3 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -409,16 +409,16 @@ msgstr "조이스틱 3..." msgid "Joystick 4..." msgstr "조이스틱 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "사운드 카드 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "사운드 카드 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "사운드 카드 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "사운드 카드 4:" msgid "MIDI Out Device:" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index 8288fb385..0855c24ac 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -409,16 +409,16 @@ msgstr "Joystick 3..." msgid "Joystick 4..." msgstr "Joystick 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Karta dźwiękowa 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Karta dźwiękowa 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Karta dźwiękowa 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Karta dźwiękowa 4:" msgid "MIDI Out Device:" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 34fe953b5..cd5a13d24 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -409,16 +409,16 @@ msgstr "Joystick 3..." msgid "Joystick 4..." msgstr "Joystick 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Placa de som 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Placa de som 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Placa de som 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Placa de som 4:" msgid "MIDI Out Device:" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index 939aceab8..1d0814af2 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -409,16 +409,16 @@ msgstr "Joystick 3..." msgid "Joystick 4..." msgstr "Joystick 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Placa de som 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Placa de som 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Placa de som 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Placa de som 4:" msgid "MIDI Out Device:" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index c0204b508..dc51931e6 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -409,16 +409,16 @@ msgstr "Джойстик 3..." msgid "Joystick 4..." msgstr "Джойстик 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Звуковая карта 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Звуковая карта 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Звуковая карта 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Звуковая карта 4:" msgid "MIDI Out Device:" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index 37a7c050a..8b06e8bf1 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -409,16 +409,16 @@ msgstr "Joystick 3..." msgid "Joystick 4..." msgstr "Joystick 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Zvuková karta 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Zvuková karta 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Zvuková karta 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Zvuková karta 4:" msgid "MIDI Out Device:" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index 5d83d8e28..325a39b20 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -409,16 +409,16 @@ msgstr "Igralna palica 3..." msgid "Joystick 4..." msgstr "Igralna palica 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Zvočna kartica 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Zvočna kartica 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Zvočna kartica 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Zvočna kartica 4:" msgid "MIDI Out Device:" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index c15694953..5b342fb1f 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -409,16 +409,16 @@ msgstr "Oyun kolu 3..." msgid "Joystick 4..." msgstr "Oyun kolu 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Ses kartı 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Ses kartı 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Ses kartı 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Ses kartı 4:" msgid "MIDI Out Device:" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index 8641388c2..33960529c 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -409,16 +409,16 @@ msgstr "Джойстик 3..." msgid "Joystick 4..." msgstr "Джойстик 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Звукова карта 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Звукова карта 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Звукова карта 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Звукова карта 4:" msgid "MIDI Out Device:" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index 2b8167670..bb457ee46 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -409,16 +409,16 @@ msgstr "操纵杆 3..." msgid "Joystick 4..." msgstr "操纵杆 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "声卡 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "声卡 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "声卡 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "声卡 4:" msgid "MIDI Out Device:" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 2f0e5c4f2..1f6dca00f 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -409,16 +409,16 @@ msgstr "搖桿 3..." msgid "Joystick 4..." msgstr "搖桿 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "音效卡 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "音效卡 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "音效卡 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "音效卡 4:" msgid "MIDI Out Device:" diff --git a/src/win/languages/en-GB.rc b/src/win/languages/en-GB.rc index 98af74409..bc0df4d05 100644 --- a/src/win/languages/en-GB.rc +++ b/src/win/languages/en-GB.rc @@ -293,10 +293,10 @@ END #define STR_JOY3 "Joystick 3..." #define STR_JOY4 "Joystick 4..." -#define STR_SOUND1 "Sound card 1:" -#define STR_SOUND2 "Sound card 2:" -#define STR_SOUND3 "Sound card 3:" -#define STR_SOUND4 "Sound card 4:" +#define STR_SOUND1 "Sound card #1:" +#define STR_SOUND2 "Sound card #2:" +#define STR_SOUND3 "Sound card #3:" +#define STR_SOUND4 "Sound card #4:" #define STR_MIDI_OUT "MIDI Out Device:" #define STR_MIDI_IN "MIDI In Device:" #define STR_MPU401 "Standalone MPU-401" diff --git a/src/win/languages/en-US.rc b/src/win/languages/en-US.rc index 7971a7948..05ef61790 100644 --- a/src/win/languages/en-US.rc +++ b/src/win/languages/en-US.rc @@ -293,10 +293,10 @@ END #define STR_JOY3 "Joystick 3..." #define STR_JOY4 "Joystick 4..." -#define STR_SOUND1 "Sound card 1:" -#define STR_SOUND2 "Sound card 2:" -#define STR_SOUND3 "Sound card 3:" -#define STR_SOUND4 "Sound card 4:" +#define STR_SOUND1 "Sound card #1:" +#define STR_SOUND2 "Sound card #2:" +#define STR_SOUND3 "Sound card #3:" +#define STR_SOUND4 "Sound card #4:" #define STR_MIDI_OUT "MIDI Out Device:" #define STR_MIDI_IN "MIDI In Device:" #define STR_MPU401 "Standalone MPU-401" From 6b9fbcba8b6c59b1a85aca07de00ff92731fa876 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 28 Jan 2024 01:54:28 +0500 Subject: [PATCH 365/936] Correct capitalization of 3Dfx for Voodoo 1/2/Banshee Voodoo 3 left unchanged to match their new logo --- src/video/vid_voodoo.c | 8 ++++---- src/video/vid_voodoo_banshee.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index a34f26503..734179fa9 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -772,7 +772,7 @@ voodoo_pci_read(int func, int addr, void *priv) switch (addr) { case 0x00: - return 0x1a; /*3dfx*/ + return 0x1a; /*3Dfx*/ case 0x01: return 0x12; @@ -1310,7 +1310,7 @@ static const device_config_t voodoo_config[] = { .type = CONFIG_SELECTION, .selection = { { - .description = "Voodoo Graphics", + .description = "3Dfx Voodoo Graphics", .value = VOODOO_1 }, { @@ -1318,7 +1318,7 @@ static const device_config_t voodoo_config[] = { .value = VOODOO_SB50 }, { - .description = "Voodoo 2", + .description = "3Dfx Voodoo 2", .value = VOODOO_2 }, { @@ -1427,7 +1427,7 @@ static const device_config_t voodoo_config[] = { }; const device_t voodoo_device = { - .name = "3DFX Voodoo Graphics", + .name = "3Dfx Voodoo Graphics", .internal_name = "voodoo", .flags = DEVICE_PCI, .local = 0, diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 460a0dcb1..cf8cc154c 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -3535,7 +3535,7 @@ banshee_force_redraw(void *priv) } const device_t voodoo_banshee_device = { - .name = "3dfx Voodoo Banshee", + .name = "3Dfx Voodoo Banshee", .internal_name = "voodoo_banshee_pci", .flags = DEVICE_PCI, .local = 0, From 871187445b7221455a67c866d782b9f3e2a11530 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 28 Jan 2024 01:55:38 +0500 Subject: [PATCH 366/936] Refer to CPU speed as frequency --- src/qt/languages/ca-ES.po | 3 +++ src/qt/languages/cs-CZ.po | 3 +++ src/qt/languages/de-DE.po | 3 +++ src/qt/languages/en-GB.po | 3 +++ src/qt/languages/en-US.po | 3 +++ src/qt/languages/es-ES.po | 3 +++ src/qt/languages/fi-FI.po | 3 +++ src/qt/languages/fr-FR.po | 3 +++ src/qt/languages/hr-HR.po | 3 +++ src/qt/languages/hu-HU.po | 3 +++ src/qt/languages/it-IT.po | 3 +++ src/qt/languages/ja-JP.po | 3 +++ src/qt/languages/ko-KR.po | 3 +++ src/qt/languages/pl-PL.po | 3 +++ src/qt/languages/pt-BR.po | 3 +++ src/qt/languages/pt-PT.po | 3 +++ src/qt/languages/ru-RU.po | 3 +++ src/qt/languages/sk-SK.po | 3 +++ src/qt/languages/sl-SI.po | 3 +++ src/qt/languages/tr-TR.po | 3 +++ src/qt/languages/uk-UA.po | 3 +++ src/qt/languages/zh-CN.po | 3 +++ src/qt/languages/zh-TW.po | 3 +++ src/qt/qt_settingsmachine.ui | 2 +- 24 files changed, 70 insertions(+), 1 deletion(-) diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po index 372475099..71b643220 100644 --- a/src/qt/languages/ca-ES.po +++ b/src/qt/languages/ca-ES.po @@ -352,6 +352,9 @@ msgstr "Tipus de CPU:" msgid "Speed:" msgstr "Velocitat:" +msgid "Frequency:" +msgstr "Freqüència:" + msgid "FPU:" msgstr "FPU:" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index b8a68ce7d..0069f245b 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -352,6 +352,9 @@ msgstr "Procesor:" msgid "Speed:" msgstr "Rychlost:" +msgid "Frequency:" +msgstr "Frekvence:" + msgid "FPU:" msgstr "Koprocesor:" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index 25e708f1b..ed8e57ffa 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -352,6 +352,9 @@ msgstr "CPU-Typ:" msgid "Speed:" msgstr "Takt:" +msgid "Frequency:" +msgstr "Frequenz:" + msgid "FPU:" msgstr "FPU-Einheit:" diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index 2c262aeaa..b56c274d3 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -352,6 +352,9 @@ msgstr "CPU type:" msgid "Speed:" msgstr "Speed:" +msgid "Frequency:" +msgstr "Frequency:" + msgid "FPU:" msgstr "FPU:" diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index cb251f661..e3cfa3f77 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -352,6 +352,9 @@ msgstr "CPU type:" msgid "Speed:" msgstr "Speed:" +msgid "Frequency:" +msgstr "Frequency:" + msgid "FPU:" msgstr "FPU:" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index 7e2ae7aa9..c0f38893d 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -352,6 +352,9 @@ msgstr "Tipo de CPU:" msgid "Speed:" msgstr "Velocidad:" +msgid "Frequency:" +msgstr "Frecuencia:" + msgid "FPU:" msgstr "FPU:" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index c8bced530..4998d008b 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -352,6 +352,9 @@ msgstr "Suorittimen tyyppi:" msgid "Speed:" msgstr "Nopeus:" +msgid "Frequency:" +msgstr "Taajuus:" + msgid "FPU:" msgstr "Apusuoritin:" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index 5a044c217..0c50b3e46 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -352,6 +352,9 @@ msgstr "Type du processeur:" msgid "Speed:" msgstr "Vitesse:" +msgid "Frequency:" +msgstr "Fréquence:" + msgid "FPU:" msgstr "FPU:" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index a42a94bb1..436bae5c5 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -352,6 +352,9 @@ msgstr "Tip procesora:" msgid "Speed:" msgstr "Brzina:" +msgid "Frequency:" +msgstr "Frekvencija:" + msgid "FPU:" msgstr "FPU uređaj:" diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index 4d0dbd01e..129df1e2b 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -352,6 +352,9 @@ msgstr "Processzor:" msgid "Speed:" msgstr "Seb.:" +msgid "Frequency:" +msgstr "Frekvencia:" + msgid "FPU:" msgstr "FPU-egység:" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index 9ba78ed43..334ecadaa 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -352,6 +352,9 @@ msgstr "Tipo del CPU:" msgid "Speed:" msgstr "Veloc.:" +msgid "Frequency:" +msgstr "Frequenza:" + msgid "FPU:" msgstr "FPU:" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index ee70f5c71..32236adaa 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -352,6 +352,9 @@ msgstr "CPUタイプ:" msgid "Speed:" msgstr "速度:" +msgid "Frequency:" +msgstr "頻度:" + msgid "FPU:" msgstr "FPU:" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index 598a9e2c3..a8ff2723d 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -352,6 +352,9 @@ msgstr "CPU 종류:" msgid "Speed:" msgstr "속도:" +msgid "Frequency:" +msgstr "빈도:" + msgid "FPU:" msgstr "FPU:" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index 0855c24ac..a449d8951 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -352,6 +352,9 @@ msgstr "Rodzaj procesora:" msgid "Speed:" msgstr "Szybkość:" +msgid "Frequency:" +msgstr "Częstotliwość:" + msgid "FPU:" msgstr "Jednostka FPU:" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index cd5a13d24..c06f24835 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -352,6 +352,9 @@ msgstr "Tipo de CPU:" msgid "Speed:" msgstr "Veloc.:" +msgid "Frequency:" +msgstr "Frequência:" + msgid "FPU:" msgstr "FPU:" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index 1d0814af2..9743bc83c 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -352,6 +352,9 @@ msgstr "Tipo do CPU:" msgid "Speed:" msgstr "Velocidade:" +msgid "Frequency:" +msgstr "Frequência:" + msgid "FPU:" msgstr "FPU:" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index dc51931e6..1c68cc3c3 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -352,6 +352,9 @@ msgstr "Тип ЦП:" msgid "Speed:" msgstr "Скорость:" +msgid "Frequency:" +msgstr "Частота:" + msgid "FPU:" msgstr "FPU:" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index 8b06e8bf1..c2f129a3d 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -352,6 +352,9 @@ msgstr "Procesor:" msgid "Speed:" msgstr "Rýchlosť:" +msgid "Frequency:" +msgstr "Frekvencia:" + msgid "FPU:" msgstr "Koprocesor:" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index 325a39b20..8c1d62ded 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -352,6 +352,9 @@ msgstr "Vrsta procesorja:" msgid "Speed:" msgstr "Hitrost:" +msgid "Frequency:" +msgstr "Pogostost:" + msgid "FPU:" msgstr "Procesor plavajoče vejice:" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index 5b342fb1f..65a039c42 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -352,6 +352,9 @@ msgstr "CPU türü:" msgid "Speed:" msgstr "Hız:" +msgid "Frequency:" +msgstr "Sıklık:" + msgid "FPU:" msgstr "FPU:" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index 33960529c..e35cd11cc 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -352,6 +352,9 @@ msgstr "Тип ЦП:" msgid "Speed:" msgstr "Швидкість:" +msgid "Frequency:" +msgstr "Частота:" + msgid "FPU:" msgstr "FPU:" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index bb457ee46..0ac54f4e7 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -352,6 +352,9 @@ msgstr "CPU 类型:" msgid "Speed:" msgstr "速度:" +msgid "Frequency:" +msgstr "频率:" + msgid "FPU:" msgstr "浮点处理器 (FPU):" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 1f6dca00f..4767b8014 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -352,6 +352,9 @@ msgstr "CPU 類型:" msgid "Speed:" msgstr "速度:" +msgid "Frequency:" +msgstr "頻率:" + msgid "FPU:" msgstr "浮點處理器 (FPU):" diff --git a/src/qt/qt_settingsmachine.ui b/src/qt/qt_settingsmachine.ui index 22ecc15df..acdba4493 100644 --- a/src/qt/qt_settingsmachine.ui +++ b/src/qt/qt_settingsmachine.ui @@ -158,7 +158,7 @@ - Speed: + Frequency: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter From c6efb053182c9a41d561cdf5f2d290adc73c6a69 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 28 Jan 2024 01:56:15 +0500 Subject: [PATCH 367/936] Assorted Russian translation fixes and additions --- src/qt/languages/ru-RU.po | 126 ++++++++++++++++++++++++++++++++------ 1 file changed, 108 insertions(+), 18 deletions(-) diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index 1c68cc3c3..75f5a51b7 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -31,6 +31,12 @@ msgstr "&Скрыть строку состояния" msgid "Hide &toolbar" msgstr "С&крыть панель инструментов" +msgid "Show status icons in fullscreen" +msgstr "Показывать значки состояния в полноэкранном режиме" + +msgid "Show non-primary monitors" +msgstr "&Показывать неосновные мониторы" + msgid "&Resizeable window" msgstr "&Изменяемый размер окна" @@ -55,8 +61,32 @@ msgstr "Open&GL (3.0)" msgid "&VNC" msgstr "&VNC" +msgid "Renderer options..." +msgstr "Параметры рендеринга..." + +msgid "OpenGL 3.0 renderer options" +msgstr "Параметры рендеринга OpenGL 3.0" + +msgid "Render behavior" +msgstr "Режим рендеринга" + +msgid "Synchronize with video" +msgstr "Синхронизировать с видео" + +msgid "Use target framerate:" +msgstr "Использовать целевую частоту кадров:" + +msgid "VSync" +msgstr "Вертикальная синхронизация" + +msgid "Shaders" +msgstr "Шейдеры" + +msgid "No shader selected" +msgstr "Шейдер не выбран" + msgid "Specify dimensions..." -msgstr "&Указать размеры..." +msgstr "&Указать размеры главного окна..." msgid "F&orce 4:3 display ratio" msgstr "У&становить соотношение сторон 4:3" @@ -127,6 +157,9 @@ msgstr "&Целочисленное масштабирование" msgid "4:&3 Integer scale" msgstr "4:&3 Целочисленное масштабирование" +msgid "Apply fullscreen stretch mode when maximized" +msgstr "Применить полноэкранный режим растяжения при разворачивании окна" + msgid "E&GA/(S)VGA settings" msgstr "Настройки E&GA/(S)VGA" @@ -193,6 +226,9 @@ msgstr "Включить интеграцию &Discord" msgid "Sound &gain..." msgstr "&Усиление звука..." +msgid "Open screenshots folder..." +msgstr "Открыть папку скриншотов..." + msgid "Begin trace\tCtrl+T" msgstr "Начать трассировку\tCtrl+T" @@ -232,6 +268,9 @@ msgstr "&Перемотка в конец" msgid "E&ject" msgstr "И&звлечь" +msgid "Eject %s" +msgstr "Извлечь %s" + msgid "&Image..." msgstr "&Образ..." @@ -241,6 +280,9 @@ msgstr "Э&кспорт в 86F..." msgid "&Mute" msgstr "О&тключить звук" +msgid "&Unmute" +msgstr "В&ключить звук" + msgid "E&mpty" msgstr "П&устой" @@ -371,19 +413,22 @@ msgid "Time synchronization" msgstr "Синхронизация времени" msgid "Disabled" -msgstr "Отключить" +msgstr "Отключено" msgid "Enabled (local time)" -msgstr "Включить (местное)" +msgstr "Включено (местное)" msgid "Enabled (UTC)" -msgstr "Включить (UTC)" +msgstr "Включено (UTC)" msgid "Dynamic Recompiler" msgstr "Динамический рекомпилятор" msgid "Video:" -msgstr "Видеокарта:" +msgstr "Видеокарта 1:" + +msgid "Video #2:" +msgstr "Видеокарта 2:" msgid "Voodoo Graphics" msgstr "Ускоритель Voodoo" @@ -425,10 +470,10 @@ msgid "Sound card #4:" msgstr "Звуковая карта 4:" msgid "MIDI Out Device:" -msgstr "MIDI Out устр-во:" +msgstr "MIDI Out устройство:" msgid "MIDI In Device:" -msgstr "MIDI In устр-во:" +msgstr "MIDI In устройство:" msgid "Standalone MPU-401" msgstr "Отдельный MPU-401" @@ -443,7 +488,7 @@ msgid "Nuked (more accurate)" msgstr "Nuked (более точный)" msgid "YMFM (faster)" -msgstr "YMFM (быстрей)" +msgstr "YMFM (быстрее)" msgid "Network type:" msgstr "Тип сети:" @@ -454,6 +499,30 @@ msgstr "Устройство PCap:" msgid "Network adapter:" msgstr "Сетевая карта:" +msgid "Network Card #1" +msgstr "Сетевая карта 1:" + +msgid "Network Card #2" +msgstr "Сетевая карта 2:" + +msgid "Network Card #3" +msgstr "Сетевая карта 3:" + +msgid "Network Card #4" +msgstr "Сетевая карта 4:" + +msgid "Mode" +msgstr "Режим:" + +msgid "Interface" +msgstr "Интерфейс:" + +msgid "Adapter" +msgstr "Адаптер:" + +msgid "VDE Socket" +msgstr "VDE Socket:" + msgid "COM1 Device:" msgstr "Устройство COM1:" @@ -479,16 +548,28 @@ msgid "LPT4 Device:" msgstr "Устройство LPT4:" msgid "Serial port 1" -msgstr "Последов. порт COM1" +msgstr "Последовательный порт COM1" msgid "Serial port 2" -msgstr "Последов. порт COM2" +msgstr "Последовательный порт COM2" msgid "Serial port 3" -msgstr "Последов. порт COM3" +msgstr "Последовательный порт COM3" msgid "Serial port 4" -msgstr "Последов. порт COM4" +msgstr "Последовательный порт COM4" + +msgid "Serial port passthrough 1" +msgstr "Сквозной последовательный порт COM1" + +msgid "Serial port passthrough 2" +msgstr "Сквозной последовательный порт COM2" + +msgid "Serial port passthrough 3" +msgstr "Сквозной последовательный порт COM3" + +msgid "Serial port passthrough 4" +msgstr "Сквозной последовательный порт COM4" msgid "Parallel port 1" msgstr "Параллельный порт LPT1" @@ -541,8 +622,14 @@ msgstr "&Создать..." msgid "&Existing..." msgstr "&Выбрать..." +msgid "Browse..." +msgstr "Выбрать..." + msgid "&Remove" -msgstr "&Убрать" +msgstr "&Удалить" + +msgid "Remove" +msgstr "Удалить" msgid "Bus:" msgstr "Шина:" @@ -557,7 +644,7 @@ msgid "&Specify..." msgstr "&Указать..." msgid "Sectors:" -msgstr "Сектора:" +msgstr "Секторы:" msgid "Heads:" msgstr "Головки:" @@ -605,7 +692,7 @@ msgid "ISA RTC:" msgstr "ISA RTC:" msgid "ISA Memory Expansion" -msgstr "Карта расширения памяти (ISA)" +msgstr "Карта расширения памяти ISA" msgid "Card 1:" msgstr "Карта 1:" @@ -661,6 +748,9 @@ msgstr "86Box не смог найти ни одного подходящего msgid "(empty)" msgstr "(пусто)" +msgid "Clear image history" +msgstr "Очистить историю образов" + msgid "All files" msgstr "Все файлы" @@ -716,7 +806,7 @@ msgid "Floppy & CD-ROM drives" msgstr "Гибкие диски и CD-ROM" msgid "Other removable devices" -msgstr "Другие съёмные устр-ва" +msgstr "Другие съёмные устройства" msgid "Other peripherals" msgstr "Другая периферия" @@ -788,7 +878,7 @@ msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" -msgstr "Система управления полетом Thrustmaster" +msgstr "Система управления полётом Thrustmaster" msgid "None" msgstr "Нет" @@ -848,7 +938,7 @@ msgid "Do you want to save the settings?" msgstr "Хотите ли вы сохранить настройки?" msgid "This will hard reset the emulated machine." -msgstr "Это приведет к холодной перезагрузке эмулируемой машины." +msgstr "Это приведёт к холодной перезагрузке эмулируемой машины." msgid "Save" msgstr "Сохранить" From 08b0806f9a8b79b3c21a725512e167e5651bec2e Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 29 Jan 2024 13:20:54 +0500 Subject: [PATCH 368/936] Add migration paths for changed device config names --- src/config.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/config.c b/src/config.c index c973abf23..7bf29155c 100644 --- a/src/config.c +++ b/src/config.c @@ -1533,7 +1533,8 @@ load_other_peripherals(void) void config_load(void) { - int i; + int i; + ini_section_t c; config_log("Loading config file '%s'..\n", cfg_path); @@ -1623,6 +1624,23 @@ config_load(void) load_other_removable_devices(); /* Other removable devices */ load_other_peripherals(); /* Other peripherals */ + /* Migrate renamed device configurations. */ + c = ini_find_section(config, "MDA"); + if (c != NULL) + ini_rename_section(c, "IBM MDA"); + c = ini_find_section(config, "CGA"); + if (c != NULL) + ini_rename_section(c, "IBM CGA"); + c = ini_find_section(config, "EGA"); + if (c != NULL) + ini_rename_section(c, "IBM EGA"); + c = ini_find_section(config, "3DFX Voodoo Graphics"); + if (c != NULL) + ini_rename_section(c, "3Dfx Voodoo Graphics"); + c = ini_find_section(config, "3dfx Voodoo Banshee"); + if (c != NULL) + ini_rename_section(c, "3Dfx Voodoo Banshee"); + /* Mark the configuration as changed. */ config_changed = 1; From 91da7aab511f4187650b6f24d64456488647a1ca Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 29 Jan 2024 15:53:26 +0600 Subject: [PATCH 369/936] Merge prep --- src/machine/m_at_socket370.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index 5e60885f3..b8cc437a1 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -312,10 +312,6 @@ machine_at_awo671r_init(const machine_t *model) device_add_inst(&w83977ef_device, 2); device_add(&keyboard_ps2_pci_device); device_add(&sst_flash_39sf020_device); - if (gfxcard[0] == VID_INTERNAL) { - extern const device_t chips_69000_onboard_device; - device_add(&chips_69000_onboard_device); - } spd_register(SPD_TYPE_SDRAM, 0x3, 256); return ret; From 00a5017f5549284529fa8055058dc628e4b962bd Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 29 Jan 2024 15:57:09 +0600 Subject: [PATCH 370/936] Re-add it again --- src/machine/m_at_socket370.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index 2b2615422..4920f3d27 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -351,6 +351,10 @@ machine_at_awo671r_init(const machine_t *model) device_add_inst(&w83977ef_device, 2); device_add(&keyboard_ps2_pci_device); device_add(&sst_flash_39sf020_device); + if (gfxcard[0] == VID_INTERNAL) { + extern const device_t chips_69000_onboard_device; + device_add(&chips_69000_onboard_device); + } spd_register(SPD_TYPE_SDRAM, 0x3, 256); return ret; From 0483b8ceecfcc5d863406732df6c2f9e974f327e Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 29 Jan 2024 11:07:11 +0100 Subject: [PATCH 371/936] FDC37C669: Fix a wrong condition causing segmentation faults. --- src/sio/sio_fdc37c669.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sio/sio_fdc37c669.c b/src/sio/sio_fdc37c669.c index cb678427c..0cd686991 100644 --- a/src/sio/sio_fdc37c669.c +++ b/src/sio/sio_fdc37c669.c @@ -305,7 +305,7 @@ fdc37c669_reset(void *priv) dev->regs[0x21] = 0x3c; dev->regs[0x22] = 0x3d; - if (dev->id == 1) { + if (dev->id != 1) { fdc_reset(dev->fdc); fdc37c669_fdc_handler(dev); } From c95a0ac599524f756eeaa95e62e82eb0db082084 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 29 Jan 2024 16:23:23 +0600 Subject: [PATCH 372/936] Update vid_c&t_69000.c --- src/video/vid_c&t_69000.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index fe22985e0..4856aff33 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -42,6 +42,7 @@ typedef struct chips_69000_t { uint8_t pci_line_interrupt; uint8_t pci_rom_enable; uint8_t read_write_bank; + uint8_t slot; atomic_bool engine_active; atomic_bool quit; thread_t *accel_thread; @@ -1193,7 +1194,7 @@ uint16_t chips_69000_readw_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_readw_mmio(addr, chips); @@ -1205,7 +1206,7 @@ uint32_t chips_69000_readl_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_readl_mmio(addr, chips); @@ -1217,7 +1218,7 @@ void chips_69000_writeb_linear(uint32_t addr, uint8_t val, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_writeb_mmio(addr, val, chips); @@ -1229,7 +1230,7 @@ void chips_69000_writew_linear(uint32_t addr, uint16_t val, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_writew_mmio(addr, val, chips); @@ -1241,7 +1242,7 @@ void chips_69000_writel_linear(uint32_t addr, uint32_t val, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_writel_mmio(addr, val, chips); @@ -1271,7 +1272,7 @@ chips_69000_init(const device_t *info) io_sethandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips); - pci_add_card(PCI_ADD_VIDEO, chips_69000_pci_read, chips_69000_pci_write, chips); + pci_add_card(PCI_ADD_VIDEO, chips_69000_pci_read, chips_69000_pci_write, chips, &chips->slot); chips->svga.bpp = 8; chips->svga.miscout = 1; From 8724f30320b1b09e32a3ab317126e0cf0ad73e9f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 29 Jan 2024 16:31:35 +0600 Subject: [PATCH 373/936] Update vid_c&t_69000.c --- src/video/vid_c&t_69000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 4856aff33..c994e8e54 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -1182,7 +1182,7 @@ uint8_t chips_69000_readb_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_readb_mmio(addr, chips); @@ -1268,7 +1268,7 @@ chips_69000_init(const device_t *info) NULL, chips_69000_in, chips_69000_out, NULL, - NULL); + chips_69000_recalctimings); io_sethandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips); From f313e420d3887db891009cd3121668fd996d30b7 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 29 Jan 2024 16:35:10 +0600 Subject: [PATCH 374/936] Ok fixed for real --- src/video/vid_c&t_69000.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index c994e8e54..a06246538 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -544,7 +544,7 @@ chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t src, uint8_t nonpatte void chips_69000_recalctimings(svga_t *svga) { - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (chips->ext_regs[0x81] & 0x10) { svga->htotal -= 5; @@ -1265,10 +1265,10 @@ chips_69000_init(const device_t *info) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_sis); svga_init(info, &chips->svga, chips, 1 << 21, /*2048kb*/ - NULL, + chips_69000_recalctimings, chips_69000_in, chips_69000_out, NULL, - chips_69000_recalctimings); + NULL); io_sethandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips); From 9fcc59e2cafa7a8ea23daf5cf6246add1061ccab Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Mon, 29 Jan 2024 14:36:54 +0300 Subject: [PATCH 375/936] Revert "Rename 586MC1 to GA-586IS" This reverts commit 3390aa8d03e1e0d8a2ae67c64547a78d666a5d1d. --- src/machine/m_at_socket4.c | 1 + src/machine/machine_table.c | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index c06388547..a32617de4 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -317,6 +317,7 @@ machine_at_586mc1_init(const machine_t *model) machine_at_award_common_init(model); + device_add(&sio_device); device_add(&intel_flash_bxt_device); device_add(&i430lx_device); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 098b9e91d..b05ab9d55 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -8725,7 +8725,7 @@ const machine_t machines[] = { }, /* Has AMI MegaKey KBC firmware. */ { - .name = "[i430LX] Gigabyte GA-586IS", + .name = "[i430LX] Micro Star 586MC1", .internal_name = "586mc1", .type = MACHINE_TYPE_SOCKET4, .chipset = MACHINE_CHIPSET_INTEL_430LX, @@ -8744,8 +8744,8 @@ const machine_t machines[] = { .min_multi = MACHINE_MULTIPLIER_FIXED, .max_multi = MACHINE_MULTIPLIER_FIXED }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_APM | MACHINE_ACPI, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, .ram = { .min = 2048, .max = 131072, From 6c4ca44d5643ec8add550f0851c2cfb4c7ee0535 Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Mon, 29 Jan 2024 16:48:42 +0300 Subject: [PATCH 376/936] Machine flag cleanups round 1: 286 --- src/machine/m_at_286_386sx.c | 8 ++++++++ src/machine/m_at_compaq.c | 5 ----- src/machine/machine_table.c | 16 ++++++++-------- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index 79a82595f..93e9ebb52 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -304,6 +304,8 @@ machine_at_award286_init(const machine_t *model) if (fdc_type == FDC_INTERNAL) device_add(&fdc_at_device); + device_add(&ide_isa_device); + return ret; } @@ -406,6 +408,8 @@ machine_at_spc4200p_init(const machine_t *model) if (fdc_type == FDC_INTERNAL) device_add(&fdc_at_device); + device_add(&ide_isa_device); + return ret; } @@ -449,6 +453,8 @@ machine_at_spc4620p_init(const machine_t *model) if (fdc_type == FDC_INTERNAL) device_add(&fdc_at_device); + device_add(&ide_isa_device); + return ret; } @@ -483,6 +489,8 @@ machine_at_deskmaster286_init(const machine_t *model) if (fdc_type == FDC_INTERNAL) device_add(&fdc_at_device); + + device_add(&ide_isa_device); return ret; } diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index 86656b181..07ecd16e0 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -795,11 +795,6 @@ machine_at_compaq_init(const machine_t *model, int type) break; case COMPAQ_PORTABLEIII: - if (gfxcard[0] == VID_INTERNAL) - device_add(&compaq_plasma_device); - machine_at_init(model); - break; - case COMPAQ_PORTABLEIII386: if (hdc_current == 1) device_add(&ide_isa_device); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index b05ab9d55..d05c16fc8 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -2737,7 +2737,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, + .flags = MACHINE_FLAGS_NONE, /* Has internal video: Paradise PVGA1A */ .ram = { .min = 640, .max = 16384, @@ -2817,7 +2817,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_AT, - .flags = MACHINE_VIDEO, + .flags = MACHINE_IDE | MACHINE_VIDEO, .ram = { .min = 640, .max = 16384, @@ -3341,7 +3341,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_AT, - .flags = MACHINE_VIDEO, + .flags = MACHINE_IDE | MACHINE_VIDEO, .ram = { .min = 512, .max = 16384, @@ -3501,7 +3501,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, + .flags = MACHINE_IDE, .ram = { .min = 512, .max = 16384, @@ -3581,7 +3581,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2, - .flags = MACHINE_FLAGS_NONE, + .flags = MACHINE_IDE, /* Has internal video: C&T VGA 411 */ .ram = { .min = 512, .max = 2048, @@ -3661,7 +3661,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2, - .flags = MACHINE_VIDEO, + .flags = MACHINE_IDE | MACHINE_VIDEO, .ram = { .min = 1024, .max = 5120, @@ -3700,8 +3700,8 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE, /* Has internal video: C&T VGA 411 */ .ram = { .min = 512, .max = 16384, From 73d663461ff4bcf9d17391f71d25ca9c5c09ccaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B2=99=E6=B2=99=E5=AE=AE=E7=B4=97=E5=A4=9C?= <117635969+kzmidze@users.noreply.github.com> Date: Mon, 29 Jan 2024 22:38:16 +0800 Subject: [PATCH 377/936] Update zh-TW.rc --- src/win/languages/zh-TW.rc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/win/languages/zh-TW.rc b/src/win/languages/zh-TW.rc index fbd4fa998..dcc01836b 100644 --- a/src/win/languages/zh-TW.rc +++ b/src/win/languages/zh-TW.rc @@ -274,7 +274,7 @@ END #define STR_MB "MB" #define STR_MEMORY "記憶體:" #define STR_TIME_SYNC "時間同步" -#define STR_DISABLED "禁用" +#define STR_DISABLED "停用" #define STR_ENABLED_LOCAL "啟用 (本地時間)" #define STR_ENABLED_UTC "啟用 (UTC)" #define STR_DYNAREC "動態重編譯器" @@ -508,7 +508,7 @@ BEGIN IDS_2144 "OpenGL 著色器 (*.GLSL)\0*.GLSL\0所有檔案 (*.*)\0*.*\0" IDS_2145 "OpenGL 選項" IDS_2146 "正在載入一個不受支援的設定" - IDS_2147 "此模擬電腦禁用了基於選定電腦的 CPU 類型過濾。\n\n能夠選中與所選機器本不相容的 CPU,但是可能會遇到與機器 BIOS 或其他軟體不相容的問題。\n\n啟用此設定不受官方支援,並且提交的任何錯誤報告可能會視為無效而關閉。" + IDS_2147 "此模擬電腦停用了基於選定電腦的 CPU 類型過濾。\n\n能夠選中與所選機器本不相容的 CPU,但是可能會遇到與機器 BIOS 或其他軟體不相容的問題。\n\n啟用此設定不受官方支援,並且提交的任何錯誤報告可能會視為無效而關閉。" IDS_2148 "繼續" IDS_2149 "磁帶: %s" IDS_2150 "磁帶映像 (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0所有檔案 (*.*)\0*.*\0" @@ -591,11 +591,11 @@ BEGIN IDS_5120 "光碟 %i (%s): %s" - IDS_5376 "禁用" + IDS_5376 "停用" IDS_5381 "ATAPI" IDS_5382 "SCSI" - IDS_5632 "禁用" + IDS_5632 "停用" IDS_5637 "ATAPI (%01i:%01i)" IDS_5638 "SCSI (%01i:%02i)" From 23781eac6de95706656d45c86f10266f5a47ceb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B2=99=E6=B2=99=E5=AE=AE=E7=B4=97=E5=A4=9C?= <117635969+kzmidze@users.noreply.github.com> Date: Mon, 29 Jan 2024 22:38:56 +0800 Subject: [PATCH 378/936] Update zh-TW.po --- src/qt/languages/zh-TW.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 4767b8014..cf53b3488 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -371,7 +371,7 @@ msgid "Time synchronization" msgstr "時間同步" msgid "Disabled" -msgstr "禁用" +msgstr "停用" msgid "Enabled (local time)" msgstr "啟用 (本地時間)" @@ -920,7 +920,7 @@ msgid "You are loading an unsupported configuration" msgstr "正在載入一個不受支援的設定" msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." -msgstr "此模擬電腦禁用了基於選定電腦的 CPU 類型過濾。\n\n能夠選中與所選機器本不相容的 CPU,但是可能會遇到與機器 BIOS 或其他軟體不相容的問題。\n\n啟用此設定不受官方支援,並且提交的任何錯誤報告可能會視為無效而關閉。" +msgstr "此模擬電腦停用了基於選定電腦的 CPU 類型過濾。\n\n能夠選中與所選機器本不相容的 CPU,但是可能會遇到與機器 BIOS 或其他軟體不相容的問題。\n\n啟用此設定不受官方支援,並且提交的任何錯誤報告可能會視為無效而關閉。" msgid "Continue" msgstr "繼續" From 63412623442074c26f5f28d61e3bb28a409f9317 Mon Sep 17 00:00:00 2001 From: maximus105 <58270614+maximus105@users.noreply.github.com> Date: Mon, 29 Jan 2024 18:05:24 +0200 Subject: [PATCH 379/936] Update qt_mainwindow.ui Fix broken translation of "ACPI shutdown" tooltip for all languages --- src/qt/qt_mainwindow.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index d682815bb..00a3181e4 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -776,7 +776,7 @@ ACPI Shutdown - ACPI Shutdown + ACPI shutdown true From 008fd0d1265b1f434e013a6a0b7a422f04441c2d Mon Sep 17 00:00:00 2001 From: maximus105 <58270614+maximus105@users.noreply.github.com> Date: Mon, 29 Jan 2024 18:19:12 +0200 Subject: [PATCH 380/936] Update qt_mainwindow.ui --- src/qt/qt_mainwindow.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index 00a3181e4..c14c33207 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -773,7 +773,7 @@ :/menuicons/win/icons/acpi_shutdown.ico:/menuicons/win/icons/acpi_shutdown.ico - ACPI Shutdown + ACPI shutdown ACPI shutdown From 9dbaee95e39db9bbc7eec94ae9791895c59a13ac Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Mon, 29 Jan 2024 19:41:36 +0300 Subject: [PATCH 381/936] Machine flag cleanups round 2: 386SX --- src/machine/m_at_286_386sx.c | 4 ++-- src/machine/machine_table.c | 14 ++++++-------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index 93e9ebb52..75800f946 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -719,7 +719,7 @@ machine_at_sbc350a_init(const machine_t *model) device_add(&ali1217_device); device_add(&fdc37c665_ide_device); - device_add(&keyboard_at_device); + device_add(&keyboard_ps2_ami_device); return ret; } @@ -743,7 +743,7 @@ machine_at_flytech386_init(const machine_t *model) if (gfxcard[0] == VID_INTERNAL) device_add(&tvga8900d_device); - device_add(&keyboard_ps2_device); + device_add(&keyboard_at_ami_device); return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index d05c16fc8..41d3a7ffe 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -2737,7 +2737,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, /* Has internal video: Paradise PVGA1A */ + .flags = MACHINE_FLAGS_NONE, .ram = { .min = 640, .max = 16384, @@ -3964,7 +3964,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has the AMIKey KBC firmware, which is an updated 'F' type. */ + /* Has the AMIKey-2 KBC. */ { .name = "[ALi M1217] AAEON SBC-350A", .internal_name = "sbc350a", @@ -4004,11 +4004,9 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has an AMI KBC firmware, the only photo of this is too low resolution - for me to read what's on the KBC chip, so I'm going to assume AMI 'F' - based on the other known HT18 AMI BIOS strings. */ + /* Has a VIA VT82C42N KBC. */ { - .name = "[ALi M1217] Flytech 386", + .name = "[ALi M1217] Flytech A36", .internal_name = "flytech386", .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_ALI_M1217, @@ -4027,7 +4025,7 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PS2, + .bus_flags = MACHINE_AT, .flags = MACHINE_IDE | MACHINE_VIDEO, .ram = { .min = 1024, @@ -4539,7 +4537,7 @@ const machine_t machines[] = { /* Has an unknown AMI KBC firmware, I'm going to assume 'F' until a photo or real hardware BIOS string is found. */ { - .name = "[SCAT] KMX-C-02", + .name = "[SCAT] Kaimei KMX-C-02", .internal_name = "kmxc02", .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_SCAT, From 0e7eadb474dd5386da32537bc54cbad15f3b45b0 Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Mon, 29 Jan 2024 22:50:46 +0300 Subject: [PATCH 382/936] Add the AMIBIOS for the "MRBIOS 386SX" as the board has been identified --- src/include/86box/machine.h | 1 + src/machine/m_at_286_386sx.c | 24 ++++++++++++++++-- src/machine/machine_table.c | 47 +++++++++++++++++++++++++++++++++--- 3 files changed, 66 insertions(+), 6 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 5dd95b673..da52c68f5 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -472,6 +472,7 @@ extern int machine_at_wd76c10_init(const machine_t *); extern int machine_at_arb1374_init(const machine_t *); extern int machine_at_sbc350a_init(const machine_t *); extern int machine_at_flytech386_init(const machine_t *); +extern int machine_at_325ax_init(const machine_t *); extern int machine_at_mr1217_init(const machine_t *); extern int machine_at_pja511m_init(const machine_t *); extern int machine_at_prox1332_init(const machine_t *); diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index 75800f946..0153c0fe7 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -748,6 +748,26 @@ machine_at_flytech386_init(const machine_t *model) return ret; } +int +machine_at_325ax_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/325ax/M27C512.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&ali1217_device); + device_add(&fdc_at_device); + device_add(&keyboard_at_ami_device); + + return ret; +} + int machine_at_mr1217_init(const machine_t *model) { @@ -759,11 +779,11 @@ machine_at_mr1217_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_ide_init(model); + machine_at_common_init(model); device_add(&ali1217_device); device_add(&fdc_at_device); - device_add(&keyboard_ps2_device); + device_add(&keyboard_at_ami_device); return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 41d3a7ffe..5aa95a33c 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -4044,10 +4044,49 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* I'm going to assume this has a standard/generic IBM-compatible AT KBC - firmware until the board is identified. */ + /* Has a JetKey KBC without version, shows up as a 'H'. */ { - .name = "[ALi M1217] MR BIOS 386SX clone", + .name = "[ALi M1217] Chaintech 325AX", + .internal_name = "325ax", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_ALI_M1217, + .init = machine_at_325ax_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .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_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 1024, + .max = 16384, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a JetKey KBC without version, shows up as a 'H'. */ + { + .name = "[ALi M1217] Chaintech 325AX (MR BIOS)", .internal_name = "mr1217", .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_ALI_M1217, @@ -4067,7 +4106,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_AT, - .flags = MACHINE_IDE, + .flags = MACHINE_FLAGS_NONE, .ram = { .min = 1024, .max = 16384, From 6a45849ba7920d773201e010e5bc2450ff5146e6 Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Mon, 29 Jan 2024 23:24:32 +0300 Subject: [PATCH 383/936] Machine flag cleanups round 3: 386DX --- src/machine/m_at_compaq.c | 2 -- src/machine/machine_table.c | 9 +++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index 07ecd16e0..428199de7 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -805,8 +805,6 @@ machine_at_compaq_init(const machine_t *model, int type) case COMPAQ_DESKPRO386: case COMPAQ_DESKPRO386_05_1988: - if (hdc_current == 1) - device_add(&ide_isa_device); device_add(&compaq_386_device); machine_at_common_init(model); device_add(&keyboard_at_compaq_device); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 5aa95a33c..70c666eeb 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -4781,8 +4781,9 @@ const machine_t machines[] = { }, /* 386DX machines */ + /* Has a Jetkey V3, which identifies as a 'B'. */ { - .name = "[ACC 2168] AMI 386DX clone", + .name = "[ACC 2168] Juko AT046DX3", .internal_name = "acc386", .type = MACHINE_TYPE_386DX, .chipset = MACHINE_CHIPSET_ACC_2168, @@ -4922,7 +4923,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_AT, - .flags = MACHINE_IDE, + .flags = MACHINE_FLAGS_NONE, .ram = { .min = 1024, .max = 16384, @@ -4961,7 +4962,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_AT, - .flags = MACHINE_IDE, + .flags = MACHINE_FLAGS_NONE, .ram = { .min = 1024, .max = 16384, @@ -5058,7 +5059,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has AMI Megakey P KBC firmware */ + /* Has a Lance LT38C41 with AMI Megakey P KBC firmware */ { .name = "[ALi M1429] ECS Panda 386V", .internal_name = "ecs386v", From 0d427c813838db3a3e1d35aae420d30dd24a1356 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 30 Jan 2024 13:41:35 +0600 Subject: [PATCH 384/936] Fix video modes for real --- src/video/vid_c&t_69000.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index fe22985e0..6c9abd742 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -39,6 +39,7 @@ typedef struct chips_69000_t { svga_t svga; uint8_t pci_conf_status; + uint8_t slot; uint8_t pci_line_interrupt; uint8_t pci_rom_enable; uint8_t read_write_bank; @@ -543,7 +544,7 @@ chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t src, uint8_t nonpatte void chips_69000_recalctimings(svga_t *svga) { - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (chips->ext_regs[0x81] & 0x10) { svga->htotal -= 5; @@ -581,7 +582,7 @@ chips_69000_recalctimings(svga_t *svga) /* Let's care about horizontal blanking end later when it matters. */ svga->ma_latch |= (svga->crtc[0x40] & 0xF) << 16; - svga->rowoffset |= (svga->crtc[0x41] & 0xF) << 16; + svga->rowoffset |= (svga->crtc[0x41] & 0xF) << 8; } svga->interlace = !!(svga->crtc[0x70] & 0x80); @@ -614,6 +615,11 @@ chips_69000_recalctimings(svga_t *svga) svga->rowoffset <<= 2; break; } + + if (chips->ext_regs[0x40] & 1) { + svga->force_dword_mode = chips->ext_regs[0x40] & 1; + svga->rowoffset >>= 2; + } } void @@ -701,6 +707,7 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) case 0x40: chips->ext_regs[chips->ext_index] = val & 0x3; chips_69000_recalc_banking(chips); + svga_recalctimings(&chips->svga); break; case 0x60: chips->ext_regs[chips->ext_index] = val & 0x43; @@ -1181,7 +1188,7 @@ uint8_t chips_69000_readb_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_readb_mmio(addr, chips); @@ -1193,7 +1200,7 @@ uint16_t chips_69000_readw_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_readw_mmio(addr, chips); @@ -1205,7 +1212,7 @@ uint32_t chips_69000_readl_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_readl_mmio(addr, chips); @@ -1217,7 +1224,7 @@ void chips_69000_writeb_linear(uint32_t addr, uint8_t val, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_writeb_mmio(addr, val, chips); @@ -1229,7 +1236,7 @@ void chips_69000_writew_linear(uint32_t addr, uint16_t val, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_writew_mmio(addr, val, chips); @@ -1241,7 +1248,7 @@ void chips_69000_writel_linear(uint32_t addr, uint32_t val, void *p) { svga_t *svga = (svga_t *) p; - chips_69000_t *chips = (chips_69000_t *) svga->p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_writel_mmio(addr, val, chips); @@ -1271,7 +1278,7 @@ chips_69000_init(const device_t *info) io_sethandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips); - pci_add_card(PCI_ADD_VIDEO, chips_69000_pci_read, chips_69000_pci_write, chips); + pci_add_card(PCI_ADD_VIDEO, chips_69000_pci_read, chips_69000_pci_write, chips, &chips->slot); chips->svga.bpp = 8; chips->svga.miscout = 1; From 9c7daacf0c4d9ccbeedafdf5454119b97eec09b7 Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Tue, 30 Jan 2024 12:09:41 +0300 Subject: [PATCH 385/936] Machine flag cleanups round 4: 486 --- src/machine/m_at_386dx_486.c | 25 ++-- src/machine/machine_table.c | 258 +++++++++++++++++------------------ 2 files changed, 138 insertions(+), 145 deletions(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index b8d4c2e48..6e3d185d4 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -93,7 +93,7 @@ machine_at_asus386_init(const machine_t *model) static void machine_at_sis401_common_init(const machine_t *model) { - machine_at_common_ide_init(model); + machine_at_common_init(model); device_add(&sis_85c401_device); device_add(&keyboard_at_ami_device); @@ -144,7 +144,7 @@ machine_at_av4_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_ide_init(model); + machine_at_common_init(model); device_add(&sis_85c460_device); device_add(&keyboard_at_ami_device); @@ -424,7 +424,7 @@ machine_at_acerv10_init(const machine_t *model) device_add(&sis_85c461_device); device_add(&keyboard_ps2_acer_pci_device); - device_add(&ide_isa_2ch_device); + device_add(&ide_isa_device); if (fdc_type == FDC_INTERNAL) device_add(&fdc_at_device); @@ -461,7 +461,7 @@ machine_at_decpclpv_init(const machine_t *model) static void machine_at_ali1429_common_init(const machine_t *model, int is_green) { - machine_at_common_ide_init(model); + machine_at_common_init(model); if (is_green) device_add(&ali1429g_device); @@ -517,7 +517,7 @@ machine_at_opti495_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_ide_init(model); + machine_at_common_init(model); device_add(&opti495_device); @@ -532,7 +532,7 @@ machine_at_opti495_init(const machine_t *model) static void machine_at_opti495_ami_common_init(const machine_t *model) { - machine_at_common_ide_init(model); + machine_at_common_init(model); device_add(&opti495_device); @@ -774,7 +774,6 @@ machine_at_ami471_init(const machine_t *model) return ret; machine_at_sis_85c471_common_init(model); - device_add(&ide_vlb_device); device_add(&keyboard_at_ami_device); return ret; @@ -792,8 +791,7 @@ machine_at_vli486sv2g_init(const machine_t *model) return ret; machine_at_sis_85c471_common_init(model); - device_add(&ide_vlb_2ch_device); - device_add(&keyboard_ps2_ami_device); + device_add(&keyboard_at_ami_device); return ret; } @@ -810,7 +808,6 @@ machine_at_dtk486_init(const machine_t *model) return ret; machine_at_sis_85c471_common_init(model); - device_add(&ide_vlb_device); device_add(&keyboard_at_device); return ret; @@ -846,7 +843,6 @@ machine_at_win471_init(const machine_t *model) return ret; machine_at_sis_85c471_common_init(model); - device_add(&ide_vlb_device); device_add(&keyboard_at_ami_device); return ret; @@ -897,7 +893,6 @@ machine_at_vi15g_init(const machine_t *model) return ret; machine_at_sis_85c471_common_init(model); - device_add(&ide_vlb_device); device_add(&keyboard_at_ami_device); return ret; @@ -1140,7 +1135,7 @@ machine_at_alfredo_init(const machine_t *model) return ret; machine_at_common_init(model); - device_add(&ide_pci_2ch_device); + device_add(&ide_pci_device); pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -1342,7 +1337,6 @@ machine_at_pci400cb_init(const machine_t *model) machine_at_common_init_ex(model, 2); device_add(&ami_1994_nvr_device); - device_add(&ide_isa_device); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -1374,7 +1368,6 @@ machine_at_g486ip_init(const machine_t *model) machine_at_common_init_ex(model, 2); device_add(&ami_1992_nvr_device); - device_add(&ide_isa_device); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -1647,7 +1640,7 @@ machine_at_tf486_init(const machine_t *model) device_add(&ali1489_device); device_add(&w83977ef_device); - device_add(&keyboard_ps2_device); + device_add(&keyboard_at_device); device_add(&sst_flash_29ee010_device); return ret; diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 70c666eeb..1af72aa38 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -5096,6 +5096,48 @@ const machine_t machines[] = { .vid_device = NULL, .snd_device = NULL, .net_device = NULL + }, + /* The board has a "ASII KB-100" which I was not able to find any information about, + but the BIOS sends commands C9 without a parameter and D5, both of which are + Phoenix MultiKey commands. */ + { + .name = "[OPTi 495] U-Board OPTi 495SLC", + .internal_name = "award495", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_OPTI_495, + .init = machine_at_opti495_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX, /* Actual machine only supports 386DXes */ + .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_AT, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL }, /* Has AMIKey F KBC firmware. */ { @@ -5181,47 +5223,6 @@ const machine_t machines[] = { }, /* 386DX/486 machines */ - /* The BIOS sends commands C9 without a parameter and D5, both of which are - Phoenix MultiKey commands. */ - { - .name = "[OPTi 495] Award 486 clone", - .internal_name = "award495", - .type = MACHINE_TYPE_386DX_486, - .chipset = MACHINE_CHIPSET_OPTI_495, - .init = machine_at_opti495_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386DX | CPU_PKG_SOCKET1, - .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_VLB, - .flags = MACHINE_IDE | MACHINE_APM, - .ram = { - .min = 1024, - .max = 32768, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, /* Has AMIKey F KBC firmware. */ { .name = "[OPTi 495] DataExpert SX495", @@ -5244,7 +5245,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_VLB, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 32768, @@ -5284,7 +5285,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_VLB, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 32768, @@ -5450,7 +5451,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_VLB, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 32768, @@ -5533,7 +5534,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_VLB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_APM, .ram = { .min = 1024, .max = 65536, @@ -5573,7 +5574,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_AT, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 65536, @@ -5613,7 +5614,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_AT, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 65536, @@ -5654,7 +5655,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_VLB, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 65536, @@ -5672,7 +5673,47 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has a MR (!) KBC firmware, which is a clone of the standard IBM PS/2 KBC firmware. */ + /* Uses an NEC 90M002A (UPD82C42C, 8042 clone) with unknown firmware. */ + { + .name = "[SiS 461] Acer V10", + .internal_name = "acerv10", + .type = MACHINE_TYPE_486, + .chipset = MACHINE_CHIPSET_SIS_461, + .init = machine_at_acerv10_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET1, + .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_PS2_VLB, + .flags = MACHINE_IDE | MACHINE_APM, /* Machine has internal SCSI */ + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has MR (!) KBC firmware, which is a clone of the standard IBM PS/2 KBC firmware. */ { .name = "[SiS 471] SiS VL-BUS 471 REV. A1", .internal_name = "px471", @@ -5755,9 +5796,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* According to Deksor on the Win3x.org forum, the BIOS string ends in a -0, - indicating an unknown KBC firmware. But it does send the AMIKey get version - command, so it must expect an AMIKey. */ + /* Has a VLSI VL82C113A SCAMP Combination I/O which holds the KBC. */ { .name = "[VLSI 82C480] HP Vectra 486VL", .internal_name = "vect486vl", @@ -5792,7 +5831,7 @@ const machine_t machines[] = { .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, - .sio_device = NULL, + .sio_device = NULL, /*Has SIO (sorta): VLSI VL82C113A SCAMP Combination I/O*/ .vid_device = &gd5428_onboard_device, .snd_device = NULL, .net_device = NULL @@ -5942,7 +5981,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, .ram = { .min = 4096, .max = 36864, @@ -5982,7 +6021,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_VLB, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 32768, @@ -6022,7 +6061,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, .ram = { .min = 1024, .max = 32768, @@ -6040,46 +6079,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Uses an NEC 90M002A (UPD82C42C, 8042 clone) with unknown firmware. */ - { - .name = "[SiS 461] Acer V10", - .internal_name = "acerv10", - .type = MACHINE_TYPE_486_S2, - .chipset = MACHINE_CHIPSET_SIS_461, - .init = machine_at_acerv10_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .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_PS2, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 1024, - .max = 32768, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, /* The BIOS does not send any non-standard keyboard controller commands and wants a PS/2 mouse, so it's an IBM PS/2 KBC (Type 1) firmware. */ { @@ -6121,7 +6120,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* AMIKey-2 */ + /* Has AMI MegaKey KBC. */ { .name = "[i420TX] J-Bond PCI400C-A", .internal_name = "pci400ca", @@ -6142,7 +6141,7 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PCI, .flags = MACHINE_SCSI, .ram = { .min = 1024, @@ -6167,7 +6166,7 @@ const machine_t machines[] = { /* 486 machines with just the ISA slot */ /* Has AMI MegaKey KBC firmware. */ { - .name = "[Contaq 82C597] Green-B", + .name = "[Contaq 82C597] Visionex Green-B", .internal_name = "greenb", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_CONTAQ_82C597, @@ -6205,7 +6204,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has a VIA VT82C42N KBC. */ + /* Version 1.0 has an AMIKEY-2, version 2.0 has a VIA VT82C42N KBC. */ { .name = "[OPTi 895] Jetway J-403TG", .internal_name = "403tg", @@ -6389,7 +6388,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_VLB, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 65536, @@ -6407,7 +6406,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has AMIKey H keyboard BIOS. */ + /* Has AMIKey-2 'H' keyboard BIOS. */ { .name = "[SiS 471] AOpen Vi15G", .internal_name = "vi15g", @@ -6429,7 +6428,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_VLB, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 65536, @@ -6469,7 +6468,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_VLB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 65536, @@ -6509,7 +6508,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_VLB, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 65536, @@ -6527,9 +6526,9 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Unknown Epox VLB Socket 3 board, has AMIKey F keyboard BIOS. */ + /* Has a Lance LT38C41L with AMIKey F keyboard BIOS. */ { - .name = "[SiS 471] Epox 486SX/DX Green", + .name = "[SiS 471] Epox GXA486SG", .internal_name = "ami471", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_SIS_471, @@ -6549,7 +6548,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_VLB, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 65536, @@ -6770,6 +6769,7 @@ const machine_t machines[] = { /* 486 machines which utilize the PCI bus */ /* Machine with ALi M1429G chipset and M1435 southbridge */ + /* Has an AMIKEY-2 KBC. */ { .name = "[ALi M1429G] MSI MS-4134", .internal_name = "ms4134", @@ -6790,8 +6790,8 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PS2_PCIV, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .bus_flags = MACHINE_PCIV, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 131072, @@ -6831,7 +6831,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_PCIV, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_APM, .ram = { .min = 1024, .max = 131072, @@ -6911,7 +6911,7 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PCI, + .bus_flags = MACHINE_PCI, /* Machine has a PISA slot */ .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 1024, @@ -7160,7 +7160,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_PCIV, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_APM, .ram = { .min = 1024, .max = 131072, @@ -7199,7 +7199,7 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PCI, .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 1024, @@ -7360,7 +7360,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_SCSI | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_SCSI | MACHINE_APM, .ram = { .min = 1024, .max = 131072, @@ -7400,7 +7400,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_APM, .ram = { .min = 2048, .max = 131072, @@ -7439,7 +7439,7 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PCI, .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 1024, @@ -7481,7 +7481,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_SCSI | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_SCSI | MACHINE_APM, .ram = { .min = 1024, .max = 131072, @@ -7521,7 +7521,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PCIV, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_APM, .ram = { .min = 2048, .max = 131072, @@ -7543,7 +7543,7 @@ const machine_t machines[] = { { .name = "[IMS 8848] Tekram G486IP", .internal_name = "g486ip", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3, /* could be s2 or pga168 */ .chipset = MACHINE_CHIPSET_IMS_8848, .init = machine_at_g486ip_init, .p1_handler = NULL, @@ -7560,8 +7560,8 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_APM, .ram = { .min = 2048, .max = 131072, @@ -7659,7 +7659,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* The BIOS does not send a single non-standard KBC command, so it has a standard PS/2 KBC. */ + /* Has a VIA VT82C42N KBC. */ { .name = "[SiS 496] Micronics M4Li", .internal_name = "m4li", @@ -7699,7 +7699,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has a BestKey KBC which clones AMI type 'H'. */ + /* Revision 1 has a Lance LT38C41L, revision 2 has a Holtek HT6542B. Another variant with a Bestkey KBC might exist as well. */ { .name = "[SiS 496] Rise Computer R418", .internal_name = "r418", @@ -7739,7 +7739,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* This has a Holtek KBC and the BIOS does not send a single non-standard KBC command, so it + /* This has a Holtek HT6542B KBC and the BIOS does not send a single non-standard KBC command, so it must be an ASIC that clones the standard IBM PS/2 KBC. */ { .name = "[SiS 496] Soyo 4SAW2", @@ -7781,7 +7781,7 @@ const machine_t machines[] = { .net_device = NULL }, /* According to MrKsoft, his real 4DPS has an AMIKey-2, which is an updated version - of type 'H'. */ + of type 'H'. There are other variants of the board with Holtek HT6542B KBCs. */ { .name = "[SiS 496] Zida Tomato 4DP", .internal_name = "4dps", @@ -7903,7 +7903,7 @@ const machine_t machines[] = { }, /* This has an AMIKey-2, which is an updated version of type 'H'. */ { - .name = "[UMC 8881] ECS Elite UM8810PAIO", + .name = "[UMC 8881] ECS Elite UM8810P-AIO", .internal_name = "ecs486", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_UMC_UM8881, @@ -7943,7 +7943,7 @@ const machine_t machines[] = { }, /* Has AMIKey Z(!) KBC firmware. */ { - .name = "[UMC 8881] Epson Action PC 2600", + .name = "[UMC 8881] Epson ActionPC 2600", .internal_name = "actionpc2600", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_UMC_UM8881, @@ -8372,7 +8372,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_APM, .ram = { .min = 32768, .max = 131072, From 82e95cf59cb43465d278d9aee5a72f0b4c11686f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 30 Jan 2024 16:56:08 +0600 Subject: [PATCH 386/936] More C&T 69000 fixes --- src/video/vid_c&t_69000.c | 70 +++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 36 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 92de759f9..5b1384b17 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -43,7 +43,6 @@ typedef struct chips_69000_t { uint8_t pci_line_interrupt; uint8_t pci_rom_enable; uint8_t read_write_bank; - uint8_t slot; atomic_bool engine_active; atomic_bool quit; thread_t *accel_thread; @@ -580,46 +579,45 @@ chips_69000_recalctimings(svga_t *svga) if (!(chips->ext_regs[0x81] & 0x10)) svga->htotal += 5; - /* Let's care about horizontal blanking end later when it matters. */ + svga->hblank_end_val = ((svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00)) | (svga->crtc[0x3c] & 0b11000000); + svga->hblank_end_len = 0x100; svga->ma_latch |= (svga->crtc[0x40] & 0xF) << 16; svga->rowoffset |= (svga->crtc[0x41] & 0xF) << 8; - } - - svga->interlace = !!(svga->crtc[0x70] & 0x80); - switch (chips->ext_regs[0x81] & 0xF) { - case 0b0010: - svga->bpp = 8; - svga->render = svga_render_8bpp_highres; - svga->rowoffset <<= 2; - break; + svga->interlace = !!(svga->crtc[0x70] & 0x80); - case 0b0100: - svga->bpp = 15; - svga->render = svga_render_15bpp_highres; - svga->rowoffset <<= 2; - break; - case 0b0101: - svga->bpp = 16; - svga->render = svga_render_16bpp_highres; - svga->rowoffset <<= 2; - break; - case 0b0110: - svga->bpp = 24; - svga->render = svga_render_24bpp_highres; - svga->rowoffset <<= 2; - break; - case 0b0111: - svga->bpp = 32; - svga->render = svga_render_32bpp_highres; - svga->rowoffset <<= 2; - break; - } + switch (chips->ext_regs[0x81] & 0xF) { + case 0b0010: + svga->bpp = 8; + svga->render = svga_render_8bpp_highres; + break; - if (chips->ext_regs[0x40] & 1) { - svga->force_dword_mode = chips->ext_regs[0x40] & 1; - svga->rowoffset >>= 2; + case 0b0100: + svga->bpp = 15; + svga->render = svga_render_15bpp_highres; + break; + case 0b0101: + svga->bpp = 16; + svga->render = svga_render_16bpp_highres; + break; + case 0b0110: + svga->bpp = 24; + svga->render = svga_render_24bpp_highres; + break; + case 0b0111: + svga->bpp = 32; + svga->render = svga_render_32bpp_highres; + break; + } + + if (chips->ext_regs[0x40] & 1) { + svga->force_dword_mode = chips->ext_regs[0x40] & 1; + } else { + svga->force_dword_mode = 0; + } + } else { + svga->force_dword_mode = 0; } } @@ -976,7 +974,7 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) } case 0x13: { - mem_mapping_set_addr(&chips->linear_mapping, val << 24, (1 << 24) - 1); + mem_mapping_set_addr(&chips->linear_mapping, val << 24, (1 << 24)); break; } case 0x3c: From 9ee49a6977fe8bac4d3ac3e6e17365b6aa721a80 Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Tue, 30 Jan 2024 15:45:09 +0300 Subject: [PATCH 387/936] Machine flag cleanups round 5: Socket 4/5 --- src/machine/m_at_socket4.c | 4 +- src/machine/machine_table.c | 152 ++++++++++++++++++------------------ 2 files changed, 78 insertions(+), 78 deletions(-) diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index a32617de4..2d7ebe0f9 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -45,7 +45,7 @@ void machine_at_premiere_common_init(const machine_t *model, int pci_switch) { machine_at_common_init(model); - device_add(&ide_pci_2ch_device); + device_add(&ide_pci_device); pci_init(PCI_CONFIG_TYPE_2 | pci_switch); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -181,7 +181,7 @@ machine_at_dellxp60_init(const machine_t *model) return ret; machine_at_common_init(model); - device_add(&ide_pci_2ch_device); + device_add(&ide_pci_device); pci_init(PCI_CONFIG_TYPE_2); 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 1af72aa38..ade0223f5 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -5695,7 +5695,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_VLB, - .flags = MACHINE_IDE | MACHINE_APM, /* Machine has internal SCSI */ + .flags = MACHINE_IDE | MACHINE_APM, /* Machine has internal SCSI: Adaptec AIC-6360 */ .ram = { .min = 1024, .max = 32768, @@ -6039,6 +6039,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* This has a standalone AMI Megakey 1993, which is type 'P'. */ + { + .name = "[IMS 8848] Tekram G486IP", + .internal_name = "g486ip", + .type = MACHINE_TYPE_486_S2, + .chipset = MACHINE_CHIPSET_IMS_8848, + .init = machine_at_g486ip_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .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_PCI, + .flags = MACHINE_APM, + .ram = { + .min = 2048, + .max = 131072, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Uses an Intel KBC with Phoenix MultiKey KBC firmware. */ { .name = "[SiS 461] DEC DECpc LPV", @@ -7539,46 +7579,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* This has a standalone AMI Megakey 1993, which is type 'P'. */ - { - .name = "[IMS 8848] Tekram G486IP", - .internal_name = "g486ip", - .type = MACHINE_TYPE_486_S3, /* could be s2 or pga168 */ - .chipset = MACHINE_CHIPSET_IMS_8848, - .init = machine_at_g486ip_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .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_PCI, - .flags = MACHINE_APM, - .ram = { - .min = 2048, - .max = 131072, - .step = 2048 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, /* This has an AMIKey-2, which is an updated version of type 'H'. */ { .name = "[SiS 496] ASUS PVI-486SP3C", @@ -8501,7 +8501,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE | MACHINE_APM, /* Machine has internal SCSI */ .ram = { .min = 2048, .max = 131072, @@ -8540,8 +8540,8 @@ const machine_t machines[] = { .min_multi = MACHINE_MULTIPLIER_FIXED, .max_multi = MACHINE_MULTIPLIER_FIXED }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE | MACHINE_APM | MACHINE_ACPI, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_APM, .ram = { .min = 2048, .max = 196608, @@ -8580,8 +8580,8 @@ const machine_t machines[] = { .min_multi = MACHINE_MULTIPLIER_FIXED, .max_multi = MACHINE_MULTIPLIER_FIXED }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE | MACHINE_APM | MACHINE_ACPI, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_IDE | MACHINE_APM, .ram = { .min = 2048, .max = 131072, @@ -8621,7 +8621,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE | MACHINE_APM, .ram = { .min = 2048, .max = 131072, @@ -8663,7 +8663,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE | MACHINE_APM, .ram = { .min = 2048, .max = 131072, @@ -8703,7 +8703,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_VIDEO_8514A | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_VIDEO_8514A | MACHINE_APM, .ram = { .min = 2048, .max = 131072, @@ -8743,7 +8743,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 2048, .max = 131072, @@ -8761,9 +8761,9 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has AMI MegaKey KBC firmware. */ + /* Has AMI MegaKey 'H' KBC firmware. */ { - .name = "[i430LX] Micro Star 586MC1", + .name = "[i430LX] Gigabyte GA-586IS", .internal_name = "586mc1", .type = MACHINE_TYPE_SOCKET4, .chipset = MACHINE_CHIPSET_INTEL_430LX, @@ -8782,8 +8782,8 @@ const machine_t machines[] = { .min_multi = MACHINE_MULTIPLIER_FIXED, .max_multi = MACHINE_MULTIPLIER_FIXED }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_APM, .ram = { .min = 2048, .max = 131072, @@ -8823,7 +8823,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, .ram = { .min = 8192, .max = 139264, @@ -8867,7 +8867,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED }, .bus_flags = MACHINE_PS2_VLB, - .flags = MACHINE_IDE | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE | MACHINE_APM, .ram = { .min = 2048, .max = 65536, @@ -8909,7 +8909,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED }, .bus_flags = MACHINE_PCIV, - .flags = MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -8951,7 +8951,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -8991,7 +8991,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -9033,7 +9033,7 @@ const machine_t machines[] = { .max_multi = 1.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 2048, .max = 131072, @@ -9073,7 +9073,7 @@ const machine_t machines[] = { .max_multi = 1.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 2048, .max = 131072, @@ -9114,7 +9114,7 @@ const machine_t machines[] = { .max_multi = 1.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 2048, .max = 131072, @@ -9154,7 +9154,7 @@ const machine_t machines[] = { .max_multi = 1.5 }, .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_APM, .ram = { .min = 2048, .max = 262144, @@ -9194,7 +9194,7 @@ const machine_t machines[] = { .max_multi = 1.5 }, .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE | MACHINE_APM, .ram = { .min = 2048, .max = 262144, @@ -9236,7 +9236,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -9276,7 +9276,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -9318,7 +9318,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -9358,7 +9358,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -9398,7 +9398,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -9438,7 +9438,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -9482,7 +9482,7 @@ const machine_t machines[] = { .max_multi = 1.5 }, .bus_flags = MACHINE_VLB, - .flags = MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_APM, .ram = { .min = 2048, .max = 65536, @@ -9523,7 +9523,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PCIV, - .flags = MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -9561,7 +9561,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 2.0 }, - .bus_flags = MACHINE_PCIV | MACHINE_PS2, + .bus_flags = MACHINE_PS2_PCIV, .flags = MACHINE_APM | MACHINE_IDE_DUAL | MACHINE_SUPER_IO, .ram = { .min = 8192, @@ -9604,7 +9604,7 @@ const machine_t machines[] = { .max_multi = 1.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -9644,7 +9644,7 @@ const machine_t machines[] = { .max_multi = 1.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -9684,7 +9684,7 @@ const machine_t machines[] = { .max_multi = 1.5 }, .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, From 844e6e8579d8a213ccc71dfcf7fb6de566c87af7 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 30 Jan 2024 21:18:55 +0600 Subject: [PATCH 388/936] Fix 8bpp modes --- src/video/vid_c&t_69000.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 5b1384b17..aa42b61d6 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -725,7 +725,7 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) break; case 0x80: chips->ext_regs[chips->ext_index] = val & 0xBF; - chips->svga.ramdac_type = (val & 0x80) ? RAMDAC_8BIT : RAMDAC_6BIT; + svga_set_ramdac_type(&chips->svga, (val & 0x80) ? RAMDAC_8BIT : RAMDAC_6BIT); break; case 0x81: chips->ext_regs[chips->ext_index] = val & 0x1f; @@ -769,7 +769,7 @@ chips_69000_out(uint16_t addr, uint8_t val, void *p) } break; case 0x3c9: - if (!(chips->ext_regs[0x09] & 0x01)) + if (!(chips->ext_regs[0x80] & 0x01)) break; if (svga->adv_flags & FLAG_RAMDAC_SHIFT) val <<= 2; @@ -840,7 +840,7 @@ chips_69000_in(uint16_t addr, void *p) case 0x3C5: return svga->seqregs[svga->seqaddr]; case 0x3c9: - if (!(chips->ext_regs[0x09] & 0x01)) { + if (!(chips->ext_regs[0x80] & 0x01)) { temp = svga_in(addr, svga); break; } From 439c1152fb4d2fe0a2d4c487a2667d683c286096 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 30 Jan 2024 22:00:12 +0600 Subject: [PATCH 389/936] C&T_69000: All modes are working --- src/video/vid_c&t_69000.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index aa42b61d6..e351f51af 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -610,14 +610,6 @@ chips_69000_recalctimings(svga_t *svga) svga->render = svga_render_32bpp_highres; break; } - - if (chips->ext_regs[0x40] & 1) { - svga->force_dword_mode = chips->ext_regs[0x40] & 1; - } else { - svga->force_dword_mode = 0; - } - } else { - svga->force_dword_mode = 0; } } @@ -638,7 +630,6 @@ chips_69000_recalc_banking(chips_69000_t *chips) svga->chain2_write = !(svga->seqregs[0x4] & 4); svga->chain4 = (svga->seqregs[0x4] & 8) || (chips->ext_regs[0xA] & 0x4); - svga->packed_chain4 = !!(chips->ext_regs[0xA] & 0x4); svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && !(svga->adv_flags & FLAG_ADDR_BY8); if (chips->ext_regs[0xA] & 1) { @@ -1288,6 +1279,8 @@ chips_69000_init(const device_t *info) chips->quit = 0; chips->engine_active = 0; chips->on_board = !!(info->local); + + chips->svga.packed_chain4 = 1; timer_add(&chips->decrement_timer, chips_69000_decrement_timer, chips, 0); timer_on_auto(&chips->decrement_timer, 1000000. / 2000.); From 2ee97bf1e190d8a00bbacf9ae3e0969a249560cd Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 30 Jan 2024 23:33:55 +0600 Subject: [PATCH 390/936] DDC work --- src/video/vid_c&t_69000.c | 44 ++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index e351f51af..5037cb1c2 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -10,11 +10,9 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Cacodemon345 * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2023-2024 Cacodemon345 */ #include #include @@ -34,6 +32,8 @@ #include <86box/vid_svga_render.h> #include <86box/pci.h> #include <86box/thread.h> +#include <86box/i2c.h> +#include <86box/vid_ddc.h> #include typedef struct chips_69000_t { @@ -81,6 +81,8 @@ typedef struct chips_69000_t { }; rom_t bios_rom; + + void* i2c_ddc, *ddc; } chips_69000_t; static video_timings_t timing_sis = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 20, .read_w = 20, .read_l = 35 }; @@ -666,7 +668,16 @@ chips_69000_read_ext_reg(chips_69000_t* chips) case 0x0A: return chips->ext_regs[index] & 0x37; case 0x63: - return 0xFF; + { + uint8_t val = chips->ext_regs[index]; + if (!(chips->ext_regs[0x62] & 0x8)) + val = (val & ~8) | (i2c_gpio_get_scl(chips->i2c_ddc) << 3); + + if (!(chips->ext_regs[0x62] & 0x4)) + val = (val & ~4) | (i2c_gpio_get_sda(chips->i2c_ddc) << 2); + + return val; + } case 0x70: return 0x3; case 0x71: @@ -711,6 +722,24 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) case 0x62: chips->ext_regs[chips->ext_index] = val & 0x9C; break; + case 0x63: + { + uint8_t scl = 0, sda = 0; + if (chips->ext_regs[0x62] & 0x8) + scl = !!(val & 8); + else + scl = i2c_gpio_get_scl(chips->i2c_ddc); + + if (chips->ext_regs[0x62] & 0x4) + sda = !!(val & 4); + else + scl = i2c_gpio_get_sda(chips->i2c_ddc); + + i2c_gpio_set(chips->i2c_ddc, scl, sda); + + chips->ext_regs[chips->ext_index] = val & 0x9F; + break; + } case 0x67: chips->ext_regs[chips->ext_index] = val & 0x2; break; @@ -1285,6 +1314,9 @@ chips_69000_init(const device_t *info) timer_add(&chips->decrement_timer, chips_69000_decrement_timer, chips, 0); timer_on_auto(&chips->decrement_timer, 1000000. / 2000.); + chips->i2c_ddc = i2c_gpio_init("c&t_69000_mga"); + chips->ddc = ddc_init(i2c_gpio_get_bus(chips->i2c_ddc)); + return chips; } @@ -1302,6 +1334,8 @@ chips_69000_close(void *p) chips->quit = 1; // thread_set_event(chips->fifo_event); // thread_wait(chips->accel_thread); + ddc_close(chips->ddc); + i2c_gpio_close(chips->i2c_ddc); svga_close(&chips->svga); free(chips); From b29df816718734b5f9479f8a8f626758e997750f Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Tue, 30 Jan 2024 20:55:03 +0300 Subject: [PATCH 391/936] Machine flag cleanups round 6: Socket 7 (ACPI removals need testing) --- src/machine/m_at_socket7_3v.c | 2 +- src/machine/machine_table.c | 148 +++++++++++++++++----------------- 2 files changed, 75 insertions(+), 75 deletions(-) diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index 5fb136d3c..2e642082d 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -547,7 +547,7 @@ machine_at_acerm3a_init(const machine_t *model) device_add(&i430hx_device); device_add(&piix3_device); device_add(&keyboard_ps2_pci_device); - device_add(&fdc37c932fr_device); + device_add(&fdc37c935_device); device_add(&sst_flash_29ee010_device); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index ade0223f5..4c1881c1b 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -7240,7 +7240,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_APM, .ram = { .min = 1024, .max = 131072, @@ -9705,9 +9705,10 @@ const machine_t machines[] = { /* Socket 7 (Single Voltage) machines */ /* 430FX */ - /* This has an AMIKey-2, which is an updated version of type 'H'. */ + /* This has an AMIKey-2, which is an updated version of type 'H'. + This also seems to be revision 2.1 with the FDC37C665 SIO. */ { - .name = "[i430FX] ASUS P/I-P54TP4XE", + .name = "[i430FX] ASUS P/I-P55TP4XE", .internal_name = "p54tp4xe", .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430FX, @@ -9727,7 +9728,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -9747,7 +9748,7 @@ const machine_t machines[] = { }, /* This has an AMIKey-2, which is an updated version of type 'H'. */ { - .name = "[i430FX] ASUS P/I-P54TP4XE (MR BIOS)", + .name = "[i430FX] ASUS P/I-P55TP4XE (MR BIOS)", .internal_name = "p54tp4xe_mr", .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430FX, @@ -9767,7 +9768,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -9785,7 +9786,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has AMIKey H KBC firmware. */ + /* Has AMIKey H KBC firmware. The KBC itself seems to differ between an AMIKEY-2 and a Winbond W83C42. */ { .name = "[i430FX] DataExpert EXP8551", .internal_name = "exp8551", @@ -9807,7 +9808,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_GAMEPORT | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -9849,7 +9850,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, .ram = { .min = 8192, .max = 131072, @@ -9890,7 +9891,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 131072, @@ -9932,7 +9933,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_GAMEPORT, .ram = { .min = 8192, .max = 131072, @@ -9974,7 +9975,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, .ram = { .min = 8192, .max = 131072, @@ -10016,7 +10017,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -10056,7 +10057,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -10097,7 +10098,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -10137,7 +10138,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -10155,7 +10156,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has an AMI 'H' KBC firmware (1992). */ + /* Has an AMI MegaKey 'H' KBC firmware (1992). */ { .name = "[i430FX] QDI FMB", .internal_name = "fmb", @@ -10177,7 +10178,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, .ram = { .min = 8192, .max = 131072, @@ -10197,9 +10198,7 @@ const machine_t machines[] = { }, /* 430HX */ - /* I can't determine what KBC firmware this has, but given that the Acer V35N and - V60 have Phoenix MultiKey KBC firmware on the chip, I'm going to assume so - does the M3A. */ + /* Has a Phoenix Multikey KBC in the SM(S)C SIO. */ { .name = "[i430HX] Acer M3A", .internal_name = "acerm3a", @@ -10221,7 +10220,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, /* Machine has internal USB and SCSI */ .ram = { .min = 8192, .max = 196608, @@ -10239,7 +10238,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has AMIKey F KBC firmware. */ + /* Has AMIKey-2 or VIA VT82C42N KBC (depending on the revision) with AMIKEY 'F' KBC firmware. */ { .name = "[i430HX] AOpen AP53", .internal_name = "ap53", @@ -10261,7 +10260,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 524288, @@ -10301,7 +10300,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ .ram = { .min = 8192, .max = 524288, @@ -10319,8 +10318,8 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* [TEST] Unable to determine what KBC this has. A list on a Danish site shows - the BIOS as having a -0 string, indicating non-AMI KBC firmware. */ + /* [TEST] The board doesn't seem to have a KBC at all, which probably means it's an on-chip one on the PC87306 SIO. + A list on a Danish site shows the BIOS as having a -0 string, indicating non-AMI KBC firmware. */ { .name = "[i430HX] Supermicro P55T2S", .internal_name = "p55t2s", @@ -10342,7 +10341,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ .ram = { .min = 8192, .max = 786432, @@ -10386,7 +10385,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ .ram = { .min = 8192, .max = 131072, @@ -10426,7 +10425,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ .ram = { .min = 8192, .max = 131072, @@ -10468,7 +10467,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, /* Machine has internal USB */ .ram = { .min = 8192, .max = 131072, @@ -10510,7 +10509,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 524288, @@ -10550,7 +10549,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 524288, @@ -10633,7 +10632,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 196608, @@ -10673,7 +10672,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 262144, @@ -10713,7 +10712,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, /* Machine has internal USB */ .ram = { .min = 8192, .max = 131072, @@ -10755,7 +10754,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, /* Has internal USB and sound: Yamaha YMF701-S */ .ram = { .min = 8192, .max = 131072, @@ -10795,7 +10794,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, /* Has internal USB and sound: Yamaha YMF701-S */ .ram = { .min = 8192, .max = 131072, @@ -10835,7 +10834,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM, /* Machine has internal USB */ .ram = { .min = 8192, .max = 196608, @@ -10875,7 +10874,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM, /* Machine has internal USB */ .ram = { .min = 8192, .max = 196608, @@ -10918,7 +10917,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 196608, @@ -10936,7 +10935,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* The base board has AMIKey-2 (updated 'H') KBC firmware. */ + /* The base board has a Holtek HT6542B with the AMIKey-2 (updated 'H') KBC firmware. */ { .name = "[i430HX] ASUS P/I-P65UP5 (C-P55T2D)", .internal_name = "p65up5_cp55t2d", @@ -10958,7 +10957,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has AMB and internal USB */ .ram = { .min = 8192, .max = 524288, @@ -10998,7 +10997,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 262144, @@ -11018,7 +11017,7 @@ const machine_t machines[] = { }, /* 430VX */ - /* This has the VIA VT82C42N KBC. */ + /* This has the VIA VT82C42N or Holtek HT6542B KBC. */ { .name = "[i430VX] AOpen AP5VM", .internal_name = "ap5vm", @@ -11040,7 +11039,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_SCSI | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_SCSI | MACHINE_APM, /* Machine has internal USB */ .ram = { .min = 8192, .max = 131072, @@ -11058,7 +11057,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has AMIKey H KBC firmware (AMIKey-2). */ + /* Has AMIKey H KBC firmware (AMIKey-2) on a BestKey KBC. */ { .name = "[i430VX] ASUS P/I-P55TVP4", .internal_name = "p55tvp4", @@ -11080,7 +11079,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has AMB and internal USB */ .ram = { .min = 8192, .max = 131072, @@ -11121,7 +11120,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ .ram = { .min = 8192, .max = 131072, @@ -11139,7 +11138,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* [TEST] Has AMIKey 'F' KBC firmware. */ + /* [TEST] Has AMIKey 'F' KBC firmware on a VIA VT82C42N KBC. */ { .name = "[i430VX] Biostar MB-8500TVX-A", .internal_name = "8500tvxa", @@ -11161,7 +11160,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ .ram = { .min = 8192, .max = 131072, @@ -11282,7 +11281,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ .ram = { .min = 8192, .max = 131072, @@ -11322,7 +11321,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -11364,7 +11363,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ .ram = { .min = 8192, .max = 131072, @@ -11404,7 +11403,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -11445,7 +11444,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ .ram = { .min = 8192, .max = 131072, @@ -11486,7 +11485,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_GAMEPORT | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_GAMEPORT | MACHINE_APM, /* Machine has internal USB */ .ram = { .min = 8192, .max = 131072, @@ -11528,7 +11527,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Has internal video: C&T B69000 */ .ram = { .min = 8192, .max = 262144, @@ -11568,7 +11567,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 262144, @@ -11608,7 +11607,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_NIC, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_NIC, /* Machine has internal USB*/ .ram = { .min = 8192, .max = 262144, @@ -11690,7 +11689,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 262144, @@ -11730,7 +11729,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, /* Machine has internal USB and sound: Yamaha YMF701-S */ .ram = { .min = 8192, .max = 262144, @@ -11748,7 +11747,8 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* The BIOS sends KBC command BB and expects it to output a byte, which is AMI KBC behavior. */ + /* The BIOS sends KBC command BB and expects it to output a byte, which is AMI KBC behavior. + A picture shows a VIA VT82C42N KBC though, so it could be a case of that KBC with AMI firmware. */ { .name = "[i430TX] PC Partner MB540N", .internal_name = "mb540n", @@ -11770,7 +11770,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 262144, @@ -11810,7 +11810,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 262144, @@ -11850,7 +11850,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 262144, @@ -11890,7 +11890,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 262144, @@ -11933,7 +11933,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 524288, @@ -11976,7 +11976,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 1048576, @@ -12018,7 +12018,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ .ram = { .min = 8192, .max = 262144, @@ -12058,7 +12058,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, /* Machine has internal USB */ .ram = { .min = 8192, .max = 262144, @@ -12098,7 +12098,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ .ram = { .min = 8192, .max = 393216, @@ -12140,7 +12140,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 1048576, @@ -12180,7 +12180,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 786432, From f018ef27889c40e54153d9d8933dc5245acdf3d5 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 31 Jan 2024 00:59:37 +0600 Subject: [PATCH 392/936] More changes --- src/video/vid_c&t_69000.c | 108 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 105 insertions(+), 3 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 5037cb1c2..5e23c0710 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -83,10 +83,68 @@ typedef struct chips_69000_t { rom_t bios_rom; void* i2c_ddc, *ddc; + + uint8_t st01; } chips_69000_t; static video_timings_t timing_sis = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 20, .read_w = 20, .read_l = 35 }; +/* Multimedia handling. */ +uint8_t +chips_69000_read_multimedia(chips_69000_t* chips) +{ + switch (chips->mm_index) { + case 0: + /* Report no playback/capture capability. */ + return 0; + default: + return chips->mm_regs[chips->mm_index]; + } + return chips->mm_regs[chips->mm_index]; +} + +/* Multimedia (write) handling. */ +void +chips_69000_write_multimedia(chips_69000_t* chips, uint8_t val) +{ + switch (chips->mm_index) { + case 0: + return; + default: + chips->mm_regs[chips->mm_index] = val; + break; + } + chips->mm_regs[chips->mm_index] = val; +} + +/* Flat panel handling. */ +uint8_t +chips_69000_read_flat_panel(chips_69000_t* chips) +{ + switch (chips->flat_panel_index) { + case 0: + /* Report no presence of flat panel module. */ + return 0; + default: + return chips->flat_panel_regs[chips->flat_panel_index]; + } + return chips->flat_panel_regs[chips->flat_panel_index]; +} + +/* Flat panel (write) handling. */ +void +chips_69000_write_flat_panel(chips_69000_t* chips, uint8_t val) +{ + switch (chips->flat_panel_index) { + case 0: + return; + default: + chips->flat_panel_regs[chips->flat_panel_index] = val; + break; + } + chips->flat_panel_regs[chips->flat_panel_index] = val; +} + void chips_69000_do_rop_8bpp(uint8_t *dst, uint8_t src, uint8_t rop) { @@ -813,6 +871,18 @@ chips_69000_out(uint16_t addr, uint8_t val, void *p) svga_out(addr, val, svga); chips_69000_recalc_banking(chips); return; +#if 1 + case 0x3D0: + chips->flat_panel_index = val; + return; + case 0x3D1: + return chips_69000_write_flat_panel(chips, val); + case 0x3D2: + chips->mm_index = val; + return; + case 0x3D3: + return chips_69000_write_multimedia(chips, val); +#endif case 0x3D4: svga->crtcreg = val & 0xff; return; @@ -850,7 +920,7 @@ chips_69000_in(uint16_t addr, void *p) { chips_69000_t *chips = (chips_69000_t *) p; svga_t *svga = &chips->svga; - uint8_t temp, index; + uint8_t temp = 0, index; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -892,6 +962,16 @@ chips_69000_in(uint16_t addr, void *p) if (svga->adv_flags & FLAG_RAMDAC_SHIFT) temp >>= 2; break; +#if 1 + case 0x3D0: + return chips->flat_panel_index; + case 0x3D1: + return chips_69000_read_flat_panel(chips); + case 0x3D2: + return chips->mm_index; + case 0x3D3: + return chips_69000_read_multimedia(chips); +#endif case 0x3D4: temp = svga->crtcreg; break; @@ -1124,6 +1204,8 @@ chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) switch (addr & 0xFFF) { case 0x00 ... 0x28: chips->bitblt_regs_b[addr & 0xFF] = val; + if ((addr & 0xFFF) == 0x023) + pclog("BitBLT/Draw operation\n"); break; case 0x600 ... 0x60F: chips->mem_regs_b[addr & 0xF] = val; @@ -1275,11 +1357,25 @@ chips_69000_writel_linear(uint32_t addr, uint32_t val, void *p) svga_writel_linear(addr & 0x1FFFFF, val, p); } +void +chips_69000_vsync_start(svga_t *svga) +{ + /* TODO: PCI interrupts for this. */ + chips_69000_t *chips = (chips_69000_t *) svga->priv; + +} + +void +chips_69000_vblank_start(svga_t *svga) +{ + chips_69000_t *chips = (chips_69000_t *) svga->priv; + /* Needed? */ +} + static void * chips_69000_init(const device_t *info) { - chips_69000_t *chips = malloc(sizeof(chips_69000_t)); - memset(chips, 0, sizeof(chips_69000_t)); + chips_69000_t *chips = calloc(1, sizeof(chips_69000_t)); /* Appears to have an odd VBIOS size. */ if (!info->local) { @@ -1302,6 +1398,8 @@ chips_69000_init(const device_t *info) chips->svga.bpp = 8; chips->svga.miscout = 1; chips->svga.recalctimings_ex = chips_69000_recalctimings; + chips->svga.vsync_callback = chips_69000_vsync_start; + chips->svga.vblank_start = chips_69000_vblank_start; mem_mapping_add(&chips->linear_mapping, 0, 0, chips_69000_readb_linear, chips_69000_readw_linear, chips_69000_readl_linear, chips_69000_writeb_linear, chips_69000_writew_linear, chips_69000_writel_linear, NULL, MEM_MAPPING_EXTERNAL, chips); @@ -1316,6 +1414,10 @@ chips_69000_init(const device_t *info) chips->i2c_ddc = i2c_gpio_init("c&t_69000_mga"); chips->ddc = ddc_init(i2c_gpio_get_bus(chips->i2c_ddc)); + + chips->flat_panel_regs[0x01] = 1; + + sizeof(chips->bitblt_regs); return chips; } From 2b0a494eded5f493240c7cdccc00709dcabfc97f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 31 Jan 2024 13:24:51 +0600 Subject: [PATCH 393/936] Report linear mapping properly --- src/video/vid_c&t_69000.c | 57 ++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 5e23c0710..9ce7f89b5 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -707,46 +707,65 @@ uint8_t chips_69000_read_ext_reg(chips_69000_t* chips) { uint8_t index = chips->ext_index; + uint8_t val = chips->ext_regs[index]; switch (index) { case 0x00: - return 0x2C; + val = 0x2C; + break; case 0x01: - return 0x10; + val = 0x10; + break; case 0x02: - return 0xC0; + val = 0xC0; + break; case 0x03: - return 0x00; + val = 0x00; + break; case 0x04: - return 0x62; + val = 0x62; + break; case 0x05: + val = 0x00; + break; case 0x06: - return 0x00; + val = chips->linear_mapping.base >> 24; + break; case 0x08: - return 0x02; + val = 0x02; + break; case 0x0A: - return chips->ext_regs[index] & 0x37; + val = chips->ext_regs[index] & 0x37; + break; case 0x63: { - uint8_t val = chips->ext_regs[index]; + val = chips->ext_regs[index]; if (!(chips->ext_regs[0x62] & 0x8)) val = (val & ~8) | (i2c_gpio_get_scl(chips->i2c_ddc) << 3); if (!(chips->ext_regs[0x62] & 0x4)) val = (val & ~4) | (i2c_gpio_get_sda(chips->i2c_ddc) << 2); - return val; + break; } case 0x70: - return 0x3; + val = 0x3; + break; case 0x71: - return 0x0; + val = 0x0; + break; } - return chips->ext_regs[index]; + //if (chips->ext_index != 0x4E && chips->ext_index != 0x4F + // && (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) + // pclog("C&T: Read ext reg 0x%02X, ret = 0x%02X\n", index, val); + return val; } void chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) { + //if (chips->ext_index != 0x4E && chips->ext_index != 0x4F + //&& (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) + // pclog("C&T: Write ext reg 0x%02X, ret = 0x%02X\n", chips->ext_index, val); switch (chips->ext_index) { case 0xA: chips->ext_regs[chips->ext_index] = val & 0x37; @@ -809,6 +828,8 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) chips->ext_regs[chips->ext_index] = val & 0x1f; svga_recalctimings(&chips->svga); break; + case 0xD2: + break; default: chips->ext_regs[chips->ext_index] = val; break; @@ -1002,11 +1023,13 @@ chips_69000_pci_read(int func, int addr, void *p) { switch (addr) { case 0x00: + return 0x2C; case 0x01: - return (0x102C >> ((addr & 1) * 8)) & 0xFF; + return 0x10; case 0x02: + return 0xC0; case 0x03: - return (0x00C0 >> ((addr & 1) * 8)) & 0xFF; + return 0x00; case 0x04: return chips->pci_conf_status; case 0x07: @@ -1074,6 +1097,10 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) } case 0x13: { + if (!(chips->pci_conf_status & PCI_COMMAND_MEM)) { + chips->linear_mapping.base = val << 24; + break; + } mem_mapping_set_addr(&chips->linear_mapping, val << 24, (1 << 24)); break; } From 4ef6aa8b64db50cad107b672d343e8f4253723ab Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Wed, 31 Jan 2024 10:36:45 +0300 Subject: [PATCH 394/936] Machine flag cleanups round 7: Super 7, Socket 8, Slot 1/2 and Socket 370 --- src/machine/machine_table.c | 155 ++++++++++++++++++------------------ 1 file changed, 76 insertions(+), 79 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 4c1881c1b..cf727380c 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -11323,7 +11323,7 @@ const machine_t machines[] = { .bus_flags = MACHINE_PS2_PCI, .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { - .min = 8192, + .min = 16384, .max = 131072, .step = 8192 }, @@ -12223,7 +12223,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, /* Machine has internal USB */ .ram = { .min = 1024, .max = 1572864, @@ -12264,7 +12264,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 1024, .max = 1572864, @@ -12304,7 +12304,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_PCIONLY, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, /* Has internal USB, video: ATI 3D Rage Pro Turbo AGP and sound: Ensoniq ES1373*/ .ram = { .min = 8192, .max = 262144, @@ -12318,8 +12318,8 @@ const machine_t machines[] = { .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, // rage - .snd_device = NULL, // es1373 + .vid_device = NULL, + .snd_device = NULL, .net_device = NULL }, /* Has the ALi M1543C southbridge with on-chip KBC. */ @@ -12344,7 +12344,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 1024, .max = 1572864, @@ -12384,7 +12384,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 1024, .max = 1572864, @@ -12427,7 +12427,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 1048576, @@ -12468,7 +12468,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 1048576, @@ -12509,7 +12509,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_A97, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, /* Machine has internal USB */ .ram = { .min = 8192, .max = 786432, @@ -12550,7 +12550,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 786432, @@ -12593,7 +12593,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 524288, @@ -12632,8 +12632,8 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .bus_flags = MACHINE_PS2_PCI, /* Machine has AMB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 524288, @@ -12675,7 +12675,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ .ram = { .min = 8192, .max = 524288, @@ -12693,7 +12693,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* The base board has AMIKey-2 (updated 'H') KBC firmware. */ + /* The base board hasa Holtek HT6542B with AMIKey-2 (updated 'H') KBC firmware. */ { .name = "[i440FX] ASUS P/I-P65UP5 (C-P6ND)", .internal_name = "p65up5_cp6nd", @@ -12714,8 +12714,8 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .bus_flags = MACHINE_PS2_PCI, /* Machine has AMB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ .ram = { .min = 8192, .max = 1048576, @@ -12733,8 +12733,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* The MB-8600TTX has an AMIKey 'F' KBC firmware, so I'm going to assume so does - the MB-8600TTC until someone can actually identify it. */ + /* Has a VIA VT82C42N with likely AMIKey 'F' KBC firmware. */ { .name = "[i440FX] Biostar MB-8600TTC", .internal_name = "8600ttc", @@ -12756,7 +12755,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ .ram = { .min = 8192, .max = 1048576, @@ -12796,7 +12795,7 @@ const machine_t machines[] = { .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, /* Machine has internal USB */ .ram = { .min = 8192, .max = 524288, @@ -12836,7 +12835,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ .ram = { .min = 8192, .max = 524288, @@ -12878,7 +12877,7 @@ const machine_t machines[] = { .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB, video: S3 ViRGE/DX and sound: Crystal CS4236B */ .ram = { .min = 8192, .max = 131072, @@ -12920,7 +12919,7 @@ const machine_t machines[] = { .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, /* Machine has internal USB */ .ram = { .min = 8192, .max = 524288, @@ -12960,7 +12959,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB and SCSI: Adaptec AIC-78xx */ .ram = { .min = 40960, .max = 524288, @@ -13000,7 +12999,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, /* Machine has internal USB */ .ram = { .min = 8192, .max = 786432, @@ -13018,9 +13017,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* I found a BIOS string of it that ends in -S, but it could be a typo for -5 - (there's quite a few AMI BIOS strings around with typo'd KBC codes), so I'm - going to give it an AMI MegaKey. */ + /* Has a VIA VT82C42N KBC with likely AMI MegaKey firmware. */ { .name = "[i440FX] PC Partner MB600N", .internal_name = "mb600n", @@ -13042,7 +13039,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ .ram = { .min = 8192, .max = 524288, @@ -13085,7 +13082,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, /* Machine has internal USB and sound: C-Media CMI8330 */ .ram = { .min = 1024, .max = 1572864, @@ -13105,7 +13102,7 @@ const machine_t machines[] = { }, /* 440FX */ - /* The base board has AMIKey-2 (updated 'H') KBC firmware. */ + /* The base board has a Holtek HT6542B KBC with AMIKey-2 (updated 'H') KBC firmware. */ { .name = "[i440FX] ASUS P/I-P65UP5 (C-PKND)", .internal_name = "p65up5_cpknd", @@ -13127,7 +13124,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ .ram = { .min = 8192, .max = 1048576, @@ -13168,7 +13165,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ .ram = { .min = 8192, .max = 786432, @@ -13211,7 +13208,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 1048576, @@ -13252,7 +13249,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 1048576, @@ -13293,7 +13290,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 786432, @@ -13336,7 +13333,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 524288, @@ -13379,7 +13376,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB and SCSI: Adaptec AIC-7890AB */ .ram = { .min = 8192, .max = 1048576, @@ -13420,7 +13417,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 1048576, @@ -13461,7 +13458,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 786432, @@ -13502,7 +13499,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 786432, @@ -13543,7 +13540,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 1048576, @@ -13584,7 +13581,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, /* Machine has internal USB, video: Matrox MGA-G200 and sound: Crystal CS4820 */ .ram = { .min = 8192, .max = 1048576, @@ -13602,7 +13599,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has the AMIKey-2 (updated 'H') KBC firmware. */ + /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 (updated 'H') KBC firmware. */ { .name = "[i440BX] LG IBM Multinet i x7G (MSI MS-6119)", .internal_name = "lgibmx7g", @@ -13624,7 +13621,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 786432, @@ -13665,7 +13662,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB and sound: Ensoniq ES1373 */ .ram = { .min = 8192, .max = 1048576, @@ -13706,7 +13703,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 786432, @@ -13748,8 +13745,8 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_AV | MACHINE_APM | MACHINE_ACPI, + .bus_flags = MACHINE_PS2_AGP, /* AGP is reserved for the internal video */ + .flags = MACHINE_IDE_DUAL | MACHINE_AV | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 524288, @@ -13789,8 +13786,8 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_AV | MACHINE_APM | MACHINE_ACPI, + .bus_flags = MACHINE_PS2_AGP, /* AGP is reserved for the internal video */ + .flags = MACHINE_IDE_DUAL | MACHINE_AV | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 524288, @@ -13813,7 +13810,7 @@ const machine_t machines[] = { /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ { - .name = "[SMSC VictoryBX-66] A-Trend ATC6310BXII", + .name = "[SMSC VictoryBX-66] A-Trend ATC-6310BXII", .internal_name = "atc6310bxii", .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_SMSC_VICTORYBX_66, @@ -13833,7 +13830,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 786432, @@ -13876,7 +13873,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, /* Machine has internal USB and sound: ESS ES1938S */ .ram = { .min = 8192, .max = 524288, @@ -13917,7 +13914,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 1572864, @@ -13958,7 +13955,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 2097152, @@ -13999,7 +13996,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, /* Machine has internal USB and sound: Ensoniq ES1373 */ .ram = { .min = 8192, .max = 3145728, @@ -14043,7 +14040,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_NOISA, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 16384, .max = 2097152, @@ -14087,7 +14084,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 786432, @@ -14129,7 +14126,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 786432, @@ -14173,7 +14170,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB and SCSI */ .ram = { .min = 16384, .max = 2097152, @@ -14214,7 +14211,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 16384, .max = 2097152, @@ -14258,7 +14255,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED, }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 786432, @@ -14300,8 +14297,8 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 /* limits assumed */ }, - .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .bus_flags = MACHINE_PS2_PCI, /* Machine has EISA, possibly for a riser? */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB, video: C&T B69000, sound: ESS ES1938S and NIC: Realtek RTL8139C */ .ram = { .min = 8192, .max = 524288, @@ -14342,7 +14339,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has USB and quad channel IDE with CMD PCI-0648 */ .ram = { .min = 8192, .max = 1048576, @@ -14383,7 +14380,7 @@ const machine_t machines[] = { .max_multi = 8.0 /* limits assumed */ }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 786432, @@ -14426,7 +14423,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 524288, @@ -14449,7 +14446,7 @@ const machine_t machines[] = { /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ { - .name = "[SMSC VictoryBX-66] A-Trend ATC7020BXII", + .name = "[SMSC VictoryBX-66] A-Trend ATC-7020BXII", .internal_name = "atc7020bxii", .type = MACHINE_TYPE_SOCKET370, .chipset = MACHINE_CHIPSET_SMSC_VICTORYBX_66, @@ -14469,7 +14466,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 1048576, @@ -14510,7 +14507,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, /* Machine has internal USB */ .ram = { .min = 8192, .max = 524288, @@ -14553,7 +14550,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ .ram = { .min = 8192, .max = 786432, @@ -14594,7 +14591,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, /* Machine has internal USB and sound: C-Media CMI8738 */ .ram = { .min = 8192, .max = 1572864, @@ -14635,7 +14632,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED }, .bus_flags = MACHINE_PS2_A97, - .flags = MACHINE_IDE_DUAL | MACHINE_AG | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_AG | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, /* Machine has internal USB */ .ram = { .min = 16384, .max = 3145728, @@ -14675,8 +14672,8 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_NOI97, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI, + .bus_flags = MACHINE_PS2_NOI97, /* Has Asus-proprietary LAN/SCSI slot */ + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, .ram = { .min = 16384, .max = 4194304, From 80eb454c8a756c5c75b9163ddd1c8325d8529165 Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Wed, 31 Jan 2024 13:09:34 +0300 Subject: [PATCH 395/936] Machine flag cleanups round 8: Actually add the USB flags --- src/machine/m_at_socket370.c | 3 + src/machine/machine_table.c | 196 +++++++++++++++++------------------ 2 files changed, 101 insertions(+), 98 deletions(-) diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index 2b2615422..4164b425a 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -141,6 +141,9 @@ machine_at_p6bap_init(const machine_t *model) device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); + if (sound_card_current[0] == SOUND_INTERNAL) + device_add(&cmi8738_onboard_device); + return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index cf727380c..519fc37b6 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -9891,7 +9891,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -10220,7 +10220,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, /* Machine has internal USB and SCSI */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal SCSI */ .ram = { .min = 8192, .max = 196608, @@ -10300,7 +10300,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -10341,7 +10341,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -10385,7 +10385,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -10425,7 +10425,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -10467,7 +10467,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -10712,7 +10712,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -10754,7 +10754,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, /* Has internal USB and sound: Yamaha YMF701-S */ + .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, /* Has internal sound: Yamaha YMF701-S */ .ram = { .min = 8192, .max = 131072, @@ -10794,7 +10794,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, /* Has internal USB and sound: Yamaha YMF701-S */ + .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, /* Has internal sound: Yamaha YMF701-S */ .ram = { .min = 8192, .max = 131072, @@ -10834,7 +10834,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 196608, @@ -10874,7 +10874,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 196608, @@ -10956,8 +10956,8 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has AMB and internal USB */ + .bus_flags = MACHINE_PS2_PCI, /* Machine has AMB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -11039,7 +11039,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_SCSI | MACHINE_APM, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_SCSI | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -11078,8 +11078,8 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has AMB and internal USB */ + .bus_flags = MACHINE_PS2_PCI, /* Machine has AMB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -11120,7 +11120,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -11160,7 +11160,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -11281,7 +11281,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -11363,7 +11363,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ + .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -11444,7 +11444,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -11485,7 +11485,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_GAMEPORT | MACHINE_APM, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_GAMEPORT | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -11567,7 +11567,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 262144, @@ -11607,7 +11607,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_NIC, /* Machine has internal USB*/ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_NIC | MACHINE_USB, .ram = { .min = 8192, .max = 262144, @@ -11689,7 +11689,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 262144, @@ -11729,7 +11729,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, /* Machine has internal USB and sound: Yamaha YMF701-S */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: Yamaha YMF701-S */ .ram = { .min = 8192, .max = 262144, @@ -11770,7 +11770,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 262144, @@ -11810,7 +11810,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 262144, @@ -11850,7 +11850,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 262144, @@ -11890,7 +11890,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 262144, @@ -11933,7 +11933,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -11976,7 +11976,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -12018,7 +12018,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 262144, @@ -12058,7 +12058,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, .max = 262144, @@ -12098,7 +12098,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 393216, @@ -12140,7 +12140,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -12180,7 +12180,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -12223,7 +12223,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 1024, .max = 1572864, @@ -12264,7 +12264,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 1024, .max = 1572864, @@ -12304,7 +12304,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_PCIONLY, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, /* Has internal USB, video: ATI 3D Rage Pro Turbo AGP and sound: Ensoniq ES1373*/ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Has internal video: ATI 3D Rage Pro Turbo AGP and sound: Ensoniq ES1373*/ .ram = { .min = 8192, .max = 262144, @@ -12344,7 +12344,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 1024, .max = 1572864, @@ -12384,7 +12384,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 1024, .max = 1572864, @@ -12427,7 +12427,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -12468,7 +12468,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -12509,7 +12509,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_A97, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -12550,7 +12550,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -12675,7 +12675,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -12715,7 +12715,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_PCI, /* Machine has AMB */ - .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -12755,7 +12755,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -12795,7 +12795,7 @@ const machine_t machines[] = { .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -12835,7 +12835,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -12877,7 +12877,7 @@ const machine_t machines[] = { .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB, video: S3 ViRGE/DX and sound: Crystal CS4236B */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, /* Machine has internal video: S3 ViRGE/DX and sound: Crystal CS4236B */ .ram = { .min = 8192, .max = 131072, @@ -12919,7 +12919,7 @@ const machine_t machines[] = { .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -12959,7 +12959,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB and SCSI: Adaptec AIC-78xx */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, /* Machine has internal SCSI: Adaptec AIC-78xx */ .ram = { .min = 40960, .max = 524288, @@ -12999,7 +12999,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -13039,7 +13039,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -13082,7 +13082,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, /* Machine has internal USB and sound: C-Media CMI8330 */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: C-Media CMI8330 */ .ram = { .min = 1024, .max = 1572864, @@ -13124,7 +13124,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -13165,7 +13165,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -13208,7 +13208,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -13249,7 +13249,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -13290,7 +13290,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -13333,7 +13333,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -13376,7 +13376,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB and SCSI: Adaptec AIC-7890AB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal SCSI: Adaptec AIC-7890AB */ .ram = { .min = 8192, .max = 1048576, @@ -13417,7 +13417,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -13458,7 +13458,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -13499,7 +13499,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -13540,7 +13540,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -13581,7 +13581,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, /* Machine has internal USB, video: Matrox MGA-G200 and sound: Crystal CS4820 */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal video: Matrox MGA-G200 and sound: Crystal CS4820 */ .ram = { .min = 8192, .max = 1048576, @@ -13621,7 +13621,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -13662,7 +13662,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB and sound: Ensoniq ES1373 */ + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal sound: Ensoniq ES1373 */ .ram = { .min = 8192, .max = 1048576, @@ -13703,7 +13703,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -13746,7 +13746,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, /* AGP is reserved for the internal video */ - .flags = MACHINE_IDE_DUAL | MACHINE_AV | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_AV | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -13787,7 +13787,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, /* AGP is reserved for the internal video */ - .flags = MACHINE_IDE_DUAL | MACHINE_AV | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_AV | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -13830,7 +13830,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -13873,7 +13873,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, /* Machine has internal USB and sound: ESS ES1938S */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: ESS ES1938S */ .ram = { .min = 8192, .max = 524288, @@ -13914,7 +13914,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1572864, @@ -13955,7 +13955,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 2097152, @@ -13996,7 +13996,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, /* Machine has internal USB and sound: Ensoniq ES1373 */ + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: Ensoniq ES1373 */ .ram = { .min = 8192, .max = 3145728, @@ -14040,7 +14040,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_NOISA, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 16384, .max = 2097152, @@ -14084,7 +14084,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -14126,7 +14126,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -14170,7 +14170,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB and SCSI */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal SCSI */ .ram = { .min = 16384, .max = 2097152, @@ -14211,7 +14211,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 16384, .max = 2097152, @@ -14255,7 +14255,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED, }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -14298,7 +14298,7 @@ const machine_t machines[] = { .max_multi = 8.0 /* limits assumed */ }, .bus_flags = MACHINE_PS2_PCI, /* Machine has EISA, possibly for a riser? */ - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB, video: C&T B69000, sound: ESS ES1938S and NIC: Realtek RTL8139C */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal video: C&T B69000, sound: ESS ES1938S and NIC: Realtek RTL8139C */ .ram = { .min = 8192, .max = 524288, @@ -14339,7 +14339,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has USB and quad channel IDE with CMD PCI-0648 */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has quad channel IDE with internal controller: CMD PCI-0648 */ .ram = { .min = 8192, .max = 1048576, @@ -14380,7 +14380,7 @@ const machine_t machines[] = { .max_multi = 8.0 /* limits assumed */ }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -14423,7 +14423,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -14466,7 +14466,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -14507,7 +14507,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -14550,7 +14550,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -14591,7 +14591,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, /* Machine has internal USB and sound: C-Media CMI8738 */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB | MACHINE_SOUND, .ram = { .min = 8192, .max = 1572864, @@ -14606,7 +14606,7 @@ const machine_t machines[] = { .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, - .snd_device = NULL, + .snd_device = &cmi8738_onboard_device, .net_device = NULL }, /* Has the VIA VT82C686B southbridge with on-chip KBC identical to the VIA @@ -14632,7 +14632,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED }, .bus_flags = MACHINE_PS2_A97, - .flags = MACHINE_IDE_DUAL | MACHINE_AG | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, /* Machine has internal USB */ + .flags = MACHINE_IDE_DUAL | MACHINE_AG | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 16384, .max = 3145728, @@ -14673,7 +14673,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_NOI97, /* Has Asus-proprietary LAN/SCSI slot */ - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 16384, .max = 4194304, @@ -14716,7 +14716,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, From a9b3fdd945dd6aa9be691bff9aa7ebfa815f2eb6 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 31 Jan 2024 16:34:34 +0600 Subject: [PATCH 396/936] BitBLT work --- src/video/vid_c&t_69000.c | 274 +++++++++++++++++++------------------- 1 file changed, 138 insertions(+), 136 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 9ce7f89b5..cab0f0f21 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -36,10 +36,55 @@ #include <86box/vid_ddc.h> #include +#pragma pack(push, 1) +typedef struct chips_69000_bitblt_t +{ + /* BR00 - Source and Destination Span Register. */ + uint16_t source_span; + uint16_t destination_span; + + /* BR01 - Pattern/Source Expansion Background Color & Transparency Key Register. */ + uint32_t pattern_source_key_bg; + + /* BR02 - Pattern/Source Expansion Foreground Color Register. */ + uint32_t pattern_source_key_fg; + + /* BR03 - Monochrome Source Control Register. */ + uint8_t monochrome_source_left_clip; + uint8_t monochrome_source_right_clip; + uint8_t monochrome_source_initial_discard; + uint8_t monochrome_source_alignment : 3; + uint8_t monochrome_source_expansion_color_reg_select : 1; + uint8_t dummy_8 : 4; + + /* BR04 - BitBLT Control Register. */ + uint32_t bitblt_control; + + /* BR05 - Pattern Address Register. */ + uint32_t pat_addr; + + /* BR06 - Source Address Register. */ + uint32_t source_addr; + + /* BR07 - Destination Address Register. */ + uint32_t destination_addr; + + /* BR08 - Destination Width & Height Register. */ + uint16_t destination_width; + uint16_t destination_height; + + /* BR09 - Source Expansion Background Color & Transparency Key Register. */ + uint32_t source_key_bg; + + /* BR0A - Source Expansion Foreground Color Register. */ + uint32_t source_key_fg; +}; +#pragma pack(pop) + typedef struct chips_69000_t { svga_t svga; uint8_t pci_conf_status; - uint8_t slot; + uint8_t slot, irq_state; uint8_t pci_line_interrupt; uint8_t pci_rom_enable; uint8_t read_write_bank; @@ -65,11 +110,21 @@ typedef struct chips_69000_t { uint8_t mem_regs_b[4 * 4]; }; union { - uint32_t bitblt_regs[16]; - uint16_t bitblt_regs_w[16 * 2]; - uint8_t bitblt_regs_b[16 * 4]; + uint32_t bitblt_regs[11]; + uint16_t bitblt_regs_w[11 * 2]; + uint8_t bitblt_regs_b[11 * 4]; + struct chips_69000_bitblt_t bitblt; }; + struct + { + struct chips_69000_bitblt_t bitblt; + + uint32_t actual_source_height; + uint32_t actual_destination_height; + uint8_t bytes_per_pixel; + } bitblt_running; + union { uint16_t subsys_vid; uint8_t subsys_vid_b[2]; @@ -145,6 +200,20 @@ chips_69000_write_flat_panel(chips_69000_t* chips, uint8_t val) chips->flat_panel_regs[chips->flat_panel_index] = val; } +void +chips_69000_interrupt(chips_69000_t* chips) +{ + pci_irq(chips->slot, PCI_INTA, 0, !!((chips->mem_regs[0] & chips->mem_regs[1]) & 0x80004040), &chips->irq_state); +} + +void +chips_69000_bitblt_interrupt(chips_69000_t* chips) +{ + chips->mem_regs[1] |= 1 << 31; + + chips_69000_interrupt(chips); +} + void chips_69000_do_rop_8bpp(uint8_t *dst, uint8_t src, uint8_t rop) { @@ -199,63 +268,6 @@ chips_69000_do_rop_8bpp(uint8_t *dst, uint8_t src, uint8_t rop) } } -void -chips_69000_do_rop_15bpp(uint16_t *dst, uint16_t src, uint8_t rop) -{ - uint16_t orig_dst = *dst & 0x8000; - switch (rop) { - case 0x00: - *dst = 0; - break; - case 0x11: - *dst = ~(*dst) & ~src; - break; - case 0x22: - *dst &= ~src; - break; - case 0x33: - *dst = ~src; - break; - case 0x44: - *dst = src & ~(*dst); - break; - case 0x55: - *dst = ~*dst; - break; - case 0x66: - *dst ^= src; - break; - case 0x77: - *dst = ~src | ~(*dst); - break; - case 0x88: - *dst &= src; - break; - case 0x99: - *dst ^= ~src; - break; - case 0xAA: - break; /* No-op. */ - case 0xBB: - *dst |= ~src; - break; - case 0xCC: - *dst = src; - break; - case 0xDD: - *dst = src | ~(*dst); - break; - case 0xEE: - *dst |= src; - break; - case 0xFF: - *dst = ~0; - break; - } - *dst &= 0x7FFF; - *dst |= orig_dst; -} - void chips_69000_do_rop_16bpp(uint16_t *dst, uint16_t src, uint8_t rop) { @@ -424,66 +436,6 @@ chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t src, uint8_t nonpattern_ } } -void -chips_69000_do_rop_15bpp_patterned(uint16_t *dst, uint16_t src, uint8_t nonpattern_src, uint8_t rop) -{ - uint16_t orig_dst = *dst & 0x8000; - switch (rop) { - case 0x00: - *dst = 0; - break; - case 0x05: - *dst = ~(*dst) & ~src; - break; - case 0x0A: - *dst &= ~src; - break; - case 0x0F: - *dst = ~src; - break; - case 0x50: - *dst = src & ~(*dst); - break; - case 0x55: - *dst = ~*dst; - break; - case 0x5A: - *dst ^= src; - break; - case 0x5F: - *dst = ~src | ~(*dst); - break; - case 0xB8: - *dst = (((src ^ *dst) & nonpattern_src) ^ src); - break; - case 0xA0: - *dst &= src; - break; - case 0xA5: - *dst ^= ~src; - break; - case 0xAA: - break; /* No-op. */ - case 0xAF: - *dst |= ~src; - break; - case 0xF0: - *dst = src; - break; - case 0xF5: - *dst = src | ~(*dst); - break; - case 0xFA: - *dst |= src; - break; - case 0xFF: - *dst = 0xFF; - break; - } - *dst &= 0x7FFF; - *dst |= orig_dst; -} - void chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint8_t nonpattern_src, uint8_t rop) { @@ -703,6 +655,24 @@ chips_69000_recalc_banking(chips_69000_t *chips) }*/ } +void +chips_69000_setup_bitblt(chips_69000_t* chips) +{ + chips->engine_active = 1; + chips->bitblt_running.bitblt = chips->bitblt; + chips->bitblt_running.actual_source_height = chips->bitblt.destination_height; + chips->bitblt_running.actual_destination_height = chips->bitblt.destination_height; + + if (!chips->bitblt_running.actual_destination_height) { + chips->bitblt_running.actual_destination_height = 1; + } + + + /*Stubbed!*/ + chips->engine_active = 0; + chips_69000_bitblt_interrupt(chips); +} + uint8_t chips_69000_read_ext_reg(chips_69000_t* chips) { @@ -736,6 +706,11 @@ chips_69000_read_ext_reg(chips_69000_t* chips) case 0x0A: val = chips->ext_regs[index] & 0x37; break; + case 0x20: + val &= ~1; + val |= !!(chips->bitblt.bitblt_control & (1 << 31)); + /* TODO: Handle BitBLT reset, if required. */ + break; case 0x63: { val = chips->ext_regs[index]; @@ -983,7 +958,6 @@ chips_69000_in(uint16_t addr, void *p) if (svga->adv_flags & FLAG_RAMDAC_SHIFT) temp >>= 2; break; -#if 1 case 0x3D0: return chips->flat_panel_index; case 0x3D1: @@ -992,7 +966,6 @@ chips_69000_in(uint16_t addr, void *p) return chips->mm_index; case 0x3D3: return chips_69000_read_multimedia(chips); -#endif case 0x3D4: temp = svga->crtcreg; break; @@ -1146,6 +1119,7 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) uint8_t chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) { + addr &= 0xFFF; switch (addr & 0xFFF) { case 0x00 ... 0x28: return chips->bitblt_regs_b[addr & 0xFF]; @@ -1208,6 +1182,7 @@ chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) uint16_t chips_69000_readw_mmio(uint32_t addr, chips_69000_t* chips) { + addr &= 0xFFF; switch (addr & 0xFFF) { default: return chips_69000_readb_mmio(addr, chips) | (chips_69000_readb_mmio(addr + 1, chips) << 8); @@ -1218,6 +1193,7 @@ chips_69000_readw_mmio(uint32_t addr, chips_69000_t* chips) uint32_t chips_69000_readl_mmio(uint32_t addr, chips_69000_t* chips) { + addr &= 0xFFF; switch (addr & 0xFFF) { default: return chips_69000_readw_mmio(addr, chips) | (chips_69000_readw_mmio(addr + 2, chips) << 16); @@ -1228,13 +1204,44 @@ chips_69000_readl_mmio(uint32_t addr, chips_69000_t* chips) void chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) { + addr &= 0xFFF; switch (addr & 0xFFF) { case 0x00 ... 0x28: chips->bitblt_regs_b[addr & 0xFF] = val; - if ((addr & 0xFFF) == 0x023) - pclog("BitBLT/Draw operation\n"); + if ((addr & 0xFFF) == 0x023) { + uint8_t cntr = 0; + pclog("BitBLT/Draw operation %hd\n", (uint8_t)cntr++); + chips_69000_setup_bitblt(chips); + } break; case 0x600 ... 0x60F: + switch (addr & 0xFFF) + { + case 0x600 ... 0x603: + { + chips->mem_regs_b[addr & 0xF] = val; + chips->mem_regs[addr >> 2] &= 0x80004040; + if (addr == 0x605 || addr == 0x607) + chips_69000_interrupt(chips); + break; + } + + case 0x604 ... 0x607: + { + chips->mem_regs_b[addr & 0xF] &= ~val; + chips->mem_regs[addr >> 2] &= 0x80004040; + if (addr == 0x605 || addr == 0x607) + chips_69000_interrupt(chips); + break; + } + + case 0x60c ... 0x60f: + { + chips->mem_regs_b[addr & 0xF] = val; + break; + } + + } chips->mem_regs_b[addr & 0xF] = val; break; case 0x768: @@ -1293,6 +1300,7 @@ chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) void chips_69000_writew_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) { + addr &= 0xFFF; switch (addr & 0xFFF) { default: chips_69000_writeb_mmio(addr, val, chips); @@ -1304,6 +1312,7 @@ chips_69000_writew_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) void chips_69000_writel_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) { + addr &= 0xFFF; switch (addr & 0xFFF) { default: chips_69000_writew_mmio(addr, val, chips); @@ -1384,19 +1393,13 @@ chips_69000_writel_linear(uint32_t addr, uint32_t val, void *p) svga_writel_linear(addr & 0x1FFFFF, val, p); } -void -chips_69000_vsync_start(svga_t *svga) -{ - /* TODO: PCI interrupts for this. */ - chips_69000_t *chips = (chips_69000_t *) svga->priv; - -} - void chips_69000_vblank_start(svga_t *svga) { chips_69000_t *chips = (chips_69000_t *) svga->priv; - /* Needed? */ + chips->mem_regs[1] |= 1 << 14; + + chips_69000_interrupt(chips); } static void * @@ -1425,7 +1428,6 @@ chips_69000_init(const device_t *info) chips->svga.bpp = 8; chips->svga.miscout = 1; chips->svga.recalctimings_ex = chips_69000_recalctimings; - chips->svga.vsync_callback = chips_69000_vsync_start; chips->svga.vblank_start = chips_69000_vblank_start; mem_mapping_add(&chips->linear_mapping, 0, 0, chips_69000_readb_linear, chips_69000_readw_linear, chips_69000_readl_linear, chips_69000_writeb_linear, chips_69000_writew_linear, chips_69000_writel_linear, NULL, MEM_MAPPING_EXTERNAL, chips); @@ -1444,7 +1446,7 @@ chips_69000_init(const device_t *info) chips->flat_panel_regs[0x01] = 1; - sizeof(chips->bitblt_regs); + sizeof(struct chips_69000_bitblt_t); return chips; } From 2b6cf4846c4ba36c41e9b14198043366ef881c25 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 1 Feb 2024 01:53:17 +0600 Subject: [PATCH 397/936] No more nonsense getting DWORD-written --- src/video/vid_c&t_69000.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index cab0f0f21..bc660283e 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -729,18 +729,18 @@ chips_69000_read_ext_reg(chips_69000_t* chips) val = 0x0; break; } - //if (chips->ext_index != 0x4E && chips->ext_index != 0x4F - // && (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) - // pclog("C&T: Read ext reg 0x%02X, ret = 0x%02X\n", index, val); + if (chips->ext_index != 0x4E && chips->ext_index != 0x4F + && (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) + pclog("C&T: Read ext reg 0x%02X, ret = 0x%02X\n", index, val); return val; } void chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) { - //if (chips->ext_index != 0x4E && chips->ext_index != 0x4F - //&& (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) - // pclog("C&T: Write ext reg 0x%02X, ret = 0x%02X\n", chips->ext_index, val); + if (chips->ext_index != 0x4E && chips->ext_index != 0x4F + && (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) + pclog("C&T: Write ext reg 0x%02X, ret = 0x%02X\n", chips->ext_index, val); switch (chips->ext_index) { case 0xA: chips->ext_regs[chips->ext_index] = val & 0x37; @@ -1119,6 +1119,7 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) uint8_t chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) { + pclog("C&T Read 0x%X\n", addr); addr &= 0xFFF; switch (addr & 0xFFF) { case 0x00 ... 0x28: @@ -1204,6 +1205,7 @@ chips_69000_readl_mmio(uint32_t addr, chips_69000_t* chips) void chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) { + pclog("C&T Write 0x%X, val = 0x%02X\n", addr, val); addr &= 0xFFF; switch (addr & 0xFFF) { case 0x00 ... 0x28: @@ -1310,7 +1312,7 @@ chips_69000_writew_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) } void -chips_69000_writel_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) +chips_69000_writel_mmio(uint32_t addr, uint32_t val, chips_69000_t* chips) { addr &= 0xFFF; switch (addr & 0xFFF) { From 9235a1020f006911a7e26296ad584b8f65bde71d Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Wed, 31 Jan 2024 23:13:14 +0300 Subject: [PATCH 398/936] Rename "Phoenix 286 clone" as the machine has been identified --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 519fc37b6..b7af1c79d 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -3361,7 +3361,7 @@ const machine_t machines[] = { }, /* Has IBM AT KBC firmware. */ { - .name = "[NEAT] Phoenix 286 clone", + .name = "[NEAT] Arche AMA-2010", .internal_name = "px286", .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_NEAT, From 79d38a52beca65a445a383e376804c7122011c82 Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Wed, 31 Jan 2024 23:16:10 +0300 Subject: [PATCH 399/936] Fix small comment typo --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index b7af1c79d..eefeea72f 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -12693,7 +12693,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* The base board hasa Holtek HT6542B with AMIKey-2 (updated 'H') KBC firmware. */ + /* The base board has a Holtek HT6542B with AMIKey-2 (updated 'H') KBC firmware. */ { .name = "[i440FX] ASUS P/I-P65UP5 (C-P6ND)", .internal_name = "p65up5_cp6nd", From 10de00c984d32f544f33e25c66c1b751aa416746 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 1 Feb 2024 15:19:23 +0600 Subject: [PATCH 400/936] BitBlt works, but improperly --- src/video/vid_c&t_69000.c | 232 +++++++++++++++++++++++++++++++++++--- 1 file changed, 216 insertions(+), 16 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index bc660283e..fde218ed8 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -78,7 +78,7 @@ typedef struct chips_69000_bitblt_t /* BR0A - Source Expansion Foreground Color Register. */ uint32_t source_key_fg; -}; +} chips_69000_bitblt_t; #pragma pack(pop) typedef struct chips_69000_t { @@ -122,6 +122,13 @@ typedef struct chips_69000_t { uint32_t actual_source_height; uint32_t actual_destination_height; + + uint32_t actual_destination_width; + + uint32_t count_x, count_y; + uint32_t x, y; + int x_dir, y_dir; + uint8_t bytes_per_pixel; } bitblt_running; @@ -144,6 +151,13 @@ typedef struct chips_69000_t { static video_timings_t timing_sis = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 20, .read_w = 20, .read_l = 35 }; +uint8_t chips_69000_readb_linear(uint32_t addr, void *p); +uint16_t chips_69000_readw_linear(uint32_t addr, void *p); +uint32_t chips_69000_readl_linear(uint32_t addr, void *p); +void chips_69000_writeb_linear(uint32_t addr, uint8_t val, void *p); +void chips_69000_writew_linear(uint32_t addr, uint16_t val, void *p); +void chips_69000_writel_linear(uint32_t addr, uint32_t val, void *p); + /* Multimedia handling. */ uint8_t chips_69000_read_multimedia(chips_69000_t* chips) @@ -209,6 +223,7 @@ chips_69000_interrupt(chips_69000_t* chips) void chips_69000_bitblt_interrupt(chips_69000_t* chips) { + chips->engine_active = 0; chips->mem_regs[1] |= 1 << 31; chips_69000_interrupt(chips); @@ -382,6 +397,10 @@ chips_69000_do_rop_24bpp(uint32_t *dst, uint32_t src, uint8_t rop) void chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t src, uint8_t nonpattern_src, uint8_t rop) { + if ((rop & 0xF) == ((rop >> 4) & 0xF)) { + return chips_69000_do_rop_8bpp(dst, nonpattern_src, rop); + } + switch (rop) { case 0x00: *dst = 0; @@ -439,6 +458,10 @@ chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t src, uint8_t nonpattern_ void chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint8_t nonpattern_src, uint8_t rop) { + if ((rop & 0xF) == ((rop >> 4) & 0xF)) { + return chips_69000_do_rop_16bpp(dst, nonpattern_src, rop); + } + switch (rop) { case 0x00: *dst = 0; @@ -497,6 +520,11 @@ void chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t src, uint8_t nonpattern_src, uint8_t rop) { uint32_t orig_dst = *dst & 0xFF000000; + + if ((rop & 0xF) == ((rop >> 4) & 0xF)) { + return chips_69000_do_rop_24bpp(dst, nonpattern_src, rop); + } + switch (rop) { case 0x00: *dst = 0; @@ -655,6 +683,99 @@ chips_69000_recalc_banking(chips_69000_t *chips) }*/ } +void +chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) +{ + uint32_t pattern_fg = chips->bitblt_running.bitblt.pattern_source_key_fg; + uint32_t pattern_bg = chips->bitblt_running.bitblt.pattern_source_key_bg; + uint8_t pattern_data = 0; + uint8_t pattern_data_8bpp[8][8]; + uint16_t pattern_data_16bpp[8][8]; + uint32_t pattern_pixel = 0; + uint32_t dest_pixel = 0; + uint32_t dest_addr = chips->bitblt_running.bitblt.destination_addr + (chips->bitblt_running.y * chips->bitblt.destination_span) + (chips->bitblt_running.x * chips->bitblt_running.bytes_per_pixel); + uint8_t vert_pat_alignment = (chips->bitblt_running.bitblt.bitblt_control >> 20) & 7; + + switch (chips->bitblt_running.bytes_per_pixel) { + case 1: /* 8 bits-per-pixel. */ + { + dest_pixel = chips_69000_readb_linear(dest_addr, chips); + break; + } + case 2: /* 16 bits-per-pixel. */ + { + dest_pixel = chips_69000_readb_linear(dest_addr, chips); + dest_pixel |= chips_69000_readb_linear(dest_addr + 1, chips) << 8; + break; + } + case 3: /* 24 bits-per-pixel. */ + { + dest_pixel = chips_69000_readb_linear(dest_addr, chips); + dest_pixel |= chips_69000_readb_linear(dest_addr + 1, chips) << 8; + dest_pixel |= chips_69000_readb_linear(dest_addr + 2, chips) << 16; + break; + } + } + + /* TODO: Find out from where it actually pulls the exact pattern x and y values. */ + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 18)) { + uint8_t is_true = 0; + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 19)) + pattern_data = 0; + else + pattern_data = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + (vert_pat_alignment + chips->bitblt_running.count_y), chips); + + is_true = !!(pattern_data & (1 << (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.count_x) & 7))); + + if (!is_true && (chips->bitblt_running.bitblt.bitblt_control & (1 << 17))) { + return; + } + + pattern_pixel = is_true ? pattern_fg : pattern_bg; + + pattern_pixel &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; + } + + switch (chips->bitblt_running.bytes_per_pixel) { + case 1: /* 8 bits-per-pixel. */ + { + chips_69000_do_rop_8bpp_patterned((uint8_t*)&dest_pixel, pattern_pixel, pixel, chips->bitblt_running.bitblt.bitblt_control & 0xFF); + break; + } + case 2: /* 16 bits-per-pixel. */ + { + chips_69000_do_rop_16bpp_patterned((uint16_t*)&dest_pixel, pattern_pixel, pixel, chips->bitblt_running.bitblt.bitblt_control & 0xFF); + break; + } + case 3: /* 24 bits-per-pixel. */ + { + chips_69000_do_rop_24bpp_patterned((uint32_t*)&dest_pixel, pattern_pixel, pixel, chips->bitblt_running.bitblt.bitblt_control & 0xFF); + break; + } + } + + switch (chips->bitblt_running.bytes_per_pixel) { + case 1: /* 8 bits-per-pixel. */ + { + chips_69000_writeb_linear(dest_addr, dest_pixel & 0xFF, chips); + break; + } + case 2: /* 16 bits-per-pixel. */ + { + chips_69000_writeb_linear(dest_addr, dest_pixel & 0xFF, chips); + chips_69000_writeb_linear(dest_addr + 1, (dest_pixel >> 8) & 0xFF, chips); + break; + } + case 3: /* 24 bits-per-pixel. */ + { + chips_69000_writeb_linear(dest_addr, dest_pixel & 0xFF, chips); + chips_69000_writeb_linear(dest_addr + 1, (dest_pixel >> 8) & 0xFF, chips); + chips_69000_writeb_linear(dest_addr + 2, (dest_pixel >> 16) & 0xFF, chips); + break; + } + } +} + void chips_69000_setup_bitblt(chips_69000_t* chips) { @@ -662,14 +783,90 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.bitblt = chips->bitblt; chips->bitblt_running.actual_source_height = chips->bitblt.destination_height; chips->bitblt_running.actual_destination_height = chips->bitblt.destination_height; + chips->bitblt_running.count_x = chips->bitblt_running.count_y = 0; - if (!chips->bitblt_running.actual_destination_height) { - chips->bitblt_running.actual_destination_height = 1; + if (chips->bitblt.bitblt_control & (1 << 23)) { + chips->bitblt_running.bytes_per_pixel = 1 + ((chips->bitblt.bitblt_control >> 24) & 3); + } else { + chips->bitblt_running.bytes_per_pixel = 1 + ((chips->ext_regs[0x20] >> 4) & 3); } - - /*Stubbed!*/ - chips->engine_active = 0; + chips->bitblt_running.actual_destination_width = chips->bitblt_running.bitblt.destination_width / chips->bitblt_running.bytes_per_pixel; + + switch ((chips->bitblt.bitblt_control >> 8) & 3) { + case 0: + chips->bitblt_running.x = 0; + chips->bitblt_running.y = 0; + chips->bitblt_running.x_dir = 1; + chips->bitblt_running.y_dir = 1; + break; + case 1: + chips->bitblt_running.x = chips->bitblt_running.actual_destination_width - 1; + chips->bitblt_running.y = 0; + chips->bitblt_running.x_dir = -1; + chips->bitblt_running.y_dir = 1; + break; + case 2: + chips->bitblt_running.x = 0; + chips->bitblt_running.y = chips->bitblt_running.bitblt.destination_height - 1; + chips->bitblt_running.x_dir = 1; + chips->bitblt_running.y_dir = -1; + break; + case 3: + chips->bitblt_running.x = chips->bitblt_running.actual_destination_width - 1; + chips->bitblt_running.y = chips->bitblt_running.bitblt.destination_height - 1; + chips->bitblt_running.x_dir = -1; + chips->bitblt_running.y_dir = -1; + break; + } + + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { + return; + } + + /* Drawing is pointless if monochrome pattern is enabled, monochrome write-masking is enabled and solid pattern is enabled. */ + if ((chips->bitblt_running.bitblt.bitblt_control & (1 << 17)) + && (chips->bitblt_running.bitblt.bitblt_control & (1 << 18)) + && (chips->bitblt_running.bitblt.bitblt_control & (1 << 19))) { + chips_69000_bitblt_interrupt(chips); + return; + } + + do { + do { + uint32_t pixel = 0; + uint32_t source_addr = chips->bitblt_running.bitblt.source_addr + (chips->bitblt_running.y * chips->bitblt.source_span) + (chips->bitblt_running.x * chips->bitblt_running.bytes_per_pixel); + + switch (chips->bitblt_running.bytes_per_pixel) { + case 1: /* 8 bits-per-pixel. */ + { + pixel = chips_69000_readb_linear(source_addr, chips); + break; + } + case 2: /* 16 bits-per-pixel. */ + { + pixel = chips_69000_readb_linear(source_addr, chips); + pixel |= chips_69000_readb_linear(source_addr + 1, chips) << 8; + break; + } + case 3: /* 24 bits-per-pixel. */ + { + pixel = chips_69000_readb_linear(source_addr, chips); + pixel |= chips_69000_readb_linear(source_addr + 1, chips) << 8; + pixel |= chips_69000_readb_linear(source_addr + 2, chips) << 16; + break; + } + } + + chips_69000_process_pixel(chips, pixel); + + chips->bitblt_running.x += chips->bitblt_running.x_dir; + } while ((chips->bitblt_running.count_x++) < chips->bitblt_running.actual_destination_width); + + chips->bitblt_running.y += chips->bitblt_running.y_dir; + chips->bitblt_running.count_x = 0; + } while ((chips->bitblt_running.count_y++) < chips->bitblt_running.actual_destination_height); + chips_69000_bitblt_interrupt(chips); } @@ -708,7 +905,7 @@ chips_69000_read_ext_reg(chips_69000_t* chips) break; case 0x20: val &= ~1; - val |= !!(chips->bitblt.bitblt_control & (1 << 31)); + val |= !!chips->engine_active; /* TODO: Handle BitBLT reset, if required. */ break; case 0x63: @@ -729,18 +926,18 @@ chips_69000_read_ext_reg(chips_69000_t* chips) val = 0x0; break; } - if (chips->ext_index != 0x4E && chips->ext_index != 0x4F - && (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) - pclog("C&T: Read ext reg 0x%02X, ret = 0x%02X\n", index, val); + // if (chips->ext_index != 0x4E && chips->ext_index != 0x4F + // && (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) + // pclog("C&T: Read ext reg 0x%02X, ret = 0x%02X\n", index, val); return val; } void chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) { - if (chips->ext_index != 0x4E && chips->ext_index != 0x4F - && (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) - pclog("C&T: Write ext reg 0x%02X, ret = 0x%02X\n", chips->ext_index, val); + // if (chips->ext_index != 0x4E && chips->ext_index != 0x4F + // && (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) + // pclog("C&T: Write ext reg 0x%02X, ret = 0x%02X\n", chips->ext_index, val); switch (chips->ext_index) { case 0xA: chips->ext_regs[chips->ext_index] = val & 0x37; @@ -1119,10 +1316,13 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) uint8_t chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) { - pclog("C&T Read 0x%X\n", addr); + //pclog("C&T Read 0x%X\n", addr); addr &= 0xFFF; switch (addr & 0xFFF) { case 0x00 ... 0x28: + if (addr == 0x10) { + return (chips->bitblt_regs_b[addr & 0xFF] & 0x7F) | (chips->engine_active ? 0x80 : 0x00); + } return chips->bitblt_regs_b[addr & 0xFF]; case 0x600 ... 0x60F: return chips->mem_regs_b[addr & 0xF]; @@ -1205,12 +1405,12 @@ chips_69000_readl_mmio(uint32_t addr, chips_69000_t* chips) void chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) { - pclog("C&T Write 0x%X, val = 0x%02X\n", addr, val); + //pclog("C&T Write 0x%X, val = 0x%02X\n", addr, val); addr &= 0xFFF; switch (addr & 0xFFF) { case 0x00 ... 0x28: chips->bitblt_regs_b[addr & 0xFF] = val; - if ((addr & 0xFFF) == 0x023) { + if ((addr & 0xFFF) == 0x023 && chips->bitblt_regs[0x8] != 0) { uint8_t cntr = 0; pclog("BitBLT/Draw operation %hd\n", (uint8_t)cntr++); chips_69000_setup_bitblt(chips); From 4e44449143d929d628e6fb09ea1a8fc512f88a6b Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Thu, 1 Feb 2024 14:05:09 +0300 Subject: [PATCH 401/936] Rename "AMI XT clone" as the machine has been identified --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index eefeea72f..f59babaea 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -437,7 +437,7 @@ const machine_t machines[] = { .net_device = NULL }, { - .name = "[8088] AMI XT clone", + .name = "[8088] Micoms XL-7 Turbo", .internal_name = "amixt", .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, From 2dba92221fdc2ffc4997dda1f52397c745efa6c5 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 1 Feb 2024 19:48:09 +0600 Subject: [PATCH 402/936] Try fixing overdrawing --- src/video/vid_c&t_69000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index fde218ed8..75848a7f5 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -861,11 +861,11 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips_69000_process_pixel(chips, pixel); chips->bitblt_running.x += chips->bitblt_running.x_dir; - } while ((chips->bitblt_running.count_x++) < chips->bitblt_running.actual_destination_width); + } while ((++chips->bitblt_running.count_x) < chips->bitblt_running.actual_destination_width); chips->bitblt_running.y += chips->bitblt_running.y_dir; chips->bitblt_running.count_x = 0; - } while ((chips->bitblt_running.count_y++) < chips->bitblt_running.actual_destination_height); + } while ((++chips->bitblt_running.count_y) < chips->bitblt_running.actual_destination_height); chips_69000_bitblt_interrupt(chips); } From 89266055913bf57f50793d83e15b63e0d0e3ec59 Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Thu, 1 Feb 2024 20:53:42 +0300 Subject: [PATCH 403/936] Revert "Rename "AMI XT clone" as the machine has been identified" This reverts commit 4e44449143d929d628e6fb09ea1a8fc512f88a6b. --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index f59babaea..eefeea72f 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -437,7 +437,7 @@ const machine_t machines[] = { .net_device = NULL }, { - .name = "[8088] Micoms XL-7 Turbo", + .name = "[8088] AMI XT clone", .internal_name = "amixt", .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, From 7cdfdb777678571ba1f1027d3f8d1a0af5124f24 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 1 Feb 2024 15:56:31 -0300 Subject: [PATCH 404/936] Lowercase the amis727 machine entry --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index eefeea72f..b672f524a 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -10570,7 +10570,7 @@ const machine_t machines[] = { /* Has Megakey 'R' KBC */ { .name = "[SiS 5511] AMI Atlas PCI-II", - .internal_name = "AMIS727", + .internal_name = "amis727", .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_SIS_5511, .init = machine_at_amis727_init, From e0503e6381b4e3562b15e51612167bee7a1cde12 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 2 Feb 2024 01:44:51 +0600 Subject: [PATCH 405/936] Patterns now are blitted correctly --- src/video/vid_c&t_69000.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 75848a7f5..05c549d2f 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -130,6 +130,9 @@ typedef struct chips_69000_t { int x_dir, y_dir; uint8_t bytes_per_pixel; + + /* Byte counter for BitBLT port writes. */ + uint8_t bytes_written; } bitblt_running; union { @@ -693,7 +696,7 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) uint16_t pattern_data_16bpp[8][8]; uint32_t pattern_pixel = 0; uint32_t dest_pixel = 0; - uint32_t dest_addr = chips->bitblt_running.bitblt.destination_addr + (chips->bitblt_running.y * chips->bitblt.destination_span) + (chips->bitblt_running.x * chips->bitblt_running.bytes_per_pixel); + uint32_t dest_addr = chips->bitblt_running.bitblt.destination_addr + (chips->bitblt_running.y * chips->bitblt_running.bitblt.destination_span) + (chips->bitblt_running.x * chips->bitblt_running.bytes_per_pixel); uint8_t vert_pat_alignment = (chips->bitblt_running.bitblt.bitblt_control >> 20) & 7; switch (chips->bitblt_running.bytes_per_pixel) { @@ -723,7 +726,7 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) if (chips->bitblt_running.bitblt.bitblt_control & (1 << 19)) pattern_data = 0; else - pattern_data = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + (vert_pat_alignment + chips->bitblt_running.count_y), chips); + pattern_data = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + ((vert_pat_alignment + chips->bitblt_running.count_y) & 7), chips); is_true = !!(pattern_data & (1 << (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.count_x) & 7))); @@ -793,7 +796,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.actual_destination_width = chips->bitblt_running.bitblt.destination_width / chips->bitblt_running.bytes_per_pixel; - switch ((chips->bitblt.bitblt_control >> 8) & 3) { + switch ((chips->bitblt_running.bitblt.bitblt_control >> 8) & 3) { case 0: chips->bitblt_running.x = 0; chips->bitblt_running.y = 0; @@ -808,13 +811,13 @@ chips_69000_setup_bitblt(chips_69000_t* chips) break; case 2: chips->bitblt_running.x = 0; - chips->bitblt_running.y = chips->bitblt_running.bitblt.destination_height - 1; + chips->bitblt_running.y = chips->bitblt_running.bitblt.destination_height; chips->bitblt_running.x_dir = 1; chips->bitblt_running.y_dir = -1; break; case 3: chips->bitblt_running.x = chips->bitblt_running.actual_destination_width - 1; - chips->bitblt_running.y = chips->bitblt_running.bitblt.destination_height - 1; + chips->bitblt_running.y = chips->bitblt_running.bitblt.destination_height; chips->bitblt_running.x_dir = -1; chips->bitblt_running.y_dir = -1; break; @@ -865,7 +868,11 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.y += chips->bitblt_running.y_dir; chips->bitblt_running.count_x = 0; - } while ((++chips->bitblt_running.count_y) < chips->bitblt_running.actual_destination_height); + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 8)) { + chips->bitblt_running.x = chips->bitblt_running.actual_destination_width - 1; + } else + chips->bitblt_running.x = 0; + } while ((chips->bitblt_running.count_y++) < chips->bitblt_running.actual_destination_height); chips_69000_bitblt_interrupt(chips); } From 2690132bc37b1785740adb179ca1c8843b6bb1d8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 2 Feb 2024 02:28:32 +0600 Subject: [PATCH 406/936] WIP BitBLT port work --- src/video/vid_c&t_69000.c | 66 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 05c549d2f..c3912fa77 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -133,6 +133,7 @@ typedef struct chips_69000_t { /* Byte counter for BitBLT port writes. */ uint8_t bytes_written; + uint8_t bytes_port[4]; } bitblt_running; union { @@ -721,14 +722,15 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) } /* TODO: Find out from where it actually pulls the exact pattern x and y values. */ + /* Also: is horizontal pattern alignment a requirement? */ if (chips->bitblt_running.bitblt.bitblt_control & (1 << 18)) { uint8_t is_true = 0; if (chips->bitblt_running.bitblt.bitblt_control & (1 << 19)) pattern_data = 0; else - pattern_data = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + ((vert_pat_alignment + chips->bitblt_running.count_y) & 7), chips); + pattern_data = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + ((vert_pat_alignment + chips->bitblt_running.y) & 7), chips); - is_true = !!(pattern_data & (1 << (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.count_x) & 7))); + is_true = !!(pattern_data & (1 << (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7))); if (!is_true && (chips->bitblt_running.bitblt.bitblt_control & (1 << 17))) { return; @@ -737,6 +739,12 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) pattern_pixel = is_true ? pattern_fg : pattern_bg; pattern_pixel &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; + } else { + if (chips->bitblt_running.bytes_per_pixel == 1) { + pattern_pixel = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + + 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7) + + (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7), chips); + } } switch (chips->bitblt_running.bytes_per_pixel) { @@ -787,6 +795,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.actual_source_height = chips->bitblt.destination_height; chips->bitblt_running.actual_destination_height = chips->bitblt.destination_height; chips->bitblt_running.count_x = chips->bitblt_running.count_y = 0; + chips->bitblt_running.bytes_written = 0; if (chips->bitblt.bitblt_control & (1 << 23)) { chips->bitblt_running.bytes_per_pixel = 1 + ((chips->bitblt.bitblt_control >> 24) & 3); @@ -877,6 +886,43 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips_69000_bitblt_interrupt(chips); } +void +chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { + + if (!chips->engine_active) + return; + + chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; + if (chips->bitblt_running.bytes_written == chips->bitblt_running.bytes_per_pixel) { + uint32_t source_pixel = chips->bitblt_running.bytes_port[0]; + chips->bitblt_running.bytes_written = 0; + if (chips->bitblt_running.bytes_per_pixel == 1) + source_pixel = (chips->bitblt_running.bytes_port[1] << 8); + if (chips->bitblt_running.bytes_per_pixel == 2) + source_pixel = (chips->bitblt_running.bytes_port[2] << 16); + + chips_69000_process_pixel(chips, source_pixel); + chips->bitblt_running.x += chips->bitblt_running.x_dir; + chips->bitblt_running.count_x++; + + if (chips->bitblt_running.count_x >= chips->bitblt_running.actual_destination_width) { + chips->bitblt_running.y += chips->bitblt_running.y_dir; + chips->bitblt_running.count_y++; + + chips->bitblt_running.count_x = 0; + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 8)) { + chips->bitblt_running.x = chips->bitblt_running.actual_destination_width - 1; + } else + chips->bitblt_running.x = 0; + + if (chips->bitblt_running.count_y > chips->bitblt_running.actual_destination_height) { + chips_69000_bitblt_interrupt(chips); + return; + } + } + } +} + uint8_t chips_69000_read_ext_reg(chips_69000_t* chips) { @@ -1413,6 +1459,10 @@ void chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) { //pclog("C&T Write 0x%X, val = 0x%02X\n", addr, val); + if (addr & 0x10000) { + chips_69000_bitblt_write(chips, val); + return; + } addr &= 0xFFF; switch (addr & 0xFFF) { case 0x00 ... 0x28: @@ -1509,6 +1559,11 @@ chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) void chips_69000_writew_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) { + if (addr & 0x10000) { + chips_69000_bitblt_write(chips, val & 0xFF); + chips_69000_bitblt_write(chips, (val >> 8) & 0xFF); + return; + } addr &= 0xFFF; switch (addr & 0xFFF) { default: @@ -1521,6 +1576,13 @@ chips_69000_writew_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) void chips_69000_writel_mmio(uint32_t addr, uint32_t val, chips_69000_t* chips) { + if (addr & 0x10000) { + chips_69000_bitblt_write(chips, val & 0xFF); + chips_69000_bitblt_write(chips, (val >> 8) & 0xFF); + chips_69000_bitblt_write(chips, (val >> 16) & 0xFF); + chips_69000_bitblt_write(chips, (val >> 24) & 0xFF); + return; + } addr &= 0xFFF; switch (addr & 0xFFF) { default: From 0a5d25fddeac00aa0f98eef663f5eb9b1f6cc0af Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 2 Feb 2024 05:25:40 +0100 Subject: [PATCH 407/936] Memory: Disable _mem_exec in phys() accesses when not using the 486+ interpreter or dynamic recompiler, and write protect support in preparation for the WD76C10 rewrite. --- src/cpu/cpu.c | 13 ++++-- src/cpu/cpu.h | 1 + src/include/86box/mem.h | 1 + src/mem/mem.c | 98 ++++++++++++++++++++++++++++------------- 4 files changed, 78 insertions(+), 35 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index c3e3c39d4..e05ec0d9c 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -182,6 +182,7 @@ int cpu_16bitbus; int cpu_64bitbus; int cpu_cyrix_alignment; int cpu_cpurst_on_sr; +int cpu_use_exec = 0; int CPUID; int is186; @@ -1784,16 +1785,20 @@ cpu_set(void) x87_concurrency = x87_concurrency_486; } + cpu_use_exec = 0; + if (is386) { #if defined(USE_DYNAREC) && !defined(USE_GDBSTUB) - if (cpu_use_dynarec) + if (cpu_use_dynarec) { cpu_exec = exec386_dynarec; - else + cpu_use_exec = 1; + } else #endif /* Use exec386 for CPU_IBM486SLC because it can reach 100 MHz. */ - if ((cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type > CPU_486DLC)) + if ((cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type > CPU_486DLC)) { cpu_exec = exec386; - else + cpu_use_exec = 1; + } else cpu_exec = exec386_2386; } else if (cpu_s->cpu_type >= CPU_286) cpu_exec = exec386_2386; diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 95625df55..b547fb99f 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -809,6 +809,7 @@ extern int hlt_reset_pending; extern cyrix_t cyrix; extern int prefetch_prefixes; +extern int cpu_use_exec; extern uint8_t use_custom_nmi_vector; extern uint32_t custom_nmi_vector; diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index 8832ad7f9..15afcb160 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -398,6 +398,7 @@ extern void mem_mapping_disable(mem_mapping_t *); extern void mem_mapping_enable(mem_mapping_t *); extern void mem_mapping_recalc(uint64_t base, uint64_t size); +extern void mem_set_wp(uint64_t base, uint64_t size, uint8_t flags, uint8_t wp); extern void mem_set_access(uint8_t bitmap, int mode, uint32_t base, uint32_t size, uint16_t access); extern uint8_t mem_readb_phys(uint32_t addr); diff --git a/src/mem/mem.c b/src/mem/mem.c index 145202260..188aa49d0 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -132,6 +132,8 @@ static mem_mapping_t *last_mapping; static mem_mapping_t *read_mapping_bus[MEM_MAPPINGS_NO]; static mem_mapping_t *write_mapping_bus[MEM_MAPPINGS_NO]; static uint8_t *_mem_exec[MEM_MAPPINGS_NO]; +static uint8_t _mem_wp[MEM_MAPPINGS_NO]; +static uint8_t _mem_wp_bus[MEM_MAPPINGS_NO]; static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff }; static mem_state_t _mem_state[MEM_MAPPINGS_NO]; static uint32_t remap_start_addr; @@ -1631,7 +1633,7 @@ mem_readb_phys(uint32_t addr) mem_logical_addr = 0xffffffff; if (map) { - if (map->exec) + if (cpu_use_exec && map->exec) ret = map->exec[(addr - map->base) & map->mask]; else if (map->read_b) ret = map->read_b(addr, map->priv); @@ -1649,7 +1651,7 @@ mem_readw_phys(uint32_t addr) mem_logical_addr = 0xffffffff; - if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->exec)) { + if (cpu_use_exec && ((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->exec)) { p = (uint16_t *) &(map->exec[(addr - map->base) & map->mask]); ret = *p; } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->read_w)) @@ -1671,7 +1673,7 @@ mem_readl_phys(uint32_t addr) mem_logical_addr = 0xffffffff; - if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->exec)) { + if (cpu_use_exec && ((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->exec)) { p = (uint32_t *) &(map->exec[(addr - map->base) & map->mask]); ret = *p; } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->read_l)) @@ -1711,7 +1713,7 @@ mem_writeb_phys(uint32_t addr, uint8_t val) mem_logical_addr = 0xffffffff; if (map) { - if (map->exec) + if (cpu_use_exec && map->exec) map->exec[(addr - map->base) & map->mask] = val; else if (map->write_b) map->write_b(addr, val, map->priv); @@ -1726,7 +1728,7 @@ mem_writew_phys(uint32_t addr, uint16_t val) mem_logical_addr = 0xffffffff; - if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->exec)) { + if (cpu_use_exec && ((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->exec)) { p = (uint16_t *) &(map->exec[(addr - map->base) & map->mask]); *p = val; } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->write_w)) @@ -1745,7 +1747,7 @@ mem_writel_phys(uint32_t addr, uint32_t val) mem_logical_addr = 0xffffffff; - if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->exec)) { + if (cpu_use_exec && ((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->exec)) { p = (uint32_t *) &(map->exec[(addr - map->base) & map->mask]); *p = val; } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->write_l)) @@ -1783,7 +1785,7 @@ mem_read_ram(uint32_t addr, UNUSED(void *priv)) mem_log("Read B %02X from %08X\n", ram[addr], addr); #endif - if (is286) + if (cpu_use_exec) addreadlookup(mem_logical_addr, addr); return ram[addr]; @@ -1797,7 +1799,7 @@ mem_read_ramw(uint32_t addr, UNUSED(void *priv)) mem_log("Read W %04X from %08X\n", *(uint16_t *) &ram[addr], addr); #endif - if (is286) + if (cpu_use_exec) addreadlookup(mem_logical_addr, addr); return *(uint16_t *) &ram[addr]; @@ -1811,7 +1813,7 @@ mem_read_raml(uint32_t addr, UNUSED(void *priv)) mem_log("Read L %08X from %08X\n", *(uint32_t *) &ram[addr], addr); #endif - if (is286) + if (cpu_use_exec) addreadlookup(mem_logical_addr, addr); return *(uint32_t *) &ram[addr]; @@ -2043,7 +2045,7 @@ mem_write_ram(uint32_t addr, uint8_t val, UNUSED(void *priv)) if ((addr >= 0xa0000) && (addr <= 0xbffff)) mem_log("Write B %02X to %08X\n", val, addr); #endif - if (is286) { + if (cpu_use_exec) { addwritelookup(mem_logical_addr, addr); mem_write_ramb_page(addr, val, &pages[addr >> 12]); } else @@ -2057,7 +2059,7 @@ mem_write_ramw(uint32_t addr, uint16_t val, UNUSED(void *priv)) if ((addr >= 0xa0000) && (addr <= 0xbffff)) mem_log("Write W %04X to %08X\n", val, addr); #endif - if (is286) { + if (cpu_use_exec) { addwritelookup(mem_logical_addr, addr); mem_write_ramw_page(addr, val, &pages[addr >> 12]); } else @@ -2071,7 +2073,7 @@ mem_write_raml(uint32_t addr, uint32_t val, UNUSED(void *priv)) if ((addr >= 0xa0000) && (addr <= 0xbffff)) mem_log("Write L %08X to %08X\n", val, addr); #endif - if (is286) { + if (cpu_use_exec) { addwritelookup(mem_logical_addr, addr); mem_write_raml_page(addr, val, &pages[addr >> 12]); } else @@ -2082,7 +2084,7 @@ static uint8_t mem_read_remapped(uint32_t addr, UNUSED(void *priv)) { addr = 0xA0000 + (addr - remap_start_addr); - if (is286) + if (cpu_use_exec) addreadlookup(mem_logical_addr, addr); return ram[addr]; } @@ -2091,7 +2093,7 @@ static uint16_t mem_read_remappedw(uint32_t addr, UNUSED(void *priv)) { addr = 0xA0000 + (addr - remap_start_addr); - if (is286) + if (cpu_use_exec) addreadlookup(mem_logical_addr, addr); return *(uint16_t *) &ram[addr]; } @@ -2100,7 +2102,7 @@ static uint32_t mem_read_remappedl(uint32_t addr, UNUSED(void *priv)) { addr = 0xA0000 + (addr - remap_start_addr); - if (is286) + if (cpu_use_exec) addreadlookup(mem_logical_addr, addr); return *(uint32_t *) &ram[addr]; } @@ -2109,7 +2111,7 @@ static uint8_t mem_read_remapped2(uint32_t addr, UNUSED(void *priv)) { addr = 0xD0000 + (addr - remap_start_addr2); - if (is286) + if (cpu_use_exec) addreadlookup(mem_logical_addr, addr); return ram[addr]; } @@ -2118,7 +2120,7 @@ static uint16_t mem_read_remappedw2(uint32_t addr, UNUSED(void *priv)) { addr = 0xD0000 + (addr - remap_start_addr2); - if (is286) + if (cpu_use_exec) addreadlookup(mem_logical_addr, addr); return *(uint16_t *) &ram[addr]; } @@ -2127,7 +2129,7 @@ static uint32_t mem_read_remappedl2(uint32_t addr, UNUSED(void *priv)) { addr = 0xD0000 + (addr - remap_start_addr2); - if (is286) + if (cpu_use_exec) addreadlookup(mem_logical_addr, addr); return *(uint32_t *) &ram[addr]; } @@ -2137,7 +2139,7 @@ mem_write_remapped(uint32_t addr, uint8_t val, UNUSED(void *priv)) { uint32_t oldaddr = addr; addr = 0xA0000 + (addr - remap_start_addr); - if (is286) { + if (cpu_use_exec) { addwritelookup(mem_logical_addr, addr); mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]); } else @@ -2149,7 +2151,7 @@ mem_write_remappedw(uint32_t addr, uint16_t val, UNUSED(void *priv)) { uint32_t oldaddr = addr; addr = 0xA0000 + (addr - remap_start_addr); - if (is286) { + if (cpu_use_exec) { addwritelookup(mem_logical_addr, addr); mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]); } else @@ -2161,7 +2163,7 @@ mem_write_remappedl(uint32_t addr, uint32_t val, UNUSED(void *priv)) { uint32_t oldaddr = addr; addr = 0xA0000 + (addr - remap_start_addr); - if (is286) { + if (cpu_use_exec) { addwritelookup(mem_logical_addr, addr); mem_write_raml_page(addr, val, &pages[oldaddr >> 12]); } else @@ -2173,7 +2175,7 @@ mem_write_remapped2(uint32_t addr, uint8_t val, UNUSED(void *priv)) { uint32_t oldaddr = addr; addr = 0xD0000 + (addr - remap_start_addr2); - if (is286) { + if (cpu_use_exec) { addwritelookup(mem_logical_addr, addr); mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]); } else @@ -2185,7 +2187,7 @@ mem_write_remappedw2(uint32_t addr, uint16_t val, UNUSED(void *priv)) { uint32_t oldaddr = addr; addr = 0xD0000 + (addr - remap_start_addr2); - if (is286) { + if (cpu_use_exec) { addwritelookup(mem_logical_addr, addr); mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]); } else @@ -2197,7 +2199,7 @@ mem_write_remappedl2(uint32_t addr, uint32_t val, UNUSED(void *priv)) { uint32_t oldaddr = addr; addr = 0xD0000 + (addr - remap_start_addr2); - if (is286) { + if (cpu_use_exec) { addwritelookup(mem_logical_addr, addr); mem_write_raml_page(addr, val, &pages[oldaddr >> 12]); } else @@ -2282,6 +2284,7 @@ mem_mapping_recalc(uint64_t base, uint64_t size) mem_mapping_t *map; int n; uint64_t c; + uint8_t wp; if (!size || (base_mapping == NULL)) return; @@ -2300,27 +2303,42 @@ mem_mapping_recalc(uint64_t base, uint64_t size) /* Walk mapping list. */ while (map != NULL) { /* In range? */ - if (map->enable && (uint64_t) map->base < ((uint64_t) base + (uint64_t) size) && ((uint64_t) map->base + (uint64_t) map->size) > (uint64_t) base) { + if (map->enable && (uint64_t) map->base < ((uint64_t) base + (uint64_t) size) && + ((uint64_t) map->base + (uint64_t) map->size) > (uint64_t) base) { uint64_t start = (map->base < base) ? map->base : base; - uint64_t end = (((uint64_t) map->base + (uint64_t) map->size) < (base + size)) ? ((uint64_t) map->base + (uint64_t) map->size) : (base + size); + uint64_t end = (((uint64_t) map->base + (uint64_t) map->size) < (base + size)) ? + ((uint64_t) map->base + (uint64_t) map->size) : (base + size); if (start < map->base) start = map->base; for (c = start; c < end; c += MEM_GRANULARITY_SIZE) { /* CPU */ n = !!in_smm; - if (map->exec && mem_mapping_access_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].x)) + wp = _mem_wp[c >> MEM_GRANULARITY_BITS]; + + if (map->exec && mem_mapping_access_allowed(map->flags, + _mem_state[c >> MEM_GRANULARITY_BITS].states[n].x)) _mem_exec[c >> MEM_GRANULARITY_BITS] = map->exec + (c - map->base); - if ((map->write_b || map->write_w || map->write_l) && mem_mapping_access_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].w)) + if (!wp && (map->write_b || map->write_w || map->write_l) && + mem_mapping_access_allowed(map->flags, + _mem_state[c >> MEM_GRANULARITY_BITS].states[n].w)) write_mapping[c >> MEM_GRANULARITY_BITS] = map; - if ((map->read_b || map->read_w || map->read_l) && mem_mapping_access_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].r)) + if ((map->read_b || map->read_w || map->read_l) && + mem_mapping_access_allowed(map->flags, + _mem_state[c >> MEM_GRANULARITY_BITS].states[n].r)) read_mapping[c >> MEM_GRANULARITY_BITS] = map; /* Bus */ n |= STATE_BUS; - if ((map->write_b || map->write_w || map->write_l) && mem_mapping_access_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].w)) + wp = _mem_wp_bus[c >> MEM_GRANULARITY_BITS]; + + if (!wp && (map->write_b || map->write_w || map->write_l) && + mem_mapping_access_allowed(map->flags, + _mem_state[c >> MEM_GRANULARITY_BITS].states[n].w)) write_mapping_bus[c >> MEM_GRANULARITY_BITS] = map; - if ((map->read_b || map->read_w || map->read_l) && mem_mapping_access_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].r)) + if ((map->read_b || map->read_w || map->read_l) && + mem_mapping_access_allowed(map->flags, + _mem_state[c >> MEM_GRANULARITY_BITS].states[n].r)) read_mapping_bus[c >> MEM_GRANULARITY_BITS] = map; } } @@ -2380,6 +2398,22 @@ mem_mapping_recalc(uint64_t base, uint64_t size) #endif } +void +mem_set_wp(uint64_t base, uint64_t size, uint8_t flags, uint8_t wp) +{ + uint64_t c; + uint64_t end = base + size; + + for (c = base; c < end; c += MEM_GRANULARITY_SIZE) { + if (flags & ACCESS_BUS) + _mem_wp_bus[c >> MEM_GRANULARITY_BITS] = wp; + if (flags & ACCESS_CPU) + _mem_wp[c >> MEM_GRANULARITY_BITS] = wp; + } + + mem_mapping_recalc(base, size); +} + void mem_mapping_set(mem_mapping_t *map, uint32_t base, @@ -2790,6 +2824,8 @@ mem_reset(void) } memset(_mem_exec, 0x00, sizeof(_mem_exec)); + memset(_mem_wp, 0x00, sizeof(_mem_wp)); + memset(_mem_wp_bus, 0x00, sizeof(_mem_wp_bus)); memset(write_mapping, 0x00, sizeof(write_mapping)); memset(read_mapping, 0x00, sizeof(read_mapping)); memset(write_mapping_bus, 0x00, sizeof(write_mapping_bus)); From a8f250b6c9e215405c648fda2068d32b10a41175 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 2 Feb 2024 05:29:34 +0100 Subject: [PATCH 408/936] LPT: Function to read register in preparation for the WD76C10 rewrite. --- src/include/86box/lpt.h | 2 ++ src/lpt.c | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/src/include/86box/lpt.h b/src/include/86box/lpt.h index a9a9eac65..4e95b64c3 100644 --- a/src/include/86box/lpt.h +++ b/src/include/86box/lpt.h @@ -83,6 +83,8 @@ extern lpt_port_t lpt_ports[PARALLEL_MAX]; extern void lpt_write(uint16_t port, uint8_t val, void *priv); extern uint8_t lpt_read(uint16_t port, void *priv); +extern uint8_t lpt_read_port(int port, uint16_t reg); + extern uint8_t lpt_read_status(int port); extern void lpt_irq(void *priv, int raise); diff --git a/src/lpt.c b/src/lpt.c index 5bbf79875..dd77b3516 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -165,6 +165,15 @@ lpt_read(uint16_t port, void *priv) return ret; } +uint8_t +lpt_read_port(int port, uint16_t reg) +{ + lpt_port_t *dev = &(lpt_ports[port]); + uint8_t ret = lpt_read(reg, dev); + + return ret; +} + uint8_t lpt_read_status(int port) { From 91ca927618794df7b6867e9ee08ed6eb45cf4587 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 2 Feb 2024 05:30:11 +0100 Subject: [PATCH 409/936] AT NVR: The ability to lock reading of a register in preparation of the WD7C610 rewrite. --- src/nvr_at.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/nvr_at.c b/src/nvr_at.c index c66799579..7e356f55d 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -692,7 +692,7 @@ nvr_read(uint16_t addr, void *priv) { nvr_t *nvr = (nvr_t *) priv; const local_t *local = (local_t *) nvr->data; - uint8_t ret; + uint8_t ret = 0xff; uint8_t addr_id = (addr & 0x0e) >> 1; uint16_t i; uint16_t checksum = 0x0000; @@ -810,7 +810,8 @@ nvr_read(uint16_t addr, void *priv) break; default: - ret = nvr->regs[local->addr[addr_id]]; + if (!(local->lock[local->addr[addr_id]] & 0x02)) + ret = nvr->regs[local->addr[addr_id]]; break; } else { From 3ceda105ef757d2dacf1e0944a6ae7a6d42bae2f Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 2 Feb 2024 05:31:33 +0100 Subject: [PATCH 410/936] ALi M6117 CPU fixes. --- src/cpu/cpu_table.c | 4 ++-- src/cpu/x86_ops_misc.h | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 947804014..fe55a4f23 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -1070,8 +1070,8 @@ const cpu_family_t cpu_families[] = { .name = "M6117", .internal_name = "m6117", .cpus = (const CPU[]) { /* All timings and edx_reset values assumed. */ - {"33", CPU_386SX, fpus_none, 33333333, 1, 5000, 0x2308, 0, 0, 0, 6,6,3,3, 4}, - {"40", CPU_386SX, fpus_none, 40000000, 1, 5000, 0x2308, 0, 0, 0, 7,7,3,3, 5}, + {"33", CPU_386SX, fpus_none, 33333333, 1, 5000, 0x2309, 0, 0, 0, 6,6,3,3, 4}, + {"40", CPU_386SX, fpus_none, 40000000, 1, 5000, 0x2309, 0, 0, 0, 7,7,3,3, 5}, {"", 0} } }, { diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index e36fa4800..cbd2b3fbe 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -129,7 +129,7 @@ opF6_a16(uint32_t fetchdat) if (dst && !(tempw & 0xff00)) { AH = src16 % dst; AL = (src16 / dst) & 0xff; - if (!cpu_iscyrix) { + if (!cpu_iscyrix && !is6117) { flags_rebuild(); cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ cpu_state.flags &= ~1; @@ -149,7 +149,7 @@ opF6_a16(uint32_t fetchdat) if (dst && ((int) temps == tempws2)) { AH = (tempws % (int) ((int8_t) dst)) & 0xff; AL = tempws2 & 0xff; - if (!cpu_iscyrix) { + if (!cpu_iscyrix && !is6117) { flags_rebuild(); cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ cpu_state.flags &= ~1; @@ -246,7 +246,7 @@ opF6_a32(uint32_t fetchdat) if (dst && !(tempw & 0xff00)) { AH = src16 % dst; AL = (src16 / dst) & 0xff; - if (!cpu_iscyrix) { + if (!cpu_iscyrix && !is6117) { flags_rebuild(); cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ cpu_state.flags &= ~1; @@ -266,7 +266,7 @@ opF6_a32(uint32_t fetchdat) if (dst && ((int) temps == tempws2)) { AH = (tempws % (int) ((int8_t) dst)) & 0xff; AL = tempws2 & 0xff; - if (!cpu_iscyrix) { + if (!cpu_iscyrix && !is6117) { flags_rebuild(); cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ cpu_state.flags &= ~1; @@ -366,7 +366,7 @@ opF7_w_a16(uint32_t fetchdat) if (dst && !(templ2 & 0xffff0000)) { DX = templ % dst; AX = (templ / dst) & 0xffff; - if (!cpu_iscyrix) + if (!cpu_iscyrix && !is6117) setznp16(AX); /*Not a Cyrix*/ } else { x86_int(0); @@ -383,7 +383,7 @@ opF7_w_a16(uint32_t fetchdat) if ((dst != 0) && ((int) temps16 == tempws2)) { DX = tempws % (int) ((int16_t) dst); AX = tempws2 & 0xffff; - if (!cpu_iscyrix) + if (!cpu_iscyrix && !is6117) setznp16(AX); /*Not a Cyrix*/ } else { x86_int(0); @@ -479,7 +479,7 @@ opF7_w_a32(uint32_t fetchdat) if (dst && !(templ2 & 0xffff0000)) { DX = templ % dst; AX = (templ / dst) & 0xffff; - if (!cpu_iscyrix) + if (!cpu_iscyrix && !is6117) setznp16(AX); /*Not a Cyrix*/ } else { // fatal("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins); @@ -497,7 +497,7 @@ opF7_w_a32(uint32_t fetchdat) if ((dst != 0) && ((int) temps16 == tempws2)) { DX = tempws % (int) ((int16_t) dst); AX = tempws2 & 0xffff; - if (!cpu_iscyrix) + if (!cpu_iscyrix && !is6117) setznp16(AX); /*Not a Cyrix*/ } else { x86_int(0); @@ -587,7 +587,7 @@ opF7_l_a16(uint32_t fetchdat) case 0x30: /*DIV EAX,l*/ if (divl(dst)) return 1; - if (!cpu_iscyrix) + if (!cpu_iscyrix && !is6117) setznp32(EAX); /*Not a Cyrix*/ CLOCK_CYCLES((is486) ? 40 : 38); PREFETCH_RUN(is486 ? 40 : 38, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); @@ -595,7 +595,7 @@ opF7_l_a16(uint32_t fetchdat) case 0x38: /*IDIV EAX,l*/ if (idivl((int32_t) dst)) return 1; - if (!cpu_iscyrix) + if (!cpu_iscyrix && !is6117) setznp32(EAX); /*Not a Cyrix*/ CLOCK_CYCLES(43); PREFETCH_RUN(43, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); @@ -680,7 +680,7 @@ opF7_l_a32(uint32_t fetchdat) case 0x30: /*DIV EAX,l*/ if (divl(dst)) return 1; - if (!cpu_iscyrix) + if (!cpu_iscyrix && !is6117) setznp32(EAX); /*Not a Cyrix*/ CLOCK_CYCLES((is486) ? 40 : 38); PREFETCH_RUN(is486 ? 40 : 38, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); @@ -688,7 +688,7 @@ opF7_l_a32(uint32_t fetchdat) case 0x38: /*IDIV EAX,l*/ if (idivl((int32_t) dst)) return 1; - if (!cpu_iscyrix) + if (!cpu_iscyrix && !is6117) setznp32(EAX); /*Not a Cyrix*/ CLOCK_CYCLES(43); PREFETCH_RUN(43, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); From ce73276bfe69ae0303fbfb8918991be8770f7053 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 2 Feb 2024 05:32:43 +0100 Subject: [PATCH 411/936] WD76C10 rewrite, closes #238. --- src/chipset/wd76c10.c | 1070 +++++++++++++++++++++++----------- src/include/86box/device.h | 103 ++-- src/include/86box/serial.h | 8 +- src/machine/m_at_286_386sx.c | 2 +- 4 files changed, 799 insertions(+), 384 deletions(-) diff --git a/src/chipset/wd76c10.c b/src/chipset/wd76c10.c index ae4b30228..ef076b606 100644 --- a/src/chipset/wd76c10.c +++ b/src/chipset/wd76c10.c @@ -8,14 +8,10 @@ * * Implementation of the Western Digital WD76C10 chipset. * - * Note: This chipset has no datasheet, everything were done via - * reverse engineering the BIOS of various machines using it. + * Authors: Miran Grca, * + * Copyright 2024 Miran Grca. * - * - * Authors: Tiseno100 - * - * Copyright 2021 Tiseno100 */ #include #include @@ -37,112 +33,452 @@ #include <86box/hdc_ide.h> #include <86box/lpt.h> #include <86box/mem.h> -#include <86box/plat_unused.h> +#include <86box/nvr.h> #include <86box/port_92.h> #include <86box/serial.h> +#include <86box/plat_fallthrough.h> #include <86box/chipset.h> /* Lock/Unlock Procedures */ -#define LOCK dev->lock -#define UNLOCKED !dev->lock +#define LOCK dev->locked +#define UNLOCKED !dev->locked + +#define WD76C10_ADDR_INVALID 0x80000000 #ifdef ENABLE_WD76C10_LOG int wd76c10_do_log = ENABLE_WD76C10_LOG; - static void wd76c10_log(const char *fmt, ...) { va_list ap; - if (wd76c10_do_log) { + if (wd76c10_do_log) + { va_start(ap, fmt); pclog_ex(fmt, ap); va_end(ap); } } #else -# define wd76c10_log(fmt, ...) +#define wd76c10_log(fmt, ...) #endif -typedef struct wd76c10_t { - uint16_t lock_reg; - uint16_t oscillator_40mhz; - uint16_t cache_flush; - uint16_t ems_page_reg; - uint16_t ems_page_reg_pointer; - uint16_t port_shadow; - uint16_t pmc_interrupt; - uint16_t high_mem_protect_boundry; - uint16_t delay_line; - uint16_t diagnostic; - uint16_t nmi_status; - uint16_t pmc_input; - uint16_t pmc_timer; - uint16_t pmc_output; - uint16_t ems_control_low_address_boundry; - uint16_t shadow_ram; - uint16_t split_addr; - uint16_t bank32staddr; - uint16_t bank10staddr; - uint16_t non_page_mode_dram_timing; - uint16_t mem_control; - uint16_t refresh_control; - uint16_t disk_chip_select; - uint16_t prog_chip_sel_addr; - uint16_t bus_timing_power_down_ctl; - uint16_t clk_control; +typedef struct { + uint32_t enable; + uint32_t virt_addr, phys_addr; + uint32_t virt_size, phys_size; +} ram_bank_t; - int lock; +typedef struct { + uint8_t enabled; - fdc_t *fdc_controller; - mem_mapping_t *mem_mapping; - serial_t *uart[2]; + uint32_t virt, phys; + uint32_t size; +} ems_page_t; + +typedef struct +{ + uint8_t ep, p92; + + uint8_t vbios_states[4]; + uint8_t bios_states[8]; + uint8_t high_bios_states[8]; + uint8_t mem_pages[1024]; + + uint16_t toggle, cpuclk, fpu_ctl, mem_ctl, + split_sa, sh_wp, hmwpb, npmdmt, + ems_ctl, ems_pp, ser_par_cs, rtc_disk_cs, + prog_cs, pmc_in; + + union + { + uint16_t bank_base_regs[2]; + uint8_t bank_bases[4]; + }; + + uint16_t ems_page_regs[40]; + + int locked; + + uint32_t mem_top, hmwp_base; + + ram_bank_t ram_banks[5]; + + ems_page_t ems_pages[40]; + + mem_mapping_t ram_mapping; + + nvr_t *nvr; + + fdc_t *fdc; + serial_t *uart[2]; } wd76c10_t; -static void -wd76c10_refresh_control(wd76c10_t *dev) +static uint32_t bank_sizes[4] = { 0x00020000, /* 64 Kbit X 16 = 1024 Kbit = 128 kB, 8x 8 */ + 0x00080000, /* 256 Kbit X 16 = 4096 Kbit = 512 kB, 9x 9 */ + 0x00200000, /* 1 Mbit X 16 = 16 Mbit = 2 MB, 10x10 */ + 0x00800000 }; /* 4 Mbit X 16 = 64 Mbit = 8 MB, 11x11 */ + +static uint32_t +wd76c10_calc_addr(wd76c10_t *dev, uint32_t addr) +{ + uint32_t ret; + uint8_t ems_page; + uint8_t ems_en = (uint8_t) ((dev->ems_ctl >> 10) & 0x03); + ems_page_t *ep; + uint8_t en_res = (uint8_t) ((dev->ems_ctl >> 7) & 0x01); + uint32_t low_boundary = (((uint32_t) (dev->ems_ctl & 0x007f)) << 17) + 131072; + ram_bank_t *rb = &(dev->ram_banks[4]); + + addr &= 0x00ffffff; + ems_page = dev->mem_pages[addr >> 14]; + + ep = &dev->ems_pages[ems_page]; + + ret = addr; + + /* First, do any address translation (EMS, low boundary filtering). */ + if ((ems_page < 0x20) && (ems_en == 0x03)) + /* Low EMS pages. */ + ret = addr - ep->virt + ep->phys; + else if ((ems_page >= 0x20) && (ems_page < 0x2a) && (ems_en >= 0x02) && ep->enabled) + /* High EMS pages. */ + ret = addr - ep->virt + ep->phys; + else if (en_res && (addr >= low_boundary)) + /* EMS low boundary. */ + ret = WD76C10_ADDR_INVALID; + + /* Then, do the split. */ + if (rb->enable && (ret >= rb->virt_addr) && (ret < (rb->virt_addr + rb->virt_size))) + ret = ret - rb->virt_addr + rb->phys_addr; + + /* Then, disable the required amount of on-board memory between 128k and 640k if so requested. */ + if ((ret >= dev->mem_top) && (ret < 0x000a0000)) + ret = WD76C10_ADDR_INVALID; + + /* Then, handle the physical memory banks. */ + if (ret >= (mem_size << 10)) + /* The physical memory address is too high or disabled, which is invalid. */ + ret = WD76C10_ADDR_INVALID; + /* Otherwise, map it to the correct bank so the BIOS can auto-size it correctly. */ + else for (uint8_t i = 0; i < 4; i++) { + rb = &(dev->ram_banks[i]); + if (rb->enable && (ret >= rb->virt_addr) && (ret < (rb->virt_addr + rb->virt_size))) { + if (rb->phys_size == 0x00000000) + ret = WD76C10_ADDR_INVALID; + else + ret = ((ret - rb->virt_addr) % rb->phys_size) + rb->phys_addr; + break; + } + } + + return ret; +} + +static uint8_t +wd76c10_read_ram(uint32_t addr, void *priv) +{ + wd76c10_t *dev = (wd76c10_t *) priv; + uint8_t ret = 0xff; + + addr = wd76c10_calc_addr(dev, addr); + + if (addr != WD76C10_ADDR_INVALID) + ret = mem_read_ram(addr, priv); + + return ret; +} + +static uint16_t +wd76c10_read_ramw(uint32_t addr, void *priv) +{ + wd76c10_t *dev = (wd76c10_t *) priv; + uint16_t ret = 0xffff; + + addr = wd76c10_calc_addr(dev, addr); + + if (addr != WD76C10_ADDR_INVALID) + ret = mem_read_ramw(addr, priv); + + return ret; +} + +static void +wd76c10_write_ram(uint32_t addr, uint8_t val, void *priv) +{ + wd76c10_t *dev = (wd76c10_t *) priv; + + addr = wd76c10_calc_addr(dev, addr); + + if (addr != WD76C10_ADDR_INVALID) + mem_write_ram(addr, val, priv); +} + +static void +wd76c10_write_ramw(uint32_t addr, uint16_t val, void *priv) +{ + wd76c10_t *dev = (wd76c10_t *) priv; + + addr = wd76c10_calc_addr(dev, addr); + + if (addr != WD76C10_ADDR_INVALID) + mem_write_ramw(addr, val, priv); +} + +static void +wd76c10_banks_recalc(wd76c10_t *dev) +{ + for (uint8_t i = 0; i < 4; i++) { + ram_bank_t *rb = &(dev->ram_banks[i]); + uint8_t bit = i << 1; + rb->virt_size = bank_sizes[(dev->mem_ctl >> bit) & 0x03]; + bit = i + 12; + rb->enable = (dev->split_sa >> bit) & 0x01; + rb->virt_addr = ((uint32_t) dev->bank_bases[i]) << 17; + } +} + +static void +wd76c10_split_recalc(wd76c10_t *dev) +{ + uint32_t sp_size = (dev->split_sa >> 8) & 0x03; + uint32_t split_size = ((sp_size - 1) * 65536); + ram_bank_t *rb = &(dev->ram_banks[4]); + + if (rb->enable && (rb->virt_size != 0x00000000)) + mem_set_mem_state(rb->virt_addr, rb->virt_size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + rb->virt_addr = ((uint32_t) ((dev->split_sa >> 2) & 0x3f)) << 19; + switch (sp_size) { + case 0x00: + rb->virt_size = 0x00000000; + break; + default: + rb->virt_size = 256 * 1024 + split_size; + break; + } + rb->enable = !!sp_size; + if (rb->enable && (rb->virt_size != 0x00000000)) + mem_set_mem_state(rb->virt_addr, rb->virt_size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); +} + +static void +wd76c10_dis_mem_recalc(wd76c10_t *dev) +{ + uint8_t dis_mem = (uint8_t) ((dev->sh_wp >> 14) & 0x03); + uint32_t mem_top; + + switch (dis_mem) { + case 0x00: + default: + mem_top = 640 * 1024; + break; + case 0x01: + mem_top = 512 * 1024; + break; + case 0x02: + mem_top = 256 * 1024; + break; + case 0x03: + mem_top = 128 * 1024; + break; + } + + dev->mem_top = mem_top; +} + +static void +wd76c10_shadow_ram_do_recalc(uint8_t *new_st, uint8_t *old_st, uint8_t min, uint8_t max, uint32_t addr) +{ + uint32_t base = 0x00000000; + int flags = 0; + + for (uint8_t i = min; i < max; i++) { + if (new_st[i] != old_st[i]) { + old_st[i] = new_st[i]; + base = addr + ((uint32_t) i) * 0x00004000; + flags = (new_st[i] & 0x01) ? MEM_READ_INTERNAL : + ((new_st[i] & 0x04) ? MEM_READ_ROMCS : MEM_READ_EXTERNAL); + flags |= (new_st[i] & 0x02) ? MEM_WRITE_INTERNAL : + ((new_st[i] & 0x04) ? MEM_WRITE_ROMCS : MEM_WRITE_EXTERNAL); + mem_set_mem_state_both(base, 0x00004000, flags); + } + } +} + + +static void +wd76c10_shadow_ram_recalc(wd76c10_t *dev) +{ + uint8_t vbios_states[4] = { 0 }; + uint8_t bios_states[8] = { 0 }; + uint8_t high_bios_states[8] = { 0 }; + uint8_t wp = (uint8_t) ((dev->sh_wp >> 12) & 0x01); + uint8_t shd = (uint8_t) ((dev->sh_wp >> 8) & 0x03); + uint8_t x_mem = (uint8_t) ((dev->sh_wp >> 7) & 0x01); + uint8_t vb_siz = (uint8_t) ((dev->sh_wp >> 4) & 0x03); + uint8_t vb_top = vb_siz + 1; + uint8_t rom_typ = (uint8_t) ((dev->sh_wp >> 2) & 0x03); + + switch (shd) { + case 0x03: + for (uint8_t i = 0; i < vb_top; i++) { + vbios_states[i] |= 0x01; /* Read. */ + if (!wp) + vbios_states[i] |= 0x02; /* Write. */ + } + if (x_mem) { + for (uint8_t i = 2; i < 4; i++) + bios_states[i] |= 0x03; /* Read/write. */ + } + fallthrough; + case 0x01: + for (uint8_t i = 4; i < 8; i++) { + bios_states[i] |= 0x01; /* Read. */ + if (!wp) + bios_states[i] |= 0x02; /* Write. */ + } + break; + case 0x02: + for (uint8_t i = 0; i < 8; i++) { + bios_states[i] |= 0x01; /* Read. */ + if (!wp) + bios_states[i] |= 0x02; /* Write. */ + } + break; + } + + switch (rom_typ) { + case 0x00: + for (uint8_t i = 0; i < 8; i++) { + bios_states[i] |= 0x04; /* CSPROM#. */ + high_bios_states[i] |= 0x04; /* CSPROM#. */ + } + break; + case 0x02: + for (uint8_t i = 0; i < vb_top; i++) + vbios_states[i] |= 0x04; /* CSPROM#. */ + fallthrough; + case 0x01: + for (uint8_t i = 4; i < 8; i++) { + bios_states[i] |= 0x04; /* CSPROM#. */ + high_bios_states[i] |= 0x04; /* CSPROM#. */ + } + break; + } + + wd76c10_shadow_ram_do_recalc(vbios_states, dev->vbios_states, 0, 4, 0x000c0000); + wd76c10_shadow_ram_do_recalc(bios_states, dev->bios_states, 0, 8, 0x000e0000); + + /* This is not shadowed, but there is a CSPROM# (= ROMCS#) toggle. */ + wd76c10_shadow_ram_do_recalc(high_bios_states, dev->high_bios_states, 0, 8, 0x00fe0000); + + flushmmucache_nopc(); +} + +static void +wd76c10_high_mem_wp_recalc(wd76c10_t *dev) +{ + uint8_t hm_wp = (uint8_t) ((dev->sh_wp >> 13) & 0x01); + uint32_t base = ((uint32_t) (dev->hmwpb & 0x00f0)) << 17; + uint32_t size = 0x01000000 - dev->hmwp_base; + + /* ACCESS_NORMAL means both ACCESS_BUS and ACCESS_CPU are set. */ + mem_set_wp(dev->hmwp_base, size, ACCESS_NORMAL, 0); + + size = 0x01000000 - base; + mem_set_wp(base, size, ACCESS_NORMAL, hm_wp); + + dev->hmwp_base = base; +} + +static void +wd76c10_pf_loc_reset(wd76c10_t *dev) +{ + uint32_t base; + + for (uint8_t i = 0x031; i <= 0x03b; i++) { + dev->mem_pages[i] = 0xff; + base = ((uint32_t) i) << 14; + mem_set_mem_state(base, 0x00004000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + } + + /* Re-apply any ROMCS#, etc. flags. */ + wd76c10_shadow_ram_recalc(dev); +} + +static void +wd76c10_pf_loc_recalc(wd76c10_t *dev) +{ + uint8_t pf_loc = (uint8_t) ((dev->ems_ctl >> 13) & 0x03); + uint8_t ems_en = (uint8_t) ((dev->ems_ctl >> 10) & 0x03); + uint8_t ems_page; + uint32_t base; + + for (uint8_t i = (0x031 + pf_loc); i <= (0x037 + pf_loc); i++) { + ems_page = (i - 0x10) & 0xf7; + dev->mem_pages[i] = ems_page; + base = ((uint32_t) i) << 14; + dev->ems_pages[ems_page].virt = base; + if ((ems_en >= 0x02) && dev->ems_pages[ems_page].enabled) + mem_set_mem_state(dev->ems_pages[ems_page].virt, 0x00004000, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } +} + +static void +wd76c10_low_pages_recalc(wd76c10_t *dev) +{ + uint8_t ems_page; + uint32_t base; + + for (uint8_t i = 0x008; i <= 0x027; i++) { + ems_page = i & 0x1f; + dev->mem_pages[i] = ems_page; + base = ((uint32_t) i) << 14; + dev->ems_pages[ems_page].virt = base; + } +} + +static void +wd76c10_ser_par_cs_recalc(wd76c10_t *dev) { - serial_remove(dev->uart[1]); /* Serial B */ - switch ((dev->refresh_control >> 1) & 7) { - case 1: + serial_remove(dev->uart[1]); + switch ((dev->ser_par_cs >> 1) & 0x07) { + case 0x01: serial_setup(dev->uart[1], 0x3f8, 3); break; - case 2: + case 0x02: serial_setup(dev->uart[1], 0x2f8, 3); break; - case 3: + case 0x03: serial_setup(dev->uart[1], 0x3e8, 3); break; - case 4: + case 0x04: serial_setup(dev->uart[1], 0x2e8, 3); break; - default: - break; } - serial_remove(dev->uart[0]); /* Serial A */ - switch ((dev->refresh_control >> 5) & 7) { - case 1: + serial_remove(dev->uart[0]); + switch ((dev->ser_par_cs >> 5) & 0x07) { + case 0x01: serial_setup(dev->uart[0], 0x3f8, 4); break; - case 2: + case 0x02: serial_setup(dev->uart[0], 0x2f8, 4); break; - case 3: + case 0x03: serial_setup(dev->uart[0], 0x3e8, 4); break; - case 4: + case 0x04: serial_setup(dev->uart[0], 0x2e8, 4); break; - default: - break; } - lpt1_remove(); /* LPT */ - switch ((dev->refresh_control >> 9) & 3) { + lpt1_remove(); + switch ((dev->ser_par_cs >> 9) & 0x03) { case 1: lpt1_init(0x3bc); lpt1_irq(7); @@ -155,413 +491,463 @@ wd76c10_refresh_control(wd76c10_t *dev) lpt1_init(0x278); lpt1_irq(7); break; - - default: - break; } } static void -wd76c10_split_addr(wd76c10_t *dev) -{ - switch ((dev->split_addr >> 8) & 3) { - case 1: - if (((dev->shadow_ram >> 8) & 3) == 2) - mem_remap_top(256); - break; - case 2: - if (((dev->shadow_ram >> 8) & 3) == 1) - mem_remap_top(320); - break; - case 3: - if (((dev->shadow_ram >> 8) & 3) == 3) - mem_remap_top(384); - break; - default: - break; - } -} - -static void -wd76c10_disk_chip_select(wd76c10_t *dev) +wd76c10_disk_cs_recalc(wd76c10_t *dev) { ide_pri_disable(); - if (!(dev->disk_chip_select & 1)) { - ide_set_base(0, !(dev->disk_chip_select & 0x0010) ? 0x1f0 : 0x170); - ide_set_side(0, !(dev->disk_chip_select & 0x0010) ? 0x3f6 : 0x376); - } - ide_pri_enable(); + ide_set_base(0, (dev->rtc_disk_cs & 0x0010) ? 0x0170 : 0x01f0); + ide_set_side(0, (dev->rtc_disk_cs & 0x0010) ? 0x0376 : 0x03f6); + if (!(dev->rtc_disk_cs & 0x0002)) + ide_pri_enable(); - fdc_remove(dev->fdc_controller); - if (!(dev->disk_chip_select & 2)) - fdc_set_base(dev->fdc_controller, !(dev->disk_chip_select & 0x0010) ? FDC_PRIMARY_ADDR : FDC_SECONDARY_ADDR); + fdc_remove(dev->fdc); + if (!(dev->rtc_disk_cs & 0x0001)) + fdc_set_base(dev->fdc, (dev->rtc_disk_cs & 0x0010) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR); } static void -wd76c10_shadow_recalc(wd76c10_t *dev) +wd76c10_outb(uint16_t port, uint8_t val, void *priv) { - switch ((dev->shadow_ram >> 14) & 3) { - case 0: - mem_set_mem_state_both(0x20000, 0x80000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - case 1: - mem_set_mem_state_both(0x80000, 0x20000, MEM_READ_DISABLED | MEM_WRITE_DISABLED); - break; - case 2: - mem_set_mem_state_both(0x40000, 0x60000, MEM_READ_DISABLED | MEM_WRITE_DISABLED); - break; - case 3: - mem_set_mem_state_both(0x20000, 0x80000, MEM_READ_DISABLED | MEM_WRITE_DISABLED); - break; - default: - break; - } + wd76c10_t *dev = (wd76c10_t *)priv; + uint8_t lk_psw = (uint8_t) ((dev->rtc_disk_cs >> 2) & 0x01); + uint8_t valxor; - switch ((dev->shadow_ram >> 8) & 3) { - case 0: - mem_set_mem_state_both(0xe0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - mem_set_mem_state_both(0xc0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - break; - case 1: - mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_INTERNAL | (!!(dev->shadow_ram & 0x1000) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)); - break; - case 2: - mem_set_mem_state_both(0xe0000, 0x20000, MEM_READ_INTERNAL | (!!(dev->shadow_ram & 0x1000) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)); - break; - case 3: - mem_set_mem_state_both(0x20000, 0x80000, MEM_READ_DISABLED | (!!(dev->shadow_ram & 0x1000) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)); - break; - default: + switch (port) { + case 0x0092: + if ((lk_psw && (val & 0x08)) || ((dev->p92 & 0x08) && !(val & 0x08))) + val = (val & 0xf7) | (dev->p92 & 0x08); + + valxor = (dev->p92 ^ val) & 0x08; + dev->p92 = (val & 0x08) | 0xf7; + + if (valxor) + nvr_lock_set(0x38, 0x08, (val & 0x08) ? 0x03 : 0x00, dev->nvr); break; } } static void -wd76c10_write(uint16_t addr, uint16_t val, void *priv) +wd76c10_outw(uint16_t port, uint16_t val, void *priv) { - wd76c10_t *dev = (wd76c10_t *) priv; + wd76c10_t *dev = (wd76c10_t *)priv; + uint8_t inc = (uint8_t) ((dev->ems_ctl >> 15) & 0x01); + uint8_t ems_en; - if (UNLOCKED) { - switch (addr) { - case 0x1072: - dev->clk_control = val; - break; + if (!dev->locked || (port < 0x1072) || (port > 0xf872) || + (port == 0xe072) || (port == 0xe872) || (port == 0xf073)) switch (port) { + case 0x1072: + dev->cpuclk = val; + break; - case 0x1872: - dev->bus_timing_power_down_ctl = val; - break; + case 0x1872: + dev->fpu_ctl = val; + break; - case 0x2072: - dev->refresh_control = val; - wd76c10_refresh_control(dev); - break; + case 0x2072: + dev->ser_par_cs = val; + wd76c10_ser_par_cs_recalc(dev); + break; - case 0x2872: - dev->disk_chip_select = val; - wd76c10_disk_chip_select(dev); - break; + case 0x2872: + dev->rtc_disk_cs = val; + wd76c10_disk_cs_recalc(dev); + break; - case 0x3072: - dev->prog_chip_sel_addr = val; - break; + case 0x3072: + dev->prog_cs = val; + break; - case 0x3872: - dev->non_page_mode_dram_timing = val; - break; + /* TODO: Log this to determine how the BIOS does bank sizing. */ + case 0x3872: + dev->mem_ctl = val; + wd76c10_banks_recalc(dev); + break; - case 0x4072: - dev->mem_control = val; - break; + case 0x4072: + dev->npmdmt = val; + break; - case 0x4872: - dev->bank10staddr = val; - break; + /* A17-A24 */ + case 0x4872: + dev->bank_base_regs[0] = val; + wd76c10_banks_recalc(dev); + break; - case 0x5072: - dev->bank32staddr = val; - break; + /* A17-A24 */ + case 0x5072: + dev->bank_base_regs[1] = val; + wd76c10_banks_recalc(dev); + break; - case 0x5872: - dev->split_addr = val; - wd76c10_split_addr(dev); - break; + case 0x5872: + dev->split_sa = val; + wd76c10_banks_recalc(dev); + wd76c10_split_recalc(dev); + break; - case 0x6072: - dev->shadow_ram = val & 0xffbf; - wd76c10_shadow_recalc(dev); - break; + case 0x6072: + dev->sh_wp = val; + wd76c10_dis_mem_recalc(dev); + wd76c10_pf_loc_reset(dev); + wd76c10_pf_loc_recalc(dev); + wd76c10_low_pages_recalc(dev); + wd76c10_high_mem_wp_recalc(dev); + break; - case 0x6872: - dev->ems_control_low_address_boundry = val & 0xecff; - break; + case 0x6872: + dev->ems_ctl = val; + wd76c10_pf_loc_reset(dev); + wd76c10_pf_loc_recalc(dev); + wd76c10_low_pages_recalc(dev); + break; - case 0x7072: - dev->pmc_output = (val >> 8) & 0x00ff; - break; + case 0x8872: + dev->pmc_in = val; + break; - case 0x7872: - dev->pmc_output = val & 0xff00; - break; + case 0xc072: + dev->hmwpb = val; + wd76c10_high_mem_wp_recalc(dev); + break; - case 0x8072: - dev->pmc_timer = val; - break; - - case 0x8872: - dev->pmc_input = val; - break; - - case 0x9072: - dev->nmi_status = val & 0x00fc; - break; - - case 0x9872: - dev->diagnostic = val & 0xfdff; - break; - - case 0xa072: - dev->delay_line = val; - break; - - case 0xc872: - dev->pmc_interrupt = val & 0xfcfc; - break; - - case 0xf072: - dev->oscillator_40mhz = 0; - break; - - case 0xf472: - dev->oscillator_40mhz = 1; - break; - - case 0xf872: - dev->cache_flush = val; - flushmmucache(); - break; - - default: - break; - } - wd76c10_log("WD76C10: dev->regs[%04x] = %04x\n", addr, val); - } - - switch (addr) { case 0xe072: - dev->ems_page_reg_pointer = val & 0x003f; + dev->ems_pp = val; + dev->ep = (val & 0x3f) % 40; break; case 0xe872: - dev->ems_page_reg = val & 0x8fff; + ems_en = (uint8_t) ((dev->ems_ctl >> 10) & 0x03); + if (ems_en) { + dev->ems_page_regs[dev->ep] = val; + dev->ems_pages[dev->ep].phys = ((uint32_t) (val & 0x0fff)) << 14; + if (dev->ep >= 32) { + dev->ems_pages[dev->ep].enabled = !!(val & 0x8000); + if (ems_en >= 0x02) { + wd76c10_pf_loc_reset(dev); + wd76c10_pf_loc_recalc(dev); + } + } else { + dev->ems_pages[dev->ep].enabled = (ems_en == 0x03); + if (ems_en == 0x03) + wd76c10_low_pages_recalc(dev); + } + } + if (inc) + dev->ep = (dev->ep + 1) % 40; break; case 0xf073: - dev->lock_reg = val & 0x00ff; - LOCK = !(val & 0x00da); + dev->locked = ((val & 0x00ff) != 0x00da); break; - default: + case 0xf872: + flushmmucache(); break; } } -static uint16_t -wd76c10_read(uint16_t addr, void *priv) +static uint8_t +wd76c10_inb(uint16_t port, void *priv) { - const wd76c10_t *dev = (wd76c10_t *) priv; + wd76c10_t *dev = (wd76c10_t *)priv; + uint8_t ret = 0xff; - wd76c10_log("WD76C10: R dev->regs[%04x]\n", addr); - switch (addr) { + switch (port) { + case 0x0092: + ret = (dev->p92 & 0x08) | 0xf7; + break; + } + + return ret; +} + +static uint16_t +wd76c10_inw(uint16_t port, void *priv) +{ + wd76c10_t *dev = (wd76c10_t *)priv; + uint8_t inc = (uint8_t) ((dev->ems_ctl >> 15) & 0x01); + uint16_t ret = 0xffff; + + wd76c10_log("WD76C10: R dev->regs[%04x]\n", port); + + if (!dev->locked || (port < 0x1072) || (port > 0xf872) || + (port == 0xe072) || (port == 0xe872) || (port == 0xf073)) switch (port) { case 0x1072: - return dev->clk_control; + ret = dev->cpuclk; + break; case 0x1872: - return dev->bus_timing_power_down_ctl; + ret = dev->fpu_ctl; + break; case 0x2072: - return dev->refresh_control; + ret = dev->ser_par_cs; + break; case 0x2872: - return dev->disk_chip_select; + ret = dev->rtc_disk_cs; + break; case 0x3072: - return dev->prog_chip_sel_addr; + ret = dev->prog_cs; + break; case 0x3872: - return dev->non_page_mode_dram_timing; + ret = dev->mem_ctl; + break; case 0x4072: - return dev->mem_control; + ret = dev->npmdmt; + break; case 0x4872: - return dev->bank10staddr; + ret = dev->bank_base_regs[0]; + break; case 0x5072: - return dev->bank32staddr; + ret = dev->bank_base_regs[1]; + break; case 0x5872: - return dev->split_addr; + ret = dev->split_sa; + break; case 0x6072: - return dev->shadow_ram; + ret = dev->sh_wp; + break; case 0x6872: - return dev->ems_control_low_address_boundry; - - case 0x7072: - return (dev->pmc_output << 8) & 0xff00; - - case 0x7872: - return (dev->pmc_output) & 0xff00; - - case 0x8072: - return dev->pmc_timer; + ret = dev->ems_ctl; + break; case 0x8872: - return dev->pmc_input; - - case 0x9072: - return dev->nmi_status; - - case 0x9872: - return dev->diagnostic; - - case 0xa072: - return dev->delay_line; + ret = dev->pmc_in; + break; case 0xb872: - return (inb(0x040b) << 8) | inb(0x04d6); + ret = dma[0].mode; + ret |= (((uint16_t) dma[1].mode) << 8); + break; - case 0xc872: - return dev->pmc_interrupt; + case 0xc072: + ret = dev->hmwpb; + break; case 0xd072: - return dev->port_shadow; + ret = (serial_read(0x0002, dev->uart[0]) & 0xc0) << 8; + ret |= (serial_read(0x0002, dev->uart[1]) & 0xc0) << 6; + ret |= (lpt_read_port(0, 0x0002) & 0x0f) << 8; + ret |= lpt_read_port(0, 0x0000); + break; case 0xe072: - return dev->ems_page_reg_pointer; + ret = (dev->ems_pp & 0xffc0) | dev->ep; + break; case 0xe872: - return dev->ems_page_reg; + ret = dev->ems_page_regs[dev->ep]; + if (inc) + dev->ep = (dev->ep + 1) % 40; + break; case 0xfc72: - return 0x0ff0; - - default: - return 0xffff; + ret = ((lpt_read_status(0) & 0x20) >> 2); + ret |= (((uint16_t) dma_m) << 4); + ret |= dev->toggle; + dev->toggle ^= 0x8000; + break; } + + return ret; } static void wd76c10_close(void *priv) { - wd76c10_t *dev = (wd76c10_t *) priv; + wd76c10_t *dev = (wd76c10_t *)priv; free(dev); } -static void * -wd76c10_init(UNUSED(const device_t *info)) + +static void +wd76c10_reset(void *priv) { - wd76c10_t *dev = (wd76c10_t *) malloc(sizeof(wd76c10_t)); - memset(dev, 0, sizeof(wd76c10_t)); + wd76c10_t *dev = (wd76c10_t *)priv; + + dev->locked = 1; + dev->toggle = 0; + + dev->p92 = 0xf7; + + dev->cpuclk = 0x1000; + dev->fpu_ctl = 0x00ca; + dev->mem_ctl = 0x0000; + dev->bank_base_regs[0] = 0x0000; + dev->bank_base_regs[1] = 0x0000; + dev->split_sa = 0x0000; + dev->sh_wp = 0x0000; + dev->hmwpb = 0x0000; + dev->npmdmt = 0x0000; + dev->ems_ctl = 0x0000; + dev->ems_pp = 0x0000; + dev->ser_par_cs = 0x0000; + dev->rtc_disk_cs = 0x0000; + + for (uint8_t i = 0; i < 40; i++) { + dev->ems_page_regs[i] = 0x0000; + dev->ems_pages[i].enabled = 0; + dev->ems_pages[i].phys = 0x00000000; + } + + nvr_lock_set(0x38, 0x08, 0x00, dev->nvr); + + wd76c10_banks_recalc(dev); + wd76c10_split_recalc(dev); + wd76c10_dis_mem_recalc(dev); + wd76c10_high_mem_wp_recalc(dev); + wd76c10_pf_loc_reset(dev); + wd76c10_pf_loc_recalc(dev); + wd76c10_low_pages_recalc(dev); + wd76c10_ser_par_cs_recalc(dev); + wd76c10_disk_cs_recalc(dev); +} + + +static void * +wd76c10_init(const device_t *info) +{ + wd76c10_t *dev = (wd76c10_t *) calloc(1, sizeof(wd76c10_t)); + uint32_t total_mem = mem_size << 10; + uint32_t accum_mem = 0x00000000; + ram_bank_t *rb; + + /* Calculate the physical RAM banks. */ + for (uint8_t i = 0; i < 4; i++) { + rb = &(dev->ram_banks[i]); + uint32_t size = 0x00000000; + for (int8_t j = 3; j >= 0; j--) { + uint32_t *bs = &(bank_sizes[j]); + if (*bs <= total_mem) { + size = *bs; + break; + } + } + if (size != 0x00000000) { + rb->phys_addr = accum_mem; + rb->phys_size = size; + total_mem -= size; + accum_mem += size; + } + } + + rb = &(dev->ram_banks[4]); + rb->phys_addr = 0x000a0000; + rb->phys_size = 0x00060000; + + memset(dev->mem_pages, 0xff, sizeof(dev->mem_pages)); + for (uint8_t i = 0x008; i < 0x01f; i++) + dev->mem_pages[i] = i; + for (uint8_t i = 0x020; i < 0x027; i++) + dev->mem_pages[i] = i - 0x20; device_add(&port_92_inv_device); - dev->uart[0] = device_add_inst(&ns16450_device, 1); - dev->uart[1] = device_add_inst(&ns16450_device, 2); - dev->fdc_controller = device_add(&fdc_at_device); + dev->nvr = device_add(&amstrad_megapc_nvr_device); + dev->uart[0] = device_add_inst(&ns16450_device, 1); + dev->uart[1] = device_add_inst(&ns16450_device, 2); + dev->fdc = device_add(&fdc_at_device); device_add(&ide_isa_device); - /* Lock Configuration */ - LOCK = 1; + wd76c10_reset(dev); + + /* Password Lock */ + io_sethandler(0x0092, 1, wd76c10_inb, NULL, NULL, wd76c10_outb, NULL, NULL, dev); /* Clock Control */ - io_sethandler(0x1072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + io_sethandler(0x1072, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); - /* Bus Timing & Power Down Control */ - io_sethandler(0x1872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + /* FPU Bus Timing & Power Down Control */ + io_sethandler(0x1872, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); - /* Refresh Control(Serial & Parallel) */ - io_sethandler(0x2072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + /* Refresh Control, Serial and Parallel Chip Selects */ + io_sethandler(0x2072, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); - /* Disk Chip Select */ - io_sethandler(0x2872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + /* RTC, PVGA, 80287 Timing, and Disk Chip Selects */ + io_sethandler(0x2872, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); - /* Programmable Chip Select Address(Needs more further examination!) */ - io_sethandler(0x3072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + /* Programmable Chip Select Address */ + io_sethandler(0x3072, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); + + /* Memory Control */ + io_sethandler(0x3872, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); + + /* Non-page Mode DRAM Memory Timing */ + io_sethandler(0x4072, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); /* Bank 1 & 0 Start Address */ - io_sethandler(0x4872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + io_sethandler(0x4872, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); /* Bank 3 & 2 Start Address */ - io_sethandler(0x5072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + io_sethandler(0x5072, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); /* Split Address */ - io_sethandler(0x5872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + io_sethandler(0x5872, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); - /* EMS Control & EMS Low level boundry */ - io_sethandler(0x6072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + /* RAM Shadow And Write Protect */ + io_sethandler(0x6072, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); - /* EMS Control & EMS Low level boundry */ - io_sethandler(0x6872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + /* EMS Control And Lower EMS Boundary */ + io_sethandler(0x6872, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); - /* PMC Output */ - io_sethandler(0x7072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + /* PMC Inputs */ + io_sethandler(0x8872, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); - /* PMC Output */ - io_sethandler(0x7872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + /* DMA Mode Shadow Register */ + io_sethandler(0xb872, 1, NULL, wd76c10_inw, NULL, NULL, NULL, NULL, dev); - /* PMC Status */ - io_sethandler(0x8072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + /* High Memory Write Protect Boundry */ + io_sethandler(0xc072, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); - /* PMC Status */ - io_sethandler(0x8872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); - - /* NMI Status (Needs further checkup) */ - io_sethandler(0x9072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); - - /* Diagnostics */ - io_sethandler(0x9872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); - - /* Delay Line */ - io_sethandler(0xa072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); - - /* DMA Mode Shadow(Needs Involvement on the DMA code) */ - io_sethandler(0xb872, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev); - - /* High Memory Protection Boundry */ - io_sethandler(0xc072, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev); - - /* PMC Interrupt Enable */ - io_sethandler(0xc872, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev); - - /* Port Shadow (Needs further lookup) */ - io_sethandler(0xd072, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev); + /* Shadow Register */ + io_sethandler(0xd072, 1, NULL, wd76c10_inw, NULL, NULL, NULL, NULL, dev); /* EMS Page Register Pointer */ - io_sethandler(0xe072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + io_sethandler(0xe072, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); /* EMS Page Register */ - io_sethandler(0xe872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + io_sethandler(0xe872, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); /* Lock/Unlock Configuration */ - io_sethandler(0xf073, 1, NULL, NULL, NULL, NULL, wd76c10_write, NULL, dev); - - /* 40Mhz Oscillator Enable Disable */ - io_sethandler(0xf072, 1, NULL, NULL, NULL, NULL, wd76c10_write, NULL, dev); - io_sethandler(0xf472, 1, NULL, NULL, NULL, NULL, wd76c10_write, NULL, dev); - - /* Lock Status */ - io_sethandler(0xfc72, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev); + io_sethandler(0xf073, 1, NULL, NULL, NULL, NULL, wd76c10_outw, NULL, dev); /* Cache Flush */ - io_sethandler(0xf872, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev); + io_sethandler(0xf872, 1, NULL, NULL, NULL, NULL, wd76c10_outw, NULL, dev); + + /* Lock Status */ + io_sethandler(0xfc72, 1, NULL, wd76c10_inw, NULL, NULL, NULL, NULL, dev); dma_ext_mode_init(); - wd76c10_shadow_recalc(dev); - wd76c10_refresh_control(dev); - wd76c10_disk_chip_select(dev); + mem_mapping_add(&dev->ram_mapping, + 0x00000000, + (mem_size + 384) << 10, + wd76c10_read_ram, + wd76c10_read_ramw, + NULL, + wd76c10_write_ram, + wd76c10_write_ramw, + NULL, + ram, + MEM_MAPPING_INTERNAL, + dev); + mem_mapping_disable(&ram_low_mapping); + mem_mapping_disable(&ram_mid_mapping); + mem_mapping_disable(&ram_high_mapping); + mem_mapping_enable(&dev->ram_mapping); + return dev; } diff --git a/src/include/86box/device.h b/src/include/86box/device.h index f5efb5dbb..71a76c6b1 100644 --- a/src/include/86box/device.h +++ b/src/include/86box/device.h @@ -41,23 +41,41 @@ #ifndef EMU_DEVICE_H #define EMU_DEVICE_H -#define CONFIG_END -1 -#define CONFIG_STRING 0 -#define CONFIG_INT 1 -#define CONFIG_BINARY 2 -#define CONFIG_SELECTION 3 -#define CONFIG_MIDI_OUT 4 -#define CONFIG_FNAME 5 -#define CONFIG_SPINNER 6 -#define CONFIG_HEX16 7 -#define CONFIG_HEX20 8 -#define CONFIG_MAC 9 -#define CONFIG_MIDI_IN 10 -#define CONFIG_BIOS 11 -#define CONFIG_SERPORT 12 +#define CONFIG_END -1 /* N/A */ -#define CONFIG_ONBOARD 256 /* only avaialble on the on-board variant */ -#define CONFIG_STANDALONE 257 /* not available on the on-board variant */ +#define CONFIG_SHIFT 4 + +#define CONFIG_TYPE_INT (0 << CONFIG_SHIFT) +#define CONFIG_TYPE_STRING (1 << CONFIG_SHIFT) +#define CONFIG_TYPE_HEX16 (2 << CONFIG_SHIFT) +#define CONFIG_TYPE_HEX20 (3 << CONFIG_SHIFT) +#define CONFIG_TYPE_MAC (4 << CONFIG_SHIFT) + +#define CONFIG_INT (0 | CONFIG_TYPE_INT) /* config_get_int() */ +#define CONFIG_BINARY (1 | CONFIG_TYPE_INT) /* config_get_int() */ +#define CONFIG_SELECTION (2 | CONFIG_TYPE_INT) /* config_get_int() */ +#define CONFIG_MIDI_OUT (3 | CONFIG_TYPE_INT) /* config_get_int() */ +#define CONFIG_SPINNER (4 | CONFIG_TYPE_INT) /* config_get_int() */ +#define CONFIG_MIDI_IN (5 | CONFIG_TYPE_INT) /* config_get_int() */ + +#define CONFIG_STRING (0 | CONFIG_TYPE_STRING) /* config_get_string() */ +#define CONFIG_FNAME (1 | CONFIG_TYPE_STRING) /* config_get_string() */ +#define CONFIG_SERPORT (2 | CONFIG_TYPE_STRING) /* config_get_string() */ +#define CONFIG_BIOS (3 | CONFIG_TYPE_STRING) /* config_get_string() */ + +#define CONFIG_HEX16 (0 | CONFIG_TYPE_HEX16) /* config_get_hex16() */ + +#define CONFIG_HEX20 (0 | CONFIG_TYPE_HEX20) /* config_get_hex20() */ + +#define CONFIG_MAC (0 | CONFIG_TYPE_MAC) /* N/A */ + +#define CONFIG_SUBTYPE_MASK (CONFIG_IS_STRING - 1) + +#define CONFIG_DEP (16 << CONFIG_SHIFT) +#define CONFIG_TYPE_MASK (CONFIG_DEP - 1) + +// #define CONFIG_ONBOARD 256 /* only avaialble on the on-board variant */ +// #define CONFIG_STANDALONE 257 /* not available on the on-board variant */ enum { DEVICE_PCJR = 2, /* requires an IBM PCjr */ @@ -100,38 +118,49 @@ enum { #define BIOS_INTERLEAVED_INVERT 8 #define BIOS_HIGH_BIT_INVERT 16 +#define device_common_config_t \ + const char *name; \ + const char *description; \ + int type; \ + const char *default_string; \ + int default_int; \ + const char *file_filter; \ + const device_config_spinner_t spinner; \ + const device_config_selection_t selection[32] + typedef struct device_config_selection_t { const char *description; int value; } device_config_selection_t; -typedef struct device_config_bios_t { - const char *name; - const char *internal_name; - int bios_type; - int files_no; - uint32_t local; - uint32_t size; - void *dev1; - void *dev2; - const char *files[9]; -} device_config_bios_t; - typedef struct device_config_spinner_t { int16_t min; int16_t max; int16_t step; } device_config_spinner_t; -typedef struct device_config_t { - const char *name; - const char *description; - int type; - const char *default_string; - int default_int; - const char *file_filter; - const device_config_spinner_t spinner; - const device_config_selection_t selection[32]; +typedef struct _device_dep_config_ { + device_common_config_t; +} device_dep_config_t; + +typedef struct device_config_bios_t { + const char *name; + const char *internal_name; + int bios_type; + int files_no; + uint32_t local; + uint32_t size; + void *dev1; + void *dev2; + const char *files[9]; + /* Configuration options that depend on the device variant. + To prevent excessive nesting, there is no CONFIG_BIOS + option a dep_config struct */ + const device_dep_config_t *dep_config; +} device_config_bios_t; + +typedef struct _device_config_ { + device_common_config_t; const device_config_bios_t bios[32]; } device_config_t; diff --git a/src/include/86box/serial.h b/src/include/86box/serial.h index bd7e85a91..08f77ea13 100644 --- a/src/include/86box/serial.h +++ b/src/include/86box/serial.h @@ -124,11 +124,11 @@ extern void serial_set_next_inst(int ni); extern void serial_standalone_init(void); extern void serial_set_clock_src(serial_t *dev, double clock_src); extern void serial_reset_port(serial_t *dev); +extern uint8_t serial_read(uint16_t addr, void *priv); extern void serial_device_timeout(void *priv); - -extern void serial_set_cts(serial_t *dev, uint8_t enabled); -extern void serial_set_dsr(serial_t *dev, uint8_t enabled); -extern void serial_set_dcd(serial_t *dev, uint8_t enabled); +extern void serial_set_cts(serial_t *dev, uint8_t enabled); +extern void serial_set_dsr(serial_t *dev, uint8_t enabled); +extern void serial_set_dcd(serial_t *dev, uint8_t enabled); extern const device_t ns8250_device; extern const device_t ns8250_pcjr_device; diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index 0153c0fe7..a688181b4 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -554,7 +554,7 @@ machine_at_wd76c10_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); if (gfxcard[0] == VID_INTERNAL) device_add(¶dise_wd90c11_megapc_device); From 285accae5bdbbd98700a10220661b298a7ed25fb Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 2 Feb 2024 05:34:38 +0100 Subject: [PATCH 412/936] Gigabyte 430LX and 430NX machine fixes. --- src/include/86box/machine.h | 4 +-- src/machine/m_at_socket4.c | 53 +++++++++++++++++-------------------- src/machine/m_at_socket5.c | 6 ++--- src/machine/machine_table.c | 8 +++--- 4 files changed, 32 insertions(+), 39 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index da52c68f5..f8267539b 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -607,7 +607,7 @@ extern int machine_at_opti560l_init(const machine_t *); extern int machine_at_ambradp60_init(const machine_t *); extern int machine_at_valuepointp60_init(const machine_t *); extern int machine_at_revenge_init(const machine_t *); -extern int machine_at_586mc1_init(const machine_t *); +extern int machine_at_586is_init(const machine_t *); extern int machine_at_pb520r_init(const machine_t *); extern int machine_at_excalibur_init(const machine_t *); @@ -621,7 +621,7 @@ extern int machine_at_p5sp4_init(const machine_t *); extern int machine_at_plato_init(const machine_t *); extern int machine_at_dellplato_init(const machine_t *); extern int machine_at_ambradp90_init(const machine_t *); -extern int machine_at_430nx_init(const machine_t *); +extern int machine_at_586ip_init(const machine_t *); extern int machine_at_tek932_init(const machine_t *); extern int machine_at_acerv30_init(const machine_t *); diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index 2d7ebe0f9..02018949c 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -60,31 +60,6 @@ machine_at_premiere_common_init(const machine_t *model, int pci_switch) device_add(&intel_flash_bxt_ami_device); } -void -machine_at_award_common_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&ide_pci_2ch_device); - - pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x01, PCI_CARD_IDE, 0, 0, 0, 0); - pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 03 = Slot 1 */ - pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 04 = Slot 2 */ - pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 05 = Slot 3 */ - pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 06 = Slot 4 */ - pci_register_slot(0x07, PCI_CARD_SCSI, 1, 2, 3, 4); /* 07 = SCSI */ - pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - - if (fdc_type == FDC_INTERNAL) - device_add(&fdc_at_device); - -#if 0 - device_add(&keyboard_ps2_pci_device); -#endif - device_add(&keyboard_ps2_ami_pci_device); -} - void machine_at_sp4_common_init(const machine_t *model) { @@ -304,12 +279,34 @@ machine_at_revenge_init(const machine_t *model) return ret; } +void +machine_at_award_common_init(const machine_t *model) +{ + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 03 = Slot 1 */ + pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 04 = Slot 2 */ + pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 05 = Slot 3 */ + pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 06 = Slot 4 */ + pci_register_slot(0x07, PCI_CARD_SCSI, 1, 2, 3, 4); /* 07 = SCSI */ + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sio_zb_device); + device_add(&intel_flash_bxt_device); +} + int -machine_at_586mc1_init(const machine_t *model) +machine_at_586is_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/586mc1/IS.34", + ret = bios_load_linear("roms/machines/586is/IS.34", 0x000e0000, 131072, 0); if (bios_only || !ret) @@ -317,8 +314,6 @@ machine_at_586mc1_init(const machine_t *model) machine_at_award_common_init(model); - device_add(&sio_device); - device_add(&intel_flash_bxt_device); device_add(&i430lx_device); return ret; diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 4a6d00f76..4a86c75d0 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -98,11 +98,11 @@ machine_at_ambradp90_init(const machine_t *model) } int -machine_at_430nx_init(const machine_t *model) +machine_at_586ip_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/430nx/IP.20", + ret = bios_load_linear("roms/machines/586ip/IP.20", 0x000e0000, 131072, 0); if (bios_only || !ret) @@ -110,8 +110,6 @@ machine_at_430nx_init(const machine_t *model) machine_at_award_common_init(model); - device_add(&sio_device); - device_add(&intel_flash_bxt_device); device_add(&i430nx_device); return ret; diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index b672f524a..0a0af878e 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -8767,7 +8767,7 @@ const machine_t machines[] = { .internal_name = "586mc1", .type = MACHINE_TYPE_SOCKET4, .chipset = MACHINE_CHIPSET_INTEL_430LX, - .init = machine_at_586mc1_init, + .init = machine_at_586is_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, @@ -9132,13 +9132,13 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has AMI MegaKey KBC firmware. */ + /* Has AMI 'H' KBC firmware. */ { .name = "[i430NX] Gigabyte GA-586IP", - .internal_name = "430nx", + .internal_name = "586ip", .type = MACHINE_TYPE_SOCKET5, .chipset = MACHINE_CHIPSET_INTEL_430NX, - .init = machine_at_430nx_init, + .init = machine_at_586ip_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, From 08660004af780143a2a15dfa97f1bf2d7daa4c56 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 2 Feb 2024 12:32:13 +0600 Subject: [PATCH 413/936] Fix BitBLT status read --- src/video/vid_c&t_69000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index c3912fa77..786a28778 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -1373,7 +1373,7 @@ chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) addr &= 0xFFF; switch (addr & 0xFFF) { case 0x00 ... 0x28: - if (addr == 0x10) { + if (addr == 0x13) { return (chips->bitblt_regs_b[addr & 0xFF] & 0x7F) | (chips->engine_active ? 0x80 : 0x00); } return chips->bitblt_regs_b[addr & 0xFF]; From 08d784fe07fd655b9d1cb6e17b2a8093bb1e7abb Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 2 Feb 2024 13:20:24 +0600 Subject: [PATCH 414/936] Working (but with pitch troubles) BitBLT emulation --- src/video/vid_c&t_69000.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 786a28778..e35f28227 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -460,7 +460,7 @@ chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t src, uint8_t nonpattern_ } void -chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint8_t nonpattern_src, uint8_t rop) +chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint16_t nonpattern_src, uint8_t rop) { if ((rop & 0xF) == ((rop >> 4) & 0xF)) { return chips_69000_do_rop_16bpp(dst, nonpattern_src, rop); @@ -521,7 +521,7 @@ chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint8_t nonpatte } void -chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t src, uint8_t nonpattern_src, uint8_t rop) +chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t src, uint32_t nonpattern_src, uint8_t rop) { uint32_t orig_dst = *dst & 0xFF000000; @@ -832,10 +832,6 @@ chips_69000_setup_bitblt(chips_69000_t* chips) break; } - if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { - return; - } - /* Drawing is pointless if monochrome pattern is enabled, monochrome write-masking is enabled and solid pattern is enabled. */ if ((chips->bitblt_running.bitblt.bitblt_control & (1 << 17)) && (chips->bitblt_running.bitblt.bitblt_control & (1 << 18)) @@ -844,6 +840,10 @@ chips_69000_setup_bitblt(chips_69000_t* chips) return; } + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { + return; + } + do { do { uint32_t pixel = 0; @@ -896,16 +896,15 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { if (chips->bitblt_running.bytes_written == chips->bitblt_running.bytes_per_pixel) { uint32_t source_pixel = chips->bitblt_running.bytes_port[0]; chips->bitblt_running.bytes_written = 0; - if (chips->bitblt_running.bytes_per_pixel == 1) - source_pixel = (chips->bitblt_running.bytes_port[1] << 8); if (chips->bitblt_running.bytes_per_pixel == 2) - source_pixel = (chips->bitblt_running.bytes_port[2] << 16); + source_pixel |= (chips->bitblt_running.bytes_port[1] << 8); + if (chips->bitblt_running.bytes_per_pixel == 3) + source_pixel |= (chips->bitblt_running.bytes_port[2] << 16); chips_69000_process_pixel(chips, source_pixel); chips->bitblt_running.x += chips->bitblt_running.x_dir; - chips->bitblt_running.count_x++; - if (chips->bitblt_running.count_x >= chips->bitblt_running.actual_destination_width) { + if (++chips->bitblt_running.count_x >= chips->bitblt_running.actual_destination_width - 1) { chips->bitblt_running.y += chips->bitblt_running.y_dir; chips->bitblt_running.count_y++; From 33cba9ef5095c3c9575ee452b518fe0ebc4692fa Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 2 Feb 2024 15:31:42 +0600 Subject: [PATCH 415/936] More ROP codes --- src/video/vid_c&t_69000.c | 114 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index e35f28227..b2cd62f07 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -133,6 +133,7 @@ typedef struct chips_69000_t { /* Byte counter for BitBLT port writes. */ uint8_t bytes_written; + uint32_t bytes_counter; uint8_t bytes_port[4]; } bitblt_running; @@ -418,6 +419,18 @@ chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t src, uint8_t nonpattern_ case 0x0F: *dst = ~src; break; + case 0x1A: + *dst = src ^ (*dst | (src & nonpattern_src)); + break; + case 0x2A: + *dst = *dst & (~(nonpattern_src & src)); + break; + case 0x3A: + *dst = nonpattern_src ^ (src | (*dst ^ nonpattern_src)); + break; + case 0x4A: + *dst = *dst ^ (src & (nonpattern_src | *dst)); + break; case 0x50: *dst = src & ~(*dst); break; @@ -430,6 +443,18 @@ chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t src, uint8_t nonpattern_ case 0x5F: *dst = ~src | ~(*dst); break; + case 0x6A: + *dst = *dst ^ (src & nonpattern_src); + break; + case 0x7A: + *dst = *dst ^ (src & (nonpattern_src | (~*dst))); + break; + case 0x8A: + *dst = *dst & (nonpattern_src | (~src)); + break; + case 0x9A: + *dst = *dst ^ (src & (~nonpattern_src)); + break; case 0xB8: *dst = (((src ^ *dst) & nonpattern_src) ^ src); break; @@ -444,6 +469,18 @@ chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t src, uint8_t nonpattern_ case 0xAF: *dst |= ~src; break; + case 0xBA: + *dst |= (src & ~nonpattern_src); + break; + case 0xCA: + *dst ^= (src & (nonpattern_src ^ *dst)); + break; + case 0xDA: + *dst ^= src & (~(nonpattern_src & *dst)); + break; + case 0xEA: + *dst |= src & nonpattern_src; + break; case 0xF0: *dst = src; break; @@ -479,6 +516,18 @@ chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint16_t nonpatt case 0x0F: *dst = ~src; break; + case 0x1A: + *dst = src ^ (*dst | (src & nonpattern_src)); + break; + case 0x2A: + *dst = *dst & (~(nonpattern_src & src)); + break; + case 0x3A: + *dst = nonpattern_src ^ (src | (*dst ^ nonpattern_src)); + break; + case 0x4A: + *dst = *dst ^ (src & (nonpattern_src | *dst)); + break; case 0x50: *dst = src & ~(*dst); break; @@ -491,6 +540,18 @@ chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint16_t nonpatt case 0x5F: *dst = ~src | ~(*dst); break; + case 0x6A: + *dst = *dst ^ (src & nonpattern_src); + break; + case 0x7A: + *dst = *dst ^ (src & (nonpattern_src | (~*dst))); + break; + case 0x8A: + *dst = *dst & (nonpattern_src | (~src)); + break; + case 0x9A: + *dst = *dst ^ (src & (~nonpattern_src)); + break; case 0xB8: *dst = (((src ^ *dst) & nonpattern_src) ^ src); break; @@ -505,6 +566,18 @@ chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint16_t nonpatt case 0xAF: *dst |= ~src; break; + case 0xBA: + *dst |= (src & ~nonpattern_src); + break; + case 0xCA: + *dst ^= (src & (nonpattern_src ^ *dst)); + break; + case 0xDA: + *dst ^= src & (~(nonpattern_src & *dst)); + break; + case 0xEA: + *dst |= src & nonpattern_src; + break; case 0xF0: *dst = src; break; @@ -542,6 +615,18 @@ chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t src, uint32_t nonpatt case 0x0F: *dst = ~src; break; + case 0x1A: + *dst = src ^ (*dst | (src & nonpattern_src)); + break; + case 0x2A: + *dst = *dst & (~(nonpattern_src & src)); + break; + case 0x3A: + *dst = nonpattern_src ^ (src | (*dst ^ nonpattern_src)); + break; + case 0x4A: + *dst = *dst ^ (src & (nonpattern_src | *dst)); + break; case 0x50: *dst = src & ~(*dst); break; @@ -554,6 +639,18 @@ chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t src, uint32_t nonpatt case 0x5F: *dst = ~src | ~(*dst); break; + case 0x6A: + *dst = *dst ^ (src & nonpattern_src); + break; + case 0x7A: + *dst = *dst ^ (src & (nonpattern_src | (~*dst))); + break; + case 0x8A: + *dst = *dst & (nonpattern_src | (~src)); + break; + case 0x9A: + *dst = *dst ^ (src & (~nonpattern_src)); + break; case 0xB8: *dst = (((src ^ *dst) & nonpattern_src) ^ src); break; @@ -568,6 +665,18 @@ chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t src, uint32_t nonpatt case 0xAF: *dst |= ~src; break; + case 0xBA: + *dst |= (src & ~nonpattern_src); + break; + case 0xCA: + *dst ^= (src & (nonpattern_src ^ *dst)); + break; + case 0xDA: + *dst ^= src & (~(nonpattern_src & *dst)); + break; + case 0xEA: + *dst |= src & nonpattern_src; + break; case 0xF0: *dst = src; break; @@ -796,6 +905,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.actual_destination_height = chips->bitblt.destination_height; chips->bitblt_running.count_x = chips->bitblt_running.count_y = 0; chips->bitblt_running.bytes_written = 0; + chips->bitblt_running.bytes_counter = 0; if (chips->bitblt.bitblt_control & (1 << 23)) { chips->bitblt_running.bytes_per_pixel = 1 + ((chips->bitblt.bitblt_control >> 24) & 3); @@ -892,6 +1002,10 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { if (!chips->engine_active) return; + + chips->bitblt_running.bytes_counter++; + if (chips->bitblt_running.bytes_counter <= (chips->bitblt_running.bitblt.source_addr & 7)) + return; chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; if (chips->bitblt_running.bytes_written == chips->bitblt_running.bytes_per_pixel) { uint32_t source_pixel = chips->bitblt_running.bytes_port[0]; From 9e7fc6a60d87fc38c75180873000a25b52d70601 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 2 Feb 2024 17:52:00 +0100 Subject: [PATCH 416/936] DMA ports 81h and 82h workaround for proper CPU speed detection on the MegaPC BIOS and limited the MegaPC CPU speeds to >= 16 MHz and <= 25 MHz. --- src/dma.c | 46 ++++++++++++++++++++++++++++++------- src/machine/machine_table.c | 4 ++-- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/dma.c b/src/dma.c index 55cf31236..1dcc3b25b 100644 --- a/src/dma.c +++ b/src/dma.c @@ -949,16 +949,46 @@ dma_page_read(uint16_t addr, UNUSED(void *priv)) uint8_t convert[8] = CHANNELS; uint8_t ret = 0xff; - addr &= 0x0f; - ret = dmaregs[2][addr]; + if (((addr & 0xfffc) == 0x80) && (CS == 0xf000) && + ((cpu_state.pc & 0xfffffff8) == 0x00007278) && + !strcmp(machine_get_internal_name(), "megapc")) switch (addr) { + /* The Amstrad MegaPC Quadtel BIOS times a sequence of: + mov ax,di + div bx + And expects this value to be at least 0x06e0 for 20 MHz, + and at least 0x0898 for 25 MHz, everything below 0x06e0 + is assumed to be 16 MHz. Given that for some reason, this + does not occur on 86Box, we have to work around it here, + we return 0x0528 for 16 MHz, because it's the next in the + mathematical sequence (it equals 0x06e0 - (0x0898 - 0x06e0)). */ + case 0x0081: + if (cpu_busspeed >= 25000000) + ret = 0x98; + else if (cpu_busspeed >= 20000000) + ret = 0xe0; + else + ret = 0x28; + break; + case 0x0082: + if (cpu_busspeed >= 25000000) + ret = 0x08; + else if (cpu_busspeed >= 20000000) + ret = 0x06; + else + ret = 0x05; + break; + } else { + addr &= 0x0f; + ret = dmaregs[2][addr]; - if (addr >= 8) - addr = convert[addr & 0x07] | 4; - else - addr = convert[addr & 0x07]; + if (addr >= 8) + addr = convert[addr & 0x07] | 4; + else + addr = convert[addr & 0x07]; - if (addr < 8) - ret = dma[addr].page_l; + if (addr < 8) + ret = dma[addr].page_l; + } return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 0a0af878e..b45a7471c 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -4628,8 +4628,8 @@ const machine_t machines[] = { .cpu = { .package = CPU_PKG_386SX, .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, + .min_bus = 16000000, + .max_bus = 25000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, From ff5ea614eee7857fd5bda0456dd7a22e5ca56cfd Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 2 Feb 2024 19:56:55 +0100 Subject: [PATCH 417/936] DMA: Change the MegaPC 0528h to 0580h. --- src/dma.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/dma.c b/src/dma.c index 1dcc3b25b..50ae598b8 100644 --- a/src/dma.c +++ b/src/dma.c @@ -959,15 +959,16 @@ dma_page_read(uint16_t addr, UNUSED(void *priv)) and at least 0x0898 for 25 MHz, everything below 0x06e0 is assumed to be 16 MHz. Given that for some reason, this does not occur on 86Box, we have to work around it here, - we return 0x0528 for 16 MHz, because it's the next in the - mathematical sequence (it equals 0x06e0 - (0x0898 - 0x06e0)). */ + we return 0x0580 for 16 MHz, because it logically follows + in the sequence (0x06e0 = 0x0898 * (20 / 25), and + 0x0580 = 0x06e0 * (16 / 20)). */ case 0x0081: if (cpu_busspeed >= 25000000) ret = 0x98; else if (cpu_busspeed >= 20000000) ret = 0xe0; else - ret = 0x28; + ret = 0x80; break; case 0x0082: if (cpu_busspeed >= 25000000) From 91494bab97bcb55d48327e6027a0771e2d181f67 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 3 Feb 2024 04:33:42 +0100 Subject: [PATCH 418/936] 808x: Fix the flags at the end of the ADC and SBB instructions, fixes #4103. --- src/cpu/808x.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/cpu/808x.c b/src/cpu/808x.c index 0b6bd66b5..90563d9ab 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -1223,34 +1223,48 @@ static void add(int bits) { int size_mask = (1 << bits) - 1; + int special_case = 0; + uint32_t temp_src = cpu_src; + + if ((cpu_alu_op == 2) && !(cpu_src & size_mask) && (cpu_state.flags & C_FLAG)) + special_case = 1; cpu_data = cpu_dest + cpu_src; + if ((cpu_alu_op == 2) && (cpu_state.flags & C_FLAG)) + cpu_src--; set_apzs(bits); set_of_add(bits); /* Anything - FF with carry on is basically anything + 0x100: value stays unchanged but carry goes on. */ - if ((cpu_alu_op == 2) && !(cpu_src & size_mask) && (cpu_state.flags & C_FLAG)) + if (special_case) cpu_state.flags |= C_FLAG; else - set_cf((cpu_src & size_mask) > (cpu_data & size_mask)); + set_cf((temp_src & size_mask) > (cpu_data & size_mask)); } static void sub(int bits) { int size_mask = (1 << bits) - 1; + int special_case = 0; + uint32_t temp_src = cpu_src; + + if ((cpu_alu_op == 3) && !(cpu_src & size_mask) && (cpu_state.flags & C_FLAG)) + special_case = 1; cpu_data = cpu_dest - cpu_src; + if ((cpu_alu_op == 3) && (cpu_state.flags & C_FLAG)) + cpu_src--; set_apzs(bits); set_of_sub(bits); /* Anything - FF with carry on is basically anything - 0x100: value stays unchanged but carry goes on. */ - if ((cpu_alu_op == 3) && !(cpu_src & size_mask) && (cpu_state.flags & C_FLAG)) + if (special_case) cpu_state.flags |= C_FLAG; else - set_cf((cpu_src & size_mask) > (cpu_dest & size_mask)); + set_cf((temp_src & size_mask) > (cpu_dest & size_mask)); } static void From 323c179cee8096efd3fc5c0f735f40b10dbd18d7 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 3 Feb 2024 15:02:49 +0600 Subject: [PATCH 419/936] Force quadword alignment --- src/video/vid_c&t_69000.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index b2cd62f07..0f058b592 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -1018,7 +1018,9 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { chips_69000_process_pixel(chips, source_pixel); chips->bitblt_running.x += chips->bitblt_running.x_dir; - if (++chips->bitblt_running.count_x >= chips->bitblt_running.actual_destination_width - 1) { + if (++chips->bitblt_running.count_x >= chips->bitblt_running.actual_destination_width) { + if (chips->bitblt_running.bitblt.destination_width & 7) + chips->bitblt_running.bitblt.source_addr = 8 - (chips->bitblt_running.bitblt.destination_width & 7); chips->bitblt_running.y += chips->bitblt_running.y_dir; chips->bitblt_running.count_y++; From 45b9cb1980c1c443e15c076d4c7e18ec3ea7702a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 3 Feb 2024 15:27:46 +0600 Subject: [PATCH 420/936] Part 2 of quadword alignment fixing --- src/video/vid_c&t_69000.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 0f058b592..6fb3ad2a5 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -1002,7 +1002,6 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { if (!chips->engine_active) return; - chips->bitblt_running.bytes_counter++; if (chips->bitblt_running.bytes_counter <= (chips->bitblt_running.bitblt.source_addr & 7)) return; @@ -1021,8 +1020,12 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { if (++chips->bitblt_running.count_x >= chips->bitblt_running.actual_destination_width) { if (chips->bitblt_running.bitblt.destination_width & 7) chips->bitblt_running.bitblt.source_addr = 8 - (chips->bitblt_running.bitblt.destination_width & 7); + else + chips->bitblt_running.bitblt.source_addr = 0; + chips->bitblt_running.y += chips->bitblt_running.y_dir; chips->bitblt_running.count_y++; + chips->bitblt_running.bytes_counter = 0; chips->bitblt_running.count_x = 0; if (chips->bitblt_running.bitblt.bitblt_control & (1 << 8)) { From 0bca52bfe5d08dfd8691c7b1ec3615933db1f290 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 3 Feb 2024 15:45:52 +0600 Subject: [PATCH 421/936] Fix height counting --- src/video/vid_c&t_69000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 6fb3ad2a5..fae8c04bd 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -1033,7 +1033,7 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { } else chips->bitblt_running.x = 0; - if (chips->bitblt_running.count_y > chips->bitblt_running.actual_destination_height) { + if (chips->bitblt_running.count_y >= chips->bitblt_running.actual_destination_height) { chips_69000_bitblt_interrupt(chips); return; } From d7e125c16e74283df716aff8e6f1b735f528fbe2 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 4 Feb 2024 00:08:18 +0500 Subject: [PATCH 422/936] Migrate configs for the Gigabyte Socket 4/5 machines (#4111) * Bring back machine migration And add migration for the Gigabyte Socket 4 and 5 machines * Fix the GA-586IS's internal name * Remove legacy CPU tables for very old builds Since backward compatibility with pre-build 2654 configs has been removed, remove forward compatibility with these builds as well --- src/config.c | 113 ++--- src/cpu/cpu.h | 19 - src/cpu/cpu_table.c | 954 ------------------------------------ src/machine/machine_table.c | 2 +- 4 files changed, 55 insertions(+), 1033 deletions(-) diff --git a/src/config.c b/src/config.c index 7bf29155c..fc68bd7d4 100644 --- a/src/config.c +++ b/src/config.c @@ -244,20 +244,71 @@ load_machine(void) { ini_section_t cat = ini_find_section(config, "Machine"); const char *p; + const char *migrate_from = NULL; int c; int i; + int j; int speed; double multi; p = ini_section_get_string(cat, "machine", NULL); - if (p != NULL) - machine = machine_get_machine_from_internal_name(p); - else + if (p != NULL) { + migrate_from = p; + /* Migrate renamed machines. */ + if (!strcmp(p, "430nx")) + machine = machine_get_machine_from_internal_name("586ip"); + else if (!strcmp(p, "586mc1")) + machine = machine_get_machine_from_internal_name("586is"); + else { + machine = machine_get_machine_from_internal_name(p); + migrate_from = NULL; + } + } else machine = 0; if (machine >= machine_count()) machine = machine_count() - 1; + /* Copy NVR files when migrating a machine to a new internal name. */ + if (migrate_from) { + char old_fn[256]; + strcpy(old_fn, migrate_from); + strcat(old_fn, "."); + c = strlen(old_fn); + char new_fn[256]; + strcpy(new_fn, machines[machine].internal_name); + strcat(new_fn, "."); + i = strlen(new_fn); + + /* Iterate through NVR files. */ + DIR *dirp = opendir(nvr_path(".")); + if (dirp) { + struct dirent *entry; + while ((entry = readdir(dirp))) { + /* Check if this file corresponds to the old name. */ + if (strncmp(entry->d_name, old_fn, c)) + continue; + + /* Add extension to the new name. */ + strcpy(&new_fn[i], &entry->d_name[c]); + + /* Only copy if a file with the new name doesn't already exist. */ + FILE *g = nvr_fopen(new_fn, "rb"); + if (!g) { + FILE *f = nvr_fopen(entry->d_name, "rb"); + g = nvr_fopen(new_fn, "wb"); + + uint8_t buf[4096]; + while ((j = fread(buf, 1, sizeof(buf), f))) + fwrite(buf, 1, j, g); + + fclose(f); + } + fclose(g); + } + } + } + cpu_override = ini_section_get_int(cat, "cpu_override", 0); cpu_f = NULL; p = ini_section_get_string(cat, "cpu_family", NULL); @@ -1864,11 +1915,6 @@ save_machine(void) { ini_section_t cat = ini_find_or_create_section(config, "Machine"); const char *p; - int c; - int i = 0; - int legacy_mfg; - int legacy_cpu = -1; - int closest_legacy_cpu = -1; p = machine_get_internal_name(); ini_section_set_string(cat, "machine", p); @@ -1885,57 +1931,6 @@ save_machine(void) ini_section_delete_var(cat, "cpu_manufacturer"); ini_section_delete_var(cat, "cpu"); - /* Look for a machine entry on the legacy table. */ - c = 0; - while (cpu_legacy_table[c].machine) { - if (!strcmp(p, cpu_legacy_table[c].machine)) - break; - c++; - } - if (cpu_legacy_table[c].machine) { - /* Look for a corresponding CPU entry. */ - const cpu_legacy_table_t *legacy_table_entry; - for (legacy_mfg = 0; legacy_mfg < 4; legacy_mfg++) { - if (!cpu_legacy_table[c].tables[legacy_mfg]) - continue; - - i = 0; - while (cpu_legacy_table[c].tables[legacy_mfg][i].family) { - legacy_table_entry = &cpu_legacy_table[c].tables[legacy_mfg][i]; - - /* Match the family name, speed and multiplier. */ - if (!strcmp(cpu_f->internal_name, legacy_table_entry->family)) { - if ((legacy_table_entry->rspeed == cpu_f->cpus[cpu].rspeed) && - (legacy_table_entry->multi == cpu_f->cpus[cpu].multi)) { - /* Exact speed/multiplier match. */ - legacy_cpu = i; - break; - } else if ((legacy_table_entry->rspeed >= cpu_f->cpus[cpu].rspeed) && - (closest_legacy_cpu == -1)) - /* Closest speed match. */ - closest_legacy_cpu = i; - } - - i++; - } - - /* Use the closest speed match if no exact match was found. */ - if ((legacy_cpu == -1) && (closest_legacy_cpu > -1)) { - legacy_cpu = closest_legacy_cpu; - break; - } else if (legacy_cpu > -1) /* exact match found */ - break; - } - - /* Set legacy values if a match was found. */ - if (legacy_cpu > -1) { - if (legacy_mfg) - ini_section_set_int(cat, "cpu_manufacturer", legacy_mfg); - if (legacy_cpu) - ini_section_set_int(cat, "cpu", legacy_cpu); - } - } - if (cpu_waitstates == 0) ini_section_delete_var(cat, "cpu_waitstates"); else diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index b547fb99f..c525fac2a 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -115,13 +115,6 @@ enum { CPU_PKG_EBGA368 = (1 << 26) }; -#define MANU_INTEL 0 -#define MANU_AMD 1 -#define MANU_CYRIX 2 -#define MANU_IDT 3 -#define MANU_NEC 4 -#define MANU_IBM 5 - #define CPU_SUPPORTS_DYNAREC 1 #define CPU_REQUIRES_DYNAREC 2 #define CPU_ALTERNATE_XTAL 4 @@ -165,17 +158,6 @@ typedef struct { const CPU *cpus; } cpu_family_t; -typedef struct { - const char *family; - const uint32_t rspeed; - const double multi; -} cpu_legacy_table_t; - -typedef struct { - const char *machine; - const cpu_legacy_table_t **tables; -} cpu_legacy_machine_t; - #define C_FLAG 0x0001 #define P_FLAG 0x0004 #define A_FLAG 0x0010 @@ -528,7 +510,6 @@ extern cpu_state_t cpu_state; extern fpu_state_t fpu_state; extern const cpu_family_t cpu_families[]; -extern const cpu_legacy_machine_t cpu_legacy_table[]; extern cpu_family_t *cpu_f; extern CPU *cpu_s; extern int cpu_override; diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index fe55a4f23..195d432ff 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -1972,957 +1972,3 @@ const cpu_family_t cpu_families[] = { } // clang-format on }; - -/* Legacy CPU tables for backwards compatibility. */ - -static const cpu_legacy_table_t cpus_8088[] = { - {"8088", 4772728, 1}, - { "8088", 7159092, 1}, - { "8088", 8000000, 1}, - { "8088", 10000000, 1}, - { "8088", 12000000, 1}, - { "8088", 16000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_pcjr[] = { - {"8088", 4772728, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_europc[] = { - {"8088_europc", 4772728, 1}, - { "8088_europc", 7159092, 1}, - { "8088_europc", 9545456, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_8086[] = { - {"8086", 7159092, 1}, - { "8086", 8000000, 1}, - { "8086", 9545456, 1}, - { "8086", 10000000, 1}, - { "8086", 12000000, 1}, - { "8086", 16000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_pc1512[] = { - {"8086", 8000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_286[] = { - {"286", 6000000, 1}, - { "286", 8000000, 1}, - { "286", 10000000, 1}, - { "286", 12500000, 1}, - { "286", 16000000, 1}, - { "286", 20000000, 1}, - { "286", 25000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_ibmat[] = { - {"286", 6000000, 1}, - { "286", 8000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_ibmxt286[] = { - {"286", 6000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_ps1_m2011[] = { - {"286", 10000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_ps2_m30_286[] = { - {"286", 10000000, 1}, - { "286", 12500000, 1}, - { "286", 16000000, 1}, - { "286", 20000000, 1}, - { "286", 25000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_i386SX[] = { - {"i386sx", 16000000, 1}, - { "i386sx", 20000000, 1}, - { "i386sx", 25000000, 1}, - { "i386sx", 33333333, 1}, - { "i386sx", 40000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_i386DX[] = { - {"i386dx", 16000000, 1}, - { "i386dx", 20000000, 1}, - { "i386dx", 25000000, 1}, - { "i386dx", 33333333, 1}, - { "i386dx", 40000000, 1}, - { "rapidcad", 25000000, 1}, - { "rapidcad", 33333333, 1}, - { "rapidcad", 40000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_Am386SX[] = { - {"am386sx", 16000000, 1}, - { "am386sx", 20000000, 1}, - { "am386sx", 25000000, 1}, - { "am386sx", 33333333, 1}, - { "am386sx", 40000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_Am386DX[] = { - {"am386dx", 25000000, 1}, - { "am386dx", 33333333, 1}, - { "am386dx", 40000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_ALiM6117[] = { - {"m6117", 33333333, 1}, - { "m6117", 40000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_486SLC[] = { - {"cx486slc", 20000000, 1}, - { "cx486slc", 25000000, 1}, - { "cx486slc", 33333333, 1}, - { "cx486srx2", 32000000, 2}, - { "cx486srx2", 40000000, 2}, - { "cx486srx2", 50000000, 2}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_IBM486SLC[] = { - {"ibm486slc", 33333333, 1}, - { "ibm486slc2", 40000000, 2}, - { "ibm486slc2", 50000000, 2}, - { "ibm486slc2", 66666666, 2}, - { "ibm486slc3", 60000000, 3}, - { "ibm486slc3", 75000000, 3}, - { "ibm486slc3", 100000000, 3}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_IBM486BL[] = { - {"ibm486bl2", 50000000, 2}, - { "ibm486bl2", 66666666, 2}, - { "ibm486bl3", 75000000, 3}, - { "ibm486bl3", 100000000, 3}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_486DLC[] = { - {"cx486dlc", 25000000, 1}, - { "cx486dlc", 33333333, 1}, - { "cx486dlc", 40000000, 1}, - { "cx486drx2", 32000000, 2}, - { "cx486drx2", 40000000, 2}, - { "cx486drx2", 50000000, 2}, - { "cx486drx2", 66666666, 2}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_i486S1[] = { - {"i486sx", 16000000, 1}, - { "i486sx", 20000000, 1}, - { "i486sx", 25000000, 1}, - { "i486sx", 33333333, 1}, - { "i486sx2", 50000000, 2}, - { "i486sx2", 66666666, 2}, - { "i486dx", 25000000, 1}, - { "i486dx", 33333333, 1}, - { "i486dx", 50000000, 1}, - { "i486dx2", 40000000, 2}, - { "i486dx2", 50000000, 2}, - { "i486dx2", 66666666, 2}, - { "idx4_od", 75000000, 3}, - { "idx4_od", 100000000, 3}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_Am486S1[] = { - {"am486sx", 33333333, 1}, - { "am486sx", 40000000, 1}, - { "am486sx2", 50000000, 2}, - { "am486sx2", 66666666, 2}, - { "am486dx", 33333333, 1}, - { "am486dx", 40000000, 1}, - { "am486dx2", 50000000, 2}, - { "am486dx2", 66666666, 2}, - { "am486dx2", 80000000, 2}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_Cx486S1[] = { - {"cx486s", 25000000, 1.0}, - { "cx486s", 33333333, 1.0}, - { "cx486s", 40000000, 1.0}, - { "cx486dx", 33333333, 1.0}, - { "cx486dx", 40000000, 1.0}, - { "cx486dx2", 50000000, 2.0}, - { "cx486dx2", 66666666, 2.0}, - { "cx486dx2", 80000000, 2.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_i486[] = { - {"i486sx", 16000000, 1.0}, - { "i486sx", 20000000, 1.0}, - { "i486sx", 25000000, 1.0}, - { "i486sx", 33333333, 1.0}, - { "i486sx2", 50000000, 2.0}, - { "i486sx2", 66666666, 2.0}, - { "i486dx", 25000000, 1.0}, - { "i486dx", 33333333, 1.0}, - { "i486dx", 50000000, 1.0}, - { "i486dx2", 40000000, 2.0}, - { "i486dx2", 50000000, 2.0}, - { "i486dx2", 66666666, 2.0}, - { "idx4", 75000000, 3.0}, - { "idx4", 100000000, 3.0}, - { "idx4_od", 75000000, 3.0}, - { "idx4_od", 100000000, 3.0}, - { "pentium_p24t", 62500000, 2.5}, - { "pentium_p24t", 83333333, 2.5}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_i486_PC330[] = { - {"i486dx2", 50000000, 2.0}, - { "i486dx2", 66666666, 2.0}, - { "idx4", 75000000, 3.0}, - { "idx4", 100000000, 3.0}, - { "pentium_p24t", 62500000, 2.5}, - { "pentium_p24t", 83333333, 2.5}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_Am486[] = { - {"am486sx", 33333333, 1.0}, - { "am486sx", 40000000, 1.0}, - { "am486sx2", 50000000, 2.0}, - { "am486sx2", 66666666, 2.0}, - { "am486dx", 33333333, 1.0}, - { "am486dx", 40000000, 1.0}, - { "am486dx2", 50000000, 2.0}, - { "am486dx2", 66666666, 2.0}, - { "am486dx2", 80000000, 2.0}, - { "am486dx4", 75000000, 3.0}, - { "am486dx4", 90000000, 3.0}, - { "am486dx4", 100000000, 3.0}, - { "am486dx4", 120000000, 3.0}, - { "am5x86", 133333333, 4.0}, - { "am5x86", 150000000, 3.0}, - { "am5x86", 160000000, 4.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_Cx486[] = { - {"cx486s", 25000000, 1.0}, - { "cx486s", 33333333, 1.0}, - { "cx486s", 40000000, 1.0}, - { "cx486dx", 33333333, 1.0}, - { "cx486dx", 40000000, 1.0}, - { "cx486dx2", 50000000, 2.0}, - { "cx486dx2", 66666666, 2.0}, - { "cx486dx2", 80000000, 2.0}, - { "cx486dx4", 75000000, 3.0}, - { "cx486dx4", 100000000, 3.0}, - { "cx5x86", 80000000, 2.0}, - { "cx5x86", 100000000, 3.0}, - { "cx5x86", 120000000, 3.0}, - { "cx5x86", 133333333, 4.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_STPCDX[] = { - {"stpc_dx", 66666666, 1.0}, - { "stpc_dx", 75000000, 1.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_STPCDX2[] = { - {"stpc_dx2", 133333333, 2.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_6x863V[] = { - {"cx6x86", 80000000, 2.0}, - { "cx6x86", 100000000, 2.0}, - { "cx6x86", 110000000, 2.0}, - { "cx6x86", 120000000, 2.0}, - { "cx6x86", 133333333, 2.0}, - { "cx6x86", 150000000, 2.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_6x86[] = { - {"cx6x86", 80000000, 2.0}, - { "cx6x86", 100000000, 2.0}, - { "cx6x86", 110000000, 2.0}, - { "cx6x86", 120000000, 2.0}, - { "cx6x86", 133333333, 2.0}, - { "cx6x86", 150000000, 2.0}, - { "cx6x86l", 110000000, 2.0}, - { "cx6x86l", 120000000, 2.0}, - { "cx6x86l", 133333333, 2.0}, - { "cx6x86l", 150000000, 2.0}, - { "cx6x86mx", 133333333, 2.0}, - { "cx6x86mx", 166666666, 2.5}, - { "cx6x86mx", 187500000, 2.5}, - { "cx6x86mx", 208333333, 2.5}, - { "mii", 233333333, 3.5}, - { "mii", 250000000, 3.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_6x86SS7[] = { - {"cx6x86", 80000000, 2.0}, - { "cx6x86", 100000000, 2.0}, - { "cx6x86", 110000000, 2.0}, - { "cx6x86", 120000000, 2.0}, - { "cx6x86", 133333333, 2.0}, - { "cx6x86", 150000000, 2.0}, - { "cx6x86l", 110000000, 2.0}, - { "cx6x86l", 120000000, 2.0}, - { "cx6x86l", 133333333, 2.0}, - { "cx6x86l", 150000000, 2.0}, - { "cx6x86mx", 133333333, 2.0}, - { "cx6x86mx", 166666666, 2.5}, - { "cx6x86mx", 187500000, 2.5}, - { "cx6x86mx", 208333333, 2.5}, - { "mii", 233333333, 3.5}, - { "mii", 250000000, 3.0}, - { "mii", 250000000, 2.5}, - { "mii", 285000000, 3.0}, - { "mii", 300000000, 3.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_WinChip[] = { - {"winchip", 75000000, 1.5}, - { "winchip", 90000000, 1.5}, - { "winchip", 100000000, 1.5}, - { "winchip", 120000000, 2.0}, - { "winchip", 133333333, 2.0}, - { "winchip", 150000000, 2.5}, - { "winchip", 166666666, 2.5}, - { "winchip", 180000000, 3.0}, - { "winchip", 200000000, 3.0}, - { "winchip", 225000000, 3.0}, - { "winchip", 240000000, 4.0}, - { "winchip2", 200000000, 3.0}, - { "winchip2", 225000000, 3.0}, - { "winchip2", 240000000, 4.0}, - { "winchip2", 250000000, 3.0}, - { "winchip2a", 200000000, 3.0}, - { "winchip2a", 233333333, 3.5}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_WinChip_SS7[] = { - {"winchip", 75000000, 1.5}, - { "winchip", 90000000, 1.5}, - { "winchip", 100000000, 1.5}, - { "winchip", 120000000, 2.0}, - { "winchip", 133333333, 2.0}, - { "winchip", 150000000, 2.5}, - { "winchip", 166666666, 2.5}, - { "winchip", 180000000, 3.0}, - { "winchip", 200000000, 3.0}, - { "winchip", 225000000, 3.0}, - { "winchip", 240000000, 4.0}, - { "winchip2", 200000000, 3.0}, - { "winchip2", 225000000, 3.0}, - { "winchip2", 240000000, 4.0}, - { "winchip2", 250000000, 3.0}, - { "winchip2a", 200000000, 3.0}, - { "winchip2a", 233333333, 3.5}, - { "winchip2a", 233333333, 7.0}, - { "winchip2a", 250000000, 2.5}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_Pentium5V[] = { - {"pentium_p5", 60000000, 1}, - { "pentium_p5", 66666666, 1}, - { "pentium_p54c_od5v", 120000000, 2}, - { "pentium_p54c_od5v", 133333333, 2}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_PentiumS5[] = { - {"pentium_p54c", 75000000, 1.5}, - { "pentium_p55c_od", 75000000, 1.5}, - { "pentium_p54c", 90000000, 1.5}, - { "pentium_p54c", 100000000, 2.0}, - { "pentium_p54c", 100000000, 1.5}, - { "pentium_p54c", 120000000, 2.0}, - { "pentium_p54c", 133333333, 2.0}, - { "pentium_p54c_od3v", 125000000, 3.0}, - { "pentium_p54c_od3v", 150000000, 2.5}, - { "pentium_p54c_od3v", 166666666, 2.5}, - { "pentium_p55c_od", 125000000, 2.5}, - { "pentium_p55c_od", 150000000, 2.5}, - { "pentium_p55c_od", 166000000, 2.5}, - { "pentium_p55c_od", 180000000, 3.0}, - { "pentium_p55c_od", 200000000, 3.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_Pentium3V[] = { - {"pentium_p54c", 75000000, 1.5}, - { "pentium_p55c_od", 75000000, 1.5}, - { "pentium_p54c", 90000000, 1.5}, - { "pentium_p54c", 100000000, 2.0}, - { "pentium_p54c", 100000000, 1.5}, - { "pentium_p54c", 120000000, 2.0}, - { "pentium_p54c", 133333333, 2.0}, - { "pentium_p54c", 150000000, 2.5}, - { "pentium_p54c", 166666666, 2.5}, - { "pentium_p54c", 200000000, 3.0}, - { "pentium_p54c_od3v", 125000000, 2.5}, - { "pentium_p54c_od3v", 150000000, 2.5}, - { "pentium_p54c_od3v", 166666666, 2.5}, - { "pentium_p55c_od", 125000000, 2.5}, - { "pentium_p55c_od", 150000000, 2.5}, - { "pentium_p55c_od", 166000000, 2.5}, - { "pentium_p55c_od", 180000000, 3.0}, - { "pentium_p55c_od", 200000000, 3.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_Pentium[] = { - {"pentium_p54c", 75000000, 1.5}, - { "pentium_p55c_od", 75000000, 1.5}, - { "pentium_p54c", 90000000, 1.5}, - { "pentium_p54c", 100000000, 2.0}, - { "pentium_p54c", 100000000, 1.5}, - { "pentium_p54c", 120000000, 2.0}, - { "pentium_p54c", 133333333, 2.0}, - { "pentium_p54c", 150000000, 2.5}, - { "pentium_p54c", 166666666, 2.5}, - { "pentium_p54c", 200000000, 3.0}, - { "pentium_p55c", 166666666, 2.5}, - { "pentium_p55c", 200000000, 3.0}, - { "pentium_p55c", 233333333, 3.5}, - { "pentium_tillamook", 120000000, 2.0}, - { "pentium_tillamook", 133333333, 2.0}, - { "pentium_tillamook", 150000000, 2.5}, - { "pentium_tillamook", 166666666, 2.5}, - { "pentium_tillamook", 200000000, 3.0}, - { "pentium_tillamook", 233333333, 3.5}, - { "pentium_tillamook", 266666666, 4.0}, - { "pentium_tillamook", 300000000, 4.5}, - { "pentium_p54c_od3v", 125000000, 2.5}, - { "pentium_p54c_od3v", 150000000, 2.5}, - { "pentium_p54c_od3v", 166666666, 2.5}, - { "pentium_p55c_od", 125000000, 2.5}, - { "pentium_p55c_od", 150000000, 2.5}, - { "pentium_p55c_od", 166000000, 2.5}, - { "pentium_p55c_od", 180000000, 3.0}, - { "pentium_p55c_od", 200000000, 3.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_K5[] = { - {"k5_5k86", 75000000, 1.5}, - { "k5_ssa5", 75000000, 1.5}, - { "k5_5k86", 90000000, 1.5}, - { "k5_ssa5", 90000000, 1.5}, - { "k5_5k86", 100000000, 1.5}, - { "k5_ssa5", 100000000, 1.5}, - { "k5_5k86", 120000000, 2.0}, - { "k5_5k86", 133333333, 2.0}, - { "k5_5k86", 150000000, 2.5}, - { "k5_5k86", 166666666, 2.5}, - { "k5_5k86", 200000000, 3.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_K56[] = { - {"k6_m6", 66666666, 1.0}, - { "k6_m6", 100000000, 1.5}, - { "k6_m6", 133333333, 2.0}, - { "k6_m6", 166666666, 2.5}, - { "k6_m6", 200000000, 3.0}, - { "k6_m6", 233333333, 3.5}, - { "k6_m7", 100000000, 1.5}, - { "k6_m7", 133333333, 2.0}, - { "k6_m7", 166666666, 2.5}, - { "k6_m7", 200000000, 3.0}, - { "k6_m7", 233333333, 3.5}, - { "k6_m7", 266666666, 4.0}, - { "k6_m7", 300000000, 4.5}, - { "k6_2", 100000000, 1.5}, - { "k6_2", 133333333, 2.0}, - { "k6_2", 166666666, 2.5}, - { "k6_2", 200000000, 3.0}, - { "k6_2", 233333333, 3.5}, - { "k6_2", 266666666, 4.0}, - { "k6_2", 300000000, 4.5}, - { "k6_2", 366666666, 5.5}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_K56_SS7[] = { - {"k6_m6", 66666666, 1.0}, - { "k6_m6", 100000000, 1.5}, - { "k6_m6", 133333333, 2.0}, - { "k6_m6", 166666666, 2.5}, - { "k6_m6", 200000000, 3.0}, - { "k6_m6", 233333333, 3.5}, - { "k6_m7", 100000000, 1.5}, - { "k6_m7", 133333333, 2.0}, - { "k6_m7", 166666666, 2.5}, - { "k6_m7", 200000000, 3.0}, - { "k6_m7", 233333333, 3.5}, - { "k6_m7", 266666666, 4.0}, - { "k6_m7", 300000000, 4.5}, - { "k6_2", 100000000, 1.5}, - { "k6_2", 133333333, 2.0}, - { "k6_2", 166666666, 2.5}, - { "k6_2", 200000000, 3.0}, - { "k6_2", 233333333, 3.5}, - { "k6_2", 266666666, 4.0}, - { "k6_2", 300000000, 3.0}, - { "k6_2", 332500000, 3.5}, - { "k6_2", 350000000, 3.5}, - { "k6_2", 366666666, 5.5}, - { "k6_2", 380000000, 4.0}, - { "k6_2", 400000000, 4.0}, - { "k6_2", 450000000, 4.5}, - { "k6_2", 475000000, 5.0}, - { "k6_2", 500000000, 5.0}, - { "k6_2", 533333333, 5.5}, - { "k6_2", 550000000, 5.5}, - { "k6_2p", 100000000, 1.5}, - { "k6_2p", 133333333, 2.0}, - { "k6_2p", 166666666, 2.5}, - { "k6_2p", 200000000, 3.0}, - { "k6_2p", 233333333, 3.5}, - { "k6_2p", 266666666, 4.0}, - { "k6_2p", 300000000, 3.0}, - { "k6_2p", 332500000, 3.5}, - { "k6_2p", 350000000, 3.5}, - { "k6_2p", 366666666, 5.5}, - { "k6_2p", 380000000, 4.0}, - { "k6_2p", 400000000, 4.0}, - { "k6_2p", 450000000, 4.5}, - { "k6_2p", 475000000, 5.0}, - { "k6_2p", 500000000, 5.0}, - { "k6_2p", 533333333, 5.5}, - { "k6_2p", 550000000, 5.5}, - { "k6_3", 100000000, 1.5}, - { "k6_3", 133333333, 2.0}, - { "k6_3", 166666666, 2.5}, - { "k6_3", 200000000, 3.0}, - { "k6_3", 233333333, 3.5}, - { "k6_3", 266666666, 4.0}, - { "k6_3", 300000000, 3.0}, - { "k6_3", 332500000, 3.5}, - { "k6_3", 350000000, 3.5}, - { "k6_3", 366666666, 5.5}, - { "k6_3", 380000000, 4.0}, - { "k6_3", 400000000, 4.0}, - { "k6_3", 450000000, 4.5}, - { "k6_3p", 75000000, 1.5}, - { "k6_3p", 100000000, 1.5}, - { "k6_3p", 133333333, 2.0}, - { "k6_3p", 166666666, 2.5}, - { "k6_3p", 200000000, 3.0}, - { "k6_3p", 233333333, 3.5}, - { "k6_3p", 266666666, 4.0}, - { "k6_3p", 300000000, 3.0}, - { "k6_3p", 332500000, 3.5}, - { "k6_3p", 350000000, 3.5}, - { "k6_3p", 366666666, 5.5}, - { "k6_3p", 380000000, 4.0}, - { "k6_3p", 400000000, 4.0}, - { "k6_3p", 450000000, 4.5}, - { "k6_3p", 475000000, 5.0}, - { "k6_3p", 500000000, 5.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_PentiumPro[] = { - {"pentiumpro", 50000000, 1.0}, - { "pentiumpro", 60000000, 1.0}, - { "pentiumpro", 66666666, 1.0}, - { "pentiumpro", 75000000, 1.5}, - { "pentiumpro", 150000000, 2.5}, - { "pentiumpro", 166666666, 2.5}, - { "pentiumpro", 180000000, 3.0}, - { "pentiumpro", 200000000, 3.0}, - { "pentium2_od", 50000000, 1.0}, - { "pentium2_od", 60000000, 1.0}, - { "pentium2_od", 66666666, 1.0}, - { "pentium2_od", 75000000, 1.5}, - { "pentium2_od", 210000000, 3.5}, - { "pentium2_od", 233333333, 3.5}, - { "pentium2_od", 240000000, 4.0}, - { "pentium2_od", 266666666, 4.0}, - { "pentium2_od", 270000000, 4.5}, - { "pentium2_od", 300000000, 4.5}, - { "pentium2_od", 300000000, 5.0}, - { "pentium2_od", 333333333, 5.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_PentiumII66[] = { - {"pentium2_klamath", 50000000, 1.0}, - { "pentium2_klamath", 60000000, 1.0}, - { "pentium2_klamath", 66666666, 1.0}, - { "pentium2_klamath", 75000000, 1.5}, - { "pentium2_klamath", 233333333, 3.5}, - { "pentium2_klamath", 266666666, 4.0}, - { "pentium2_klamath", 300000000, 4.5}, - { "pentium2_deschutes", 50000000, 1.0}, - { "pentium2_deschutes", 60000000, 1.0}, - { "pentium2_deschutes", 66666666, 1.0}, - { "pentium2_deschutes", 75000000, 1.5}, - { "pentium2_deschutes", 266666666, 4.0}, - { "pentium2_deschutes", 300000000, 4.5}, - { "pentium2_deschutes", 333333333, 5.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_PentiumII[] = { - {"pentium2_klamath", 50000000, 1.0}, - { "pentium2_klamath", 60000000, 1.0}, - { "pentium2_klamath", 66666666, 1.0}, - { "pentium2_klamath", 75000000, 1.5}, - { "pentium2_klamath", 233333333, 3.5}, - { "pentium2_klamath", 266666666, 4.0}, - { "pentium2_klamath", 300000000, 4.5}, - { "pentium2_deschutes", 50000000, 1.0}, - { "pentium2_deschutes", 60000000, 1.0}, - { "pentium2_deschutes", 66666666, 1.0}, - { "pentium2_deschutes", 75000000, 1.5}, - { "pentium2_deschutes", 266666666, 4.0}, - { "pentium2_deschutes", 300000000, 4.5}, - { "pentium2_deschutes", 333333333, 5.0}, - { "pentium2_deschutes", 350000000, 3.5}, - { "pentium2_deschutes", 400000000, 4.0}, - { "pentium2_deschutes", 450000000, 4.5}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_Xeon[] = { - {"pentium2_xeon", 75000000, 1.5}, - { "pentium2_xeon", 100000000, 1.5}, - { "pentium2_xeon", 133333333, 2.0}, - { "pentium2_xeon", 166666666, 2.5}, - { "pentium2_xeon", 400000000, 4.0}, - { "pentium2_xeon", 450000000, 4.5}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_Celeron[] = { - {"celeron_mendocino", 66666666, 1.0}, - { "celeron_mendocino", 100000000, 1.5}, - { "celeron_mendocino", 133333333, 2.0}, - { "celeron_mendocino", 166666666, 2.5}, - { "celeron_mendocino", 300000000, 4.5}, - { "celeron_mendocino", 333333333, 5.0}, - { "celeron_mendocino", 366666666, 5.5}, - { "celeron_mendocino", 400000000, 6.0}, - { "celeron_mendocino", 433333333, 6.5}, - { "celeron_mendocino", 466666666, 7.0}, - { "celeron_mendocino", 500000000, 7.5}, - { "celeron_mendocino", 533333333, 8.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_PentiumIID[] = { - {"pentium2_deschutes", 50000000, 1.0}, - { "pentium2_deschutes", 60000000, 1.0}, - { "pentium2_deschutes", 66666666, 1.0}, - { "pentium2_deschutes", 75000000, 1.5}, - { "pentium2_deschutes", 266666666, 4.0}, - { "pentium2_deschutes", 300000000, 4.5}, - { "pentium2_deschutes", 333333333, 5.0}, - { "pentium2_deschutes", 350000000, 3.5}, - { "pentium2_deschutes", 400000000, 4.0}, - { "pentium2_deschutes", 450000000, 4.5}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_Cyrix3[] = { - {"c3_samuel", 66666666, 1.0}, - { "c3_samuel", 233333333, 3.5}, - { "c3_samuel", 266666666, 4.0}, - { "c3_samuel", 300000000, 4.5}, - { "c3_samuel", 333333333, 5.0}, - { "c3_samuel", 350000000, 3.5}, - { "c3_samuel", 400000000, 4.0}, - { "c3_samuel", 450000000, 4.5}, - { "c3_samuel", 500000000, 5.0}, - { "c3_samuel", 550000000, 5.5}, - { "c3_samuel", 600000000, 6.0}, - { "c3_samuel", 650000000, 6.5}, - { "c3_samuel", 700000000, 7.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t *cputables_8088[4] = { cpus_8088 }; -static const cpu_legacy_table_t *cputables_pcjr[4] = { cpus_pcjr }; -static const cpu_legacy_table_t *cputables_europc[4] = { cpus_europc }; -static const cpu_legacy_table_t *cputables_pc1512[4] = { cpus_pc1512 }; -static const cpu_legacy_table_t *cputables_8086[4] = { cpus_8086 }; -static const cpu_legacy_table_t *cputables_286[4] = { cpus_286 }; -static const cpu_legacy_table_t *cputables_ibmat[4] = { cpus_ibmat }; -static const cpu_legacy_table_t *cputables_ps1_m2011[4] = { cpus_ps1_m2011 }; -static const cpu_legacy_table_t *cputables_ps2_m30_286_IBM486SLC[4] = { cpus_ps2_m30_286, cpus_IBM486SLC }; -static const cpu_legacy_table_t *cputables_ibmxt286[4] = { cpus_ibmxt286 }; -static const cpu_legacy_table_t *cputables_i386SX_Am386SX_486SLC[4] = { cpus_i386SX, cpus_Am386SX, cpus_486SLC }; -static const cpu_legacy_table_t *cputables_ALiM6117[4] = { cpus_ALiM6117 }; -static const cpu_legacy_table_t *cputables_i386SX_Am386SX_486SLC_IBM486SLC[4] = { cpus_i386SX, cpus_Am386SX, cpus_486SLC, cpus_IBM486SLC }; -static const cpu_legacy_table_t *cputables_i386DX_Am386DX_486DLC[4] = { cpus_i386DX, cpus_Am386DX, cpus_486DLC }; -static const cpu_legacy_table_t *cputables_i386DX_Am386DX_486DLC_IBM486BL[4] = { cpus_i386DX, cpus_Am386DX, cpus_486DLC, cpus_IBM486BL }; -static const cpu_legacy_table_t *cputables_i486_Am486_Cx486[4] = { cpus_i486, cpus_Am486, cpus_Cx486 }; -static const cpu_legacy_table_t *cputables_i486S1_Am486S1_Cx486S1[4] = { cpus_i486S1, cpus_Am486S1, cpus_Cx486S1 }; -static const cpu_legacy_table_t *cputables_IBM486SLC[4] = { cpus_IBM486SLC }; -static const cpu_legacy_table_t *cputables_i486_PC330[4] = { cpus_i486_PC330 }; -static const cpu_legacy_table_t *cputables_STPCDX[4] = { cpus_STPCDX }; -static const cpu_legacy_table_t *cputables_STPCDX2[4] = { cpus_STPCDX2 }; -static const cpu_legacy_table_t *cputables_Pentium5V[4] = { cpus_Pentium5V }; -static const cpu_legacy_table_t *cputables_PentiumS5_WinChip_K5[4] = { cpus_PentiumS5, cpus_WinChip, cpus_K5 }; -static const cpu_legacy_table_t *cputables_Pentium3V_WinChip_K5_6x863V[4] = { cpus_Pentium3V, cpus_WinChip, cpus_K5, cpus_6x863V }; -static const cpu_legacy_table_t *cputables_Pentium3V_K5[4] = { cpus_Pentium3V, cpus_K5 }; -static const cpu_legacy_table_t *cputables_Pentium_WinChip_K56_6x86[4] = { cpus_Pentium, cpus_WinChip, cpus_K56, cpus_6x86 }; -static const cpu_legacy_table_t *cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7[4] = { cpus_Pentium, cpus_WinChip_SS7, cpus_K56_SS7, cpus_6x86SS7 }; -static const cpu_legacy_table_t *cputables_PentiumPro[4] = { cpus_PentiumPro }; -static const cpu_legacy_table_t *cputables_PentiumII66[4] = { cpus_PentiumII66 }; -static const cpu_legacy_table_t *cputables_PentiumII_Celeron_Cyrix3[4] = { cpus_PentiumII, cpus_Celeron, cpus_Cyrix3 }; -static const cpu_legacy_table_t *cputables_Xeon[4] = { cpus_Xeon }; -static const cpu_legacy_table_t *cputables_Celeron_Cyrix3[4] = { cpus_Celeron, cpus_Cyrix3 }; -static const cpu_legacy_table_t *cputables_Celeron[4] = { cpus_Celeron }; -static const cpu_legacy_table_t *cputables_PentiumIID_Celeron[4] = { cpus_PentiumIID, cpus_Celeron }; - -const cpu_legacy_machine_t cpu_legacy_table[] = { - {"ibmpc", cputables_8088 }, - { "ibmpc82", cputables_8088 }, - { "ibmpcjr", cputables_pcjr }, - { "ibmxt", cputables_8088 }, - { "ibmxt86", cputables_8088 }, - { "americxt", cputables_8088 }, - { "amixt", cputables_8088 }, - { "portable", cputables_8088 }, - { "dtk", cputables_8088 }, - { "genxt", cputables_8088 }, - { "jukopc", cputables_8088 }, - { "openxt", cputables_8088 }, - { "pxxt", cputables_8088 }, - { "europc", cputables_europc }, - { "tandy", cputables_europc }, - { "tandy1000hx", cputables_europc }, - { "t1000", cputables_8088 }, - { "ltxt", cputables_8088 }, - { "xi8088", cputables_8088 }, - { "zdsupers", cputables_8088 }, - { "pc1512", cputables_pc1512 }, - { "pc1640", cputables_8086 }, - { "pc2086", cputables_8086 }, - { "pc3086", cputables_8086 }, - { "pc200", cputables_8086 }, - { "ppc512", cputables_8086 }, - { "deskpro", cputables_8086 }, - { "m24", cputables_8086 }, - { "iskra3104", cputables_8086 }, - { "tandy1000sl2", cputables_8086 }, - { "t1200", cputables_8086 }, - { "lxt3", cputables_8086 }, - { "hed919", cputables_286 }, - { "ibmat", cputables_ibmat }, - { "ibmps1es", cputables_ps1_m2011 }, - { "ibmps2_m30_286", cputables_ps2_m30_286_IBM486SLC }, - { "ibmxt286", cputables_ibmxt286 }, - { "ibmatami", cputables_ibmat }, - { "cmdpc30", cputables_286 }, - { "portableii", cputables_286 }, - { "portableiii", cputables_286 }, - { "mr286", cputables_286 }, - { "open_at", cputables_286 }, - { "ibmatpx", cputables_ibmat }, - { "ibmatquadtel", cputables_ibmat }, - { "siemens", cputables_286 }, - { "t3100e", cputables_286 }, - { "quadt286", cputables_286 }, - { "tg286m", cputables_286 }, - { "ami286", cputables_286 }, - { "px286", cputables_286 }, - { "award286", cputables_286 }, - { "gw286ct", cputables_286 }, - { "gdc212m", cputables_286 }, - { "super286c", cputables_286 }, - { "super286tr", cputables_286 }, - { "spc4200p", cputables_286 }, - { "spc4216p", cputables_286 }, - { "deskmaster286", cputables_286 }, - { "ibmps2_m50", cputables_ps2_m30_286_IBM486SLC }, - { "ibmps1_2121", cputables_i386SX_Am386SX_486SLC }, - { "ibmps1_2121_isa", cputables_i386SX_Am386SX_486SLC }, - { "arb1375", cputables_ALiM6117 }, - { "pja511m", cputables_ALiM6117 }, - { "ama932j", cputables_i386SX_Am386SX_486SLC }, - { "adi386sx", cputables_i386SX_Am386SX_486SLC }, - { "shuttle386sx", cputables_i386SX_Am386SX_486SLC }, - { "dtk386", cputables_i386SX_Am386SX_486SLC }, - { "awardsx", cputables_i386SX_Am386SX_486SLC }, - { "cmdsl386sx25", cputables_i386SX_Am386SX_486SLC }, - { "kmxc02", cputables_i386SX_Am386SX_486SLC }, - { "megapc", cputables_i386SX_Am386SX_486SLC }, - { "ibmps2_m55sx", cputables_i386SX_Am386SX_486SLC_IBM486SLC }, - { "acc386", cputables_i386DX_Am386DX_486DLC }, - { "ecs386", cputables_i386DX_Am386DX_486DLC }, - { "portableiii386", cputables_i386DX_Am386DX_486DLC }, - { "micronics386", cputables_i386DX_Am386DX_486DLC }, - { "asus386", cputables_i386DX_Am386DX_486DLC }, - { "ustechnologies386", cputables_i386DX_Am386DX_486DLC }, - { "award386dx", cputables_i386DX_Am386DX_486DLC }, - { "ibmps2_m70_type3", cputables_i386DX_Am386DX_486DLC_IBM486BL }, - { "ibmps2_m80", cputables_i386DX_Am386DX_486DLC_IBM486BL }, - { "pb410a", cputables_i486_Am486_Cx486 }, - { "acera1g", cputables_i486_Am486_Cx486 }, - { "win486", cputables_i486_Am486_Cx486 }, - { "ali1429", cputables_i486S1_Am486S1_Cx486S1 }, - { "cs4031", cputables_i486S1_Am486S1_Cx486S1 }, - { "rycleopardlx", cputables_IBM486SLC }, - { "award486", cputables_i486S1_Am486S1_Cx486S1 }, - { "ami486", cputables_i486S1_Am486S1_Cx486S1 }, - { "mr486", cputables_i486_Am486_Cx486 }, - { "pc330_6571", cputables_i486_PC330 }, - { "403tg", cputables_i486_Am486_Cx486 }, - { "sis401", cputables_i486_Am486_Cx486 }, - { "valuepoint433", cputables_i486_Am486_Cx486 }, - { "ami471", cputables_i486_Am486_Cx486 }, - { "win471", cputables_i486_Am486_Cx486 }, - { "vi15g", cputables_i486_Am486_Cx486 }, - { "vli486sv2g", cputables_i486_Am486_Cx486 }, - { "dtk486", cputables_i486_Am486_Cx486 }, - { "px471", cputables_i486_Am486_Cx486 }, - { "486vchd", cputables_i486S1_Am486S1_Cx486S1 }, - { "ibmps1_2133", cputables_i486S1_Am486S1_Cx486S1 }, - { "vect486vl", cputables_i486S1_Am486S1_Cx486S1 }, - { "ibmps2_m70_type4", cputables_i486S1_Am486S1_Cx486S1 }, - { "abpb4", cputables_i486_Am486_Cx486 }, - { "486ap4", cputables_i486_Am486_Cx486 }, - { "486sp3g", cputables_i486_Am486_Cx486 }, - { "alfredo", cputables_i486_Am486_Cx486 }, - { "ls486e", cputables_i486_Am486_Cx486 }, - { "m4li", cputables_i486_Am486_Cx486 }, - { "r418", cputables_i486_Am486_Cx486 }, - { "4sa2", cputables_i486_Am486_Cx486 }, - { "4dps", cputables_i486_Am486_Cx486 }, - { "itoxstar", cputables_STPCDX }, - { "arb1479", cputables_STPCDX2 }, - { "pcm9340", cputables_STPCDX2 }, - { "pcm5330", cputables_STPCDX2 }, - { "486vipio2", cputables_i486_Am486_Cx486 }, - { "p5mp3", cputables_Pentium5V }, - { "dellxp60", cputables_Pentium5V }, - { "opti560l", cputables_Pentium5V }, - { "ambradp60", cputables_Pentium5V }, - { "valuepointp60", cputables_Pentium5V }, - { "revenge", cputables_Pentium5V }, - { "586mc1", cputables_Pentium5V }, - { "pb520r", cputables_Pentium5V }, - { "excalibur", cputables_Pentium5V }, - { "plato", cputables_PentiumS5_WinChip_K5 }, - { "ambradp90", cputables_PentiumS5_WinChip_K5 }, - { "430nx", cputables_PentiumS5_WinChip_K5 }, - { "acerv30", cputables_PentiumS5_WinChip_K5 }, - { "apollo", cputables_PentiumS5_WinChip_K5 }, - { "vectra54", cputables_PentiumS5_WinChip_K5 }, - { "zappa", cputables_PentiumS5_WinChip_K5 }, - { "powermate_v", cputables_PentiumS5_WinChip_K5 }, - { "mb500n", cputables_PentiumS5_WinChip_K5 }, - { "p54tp4xe", cputables_Pentium3V_WinChip_K5_6x863V }, - { "mr586", cputables_Pentium3V_WinChip_K5_6x863V }, - { "gw2katx", cputables_Pentium3V_WinChip_K5_6x863V }, - { "thor", cputables_Pentium3V_WinChip_K5_6x863V }, - { "mrthor", cputables_Pentium3V_WinChip_K5_6x863V }, - { "endeavor", cputables_Pentium3V_WinChip_K5_6x863V }, - { "pb640", cputables_Pentium3V_WinChip_K5_6x863V }, - { "chariot", cputables_Pentium3V_K5 }, - { "acerm3a", cputables_Pentium3V_WinChip_K5_6x863V }, - { "ap53", cputables_Pentium3V_WinChip_K5_6x863V }, - { "8500tuc", cputables_Pentium3V_WinChip_K5_6x863V }, - { "p55t2s", cputables_Pentium3V_WinChip_K5_6x863V }, - { "acerv35n", cputables_Pentium_WinChip_K56_6x86 }, - { "p55t2p4", cputables_Pentium_WinChip_K56_6x86 }, - { "m7shi", cputables_Pentium_WinChip_K56_6x86 }, - { "tc430hx", cputables_Pentium_WinChip_K56_6x86 }, - { "equium5200", cputables_Pentium_WinChip_K56_6x86 }, - { "pcv240", cputables_Pentium_WinChip_K56_6x86 }, - { "p65up5_cp55t2d", cputables_Pentium_WinChip_K56_6x86 }, - { "p55tvp4", cputables_Pentium_WinChip_K56_6x86 }, - { "8500tvxa", cputables_Pentium_WinChip_K56_6x86 }, - { "presario4500", cputables_Pentium_WinChip_K56_6x86 }, - { "p55va", cputables_Pentium_WinChip_K56_6x86 }, - { "gw2kte", cputables_Pentium_WinChip_K56_6x86 }, - { "brio80xx", cputables_Pentium_WinChip_K56_6x86 }, - { "pb680", cputables_Pentium_WinChip_K56_6x86 }, - { "430vx", cputables_Pentium_WinChip_K56_6x86 }, - { "nupro592", cputables_Pentium_WinChip_K56_6x86 }, - { "tx97", cputables_Pentium_WinChip_K56_6x86 }, - { "an430tx", cputables_Pentium_WinChip_K56_6x86 }, - { "ym430tx", cputables_Pentium_WinChip_K56_6x86 }, - { "mb540n", cputables_Pentium_WinChip_K56_6x86 }, - { "p5mms98", cputables_Pentium_WinChip_K56_6x86 }, - { "ficva502", cputables_Pentium_WinChip_K56_6x86 }, - { "ficpa2012", cputables_Pentium_WinChip_K56_6x86 }, - { "ax59pro", cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7}, - { "ficva503p", cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7}, - { "ficva503a", cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7}, - { "v60n", cputables_PentiumPro }, - { "p65up5_cp6nd", cputables_PentiumPro }, - { "8600ttc", cputables_PentiumPro }, - { "686nx", cputables_PentiumPro }, - { "ap440fx", cputables_PentiumPro }, - { "vs440fx", cputables_PentiumPro }, - { "m6mi", cputables_PentiumPro }, - { "mb600n", cputables_PentiumPro }, - { "p65up5_cpknd", cputables_PentiumII66 }, - { "kn97", cputables_PentiumII66 }, - { "lx6", cputables_PentiumII66 }, - { "spitfire", cputables_PentiumII66 }, - { "p6i440e2", cputables_PentiumII66 }, - { "p2bls", cputables_PentiumII_Celeron_Cyrix3 }, - { "p3bf", cputables_PentiumII_Celeron_Cyrix3 }, - { "bf6", cputables_PentiumII_Celeron_Cyrix3 }, - { "ax6bc", cputables_PentiumII_Celeron_Cyrix3 }, - { "atc6310bxii", cputables_PentiumII_Celeron_Cyrix3 }, - { "686bx", cputables_PentiumII_Celeron_Cyrix3 }, - { "tsunamiatx", cputables_PentiumII_Celeron_Cyrix3 }, - { "p6sba", cputables_PentiumII_Celeron_Cyrix3 }, - { "ergox365", cputables_PentiumII_Celeron_Cyrix3 }, - { "ficka6130", cputables_PentiumII_Celeron_Cyrix3 }, - { "6gxu", cputables_Xeon }, - { "fw6400gx", cputables_Xeon }, - { "s2dge", cputables_Xeon }, - { "s370slm", cputables_Celeron_Cyrix3 }, - { "awo671r", cputables_Celeron_Cyrix3 }, - { "cubx", cputables_Celeron_Cyrix3 }, - { "atc7020bxii", cputables_Celeron_Cyrix3 }, - { "ambx133", cputables_Celeron_Cyrix3 }, - { "trinity371", cputables_Celeron }, - { "63a", cputables_Celeron_Cyrix3 }, - { "apas3", cputables_Celeron_Cyrix3 }, - { "wcf681", cputables_Celeron_Cyrix3 }, - { "6via90ap", cputables_Celeron_Cyrix3 }, - { "p6bap", cputables_Celeron_Cyrix3 }, - { "603tcf", cputables_Celeron_Cyrix3 }, - { "vpc2007", cputables_PentiumIID_Celeron }, - { NULL, NULL } -}; diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index b45a7471c..5e864fbb8 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -8764,7 +8764,7 @@ const machine_t machines[] = { /* Has AMI MegaKey 'H' KBC firmware. */ { .name = "[i430LX] Gigabyte GA-586IS", - .internal_name = "586mc1", + .internal_name = "586is", .type = MACHINE_TYPE_SOCKET4, .chipset = MACHINE_CHIPSET_INTEL_430LX, .init = machine_at_586is_init, From ac0f7ec9e7f5e1a7d36a5f25db11ba317097f62c Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 4 Feb 2024 01:23:26 +0600 Subject: [PATCH 423/936] Implement color transparency and 16/24-bpp color patterns --- src/video/vid_c&t_69000.c | 56 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index fae8c04bd..efa619491 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -854,6 +854,43 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) + 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7) + (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7), chips); } + if (chips->bitblt_running.bytes_per_pixel == 2) { + pattern_pixel = chips_69000_readw_linear(chips->bitblt_running.bitblt.pat_addr + + (2 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + + (2 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)), chips); + } + if (chips->bitblt_running.bytes_per_pixel == 3) { + pattern_pixel = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + + (3 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + + (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)), chips); + + pattern_pixel |= chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + + (3 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + + (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)) + 1, chips) << 8; + + pattern_pixel |= chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + + (3 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + + (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)) + 2, chips) << 16; + } + } + + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 14)) { + switch ((chips->bitblt_running.bitblt.bitblt_control >> 15) & 3) { + case 1: + case 3: + { + uint32_t color_key = (chips->bitblt_running.bitblt.monochrome_source_expansion_color_reg_select) + ? chips->bitblt_running.bitblt.source_key_bg + : chips->bitblt_running.bitblt.pattern_source_key_bg; + color_key &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; + + if (!!(color_key == dest_pixel) == !!(chips->bitblt_running.bitblt.bitblt_control & (1 << 16))) { + return; + } + + break; + } + } } switch (chips->bitblt_running.bytes_per_pixel) { @@ -874,6 +911,25 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) } } + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 14)) { + switch ((chips->bitblt_running.bitblt.bitblt_control >> 15) & 3) { + case 0: + case 2: + { + uint32_t color_key = (chips->bitblt_running.bitblt.monochrome_source_expansion_color_reg_select) + ? chips->bitblt_running.bitblt.source_key_bg + : chips->bitblt_running.bitblt.pattern_source_key_bg; + color_key &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; + + if (!!(color_key == dest_pixel) == !!(chips->bitblt_running.bitblt.bitblt_control & (1 << 16))) { + return; + } + + break; + } + } + } + switch (chips->bitblt_running.bytes_per_pixel) { case 1: /* 8 bits-per-pixel. */ { From f582e9716836023fac9dec712ff06e80e13dd14e Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 3 Feb 2024 22:30:14 +0100 Subject: [PATCH 424/936] Refactor 5380-based SCSI controllers This should fix more timing issues with said SCSI controllers in various CPU/HDD/CD-ROM speeds. --- src/scsi/scsi_ncr5380.c | 510 +++++++++++++++++++--------------------- 1 file changed, 241 insertions(+), 269 deletions(-) diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index f271df3ec..5c6f0c22d 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -207,12 +207,6 @@ ncr_log(const char *fmt, ...) #define SET_BUS_STATE(ncr, state) ncr->cur_bus = (ncr->cur_bus & ~(SCSI_PHASE_MESSAGE_IN)) | (state & (SCSI_PHASE_MESSAGE_IN)) -static void -ncr_dma_send(ncr5380_t *ncr_dev, ncr_t *ncr, scsi_device_t *dev); - -static void -ncr_dma_initiator_receive(ncr5380_t *ncr_dev, ncr_t *ncr, scsi_device_t *dev); - static void ncr_callback(void *priv); @@ -256,7 +250,7 @@ static void ncr_reset(ncr5380_t *ncr_dev, ncr_t *ncr) { memset(ncr, 0x00, sizeof(ncr_t)); - ncr_log("NCR reset\n"); + ncr_log("NCR Reset\n"); timer_stop(&ncr_dev->timer); @@ -266,27 +260,6 @@ ncr_reset(ncr5380_t *ncr_dev, ncr_t *ncr) ncr_irq(ncr_dev, ncr, 0); } -static void -ncr_timer_on(ncr5380_t *ncr_dev, ncr_t *ncr, int callback) -{ - double p = ncr_dev->period; - - if (ncr->data_wait & 2) - ncr->data_wait &= ~2; - - if (callback) { - if (ncr_dev->type == 3) - p *= 512.0; - else - p *= 144.0; - } - - p += 1.0; - - ncr_log("P = %lf, command = %02x, callback = %i, period = %lf, t128 pos = %i\n", p, ncr->command[0], callback, ncr_dev->period, ncr_dev->t128.host_pos); - timer_on_auto(&ncr_dev->timer, p); -} - static uint32_t get_bus_host(ncr_t *ncr) { @@ -477,13 +450,8 @@ ncr_bus_update(void *priv, int bus) /*If the SCSI phase is Data In or Data Out, allocate the SCSI buffer based on the transfer length of the command*/ if (dev->buffer_length && (dev->phase == SCSI_PHASE_DATA_IN || dev->phase == SCSI_PHASE_DATA_OUT)) { p = scsi_device_get_callback(dev); - if (p <= 0.0) { - ncr_dev->period = 0.2; - } else { - ncr_dev->period = p / ((double) dev->buffer_length); - } - ncr->data_wait |= 2; - ncr_log("SCSI ID %i: command 0x%02x for p = %lf, update = %lf, len = %i\n", ncr->target_id, ncr->command[0], p, ncr_dev->period, dev->buffer_length); + ncr_dev->period = (p > 0.0) ? p : (((double) dev->buffer_length) * 0.2); + ncr_log("SCSI ID %i: command 0x%02x for p = %lf, update = %lf, len = %i, dmamode = %x\n", ncr->target_id, ncr->command[0], scsi_device_get_callback(dev), ncr_dev->period, dev->buffer_length, ncr->dma_mode); } } ncr->new_phase = dev->phase; @@ -502,14 +470,15 @@ ncr_bus_update(void *priv, int bus) } else { ncr->tx_data = dev->sc->temp_buffer[ncr->data_pos++]; ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(ncr->tx_data) | BUS_DBP | BUS_REQ; - if (ncr->data_wait & 2) - ncr->data_wait &= ~2; if (ncr->dma_mode == DMA_IDLE) { /*If a data in command that is not read 6/10 has been issued*/ ncr->data_wait |= 1; ncr_log("DMA mode idle in\n"); timer_on_auto(&ncr_dev->timer, ncr_dev->period); - } else + } else { + ncr_log("DMA mode IN.\n"); ncr->clear_req = 3; + } + ncr->cur_bus &= ~BUS_REQ; ncr->new_phase = SCSI_PHASE_DATA_IN; } @@ -532,9 +501,9 @@ ncr_bus_update(void *priv, int bus) ncr->data_wait |= 1; ncr_log("DMA mode idle out\n"); timer_on_auto(&ncr_dev->timer, ncr_dev->period); - } else { + } else ncr->clear_req = 3; - } + ncr->cur_bus &= ~BUS_REQ; ncr_log("CurBus ~REQ_DataOut=%02x\n", ncr->cur_bus); } @@ -594,7 +563,7 @@ ncr_write(uint16_t port, uint8_t val, void *priv) { ncr5380_t *ncr_dev = (ncr5380_t *) priv; ncr_t *ncr = &ncr_dev->ncr; - const scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; int bus_host = 0; ncr_log("NCR5380 write(%04x,%02x)\n", port & 7, val); @@ -627,7 +596,7 @@ ncr_write(uint16_t port, uint8_t val, void *priv) /*Don't stop the timer until it finishes the transfer*/ if (ncr_dev->t128.block_loaded && (ncr->mode & MODE_DMA)) { ncr_log("Continuing DMA mode\n"); - ncr_timer_on(ncr_dev, ncr, 0); + timer_on_auto(&ncr_dev->timer, ncr_dev->period + 1.0); } /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ @@ -639,10 +608,9 @@ ncr_write(uint16_t port, uint8_t val, void *priv) } } else { /*Don't stop the timer until it finishes the transfer*/ - if (ncr_dev->block_count_loaded && (ncr->mode & MODE_DMA) && - !timer_is_on(&ncr_dev->timer)) { + if (ncr_dev->block_count_loaded && (ncr->mode & MODE_DMA)) { ncr_log("Continuing DMA mode\n"); - ncr_timer_on(ncr_dev, ncr, 0); + timer_on_auto(&ncr_dev->timer, 40.0); } /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ @@ -669,22 +637,22 @@ ncr_write(uint16_t port, uint8_t val, void *priv) /*a Write 6/10 has occurred, start the timer when the block count is loaded*/ ncr->dma_mode = DMA_SEND; if (ncr_dev->type == 3) { - if (dev->buffer_length > 0) { + if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer) && (dev->buffer_length > 0)) { memset(ncr_dev->t128.buffer, 0, MIN(512, dev->buffer_length)); - - ncr_log("DMA send timer start, enabled? = %i\n", timer_is_on(&ncr_dev->timer)); - ncr_dev->t128.block_count = dev->buffer_length >> 9; - ncr_dev->t128.block_loaded = 1; - - ncr_dev->t128.host_pos = 0; ncr_dev->t128.status |= 0x04; + ncr_dev->t128.host_pos = 0; + ncr_dev->t128.block_count = dev->buffer_length >> 9; + + if (dev->buffer_length < 512) + ncr_dev->t128.block_count = 1; + + ncr_dev->t128.block_loaded = 1; } } else { - if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer)) { + if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer) && (dev->buffer_length > 0)) { memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length)); - ncr_log("DMA send timer on\n"); - ncr_timer_on(ncr_dev, ncr, 0); + timer_on_auto(&ncr_dev->timer, ncr_dev->period + 1.0); } } break; @@ -694,28 +662,23 @@ ncr_write(uint16_t port, uint8_t val, void *priv) /*a Read 6/10 has occurred, start the timer when the block count is loaded*/ ncr->dma_mode = DMA_INITIATOR_RECEIVE; if (ncr_dev->type == 3) { - ncr_log("DMA receive timer start, enabled? = %i, cdb[0] = %02x, buflen = %i\n", - timer_is_on(&ncr_dev->timer), ncr->command[0], dev->buffer_length); - if (dev->buffer_length > 0) { + if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer) && (dev->buffer_length > 0)) { memset(ncr_dev->t128.buffer, 0, MIN(512, dev->buffer_length)); - + ncr_dev->t128.status |= 0x04; + ncr_dev->t128.host_pos = MIN(512, dev->buffer_length); ncr_dev->t128.block_count = dev->buffer_length >> 9; if (dev->buffer_length < 512) ncr_dev->t128.block_count = 1; ncr_dev->t128.block_loaded = 1; - - ncr_dev->t128.host_pos = MIN(512, dev->buffer_length); - ncr_dev->t128.status |= 0x04; timer_on_auto(&ncr_dev->timer, 0.02); } } else { - if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer)) { + if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer) && (dev->buffer_length > 0)) { memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length)); - - ncr_log("DMA receive timer start\n"); - ncr_timer_on(ncr_dev, ncr, 0); + ncr_log("DMA initiator receive timer on\n"); + timer_on_auto(&ncr_dev->timer, ncr_dev->period + 1.0); } } break; @@ -725,10 +688,8 @@ ncr_write(uint16_t port, uint8_t val, void *priv) break; } - if (ncr->dma_mode == DMA_IDLE || ncr_dev->type == 0 || ncr_dev->type >= 3) { - bus_host = get_bus_host(ncr); - ncr_bus_update(priv, bus_host); - } + bus_host = get_bus_host(ncr); + ncr_bus_update(priv, bus_host); } static uint8_t @@ -853,7 +814,7 @@ memio_read(uint32_t addr, void *priv) { ncr5380_t *ncr_dev = (ncr5380_t *) priv; ncr_t *ncr = &ncr_dev->ncr; - const scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; uint8_t ret = 0xff; addr &= 0x3fff; @@ -885,6 +846,7 @@ memio_read(uint32_t addr, void *priv) ret = 0xff; } else { ret = ncr_dev->buffer[ncr_dev->buffer_host_pos++]; + ncr_log("Read host pos = %i, ret = %02x\n", ncr_dev->buffer_host_pos, ret); if (ncr_dev->buffer_host_pos == MIN(128, dev->buffer_length)) { ncr_dev->status_ctrl |= STATUS_BUFFER_NOT_READY; @@ -914,11 +876,9 @@ memio_read(uint32_t addr, void *priv) break; case 0x3982: /* switch register read */ - ret = 0xff; - break; - - case 0x3983: - ret = 0xff; + ret = 0xf8; + ret |= (ncr_dev->irq & 0x07); + ncr_log("Switches read=%02x.\n", ret); break; default: @@ -944,7 +904,7 @@ memio_write(uint32_t addr, uint8_t val, void *priv) { ncr5380_t *ncr_dev = (ncr5380_t *) priv; ncr_t *ncr = &ncr_dev->ncr; - const scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; addr &= 0x3fff; @@ -992,9 +952,6 @@ memio_write(uint32_t addr, uint8_t val, void *priv) ncr_dev->block_count = val; ncr_dev->block_count_loaded = 1; - if (ncr->mode & MODE_DMA) - ncr_timer_on(ncr_dev, ncr, 0); - if (ncr_dev->status_ctrl & CTRL_DATA_DIR) { ncr_dev->buffer_host_pos = MIN(128, dev->buffer_length); ncr_dev->status_ctrl |= STATUS_BUFFER_NOT_READY; @@ -1117,191 +1074,43 @@ t130b_out(uint16_t port, uint8_t val, void *priv) } } -static void -ncr_dma_send(ncr5380_t *ncr_dev, ncr_t *ncr, scsi_device_t *dev) -{ - int bus; - uint8_t data; - - if (scsi_device_get_callback(dev) > 0.0) - ncr_timer_on(ncr_dev, ncr, 1); - else - ncr_timer_on(ncr_dev, ncr, 0); - - for (uint8_t c = 0; c < 10; c++) { - ncr_bus_read(ncr_dev); - if (ncr->cur_bus & BUS_REQ) - break; - } - - /* Data ready. */ - if (ncr_dev->type == 3) - data = ncr_dev->t128.buffer[ncr_dev->t128.pos]; - else - data = ncr_dev->buffer[ncr_dev->buffer_pos]; - bus = get_bus_host(ncr) & ~BUS_DATAMASK; - bus |= BUS_SETDATA(data); - - ncr_bus_update(ncr_dev, bus | BUS_ACK); - ncr_bus_update(ncr_dev, bus & ~BUS_ACK); - - if (ncr_dev->type == 3) { - ncr_dev->t128.pos++; - ncr_log("Buffer pos for writing = %d, data = %02x\n", ncr_dev->t128.pos, data); - - if (ncr_dev->t128.pos == MIN(512, dev->buffer_length)) { - ncr_dev->t128.pos = 0; - ncr_dev->t128.host_pos = 0; - ncr_dev->t128.status &= ~0x02; - ncr_dev->t128.block_count = (ncr_dev->t128.block_count - 1) & 0xff; - ncr_log("Remaining blocks to be written=%d\n", ncr_dev->t128.block_count); - if (!ncr_dev->t128.block_count) { - ncr_dev->t128.block_loaded = 0; - ncr_log("IO End of write transfer\n"); - ncr->tcr |= TCR_LAST_BYTE_SENT; - ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr_dev->timer); - if (ncr->mode & MODE_ENA_EOP_INT) { - ncr_log("NCR write irq\n"); - ncr_irq(ncr_dev, ncr, 1); - } - } - return; - } - } else { - ncr_dev->buffer_pos++; - ncr_log("Buffer pos for writing = %d\n", ncr_dev->buffer_pos); - - if (ncr_dev->buffer_pos == MIN(128, dev->buffer_length)) { - ncr_dev->buffer_pos = 0; - ncr_dev->buffer_host_pos = 0; - ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - ncr_dev->ncr_busy = 0; - ncr_dev->block_count = (ncr_dev->block_count - 1) & 0xff; - ncr_log("Remaining blocks to be written=%d\n", ncr_dev->block_count); - if (!ncr_dev->block_count) { - ncr_dev->block_count_loaded = 0; - ncr_log("IO End of write transfer\n"); - ncr->tcr |= TCR_LAST_BYTE_SENT; - ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr_dev->timer); - if (ncr->mode & MODE_ENA_EOP_INT) { - ncr_log("NCR write irq\n"); - ncr_irq(ncr_dev, ncr, 1); - } - } - return; - } - } - ncr_dma_send(ncr_dev, ncr, dev); -} - -static void -ncr_dma_initiator_receive(ncr5380_t *ncr_dev, ncr_t *ncr, scsi_device_t *dev) -{ - int bus; - uint8_t temp; - - if (scsi_device_get_callback(dev) > 0.0) { - ncr_timer_on(ncr_dev, ncr, 1); - } else { - ncr_timer_on(ncr_dev, ncr, 0); - } - - for (uint8_t c = 0; c < 10; c++) { - ncr_bus_read(ncr_dev); - if (ncr->cur_bus & BUS_REQ) - break; - } - - /* Data ready. */ - ncr_bus_read(ncr_dev); - temp = BUS_GETDATA(ncr->cur_bus); - - bus = get_bus_host(ncr); - - ncr_bus_update(ncr_dev, bus | BUS_ACK); - ncr_bus_update(ncr_dev, bus & ~BUS_ACK); - - if (ncr_dev->type == 3) { - ncr_dev->t128.buffer[ncr_dev->t128.pos++] = temp; - ncr_log("Buffer pos for reading = %d, temp = %02x\n", ncr_dev->t128.pos, temp); - - if (ncr_dev->t128.pos == MIN(512, dev->buffer_length)) { - ncr_dev->t128.pos = 0; - ncr_dev->t128.host_pos = 0; - ncr_dev->t128.status &= ~0x02; - ncr_dev->t128.block_count = (ncr_dev->t128.block_count - 1) & 0xff; - ncr_log("Remaining blocks to be read=%d, status=%02x, len=%i, cdb[0] = %02x\n", ncr_dev->t128.block_count, ncr_dev->t128.status, dev->buffer_length, ncr->command[0]); - if (!ncr_dev->t128.block_count) { - ncr_dev->t128.block_loaded = 0; - ncr_log("IO End of read transfer\n"); - ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr_dev->timer); - if (ncr->mode & MODE_ENA_EOP_INT) { - ncr_log("NCR read irq\n"); - ncr_irq(ncr_dev, ncr, 1); - } - } - return; - } - } else { - ncr_dev->buffer[ncr_dev->buffer_pos++] = temp; - ncr_log("Buffer pos for reading = %d\n", ncr_dev->buffer_pos); - - if (ncr_dev->buffer_pos == MIN(128, dev->buffer_length)) { - ncr_dev->buffer_pos = 0; - ncr_dev->buffer_host_pos = 0; - ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - ncr_dev->block_count = (ncr_dev->block_count - 1) & 0xff; - ncr_log("Remaining blocks to be read=%d\n", ncr_dev->block_count); - if (!ncr_dev->block_count) { - ncr_dev->block_count_loaded = 0; - ncr_log("IO End of read transfer\n"); - ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr_dev->timer); - if (ncr->mode & MODE_ENA_EOP_INT) { - ncr_log("NCR read irq\n"); - ncr_irq(ncr_dev, ncr, 1); - } - } - return; - } - } - ncr_dma_initiator_receive(ncr_dev, ncr, dev); -} - static void ncr_callback(void *priv) { ncr5380_t *ncr_dev = (ncr5380_t *) priv; ncr_t *ncr = &ncr_dev->ncr; scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + int tx = 0; + int bytes_transferred = 0; + int bus; + uint8_t temp; - if (ncr_dev->type == 3) { - ncr_log("DMA Callback, load = %i\n", ncr_dev->t128.block_loaded); - if (ncr->dma_mode != DMA_IDLE && (ncr->mode & MODE_DMA) && ncr_dev->t128.block_loaded) { - ncr_log("Timer on! Host POS = %i, status = %02x, DMA mode = %i, Period = %lf\n", ncr_dev->t128.host_pos, ncr_dev->t128.status, ncr->dma_mode, scsi_device_get_callback(dev)); - if (ncr_dev->t128.host_pos == MIN(512, dev->buffer_length) && ncr_dev->t128.block_count) { - ncr_dev->t128.status |= 0x04; - } - ncr_timer_on(ncr_dev, ncr, 0); - } + if (ncr_dev->type != 3) { + if (ncr->dma_mode != DMA_IDLE) + timer_on_auto(&ncr_dev->timer, 1.0); } else { - ncr_log("DMA mode=%d, status ctrl = %02x\n", ncr->dma_mode, ncr_dev->status_ctrl); - if (ncr->dma_mode != DMA_IDLE && (ncr->mode & MODE_DMA) && ncr_dev->block_count_loaded) { - ncr_timer_on(ncr_dev, ncr, 0); + if ((ncr->dma_mode != DMA_IDLE) && (ncr->mode & MODE_DMA) && ncr_dev->t128.block_loaded) { + if ((ncr_dev->t128.host_pos == MIN(512, dev->buffer_length)) && ncr_dev->t128.block_count) + ncr_dev->t128.status |= 0x04; + + timer_on_auto(&ncr_dev->timer, ncr_dev->period / 55.0); } } if (ncr->data_wait & 1) { ncr->clear_req = 3; ncr->data_wait &= ~1; - if (ncr->dma_mode == DMA_IDLE) { - return; + if (ncr_dev->type == 3) { + if (ncr->dma_mode == DMA_IDLE) + return; } } + if (ncr_dev->type != 3) { + if (ncr->dma_mode == DMA_IDLE) + return; + } + switch (ncr->dma_mode) { case DMA_SEND: if (ncr_dev->type != 3) { @@ -1317,9 +1126,54 @@ ncr_callback(void *priv) if (!ncr_dev->block_count_loaded) break; + + while (bytes_transferred < 50) { + for (tx = 0; tx < 10; tx++) { + ncr_bus_read(ncr_dev); + if (ncr->cur_bus & BUS_REQ) + break; + } + + if (tx == 10) + break; + + /* Data ready. */ + temp = ncr_dev->buffer[ncr_dev->buffer_pos]; + + bus = get_bus_host(ncr) & ~BUS_DATAMASK; + bus |= BUS_SETDATA(temp); + + ncr_bus_update(ncr_dev, bus | BUS_ACK); + ncr_bus_update(ncr_dev, bus & ~BUS_ACK); + + ncr_dev->buffer_pos++; + bytes_transferred++; + ncr_log("Buffer pos for writing = %d\n", ncr_dev->buffer_pos); + + if (ncr_dev->buffer_pos == MIN(128, dev->buffer_length)) { + ncr_dev->buffer_pos = 0; + ncr_dev->buffer_host_pos = 0; + ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + ncr_dev->ncr_busy = 0; + ncr_dev->block_count = (ncr_dev->block_count - 1) & 0xff; + ncr_log("Remaining blocks to be written=%d\n", ncr_dev->block_count); + if (!ncr_dev->block_count) { + ncr_dev->block_count_loaded = 0; + ncr_log("IO End of write transfer\n"); + ncr->tcr |= TCR_LAST_BYTE_SENT; + ncr->isr |= STATUS_END_OF_DMA; + timer_stop(&ncr_dev->timer); + if (ncr->mode & MODE_ENA_EOP_INT) { + ncr_log("NCR write irq\n"); + ncr_irq(ncr_dev, ncr, 1); + } + } + break; + } + } } else { if (!(ncr_dev->t128.status & 0x04)) { - ncr_log("Write status busy\n"); + ncr_log("Write status busy, block count = %i, host pos = %i\n", ncr_dev->t128.block_count, ncr_dev->t128.host_pos); break; } @@ -1330,8 +1184,47 @@ ncr_callback(void *priv) if (ncr_dev->t128.host_pos < MIN(512, dev->buffer_length)) break; + +write_again: + for (uint8_t c = 0; c < 10; c++) { + ncr_bus_read(ncr_dev); + if (ncr->cur_bus & BUS_REQ) + break; + } + + /* Data ready. */ + temp = ncr_dev->t128.buffer[ncr_dev->t128.pos]; + + bus = get_bus_host(ncr) & ~BUS_DATAMASK; + bus |= BUS_SETDATA(temp); + + ncr_bus_update(ncr_dev, bus | BUS_ACK); + ncr_bus_update(ncr_dev, bus & ~BUS_ACK); + + ncr_dev->t128.pos++; + ncr_log("Buffer pos for writing = %d\n", ncr_dev->t128.pos); + + if (ncr_dev->t128.pos == MIN(512, dev->buffer_length)) { + ncr_dev->t128.pos = 0; + ncr_dev->t128.host_pos = 0; + ncr_dev->t128.status &= ~0x02; + ncr_dev->t128.block_count = (ncr_dev->t128.block_count - 1) & 0xff; + ncr_log("Remaining blocks to be written=%d\n", ncr_dev->t128.block_count); + if (!ncr_dev->t128.block_count) { + ncr_dev->t128.block_loaded = 0; + ncr_log("IO End of write transfer\n"); + ncr->tcr |= TCR_LAST_BYTE_SENT; + ncr->isr |= STATUS_END_OF_DMA; + timer_stop(&ncr_dev->timer); + if (ncr->mode & MODE_ENA_EOP_INT) { + ncr_log("NCR write irq\n"); + ncr_irq(ncr_dev, ncr, 1); + } + } + break; + } else + goto write_again; } - ncr_dma_send(ncr_dev, ncr, dev); break; case DMA_INITIATOR_RECEIVE: @@ -1348,6 +1241,49 @@ ncr_callback(void *priv) if (!ncr_dev->block_count_loaded) break; + + while (bytes_transferred < 50) { + for (tx = 0; tx < 10; tx++) { + ncr_bus_read(ncr_dev); + if (ncr->cur_bus & BUS_REQ) + break; + } + + if (tx == 10) + break; + + /* Data ready. */ + ncr_bus_read(ncr_dev); + temp = BUS_GETDATA(ncr->cur_bus); + + bus = get_bus_host(ncr); + + ncr_bus_update(ncr_dev, bus | BUS_ACK); + ncr_bus_update(ncr_dev, bus & ~BUS_ACK); + + ncr_dev->buffer[ncr_dev->buffer_pos++] = temp; + ncr_log("Buffer pos for reading = %d\n", ncr_dev->buffer_pos); + bytes_transferred++; + + if (ncr_dev->buffer_pos == MIN(128, dev->buffer_length)) { + ncr_dev->buffer_pos = 0; + ncr_dev->buffer_host_pos = 0; + ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + ncr_dev->block_count = (ncr_dev->block_count - 1) & 0xff; + ncr_log("Remaining blocks to be read=%d\n", ncr_dev->block_count); + if (!ncr_dev->block_count) { + ncr_dev->block_count_loaded = 0; + ncr_log("IO End of read transfer\n"); + ncr->isr |= STATUS_END_OF_DMA; + timer_stop(&ncr_dev->timer); + if (ncr->mode & MODE_ENA_EOP_INT) { + ncr_log("NCR read irq\n"); + ncr_irq(ncr_dev, ncr, 1); + } + } + break; + } + } } else { if (!(ncr_dev->t128.status & 0x04)) { ncr_log("Read status busy, block count = %i, host pos = %i\n", ncr_dev->t128.block_count, ncr_dev->t128.host_pos); @@ -1361,8 +1297,46 @@ ncr_callback(void *priv) if (ncr_dev->t128.host_pos < MIN(512, dev->buffer_length)) break; + +read_again: + for (uint8_t c = 0; c < 10; c++) { + ncr_bus_read(ncr_dev); + if (ncr->cur_bus & BUS_REQ) + break; + } + + /* Data ready. */ + ncr_bus_read(ncr_dev); + temp = BUS_GETDATA(ncr->cur_bus); + + bus = get_bus_host(ncr); + + ncr_bus_update(ncr_dev, bus | BUS_ACK); + ncr_bus_update(ncr_dev, bus & ~BUS_ACK); + + ncr_dev->t128.buffer[ncr_dev->t128.pos++] = temp; + ncr_log("Buffer pos for reading=%d, temp=%02x, len=%d.\n", ncr_dev->t128.pos, temp, dev->buffer_length); + + if (ncr_dev->t128.pos == MIN(512, dev->buffer_length)) { + ncr_dev->t128.pos = 0; + ncr_dev->t128.host_pos = 0; + ncr_dev->t128.status &= ~0x02; + ncr_dev->t128.block_count = (ncr_dev->t128.block_count - 1) & 0xff; + ncr_log("Remaining blocks to be read=%d, status=%02x, len=%i, cdb[0] = %02x\n", ncr_dev->t128.block_count, ncr_dev->t128.status, dev->buffer_length, ncr->command[0]); + if (!ncr_dev->t128.block_count) { + ncr_dev->t128.block_loaded = 0; + ncr_log("IO End of read transfer\n"); + ncr->isr |= STATUS_END_OF_DMA; + timer_stop(&ncr_dev->timer); + if (ncr->mode & MODE_ENA_EOP_INT) { + ncr_log("NCR read irq\n"); + ncr_irq(ncr_dev, ncr, 1); + } + } + break; + } else + goto read_again; } - ncr_dma_initiator_receive(ncr_dev, ncr, dev); break; default: @@ -1375,7 +1349,8 @@ ncr_callback(void *priv) ncr_log("Updating DMA\n"); ncr->mode &= ~MODE_DMA; ncr->dma_mode = DMA_IDLE; - timer_on_auto(&ncr_dev->timer, 10.0); + if (ncr_dev->type == 3) + timer_on_auto(&ncr_dev->timer, 10.0); } } @@ -1392,12 +1367,12 @@ t128_read(uint32_t addr, void *priv) ret = ncr_dev->bios_rom.rom[addr & 0x1fff]; else if ((addr >= 0x1800) && (addr < 0x1880)) ret = ncr_dev->t128.ext_ram[addr & 0x7f]; - else if ((addr >= 0x1c00) && (addr < 0x1c20)) + else if ((addr >= 0x1c00) && (addr < 0x1c20)) { ret = ncr_dev->t128.ctrl; - else if ((addr >= 0x1c20) && (addr < 0x1c40)) { + ncr_log("T128 ctrl read=%02x, dma=%02x\n", ret, ncr->mode & MODE_DMA); + } else if ((addr >= 0x1c20) && (addr < 0x1c40)) { ret = ncr_dev->t128.status; - ncr_log("T128 status read = %02x, cur bus = %02x, req = %02x, dma = %02x\n", - ret, ncr->cur_bus, ncr->cur_bus & BUS_REQ, ncr->mode & MODE_DMA); + ncr_log("T128 status read=%02x, dma=%02x\n", ret, ncr->mode & MODE_DMA); } else if ((addr >= 0x1d00) && (addr < 0x1e00)) ret = ncr_read((addr - 0x1d00) >> 5, ncr_dev); else if (addr >= 0x1e00 && addr < 0x2000) { @@ -1414,7 +1389,7 @@ t128_read(uint32_t addr, void *priv) ncr_dev->t128.status &= ~0x04; ncr_log("Transfer busy read, status = %02x, period = %lf\n", ncr_dev->t128.status, ncr_dev->period); - if (ncr_dev->period == 0.2 || ncr_dev->period == 0.02) + if ((ncr_dev->period == 0.2) || (ncr_dev->period == 0.02)) timer_on_auto(&ncr_dev->timer, 40.2); } else if ((ncr_dev->t128.host_pos < MIN(512, dev->buffer_length)) && (scsi_device_get_callback(dev) > 100.0)) @@ -1436,12 +1411,11 @@ t128_write(uint32_t addr, uint8_t val, void *priv) if ((addr >= 0x1800) && (addr < 0x1880)) ncr_dev->t128.ext_ram[addr & 0x7f] = val; else if ((addr >= 0x1c00) && (addr < 0x1c20)) { - if ((val & 0x02) && !(ncr_dev->t128.ctrl & 0x02)) { + if ((val & 0x02) && !(ncr_dev->t128.ctrl & 0x02)) ncr_dev->t128.status |= 0x02; - ncr_log("Timer fired\n"); - } + ncr_dev->t128.ctrl = val; - ncr_log("T128 ctrl write = %02x\n", val); + ncr_log("T128 ctrl write=%02x\n", val); } else if ((addr >= 0x1d00) && (addr < 0x1e00)) ncr_write((addr - 0x1d00) >> 5, val, ncr_dev); else if ((addr >= 0x1e00) && (addr < 0x2000)) { @@ -1455,11 +1429,11 @@ t128_write(uint32_t addr, uint8_t val, void *priv) if (ncr_dev->t128.host_pos == MIN(512, dev->buffer_length)) { ncr_dev->t128.status &= ~0x04; + ncr_dev->ncr_busy = 1; ncr_log("Transfer busy write, status = %02x\n", ncr_dev->t128.status); timer_on_auto(&ncr_dev->timer, 0.02); } - } else - ncr_log("Write PDMA addr = %i, val = %02x\n", addr & 0x1ff, val); + } } } @@ -1645,14 +1619,12 @@ ncr_init(const device_t *info) sprintf(&temp[strlen(temp)], " IRQ=%d", ncr_dev->irq); ncr_log("%s\n", temp); - ncr_reset(ncr_dev, &ncr_dev->ncr); if ((ncr_dev->type < 3) || (ncr_dev->type == 4)) { - ncr_dev->status_ctrl = STATUS_BUFFER_NOT_READY; - ncr_dev->buffer_host_pos = 128; + ncr_dev->status_ctrl = STATUS_BUFFER_NOT_READY; + ncr_dev->buffer_host_pos = 128; } else { - ncr_dev->t128.status = 0x04; - ncr_dev->t128.host_pos = 512; - + ncr_dev->t128.status = 0x04; + ncr_dev->t128.host_pos = 512; if (!ncr_dev->t128.bios_enabled) ncr_dev->t128.status |= 0x80; } From 3cfb9edb881f12b16450be18aba571a26d9fd5bd Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 3 Feb 2024 22:52:41 +0100 Subject: [PATCH 425/936] S3 Trio: Fix blanking calculation. --- src/video/vid_s3.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 14728bac8..ad7e77aa7 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3273,10 +3273,8 @@ s3_recalctimings(svga_t *svga) svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18); } - svga->hblankstart = (((svga->crtc[0x5d] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; + svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2] + 1; - if (svga->crtc[0x5d] & 0x04) - svga->hblankstart += 0x100; if (s3->chip >= S3_VISION964) { /* NOTE: The S3 Trio64V+ datasheet says this is bit 7, but then where is bit 6? The datasheets for the pre-Trio64V+ cards say +64, which implies bit 6, @@ -4191,7 +4189,7 @@ s3_trio64v_recalctimings(svga_t *svga) /* Also make sure vertical blanking starts on display end. */ svga->vblankstart = svga->dispend; } else { - svga->hblankstart = (((svga->crtc[0x5d] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; + svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2] + 1; /* NOTE: The S3 Trio64V+ datasheet says this is bit 7, but then where is bit 6? The datasheets for the pre-Trio64V+ cards say +64, which implies bit 6, From ecbe6951d24b68e2ff7d62cd8987cd813ccabddf Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 4 Feb 2024 02:51:45 +0100 Subject: [PATCH 426/936] ET4000: Remove a now long obsolete block from et4000_recalctimings(), fixes #4113. --- src/video/vid_et4000.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index c5e2772f2..1a8e3f531 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -667,12 +667,6 @@ et4000_recalctimings(svga_t *svga) } } - if ((svga->seqregs[0x0e] & 0x02) && ((svga->gdcreg[5] & 0x60) >= 0x40)) { - svga->ma_latch <<= (1 << 0); - svga->rowoffset <<= (1 << 0); - svga->render = svga_render_8bpp_highres; - } - if (dev->type == ET4000_TYPE_TC6058AF) { if (svga->render == svga_render_8bpp_lowres) svga->render = svga_render_8bpp_tseng_lowres; From f21f42445e578c03df62ee17787cfbb2f846580d Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 4 Feb 2024 05:49:53 +0100 Subject: [PATCH 427/936] ET4000: Fix Chain 4. --- src/video/vid_et4000.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 1a8e3f531..984071ade 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -286,11 +286,7 @@ et4000_out(uint16_t addr, uint8_t val, void *priv) return; case 0x3cf: - if ((svga->gdcaddr & 15) == 5) { - svga->chain4 &= ~0x02; - if (val & 0x40) - svga->chain4 |= (svga->seqregs[0x0e] & 0x02); - } else if ((svga->gdcaddr & 15) == 6) { + if ((svga->gdcaddr & 15) == 6) { if (!(svga->crtc[0x36] & 0x10) && !(val & 0x08)) { svga->write_bank = (dev->banking & 0x0f) * 0x10000; svga->read_bank = ((dev->banking >> 4) & 0x0f) * 0x10000; From 35cae93fed7f83c17e9c23facf1c9217abd75c2b Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 4 Feb 2024 16:25:17 +0600 Subject: [PATCH 428/936] More monochrome source work Mostly correct now. --- src/video/vid_c&t_69000.c | 189 +++++++++++++++++++++++++++++++++++++- 1 file changed, 185 insertions(+), 4 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index efa619491..b34c5c826 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -34,6 +34,7 @@ #include <86box/thread.h> #include <86box/i2c.h> #include <86box/vid_ddc.h> +#include <86box/plat_unused.h> #include #pragma pack(push, 1) @@ -134,7 +135,11 @@ typedef struct chips_69000_t { /* Byte counter for BitBLT port writes. */ uint8_t bytes_written; uint32_t bytes_counter; - uint8_t bytes_port[4]; + uint8_t bytes_port[8]; + + /* Monochrome sources. */ + uint8_t mono_is_first_quadword; + uint8_t mono_bit_cntr; } bitblt_running; union { @@ -952,6 +957,153 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) } } +void +chips_69000_process_mono_data(UNUSED(chips_69000_t* chips), uint64_t val) +{ + /* Notes: + Reserved value of 0b000 for monochrome source alignment makes it use Destination Scanline Width. + + TODO: + Actually implement this. + + Figure out how alignment works. The example provided is unclear about non-quadword alignment. + (Outside of the one xf86-video-chips already documents). + Maybe it merely advances the source address pointer by alignment after consuming a byte. + + Edit: It actually consumes all 8 bytes of the quadword before incrementing the pitch. + Which begs the next question: Are those 8 bytes for same-scanline drawing or for y-incremented drawing? + And is 4-byte-or-less alignment relevant for our purposes? The Monochrome Source Register only talks about quadwords, nothing else. + */ + + uint64_t i = 0; + uint8_t is_true = 0; + int orig_x = chips->bitblt_running.x; + int orig_y = chips->bitblt_running.y; + uint32_t source_fg = chips->bitblt_running.bitblt.pattern_source_key_fg; + uint32_t source_bg = chips->bitblt_running.bitblt.pattern_source_key_bg; + + int orig_count_x = chips->bitblt_running.count_x; + int orig_count_y = chips->bitblt_running.count_y; + + chips->bitblt_running.count_x = chips->bitblt_running.count_y = 0; + + if (chips->bitblt_running.bitblt.monochrome_source_expansion_color_reg_select) { + source_fg = chips->bitblt_running.bitblt.source_key_fg; + source_bg = chips->bitblt_running.bitblt.source_key_bg; + } + + for (i = 0; i < 64; i++) { + uint32_t pixel = 0x0; + if (chips->bitblt_running.mono_is_first_quadword && (i < chips->bitblt_running.bitblt.monochrome_source_initial_discard)) + goto increment; + + if (i < chips->bitblt_running.bitblt.monochrome_source_left_clip) + goto increment; + + if (i >= (64 - chips->bitblt_running.bitblt.monochrome_source_right_clip)) + goto increment; + + is_true = !!(val & (1 << (i))); + + if (!is_true && (chips->bitblt_running.bitblt.bitblt_control & (1 << 13))) { + goto increment; + } + + pixel = is_true ? source_fg : source_bg; + pixel &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; + + chips->bitblt_running.x = orig_x + (chips->bitblt_running.count_x); + chips->bitblt_running.y = orig_y + chips->bitblt_running.count_y; + + if ((orig_count_x + (chips->bitblt_running.count_x)) < chips->bitblt_running.actual_destination_width + && (orig_count_y + chips->bitblt_running.count_y) < chips->bitblt_running.actual_destination_height) + chips_69000_process_pixel(chips, pixel); + +increment: + chips->bitblt_running.count_x++; + if (chips->bitblt_running.count_x == 8) { + chips->bitblt_running.count_x = 0; + chips->bitblt_running.count_y++; + } + } + chips->bitblt_running.x = orig_x; + chips->bitblt_running.y = orig_y; + chips->bitblt_running.count_x = orig_count_x; + chips->bitblt_running.count_y = orig_count_y; + chips->bitblt_running.x += chips->bitblt_running.x_dir * 8; + chips->bitblt_running.count_x += 8; + chips->bitblt_running.mono_is_first_quadword = 0; + if (chips->bitblt_running.count_x >= chips->bitblt_running.actual_destination_width) { + chips->bitblt_running.count_y += 8; + chips->bitblt_running.y += chips->bitblt_running.y_dir * 8; + chips->bitblt_running.count_x = 0; + if (chips->bitblt_running.count_y > chips->bitblt_running.actual_destination_height) + chips_69000_bitblt_interrupt(chips); + } +} + +void +chips_69000_process_mono_data_non_qword(UNUSED(chips_69000_t* chips), uint8_t val) +{ + uint64_t i = 0; + uint8_t is_true = 0; + int orig_x = chips->bitblt_running.x; + int orig_y = chips->bitblt_running.y; + uint32_t source_fg = chips->bitblt_running.bitblt.pattern_source_key_fg; + uint32_t source_bg = chips->bitblt_running.bitblt.pattern_source_key_bg; + + if (chips->bitblt_running.bitblt.monochrome_source_expansion_color_reg_select) { + source_fg = chips->bitblt_running.bitblt.source_key_fg; + source_bg = chips->bitblt_running.bitblt.source_key_bg; + } + + for (i = chips->bitblt_running.mono_bit_cntr; i < (chips->bitblt_running.mono_bit_cntr + 8); i++) { + uint32_t pixel = 0x0; + if (chips->bitblt_running.mono_is_first_quadword && (i < chips->bitblt_running.bitblt.monochrome_source_initial_discard)) + continue; + + if (i < chips->bitblt_running.bitblt.monochrome_source_left_clip) + continue; + + if (i >= (64 - chips->bitblt_running.bitblt.monochrome_source_right_clip)) + continue; + + is_true = !!(val & (1 << (8 - (i & 7)))); + + if (!is_true && (chips->bitblt_running.bitblt.bitblt_control & (1 << 13))) { + continue; + } + + pixel = is_true ? source_fg : source_bg; + pixel &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; + + chips->bitblt_running.x = orig_x + (i & 7); + + //if ((chips->bitblt_running.count_x + (i & 7)) < chips->bitblt_running.actual_destination_width) + chips_69000_process_pixel(chips, pixel); + } + chips->bitblt_running.mono_bit_cntr += 8; + chips->bitblt_running.x = orig_x; + chips->bitblt_running.y = orig_y; + chips->bitblt_running.x += chips->bitblt_running.x_dir * 8; + chips->bitblt_running.count_x += 8; + if (chips->bitblt_running.mono_bit_cntr >= 64) { + chips->bitblt_running.mono_is_first_quadword = 0; + chips->bitblt_running.mono_bit_cntr = 0; + } + if (chips->bitblt_running.count_x >= chips->bitblt_running.actual_destination_width) { + chips->bitblt_running.count_y += 1; + chips->bitblt_running.y += chips->bitblt_running.y_dir * 1; + chips->bitblt_running.count_x = 0; + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 8)) { + chips->bitblt_running.x = chips->bitblt_running.actual_destination_width - 1; + } else + chips->bitblt_running.x = 0; + if (chips->bitblt_running.count_y >= chips->bitblt_running.actual_destination_height) + chips_69000_bitblt_interrupt(chips); + } +} + void chips_69000_setup_bitblt(chips_69000_t* chips) { @@ -962,6 +1114,9 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.count_x = chips->bitblt_running.count_y = 0; chips->bitblt_running.bytes_written = 0; chips->bitblt_running.bytes_counter = 0; + chips->bitblt_running.mono_is_first_quadword = 1; + chips->bitblt_running.mono_bit_cntr = 0; + int orig_cycles = cycles; if (chips->bitblt.bitblt_control & (1 << 23)) { chips->bitblt_running.bytes_per_pixel = 1 + ((chips->bitblt.bitblt_control >> 24) & 3); @@ -1010,6 +1165,10 @@ chips_69000_setup_bitblt(chips_69000_t* chips) return; } + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { + pclog("C&T: Monochrome blit\n"); + } + do { do { uint32_t pixel = 0; @@ -1048,7 +1207,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) } else chips->bitblt_running.x = 0; } while ((chips->bitblt_running.count_y++) < chips->bitblt_running.actual_destination_height); - + cycles = orig_cycles; chips_69000_bitblt_interrupt(chips); } @@ -1058,6 +1217,27 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { if (!chips->engine_active) return; + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { + chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; + if (chips->bitblt_running.bitblt.monochrome_source_alignment == 4 + && chips->bitblt_running.bytes_written == 4) { + chips->bitblt_running.bytes_written = 0; + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); + } else if (chips->bitblt_running.bytes_written == 8) { + chips->bitblt_running.bytes_written = 0; + uint64_t mono_data = chips->bitblt_running.bytes_port[0]; + mono_data |= (uint64_t)chips->bitblt_running.bytes_port[1] << 8ull; + mono_data |= (uint64_t)chips->bitblt_running.bytes_port[2] << 16ull; + mono_data |= (uint64_t)chips->bitblt_running.bytes_port[3] << 24ull; + mono_data |= (uint64_t)chips->bitblt_running.bytes_port[4] << 32ull; + mono_data |= (uint64_t)chips->bitblt_running.bytes_port[5] << 40ull; + mono_data |= (uint64_t)chips->bitblt_running.bytes_port[6] << 48ull; + mono_data |= (uint64_t)chips->bitblt_running.bytes_port[7] << 56ull; + chips_69000_process_mono_data(chips, mono_data); + } + return; + } + chips->bitblt_running.bytes_counter++; if (chips->bitblt_running.bytes_counter <= (chips->bitblt_running.bitblt.source_addr & 7)) return; @@ -1291,7 +1471,6 @@ chips_69000_out(uint16_t addr, uint8_t val, void *p) svga_out(addr, val, svga); chips_69000_recalc_banking(chips); return; -#if 1 case 0x3D0: chips->flat_panel_index = val; return; @@ -1302,7 +1481,6 @@ chips_69000_out(uint16_t addr, uint8_t val, void *p) return; case 0x3D3: return chips_69000_write_multimedia(chips, val); -#endif case 0x3D4: svga->crtcreg = val & 0xff; return; @@ -1751,6 +1929,9 @@ void chips_69000_writel_mmio(uint32_t addr, uint32_t val, chips_69000_t* chips) { if (addr & 0x10000) { + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { + pclog("BitBLT mono 0x%08X\n", val); + } chips_69000_bitblt_write(chips, val & 0xFF); chips_69000_bitblt_write(chips, (val >> 8) & 0xFF); chips_69000_bitblt_write(chips, (val >> 16) & 0xFF); From 4e8815e0b70a695de9935fe3f3e9eeda6847dff4 Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Sun, 4 Feb 2024 14:00:18 +0300 Subject: [PATCH 429/936] Add A-Trend 4GPV5 machine (Award 4.99G) --- src/include/86box/machine.h | 1 + src/machine/m_at_386dx_486.c | 23 +++++++++++++++++++++ src/machine/machine_table.c | 40 ++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index f8267539b..4fba180b2 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -533,6 +533,7 @@ extern int machine_at_win471_init(const machine_t *); extern int machine_at_pci400ca_init(const machine_t *); extern int machine_at_vi15g_init(const machine_t *); extern int machine_at_greenb_init(const machine_t *); +extern int machine_at_4gpv5_init(const machine_t *); extern int machine_at_r418_init(const machine_t *); extern int machine_at_ls486e_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 6e3d185d4..5a47af620 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -921,6 +921,29 @@ machine_at_greenb_init(const machine_t *model) return ret; } +int +machine_at_4gpv5_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/4gpv5/4GPV5.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&contaq_82c596a_device); + + device_add(&keyboard_at_device); + + return ret; +} + static void machine_at_sis_85c496_common_init(UNUSED(const machine_t *model)) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 5e864fbb8..a28aa225b 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -6204,6 +6204,46 @@ const machine_t machines[] = { /* 486 machines - Socket 3 */ /* 486 machines with just the ISA slot */ + /* Has a Fujitsu MBL8042H KBC. */ + { + .name = "[Contaq 82C596A] A-Trend 4GPV5", + .internal_name = "4gpv5", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_CONTAQ_82C596, + .init = machine_at_4gpv5_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .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_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Has AMI MegaKey KBC firmware. */ { .name = "[Contaq 82C597] Visionex Green-B", From 778a363b99e2805bd4504986d08c254ac513408c Mon Sep 17 00:00:00 2001 From: maximus105 <58270614+maximus105@users.noreply.github.com> Date: Sun, 4 Feb 2024 17:38:52 +0200 Subject: [PATCH 430/936] Update uk-UA.po --- src/qt/languages/uk-UA.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index e35cd11cc..0d8522f15 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -857,7 +857,7 @@ msgid "About 86Box" msgstr "Про 86Box" msgid "86Box v" -msgstr "86Box v." +msgstr "86Box v" msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." msgstr "Емулятор старих комп'ютерів\n\nАвтори: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nВипускаєтся під ліцензією GNU General Public License версії 2 або більше пізніше. Додадкову інформацію см. у файлі LICENSE." From 0b5d4d03c5d7f88fce3fa3fef9016f6e2f0256de Mon Sep 17 00:00:00 2001 From: maximus105 <58270614+maximus105@users.noreply.github.com> Date: Sun, 4 Feb 2024 17:40:49 +0200 Subject: [PATCH 431/936] Update ru-RU.po --- src/qt/languages/ru-RU.po | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index 75f5a51b7..04f3bc5b3 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -712,6 +712,9 @@ msgstr "Устройство ISABugger" msgid "POST card" msgstr "Карта POST" +msgid "86Box Unit Tester" +msgstr "Модульный Тестер 86Box" + msgid "FONT_SIZE" msgstr "9" @@ -947,7 +950,7 @@ msgid "About 86Box" msgstr "О 86Box" msgid "86Box v" -msgstr "86Box v." +msgstr "86Box v" msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." msgstr "Эмулятор старых компьютеров\n\nАвторы: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nВыпускается под лицензией GNU General Public License версии 2 или более поздней. Дополнительную информацию см. в файле LICENSE." From 26fe0f85a1f46bcdf33e20c3274a1c9f59c4af42 Mon Sep 17 00:00:00 2001 From: maximus105 <58270614+maximus105@users.noreply.github.com> Date: Sun, 4 Feb 2024 17:41:52 +0200 Subject: [PATCH 432/936] Update qt_settingsmachine.ui --- src/qt/qt_settingsmachine.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_settingsmachine.ui b/src/qt/qt_settingsmachine.ui index acdba4493..54bc06f5c 100644 --- a/src/qt/qt_settingsmachine.ui +++ b/src/qt/qt_settingsmachine.ui @@ -100,7 +100,7 @@ - PIT Mode: + PIT mode: From 7d1f3c102efb9b6d94def351b451d18bfd60e73e Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 4 Feb 2024 17:49:41 +0100 Subject: [PATCH 433/936] Contaq 82x59x: Only delete the SMRAM structs on the 597. --- src/chipset/contaq_82c59x.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/chipset/contaq_82c59x.c b/src/chipset/contaq_82c59x.c index ec7050b1e..5c2910227 100644 --- a/src/chipset/contaq_82c59x.c +++ b/src/chipset/contaq_82c59x.c @@ -311,8 +311,10 @@ contaq_82c59x_close(void *priv) { contaq_82c59x_t *dev = (contaq_82c59x_t *) priv; - smram_del(dev->smram[1]); - smram_del(dev->smram[0]); + if (dev->green) { + smram_del(dev->smram[1]); + smram_del(dev->smram[0]); + } free(dev); } From fb335a754a9600ce6897b06b79759ea398ef69aa Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 4 Feb 2024 23:35:37 +0500 Subject: [PATCH 434/936] Merge the XTIDE XT/XT+ and AT/386 BIOS variations --- src/config.c | 22 ++++---- src/disk/hdc.c | 2 - src/disk/hdc_xtide.c | 122 +++++++++++++++++----------------------- src/include/86box/hdc.h | 2 - 4 files changed, 64 insertions(+), 84 deletions(-) diff --git a/src/config.c b/src/config.c index fc68bd7d4..243413e99 100644 --- a/src/config.c +++ b/src/config.c @@ -772,6 +772,7 @@ static void load_storage_controllers(void) { ini_section_t cat = ini_find_section(config, "Storage controllers"); + ini_section_t migration_cat; char *p; char temp[512]; int c; @@ -805,17 +806,16 @@ load_storage_controllers(void) } free_p = 1; } - if (!strcmp(p, "mfm_xt")) - hdc_current = hdc_get_from_internal_name("st506_xt"); - else if (!strcmp(p, "mfm_xt_dtc5150x")) - hdc_current = hdc_get_from_internal_name("st506_xt_dtc5150x"); - else if (!strcmp(p, "mfm_at")) - hdc_current = hdc_get_from_internal_name("st506_at"); - else if (!strcmp(p, "vlb_isa")) - hdc_current = hdc_get_from_internal_name("ide_vlb"); - else if (!strcmp(p, "vlb_isa_2ch")) - hdc_current = hdc_get_from_internal_name("ide_vlb_2ch"); - else + /* Migrate renamed and merged cards. */ + if (!strcmp(p, "xtide_plus")) { + hdc_current = hdc_get_from_internal_name("xtide"); + migration_cat = ini_find_or_create_section(config, "PC/XT XTIDE"); + ini_section_set_string(migration_cat, "bios", "xt_plus"); + } else if (!strcmp(p, "xtide_at_386")) { + hdc_current = hdc_get_from_internal_name("xtide_at"); + migration_cat = ini_find_or_create_section(config, "PC/AT XTIDE"); + ini_section_set_string(migration_cat, "bios", "at_386"); + } else hdc_current = hdc_get_from_internal_name(p); if (free_p) { diff --git a/src/disk/hdc.c b/src/disk/hdc.c index 07df9d0e6..7bfb7e05a 100644 --- a/src/disk/hdc.c +++ b/src/disk/hdc.c @@ -100,12 +100,10 @@ static const struct { { &ide_isa_device }, { &ide_isa_2ch_device }, { &xtide_at_device }, - { &xtide_at_386_device }, { &xtide_at_ps2_device }, { &xta_wdxt150_device }, { &xtide_acculogic_device }, { &xtide_device }, - { &xtide_plus_device }, { &esdi_ps2_device }, { &ide_pci_device }, { &ide_pci_2ch_device }, diff --git a/src/disk/hdc_xtide.c b/src/disk/hdc_xtide.c index dfe5931f1..057d4f0ed 100644 --- a/src/disk/hdc_xtide.c +++ b/src/disk/hdc_xtide.c @@ -49,9 +49,9 @@ #define ROM_PATH_XT "roms/hdd/xtide/ide_xt.bin" #define ROM_PATH_XTP "roms/hdd/xtide/ide_xtp.bin" #define ROM_PATH_AT "roms/hdd/xtide/ide_at.bin" +#define ROM_PATH_AT_386 "roms/hdd/xtide/ide_386.bin" #define ROM_PATH_PS2 "roms/hdd/xtide/SIDE1V12.BIN" #define ROM_PATH_PS2AT "roms/hdd/xtide/ide_at_1_1_5.bin" -#define ROM_PATH_AT_386 "roms/hdd/xtide/ide_386.bin" typedef struct xtide_t { void *ide_board; @@ -136,13 +136,9 @@ xtide_init(const device_t *info) memset(xtide, 0x00, sizeof(xtide_t)); - if (info->local == 1) { - rom_init(&xtide->bios_rom, ROM_PATH_XTP, + rom_init(&xtide->bios_rom, + device_get_bios_file(info, device_get_config_bios("bios"), 0), 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); - } else { - rom_init(&xtide->bios_rom, ROM_PATH_XT, - 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); - } xtide->ide_board = ide_xtide_init(); @@ -153,18 +149,6 @@ xtide_init(const device_t *info) return xtide; } -static int -xtide_available(void) -{ - return (rom_present(ROM_PATH_XT)); -} - -static int -xtide_plus_available(void) -{ - return (rom_present(ROM_PATH_XTP)); -} - static void * xtide_at_init(const device_t *info) { @@ -172,31 +156,15 @@ xtide_at_init(const device_t *info) memset(xtide, 0x00, sizeof(xtide_t)); - if (info->local == 1) { - rom_init(&xtide->bios_rom, ROM_PATH_AT_386, + rom_init(&xtide->bios_rom, + device_get_bios_file(info, device_get_config_bios("bios"), 0), 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); - } else { - rom_init(&xtide->bios_rom, ROM_PATH_AT, - 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); - } device_add(&ide_isa_2ch_device); return xtide; } -static int -xtide_at_available(void) -{ - return (rom_present(ROM_PATH_AT)); -} - -static int -xtide_at_386_available(void) -{ - return (rom_present(ROM_PATH_AT_386)); -} - static void * xtide_acculogic_init(UNUSED(const device_t *info)) { @@ -261,6 +229,50 @@ xtide_at_close(void *priv) free(xtide); } +static const device_config_t xtide_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS", + .type = CONFIG_BIOS, + .default_string = "xt", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, /*W1*/ + .bios = { + { .name = "Regular XT", .internal_name = "xt", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 8192, .files = { ROM_PATH_XT, "" } }, + { .name = "XT+ (V20/V30/8018x)", .internal_name = "xt_plus", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 8192, .files = { ROM_PATH_XTP, "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +static const device_config_t xtide_at_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS", + .type = CONFIG_BIOS, + .default_string = "at", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, /*W1*/ + .bios = { + { .name = "Regular AT", .internal_name = "at", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 8192, .files = { ROM_PATH_AT, "" } }, + { .name = "386", .internal_name = "at_386", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 8192, .files = { ROM_PATH_AT_386, "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + const device_t xtide_device = { .name = "PC/XT XTIDE", .internal_name = "xtide", @@ -269,24 +281,10 @@ const device_t xtide_device = { .init = xtide_init, .close = xtide_close, .reset = NULL, - { .available = xtide_available }, + { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, - .config = NULL -}; - -const device_t xtide_plus_device = { - .name = "PC/XT XTIDE (V20/V30/8018x)", - .internal_name = "xtide_plus", - .flags = DEVICE_ISA, - .local = 1, - .init = xtide_init, - .close = xtide_close, - .reset = NULL, - { .available = xtide_plus_available }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .config = xtide_config }; const device_t xtide_at_device = { @@ -297,24 +295,10 @@ const device_t xtide_at_device = { .init = xtide_at_init, .close = xtide_at_close, .reset = NULL, - { .available = xtide_at_available }, + { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, - .config = NULL -}; - -const device_t xtide_at_386_device = { - .name = "PC/AT XTIDE (386)", - .internal_name = "xtide_at_386", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 1, - .init = xtide_at_init, - .close = xtide_at_close, - .reset = NULL, - { .available = xtide_at_386_available }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .config = xtide_at_config }; const device_t xtide_acculogic_device = { diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h index b0e775886..01f927185 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -89,9 +89,7 @@ extern const device_t xta_wdxt150_device; /* xta_wdxt150 */ extern const device_t xta_hd20_device; /* EuroPC internal */ extern const device_t xtide_device; /* xtide_xt */ -extern const device_t xtide_plus_device; /* xtide_xt_plus */ extern const device_t xtide_at_device; /* xtide_at */ -extern const device_t xtide_at_386_device; /* xtide_at_386 */ extern const device_t xtide_acculogic_device; /* xtide_ps2 */ extern const device_t xtide_at_ps2_device; /* xtide_at_ps2 */ From 795e1bce23220a6009e25670046f1c5e69aba5ef Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Tue, 30 Jan 2024 21:16:37 +0500 Subject: [PATCH 435/936] Change CR0 bit 4 behavior: Now it's always hardcoded to 1, unless the CPU is 386DX with no or 287 FPU --- src/cpu/x86_ops_mov_ctrl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h index b0c841f83..eafe3cdde 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu/x86_ops_mov_ctrl.h @@ -124,7 +124,7 @@ opMOV_CRx_r_a16(uint32_t fetchdat) if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) cpu_state.seg_cs.access &= 0x9f; cr0 = cpu_state.regs[cpu_rm].l; - if (cpu_16bitbus) + if ((cpu_s->cpu_type != CPU_386DX) || (fpu_type == FPU_387)) cr0 |= 0x10; if (!(cr0 & 0x80000000)) mmu_perm = 4; @@ -181,7 +181,7 @@ opMOV_CRx_r_a32(uint32_t fetchdat) if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) cpu_state.seg_cs.access &= 0x9f; cr0 = cpu_state.regs[cpu_rm].l; - if (cpu_16bitbus) + if ((cpu_s->cpu_type != CPU_386DX) || (fpu_type == FPU_387)) cr0 |= 0x10; if (!(cr0 & 0x80000000)) mmu_perm = 4; From 68a73dffe03959647b3e30b134edd294dc2ec6e4 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Tue, 30 Jan 2024 21:20:22 +0500 Subject: [PATCH 436/936] Give the Compaq Deskpro 386 its own set of CPUs Both BIOSes can now take a 16, 20 or 25 MHz 386DX, with the 16 MHz one paired with a 287 FPU. Also remove unused CPU packages from the enum --- src/config.c | 7 ++++- src/cpu/cpu.h | 52 ++++++++++++++++++------------------- src/cpu/cpu_table.c | 11 ++++++++ src/machine/machine_table.c | 8 +++--- 4 files changed, 46 insertions(+), 32 deletions(-) diff --git a/src/config.c b/src/config.c index fc68bd7d4..6507097e9 100644 --- a/src/config.c +++ b/src/config.c @@ -313,7 +313,12 @@ load_machine(void) cpu_f = NULL; p = ini_section_get_string(cat, "cpu_family", NULL); if (p) { - cpu_f = cpu_get_family(p); + /* Migrate CPU family changes. */ + if ((!strcmp(machines[machine].internal_name, "deskpro386") || + !strcmp(machines[machine].internal_name, "deskpro386_05_1988"))) + cpu_f = cpu_get_family("i386dx_deskpro386"); + else + cpu_f = cpu_get_family(p); if (cpu_f && !cpu_family_is_eligible(cpu_f, machine)) /* only honor eligible families */ cpu_f = NULL; diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index c525fac2a..8e378ebce 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -86,33 +86,31 @@ enum { }; enum { - CPU_PKG_8088 = (1 << 0), - CPU_PKG_8088_EUROPC = (1 << 1), - CPU_PKG_8086 = (1 << 2), - CPU_PKG_188 = (1 << 3), - CPU_PKG_186 = (1 << 4), - CPU_PKG_286 = (1 << 5), - CPU_PKG_386SX = (1 << 6), - CPU_PKG_386DX = (1 << 7), - CPU_PKG_M6117 = (1 << 8), - CPU_PKG_386SLC_IBM = (1 << 9), - CPU_PKG_486SLC = (1 << 10), - CPU_PKG_486SLC_IBM = (1 << 11), - CPU_PKG_486BL = (1 << 12), - CPU_PKG_486DLC = (1 << 13), - CPU_PKG_SOCKET1 = (1 << 14), - CPU_PKG_SOCKET3 = (1 << 15), - CPU_PKG_SOCKET3_PC330 = (1 << 16), - CPU_PKG_STPC = (1 << 17), - CPU_PKG_SOCKET4 = (1 << 18), - CPU_PKG_SOCKET5_7 = (1 << 19), - CPU_PKG_SOCKET8 = (1 << 20), - CPU_PKG_SLOT1 = (1 << 21), - CPU_PKG_SLOT2 = (1 << 22), - CPU_PKG_SLOTA = (1 << 23), - CPU_PKG_SOCKET370 = (1 << 24), - CPU_PKG_SOCKETA = (1 << 25), - CPU_PKG_EBGA368 = (1 << 26) + CPU_PKG_8088 = (1 << 0), + CPU_PKG_8088_EUROPC = (1 << 1), + CPU_PKG_8086 = (1 << 2), + CPU_PKG_188 = (1 << 3), + CPU_PKG_186 = (1 << 4), + CPU_PKG_286 = (1 << 5), + CPU_PKG_386SX = (1 << 6), + CPU_PKG_386DX = (1 << 7), + CPU_PKG_386DX_DESKPRO386 = (1 << 8), + CPU_PKG_M6117 = (1 << 9), + CPU_PKG_386SLC_IBM = (1 << 10), + CPU_PKG_486SLC = (1 << 11), + CPU_PKG_486SLC_IBM = (1 << 12), + CPU_PKG_486BL = (1 << 13), + CPU_PKG_486DLC = (1 << 14), + CPU_PKG_SOCKET1 = (1 << 15), + CPU_PKG_SOCKET3 = (1 << 16), + CPU_PKG_SOCKET3_PC330 = (1 << 17), + CPU_PKG_STPC = (1 << 18), + CPU_PKG_SOCKET4 = (1 << 19), + CPU_PKG_SOCKET5_7 = (1 << 20), + CPU_PKG_SOCKET8 = (1 << 21), + CPU_PKG_SLOT1 = (1 << 22), + CPU_PKG_SLOT2 = (1 << 23), + CPU_PKG_SOCKET370 = (1 << 24) }; #define CPU_SUPPORTS_DYNAREC 1 diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 195d432ff..7a478f6f0 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -1043,6 +1043,17 @@ const cpu_family_t cpu_families[] = { {"", 0} } }, { + .package = CPU_PKG_386DX_DESKPRO386, + .manufacturer = "Intel", + .name = "i386DX", + .internal_name = "i386dx_deskpro386", + .cpus = (const CPU[]) { + {"16", CPU_386DX, fpus_80286, 16000000, 1, 5000, 0x0308, 0, 0, 0, 3,3,3,3, 2}, + {"20", CPU_386DX, fpus_80386, 20000000, 1, 5000, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"25", CPU_386DX, fpus_80386, 25000000, 1, 5000, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"", 0} + } + }, { .package = CPU_PKG_386DX, .manufacturer = "Intel", .name = "RapidCAD", diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index a28aa225b..d2e49709e 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -4913,10 +4913,10 @@ const machine_t machines[] = { .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_386DX, + .package = CPU_PKG_386DX_DESKPRO386, .block = CPU_BLOCK(CPU_486DLC, CPU_RAPIDCAD), .min_bus = 16000000, - .max_bus = 16000000, + .max_bus = 25000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -4952,9 +4952,9 @@ const machine_t machines[] = { .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_386DX, + .package = CPU_PKG_386DX_DESKPRO386, .block = CPU_BLOCK(CPU_486DLC, CPU_RAPIDCAD), - .min_bus = 25000000, + .min_bus = 16000000, .max_bus = 25000000, .min_voltage = 0, .max_voltage = 0, From 485d17e117ee743a9c3da831fccfcdfa9048dd60 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 5 Feb 2024 13:03:34 +0600 Subject: [PATCH 437/936] Fix height overdrawing and BitBlt direction --- src/video/vid_c&t_69000.c | 59 +++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index b34c5c826..a101232b9 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -127,7 +127,7 @@ typedef struct chips_69000_t { uint32_t actual_destination_width; uint32_t count_x, count_y; - uint32_t x, y; + int x, y; int x_dir, y_dir; uint8_t bytes_per_pixel; @@ -1079,7 +1079,7 @@ chips_69000_process_mono_data_non_qword(UNUSED(chips_69000_t* chips), uint8_t va chips->bitblt_running.x = orig_x + (i & 7); - //if ((chips->bitblt_running.count_x + (i & 7)) < chips->bitblt_running.actual_destination_width) + if ((chips->bitblt_running.count_x + (i & 7)) <= chips->bitblt_running.actual_destination_width) chips_69000_process_pixel(chips, pixel); } chips->bitblt_running.mono_bit_cntr += 8; @@ -1095,10 +1095,7 @@ chips_69000_process_mono_data_non_qword(UNUSED(chips_69000_t* chips), uint8_t va chips->bitblt_running.count_y += 1; chips->bitblt_running.y += chips->bitblt_running.y_dir * 1; chips->bitblt_running.count_x = 0; - if (chips->bitblt_running.bitblt.bitblt_control & (1 << 8)) { - chips->bitblt_running.x = chips->bitblt_running.actual_destination_width - 1; - } else - chips->bitblt_running.x = 0; + chips->bitblt_running.x = 0; if (chips->bitblt_running.count_y >= chips->bitblt_running.actual_destination_height) chips_69000_bitblt_interrupt(chips); } @@ -1126,28 +1123,23 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.actual_destination_width = chips->bitblt_running.bitblt.destination_width / chips->bitblt_running.bytes_per_pixel; + chips->bitblt_running.x = 0; + chips->bitblt_running.y = 0; + switch ((chips->bitblt_running.bitblt.bitblt_control >> 8) & 3) { case 0: - chips->bitblt_running.x = 0; - chips->bitblt_running.y = 0; chips->bitblt_running.x_dir = 1; chips->bitblt_running.y_dir = 1; break; case 1: - chips->bitblt_running.x = chips->bitblt_running.actual_destination_width - 1; - chips->bitblt_running.y = 0; chips->bitblt_running.x_dir = -1; chips->bitblt_running.y_dir = 1; break; case 2: - chips->bitblt_running.x = 0; - chips->bitblt_running.y = chips->bitblt_running.bitblt.destination_height; chips->bitblt_running.x_dir = 1; chips->bitblt_running.y_dir = -1; break; case 3: - chips->bitblt_running.x = chips->bitblt_running.actual_destination_width - 1; - chips->bitblt_running.y = chips->bitblt_running.bitblt.destination_height; chips->bitblt_running.x_dir = -1; chips->bitblt_running.y_dir = -1; break; @@ -1161,12 +1153,21 @@ chips_69000_setup_bitblt(chips_69000_t* chips) return; } - if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { - return; + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { + pclog("C&T: Monochrome blit (monochrome_source_alignment = %d, " + "monochrome left clip = %d, " + "monochrome right clip = %d, " + "monochrome initial discard = %d, " + "destination_width = %d, destination_height = %d\n", chips->bitblt_running.bitblt.monochrome_source_alignment, + chips->bitblt_running.bitblt.monochrome_source_left_clip, + chips->bitblt_running.bitblt.monochrome_source_right_clip, + chips->bitblt_running.bitblt.monochrome_source_initial_discard, + chips->bitblt_running.bitblt.destination_width, + chips->bitblt_running.bitblt.destination_height); } - if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { - pclog("C&T: Monochrome blit\n"); + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { + return; } do { @@ -1202,11 +1203,8 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.y += chips->bitblt_running.y_dir; chips->bitblt_running.count_x = 0; - if (chips->bitblt_running.bitblt.bitblt_control & (1 << 8)) { - chips->bitblt_running.x = chips->bitblt_running.actual_destination_width - 1; - } else - chips->bitblt_running.x = 0; - } while ((chips->bitblt_running.count_y++) < chips->bitblt_running.actual_destination_height); + chips->bitblt_running.x = 0; + } while ((++chips->bitblt_running.count_y) < chips->bitblt_running.actual_destination_height); cycles = orig_cycles; chips_69000_bitblt_interrupt(chips); } @@ -1223,6 +1221,12 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { && chips->bitblt_running.bytes_written == 4) { chips->bitblt_running.bytes_written = 0; chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); + if (chips->bitblt_running.actual_destination_width > 8) + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[1]); + if (chips->bitblt_running.actual_destination_width > 16) + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[2]); + if (chips->bitblt_running.actual_destination_width > 24) + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[3]); } else if (chips->bitblt_running.bytes_written == 8) { chips->bitblt_running.bytes_written = 0; uint64_t mono_data = chips->bitblt_running.bytes_port[0]; @@ -1264,10 +1268,7 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { chips->bitblt_running.bytes_counter = 0; chips->bitblt_running.count_x = 0; - if (chips->bitblt_running.bitblt.bitblt_control & (1 << 8)) { - chips->bitblt_running.x = chips->bitblt_running.actual_destination_width - 1; - } else - chips->bitblt_running.x = 0; + chips->bitblt_running.x = 0; if (chips->bitblt_running.count_y >= chips->bitblt_running.actual_destination_height) { chips_69000_bitblt_interrupt(chips); @@ -1820,8 +1821,6 @@ chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) case 0x00 ... 0x28: chips->bitblt_regs_b[addr & 0xFF] = val; if ((addr & 0xFFF) == 0x023 && chips->bitblt_regs[0x8] != 0) { - uint8_t cntr = 0; - pclog("BitBLT/Draw operation %hd\n", (uint8_t)cntr++); chips_69000_setup_bitblt(chips); } break; @@ -1929,7 +1928,7 @@ void chips_69000_writel_mmio(uint32_t addr, uint32_t val, chips_69000_t* chips) { if (addr & 0x10000) { - if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { + if ((chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) && chips->bitblt_running.bitblt.destination_width > 8) { pclog("BitBLT mono 0x%08X\n", val); } chips_69000_bitblt_write(chips, val & 0xFF); From d6e1d6aa322f51edb2e5c9a7faa5de883e8c2b15 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 5 Feb 2024 15:23:36 +0600 Subject: [PATCH 438/936] Monochrome drawing is now finally fixed --- src/video/vid_c&t_69000.c | 196 +++++++++++++++++++------------------- 1 file changed, 98 insertions(+), 98 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index a101232b9..afdc748e6 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -405,10 +405,10 @@ chips_69000_do_rop_24bpp(uint32_t *dst, uint32_t src, uint8_t rop) } void -chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t src, uint8_t nonpattern_src, uint8_t rop) +chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t pattern, uint8_t src, uint8_t rop) { if ((rop & 0xF) == ((rop >> 4) & 0xF)) { - return chips_69000_do_rop_8bpp(dst, nonpattern_src, rop); + return chips_69000_do_rop_8bpp(dst, src, rop); } switch (rop) { @@ -416,84 +416,84 @@ chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t src, uint8_t nonpattern_ *dst = 0; break; case 0x05: - *dst = ~(*dst) & ~src; + *dst = ~(*dst) & ~pattern; break; case 0x0A: - *dst &= ~src; + *dst &= ~pattern; break; case 0x0F: - *dst = ~src; + *dst = ~pattern; break; case 0x1A: - *dst = src ^ (*dst | (src & nonpattern_src)); + *dst = pattern ^ (*dst | (pattern & src)); break; case 0x2A: - *dst = *dst & (~(nonpattern_src & src)); + *dst = *dst & (~(src & pattern)); break; case 0x3A: - *dst = nonpattern_src ^ (src | (*dst ^ nonpattern_src)); + *dst = src ^ (pattern | (*dst ^ src)); break; case 0x4A: - *dst = *dst ^ (src & (nonpattern_src | *dst)); + *dst = *dst ^ (pattern & (src | *dst)); break; case 0x50: - *dst = src & ~(*dst); + *dst = pattern & ~(*dst); break; case 0x55: *dst = ~*dst; break; case 0x5A: - *dst ^= src; + *dst ^= pattern; break; case 0x5F: - *dst = ~src | ~(*dst); + *dst = ~pattern | ~(*dst); break; case 0x6A: - *dst = *dst ^ (src & nonpattern_src); + *dst = *dst ^ (pattern & src); break; case 0x7A: - *dst = *dst ^ (src & (nonpattern_src | (~*dst))); + *dst = *dst ^ (pattern & (src | (~*dst))); break; case 0x8A: - *dst = *dst & (nonpattern_src | (~src)); + *dst = *dst & (src | (~pattern)); break; case 0x9A: - *dst = *dst ^ (src & (~nonpattern_src)); + *dst = *dst ^ (pattern & (~src)); break; case 0xB8: - *dst = (((src ^ *dst) & nonpattern_src) ^ src); + *dst = (((pattern ^ *dst) & src) ^ pattern); break; case 0xA0: - *dst &= src; + *dst &= pattern; break; case 0xA5: - *dst ^= ~src; + *dst ^= ~pattern; break; case 0xAA: break; /* No-op. */ case 0xAF: - *dst |= ~src; + *dst |= ~pattern; break; case 0xBA: - *dst |= (src & ~nonpattern_src); + *dst |= (pattern & ~src); break; case 0xCA: - *dst ^= (src & (nonpattern_src ^ *dst)); + *dst ^= (pattern & (src ^ *dst)); break; case 0xDA: - *dst ^= src & (~(nonpattern_src & *dst)); + *dst ^= pattern & (~(src & *dst)); break; case 0xEA: - *dst |= src & nonpattern_src; + *dst |= pattern & src; break; case 0xF0: - *dst = src; + *dst = pattern; break; case 0xF5: - *dst = src | ~(*dst); + *dst = pattern | ~(*dst); break; case 0xFA: - *dst |= src; + *dst |= pattern; break; case 0xFF: *dst = 0xFF; @@ -502,10 +502,10 @@ chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t src, uint8_t nonpattern_ } void -chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint16_t nonpattern_src, uint8_t rop) +chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t pattern, uint16_t src, uint8_t rop) { if ((rop & 0xF) == ((rop >> 4) & 0xF)) { - return chips_69000_do_rop_16bpp(dst, nonpattern_src, rop); + return chips_69000_do_rop_16bpp(dst, src, rop); } switch (rop) { @@ -513,84 +513,84 @@ chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint16_t nonpatt *dst = 0; break; case 0x05: - *dst = ~(*dst) & ~src; + *dst = ~(*dst) & ~pattern; break; case 0x0A: - *dst &= ~src; + *dst &= ~pattern; break; case 0x0F: - *dst = ~src; + *dst = ~pattern; break; case 0x1A: - *dst = src ^ (*dst | (src & nonpattern_src)); + *dst = pattern ^ (*dst | (pattern & src)); break; case 0x2A: - *dst = *dst & (~(nonpattern_src & src)); + *dst = *dst & (~(src & pattern)); break; case 0x3A: - *dst = nonpattern_src ^ (src | (*dst ^ nonpattern_src)); + *dst = src ^ (pattern | (*dst ^ src)); break; case 0x4A: - *dst = *dst ^ (src & (nonpattern_src | *dst)); + *dst = *dst ^ (pattern & (src | *dst)); break; case 0x50: - *dst = src & ~(*dst); + *dst = pattern & ~(*dst); break; case 0x55: *dst = ~*dst; break; case 0x5A: - *dst ^= src; + *dst ^= pattern; break; case 0x5F: - *dst = ~src | ~(*dst); + *dst = ~pattern | ~(*dst); break; case 0x6A: - *dst = *dst ^ (src & nonpattern_src); + *dst = *dst ^ (pattern & src); break; case 0x7A: - *dst = *dst ^ (src & (nonpattern_src | (~*dst))); + *dst = *dst ^ (pattern & (src | (~*dst))); break; case 0x8A: - *dst = *dst & (nonpattern_src | (~src)); + *dst = *dst & (src | (~pattern)); break; case 0x9A: - *dst = *dst ^ (src & (~nonpattern_src)); + *dst = *dst ^ (pattern & (~src)); break; case 0xB8: - *dst = (((src ^ *dst) & nonpattern_src) ^ src); + *dst = (((pattern ^ *dst) & src) ^ pattern); break; case 0xA0: - *dst &= src; + *dst &= pattern; break; case 0xA5: - *dst ^= ~src; + *dst ^= ~pattern; break; case 0xAA: break; /* No-op. */ case 0xAF: - *dst |= ~src; + *dst |= ~pattern; break; case 0xBA: - *dst |= (src & ~nonpattern_src); + *dst |= (pattern & ~src); break; case 0xCA: - *dst ^= (src & (nonpattern_src ^ *dst)); + *dst ^= (pattern & (src ^ *dst)); break; case 0xDA: - *dst ^= src & (~(nonpattern_src & *dst)); + *dst ^= pattern & (~(src & *dst)); break; case 0xEA: - *dst |= src & nonpattern_src; + *dst |= pattern & src; break; case 0xF0: - *dst = src; + *dst = pattern; break; case 0xF5: - *dst = src | ~(*dst); + *dst = pattern | ~(*dst); break; case 0xFA: - *dst |= src; + *dst |= pattern; break; case 0xFF: *dst = 0xFF; @@ -599,12 +599,12 @@ chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint16_t nonpatt } void -chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t src, uint32_t nonpattern_src, uint8_t rop) +chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t pattern, uint32_t src, uint8_t rop) { uint32_t orig_dst = *dst & 0xFF000000; if ((rop & 0xF) == ((rop >> 4) & 0xF)) { - return chips_69000_do_rop_24bpp(dst, nonpattern_src, rop); + return chips_69000_do_rop_24bpp(dst, src, rop); } switch (rop) { @@ -612,84 +612,84 @@ chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t src, uint32_t nonpatt *dst = 0; break; case 0x05: - *dst = ~(*dst) & ~src; + *dst = ~(*dst) & ~pattern; break; case 0x0A: - *dst &= ~src; + *dst &= ~pattern; break; case 0x0F: - *dst = ~src; + *dst = ~pattern; break; case 0x1A: - *dst = src ^ (*dst | (src & nonpattern_src)); + *dst = pattern ^ (*dst | (pattern & src)); break; case 0x2A: - *dst = *dst & (~(nonpattern_src & src)); + *dst = *dst & (~(src & pattern)); break; case 0x3A: - *dst = nonpattern_src ^ (src | (*dst ^ nonpattern_src)); + *dst = src ^ (pattern | (*dst ^ src)); break; case 0x4A: - *dst = *dst ^ (src & (nonpattern_src | *dst)); + *dst = *dst ^ (pattern & (src | *dst)); break; case 0x50: - *dst = src & ~(*dst); + *dst = pattern & ~(*dst); break; case 0x55: *dst = ~*dst; break; case 0x5A: - *dst ^= src; + *dst ^= pattern; break; case 0x5F: - *dst = ~src | ~(*dst); + *dst = ~pattern | ~(*dst); break; case 0x6A: - *dst = *dst ^ (src & nonpattern_src); + *dst = *dst ^ (pattern & src); break; case 0x7A: - *dst = *dst ^ (src & (nonpattern_src | (~*dst))); + *dst = *dst ^ (pattern & (src | (~*dst))); break; case 0x8A: - *dst = *dst & (nonpattern_src | (~src)); + *dst = *dst & (src | (~pattern)); break; case 0x9A: - *dst = *dst ^ (src & (~nonpattern_src)); + *dst = *dst ^ (pattern & (~src)); break; case 0xB8: - *dst = (((src ^ *dst) & nonpattern_src) ^ src); + *dst = (((pattern ^ *dst) & src) ^ pattern); break; case 0xA0: - *dst &= src; + *dst &= pattern; break; case 0xA5: - *dst ^= ~src; + *dst ^= ~pattern; break; case 0xAA: break; /* No-op. */ case 0xAF: - *dst |= ~src; + *dst |= ~pattern; break; case 0xBA: - *dst |= (src & ~nonpattern_src); + *dst |= (pattern & ~src); break; case 0xCA: - *dst ^= (src & (nonpattern_src ^ *dst)); + *dst ^= (pattern & (src ^ *dst)); break; case 0xDA: - *dst ^= src & (~(nonpattern_src & *dst)); + *dst ^= pattern & (~(src & *dst)); break; case 0xEA: - *dst |= src & nonpattern_src; + *dst |= pattern & src; break; case 0xF0: - *dst = src; + *dst = pattern; break; case 0xF5: - *dst = src | ~(*dst); + *dst = pattern | ~(*dst); break; case 0xFA: - *dst |= src; + *dst |= pattern; break; case 0xFF: *dst = 0xFF; @@ -1048,7 +1048,6 @@ chips_69000_process_mono_data_non_qword(UNUSED(chips_69000_t* chips), uint8_t va uint64_t i = 0; uint8_t is_true = 0; int orig_x = chips->bitblt_running.x; - int orig_y = chips->bitblt_running.y; uint32_t source_fg = chips->bitblt_running.bitblt.pattern_source_key_fg; uint32_t source_bg = chips->bitblt_running.bitblt.pattern_source_key_bg; @@ -1059,6 +1058,7 @@ chips_69000_process_mono_data_non_qword(UNUSED(chips_69000_t* chips), uint8_t va for (i = chips->bitblt_running.mono_bit_cntr; i < (chips->bitblt_running.mono_bit_cntr + 8); i++) { uint32_t pixel = 0x0; + if (chips->bitblt_running.mono_is_first_quadword && (i < chips->bitblt_running.bitblt.monochrome_source_initial_discard)) continue; @@ -1068,7 +1068,7 @@ chips_69000_process_mono_data_non_qword(UNUSED(chips_69000_t* chips), uint8_t va if (i >= (64 - chips->bitblt_running.bitblt.monochrome_source_right_clip)) continue; - is_true = !!(val & (1 << (8 - (i & 7)))); + is_true = !!(val & (1 << (7 - (i & 7)))); if (!is_true && (chips->bitblt_running.bitblt.bitblt_control & (1 << 13))) { continue; @@ -1077,14 +1077,13 @@ chips_69000_process_mono_data_non_qword(UNUSED(chips_69000_t* chips), uint8_t va pixel = is_true ? source_fg : source_bg; pixel &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; - chips->bitblt_running.x = orig_x + (i & 7); + chips->bitblt_running.x = (orig_x + (i & 7) * chips->bitblt_running.x_dir); - if ((chips->bitblt_running.count_x + (i & 7)) <= chips->bitblt_running.actual_destination_width) + if ((chips->bitblt_running.count_x + (i & 7)) < chips->bitblt_running.actual_destination_width) chips_69000_process_pixel(chips, pixel); } chips->bitblt_running.mono_bit_cntr += 8; chips->bitblt_running.x = orig_x; - chips->bitblt_running.y = orig_y; chips->bitblt_running.x += chips->bitblt_running.x_dir * 8; chips->bitblt_running.count_x += 8; if (chips->bitblt_running.mono_bit_cntr >= 64) { @@ -1147,11 +1146,15 @@ chips_69000_setup_bitblt(chips_69000_t* chips) /* Drawing is pointless if monochrome pattern is enabled, monochrome write-masking is enabled and solid pattern is enabled. */ if ((chips->bitblt_running.bitblt.bitblt_control & (1 << 17)) - && (chips->bitblt_running.bitblt.bitblt_control & (1 << 18)) - && (chips->bitblt_running.bitblt.bitblt_control & (1 << 19))) { - chips_69000_bitblt_interrupt(chips); - return; - } + && (chips->bitblt_running.bitblt.bitblt_control & (1 << 18)) + && (chips->bitblt_running.bitblt.bitblt_control & (1 << 19))) { + chips_69000_bitblt_interrupt(chips); + return; + } + + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { + return; + } if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { pclog("C&T: Monochrome blit (monochrome_source_alignment = %d, " @@ -1166,10 +1169,6 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.bitblt.destination_height); } - if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { - return; - } - do { do { uint32_t pixel = 0; @@ -1212,8 +1211,9 @@ chips_69000_setup_bitblt(chips_69000_t* chips) void chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { - if (!chips->engine_active) + if (!chips->engine_active) { return; + } if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; @@ -1928,8 +1928,8 @@ void chips_69000_writel_mmio(uint32_t addr, uint32_t val, chips_69000_t* chips) { if (addr & 0x10000) { - if ((chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) && chips->bitblt_running.bitblt.destination_width > 8) { - pclog("BitBLT mono 0x%08X\n", val); + if ((chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { + //pclog("BitBLT mono 0x%08X\n", val); } chips_69000_bitblt_write(chips, val & 0xFF); chips_69000_bitblt_write(chips, (val >> 8) & 0xFF); From 7b05547e5931c5f856875ec3dfba5b59e66322a2 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 5 Feb 2024 15:41:10 +0600 Subject: [PATCH 439/936] Use bytes to count image --- src/video/vid_c&t_69000.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index afdc748e6..f47de012d 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -135,6 +135,7 @@ typedef struct chips_69000_t { /* Byte counter for BitBLT port writes. */ uint8_t bytes_written; uint32_t bytes_counter; + uint32_t bytes_in_line_written; uint8_t bytes_port[8]; /* Monochrome sources. */ @@ -1112,6 +1113,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.bytes_counter = 0; chips->bitblt_running.mono_is_first_quadword = 1; chips->bitblt_running.mono_bit_cntr = 0; + chips->bitblt_running.bytes_in_line_written = 0; int orig_cycles = cycles; if (chips->bitblt.bitblt_control & (1 << 23)) { @@ -1153,6 +1155,9 @@ chips_69000_setup_bitblt(chips_69000_t* chips) } if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { + if (!(chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { + pclog("source_span = %d, dest_span = %d\n", chips->bitblt_running.bitblt.source_span, chips->bitblt_running.bitblt.destination_span); + } return; } @@ -1253,11 +1258,13 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { source_pixel |= (chips->bitblt_running.bytes_port[1] << 8); if (chips->bitblt_running.bytes_per_pixel == 3) source_pixel |= (chips->bitblt_running.bytes_port[2] << 16); + + chips->bitblt_running.bytes_in_line_written += chips->bitblt_running.bytes_per_pixel; chips_69000_process_pixel(chips, source_pixel); chips->bitblt_running.x += chips->bitblt_running.x_dir; - if (++chips->bitblt_running.count_x >= chips->bitblt_running.actual_destination_width) { + if (chips->bitblt_running.bytes_in_line_written >= chips->bitblt_running.bitblt.destination_width) { if (chips->bitblt_running.bitblt.destination_width & 7) chips->bitblt_running.bitblt.source_addr = 8 - (chips->bitblt_running.bitblt.destination_width & 7); else @@ -1266,6 +1273,7 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { chips->bitblt_running.y += chips->bitblt_running.y_dir; chips->bitblt_running.count_y++; chips->bitblt_running.bytes_counter = 0; + chips->bitblt_running.bytes_in_line_written = 0; chips->bitblt_running.count_x = 0; chips->bitblt_running.x = 0; From e60c1dfc50d6837c733b270839bc7ac98f02566d Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 6 Feb 2024 04:23:44 +0100 Subject: [PATCH 440/936] ET3000AX and ET4000AX fixes. --- src/video/vid_et3000.c | 316 +++++++++++++++++++++++++++++++++++++---- src/video/vid_et4000.c | 78 ++++++++-- 2 files changed, 356 insertions(+), 38 deletions(-) diff --git a/src/video/vid_et3000.c b/src/video/vid_et3000.c index 4f7dbae3e..97da08822 100644 --- a/src/video/vid_et3000.c +++ b/src/video/vid_et3000.c @@ -14,11 +14,13 @@ * * Copyright 2016-2018 Miran Grca. */ -#include +#include #include +#include #include #include #include +#define HAVE_STDARG_H #include <86box/86box.h> #include <86box/io.h> #include <86box/mca.h> @@ -40,7 +42,12 @@ typedef struct { rom_t bios_rom; + uint8_t pel_wd; uint8_t banking; + uint8_t reg_3d8; + uint8_t reg_3bf; + uint8_t tries; + uint8_t ext_enable; } et3000_t; static video_timings_t timing_et3000_isa = { VIDEO_ISA, 3, 3, 6, 5, 5, 10 }; @@ -48,30 +55,130 @@ static video_timings_t timing_et3000_isa = { VIDEO_ISA, 3, 3, 6, 5, 5, 10 }; static uint8_t et3000_in(uint16_t addr, void *priv); static void et3000_out(uint16_t addr, uint8_t val, void *priv); +#ifdef ENABLE_ET3000_LOG +int svga_do_log = ENABLE_ET3000_LOG; + +static void +et3000_log(const char *fmt, ...) +{ + va_list ap; + + if (et3000_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define et3000_log(fmt, ...) +#endif + static uint8_t et3000_in(uint16_t addr, void *priv) { et3000_t *dev = (et3000_t *) priv; svga_t *svga = &dev->svga; + uint8_t ret = 0xff; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if ((addr >= 0x03b0) && (addr < 0x03bc) && (svga->miscout & 1)) + return 0xff; + + if ((addr >= 0x03d0) && (addr < 0x03dc) && !(svga->miscout & 1)) + return 0xff; switch (addr) { - case 0x3cd: /*Banking*/ - return dev->banking; - - case 0x3d4: - return svga->crtcreg; - - case 0x3d5: - return svga->crtc[svga->crtcreg]; - default: + ret = svga_in(addr, svga); + +#ifdef ENABLE_ET3000_LOG + if (addr != 0x03da) + et3000_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, addr, ret); +#endif + break; + + case 0x3c1: + /* It appears the extended attribute registers are **NOT** + protected by key on the ET3000AX, as the BIOS attempts to + write to attribute register 16h without the key. */ + ret = svga_in(addr, svga); + et3000_log("[%04X:%08X] [R] %04X: %02X = %02X (%i)\n", CS, cpu_state.pc, + addr, svga->attraddr, ret, dev->ext_enable); + break; + + case 0x3c5: + if ((svga->seqaddr >= 6) && !dev->ext_enable) + ret = 0xff; + else + ret = svga_in(addr, svga); + et3000_log("[%04X:%08X] [R] %04X: %02X = %02X (%i)\n", CS, cpu_state.pc, + addr, svga->seqaddr, ret, dev->ext_enable); + break; + + case 0x3cf: + if ((svga->gdcaddr >= 0x0d) && !dev->ext_enable) + ret = 0xff; + else + ret = svga_in(addr, svga); + et3000_log("[%04X:%08X] [R] %04X: %02X = %02X (%i)\n", CS, cpu_state.pc, + addr, svga->gdcaddr & 15, ret, dev->ext_enable); + break; + + case 0x3cb: /*PEL Address/Data Wd*/ + ret = dev->pel_wd; + et3000_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, addr, ret); + break; + + case 0x3cd: /*Banking*/ + ret = dev->banking; + et3000_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, addr, ret); + break; + + case 0x3b4: + case 0x3d4: + ret = svga->crtcreg; + et3000_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, addr, ret); + break; + + case 0x3b5: + case 0x3d5: + if ((svga->crtcreg >= 0x18) && (svga->crtcreg < 0x23) && !dev->ext_enable) + ret = 0xff; + else if (svga->crtcreg > 0x25) + ret = 0xff; + else + ret = svga->crtc[svga->crtcreg]; + et3000_log("[%04X:%08X] [R] %04X: %02X = %02X\n", CS, cpu_state.pc, + addr, svga->crtcreg, ret); + break; + + case 0x3b8: + case 0x3d8: + ret = dev->reg_3d8; + et3000_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, addr, ret); + break; + + case 0x3ba: + case 0x3da: + svga->attrff = 0; + + if (svga->cgastat & 0x01) + svga->cgastat &= ~0x30; + else + svga->cgastat ^= 0x30; + + ret = svga->cgastat; + + if ((svga->fcr & 0x08) && svga->dispon) + ret |= 0x08; + break; + + case 0x3bf: + ret = dev->reg_3bf; + et3000_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, addr, ret); break; } - return svga_in(addr, svga); + return ret; } static void @@ -80,47 +187,119 @@ et3000_out(uint16_t addr, uint8_t val, void *priv) et3000_t *dev = (et3000_t *) priv; svga_t *svga = &dev->svga; uint8_t old; + uint8_t index; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + et3000_log("[%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, addr, val); + + if ((addr >= 0x03b0) && (addr < 0x03bc) && (svga->miscout & 1)) + return; + + if ((addr >= 0x03d0) && (addr < 0x03dc) && !(svga->miscout & 1)) + return; switch (addr) { case 0x3c0: - case 0x3c1: + /* It appears the extended attribute registers are **NOT** + protected by key on the ET3000AX, as the BIOS attempts to + write to attribute register 16h without the key. */ + if (svga->attrff && (svga->attraddr == 0x11) && (svga->attrregs[0x16] & 0x01)) + val = (val & 0xf0) | (svga->attrregs[0x11] & 0x0f); +#ifdef ENABLE_ET3000_LOG + if (svga->attrff && (svga->attraddr > 0x14)) + et3000_log("3C1: %02X = %02X\n", svga->attraddr, val); +#endif if (svga->attrff && (svga->attraddr == 0x16)) { svga->attrregs[0x16] = val; svga->chain4 &= ~0x10; if (svga->gdcreg[5] & 0x40) svga->chain4 |= (svga->attrregs[0x16] & 0x10); svga_recalctimings(svga); + return; } break; + case 0x3c1: + return; + case 0x3c2: + svga->miscout = val; + svga->vidclock = val & 4; + svga_recalctimings(svga); + return; + + case 0x3c4: + svga->seqaddr = val & 0x07; + return; case 0x3c5: + if ((svga->seqaddr >= 6) && !dev->ext_enable) + return; + if (svga->seqaddr == 4) { svga->seqregs[4] = val; svga->chain2_write = !(val & 4); svga->chain4 = (svga->chain4 & ~8) | (val & 8); - svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4 && !(svga->adv_flags & FLAG_ADDR_BY8); + et3000_log("CHAIN2 = %i, CHAIN4 = %i\n", svga->chain2_write, svga->chain4); + svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && + !svga->gdcreg[1]) && svga->chain4 && + !(svga->adv_flags & FLAG_ADDR_BY8); return; } +#ifdef ENABLE_ET3000_LOG + else if (svga->seqaddr > 4) + et3000_log("3C5: %02X = %02X\n", svga->seqaddr, val); +#endif break; - case 0x3cf: - if ((svga->gdcaddr & 15) == 5) { - svga->chain4 &= ~0x10; - if (val & 0x40) - svga->chain4 |= (svga->attrregs[0x16] & 0x10); + case 0x3c9: + if (svga->adv_flags & FLAG_RAMDAC_SHIFT) + val <<= 2; + svga->fullchange = svga->monitor->mon_changeframecount; + switch (svga->dac_pos) { + case 0: + if (!(svga->attrregs[0x16] & 0x02) && !(svga->attrregs[0x17] & 0x80)) + svga->dac_r = val; + svga->dac_pos++; + break; + case 1: + if (!(svga->attrregs[0x16] & 0x02) && !(svga->attrregs[0x17] & 0x80)) + svga->dac_g = val; + svga->dac_pos++; + break; + case 2: + index = svga->dac_addr & 255; + if (!(svga->attrregs[0x16] & 0x02) && !(svga->attrregs[0x17] & 0x80)) { + svga->dac_b = val; + svga->vgapal[index].r = svga->dac_r; + svga->vgapal[index].g = svga->dac_g; + svga->vgapal[index].b = svga->dac_b; + if (svga->ramdac_type == RAMDAC_8BIT) + svga->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, + svga->vgapal[index].b); + else + svga->pallook[index] = makecol32(video_6to8[svga->vgapal[index].r & 0x3f], + video_6to8[svga->vgapal[index].g & 0x3f], + video_6to8[svga->vgapal[index].b & 0x3f]); + } + svga->dac_pos = 0; + svga->dac_addr = (svga->dac_addr + 1) & 255; + break; + + default: + break; } + return; + + case 0x3cb: /*PEL Address/Data Wd*/ + et3000_log("3CB = %02X\n", val); + dev->pel_wd = val; break; case 0x3cd: /*Banking*/ - dev->banking = val; + et3000_log("3CD = %02X\n", val); if (!(svga->crtc[0x23] & 0x80) && !(svga->gdcreg[6] & 0x08)) { switch ((val >> 6) & 3) { case 0: /*128K segments*/ - svga->write_bank = (val & 7) << 17; + svga->write_bank = ((val >> 0) & 7) << 17; svga->read_bank = ((val >> 3) & 7) << 17; break; case 1: /*64K segments*/ @@ -132,13 +311,68 @@ et3000_out(uint16_t addr, uint8_t val, void *priv) break; } } + dev->banking = val; return; + case 0x3ce: + svga->gdcaddr = val & 0x0f; + return; + case 0x3cf: + if ((svga->gdcaddr >= 0x0d) && !dev->ext_enable) + return; + + if ((svga->gdcaddr & 15) == 5) { + svga->chain4 &= ~0x10; + if (val & 0x40) + svga->chain4 |= (svga->attrregs[0x16] & 0x10); + } else if ((svga->gdcaddr & 15) == 6) { + if (!(svga->crtc[0x23] & 0x80) && !(val & 0x08)) { + switch ((dev->banking >> 6) & 3) { + case 0: /*128K segments*/ + svga->write_bank = ((dev->banking >> 0) & 7) << 17; + svga->read_bank = ((dev->banking >> 3) & 7) << 17; + break; + case 1: /*64K segments*/ + svga->write_bank = (dev->banking & 7) << 16; + svga->read_bank = ((dev->banking >> 3) & 7) << 16; + break; + + default: + break; + } + } else + svga->write_bank = svga->read_bank = 0; + + old = svga->gdcreg[6]; + svga_out(addr, val, svga); + if ((old & 0xc) != 0 && (val & 0xc) == 0) { + /* Override mask - ET3000 supports linear 128k at A0000. */ + svga->banked_mask = 0x1ffff; + } + return; + } +#ifdef ENABLE_ET3000_LOG + else if ((svga->gdcaddr & 15) > 8) + et3000_log("3CF: %02X = %02X\n", (svga->gdcaddr & 15), val); +#endif + break; + + case 0x3b4: case 0x3d4: svga->crtcreg = val & 0x3f; return; + case 0x3b5: case 0x3d5: + if ((svga->crtcreg >= 0x18) && (svga->crtcreg < 0x23) && !dev->ext_enable) + return; + else if (svga->crtcreg > 0x25) + return; + + /* Unlike the ET4000AX, which protects all bits of the + overflow high register (0x35 there, 0x25 here) except for + bits 4 and 7, if bit 7 of CRTC 11h is set, the ET3000AX + does not to that. */ if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) @@ -146,6 +380,11 @@ et3000_out(uint16_t addr, uint8_t val, void *priv) old = svga->crtc[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; +#ifdef ENABLE_ET3000_LOG + if (svga->crtcreg > 0x18) + et3000_log("3D5: %02X = %02X\n", svga->crtcreg, val); +#endif + if (old != val) { if (svga->crtcreg < 0x0e || svga->crtcreg > 0x10) { svga->fullchange = changeframecount; @@ -154,6 +393,27 @@ et3000_out(uint16_t addr, uint8_t val, void *priv) } break; + case 0x3b8: + case 0x3d8: + et3000_log("%04X = %02X\n", addr, val); + dev->reg_3d8 = val; + if ((val == 0xa0) && (dev->tries == 1)) { + dev->ext_enable = 1; + dev->tries = 0; + } else if (val == 0x29) + dev->tries = 1; + return; + + case 0x3bf: + et3000_log("%04X = %02X\n", addr, val); + dev->reg_3bf = val; + if ((val == 0x01) && (dev->tries == 1)) { + dev->ext_enable = 0; + dev->tries = 0; + } else if (val == 0x03) + dev->tries = 1; + return; + default: break; } @@ -199,10 +459,8 @@ et3000_recalctimings(svga_t *svga) } } -#if 0 - pclog("HDISP = %i, HTOTAL = %i, ROWOFFSET = %i, INTERLACE = %i\n", - svga->hdisp, svga->htotal, svga->rowoffset, svga->interlace); -#endif + et3000_log("HDISP = %i, HTOTAL = %i, ROWOFFSET = %i, INTERLACE = %i\n", + svga->hdisp, svga->htotal, svga->rowoffset, svga->interlace); switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x24] << 1) & 4)) { case 0: @@ -238,7 +496,7 @@ et3000_init(const device_t *info) svga_init(info, &dev->svga, dev, device_get_config_int("memory") << 10, et3000_recalctimings, et3000_in, et3000_out, NULL, NULL); - io_sethandler(0x03c0, 32, + io_sethandler(0x03b0, 48, et3000_in, NULL, NULL, et3000_out, NULL, NULL, dev); break; diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 984071ade..f5f9ad813 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -244,11 +244,61 @@ et4000_out(uint16_t addr, uint8_t val, void *priv) et4000_t *dev = (et4000_t *) priv; svga_t *svga = &dev->svga; uint8_t old; + uint8_t pal4to16[16] = { 0, 7, 0x38, 0x3f, 0, 3, 4, 0x3f, 0, 2, 4, 0x3e, 0, 3, 5, 0x3f }; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; switch (addr) { + case 0x3c0: + case 0x3c1: + if (!svga->attrff) { + svga->attraddr = val & 0x1f; + if ((val & 0x20) != svga->attr_palette_enable) { + svga->fullchange = 3; + svga->attr_palette_enable = val & 0x20; + svga_recalctimings(svga); + } + } else { + if ((svga->attraddr == 0x13) && (svga->attrregs[0x13] != val)) + svga->fullchange = svga->monitor->mon_changeframecount; + old = svga->attrregs[svga->attraddr & 0x1f]; + svga->attrregs[svga->attraddr & 0x1f] = val; + if (svga->attraddr < 0x10) + svga->fullchange = svga->monitor->mon_changeframecount; + + if ((svga->attraddr == 0x10) || (svga->attraddr == 0x14) || (svga->attraddr < 0x10)) { + for (int c = 0; c < 0x10; c++) { + if (svga->attrregs[0x10] & 0x80) + svga->egapal[c] = (svga->attrregs[c] & 0xf) | ((svga->attrregs[0x14] & 0xf) << 4); + else if (svga->ati_4color) + svga->egapal[c] = pal4to16[(c & 0x03) | ((val >> 2) & 0xc)]; + else + svga->egapal[c] = (svga->attrregs[c] & 0x3f) | ((svga->attrregs[0x14] & 0xc) << 4); + } + svga->fullchange = svga->monitor->mon_changeframecount; + } + /* Recalculate timings on change of attribute register 0x11 + (overscan border color) too. */ + if (svga->attraddr == 0x10) { + svga->chain4 &= ~0x02; + if ((val & 0x40) && (svga->attrregs[0x10] & 0x40)) + svga->chain4 |= (svga->seqregs[0x0e] & 0x02); + if (old != val) + svga_recalctimings(svga); + } else if (svga->attraddr == 0x11) { + svga->overscan_color = svga->pallook[svga->attrregs[0x11]]; + if (old != val) + svga_recalctimings(svga); + } else if (svga->attraddr == 0x12) { + if ((val & 0xf) != svga->plane_mask) + svga->fullchange = svga->monitor->mon_changeframecount; + svga->plane_mask = val & 0xf; + } + } + svga->attrff ^= 1; + return; + case 0x3c5: if (svga->seqaddr == 4) { svga->seqregs[4] = val; @@ -260,7 +310,7 @@ et4000_out(uint16_t addr, uint8_t val, void *priv) } else if (svga->seqaddr == 0x0e) { svga->seqregs[0x0e] = val; svga->chain4 &= ~0x02; - if (svga->gdcreg[5] & 0x40) + if ((svga->gdcreg[5] & 0x40) && svga->lowres) svga->chain4 |= (svga->seqregs[0x0e] & 0x02); svga_recalctimings(svga); return; @@ -286,7 +336,11 @@ et4000_out(uint16_t addr, uint8_t val, void *priv) return; case 0x3cf: - if ((svga->gdcaddr & 15) == 6) { + if ((svga->gdcaddr & 15) == 5) { + svga->chain4 &= ~0x02; + if ((val & 0x40) && svga->lowres) + svga->chain4 |= (svga->seqregs[0x0e] & 0x02); + } else if ((svga->gdcaddr & 15) == 6) { if (!(svga->crtc[0x36] & 0x10) && !(val & 0x08)) { svga->write_bank = (dev->banking & 0x0f) * 0x10000; svga->read_bank = ((dev->banking >> 4) & 0x0f) * 0x10000; @@ -663,13 +717,6 @@ et4000_recalctimings(svga_t *svga) } } - if (dev->type == ET4000_TYPE_TC6058AF) { - if (svga->render == svga_render_8bpp_lowres) - svga->render = svga_render_8bpp_tseng_lowres; - else if (svga->render == svga_render_8bpp_highres) - svga->render = svga_render_8bpp_tseng_highres; - } - if ((svga->bpp == 8) && ((svga->gdcreg[5] & 0x60) >= 0x40)) { svga->map8 = svga->pallook; if (svga->lowres) @@ -677,6 +724,19 @@ et4000_recalctimings(svga_t *svga) else svga->render = svga_render_8bpp_highres; } + + if ((svga->seqregs[0x0e] & 0x02) && ((svga->gdcreg[5] & 0x60) >= 0x40) && svga->lowres) { + svga->ma_latch <<= 1; + svga->rowoffset <<= 1; + svga->render = svga_render_8bpp_highres; + } + + if (dev->type == ET4000_TYPE_TC6058AF) { + if (svga->render == svga_render_8bpp_lowres) + svga->render = svga_render_8bpp_tseng_lowres; + else if (svga->render == svga_render_8bpp_highres) + svga->render = svga_render_8bpp_tseng_highres; + } } static void From cbf1749a25753d69d1e1c2cf584b5a6e603b3a7f Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 6 Feb 2024 19:50:21 +0100 Subject: [PATCH 441/936] Fixed the reported CPU inacuracies, closes #4121. --- src/cpu/386_ops.h | 92 +++++++++++++++++++++++++++++++++++++++++ src/cpu/x86_ops_pmode.h | 2 + 2 files changed, 94 insertions(+) diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index 710031ef1..262b4e0bc 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -641,6 +641,98 @@ const OpFn OP_TABLE(386_0f)[1024] = { // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, ILLEGAL, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, +/*b0*/ ILLEGAL, ILLEGAL, opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, + +/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*32-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ opMOV_b_r_a16, opMOV_l_r_a16, opMOV_r_b_a16, opMOV_r_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, ILLEGAL, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, +/*b0*/ ILLEGAL, ILLEGAL, opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, + +/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*16-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ opMOV_b_r_a32, opMOV_w_r_a32, opMOV_r_b_a32, opMOV_r_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, ILLEGAL, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, +/*b0*/ ILLEGAL, ILLEGAL, opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, + +/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*32-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ opMOV_b_r_a32, opMOV_l_r_a32, opMOV_r_b_a32, opMOV_r_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, ILLEGAL, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, +/*b0*/ ILLEGAL, ILLEGAL, opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, + +/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + // clang-format on +}; + +const OpFn OP_TABLE(486dlc_0f)[1024] = { + // clang-format off + /*16-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, diff --git a/src/cpu/x86_ops_pmode.h b/src/cpu/x86_ops_pmode.h index 1254d7289..e84847a7b 100644 --- a/src/cpu/x86_ops_pmode.h +++ b/src/cpu/x86_ops_pmode.h @@ -367,6 +367,7 @@ op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) switch (rmdat & 0x38) { case 0x00: /*SGDT*/ + ILLEGAL_ON(cpu_mod == 3); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(gdt.limit); @@ -389,6 +390,7 @@ op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) PREFETCH_RUN(7, 2, rmdat, 0, 0, 1, 1, ea32); break; case 0x10: /*LGDT*/ + ILLEGAL_ON(cpu_mod == 3); if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { x86gpf(NULL, 0); break; From ecd90616f1e8c96623ee07debd41415a02cc77a9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 6 Feb 2024 19:51:02 +0100 Subject: [PATCH 442/936] Removed an unnecessary CPU operations table. --- src/cpu/386_ops.h | 92 ----------------------------------------------- 1 file changed, 92 deletions(-) diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index 262b4e0bc..1bb3c167f 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -729,98 +729,6 @@ const OpFn OP_TABLE(386_0f)[1024] = { // clang-format on }; -const OpFn OP_TABLE(486dlc_0f)[1024] = { - // clang-format off - /*16-bit data, 16-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - -/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - -/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, -/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, -/*a0*/ opPUSH_FS_w, opPOP_FS_w, ILLEGAL, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, -/*b0*/ ILLEGAL, ILLEGAL, opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, - -/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - - /*32-bit data, 16-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ opMOV_b_r_a16, opMOV_l_r_a16, opMOV_r_b_a16, opMOV_r_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - -/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - -/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, -/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, -/*a0*/ opPUSH_FS_l, opPOP_FS_l, ILLEGAL, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, -/*b0*/ ILLEGAL, ILLEGAL, opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, - -/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - - /*16-bit data, 32-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ opMOV_b_r_a32, opMOV_w_r_a32, opMOV_r_b_a32, opMOV_r_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - -/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - -/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, -/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, -/*a0*/ opPUSH_FS_w, opPOP_FS_w, ILLEGAL, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, -/*b0*/ ILLEGAL, ILLEGAL, opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, - -/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - - /*32-bit data, 32-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ opMOV_b_r_a32, opMOV_l_r_a32, opMOV_r_b_a32, opMOV_r_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - -/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - -/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, -/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, -/*a0*/ opPUSH_FS_l, opPOP_FS_l, ILLEGAL, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, -/*b0*/ ILLEGAL, ILLEGAL, opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, - -/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - // clang-format on -}; - const OpFn OP_TABLE(486_0f)[1024] = { // clang-format off /*16-bit data, 16-bit addr*/ From cd03088873117e86aebb58fe2f483803f8a62b27 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 7 Feb 2024 00:51:17 +0600 Subject: [PATCH 443/936] Source offset trouble fixed WIP hardware cursor --- src/video/vid_c&t_69000.c | 115 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 111 insertions(+), 4 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index f47de012d..f3e3132b2 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -134,8 +134,10 @@ typedef struct chips_69000_t { /* Byte counter for BitBLT port writes. */ uint8_t bytes_written; + uint8_t bytes_skip; uint32_t bytes_counter; uint32_t bytes_in_line_written; + uint32_t bytes_in_line_counter; uint8_t bytes_port[8]; /* Monochrome sources. */ @@ -1114,6 +1116,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.mono_is_first_quadword = 1; chips->bitblt_running.mono_bit_cntr = 0; chips->bitblt_running.bytes_in_line_written = 0; + chips->bitblt_running.bytes_skip = 0; int orig_cycles = cycles; if (chips->bitblt.bitblt_control & (1 << 23)) { @@ -1156,12 +1159,17 @@ chips_69000_setup_bitblt(chips_69000_t* chips) if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { if (!(chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { - pclog("source_span = %d, dest_span = %d\n", chips->bitblt_running.bitblt.source_span, chips->bitblt_running.bitblt.destination_span); + //pclog("source_span = %d, dest_span = %d\n", chips->bitblt_running.bitblt.source_span, chips->bitblt_running.bitblt.destination_span); + //pclog("destination_width = %d (qword aligned = %d), skip left = %d\n", chips->bitblt_running.bitblt.destination_width, (chips->bitblt_running.bitblt.destination_width + 7) & ~7, chips->bitblt_running.bitblt.source_addr); + chips->bitblt_running.bytes_in_line_counter = (chips->bitblt_running.bitblt.source_addr + chips->bitblt_running.bitblt.destination_width + 7) & ~7; + if ((chips->bitblt_running.bitblt.source_addr + (chips->bitblt_running.bitblt.destination_width)) > ((chips->bitblt_running.bitblt.destination_width + 7) & ~7)) + chips->bitblt_running.bytes_skip = 8 + (((chips->bitblt_running.bitblt.destination_width + 7) & ~7) - chips->bitblt_running.bitblt.destination_width); } return; } if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { + uint32_t source_addr = chips->bitblt_running.bitblt.source_addr; pclog("C&T: Monochrome blit (monochrome_source_alignment = %d, " "monochrome left clip = %d, " "monochrome right clip = %d, " @@ -1172,6 +1180,12 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.bitblt.monochrome_source_initial_discard, chips->bitblt_running.bitblt.destination_width, chips->bitblt_running.bitblt.destination_height); + + while (chips->engine_active) { + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); + + source_addr += chips->bitblt_running.x_dir; + } } do { @@ -1248,8 +1262,9 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { } chips->bitblt_running.bytes_counter++; - if (chips->bitblt_running.bytes_counter <= (chips->bitblt_running.bitblt.source_addr & 7)) + if (chips->bitblt_running.bytes_counter <= (chips->bitblt_running.bitblt.source_addr)) { return; + } chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; if (chips->bitblt_running.bytes_written == chips->bitblt_running.bytes_per_pixel) { uint32_t source_pixel = chips->bitblt_running.bytes_port[0]; @@ -1265,8 +1280,11 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { chips->bitblt_running.x += chips->bitblt_running.x_dir; if (chips->bitblt_running.bytes_in_line_written >= chips->bitblt_running.bitblt.destination_width) { - if (chips->bitblt_running.bitblt.destination_width & 7) - chips->bitblt_running.bitblt.source_addr = 8 - (chips->bitblt_running.bitblt.destination_width & 7); + if (chips->bitblt_running.bytes_skip) { + chips->bitblt_running.bitblt.source_addr = chips->bitblt_running.bytes_skip; + } + else if (chips->bitblt_running.bitblt.destination_width & 7) + chips->bitblt_running.bitblt.source_addr = 8 - ((chips->bitblt_running.bitblt.destination_width) & 7); else chips->bitblt_running.bitblt.source_addr = 0; @@ -1416,6 +1434,34 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) chips->ext_regs[chips->ext_index] = val & 0x1f; svga_recalctimings(&chips->svga); break; + case 0xA0: + chips->ext_regs[chips->ext_index] = val; + chips->svga.hwcursor.ena = ((val & 7) == 0b101) || ((val & 7) == 0b1); + break; + case 0xA2: + chips->ext_regs[chips->ext_index] = val; + chips->svga.hwcursor.addr = (val << 8) | ((chips->ext_regs[0xA3] & 0x3F) << 16); + break; + case 0xA3: + chips->ext_regs[chips->ext_index] = val; + chips->svga.hwcursor.addr = ((chips->ext_regs[0xA2]) << 8) | ((val & 0x3F) << 16); + break; + case 0xA4: + chips->ext_regs[chips->ext_index] = val; + chips->svga.hwcursor.x = val | (chips->ext_regs[0xA5] & 7) << 8; + break; + case 0xA5: + chips->ext_regs[chips->ext_index] = val; + chips->svga.hwcursor.x = chips->ext_regs[0xA4] | (val & 7) << 8; + break; + case 0xA6: + chips->ext_regs[chips->ext_index] = val; + chips->svga.hwcursor.y = val | (chips->ext_regs[0xA7] & 7) << 8; + break; + case 0xA7: + chips->ext_regs[chips->ext_index] = val; + chips->svga.hwcursor.y = chips->ext_regs[0xA6] | (val & 7) << 8; + break; case 0xD2: break; default: @@ -2035,6 +2081,66 @@ chips_69000_vblank_start(svga_t *svga) chips_69000_interrupt(chips); } +static void +chips_69000_hwcursor_draw(svga_t *svga, int displine) +{ + chips_69000_t *chips = (chips_69000_t *) svga->priv; + uint64_t dat[2]; + int offset = svga->hwcursor_latch.x; + + if ((chips->ext_regs[0xA0] & 7) == 1) { + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += (svga->hwcursor_on & 1) ? 8 : 4; + + dat[0] = *(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr]); + dat[1] = *(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr + 8]); + svga->hwcursor_latch.addr += (svga->hwcursor_on & 1) ? 8 : 4; + + for (uint8_t x = 0; x < 32; x++) { + if (!(dat[1] & (1ULL << 31))) + svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 31)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[4]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[5]); + else if (dat[0] & (1ULL << 31)) + svga->monitor->target_buffer->line[displine][offset + svga->x_add] ^= 0xffffff; + + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += (svga->hwcursor_on & 1) ? 8 : 4; + + return; + } + + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += (chips->ext_regs[0xA0] & 7) == 1 ? 8 : 16; + + dat[0] = *(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr]); + dat[1] = *(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr + 8]); + svga->hwcursor_latch.addr += 16; + switch (chips->ext_regs[0xa0] & 7) { + case 0b101: + for (uint8_t x = 0; x < 64; x++) { + if (!(dat[1] & (1ULL << 63))) + svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[1]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[0]); + else if (dat[0] & (1ULL << 63)) + svga->monitor->target_buffer->line[displine][offset + svga->x_add] ^= 0xffffff; + + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + break; + + default: + break; + } + + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 16; +} + static void * chips_69000_init(const device_t *info) { @@ -2062,6 +2168,7 @@ chips_69000_init(const device_t *info) chips->svga.miscout = 1; chips->svga.recalctimings_ex = chips_69000_recalctimings; chips->svga.vblank_start = chips_69000_vblank_start; + chips->svga.hwcursor_draw = chips_69000_hwcursor_draw; mem_mapping_add(&chips->linear_mapping, 0, 0, chips_69000_readb_linear, chips_69000_readw_linear, chips_69000_readl_linear, chips_69000_writeb_linear, chips_69000_writew_linear, chips_69000_writel_linear, NULL, MEM_MAPPING_EXTERNAL, chips); From 614241b8b29cf154660544a2e568cc93f1b50de8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 7 Feb 2024 01:25:54 +0600 Subject: [PATCH 444/936] Non-CPU-driven monochrome source blits --- src/video/vid_c&t_69000.c | 76 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 5 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index f3e3132b2..d73042552 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -137,7 +137,6 @@ typedef struct chips_69000_t { uint8_t bytes_skip; uint32_t bytes_counter; uint32_t bytes_in_line_written; - uint32_t bytes_in_line_counter; uint8_t bytes_port[8]; /* Monochrome sources. */ @@ -1103,6 +1102,8 @@ chips_69000_process_mono_data_non_qword(UNUSED(chips_69000_t* chips), uint8_t va } } +void chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data); + void chips_69000_setup_bitblt(chips_69000_t* chips) { @@ -1161,7 +1162,6 @@ chips_69000_setup_bitblt(chips_69000_t* chips) if (!(chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { //pclog("source_span = %d, dest_span = %d\n", chips->bitblt_running.bitblt.source_span, chips->bitblt_running.bitblt.destination_span); //pclog("destination_width = %d (qword aligned = %d), skip left = %d\n", chips->bitblt_running.bitblt.destination_width, (chips->bitblt_running.bitblt.destination_width + 7) & ~7, chips->bitblt_running.bitblt.source_addr); - chips->bitblt_running.bytes_in_line_counter = (chips->bitblt_running.bitblt.source_addr + chips->bitblt_running.bitblt.destination_width + 7) & ~7; if ((chips->bitblt_running.bitblt.source_addr + (chips->bitblt_running.bitblt.destination_width)) > ((chips->bitblt_running.bitblt.destination_width + 7) & ~7)) chips->bitblt_running.bytes_skip = 8 + (((chips->bitblt_running.bitblt.destination_width + 7) & ~7) - chips->bitblt_running.bitblt.destination_width); } @@ -1182,9 +1182,49 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.bitblt.destination_height); while (chips->engine_active) { - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); + switch (chips->bitblt_running.bitblt.monochrome_source_alignment) { + case 0: /* Source-span aligned. */ + { + /* TODO: This is handled purely on a best case basis. */ + uint32_t orig_count_y = chips->bitblt_running.count_y; + uint32_t orig_source_addr = chips->bitblt_running.bitblt.source_addr; + while (orig_count_y == chips->bitblt_running.count_y) { + uint8_t data = chips_69000_readb_linear(orig_source_addr, chips); + orig_source_addr++; + chips_69000_bitblt_write(chips, data & 0xFF); + if ((source_addr + chips->bitblt_running.bitblt.source_span) == orig_source_addr) + break; + } - source_addr += chips->bitblt_running.x_dir; + source_addr = chips->bitblt_running.bitblt.source_addr + chips->bitblt_running.bitblt.source_span; + chips->bitblt_running.bitblt.source_addr = source_addr; + break; + } + case 4: /* Doubleword-aligned*/ + { + uint32_t data = chips_69000_readl_linear(source_addr, chips); + chips_69000_bitblt_write(chips, data & 0xFF); + chips_69000_bitblt_write(chips, (data >> 8) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 16) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 24) & 0xFF); + source_addr += 4; + break; + } + case 5: /* Quadword-aligned*/ + { + uint64_t data = (uint64_t)chips_69000_readl_linear(source_addr, chips) | ((uint64_t)chips_69000_readl_linear(source_addr + 4, chips) << 32ull); + chips_69000_bitblt_write(chips, data & 0xFF); + chips_69000_bitblt_write(chips, (data >> 8) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 16) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 24) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 32ull) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 40ull) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 48ull) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 56ull) & 0xFF); + source_addr += 8; + break; + } + } } } @@ -1236,7 +1276,16 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; - if (chips->bitblt_running.bitblt.monochrome_source_alignment == 4 + if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0) { + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); + chips->bitblt_running.bytes_written &= 7; + } else if (chips->bitblt_running.bitblt.monochrome_source_alignment == 3 + && chips->bitblt_running.bytes_written == 2) { + chips->bitblt_running.bytes_written = 0; + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); + if (chips->bitblt_running.actual_destination_width > 8) + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[1]); + } else if (chips->bitblt_running.bitblt.monochrome_source_alignment == 4 && chips->bitblt_running.bytes_written == 4) { chips->bitblt_running.bytes_written = 0; chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); @@ -1246,6 +1295,23 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[2]); if (chips->bitblt_running.actual_destination_width > 24) chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[3]); + } else if (chips->bitblt_running.bitblt.monochrome_source_alignment == 5 && chips->bitblt_running.bytes_written == 8) { + chips->bitblt_running.bytes_written = 0; + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); + if (chips->bitblt_running.actual_destination_width > 8) + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[1]); + if (chips->bitblt_running.actual_destination_width > 16) + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[2]); + if (chips->bitblt_running.actual_destination_width > 24) + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[3]); + if (chips->bitblt_running.actual_destination_width > 32) + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[4]); + if (chips->bitblt_running.actual_destination_width > 40) + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[5]); + if (chips->bitblt_running.actual_destination_width > 48) + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[6]); + if (chips->bitblt_running.actual_destination_width > 52) + chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[7]); } else if (chips->bitblt_running.bytes_written == 8) { chips->bitblt_running.bytes_written = 0; uint64_t mono_data = chips->bitblt_running.bytes_port[0]; From df91185e7505812a52d6508f1504475cc16dc26a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 7 Feb 2024 01:32:46 +0600 Subject: [PATCH 445/936] Minor line fix --- src/video/vid_c&t_69000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index d73042552..b01be7adb 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -1278,7 +1278,7 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0) { chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); - chips->bitblt_running.bytes_written &= 7; + chips->bitblt_running.bytes_written = 0; } else if (chips->bitblt_running.bitblt.monochrome_source_alignment == 3 && chips->bitblt_running.bytes_written == 2) { chips->bitblt_running.bytes_written = 0; From 1808498370edfeba58f03d6d10f48acb61f8272c Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 7 Feb 2024 01:40:15 +0600 Subject: [PATCH 446/936] Add note about bytes_skip calculation --- src/video/vid_c&t_69000.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index b01be7adb..ee83ba6a9 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -1160,8 +1160,9 @@ chips_69000_setup_bitblt(chips_69000_t* chips) if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { if (!(chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { - //pclog("source_span = %d, dest_span = %d\n", chips->bitblt_running.bitblt.source_span, chips->bitblt_running.bitblt.destination_span); - //pclog("destination_width = %d (qword aligned = %d), skip left = %d\n", chips->bitblt_running.bitblt.destination_width, (chips->bitblt_running.bitblt.destination_width + 7) & ~7, chips->bitblt_running.bitblt.source_addr); + /* Yes, the NT 4.0 and Linux drivers will send this many amount of bytes to the video adapter on quadword-boundary-crossing image blits. + This weird calculation is intended and deliberate. + */ if ((chips->bitblt_running.bitblt.source_addr + (chips->bitblt_running.bitblt.destination_width)) > ((chips->bitblt_running.bitblt.destination_width + 7) & ~7)) chips->bitblt_running.bytes_skip = 8 + (((chips->bitblt_running.bitblt.destination_width + 7) & ~7) - chips->bitblt_running.bitblt.destination_width); } From bf85d8088b2d489b2230b692bffc2bc83e46ab6a Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 6 Feb 2024 21:01:11 +0100 Subject: [PATCH 447/936] Fixed the registers collision between SiS 496/497 and Cyrix registers, which fixes the 4SAW2 on Cyrix CPU's, and removed the block on those CPU's for that machine. --- src/chipset/sis_85c496.c | 2 +- src/machine/machine_table.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chipset/sis_85c496.c b/src/chipset/sis_85c496.c index 4d1db2d9e..b9b2544c8 100644 --- a/src/chipset/sis_85c496.c +++ b/src/chipset/sis_85c496.c @@ -123,7 +123,7 @@ sis_85c497_isa_read(uint16_t port, void *priv) const sis_85c496_t *dev = (sis_85c496_t *) priv; uint8_t ret = 0xff; - if (port == 0x23) + if ((port == 0x23) && (dev->cur_reg < 0xc0)) ret = dev->regs[dev->cur_reg]; else if (port == 0x33) ret = 0x3c /*random_generate()*/; diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index d2e49709e..13a5d5452 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -7793,7 +7793,7 @@ const machine_t machines[] = { .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK(CPU_i486SX, CPU_i486DX, CPU_Am486SX, CPU_Am486DX, CPU_Cx486S, CPU_Cx486DX, CPU_Cx5x86), + .block = CPU_BLOCK(CPU_i486SX, CPU_i486DX, CPU_Am486SX, CPU_Am486DX), .min_bus = 0, .max_bus = 0, .min_voltage = 0, From ad9503ec2831e07deded143e58bf26aa585c1910 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 6 Feb 2024 21:09:38 +0100 Subject: [PATCH 448/936] More fixes to the 5380-based core. More timer related fixes regarding the speed combinations, looking at you, Rancho (8.10R and 8.20R), but at least it should solve most problems with boots. --- src/scsi/scsi_ncr5380.c | 57 +++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 36 deletions(-) diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index 5c6f0c22d..e9ebe8504 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -607,12 +607,6 @@ ncr_write(uint16_t port, uint8_t val, void *priv) ncr->dma_mode = DMA_IDLE; } } else { - /*Don't stop the timer until it finishes the transfer*/ - if (ncr_dev->block_count_loaded && (ncr->mode & MODE_DMA)) { - ncr_log("Continuing DMA mode\n"); - timer_on_auto(&ncr_dev->timer, 40.0); - } - /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ if (!ncr_dev->block_count_loaded && !(ncr->mode & MODE_DMA)) { ncr_log("No DMA mode\n"); @@ -648,12 +642,6 @@ ncr_write(uint16_t port, uint8_t val, void *priv) ncr_dev->t128.block_loaded = 1; } - } else { - if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer) && (dev->buffer_length > 0)) { - memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length)); - ncr_log("DMA send timer on\n"); - timer_on_auto(&ncr_dev->timer, ncr_dev->period + 1.0); - } } break; @@ -674,12 +662,6 @@ ncr_write(uint16_t port, uint8_t val, void *priv) ncr_dev->t128.block_loaded = 1; timer_on_auto(&ncr_dev->timer, 0.02); } - } else { - if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer) && (dev->buffer_length > 0)) { - memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length)); - ncr_log("DMA initiator receive timer on\n"); - timer_on_auto(&ncr_dev->timer, ncr_dev->period + 1.0); - } } break; @@ -842,8 +824,9 @@ memio_read(uint32_t addr, void *priv) break; case 0x3900: - if (ncr_dev->buffer_host_pos >= MIN(128, dev->buffer_length) || !(ncr_dev->status_ctrl & CTRL_DATA_DIR)) { + if (ncr_dev->buffer_host_pos >= MIN(128, dev->buffer_length) || (!(ncr_dev->status_ctrl & CTRL_DATA_DIR))) { ret = 0xff; + ncr_log("No Read.\n"); } else { ret = ncr_dev->buffer[ncr_dev->buffer_host_pos++]; ncr_log("Read host pos = %i, ret = %02x\n", ncr_dev->buffer_host_pos, ret); @@ -948,7 +931,7 @@ memio_write(uint32_t addr, uint8_t val, void *priv) break; case 0x3981: /* block counter register */ - ncr_log("Write block counter register: val=%d, dma mode = %i, period = %lf\n", val, ncr->dma_mode, ncr_dev->period); + ncr_log("Write block counter register: val=%d, dma mode=%x, period=%lf\n", val, ncr->dma_mode, ncr_dev->period); ncr_dev->block_count = val; ncr_dev->block_count_loaded = 1; @@ -959,6 +942,11 @@ memio_write(uint32_t addr, uint8_t val, void *priv) ncr_dev->buffer_host_pos = 0; ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; } + if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer) && (dev->buffer_length > 0)) { + memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length)); + ncr_log("DMA timer on\n"); + timer_on_auto(&ncr_dev->timer, ncr_dev->period); + } break; default: @@ -1080,9 +1068,9 @@ ncr_callback(void *priv) ncr5380_t *ncr_dev = (ncr5380_t *) priv; ncr_t *ncr = &ncr_dev->ncr; scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; - int tx = 0; - int bytes_transferred = 0; int bus; + int bytes_tx = 0; + int limit = 100; uint8_t temp; if (ncr_dev->type != 3) { @@ -1127,16 +1115,13 @@ ncr_callback(void *priv) if (!ncr_dev->block_count_loaded) break; - while (bytes_transferred < 50) { - for (tx = 0; tx < 10; tx++) { + while (bytes_tx < limit) { + for (uint8_t c = 0; c < 10; c++) { ncr_bus_read(ncr_dev); if (ncr->cur_bus & BUS_REQ) break; } - if (tx == 10) - break; - /* Data ready. */ temp = ncr_dev->buffer[ncr_dev->buffer_pos]; @@ -1147,13 +1132,14 @@ ncr_callback(void *priv) ncr_bus_update(ncr_dev, bus & ~BUS_ACK); ncr_dev->buffer_pos++; - bytes_transferred++; + bytes_tx++; ncr_log("Buffer pos for writing = %d\n", ncr_dev->buffer_pos); if (ncr_dev->buffer_pos == MIN(128, dev->buffer_length)) { + bytes_tx = 0; + ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; ncr_dev->buffer_pos = 0; ncr_dev->buffer_host_pos = 0; - ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; ncr_dev->ncr_busy = 0; ncr_dev->block_count = (ncr_dev->block_count - 1) & 0xff; ncr_log("Remaining blocks to be written=%d\n", ncr_dev->block_count); @@ -1208,6 +1194,7 @@ write_again: ncr_dev->t128.pos = 0; ncr_dev->t128.host_pos = 0; ncr_dev->t128.status &= ~0x02; + ncr_dev->ncr_busy = 0; ncr_dev->t128.block_count = (ncr_dev->t128.block_count - 1) & 0xff; ncr_log("Remaining blocks to be written=%d\n", ncr_dev->t128.block_count); if (!ncr_dev->t128.block_count) { @@ -1242,16 +1229,13 @@ write_again: if (!ncr_dev->block_count_loaded) break; - while (bytes_transferred < 50) { - for (tx = 0; tx < 10; tx++) { + while (bytes_tx < limit) { + for (uint8_t c = 0; c < 10; c++) { ncr_bus_read(ncr_dev); if (ncr->cur_bus & BUS_REQ) break; } - if (tx == 10) - break; - /* Data ready. */ ncr_bus_read(ncr_dev); temp = BUS_GETDATA(ncr->cur_bus); @@ -1263,12 +1247,13 @@ write_again: ncr_dev->buffer[ncr_dev->buffer_pos++] = temp; ncr_log("Buffer pos for reading = %d\n", ncr_dev->buffer_pos); - bytes_transferred++; + bytes_tx++; if (ncr_dev->buffer_pos == MIN(128, dev->buffer_length)) { + bytes_tx = 0; + ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; ncr_dev->buffer_pos = 0; ncr_dev->buffer_host_pos = 0; - ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; ncr_dev->block_count = (ncr_dev->block_count - 1) & 0xff; ncr_log("Remaining blocks to be read=%d\n", ncr_dev->block_count); if (!ncr_dev->block_count) { From 0d88e8394cdc85a0494056fe6d2f51a583405bdf Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 6 Feb 2024 21:18:25 +0100 Subject: [PATCH 449/936] SCSI CD-ROM fixes of the day. 1.Re-implemented in the best way possible the muted part of the Toshiba/NEC Play Audio commands and related, per spec. 2. Forgot to add a check to a Sony Vendor Data Out command when the len is 0 it should become a Status command, fixes emulator crashes when len is 0 using some CD software. --- src/cdrom/cdrom.c | 40 +++++++++++++++++++++++---------------- src/include/86box/cdrom.h | 1 + src/scsi/scsi_cdrom.c | 8 ++++++++ 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 897083708..ea025de2a 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -442,7 +442,7 @@ cdrom_audio_callback(cdrom_t *dev, int16_t *output, int len) { int ret = 1; - if (!dev->sound_on || (dev->cd_status != CD_STATUS_PLAYING)) { + if (!dev->sound_on || (dev->cd_status != CD_STATUS_PLAYING) || dev->audio_muted_soft) { cdrom_log("CD-ROM %i: Audio callback while not playing\n", dev->id); if (dev->cd_status == CD_STATUS_PLAYING) dev->seek_pos += (len >> 11); @@ -557,6 +557,7 @@ cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf) len += pos; } + dev->audio_muted_soft = 0; /* Do this at this point, since it's at this point that we know the actual LBA position to start playing from. */ if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) { @@ -578,6 +579,7 @@ cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit) int m = 0; int s = 0; int f = 0; + uint32_t pos2 = 0; if (dev->cd_status == CD_STATUS_DATA_ONLY) return 0; @@ -614,14 +616,21 @@ cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit) break; } + pos2 = pos - 1; + if (pos2 == 0xffffffff) + pos2 = pos + 1; + /* Do this at this point, since it's at this point that we know the actual LBA position to start playing from. */ - if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) { - cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos); - cdrom_stop(dev); - return 0; - } + if (!(dev->ops->track_type(dev, pos2) & CD_TRACK_AUDIO)) { + cdrom_log("CD-ROM %i: Track Search: LBA %08X not on an audio track\n", dev->id, pos); + dev->audio_muted_soft = 1; + if (dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO) + dev->audio_muted_soft = 0; + } else + dev->audio_muted_soft = 0; + cdrom_log("Track Search Toshiba: Muted?=%d, LBA=%08X.\n", dev->audio_muted_soft, pos); dev->cd_buflen = 0; dev->cd_status = playbit ? CD_STATUS_PLAYING : CD_STATUS_PAUSED; return 1; @@ -647,6 +656,7 @@ cdrom_audio_track_search_pioneer(cdrom_t *dev, uint32_t pos, uint8_t playbit) dev->seek_pos = pos; + dev->audio_muted_soft = 0; /* Do this at this point, since it's at this point that we know the actual LBA position to start playing from. */ if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) { @@ -676,6 +686,7 @@ cdrom_audio_play_pioneer(cdrom_t *dev, uint32_t pos) pos = MSFtoLBA(m, s, f) - 150; dev->cd_end = pos; + dev->audio_muted_soft = 0; dev->cd_buflen = 0; dev->cd_status = CD_STATUS_PLAYING; return 1; @@ -717,16 +728,7 @@ cdrom_audio_play_toshiba(cdrom_t *dev, uint32_t pos, int type) break; } - cdrom_log("Toshiba/NEC Play Audio: MSF = %06x, type = %02x, cdstatus = %02x\n", pos, type, dev->cd_status); - - /* Do this at this point, since it's at this point that we know the - actual LBA position to start playing from. */ - if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) { - cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos); - cdrom_stop(dev); - return 0; - } - + cdrom_log("Toshiba Play Audio: Muted?=%d, LBA=%08X.\n", dev->audio_muted_soft, pos); dev->cd_buflen = 0; dev->cd_status = CD_STATUS_PLAYING; return 1; @@ -770,6 +772,7 @@ cdrom_audio_scan(cdrom_t *dev, uint32_t pos, int type) break; } + dev->audio_muted_soft = 0; /* Do this at this point, since it's at this point that we know the actual LBA position to start playing from. */ if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) { @@ -1007,6 +1010,11 @@ cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b) else ret = (dev->cd_status == CD_STATUS_PLAYING) ? 0x00 : dev->audio_op; + /*If a valid audio track is detected with audio on, unmute it.*/ + if (dev->ops->track_type(dev, dev->seek_pos) & CD_TRACK_AUDIO) + dev->audio_muted_soft = 0; + + cdrom_log("SubCodeQ: Play Status: Seek LBA=%08x, CDEND=%08x, mute=%d.\n", dev->seek_pos, dev->cd_end, dev->audio_muted_soft); b[0] = subc.attr; b[1] = bin2bcd(subc.track); b[2] = bin2bcd(subc.index); diff --git a/src/include/86box/cdrom.h b/src/include/86box/cdrom.h index d188c9243..15127b06e 100644 --- a/src/include/86box/cdrom.h +++ b/src/include/86box/cdrom.h @@ -244,6 +244,7 @@ typedef struct cdrom { int prev_host_drive; int cd_buflen; int audio_op; + int audio_muted_soft; int sony_msf; const cdrom_ops_t *ops; diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 65417ebe3..f52401785 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -3613,6 +3613,14 @@ atapi_out: dev->sony_vendor = 1; len = (cdb[7] << 8) | cdb[8]; + if (!len) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_log("CD-ROM %i: PlayBack Control Sony All done - callback set\n", dev->id); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + break; + } scsi_cdrom_buf_alloc(dev, 65536); scsi_cdrom_set_buf_len(dev, BufLen, &len); From 9926e1ff6aff3b85aa759d0b64df6bc8b9a87855 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 6 Feb 2024 21:26:23 +0100 Subject: [PATCH 450/936] SVGA video card fixes of the day. Vendor banking should be 0 when plain IBM VGA modes are set, fixes corrupt text modes (Cirrus and Paradise at the moment). --- src/video/vid_cl54xx.c | 3 +- src/video/vid_paradise.c | 125 ++++++++++++++++++++------------------- 2 files changed, 65 insertions(+), 63 deletions(-) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 469de649b..b8f749568 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -817,6 +817,7 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429) svga->set_reset_disabled = svga->seqregs[7] & 1; gd54xx_set_svga_fast(gd54xx); + gd54xx_recalc_banking(gd54xx); svga_recalctimings(svga); break; case 0x17: @@ -1642,7 +1643,7 @@ gd54xx_recalc_banking(gd54xx_t *gd54xx) svga->extra_banks[1] = svga->extra_banks[0] + 0x8000; } - svga->write_bank = svga->read_bank = svga->extra_banks[0]; + svga->write_bank = svga->read_bank = svga->packed_chain4 ? svga->extra_banks[0] : 0; } static void diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index ad197f302..30666e82c 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -51,7 +51,7 @@ typedef struct paradise_t { uint32_t read_bank[4], write_bank[4]; int interlace; - int check, check2; + int check; struct { uint8_t reg_block_ptr; @@ -79,6 +79,7 @@ paradise_in(uint16_t addr, void *priv) { paradise_t *paradise = (paradise_t *) priv; svga_t *svga = ¶dise->svga; + uint8_t temp = 0; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -109,13 +110,14 @@ paradise_in(uint16_t addr, void *priv) } switch (svga->gdcaddr) { case 0x0b: + temp = svga->gdcreg[0x0b]; if (paradise->type == WD90C30) { if (paradise->vram_mask == ((512 << 10) - 1)) { - svga->gdcreg[0x0b] |= 0xc0; - svga->gdcreg[0x0b] &= ~0x40; + temp &= ~0x40; + temp |= 0xc0; } } - return svga->gdcreg[0x0b]; + return temp; case 0x0f: return (svga->gdcreg[0x0f] & 0x17) | 0x80; @@ -184,9 +186,10 @@ paradise_out(uint16_t addr, uint8_t val, void *priv) return; } + old = svga->gdcreg[svga->gdcaddr]; switch (svga->gdcaddr) { case 6: - if ((svga->gdcreg[6] & 0x0c) != (val & 0x0c)) { + if (old ^ (val & 0x0c)) { switch (val & 0x0c) { case 0x00: /*128k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); @@ -208,9 +211,9 @@ paradise_out(uint16_t addr, uint8_t val, void *priv) default: break; } + svga->gdcreg[6] = val; + paradise_remap(paradise); } - svga->gdcreg[6] = val; - paradise_remap(paradise); return; case 9: @@ -222,6 +225,10 @@ paradise_out(uint16_t addr, uint8_t val, void *priv) svga->gdcreg[0x0b] = val; paradise_remap(paradise); return; + case 0x0e: + svga->gdcreg[0x0e] = val; + svga_recalctimings(svga); + return; default: break; @@ -258,15 +265,6 @@ paradise_out(uint16_t addr, uint8_t val, void *priv) } break; - case 0x46e8: - io_removehandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); - mem_mapping_disable(¶dise->svga.mapping); - if (val & 8) { - io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); - mem_mapping_enable(¶dise->svga.mapping); - } - break; - default: break; } @@ -277,7 +275,7 @@ paradise_out(uint16_t addr, uint8_t val, void *priv) void paradise_remap(paradise_t *paradise) { - const svga_t *svga = ¶dise->svga; + svga_t *svga = ¶dise->svga; paradise->check = 0; @@ -319,8 +317,6 @@ paradise_recalctimings(svga_t *svga) { const paradise_t *paradise = (paradise_t *) svga->priv; - svga->lowres = !(svga->gdcreg[0x0e] & 0x01); - if (paradise->type == WD90C30) { if (svga->crtc[0x3e] & 0x01) svga->vtotal |= 0x400; @@ -335,50 +331,42 @@ paradise_recalctimings(svga_t *svga) svga->interlace = !!(svga->crtc[0x2d] & 0x20); - if (!svga->interlace && svga->lowres && (svga->hdisp >= 1024) && ((svga->gdcreg[5] & 0x60) == 0) && (svga->miscout >= 0x27) && (svga->miscout <= 0x2f) && ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1))) { /*Horrible tweak to re-enable the interlace after returning to + if (!svga->interlace && !(svga->gdcreg[0x0e] & 0x01) && (svga->hdisp >= 1024) && ((svga->gdcreg[5] & 0x60) == 0) && (svga->miscout >= 0x27) && (svga->miscout <= 0x2f) && ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1))) { /*Horrible tweak to re-enable the interlace after returning to a windowed DOS box in Win3.x*/ svga->interlace = 1; } } - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ - svga->interlace = 0; - } - if (paradise->type < WD90C30) { - if ((svga->bpp >= 8) && !svga->lowres) { - svga->render = svga_render_8bpp_highres; - } - } else { - if ((svga->bpp >= 8) && !svga->lowres) { - if (svga->bpp == 16) { - svga->render = svga_render_16bpp_highres; - svga->hdisp >>= 1; - if (svga->hdisp == 788) - svga->hdisp += 12; - if (svga->hdisp == 800) - svga->ma_latch -= 3; - } else if (svga->bpp == 15) { - svga->render = svga_render_15bpp_highres; - svga->hdisp >>= 1; - if (svga->hdisp == 788) - svga->hdisp += 12; - if (svga->hdisp == 800) - svga->ma_latch -= 3; - } else { + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + if ((svga->bpp >= 8) && (svga->gdcreg[0x0e] & 0x01)) { svga->render = svga_render_8bpp_highres; } } + } else { + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + if ((svga->bpp >= 8) && (svga->gdcreg[0x0e] & 0x01)) { + if (svga->bpp == 16) { + svga->render = svga_render_16bpp_highres; + svga->hdisp >>= 1; + if (svga->hdisp == 788) + svga->hdisp += 12; + if (svga->hdisp == 800) + svga->ma_latch -= 3; + } else if (svga->bpp == 15) { + svga->render = svga_render_15bpp_highres; + svga->hdisp >>= 1; + if (svga->hdisp == 788) + svga->hdisp += 12; + if (svga->hdisp == 800) + svga->ma_latch -= 3; + } else { + svga->render = svga_render_8bpp_highres; + } + } + } } - - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ - if (svga->hdisp == 360) - svga->hdisp <<= 1; - if (svga->seqregs[1] & 8) { - svga->render = svga_render_text_40; - } else - svga->render = svga_render_text_80; - } + svga->vram_display_mask = (svga->crtc[0x2f] & 0x02) ? 0x3ffff : paradise->vram_mask; } static void @@ -389,10 +377,15 @@ paradise_write(uint32_t addr, uint8_t val, void *priv) uint32_t prev_addr; uint32_t prev_addr2; + if (!(svga->gdcreg[5] & 0x40)) { + svga_write(addr, val, svga); + return; + } + addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; /*Could be done in a better way but it works.*/ - if (!svga->lowres) { + if (svga->gdcreg[0x0e] & 0x01) { if (paradise->check) { prev_addr = addr & 3; prev_addr2 = addr & 0xfffc; @@ -427,7 +420,6 @@ paradise_write(uint32_t addr, uint8_t val, void *priv) } } } - svga_write_linear(addr, val, svga); } static void @@ -438,10 +430,15 @@ paradise_writew(uint32_t addr, uint16_t val, void *priv) uint32_t prev_addr; uint32_t prev_addr2; + if (!(svga->gdcreg[5] & 0x40)) { + svga_writew(addr, val, svga); + return; + } + addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; /*Could be done in a better way but it works.*/ - if (!svga->lowres) { + if (svga->gdcreg[0x0e] & 0x01) { if (paradise->check) { prev_addr = addr & 3; prev_addr2 = addr & 0xfffc; @@ -476,7 +473,6 @@ paradise_writew(uint32_t addr, uint16_t val, void *priv) } } } - svga_writew_linear(addr, val, svga); } @@ -488,10 +484,14 @@ paradise_read(uint32_t addr, void *priv) uint32_t prev_addr; uint32_t prev_addr2; + if (!(svga->gdcreg[5] & 0x40)) { + return svga_read(addr, svga); + } + addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; /*Could be done in a better way but it works.*/ - if (!svga->lowres) { + if (svga->gdcreg[0x0e] & 0x01) { if (paradise->check) { prev_addr = addr & 3; prev_addr2 = addr & 0xfffc; @@ -526,7 +526,6 @@ paradise_read(uint32_t addr, void *priv) } } } - return svga_read_linear(addr, svga); } static uint16_t @@ -537,10 +536,14 @@ paradise_readw(uint32_t addr, void *priv) uint32_t prev_addr; uint32_t prev_addr2; + if (!(svga->gdcreg[5] & 0x40)) { + return svga_readw(addr, svga); + } + addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; /*Could be done in a better way but it works.*/ - if (!svga->lowres) { + if (svga->gdcreg[0x0e] & 0x01) { if (paradise->check) { prev_addr = addr & 3; prev_addr2 = addr & 0xfffc; @@ -575,7 +578,6 @@ paradise_readw(uint32_t addr, void *priv) } } } - return svga_readw_linear(addr, svga); } @@ -641,7 +643,6 @@ paradise_init(const device_t *info, uint32_t memsize) case WD90C11: svga->crtc[0x36] = '1'; svga->crtc[0x37] = '1'; - io_sethandler(0x46e8, 0x0001, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); break; case WD90C30: svga->crtc[0x36] = '3'; From 792485f48f6670051cfa001c487e8563fbe193f7 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 6 Feb 2024 21:34:00 +0100 Subject: [PATCH 451/936] Radius Video7 ISA card update about the I/O handler. Don't touch the POS I/O ports at all, fixes hang ups with the card in question using the IBM PS/1 machines, which rely on those ports. --- src/video/vid_ht216.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index 803d5658c..35d335ed2 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -454,14 +454,10 @@ ht216_out(uint16_t addr, uint8_t val, void *priv) break; case 0x46e8: - if ((ht216->id == 0x7152) && ht216->isabus) - io_removehandler(0x0105, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); io_removehandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); mem_mapping_disable(&svga->mapping); mem_mapping_disable(&ht216->linear_mapping); if (val & 8) { - if ((ht216->id == 0x7152) && ht216->isabus) - io_sethandler(0x0105, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); mem_mapping_enable(&svga->mapping); ht216_remap(ht216); From e648af9a71af141c2c6276ff17041c268cc67afc Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 6 Feb 2024 21:40:26 +0100 Subject: [PATCH 452/936] HDISP updates on S3 968 cards. Attempt at fixing the half horizontal display bugs in the best possible way without affecting the vendor drivers (which don't enable bit 6 of gdcreg5 for 256 colors and greater but generic non-vendor specific drivers do). --- src/video/vid_s3.c | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index ad7e77aa7..342a62ce7 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3273,8 +3273,7 @@ s3_recalctimings(svga_t *svga) svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18); } - svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2] + 1; - + svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2] + 1; if (s3->chip >= S3_VISION964) { /* NOTE: The S3 Trio64V+ datasheet says this is bit 7, but then where is bit 6? The datasheets for the pre-Trio64V+ cards say +64, which implies bit 6, @@ -3401,7 +3400,6 @@ s3_recalctimings(svga_t *svga) svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; break; - case S3_SPEA_MERCURY_P64V: case S3_ELSAWIN2KPROX: switch (s3->width) { case 1280: @@ -3413,15 +3411,22 @@ s3_recalctimings(svga_t *svga) break; } break; + case S3_SPEA_MERCURY_P64V: case S3_MIROVIDEO40SV_ERGO_968: switch (s3->width) { case 1152: case 1280: + case 1600: svga->hdisp <<= 1; svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; break; default: + if (svga->attrregs[0x10] & 0x40) { + svga->hdisp <<= 1; + svga->hblankstart <<= 1; + svga->hblank_end_val <<= 1; + } break; } break; @@ -3617,6 +3622,16 @@ s3_recalctimings(svga_t *svga) break; } break; + + case S3_MIROVIDEO40SV_ERGO_968: + case S3_SPEA_MERCURY_P64V: + if (svga->attrregs[0x10] & 0x40) { + svga->hdisp <<= 1; + svga->hblankstart <<= 1; + svga->hblank_end_val <<= 1; + } + break; + default: break; } @@ -3811,6 +3826,16 @@ s3_recalctimings(svga_t *svga) break; } break; + + case S3_MIROVIDEO40SV_ERGO_968: + case S3_SPEA_MERCURY_P64V: + if (svga->attrregs[0x10] & 0x40) { + svga->hdisp <<= 1; + svga->hblankstart <<= 1; + svga->hblank_end_val <<= 1; + } + break; + default: break; } @@ -4043,6 +4068,16 @@ s3_recalctimings(svga_t *svga) break; } break; + + case S3_MIROVIDEO40SV_ERGO_968: + case S3_SPEA_MERCURY_P64V: + if (svga->attrregs[0x10] & 0x40) { + svga->hdisp <<= 1; + svga->hblankstart <<= 1; + svga->hblank_end_val <<= 1; + } + break; + default: break; } @@ -4189,7 +4224,7 @@ s3_trio64v_recalctimings(svga_t *svga) /* Also make sure vertical blanking starts on display end. */ svga->vblankstart = svga->dispend; } else { - svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2] + 1; + svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2] + 1; /* NOTE: The S3 Trio64V+ datasheet says this is bit 7, but then where is bit 6? The datasheets for the pre-Trio64V+ cards say +64, which implies bit 6, From cb4f0fe85a8f5536e8baa3feac1a4bd4abf75309 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 6 Feb 2024 22:41:59 +0100 Subject: [PATCH 453/936] Revert "HDISP updates on S3 968 cards." This reverts commit e648af9a71af141c2c6276ff17041c268cc67afc. --- src/video/vid_s3.c | 43 ++++--------------------------------------- 1 file changed, 4 insertions(+), 39 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 342a62ce7..ad7e77aa7 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3273,7 +3273,8 @@ s3_recalctimings(svga_t *svga) svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18); } - svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2] + 1; + svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2] + 1; + if (s3->chip >= S3_VISION964) { /* NOTE: The S3 Trio64V+ datasheet says this is bit 7, but then where is bit 6? The datasheets for the pre-Trio64V+ cards say +64, which implies bit 6, @@ -3400,6 +3401,7 @@ s3_recalctimings(svga_t *svga) svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; break; + case S3_SPEA_MERCURY_P64V: case S3_ELSAWIN2KPROX: switch (s3->width) { case 1280: @@ -3411,22 +3413,15 @@ s3_recalctimings(svga_t *svga) break; } break; - case S3_SPEA_MERCURY_P64V: case S3_MIROVIDEO40SV_ERGO_968: switch (s3->width) { case 1152: case 1280: - case 1600: svga->hdisp <<= 1; svga->hblankstart <<= 1; svga->hblank_end_val <<= 1; break; default: - if (svga->attrregs[0x10] & 0x40) { - svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; - } break; } break; @@ -3622,16 +3617,6 @@ s3_recalctimings(svga_t *svga) break; } break; - - case S3_MIROVIDEO40SV_ERGO_968: - case S3_SPEA_MERCURY_P64V: - if (svga->attrregs[0x10] & 0x40) { - svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; - } - break; - default: break; } @@ -3826,16 +3811,6 @@ s3_recalctimings(svga_t *svga) break; } break; - - case S3_MIROVIDEO40SV_ERGO_968: - case S3_SPEA_MERCURY_P64V: - if (svga->attrregs[0x10] & 0x40) { - svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; - } - break; - default: break; } @@ -4068,16 +4043,6 @@ s3_recalctimings(svga_t *svga) break; } break; - - case S3_MIROVIDEO40SV_ERGO_968: - case S3_SPEA_MERCURY_P64V: - if (svga->attrregs[0x10] & 0x40) { - svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; - } - break; - default: break; } @@ -4224,7 +4189,7 @@ s3_trio64v_recalctimings(svga_t *svga) /* Also make sure vertical blanking starts on display end. */ svga->vblankstart = svga->dispend; } else { - svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2] + 1; + svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2] + 1; /* NOTE: The S3 Trio64V+ datasheet says this is bit 7, but then where is bit 6? The datasheets for the pre-Trio64V+ cards say +64, which implies bit 6, From e0aa4db15167bbd6a266dbb92af46909be246ee1 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 6 Feb 2024 22:44:58 +0100 Subject: [PATCH 454/936] Update on Cirrus banking. When I say banking should be 0 when IBM VGA modes are set, they must be, Cirrus... Also, updated the vram mask using the gd54xx struct rather than svga's for consistency. --- src/video/vid_cl54xx.c | 85 ++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 41 deletions(-) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index b8f749568..6edece1eb 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -809,15 +809,14 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((val & 0x3f) * 256)); break; case 0x07: - svga->packed_chain4 = svga->seqregs[7] & 1; + svga->packed_chain4 = svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA; if (gd54xx_is_5422(svga)) gd543x_recalc_mapping(gd54xx); else svga->seqregs[svga->seqaddr] &= 0x0f; if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429) - svga->set_reset_disabled = svga->seqregs[7] & 1; + svga->set_reset_disabled = svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA; gd54xx_set_svga_fast(gd54xx); - gd54xx_recalc_banking(gd54xx); svga_recalctimings(svga); break; case 0x17: @@ -1643,7 +1642,11 @@ gd54xx_recalc_banking(gd54xx_t *gd54xx) svga->extra_banks[1] = svga->extra_banks[0] + 0x8000; } - svga->write_bank = svga->read_bank = svga->packed_chain4 ? svga->extra_banks[0] : 0; + if (!(svga->gdcreg[5] & 0x40) || !(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) { + svga->extra_banks[0] = 0; + svga->extra_banks[1] = 0x8000; + } + svga->write_bank = svga->read_bank = svga->extra_banks[0]; } static void @@ -1662,7 +1665,7 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) gd54xx->mmio_vram_overlap = 0; - if (!gd54xx_is_5422(svga) || !(svga->seqregs[7] & 0xf0) || !(svga->seqregs[0x07] & 0x01)) { + if (!gd54xx_is_5422(svga) || !(svga->seqregs[0x07] & 0xf0) || !(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) { mem_mapping_disable(&gd54xx->linear_mapping); mem_mapping_disable(&gd54xx->aperture2_mapping); switch (svga->gdcreg[6] & 0x0c) { @@ -1688,7 +1691,7 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) break; } - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x07] & 0x01) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)) { + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)) { if (gd54xx->mmio_vram_overlap) { mem_mapping_disable(&svga->mapping); mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x08000); @@ -1699,10 +1702,10 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) } else { if ((svga->crtc[0x27] <= CIRRUS_ID_CLGD5429) || (!gd54xx->pci && !gd54xx->vlb)) { if (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) { - base = (svga->seqregs[7] & 0xf0) << 16; + base = (svga->seqregs[0x07] & 0xf0) << 16; size = 1 * 1024 * 1024; } else { - base = (svga->seqregs[7] & 0xe0) << 16; + base = (svga->seqregs[0x07] & 0xe0) << 16; size = 2 * 1024 * 1024; } } else if (gd54xx->pci) { @@ -1790,7 +1793,7 @@ gd54xx_recalctimings(svga_t *svga) } svga->map8 = svga->pallook; - if (svga->seqregs[7] & CIRRUS_SR7_BPP_SVGA) { + if (svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) { if (linedbl) svga->render = svga_render_8bpp_lowres; else { @@ -1840,7 +1843,7 @@ gd54xx_recalctimings(svga_t *svga) break; case 5: - if (gd54xx_is_5434(svga) && (svga->seqregs[7] & CIRRUS_SR7_BPP_32)) { + if (gd54xx_is_5434(svga) && (svga->seqregs[0x07] & CIRRUS_SR7_BPP_32)) { svga->bpp = 32; if (linedbl) svga->render = svga_render_32bpp_lowres; @@ -1877,7 +1880,7 @@ gd54xx_recalctimings(svga_t *svga) break; case 0xf: - switch (svga->seqregs[7] & CIRRUS_SR7_BPP_MASK) { + switch (svga->seqregs[0x07] & CIRRUS_SR7_BPP_MASK) { case CIRRUS_SR7_BPP_32: if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5430) { svga->bpp = 32; @@ -1957,7 +1960,7 @@ gd54xx_recalctimings(svga_t *svga) uint8_t m = gd54xx->vclk_d[clocksel] & 0x01 ? 2 : 1; float freq = (14318184.0F * ((float) n / ((float) d * m))); if (gd54xx_is_5422(svga)) { - switch (svga->seqregs[7] & (gd54xx_is_5434(svga) ? 0xe : 6)) { + switch (svga->seqregs[0x07] & (gd54xx_is_5434(svga) ? 0xe : 6)) { case 2: freq /= 2.0F; break; @@ -2194,7 +2197,7 @@ gd54xx_write(uint32_t addr, uint8_t val, void *priv) return; } - if ((svga->seqregs[0x07] & 0x01) == 0) { + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) { svga_write(addr, val, svga); return; } @@ -2216,7 +2219,7 @@ gd54xx_writew(uint32_t addr, uint16_t val, void *priv) return; } - if ((svga->seqregs[0x07] & 0x01) == 0) { + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) { svga_writew(addr, val, svga); return; } @@ -2347,7 +2350,7 @@ gd54xx_readb_linear(uint32_t addr, void *priv) uint8_t ap = gd54xx_get_aperture(addr); addr &= 0x003fffff; /* 4 MB mask */ - if ((svga->seqregs[0x07] & 0x01) == 0) + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) return svga_read_linear(addr, svga); if ((addr >= (svga->vram_max - 256)) && (addr < svga->vram_max)) { @@ -2390,7 +2393,7 @@ gd54xx_readw_linear(uint32_t addr, void *priv) addr &= 0x003fffff; /* 4 MB mask */ - if ((svga->seqregs[0x07] & 0x01) == 0) + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) return svga_readw_linear(addr, svga); if ((addr >= (svga->vram_max - 256)) && (addr < svga->vram_max)) { @@ -2440,7 +2443,7 @@ gd54xx_readl_linear(uint32_t addr, void *priv) addr &= 0x003fffff; /* 4 MB mask */ - if ((svga->seqregs[0x07] & 0x01) == 0) + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) return svga_readl_linear(addr, svga); if ((addr >= (svga->vram_max - 256)) && (addr < svga->vram_max)) { @@ -2580,7 +2583,7 @@ gd54xx_writeb_linear(uint32_t addr, uint8_t val, void *priv) uint8_t ap = gd54xx_get_aperture(addr); - if ((svga->seqregs[0x07] & 0x01) == 0) { + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) { svga_write_linear(addr, val, svga); return; } @@ -2627,7 +2630,7 @@ gd54xx_writew_linear(uint32_t addr, uint16_t val, void *priv) uint32_t old_addr = addr; uint8_t ap = gd54xx_get_aperture(addr); - if ((svga->seqregs[0x07] & 0x01) == 0) { + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) { svga_writew_linear(addr, val, svga); return; } @@ -2694,7 +2697,7 @@ gd54xx_writel_linear(uint32_t addr, uint32_t val, void *priv) uint32_t old_addr = addr; uint8_t ap = gd54xx_get_aperture(addr); - if ((svga->seqregs[0x07] & 0x01) == 0) { + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) { svga_writel_linear(addr, val, svga); return; } @@ -2771,7 +2774,7 @@ gd54xx_read(uint32_t addr, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; - if ((svga->seqregs[0x07] & 0x01) == 0) + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) return svga_read(addr, svga); if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) @@ -2788,7 +2791,7 @@ gd54xx_readw(uint32_t addr, void *priv) svga_t *svga = &gd54xx->svga; uint16_t ret; - if ((svga->seqregs[0x07] & 0x01) == 0) + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) return svga_readw(addr, svga); if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { @@ -2808,7 +2811,7 @@ gd54xx_readl(uint32_t addr, void *priv) svga_t *svga = &gd54xx->svga; uint32_t ret; - if ((svga->seqregs[0x07] & 0x01) == 0) + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) return svga_readl(addr, svga); if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { @@ -3446,7 +3449,7 @@ gd54xx_pattern_copy(gd54xx_t *gd54xx) if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) pattern_pitch = 1; - dsta = gd54xx->blt.dst_addr & svga->vram_mask; + dsta = gd54xx->blt.dst_addr & gd54xx->vram_mask; /* The vertical offset is in the three low-order bits of the Source Address register. */ pattern_y = gd54xx->blt.src_addr & 0x07; @@ -3460,7 +3463,7 @@ gd54xx_pattern_copy(gd54xx_t *gd54xx) */ /* The boundary has to be equal to the size of the pattern. */ - srca = (gd54xx->blt.src_addr & ~0x07) & svga->vram_mask; + srca = (gd54xx->blt.src_addr & ~0x07) & gd54xx->vram_mask; for (uint16_t y = 0; y <= gd54xx->blt.height; y++) { /* Go to the correct pattern line. */ @@ -3471,16 +3474,16 @@ gd54xx_pattern_copy(gd54xx_t *gd54xx) if (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) bitmask = 1; else - bitmask = svga->vram[srca2 & svga->vram_mask] & (0x80 >> pixel); + bitmask = svga->vram[srca2 & gd54xx->vram_mask] & (0x80 >> pixel); } for (int xx = 0; xx < gd54xx->blt.pixel_width; xx++) { if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) src = gd54xx_color_expand(gd54xx, bitmask, xx); else { - src = svga->vram[(srca2 + (x % (gd54xx->blt.pixel_width << 3)) + xx) & svga->vram_mask]; + src = svga->vram[(srca2 + (x % (gd54xx->blt.pixel_width << 3)) + xx) & gd54xx->vram_mask]; bitmask = gd54xx_transparent_comp(gd54xx, xx, src); } - dst = &(svga->vram[(dsta + x + xx) & svga->vram_mask]); + dst = &(svga->vram[(dsta + x + xx) & gd54xx->vram_mask]); target = *dst; gd54xx_rop(gd54xx, &target, &target, &src); if (gd54xx->blt.pixel_width == 3) @@ -3489,7 +3492,7 @@ gd54xx_pattern_copy(gd54xx_t *gd54xx) gd54xx_blit(gd54xx, bitmask, dst, target, (x < gd54xx->blt.pattern_x)); } pixel = (pixel + 1) & 7; - svga->changedvram[((dsta + x) & svga->vram_mask) >> 12] = changeframecount; + svga->changedvram[((dsta + x) & gd54xx->vram_mask) >> 12] = changeframecount; } pattern_y = (pattern_y + 1) & 7; dsta += gd54xx->blt.dst_pitch; @@ -3550,7 +3553,7 @@ gd54xx_mem_sys_src(gd54xx_t *gd54xx, uint32_t cpu_dat, uint32_t count) bitmask = gd54xx_transparent_comp(gd54xx, gd54xx->blt.xx_count, exp); } - dst = &(svga->vram[gd54xx->blt.dst_addr_backup & svga->vram_mask]); + dst = &(svga->vram[gd54xx->blt.dst_addr_backup & gd54xx->vram_mask]); target = *dst; gd54xx_rop(gd54xx, &target, &target, &exp); if ((gd54xx->blt.pixel_width == 3) && (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND)) @@ -3563,7 +3566,7 @@ gd54xx_mem_sys_src(gd54xx_t *gd54xx, uint32_t cpu_dat, uint32_t count) if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) gd54xx->blt.xx_count = (gd54xx->blt.xx_count + 1) % gd54xx->blt.pixel_width; - svga->changedvram[(gd54xx->blt.dst_addr_backup & svga->vram_mask) >> 12] = changeframecount; + svga->changedvram[(gd54xx->blt.dst_addr_backup & gd54xx->vram_mask) >> 12] = changeframecount; if (!gd54xx->blt.xx_count) { /* 1 mask bit = 1 blitted pixel */ @@ -3620,18 +3623,18 @@ gd54xx_normal_blit(uint32_t count, gd54xx_t *gd54xx, svga_t *svga) mask = 0; if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) { - mask = svga->vram[src_addr & svga->vram_mask] & (0x80 >> (gd54xx->blt.x_count / gd54xx->blt.pixel_width)); + mask = svga->vram[src_addr & gd54xx->vram_mask] & (0x80 >> (gd54xx->blt.x_count / gd54xx->blt.pixel_width)); shift = (gd54xx->blt.x_count % gd54xx->blt.pixel_width); src = gd54xx_color_expand(gd54xx, mask, shift); } else { - src = svga->vram[src_addr & svga->vram_mask]; + src = svga->vram[src_addr & gd54xx->vram_mask]; src_addr += gd54xx->blt.dir; mask = 1; } count--; - dst = svga->vram[dst_addr & svga->vram_mask]; - svga->changedvram[(dst_addr & svga->vram_mask) >> 12] = changeframecount; + dst = svga->vram[dst_addr & gd54xx->vram_mask]; + svga->changedvram[(dst_addr & gd54xx->vram_mask) >> 12] = changeframecount; gd54xx_rop(gd54xx, &dst, &dst, (const uint8_t *) &src); @@ -3643,7 +3646,7 @@ gd54xx_normal_blit(uint32_t count, gd54xx_t *gd54xx, svga_t *svga) mask = 0; if (((gd54xx->blt.width - width) >= gd54xx->blt.pattern_x) && !((gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) && !mask)) { - svga->vram[dst_addr & svga->vram_mask] = dst; + svga->vram[dst_addr & gd54xx->vram_mask] = dst; } dst_addr += gd54xx->blt.dir; @@ -3667,10 +3670,10 @@ gd54xx_normal_blit(uint32_t count, gd54xx_t *gd54xx, svga_t *svga) } else src_addr = gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr_backup + (gd54xx->blt.src_pitch * gd54xx->blt.dir); - dst_addr &= svga->vram_mask; - gd54xx->blt.dst_addr_backup &= svga->vram_mask; - src_addr &= svga->vram_mask; - gd54xx->blt.src_addr_backup &= svga->vram_mask; + dst_addr &= gd54xx->vram_mask; + gd54xx->blt.dst_addr_backup &= gd54xx->vram_mask; + src_addr &= gd54xx->vram_mask; + gd54xx->blt.src_addr_backup &= gd54xx->vram_mask; gd54xx->blt.x_count = 0; @@ -3711,7 +3714,7 @@ gd54xx_mem_sys_dest(uint32_t count, gd54xx_t *gd54xx, svga_t *svga) gd54xx->blt.msd_buf_pos = 0; while (gd54xx->blt.msd_buf_pos < 32) { - gd54xx->blt.msd_buf[gd54xx->blt.msd_buf_pos & 0x1f] = svga->vram[gd54xx->blt.src_addr_backup & svga->vram_mask]; + gd54xx->blt.msd_buf[gd54xx->blt.msd_buf_pos & 0x1f] = svga->vram[gd54xx->blt.src_addr_backup & gd54xx->vram_mask]; gd54xx->blt.src_addr_backup += gd54xx->blt.dir; gd54xx->blt.msd_buf_pos++; From 1b5ac0f68a7692cb8b3122eb854a791ec3d38afe Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 6 Feb 2024 23:35:43 +0100 Subject: [PATCH 455/936] TVP3026: Correctly apply the RAMDAC multiplex mode. --- src/video/vid_tvp3026_ramdac.c | 59 ++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c index a28cc2aed..4b63892de 100644 --- a/src/video/vid_tvp3026_ramdac.c +++ b/src/video/vid_tvp3026_ramdac.c @@ -517,6 +517,65 @@ tvp3026_recalctimings(void *priv, svga_t *svga) svga->interlace = (ramdac->ccr & 0x40); /* TODO: Figure out gamma correction for 15/16 bpp color. */ svga->lut_map = !!(svga->bpp >= 15 && (ramdac->true_color & 0xf0) != 0x00); + + switch (ramdac->mcr) { + case 0x41: + case 0x4a: + case 0x61: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + case 0x42: + case 0x4b: + case 0x62: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 0x43: + case 0x4c: + case 0x63: + svga->hdisp <<= 3; + svga->dots_per_clock <<= 3; + break; + case 0x44: + case 0x64: + svga->hdisp <<= 4; + svga->dots_per_clock <<= 4; + break; + case 0x5b: + switch (ramdac->true_color) { + case 0x16: + case 0x17: + svga->hdisp = (svga->hdisp << 2) / 3; + svga->dots_per_clock = (svga->dots_per_clock << 2) / 3; + break; + case 0x1e: + case 0x1f: + svga->hdisp = (svga->hdisp * 5) >> 2; + svga->dots_per_clock = (svga->dots_per_clock * 5) >> 2; + break; + } + break; + case 0x5c: + switch (ramdac->true_color) { + case 0x06: + case 0x07: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + case 0x16: + case 0x17: + svga->hdisp = (svga->hdisp << 3) / 3; + svga->dots_per_clock = (svga->dots_per_clock << 3) / 3; + break; + case 0x1e: + case 0x1f: + svga->hdisp = (svga->hdisp * 5) >> 1; + svga->dots_per_clock = (svga->dots_per_clock * 5) >> 1; + break; + } + break; + } } uint32_t From 30e768955c984127847d6aeb348f016aeb0d67f9 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 6 Feb 2024 23:50:32 +0100 Subject: [PATCH 456/936] 9001st update on Cirrus banking... 1. VRAM mask consistency... 2. Don't apply the IBM VGA mode check to linear functions, where banking isn't used at all. --- src/video/vid_cl54xx.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 6edece1eb..aaa208a23 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -816,6 +816,7 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) svga->seqregs[svga->seqaddr] &= 0x0f; if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429) svga->set_reset_disabled = svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA; + gd54xx_recalc_banking(gd54xx); gd54xx_set_svga_fast(gd54xx); svga_recalctimings(svga); break; @@ -2009,11 +2010,11 @@ gd54xx_hwcursor_draw(svga_t *svga, int displine) svga->hwcursor_latch.addr += pitch; for (int x = 0; x < svga->hwcursor.cur_xsize; x += 8) { - dat[0] = svga->vram[svga->hwcursor_latch.addr & svga->vram_display_mask]; + dat[0] = svga->vram[svga->hwcursor_latch.addr & gd54xx->vram_mask]; if (svga->hwcursor.cur_xsize == 64) - dat[1] = svga->vram[(svga->hwcursor_latch.addr + 0x08) & svga->vram_display_mask]; + dat[1] = svga->vram[(svga->hwcursor_latch.addr + 0x08) & gd54xx->vram_mask]; else - dat[1] = svga->vram[(svga->hwcursor_latch.addr + 0x80) & svga->vram_display_mask]; + dat[1] = svga->vram[(svga->hwcursor_latch.addr + 0x80) & gd54xx->vram_mask]; for (uint8_t xx = 0; xx < 8; xx++) { b0 = (dat[0] >> (7 - xx)) & 1; b1 = (dat[1] >> (7 - xx)) & 1; @@ -2350,7 +2351,7 @@ gd54xx_readb_linear(uint32_t addr, void *priv) uint8_t ap = gd54xx_get_aperture(addr); addr &= 0x003fffff; /* 4 MB mask */ - if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) return svga_read_linear(addr, svga); if ((addr >= (svga->vram_max - 256)) && (addr < svga->vram_max)) { @@ -2393,7 +2394,7 @@ gd54xx_readw_linear(uint32_t addr, void *priv) addr &= 0x003fffff; /* 4 MB mask */ - if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) return svga_readw_linear(addr, svga); if ((addr >= (svga->vram_max - 256)) && (addr < svga->vram_max)) { @@ -2443,7 +2444,7 @@ gd54xx_readl_linear(uint32_t addr, void *priv) addr &= 0x003fffff; /* 4 MB mask */ - if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) return svga_readl_linear(addr, svga); if ((addr >= (svga->vram_max - 256)) && (addr < svga->vram_max)) { @@ -2583,7 +2584,7 @@ gd54xx_writeb_linear(uint32_t addr, uint8_t val, void *priv) uint8_t ap = gd54xx_get_aperture(addr); - if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) { + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) { svga_write_linear(addr, val, svga); return; } @@ -2630,7 +2631,7 @@ gd54xx_writew_linear(uint32_t addr, uint16_t val, void *priv) uint32_t old_addr = addr; uint8_t ap = gd54xx_get_aperture(addr); - if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) { + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) { svga_writew_linear(addr, val, svga); return; } @@ -2697,7 +2698,7 @@ gd54xx_writel_linear(uint32_t addr, uint32_t val, void *priv) uint32_t old_addr = addr; uint8_t ap = gd54xx_get_aperture(addr); - if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) { + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) { svga_writel_linear(addr, val, svga); return; } From f3d585a1e1ec3f5f54d55d915a9258eb334c1cbd Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 7 Feb 2024 00:11:02 +0100 Subject: [PATCH 457/936] Fix horizontal blanking calculation, fixes some S3 blanking excesses. --- src/include/86box/vid_svga.h | 4 +- src/video/vid_ati28800.c | 6 +- src/video/vid_ati_mach8.c | 36 +++--- src/video/vid_cl54xx.c | 8 +- src/video/vid_et4000.c | 3 +- src/video/vid_et4000w32.c | 9 +- src/video/vid_mga.c | 9 +- src/video/vid_s3.c | 223 +++++++++++---------------------- src/video/vid_s3_virge.c | 18 +-- src/video/vid_svga.c | 66 ++++++---- src/video/vid_voodoo_banshee.c | 33 +++-- 11 files changed, 189 insertions(+), 226 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index f644c2b63..32bfbfd2f 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -118,16 +118,16 @@ typedef struct svga_t { int vram_display_mask; int vidclock; int dots_per_clock; - int hblank_ext; int hwcursor_on; int dac_hwcursor_on; int overlay_on; int set_override; int hblankstart; int hblankend; - int hblank_sub; int hblank_end_val; int hblank_end_len; + int hblank_end_mask; + int hblank_sub; int packed_4bpp; int ati_4color; diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index 1f2b69e25..be9654aca 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -429,8 +429,7 @@ ati28800_recalctimings(svga_t *svga) svga->hdisp <<= 1; svga->htotal <<= 1; svga->rowoffset <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; svga->gdcreg[5] &= ~0x40; } @@ -446,8 +445,7 @@ ati28800_recalctimings(svga_t *svga) if ((ati28800->regs[0xb6] & 0x18) == 8) { svga->hdisp <<= 1; svga->htotal <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; svga->ati_4color = 1; } else svga->ati_4color = 0; diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index de40dc24e..ff6024677 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2485,6 +2485,9 @@ ati8514_recalctimings(svga_t *svga) { const mach_t *mach = (mach_t *) svga->ext8514; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint32_t dot; + uint32_t adj_dot; + uint32_t eff_mask; mach_log("ON0=%d, ON1=%d, vgahdisp=%d.\n", dev->on[0], dev->on[1], svga->hdisp); if (dev->on[0] || dev->on[1]) { @@ -2528,19 +2531,26 @@ ati8514_recalctimings(svga_t *svga) svga->map8 = dev->pallook; svga->render8514 = ibm8514_render_8bpp; - dev->hblankend = (dev->h_blankstart & ~0x3f) | dev->h_blank_end_val; - if (dev->hblankend <= dev->h_blankstart) - dev->hblankend += 0x40; - - dev->hblankend += dev->hblank_ext; - + dot = svga->hblankstart; + adj_dot = svga->hblankstart; + eff_mask = 0x0000003f; dev->hblank_sub = 0; - if (dev->hblankend > dev->h_total) { - dev->hblankend &= 0x3f; - dev->hblank_sub = dev->hblankend + 1; - dev->h_disp -= dev->hblank_sub; + while (1) { + if (dot == dev->h_total) + dot = 0; + + if (adj_dot >= dev->h_total) + dev->hblank_sub++; + + if ((dot & 0x0000003f) == (svga->hblank_end_val & 0x0000003f)) + break; + + dot++; + adj_dot++; } + + dev->h_disp -= dev->hblank_sub); } else { if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ if (svga->seqregs[1] & 8) { /*40 column*/ @@ -2582,8 +2592,7 @@ mach_recalctimings(svga_t *svga) if ((mach->regs[0xb6] & 0x18) >= 0x10) { svga->hdisp <<= 1; svga->htotal <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; svga->rowoffset <<= 1; svga->gdcreg[5] &= ~0x40; } @@ -2601,8 +2610,7 @@ mach_recalctimings(svga_t *svga) if ((mach->regs[0xb6] & 0x18) == 8) { svga->hdisp <<= 1; svga->htotal <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; svga->ati_4color = 1; } else svga->ati_4color = 0; diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index aaa208a23..7ae985e95 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -1766,6 +1766,8 @@ gd54xx_recalctimings(svga_t *svga) svga->hblank_end_val = (svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00) | (((svga->crtc[0x1a] >> 4) & 3) << 6); + svga->hblank_end_mask = 0x0000007f; + if (svga->crtc[0x1b] & 0x20) { svga->hblankstart = svga->crtc[1] + ((svga->crtc[3] >> 5) & 3) + 1; svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); @@ -1774,9 +1776,6 @@ gd54xx_recalctimings(svga_t *svga) if (!svga->scrblank && svga->attr_palette_enable) svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; - /* No overscan in this mode. */ - svga->hblank_overscan = 0; - svga->monitor->mon_overscan_y = 0; svga->monitor->mon_overscan_x = 0; @@ -1801,8 +1800,7 @@ gd54xx_recalctimings(svga_t *svga) svga->render = svga_render_8bpp_highres; if ((svga->dispend == 512) && !svga->interlace && gd54xx_is_5434(svga)) { svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; } } } else if (svga->gdcreg[5] & 0x40) diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index f5f9ad813..6d52fc91b 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -668,8 +668,7 @@ et4000_recalctimings(svga_t *svga) svga->htotal += 256; if (svga->attrregs[0x16] & 0x20) { svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; } switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x34] << 1) & 4)) { diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index f3cac960b..259fefffb 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -450,8 +450,7 @@ et4000w32p_recalctimings(svga_t *svga) svga->htotal += 256; if (svga->attrregs[0x16] & 0x20) { svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; } svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((svga->miscout >> 2) & 3, svga->clock_gen); @@ -502,8 +501,7 @@ et4000w32p_recalctimings(svga_t *svga) case 16: if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; } if (et4000->type <= ET4000W32P_REVC) { if (et4000->type == ET4000W32P_REVC) { @@ -515,8 +513,7 @@ et4000w32p_recalctimings(svga_t *svga) break; case 24: svga->hdisp /= 3; - svga->hblankstart /= 3; - svga->hblank_end_val /= 3; + svga->dots_per_clock /= 3; if (et4000->type <= ET4000W32P_REVC) et4000->adjust_cursor = 2; if ((et4000->type == ET4000W32P_DIAMOND) && ((svga->hdisp == (640 / 2)) || (svga->hdisp == 1232))) { diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index bc335fc9c..088085355 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -976,11 +976,10 @@ mystique_recalctimings(svga_t *svga) svga->hdisp_time = svga->hdisp; svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); - svga->dots_per_clock = 8; - svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | - (((mystique->crtcext_regs[1] & 0x40) >> 6) << 6); - - svga->hblank_overscan = 0; + svga->dots_per_clock = 8; + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | + (((mystique->crtcext_regs[1] & 0x40) >> 6) << 6); + svga->hblank_end_mask = 0x0000007f; if (mystique->type != MGA_2164W && mystique->type != MGA_2064W) svga->lut_map = !!(mystique->xmiscctrl & XMISCCTRL_RAMCS); diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index ad7e77aa7..d8691ad77 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3153,6 +3153,17 @@ s3_recalctimings(svga_t *svga) int clk_sel = (svga->miscout >> 2) & 3; uint8_t mask = 0xc0; + if (svga->crtc[0x33] & 0x20) { + /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ + if (!svga->scrblank && svga->attr_palette_enable) + svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; + } else { + 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); + } + } + svga->hdisp = svga->hdisp_old; svga->ma_latch |= (s3->ma_ext << 16); @@ -3255,24 +3266,15 @@ s3_recalctimings(svga_t *svga) ((svga->crtc[3] >> 5) & 3) + 1; svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); - /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ - if (!svga->scrblank && svga->attr_palette_enable) - svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; - - /* No overscan in this mode. */ - svga->hblank_overscan = 0; - svga->monitor->mon_overscan_y = 0; svga->monitor->mon_overscan_x = 0; /* Also make sure vertical blanking starts on display end. */ svga->vblankstart = svga->dispend; - } else if (s3->chip >= S3_86C801) { - 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); - } + if (s3->chip >= S3_VISION964) + svga->hblank_end_mask = 0x7f; + } else if (s3->chip >= S3_86C801) { svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2] + 1; if (s3->chip >= S3_VISION964) { @@ -3280,8 +3282,9 @@ s3_recalctimings(svga_t *svga) The datasheets for the pre-Trio64V+ cards say +64, which implies bit 6, and, contrary to VGADOC, it also exists on Trio32, Trio64, Vision868, and Vision968. */ - svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | - (((svga->crtc[0x5d] & 0x08) >> 3) << 6); + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | + (((svga->crtc[0x5d] & 0x08) >> 3) << 6); + svga->hblank_end_mask = 0x7f; } } @@ -3329,20 +3332,17 @@ s3_recalctimings(svga_t *svga) switch (s3->width) { case 1280: svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; break; case 2048: /*Account for the 1280x1024 resolution*/ switch (svga->hdisp) { case 320: svga->hdisp <<= 2; - svga->hblankstart <<= 2; - svga->hblank_end_val <<= 2; + svga->dots_per_clock <<= 2; break; case 640: svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; break; default: break; @@ -3363,8 +3363,7 @@ s3_recalctimings(svga_t *svga) switch (s3->width) { case 640: svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; break; default: break; @@ -3382,8 +3381,7 @@ s3_recalctimings(svga_t *svga) case 1280: case 1600: svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; default: break; } @@ -3398,29 +3396,16 @@ s3_recalctimings(svga_t *svga) case S3_PHOENIX_VISION968: case S3_NUMBER9_9FX_771: svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; + if (svga->hdisp == 832) + svga->hdisp -= 32; break; - case S3_SPEA_MERCURY_P64V: case S3_ELSAWIN2KPROX: switch (s3->width) { case 1280: case 1600: svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; - default: - break; - } - break; - case S3_MIROVIDEO40SV_ERGO_968: - switch (s3->width) { - case 1152: - case 1280: - svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; - break; + svga->dots_per_clock <<= 1; default: break; } @@ -3464,16 +3449,14 @@ s3_recalctimings(svga_t *svga) case S3_86C911: case S3_86C924: svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; break; case S3_86C801: switch (s3->card_type) { case S3_PHOENIX_86C801: svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; break; default: @@ -3487,22 +3470,19 @@ s3_recalctimings(svga_t *svga) case S3_PHOENIX_86C805: case S3_86C805_ONBOARD: svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; break; case S3_SPEA_MIRAGE_86C805: svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; switch (s3->width) { case 800: case 1024: if (svga->hdisp == 400) { /*SPEA specific drivers + its VBE RAM BIOS...*/ svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; } break; default: @@ -3519,8 +3499,7 @@ s3_recalctimings(svga_t *svga) case S3_METHEUS_86C928: if (!s3->color_16bit) { svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; } switch (svga->hdisp) { /*This might be a driver issue*/ case 800: @@ -3544,8 +3523,7 @@ s3_recalctimings(svga_t *svga) switch (s3->width) { case 640: svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; break; default: break; @@ -3558,8 +3536,7 @@ s3_recalctimings(svga_t *svga) break; case S3_VISION864: svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; break; case S3_VISION964: switch (s3->card_type) { @@ -3568,8 +3545,7 @@ s3_recalctimings(svga_t *svga) case 1280: case 1600: svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; break; default: break; @@ -3585,8 +3561,7 @@ s3_recalctimings(svga_t *svga) case S3_PHOENIX_VISION868: case S3_NUMBER9_9FX_531: svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; break; default: @@ -3598,8 +3573,7 @@ s3_recalctimings(svga_t *svga) case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; /* TODO: Is this still needed? */ if (svga->hdisp == 832) svga->hdisp -= 32; @@ -3610,8 +3584,7 @@ s3_recalctimings(svga_t *svga) case 1280: case 1600: svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; break; default: break; @@ -3625,8 +3598,7 @@ s3_recalctimings(svga_t *svga) case S3_TRIO64: case S3_TRIO32: svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; break; default: @@ -3662,16 +3634,14 @@ s3_recalctimings(svga_t *svga) case S3_86C911: case S3_86C924: svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; break; case S3_86C801: switch (s3->card_type) { case S3_PHOENIX_86C801: svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; break; default: @@ -3685,8 +3655,7 @@ s3_recalctimings(svga_t *svga) case S3_PHOENIX_86C805: case S3_86C805_ONBOARD: svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; break; case S3_SPEA_MIRAGE_86C805: @@ -3697,8 +3666,7 @@ s3_recalctimings(svga_t *svga) if (svga->hdisp == 400) { /*SPEA specific drivers + its VBE RAM BIOS...*/ svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; } break; default: @@ -3714,8 +3682,7 @@ s3_recalctimings(svga_t *svga) switch (s3->card_type) { case S3_METHEUS_86C928: svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; switch (svga->hdisp) { /*This might be a driver issue*/ case 800: s3->width = 1024; @@ -3738,8 +3705,7 @@ s3_recalctimings(svga_t *svga) switch (s3->width) { case 640: svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; break; default: break; @@ -3752,16 +3718,14 @@ s3_recalctimings(svga_t *svga) break; case S3_VISION864: svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; break; case S3_VISION868: switch (s3->card_type) { case S3_PHOENIX_VISION868: case S3_NUMBER9_9FX_531: svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; break; default: @@ -3775,8 +3739,7 @@ s3_recalctimings(svga_t *svga) case 1280: case 1600: svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; break; default: break; @@ -3792,8 +3755,7 @@ s3_recalctimings(svga_t *svga) case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; /* TODO: Is this still needed? */ if (svga->hdisp == 832) svga->hdisp -= 32; @@ -3804,8 +3766,7 @@ s3_recalctimings(svga_t *svga) case 1280: case 1600: svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; break; default: break; @@ -3819,8 +3780,7 @@ s3_recalctimings(svga_t *svga) case S3_TRIO64: case S3_TRIO32: svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; break; default: @@ -3863,8 +3823,7 @@ s3_recalctimings(svga_t *svga) switch (s3->card_type) { case S3_AMI_86C924: svga->hdisp = (svga->hdisp << 1) / 3; - svga->hblankstart = (svga->hblankstart << 1) / 3; - svga->hblank_end_val = (svga->hblank_end_val << 1) / 3; + svga->dots_per_clock = (svga->dots_per_clock << 1) / 3; /* TODO: Is this still needed? */ if (svga->hdisp == 645) svga->hdisp -= 5; @@ -3878,8 +3837,7 @@ s3_recalctimings(svga_t *svga) case S3_PHOENIX_86C801: case S3_SPEA_MIRAGE_86C801: svga->hdisp = (svga->hdisp << 1) / 3; - svga->hblankstart = (svga->hblankstart << 1) / 3; - svga->hblank_end_val = (svga->hblank_end_val << 1) / 3; + svga->dots_per_clock = (svga->dots_per_clock << 1) / 3; break; default: break; @@ -3893,8 +3851,7 @@ s3_recalctimings(svga_t *svga) case S3_SPEA_MIRAGE_86C805: case S3_86C805_ONBOARD: svga->hdisp = (svga->hdisp << 1) / 3; - svga->hblankstart = (svga->hblankstart << 1) / 3; - svga->hblank_end_val = (svga->hblank_end_val << 1) / 3; + svga->dots_per_clock = (svga->dots_per_clock << 1) / 3; break; default: break; @@ -3904,8 +3861,7 @@ s3_recalctimings(svga_t *svga) switch (s3->card_type) { case S3_SPEA_MERCURY_LITE_PCI: svga->hdisp = (svga->hdisp << 1) / 3; - svga->hblankstart = (svga->hblankstart << 1) / 3; - svga->hblank_end_val = (svga->hblank_end_val << 1) / 3; + svga->dots_per_clock = (svga->dots_per_clock << 1) / 3; break; default: break; @@ -3913,34 +3869,13 @@ s3_recalctimings(svga_t *svga) break; case S3_VISION864: svga->hdisp = (svga->hdisp << 1) / 3; - svga->hblankstart = (svga->hblankstart << 1) / 3; - svga->hblank_end_val = (svga->hblank_end_val << 1) / 3; - break; - case S3_VISION968: - switch (s3->card_type) { - case S3_MIROVIDEO40SV_ERGO_968: - case S3_SPEA_MERCURY_P64V: - switch (s3->width) { - case 1280: - svga->hdisp = ((svga->hdisp << 1) / 3) << 1; - svga->hblankstart = (svga->hblankstart << 1) / 3; - svga->hblank_end_val = ((svga->hblank_end_val << 1) / 3) << 1; - break; - default: - break; - } - break; - - default: - break; - } + svga->dots_per_clock = (svga->dots_per_clock << 1) / 3; break; case S3_TRIO64: case S3_TRIO32: svga->hdisp /= 3; - svga->hblankstart /= 3; - svga->hblank_end_val /= 3; + svga->dots_per_clock /= 3; break; default: @@ -3969,7 +3904,8 @@ s3_recalctimings(svga_t *svga) svga->hdisp = 640; } } else { - if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_SPEA_MERCURY_P64V) + if ((s3->card_type == S3_MIROVIDEO40SV_ERGO_968) || + (s3->card_type == S3_PHOENIX_VISION968) || (s3->card_type == S3_SPEA_MERCURY_P64V)) svga->hdisp = s3->width; } #endif @@ -3982,8 +3918,7 @@ s3_recalctimings(svga_t *svga) case S3_PHOENIX_VISION868: case S3_NUMBER9_9FX_531: svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; break; default: break; @@ -3996,8 +3931,7 @@ s3_recalctimings(svga_t *svga) case 800: case 1024: svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; break; default: break; @@ -4008,8 +3942,7 @@ s3_recalctimings(svga_t *svga) case 1280: case 1600: svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; break; default: break; @@ -4024,8 +3957,7 @@ s3_recalctimings(svga_t *svga) case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; /* TODO: Is this still needed? */ if (svga->hdisp == 832) svga->hdisp -= 32; @@ -4036,8 +3968,7 @@ s3_recalctimings(svga_t *svga) case 1280: case 1600: svga->hdisp <<= 1; - svga->hblankstart <<= 1; - svga->hblank_end_val <<= 1; + svga->dots_per_clock <<= 1; break; default: break; @@ -4105,7 +4036,8 @@ s3_recalctimings(svga_t *svga) if (svga->crtc[0x31] & 0x08) { svga->vram_display_mask = s3->vram_mask; if (svga->bpp == 8) { - svga->render = svga_render_8bpp_highres; /*Enhanced 4bpp mode, just like the 8bpp mode per spec.*/ + /*Enhanced 4bpp mode, just like the 8bpp mode per the spec. */ + svga->render = svga_render_8bpp_highres; svga->rowoffset <<= 1; } } @@ -4125,6 +4057,12 @@ s3_trio64v_recalctimings(svga_t *svga) svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18); } + if ((svga->crtc[0x33] & 0x20) ||((svga->crtc[0x67] & 0xc) == 0xc)) { + /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ + if (!svga->scrblank && svga->attr_palette_enable) + svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; + } + svga->hdisp = svga->hdisp_old; if (svga->crtc[0x5d] & 0x01) svga->htotal |= 0x100; @@ -4176,13 +4114,6 @@ s3_trio64v_recalctimings(svga_t *svga) ((svga->crtc[3] >> 5) & 3) + 1; svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); - /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ - if (!svga->scrblank && svga->attr_palette_enable) - svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; - - /* No overscan in this mode. */ - svga->hblank_overscan = 0; - svga->monitor->mon_overscan_y = 0; svga->monitor->mon_overscan_x = 0; @@ -4197,6 +4128,7 @@ s3_trio64v_recalctimings(svga_t *svga) and Vision968. */ svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | (((svga->crtc[0x5d] & 0x08) >> 3) << 6); + svga->hblank_end_mask = 0x7f; } if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ @@ -4220,20 +4152,17 @@ s3_trio64v_recalctimings(svga_t *svga) case 15: svga->render = svga_render_15bpp_highres; svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; break; case 16: svga->render = svga_render_16bpp_highres; svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; break; case 24: svga->render = svga_render_24bpp_highres; svga->hdisp /= 3; - svga->hblankstart >>= 1; - svga->hblank_end_val /= 3; + svga->dots_per_clock /= 3; break; case 32: svga->render = svga_render_32bpp_highres; diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index a0bf98815..3184a1ccd 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -783,6 +783,12 @@ s3_virge_recalctimings(svga_t *svga) svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18); } + if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) { + /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ + if (!svga->scrblank && svga->attr_palette_enable) + svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; + } + if (svga->crtc[0x5d] & 0x01) svga->htotal += 0x100; if (svga->crtc[0x5d] & 0x02) { @@ -824,13 +830,6 @@ s3_virge_recalctimings(svga_t *svga) ((svga->crtc[3] >> 5) & 3) + 1; svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); - /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ - if (!svga->scrblank && svga->attr_palette_enable) - svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; - - /* No overscan in this mode. */ - svga->hblank_overscan = 0; - svga->monitor->mon_overscan_y = 0; svga->monitor->mon_overscan_x = 0; @@ -839,8 +838,9 @@ s3_virge_recalctimings(svga_t *svga) } else { svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2] + 1; - svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | - (((svga->crtc[0x5d] & 0x08) >> 3) << 6); + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | + (((svga->crtc[0x5d] & 0x08) >> 3) << 6); + svga->hblank_end_mask = 0x7f; } if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 692bfef27..a1ab605ea 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -641,10 +641,17 @@ svga_recalctimings(svga_t *svga) svga->render = svga_render_blank; if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { /* TODO: In case of bug reports, disable 9-dots-wide character clocks in graphics modes. */ - if (svga->seqregs[1] & 8) - svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; - else - svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { + if (svga->seqregs[1] & 8) + svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; + else + svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; + } else { + if (svga->seqregs[1] & 8) + svga->hdisp *= 16; + else + svga->hdisp *= 8; + } if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ if (svga->seqregs[1] & 8) { /*40 column*/ @@ -740,19 +747,24 @@ svga_recalctimings(svga_t *svga) svga->hblankstart = svga->crtc[2] + 1; svga->hblank_end_val = (svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00); + svga->hblank_end_mask = 0x0000003f; svga_log("htotal = %i, hblankstart = %i, hblank_end_val = %02X\n", svga->htotal, svga->hblankstart, svga->hblank_end_val); - svga->hblank_end_len = 0x00000040; - svga->hblank_overscan = 1; - if (!svga->scrblank && svga->attr_palette_enable) { /* TODO: In case of bug reports, disable 9-dots-wide character clocks in graphics modes. */ - if (svga->seqregs[1] & 8) - svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18); - else - svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 8 : 9); + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { + if (svga->seqregs[1] & 8) + svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18); + else + svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 8 : 9); + } else { + if (svga->seqregs[1] & 8) + svga->dots_per_clock = 16; + else + svga->dots_per_clock = 8; + } } else svga->dots_per_clock = 1; @@ -768,18 +780,31 @@ svga_recalctimings(svga_t *svga) xga_recalctimings(svga); if (!svga->hoverride) { - svga->hblankend = (svga->hblankstart & ~(svga->hblank_end_len - 1)) | svga->hblank_end_val; - if (svga->hblankend <= svga->hblankstart) - svga->hblankend += svga->hblank_end_len; - svga->hblankend += svga->hblank_ext; - + uint32_t dot = svga->hblankstart; + uint32_t adj_dot = svga->hblankstart; + /* Verified with both the Voodoo 3 and the S3 cards: compare 7 bits if bit 7 is set, + otherwise compare 6 bits. */ + uint32_t eff_mask = (svga->hblank_end_val & ~0x0000003f) ? svga->hblank_end_mask : 0x0000003f; svga->hblank_sub = 0; - if (svga->hblankend > svga->htotal) { - svga->hblankend &= (svga->hblank_end_len - 1); - svga->hblank_sub = svga->hblankend + svga->hblank_overscan; - svga->hdisp -= (svga->hblank_sub * svga->dots_per_clock); + svga_log("Blank: %04i-%04i, Total: %04i, Mask: %02X\n", svga->hblankstart, svga->hblank_end_val, + svga->htotal, eff_mask); + + while (1) { + if (dot == svga->htotal) + dot = 0; + + if (adj_dot >= svga->htotal) + svga->hblank_sub++; + + if ((dot & eff_mask) == (svga->hblank_end_val & eff_mask)) + break; + + dot++; + adj_dot++; } + + svga->hdisp -= (svga->hblank_sub * svga->dots_per_clock); } if (svga->hdisp >= 2048) @@ -1278,7 +1303,6 @@ svga_init(const device_t *info, svga_t *svga, void *priv, int memsize, svga->ramdac_type = RAMDAC_6BIT; svga->map8 = svga->pallook; - svga->hblank_overscan = 1; /* Do at least 1 character of overscan after horizontal blanking. */ return 0; } diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index cf8cc154c..9fec8c073 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -556,17 +556,20 @@ banshee_recalctimings(svga_t *svga) if (banshee->vidProcCfg & VIDPROCCFG_VIDPROC_ENABLE) { /* Video processing mode - assume timings akin to Cirrus' special blanking mode, that is, no overscan and relying on display end to blank. */ - svga->hblankstart = svga->crtc[1] + ((svga->crtc[3] >> 5) & 3) + - (((svga->crtc[0x1a] & 0x04) >> 2) << 8) + 1; + if (banshee->vgaInit0 & 0x40) { + svga->hblankstart = svga->crtc[1] + ((svga->crtc[3] >> 5) & 3) + + (((svga->crtc[0x1a] & 0x04) >> 2) << 8) + 1; + svga->hblank_end_mask = 0x0000007f; + } else { + svga->hblankstart = svga->crtc[1] + ((svga->crtc[3] >> 5) & 3) + 1; + svga->hblank_end_mask = 0x0000003f; + } svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ if (!svga->scrblank && svga->attr_palette_enable) svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; - /* No overscan in this mode. */ - svga->hblank_overscan = 0; - svga->monitor->mon_overscan_y = 0; svga->monitor->mon_overscan_x = 0; @@ -575,9 +578,16 @@ banshee_recalctimings(svga_t *svga) svga->linedbl = 0; } else { - svga->hblankstart = (((svga->crtc[0x1a] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; - svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | - (((svga->crtc[0x1a] & 0x20) >> 5) << 6); + if (banshee->vgaInit0 & 0x40) { + svga->hblankstart = (((svga->crtc[0x1a] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | + (((svga->crtc[0x1a] & 0x20) >> 5) << 6); + svga->hblank_end_mask = 0x0000007f; + } else { + svga->hblankstart = svga->crtc[2] + 1; + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5); + svga->hblank_end_mask = 0x0000003f; + } } /*6 R/W Vertical Retrace Start bit 10 0x10 @@ -642,9 +652,10 @@ banshee_recalctimings(svga_t *svga) if (banshee->vidProcCfg & VIDPROCCFG_2X_MODE) { svga->hdisp *= 2; - svga->htotal *= 2; - svga->hblankstart *= 2; - svga->hblank_end_val *= 2; + // svga->htotal *= 2; + // svga->hblankstart *= 2; + // svga->hblank_end_val *= 2; + svga->dots_per_clock *= 2; } svga->interlace = !!(banshee->vidProcCfg & VIDPROCCFG_INTERLACE); From 7198b78069a84b9bb8a04fd1420152a0c470d4a7 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 7 Feb 2024 01:53:16 +0100 Subject: [PATCH 458/936] Couple of changes in the video side. 1. Second attempt to fix the banking in the Cirrus (sigh, why doesn't banking get nulled automatically...) 2. Introduce a new timer to the 8514/A side so it won't slow the VGA clock down it was shared before. --- src/include/86box/vid_8514a.h | 3 + src/include/86box/vid_svga.h | 4 +- src/include/86box/vid_svga_render.h | 1 + src/video/vid_8514a.c | 259 +++++++++++++++------------- src/video/vid_ati_mach8.c | 55 ++---- src/video/vid_cl54xx.c | 4 - src/video/vid_svga.c | 75 +++++++- 7 files changed, 234 insertions(+), 167 deletions(-) diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h index ce346e84d..fab504bbe 100644 --- a/src/include/86box/vid_8514a.h +++ b/src/include/86box/vid_8514a.h @@ -64,6 +64,9 @@ typedef struct ibm8514_t { int hwcursor_on; int modechange; + uint64_t dispontime; + uint64_t dispofftime; + struct { uint16_t subsys_cntl; uint16_t setup_md; diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 32bfbfd2f..624e85a1b 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -166,8 +166,10 @@ typedef struct svga_t { latch_t latch; pc_timer_t timer; + pc_timer_t timer8514; double clock; + double clock8514; hwcursor_t hwcursor; hwcursor_t hwcursor_latch; @@ -287,7 +289,7 @@ typedef struct svga_t { extern int vga_on; -extern void ibm8514_poll(void *priv, svga_t *svga); +extern void ibm8514_poll(void *priv); extern void ibm8514_recalctimings(svga_t *svga); extern uint8_t ibm8514_ramdac_in(uint16_t port, void *priv); extern void ibm8514_ramdac_out(uint16_t port, uint8_t val, void *priv); diff --git a/src/include/86box/vid_svga_render.h b/src/include/86box/vid_svga_render.h index 33bb13bbf..febb5f917 100644 --- a/src/include/86box/vid_svga_render.h +++ b/src/include/86box/vid_svga_render.h @@ -75,6 +75,7 @@ extern void svga_render_ABGR8888_highres(svga_t *svga); extern void svga_render_RGBA8888_lowres(svga_t *svga); extern void svga_render_RGBA8888_highres(svga_t *svga); +extern void ibm8514_render_blank(svga_t *svga); extern void ibm8514_render_8bpp(svga_t *svga); extern void ibm8514_render_15bpp(svga_t *svga); extern void ibm8514_render_16bpp(svga_t *svga); diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index fdbd39979..3505d1e0b 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -925,7 +925,7 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) if (!(port & 1)) { if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { dev->hsync_width = val; - dev->hblank_end_val = (dev->hblankstart + (dev->hsync_start & 0x1f) - 1) & 0x3f; + dev->hblank_end_val = (dev->hblankstart + (dev->hsync_width & 0x1f) - 1) & 0x3f; } } ibm8514_log("IBM 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); @@ -3831,6 +3831,25 @@ bitblt: } } +void +ibm8514_render_blank(svga_t *svga) +{ + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + if ((dev->displine + svga->y_add) < 0) + return; + + if (dev->firstline_draw == 2000) + dev->firstline_draw = dev->displine; + dev->lastline_draw = dev->displine; + + uint32_t *line_ptr = &svga->monitor->target_buffer->line[dev->displine + svga->y_add][svga->x_add]; + uint32_t line_width = (uint32_t)(dev->h_disp) * sizeof(uint32_t); + + if (dev->h_disp > 0) + memset(line_ptr, 0, line_width); +} + void ibm8514_render_8bpp(svga_t *svga) { @@ -4106,148 +4125,153 @@ ibm8514_render_overscan_right(ibm8514_t *dev, svga_t *svga) } void -ibm8514_poll(void *priv, svga_t *svga) +ibm8514_poll(void *priv) { - ibm8514_t *dev = (ibm8514_t *) priv; + svga_t *svga = (svga_t *)priv; + ibm8514_t *dev = (ibm8514_t *)svga->dev8514; uint32_t x; int wx; int wy; - if (!dev->linepos) { - if ((dev->displine == 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 + 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, svga->dispofftime); - svga->cgastat |= 1; - dev->linepos = 1; - - if (dev->dispon) { - dev->hdisp_on = 1; - - dev->ma &= dev->vram_mask; - - if (dev->firstline == 2000) { - dev->firstline = dev->displine; - video_wait_for_buffer_monitor(svga->monitor_index); + ibm8514_log("IBM 8514/A poll.\n"); + if (dev->on[0] || dev->on[1]) { + ibm8514_log("ON!\n"); + if (!dev->linepos) { + if ((dev->displine == 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->ma >> 12] = dev->changedvram[(dev->ma >> 12) + 1] = dev->interlace ? 3 : 2; + if ((dev->displine == (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->timer8514, dev->dispofftime); + svga->cgastat |= 1; + dev->linepos = 1; - svga->x_add = (overscan_x >> 1); - ibm8514_render_overscan_left(dev, svga); - ibm8514_render_overscan_right(dev, svga); - svga->x_add = (overscan_x >> 1); + 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_on--; - if (dev->hwcursor_on && dev->interlace) + dev->ma &= 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->ma >> 12] = dev->changedvram[(dev->ma >> 12) + 1] = dev->interlace ? 3 : 2; + + svga->render8514(svga); + + svga->x_add = (overscan_x >> 1); + ibm8514_render_overscan_left(dev, svga); + ibm8514_render_overscan_right(dev, svga); + svga->x_add = (overscan_x >> 1); + + if (dev->hwcursor_on) { + if (svga->hwcursor_draw) + svga->hwcursor_draw(svga, dev->displine + svga->y_add); 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 > 1500) - dev->displine = 0; - } else { - timer_advance_u64(&svga->timer, svga->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 > 1500) + dev->displine = 0; + } else { + timer_advance_u64(&svga->timer8514, dev->dispontime); + if (dev->dispon) + svga->cgastat &= ~1; + dev->hdisp_on = 0; - dev->linepos = 0; - if (dev->dispon) { - if (dev->sc == dev->rowcount) { - dev->sc = 0; - dev->maback += (dev->rowoffset << 3); - if (dev->interlace) + dev->linepos = 0; + if (dev->dispon) { + if (dev->sc == dev->rowcount) { + dev->sc = 0; dev->maback += (dev->rowoffset << 3); + if (dev->interlace) + dev->maback += (dev->rowoffset << 3); - dev->maback &= dev->vram_mask; - dev->ma = dev->maback; - } else { - dev->sc++; - dev->sc &= 0x1f; - dev->ma = dev->maback; - } - } - - dev->vc++; - dev->vc &= 0x7ff; - - if (dev->vc == dev->dispend) { - dev->dispon = 0; - - for (x = 0; x < ((dev->vram_mask + 1) >> 12); x++) { - if (dev->changedvram[x]) - dev->changedvram[x]--; + dev->maback &= dev->vram_mask; + dev->ma = dev->maback; + } else { + dev->sc++; + dev->sc &= 0x1f; + dev->ma = dev->maback; + } } - 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 &= 0x7ff; - if (dev->interlace && !dev->oddeven) - dev->lastline++; - if (dev->interlace && dev->oddeven) - dev->firstline--; + if (dev->vc == dev->dispend) { + 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->ma = dev->maback = (dev->rowoffset << 1); - else - dev->ma = dev->maback = 0; + dev->firstline_draw = 2000; + dev->lastline_draw = 0; - dev->ma = (dev->ma << 2); - dev->maback = (dev->maback << 2); - } - if (dev->vc == dev->v_total) { - dev->vc = 0; - dev->sc = 0; - dev->dispon = 1; - dev->displine = (dev->interlace && dev->oddeven) ? 1 : 0; + dev->oddeven ^= 1; - svga->x_add = (overscan_x >> 1); + 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->ma = dev->maback = (dev->rowoffset << 1); + else + dev->ma = dev->maback = 0; + + dev->ma = (dev->ma << 2); + dev->maback = (dev->maback << 2); + } + if (dev->vc == dev->v_total) { + dev->vc = 0; + dev->sc = 0; + dev->dispon = 1; + dev->displine = (dev->interlace && dev->oddeven) ? 1 : 0; + + svga->x_add = (overscan_x >> 1); + + dev->hwcursor_on = 0; + dev->hwcursor_latch = dev->hwcursor; + } } } } @@ -4257,6 +4281,7 @@ ibm8514_recalctimings(svga_t *svga) { ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + svga->render8514 = ibm8514_render_blank; #ifdef ATI_8514_ULTRA if (dev->extensions) { if (svga->ext8514 != NULL) @@ -4283,14 +4308,14 @@ ibm8514_recalctimings(svga_t *svga) dev->h_disp = 1024; dev->dispend = 768; } - svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0; } else { dev->pitch = 640; if (!dev->h_disp) { dev->h_disp = 640; dev->dispend = 480; } - svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; } if (dev->interlace) { @@ -4429,6 +4454,8 @@ ibm8514_init(const device_t *info) } #endif + timer_add(&svga->timer8514, ibm8514_poll, svga, 0); + return svga; } diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index ff6024677..5628e149a 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2485,9 +2485,6 @@ ati8514_recalctimings(svga_t *svga) { const mach_t *mach = (mach_t *) svga->ext8514; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; - uint32_t dot; - uint32_t adj_dot; - uint32_t eff_mask; mach_log("ON0=%d, ON1=%d, vgahdisp=%d.\n", dev->on[0], dev->on[1], svga->hdisp); if (dev->on[0] || dev->on[1]) { @@ -2530,27 +2527,6 @@ ati8514_recalctimings(svga_t *svga) mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, advfunc_cntl=%x, shadow=%x.\n", dev->accel.advfunc_cntl & 4, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, dev->accel.advfunc_cntl & 4, mach->shadow_set & 3); svga->map8 = dev->pallook; svga->render8514 = ibm8514_render_8bpp; - - dot = svga->hblankstart; - adj_dot = svga->hblankstart; - eff_mask = 0x0000003f; - dev->hblank_sub = 0; - - while (1) { - if (dot == dev->h_total) - dot = 0; - - if (adj_dot >= dev->h_total) - dev->hblank_sub++; - - if ((dot & 0x0000003f) == (svga->hblank_end_val & 0x0000003f)) - break; - - dot++; - adj_dot++; - } - - dev->h_disp -= dev->hblank_sub); } else { if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ if (svga->seqregs[1] & 8) { /*40 column*/ @@ -2615,6 +2591,8 @@ mach_recalctimings(svga_t *svga) } else svga->ati_4color = 0; } + + svga->render8514 = ibm8514_render_blank; mach_log("ON[0]=%d, ON[1]=%d, exton[0]=%d, exton[1]=%d, vendormode0=%d, vendormode1=%d.\n", dev->on[0], dev->on[1], mach->ext_on[0], mach->ext_on[1], dev->vendor_mode[0], dev->vendor_mode[1]); if (dev->on[0] || dev->on[1]) { mach_log("8514/A ON.\n"); @@ -2639,14 +2617,14 @@ mach_recalctimings(svga_t *svga) if ((dev->local & 0xff) >= 0x02) { if ((dev->accel.advfunc_cntl ^ dev->modechange) & 0x04) { if ((mach->shadow_set ^ mach->compat_mode) & 0x03) - svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); else - svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0; } else { if ((mach->shadow_set ^ mach->compat_mode) & 0x03) - svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); else - svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; } if (dev->interlace) { @@ -2706,13 +2684,13 @@ mach_recalctimings(svga_t *svga) } switch (mach->regs[0xb8] & 0xc0) { case 0x40: - svga->clock *= 2; + svga->clock8514 *= 2; break; case 0x80: - svga->clock *= 3; + svga->clock8514 *= 3; break; case 0xc0: - svga->clock *= 4; + svga->clock8514 *= 4; break; default: @@ -2721,21 +2699,20 @@ mach_recalctimings(svga_t *svga) } else { if ((dev->accel.advfunc_cntl ^ dev->modechange) & 0x04) { if ((mach->shadow_set ^ mach->compat_mode) & 0x03) - svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); else - svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0; } else { if ((mach->shadow_set ^ mach->compat_mode) & 0x03) - svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); else - svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; if (((mach->shadow_set & 0x03) != 0x02) || !(dev->accel.advfunc_cntl & 0x04)) { /*Shadow set of 2 and bit 2 of port 0x4ae8 mean 1024x768+*/ if (!(mach->accel.clock_sel & 0x01)) { dev->h_disp = 640; dev->dispend = 480; } - dev->interlace = 0; } } @@ -2754,7 +2731,7 @@ mach_recalctimings(svga_t *svga) svga->map8 = dev->pallook; svga->render8514 = ibm8514_render_8bpp; if (mach->regs[0xb8] & 0x40) - svga->clock *= 2; + svga->clock8514 *= 2; } } @@ -3670,7 +3647,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 if (!(port & 1)) { if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { dev->hsync_width = val; - dev->hblank_end_val = (dev->hblankstart + (dev->hsync_start & 0x1f) - 1) & 0x3f; + dev->hblank_end_val = (dev->hblankstart + (dev->hsync_width & 0x1f) - 1) & 0x3f; } } mach_log("ATI 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); @@ -6080,6 +6057,8 @@ mach8_init(const device_t *info) } else ati_eeprom_load_mach8(&mach->eeprom, "mach8.nvr"); + timer_add(&svga->timer8514, ibm8514_poll, svga, 0); + return mach; } diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 7ae985e95..49899b7b4 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -1643,10 +1643,6 @@ gd54xx_recalc_banking(gd54xx_t *gd54xx) svga->extra_banks[1] = svga->extra_banks[0] + 0x8000; } - if (!(svga->gdcreg[5] & 0x40) || !(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) { - svga->extra_banks[0] = 0; - svga->extra_banks[1] = 0x8000; - } svga->write_bank = svga->read_bank = svga->extra_banks[0]; } diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index a1ab605ea..d982a1ada 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -222,6 +222,7 @@ svga_out(uint16_t addr, uint8_t val, void *priv) svga_log("3C3: VGA ON = %d.\n", val & 0x01); vga_on = val & 0x01; + svga_recalctimings(svga); break; case 0x3c4: svga->seqaddr = val; @@ -567,11 +568,15 @@ svga_set_ramdac_type(svga_t *svga, int type) void svga_recalctimings(svga_t *svga) { - const ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; double crtcconst; double _dispontime; double _dispofftime; double disptime; + double crtcconst8514; + double _dispontime8514; + double _dispofftime8514; + double disptime8514; #ifdef ENABLE_SVGA_LOG int vsyncend; int vblankend; @@ -805,6 +810,31 @@ svga_recalctimings(svga_t *svga) } svga->hdisp -= (svga->hblank_sub * svga->dots_per_clock); + + if (ibm8514_active && (svga->dev8514 != NULL)) { + if (dev->on[0] || dev->on[1]) { + uint32_t dot8514 = dev->h_blankstart; + uint32_t adj_dot8514 = dev->h_blankstart; + uint32_t eff_mask8514 = 0x0000003f; + dev->hblank_sub = 0; + + while (1) { + if (dot8514 == dev->h_total) + dot = 0; + + if (adj_dot8514 >= dev->h_total) + dev->hblank_sub++; + + if ((dot8514 & eff_mask8514) == (dev->h_blank_end_val & eff_mask8514)) + break; + + dot8514++; + adj_dot8514++; + } + + dev->h_disp -= dev->hblank_sub; + } + } } if (svga->hdisp >= 2048) @@ -817,6 +847,10 @@ svga_recalctimings(svga_t *svga) svga->dispend = svga->vblankstart; crtcconst = svga->clock * svga->char_width; + if (ibm8514_active && (svga->dev8514 != NULL)) { + if (dev->on[0] || dev->on[1]) + crtcconst8514 = svga->clock8514; + } #ifdef ENABLE_SVGA_LOG vsyncend = (svga->vsyncstart & 0xfffffff0) | (svga->crtc[0x11] & 0x0f); @@ -858,6 +892,13 @@ svga_recalctimings(svga_t *svga) disptime = svga->htotal; _dispontime = svga->hdisp_time; + if (ibm8514_active && (svga->dev8514 != NULL)) { + if (dev->on[0] || dev->on[1]) { + disptime8514 = dev->htotal; + _dispontime8514 = dev->hdisped; + } + } + if (svga->seqregs[1] & 8) { disptime *= 2; _dispontime *= 2; @@ -874,6 +915,27 @@ svga_recalctimings(svga_t *svga) if (svga->dispofftime < TIMER_USEC) svga->dispofftime = TIMER_USEC; + if (ibm8514_active && (svga->dev8514 != NULL)) { + if (dev->on[0] || dev->on[1]) { + _dispofftime8514 = disptime8514 - _dispontime8514; + _dispontime8514 *= crtcconst8514; + _dispofftime8514 *= crtcconst8514; + + dev->dispontime = (uint64_t) (_dispontime8514); + dev->dispofftime = (uint64_t) (_dispofftime8514); + if (dev->dispontime < TIMER_USEC) + dev->dispontime = TIMER_USEC; + if (dev->dispofftime < TIMER_USEC) + dev->dispofftime = TIMER_USEC; + + timer_disable(&svga->timer); + timer_enable(&svga->timer8514); + } else { + timer_disable(&svga->timer8514); + timer_enable(&svga->timer); + } + } + if (!svga->force_old_addr) svga_recalc_remap_func(svga); @@ -946,10 +1008,6 @@ svga_poll(void *priv) int old_ma; if (!svga->override) { - if (ibm8514_active && dev && (dev->on[0] || dev->on[1])) { - ibm8514_poll(dev, svga); - return; - } if (xga_active && xga && xga->on) { if ((xga->disp_cntl_2 & 7) >= 2) { xga_poll(xga, svga); @@ -1347,9 +1405,10 @@ svga_decode_addr(svga_t *svga, uint32_t addr, int write) } if (memory_map_mode <= 1) { - if (svga->adv_flags & FLAG_EXTRA_BANKS) - addr = (addr & 0x17fff) + svga->extra_banks[(addr >> 15) & 1]; - else { + if (svga->adv_flags & FLAG_EXTRA_BANKS) { + if ((svga->gdcreg[5] & 0x40) || svga->packed_chain4) + addr = (addr & 0x17fff) + svga->extra_banks[(addr >> 15) & 1]; + } else { if (write) addr += svga->write_bank; else From f8647f07a318adbd15fd0d9dfa5d96a9c8133ea4 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 7 Feb 2024 03:06:19 +0100 Subject: [PATCH 459/936] Mach64 temporary updates: Temporarily replace the ATI68860 8bpp renderer with a clone one while the current renderer (8bpp) is being fixed for proper colors on the Mach64. --- src/include/86box/vid_svga_render.h | 2 +- src/video/vid_ati68860_ramdac.c | 9 ++++++--- src/video/vid_svga_render.c | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/include/86box/vid_svga_render.h b/src/include/86box/vid_svga_render.h index febb5f917..224d96c8e 100644 --- a/src/include/86box/vid_svga_render.h +++ b/src/include/86box/vid_svga_render.h @@ -53,7 +53,7 @@ extern void svga_render_4bpp_lowres(svga_t *svga); extern void svga_render_4bpp_highres(svga_t *svga); extern void svga_render_8bpp_lowres(svga_t *svga); extern void svga_render_8bpp_highres(svga_t *svga); -extern void svga_render_8bpp_incompatible_highres(svga_t *svga); +extern void svga_render_8bpp_clone_highres(svga_t *svga); extern void svga_render_8bpp_tseng_lowres(svga_t *svga); extern void svga_render_8bpp_tseng_highres(svga_t *svga); extern void svga_render_8bpp_gs_lowres(svga_t *svga); diff --git a/src/video/vid_ati68860_ramdac.c b/src/video/vid_ati68860_ramdac.c index 2cb0c4c98..ac2a0f7cb 100644 --- a/src/video/vid_ati68860_ramdac.c +++ b/src/video/vid_ati68860_ramdac.c @@ -130,7 +130,8 @@ ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga) ramdac->render = svga_render_4bpp_highres; break; case 0x83: - ramdac->render = svga_render_8bpp_highres; + /*FIXME*/ + ramdac->render = svga_render_8bpp_clone_highres; break; case 0xa0: case 0xb0: @@ -155,7 +156,8 @@ ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga) ramdac->render = svga_render_RGBA8888_highres; break; default: - ramdac->render = svga_render_8bpp_highres; + /*FIXME*/ + ramdac->render = svga_render_8bpp_clone_highres; break; } break; @@ -235,7 +237,8 @@ ati68860_ramdac_init(UNUSED(const device_t *info)) ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) malloc(sizeof(ati68860_ramdac_t)); memset(ramdac, 0, sizeof(ati68860_ramdac_t)); - ramdac->render = svga_render_8bpp_highres; + /*FIXME*/ + ramdac->render = svga_render_8bpp_clone_highres; return ramdac; } diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 5a2728f8a..9b395ea6c 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -717,7 +717,7 @@ void svga_render_8bpp_lowres(svga_t *svga) { svga_render_indexed_gfx(svga, false void svga_render_8bpp_highres(svga_t *svga) { svga_render_indexed_gfx(svga, true, true); } void -svga_render_8bpp_incompatible_highres(svga_t *svga) +svga_render_8bpp_clone_highres(svga_t *svga) { int x; uint32_t *p; From 2da7b196ac1609fc2bafb4ccd24b147dd040de87 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Thu, 25 Jan 2024 18:06:47 +0500 Subject: [PATCH 460/936] Rename unnamed MSR vars to real names where known --- src/cpu/cpu.c | 69 +++++++++++++++++++++++++++++++-------------------- src/cpu/cpu.h | 29 ++++++++++++---------- 2 files changed, 58 insertions(+), 40 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index e05ec0d9c..7322ad89d 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -2717,8 +2717,8 @@ cpu_RDMSR(void) EDX = tsc >> 32; break; case 0x00000083: - EAX = msr.ecx83 & 0xffffffff; - EDX = msr.ecx83 >> 32; + EAX = msr.amd_hwcr & 0xffffffff; + EDX = msr.amd_hwcr >> 32; break; case 0xc0000080: EAX = msr.amd_efer & 0xffffffff; @@ -2868,15 +2868,15 @@ amd_k_invalid_rdmsr: } break; case 0x79: - EAX = msr.ecx79 & 0xffffffff; - EDX = msr.ecx79 >> 32; + EAX = msr.bios_updt & 0xffffffff; + EDX = msr.bios_updt >> 32; break; case 0x88: case 0x89: case 0x8a: case 0x8b: - EAX = msr.ecx8x[ECX - 0x88] & 0xffffffff; - EDX = msr.ecx8x[ECX - 0x88] >> 32; + EAX = msr.bbl_cr_dx[ECX - 0x88] & 0xffffffff; + EDX = msr.bbl_cr_dx[ECX - 0x88] >> 32; break; case 0xc1: case 0xc2: @@ -2894,19 +2894,28 @@ amd_k_invalid_rdmsr: EDX = msr.mtrr_cap >> 32; break; case 0x116: - EAX = msr.ecx116 & 0xffffffff; - EDX = msr.ecx116 >> 32; + EAX = msr.bbl_cr_addr & 0xffffffff; + EDX = msr.bbl_cr_addr >> 32; break; case 0x118: + EAX = msr.bbl_cr_decc & 0xffffffff; + EDX = msr.bbl_cr_decc >> 32; + break; case 0x119: + EAX = msr.bbl_cr_ctl & 0xffffffff; + EDX = msr.bbl_cr_ctl >> 32; + break; case 0x11a: + EAX = msr.bbl_cr_trig & 0xffffffff; + EDX = msr.bbl_cr_trig >> 32; + break; case 0x11b: - EAX = msr.ecx11x[ECX - 0x118] & 0xffffffff; - EDX = msr.ecx11x[ECX - 0x118] >> 32; + EAX = msr.bbl_cr_busy & 0xffffffff; + EDX = msr.bbl_cr_busy >> 32; break; case 0x11e: - EAX = msr.ecx11e & 0xffffffff; - EDX = msr.ecx11e >> 32; + EAX = msr.bbl_cr_ctl3 & 0xffffffff; + EDX = msr.bbl_cr_ctl3 >> 32; break; case 0x174: if (cpu_s->cpu_type == CPU_PENTIUMPRO) @@ -2941,20 +2950,20 @@ amd_k_invalid_rdmsr: EDX = msr.mcg_ctl >> 32; break; case 0x186: - EAX = msr.ecx186 & 0xffffffff; - EDX = msr.ecx186 >> 32; + EAX = msr.evntsel0 & 0xffffffff; + EDX = msr.evntsel0 >> 32; break; case 0x187: - EAX = msr.ecx187 & 0xffffffff; - EDX = msr.ecx187 >> 32; + EAX = msr.evntsel1 & 0xffffffff; + EDX = msr.evntsel1 >> 32; break; case 0x1d9: EAX = msr.debug_ctl & 0xffffffff; EDX = msr.debug_ctl >> 32; break; case 0x1e0: - EAX = msr.ecx1e0 & 0xffffffff; - EDX = msr.ecx1e0 >> 32; + EAX = msr.rob_cr_bkuptmpdr6 & 0xffffffff; + EDX = msr.rob_cr_bkuptmpdr6 >> 32; break; case 0x200: case 0x201: @@ -3207,7 +3216,7 @@ cpu_WRMSR(void) tsc = EAX | ((uint64_t) EDX << 32); break; case 0x83: - msr.ecx83 = EAX | ((uint64_t) EDX << 32); + msr.amd_hwcr = EAX | ((uint64_t) EDX << 32); break; case 0xc0000080: temp = EAX | ((uint64_t) EDX << 32); @@ -3319,13 +3328,13 @@ amd_k_invalid_wrmsr: case 0x2a: break; case 0x79: - msr.ecx79 = EAX | ((uint64_t) EDX << 32); + msr.bios_updt = EAX | ((uint64_t) EDX << 32); break; case 0x88: case 0x89: case 0x8a: case 0x8b: - msr.ecx8x[ECX - 0x88] = EAX | ((uint64_t) EDX << 32); + msr.bbl_cr_dx[ECX - 0x88] = EAX | ((uint64_t) EDX << 32); break; case 0xc1: case 0xc2: @@ -3341,16 +3350,22 @@ amd_k_invalid_wrmsr: msr.mtrr_cap = EAX | ((uint64_t) EDX << 32); break; case 0x116: - msr.ecx116 = EAX | ((uint64_t) EDX << 32); + msr.bbl_cr_addr = EAX | ((uint64_t) EDX << 32); break; case 0x118: + msr.bbl_cr_decc = EAX | ((uint64_t) EDX << 32); + break; case 0x119: + msr.bbl_cr_ctl = EAX | ((uint64_t) EDX << 32); + break; case 0x11a: + msr.bbl_cr_trig = EAX | ((uint64_t) EDX << 32); + break; case 0x11b: - msr.ecx11x[ECX - 0x118] = EAX | ((uint64_t) EDX << 32); + msr.bbl_cr_busy = EAX | ((uint64_t) EDX << 32); break; case 0x11e: - msr.ecx11e = EAX | ((uint64_t) EDX << 32); + msr.bbl_cr_ctl3 = EAX | ((uint64_t) EDX << 32); break; case 0x174: if (cpu_s->cpu_type == CPU_PENTIUMPRO) @@ -3380,16 +3395,16 @@ amd_k_invalid_wrmsr: msr.mcg_ctl = EAX | ((uint64_t) EDX << 32); break; case 0x186: - msr.ecx186 = EAX | ((uint64_t) EDX << 32); + msr.evntsel0 = EAX | ((uint64_t) EDX << 32); break; case 0x187: - msr.ecx187 = EAX | ((uint64_t) EDX << 32); + msr.evntsel1 = EAX | ((uint64_t) EDX << 32); break; case 0x1d9: msr.debug_ctl = EAX | ((uint64_t) EDX << 32); break; case 0x1e0: - msr.ecx1e0 = EAX | ((uint64_t) EDX << 32); + msr.rob_cr_bkuptmpdr6 = EAX | ((uint64_t) EDX << 32); break; case 0x200: case 0x201: diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 8e378ebce..24b365693 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -239,15 +239,15 @@ typedef struct { like a real Deschutes does. */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecx79; /* 0x00000079 */ + uint64_t bios_updt; /* 0x00000079 */ /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t ecx83; /* 0x00000083 - AMD K5 and K6 MSR's. */ + uint64_t amd_hwcr; /* 0x00000083 - AMD K5 and K6 MSR's. */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecx8x[4]; /* 0x00000088 - 0x0000008b */ - uint64_t ia32_pmc[8]; /* 0x000000c1 - 0x000000c8 */ - uint64_t mtrr_cap; /* 0x000000fe */ + uint64_t bbl_cr_dx[4]; /* 0x00000088 - 0x0000008b */ + uint64_t ia32_pmc[8]; /* 0x000000c1 - 0x000000c8 */ + uint64_t mtrr_cap; /* 0x000000fe */ /* IDT WinChip and WinChip 2 MSR's that are also on the VIA Cyrix III */ uint32_t fcr; /* 0x00000107 (IDT), 0x00001107 (VIA) */ @@ -255,9 +255,12 @@ typedef struct { uint64_t fcr3; /* 0x00000108 (IDT), 0x00001108 (VIA) */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecx116; /* 0x00000116 */ - uint64_t ecx11x[4]; /* 0x00000118 - 0x0000011b */ - uint64_t ecx11e; /* 0x0000011e */ + uint64_t bbl_cr_addr; /* 0x00000116 */ + uint64_t bbl_cr_decc; /* 0x00000118 */ + uint64_t bbl_cr_ctl; /* 0x00000119 */ + uint64_t bbl_cr_trig; /* 0x0000011a */ + uint64_t bbl_cr_busy; /* 0x0000011b */ + uint64_t bbl_cr_ctl3; /* 0x0000011e */ /* Pentium II Klamath and Pentium II Deschutes MSR's */ uint16_t sysenter_cs; /* 0x00000174 - SYSENTER/SYSEXIT MSR's */ @@ -265,13 +268,13 @@ typedef struct { uint32_t sysenter_eip; /* 0x00000176 - SYSENTER/SYSEXIT MSR's */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t mcg_ctl; /* 0x0000017b - Machine Check Architecture */ - uint64_t ecx186; /* 0x00000186, 0x00000187 */ - uint64_t ecx187; /* 0x00000186, 0x00000187 */ + uint64_t mcg_ctl; /* 0x0000017b - Machine Check Architecture */ + uint64_t evntsel0; /* 0x00000186 */ + uint64_t evntsel1; /* 0x00000187 */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t debug_ctl; /* 0x000001d9 - Debug Registers Control */ - uint64_t ecx1e0; /* 0x000001e0 */ + uint64_t debug_ctl; /* 0x000001d9 - Debug Registers Control */ + uint64_t rob_cr_bkuptmpdr6; /* 0x000001e0 */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's that are also on the VIA Cyrix III */ From 032a161c4acc4214c3457a12b4b793fd665bc95e Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 26 Jan 2024 16:58:45 +0500 Subject: [PATCH 461/936] Implement IDT/VIA FCR2 CPUID family/model spoofing --- src/cpu/cpu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 7322ad89d..b76e56077 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1961,7 +1961,7 @@ cpu_CPUID(void) EDX = 0x48727561; } } else if (EAX == 1) { - EAX = 0x540; + EAX = ((msr.fcr2 & 0x0ff0) ? ((msr.fcr2 & 0x0ff0) | (CPUID & 0xf00f)) : CPUID); EBX = ECX = 0; EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; if (cpu_has_feature(CPU_FEATURE_CX8)) @@ -1987,7 +1987,7 @@ cpu_CPUID(void) } break; case 1: - EAX = CPUID; + EAX = ((msr.fcr2 & 0x0ff0) ? ((msr.fcr2 & 0x0ff0) | (CPUID & 0xf00f)) : CPUID); EBX = ECX = 0; EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; if (cpu_has_feature(CPU_FEATURE_CX8)) @@ -2464,7 +2464,7 @@ cpu_CPUID(void) } break; case 1: - EAX = CPUID; + EAX = ((msr.fcr2 & 0x0ff0) ? ((msr.fcr2 & 0x0ff0) | (CPUID & 0xf00f)) : CPUID); EBX = ECX = 0; EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_MMX | CPUID_MTRR; if (cpu_has_feature(CPU_FEATURE_CX8)) From a1540eee92e2bb81208a97d77edf697124cde001 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 26 Jan 2024 17:02:22 +0500 Subject: [PATCH 462/936] Remove the machine check CPUID flag from the P24T --- src/cpu/cpu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index b76e56077..ce549b798 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -2038,7 +2038,9 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + if (cpu_s->cpu_type != CPU_P24T) + EDX |= CPUID_MCE; } else EAX = EBX = ECX = EDX = 0; break; From 37cf0b684538d423dc734dd7c1f39b1c382d5203 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 26 Jan 2024 22:06:05 +0500 Subject: [PATCH 463/936] Separate Pentium and Cx6x86 MSR handling --- src/cpu/cpu.c | 60 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index ce549b798..027c6de13 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -2782,14 +2782,7 @@ amd_k_invalid_rdmsr: case CPU_P24T: case CPU_PENTIUM: case CPU_PENTIUMMMX: -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - case CPU_Cx6x86: - case CPU_Cx6x86L: - case CPU_CxGX1: - case CPU_Cx6x86MX: - if (cpu_s->cpu_type < CPU_Cx6x86) -#endif - EAX = EDX = 0; + EAX = EDX = 0; switch (ECX) { case 0x00: case 0x01: @@ -2802,6 +2795,24 @@ amd_k_invalid_rdmsr: cpu_log("RDMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); break; +#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) + case CPU_Cx6x86: + case CPU_Cx6x86L: + case CPU_CxGX1: + case CPU_Cx6x86MX: + switch (ECX) { + case 0x00: + case 0x01: + break; + case 0x10: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + } + cpu_log("RDMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); + break; +#endif + case CPU_PENTIUMPRO: case CPU_PENTIUM2: case CPU_PENTIUM2D: @@ -3276,12 +3287,6 @@ amd_k_invalid_wrmsr: case CPU_P24T: case CPU_PENTIUM: case CPU_PENTIUMMMX: -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - case CPU_Cx6x86: - case CPU_Cx6x86L: - case CPU_CxGX1: - case CPU_Cx6x86MX: -#endif cpu_log("WRMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); switch (ECX) { case 0x00: @@ -3291,18 +3296,29 @@ amd_k_invalid_wrmsr: tsc = EAX | ((uint64_t) EDX << 32); break; case 0x8b: -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - if (cpu_s->cpu_type < CPU_Cx6x86) { -#endif - cpu_log("WRMSR: Invalid MSR: 0x8B\n"); - x86gpf(NULL, 0); /* Needed for Vista to correctly break on Pentium */ -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - } -#endif + cpu_log("WRMSR: Invalid MSR: 0x8B\n"); + x86gpf(NULL, 0); /* Needed for Vista to correctly break on Pentium */ break; } break; +#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) + case CPU_Cx6x86: + case CPU_Cx6x86L: + case CPU_CxGX1: + case CPU_Cx6x86MX: + cpu_log("WRMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); + switch (ECX) { + case 0x00: + case 0x01: + break; + case 0x10: + tsc = EAX | ((uint64_t) EDX << 32); + break; + } + break; +#endif + case CPU_PENTIUMPRO: case CPU_PENTIUM2: case CPU_PENTIUM2D: From aef257378ef8bab586ef493973100e87adaf3732 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 29 Jan 2024 23:37:31 +0500 Subject: [PATCH 464/936] Add PGE to AMD K5 and K6-2C/III/2+/III+ --- src/cpu/cpu.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 027c6de13..f00f7227a 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -57,12 +57,15 @@ enum { CPUID_FPU = (1 << 0), CPUID_VME = (1 << 1), + CPUID_DE = (1 << 2), CPUID_PSE = (1 << 3), CPUID_TSC = (1 << 4), CPUID_MSR = (1 << 5), CPUID_PAE = (1 << 6), CPUID_MCE = (1 << 7), CPUID_CMPXCHG8B = (1 << 8), + CPUID_APIC = (1 << 9), + CPUID_AMDPGE = (1 << 9), CPUID_AMDSEP = (1 << 10), CPUID_SEP = (1 << 11), CPUID_MTRR = (1 << 12), @@ -1605,11 +1608,16 @@ cpu_set(void) cpu_CR4_mask |= (CR4_VME | CR4_PVI | CR4_PSE); if (cpu_s->cpu_type <= CPU_K6) cpu_CR4_mask |= CR4_PCE; - } + else if (cpu_s->cpu_type >= CPU_K6_2C) + cpu_CR4_mask |= CR4_PGE; + } else + cpu_CR4_mask |= CR4_PGE; #else cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; if (cpu_s->cpu_type == CPU_K6) cpu_CR4_mask |= CR4_PCE; + else if (cpu_s->cpu_type >= CPU_K6_2C) + cpu_CR4_mask |= CR4_PGE; #endif #ifdef USE_DYNAREC @@ -2055,7 +2063,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDPGE; } else EAX = EBX = ECX = EDX = 0; break; @@ -2069,14 +2077,14 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE; } else if (EAX == 0x80000000) { EAX = 0x80000005; EBX = ECX = EDX = 0; } else if (EAX == 0x80000001) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE; } else if (EAX == 0x80000002) { EAX = 0x2D444D41; EBX = 0x7428354B; @@ -2154,6 +2162,8 @@ cpu_CPUID(void) EAX = CPUID; EBX = ECX = 0; EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; + if (cpu_s->cpu_type == CPU_K6_2C) + EDX |= CPUID_PGE; break; case 0x80000000: EAX = 0x80000005; @@ -2163,6 +2173,8 @@ cpu_CPUID(void) EAX = CPUID + 0x100; EBX = ECX = 0; EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; + if (cpu_s->cpu_type == CPU_K6_2C) + EDX |= CPUID_PGE; break; case 0x80000002: /* Processor name string */ EAX = 0x2d444d41; /* AMD-K6(tm) 3D pr */ @@ -2199,7 +2211,7 @@ cpu_CPUID(void) case 1: EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE | CPUID_MMX; break; case 0x80000000: EAX = 0x80000006; @@ -2208,7 +2220,7 @@ cpu_CPUID(void) case 0x80000001: EAX = CPUID + 0x100; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_PGE | CPUID_MMX | CPUID_3DNOW; break; case 0x80000002: /* Processor name string */ EAX = 0x2d444d41; /* AMD-K6(tm) 3D+ P */ @@ -2250,7 +2262,7 @@ cpu_CPUID(void) case 1: EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE | CPUID_MMX; break; case 0x80000000: EAX = 0x80000007; @@ -2259,7 +2271,7 @@ cpu_CPUID(void) case 0x80000001: EAX = CPUID + 0x100; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW | CPUID_3DNOWE; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_PGE | CPUID_3DNOW | CPUID_3DNOWE; break; case 0x80000002: /* Processor name string */ EAX = 0x2d444d41; /* AMD-K6(tm)-III P */ From 963525ff2e81deb6431bdbce154f1c1318b5fd18 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 29 Jan 2024 23:42:37 +0500 Subject: [PATCH 465/936] Correct the CPUID SEP bit on AMD K6-2 and later They use the standard bit 11, not he AMD-specific bit 10 --- src/cpu/cpu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index f00f7227a..bf36b119d 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -2172,7 +2172,7 @@ cpu_CPUID(void) case 0x80000001: EAX = CPUID + 0x100; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_MMX | CPUID_3DNOW; if (cpu_s->cpu_type == CPU_K6_2C) EDX |= CPUID_PGE; break; @@ -2220,7 +2220,7 @@ cpu_CPUID(void) case 0x80000001: EAX = CPUID + 0x100; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_PGE | CPUID_MMX | CPUID_3DNOW; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_PGE | CPUID_MMX | CPUID_3DNOW; break; case 0x80000002: /* Processor name string */ EAX = 0x2d444d41; /* AMD-K6(tm) 3D+ P */ @@ -2271,7 +2271,7 @@ cpu_CPUID(void) case 0x80000001: EAX = CPUID + 0x100; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_PGE | CPUID_3DNOW | CPUID_3DNOWE; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_MMX | CPUID_PGE | CPUID_3DNOW | CPUID_3DNOWE; break; case 0x80000002: /* Processor name string */ EAX = 0x2d444d41; /* AMD-K6(tm)-III P */ From 1bb31f39378f3c93d2f3f82b323ad9fb921595ef Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 29 Jan 2024 23:44:26 +0500 Subject: [PATCH 466/936] Remove the AP61 hack completely It's no longer needed --- src/cpu/cpu.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index bf36b119d..45ea87b98 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -2391,20 +2391,14 @@ cpu_CPUID(void) EBX = ECX = 0; EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_CMOV; } else if (EAX == 2) { - /* if (!strcmp(machine_get_internal_name(), "ap61")) { - EAX = 0x00000001; - EDX = 0x00000000; - } else */ { - EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries - Instruction TLB: 4 MB pages, fully associative, 2 entries - Data TLB: 4 KB pages, 4-way set associative, 64 entries */ - EDX = 0x06040a42; /* 2nd-level cache: 256 KB, 4-way set associative, 32-byte line size - 1st-level data cache: 8 KB, 2-way set associative, 32-byte line size - Data TLB: 4 MB pages, 4-way set associative, 8 entries - 1st-level instruction cache:8 KB, 4-way set associative, 32-byte line size */ - } - + EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries + Instruction TLB: 4 MB pages, fully associative, 2 entries + Data TLB: 4 KB pages, 4-way set associative, 64 entries */ EBX = ECX = 0; + EDX = 0x06040a42; /* 2nd-level cache: 256 KB, 4-way set associative, 32-byte line size + 1st-level data cache: 8 KB, 2-way set associative, 32-byte line size + Data TLB: 4 MB pages, 4-way set associative, 8 entries + 1st-level instruction cache: 8 KB, 4-way set associative, 32-byte line size */ } else EAX = EBX = ECX = EDX = 0; break; From b86015635092be623abc105353a489e87357502f Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 31 Jan 2024 13:45:04 +0500 Subject: [PATCH 467/936] Remove an accidentally committed duplicate file --- src/cpu/x886seg_2386.c | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 src/cpu/x886seg_2386.c diff --git a/src/cpu/x886seg_2386.c b/src/cpu/x886seg_2386.c deleted file mode 100644 index 335c757e4..000000000 --- a/src/cpu/x886seg_2386.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * x86 CPU segment emulation for the 286/386 interpreter. - * - * - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#ifndef OPS_286_386 -# define OPS_286_386 -#endif -#include "x86seg.c" From 1e4455d98cecf86b140ebdd53c8104a367b72340 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Thu, 1 Feb 2024 18:34:58 +0500 Subject: [PATCH 468/936] Add comments with MSR and CPUID flag names Reorganize the MSR struct --- src/cpu/386_common.c | 6 +- src/cpu/cpu.c | 377 ++++++++++++++++++++++++++----------------- src/cpu/cpu.h | 120 ++++++-------- 3 files changed, 276 insertions(+), 227 deletions(-) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 4b4037207..f9ca3408d 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -128,9 +128,9 @@ uint32_t addr64a_2[8]; static pc_timer_t *cpu_fast_off_timer = NULL; static double cpu_fast_off_period = 0.0; -#define AMD_SYSCALL_EIP (msr.star & 0xFFFFFFFF) -#define AMD_SYSCALL_SB ((msr.star >> 32) & 0xFFFF) -#define AMD_SYSRET_SB ((msr.star >> 48) & 0xFFFF) +#define AMD_SYSCALL_EIP (msr.amd_star & 0xFFFFFFFF) +#define AMD_SYSCALL_SB ((msr.amd_star >> 32) & 0xFFFF) +#define AMD_SYSRET_SB ((msr.amd_star >> 48) & 0xFFFF) /* These #define's and enum have been borrowed from Bochs. */ /* SMM feature masks */ diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 45ea87b98..5a68ecf38 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -55,30 +55,31 @@ #define CCR3_NMI_EN (1 << 1) enum { - CPUID_FPU = (1 << 0), - CPUID_VME = (1 << 1), - CPUID_DE = (1 << 2), - CPUID_PSE = (1 << 3), - CPUID_TSC = (1 << 4), - CPUID_MSR = (1 << 5), - CPUID_PAE = (1 << 6), - CPUID_MCE = (1 << 7), - CPUID_CMPXCHG8B = (1 << 8), - CPUID_APIC = (1 << 9), - CPUID_AMDPGE = (1 << 9), - CPUID_AMDSEP = (1 << 10), - CPUID_SEP = (1 << 11), - CPUID_MTRR = (1 << 12), - CPUID_PGE = (1 << 13), - CPUID_MCA = (1 << 14), - CPUID_CMOV = (1 << 15), - CPUID_MMX = (1 << 23), - CPUID_FXSR = (1 << 24) + CPUID_FPU = (1 << 0), /* On-chip Floating Point Unit */ + CPUID_VME = (1 << 1), /* Virtual 8086 mode extensions */ + CPUID_DE = (1 << 2), /* Debugging extensions */ + CPUID_PSE = (1 << 3), /* Page Size Extension */ + CPUID_TSC = (1 << 4), /* Time Stamp Counter */ + CPUID_MSR = (1 << 5), /* Model-specific registers */ + CPUID_PAE = (1 << 6), /* Physical Address Extension */ + CPUID_MCE = (1 << 7), /* Machine Check Exception */ + CPUID_CMPXCHG8B = (1 << 8), /* CMPXCHG8B instruction */ + CPUID_APIC = (1 << 9), /* On-chip APIC */ + CPUID_AMDPGE = (1 << 9), /* Global Page Enable (AMD K5 Model 0 only) */ + CPUID_AMDSEP = (1 << 10), /* SYSCALL and SYSRET instructions (AMD K6 only) */ + CPUID_SEP = (1 << 11), /* SYSENTER and SYSEXIT instructions (SYSCALL and SYSRET if EAX=80000001h) */ + CPUID_MTRR = (1 << 12), /* Memory type range registers */ + CPUID_PGE = (1 << 13), /* Page Global Enable */ + CPUID_MCA = (1 << 14), /* Machine Check Architecture */ + CPUID_CMOV = (1 << 15), /* Conditional move instructions */ + CPUID_PAT = (1 << 16), /* Page Attribute Table */ + CPUID_MMX = (1 << 23), /* MMX technology */ + CPUID_FXSR = (1 << 24) /* FXSAVE and FXRSTOR instructions */ }; -/*Addition flags returned by CPUID function 0x80000001*/ -#define CPUID_3DNOW (1UL << 31UL) -#define CPUID_3DNOWE (1UL << 30UL) +/* Additional flags returned by CPUID function 0x80000001 */ +#define CPUID_3DNOWE (1UL << 30UL) /* Extended 3DNow! instructions */ +#define CPUID_3DNOW (1UL << 31UL) /* 3DNow! instructions */ /* Make sure this is as low as possible. */ cpu_state_t cpu_state; @@ -2560,14 +2561,17 @@ cpu_RDMSR(void) case CPU_IBM486BL: EAX = EDX = 0; switch (ECX) { + /* Processor Operation Register */ case 0x1000: EAX = msr.ibm_por & ((cpu_s->cpu_type > CPU_IBM386SLC) ? 0xffeff : 0xfeff); break; + /* Cache Region Control Register */ case 0x1001: EAX = msr.ibm_crcr & 0xffffffffff; break; + /* Processor Operation Register */ case 0x1002: if ((cpu_s->cpu_type > CPU_IBM386SLC) && cpu_s->multi) EAX = msr.ibm_por2 & 0x3f000000; @@ -2579,26 +2583,33 @@ cpu_RDMSR(void) case CPU_WINCHIP2: EAX = EDX = 0; switch (ECX) { + /* TR1 - Test Register 1 */ case 0x02: EAX = msr.tr1; break; + /* TR12 - Test Register 12 */ case 0x0e: EAX = msr.tr12; break; + /* Time Stamp Counter */ case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; break; + /* Performance Monitor - Control and Event Select */ case 0x11: EAX = msr.cesr; break; + /* Feature Control Register */ case 0x107: EAX = msr.fcr; break; + /* Feature Control Register 2 */ case 0x108: EAX = msr.fcr2 & 0xffffffff; EDX = msr.fcr2 >> 32; break; + /* Feature Control Register 4 */ case 0x10a: EAX = cpu_multi & 3; break; @@ -2608,13 +2619,17 @@ cpu_RDMSR(void) case CPU_CYRIX3S: EAX = EDX = 0; switch (ECX) { + /* Machine Check Exception Address */ case 0x00: + /* Machine Check Exception Type */ case 0x01: break; + /* Time Stamp Counter */ case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; break; + /* EBL_CR_POWERON - Processor Hard Power-On Configuration */ case 0x2a: EAX = 0xc4000000; EDX = 0; @@ -2641,29 +2656,18 @@ cpu_RDMSR(void) if (cpu_busspeed >= 84000000) EAX |= (1 << 19); break; + /* Feature Control Register */ case 0x1107: EAX = msr.fcr; break; + /* Feature Control Register 2 */ case 0x1108: EAX = msr.fcr2 & 0xffffffff; EDX = msr.fcr2 >> 32; break; - case 0x200: - case 0x201: - case 0x202: - case 0x203: - case 0x204: - case 0x205: - case 0x206: - case 0x207: - case 0x208: - case 0x209: - case 0x20a: - case 0x20b: - case 0x20c: - case 0x20d: - case 0x20e: - case 0x20f: + /* ECX & 0: MTRRphysBase0 ... MTRRphysBase7 + ECX & 1: MTRRphysMask0 ... MTRRphysMask7 */ + case 0x200 ... 0x20f: if (ECX & 1) { EAX = msr.mtrr_physmask[(ECX - 0x200) >> 1] & 0xffffffff; EDX = msr.mtrr_physmask[(ECX - 0x200) >> 1] >> 32; @@ -2672,29 +2676,27 @@ cpu_RDMSR(void) EDX = msr.mtrr_physbase[(ECX - 0x200) >> 1] >> 32; } break; + /* MTRRfix64K_00000 */ case 0x250: EAX = msr.mtrr_fix64k_8000 & 0xffffffff; EDX = msr.mtrr_fix64k_8000 >> 32; break; + /* MTRRfix16K_80000 */ case 0x258: EAX = msr.mtrr_fix16k_8000 & 0xffffffff; EDX = msr.mtrr_fix16k_8000 >> 32; break; + /* MTRRfix16K_A0000 */ case 0x259: EAX = msr.mtrr_fix16k_a000 & 0xffffffff; EDX = msr.mtrr_fix16k_a000 >> 32; break; - case 0x268: - case 0x269: - case 0x26a: - case 0x26b: - case 0x26c: - case 0x26d: - case 0x26e: - case 0x26f: + /* MTRRfix4K_C0000 ... MTRRfix4K_F8000 */ + case 0x268 ... 0x26f: EAX = msr.mtrr_fix4k[ECX - 0x268] & 0xffffffff; EDX = msr.mtrr_fix4k[ECX - 0x268] >> 32; break; + /* MTRRdefType */ case 0x2ff: EAX = msr.mtrr_deftype & 0xffffffff; EDX = msr.mtrr_deftype >> 32; @@ -2714,35 +2716,44 @@ cpu_RDMSR(void) case CPU_K6_3P: EAX = EDX = 0; switch (ECX) { + /* Machine Check Address Register */ case 0x00000000: + /* Machine Check Type Register */ case 0x00000001: break; + /* Test Register 12 */ case 0x0000000e: EAX = msr.tr12; break; + /* Time Stamp Counter */ case 0x00000010: EAX = tsc & 0xffffffff; EDX = tsc >> 32; break; + /* Hardware Configuration Register */ case 0x00000083: EAX = msr.amd_hwcr & 0xffffffff; EDX = msr.amd_hwcr >> 32; break; + /* Extended Feature Enable Register */ case 0xc0000080: EAX = msr.amd_efer & 0xffffffff; EDX = msr.amd_efer >> 32; break; + /* SYSCALL Target Address Register */ case 0xc0000081: if (cpu_s->cpu_type < CPU_K6_2) goto amd_k_invalid_rdmsr; - EAX = msr.star & 0xffffffff; - EDX = msr.star >> 32; + EAX = msr.amd_star & 0xffffffff; + EDX = msr.amd_star >> 32; break; + /* Write-Handling Control Register */ case 0xc0000082: EAX = msr.amd_whcr & 0xffffffff; EDX = msr.amd_whcr >> 32; break; + /* UC/WC Cacheability Control Register */ case 0xc0000085: if (cpu_s->cpu_type < CPU_K6_2C) goto amd_k_invalid_rdmsr; @@ -2750,6 +2761,7 @@ cpu_RDMSR(void) EAX = msr.amd_uwccr & 0xffffffff; EDX = msr.amd_uwccr >> 32; break; + /* Enhanced Power Management Register */ case 0xc0000086: if (cpu_s->cpu_type < CPU_K6_2P) goto amd_k_invalid_rdmsr; @@ -2757,6 +2769,7 @@ cpu_RDMSR(void) EAX = msr.amd_epmr & 0xffffffff; EDX = msr.amd_epmr >> 32; break; + /* Processor State Observability Register */ case 0xc0000087: if (cpu_s->cpu_type < CPU_K6_2C) goto amd_k_invalid_rdmsr; @@ -2764,6 +2777,7 @@ cpu_RDMSR(void) EAX = msr.amd_psor & 0xffffffff; EDX = msr.amd_psor >> 32; break; + /* Page Flush/Invalidate Register */ case 0xc0000088: if (cpu_s->cpu_type < CPU_K6_2C) goto amd_k_invalid_rdmsr; @@ -2771,6 +2785,7 @@ cpu_RDMSR(void) EAX = msr.amd_pfir & 0xffffffff; EDX = msr.amd_pfir >> 32; break; + /* Level-2 Cache Array Access Register */ case 0xc0000089: if (cpu_s->cpu_type < CPU_K6_3) goto amd_k_invalid_rdmsr; @@ -2790,9 +2805,12 @@ amd_k_invalid_rdmsr: case CPU_PENTIUMMMX: EAX = EDX = 0; switch (ECX) { + /* Machine Check Exception Address */ case 0x00: + /* Machine Check Exception Type */ case 0x01: break; + /* Time Stamp Counter */ case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; @@ -2807,9 +2825,12 @@ amd_k_invalid_rdmsr: case CPU_CxGX1: case CPU_Cx6x86MX: switch (ECX) { + /* Machine Check Exception Address */ case 0x00: + /* Machine Check Exception Type */ case 0x01: break; + /* Time Stamp Counter */ case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; @@ -2826,13 +2847,17 @@ amd_k_invalid_rdmsr: /* Per RichardG's probing of a real Deschutes using my RDMSR tool, we have discovered that the top 18 bits are filtered out. */ switch (ECX & 0x00003fff) { + /* Machine Check Exception Address */ case 0x00: + /* Machine Check Exception Type */ case 0x01: break; + /* Time Stamp Counter */ case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; break; + /* IA32_PLATFORM_ID - Platform ID */ case 0x17: if (cpu_s->cpu_type != CPU_PENTIUM2D) goto i686_invalid_rdmsr; @@ -2842,16 +2867,18 @@ amd_k_invalid_rdmsr: else if (cpu_f->package == CPU_PKG_SOCKET370) EDX |= 0x100000; break; + /* IA32_APIC_BASE - APIC Base Address */ case 0x1B: EAX = msr.apic_base & 0xffffffff; EDX = msr.apic_base >> 32; cpu_log("APIC_BASE read : %08X%08X\n", EDX, EAX); break; - /* Unknown (undocumented?) MSR used by the Hyper-V BIOS. */ + /* Unknown (undocumented?) MSR used by the Hyper-V BIOS */ case 0x20: EAX = msr.ecx20 & 0xffffffff; EDX = msr.ecx20 >> 32; break; + /* EBL_CR_POWERON - Processor Hard Power-On Configuration */ case 0x2a: EAX = 0xc4000000; EDX = 0; @@ -2886,56 +2913,58 @@ amd_k_invalid_rdmsr: EAX |= (1 << 19); } break; + /* BIOS_UPDT_TRIG - BIOS Update Trigger */ case 0x79: EAX = msr.bios_updt & 0xffffffff; EDX = msr.bios_updt >> 32; break; - case 0x88: - case 0x89: - case 0x8a: - case 0x8b: + /* BBL_CR_D0 ... BBL_CR_D3 - Chunk 0..3 Data Register + 8Bh: BIOS_SIGN - BIOS Update Signature */ + case 0x88 ... 0x8b: EAX = msr.bbl_cr_dx[ECX - 0x88] & 0xffffffff; EDX = msr.bbl_cr_dx[ECX - 0x88] >> 32; break; - case 0xc1: - case 0xc2: - case 0xc3: - case 0xc4: - case 0xc5: - case 0xc6: - case 0xc7: - case 0xc8: + /* PERFCTR0 ... PERFCTR7 - Performance Counter Register 0..7 */ + case 0xc1 ... 0xc8: EAX = msr.ia32_pmc[ECX - 0xC1] & 0xffffffff; EDX = msr.ia32_pmc[ECX - 0xC1] >> 32; break; + /* MTRRcap */ case 0xfe: EAX = msr.mtrr_cap & 0xffffffff; EDX = msr.mtrr_cap >> 32; break; + /* BBL_CR_ADDR - L2 Cache Address Register */ case 0x116: EAX = msr.bbl_cr_addr & 0xffffffff; EDX = msr.bbl_cr_addr >> 32; break; + /* BBL_CR_DECC - L2 Cache Date ECC Register */ case 0x118: EAX = msr.bbl_cr_decc & 0xffffffff; EDX = msr.bbl_cr_decc >> 32; break; + /* BBL_CR_CTL - L2 Cache Control Register */ case 0x119: EAX = msr.bbl_cr_ctl & 0xffffffff; EDX = msr.bbl_cr_ctl >> 32; break; + /* BBL_CR_TRIG - L2 Cache Trigger Register */ case 0x11a: EAX = msr.bbl_cr_trig & 0xffffffff; EDX = msr.bbl_cr_trig >> 32; break; + /* BBL_CR_BUSY - L2 Cache Busy Register */ case 0x11b: EAX = msr.bbl_cr_busy & 0xffffffff; EDX = msr.bbl_cr_busy >> 32; break; + /* BBL_CR_CTL3 - L2 Cache Control Register 3 */ case 0x11e: EAX = msr.bbl_cr_ctl3 & 0xffffffff; EDX = msr.bbl_cr_ctl3 >> 32; break; + /* SYSENTER_CS - SYSENTER target CS */ case 0x174: if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr; @@ -2944,6 +2973,7 @@ amd_k_invalid_rdmsr: EAX |= msr.sysenter_cs; EDX = 0x00000000; break; + /* SYSENTER_ESP - SYSENTER target ESP */ case 0x175: if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr; @@ -2951,6 +2981,7 @@ amd_k_invalid_rdmsr: EAX = msr.sysenter_esp; EDX = 0x00000000; break; + /* SYSENTER_EIP - SYSENTER target EIP */ case 0x176: if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr; @@ -2958,48 +2989,42 @@ amd_k_invalid_rdmsr: EAX = msr.sysenter_eip; EDX = 0x00000000; break; + /* MCG_CAP - Machine Check Global Capability */ case 0x179: EAX = 0x00000105; EDX = 0x00000000; break; + /* MCG_STATUS - Machine Check Global Status */ case 0x17a: break; + /* MCG_CTL - Machine Check Global Control */ case 0x17b: EAX = msr.mcg_ctl & 0xffffffff; EDX = msr.mcg_ctl >> 32; break; + /* EVNTSEL0 - Performance Counter Event Select 0 */ case 0x186: EAX = msr.evntsel0 & 0xffffffff; EDX = msr.evntsel0 >> 32; break; + /* EVNTSEL1 - Performance Counter Event Select 1 */ case 0x187: EAX = msr.evntsel1 & 0xffffffff; EDX = msr.evntsel1 >> 32; break; + /* DEBUGCTLMSR - Debugging Control Register */ case 0x1d9: EAX = msr.debug_ctl & 0xffffffff; EDX = msr.debug_ctl >> 32; break; + /* ROB_CR_BKUPTMPDR6 */ case 0x1e0: EAX = msr.rob_cr_bkuptmpdr6 & 0xffffffff; EDX = msr.rob_cr_bkuptmpdr6 >> 32; break; - case 0x200: - case 0x201: - case 0x202: - case 0x203: - case 0x204: - case 0x205: - case 0x206: - case 0x207: - case 0x208: - case 0x209: - case 0x20a: - case 0x20b: - case 0x20c: - case 0x20d: - case 0x20e: - case 0x20f: + /* ECX & 0: MTRRphysBase0 ... MTRRphysBase7 + ECX & 1: MTRRphysMask0 ... MTRRphysMask7 */ + case 0x200 ... 0x20f: if (ECX & 1) { EAX = msr.mtrr_physmask[(ECX - 0x200) >> 1] & 0xffffffff; EDX = msr.mtrr_physmask[(ECX - 0x200) >> 1] >> 32; @@ -3008,56 +3033,71 @@ amd_k_invalid_rdmsr: EDX = msr.mtrr_physbase[(ECX - 0x200) >> 1] >> 32; } break; + /* MTRRfix64K_00000 */ case 0x250: EAX = msr.mtrr_fix64k_8000 & 0xffffffff; EDX = msr.mtrr_fix64k_8000 >> 32; break; + /* MTRRfix16K_80000 */ case 0x258: EAX = msr.mtrr_fix16k_8000 & 0xffffffff; EDX = msr.mtrr_fix16k_8000 >> 32; break; + /* MTRRfix16K_A0000 */ case 0x259: EAX = msr.mtrr_fix16k_a000 & 0xffffffff; EDX = msr.mtrr_fix16k_a000 >> 32; break; - case 0x268: - case 0x269: - case 0x26a: - case 0x26b: - case 0x26c: - case 0x26d: - case 0x26e: - case 0x26f: + /* MTRRfix4K_C0000 ... MTRRfix4K_F8000 */ + case 0x268 ... 0x26f: EAX = msr.mtrr_fix4k[ECX - 0x268] & 0xffffffff; EDX = msr.mtrr_fix4k[ECX - 0x268] >> 32; break; + /* Page Attribute Table */ case 0x277: EAX = msr.pat & 0xffffffff; EDX = msr.pat >> 32; break; + /* MTRRdefType */ case 0x2ff: EAX = msr.mtrr_deftype & 0xffffffff; EDX = msr.mtrr_deftype >> 32; break; + /* MC0_CTL - Machine Check 0 Control */ case 0x400: + /* MC1_CTL - Machine Check 1 Control */ case 0x404: + /* MC2_CTL - Machine Check 2 Control */ case 0x408: + /* MC4_CTL - Machine Check 4 Control */ case 0x40c: + /* MC3_CTL - Machine Check 3 Control */ case 0x410: EAX = msr.mca_ctl[(ECX - 0x400) >> 2] & 0xffffffff; EDX = msr.mca_ctl[(ECX - 0x400) >> 2] >> 32; break; + /* MC0_STATUS - Machine Check 0 Status */ case 0x401: + /* MC0_ADDR - Machine Check 0 Address */ case 0x402: + /* MC1_STATUS - Machine Check 1 Status */ case 0x405: + /* MC1_ADDR - Machine Check 1 Address */ case 0x406: - case 0x407: + /* MC2_STATUS - Machine Check 2 Status */ case 0x409: + /* MC2_ADDR - Machine Check 2 Address */ + case 0x40a: + /* MC4_STATUS - Machine Check 4 Status */ case 0x40d: + /* MC4_ADDR - Machine Check 4 Address */ case 0x40e: + /* MC3_STATUS - Machine Check 3 Status */ case 0x411: + /* MC3_ADDR - Machine Check 3 Address */ case 0x412: break; + /* Unknown */ case 0x570: EAX = msr.ecx570 & 0xffffffff; EDX = msr.ecx570 >> 32; @@ -3086,13 +3126,16 @@ cpu_WRMSR(void) case CPU_IBM486BL: case CPU_IBM486SLC: switch (ECX) { + /* Processor Operation Register */ case 0x1000: msr.ibm_por = EAX & ((cpu_s->cpu_type > CPU_IBM386SLC) ? 0xffeff : 0xfeff); cpu_cache_int_enabled = (EAX & (1 << 7)); break; + /* Cache Region Control Register */ case 0x1001: msr.ibm_crcr = EAX & 0xffffffffff; break; + /* Processor Operation Register */ case 0x1002: if ((cpu_s->cpu_type > CPU_IBM386SLC) && cpu_s->multi) msr.ibm_por2 = EAX & 0x3f000000; @@ -3103,18 +3146,23 @@ cpu_WRMSR(void) case CPU_WINCHIP: case CPU_WINCHIP2: switch (ECX) { + /* TR1 - Test Register 1 */ case 0x02: msr.tr1 = EAX & 2; break; + /* TR12 - Test Register 12 */ case 0x0e: msr.tr12 = EAX & 0x228; break; + /* Time Stamp Counter */ case 0x10: tsc = EAX | ((uint64_t) EDX << 32); break; + /* Performance Monitor - Control and Event Select */ case 0x11: msr.cesr = EAX & 0xff00ff; break; + /* Feature Control Register */ case 0x107: msr.fcr = EAX; if (EAX & (1 << 9)) @@ -3134,9 +3182,11 @@ cpu_WRMSR(void) else CPUID = cpu_s->cpuid_model; break; + /* Feature Control Register 2 */ case 0x108: msr.fcr2 = EAX | ((uint64_t) EDX << 32); break; + /* Feature Control Register 3 */ case 0x109: msr.fcr3 = EAX | ((uint64_t) EDX << 32); break; @@ -3145,12 +3195,16 @@ cpu_WRMSR(void) case CPU_CYRIX3S: switch (ECX) { + /* Machine Check Exception Address */ case 0x00: + /* Machine Check Exception Type */ case 0x01: break; + /* Time Stamp Counter */ case 0x10: tsc = EAX | ((uint64_t) EDX << 32); break; + /* Feature Control Register */ case 0x1107: msr.fcr = EAX; if (EAX & (1 << 1)) @@ -3162,52 +3216,39 @@ cpu_WRMSR(void) else cpu_CR4_mask &= ~CR4_PGE; break; + /* Feature Control Register 2 */ case 0x1108: msr.fcr2 = EAX | ((uint64_t) EDX << 32); break; + /* Feature Control Register 3 */ case 0x1109: msr.fcr3 = EAX | ((uint64_t) EDX << 32); break; - case 0x200: - case 0x201: - case 0x202: - case 0x203: - case 0x204: - case 0x205: - case 0x206: - case 0x207: - case 0x208: - case 0x209: - case 0x20a: - case 0x20b: - case 0x20c: - case 0x20d: - case 0x20e: - case 0x20f: + /* ECX & 0: MTRRphysBase0 ... MTRRphysBase7 + ECX & 1: MTRRphysMask0 ... MTRRphysMask7 */ + case 0x200 ... 0x20f: if (ECX & 1) msr.mtrr_physmask[(ECX - 0x200) >> 1] = EAX | ((uint64_t) EDX << 32); else msr.mtrr_physbase[(ECX - 0x200) >> 1] = EAX | ((uint64_t) EDX << 32); break; + /* MTRRfix64K_00000 */ case 0x250: msr.mtrr_fix64k_8000 = EAX | ((uint64_t) EDX << 32); break; + /* MTRRfix16K_80000 */ case 0x258: msr.mtrr_fix16k_8000 = EAX | ((uint64_t) EDX << 32); break; + /* MTRRfix16K_A0000 */ case 0x259: msr.mtrr_fix16k_a000 = EAX | ((uint64_t) EDX << 32); break; - case 0x268: - case 0x269: - case 0x26A: - case 0x26B: - case 0x26C: - case 0x26D: - case 0x26E: - case 0x26F: + /* MTRRfix4K_C0000 ... MTRRfix4K_F8000 */ + case 0x268 ... 0x26f: msr.mtrr_fix4k[ECX - 0x268] = EAX | ((uint64_t) EDX << 32); break; + /* MTRRdefType */ case 0x2ff: msr.mtrr_deftype = EAX | ((uint64_t) EDX << 32); break; @@ -3225,18 +3266,24 @@ cpu_WRMSR(void) case CPU_K6_2P: case CPU_K6_3P: switch (ECX) { + /* Machine Check Address Register */ case 0x00: + /* Machine Check Type Register */ case 0x01: break; + /* Test Register 12 */ case 0x0e: msr.tr12 = EAX & 0x228; break; + /* Time Stamp Counter */ case 0x10: tsc = EAX | ((uint64_t) EDX << 32); break; + /* Hardware Configuration Register */ case 0x83: msr.amd_hwcr = EAX | ((uint64_t) EDX << 32); break; + /* Extended Feature Enable Register */ case 0xc0000080: temp = EAX | ((uint64_t) EDX << 32); if (temp & ~1ULL) @@ -3244,39 +3291,46 @@ cpu_WRMSR(void) else msr.amd_efer = temp; break; + /* SYSCALL Target Address Register */ case 0xc0000081: if (cpu_s->cpu_type < CPU_K6_2) goto amd_k_invalid_wrmsr; - msr.star = EAX | ((uint64_t) EDX << 32); + msr.amd_star = EAX | ((uint64_t) EDX << 32); break; + /* Write-Handling Control Register */ case 0xc0000082: msr.amd_whcr = EAX | ((uint64_t) EDX << 32); break; + /* UC/WC Cacheability Control Register */ case 0xc0000085: if (cpu_s->cpu_type < CPU_K6_2C) goto amd_k_invalid_wrmsr; msr.amd_uwccr = EAX | ((uint64_t) EDX << 32); break; + /* Enhanced Power Management Register */ case 0xc0000086: if (cpu_s->cpu_type < CPU_K6_2P) goto amd_k_invalid_wrmsr; msr.amd_epmr = EAX | ((uint64_t) EDX << 32); break; + /* Processor State Observability Register */ case 0xc0000087: if (cpu_s->cpu_type < CPU_K6_2C) goto amd_k_invalid_wrmsr; msr.amd_psor = EAX | ((uint64_t) EDX << 32); break; + /* Page Flush/Invalidate Register */ case 0xc0000088: if (cpu_s->cpu_type < CPU_K6_2C) goto amd_k_invalid_wrmsr; msr.amd_pfir = EAX | ((uint64_t) EDX << 32); break; + /* Level-2 Cache Array Access Register */ case 0xc0000089: if (cpu_s->cpu_type < CPU_K6_3) goto amd_k_invalid_wrmsr; @@ -3295,12 +3349,16 @@ amd_k_invalid_wrmsr: case CPU_PENTIUMMMX: cpu_log("WRMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); switch (ECX) { + /* Machine Check Exception Address */ case 0x00: + /* Machine Check Exception Type */ case 0x01: break; + /* Time Stamp Counter */ case 0x10: tsc = EAX | ((uint64_t) EDX << 32); break; + /* BIOS Update Signature */ case 0x8b: cpu_log("WRMSR: Invalid MSR: 0x8B\n"); x86gpf(NULL, 0); /* Needed for Vista to correctly break on Pentium */ @@ -3315,9 +3373,12 @@ amd_k_invalid_wrmsr: case CPU_Cx6x86MX: cpu_log("WRMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); switch (ECX) { + /* Machine Check Exception Address */ case 0x00: + /* Machine Check Exception Type */ case 0x01: break; + /* Time Stamp Counter */ case 0x10: tsc = EAX | ((uint64_t) EDX << 32); break; @@ -3331,171 +3392,189 @@ amd_k_invalid_wrmsr: /* Per RichardG's probing of a real Deschutes using my RDMSR tool, we have discovered that the top 18 bits are filtered out. */ switch (ECX & 0x00003fff) { + /* Machine Check Exception Address */ case 0x00: + /* Machine Check Exception Type */ case 0x01: if (EAX || EDX) x86gpf(NULL, 0); break; + /* Time Stamp Counter */ case 0x10: tsc = EAX | ((uint64_t) EDX << 32); break; + /* IA32_APIC_BASE - APIC Base Address */ case 0x1b: cpu_log("APIC_BASE write: %08X%08X\n", EDX, EAX); #if 0 msr.apic_base = EAX | ((uint64_t) EDX << 32); #endif break; - /* Unknown (undocumented?) MSR used by the Hyper-V BIOS. */ + /* Unknown (undocumented?) MSR used by the Hyper-V BIOS */ case 0x20: msr.ecx20 = EAX | ((uint64_t) EDX << 32); break; + /* EBL_CR_POWERON - Processor Hard Power-On Configuration */ case 0x2a: break; + /* BIOS_UPDT_TRIG - BIOS Update Trigger */ case 0x79: msr.bios_updt = EAX | ((uint64_t) EDX << 32); break; - case 0x88: - case 0x89: - case 0x8a: - case 0x8b: + /* BBL_CR_D0 ... BBL_CR_D3 - Chunk 0..3 Data Register + 8Bh: BIOS_SIGN - BIOS Update Signature */ + case 0x88 ... 0x8b: msr.bbl_cr_dx[ECX - 0x88] = EAX | ((uint64_t) EDX << 32); break; - case 0xc1: - case 0xc2: - case 0xc3: - case 0xc4: - case 0xc5: - case 0xc6: - case 0xc7: - case 0xc8: + /* PERFCTR0 ... PERFCTR7 - Performance Counter Register 0..7 */ + case 0xc1 ... 0xc8: msr.ia32_pmc[ECX - 0xC1] = EAX | ((uint64_t) EDX << 32); break; + /* MTRRcap */ case 0xfe: msr.mtrr_cap = EAX | ((uint64_t) EDX << 32); break; + /* BBL_CR_ADDR - L2 Cache Address Register */ case 0x116: msr.bbl_cr_addr = EAX | ((uint64_t) EDX << 32); break; + /* BBL_CR_DECC - L2 Cache Date ECC Register */ case 0x118: msr.bbl_cr_decc = EAX | ((uint64_t) EDX << 32); break; + /* BBL_CR_CTL - L2 Cache Control Register */ case 0x119: msr.bbl_cr_ctl = EAX | ((uint64_t) EDX << 32); break; + /* BBL_CR_TRIG - L2 Cache Trigger Register */ case 0x11a: msr.bbl_cr_trig = EAX | ((uint64_t) EDX << 32); break; + /* BBL_CR_BUSY - L2 Cache Busy Register */ case 0x11b: msr.bbl_cr_busy = EAX | ((uint64_t) EDX << 32); break; + /* BBL_CR_CTL3 - L2 Cache Control Register 3 */ case 0x11e: msr.bbl_cr_ctl3 = EAX | ((uint64_t) EDX << 32); break; + /* SYSENTER_CS - SYSENTER target CS */ case 0x174: if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; msr.sysenter_cs = EAX & 0xFFFF; break; + /* SYSENTER_ESP - SYSENTER target ESP */ case 0x175: if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; msr.sysenter_esp = EAX; break; + /* SYSENTER_EIP - SYSENTER target EIP */ case 0x176: if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; msr.sysenter_eip = EAX; break; + /* MCG_CAP - Machine Check Global Capability */ case 0x179: break; + /* MCG_STATUS - Machine Check Global Status */ case 0x17a: if (EAX || EDX) x86gpf(NULL, 0); break; + /* MCG_CTL - Machine Check Global Control */ case 0x17b: msr.mcg_ctl = EAX | ((uint64_t) EDX << 32); break; + /* EVNTSEL0 - Performance Counter Event Select 0 */ case 0x186: msr.evntsel0 = EAX | ((uint64_t) EDX << 32); break; + /* EVNTSEL1 - Performance Counter Event Select 1 */ case 0x187: msr.evntsel1 = EAX | ((uint64_t) EDX << 32); break; + /* DEBUGCTLMSR - Debugging Control Register */ case 0x1d9: msr.debug_ctl = EAX | ((uint64_t) EDX << 32); break; + /* ROB_CR_BKUPTMPDR6 */ case 0x1e0: msr.rob_cr_bkuptmpdr6 = EAX | ((uint64_t) EDX << 32); break; - case 0x200: - case 0x201: - case 0x202: - case 0x203: - case 0x204: - case 0x205: - case 0x206: - case 0x207: - case 0x208: - case 0x209: - case 0x20a: - case 0x20b: - case 0x20c: - case 0x20d: - case 0x20e: - case 0x20f: + /* ECX & 0: MTRRphysBase0 ... MTRRphysBase7 + ECX & 1: MTRRphysMask0 ... MTRRphysMask7 */ + case 0x200 ... 0x20f: if (ECX & 1) msr.mtrr_physmask[(ECX - 0x200) >> 1] = EAX | ((uint64_t) EDX << 32); else msr.mtrr_physbase[(ECX - 0x200) >> 1] = EAX | ((uint64_t) EDX << 32); break; + /* MTRRfix64K_00000 */ case 0x250: msr.mtrr_fix64k_8000 = EAX | ((uint64_t) EDX << 32); break; + /* MTRRfix16K_80000 */ case 0x258: msr.mtrr_fix16k_8000 = EAX | ((uint64_t) EDX << 32); break; + /* MTRRfix16K_A0000 */ case 0x259: msr.mtrr_fix16k_a000 = EAX | ((uint64_t) EDX << 32); break; - case 0x268: - case 0x269: - case 0x26a: - case 0x26b: - case 0x26c: - case 0x26d: - case 0x26e: - case 0x26f: + /* MTRRfix4K_C0000 ... MTRRfix4K_F8000 */ + case 0x268 ... 0x26f: msr.mtrr_fix4k[ECX - 0x268] = EAX | ((uint64_t) EDX << 32); break; + /* Page Attribute Table */ case 0x277: msr.pat = EAX | ((uint64_t) EDX << 32); break; + /* MTRRdefType */ case 0x2ff: msr.mtrr_deftype = EAX | ((uint64_t) EDX << 32); break; + /* MC0_CTL - Machine Check 0 Control */ case 0x400: + /* MC1_CTL - Machine Check 1 Control */ case 0x404: + /* MC2_CTL - Machine Check 2 Control */ case 0x408: + /* MC4_CTL - Machine Check 4 Control */ case 0x40c: + /* MC3_CTL - Machine Check 3 Control */ case 0x410: msr.mca_ctl[(ECX - 0x400) >> 2] = EAX | ((uint64_t) EDX << 32); break; + /* MC0_STATUS - Machine Check 0 Status */ case 0x401: + /* MC0_ADDR - Machine Check 0 Address */ case 0x402: + /* MC1_STATUS - Machine Check 1 Status */ case 0x405: + /* MC1_ADDR - Machine Check 1 Address */ case 0x406: - case 0x407: + /* MC2_STATUS - Machine Check 2 Status */ case 0x409: + /* MC2_ADDR - Machine Check 2 Address */ + case 0x40a: + /* MC4_STATUS - Machine Check 4 Status */ case 0x40d: + /* MC4_ADDR - Machine Check 4 Address */ case 0x40e: + /* MC3_STATUS - Machine Check 3 Status */ case 0x411: + /* MC3_ADDR - Machine Check 3 Address */ case 0x412: if (EAX || EDX) x86gpf(NULL, 0); break; + /* Unknown */ case 0x570: msr.ecx570 = EAX | ((uint64_t) EDX << 32); break; diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 24b365693..429741839 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -226,35 +226,41 @@ typedef union { } MMX_REG; typedef struct { - /* IDT WinChip and WinChip 2 MSR's */ - uint32_t tr1; /* 0x00000002, 0x0000000e */ - uint32_t tr12; /* 0x00000002, 0x0000000e */ - uint32_t cesr; /* 0x00000011 */ + /* IBM 386SLC/486SLC/486BL MSRs */ + uint64_t ibm_por; /* 0x00001000 - 386SLC and later */ + uint64_t ibm_crcr; /* 0x00001001 - 386SLC and later */ + uint64_t ibm_por2; /* 0x00001002 - 486SLC and later */ - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t apic_base; /* 0x0000001b - Should the Pentium not also have this? */ - - /* Weird long MSR's used by the Hyper-V BIOS. */ - uint64_t ecx20; /* 0x00000020, really 0x40000020, but we filter out the top 18 bits - like a real Deschutes does. */ - - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t bios_updt; /* 0x00000079 */ - - /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t amd_hwcr; /* 0x00000083 - AMD K5 and K6 MSR's. */ - - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t bbl_cr_dx[4]; /* 0x00000088 - 0x0000008b */ - uint64_t ia32_pmc[8]; /* 0x000000c1 - 0x000000c8 */ - uint64_t mtrr_cap; /* 0x000000fe */ - - /* IDT WinChip and WinChip 2 MSR's that are also on the VIA Cyrix III */ + /* IDT WinChip C6/2/VIA Cyrix III MSRs */ uint32_t fcr; /* 0x00000107 (IDT), 0x00001107 (VIA) */ uint64_t fcr2; /* 0x00000108 (IDT), 0x00001108 (VIA) */ uint64_t fcr3; /* 0x00000108 (IDT), 0x00001108 (VIA) */ - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ + /* AMD K5/K6 MSRs */ + uint64_t amd_hwcr; /* 0x00000083 - all K5 and K6 */ + + uint64_t amd_efer; /* 0xc0000080 - all K5 and K6 */ + uint64_t amd_star; /* 0xc0000081 - K6-2 and later */ + uint64_t amd_whcr; /* 0xc0000082 - all K5 and K6 */ + uint64_t amd_uwccr; /* 0xc0000085 - K6-2C and later */ + uint64_t amd_epmr; /* 0xc0000086 - K6-III+/2+ only */ + uint64_t amd_psor; /* 0xc0000087 - K6-2C and later */ + uint64_t amd_pfir; /* 0xc0000088 - K6-2C and later */ + uint64_t amd_l2aar; /* 0xc0000089 - K6-III and later */ + + /* Pentium/Pentium MMX MSRs */ + uint32_t tr1; /* 0x00000002 - also on WinChip C6/2 */ + uint32_t tr12; /* 0x0000000e - also on WinChip C6/2 */ + uint32_t cesr; /* 0x00000011 - also on WinChip C6/2 */ + + /* Pentium Pro/II MSRs */ + uint64_t apic_base; /* 0x0000001b */ + uint64_t bios_updt; /* 0x00000079 */ + + uint64_t bbl_cr_dx[4]; /* 0x00000088 - 0x0000008b */ + uint64_t ia32_pmc[8]; /* 0x000000c1 - 0x000000c8 */ + uint64_t mtrr_cap; /* 0x000000fe */ + uint64_t bbl_cr_addr; /* 0x00000116 */ uint64_t bbl_cr_decc; /* 0x00000118 */ uint64_t bbl_cr_ctl; /* 0x00000119 */ @@ -262,68 +268,32 @@ typedef struct { uint64_t bbl_cr_busy; /* 0x0000011b */ uint64_t bbl_cr_ctl3; /* 0x0000011e */ - /* Pentium II Klamath and Pentium II Deschutes MSR's */ - uint16_t sysenter_cs; /* 0x00000174 - SYSENTER/SYSEXIT MSR's */ - uint32_t sysenter_esp; /* 0x00000175 - SYSENTER/SYSEXIT MSR's */ - uint32_t sysenter_eip; /* 0x00000176 - SYSENTER/SYSEXIT MSR's */ + uint16_t sysenter_cs; /* 0x00000174 - Pentium II and later */ + uint32_t sysenter_esp; /* 0x00000175 - Pentium II and later */ + uint32_t sysenter_eip; /* 0x00000176 - Pentium II and later */ - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t mcg_ctl; /* 0x0000017b - Machine Check Architecture */ - uint64_t evntsel0; /* 0x00000186 */ - uint64_t evntsel1; /* 0x00000187 */ - - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t debug_ctl; /* 0x000001d9 - Debug Registers Control */ + uint64_t mcg_ctl; /* 0x0000017b */ + uint64_t evntsel0; /* 0x00000186 */ + uint64_t evntsel1; /* 0x00000187 */ + uint64_t debug_ctl; /* 0x000001d9 */ uint64_t rob_cr_bkuptmpdr6; /* 0x000001e0 */ - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's that are also - on the VIA Cyrix III */ - uint64_t mtrr_physbase[8]; /* 0x00000200 - 0x0000020f */ + /* MTTR-related MSRs also present on the VIA Cyrix III */ + uint64_t mtrr_physbase[8]; /* 0x00000200 - 0x0000020f (ECX & 0) */ uint64_t mtrr_physmask[8]; /* 0x00000200 - 0x0000020f (ECX & 1) */ uint64_t mtrr_fix64k_8000; /* 0x00000250 */ uint64_t mtrr_fix16k_8000; /* 0x00000258 */ uint64_t mtrr_fix16k_a000; /* 0x00000259 */ uint64_t mtrr_fix4k[8]; /* 0x00000268 - 0x0000026f */ + uint64_t mtrr_deftype; /* 0x000002ff */ - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t pat; /* 0x00000277 */ - - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's that are also - on the VIA Cyrix III */ - uint64_t mtrr_deftype; /* 0x000002ff */ - - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t mca_ctl[5]; /* 0x00000400, 0x00000404, 0x00000408, 0x0000040c, 0x00000410 - Machine Check Architecture */ + uint64_t pat; /* 0x00000277 - Pentium II Deschutes and later */ + uint64_t mca_ctl[5]; /* 0x00000400, 0x00000404, 0x00000408, 0x0000040c, 0x00000410 */ uint64_t ecx570; /* 0x00000570 */ - /* IBM 386SLC, 486SLC, and 486BL MSR's */ - uint64_t ibm_por; /* 0x00001000 - Processor Operation Register */ - uint64_t ibm_crcr; /* 0x00001001 - Cache Region Control Register */ - - /* IBM 486SLC and 486BL MSR's */ - uint64_t ibm_por2; /* 0x00001002 - Processor Operation Register */ - - /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t amd_efer; /* 0xc0000080 */ - - /* AMD K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t star; /* 0xc0000081 */ - - /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t amd_whcr; /* 0xc0000082 */ - - /* AMD K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t amd_uwccr; /* 0xc0000085 */ - - /* AMD K6-2P and K6-3P MSR's */ - uint64_t amd_epmr; /* 0xc0000086 */ - - /* AMD K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t amd_psor; /* 0xc0000087, 0xc0000088 */ - uint64_t amd_pfir; /* 0xc0000087, 0xc0000088 */ - - /* K6-3, K6-2P, and K6-3P MSR's */ - uint64_t amd_l2aar; /* 0xc0000089 */ + /* Other/Unclassified MSRs */ + uint64_t ecx20; /* 0x00000020, really 0x40000020, but we filter out the top 18 bits + like a real Deschutes does. */ } msr_t; typedef struct { From 2a3d13d306ff911ca3f5e46dea47be171c93d935 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Thu, 1 Feb 2024 21:08:28 +0500 Subject: [PATCH 469/936] Various consistency changes --- src/cpu/cpu.c | 222 +++++++++++++++++++++++++++----------------------- 1 file changed, 121 insertions(+), 101 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 5a68ecf38..f57c874a8 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1915,7 +1915,7 @@ cpu_CPUID(void) case CPU_i486SX_SLENH: if (!EAX) { EAX = 0x00000001; - EBX = 0x756e6547; + EBX = 0x756e6547; /* GenuineIntel */ EDX = 0x49656e69; ECX = 0x6c65746e; } else if (EAX == 1) { @@ -1929,7 +1929,7 @@ cpu_CPUID(void) case CPU_i486DX_SLENH: if (!EAX) { EAX = 0x00000001; - EBX = 0x756e6547; + EBX = 0x756e6547; /* GenuineIntel */ EDX = 0x49656e69; ECX = 0x6c65746e; } else if (EAX == 1) { @@ -1945,21 +1945,21 @@ cpu_CPUID(void) case CPU_ENH_Am486DX: if (!EAX) { - EAX = 1; - EBX = 0x68747541; + EAX = 0x00000001; + EBX = 0x68747541;/* AuthenticAMD */ ECX = 0x444D4163; EDX = 0x69746E65; } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU; /*FPU*/ + EDX = CPUID_FPU; } else EAX = EBX = ECX = EDX = 0; break; case CPU_WINCHIP: if (!EAX) { - EAX = 1; + EAX = 0x00000001; if (msr.fcr2 & (1 << 14)) { EBX = msr.fcr3 >> 32; ECX = msr.fcr3 & 0xffffffff; @@ -1984,7 +1984,7 @@ cpu_CPUID(void) case CPU_WINCHIP2: switch (EAX) { case 0: - EAX = 1; + EAX = 0x00000001; if (msr.fcr2 & (1 << 14)) { EBX = msr.fcr3 >> 32; ECX = msr.fcr3 & 0xffffffff; @@ -2041,7 +2041,7 @@ cpu_CPUID(void) case CPU_PENTIUM: if (!EAX) { EAX = 0x00000001; - EBX = 0x756e6547; + EBX = 0x756e6547; /* GenuineIntel */ EDX = 0x49656e69; ECX = 0x6c65746e; } else if (EAX == 1) { @@ -2058,7 +2058,7 @@ cpu_CPUID(void) case CPU_K5: if (!EAX) { EAX = 0x00000001; - EBX = 0x68747541; + EBX = 0x68747541; /* AuthenticAMD */ EDX = 0x69746E65; ECX = 0x444D4163; } else if (EAX == 1) { @@ -2070,91 +2070,111 @@ cpu_CPUID(void) break; case CPU_5K86: - if (!EAX) { - EAX = 0x00000001; - EBX = 0x68747541; - EDX = 0x69746E65; - ECX = 0x444D4163; - } else if (EAX == 1) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE; - } else if (EAX == 0x80000000) { - EAX = 0x80000005; - EBX = ECX = EDX = 0; - } else if (EAX == 0x80000001) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE; - } else if (EAX == 0x80000002) { - EAX = 0x2D444D41; - EBX = 0x7428354B; - ECX = 0x5020296D; - EDX = 0x65636F72; - } else if (EAX == 0x80000003) { - EAX = 0x726F7373; - EBX = ECX = EDX = 0; - } else if (EAX == 0x80000004) - EAX = EBX = ECX = EDX = 0; - else if (EAX == 0x80000005) { - EAX = 0; - EBX = 0x04800000; - ECX = 0x08040120; - EDX = 0x10040120; - } else - EAX = EBX = ECX = EDX = 0; + switch (EAX) { + case 0: + EAX = 0x00000001; + EBX = 0x68747541; /* AuthenticAMD */ + EDX = 0x69746E65; + ECX = 0x444D4163; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE; + break; + case 0x80000000: + EAX = 0x80000005; + EBX = ECX = EDX = 0; + break; + case 0x80000001: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE; + break; + case 0x80000002: /* Processor name string */ + EAX = 0x2D444D41; /* AMD-K5(tm) Proce */ + EBX = 0x7428354B; + ECX = 0x5020296D; + EDX = 0x65636F72; + break; + case 0x80000003: /* Processor name string */ + EAX = 0x726F7373; /* ssor */ + EBX = ECX = EDX = 0; + break; + case 0x80000005: /* Cache information */ + EAX = 0; + EBX = 0x04800000; /* TLBs */ + ECX = 0x08040120; /* L1 data cache */ + EDX = 0x10040120; /* L1 instruction cache */ + break; + default: + EAX = EBX = ECX = EDX = 0; + break; + } break; #endif case CPU_K6: - if (!EAX) { - EAX = 0x00000001; - EBX = 0x68747541; - EDX = 0x69746E65; - ECX = 0x444D4163; - } else if (EAX == 1) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; - } else if (EAX == 0x80000000) { - EAX = 0x80000005; - EBX = ECX = EDX = 0; - } else if (EAX == 0x80000001) { - EAX = CPUID + 0x100; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX; - } else if (EAX == 0x80000002) { - EAX = 0x2D444D41; - EBX = 0x6D74364B; - ECX = 0x202F7720; - EDX = 0x746C756D; - } else if (EAX == 0x80000003) { - EAX = 0x64656D69; - EBX = 0x65206169; - ECX = 0x6E657478; - EDX = 0x6E6F6973; - } else if (EAX == 0x80000004) { - EAX = 0x73; - EBX = ECX = EDX = 0; - } else if (EAX == 0x80000005) { - EAX = 0; - EBX = 0x02800140; - ECX = 0x20020220; - EDX = 0x20020220; - } else if (EAX == 0x8FFFFFFF) { - EAX = 0x4778654E; - EBX = 0x72656E65; - ECX = 0x6F697461; - EDX = 0x444D416E; - } else - EAX = EBX = ECX = EDX = 0; + switch (EAX) { + case 0: + EAX = 0x00000001; + EBX = 0x68747541; /* AuthenticAMD */ + EDX = 0x69746E65; + ECX = 0x444D4163; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000005; + EBX = ECX = EDX = 0; + break; + case 0x80000001: + EAX = CPUID + 0x100; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX; + break; + case 0x80000002: /* Processor name string */ + EAX = 0x2D444D41; /* AMD-K6tm w/ mult */ + EBX = 0x6D74364B; + ECX = 0x202F7720; + EDX = 0x746C756D; + break; + case 0x80000003: /* Processor name string */ + EAX = 0x64656D69; /* imedia extension */ + EBX = 0x65206169; + ECX = 0x6E657478; + EDX = 0x6E6F6973; + break; + case 0x80000004: /* Processor name string */ + EAX = 0x73; /* s */ + EBX = ECX = EDX = 0; + break; + case 0x80000005: /* Cache information */ + EAX = 0; + EBX = 0x02800140; /* TLBs */ + ECX = 0x20020220; /* L1 data cache */ + EDX = 0x20020220; /* L1 instruction cache */ + break; + case 0x8FFFFFFF: /* Easter egg */ + EAX = 0x4778654E; /* NexGenerationAMD */ + EBX = 0x72656E65; + ECX = 0x6F697461; + EDX = 0x444D416E; + break; + default: + EAX = EBX = ECX = EDX = 0; + break; + } break; case CPU_K6_2: case CPU_K6_2C: switch (EAX) { case 0: - EAX = 1; + EAX = 0x00000001; EBX = 0x68747541; /* AuthenticAMD */ ECX = 0x444d4163; EDX = 0x69746e65; @@ -2189,11 +2209,11 @@ cpu_CPUID(void) ECX = 0x00000000; EDX = 0x00000000; break; - case 0x80000005: /*Cache information*/ + case 0x80000005: /* Cache information */ EAX = 0; - EBX = 0x02800140; /*TLBs*/ - ECX = 0x20020220; /*L1 data cache*/ - EDX = 0x20020220; /*L1 instruction cache*/ + EBX = 0x02800140; /* TLBs */ + ECX = 0x20020220; /* L1 data cache */ + EDX = 0x20020220; /* L1 instruction cache */ break; default: EAX = EBX = ECX = EDX = 0; @@ -2204,7 +2224,7 @@ cpu_CPUID(void) case CPU_K6_3: switch (EAX) { case 0: - EAX = 1; + EAX = 0x00000001; EBX = 0x68747541; /* AuthenticAMD */ ECX = 0x444d4163; EDX = 0x69746e65; @@ -2238,8 +2258,8 @@ cpu_CPUID(void) case 0x80000005: /* Cache information */ EAX = 0; EBX = 0x02800140; /* TLBs */ - ECX = 0x20020220; /*L1 data cache*/ - EDX = 0x20020220; /*L1 instruction cache*/ + ECX = 0x20020220; /* L1 data cache */ + EDX = 0x20020220; /* L1 instruction cache */ break; case 0x80000006: /* L2 Cache information */ EAX = EBX = EDX = 0; @@ -2255,7 +2275,7 @@ cpu_CPUID(void) case CPU_K6_3P: switch (EAX) { case 0: - EAX = 1; + EAX = 0x00000001; EBX = 0x68747541; /* AuthenticAMD */ ECX = 0x444d4163; EDX = 0x69746e65; @@ -2312,7 +2332,7 @@ cpu_CPUID(void) case CPU_PENTIUMMMX: if (!EAX) { EAX = 0x00000001; - EBX = 0x756e6547; + EBX = 0x756e6547; /* GenuineIntel */ EDX = 0x49656e69; ECX = 0x6c65746e; } else if (EAX == 1) { @@ -2327,7 +2347,7 @@ cpu_CPUID(void) case CPU_Cx6x86: if (!EAX) { EAX = 0x00000001; - EBX = 0x69727943; + EBX = 0x69727943; /* CyrixInstead */ EDX = 0x736e4978; ECX = 0x64616574; } else if (EAX == 1) { @@ -2341,7 +2361,7 @@ cpu_CPUID(void) case CPU_Cx6x86L: if (!EAX) { EAX = 0x00000001; - EBX = 0x69727943; + EBX = 0x69727943; /* CyrixInstead */ EDX = 0x736e4978; ECX = 0x64616574; } else if (EAX == 1) { @@ -2355,7 +2375,7 @@ cpu_CPUID(void) case CPU_CxGX1: if (!EAX) { EAX = 0x00000001; - EBX = 0x69727943; + EBX = 0x69727943; /* CyrixInstead */ EDX = 0x736e4978; ECX = 0x64616574; } else if (EAX == 1) { @@ -2369,7 +2389,7 @@ cpu_CPUID(void) case CPU_Cx6x86MX: if (!EAX) { EAX = 0x00000001; - EBX = 0x69727943; + EBX = 0x69727943; /* CyrixInstead */ EDX = 0x736e4978; ECX = 0x64616574; } else if (EAX == 1) { @@ -2384,7 +2404,7 @@ cpu_CPUID(void) case CPU_PENTIUMPRO: if (!EAX) { EAX = 0x00000002; - EBX = 0x756e6547; + EBX = 0x756e6547; /* GenuineIntel */ EDX = 0x49656e69; ECX = 0x6c65746e; } else if (EAX == 1) { @@ -2407,7 +2427,7 @@ cpu_CPUID(void) case CPU_PENTIUM2: if (!EAX) { EAX = 0x00000002; - EBX = 0x756e6547; + EBX = 0x756e6547; /* GenuineIntel */ EDX = 0x49656e69; ECX = 0x6c65746e; } else if (EAX == 1) { @@ -2430,7 +2450,7 @@ cpu_CPUID(void) case CPU_PENTIUM2D: if (!EAX) { EAX = 0x00000002; - EBX = 0x756e6547; + EBX = 0x756e6547; /* GenuineIntel */ EDX = 0x49656e69; ECX = 0x6c65746e; } else if (EAX == 1) { @@ -2461,7 +2481,7 @@ cpu_CPUID(void) case CPU_CYRIX3S: switch (EAX) { case 0: - EAX = 1; + EAX = 0x00000001; if (msr.fcr2 & (1 << 14)) { EBX = msr.fcr3 >> 32; ECX = msr.fcr3 & 0xffffffff; From 8520e6be85dcf2bedf8000105f1b5f531f3eb7ee Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 3 Feb 2024 21:35:32 +0500 Subject: [PATCH 470/936] Show actual clocks for CPUs w/ Performance Ratings --- src/cpu/cpu_table.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 7a478f6f0..521732eee 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -1398,9 +1398,9 @@ const cpu_family_t cpu_families[] = { .name = "Am5x86", .internal_name = "am5x86", .cpus = (const CPU[]) { - {"P75", CPU_ENH_Am486DX, fpus_internal, 133333333, 4.0, 5000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16}, - {"P75+", CPU_ENH_Am486DX, fpus_internal, 150000000, 3.0, 5000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*The rare P75+ was indeed a triple-clocked 150 MHz according to research*/ - {"P90", CPU_ENH_Am486DX, fpus_internal, 160000000, 4.0, 5000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*160 MHz on a 40 MHz bus was a common overclock and "5x86/P90" was used by a number of BIOSes to refer to that configuration*/ + {"133 (P75)", CPU_ENH_Am486DX, fpus_internal, 133333333, 4.0, 5000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16}, + {"150 (P75+)", CPU_ENH_Am486DX, fpus_internal, 150000000, 3.0, 5000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*The rare P75+ was indeed a triple-clocked 150 MHz according to research*/ + {"160 (P90)", CPU_ENH_Am486DX, fpus_internal, 160000000, 4.0, 5000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*160 MHz on a 40 MHz bus was a common overclock and "5x86/P90" was used by a number of BIOSes to refer to that configuration*/ {"", 0} } }, { @@ -1774,12 +1774,12 @@ const cpu_family_t cpu_families[] = { .name = "Cx6x86", .internal_name = "cx6x86", .cpus = (const CPU[]) { - {"P90", CPU_Cx6x86, fpus_internal, 80000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, - {"PR120+", CPU_Cx6x86, fpus_internal, 100000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, - {"PR133+", CPU_Cx6x86, fpus_internal, 110000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, - {"PR150+", CPU_Cx6x86, fpus_internal, 120000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, - {"PR166+", CPU_Cx6x86, fpus_internal, 133333333, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, - {"PR200+", CPU_Cx6x86, fpus_internal, 150000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + {"80 (PR90+)", CPU_Cx6x86, fpus_internal, 80000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, + {"100 (PR120+)", CPU_Cx6x86, fpus_internal, 100000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, + {"110 (PR133+)", CPU_Cx6x86, fpus_internal, 110000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"120 (PR150+)", CPU_Cx6x86, fpus_internal, 120000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"133 (PR166+)", CPU_Cx6x86, fpus_internal, 133333333, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"150 (PR200+)", CPU_Cx6x86, fpus_internal, 150000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, {"", 0} } }, { @@ -1788,10 +1788,10 @@ const cpu_family_t cpu_families[] = { .name = "Cx6x86L", .internal_name = "cx6x86l", .cpus = (const CPU[]) { - {"PR133+", CPU_Cx6x86L, fpus_internal, 110000000, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, - {"PR150+", CPU_Cx6x86L, fpus_internal, 120000000, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, - {"PR166+", CPU_Cx6x86L, fpus_internal, 133333333, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, - {"PR200+", CPU_Cx6x86L, fpus_internal, 150000000, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + {"110 (PR133+)", CPU_Cx6x86L, fpus_internal, 110000000, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"120 (PR150+)", CPU_Cx6x86L, fpus_internal, 120000000, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"133 (PR166+)", CPU_Cx6x86L, fpus_internal, 133333333, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"150 (PR200+)", CPU_Cx6x86L, fpus_internal, 150000000, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, {"", 0} } }, { @@ -1800,10 +1800,10 @@ const cpu_family_t cpu_families[] = { .name = "Cx6x86MX", .internal_name = "cx6x86mx", .cpus = (const CPU[]) { - {"PR166", CPU_Cx6x86MX, fpus_internal, 133333333, 2.0, 2900, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, - {"PR200", CPU_Cx6x86MX, fpus_internal, 166666666, 2.5, 2900, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, - {"PR233", CPU_Cx6x86MX, fpus_internal, 187500000, 2.5, 2900, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 45/2}, - {"PR266", CPU_Cx6x86MX, fpus_internal, 208333333, 2.5, 2700, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25}, + {"133 (PR166)", CPU_Cx6x86MX, fpus_internal, 133333333, 2.0, 2900, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"166 (PR200)", CPU_Cx6x86MX, fpus_internal, 166666666, 2.5, 2900, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"187.5 (PR233)", CPU_Cx6x86MX, fpus_internal, 187500000, 2.5, 2900, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 45/2}, + {"208.3 (PR266)", CPU_Cx6x86MX, fpus_internal, 208333333, 2.5, 2700, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25}, {"", 0} } }, { @@ -1812,11 +1812,11 @@ const cpu_family_t cpu_families[] = { .name = "MII", .internal_name = "mii", .cpus = (const CPU[]) { - {"PR300", CPU_Cx6x86MX, fpus_internal, 233333333, 3.5, 2900, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,11,11, 28}, - {"PR333", CPU_Cx6x86MX, fpus_internal, 250000000, 3.0, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 9, 9, 30}, - {"PR366", CPU_Cx6x86MX, fpus_internal, 250000000, 2.5, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 7, 7, 30}, - {"PR400", CPU_Cx6x86MX, fpus_internal, 285000000, 3.0, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 34}, - {"PR433", CPU_Cx6x86MX, fpus_internal, 300000000, 3.0, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 36}, + {"233 (PR300)", CPU_Cx6x86MX, fpus_internal, 233333333, 3.5, 2900, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,11,11, 28}, + {"250/83 (PR333)", CPU_Cx6x86MX, fpus_internal, 250000000, 3.0, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 9, 9, 30}, + {"250/100 (PR366)", CPU_Cx6x86MX, fpus_internal, 250000000, 2.5, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 7, 7, 30}, + {"285 (PR400)", CPU_Cx6x86MX, fpus_internal, 285000000, 3.0, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 34}, + {"300 (PR433)", CPU_Cx6x86MX, fpus_internal, 300000000, 3.0, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 36}, {"", 0} } }, From 8143ccdc9b0d9bfa8dc61669cc60daca22b9fa70 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 5 Feb 2024 13:18:00 +0500 Subject: [PATCH 471/936] K5 reorganization Rename SSA/5 to Model 0 and 5k86 to Model 1/2/3 and swap their ordering Remove the Model 0 CPUs from the Model 1 (5k86) table --- src/cpu/cpu_table.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 521732eee..502b2c86e 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -1615,23 +1615,7 @@ const cpu_family_t cpu_families[] = { { .package = CPU_PKG_SOCKET5_7, .manufacturer = "AMD", - .name = "K5 (5k86)", - .internal_name = "k5_5k86", - .cpus = (const CPU[]) { - {"75 (P75)", CPU_K5, fpus_internal, 75000000, 1.5, 3520, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, - {"90 (P90)", CPU_K5, fpus_internal, 90000000, 1.5, 3520, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2}, - {"100 (P100)", CPU_K5, fpus_internal, 100000000, 1.5, 3520, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12}, - {"90 (PR120)", CPU_5K86, fpus_internal, 120000000, 2.0, 3520, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, - {"100 (PR133)", CPU_5K86, fpus_internal, 133333333, 2.0, 3520, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, - {"105 (PR150)", CPU_5K86, fpus_internal, 150000000, 2.5, 3520, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, - {"116.5 (PR166)", CPU_5K86, fpus_internal, 166666666, 2.5, 3520, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, - {"133 (PR200)", CPU_5K86, fpus_internal, 200000000, 3.0, 3520, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, - {"", 0} - } - }, { - .package = CPU_PKG_SOCKET5_7, - .manufacturer = "AMD", - .name = "K5 (SSA/5)", + .name = "K5 (Model 0)", .internal_name = "k5_ssa5", .cpus = (const CPU[]) { {"75 (PR75)", CPU_K5, fpus_internal, 75000000, 1.5, 3520, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, @@ -1639,6 +1623,19 @@ const cpu_family_t cpu_families[] = { {"100 (PR100)", CPU_K5, fpus_internal, 100000000, 1.5, 3520, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12}, {"", 0} } + }, { + .package = CPU_PKG_SOCKET5_7, + .manufacturer = "AMD", + .name = "K5 (Model 1/2/3)", + .internal_name = "k5_5k86", + .cpus = (const CPU[]) { + {"90 (PR120)", CPU_5K86, fpus_internal, 120000000, 2.0, 3520, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, + {"100 (PR133)", CPU_5K86, fpus_internal, 133333333, 2.0, 3520, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, + {"105 (PR150)", CPU_5K86, fpus_internal, 150000000, 2.5, 3520, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, + {"116.7 (PR166)", CPU_5K86, fpus_internal, 166666666, 2.5, 3520, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, + {"133 (PR200)", CPU_5K86, fpus_internal, 200000000, 3.0, 3520, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, + {"", 0} + } }, #endif { From 1b9bf568f2a9024cc1b5d4fceba837223ca35084 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 3 Feb 2024 21:39:40 +0500 Subject: [PATCH 472/936] Implement missing Pentium MSRs Includes obscure behavior, like undocumented "high" MSRs --- src/cpu/cpu.c | 299 +++++++++++++++++++++++++++++++++++++++++++++++--- src/cpu/cpu.h | 23 +++- 2 files changed, 304 insertions(+), 18 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index f57c874a8..fbdb85aa2 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -248,8 +248,7 @@ uint32_t cache_index = 0; uint8_t _cache[2048]; uint64_t cpu_CR4_mask; -uint64_t tsc = 0; -uint64_t pmc[2] = { 0, 0 }; +uint64_t tsc = 0; double cpu_dmulti; double cpu_busspeed; @@ -2824,17 +2823,159 @@ amd_k_invalid_rdmsr: case CPU_PENTIUM: case CPU_PENTIUMMMX: EAX = EDX = 0; - switch (ECX) { + /* Filter out the upper 27 bits when ECX value is over 0x80000000, as per: + Ralf Brown, Pentium Model-Specific Registers and What They Reveal. + https://www.cs.cmu.edu/~ralf/papers/highmsr.html + But leave the bit 31 intact to be able to handle both low and high + MSRs in a single switch block. */ + switch (ECX & (ECX > 0x7fffffff ? 0x8000001f : 0x7fffffff)) { /* Machine Check Exception Address */ - case 0x00: + case 0x00000000: + case 0x80000000: + EAX = msr.mcar & 0xffffffff; + EDX = msr.mcar >> 32; + break; /* Machine Check Exception Type */ - case 0x01: + case 0x00000001: + case 0x80000001: + EAX = msr.mctr & 0xffffffff; + EDX = msr.mctr >> 32; + msr.mctr &= ~0x1; /* clear the machine check pending bit */ + break; + /* TR1 - Parity Reversal Test Register */ + case 0x00000002: + case 0x80000002: + EAX = msr.tr1; + break; + /* TR2 - Instruction Cache End Bit */ + case 0x00000004: + case 0x80000004: + if (cpu_s->cpu_type == CPU_PENTIUMMMX) + goto pentium_invalid_rdmsr; + EAX = msr.tr2; + break; + /* TR3 - Cache Test Data */ + case 0x00000005: + case 0x80000005: + EAX = msr.tr3; + break; + /* TR4 - Cache Test Tag */ + case 0x00000006: + case 0x80000006: + EAX = msr.tr4; + break; + /* TR5 - Cache Test Control */ + case 0x00000007: + case 0x80000007: + EAX = msr.tr5; + break; + /* TR6 - TLB Test Command */ + case 0x00000008: + case 0x80000008: + EAX = msr.tr6; + break; + /* TR7 - TLB Test Data */ + case 0x00000009: + case 0x80000009: + EAX = msr.tr7; + break; + /* TR9 - Branch Target Buffer Tag */ + case 0x0000000b: + case 0x8000000b: + EAX = msr.tr9; + break; + /* TR10 - Branch Target Buffer Target */ + case 0x0000000c: + case 0x8000000c: + EAX = msr.tr10; + break; + /* TR11 - Branch Target Buffer Control */ + case 0x0000000d: + case 0x8000000d: + EAX = msr.tr11; + break; + /* TR12 - New Feature Control */ + case 0x0000000e: + case 0x8000000e: + EAX = msr.tr12; break; /* Time Stamp Counter */ - case 0x10: + case 0x00000010: + case 0x80000010: EAX = tsc & 0xffffffff; EDX = tsc >> 32; break; + /* Performance Monitor - Control and Event Select */ + case 0x00000011: + case 0x80000011: + EAX = msr.cesr; + break; + /* Performance Monitor - Event Counter 0 */ + case 0x00000012: + case 0x80000012: + EAX = msr.pmc[0] & 0xffffffff; + EDX = msr.pmc[0] >> 32; + break; + /* Performance Monitor - Event Counter 1 */ + case 0x00000013: + case 0x80000013: + EAX = msr.pmc[1] & 0xffffffff; + EDX = msr.pmc[1] >> 32; + break; + /* Unknown */ + case 0x00000014: + case 0x80000014: + if ((CPUID & 0xfff) <= 0x520) + goto pentium_invalid_rdmsr; + break; + /* Unknown, possibly paging-related; initial value is 0004h, + becomes 0008h once paging is enabled */ + case 0x80000018: + EAX = ((cr0 & (1 << 31)) ? 0x00000008 : 0x00000004); + break; + /* Floating point - last prefetched opcode + bits 10-8: low three bits of first byte of FP instruction + bits 7-0: second byte of floating-point instruction */ + case 0x80000019: + EAX = 0; + break; + /* Floating point - last executed non-control opcode */ + case 0x8000001a: + EAX = 0; + break; + /* Floating point - last non-control exception opcode - part + of FSTENV/FSAVE'd environment */ + case 0x8000001b: + EAX = msr.fp_last_xcpt; + break; + /* Unknown */ + case 0x8000001c: + EAX = 0x00000004; + break; + /* Probe Mode Control */ + case 0x8000001d: + EAX = msr.probe_ctl; + break; + /* Unknown, possibly scratchpad register */ + case 0x8000001e: + EAX = msr.ecx8000001e; + break; + /* Unknown, possibly scratchpad register */ + case 0x8000001f: + EAX = msr.ecx8000001f; + break; + /* Reserved/Unimplemented */ + case 0x80000003: + case 0x8000000a: + case 0x8000000f: + case 0x80000015 ... 0x80000017: + EAX = (ECX & 0x1f) * 2; + break; + default: +pentium_invalid_rdmsr: + cpu_log("RDMSR: Invalid MSR: %08X\n", ECX); + x86gpf(NULL, 0); + break; } cpu_log("RDMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); break; @@ -3368,20 +3509,150 @@ amd_k_invalid_wrmsr: case CPU_PENTIUM: case CPU_PENTIUMMMX: cpu_log("WRMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); - switch (ECX) { + /* Filter out the upper 27 bits when ECX value is over 0x80000000, as per: + Ralf Brown, Pentium Model-Specific Registers and What They Reveal. + https://www.cs.cmu.edu/~ralf/papers/highmsr.html + But leave the bit 31 intact to be able to handle both low and high + MSRs in a single switch block. */ + switch (ECX & (ECX > 0x7fffffff ? 0x8000001f : 0x7fffffff)) { /* Machine Check Exception Address */ - case 0x00: + case 0x00000000: + case 0x80000000: /* Machine Check Exception Type */ - case 0x01: + case 0x00000001: + case 0x80000001: + break; + /* TR1 - Parity Reversal Test Register */ + case 0x00000002: + case 0x80000002: + msr.tr1 = EAX & 0x3fff; + break; + /* TR2 - Instruction Cache End Bit */ + case 0x00000004: + case 0x80000004: + if (cpu_s->cpu_type == CPU_PENTIUMMMX) + goto pentium_invalid_wrmsr; + msr.tr2 = EAX & 0xf; + break; + /* TR3 - Cache Test Data */ + case 0x00000005: + case 0x80000005: + msr.tr3 = EAX; + break; + /* TR4 - Cache Test Tag */ + case 0x00000006: + case 0x80000006: + msr.tr4 = EAX & ((cpu_s->cpu_type == CPU_PENTIUMMMX) ? 0xffffff1f : 0xffffff07); + break; + /* TR5 - Cache Test Control */ + case 0x00000007: + case 0x80000007: + msr.tr5 = EAX & ((cpu_s->cpu_type == CPU_PENTIUMMMX) ? 0x87fff : 0x7fff); + break; + /* TR6 - TLB Test Command */ + case 0x00000008: + case 0x80000008: + msr.tr6 = EAX & 0xffffff07; + break; + /* TR7 - TLB Test Data */ + case 0x00000009: + case 0x80000009: + msr.tr7 = EAX & ((cpu_s->cpu_type == CPU_PENTIUMMMX) ? 0xfffffc7f : 0xffffff9c); + break; + /* TR9 - Branch Target Buffer Tag */ + case 0x0000000b: + case 0x8000000b: + msr.tr9 = EAX & ((cpu_s->cpu_type == CPU_PENTIUMMMX) ? 0xffffffff : 0xffffffc3); + break; + /* TR10 - Branch Target Buffer Target */ + case 0x0000000c: + case 0x8000000c: + msr.tr10 = EAX; + break; + /* TR11 - Branch Target Buffer Control */ + case 0x0000000d: + case 0x8000000d: + msr.tr11 = EAX & ((cpu_s->cpu_type >= CPU_PENTIUMMMX) ? 0x3001fcf : 0xfcf); + break; + /* TR12 - New Feature Control */ + case 0x0000000e: + case 0x8000000e: + if (cpu_s->cpu_type == CPU_PENTIUMMMX) + temp = EAX & 0x38034f; + else if ((CPUID & 0xfff) >= 0x52b) + temp = EAX & 0x20435f; + else if ((CPUID & 0xfff) >= 0x520) + temp = EAX & 0x20035f; + else + temp = EAX & 0x20030f; + msr.tr12 = temp; break; /* Time Stamp Counter */ - case 0x10: + case 0x00000010: + case 0x80000010: tsc = EAX | ((uint64_t) EDX << 32); break; - /* BIOS Update Signature */ - case 0x8b: - cpu_log("WRMSR: Invalid MSR: 0x8B\n"); - x86gpf(NULL, 0); /* Needed for Vista to correctly break on Pentium */ + /* Performance Monitor - Control and Event Select */ + case 0x00000011: + case 0x80000011: + msr.cesr = EAX & 0x3ff03ff; + break; + /* Performance Monitor - Event Counter 0 */ + case 0x00000012: + case 0x80000012: + msr.pmc[0] = EAX | ((uint64_t) EDX << 32); + break; + /* Performance Monitor - Event Counter 1 */ + case 0x00000013: + case 0x80000013: + msr.pmc[1] = EAX | ((uint64_t) EDX << 32); + break; + /* Unknown */ + case 0x00000014: + case 0x80000014: + if ((CPUID & 0xfff) <= 0x520) + goto pentium_invalid_wrmsr; + break; + /* Unknown, possibly paging-related; initial value is 0004h, + becomes 0008h once paging is enabled */ + case 0x80000018: + /* Floating point - last prefetched opcode + bits 10-8: low three bits of first byte of FP instruction + bits 7-0: second byte of floating-point instruction */ + case 0x80000019: + /* Floating point - last executed non-control opcode */ + case 0x8000001a: + break; + /* Floating point - last non-control exception opcode - part + of FSTENV/FSAVE'd environment */ + case 0x8000001b: + EAX = msr.fp_last_xcpt & 0x7ff; + break; + /* Unknown */ + case 0x8000001c: + break; + /* Probe Mode Control */ + case 0x8000001d: + EAX = msr.probe_ctl & 0x7; + break; + /* Unknown, possibly scratchpad register */ + case 0x8000001e: + msr.ecx8000001e = EAX; + break; + /* Unknown, possibly scratchpad register */ + case 0x8000001f: + msr.ecx8000001f = EAX; + break; + /* Reserved/Unimplemented */ + case 0x80000003: + case 0x8000000a: + case 0x8000000f: + case 0x80000015 ... 0x80000017: + break; + default: +pentium_invalid_wrmsr: + cpu_log("WRMSR: Invalid MSR: %08X\n", ECX); + x86gpf(NULL, 0); break; } break; diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 429741839..42246d6ed 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -249,9 +249,25 @@ typedef struct { uint64_t amd_l2aar; /* 0xc0000089 - K6-III and later */ /* Pentium/Pentium MMX MSRs */ - uint32_t tr1; /* 0x00000002 - also on WinChip C6/2 */ - uint32_t tr12; /* 0x0000000e - also on WinChip C6/2 */ - uint32_t cesr; /* 0x00000011 - also on WinChip C6/2 */ + uint64_t mcar; /* 0x00000000 - also on K5 and (R/W) K6 */ + uint64_t mctr; /* 0x00000001 - also on K5 and (R/W) K6 */ + uint32_t tr1; /* 0x00000002 - also on WinChip C6/2 */ + uint32_t tr2; /* 0x00000004 - reserved on PMMX */ + uint32_t tr3; /* 0x00000005 */ + uint32_t tr4; /* 0x00000006 */ + uint32_t tr5; /* 0x00000007 */ + uint32_t tr6; /* 0x00000008 */ + uint32_t tr7; /* 0x00000009 */ + uint32_t tr9; /* 0x0000000b */ + uint32_t tr10; /* 0x0000000c */ + uint32_t tr11; /* 0x0000000d */ + uint32_t tr12; /* 0x0000000e - also on WinChip C6/2 and K6 */ + uint32_t cesr; /* 0x00000011 - also on WinChip C6/2 and Cx6x86MX */ + uint64_t pmc[2]; /* 0x00000012, 0x00000013 - also on WinChip C6/2 and Cx6x86MX */ + uint32_t fp_last_xcpt; /* 0x8000001b - undocumented */ + uint32_t probe_ctl; /* 0x8000001d - undocumented */ + uint32_t ecx8000001e; /* 0x8000001e - undocumented */ + uint32_t ecx8000001f; /* 0x8000001f - undocumented */ /* Pentium Pro/II MSRs */ uint64_t apic_base; /* 0x0000001b */ @@ -559,7 +575,6 @@ extern double bus_timing; extern double isa_timing; extern double pci_timing; extern double agp_timing; -extern uint64_t pmc[2]; extern uint16_t temp_seg_data[4]; extern uint16_t cs_msr; extern uint32_t esp_msr; From 65f40ca71d5ea23380ef43aff8de7d76cc97e797 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 4 Feb 2024 17:19:12 +0500 Subject: [PATCH 473/936] Implement missing WinChip C6/2 and Cyrix III MSRs --- src/cpu/cpu.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++---- src/cpu/cpu.h | 8 ++-- 2 files changed, 106 insertions(+), 11 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index fbdb85aa2..be322635f 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -2538,9 +2538,12 @@ cpu_ven_reset(void) switch (cpu_s->cpu_type) { case CPU_WINCHIP: case CPU_WINCHIP2: - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - if (cpu_s->cpu_type == CPU_WINCHIP2) - msr.fcr |= (1 << 18) | (1 << 20); + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + msr.mcr_ctrl = 0xf8000000; + if (cpu_s->cpu_type == CPU_WINCHIP2) { + msr.fcr |= (1 << 18) | (1 << 20); + msr.mcr_ctrl |= (1 << 17); + } break; case CPU_K6_2P: @@ -2602,11 +2605,11 @@ cpu_RDMSR(void) case CPU_WINCHIP2: EAX = EDX = 0; switch (ECX) { - /* TR1 - Test Register 1 */ + /* Pentium Processor Parity Reversal Register */ case 0x02: EAX = msr.tr1; break; - /* TR12 - Test Register 12 */ + /* Pentium Processor New Feature Control */ case 0x0e: EAX = msr.tr12; break; @@ -2619,6 +2622,16 @@ cpu_RDMSR(void) case 0x11: EAX = msr.cesr; break; + /* Performance Monitor - Event Counter 0 */ + case 0x12: + EAX = msr.pmc[0] & 0xffffffff; + EDX = msr.pmc[0] >> 32; + break; + /* Performance Monitor - Event Counter 1 */ + case 0x13: + EAX = msr.pmc[1] & 0xffffffff; + EDX = msr.pmc[1] >> 32; + break; /* Feature Control Register */ case 0x107: EAX = msr.fcr; @@ -2632,6 +2645,17 @@ cpu_RDMSR(void) case 0x10a: EAX = cpu_multi & 3; break; + /* Memory Configuration Register Control */ + case 0x120: + EAX = msr.mcr_ctrl; + break; + /* Unknown */ + case 0x131: + case 0x142 ... 0x145: + case 0x147: + case 0x150: + case 0x151: + break; } break; @@ -2675,6 +2699,29 @@ cpu_RDMSR(void) if (cpu_busspeed >= 84000000) EAX |= (1 << 19); break; + /* PERFCTR0 - Performance Counter Register 0 - aliased to TSC */ + case 0xc1: + EAX = tsc & 0xffffffff; + EDX = (tsc >> 32) & 0xff; + break; + /* PERFCTR1 - Performance Counter Register 1 */ + case 0xc2: + EAX = msr.ia32_pmc[1] & 0xffffffff; + EDX = msr.ia32_pmc[1] >> 32; + break; + /* BBL_CR_CTL3 - L2 Cache Control Register 3 */ + case 0x11e: + EAX = 0x800000; /* L2 cache disabled */ + break; + /* EVNTSEL0 - Performance Counter Event Select 0 - hardcoded */ + case 0x186: + EAX = 0x470079; + break; + /* EVNTSEL1 - Performance Counter Event Select 1 */ + case 0x187: + EAX = msr.evntsel1 & 0xffffffff; + EDX = msr.evntsel1 >> 32; + break; /* Feature Control Register */ case 0x1107: EAX = msr.fcr; @@ -3307,13 +3354,13 @@ cpu_WRMSR(void) case CPU_WINCHIP: case CPU_WINCHIP2: switch (ECX) { - /* TR1 - Test Register 1 */ + /* Pentium Processor Parity Reversal Register */ case 0x02: msr.tr1 = EAX & 2; break; - /* TR12 - Test Register 12 */ + /* Pentium Processor New Feature Control */ case 0x0e: - msr.tr12 = EAX & 0x228; + msr.tr12 = EAX & 0x248; break; /* Time Stamp Counter */ case 0x10: @@ -3323,6 +3370,14 @@ cpu_WRMSR(void) case 0x11: msr.cesr = EAX & 0xff00ff; break; + /* Performance Monitor - Event Counter 0 */ + case 0x12: + msr.pmc[0] = EAX | ((uint64_t) EDX << 32); + break; + /* Performance Monitor - Event Counter 1 */ + case 0x13: + msr.pmc[1] = EAX | ((uint64_t) EDX << 32); + break; /* Feature Control Register */ case 0x107: msr.fcr = EAX; @@ -3351,6 +3406,28 @@ cpu_WRMSR(void) case 0x109: msr.fcr3 = EAX | ((uint64_t) EDX << 32); break; + /* Memory Configuration Register 0..7 */ + case 0x110 ... 0x117: + temp = ECX - 0x110; + if (cpu_s->cpu_type == CPU_WINCHIP2) { + if (EAX & 0x1f) + msr.mcr_ctrl |= (1 << (temp + 9)); + else + msr.mcr_ctrl &= ~(1 << (temp + 9)); + } + msr.mcr[temp] = EAX | ((uint64_t) EDX << 32); + break; + /* Memory Configuration Register Control */ + case 0x120: + msr.mcr_ctrl = EAX & ((cpu_s->cpu_type == CPU_WINCHIP2) ? 0x1df : 0x1f); + break; + /* Unknown */ + case 0x131: + case 0x142 ... 0x145: + case 0x147: + case 0x150: + case 0x151: + break; } break; @@ -3365,6 +3442,22 @@ cpu_WRMSR(void) case 0x10: tsc = EAX | ((uint64_t) EDX << 32); break; + /* PERFCTR0 - Performance Counter Register 0 - aliased to TSC */ + case 0xc1: + break; + /* PERFCTR0 - Performance Counter Register 1 */ + case 0xc2: + msr.ia32_pmc[1] = EAX | ((uint64_t) EDX << 32); + break; + /* BBL_CR_CTL3 - L2 Cache Control Register 3 */ + case 0x11e: + /* EVNTSEL0 - Performance Counter Event Select 0 - hardcoded */ + case 0x186: + break; + /* EVNTSEL1 - Performance Counter Event Select 1 */ + case 0x187: + msr.evntsel1 = EAX | ((uint64_t) EDX << 32); + break; /* Feature Control Register */ case 0x1107: msr.fcr = EAX; diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 42246d6ed..8ff02d40d 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -232,9 +232,11 @@ typedef struct { uint64_t ibm_por2; /* 0x00001002 - 486SLC and later */ /* IDT WinChip C6/2/VIA Cyrix III MSRs */ - uint32_t fcr; /* 0x00000107 (IDT), 0x00001107 (VIA) */ - uint64_t fcr2; /* 0x00000108 (IDT), 0x00001108 (VIA) */ - uint64_t fcr3; /* 0x00000108 (IDT), 0x00001108 (VIA) */ + uint32_t fcr; /* 0x00000107 (IDT), 0x00001107 (VIA) */ + uint64_t fcr2; /* 0x00000108 (IDT), 0x00001108 (VIA) */ + uint64_t fcr3; /* 0x00000108 (IDT), 0x00001108 (VIA) */ + uint64_t mcr[8]; /* 0x00000110 - 0x00000117 (IDT) */ + uint32_t mcr_ctrl; /* 0x00000120 (IDT) */ /* AMD K5/K6 MSRs */ uint64_t amd_hwcr; /* 0x00000083 - all K5 and K6 */ From e54b57641c109b616410cbad2c6b2248ba6b6aef Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 4 Feb 2024 21:39:07 +0500 Subject: [PATCH 474/936] Implement missing IBM, AMD and Cyrix MSRs --- src/cpu/cpu.c | 139 +++++++++++++++++++++++++++++++++++++++++++------- src/cpu/cpu.h | 10 ++-- 2 files changed, 127 insertions(+), 22 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index be322635f..9b01b8ab7 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -2590,7 +2590,8 @@ cpu_RDMSR(void) /* Cache Region Control Register */ case 0x1001: - EAX = msr.ibm_crcr & 0xffffffffff; + EAX = msr.ibm_crcr & 0xffffffff; + EDX = (msr.ibm_crcr >> 32) & 0x0000ffff; break; /* Processor Operation Register */ @@ -2598,6 +2599,12 @@ cpu_RDMSR(void) if ((cpu_s->cpu_type > CPU_IBM386SLC) && cpu_s->multi) EAX = msr.ibm_por2 & 0x3f000000; break; + + /* Processor Control Register */ + case 0x1004: + if (cpu_s->cpu_type > CPU_IBM486SLC) + EAX = msr.ibm_pcr & 0x00d6001a; + break; } break; @@ -2780,12 +2787,20 @@ cpu_RDMSR(void) case CPU_K6_3: case CPU_K6_2P: case CPU_K6_3P: - EAX = EDX = 0; + EAX = 0; + /* EDX is left unchanged when reading this MSR! */ + if (ECX != 0x82) + EDX = 0; switch (ECX) { /* Machine Check Address Register */ case 0x00000000: + EAX = msr.mcar & 0xffffffff; + EDX = msr.mcar >> 32; + break; /* Machine Check Type Register */ case 0x00000001: + EAX = msr.mctr & 0xffffffff; + EDX = msr.mctr >> 32; break; /* Test Register 12 */ case 0x0000000e: @@ -2796,11 +2811,32 @@ cpu_RDMSR(void) EAX = tsc & 0xffffffff; EDX = tsc >> 32; break; + /* Array Access Register */ + case 0x00000082: + if (cpu_s->cpu_type > CPU_5K86) + goto amd_k_invalid_rdmsr; + EAX = msr.amd_aar & 0xffffffff; + /* EDX is left unchanged! */ + break; /* Hardware Configuration Register */ case 0x00000083: EAX = msr.amd_hwcr & 0xffffffff; EDX = msr.amd_hwcr >> 32; break; + /* Write Allocate Top-of-Memory and Control Register */ + case 0x00000085: + if (cpu_s->cpu_type != CPU_5K86) + goto amd_k_invalid_rdmsr; + EAX = msr.amd_watmcr & 0xffffffff; + EDX = msr.amd_watmcr >> 32; + break; + /* Write Allocate Programmable Memory Range Register */ + case 0x00000086: + if (cpu_s->cpu_type != CPU_5K86) + goto amd_k_invalid_rdmsr; + EAX = msr.amd_wapmrr & 0xffffffff; + EDX = msr.amd_wapmrr >> 32; + break; /* Extended Feature Enable Register */ case 0xc0000080: EAX = msr.amd_efer & 0xffffffff; @@ -3033,16 +3069,37 @@ pentium_invalid_rdmsr: case CPU_CxGX1: case CPU_Cx6x86MX: switch (ECX) { - /* Machine Check Exception Address */ - case 0x00: - /* Machine Check Exception Type */ - case 0x01: + /* Test Data */ + case 0x03: + EAX = msr.tr3; + break; + /* Test Address */ + case 0x04: + EAX = msr.tr4; + break; + /* Test Command/Status */ + case 0x05: + EAX = msr.tr5; break; /* Time Stamp Counter */ case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; break; + /* Performance Monitor - Control and Event Select */ + case 0x11: + EAX = msr.cesr; + break; + /* Performance Monitor - Event Counter 0 */ + case 0x12: + EAX = msr.pmc[0] & 0xffffffff; + EDX = msr.pmc[0] >> 32; + break; + /* Performance Monitor - Event Counter 1 */ + case 0x13: + EAX = msr.pmc[1] & 0xffffffff; + EDX = msr.pmc[1] >> 32; + break; } cpu_log("RDMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); break; @@ -3331,8 +3388,8 @@ cpu_WRMSR(void) switch (cpu_s->cpu_type) { case CPU_IBM386SLC: - case CPU_IBM486BL: case CPU_IBM486SLC: + case CPU_IBM486BL: switch (ECX) { /* Processor Operation Register */ case 0x1000: @@ -3341,13 +3398,18 @@ cpu_WRMSR(void) break; /* Cache Region Control Register */ case 0x1001: - msr.ibm_crcr = EAX & 0xffffffffff; + msr.ibm_crcr = EAX | ((uint64_t) (EDX & 0x0000ffff) << 32); break; /* Processor Operation Register */ case 0x1002: if ((cpu_s->cpu_type > CPU_IBM386SLC) && cpu_s->multi) msr.ibm_por2 = EAX & 0x3f000000; break; + /* Processor Control Register */ + case 0x1004: + if (cpu_s->cpu_type > CPU_IBM486SLC) + msr.ibm_pcr = EAX & 0x00d6001a; + break; } break; @@ -3521,22 +3583,45 @@ cpu_WRMSR(void) case CPU_K6_3P: switch (ECX) { /* Machine Check Address Register */ - case 0x00: + case 0x00000000: + if (cpu_s->cpu_type > CPU_5K86) + msr.mcar = EAX | ((uint64_t) EDX << 32); + break; /* Machine Check Type Register */ - case 0x01: + case 0x00000001: + if (cpu_s->cpu_type > CPU_5K86) + msr.mctr = EAX | ((uint64_t) EDX << 32); break; /* Test Register 12 */ - case 0x0e: - msr.tr12 = EAX & 0x228; + case 0x0000000e: + msr.tr12 = EAX & 0x8; break; /* Time Stamp Counter */ - case 0x10: + case 0x00000010: tsc = EAX | ((uint64_t) EDX << 32); break; + /* Array Access Register */ + case 0x00000082: + if (cpu_s->cpu_type > CPU_5K86) + goto amd_k_invalid_wrmsr; + msr.amd_aar = EAX | ((uint64_t) EDX << 32); + break; /* Hardware Configuration Register */ - case 0x83: + case 0x00000083: msr.amd_hwcr = EAX | ((uint64_t) EDX << 32); break; + /* Write Allocate Top-of-Memory and Control Register */ + case 0x00000085: + if (cpu_s->cpu_type != CPU_5K86) + goto amd_k_invalid_wrmsr; + msr.amd_watmcr = EAX | ((uint64_t) EDX << 32); + break; + /* Write Allocate Programmable Memory Range Register */ + case 0x00000086: + if (cpu_s->cpu_type != CPU_5K86) + goto amd_k_invalid_wrmsr; + msr.amd_wapmrr = EAX | ((uint64_t) EDX << 32); + break; /* Extended Feature Enable Register */ case 0xc0000080: temp = EAX | ((uint64_t) EDX << 32); @@ -3757,15 +3842,31 @@ pentium_invalid_wrmsr: case CPU_Cx6x86MX: cpu_log("WRMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); switch (ECX) { - /* Machine Check Exception Address */ - case 0x00: - /* Machine Check Exception Type */ - case 0x01: - break; + /* Test Data */ + case 0x03: + msr.tr3 = EAX; + /* Test Address */ + case 0x04: + msr.tr4 = EAX; + /* Test Command/Status */ + case 0x05: + msr.tr5 = EAX & 0x008f0f3b; /* Time Stamp Counter */ case 0x10: tsc = EAX | ((uint64_t) EDX << 32); break; + /* Performance Monitor - Control and Event Select */ + case 0x11: + msr.cesr = EAX & 0x7ff07ff; + break; + /* Performance Monitor - Event Counter 0 */ + case 0x12: + msr.pmc[0] = EAX | ((uint64_t) EDX << 32); + break; + /* Performance Monitor - Event Counter 1 */ + case 0x13: + msr.pmc[1] = EAX | ((uint64_t) EDX << 32); + break; } break; #endif diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 8ff02d40d..3a6d73cd4 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -230,6 +230,7 @@ typedef struct { uint64_t ibm_por; /* 0x00001000 - 386SLC and later */ uint64_t ibm_crcr; /* 0x00001001 - 386SLC and later */ uint64_t ibm_por2; /* 0x00001002 - 486SLC and later */ + uint64_t ibm_pcr; /* 0x00001004 - 486BL3 */ /* IDT WinChip C6/2/VIA Cyrix III MSRs */ uint32_t fcr; /* 0x00000107 (IDT), 0x00001107 (VIA) */ @@ -239,11 +240,14 @@ typedef struct { uint32_t mcr_ctrl; /* 0x00000120 (IDT) */ /* AMD K5/K6 MSRs */ - uint64_t amd_hwcr; /* 0x00000083 - all K5 and K6 */ + uint64_t amd_aar; /* 0x00000082 - all K5 */ + uint64_t amd_hwcr; /* 0x00000083 - all K5 and all K6 */ + uint64_t amd_watmcr; /* 0x00000085 - K5 Model 1 and later */ + uint64_t amd_wapmrr; /* 0x00000086 - K5 Model 1 and later */ - uint64_t amd_efer; /* 0xc0000080 - all K5 and K6 */ + uint64_t amd_efer; /* 0xc0000080 - all K5 and all K6 */ uint64_t amd_star; /* 0xc0000081 - K6-2 and later */ - uint64_t amd_whcr; /* 0xc0000082 - all K5 and K6 */ + uint64_t amd_whcr; /* 0xc0000082 - all K5 and all K6 */ uint64_t amd_uwccr; /* 0xc0000085 - K6-2C and later */ uint64_t amd_epmr; /* 0xc0000086 - K6-III+/2+ only */ uint64_t amd_psor; /* 0xc0000087 - K6-2C and later */ From 996769095bff9330c9673a5ec2031bc9bd03bc08 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 5 Feb 2024 17:03:10 +0500 Subject: [PATCH 475/936] Implement most missing P6 MSRs Remove the 6 extraneous performance counter MSRs which haven't existed on P6 --- src/cpu/cpu.c | 163 ++++++++++++++++++++++++++++++++++++++++---------- src/cpu/cpu.h | 11 ++-- 2 files changed, 139 insertions(+), 35 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 9b01b8ab7..4398df36c 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -2713,8 +2713,8 @@ cpu_RDMSR(void) break; /* PERFCTR1 - Performance Counter Register 1 */ case 0xc2: - EAX = msr.ia32_pmc[1] & 0xffffffff; - EDX = msr.ia32_pmc[1] >> 32; + EAX = msr.perfctr[1] & 0xffffffff; + EDX = msr.perfctr[1] >> 32; break; /* BBL_CR_CTL3 - L2 Cache Control Register 3 */ case 0x11e: @@ -2726,8 +2726,8 @@ cpu_RDMSR(void) break; /* EVNTSEL1 - Performance Counter Event Select 1 */ case 0x187: - EAX = msr.evntsel1 & 0xffffffff; - EDX = msr.evntsel1 >> 32; + EAX = msr.evntsel[1] & 0xffffffff; + EDX = msr.evntsel[1] >> 32; break; /* Feature Control Register */ case 0x1107: @@ -3124,13 +3124,16 @@ pentium_invalid_rdmsr: break; /* IA32_PLATFORM_ID - Platform ID */ case 0x17: - if (cpu_s->cpu_type != CPU_PENTIUM2D) + if (cpu_s->cpu_type < CPU_PENTIUM2D) goto i686_invalid_rdmsr; if (cpu_f->package == CPU_PKG_SLOT2) - EDX |= 0x80000; + EDX |= (1 << 19); else if (cpu_f->package == CPU_PKG_SOCKET370) - EDX |= 0x100000; + EDX |= (1 << 20); + break; + /* Unknown */ + case 0x18: break; /* IA32_APIC_BASE - APIC Base Address */ case 0x1B: @@ -3143,6 +3146,11 @@ pentium_invalid_rdmsr: EAX = msr.ecx20 & 0xffffffff; EDX = msr.ecx20 >> 32; break; + /* Unknown */ + case 0x21: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_rdmsr; + break; /* EBL_CR_POWERON - Processor Hard Power-On Configuration */ case 0x2a: EAX = 0xc4000000; @@ -3178,6 +3186,21 @@ pentium_invalid_rdmsr: EAX |= (1 << 19); } break; + /* Unknown */ + case 0x32: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_rdmsr; + break; + /* TEST_CTL - Test Control Register */ + case 0x33: + EAX = msr.test_ctl; + break; + /* Unknown */ + case 0x34: + case 0x3a: + case 0x3b: + case 0x50 ... 0x54: + break; /* BIOS_UPDT_TRIG - BIOS Update Trigger */ case 0x79: EAX = msr.bios_updt & 0xffffffff; @@ -3189,10 +3212,15 @@ pentium_invalid_rdmsr: EAX = msr.bbl_cr_dx[ECX - 0x88] & 0xffffffff; EDX = msr.bbl_cr_dx[ECX - 0x88] >> 32; break; - /* PERFCTR0 ... PERFCTR7 - Performance Counter Register 0..7 */ - case 0xc1 ... 0xc8: - EAX = msr.ia32_pmc[ECX - 0xC1] & 0xffffffff; - EDX = msr.ia32_pmc[ECX - 0xC1] >> 32; + /* Unknown */ + case 0xae: + break; + /* PERFCTR0 - Performance Counter Register 0 */ + case 0xc1: + /* PERFCTR1 - Performance Counter Register 1 */ + case 0xc2: + EAX = msr.perfctr[ECX - 0xC1] & 0xffffffff; + EDX = msr.perfctr[ECX - 0xC1] >> 32; break; /* MTRRcap */ case 0xfe: @@ -3229,6 +3257,13 @@ pentium_invalid_rdmsr: EAX = msr.bbl_cr_ctl3 & 0xffffffff; EDX = msr.bbl_cr_ctl3 >> 32; break; + /* Unknown */ + case 0x131: + case 0x14e ... 0x151: + case 0x154: + case 0x15b: + case 0x15f: + break; /* SYSENTER_CS - SYSENTER target CS */ case 0x174: if (cpu_s->cpu_type == CPU_PENTIUMPRO) @@ -3269,23 +3304,30 @@ pentium_invalid_rdmsr: break; /* EVNTSEL0 - Performance Counter Event Select 0 */ case 0x186: - EAX = msr.evntsel0 & 0xffffffff; - EDX = msr.evntsel0 >> 32; - break; /* EVNTSEL1 - Performance Counter Event Select 1 */ case 0x187: - EAX = msr.evntsel1 & 0xffffffff; - EDX = msr.evntsel1 >> 32; + EAX = msr.evntsel[ECX - 0x186] & 0xffffffff; + EDX = msr.evntsel[ECX - 0x186] >> 32; + break; + /* Unknown */ + case 0x1d3: break; /* DEBUGCTLMSR - Debugging Control Register */ case 0x1d9: - EAX = msr.debug_ctl & 0xffffffff; - EDX = msr.debug_ctl >> 32; + EAX = msr.debug_ctl; + break; + /* LASTBRANCHFROMIP - address from which a branch was last taken */ + case 0x1db: + /* LASTBRANCHTOIP - destination address of the last taken branch instruction */ + case 0x1dc: + /* LASTINTFROMIP - address at which an interrupt last occurred */ + case 0x1dd: + /* LASTINTTOIP - address to which the last interrupt caused a branch */ + case 0x1de: break; /* ROB_CR_BKUPTMPDR6 */ case 0x1e0: - EAX = msr.rob_cr_bkuptmpdr6 & 0xffffffff; - EDX = msr.rob_cr_bkuptmpdr6 >> 32; + EAX = msr.rob_cr_bkuptmpdr6; break; /* ECX & 0: MTRRphysBase0 ... MTRRphysBase7 ECX & 1: MTRRphysMask0 ... MTRRphysMask7 */ @@ -3320,9 +3362,16 @@ pentium_invalid_rdmsr: break; /* Page Attribute Table */ case 0x277: + if (cpu_s->cpu_type < CPU_PENTIUM2D) + goto i686_invalid_rdmsr; EAX = msr.pat & 0xffffffff; EDX = msr.pat >> 32; break; + /* Unknown */ + case 0x280: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_rdmsr; + break; /* MTRRdefType */ case 0x2ff: EAX = msr.mtrr_deftype & 0xffffffff; @@ -3367,6 +3416,12 @@ pentium_invalid_rdmsr: EAX = msr.ecx570 & 0xffffffff; EDX = msr.ecx570 >> 32; break; + /* Unknown, possibly debug registers? */ + case 0x1000 ... 0x1007: + /* Unknown, possibly control registers? */ + case 0x2000: + case 0x2002 ... 0x2004: + break; default: i686_invalid_rdmsr: cpu_log("RDMSR: Invalid MSR: %08X\n", ECX); @@ -3509,7 +3564,7 @@ cpu_WRMSR(void) break; /* PERFCTR0 - Performance Counter Register 1 */ case 0xc2: - msr.ia32_pmc[1] = EAX | ((uint64_t) EDX << 32); + msr.perfctr[1] = EAX | ((uint64_t) EDX << 32); break; /* BBL_CR_CTL3 - L2 Cache Control Register 3 */ case 0x11e: @@ -3518,7 +3573,7 @@ cpu_WRMSR(void) break; /* EVNTSEL1 - Performance Counter Event Select 1 */ case 0x187: - msr.evntsel1 = EAX | ((uint64_t) EDX << 32); + msr.evntsel[1] = EAX | ((uint64_t) EDX << 32); break; /* Feature Control Register */ case 0x1107: @@ -3888,6 +3943,9 @@ pentium_invalid_wrmsr: case 0x10: tsc = EAX | ((uint64_t) EDX << 32); break; + /* Unknown */ + case 0x18: + break; /* IA32_APIC_BASE - APIC Base Address */ case 0x1b: cpu_log("APIC_BASE write: %08X%08X\n", EDX, EAX); @@ -3899,9 +3957,29 @@ pentium_invalid_wrmsr: case 0x20: msr.ecx20 = EAX | ((uint64_t) EDX << 32); break; + /* Unknown */ + case 0x21: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_wrmsr; + break; /* EBL_CR_POWERON - Processor Hard Power-On Configuration */ case 0x2a: break; + /* Unknown */ + case 0x32: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_wrmsr; + break; + /* TEST_CTL - Test Control Register */ + case 0x33: + msr.test_ctl = EAX; + break; + /* Unknown */ + case 0x34: + case 0x3a: + case 0x3b: + case 0x50 ... 0x54: + break; /* BIOS_UPDT_TRIG - BIOS Update Trigger */ case 0x79: msr.bios_updt = EAX | ((uint64_t) EDX << 32); @@ -3911,9 +3989,14 @@ pentium_invalid_wrmsr: case 0x88 ... 0x8b: msr.bbl_cr_dx[ECX - 0x88] = EAX | ((uint64_t) EDX << 32); break; - /* PERFCTR0 ... PERFCTR7 - Performance Counter Register 0..7 */ - case 0xc1 ... 0xc8: - msr.ia32_pmc[ECX - 0xC1] = EAX | ((uint64_t) EDX << 32); + /* Unknown */ + case 0xae: + break; + /* PERFCTR0 - Performance Counter Register 0 */ + case 0xc1: + /* PERFCTR1 - Performance Counter Register 1 */ + case 0xc2: + msr.perfctr[ECX - 0xC1] = EAX | ((uint64_t) EDX << 32); break; /* MTRRcap */ case 0xfe: @@ -3943,6 +4026,13 @@ pentium_invalid_wrmsr: case 0x11e: msr.bbl_cr_ctl3 = EAX | ((uint64_t) EDX << 32); break; + /* Unknown */ + case 0x131: + case 0x14e ... 0x151: + case 0x154: + case 0x15b: + case 0x15f: + break; /* SYSENTER_CS - SYSENTER target CS */ case 0x174: if (cpu_s->cpu_type == CPU_PENTIUMPRO) @@ -3978,19 +4068,19 @@ pentium_invalid_wrmsr: break; /* EVNTSEL0 - Performance Counter Event Select 0 */ case 0x186: - msr.evntsel0 = EAX | ((uint64_t) EDX << 32); - break; /* EVNTSEL1 - Performance Counter Event Select 1 */ case 0x187: - msr.evntsel1 = EAX | ((uint64_t) EDX << 32); + msr.evntsel[ECX - 0x186] = EAX | ((uint64_t) EDX << 32); + break; + case 0x1d3: break; /* DEBUGCTLMSR - Debugging Control Register */ case 0x1d9: - msr.debug_ctl = EAX | ((uint64_t) EDX << 32); + msr.debug_ctl = EAX; break; /* ROB_CR_BKUPTMPDR6 */ case 0x1e0: - msr.rob_cr_bkuptmpdr6 = EAX | ((uint64_t) EDX << 32); + msr.rob_cr_bkuptmpdr6 = EAX; break; /* ECX & 0: MTRRphysBase0 ... MTRRphysBase7 ECX & 1: MTRRphysMask0 ... MTRRphysMask7 */ @@ -4018,8 +4108,15 @@ pentium_invalid_wrmsr: break; /* Page Attribute Table */ case 0x277: + if (cpu_s->cpu_type < CPU_PENTIUM2D) + goto i686_invalid_wrmsr; msr.pat = EAX | ((uint64_t) EDX << 32); break; + /* Unknown */ + case 0x280: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_wrmsr; + break; /* MTRRdefType */ case 0x2ff: msr.mtrr_deftype = EAX | ((uint64_t) EDX << 32); @@ -4063,6 +4160,12 @@ pentium_invalid_wrmsr: case 0x570: msr.ecx570 = EAX | ((uint64_t) EDX << 32); break; + /* Unknown, possibly debug registers? */ + case 0x1000 ... 0x1007: + /* Unknown, possibly control registers? */ + case 0x2000: + case 0x2002 ... 0x2004: + break; default: i686_invalid_wrmsr: cpu_log("WRMSR: Invalid MSR: %08X\n", ECX); diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 3a6d73cd4..c829a0e17 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -277,10 +277,11 @@ typedef struct { /* Pentium Pro/II MSRs */ uint64_t apic_base; /* 0x0000001b */ + uint32_t test_ctl; /* 0x00000033 */ uint64_t bios_updt; /* 0x00000079 */ uint64_t bbl_cr_dx[4]; /* 0x00000088 - 0x0000008b */ - uint64_t ia32_pmc[8]; /* 0x000000c1 - 0x000000c8 */ + uint64_t perfctr[2]; /* 0x000000c1, 0x000000c2 */ uint64_t mtrr_cap; /* 0x000000fe */ uint64_t bbl_cr_addr; /* 0x00000116 */ @@ -295,10 +296,10 @@ typedef struct { uint32_t sysenter_eip; /* 0x00000176 - Pentium II and later */ uint64_t mcg_ctl; /* 0x0000017b */ - uint64_t evntsel0; /* 0x00000186 */ - uint64_t evntsel1; /* 0x00000187 */ - uint64_t debug_ctl; /* 0x000001d9 */ - uint64_t rob_cr_bkuptmpdr6; /* 0x000001e0 */ + uint64_t evntsel[2]; /* 0x00000186, 0x00000187 */ + + uint32_t debug_ctl; /* 0x000001d9 */ + uint32_t rob_cr_bkuptmpdr6; /* 0x000001e0 */ /* MTTR-related MSRs also present on the VIA Cyrix III */ uint64_t mtrr_physbase[8]; /* 0x00000200 - 0x0000020f (ECX & 0) */ From 5ce8b9e1a1f398314d63d4155daa30c825f8607f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 8 Feb 2024 00:34:29 +0600 Subject: [PATCH 476/936] 24-bpp image blit fixes --- src/video/vid_c&t_69000.c | 130 +++++++++++++++++++++++++++----------- 1 file changed, 92 insertions(+), 38 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index ee83ba6a9..60afb8d65 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -35,6 +35,7 @@ #include <86box/i2c.h> #include <86box/vid_ddc.h> #include <86box/plat_unused.h> +#include <86box/bswap.h> #include #pragma pack(push, 1) @@ -352,7 +353,6 @@ chips_69000_do_rop_16bpp(uint16_t *dst, uint16_t src, uint8_t rop) void chips_69000_do_rop_24bpp(uint32_t *dst, uint32_t src, uint8_t rop) { - uint32_t orig_dst = *dst & 0xFF000000; switch (rop) { case 0x00: *dst = 0; @@ -402,8 +402,6 @@ chips_69000_do_rop_24bpp(uint32_t *dst, uint32_t src, uint8_t rop) *dst = 0xFF; break; } - *dst &= 0xFFFFFF; - *dst |= orig_dst; } void @@ -868,15 +866,15 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) } if (chips->bitblt_running.bytes_per_pixel == 3) { pattern_pixel = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr - + (3 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + + (4 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)), chips); pattern_pixel |= chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr - + (3 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + + (4 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)) + 1, chips) << 8; pattern_pixel |= chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr - + (3 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + + (4 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)) + 2, chips) << 16; } } @@ -962,21 +960,6 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) void chips_69000_process_mono_data(UNUSED(chips_69000_t* chips), uint64_t val) { - /* Notes: - Reserved value of 0b000 for monochrome source alignment makes it use Destination Scanline Width. - - TODO: - Actually implement this. - - Figure out how alignment works. The example provided is unclear about non-quadword alignment. - (Outside of the one xf86-video-chips already documents). - Maybe it merely advances the source address pointer by alignment after consuming a byte. - - Edit: It actually consumes all 8 bytes of the quadword before incrementing the pitch. - Which begs the next question: Are those 8 bytes for same-scanline drawing or for y-incremented drawing? - And is 4-byte-or-less alignment relevant for our purposes? The Monochrome Source Register only talks about quadwords, nothing else. - */ - uint64_t i = 0; uint8_t is_true = 0; int orig_x = chips->bitblt_running.x; @@ -1276,6 +1259,7 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { } if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { + int orig_cycles = cycles; chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0) { chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); @@ -1325,6 +1309,7 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { mono_data |= (uint64_t)chips->bitblt_running.bytes_port[7] << 56ull; chips_69000_process_mono_data(chips, mono_data); } + cycles = orig_cycles; return; } @@ -1334,16 +1319,18 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { } chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; if (chips->bitblt_running.bytes_written == chips->bitblt_running.bytes_per_pixel) { + int orig_cycles = cycles; uint32_t source_pixel = chips->bitblt_running.bytes_port[0]; chips->bitblt_running.bytes_written = 0; - if (chips->bitblt_running.bytes_per_pixel == 2) + if (chips->bitblt_running.bytes_per_pixel >= 2) source_pixel |= (chips->bitblt_running.bytes_port[1] << 8); - if (chips->bitblt_running.bytes_per_pixel == 3) + if (chips->bitblt_running.bytes_per_pixel >= 3) source_pixel |= (chips->bitblt_running.bytes_port[2] << 16); chips->bitblt_running.bytes_in_line_written += chips->bitblt_running.bytes_per_pixel; chips_69000_process_pixel(chips, source_pixel); + cycles = orig_cycles; chips->bitblt_running.x += chips->bitblt_running.x_dir; if (chips->bitblt_running.bytes_in_line_written >= chips->bitblt_running.bitblt.destination_width) { @@ -1504,6 +1491,7 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) case 0xA0: chips->ext_regs[chips->ext_index] = val; chips->svga.hwcursor.ena = ((val & 7) == 0b101) || ((val & 7) == 0b1); + chips->svga.hwcursor.cur_xsize = chips->svga.hwcursor.cur_ysize = ((val & 7) == 0b1) ? 32 : 64; break; case 0xA2: chips->ext_regs[chips->ext_index] = val; @@ -1529,6 +1517,12 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) chips->ext_regs[chips->ext_index] = val; chips->svga.hwcursor.y = chips->ext_regs[0xA6] | (val & 7) << 8; break; + case 0xC8: + case 0xC9: + case 0xCB: + chips->ext_regs[chips->ext_index] = val; + svga_recalctimings(&chips->svga); + break; case 0xD2: break; default: @@ -1575,6 +1569,14 @@ chips_69000_out(uint16_t addr, uint8_t val, void *p) val <<= 2; svga->fullchange = svga->monitor->mon_changeframecount; switch (svga->dac_pos) { + case 0: + svga->dac_r = val; + svga->dac_pos++; + break; + case 1: + svga->dac_g = val; + svga->dac_pos++; + break; case 2: index = svga->dac_addr & 7; chips->cursor_palette[index].r = svga->dac_r; @@ -2153,44 +2155,49 @@ chips_69000_hwcursor_draw(svga_t *svga, int displine) { chips_69000_t *chips = (chips_69000_t *) svga->priv; uint64_t dat[2]; - int offset = svga->hwcursor_latch.x; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; +#if 0 if ((chips->ext_regs[0xA0] & 7) == 1) { + uint32_t oddaddr = (displine - svga->hwcursor_latch.y) & 1; + uint32_t dat_32[2]; if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += (svga->hwcursor_on & 1) ? 8 : 4; + svga->hwcursor_latch.addr += oddaddr ? 8 : 4; - dat[0] = *(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr]); - dat[1] = *(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr + 8]); - svga->hwcursor_latch.addr += (svga->hwcursor_on & 1) ? 8 : 4; + dat_32[1] = bswap32(*(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr])); + dat_32[0] = bswap32(*(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr + 8])); + svga->hwcursor_latch.addr += oddaddr ? 4 : 8; for (uint8_t x = 0; x < 32; x++) { - if (!(dat[1] & (1ULL << 31))) - svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 31)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[4]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[5]); - else if (dat[0] & (1ULL << 31)) + if (!(dat_32[1] & (1ULL << 31))) + svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat_32[0] & (1ULL << 31)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[4]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[5]); + else if (dat_32[0] & (1ULL << 31)) svga->monitor->target_buffer->line[displine][offset + svga->x_add] ^= 0xffffff; offset++; - dat[0] <<= 1; - dat[1] <<= 1; + dat_32[0] <<= 1; + dat_32[1] <<= 1; } if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += (svga->hwcursor_on & 1) ? 8 : 4; + svga->hwcursor_latch.addr += oddaddr ? 8 : 4; return; } +#endif if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += (chips->ext_regs[0xA0] & 7) == 1 ? 8 : 16; + svga->hwcursor_latch.addr += 16; - dat[0] = *(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr]); - dat[1] = *(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr + 8]); + dat[1] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr])); + dat[0] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr + 8])); svga->hwcursor_latch.addr += 16; switch (chips->ext_regs[0xa0] & 7) { + case 0b1: case 0b101: for (uint8_t x = 0; x < 64; x++) { if (!(dat[1] & (1ULL << 63))) - svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[1]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[0]); + svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[4]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[5]); else if (dat[0] & (1ULL << 63)) svga->monitor->target_buffer->line[displine][offset + svga->x_add] ^= 0xffffff; @@ -2208,6 +2215,51 @@ chips_69000_hwcursor_draw(svga_t *svga, int displine) svga->hwcursor_latch.addr += 16; } +static float +chips_69000_getclock(int clock, void *priv) +{ + const chips_69000_t *chips = (chips_69000_t *) priv; + + if (clock == 0) + return 25175000.0; + if (clock == 1) + return 28322000.0; + + int m = chips->ext_regs[0xc8]; + int n = chips->ext_regs[0xc9]; + int pl = (chips->ext_regs[0xcb] >> 4) & 7; + + float fvco = 14318181.0 * ((float)(m + 2) / (float)(n + 2)); + if (chips->ext_regs[0xcb] & 4) + fvco *= 4.0; + float fo = fvco / (float)(1 << pl); + + return fo; +} + +uint32_t +chips_69000_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) +{ + uint32_t ret = 0x00000000; + + if (svga->lut_map) { + if (bpp == 15) { + uint8_t b = getcolr(svga->pallook[(color & 0x1f) << 3]); + uint8_t g = getcolg(svga->pallook[(color & 0x3e0) >> 2]); + uint8_t r = getcolb(svga->pallook[(color & 0x7c00) >> 7]); + ret = (video_15to32[color] & 0xFF000000) | makecol(r, g, b); + } else { + uint8_t b = getcolr(svga->pallook[(color & 0x1f) << 3]); + uint8_t g = getcolg(svga->pallook[(color & 0x7e0) >> 3]); + uint8_t r = getcolb(svga->pallook[(color & 0xf800) >> 8]); + ret = (video_16to32[color] & 0xFF000000) | makecol(r, g, b); + } + } else + ret = (bpp == 15) ? video_15to32[color] : video_16to32[color]; + + return ret; +} + static void * chips_69000_init(const device_t *info) { @@ -2236,6 +2288,8 @@ chips_69000_init(const device_t *info) chips->svga.recalctimings_ex = chips_69000_recalctimings; chips->svga.vblank_start = chips_69000_vblank_start; chips->svga.hwcursor_draw = chips_69000_hwcursor_draw; + chips->svga.getclock = chips_69000_getclock; + chips->svga.conv_16to32 = chips_69000_conv_16to32; mem_mapping_add(&chips->linear_mapping, 0, 0, chips_69000_readb_linear, chips_69000_readw_linear, chips_69000_readl_linear, chips_69000_writeb_linear, chips_69000_writew_linear, chips_69000_writel_linear, NULL, MEM_MAPPING_EXTERNAL, chips); From 89cc2a3956e5d9dda3d0939765dd1fcbf96cb38f Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 7 Feb 2024 20:45:45 +0100 Subject: [PATCH 477/936] NEC CD-ROM: Make command DAh not also set speed. --- src/scsi/scsi_cdrom.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index f52401785..a6420fb01 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -1864,7 +1864,9 @@ begin: cdrom_audio_pause_resume(dev->drv, 0x00); dev->drv->audio_op = 0x01; scsi_cdrom_command_complete(dev); - break; + if ((dev->packet_status == PHASE_COMPLETE) || (dev->packet_status == PHASE_ERROR)) + scsi_cdrom_buf_free(dev); + return; } fallthrough; case GPCMD_SET_SPEED: From ca11dae903736cabc34adb3321630e2f57162162 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 7 Feb 2024 20:56:25 +0100 Subject: [PATCH 478/936] Fix SVGA code warnings. See above. --- src/video/vid_svga.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index d982a1ada..edb05086a 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -573,10 +573,10 @@ svga_recalctimings(svga_t *svga) double _dispontime; double _dispofftime; double disptime; - double crtcconst8514; - double _dispontime8514; - double _dispofftime8514; - double disptime8514; + double crtcconst8514 = 0.0; + double _dispontime8514 = 0.0; + double _dispofftime8514 = 0.0; + double disptime8514 = 0.0; #ifdef ENABLE_SVGA_LOG int vsyncend; int vblankend; @@ -998,7 +998,6 @@ void svga_poll(void *priv) { svga_t *svga = (svga_t *) priv; - ibm8514_t *dev = (ibm8514_t *) svga->dev8514; xga_t *xga = (xga_t *) svga->xga; uint32_t x; uint32_t blink_delay; From 395941aa54a30aaba1709f3db42ac67c2f9f2abf Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 8 Feb 2024 02:07:49 +0600 Subject: [PATCH 479/936] HWCursor work --- src/video/vid_c&t_69000.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 60afb8d65..df41e9095 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -207,6 +207,8 @@ chips_69000_read_flat_panel(chips_69000_t* chips) case 0: /* Report no presence of flat panel module. */ return 0; + case 1: + return 1; default: return chips->flat_panel_regs[chips->flat_panel_index]; } @@ -745,6 +747,10 @@ chips_69000_recalctimings(svga_t *svga) svga->interlace = !!(svga->crtc[0x70] & 0x80); + if (svga->dispend == 2002 && svga->hdisp == 1024) { + svga->dispend = 1280; + } + switch (chips->ext_regs[0x81] & 0xF) { case 0b0010: svga->bpp = 8; @@ -1413,6 +1419,9 @@ chips_69000_read_ext_reg(chips_69000_t* chips) case 0x71: val = 0x0; break; + case 0xD0: + val |= 1; + break; } // if (chips->ext_index != 0x4E && chips->ext_index != 0x4F // && (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) @@ -2189,13 +2198,21 @@ chips_69000_hwcursor_draw(svga_t *svga, int displine) if (svga->interlace && svga->hwcursor_oddeven) svga->hwcursor_latch.addr += 16; - dat[1] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr])); - dat[0] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr + 8])); - svga->hwcursor_latch.addr += 16; + if ((svga->hwcursor_on & 1) && (chips->ext_regs[0xa0] & 7) == 0b1) { + dat[1] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr - 16])); + dat[0] = bswap64(*(uint64_t *) (&svga->vram[(svga->hwcursor_latch.addr - 16) + 8])); + dat[1] <<= 32ULL; + dat[0] <<= 32ULL; + } + else { + dat[1] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr])); + dat[0] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr + 8])); + svga->hwcursor_latch.addr += 16; + } switch (chips->ext_regs[0xa0] & 7) { case 0b1: case 0b101: - for (uint8_t x = 0; x < 64; x++) { + for (uint8_t x = 0; x < (((chips->ext_regs[0xa0] & 7) == 0b1) ? 32 : 64); x++) { if (!(dat[1] & (1ULL << 63))) svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[4]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[5]); else if (dat[0] & (1ULL << 63)) From a0078e6d2b6e915afd15edb633f5812904dfb52d Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 8 Feb 2024 13:22:01 +0600 Subject: [PATCH 480/936] Fix inverted hardware cursor color --- src/video/vid_c&t_69000.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index df41e9095..8128c8086 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -1157,6 +1157,10 @@ chips_69000_setup_bitblt(chips_69000_t* chips) } return; } + + if (chips->bitblt_running.x_dir == -1 && chips->bitblt_running.bytes_per_pixel == 3) { + //chips->bitblt_running.actual_destination_width++; + } if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { uint32_t source_addr = chips->bitblt_running.bitblt.source_addr; @@ -2168,14 +2172,12 @@ chips_69000_hwcursor_draw(svga_t *svga, int displine) #if 0 if ((chips->ext_regs[0xA0] & 7) == 1) { - uint32_t oddaddr = (displine - svga->hwcursor_latch.y) & 1; + uint32_t evenline = svga->hwcursor_latch.cur_ysize - ((svga->hwcursor_on) & ~1) >> 1; uint32_t dat_32[2]; - if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += oddaddr ? 8 : 4; - dat_32[1] = bswap32(*(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr])); - dat_32[0] = bswap32(*(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr + 8])); - svga->hwcursor_latch.addr += oddaddr ? 4 : 8; + dat_32[1] = bswap32(*(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr + (((displine - svga->hwcursor_latch.y) & 1) ? 4 : 0)])); + dat_32[0] = bswap32(*(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr + 8 + (((displine - svga->hwcursor_latch.y) & 1) ? 4 : 0)])); + svga->hwcursor_latch.addr = svga->hwcursor.addr + (evenline * 16); for (uint8_t x = 0; x < 32; x++) { if (!(dat_32[1] & (1ULL << 31))) @@ -2188,9 +2190,6 @@ chips_69000_hwcursor_draw(svga_t *svga, int displine) dat_32[1] <<= 1; } - if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += oddaddr ? 8 : 4; - return; } #endif @@ -2214,7 +2213,7 @@ chips_69000_hwcursor_draw(svga_t *svga, int displine) case 0b101: for (uint8_t x = 0; x < (((chips->ext_regs[0xa0] & 7) == 0b1) ? 32 : 64); x++) { if (!(dat[1] & (1ULL << 63))) - svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[4]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[5]); + svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[5]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[4]); else if (dat[0] & (1ULL << 63)) svga->monitor->target_buffer->line[displine][offset + svga->x_add] ^= 0xffffff; From 4a087b81c64f0d5195127367ccf9d620799bcd28 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 8 Feb 2024 15:51:15 +0600 Subject: [PATCH 481/936] Fix RTL BitBlt on 16+ bpp --- src/video/vid_c&t_69000.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 8128c8086..2e11764d9 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -1128,6 +1128,8 @@ chips_69000_setup_bitblt(chips_69000_t* chips) case 1: chips->bitblt_running.x_dir = -1; chips->bitblt_running.y_dir = 1; + chips->bitblt_running.bitblt.source_addr -= (chips->bitblt_running.bytes_per_pixel - 1); + chips->bitblt_running.bitblt.destination_addr -= (chips->bitblt_running.bytes_per_pixel - 1); break; case 2: chips->bitblt_running.x_dir = 1; @@ -1136,6 +1138,8 @@ chips_69000_setup_bitblt(chips_69000_t* chips) case 3: chips->bitblt_running.x_dir = -1; chips->bitblt_running.y_dir = -1; + chips->bitblt_running.bitblt.source_addr -= (chips->bitblt_running.bytes_per_pixel - 1); + chips->bitblt_running.bitblt.destination_addr -= (chips->bitblt_running.bytes_per_pixel - 1); break; } @@ -1517,18 +1521,26 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) case 0xA4: chips->ext_regs[chips->ext_index] = val; chips->svga.hwcursor.x = val | (chips->ext_regs[0xA5] & 7) << 8; + if (chips->ext_regs[0xA5] & 0x80) + chips->svga.hwcursor.x = -chips->svga.hwcursor.x; break; case 0xA5: chips->ext_regs[chips->ext_index] = val; chips->svga.hwcursor.x = chips->ext_regs[0xA4] | (val & 7) << 8; + if (chips->ext_regs[0xA5] & 0x80) + chips->svga.hwcursor.x = -chips->svga.hwcursor.x; break; case 0xA6: chips->ext_regs[chips->ext_index] = val; chips->svga.hwcursor.y = val | (chips->ext_regs[0xA7] & 7) << 8; + if (chips->ext_regs[0xA7] & 0x80) + chips->svga.hwcursor.y = -chips->svga.hwcursor.y; break; case 0xA7: chips->ext_regs[chips->ext_index] = val; chips->svga.hwcursor.y = chips->ext_regs[0xA6] | (val & 7) << 8; + if (chips->ext_regs[0xA7] & 0x80) + chips->svga.hwcursor.y = -chips->svga.hwcursor.y; break; case 0xC8: case 0xC9: @@ -2213,9 +2225,9 @@ chips_69000_hwcursor_draw(svga_t *svga, int displine) case 0b101: for (uint8_t x = 0; x < (((chips->ext_regs[0xa0] & 7) == 0b1) ? 32 : 64); x++) { if (!(dat[1] & (1ULL << 63))) - svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[5]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[4]); + svga->monitor->target_buffer->line[displine & 2047][(offset + svga->x_add) & 2047] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[5]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[4]); else if (dat[0] & (1ULL << 63)) - svga->monitor->target_buffer->line[displine][offset + svga->x_add] ^= 0xffffff; + svga->monitor->target_buffer->line[displine & 2047][(offset + svga->x_add) & 2047] ^= 0xffffff; offset++; dat[0] <<= 1; From 3e098b190e25553f4a4491660bcc0fd1a48a51ca Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 8 Feb 2024 16:08:05 +0600 Subject: [PATCH 482/936] HW cursor position fixing --- src/video/vid_c&t_69000.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 2e11764d9..4f8254477 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -1533,8 +1533,10 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) case 0xA6: chips->ext_regs[chips->ext_index] = val; chips->svga.hwcursor.y = val | (chips->ext_regs[0xA7] & 7) << 8; - if (chips->ext_regs[0xA7] & 0x80) - chips->svga.hwcursor.y = -chips->svga.hwcursor.y; + if (chips->ext_regs[0xA7] & 0x80) { + chips->svga.hwcursor.yoff = chips->svga.hwcursor.y; + chips->svga.hwcursor.y = 0; + } break; case 0xA7: chips->ext_regs[chips->ext_index] = val; From da3203a6c10c48426d1296a7abaf2a74da3878c2 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 9 Feb 2024 00:20:59 +0600 Subject: [PATCH 483/936] Force interlace to be off at 1280x1024 --- src/video/vid_c&t_69000.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 4f8254477..cbfb7b6d6 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -747,8 +747,8 @@ chips_69000_recalctimings(svga_t *svga) svga->interlace = !!(svga->crtc[0x70] & 0x80); - if (svga->dispend == 2002 && svga->hdisp == 1024) { - svga->dispend = 1280; + if (svga->hdisp == 1280 && svga->dispend == 1024) { + svga->interlace = 0; } switch (chips->ext_regs[0x81] & 0xF) { @@ -1541,8 +1541,10 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) case 0xA7: chips->ext_regs[chips->ext_index] = val; chips->svga.hwcursor.y = chips->ext_regs[0xA6] | (val & 7) << 8; - if (chips->ext_regs[0xA7] & 0x80) - chips->svga.hwcursor.y = -chips->svga.hwcursor.y; + if (chips->ext_regs[0xA7] & 0x80){ + chips->svga.hwcursor.yoff = chips->svga.hwcursor.y; + chips->svga.hwcursor.y = 0; + } break; case 0xC8: case 0xC9: From d646efc2888fdf9aedff7450d33507634b08f616 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 9 Feb 2024 12:44:43 +0600 Subject: [PATCH 484/936] Fix hardware cursor in interlaced modes Report 1280*1024 Dual Scan STN Color Panel for now --- src/video/vid_c&t_69000.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index cbfb7b6d6..9968e5205 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -209,6 +209,8 @@ chips_69000_read_flat_panel(chips_69000_t* chips) return 0; case 1: return 1; + case 0x10: + return 1; default: return chips->flat_panel_regs[chips->flat_panel_index]; } @@ -1425,7 +1427,7 @@ chips_69000_read_ext_reg(chips_69000_t* chips) val = 0x3; break; case 0x71: - val = 0x0; + val = 0b01101000; break; case 0xD0: val |= 1; @@ -2186,29 +2188,26 @@ chips_69000_hwcursor_draw(svga_t *svga, int displine) uint64_t dat[2]; int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; -#if 0 - if ((chips->ext_regs[0xA0] & 7) == 1) { - uint32_t evenline = svga->hwcursor_latch.cur_ysize - ((svga->hwcursor_on) & ~1) >> 1; - uint32_t dat_32[2]; - - dat_32[1] = bswap32(*(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr + (((displine - svga->hwcursor_latch.y) & 1) ? 4 : 0)])); - dat_32[0] = bswap32(*(uint32_t *) (&svga->vram[svga->hwcursor_latch.addr + 8 + (((displine - svga->hwcursor_latch.y) & 1) ? 4 : 0)])); - svga->hwcursor_latch.addr = svga->hwcursor.addr + (evenline * 16); - + if (svga->interlace && (chips->ext_regs[0xa0] & 7) == 0b1) { + dat[1] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr])); + dat[0] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr + 8])); + svga->hwcursor_latch.addr += 16; + if (svga->hwcursor_oddeven) { + dat[1] <<= 32ULL; + dat[0] <<= 32ULL; + } for (uint8_t x = 0; x < 32; x++) { - if (!(dat_32[1] & (1ULL << 31))) - svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat_32[0] & (1ULL << 31)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[4]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[5]); - else if (dat_32[0] & (1ULL << 31)) - svga->monitor->target_buffer->line[displine][offset + svga->x_add] ^= 0xffffff; + if (!(dat[1] & (1ULL << 63))) + svga->monitor->target_buffer->line[displine & 2047][(offset + svga->x_add) & 2047] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[5]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[4]); + else if (dat[0] & (1ULL << 63)) + svga->monitor->target_buffer->line[displine & 2047][(offset + svga->x_add) & 2047] ^= 0xffffff; offset++; - dat_32[0] <<= 1; - dat_32[1] <<= 1; + dat[0] <<= 1; + dat[1] <<= 1; } - return; } -#endif if (svga->interlace && svga->hwcursor_oddeven) svga->hwcursor_latch.addr += 16; @@ -2339,8 +2338,6 @@ chips_69000_init(const device_t *info) chips->flat_panel_regs[0x01] = 1; - sizeof(struct chips_69000_bitblt_t); - return chips; } From 5a3d74d64f0a09c4aedbad794f3e94da89976c59 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 9 Feb 2024 12:14:35 +0100 Subject: [PATCH 485/936] 286/386 interpreter fixes - the correct opcode arrays are now used and fixed the debug registers. --- src/cpu/386.c | 14 +-- src/cpu/386_common.c | 10 +- src/cpu/386_common.h | 58 ++++++++--- src/cpu/386_ops.h | 12 ++- src/cpu/cpu.h | 1 + src/cpu/x86.c | 6 ++ src/cpu/x86_ops_fpu_2386.h | 113 ++++++++++++++++++++ src/cpu/x86_ops_misc.h | 17 +++ src/cpu/x86_ops_mov_ctrl_2386.h | 154 +++++++++++++++++++++------ src/cpu/x86_ops_mov_seg.h | 8 ++ src/cpu/x86_ops_prefix_2386.h | 179 ++++++++++++++++++++++++++++++++ src/cpu/x86_ops_rep_2386.h | 4 +- src/cpu/x86_ops_stack.h | 8 ++ src/include/86box/mem.h | 1 + src/mem/mmu_2386.c | 146 +++++++++++++------------- src/mem/rom.c | 6 ++ 16 files changed, 597 insertions(+), 140 deletions(-) create mode 100644 src/cpu/x86_ops_fpu_2386.h create mode 100644 src/cpu/x86_ops_prefix_2386.h diff --git a/src/cpu/386.c b/src/cpu/386.c index b5a1e61e3..c7e31de22 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -25,6 +25,7 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/machine.h> +#include <86box/plat_fallthrough.h> #include <86box/gdbstub.h> #ifndef OPS_286_386 # define OPS_286_386 @@ -262,11 +263,10 @@ exec386_2386(int32_t cycs) CHECK_READ_CS(MIN(ol, 4)); ins_fetch_fault = cpu_386_check_instruction_fault(); - if (!cpu_state.abrt && ins_fetch_fault) { - x86gen(); + /* Breakpoint fault has priority over other faults. */ + if (ins_fetch_fault) { ins_fetch_fault = 0; - /* No instructions executed at this point. */ - goto block_ended; + cpu_state.abrt = 1; } if (!cpu_state.abrt) { @@ -279,7 +279,8 @@ exec386_2386(int32_t cycs) trap |= !!(cpu_state.flags & T_FLAG); cpu_state.pc++; - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + cpu_state.eflags &= ~(RF_FLAG); + x86_2386_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); if (x86_was_reset) break; } @@ -319,8 +320,7 @@ block_ended: #endif } } - if (!x86_was_reset && ins_fetch_fault) - x86gen(); /* This is supposed to be the first one serviced by the processor according to the manual. */ +according to the manual. */ } else if (trap) { flags_rebuild(); if (trap & 2) dr[6] |= 0x8000; diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index f9ca3408d..d74b181bf 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -1412,7 +1412,7 @@ x86_int(int num) cpu_state.pc = cpu_state.oldpc; if (msw & 1) - is486 ? pmodeint(num, 0) : pmodeint_2386(num, 0); + cpu_use_exec ? pmodeint(num, 0) : pmodeint_2386(num, 0); else { addr = (num << 2) + idt.base; @@ -1445,7 +1445,7 @@ x86_int(int num) oxpc = cpu_state.pc; #endif cpu_state.pc = readmemw(0, addr); - is486 ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2)); + cpu_use_exec ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2)); } } @@ -1462,7 +1462,7 @@ x86_int_sw(int num) cycles -= timing_int; if (msw & 1) - is486 ? pmodeint(num, 1) : pmodeint_2386(num, 1); + cpu_use_exec ? pmodeint(num, 1) : pmodeint_2386(num, 1); else { addr = (num << 2) + idt.base; @@ -1487,7 +1487,7 @@ x86_int_sw(int num) oxpc = cpu_state.pc; #endif cpu_state.pc = readmemw(0, addr); - is486 ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2)); + cpu_use_exec ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2)); cycles -= timing_int_rm; } } @@ -1529,7 +1529,7 @@ x86_int_sw_rm(int num) cpu_state.eflags &= ~VIF_FLAG; cpu_state.flags &= ~T_FLAG; cpu_state.pc = new_pc; - is486 ? loadcs(new_cs) : loadcs_2386(new_cs); + cpu_use_exec ? loadcs(new_cs) : loadcs_2386(new_cs); #ifndef USE_NEW_DYNAREC oxpc = cpu_state.pc; #endif diff --git a/src/cpu/386_common.h b/src/cpu/386_common.h index 35d4f7cc8..a98a3e930 100644 --- a/src/cpu/386_common.h +++ b/src/cpu/386_common.h @@ -225,19 +225,37 @@ int checkio(uint32_t port, int mask); static __inline uint8_t fastreadb(uint32_t a) { - return readmembl_2386(a); + uint8_t ret; + read_type = 1; + ret = readmembl_2386(a); + read_type = 4; + if (cpu_state.abrt) + return 0; + return ret; } static __inline uint16_t fastreadw(uint32_t a) { - return readmemwl_2386(a); + uint16_t ret; + read_type = 1; + ret = readmemwl_2386(a); + read_type = 4; + if (cpu_state.abrt) + return 0; + return ret; } static __inline uint32_t fastreadl(uint32_t a) { - return readmemll_2386(a); + uint32_t ret; + read_type = 1; + ret = readmemll_2386(a); + read_type = 4; + if (cpu_state.abrt) + return 0; + return ret; } #else static __inline uint8_t @@ -342,31 +360,41 @@ extern int opcode_length[256]; static __inline uint16_t fastreadw_fetch(uint32_t a) { - uint16_t val; + uint16_t ret; if ((a & 0xFFF) > 0xFFE) { - val = fastreadb(a); - if (opcode_length[val & 0xff] > 1) - val |= ((uint16_t) fastreadb(a + 1) << 8); - return val; + ret = fastreadb(a); + if (!cpu_state.abrt && (opcode_length[ret & 0xff] > 1)) + ret |= ((uint16_t) fastreadb(a + 1) << 8); + } else if (cpu_state.abrt) + ret = 0; + else { + read_type = 1; + ret = readmemwl_2386(a); + read_type = 4; } - return readmemwl_2386(a); + return ret; } static __inline uint32_t fastreadl_fetch(uint32_t a) { - uint32_t val; + uint32_t ret; if (cpu_16bitbus || ((a & 0xFFF) > 0xFFC)) { - val = fastreadw_fetch(a); - if (opcode_length[val & 0xff] > 2) - val |= ((uint32_t) fastreadw(a + 2) << 16); - return val; + ret = fastreadw_fetch(a); + if (!cpu_state.abrt && (opcode_length[ret & 0xff] > 2)) + ret |= ((uint32_t) fastreadw(a + 2) << 16); + } else if (cpu_state.abrt) + ret = 0; + else { + read_type = 1; + ret = readmemll_2386(a); + read_type = 4; } - return readmemll_2386(a); + return ret; } #else static __inline uint16_t diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index 1bb3c167f..3e0d191f2 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -186,7 +186,11 @@ extern void x386_dynarec_log(const char *fmt, ...); #else # include "x86_ops_flag.h" #endif -#include "x86_ops_fpu.h" +#ifdef OPS_286_386 +# include "x86_ops_fpu_2386.h" +#else +# include "x86_ops_fpu.h" +#endif #include "x86_ops_inc_dec.h" #include "x86_ops_int.h" #include "x86_ops_io.h" @@ -216,7 +220,11 @@ extern void x386_dynarec_log(const char *fmt, ...); #endif #include "x86_ops_mul.h" #include "x86_ops_pmode.h" -#include "x86_ops_prefix.h" +#ifdef OPS_286_386 +# include "x86_ops_prefix_2386.h" +#else +# include "x86_ops_prefix.h" +#endif #ifdef IS_DYNAREC # include "x86_ops_rep_dyn.h" #else diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index c829a0e17..db11b6135 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -174,6 +174,7 @@ typedef struct { #define VIP_FLAG 0x0010 /* in EFLAGS */ #define VID_FLAG 0x0020 /* in EFLAGS */ +#define EM_FLAG 0x00004 /* in CR0 */ #define WP_FLAG 0x10000 /* in CR0 */ #define CR4_VME (1 << 0) /* Virtual 8086 Mode Extensions */ diff --git a/src/cpu/x86.c b/src/cpu/x86.c index 64ff6be4c..8e4a5b547 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -275,6 +275,12 @@ reset_common(int hard) cr4 = 0; cpu_state.eflags = 0; cgate32 = 0; + if (is386 && !is486) { + for (uint8_t i = 0; i < 4; i++) + dr[i] = 0x00000000; + dr[6] = 0xffff1ff0; + dr[7] = 0x00000400; + } if (is286) { if (is486) loadcs(0xF000); diff --git a/src/cpu/x86_ops_fpu_2386.h b/src/cpu/x86_ops_fpu_2386.h new file mode 100644 index 000000000..52c24d995 --- /dev/null +++ b/src/cpu/x86_ops_fpu_2386.h @@ -0,0 +1,113 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +static int +opESCAPE_d8_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat); +} +static int +opESCAPE_d8_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat); +} + +static int +opESCAPE_d9_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_d9_a16[fetchdat & 0xff](fetchdat); +} +static int +opESCAPE_d9_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_d9_a32[fetchdat & 0xff](fetchdat); +} + +static int +opESCAPE_da_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_da_a16[fetchdat & 0xff](fetchdat); +} +static int +opESCAPE_da_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_da_a32[fetchdat & 0xff](fetchdat); +} + +static int +opESCAPE_db_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_db_a16[fetchdat & 0xff](fetchdat); +} +static int +opESCAPE_db_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_db_a32[fetchdat & 0xff](fetchdat); +} + +static int +opESCAPE_dc_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat); +} +static int +opESCAPE_dc_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat); +} + +static int +opESCAPE_dd_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_dd_a16[fetchdat & 0xff](fetchdat); +} +static int +opESCAPE_dd_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_dd_a32[fetchdat & 0xff](fetchdat); +} + +static int +opESCAPE_de_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_de_a16[fetchdat & 0xff](fetchdat); +} +static int +opESCAPE_de_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_de_a32[fetchdat & 0xff](fetchdat); +} + +static int +opESCAPE_df_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_df_a16[fetchdat & 0xff](fetchdat); +} +static int +opESCAPE_df_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_df_a32[fetchdat & 0xff](fetchdat); +} + +static int +opWAIT(uint32_t fetchdat) +{ + if ((cr0 & 0xa) == 0xa) { + x86_int(7); + return 1; + } + +#if 0 + if (!cpu_use_dynarec && fpu_softfloat) { +#endif + if (fpu_softfloat) { + if (fpu_state.swd & FPU_SW_Summary) { + if (cr0 & 0x20) { + x86_int(16); + return 1; + } + } + } + CLOCK_CYCLES(4); + return 0; +} diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index cbd2b3fbe..87dddefd8 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -726,6 +726,22 @@ opHLT(uint32_t fetchdat) return 0; } +#ifdef OPS_286_386 +static int +opLOCK(uint32_t fetchdat) +{ + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 0; + cpu_state.pc++; + + ILLEGAL_ON((fetchdat & 0xff) == 0x90); + + CLOCK_CYCLES(4); + PREFETCH_PREFIX(); + return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} +#else static int opLOCK(uint32_t fetchdat) { @@ -740,6 +756,7 @@ opLOCK(uint32_t fetchdat) PREFETCH_PREFIX(); return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } +#endif static int opBOUND_w_a16(uint32_t fetchdat) diff --git a/src/cpu/x86_ops_mov_ctrl_2386.h b/src/cpu/x86_ops_mov_ctrl_2386.h index c57dc8226..cae6c9957 100644 --- a/src/cpu/x86_ops_mov_ctrl_2386.h +++ b/src/cpu/x86_ops_mov_ctrl_2386.h @@ -82,18 +82,41 @@ opMOV_r_CRx_a32(uint32_t fetchdat) static int opMOV_r_DRx_a16(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + if ((CPL > 0) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } - fetch_ea_16(fetchdat); - if (cpu_reg == 4 || cpu_reg == 5) { - if (cr4 & 0x8) - x86illegal(); - else - cpu_reg += 2; + if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) { + trap |= 1; + return 1; + } + fetch_ea_16(fetchdat); + switch (cpu_reg) { + case 0 ... 3: + cpu_state.regs[cpu_rm].l = dr[cpu_reg]; + break; + case 4: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 6: + cpu_state.regs[cpu_rm].l = dr[6]; + break; + case 5: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 7: + cpu_state.regs[cpu_rm].l = dr[7]; + break; + default: + x86illegal(); + return 1; } - cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); CLOCK_CYCLES(6); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); return 0; @@ -101,18 +124,41 @@ opMOV_r_DRx_a16(uint32_t fetchdat) static int opMOV_r_DRx_a32(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + if ((CPL > 0) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } - fetch_ea_32(fetchdat); - if (cpu_reg == 4 || cpu_reg == 5) { - if (cr4 & 0x8) - x86illegal(); - else - cpu_reg += 2; + if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) { + trap |= 1; + return 1; + } + fetch_ea_32(fetchdat); + switch (cpu_reg) { + case 0 ... 3: + cpu_state.regs[cpu_rm].l = dr[cpu_reg]; + break; + case 4: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 6: + cpu_state.regs[cpu_rm].l = dr[6]; + break; + case 5: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 7: + cpu_state.regs[cpu_rm].l = dr[7]; + break; + default: + x86illegal(); + return 1; } - cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); CLOCK_CYCLES(6); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); return 0; @@ -236,24 +282,41 @@ opMOV_CRx_r_a32(uint32_t fetchdat) static int opMOV_DRx_r_a16(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + if ((CPL > 0) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } - if ((dr[6] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) { - dr[7] |= 0x2000; - dr[6] &= ~0x2000; - x86gen(); + if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) { + trap |= 1; return 1; } fetch_ea_16(fetchdat); - if (cpu_reg == 4 || cpu_reg == 5) { - if (cr4 & 0x8) + switch (cpu_reg) { + case 0 ... 3: + dr[cpu_reg] = cpu_state.regs[cpu_rm].l; + break; + case 4: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 6: + dr[6] = (dr[6] & 0xffff0ff0) | (cpu_state.regs[cpu_rm].l & 0x0000f00f); + break; + case 5: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 7: + dr[7] = cpu_state.regs[cpu_rm].l | 0x00000400; + break; + default: x86illegal(); - else - cpu_reg += 2; + return 1; } - dr[cpu_reg] = cpu_state.regs[cpu_rm].l; CLOCK_CYCLES(6); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); CPU_BLOCK_END(); @@ -262,18 +325,41 @@ opMOV_DRx_r_a16(uint32_t fetchdat) static int opMOV_DRx_r_a32(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + if ((CPL > 0) && (cr0 & 1)) { x86gpf(NULL, 0); return 1; } - fetch_ea_16(fetchdat); - if (cpu_reg == 4 || cpu_reg == 5) { - if (cr4 & 0x8) - x86illegal(); - else - cpu_reg += 2; + if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) { + trap |= 1; + return 1; + } + fetch_ea_32(fetchdat); + switch (cpu_reg) { + case 0 ... 3: + dr[cpu_reg] = cpu_state.regs[cpu_rm].l; + break; + case 4: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 6: + dr[6] = (dr[6] & 0xffff0ff0) | (cpu_state.regs[cpu_rm].l & 0x0000f00f); + break; + case 5: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 7: + dr[7] = cpu_state.regs[cpu_rm].l | 0x00000400; + break; + default: + x86illegal(); + return 1; } - dr[cpu_reg] = cpu_state.regs[cpu_rm].l; CLOCK_CYCLES(6); PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); CPU_BLOCK_END(); diff --git a/src/cpu/x86_ops_mov_seg.h b/src/cpu/x86_ops_mov_seg.h index 2a798db5c..7fcc92312 100644 --- a/src/cpu/x86_ops_mov_seg.h +++ b/src/cpu/x86_ops_mov_seg.h @@ -195,7 +195,11 @@ opMOV_seg_w_a16(uint32_t fetchdat) cpu_state.pc++; if (cpu_state.abrt) return 1; +#ifdef OPS_286_386 + x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#else x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#endif return 1; case 0x20: /*FS*/ op_loadseg(new_seg, &cpu_state.seg_fs); @@ -240,7 +244,11 @@ opMOV_seg_w_a32(uint32_t fetchdat) cpu_state.pc++; if (cpu_state.abrt) return 1; +#ifdef OPS_286_386 + x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#else x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#endif return 1; case 0x20: /*FS*/ op_loadseg(new_seg, &cpu_state.seg_fs); diff --git a/src/cpu/x86_ops_prefix_2386.h b/src/cpu/x86_ops_prefix_2386.h new file mode 100644 index 000000000..7c87f0bf3 --- /dev/null +++ b/src/cpu/x86_ops_prefix_2386.h @@ -0,0 +1,179 @@ +#define op_seg(name, seg, opcode_table, normal_opcode_table) \ + static int op##name##_w_a16(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[fetchdat & 0xff]) \ + return opcode_table[fetchdat & 0xff](fetchdat >> 8); \ + return normal_opcode_table[fetchdat & 0xff](fetchdat >> 8); \ + } \ + \ + static int op##name##_l_a16(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x100]) \ + return opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ + return normal_opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ + } \ + \ + static int op##name##_w_a32(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x200]) \ + return opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ + return normal_opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ + } \ + \ + static int op##name##_l_a32(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x300]) \ + return opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ + return normal_opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ + } + +// clang-format off +op_seg(CS, cpu_state.seg_cs, x86_2386_opcodes, x86_2386_opcodes) +op_seg(DS, cpu_state.seg_ds, x86_2386_opcodes, x86_2386_opcodes) +op_seg(ES, cpu_state.seg_es, x86_2386_opcodes, x86_2386_opcodes) +op_seg(FS, cpu_state.seg_fs, x86_2386_opcodes, x86_2386_opcodes) +op_seg(GS, cpu_state.seg_gs, x86_2386_opcodes, x86_2386_opcodes) +op_seg(SS, cpu_state.seg_ss, x86_2386_opcodes, x86_2386_opcodes) + +op_seg(CS_REPE, cpu_state.seg_cs, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_seg(DS_REPE, cpu_state.seg_ds, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_seg(ES_REPE, cpu_state.seg_es, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_seg(FS_REPE, cpu_state.seg_fs, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_seg(GS_REPE, cpu_state.seg_gs, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_seg(SS_REPE, cpu_state.seg_ss, x86_2386_opcodes_REPE, x86_2386_opcodes) + +op_seg(CS_REPNE, cpu_state.seg_cs, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_seg(DS_REPNE, cpu_state.seg_ds, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_seg(ES_REPNE, cpu_state.seg_es, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_seg(FS_REPNE, cpu_state.seg_fs, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_seg(GS_REPNE, cpu_state.seg_gs, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_seg(SS_REPNE, cpu_state.seg_ss, x86_2386_opcodes_REPNE, x86_2386_opcodes) + // clang-format on + +static int +op_66(uint32_t fetchdat) /*Data size select*/ +{ + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; + + cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} +static int +op_67(uint32_t fetchdat) /*Address size select*/ +{ + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; + + cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} + +static int +op_66_REPE(uint32_t fetchdat) /*Data size select*/ +{ + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; + + cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} +static int +op_67_REPE(uint32_t fetchdat) /*Address size select*/ +{ + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; + + cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} +static int +op_66_REPNE(uint32_t fetchdat) /*Data size select*/ +{ + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; + + cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} +static int +op_67_REPNE(uint32_t fetchdat) /*Address size select*/ +{ + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; + + cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} diff --git a/src/cpu/x86_ops_rep_2386.h b/src/cpu/x86_ops_rep_2386.h index b6f64e90d..fe5048340 100644 --- a/src/cpu/x86_ops_rep_2386.h +++ b/src/cpu/x86_ops_rep_2386.h @@ -836,7 +836,7 @@ REP_OPS_CMPS_SCAS(a32_E, ECX, ESI, EDI, 1) static int opREPNE(uint32_t fetchdat) { - fetchdat = fastreadl(cs + cpu_state.pc); + fetchdat = fastreadl_fetch(cs + cpu_state.pc); if (cpu_state.abrt) return 1; cpu_state.pc++; @@ -850,7 +850,7 @@ opREPNE(uint32_t fetchdat) static int opREPE(uint32_t fetchdat) { - fetchdat = fastreadl(cs + cpu_state.pc); + fetchdat = fastreadl_fetch(cs + cpu_state.pc); if (cpu_state.abrt) return 1; cpu_state.pc++; diff --git a/src/cpu/x86_ops_stack.h b/src/cpu/x86_ops_stack.h index 13eb883d3..fbf603ddb 100644 --- a/src/cpu/x86_ops_stack.h +++ b/src/cpu/x86_ops_stack.h @@ -667,7 +667,11 @@ opPOP_SS_w(uint32_t fetchdat) cpu_state.pc++; if (cpu_state.abrt) return 1; +#ifdef OPS_286_386 + x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#else x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#endif return 1; } @@ -695,7 +699,11 @@ opPOP_SS_l(uint32_t fetchdat) cpu_state.pc++; if (cpu_state.abrt) return 1; +#ifdef OPS_286_386 + x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#else x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#endif return 1; } diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index 15afcb160..bc949834f 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -303,6 +303,7 @@ extern int mmu_perm; extern uint8_t high_page; /* if a high (> 4 gb) page was detected */ extern uint32_t pages_sz; /* #pages in table */ +extern int read_type; extern int mem_a20_state; extern int mem_a20_alt; diff --git a/src/mem/mmu_2386.c b/src/mem/mmu_2386.c index 9ed26edfa..7c286b605 100644 --- a/src/mem/mmu_2386.c +++ b/src/mem/mmu_2386.c @@ -39,52 +39,43 @@ #include <86box/rom.h> #include <86box/gdbstub.h> -/* Set trap for data address breakpoints. */ -void -mem_debug_check_addr(uint32_t addr, int write) -{ - int i = 0; - int set_trap = 0; +/* As below, 1 = exec, 4 = read. */ +int read_type = 4; - if (!(dr[7] & 0xFF)) +/* Set trap for data address breakpoints - 1 = exec, 2 = write, 4 = read. */ +void +mem_debug_check_addr(uint32_t addr, int flags) +{ + uint32_t bp_addr; + uint32_t bp_mask; + uint32_t len_type_pair; + int bp_enabled; + uint8_t match_flags[4] = { 0, 2, 0, 6 }; + char *bp_types[5] = { "N/A 0", "EXEC ", "WRITE", "N/A 3", "READ " }; + + if (cpu_state.abrt || ((flags == 1) && (cpu_state.eflags & RF_FLAG))) return; - for (i = 0; i < 4; i++) { - uint32_t dr_addr = dr[i]; - int breakpoint_enabled = !!(dr[7] & (0x3 << (2 * i))); - int len_type_pair = ((dr[7] >> 16) & (0xF << (4 * i))) >> (4 * i); - if (!breakpoint_enabled) - continue; - if (!write && (len_type_pair & 3) != 3) - continue; - if ((len_type_pair & 3) != 1) - continue; - - switch ((len_type_pair >> 2) & 3) - { - case 0x00: - if (dr_addr == addr) { - set_trap = 1; - dr[6] |= (1 << i); - } - break; - case 0x01: - if ((dr_addr & ~1) == addr || ((dr_addr & ~1) + 1) == (addr + 1)) { - set_trap = 1; - dr[6] |= (1 << i); - } - break; - case 0x03: - dr_addr &= ~3; - if (addr >= dr_addr && addr < (dr_addr + 4)) { - set_trap = 1; - dr[6] |= (1 << i); - } - break; + if (dr[7] & 0x000000ff) for (uint8_t i = 0; i < 4; i++) { + bp_addr = dr[i]; + bp_enabled = (dr[7] >> (i << 1)) & 0x03; + len_type_pair = (dr[7] >> (16 + (i << 2))) & 0x0f; + bp_mask = ~((len_type_pair >> 2) & 0x03); + + if ((flags & match_flags[len_type_pair & 0x03]) && ((bp_addr & bp_mask) == (addr & bp_mask))) { + /* + From the Intel i386 documemntation: + + (Note that the processor sets Bn regardless of whether Gn or + Ln is set. If more than one breakpoint condition occurs at one time and if + the breakpoint trap occurs due to an enabled condition other than n, Bn may + be set, even though neither Gn nor Ln is set.) + */ + dr[6] |= (1 << i); + if (bp_enabled) + trap |= (read_type == 1) ? 8 : 4; } } - if (set_trap) - trap |= 4; } uint8_t @@ -291,7 +282,7 @@ readmembl_2386(uint32_t addr) GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1); - mem_debug_check_addr(addr, 0); + mem_debug_check_addr(addr, read_type); addr64 = (uint64_t) addr; mem_logical_addr = addr; @@ -319,7 +310,7 @@ writemembl_2386(uint32_t addr, uint8_t val) mem_mapping_t *map; uint64_t a; - mem_debug_check_addr(addr, 1); + mem_debug_check_addr(addr, 2); GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1); addr64 = (uint64_t) addr; @@ -397,8 +388,8 @@ readmemwl_2386(uint32_t addr) addr64a[0] = addr; addr64a[1] = addr + 1; - mem_debug_check_addr(addr, 0); - mem_debug_check_addr(addr + 1, 0); + mem_debug_check_addr(addr, read_type); + mem_debug_check_addr(addr + 1, read_type); GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 2); mem_logical_addr = addr; @@ -419,7 +410,8 @@ readmemwl_2386(uint32_t addr) } } - return readmembl_no_mmut(addr, addr64a[0]) | (((uint16_t) readmembl_no_mmut(addr + 1, addr64a[1])) << 8); + return readmembl_no_mmut_2386(addr, addr64a[0]) | + (((uint16_t) readmembl_no_mmut_2386(addr + 1, addr64a[1])) << 8); } } @@ -454,8 +446,8 @@ writememwl_2386(uint32_t addr, uint16_t val) addr64a[0] = addr; addr64a[1] = addr + 1; - mem_debug_check_addr(addr, 1); - mem_debug_check_addr(addr + 1, 1); + mem_debug_check_addr(addr, 2); + mem_debug_check_addr(addr + 1, 2); GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 2); mem_logical_addr = addr; @@ -482,8 +474,8 @@ writememwl_2386(uint32_t addr, uint16_t val) /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass their result as a parameter to be used if needed. */ - writemembl_no_mmut(addr, addr64a[0], val); - writemembl_no_mmut(addr + 1, addr64a[1], val >> 8); + writemembl_no_mmut_2386(addr, addr64a[0], val); + writemembl_no_mmut_2386(addr + 1, addr64a[1], val >> 8); return; } } @@ -531,7 +523,8 @@ readmemwl_no_mmut_2386(uint32_t addr, uint32_t *a64) return 0xffff; } - return readmembl_no_mmut(addr, a64[0]) | (((uint16_t) readmembl_no_mmut(addr + 1, a64[1])) << 8); + return readmembl_no_mmut_2386(addr, a64[0]) | + (((uint16_t) readmembl_no_mmut_2386(addr + 1, a64[1])) << 8); } } @@ -574,8 +567,8 @@ writememwl_no_mmut_2386(uint32_t addr, uint32_t *a64, uint16_t val) return; } - writemembl_no_mmut(addr, a64[0], val); - writemembl_no_mmut(addr + 1, a64[1], val >> 8); + writemembl_no_mmut_2386(addr, a64[0], val); + writemembl_no_mmut_2386(addr + 1, a64[1], val >> 8); return; } } @@ -611,7 +604,7 @@ readmemll_2386(uint32_t addr) for (i = 0; i < 4; i++) { addr64a[i] = (uint64_t) (addr + i); - mem_debug_check_addr(addr + i, 0); + mem_debug_check_addr(addr + i, read_type); } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 4); @@ -619,8 +612,8 @@ readmemll_2386(uint32_t addr) high_page = 0; - if (addr & 3) { - if (!cpu_cyrix_alignment || (addr & 7) > 4) + if (cpu_16bitbus || (addr & 3)) { + if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4)) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffc) { if (cr0 >> 31) { @@ -647,7 +640,8 @@ readmemll_2386(uint32_t addr) /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass their result as a parameter to be used if needed. */ - return readmemwl_no_mmut(addr, addr64a) | (((uint32_t) readmemwl_no_mmut(addr + 2, &(addr64a[2]))) << 16); + return readmemwl_no_mmut_2386(addr, addr64a) | + (((uint32_t) readmemwl_no_mmut(addr + 2, &(addr64a[2]))) << 16); } } @@ -684,7 +678,7 @@ writememll_2386(uint32_t addr, uint32_t val) for (i = 0; i < 4; i++) { addr64a[i] = (uint64_t) (addr + i); - mem_debug_check_addr(addr + i, 1); + mem_debug_check_addr(addr + i, 2); } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 4); @@ -692,8 +686,8 @@ writememll_2386(uint32_t addr, uint32_t val) high_page = 0; - if (addr & 3) { - if (!cpu_cyrix_alignment || (addr & 7) > 4) + if (cpu_16bitbus || (addr & 3)) { + if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4)) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffc) { if (cr0 >> 31) { @@ -724,8 +718,8 @@ writememll_2386(uint32_t addr, uint32_t val) /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass their result as a parameter to be used if needed. */ - writememwl_no_mmut(addr, &(addr64a[0]), val); - writememwl_no_mmut(addr + 2, &(addr64a[2]), val >> 16); + writememwl_no_mmut_2386(addr, &(addr64a[0]), val); + writememwl_no_mmut_2386(addr + 2, &(addr64a[2]), val >> 16); return; } } @@ -770,8 +764,8 @@ readmemll_no_mmut_2386(uint32_t addr, uint32_t *a64) mem_logical_addr = addr; - if (addr & 3) { - if (!cpu_cyrix_alignment || (addr & 7) > 4) + if (cpu_16bitbus || (addr & 3)) { + if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4)) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffc) { if (cr0 >> 31) { @@ -779,7 +773,8 @@ readmemll_no_mmut_2386(uint32_t addr, uint32_t *a64) return 0xffffffff; } - return readmemwl_no_mmut(addr, a64) | ((uint32_t) (readmemwl_no_mmut(addr + 2, &(a64[2]))) << 16); + return readmemwl_no_mmut_2386(addr, a64) | + ((uint32_t) (readmemwl_no_mmut_2386(addr + 2, &(a64[2]))) << 16); } } @@ -815,8 +810,8 @@ writememll_no_mmut_2386(uint32_t addr, uint32_t *a64, uint32_t val) mem_logical_addr = addr; - if (addr & 3) { - if (!cpu_cyrix_alignment || (addr & 7) > 4) + if (cpu_16bitbus || (addr & 3)) { + if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4)) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffc) { if (cr0 >> 31) { @@ -824,8 +819,8 @@ writememll_no_mmut_2386(uint32_t addr, uint32_t *a64, uint32_t val) return; } - writememwl_no_mmut(addr, &(a64[0]), val); - writememwl_no_mmut(addr + 2, &(a64[2]), val >> 16); + writememwl_no_mmut_2386(addr, &(a64[0]), val); + writememwl_no_mmut_2386(addr + 2, &(a64[2]), val >> 16); return; } } @@ -867,7 +862,7 @@ readmemql_2386(uint32_t addr) for (i = 0; i < 8; i++) { addr64a[i] = (uint64_t) (addr + i); - mem_debug_check_addr(addr + i, 0); + mem_debug_check_addr(addr + i, read_type); } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 8); @@ -902,7 +897,8 @@ readmemql_2386(uint32_t addr) /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass their result as a parameter to be used if needed. */ - return readmemll_no_mmut(addr, addr64a) | (((uint64_t) readmemll_no_mmut(addr + 4, &(addr64a[4]))) << 32); + return readmemll_no_mmut_2386(addr, addr64a) | + (((uint64_t) readmemll_no_mmut_2386(addr + 4, &(addr64a[4]))) << 32); } } @@ -932,7 +928,7 @@ writememql_2386(uint32_t addr, uint64_t val) for (i = 0; i < 8; i++) { addr64a[i] = (uint64_t) (addr + i); - mem_debug_check_addr(addr + i, 1); + mem_debug_check_addr(addr + i, 2); } GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 8); @@ -971,8 +967,8 @@ writememql_2386(uint32_t addr, uint64_t val) /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass their result as a parameter to be used if needed. */ - writememll_no_mmut(addr, addr64a, val); - writememll_no_mmut(addr + 4, &(addr64a[4]), val >> 32); + writememll_no_mmut_2386(addr, addr64a, val); + writememll_no_mmut_2386(addr + 4, &(addr64a[4]), val >> 32); return; } } @@ -1019,7 +1015,7 @@ do_mmutranslate_2386(uint32_t addr, uint32_t *a64, int num, int write) uint32_t last_addr = addr + (num - 1); uint64_t a = 0x0000000000000000ULL; - mem_debug_check_addr(addr, write); + mem_debug_check_addr(addr, write ? 2 : read_type); for (i = 0; i < num; i++) a64[i] = (uint64_t) addr; diff --git a/src/mem/rom.c b/src/mem/rom.c index 4a20e8ebc..f9718b7ce 100644 --- a/src/mem/rom.c +++ b/src/mem/rom.c @@ -296,6 +296,12 @@ rom_load_linear_inverted(const char *fn, uint32_t addr, int sz, int off, uint8_t fatal("rom_load_linear_inverted(): Error reading the upper half of the data\n"); if (fread(ptr + addr, sz >> 1, 1, fp) > (sz >> 1)) fatal("rom_load_linear_inverted(): Error reading the lower half of the data\n"); + if (sz == 0x40000) { + if (fread(ptr + addr + 0x30000, 1, sz >> 1, fp) > (sz >> 1)) + fatal("rom_load_linear_inverted(): Error reading the upper half of the data\n"); + if (fread(ptr + addr + 0x20000, sz >> 1, 1, fp) > (sz >> 1)) + fatal("rom_load_linear_inverted(): Error reading the lower half of the data\n"); + } } (void) fclose(fp); From 30e7a495584ecb684288578ea27e3f9cb0413024 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 9 Feb 2024 12:15:28 +0100 Subject: [PATCH 486/936] Fix compile-breaking mistakes in cpu/386.c. --- src/cpu/386.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/cpu/386.c b/src/cpu/386.c index c7e31de22..ad310d31e 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -297,7 +297,6 @@ exec386_2386(int32_t cycs) if (cpu_end_block_after_ins) cpu_end_block_after_ins--; -block_ended: if (cpu_state.abrt) { flags_rebuild(); tempi = cpu_state.abrt & ABRT_MASK; @@ -320,7 +319,6 @@ block_ended: #endif } } -according to the manual. */ } else if (trap) { flags_rebuild(); if (trap & 2) dr[6] |= 0x8000; From 3f8952a558ddfaf1adda3b92b8604a35add52c67 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 9 Feb 2024 18:02:33 +0100 Subject: [PATCH 487/936] More (S)VGA horizontal blanking fixes and CPU CR0 bit 4 fixes. --- src/cpu/x86.c | 2 ++ src/cpu/x86_ops_mov_ctrl.h | 4 ++-- src/include/86box/vid_svga.h | 2 ++ src/video/vid_cl54xx.c | 6 +++--- src/video/vid_s3.c | 22 +++++++++------------- src/video/vid_s3_virge.c | 34 +++++++++++++++++++--------------- src/video/vid_svga.c | 34 ++++++++++++++++++---------------- src/video/vid_voodoo_banshee.c | 6 +++--- 8 files changed, 58 insertions(+), 52 deletions(-) diff --git a/src/cpu/x86.c b/src/cpu/x86.c index 8e4a5b547..2c8c29d49 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -270,6 +270,8 @@ reset_common(int hard) cr0 = 1 << 30; else cr0 = 0; + if (is386 && !is486 && (fpu_type == FPU_387)) + cr0 |= 0x10; cpu_cache_int_enabled = 0; cpu_update_waitstates(); cr4 = 0; diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h index eafe3cdde..b0c841f83 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu/x86_ops_mov_ctrl.h @@ -124,7 +124,7 @@ opMOV_CRx_r_a16(uint32_t fetchdat) if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) cpu_state.seg_cs.access &= 0x9f; cr0 = cpu_state.regs[cpu_rm].l; - if ((cpu_s->cpu_type != CPU_386DX) || (fpu_type == FPU_387)) + if (cpu_16bitbus) cr0 |= 0x10; if (!(cr0 & 0x80000000)) mmu_perm = 4; @@ -181,7 +181,7 @@ opMOV_CRx_r_a32(uint32_t fetchdat) if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) cpu_state.seg_cs.access &= 0x9f; cr0 = cpu_state.regs[cpu_rm].l; - if ((cpu_s->cpu_type != CPU_386DX) || (fpu_type == FPU_387)) + if (cpu_16bitbus) cr0 |= 0x10; if (!(cr0 & 0x80000000)) mmu_perm = 4; diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 624e85a1b..2f8a83a1d 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -171,6 +171,8 @@ typedef struct svga_t { double clock; double clock8514; + double multiplier; + hwcursor_t hwcursor; hwcursor_t hwcursor_latch; hwcursor_t dac_hwcursor; diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 49899b7b4..b8db0440d 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -1762,11 +1762,11 @@ gd54xx_recalctimings(svga_t *svga) svga->hblank_end_val = (svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00) | (((svga->crtc[0x1a] >> 4) & 3) << 6); - svga->hblank_end_mask = 0x0000007f; + svga->hblank_end_mask = 0x000000ff; if (svga->crtc[0x1b] & 0x20) { - svga->hblankstart = svga->crtc[1] + ((svga->crtc[3] >> 5) & 3) + 1; - svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); + svga->hblankstart = svga->crtc[1]/* + ((svga->crtc[3] >> 5) & 3)*/ + 1; + svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ if (!svga->scrblank && svga->attr_palette_enable) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index d8691ad77..ca737e7fe 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3262,9 +3262,9 @@ s3_recalctimings(svga_t *svga) if (svga->crtc[0x33] & 0x20) { /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ - svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1] + - ((svga->crtc[3] >> 5) & 3) + 1; - svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); + svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1]/* + + ((svga->crtc[3] >> 5) & 3)*/ + 1; + svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; svga->monitor->mon_overscan_y = 0; svga->monitor->mon_overscan_x = 0; @@ -4108,11 +4108,11 @@ s3_trio64v_recalctimings(svga_t *svga) break; } - if ((svga->crtc[0x33] & 0x20) ||((svga->crtc[0x67] & 0xc) == 0xc)) { + if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) { /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ - svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1] + - ((svga->crtc[3] >> 5) & 3) + 1; - svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); + svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1]/* + + ((svga->crtc[3] >> 5) & 3)*/ + 1; + svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; svga->monitor->mon_overscan_y = 0; svga->monitor->mon_overscan_x = 0; @@ -4204,15 +4204,11 @@ s3_trio64v_recalctimings(svga_t *svga) svga->render = svga_render_8bpp_highres; break; case 3: /*KRGB-16 (1.5.5.5)*/ - svga->htotal >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->multiplier = 0.5; svga->render = svga_render_15bpp_highres; break; case 5: /*RGB-16 (5.6.5)*/ - svga->htotal >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->multiplier = 0.5; svga->render = svga_render_16bpp_highres; break; case 6: /*RGB-24 (8.8.8)*/ diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 3184a1ccd..1cb6424fb 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -826,9 +826,9 @@ s3_virge_recalctimings(svga_t *svga) if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) { /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ - svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1] + - ((svga->crtc[3] >> 5) & 3) + 1; - svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); + svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1]/* + + ((svga->crtc[3] >> 5) & 3)*/ + 1; + svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; svga->monitor->mon_overscan_y = 0; svga->monitor->mon_overscan_x = 0; @@ -862,19 +862,21 @@ s3_virge_recalctimings(svga_t *svga) case 15: svga->render = svga_render_15bpp_highres; if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) { - svga->htotal >>= 1; + // svga->htotal >>= 1; + // if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) + // svga->hblank_end_val = svga->htotal - 1; svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; } break; case 16: svga->render = svga_render_16bpp_highres; if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) { - svga->htotal >>= 1; + // svga->htotal >>= 1; + // if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) + // svga->hblank_end_val = svga->htotal - 1; svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; } break; case 24: @@ -921,15 +923,17 @@ s3_virge_recalctimings(svga_t *svga) svga->render = svga_render_8bpp_highres; break; case 3: /*KRGB-16 (1.5.5.5)*/ - svga->htotal >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + // svga->htotal >>= 1; + // if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) + // svga->hblank_end_val = svga->htotal - 1; + // svga->dots_per_clock >>= 1; svga->render = svga_render_15bpp_highres; break; case 5: /*RGB-16 (5.6.5)*/ - svga->htotal >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + // svga->htotal >>= 1; + // if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) + // svga->hblank_end_val = svga->htotal - 1; + // svga->dots_per_clock >>= 1; svga->render = svga_render_16bpp_highres; break; case 6: /*RGB-24 (8.8.8)*/ diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index edb05086a..a3ad2edd8 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -773,6 +773,8 @@ svga_recalctimings(svga_t *svga) } else svga->dots_per_clock = 1; + svga->multiplier = 1.0; + if (svga->recalctimings_ex) svga->recalctimings_ex(svga); @@ -813,26 +815,26 @@ svga_recalctimings(svga_t *svga) if (ibm8514_active && (svga->dev8514 != NULL)) { if (dev->on[0] || dev->on[1]) { - uint32_t dot8514 = dev->h_blankstart; - uint32_t adj_dot8514 = dev->h_blankstart; - uint32_t eff_mask8514 = 0x0000003f; - dev->hblank_sub = 0; + uint32_t dot8514 = dev->h_blankstart; + uint32_t adj_dot8514 = dev->h_blankstart; + uint32_t eff_mask8514 = 0x0000003f; + dev->hblank_sub = 0; - while (1) { - if (dot8514 == dev->h_total) - dot = 0; + while (1) { + if (dot8514 == dev->h_total) + dot = 0; - if (adj_dot8514 >= dev->h_total) - dev->hblank_sub++; + if (adj_dot8514 >= dev->h_total) + dev->hblank_sub++; - if ((dot8514 & eff_mask8514) == (dev->h_blank_end_val & eff_mask8514)) - break; + if ((dot8514 & eff_mask8514) == (dev->h_blank_end_val & eff_mask8514)) + break; - dot8514++; - adj_dot8514++; - } + dot8514++; + adj_dot8514++; + } - dev->h_disp -= dev->hblank_sub; + dev->h_disp -= dev->hblank_sub; } } } @@ -889,7 +891,7 @@ svga_recalctimings(svga_t *svga) svga->htotal, hdispstart, hdispend, hsyncstart, hsyncend, svga->hblankstart, svga->hblankend); - disptime = svga->htotal; + disptime = svga->htotal * svga->multiplier; _dispontime = svga->hdisp_time; if (ibm8514_active && (svga->dev8514 != NULL)) { diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 9fec8c073..f03f6efd4 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -557,14 +557,14 @@ banshee_recalctimings(svga_t *svga) /* Video processing mode - assume timings akin to Cirrus' special blanking mode, that is, no overscan and relying on display end to blank. */ if (banshee->vgaInit0 & 0x40) { - svga->hblankstart = svga->crtc[1] + ((svga->crtc[3] >> 5) & 3) + + svga->hblankstart = svga->crtc[1]/* + ((svga->crtc[3] >> 5) & 3)*/ + (((svga->crtc[0x1a] & 0x04) >> 2) << 8) + 1; svga->hblank_end_mask = 0x0000007f; } else { - svga->hblankstart = svga->crtc[1] + ((svga->crtc[3] >> 5) & 3) + 1; + svga->hblankstart = svga->crtc[1]/* + ((svga->crtc[3] >> 5) & 3)*/ + 1; svga->hblank_end_mask = 0x0000003f; } - svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); + svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ if (!svga->scrblank && svga->attr_palette_enable) From a330860b2ed9000489276eb40c2bb1b9b5c25d18 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 9 Feb 2024 18:28:09 +0100 Subject: [PATCH 488/936] Fixed the Cirrus banking issue for good (really) A bit controversial regarding extra_banks but this should be enough to fix everything in the banks of the CL-GD54xx (up to 5480). --- src/video/vid_cl54xx.c | 44 ++++++++++++++---------------------------- src/video/vid_svga.c | 13 ++++--------- 2 files changed, 18 insertions(+), 39 deletions(-) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index b8db0440d..5d376effe 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -816,7 +816,7 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) svga->seqregs[svga->seqaddr] &= 0x0f; if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429) svga->set_reset_disabled = svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA; - gd54xx_recalc_banking(gd54xx); + gd54xx_set_svga_fast(gd54xx); svga_recalctimings(svga); break; @@ -1642,8 +1642,6 @@ gd54xx_recalc_banking(gd54xx_t *gd54xx) } else svga->extra_banks[1] = svga->extra_banks[0] + 0x8000; } - - svga->write_bank = svga->read_bank = svga->extra_banks[0]; } static void @@ -1977,11 +1975,16 @@ gd54xx_recalctimings(svga_t *svga) svga->htotal += ((svga->crtc[0x1c] >> 3) & 0x07); if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ - if (svga->seqregs[1] & 8) { + if (svga->seqregs[1] & 8) svga->render = svga_render_text_40; - } else + else svga->render = svga_render_text_80; } + + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) { + svga->extra_banks[0] = 0; + svga->extra_banks[1] = 0x8000; + } } static void @@ -2192,13 +2195,8 @@ gd54xx_write(uint32_t addr, uint8_t val, void *priv) return; } - if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) { - svga_write(addr, val, svga); - return; - } - + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; - svga_write_linear(addr, val, svga); } @@ -2214,11 +2212,7 @@ gd54xx_writew(uint32_t addr, uint16_t val, void *priv) return; } - if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) { - svga_writew(addr, val, svga); - return; - } - + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; if (svga->writemode < 4) @@ -2243,11 +2237,7 @@ gd54xx_writel(uint32_t addr, uint32_t val, void *priv) return; } - if ((svga->seqregs[0x07] & 0x01) == 0) { - svga_writel(addr, val, svga); - return; - } - + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; if (svga->writemode < 4) @@ -2769,12 +2759,10 @@ gd54xx_read(uint32_t addr, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; - if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) - return svga_read(addr, svga); - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) return gd54xx_mem_sys_dest_read(gd54xx, 0); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_read_linear(addr, svga); } @@ -2786,15 +2774,13 @@ gd54xx_readw(uint32_t addr, void *priv) svga_t *svga = &gd54xx->svga; uint16_t ret; - if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) - return svga_readw(addr, svga); - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { ret = gd54xx_read(addr, priv); ret |= gd54xx_read(addr + 1, priv) << 8; return ret; } + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_readw_linear(addr, svga); } @@ -2806,9 +2792,6 @@ gd54xx_readl(uint32_t addr, void *priv) svga_t *svga = &gd54xx->svga; uint32_t ret; - if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) - return svga_readl(addr, svga); - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { ret = gd54xx_read(addr, priv); ret |= gd54xx_read(addr + 1, priv) << 8; @@ -2817,6 +2800,7 @@ gd54xx_readl(uint32_t addr, void *priv) return ret; } + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_readl_linear(addr, svga); } diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index a3ad2edd8..81cc50bc4 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1406,15 +1406,10 @@ svga_decode_addr(svga_t *svga, uint32_t addr, int write) } if (memory_map_mode <= 1) { - if (svga->adv_flags & FLAG_EXTRA_BANKS) { - if ((svga->gdcreg[5] & 0x40) || svga->packed_chain4) - addr = (addr & 0x17fff) + svga->extra_banks[(addr >> 15) & 1]; - } else { - if (write) - addr += svga->write_bank; - else - addr += svga->read_bank; - } + if (write) + addr += svga->write_bank; + else + addr += svga->read_bank; } return addr; From 2ab99dda0b7091cb7a80e59406ae259d8bc6ff62 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 10 Feb 2024 03:05:56 +0100 Subject: [PATCH 489/936] Made LOCK instruction legality more accurate on 386, closes #4132. --- src/cpu/386_common.c | 47 ++++++++++++++++++++++++++++++++++++++++++ src/cpu/cpu.h | 12 +++++++++++ src/cpu/x86_ops_misc.h | 41 ++++++++++++++++++++++++++++++++++-- src/mem/mmu_2386.c | 1 - 4 files changed, 98 insertions(+), 3 deletions(-) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index d74b181bf..77d984048 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -120,6 +120,53 @@ int opcode_length[256] = { 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, /* 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 1, 1, 1, 1, /* 0xex */ 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3 }; /* 0xfx */ +/* 0 = no, 1 = always, 2 = depends on second opcode, 3 = depends on mod/rm */ +int lock_legal[256] = { 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 2, /* 0x0x */ + 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, /* 0x1x */ + 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, /* 0x2x */ + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x3x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x4x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x5x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x6x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x7x */ + 3, 3, 3, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x8x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xax */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xbx */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xcx */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xdx */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xex */ + 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 3, 3 }; /* 0xfx */ + +int lock_legal_0f[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x1x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x2x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x3x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x4x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x5x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x6x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x7x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x8x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9x */ + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, /* 0xax */ + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, /* 0xbx */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xcx */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xdx */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xex */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* 0xfx */ + +/* (modrm >> 3) & 0x07 */ +int lock_legal_ba[8] = { 0, 0, 0, 0, 1, 1, 1, 1 }; + +/* Also applies to 81, 82, and 83 */ +int lock_legal_80[8] = { 1, 1, 1, 1, 1, 1, 1, 0 }; + +/* Also applies to F7 */ +int lock_legal_f6[8] = { 0, 0, 1, 1, 0, 0, 0, 0 }; + +/* Also applies to FF */ +int lock_legal_fe[8] = { 1, 1, 0, 0, 0, 0, 0, 0 }; + uint32_t addr64; uint32_t addr64_2; uint32_t addr64a[8]; diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index db11b6135..1456d2ee8 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -763,6 +763,11 @@ void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg); #define SMHR_VALID (1 << 0) #define SMHR_ADDR_MASK (0xfffffffc) +typedef union { + uint32_t fd; + uint8_t b[4]; +} fetch_dat_t; + typedef struct { struct { uint32_t base; @@ -817,4 +822,11 @@ extern void prefetch_flush(void); extern void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32); +extern int lock_legal[256]; +extern int lock_legal_0f[256]; +extern int lock_legal_ba[8]; +extern int lock_legal_80[8]; +extern int lock_legal_f6[8]; +extern int lock_legal_fe[8]; + #endif /*EMU_CPU_H*/ diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index 87dddefd8..419ee7dc2 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -730,12 +730,49 @@ opHLT(uint32_t fetchdat) static int opLOCK(uint32_t fetchdat) { - fetchdat = fastreadl(cs + cpu_state.pc); + int legal; + fetch_dat_t fetch_dat; + fetchdat = fastreadl_fetch(cs + cpu_state.pc); if (cpu_state.abrt) return 0; cpu_state.pc++; - ILLEGAL_ON((fetchdat & 0xff) == 0x90); + fetch_dat.fd = fetchdat; + + legal = lock_legal[fetch_dat.b[0]]; + if (legal == 1) + legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + else if (legal == 2) { + legal = lock_legal[fetch_dat.b[1]]; + if (legal == 1) + legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,reg is illegal */ + else if (legal == 3) { + legal = lock_legal_ba[(fetch_dat.b[2] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,imm is illegal */ + } + } else if (legal == 3) switch(fetch_dat.b[0]) { + case 0x80 ... 0x83: + legal = lock_legal_80[(fetch_dat.b[1] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + break; + case 0xf6 ... 0xf7: + legal = lock_legal_f6[(fetch_dat.b[1] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + break; + case 0xfe ... 0xff: + legal = lock_legal_f6[(fetch_dat.b[1] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + break; + default: + legal = 0; + break; + } + + ILLEGAL_ON(legal == 0); CLOCK_CYCLES(4); PREFETCH_PREFIX(); diff --git a/src/mem/mmu_2386.c b/src/mem/mmu_2386.c index 7c286b605..abc34ff96 100644 --- a/src/mem/mmu_2386.c +++ b/src/mem/mmu_2386.c @@ -51,7 +51,6 @@ mem_debug_check_addr(uint32_t addr, int flags) uint32_t len_type_pair; int bp_enabled; uint8_t match_flags[4] = { 0, 2, 0, 6 }; - char *bp_types[5] = { "N/A 0", "EXEC ", "WRITE", "N/A 3", "READ " }; if (cpu_state.abrt || ((flags == 1) && (cpu_state.eflags & RF_FLAG))) return; From 4dc7342d5e97bb7726036b81a12afb33c70735b1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 10 Feb 2024 04:51:07 +0100 Subject: [PATCH 490/936] Split the NE1000 and NE2000 into the Novell and Compatible versions, with I/O base address and IRQ selections per the Windows 95 .INF file, and added the D-Link DL-220P ISA PnP NE2000 clone. --- src/include/86box/net_ne2000.h | 18 +- src/network/net_ne2000.c | 294 ++++++++++++++++++++++++++++++--- src/network/network.c | 3 + 3 files changed, 283 insertions(+), 32 deletions(-) diff --git a/src/include/86box/net_ne2000.h b/src/include/86box/net_ne2000.h index 350668ccb..907f1e9c1 100644 --- a/src/include/86box/net_ne2000.h +++ b/src/include/86box/net_ne2000.h @@ -37,18 +37,24 @@ #define NET_NE2000_H enum { - NE2K_NONE = 0, - NE2K_NE1000 = 1, /* 8-bit ISA NE1000 */ - NE2K_NE2000 = 2, /* 16-bit ISA NE2000 */ - NE2K_ETHERNEXT_MC = 3, /* 16-bit MCA EtherNext/MC */ - NE2K_RTL8019AS = 4, /* 16-bit ISA PnP Realtek 8019AS */ - NE2K_RTL8029AS = 5 /* 32-bit PCI Realtek 8029AS */ + NE2K_NONE = 0, + NE2K_NE1000 = 1, /* 8-bit ISA NE1000 */ + NE2K_NE1000_COMPAT = 2, /* 16-bit ISA NE2000-Compatible */ + NE2K_NE2000 = 3, /* 16-bit ISA NE2000 */ + NE2K_NE2000_COMPAT = 4, /* 16-bit ISA NE2000-Compatible */ + NE2K_ETHERNEXT_MC = 5, /* 16-bit MCA EtherNext/MC */ + NE2K_RTL8019AS = 6, /* 16-bit ISA PnP Realtek 8019AS */ + NE2K_DE220P = 7, /* 16-bit ISA PnP D-Link DE-220P */ + NE2K_RTL8029AS = 8 /* 32-bit PCI Realtek 8029AS */ }; extern const device_t ne1000_device; +extern const device_t ne1000_compat_device; extern const device_t ne2000_device; +extern const device_t ne2000_compat_device; extern const device_t ethernext_mc_device; extern const device_t rtl8019as_device; +extern const device_t de220p_device; extern const device_t rtl8029as_device; #endif /*NET_NE2000_H*/ diff --git a/src/network/net_ne2000.c b/src/network/net_ne2000.c index c7fba404f..03327ac0c 100644 --- a/src/network/net_ne2000.c +++ b/src/network/net_ne2000.c @@ -82,19 +82,6 @@ #define PCI_DEVID 0x8029 /* RTL8029AS */ #define PCI_REGSIZE 256 /* size of PCI space */ -static uint8_t rtl8019as_pnp_rom[] = { - 0x4a, 0x8c, 0x80, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* RTL8019, dummy checksum (filled in by isapnp_add_card) */ - 0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */ - 0x82, 0x22, 0x00, 'R', 'E', 'A', 'L', 'T', 'E', 'K', ' ', 'P', 'L', 'U', 'G', ' ', '&', ' ', 'P', 'L', 'A', 'Y', ' ', 'E', 'T', 'H', 'E', 'R', 'N', 'E', 'T', ' ', 'C', 'A', 'R', 'D', 0x00, /* ANSI identifier */ - - 0x16, 0x4a, 0x8c, 0x80, 0x19, 0x02, 0x00, /* logical device RTL8019 */ - 0x1c, 0x41, 0xd0, 0x80, 0xd6, /* compatible device PNP80D6 */ - 0x47, 0x00, 0x20, 0x02, 0x80, 0x03, 0x20, 0x20, /* I/O 0x220-0x380, decodes 10-bit, 32-byte alignment, 32 addresses */ - 0x23, 0x38, 0x9e, 0x01, /* IRQ 3/4/5/9/10/11/12/15, high true edge sensitive */ - - 0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */ -}; - typedef struct nic_t { dp8390_t *dp8390; @@ -947,7 +934,7 @@ nic_init(const device_t *info) if (dev->board != NE2K_ETHERNEXT_MC) { dev->base_address = device_get_config_hex16("base"); dev->base_irq = device_get_config_int("irq"); - if (dev->board == NE2K_NE2000) { + if ((dev->board == NE2K_NE2000) || (dev->board == NE2K_NE2000_COMPAT)) { dev->bios_addr = device_get_config_hex20("bios_addr"); dev->has_bios = !!dev->bios_addr; } else { @@ -993,6 +980,16 @@ nic_init(const device_t *info) dp8390_mem_alloc(dev->dp8390, 0x2000, 0x2000); break; + case NE2K_NE1000_COMPAT: + dev->maclocal[0] = 0x00; /* 00:86:B0 (86Box OID) */ + dev->maclocal[1] = 0x86; + dev->maclocal[2] = 0xB0; + dev->is_8bit = 1; + rom = NULL; + dp8390_set_defaults(dev->dp8390, DP8390_FLAG_CHECK_CR | DP8390_FLAG_CLEAR_IRQ); + dp8390_mem_alloc(dev->dp8390, 0x2000, 0x2000); + break; + case NE2K_NE2000: dev->maclocal[0] = 0x00; /* 00:00:D8 (Novell OID) */ dev->maclocal[1] = 0x00; @@ -1002,6 +999,15 @@ nic_init(const device_t *info) dp8390_mem_alloc(dev->dp8390, 0x4000, 0x4000); break; + case NE2K_NE2000_COMPAT: + dev->maclocal[0] = 0x00; /* 00:86:B0 (86Box OID) */ + dev->maclocal[1] = 0x86; + dev->maclocal[2] = 0xB0; + rom = ROM_PATH_NE2000; + dp8390_set_defaults(dev->dp8390, DP8390_FLAG_EVEN_MAC | DP8390_FLAG_CHECK_CR | DP8390_FLAG_CLEAR_IRQ); + dp8390_mem_alloc(dev->dp8390, 0x4000, 0x4000); + break; + case NE2K_ETHERNEXT_MC: dev->maclocal[0] = 0x00; /* 00:00:D8 (Networth Inc. OID) */ dev->maclocal[1] = 0x00; @@ -1013,6 +1019,16 @@ nic_init(const device_t *info) dp8390_mem_alloc(dev->dp8390, 0x4000, 0x4000); break; + case NE2K_DE220P: + dev->maclocal[0] = 0x00; /* 00:80:C8 (D-Link OID) */ + dev->maclocal[1] = 0x80; + dev->maclocal[2] = 0xC8; + rom = NULL; + dp8390_set_defaults(dev->dp8390, DP8390_FLAG_EVEN_MAC | DP8390_FLAG_CLEAR_IRQ); + dp8390_set_id(dev->dp8390, 0x50, 0x70); + dp8390_mem_alloc(dev->dp8390, 0x4000, 0x8000); + break; + case NE2K_RTL8019AS: case NE2K_RTL8029AS: dev->is_pci = (dev->board == NE2K_RTL8029AS) ? 1 : 0; @@ -1043,7 +1059,7 @@ nic_init(const device_t *info) * Make this device known to the I/O system. * PnP and PCI devices start with address spaces inactive. */ - if (dev->board < NE2K_RTL8019AS && dev->board != NE2K_ETHERNEXT_MC) + if ((dev->board < NE2K_RTL8019AS) && (dev->board != NE2K_ETHERNEXT_MC)) nic_ioset(dev, dev->base_address); /* Set up our BIOS ROM space, if any. */ @@ -1108,9 +1124,44 @@ nic_init(const device_t *info) dev->eeprom[0x78] = dev->eeprom[0x7C] = (PCI_VENDID & 0xff); dev->eeprom[0x79] = dev->eeprom[0x7D] = (PCI_VENDID >> 8); } else { - memcpy(&dev->eeprom[0x12], rtl8019as_pnp_rom, sizeof(rtl8019as_pnp_rom)); + const char *pnp_rom_file = NULL; + int pnp_rom_len = 0x4a; + switch (dev->board) { + case NE2K_RTL8019AS: + pnp_rom_file = "roms/network/rtl8019as/RTL8019A.BIN"; + break; - dev->pnp_card = isapnp_add_card(&dev->eeprom[0x12], sizeof(rtl8019as_pnp_rom), nic_pnp_config_changed, nic_pnp_csn_changed, nic_pnp_read_vendor_reg, nic_pnp_write_vendor_reg, dev); + case NE2K_DE220P: + pnp_rom_file = "roms/network/de220p/dlk2201a.bin"; + pnp_rom_len = 0x43; + break; + + default: + break; + } + + uint8_t *pnp_rom = NULL; + if (pnp_rom_file) { + FILE *fp = rom_fopen(pnp_rom_file, "rb"); + if (fp) { + if (fread(&dev->eeprom[0x12], 1, pnp_rom_len, fp) == pnp_rom_len) + pnp_rom = &dev->eeprom[0x12]; + fclose(fp); + } + } + + switch (info->local) { + case NE2K_RTL8019AS: + case NE2K_DE220P: + dev->pnp_card = isapnp_add_card(pnp_rom, pnp_rom_len, + nic_pnp_config_changed, nic_pnp_csn_changed, + nic_pnp_read_vendor_reg, nic_pnp_write_vendor_reg, + dev); + break; + + default: + break; + } } } @@ -1137,6 +1188,18 @@ nic_close(void *priv) free(dev); } +static int +rtl8019as_available(void) +{ + return rom_present("roms/network/rtl8019as/RTL8019A.BIN"); +} + +static int +de220p_available(void) +{ + return rom_present("roms/network/de220p/dlk2201a.bin"); +} + // clang-format off static const device_config_t ne1000_config[] = { { @@ -1148,12 +1211,11 @@ static const device_config_t ne1000_config[] = { .file_filter = "", .spinner = { 0 }, .selection = { - { .description = "0x280", .value = 0x280 }, + /* Source: Windows 95 .INF file. */ { .description = "0x300", .value = 0x300 }, { .description = "0x320", .value = 0x320 }, { .description = "0x340", .value = 0x340 }, { .description = "0x360", .value = 0x360 }, - { .description = "0x380", .value = 0x380 }, { .description = "" } }, }, @@ -1166,12 +1228,71 @@ static const device_config_t ne1000_config[] = { .file_filter = "", .spinner = { 0 }, .selection = { + /* Source: Windows 95 .INF file. */ { .description = "IRQ 2", .value = 2 }, { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 4", .value = 4 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 9", .value = 9 }, + { .description = "" } + }, + }, + { + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = "", + .default_int = -1 + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +static const device_config_t ne1000_compat_config[] = { + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x300, + .file_filter = "", + .spinner = { 0 }, + .selection = { + /* Source: Windows 95 .INF file. */ + { .description = "0x200", .value = 0x200 }, + { .description = "0x220", .value = 0x220 }, + { .description = "0x240", .value = 0x240 }, + { .description = "0x260", .value = 0x260 }, + { .description = "0x280", .value = 0x280 }, + { .description = "0x2a0", .value = 0x2a0 }, + { .description = "0x2c0", .value = 0x2c0 }, + { .description = "0x2e0", .value = 0x2e0 }, + { .description = "0x300", .value = 0x300 }, + { .description = "0x320", .value = 0x320 }, + { .description = "0x340", .value = 0x340 }, + { .description = "0x360", .value = 0x360 }, + { .description = "0x380", .value = 0x380 }, + { .description = "0x3a0", .value = 0x3a0 }, + { .description = "0x3c0", .value = 0x3c0 }, + { .description = "0x3e0", .value = 0x3e0 }, + { .description = "" } + }, + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 3, + .file_filter = "", + .spinner = { 0 }, + .selection = { + /* Source: Windows 95 .INF file. */ + { .description = "IRQ 2", .value = 2 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 4", .value = 4 }, { .description = "IRQ 5", .value = 5 }, { .description = "IRQ 7", .value = 7 }, - { .description = "IRQ 10", .value = 10 }, - { .description = "IRQ 11", .value = 11 }, + { .description = "IRQ 9", .value = 9 }, { .description = "" } }, }, @@ -1195,12 +1316,11 @@ static const device_config_t ne2000_config[] = { .file_filter = "", .spinner = { 0 }, .selection = { - { .description = "0x280", .value = 0x280 }, + /* Source: Windows 95 .INF file. */ { .description = "0x300", .value = 0x300 }, { .description = "0x320", .value = 0x320 }, { .description = "0x340", .value = 0x340 }, { .description = "0x360", .value = 0x360 }, - { .description = "0x380", .value = 0x380 }, { .description = "" } }, }, @@ -1213,12 +1333,92 @@ static const device_config_t ne2000_config[] = { .file_filter = "", .spinner = { 0 }, .selection = { + /* Source: Windows 95 .INF file. */ { .description = "IRQ 2", .value = 2 }, { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 4", .value = 4 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 9", .value = 9 }, + { .description = "" } + }, + }, + { + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = "", + .default_int = -1 + }, + { + .name = "bios_addr", + .description = "BIOS address", + .type = CONFIG_HEX20, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0x00000 }, + { .description = "D000", .value = 0xD0000 }, + { .description = "D800", .value = 0xD8000 }, + { .description = "C800", .value = 0xC8000 }, + { .description = "" } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +static const device_config_t ne2000_compat_config[] = { + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x300, + .file_filter = "", + .spinner = { 0 }, + .selection = { + /* Source: Windows 95 .INF file. */ + { .description = "0x200", .value = 0x200 }, + { .description = "0x220", .value = 0x220 }, + { .description = "0x240", .value = 0x240 }, + { .description = "0x260", .value = 0x260 }, + { .description = "0x280", .value = 0x280 }, + { .description = "0x2a0", .value = 0x2a0 }, + { .description = "0x2c0", .value = 0x2c0 }, + { .description = "0x2e0", .value = 0x2e0 }, + { .description = "0x300", .value = 0x300 }, + { .description = "0x320", .value = 0x320 }, + { .description = "0x340", .value = 0x340 }, + { .description = "0x360", .value = 0x360 }, + { .description = "0x380", .value = 0x380 }, + { .description = "0x3a0", .value = 0x3a0 }, + { .description = "0x3c0", .value = 0x3c0 }, + { .description = "0x3e0", .value = 0x3e0 }, + { .description = "" } + }, + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 10, + .file_filter = "", + .spinner = { 0 }, + .selection = { + /* Source: Windows 95 .INF file - not giving impossible IRQ's + such as 6, 8, or 13. */ + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 4", .value = 4 }, { .description = "IRQ 5", .value = 5 }, { .description = "IRQ 7", .value = 7 }, + { .description = "IRQ 9", .value = 9 }, { .description = "IRQ 10", .value = 10 }, { .description = "IRQ 11", .value = 11 }, + { .description = "IRQ 12", .value = 12 }, + { .description = "IRQ 14", .value = 14 }, + { .description = "IRQ 15", .value = 15 }, { .description = "" } }, }, @@ -1291,7 +1491,7 @@ static const device_config_t mca_mac_config[] = { const device_t ne1000_device = { .name = "Novell NE1000", - .internal_name = "ne1k", + .internal_name = "novell_ne1k", .flags = DEVICE_ISA, .local = NE2K_NE1000, .init = nic_init, @@ -1303,9 +1503,23 @@ const device_t ne1000_device = { .config = ne1000_config }; +const device_t ne1000_compat_device = { + .name = "NE1000 Compatible", + .internal_name = "ne1k", + .flags = DEVICE_ISA, + .local = NE2K_NE1000_COMPAT, + .init = nic_init, + .close = nic_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ne1000_compat_config +}; + const device_t ne2000_device = { .name = "Novell NE2000", - .internal_name = "ne2k", + .internal_name = "novell_ne2k", .flags = DEVICE_ISA | DEVICE_AT, .local = NE2K_NE2000, .init = nic_init, @@ -1317,6 +1531,20 @@ const device_t ne2000_device = { .config = ne2000_config }; +const device_t ne2000_compat_device = { + .name = "NE2000 Compatible", + .internal_name = "ne2k", + .flags = DEVICE_ISA | DEVICE_AT, + .local = NE2K_NE2000_COMPAT, + .init = nic_init, + .close = nic_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ne2000_compat_config +}; + const device_t ethernext_mc_device = { .name = "NetWorth EtherNext/MC", .internal_name = "ethernextmc", @@ -1339,7 +1567,21 @@ const device_t rtl8019as_device = { .init = nic_init, .close = nic_close, .reset = NULL, - { .available = NULL }, + { .available = rtl8019as_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = rtl8019as_config +}; + +const device_t de220p_device = { + .name = "D-Link DE-220P", + .internal_name = "de220p", + .flags = DEVICE_ISA | DEVICE_AT, + .local = NE2K_DE220P, + .init = nic_init, + .close = nic_close, + .reset = NULL, + { .available = de220p_available }, .speed_changed = NULL, .force_redraw = NULL, .config = rtl8019as_config diff --git a/src/network/network.c b/src/network/network.c index 4d11ba955..6b3a9fd1c 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -117,6 +117,9 @@ static const device_t *net_cards[] = { &threec503_device, &pcnet_am79c960_device, &pcnet_am79c961_device, + &de220p_device, + &ne1000_compat_device, + &ne2000_compat_device, &ne1000_device, &ne2000_device, &pcnet_am79c960_eb_device, From 18adcb8e0e37515e47bcb17bca6a72be5abc8a6a Mon Sep 17 00:00:00 2001 From: maximus105 <58270614+maximus105@users.noreply.github.com> Date: Sat, 10 Feb 2024 11:57:40 +0200 Subject: [PATCH 491/936] Add files via upload --- src/machine/machine_table.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 13a5d5452..24fa879bc 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -2579,7 +2579,7 @@ const machine_t machines[] = { .flags = MACHINE_XTA | MACHINE_VIDEO_FIXED, .ram = { .min = 512, - .max = 16384, + .max = 15360, .step = 512 }, .nvrmask = 63, @@ -2729,8 +2729,8 @@ const machine_t machines[] = { .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, + .min_bus = 6000000, + .max_bus = 12500000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -2740,8 +2740,8 @@ const machine_t machines[] = { .flags = MACHINE_FLAGS_NONE, .ram = { .min = 640, - .max = 16384, - .step = 128 + .max = 14912, + .step = 64 }, .nvrmask = 127, .kbc_device = NULL, @@ -3093,8 +3093,8 @@ const machine_t machines[] = { .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, + .min_bus = 6000000, + .max_bus = 12500000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -3504,7 +3504,7 @@ const machine_t machines[] = { .flags = MACHINE_IDE, .ram = { .min = 512, - .max = 16384, + .max = 8192, .step = 128 }, .nvrmask = 127, @@ -3544,7 +3544,7 @@ const machine_t machines[] = { .flags = MACHINE_FLAGS_NONE, .ram = { .min = 512, - .max = 16384, + .max = 8192, .step = 128 }, .nvrmask = 127, @@ -3704,7 +3704,7 @@ const machine_t machines[] = { .flags = MACHINE_IDE, /* Has internal video: C&T VGA 411 */ .ram = { .min = 512, - .max = 16384, + .max = 8192, .step = 128 }, .nvrmask = 127, From 9b4f98cb044befc1f2831d3c7596d9c590c91662 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 11 Feb 2024 11:07:58 +0600 Subject: [PATCH 492/936] Rewritten monochrome source data handling, partially fixes text drawing under Windows 98 SE --- src/video/vid_c&t_69000.c | 334 ++++++++++++++++++-------------------- 1 file changed, 160 insertions(+), 174 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 9968e5205..2935b7085 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -136,13 +136,12 @@ typedef struct chips_69000_t { /* Byte counter for BitBLT port writes. */ uint8_t bytes_written; uint8_t bytes_skip; + uint8_t mono_bytes_skip; + uint8_t mono_bits_skip_left; + uint8_t mono_bytes_to_skip; uint32_t bytes_counter; uint32_t bytes_in_line_written; uint8_t bytes_port[8]; - - /* Monochrome sources. */ - uint8_t mono_is_first_quadword; - uint8_t mono_bit_cntr; } bitblt_running; union { @@ -933,6 +932,7 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) ? chips->bitblt_running.bitblt.source_key_bg : chips->bitblt_running.bitblt.pattern_source_key_bg; color_key &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; + dest_pixel &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; if (!!(color_key == dest_pixel) == !!(chips->bitblt_running.bitblt.bitblt_control & (1 << 16))) { return; @@ -966,81 +966,10 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) } void -chips_69000_process_mono_data(UNUSED(chips_69000_t* chips), uint64_t val) +chips_69000_process_mono_bit(chips_69000_t* chips, uint8_t val) { - uint64_t i = 0; - uint8_t is_true = 0; - int orig_x = chips->bitblt_running.x; - int orig_y = chips->bitblt_running.y; - uint32_t source_fg = chips->bitblt_running.bitblt.pattern_source_key_fg; - uint32_t source_bg = chips->bitblt_running.bitblt.pattern_source_key_bg; - - int orig_count_x = chips->bitblt_running.count_x; - int orig_count_y = chips->bitblt_running.count_y; - - chips->bitblt_running.count_x = chips->bitblt_running.count_y = 0; - - if (chips->bitblt_running.bitblt.monochrome_source_expansion_color_reg_select) { - source_fg = chips->bitblt_running.bitblt.source_key_fg; - source_bg = chips->bitblt_running.bitblt.source_key_bg; - } - - for (i = 0; i < 64; i++) { - uint32_t pixel = 0x0; - if (chips->bitblt_running.mono_is_first_quadword && (i < chips->bitblt_running.bitblt.monochrome_source_initial_discard)) - goto increment; - - if (i < chips->bitblt_running.bitblt.monochrome_source_left_clip) - goto increment; - - if (i >= (64 - chips->bitblt_running.bitblt.monochrome_source_right_clip)) - goto increment; - - is_true = !!(val & (1 << (i))); - - if (!is_true && (chips->bitblt_running.bitblt.bitblt_control & (1 << 13))) { - goto increment; - } - - pixel = is_true ? source_fg : source_bg; - pixel &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; - - chips->bitblt_running.x = orig_x + (chips->bitblt_running.count_x); - chips->bitblt_running.y = orig_y + chips->bitblt_running.count_y; - - if ((orig_count_x + (chips->bitblt_running.count_x)) < chips->bitblt_running.actual_destination_width - && (orig_count_y + chips->bitblt_running.count_y) < chips->bitblt_running.actual_destination_height) - chips_69000_process_pixel(chips, pixel); - -increment: - chips->bitblt_running.count_x++; - if (chips->bitblt_running.count_x == 8) { - chips->bitblt_running.count_x = 0; - chips->bitblt_running.count_y++; - } - } - chips->bitblt_running.x = orig_x; - chips->bitblt_running.y = orig_y; - chips->bitblt_running.count_x = orig_count_x; - chips->bitblt_running.count_y = orig_count_y; - chips->bitblt_running.x += chips->bitblt_running.x_dir * 8; - chips->bitblt_running.count_x += 8; - chips->bitblt_running.mono_is_first_quadword = 0; - if (chips->bitblt_running.count_x >= chips->bitblt_running.actual_destination_width) { - chips->bitblt_running.count_y += 8; - chips->bitblt_running.y += chips->bitblt_running.y_dir * 8; - chips->bitblt_running.count_x = 0; - if (chips->bitblt_running.count_y > chips->bitblt_running.actual_destination_height) - chips_69000_bitblt_interrupt(chips); - } -} - -void -chips_69000_process_mono_data_non_qword(UNUSED(chips_69000_t* chips), uint8_t val) -{ - uint64_t i = 0; - uint8_t is_true = 0; - int orig_x = chips->bitblt_running.x; + uint32_t pixel = 0x0; + uint8_t is_true = !!val; uint32_t source_fg = chips->bitblt_running.bitblt.pattern_source_key_fg; uint32_t source_bg = chips->bitblt_running.bitblt.pattern_source_key_bg; @@ -1049,46 +978,35 @@ chips_69000_process_mono_data_non_qword(UNUSED(chips_69000_t* chips), uint8_t va source_bg = chips->bitblt_running.bitblt.source_key_bg; } - for (i = chips->bitblt_running.mono_bit_cntr; i < (chips->bitblt_running.mono_bit_cntr + 8); i++) { - uint32_t pixel = 0x0; - - if (chips->bitblt_running.mono_is_first_quadword && (i < chips->bitblt_running.bitblt.monochrome_source_initial_discard)) - continue; - - if (i < chips->bitblt_running.bitblt.monochrome_source_left_clip) - continue; - - if (i >= (64 - chips->bitblt_running.bitblt.monochrome_source_right_clip)) - continue; - - is_true = !!(val & (1 << (7 - (i & 7)))); - - if (!is_true && (chips->bitblt_running.bitblt.bitblt_control & (1 << 13))) { - continue; - } - - pixel = is_true ? source_fg : source_bg; - pixel &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; - - chips->bitblt_running.x = (orig_x + (i & 7) * chips->bitblt_running.x_dir); - - if ((chips->bitblt_running.count_x + (i & 7)) < chips->bitblt_running.actual_destination_width) - chips_69000_process_pixel(chips, pixel); + if (chips->bitblt_running.bitblt.monochrome_source_initial_discard) { + chips->bitblt_running.bitblt.monochrome_source_initial_discard--; + return; } - chips->bitblt_running.mono_bit_cntr += 8; - chips->bitblt_running.x = orig_x; - chips->bitblt_running.x += chips->bitblt_running.x_dir * 8; - chips->bitblt_running.count_x += 8; - if (chips->bitblt_running.mono_bit_cntr >= 64) { - chips->bitblt_running.mono_is_first_quadword = 0; - chips->bitblt_running.mono_bit_cntr = 0; + + if (chips->bitblt_running.mono_bits_skip_left) { + chips->bitblt_running.mono_bits_skip_left--; + return; } + + if (!is_true && (chips->bitblt_running.bitblt.bitblt_control & (1 << 13))) { + goto advance; + } + pixel = is_true ? source_fg : source_bg; + pixel &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; + + chips_69000_process_pixel(chips, pixel); + +advance: + chips->bitblt_running.x += chips->bitblt_running.x_dir; + chips->bitblt_running.count_x += 1; if (chips->bitblt_running.count_x >= chips->bitblt_running.actual_destination_width) { chips->bitblt_running.count_y += 1; chips->bitblt_running.y += chips->bitblt_running.y_dir * 1; chips->bitblt_running.count_x = 0; chips->bitblt_running.x = 0; - if (chips->bitblt_running.count_y >= chips->bitblt_running.actual_destination_height) + chips->bitblt_running.mono_bytes_to_skip = chips->bitblt_running.mono_bytes_skip; + chips->bitblt_running.mono_bits_skip_left = chips->bitblt_running.bitblt.monochrome_source_left_clip; + if (chips->bitblt_running.count_y >= (chips->bitblt_running.actual_destination_height)) chips_69000_bitblt_interrupt(chips); } } @@ -1099,18 +1017,25 @@ void chips_69000_setup_bitblt(chips_69000_t* chips) { chips->engine_active = 1; + + memset(&chips->bitblt_running, 0, sizeof(chips->bitblt_running)); + chips->bitblt_running.bitblt = chips->bitblt; chips->bitblt_running.actual_source_height = chips->bitblt.destination_height; chips->bitblt_running.actual_destination_height = chips->bitblt.destination_height; chips->bitblt_running.count_x = chips->bitblt_running.count_y = 0; chips->bitblt_running.bytes_written = 0; chips->bitblt_running.bytes_counter = 0; - chips->bitblt_running.mono_is_first_quadword = 1; - chips->bitblt_running.mono_bit_cntr = 0; chips->bitblt_running.bytes_in_line_written = 0; chips->bitblt_running.bytes_skip = 0; + chips->bitblt_running.mono_bytes_skip = 0; + chips->bitblt_running.mono_bytes_to_skip = 0; + chips->bitblt_running.mono_bits_skip_left = 0; int orig_cycles = cycles; + if (chips->bitblt_running.bitblt.source_span != chips->bitblt_running.bitblt.destination_span) + pclog("source_span = %d, destination_span = %d\n", chips->bitblt_running.bitblt.source_span, chips->bitblt_running.bitblt.destination_span); + if (chips->bitblt.bitblt_control & (1 << 23)) { chips->bitblt_running.bytes_per_pixel = 1 + ((chips->bitblt.bitblt_control >> 24) & 3); } else { @@ -1152,6 +1077,19 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips_69000_bitblt_interrupt(chips); return; } + + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { + pclog("C&T: Monochrome blit (monochrome_source_alignment = %d, " + "monochrome left clip = %d, " + "monochrome right clip = %d, " + "monochrome initial discard = %d, " + "destination_width = %d, destination_height = %d)\n", chips->bitblt_running.bitblt.monochrome_source_alignment, + chips->bitblt_running.bitblt.monochrome_source_left_clip, + chips->bitblt_running.bitblt.monochrome_source_right_clip, + chips->bitblt_running.bitblt.monochrome_source_initial_discard, + chips->bitblt_running.bitblt.destination_width, + chips->bitblt_running.bitblt.destination_height); + } if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { if (!(chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { @@ -1160,26 +1098,18 @@ chips_69000_setup_bitblt(chips_69000_t* chips) */ if ((chips->bitblt_running.bitblt.source_addr + (chips->bitblt_running.bitblt.destination_width)) > ((chips->bitblt_running.bitblt.destination_width + 7) & ~7)) chips->bitblt_running.bytes_skip = 8 + (((chips->bitblt_running.bitblt.destination_width + 7) & ~7) - chips->bitblt_running.bitblt.destination_width); + } else { + chips->bitblt_running.mono_bytes_skip = (chips->bitblt_running.actual_destination_width <= 32 + && chips->bitblt_running.bitblt.monochrome_source_alignment == 0 + && chips->bitblt_running.actual_destination_width > 16) ? 4 : 0; + chips->bitblt_running.mono_bits_skip_left = chips->bitblt_running.bitblt.monochrome_source_left_clip; } + return; } - - if (chips->bitblt_running.x_dir == -1 && chips->bitblt_running.bytes_per_pixel == 3) { - //chips->bitblt_running.actual_destination_width++; - } if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { uint32_t source_addr = chips->bitblt_running.bitblt.source_addr; - pclog("C&T: Monochrome blit (monochrome_source_alignment = %d, " - "monochrome left clip = %d, " - "monochrome right clip = %d, " - "monochrome initial discard = %d, " - "destination_width = %d, destination_height = %d\n", chips->bitblt_running.bitblt.monochrome_source_alignment, - chips->bitblt_running.bitblt.monochrome_source_left_clip, - chips->bitblt_running.bitblt.monochrome_source_right_clip, - chips->bitblt_running.bitblt.monochrome_source_initial_discard, - chips->bitblt_running.bitblt.destination_width, - chips->bitblt_running.bitblt.destination_height); while (chips->engine_active) { switch (chips->bitblt_running.bitblt.monochrome_source_alignment) { @@ -1200,6 +1130,13 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.bitblt.source_addr = source_addr; break; } + case 2: /* Byte-aligned */ + { + uint32_t data = chips_69000_readb_linear(source_addr, chips); + chips_69000_bitblt_write(chips, data & 0xFF); + source_addr += 1; + break; + } case 4: /* Doubleword-aligned*/ { uint32_t data = chips_69000_readl_linear(source_addr, chips); @@ -1226,6 +1163,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) } } } + return; } do { @@ -1276,54 +1214,75 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { int orig_cycles = cycles; + if (chips->bitblt_running.mono_bytes_to_skip) { + chips->bitblt_running.mono_bytes_to_skip--; + return; + } chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; - if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0) { - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); + if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0 || chips->bitblt_running.bitblt.monochrome_source_alignment == 2) { + int orig_count_y = chips->bitblt_running.count_y; + int i = 0; + uint8_t val = chips->bitblt_running.bytes_port[0]; chips->bitblt_running.bytes_written = 0; + + for (i = 0; i < 8; i++) { + chips_69000_process_mono_bit(chips, !!(val & (1 << (7 - i)))); + if (orig_count_y != chips->bitblt_running.count_y) { + cycles = orig_cycles; + return; + } + } } else if (chips->bitblt_running.bitblt.monochrome_source_alignment == 3 && chips->bitblt_running.bytes_written == 2) { + int orig_count_y = chips->bitblt_running.count_y; + int i = 0; + uint16_t val = (chips->bitblt_running.bytes_port[1]) | (chips->bitblt_running.bytes_port[0] << 8); chips->bitblt_running.bytes_written = 0; - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); - if (chips->bitblt_running.actual_destination_width > 8) - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[1]); + + for (i = 0; i < 16; i++) { + chips_69000_process_mono_bit(chips, !!(val & (1 << (15 - i)))); + if (orig_count_y != chips->bitblt_running.count_y) { + cycles = orig_cycles; + return; + } + } } else if (chips->bitblt_running.bitblt.monochrome_source_alignment == 4 && chips->bitblt_running.bytes_written == 4) { + int orig_count_y = chips->bitblt_running.count_y; + int i = 0; + uint32_t val = chips->bitblt_running.bytes_port[3] | (chips->bitblt_running.bytes_port[2] << 8) | (chips->bitblt_running.bytes_port[1] << 16) | (chips->bitblt_running.bytes_port[0] << 24); chips->bitblt_running.bytes_written = 0; - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); - if (chips->bitblt_running.actual_destination_width > 8) - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[1]); - if (chips->bitblt_running.actual_destination_width > 16) - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[2]); - if (chips->bitblt_running.actual_destination_width > 24) - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[3]); + + for (i = 0; i < 32; i++) { + chips_69000_process_mono_bit(chips, !!(val & (1 << (31 - i)))); + if (orig_count_y != chips->bitblt_running.count_y) { + cycles = orig_cycles; + return; + } + } } else if (chips->bitblt_running.bitblt.monochrome_source_alignment == 5 && chips->bitblt_running.bytes_written == 8) { + int orig_count_y = chips->bitblt_running.count_y; + int i = 0; + uint64_t val = 0; + + val |= chips->bitblt_running.bytes_port[7]; + val |= chips->bitblt_running.bytes_port[6] << 8; + val |= chips->bitblt_running.bytes_port[5] << 16; + val |= chips->bitblt_running.bytes_port[4] << 24; + val |= (uint64_t)chips->bitblt_running.bytes_port[3] << 32ULL; + val |= (uint64_t)chips->bitblt_running.bytes_port[2] << 40ULL; + val |= (uint64_t)chips->bitblt_running.bytes_port[1] << 48ULL; + val |= (uint64_t)chips->bitblt_running.bytes_port[0] << 56ULL; + chips->bitblt_running.bytes_written = 0; - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[0]); - if (chips->bitblt_running.actual_destination_width > 8) - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[1]); - if (chips->bitblt_running.actual_destination_width > 16) - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[2]); - if (chips->bitblt_running.actual_destination_width > 24) - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[3]); - if (chips->bitblt_running.actual_destination_width > 32) - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[4]); - if (chips->bitblt_running.actual_destination_width > 40) - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[5]); - if (chips->bitblt_running.actual_destination_width > 48) - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[6]); - if (chips->bitblt_running.actual_destination_width > 52) - chips_69000_process_mono_data_non_qword(chips, chips->bitblt_running.bytes_port[7]); - } else if (chips->bitblt_running.bytes_written == 8) { - chips->bitblt_running.bytes_written = 0; - uint64_t mono_data = chips->bitblt_running.bytes_port[0]; - mono_data |= (uint64_t)chips->bitblt_running.bytes_port[1] << 8ull; - mono_data |= (uint64_t)chips->bitblt_running.bytes_port[2] << 16ull; - mono_data |= (uint64_t)chips->bitblt_running.bytes_port[3] << 24ull; - mono_data |= (uint64_t)chips->bitblt_running.bytes_port[4] << 32ull; - mono_data |= (uint64_t)chips->bitblt_running.bytes_port[5] << 40ull; - mono_data |= (uint64_t)chips->bitblt_running.bytes_port[6] << 48ull; - mono_data |= (uint64_t)chips->bitblt_running.bytes_port[7] << 56ull; - chips_69000_process_mono_data(chips, mono_data); + + for (i = 0; i < 64; i++) { + chips_69000_process_mono_bit(chips, !!(val & (1 << (63 - i)))); + if (orig_count_y != chips->bitblt_running.count_y) { + cycles = orig_cycles; + return; + } + } } cycles = orig_cycles; return; @@ -1433,18 +1392,12 @@ chips_69000_read_ext_reg(chips_69000_t* chips) val |= 1; break; } - // if (chips->ext_index != 0x4E && chips->ext_index != 0x4F - // && (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) - // pclog("C&T: Read ext reg 0x%02X, ret = 0x%02X\n", index, val); return val; } void chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) { - // if (chips->ext_index != 0x4E && chips->ext_index != 0x4F - // && (chips->ext_index < 0xE0 || chips->ext_index > 0xEB)) - // pclog("C&T: Write ext reg 0x%02X, ret = 0x%02X\n", chips->ext_index, val); switch (chips->ext_index) { case 0xA: chips->ext_regs[chips->ext_index] = val & 0x37; @@ -1658,9 +1611,11 @@ chips_69000_out(uint16_t addr, uint8_t val, void *p) } } break; + case 0x3B6: case 0x3D6: chips->ext_index = val; return; + case 0x3B7: case 0x3D7: return chips_69000_write_ext_reg(chips, val); @@ -1732,9 +1687,11 @@ chips_69000_in(uint16_t addr, void *p) else temp = svga->crtc[svga->crtcreg]; break; + case 0x3B6: case 0x3D6: temp = chips->ext_index; break; + case 0x3B7: case 0x3D7: temp = chips_69000_read_ext_reg(chips); break; @@ -1876,7 +1833,6 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) uint8_t chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) { - //pclog("C&T Read 0x%X\n", addr); addr &= 0xFFF; switch (addr & 0xFFF) { case 0x00 ... 0x28: @@ -1884,6 +1840,10 @@ chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) return (chips->bitblt_regs_b[addr & 0xFF] & 0x7F) | (chips->engine_active ? 0x80 : 0x00); } return chips->bitblt_regs_b[addr & 0xFF]; + case 0x3b: + return (chips->engine_active ? 0x80 : 0x00); + case 0x38: + return (0xFF - chips->ext_regs[0xD2]); case 0x600 ... 0x60F: return chips->mem_regs_b[addr & 0xF]; case 0x768: @@ -1937,7 +1897,7 @@ chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) case 0x7B4: return chips_69000_in(0x3da, chips); } - return 0xFF; + return 0x00; } uint16_t @@ -1978,6 +1938,9 @@ chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) chips_69000_setup_bitblt(chips); } break; + default: + pclog("C&T Write (unknown) 0x%X, val = 0x%02X\n", addr, val); + break; case 0x600 ... 0x60F: switch (addr & 0xFFF) { @@ -2065,6 +2028,9 @@ void chips_69000_writew_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) { if (addr & 0x10000) { + if ((chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { + pclog("BitBLT mono 0x%04X\n", val); + } chips_69000_bitblt_write(chips, val & 0xFF); chips_69000_bitblt_write(chips, (val >> 8) & 0xFF); return; @@ -2083,7 +2049,7 @@ chips_69000_writel_mmio(uint32_t addr, uint32_t val, chips_69000_t* chips) { if (addr & 0x10000) { if ((chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { - //pclog("BitBLT mono 0x%08X\n", val); + pclog("BitBLT mono 0x%08X\n", val); } chips_69000_bitblt_write(chips, val & 0xFF); chips_69000_bitblt_write(chips, (val >> 8) & 0xFF); @@ -2118,6 +2084,13 @@ chips_69000_readw_linear(uint32_t addr, void *p) svga_t *svga = (svga_t *) p; chips_69000_t *chips = (chips_69000_t *) svga->priv; + if (addr & 0x800000) { + if (addr & 0x400000) + return bswap16(chips_69000_readw_mmio(addr, chips)); + + return bswap16(svga_readw_linear(addr & 0x1FFFFF, p)); + } + if (addr & 0x400000) return chips_69000_readw_mmio(addr, chips); @@ -2130,6 +2103,13 @@ chips_69000_readl_linear(uint32_t addr, void *p) svga_t *svga = (svga_t *) p; chips_69000_t *chips = (chips_69000_t *) svga->priv; + if (addr & 0x800000) { + if (addr & 0x400000) + return bswap32(chips_69000_readl_mmio(addr, chips)); + + return bswap32(svga_readl_linear(addr & 0x1FFFFF, p)); + } + if (addr & 0x400000) return chips_69000_readl_mmio(addr, chips); @@ -2154,6 +2134,9 @@ chips_69000_writew_linear(uint32_t addr, uint16_t val, void *p) svga_t *svga = (svga_t *) p; chips_69000_t *chips = (chips_69000_t *) svga->priv; + if (addr & 0x800000) + val = bswap16(val); + if (addr & 0x400000) return chips_69000_writew_mmio(addr, val, chips); @@ -2166,6 +2149,9 @@ chips_69000_writel_linear(uint32_t addr, uint32_t val, void *p) svga_t *svga = (svga_t *) p; chips_69000_t *chips = (chips_69000_t *) svga->priv; + if (addr & 0x800000) + val = bswap32(val); + if (addr & 0x400000) return chips_69000_writel_mmio(addr, val, chips); From 376b704ceab0f2edd8326b18500831b99563fb3e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 12 Feb 2024 01:25:27 +0600 Subject: [PATCH 493/936] Fix 16+ bpp text background drawing --- src/video/vid_c&t_69000.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 2935b7085..94b5750ce 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -141,7 +141,7 @@ typedef struct chips_69000_t { uint8_t mono_bytes_to_skip; uint32_t bytes_counter; uint32_t bytes_in_line_written; - uint8_t bytes_port[8]; + uint8_t bytes_port[256]; } bitblt_running; union { @@ -1835,7 +1835,7 @@ chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) { addr &= 0xFFF; switch (addr & 0xFFF) { - case 0x00 ... 0x28: + case 0x00 ... 0x2B: if (addr == 0x13) { return (chips->bitblt_regs_b[addr & 0xFF] & 0x7F) | (chips->engine_active ? 0x80 : 0x00); } @@ -1932,7 +1932,7 @@ chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) } addr &= 0xFFF; switch (addr & 0xFFF) { - case 0x00 ... 0x28: + case 0x00 ... 0x2B: chips->bitblt_regs_b[addr & 0xFF] = val; if ((addr & 0xFFF) == 0x023 && chips->bitblt_regs[0x8] != 0) { chips_69000_setup_bitblt(chips); From a9a6c9c1219b209dc0d49bf0d557589810bb9aa4 Mon Sep 17 00:00:00 2001 From: JoshuaMaitland Date: Mon, 12 Feb 2024 18:10:18 +0000 Subject: [PATCH 494/936] Bumped the minimum ram to 8MB on ASUS P5A It would cause a hang in the BIOS if it's lower than 8MB --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 24fa879bc..8baf908e6 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -12265,7 +12265,7 @@ const machine_t machines[] = { .bus_flags = MACHINE_PS2_AGP, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, .ram = { - .min = 1024, + .min = 8192, .max = 1572864, .step = 8192 }, From 40d7e626fc94e2b47d362f6a38488a7798fe799f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 13 Feb 2024 01:15:53 +0600 Subject: [PATCH 495/936] Fix monochrome blits for real --- src/video/vid_c&t_69000.c | 62 +++++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 15 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 94b5750ce..697d7d19b 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -137,6 +137,7 @@ typedef struct chips_69000_t { uint8_t bytes_written; uint8_t bytes_skip; uint8_t mono_bytes_skip; + uint32_t mono_bytes_pitch; uint8_t mono_bits_skip_left; uint8_t mono_bytes_to_skip; uint32_t bytes_counter; @@ -973,6 +974,9 @@ chips_69000_process_mono_bit(chips_69000_t* chips, uint8_t val) uint32_t source_fg = chips->bitblt_running.bitblt.pattern_source_key_fg; uint32_t source_bg = chips->bitblt_running.bitblt.pattern_source_key_bg; + if (!chips->engine_active) + return; + if (chips->bitblt_running.bitblt.monochrome_source_expansion_color_reg_select) { source_fg = chips->bitblt_running.bitblt.source_key_fg; source_bg = chips->bitblt_running.bitblt.source_key_bg; @@ -1019,7 +1023,6 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->engine_active = 1; memset(&chips->bitblt_running, 0, sizeof(chips->bitblt_running)); - chips->bitblt_running.bitblt = chips->bitblt; chips->bitblt_running.actual_source_height = chips->bitblt.destination_height; chips->bitblt_running.actual_destination_height = chips->bitblt.destination_height; @@ -1029,13 +1032,11 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.bytes_in_line_written = 0; chips->bitblt_running.bytes_skip = 0; chips->bitblt_running.mono_bytes_skip = 0; + chips->bitblt_running.mono_bytes_pitch = 0; chips->bitblt_running.mono_bytes_to_skip = 0; chips->bitblt_running.mono_bits_skip_left = 0; int orig_cycles = cycles; - if (chips->bitblt_running.bitblt.source_span != chips->bitblt_running.bitblt.destination_span) - pclog("source_span = %d, destination_span = %d\n", chips->bitblt_running.bitblt.source_span, chips->bitblt_running.bitblt.destination_span); - if (chips->bitblt.bitblt_control & (1 << 23)) { chips->bitblt_running.bytes_per_pixel = 1 + ((chips->bitblt.bitblt_control >> 24) & 3); } else { @@ -1055,7 +1056,8 @@ chips_69000_setup_bitblt(chips_69000_t* chips) case 1: chips->bitblt_running.x_dir = -1; chips->bitblt_running.y_dir = 1; - chips->bitblt_running.bitblt.source_addr -= (chips->bitblt_running.bytes_per_pixel - 1); + if (!(chips->bitblt_running.bitblt.bitblt_control & (1 << 10))) + chips->bitblt_running.bitblt.source_addr -= (chips->bitblt_running.bytes_per_pixel - 1); chips->bitblt_running.bitblt.destination_addr -= (chips->bitblt_running.bytes_per_pixel - 1); break; case 2: @@ -1065,7 +1067,8 @@ chips_69000_setup_bitblt(chips_69000_t* chips) case 3: chips->bitblt_running.x_dir = -1; chips->bitblt_running.y_dir = -1; - chips->bitblt_running.bitblt.source_addr -= (chips->bitblt_running.bytes_per_pixel - 1); + if (!(chips->bitblt_running.bitblt.bitblt_control & (1 << 10))) + chips->bitblt_running.bitblt.source_addr -= (chips->bitblt_running.bytes_per_pixel - 1); chips->bitblt_running.bitblt.destination_addr -= (chips->bitblt_running.bytes_per_pixel - 1); break; } @@ -1078,6 +1081,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) return; } +#if 0 if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { pclog("C&T: Monochrome blit (monochrome_source_alignment = %d, " "monochrome left clip = %d, " @@ -1090,6 +1094,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.bitblt.destination_width, chips->bitblt_running.bitblt.destination_height); } +#endif if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { if (!(chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { @@ -1099,10 +1104,12 @@ chips_69000_setup_bitblt(chips_69000_t* chips) if ((chips->bitblt_running.bitblt.source_addr + (chips->bitblt_running.bitblt.destination_width)) > ((chips->bitblt_running.bitblt.destination_width + 7) & ~7)) chips->bitblt_running.bytes_skip = 8 + (((chips->bitblt_running.bitblt.destination_width + 7) & ~7) - chips->bitblt_running.bitblt.destination_width); } else { - chips->bitblt_running.mono_bytes_skip = (chips->bitblt_running.actual_destination_width <= 32 - && chips->bitblt_running.bitblt.monochrome_source_alignment == 0 - && chips->bitblt_running.actual_destination_width > 16) ? 4 : 0; + chips->bitblt_running.mono_bytes_skip = 0; chips->bitblt_running.mono_bits_skip_left = chips->bitblt_running.bitblt.monochrome_source_left_clip; + + if (!chips->bitblt_running.mono_bytes_skip && chips->bitblt_running.bitblt.monochrome_source_alignment == 0) { + chips->bitblt_running.mono_bytes_pitch = ((chips->bitblt_running.actual_destination_width + chips->bitblt_running.bitblt.monochrome_source_left_clip + 63) & ~63) / 8; + } } return; @@ -1119,9 +1126,15 @@ chips_69000_setup_bitblt(chips_69000_t* chips) uint32_t orig_count_y = chips->bitblt_running.count_y; uint32_t orig_source_addr = chips->bitblt_running.bitblt.source_addr; while (orig_count_y == chips->bitblt_running.count_y) { + int i = 0; uint8_t data = chips_69000_readb_linear(orig_source_addr, chips); orig_source_addr++; - chips_69000_bitblt_write(chips, data & 0xFF); + for (i = 0; i < 8; i++) { + chips_69000_process_mono_bit(chips, !!(data & (1 << (7 - i)))); + if (orig_count_y != chips->bitblt_running.count_y) { + break; + } + } if ((source_addr + chips->bitblt_running.bitblt.source_span) == orig_source_addr) break; } @@ -1219,7 +1232,23 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { return; } chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; - if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0 || chips->bitblt_running.bitblt.monochrome_source_alignment == 2) { + if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0 && chips->bitblt_running.mono_bytes_pitch && chips->bitblt_running.mono_bytes_pitch == chips->bitblt_running.bytes_written) { + int orig_count_y = chips->bitblt_running.count_y; + int i = 0, j = 0; + uint8_t val = chips->bitblt_running.bytes_port[0]; + chips->bitblt_running.bytes_written = 0; + + for (j = 0; j < chips->bitblt_running.mono_bytes_pitch; j++) { + for (i = 0; i < 8; i++) { + chips_69000_process_mono_bit(chips, !!(chips->bitblt_running.bytes_port[j] & (1 << (7 - i)))); + if (orig_count_y != chips->bitblt_running.count_y) { + cycles = orig_cycles; + return; + } + } + } + } + else if ((chips->bitblt_running.bitblt.monochrome_source_alignment == 0 && !chips->bitblt_running.mono_bytes_pitch) || chips->bitblt_running.bitblt.monochrome_source_alignment == 2) { int orig_count_y = chips->bitblt_running.count_y; int i = 0; uint8_t val = chips->bitblt_running.bytes_port[0]; @@ -1289,7 +1318,7 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { } chips->bitblt_running.bytes_counter++; - if (chips->bitblt_running.bytes_counter <= (chips->bitblt_running.bitblt.source_addr)) { + if (chips->bitblt_running.bytes_counter <= (chips->bitblt_running.bitblt.source_addr & 7)) { return; } chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; @@ -1843,7 +1872,7 @@ chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) case 0x3b: return (chips->engine_active ? 0x80 : 0x00); case 0x38: - return (0xFF - chips->ext_regs[0xD2]); + return 0x7F; case 0x600 ... 0x60F: return chips->mem_regs_b[addr & 0xF]; case 0x768: @@ -1933,6 +1962,9 @@ chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) addr &= 0xFFF; switch (addr & 0xFFF) { case 0x00 ... 0x2B: + if (addr <= 0x3) { + //pclog("[%04X:%08X] C&T Write span 0x%X, val = 0x%02X\n", CS, cpu_state.pc, addr, val); + } chips->bitblt_regs_b[addr & 0xFF] = val; if ((addr & 0xFFF) == 0x023 && chips->bitblt_regs[0x8] != 0) { chips_69000_setup_bitblt(chips); @@ -2029,7 +2061,7 @@ chips_69000_writew_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) { if (addr & 0x10000) { if ((chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { - pclog("BitBLT mono 0x%04X\n", val); + //pclog("BitBLT mono 0x%04X\n", val); } chips_69000_bitblt_write(chips, val & 0xFF); chips_69000_bitblt_write(chips, (val >> 8) & 0xFF); @@ -2049,7 +2081,7 @@ chips_69000_writel_mmio(uint32_t addr, uint32_t val, chips_69000_t* chips) { if (addr & 0x10000) { if ((chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { - pclog("BitBLT mono 0x%08X\n", val); + //pclog("BitBLT mono 0x%08X\n", val); } chips_69000_bitblt_write(chips, val & 0xFF); chips_69000_bitblt_write(chips, (val >> 8) & 0xFF); From 62135c5c8a4096d1f4feeb93b29094b5576d5560 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 13 Feb 2024 01:28:14 +0600 Subject: [PATCH 496/936] Minor cleanup --- src/video/vid_c&t_69000.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 697d7d19b..973502f55 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -136,10 +136,8 @@ typedef struct chips_69000_t { /* Byte counter for BitBLT port writes. */ uint8_t bytes_written; uint8_t bytes_skip; - uint8_t mono_bytes_skip; uint32_t mono_bytes_pitch; uint8_t mono_bits_skip_left; - uint8_t mono_bytes_to_skip; uint32_t bytes_counter; uint32_t bytes_in_line_written; uint8_t bytes_port[256]; @@ -1008,7 +1006,6 @@ advance: chips->bitblt_running.y += chips->bitblt_running.y_dir * 1; chips->bitblt_running.count_x = 0; chips->bitblt_running.x = 0; - chips->bitblt_running.mono_bytes_to_skip = chips->bitblt_running.mono_bytes_skip; chips->bitblt_running.mono_bits_skip_left = chips->bitblt_running.bitblt.monochrome_source_left_clip; if (chips->bitblt_running.count_y >= (chips->bitblt_running.actual_destination_height)) chips_69000_bitblt_interrupt(chips); @@ -1031,9 +1028,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.bytes_counter = 0; chips->bitblt_running.bytes_in_line_written = 0; chips->bitblt_running.bytes_skip = 0; - chips->bitblt_running.mono_bytes_skip = 0; chips->bitblt_running.mono_bytes_pitch = 0; - chips->bitblt_running.mono_bytes_to_skip = 0; chips->bitblt_running.mono_bits_skip_left = 0; int orig_cycles = cycles; @@ -1104,10 +1099,9 @@ chips_69000_setup_bitblt(chips_69000_t* chips) if ((chips->bitblt_running.bitblt.source_addr + (chips->bitblt_running.bitblt.destination_width)) > ((chips->bitblt_running.bitblt.destination_width + 7) & ~7)) chips->bitblt_running.bytes_skip = 8 + (((chips->bitblt_running.bitblt.destination_width + 7) & ~7) - chips->bitblt_running.bitblt.destination_width); } else { - chips->bitblt_running.mono_bytes_skip = 0; chips->bitblt_running.mono_bits_skip_left = chips->bitblt_running.bitblt.monochrome_source_left_clip; - if (!chips->bitblt_running.mono_bytes_skip && chips->bitblt_running.bitblt.monochrome_source_alignment == 0) { + if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0) { chips->bitblt_running.mono_bytes_pitch = ((chips->bitblt_running.actual_destination_width + chips->bitblt_running.bitblt.monochrome_source_left_clip + 63) & ~63) / 8; } } @@ -1227,10 +1221,6 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { int orig_cycles = cycles; - if (chips->bitblt_running.mono_bytes_to_skip) { - chips->bitblt_running.mono_bytes_to_skip--; - return; - } chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0 && chips->bitblt_running.mono_bytes_pitch && chips->bitblt_running.mono_bytes_pitch == chips->bitblt_running.bytes_written) { int orig_count_y = chips->bitblt_running.count_y; From 6e35d009420739e2acd29c5f77fa55dd1ef758c4 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 13 Feb 2024 01:49:43 +0600 Subject: [PATCH 497/936] Gamma correction support --- src/video/vid_c&t_69000.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 973502f55..6f41ba2df 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -752,6 +752,9 @@ chips_69000_recalctimings(svga_t *svga) } switch (chips->ext_regs[0x81] & 0xF) { + default: + svga->bpp = 8; + break; case 0b0010: svga->bpp = 8; svga->render = svga_render_8bpp_highres; @@ -1479,6 +1482,10 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) chips->ext_regs[chips->ext_index] = val & 0x1f; svga_recalctimings(&chips->svga); break; + case 0x82: + chips->ext_regs[chips->ext_index] = val & 0xf; + chips->svga.lut_map = !!(val & 0x8); + break; case 0xA0: chips->ext_regs[chips->ext_index] = val; chips->svga.hwcursor.ena = ((val & 7) == 0b101) || ((val & 7) == 0b1); From afa545ca25f164ba6ccffb271306b4791d441288 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 13 Feb 2024 01:57:54 +0600 Subject: [PATCH 498/936] Bit-depth fixes --- src/video/vid_c&t_69000.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 6f41ba2df..273c5de5c 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -777,6 +777,8 @@ chips_69000_recalctimings(svga_t *svga) svga->render = svga_render_32bpp_highres; break; } + } else { + svga->bpp = 8; } } From fd33034915f36824d6d5c7ea60d9dc6c04895077 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 13 Feb 2024 11:42:15 +0600 Subject: [PATCH 499/936] 1600x1200 resolution fixes Fix source address behaviour properly --- src/video/vid_c&t_69000.c | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 273c5de5c..0118bcd1f 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -15,6 +15,7 @@ * Copyright 2023-2024 Cacodemon345 */ #include +#include #include #include #include @@ -90,8 +91,8 @@ typedef struct chips_69000_t { uint8_t pci_line_interrupt; uint8_t pci_rom_enable; uint8_t read_write_bank; - atomic_bool engine_active; - atomic_bool quit; + bool engine_active; + bool quit; thread_t *accel_thread; event_t *fifo_event, *fifo_data_event; pc_timer_t decrement_timer; @@ -1095,8 +1096,9 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.bitblt.destination_height); } #endif - + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { + chips->bitblt_running.bitblt.source_addr &= 7; if (!(chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { /* Yes, the NT 4.0 and Linux drivers will send this many amount of bytes to the video adapter on quadword-boundary-crossing image blits. This weird calculation is intended and deliberate. @@ -1121,6 +1123,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) switch (chips->bitblt_running.bitblt.monochrome_source_alignment) { case 0: /* Source-span aligned. */ { + /* Note: This value means quadword-alignment when BitBLT port is the source. */ /* TODO: This is handled purely on a best case basis. */ uint32_t orig_count_y = chips->bitblt_running.count_y; uint32_t orig_source_addr = chips->bitblt_running.bitblt.source_addr; @@ -1142,6 +1145,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) chips->bitblt_running.bitblt.source_addr = source_addr; break; } + case 1: /* Bit-aligned */ case 2: /* Byte-aligned */ { uint32_t data = chips_69000_readb_linear(source_addr, chips); @@ -1149,6 +1153,14 @@ chips_69000_setup_bitblt(chips_69000_t* chips) source_addr += 1; break; } + case 3: /* Word-aligned*/ + { + uint32_t data = chips_69000_readw_linear(source_addr, chips); + chips_69000_bitblt_write(chips, data & 0xFF); + chips_69000_bitblt_write(chips, (data >> 8) & 0xFF); + source_addr += 2; + break; + } case 4: /* Doubleword-aligned*/ { uint32_t data = chips_69000_readl_linear(source_addr, chips); @@ -1243,7 +1255,9 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { } } } - else if ((chips->bitblt_running.bitblt.monochrome_source_alignment == 0 && !chips->bitblt_running.mono_bytes_pitch) || chips->bitblt_running.bitblt.monochrome_source_alignment == 2) { + else if ((chips->bitblt_running.bitblt.monochrome_source_alignment == 0 && !chips->bitblt_running.mono_bytes_pitch) + || chips->bitblt_running.bitblt.monochrome_source_alignment == 2 + || chips->bitblt_running.bitblt.monochrome_source_alignment == 1) { int orig_count_y = chips->bitblt_running.count_y; int i = 0; uint8_t val = chips->bitblt_running.bytes_port[0]; @@ -1251,7 +1265,7 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { for (i = 0; i < 8; i++) { chips_69000_process_mono_bit(chips, !!(val & (1 << (7 - i)))); - if (orig_count_y != chips->bitblt_running.count_y) { + if (orig_count_y != chips->bitblt_running.count_y && chips->bitblt_running.bitblt.monochrome_source_alignment != 1) { cycles = orig_cycles; return; } @@ -1313,7 +1327,7 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { } chips->bitblt_running.bytes_counter++; - if (chips->bitblt_running.bytes_counter <= (chips->bitblt_running.bitblt.source_addr & 7)) { + if (chips->bitblt_running.bytes_counter <= (chips->bitblt_running.bitblt.source_addr)) { return; } chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; @@ -2308,6 +2322,16 @@ chips_69000_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) return ret; } +static int +chips_69000_line_compare(svga_t* svga) +{ + /* Line compare glitches out at 1600x1200 and above. Disable it. */ + if (svga->dispend >= 1200) + return 0; + + return 1; +} + static void * chips_69000_init(const device_t *info) { @@ -2338,6 +2362,7 @@ chips_69000_init(const device_t *info) chips->svga.hwcursor_draw = chips_69000_hwcursor_draw; chips->svga.getclock = chips_69000_getclock; chips->svga.conv_16to32 = chips_69000_conv_16to32; + chips->svga.line_compare = chips_69000_line_compare; mem_mapping_add(&chips->linear_mapping, 0, 0, chips_69000_readb_linear, chips_69000_readw_linear, chips_69000_readl_linear, chips_69000_writeb_linear, chips_69000_writew_linear, chips_69000_writel_linear, NULL, MEM_MAPPING_EXTERNAL, chips); From b95139033c77702814ae0c3e99c37eed87df3284 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 13 Feb 2024 11:45:28 +0600 Subject: [PATCH 500/936] Timing and name changes --- src/video/vid_c&t_69000.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index 0118bcd1f..bbf1cfb3a 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -161,7 +161,8 @@ typedef struct chips_69000_t { uint8_t st01; } chips_69000_t; -static video_timings_t timing_sis = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 20, .read_w = 20, .read_l = 35 }; +/* TODO: Probe timings on real hardware. */ +static video_timings_t timing_chips = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 10, .read_w = 10, .read_l = 10 }; uint8_t chips_69000_readb_linear(uint32_t addr, void *p); uint16_t chips_69000_readw_linear(uint32_t addr, void *p); @@ -1567,7 +1568,6 @@ chips_69000_out(uint16_t addr, uint8_t val, void *p) if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; - // if (!(addr == 0x3CC || addr == 0x3C9)) pclog("SiS SVGA out: 0x%X, 0x%X\n", addr, val); switch (addr) { case 0x3c0: if (!(chips->ext_regs[0x09] & 0x02)) @@ -1675,7 +1675,6 @@ chips_69000_in(uint16_t addr, void *p) if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; - // if (!(addr == 0x3CC || addr == 0x3C9)) pclog("SiS SVGA in: 0x%X\n", addr); switch (addr) { case 0x3C5: return svga->seqregs[svga->seqaddr]; @@ -2343,7 +2342,7 @@ chips_69000_init(const device_t *info) mem_mapping_disable(&chips->bios_rom.mapping); } - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_sis); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_chips); svga_init(info, &chips->svga, chips, 1 << 21, /*2048kb*/ chips_69000_recalctimings, @@ -2421,7 +2420,7 @@ chips_69000_force_redraw(void *p) } const device_t chips_69000_device = { - .name = "Chips & Technologies 69000", + .name = "Chips & Technologies B69000", .internal_name = "c&t_69000", .flags = DEVICE_PCI, .local = 0, @@ -2435,7 +2434,7 @@ const device_t chips_69000_device = { }; const device_t chips_69000_onboard_device = { - .name = "Chips & Technologies 69000 (onboard)", + .name = "Chips & Technologies B69000 (onboard)", .internal_name = "c&t_69000_onboard", .flags = DEVICE_PCI, .local = 1, From baac839d892bfd7dea0fa0c14734f00d0f10bdae Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 13 Feb 2024 17:04:53 +0600 Subject: [PATCH 501/936] Unused variables cleanup --- src/video/vid_c&t_69000.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_c&t_69000.c index bbf1cfb3a..b15546a69 100644 --- a/src/video/vid_c&t_69000.c +++ b/src/video/vid_c&t_69000.c @@ -820,8 +820,6 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) uint32_t pattern_fg = chips->bitblt_running.bitblt.pattern_source_key_fg; uint32_t pattern_bg = chips->bitblt_running.bitblt.pattern_source_key_bg; uint8_t pattern_data = 0; - uint8_t pattern_data_8bpp[8][8]; - uint16_t pattern_data_16bpp[8][8]; uint32_t pattern_pixel = 0; uint32_t dest_pixel = 0; uint32_t dest_addr = chips->bitblt_running.bitblt.destination_addr + (chips->bitblt_running.y * chips->bitblt_running.bitblt.destination_span) + (chips->bitblt_running.x * chips->bitblt_running.bytes_per_pixel); @@ -1243,7 +1241,6 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0 && chips->bitblt_running.mono_bytes_pitch && chips->bitblt_running.mono_bytes_pitch == chips->bitblt_running.bytes_written) { int orig_count_y = chips->bitblt_running.count_y; int i = 0, j = 0; - uint8_t val = chips->bitblt_running.bytes_port[0]; chips->bitblt_running.bytes_written = 0; for (j = 0; j < chips->bitblt_running.mono_bytes_pitch; j++) { From 8ed622f67b681fe08b864609c772785e64bdda97 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 13 Feb 2024 17:06:10 +0600 Subject: [PATCH 502/936] Move extern into video.h (part 1) --- src/include/86box/video.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 9e15a5cf9..47d237b10 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -579,6 +579,7 @@ extern const device_t wy700_device; /* Chips & Technologies */ extern const device_t chips_69000_device; +extern const device_t chips_69000_onboard_device; #endif From 49ab582234bb3589c1d3f9fee05547e154bfcc43 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 13 Feb 2024 17:07:19 +0600 Subject: [PATCH 503/936] Move extern into video.h (part 2) --- src/machine/m_at_socket370.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index 8344e6b8f..dce0034ff 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -355,7 +355,6 @@ machine_at_awo671r_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&sst_flash_39sf020_device); if (gfxcard[0] == VID_INTERNAL) { - extern const device_t chips_69000_onboard_device; device_add(&chips_69000_onboard_device); } spd_register(SPD_TYPE_SDRAM, 0x3, 256); From 5acec5dfa42fcf7629645644892e2610424ebb43 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Tue, 13 Feb 2024 18:40:07 +0500 Subject: [PATCH 504/936] qt: Remove the Direct3D 9 renderer --- src/qt/CMakeLists.txt | 3 +- src/qt/qt.c | 7 +- src/qt/qt_d3d9renderer.cpp | 200 ----------------------------------- src/qt/qt_d3d9renderer.hpp | 45 -------- src/qt/qt_main.cpp | 2 +- src/qt/qt_mainwindow.cpp | 29 +---- src/qt/qt_mainwindow.hpp | 2 - src/qt/qt_mainwindow.ui | 12 --- src/qt/qt_renderercommon.hpp | 3 - src/qt/qt_rendererstack.cpp | 95 ++--------------- src/qt/qt_rendererstack.hpp | 9 +- 11 files changed, 18 insertions(+), 389 deletions(-) delete mode 100644 src/qt/qt_d3d9renderer.cpp delete mode 100644 src/qt/qt_d3d9renderer.hpp diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index fb96de1ea..4f073cf4a 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -197,8 +197,7 @@ if(WIN32) else() target_sources(plat PRIVATE win_joystick_rawinput.c) endif() - target_sources(ui PRIVATE qt_d3d9renderer.hpp qt_d3d9renderer.cpp) - target_link_libraries(86Box hid d3d9) + target_link_libraries(86Box hid) # CMake 3.22 messed this up for clang/clang++ # See https://gitlab.kitware.com/cmake/cmake/-/issues/22611 diff --git a/src/qt/qt.c b/src/qt/qt.c index c2a5396da..47f5b9410 100644 --- a/src/qt/qt.c +++ b/src/qt/qt.c @@ -52,10 +52,8 @@ plat_vidapi(char *api) return 3; } else if (!strcasecmp(api, "qt_vulkan")) { return 4; - } else if (!strcasecmp(api, "qt_d3d9")) { - return 5; } else if (!strcasecmp(api, "vnc")) { - return 6; + return 5; } return 0; @@ -83,9 +81,6 @@ plat_vidapi_name(int api) name = "qt_vulkan"; break; case 5: - name = "qt_d3d9"; - break; - case 6: name = "vnc"; break; default: diff --git a/src/qt/qt_d3d9renderer.cpp b/src/qt/qt_d3d9renderer.cpp deleted file mode 100644 index 868f58274..000000000 --- a/src/qt/qt_d3d9renderer.cpp +++ /dev/null @@ -1,200 +0,0 @@ -#include "qt_mainwindow.hpp" -#include "qt_d3d9renderer.hpp" -#include -#include - -extern "C" { -#include <86box/86box.h> -#include <86box/video.h> -} - -D3D9Renderer::D3D9Renderer(QWidget *parent, int monitor_index) - : QWidget { parent } - , RendererCommon() -{ - QPalette pal = palette(); - pal.setColor(QPalette::Window, Qt::black); - setAutoFillBackground(true); - setPalette(pal); - - setAttribute(Qt::WA_NativeWindow); - setAttribute(Qt::WA_PaintOnScreen); - setAttribute(Qt::WA_NoSystemBackground); - setAttribute(Qt::WA_OpaquePaintEvent); - - windowHandle = (HWND) winId(); - surfaceInUse = true; - finalized = true; - - RendererCommon::parentWidget = parent; - - this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - this->m_monitor_index = monitor_index; - - d3d9surface = nullptr; - d3d9dev = nullptr; - d3d9 = nullptr; -} - -D3D9Renderer::~D3D9Renderer() -{ - finalize(); -} - -void -D3D9Renderer::finalize() -{ - if (!finalized) { - while (surfaceInUse) { } - finalized = true; - } - surfaceInUse = true; - if (d3d9surface) { - d3d9surface->Release(); - d3d9surface = nullptr; - } - if (d3d9dev) { - d3d9dev->Release(); - d3d9dev = nullptr; - } - if (d3d9) { - d3d9->Release(); - d3d9 = nullptr; - } -} - -void -D3D9Renderer::hideEvent(QHideEvent *event) -{ - finalize(); -} - -void -D3D9Renderer::showEvent(QShowEvent *event) -{ - if (d3d9) finalize(); - params = {}; - - if (FAILED(Direct3DCreate9Ex(D3D_SDK_VERSION, &d3d9))) { - return error("Failed to create Direct3D 9 context"); - } - - params.Windowed = true; - params.SwapEffect = D3DSWAPEFFECT_FLIPEX; - params.BackBufferWidth = width() * devicePixelRatioF(); - params.BackBufferHeight = height() * devicePixelRatioF(); - params.BackBufferCount = 1; - params.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; - params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - params.hDeviceWindow = (HWND) winId(); - - HRESULT result = d3d9->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, windowHandle, D3DCREATE_MULTITHREADED | D3DCREATE_HARDWARE_VERTEXPROCESSING, ¶ms, nullptr, &d3d9dev); - if (FAILED(result)) - result = d3d9->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, windowHandle, D3DCREATE_MULTITHREADED | D3DCREATE_SOFTWARE_VERTEXPROCESSING, ¶ms, nullptr, &d3d9dev); - if (FAILED(result)) { - return error("Failed to create Direct3D 9 device"); - } - - result = d3d9dev->CreateOffscreenPlainSurface(2048, 2048, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d9surface, nullptr); - if (FAILED(result)) - result = d3d9dev->CreateOffscreenPlainSurface(1024, 1024, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d9surface, nullptr); - if (FAILED(result)) { - return error("Failed to create Direct3D 9 surface"); - } - if (!alreadyInitialized) { - emit initialized(); - alreadyInitialized = true; - } - surfaceInUse = false; - finalized = false; -} - -void -D3D9Renderer::paintEvent(QPaintEvent *event) -{ - IDirect3DSurface9 *backbuffer = nullptr; - RECT srcRect; - RECT dstRect; - HRESULT result = d3d9dev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); - - if (FAILED(result)) { - return; - } - - srcRect.top = source.top(); - srcRect.bottom = source.bottom(); - srcRect.left = source.left(); - srcRect.right = source.right(); - dstRect.top = destination.top() * devicePixelRatioF(); - dstRect.bottom = destination.bottom() * devicePixelRatioF(); - dstRect.left = destination.left() * devicePixelRatioF(); - dstRect.right = destination.right() * devicePixelRatioF(); - d3d9dev->BeginScene(); - d3d9dev->Clear(0, nullptr, D3DCLEAR_TARGET, 0xFF000000, 0, 0); - while (surfaceInUse) { } - surfaceInUse = true; - d3d9dev->StretchRect(d3d9surface, &srcRect, backbuffer, &dstRect, video_filter_method == 0 ? D3DTEXF_POINT : D3DTEXF_LINEAR); - result = d3d9dev->EndScene(); - surfaceInUse = false; - if (SUCCEEDED(result)) { - if (FAILED(d3d9dev->PresentEx(nullptr, nullptr, 0, nullptr, 0))) { - finalize(); - showEvent(nullptr); - } - } -} - -bool -D3D9Renderer::event(QEvent *event) -{ - bool res = false; - if (!eventDelegate(event, res)) - return QWidget::event(event); - return res; -} - -void -D3D9Renderer::resizeEvent(QResizeEvent *event) -{ - onResize(event->size().width() * devicePixelRatioF(), event->size().height() * devicePixelRatioF()); - - params.BackBufferWidth = event->size().width() * devicePixelRatioF(); - params.BackBufferHeight = event->size().height() * devicePixelRatioF(); - if (d3d9dev) - d3d9dev->Reset(¶ms); - QWidget::resizeEvent(event); -} - -void -D3D9Renderer::blit(int x, int y, int w, int h) -{ - if (blitDummied || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || surfaceInUse) { - video_blit_complete_monitor(m_monitor_index); - return; - } - surfaceInUse = true; - auto origSource = source; - source.setRect(x, y, w, h); - RECT srcRect; - D3DLOCKED_RECT lockRect; - srcRect.top = source.top(); - srcRect.bottom = source.bottom(); - srcRect.left = source.left(); - srcRect.right = source.right(); - - if (monitors[m_monitor_index].mon_screenshots) { - video_screenshot_monitor((uint32_t *) &(monitors[m_monitor_index].target_buffer->line[y][x]), 0, 0, 2048, m_monitor_index); - } - if (SUCCEEDED(d3d9surface->LockRect(&lockRect, &srcRect, 0))) { - for (int y1 = 0; y1 < h; y1++) { - video_copy(((uint8_t *) lockRect.pBits) + (y1 * lockRect.Pitch), &(monitors[m_monitor_index].target_buffer->line[y + y1][x]), w * 4); - } - video_blit_complete_monitor(m_monitor_index); - d3d9surface->UnlockRect(); - } else - video_blit_complete_monitor(m_monitor_index); - if (origSource != source) - onResize(this->width() * devicePixelRatioF(), this->height() * devicePixelRatioF()); - surfaceInUse = false; - QTimer::singleShot(0, this, [this] { this->update(); }); -} diff --git a/src/qt/qt_d3d9renderer.hpp b/src/qt/qt_d3d9renderer.hpp deleted file mode 100644 index 37c27443b..000000000 --- a/src/qt/qt_d3d9renderer.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef D3D9RENDERER_HPP -#define D3D9RENDERER_HPP - -#include -#include "qt_renderercommon.hpp" - -#include -#include -#include - -class D3D9Renderer : public QWidget, public RendererCommon { - Q_OBJECT -public: - explicit D3D9Renderer(QWidget *parent = nullptr, int monitor_index = 0); - ~D3D9Renderer(); - bool hasBlitFunc() override { return true; } - void blit(int x, int y, int w, int h) override; - void finalize() override; - -protected: - void showEvent(QShowEvent *event) override; - void hideEvent(QHideEvent *event) override; - void resizeEvent(QResizeEvent *event) override; - void paintEvent(QPaintEvent *event) override; - bool event(QEvent *event) override; - QPaintEngine *paintEngine() const override { return nullptr; } - -signals: - void initialized(); - void error(QString); - -private: - HWND windowHandle = 0; - D3DPRESENT_PARAMETERS params {}; - IDirect3D9Ex *d3d9 = nullptr; - IDirect3DDevice9Ex *d3d9dev = nullptr; - IDirect3DSurface9 *d3d9surface = nullptr; - - std::atomic surfaceInUse { false }; - std::atomic finalized { false }; - bool alreadyInitialized = false; - int m_monitor_index = 0; -}; - -#endif // D3D9RENDERER_HPP diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 4d02e2601..cafd4fd8e 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -342,7 +342,7 @@ main(int argc, char *argv[]) /* Set the PAUSE mode depending on the renderer. */ #ifdef USE_VNC - if (vnc_enabled && vid_api != 6) + if (vnc_enabled && vid_api != 5) plat_pause(1); else #endif diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index eb4634dee..ace052a32 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -157,8 +157,6 @@ keyb_filter(BMessage *message, BHandler **target, BMessageFilter *filter) static BMessageFilter *filter; #endif -std::atomic blitDummied { false }; - extern void qt_mouse_capture(int); extern "C" void qt_blit(int x, int y, int w, int h, int monitor_index); @@ -369,14 +367,9 @@ MainWindow::MainWindow(QWidget *parent) ui->actionVulkan->setVisible(false); ui->actionOpenGL_3_0_Core->setVisible(false); } -#if !defined Q_OS_WINDOWS - ui->actionDirect3D_9->setVisible(false); - if (vid_api == 5) - vid_api = 0; -#endif #ifndef USE_VNC - if (vid_api == 6) + if (vid_api == 5) vid_api = 0; ui->actionVNC->setVisible(false); #endif @@ -410,14 +403,13 @@ MainWindow::MainWindow(QWidget *parent) actGroup->addAction(ui->actionHardware_Renderer_OpenGL_ES); actGroup->addAction(ui->actionOpenGL_3_0_Core); actGroup->addAction(ui->actionVulkan); - actGroup->addAction(ui->actionDirect3D_9); actGroup->addAction(ui->actionVNC); actGroup->setExclusive(true); connect(actGroup, &QActionGroup::triggered, [this](QAction *action) { vid_api = action->property("vid_api").toInt(); #ifdef USE_VNC - if (vnc_enabled && vid_api != 6) { + if (vnc_enabled && vid_api != 5) { startblit(); vnc_enabled = 0; vnc_close(); @@ -442,11 +434,8 @@ MainWindow::MainWindow(QWidget *parent) case 4: newVidApi = RendererStack::Renderer::Vulkan; break; - case 5: - newVidApi = RendererStack::Renderer::Direct3D9; - break; #ifdef USE_VNC - case 6: + case 5: { newVidApi = RendererStack::Renderer::Software; startblit(); @@ -612,7 +601,7 @@ MainWindow::MainWindow(QWidget *parent) video_setblit(qt_blit); if (start_in_fullscreen) { - connect(ui->stackedWidget, &RendererStack::blit, this, [this] () { + connect(ui->stackedWidget, &RendererStack::blitToRenderer, this, [this] () { if (start_in_fullscreen) { QTimer::singleShot(100, ui->actionFullscreen, &QAction::trigger); start_in_fullscreen = 0; @@ -1156,8 +1145,6 @@ MainWindow::on_actionFullscreen_triggered() { if (video_fullscreen > 0) { showNormal(); - if (vid_api == 5) - QTimer::singleShot(0, this, [this]() { ui->stackedWidget->switchRenderer(RendererStack::Renderer::Direct3D9); }); ui->menubar->show(); if (!hide_status_bar) ui->statusbar->show(); @@ -1193,8 +1180,6 @@ MainWindow::on_actionFullscreen_triggered() ui->toolBar->hide(); ui->stackedWidget->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); showFullScreen(); - if (vid_api == 5) - QTimer::singleShot(0, this, [this]() { ui->stackedWidget->switchRenderer(RendererStack::Renderer::Direct3D9); }); } ui->stackedWidget->onResize(width(), height()); } @@ -1316,7 +1301,7 @@ void MainWindow::blitToWidget(int x, int y, int w, int h, int monitor_index) { if (monitor_index >= 1) { - if (!blitDummied && renderers[monitor_index] && renderers[monitor_index]->isVisible()) + if (renderers[monitor_index] && renderers[monitor_index]->isVisible()) renderers[monitor_index]->blit(x, y, w, h); else video_blit_complete_monitor(monitor_index); @@ -1976,8 +1961,6 @@ MainWindow::on_actionShow_non_primary_monitors_triggered() { show_second_monitors = (int) ui->actionShow_non_primary_monitors->isChecked(); - blitDummied = true; - if (show_second_monitors) { for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) { auto &secondaryRenderer = renderers[monitor_index]; @@ -2007,8 +1990,6 @@ MainWindow::on_actionShow_non_primary_monitors_triggered() } } } - - blitDummied = false; } void diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 553f9602c..64a97f012 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -12,8 +12,6 @@ class MediaMenu; class RendererStack; -extern std::atomic blitDummied; - namespace Ui { class MainWindow; } diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index c14c33207..d77c8d171 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -117,7 +117,6 @@ - @@ -831,17 +830,6 @@ MCA devices... - - - true - - - Direct3D 9 - - - 5 - - true diff --git a/src/qt/qt_renderercommon.hpp b/src/qt/qt_renderercommon.hpp index 897240d27..af72474c7 100644 --- a/src/qt/qt_renderercommon.hpp +++ b/src/qt/qt_renderercommon.hpp @@ -35,9 +35,6 @@ public: /* Reloads options of renderer */ virtual void reloadOptions() { } - virtual bool hasBlitFunc() { return false; } - virtual void blit(int x, int y, int w, int h) { } - int r_monitor_index = 0; protected: diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index e5ed77ba7..0f86e8ee6 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -25,9 +25,6 @@ #include "qt_openglrenderer.hpp" #include "qt_softwarerenderer.hpp" #include "qt_vulkanwindowrenderer.hpp" -#ifdef Q_OS_WIN -# include "qt_d3d9renderer.hpp" -#endif #include "qt_mainwindow.hpp" #include "qt_util.hpp" @@ -279,40 +276,14 @@ RendererStack::switchRenderer(Renderer renderer) { startblit(); if (current) { - if ((current_vid_api == Renderer::Direct3D9 && renderer != Renderer::Direct3D9) - || (current_vid_api != Renderer::Direct3D9 && renderer == Renderer::Direct3D9)) { - rendererWindow->finalize(); - if (rendererWindow->hasBlitFunc()) { - while (directBlitting) { } - connect(this, &RendererStack::blit, this, &RendererStack::blitDummy, Qt::DirectConnection); - disconnect(this, &RendererStack::blit, this, &RendererStack::blitRenderer); - } else { - connect(this, &RendererStack::blit, this, &RendererStack::blitDummy, Qt::DirectConnection); - disconnect(this, &RendererStack::blit, this, &RendererStack::blitCommon); - } + rendererWindow->finalize(); + removeWidget(current.get()); + disconnect(this, &RendererStack::blitToRenderer, nullptr, nullptr); - removeWidget(current.get()); - disconnect(this, &RendererStack::blitToRenderer, nullptr, nullptr); + /* Create new renderer only after previous is destroyed! */ + connect(current.get(), &QObject::destroyed, [this, renderer](QObject *) { createRenderer(renderer); }); - /* Create new renderer only after previous is destroyed! */ - connect(current.get(), &QObject::destroyed, [this, renderer](QObject *) { - createRenderer(renderer); - disconnect(this, &RendererStack::blit, this, &RendererStack::blitDummy); - blitDummied = false; - QTimer::singleShot(1000, this, []() { blitDummied = false; }); - }); - - rendererWindow->hasBlitFunc() ? current.reset() : current.release()->deleteLater(); - } else { - rendererWindow->finalize(); - removeWidget(current.get()); - disconnect(this, &RendererStack::blitToRenderer, nullptr, nullptr); - - /* Create new renderer only after previous is destroyed! */ - connect(current.get(), &QObject::destroyed, [this, renderer](QObject *) { createRenderer(renderer); }); - - current.release()->deleteLater(); - } + current.release()->deleteLater(); } else { createRenderer(renderer); } @@ -321,7 +292,6 @@ RendererStack::switchRenderer(Renderer renderer) void RendererStack::createRenderer(Renderer renderer) { - current_vid_api = renderer; switch (renderer) { default: case Renderer::Software: @@ -374,27 +344,6 @@ RendererStack::createRenderer(Renderer renderer) current.reset(this->createWindowContainer(hw, this)); break; } -#ifdef Q_OS_WIN - case Renderer::Direct3D9: - { - this->createWinId(); - auto hw = new D3D9Renderer(this, m_monitor_index); - rendererWindow = hw; - connect(hw, &D3D9Renderer::error, this, [this](QString str) { - auto msgBox = new QMessageBox(QMessageBox::Critical, "86Box", QString("Failed to initialize D3D9 renderer. Falling back to software rendering.\n\n") + str, QMessageBox::Ok); - msgBox->setAttribute(Qt::WA_DeleteOnClose); - msgBox->show(); - imagebufs = {}; - QTimer::singleShot(0, this, [this]() { switchRenderer(Renderer::Software); }); - }); - connect(hw, &D3D9Renderer::initialized, this, [this]() { - endblit(); - emit rendererChanged(); - }); - current.reset(hw); - break; - } -#endif #if QT_CONFIG(vulkan) case Renderer::Vulkan: { @@ -444,44 +393,18 @@ RendererStack::createRenderer(Renderer renderer) currentBuf = 0; - if (rendererWindow->hasBlitFunc()) { - connect(this, &RendererStack::blit, this, &RendererStack::blitRenderer, Qt::DirectConnection); - } else { - connect(this, &RendererStack::blit, this, &RendererStack::blitCommon, Qt::DirectConnection); - } - - if (renderer != Renderer::OpenGL3 && renderer != Renderer::Vulkan && renderer != Renderer::Direct3D9) { + if (renderer != Renderer::OpenGL3 && renderer != Renderer::Vulkan) { imagebufs = rendererWindow->getBuffers(); endblit(); emit rendererChanged(); } } -void -RendererStack::blitDummy(int x, int y, int w, int h) -{ - video_blit_complete_monitor(m_monitor_index); - blitDummied = true; -} - -void -RendererStack::blitRenderer(int x, int y, int w, int h) -{ - if (blitDummied) { - blitDummied = false; - video_blit_complete_monitor(m_monitor_index); - return; - } - directBlitting = true; - rendererWindow->blit(x, y, w, h); - directBlitting = false; -} - // called from blitter thread void -RendererStack::blitCommon(int x, int y, int w, int h) +RendererStack::blit(int x, int y, int w, int h) { - if (blitDummied || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || imagebufs.empty() || std::get(imagebufs[currentBuf])->test_and_set()) { + if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || imagebufs.empty() || std::get(imagebufs[currentBuf])->test_and_set()) { video_blit_complete_monitor(m_monitor_index); return; } diff --git a/src/qt/qt_rendererstack.hpp b/src/qt/qt_rendererstack.hpp index c9d90869b..5a08b351c 100644 --- a/src/qt/qt_rendererstack.hpp +++ b/src/qt/qt_rendererstack.hpp @@ -59,7 +59,6 @@ public: OpenGLES, OpenGL3, Vulkan, - Direct3D9, None = -1 }; void switchRenderer(Renderer renderer); @@ -81,13 +80,10 @@ public: signals: void blitToRenderer(int buf_idx, int x, int y, int w, int h); - void blit(int x, int y, int w, int h); void rendererChanged(); public slots: - void blitCommon(int x, int y, int w, int h); - void blitRenderer(int x, int y, int w, int h); - void blitDummy(int x, int y, int w, int h); + void blit(int x, int y, int w, int h); private: void createRenderer(Renderer renderer); @@ -107,13 +103,10 @@ private: int isMouseDown = 0; int m_monitor_index = 0; - Renderer current_vid_api = Renderer::None; - std::vector> imagebufs; RendererCommon *rendererWindow { nullptr }; std::unique_ptr current; - std::atomic directBlitting { false }; }; #endif // QT_RENDERERCONTAINER_HPP From 224daa92d0f32029cbc59bbd32eb9869bc3d7e79 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Tue, 13 Feb 2024 21:13:25 +0500 Subject: [PATCH 505/936] qt: Remove fullscreen status icons --- src/config.c | 7 ----- src/include/86box/plat.h | 1 - src/qt/languages/ru-RU.po | 3 -- src/qt/qt_hardwarerenderer.cpp | 16 ----------- src/qt/qt_hardwarerenderer.hpp | 2 +- src/qt/qt_mainwindow.cpp | 9 ------ src/qt/qt_mainwindow.hpp | 1 - src/qt/qt_mainwindow.ui | 9 ------ src/qt/qt_renderercommon.cpp | 52 ---------------------------------- src/qt/qt_softwarerenderer.cpp | 2 -- src/unix/unix.c | 1 - src/win/win_ui.c | 2 -- 12 files changed, 1 insertion(+), 104 deletions(-) diff --git a/src/config.c b/src/config.c index f1807c316..3e4fd7222 100644 --- a/src/config.c +++ b/src/config.c @@ -139,8 +139,6 @@ load_general(void) rctrl_is_lalt = ini_section_get_int(cat, "rctrl_is_lalt", 0); update_icons = ini_section_get_int(cat, "update_icons", 1); - status_icons_fullscreen = !!ini_section_get_int(cat, "status_icons_fullscreen", 0); - window_remember = ini_section_get_int(cat, "window_remember", 0); if (!window_remember && !(vid_resize & 2)) @@ -1859,11 +1857,6 @@ save_general(void) else ini_section_delete_var(cat, "open_dir_usr_path"); - if (status_icons_fullscreen) - ini_section_set_int(cat, "status_icons_fullscreen", status_icons_fullscreen); - else - ini_section_delete_var(cat, "status_icons_fullscreen"); - if (video_framerate != -1) ini_section_set_int(cat, "video_gl_framerate", video_framerate); else diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index 1f5f2b695..84f0318c2 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -107,7 +107,6 @@ extern int infocus; extern char emu_version[200]; /* version ID string */ extern int rctrl_is_lalt; extern int update_icons; -extern int status_icons_fullscreen; extern int kbd_req_capture; extern int hide_status_bar; diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index 04f3bc5b3..8683cc4d9 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -31,9 +31,6 @@ msgstr "&Скрыть строку состояния" msgid "Hide &toolbar" msgstr "С&крыть панель инструментов" -msgid "Show status icons in fullscreen" -msgstr "Показывать значки состояния в полноэкранном режиме" - msgid "Show non-primary monitors" msgstr "&Показывать неосновные мониторы" diff --git a/src/qt/qt_hardwarerenderer.cpp b/src/qt/qt_hardwarerenderer.cpp index 47f0de718..ee2ec07df 100644 --- a/src/qt/qt_hardwarerenderer.cpp +++ b/src/qt/qt_hardwarerenderer.cpp @@ -136,22 +136,6 @@ HardwareRenderer::initializeGL() m_context->swapBuffers(this); } -void -HardwareRenderer::paintOverGL() -{ - /* Context switching is needed to make use of QPainter to draw status bar icons in fullscreen. - Especially since it seems to be impossible to use QPainter on externally-created OpenGL contexts. */ - if (video_fullscreen && status_icons_fullscreen) { - m_context->makeCurrent(nullptr); - makeCurrent(); - QPainter painter(this); - drawStatusBarIcons(&painter); - painter.end(); - doneCurrent(); - m_context->makeCurrent(this); - } -} - void HardwareRenderer::paintGL() { diff --git a/src/qt/qt_hardwarerenderer.hpp b/src/qt/qt_hardwarerenderer.hpp index 1918cda18..f7861d2bd 100644 --- a/src/qt/qt_hardwarerenderer.hpp +++ b/src/qt/qt_hardwarerenderer.hpp @@ -53,7 +53,7 @@ public: { onResize(size().width(), size().height()); } - void paintOverGL() override; + std::vector> getBuffers() override; HardwareRenderer(QWidget *parent = nullptr, RenderType rtype = RenderType::OpenGL) : QOpenGLWindow(QOpenGLWindow::NoPartialUpdate, parent->windowHandle()) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index ace052a32..f24ab0788 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -340,7 +340,6 @@ MainWindow::MainWindow(QWidget *parent) ui->actionUpdate_status_bar_icons->setChecked(update_icons); ui->actionEnable_Discord_integration->setChecked(enable_discord); ui->actionApply_fullscreen_stretch_mode_when_maximized->setChecked(video_fullscreen_scale_maximized); - ui->actionShow_status_icons_in_fullscreen->setChecked(status_icons_fullscreen); #ifndef DISCORD ui->actionEnable_Discord_integration->setVisible(false); @@ -2032,11 +2031,3 @@ void MainWindow::on_actionACPI_Shutdown_triggered() { acpi_pwrbut_pressed = 1; } - -void MainWindow::on_actionShow_status_icons_in_fullscreen_triggered() -{ - status_icons_fullscreen = !status_icons_fullscreen; - ui->actionShow_status_icons_in_fullscreen->setChecked(status_icons_fullscreen); - config_save(); -} - diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 64a97f012..950d145c1 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -142,7 +142,6 @@ private slots: void on_actionCursor_Puck_triggered(); void on_actionACPI_Shutdown_triggered(); - void on_actionShow_status_icons_in_fullscreen_triggered(); private slots: void on_actionShow_non_primary_monitors_triggered(); diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index d77c8d171..ccdb5a9cf 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -179,7 +179,6 @@ - @@ -870,14 +869,6 @@ Cursor/Puck - - - true - - - Show status icons in fullscreen - - true diff --git a/src/qt/qt_renderercommon.cpp b/src/qt/qt_renderercommon.cpp index 05c35e09b..178134c9d 100644 --- a/src/qt/qt_renderercommon.cpp +++ b/src/qt/qt_renderercommon.cpp @@ -17,15 +17,11 @@ #include "qt_renderercommon.hpp" #include "qt_mainwindow.hpp" -#include "qt_machinestatus.hpp" #include #include #include #include -#include -#include -#include #include @@ -33,8 +29,6 @@ extern "C" { #include <86box/86box.h> #include <86box/plat.h> #include <86box/video.h> - -int status_icons_fullscreen = 0; } RendererCommon::RendererCommon() = default; @@ -137,52 +131,6 @@ RendererCommon::onResize(int width, int height) monitors[r_monitor_index].mon_res_y = (double) destination.height(); } -void RendererCommon::drawStatusBarIcons(QPainter* painter) -{ - uint32_t x = 0; - auto prevcompositionMode = painter->compositionMode(); - painter->setCompositionMode(QPainter::CompositionMode::CompositionMode_SourceOver); - for (int i = 0; i < main_window->statusBar()->children().count(); i++) { - QLabel* label = qobject_cast(main_window->statusBar()->children()[i]); - if (label) { -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - const QPixmap pixmap = label->pixmap(); -#elif QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) - const QPixmap pixmap = label->pixmap(Qt::ReturnByValue); -#else - const QPixmap pixmap = (label->pixmap() ? *label->pixmap() : QPixmap()); -#endif - if (!pixmap.isNull()) { - painter->setBrush(QColor::fromRgbF(0, 0, 0, 1.)); - painter->fillRect(x, painter->device()->height() - pixmap.height() - 5, - pixmap.width(), pixmap.height() + 5, QColor::fromRgbF(0, 0, 0, .5)); - painter->drawPixmap(x + main_window->statusBar()->layout()->spacing() / 2, - painter->device()->height() - pixmap.height() - 3, pixmap); - x += pixmap.width(); - if (i <= main_window->statusBar()->children().count() - 3) { - painter->fillRect(x, painter->device()->height() - pixmap.height() - 5, - main_window->statusBar()->layout()->spacing(), pixmap.height() + 5, - QColor::fromRgbF(0, 0, 0, .5)); - x += main_window->statusBar()->layout()->spacing(); - } else - painter->fillRect(x, painter->device()->height() - pixmap.height() - 4, 4, - pixmap.height() + 4, QColor::fromRgbF(0, 0, 0, .5)); - } - } - } - if (main_window->status->getMessage().isEmpty() == false) { - auto curStatusMsg = main_window->status->getMessage(); - auto textSize = painter->fontMetrics().size(Qt::TextSingleLine, QChar(' ') + curStatusMsg + QChar(' ')); - painter->setPen(QColor(0, 0, 0, 127)); - painter->fillRect(painter->device()->width() - textSize.width(), painter->device()->height() - textSize.height(), - textSize.width(), textSize.height(), QColor(0, 0, 0, 127)); - painter->setPen(QColor(255, 255, 255, 255)); - painter->drawText(QRectF(painter->device()->width() - textSize.width(), painter->device()->height() - textSize.height(), - textSize.width(), textSize.height()), Qt::TextSingleLine, QChar(' ') + curStatusMsg + QChar(' ')); - } - painter->setCompositionMode(prevcompositionMode); -} - bool RendererCommon::eventDelegate(QEvent *event, bool &result) { diff --git a/src/qt/qt_softwarerenderer.cpp b/src/qt/qt_softwarerenderer.cpp index ab9ed932d..a8c0229d3 100644 --- a/src/qt/qt_softwarerenderer.cpp +++ b/src/qt/qt_softwarerenderer.cpp @@ -24,7 +24,6 @@ extern "C" { #include <86box/86box.h> -#include <86box/plat.h> #include <86box/video.h> } @@ -114,7 +113,6 @@ SoftwareRenderer::onPaint(QPaintDevice *device) #endif painter.setCompositionMode(QPainter::CompositionMode_Plus); painter.drawImage(destination, *images[cur_image], source); - if (video_fullscreen && status_icons_fullscreen) drawStatusBarIcons(&painter); } std::vector> diff --git a/src/unix/unix.c b/src/unix/unix.c index 4f21ddd53..a5e4917f3 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -63,7 +63,6 @@ extern wchar_t sdl_win_title[512]; plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; joystick_t joystick_state[MAX_JOYSTICKS]; int joysticks_present; -int status_icons_fullscreen = 0; /* unused. */ SDL_mutex *blitmtx; SDL_threadID eventthread; static int exit_event = 0; diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 73119140c..207158b29 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -76,8 +76,6 @@ int hide_status_bar = 0; int hide_tool_bar = 0; int dpi = 96; -int status_icons_fullscreen = 0; /* unused. */ - extern char openfilestring[512]; extern WCHAR wopenfilestring[512]; From 307e15019ecda07b8b8f7403f7e23e3df90c11b3 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Tue, 13 Feb 2024 21:41:01 +0500 Subject: [PATCH 506/936] Remove a long-unused string --- src/include/86box/language.h | 1 - src/qt/languages/ca-ES.po | 3 --- src/qt/languages/cs-CZ.po | 3 --- src/qt/languages/de-DE.po | 3 --- src/qt/languages/en-GB.po | 3 --- src/qt/languages/en-US.po | 3 --- src/qt/languages/es-ES.po | 3 --- src/qt/languages/fi-FI.po | 3 --- src/qt/languages/fr-FR.po | 3 --- src/qt/languages/hr-HR.po | 3 --- src/qt/languages/hu-HU.po | 3 --- src/qt/languages/it-IT.po | 3 --- src/qt/languages/ja-JP.po | 3 --- src/qt/languages/ko-KR.po | 3 --- src/qt/languages/pl-PL.po | 3 --- src/qt/languages/pt-BR.po | 3 --- src/qt/languages/pt-PT.po | 3 --- src/qt/languages/ru-RU.po | 3 --- src/qt/languages/sk-SK.po | 3 --- src/qt/languages/sl-SI.po | 3 --- src/qt/languages/tr-TR.po | 3 --- src/qt/languages/uk-UA.po | 3 --- src/qt/languages/zh-CN.po | 3 --- src/qt/languages/zh-TW.po | 3 --- src/qt/qt_platform.cpp | 1 - src/unix/unix.c | 2 -- src/win/languages/cs-CZ.rc | 1 - src/win/languages/de-DE.rc | 1 - src/win/languages/en-GB.rc | 1 - src/win/languages/en-US.rc | 1 - src/win/languages/es-ES.rc | 1 - src/win/languages/fi-FI.rc | 1 - src/win/languages/fr-FR.rc | 1 - src/win/languages/hr-HR.rc | 1 - src/win/languages/hu-HU.rc | 1 - src/win/languages/it-IT.rc | 1 - src/win/languages/ja-JP.rc | 1 - src/win/languages/ko-KR.rc | 1 - src/win/languages/pl-PL.rc | 1 - src/win/languages/pt-BR.rc | 1 - src/win/languages/pt-PT.rc | 1 - src/win/languages/ru-RU.rc | 1 - src/win/languages/sl-SI.rc | 1 - src/win/languages/tr-TR.rc | 1 - src/win/languages/uk-UA.rc | 1 - src/win/languages/zh-CN.rc | 1 - src/win/languages/zh-TW.rc | 1 - 47 files changed, 94 deletions(-) diff --git a/src/include/86box/language.h b/src/include/86box/language.h index af459c0ff..3c96e711f 100644 --- a/src/include/86box/language.h +++ b/src/include/86box/language.h @@ -97,7 +97,6 @@ #define IDS_2108 2108 // "%u MB (CHS: %i, %i, %i)" #define IDS_2109 2109 // "Floppy %i (%s): %ls" #define IDS_2110 2110 // "All floppy images (*.0??;*.." -#define IDS_2112 2112 // "Unable to initialize SDL..." #define IDS_2113 2113 // "Are you sure you want to..." #define IDS_2114 2114 // "Are you sure you want to..." #define IDS_2115 2115 // "Unable to initialize Ghostscript..." diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po index 71b643220..483e6ee53 100644 --- a/src/qt/languages/ca-ES.po +++ b/src/qt/languages/ca-ES.po @@ -814,9 +814,6 @@ msgstr "Imatges avançates del sector" msgid "Flux images" msgstr "Imatges de flux" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "No has estat possible inicialitzar SDL, és necessari SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Esteu segur que voleu restablir la màquina emulada?" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index 0069f245b..84c795092 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -814,9 +814,6 @@ msgstr "Rozšířené sektorové obrazy" msgid "Flux images" msgstr "Obrazy magnetického toku" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Nastala chyba při inicializaci knihovny SDL, je potřeba SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Opravdu chcete resetovat emulovaný počítač?" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index ed8e57ffa..4a4fde3c2 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -814,9 +814,6 @@ msgstr "Fortgeschrittene Sektorimages" msgid "Flux images" msgstr "Fluximages" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "SDL konnte nicht initialisiert werden, die Datei SDL2.dll wird benötigt" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Sind Sie sich sicher, dass Sie einen Hard-Reset für das emulierte System durchführen wollen?" diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index b56c274d3..031a365c0 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -814,9 +814,6 @@ msgstr "Advanced sector images" msgid "Flux images" msgstr "Flux images" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Unable to initialize SDL, SDL2.dll is required" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Are you sure you want to hard reset the emulated machine?" diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index e3cfa3f77..06a4b60f1 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -814,9 +814,6 @@ msgstr "Advanced sector images" msgid "Flux images" msgstr "Flux images" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Unable to initialize SDL, SDL2.dll is required" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Are you sure you want to hard reset the emulated machine?" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index c0f38893d..60ac5fb5c 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -814,9 +814,6 @@ msgstr "Imágenes avanzadas de sector" msgid "Flux images" msgstr "Imágenes de fluxo" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Incapaz de inicializar SDL, se requiere SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "¿Está seguro de que quieres hacer una reinicialización completa de la máquina emulada?" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index 4998d008b..50ebffccb 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -814,9 +814,6 @@ msgstr "Kehittyneet sektorilevykuvat" msgid "Flux images" msgstr "Flux-levykuvat" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "SDL:n alustus epäonnistui. Tarvitaan SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Haluatko varmasti käynnistää emuloidun tietokoneen uudelleen?" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index 0c50b3e46..52bccebd2 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -814,9 +814,6 @@ msgstr "Images du secteur avancés" msgid "Flux images" msgstr "Images du flux" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Impossible d'initialiser SDL, SDL2.dll est nécessaire" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Etes-vous sûr de vouloir réinitialiser la machine émulée ?" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index 436bae5c5..19b6a6e85 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -814,9 +814,6 @@ msgstr "Napredne sektorske slike" msgid "Flux images" msgstr "Flux slike" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Nije moguće inicijalizirati SDL, SDL2.dll je potrebno" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Jeste li sigurni da želite hard resetirati emulirani sistem?" diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index 129df1e2b..338d2ff5e 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -814,9 +814,6 @@ msgstr "Továbbfejlesztett szektor képek" msgid "Flux images" msgstr "Flux képekfájlok" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Az SDL inicializálása nem lehetséges, az SDL2.dll fájl szükséges" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Biztosan szeretné újraindítani az emulált gépet?" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index 334ecadaa..20c15c656 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -814,9 +814,6 @@ msgstr "Immagini da settori avanzati" msgid "Flux images" msgstr "Immagini flusso" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Impossibile inizializzare SDL, SDL2.dll è necessario" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Sei sicuro di voler riavviare la macchina emulata?" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index 32236adaa..d0f206dc9 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -814,9 +814,6 @@ msgstr "アドバンスドセクターイメージ" msgid "Flux images" msgstr "Fluxイメージ" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "SDLが初期化できません。SDL2.dllが必要です" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "使用中のマシンをハード リセットしますか?" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index a8ff2723d..f5d1502b0 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -814,9 +814,6 @@ msgstr "어드밴스드 섹터 이미지" msgid "Flux images" msgstr "플럭스 이미지" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "SDL을 초기화할 수 없습니다. SDL2.dll이 필요합니다" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "실행중인 머신을 재시작하시겠습니까?" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index a449d8951..eb7a13e4e 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -814,9 +814,6 @@ msgstr "Zaawansowane obrazy sektorów" msgid "Flux images" msgstr "Flux images" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Nie można zainicjować SDL, wymagany SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Jesteś pewien że chcesz wykonać twardy reset emulowanej maszyny?" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index c06f24835..148ca716c 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -814,9 +814,6 @@ msgstr "Imagens de setor avançado" msgid "Flux images" msgstr "Imagens de fluxo" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Não é possível inicializar o SDL, é necessário o SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Tem certeza de que deseja reiniciar completamente a máquina emulada?" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index 9743bc83c..e309d91bf 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -814,9 +814,6 @@ msgstr "Imagens avançadas de sector" msgid "Flux images" msgstr "Imagens de fluxo" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Não foi possível inicializar o SDL. O ficheiro SDL2.dll é necessário!" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Tem a certeza de que quer um reinício completo da máquina emulada?" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index 8683cc4d9..4aa99eb87 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -904,9 +904,6 @@ msgstr "Расширенные образы секторов" msgid "Flux images" msgstr "Образы Flux" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Невозможно инициализировать SDL, требуется SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Вы уверены, что хотите выполнить холодную перезагрузку эмулируемой машины?" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index c2f129a3d..376723efa 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -814,9 +814,6 @@ msgstr "Rozšírené sektorové obrazy" msgid "Flux images" msgstr "Obrazy magnetického toku" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Nastala chyba pri inicializácii knižnice SDL, je potreba SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Naozaj chcete resetovať emulovaný počítač?" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index 8c1d62ded..cde1011d1 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -814,9 +814,6 @@ msgstr "Napredne sektorske slike" msgid "Flux images" msgstr "Tokovne slike" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Ne morem inicializirati SDL, potrebna je knjižica SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Ste prepričani, da želite ponovno zagnati emulirani sistem?" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index 65a039c42..0989218e5 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -814,9 +814,6 @@ msgstr "Gelişmiş sektör imajları" msgid "Flux images" msgstr "Flux images" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "SDL başlatılamadı, SDL2.dll gerekmektedir" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Emüle edilen makineyi yeniden başlatmak istediğinizden emin misiniz?" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index 0d8522f15..76796a57a 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -814,9 +814,6 @@ msgstr "Розширені образи секторів" msgid "Flux images" msgstr "Образи Flux" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Неможливо ініціалізувати SDL, потрібно SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Ви впевнені, що хочете виконати холодне перезавантаження емульованої машини?" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index 0ac54f4e7..94c468d80 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -814,9 +814,6 @@ msgstr "高级扇区映像" msgid "Flux images" msgstr "Flux 映像" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "无法初始化 SDL,需要 SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "确定要硬重置模拟器吗?" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index cf53b3488..7836f7ef8 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -814,9 +814,6 @@ msgstr "進階磁區映像" msgid "Flux images" msgstr "Flux 映像" -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "無法初始化 SDL,需要 SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "確定要硬重設模擬器嗎?" diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 6890bd407..356334bac 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -602,7 +602,6 @@ ProgSettings::reloadStrings() translatedstrings[IDS_2094] = QCoreApplication::translate("", "Failed to set up PCap").toStdWString(); translatedstrings[IDS_2095] = QCoreApplication::translate("", "No PCap devices found").toStdWString(); translatedstrings[IDS_2096] = QCoreApplication::translate("", "Invalid PCap device").toStdWString(); - translatedstrings[IDS_2112] = QCoreApplication::translate("", "Unable to initialize SDL, libsdl2 is required").toStdWString(); translatedstrings[IDS_2130] = QCoreApplication::translate("", "Make sure libpcap is installed and that you are on a libpcap-compatible network connection.").toStdWString(); translatedstrings[IDS_2115] = QCoreApplication::translate("", "Unable to initialize Ghostscript").toStdWString(); translatedstrings[IDS_2063] = QCoreApplication::translate("", "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine.").toStdWString(); diff --git a/src/unix/unix.c b/src/unix/unix.c index a5e4917f3..6c21bfa45 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -262,8 +262,6 @@ plat_get_string(int i) return L"No PCap devices found"; case IDS_2096: return L"Invalid PCap device"; - case IDS_2112: - return L"Unable to initialize SDL, libsdl2 is required"; case IDS_2133: return L"libgs is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files."; case IDS_2130: diff --git a/src/win/languages/cs-CZ.rc b/src/win/languages/cs-CZ.rc index 353ea55b6..cbda41e7e 100644 --- a/src/win/languages/cs-CZ.rc +++ b/src/win/languages/cs-CZ.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Disketová mechanika %i (%s): %ls" IDS_2110 "Všechny obrazy (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Rozšířené sektorové obrazy (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Základní sektorové obrazy (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Obrazy magnetického toku (*.FDI)\0*.FDI\0Obrazy povrchu (*.86F;*.MFM)\0*.86F;*.MFM\0Všechny soubory (*.*)\0*.*\0" - IDS_2112 "Nastala chyba při inicializaci knihovny SDL, je potřeba SDL2.dll" IDS_2113 "Opravdu chcete resetovat emulovaný počítač?" IDS_2114 "Opravdu chcete ukončit 86Box?" IDS_2115 "Nastala chyba při inicializaci knihovny Ghostscript" diff --git a/src/win/languages/de-DE.rc b/src/win/languages/de-DE.rc index 0fe48b0ef..9859d3d26 100644 --- a/src/win/languages/de-DE.rc +++ b/src/win/languages/de-DE.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Diskette %i (%s): %ls" IDS_2110 "Alle Images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Fortgeschrittene Sektorimages (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basissektorimages (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Fluximages (*.FDI)\0*.FDI\0Oberflächenimages (*.86F;*.MFM)\0*.86F;*.MFM\0Alle Dateien (*.*)\0*.*\0" - IDS_2112 "SDL konnte nicht initialisiert werden, die Datei SDL2.dll wird benötigt" IDS_2113 "Sind Sie sich sicher, dass Sie einen Hard-Reset für das emulierte System durchführen wollen?" IDS_2114 "Sind Sie sich sicher, dass Sie 86Box beenden wollen?" IDS_2115 "Ghostscript konnte nicht initialisiert werden" diff --git a/src/win/languages/en-GB.rc b/src/win/languages/en-GB.rc index bc0df4d05..a974b1862 100644 --- a/src/win/languages/en-GB.rc +++ b/src/win/languages/en-GB.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Floppy %i (%s): %ls" IDS_2110 "All images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2112 "Unable to initialize SDL, SDL2.dll is required" IDS_2113 "Are you sure you want to hard reset the emulated machine?" IDS_2114 "Are you sure you want to exit 86Box?" IDS_2115 "Unable to initialize Ghostscript" diff --git a/src/win/languages/en-US.rc b/src/win/languages/en-US.rc index 05ef61790..c12fb4a45 100644 --- a/src/win/languages/en-US.rc +++ b/src/win/languages/en-US.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Floppy %i (%s): %ls" IDS_2110 "All images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2112 "Unable to initialize SDL, SDL2.dll is required" IDS_2113 "Are you sure you want to hard reset the emulated machine?" IDS_2114 "Are you sure you want to exit 86Box?" IDS_2115 "Unable to initialize Ghostscript" diff --git a/src/win/languages/es-ES.rc b/src/win/languages/es-ES.rc index e9fef50d4..4888c09f4 100644 --- a/src/win/languages/es-ES.rc +++ b/src/win/languages/es-ES.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Disquete %i (%s): %ls" IDS_2110 "Todas las Imágenes (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2112 "Incapaz de inicializar SDL, se requiere SDL2.dll" IDS_2113 "¿Seguro que quieres resetear la máquina emulada?" IDS_2114 "¿Seguro que quieres cerrar 86Box?" IDS_2115 "Incapaz de inicializar Ghostscript" diff --git a/src/win/languages/fi-FI.rc b/src/win/languages/fi-FI.rc index 1b958cc82..029cce6c0 100644 --- a/src/win/languages/fi-FI.rc +++ b/src/win/languages/fi-FI.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u Mt (CHS: %i, %i, %i)" IDS_2109 "Levyke %i (%s): %ls" IDS_2110 "Kaikki levykuvat (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Kehittyneet sektorilevykuvat (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Perussektorilevykuvat (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux-levykuvat (*.FDI)\0*.FDI\0Pintalevykuvat (*.86F;*.MFM)\0*.86F;*.MFM\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2112 "SDL:n alustus epäonnistui. Tarvitaan SDL2.dll" IDS_2113 "Haluatko varmasti käynnistää emuloidun tietokoneen uudelleen?" IDS_2114 "Haluatko varmasti sulkea 86Boxin?" IDS_2115 "Ghostscriptin alustus epäonnistui" diff --git a/src/win/languages/fr-FR.rc b/src/win/languages/fr-FR.rc index 8c77979ef..425656c28 100644 --- a/src/win/languages/fr-FR.rc +++ b/src/win/languages/fr-FR.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u Mo (CTS: %i, %i, %i)" IDS_2109 "Disquette %i (%s): %ls" IDS_2110 "Toutes les images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Images du secteur avancés (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Images du secteur basiques (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Images du flux (*.FDI)\0*.FDI\0Images de surface (*.86F;*.MFM)\0*.86F;*.MFM\0Tous les fichiers (*.*)\0*.*\0" - IDS_2112 "Impossible d'initialiser SDL, SDL2.dll est nécessaire" IDS_2113 "Etes-vous sûr de vouloir réinitialiser la machine émulée ?" IDS_2114 "Etes-vous sûr de vouloir quitter 86Box?" IDS_2115 "Impossible d'initialiser Ghostscript" diff --git a/src/win/languages/hr-HR.rc b/src/win/languages/hr-HR.rc index 2e6caea43..f01b2a881 100644 --- a/src/win/languages/hr-HR.rc +++ b/src/win/languages/hr-HR.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Disketa %i (%s): %ls" IDS_2110 "Sve slike (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Napredne sektorske slike (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Osnovne sektorske slike (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux slike (*.FDI)\0*.FDI\0Površinske slike (*.86F;*.MFM)\0*.86F;*.MFM\0Sve datoteke (*.*)\0*.*\0" - IDS_2112 "Nije moguće inicijalizirati SDL, SDL2.dll je potrebno" IDS_2113 "Jeste li sigurni da želite hard resetirati emulirani sistem?" IDS_2114 "Jeste li sigurni da želite zatvoriti 86Box?" IDS_2115 "Nije moguće inicijalizirati GhostScript" diff --git a/src/win/languages/hu-HU.rc b/src/win/languages/hu-HU.rc index 34bf512c1..52189426a 100644 --- a/src/win/languages/hu-HU.rc +++ b/src/win/languages/hu-HU.rc @@ -469,7 +469,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Floppy %i (%s): %ls" IDS_2110 "Minden képfájl (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Továbbfejlesztett szektor képek (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Alapvető szektor képek (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux képekfájlok (*.FDI)\0*.FDI\0Felületi képfájlok (*.86F;*.MFM)\0*.86F;*.MFM\0Minden fájl (*.*)\0*.*\0" - IDS_2112 "Az SDL inicializálása nem lehetséges, az SDL2.dll fájl szükséges" IDS_2113 "Biztosan szeretné újraindítani az emulált gépet?" IDS_2114 "Biztos benne, hogy ki szeretne lépni a 86Box-ból?" IDS_2115 "Nem sikerült inicializálni a Ghostscript-et" diff --git a/src/win/languages/it-IT.rc b/src/win/languages/it-IT.rc index 6f5b67201..e5868caa0 100644 --- a/src/win/languages/it-IT.rc +++ b/src/win/languages/it-IT.rc @@ -465,7 +465,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Floppy %i (%s): %ls" IDS_2110 "Tutte le immagini (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Immagini da settori avanzati (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Imagini da settori basilari (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Immagini flusso (*.FDI)\0*.FDI\0Immagini da superficie (*.86F;*.MFM)\0*.86F;*.MFM\0Tutti i file (*.*)\0*.*\0" - IDS_2112 "Impossibile inizializzare SDL, SDL2.dll è necessario" IDS_2113 "Sei sicuro di voler riavviare la macchina emulata?" IDS_2114 "Sei sicuro di voler uscire da 86Box?" IDS_2115 "Impossibile inizializzare Ghostscript" diff --git a/src/win/languages/ja-JP.rc b/src/win/languages/ja-JP.rc index a8e90d062..4090abf00 100644 --- a/src/win/languages/ja-JP.rc +++ b/src/win/languages/ja-JP.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS値: %i、%i、%i)" IDS_2109 "フロッピー %i (%s): %ls" IDS_2110 "すべてのイメージ (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0アドバンスド セクター イメージ (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0ベーシック セクター イメージ (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0フラックスイメージ (*.FDI)\0*.FDI\0サーフェス イメージ (*.86F;*.MFM)\0*.86F;*.MFM\0すべてのファイル (*.*)\0*.*\0" - IDS_2112 "SDLが初期化できません。SDL2.dllが必要です" IDS_2113 "使用中のマシンをハードリ セットしますか?" IDS_2114 "86Boxを終了しますか?" IDS_2115 "Ghostscriptが初期化できません" diff --git a/src/win/languages/ko-KR.rc b/src/win/languages/ko-KR.rc index 535ff1df4..7550e0779 100644 --- a/src/win/languages/ko-KR.rc +++ b/src/win/languages/ko-KR.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "플로피 %i (%s): %ls" IDS_2110 "모든 이미지 (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0어드밴스드 섹터 이미지 (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0기본 섹터 이미지 (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0플럭스 이미지 (*.FDI)\0*.FDI\0표면 이미지 (*.86F;*.MFM)\0*.86F;*.MFM\0모든 파일 (*.*)\0*.*\0" - IDS_2112 "SDL을 초기화할 수 없습니다. SDL2.dll이 필요합니다" IDS_2113 "실행중인 머신을 재시작하시겠습니까?" IDS_2114 "86Box를 끝내시겠습니까?" IDS_2115 "Ghostscript를 초기화할 수 없습니다" diff --git a/src/win/languages/pl-PL.rc b/src/win/languages/pl-PL.rc index bdd73f6cf..623415045 100644 --- a/src/win/languages/pl-PL.rc +++ b/src/win/languages/pl-PL.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Dyskietka %i (%s): %ls" IDS_2110 "Wszystkie obrazy (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Zaawansowane obrazy sektorów (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Podstawowe obrazy sektorów (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Obrazy powierzchniowe (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2112 "Nie można zainicjować SDL, wymagany SDL2.dll" IDS_2113 "Jesteś pewien że chcesz wykonać twardy reset emulowanej maszyny?" IDS_2114 "Jesteś pewien że chcesz zakończyć 86Box?" IDS_2115 "Nie można zainicjować Ghostscript" diff --git a/src/win/languages/pt-BR.rc b/src/win/languages/pt-BR.rc index 48cbba111..4f72a41a4 100644 --- a/src/win/languages/pt-BR.rc +++ b/src/win/languages/pt-BR.rc @@ -467,7 +467,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Disquete %i (%s): %ls" IDS_2110 "Todas as imagens (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Imagens de setor avançado (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Imagens de setor básico (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Imagens de fluxo (*.FDI)\0*.FDI\0Imagens de superfície (*.86F;*.MFM)\0*.86F;*.MFM\0Todos os arquivos (*.*)\0*.*\0" - IDS_2112 "Não é possível inicializar o SDL, é necessário o SDL2.dll" IDS_2113 "Tem certeza de que deseja reiniciar completamente a máquina emulada?" IDS_2114 "Tem certeza de que deseja sair do 86Box?" IDS_2115 "Não é possível inicializar o Ghostscript" diff --git a/src/win/languages/pt-PT.rc b/src/win/languages/pt-PT.rc index e4394b0cb..c17cfe362 100644 --- a/src/win/languages/pt-PT.rc +++ b/src/win/languages/pt-PT.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CCS: %i, %i, %i)" IDS_2109 "Disquete %i (%s): %ls" IDS_2110 "Todas as imagens (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Imagens avançadas de sector (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Imagens básicas de sector (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Imagens de fluxo (*.FDI)\0*.FDI\0Imagens de superfície (*.86F;*.MFM)\0*.86F;*.MFM\0Todos os ficheiros (*.*)\0*.*\0" - IDS_2112 "Não foi possível inicializar o SDL. O ficheiro SDL2.dll é necessário!" IDS_2113 "Tem a certeza de que quer um reinício completo da máquina emulada?" IDS_2114 "Tem a certeza de que quer sair do 86Box?" IDS_2115 "Não foi possível inicializar o Ghostscript" diff --git a/src/win/languages/ru-RU.rc b/src/win/languages/ru-RU.rc index 01562063a..719dd5a35 100644 --- a/src/win/languages/ru-RU.rc +++ b/src/win/languages/ru-RU.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u МБ (CHS: %i, %i, %i)" IDS_2109 "Дисковод %i (%s): %ls" IDS_2110 "Все образы (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Расширенные образы секторов (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Основные образы секторов (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Образы Flux (*.FDI)\0*.FDI\0Образы Surface (*.86F;*.MFM)\0*.86F;*.MFM\0Все файлы (*.*)\0*.*\0" - IDS_2112 "Невозможно инициализировать SDL, требуется SDL2.dll" IDS_2113 "Вы уверены, что хотите выполнить холодную перезагрузку эмулируемой машины?" IDS_2114 "Вы уверены, что хотите выйти из 86Box?" IDS_2115 "Невозможно инициализировать Ghostscript" diff --git a/src/win/languages/sl-SI.rc b/src/win/languages/sl-SI.rc index 80da82276..3a8b12dbb 100644 --- a/src/win/languages/sl-SI.rc +++ b/src/win/languages/sl-SI.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Disketa %i (%s): %ls" IDS_2110 "Vse slike (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Napredne sektorske slike (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Osnovne sektorske slike (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Tokovne slike (*.FDI)\0*.FDI\0Površinske slike (*.86F;*.MFM)\0*.86F;*.MFM\0Vse datoteke (*.*)\0*.*\0" - IDS_2112 "Ne morem inicializirati SDL, potrebna je knjižica SDL2.dll" IDS_2113 "Ste prepričani, da želite ponovno zagnati emulirani sistem?" IDS_2114 "Ste prepričani, da želite zapreti 86Box?" IDS_2115 "Ne morem inicializirati Ghostscript" diff --git a/src/win/languages/tr-TR.rc b/src/win/languages/tr-TR.rc index d7285bdf7..80a436c5d 100644 --- a/src/win/languages/tr-TR.rc +++ b/src/win/languages/tr-TR.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Disket %i (%s): %ls" IDS_2110 "Tüm imajlar (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Gelişmiş sektör imajları (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basit sektör imajları (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Yüzey imajları (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2112 "SDL başlatılamadı, SDL2.dll gerekmektedir" IDS_2113 "Emüle edilen makineyi yeniden başlatmak istediğinizden emin misiniz?" IDS_2114 "86Box'tan çıkmak istediğinize emin misiniz?" IDS_2115 "Ghostscript başlatılamadı" diff --git a/src/win/languages/uk-UA.rc b/src/win/languages/uk-UA.rc index d9674260c..53f401e81 100644 --- a/src/win/languages/uk-UA.rc +++ b/src/win/languages/uk-UA.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u МБ (CHS: %i, %i, %i)" IDS_2109 "Дисковод %i (%s): %ls" IDS_2110 "Усі образи (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Розширені образи секторів (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Основні образи секторів (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Образи Flux (*.FDI)\0*.FDI\0Образи Surface (*.86F;*.MFM)\0*.86F;*.MFM\0Усі файли (*.*)\0*.*\0" - IDS_2112 "Неможливо ініціалізувати SDL, потрібно SDL2.dll" IDS_2113 "Ви впевнені, що хочете виконати холодне перезавантаження емульованої машини?" IDS_2114 "Ви впевнені, що хочете вийти з 86Box?" IDS_2115 "Неможливо ініціалізувати Ghostscript" diff --git a/src/win/languages/zh-CN.rc b/src/win/languages/zh-CN.rc index 1be833eb3..1139de4ea 100644 --- a/src/win/languages/zh-CN.rc +++ b/src/win/languages/zh-CN.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "软盘 %i (%s): %ls" IDS_2110 "所有映像 (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0高级扇区映像 (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0基本扇区映像 (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux 映像 (*.FDI)\0*.FDI\0表面映像 (*.86F;*.MFM)\0*.86F;*.MFM\0所有文件 (*.*)\0*.*\0" - IDS_2112 "无法初始化 SDL,需要 SDL2.dll" IDS_2113 "确定要硬重置模拟器吗?" IDS_2114 "确定要退出 86Box 吗?" IDS_2115 "无法初始化 Ghostscript" diff --git a/src/win/languages/zh-TW.rc b/src/win/languages/zh-TW.rc index dcc01836b..58324442d 100644 --- a/src/win/languages/zh-TW.rc +++ b/src/win/languages/zh-TW.rc @@ -464,7 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "軟碟 %i (%s): %ls" IDS_2110 "所有映像 (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0進階磁區映像 (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0基本磁區映像 (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux 映像 (*.FDI)\0*.FDI\0表面映像 (*.86F;*.MFM)\0*.86F;*.MFM\0所有檔案 (*.*)\0*.*\0" - IDS_2112 "無法初始化 SDL,需要 SDL2.dll" IDS_2113 "確定要硬重設模擬器嗎?" IDS_2114 "確定要退出 86Box 嗎?" IDS_2115 "無法初始化 Ghostscript" From 0e53b86d25314d1548654762fe31161984ee26dc Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Tue, 13 Feb 2024 22:28:27 +0500 Subject: [PATCH 507/936] Move the Matrox Millennium II and G100 to the Dev branch --- CMakeLists.txt | 1 + src/include/86box/video.h | 2 ++ src/video/CMakeLists.txt | 4 ++++ src/video/vid_mga.c | 6 ++++++ src/video/vid_table.c | 4 ++++ src/win/Makefile.mingw | 10 ++++++++++ 6 files changed, 27 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index a6b50baf3..7767166af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -153,6 +153,7 @@ cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF) cmake_dependent_option(LASERXT "VTech Laser XT" ON "DEV_BRANCH" OFF) +cmake_dependent_option(MGA2 "Matrox Millennium II and Productiva G100" ON "DEV_BRANCH" OFF) cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF) cmake_dependent_option(PAS16 "Pro Audio Spectrum 16" ON "DEV_BRANCH" OFF) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index e82807a12..612d1e503 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -439,8 +439,10 @@ extern const device_t pgc_device; extern const device_t millennium_device; extern const device_t mystique_device; extern const device_t mystique_220_device; +# if defined(DEV_BRANCH) && defined(USE_MGA2) extern const device_t millennium_ii_device; extern const device_t productiva_g100_device; +# endif /* Oak OTI-0x7 */ extern const device_t oti037c_device; diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index 638837757..a11bb0a12 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -28,6 +28,10 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_mga.c vid_nga.c vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c) +if(MGA2) + target_compile_definitions(vid PRIVATE USE_MGA2) +endif() + if(VGAWONDER) target_compile_definitions(vid PRIVATE USE_VGAWONDER) endif() diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 088085355..c8836f129 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -6541,6 +6541,7 @@ mystique_220_available(void) return rom_present(ROM_MYSTIQUE_220); } +#if defined(DEV_BRANCH) && defined(USE_MGA2) static int millennium_ii_available(void) { @@ -6552,6 +6553,7 @@ matrox_g100_available(void) { return rom_present(ROM_G100); } +#endif static void mystique_speed_changed(void *priv) @@ -6601,6 +6603,7 @@ static const device_config_t mystique_config[] = { // clang-format on }; +#if defined(DEV_BRANCH) && defined(USE_MGA2) static const device_config_t millennium_ii_config[] = { // clang-format off { @@ -6632,6 +6635,7 @@ static const device_config_t millennium_ii_config[] = { } // clang-format on }; +#endif const device_t millennium_device = { .name = "Matrox Millennium", @@ -6675,6 +6679,7 @@ const device_t mystique_220_device = { .config = mystique_config }; +#if defined(DEV_BRANCH) && defined(USE_MGA2) const device_t millennium_ii_device = { .name = "Matrox Millennium II", .internal_name = "millennium_ii", @@ -6702,3 +6707,4 @@ const device_t productiva_g100_device = { .force_redraw = mystique_force_redraw, .config = millennium_ii_config }; +#endif diff --git a/src/video/vid_table.c b/src/video/vid_table.c index d40f00e13..70e5a6359 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -208,7 +208,9 @@ video_cards[] = { { &s3_diamond_stealth_4000_pci_device }, { &s3_trio3d2x_pci_device }, { &millennium_device }, +#if defined(DEV_BRANCH) && defined(USE_MGA2) { &millennium_ii_device }, +#endif { &mystique_device }, { &mystique_220_device }, { &tgui9440_pci_device }, @@ -259,7 +261,9 @@ video_cards[] = { { &s3_virge_357_agp_device }, { &s3_diamond_stealth_4000_agp_device }, { &s3_trio3d2x_agp_device }, +#if defined(DEV_BRANCH) && defined(USE_MGA2) { &productiva_g100_device, VIDEO_FLAG_TYPE_SPECIAL }, +#endif { &velocity_100_agp_device }, { &velocity_200_agp_device }, { &voodoo_3_1000_agp_device }, diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 0cf34d6c6..b889558ba 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -64,6 +64,9 @@ ifeq ($(DEV_BUILD), y) ifndef LASERXT LASERXT := y endif + ifndef MGA2 + MGA2 := y + endif ifndef OLIVETTI OLIVETTI := y endif @@ -125,6 +128,9 @@ else ifndef LASERXT LASERXT := n endif + ifndef MGA2 + MGA2 := n + endif ifndef OLIVETTI OLIVETTI := n endif @@ -490,6 +496,10 @@ ifeq ($(DEV_BRANCH), y) DEVBROBJ += m_xt_laserxt.o endif + ifeq ($(MGA2), y) + OPTS += -DUSE_MGA2 + endif + ifeq ($(OPEN_AT), y) OPTS += -DUSE_OPEN_AT endif From c7204f3c9fab2fc9943eb8e227655fee90a9fc3c Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 14 Feb 2024 02:51:19 +0600 Subject: [PATCH 508/936] Devbranch OPL4-ML daughterboard emulation (part 1) --- src/sound/CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index d6672ac18..aeaa8c0be 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -18,7 +18,7 @@ add_library(snd OBJECT sound.c snd_opl.c snd_opl_nuked.c snd_opl_ymfm.cpp snd_re snd_lpt_dss.c snd_ps1.c snd_adlib.c snd_adlibgold.c snd_ad1848.c snd_audiopci.c snd_azt2316a.c snd_cms.c snd_cmi8x38.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c snd_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c - snd_optimc.c midi_opl4.c midi_opl4_yrw801.c) + snd_optimc.c) if(OPENAL) if(VCPKG_TOOLCHAIN) @@ -125,5 +125,10 @@ if(GUSMAX) target_compile_definitions(snd PRIVATE USE_GUSMAX) endif() +if(OPL4ML) + target_compile_definitions(snd PRIVATE USE_OPL4ML) + target_sources(snd PRIVATE target_sources(snd PRIVATE midi_opl4.c midi_opl4_yrw801.c) +endif() + add_subdirectory(resid-fp) target_link_libraries(86Box resid-fp) From c81c04a2a9b26d3de7dbf0997a6db7ede73e8ee6 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 14 Feb 2024 02:54:41 +0600 Subject: [PATCH 509/936] Devbranch OPL4-ML daughterboard emulation (part 2) --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7767166af..80b56d619 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -160,6 +160,7 @@ cmake_dependent_option(PAS16 "Pro Audio Spectrum 16" cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF) cmake_dependent_option(VGAWONDER "ATI VGA Wonder (ATI-18800)" ON "DEV_BRANCH" OFF) cmake_dependent_option(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF) +cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF) # Ditto but for Qt if(QT) From c7c05676061dd195baa5a9ae73c20adb8873196d Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 14 Feb 2024 02:58:31 +0600 Subject: [PATCH 510/936] Devbranch OPL4-ML daughterboard emulation (part 3) --- src/sound/midi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sound/midi.c b/src/sound/midi.c index c5dbd666f..bb107acbf 100644 --- a/src/sound/midi.c +++ b/src/sound/midi.c @@ -100,7 +100,9 @@ static const MIDI_OUT_DEVICE devices[] = { #ifdef USE_RTMIDI { &rtmidi_output_device }, #endif +#if defined(DEV_BRANCH) && defined(USE_OPL4ML) { &opl4_midi_device }, +#endif { NULL } // clang-format on }; From 63329bc922df9d98954f6a5a09cef8f400d37ca8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 14 Feb 2024 03:02:14 +0600 Subject: [PATCH 511/936] Fix bad line --- src/sound/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index aeaa8c0be..72f05ff6d 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -127,7 +127,7 @@ endif() if(OPL4ML) target_compile_definitions(snd PRIVATE USE_OPL4ML) - target_sources(snd PRIVATE target_sources(snd PRIVATE midi_opl4.c midi_opl4_yrw801.c) + target_sources(snd PRIVATE midi_opl4.c midi_opl4_yrw801.c) endif() add_subdirectory(resid-fp) From f7c995738ca5aba8b380b7abcf5a7474851aae64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Wed, 14 Feb 2024 02:29:31 +0100 Subject: [PATCH 512/936] Fixed a bug in the 386 implementation of LOCK. --- src/cpu/x86_ops_misc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index 419ee7dc2..8e9c9f785 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -743,7 +743,7 @@ opLOCK(uint32_t fetchdat) if (legal == 1) legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ else if (legal == 2) { - legal = lock_legal[fetch_dat.b[1]]; + legal = lock_legal_0f[fetch_dat.b[1]]; if (legal == 1) legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,reg is illegal */ else if (legal == 3) { From e8406cdbc7b30e90511afe9beb3d2febf79c0758 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 14 Feb 2024 14:17:42 +0500 Subject: [PATCH 513/936] Rename vid_c&t_69000.c to avoid & in the filename Apparently CMake chokes on it in a few cases --- src/video/CMakeLists.txt | 5 ++--- src/video/{vid_c&t_69000.c => vid_chips_69000.c} | 0 2 files changed, 2 insertions(+), 3 deletions(-) rename src/video/{vid_c&t_69000.c => vid_chips_69000.c} (100%) diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index d14120caf..dc0cac1ff 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -19,15 +19,14 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c vid_sigma.c vid_wy700.c vid_ega.c vid_ega_render.c vid_svga.c vid_8514a.c vid_svga_render.c vid_ddc.c vid_vga.c vid_ati_eeprom.c vid_ati18800.c vid_ati28800.c vid_ati_mach8.c vid_ati_mach64.c vid_ati68875_ramdac.c - vid_ati68860_ramdac.c vid_bt48x_ramdac.c + vid_ati68860_ramdac.c vid_bt48x_ramdac.c vid_chips_69000.c vid_av9194.c vid_icd2061.c vid_ics2494.c vid_ics2595.c vid_cl54xx.c vid_et3000.c vid_et4000.c vid_sc1148x_ramdac.c vid_sc1502x_ramdac.c vid_et4000w32.c vid_stg_ramdac.c vid_ht216.c vid_oak_oti.c vid_paradise.c vid_rtg310x.c vid_f82c425.c vid_ti_cf62011.c vid_tvga.c vid_tgui9440.c vid_tkd8001_ramdac.c vid_att20c49x_ramdac.c vid_s3.c vid_s3_virge.c vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_mga.c vid_nga.c - vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c - vid_c&t_69000.c) + vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c) if(MGA2) target_compile_definitions(vid PRIVATE USE_MGA2) diff --git a/src/video/vid_c&t_69000.c b/src/video/vid_chips_69000.c similarity index 100% rename from src/video/vid_c&t_69000.c rename to src/video/vid_chips_69000.c From be27b6b6b22918adce315c8090be426339dce624 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 14 Feb 2024 14:18:33 +0500 Subject: [PATCH 514/936] Fix a forgotten change from D3D9 renderer removal It only affected the VNC renderer --- src/qt/qt_mainwindow.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index ccdb5a9cf..08d8bbf63 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -845,7 +845,7 @@ VNC - 6 + 5 From 0ecbc24763d021ee35408117e57a188eccc408ac Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 14 Feb 2024 14:19:35 +0500 Subject: [PATCH 515/936] Improve the OPL4-ML devbranching --- CMakeLists.txt | 2 +- src/include/86box/midi.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 80b56d619..f13e91791 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -156,11 +156,11 @@ cmake_dependent_option(LASERXT "VTech Laser XT" cmake_dependent_option(MGA2 "Matrox Millennium II and Productiva G100" ON "DEV_BRANCH" OFF) cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF) +cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF) cmake_dependent_option(PAS16 "Pro Audio Spectrum 16" ON "DEV_BRANCH" OFF) cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF) cmake_dependent_option(VGAWONDER "ATI VGA Wonder (ATI-18800)" ON "DEV_BRANCH" OFF) cmake_dependent_option(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF) -cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF) # Ditto but for Qt if(QT) diff --git a/src/include/86box/midi.h b/src/include/86box/midi.h index 4bc678817..7f7ad89ae 100644 --- a/src/include/86box/midi.h +++ b/src/include/86box/midi.h @@ -102,7 +102,9 @@ extern void midi_in_sysex(uint8_t *buffer, uint32_t len); #ifdef EMU_DEVICE_H extern const device_t rtmidi_output_device; extern const device_t rtmidi_input_device; +# if defined(DEV_BRANCH) && defined(USE_OPL4ML) extern const device_t opl4_midi_device; +# endif # ifdef USE_FLUIDSYNTH extern const device_t fluidsynth_device; # endif From 821f40deb1201cc9c82f6921da8a7bf057558998 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 14 Feb 2024 14:19:48 +0500 Subject: [PATCH 516/936] Fix the legacy Makefile --- src/win/Makefile.mingw | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index b889558ba..94b8af74a 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -73,6 +73,9 @@ ifeq ($(DEV_BUILD), y) ifndef OPEN_AT OPEN_AT := y endif + ifndef OPL4ML + OPL4ML := y + endif ifndef PAS16 PAS16 := y endif @@ -137,6 +140,9 @@ else ifndef OPEN_AT OPEN_AT := n endif + ifndef OPL4ML + OPL4ML := n + endif ifndef PAS16 PAS16 := n endif @@ -504,6 +510,11 @@ ifeq ($(DEV_BRANCH), y) OPTS += -DUSE_OPEN_AT endif + ifeq ($(OPL4ML), y) + OPTS += -DUSE_OPL4ML + DEVBROBJ += midi_opl4.o midi_opl4_yrw801.o + endif + ifeq ($(PAS16), y) OPTS += -DUSE_PAS16 DEVBROBJ += snd_pas16.o @@ -708,8 +719,6 @@ SNDOBJ := sound.o \ wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ wave8580_PST.o wave.o \ midi.o \ - midi_opl4.o \ - midi_opl4_yrw801.o \ snd_speaker.o \ snd_pssj.o \ snd_ps1.o \ @@ -744,10 +753,11 @@ VIDOBJ := agpgart.o video.o \ vid_vga.o \ vid_ati_eeprom.o \ vid_ati18800.o vid_ati28800.o \ - vid_ati_mach8.o \ + vid_ati_mach8.o \ vid_ati68875_ramdac.o \ vid_ati_mach64.o vid_ati68860_ramdac.o \ vid_bt48x_ramdac.o \ + vid_chips_69000.o \ vid_av9194.o vid_icd2061.o vid_ics2494.o vid_ics2595.o \ vid_cl54xx.o \ vid_et3000.o \ From 9b87dbe7bac0fedfeaec77e87b46595ce40c88ba Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 14 Feb 2024 14:48:58 +0500 Subject: [PATCH 517/936] Fix warnings in vid_chips_69000.c --- src/video/vid_chips_69000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index b15546a69..deabc2b6a 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -1988,7 +1988,7 @@ chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) case 0x600 ... 0x603: { chips->mem_regs_b[addr & 0xF] = val; - chips->mem_regs[addr >> 2] &= 0x80004040; + chips->mem_regs[(addr >> 2) & 0x3] &= 0x80004040; if (addr == 0x605 || addr == 0x607) chips_69000_interrupt(chips); break; @@ -1997,7 +1997,7 @@ chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) case 0x604 ... 0x607: { chips->mem_regs_b[addr & 0xF] &= ~val; - chips->mem_regs[addr >> 2] &= 0x80004040; + chips->mem_regs[(addr >> 2) & 0x3] &= 0x80004040; if (addr == 0x605 || addr == 0x607) chips_69000_interrupt(chips); break; From 0240f11bbee31327eb9b48346da55f891ee03777 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 14 Feb 2024 17:05:28 +0100 Subject: [PATCH 518/936] Matrox MGA fixes: 1. When the 128K banking is activated, use a mask of 0xffff instead of 0x1ffff. 2. Debian uses standard VGA mapping when in chain4 mode and its lfb is adapted accordingly. 3. Fixed the decode VRAM mask on the Millennium II so that the vram is detected correctly and no more glitches. 4. Undev the Millennium II as well. --- src/include/86box/video.h | 2 +- src/video/vid_mga.c | 50 +++++++++++++++++++++++---------------- src/video/vid_table.c | 2 -- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 26c9bd939..e1fa58b74 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -439,8 +439,8 @@ extern const device_t pgc_device; extern const device_t millennium_device; extern const device_t mystique_device; extern const device_t mystique_220_device; -# if defined(DEV_BRANCH) && defined(USE_MGA2) extern const device_t millennium_ii_device; +# if defined(DEV_BRANCH) && defined(USE_MGA2) extern const device_t productiva_g100_device; # endif diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index c8836f129..767ec57a0 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -1137,7 +1137,7 @@ mystique_recalc_mapping(mystique_t *mystique) switch (svga->gdcreg[6] & 0x0C) { case 0x0: /*128k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0x1ffff; + svga->banked_mask = 0xffff; break; case 0x4: /*64k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); @@ -2812,13 +2812,21 @@ mystique_readb_linear(uint32_t addr, void *priv) const svga_t *svga = (svga_t *) priv; mystique_t *mystique = (mystique_t *) svga->priv; - if (mystique->type < MGA_1064SG) { - if (!svga->fast) - return svga_read_linear(addr, priv); - } - cycles -= svga->monitor->mon_video_timing_read_b; + if ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) { + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xff; + + return svga->vram[addr & svga->vram_mask]; + } else if (svga->chain4 && !svga->force_old_addr) { + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_read) { + addr &= ~1; + addr <<= 2; + } + addr &= svga->decode_mask; if (addr >= svga->vram_max) return 0xff; @@ -2860,15 +2868,17 @@ mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv) svga_t *svga = (svga_t *) priv; mystique_t *mystique = (mystique_t *) svga->priv; - if (mystique->type < MGA_1064SG) { - if (!svga->fast) { - svga_write_linear(addr, val, priv); - return; - } - } - cycles -= svga->monitor->mon_video_timing_write_b; + if (((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && (svga->writemode < 4)) { + addr &= ~3; + } else if (svga->chain4 && (svga->writemode < 4)) { + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_write) { + addr &= ~1; + addr <<= 2; + } + addr &= svga->decode_mask; if (addr >= svga->vram_max) return; @@ -6401,8 +6411,8 @@ mystique_init(const device_t *info) mystique->svga.clock_gen = mystique->svga.ramdac; mystique->svga.getclock = tvp3026_getclock; mystique->svga.conv_16to32 = tvp3026_conv_16to32; - if (mystique->vram_size >= 16) - mystique->svga.decode_mask = mystique->svga.vram_mask; + if (mystique->type == MGA_2164W) + mystique->svga.decode_mask = 0xffffff; tvp3026_gpio(mystique_tvp3026_gpio_read, mystique_tvp3026_gpio_write, mystique, mystique->svga.ramdac); } else { video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_mystique); @@ -6413,8 +6423,8 @@ mystique_init(const device_t *info) NULL); mystique->svga.clock_gen = mystique; mystique->svga.getclock = mystique_getclock; - if (mystique->vram_size >= 16) - mystique->svga.decode_mask = mystique->svga.vram_mask; + if (mystique->type == MGA_G100) + mystique->svga.decode_mask = 0xffffff; } io_sethandler(0x03c0, 0x0020, mystique_in, NULL, NULL, mystique_out, NULL, NULL, mystique); @@ -6541,13 +6551,13 @@ mystique_220_available(void) return rom_present(ROM_MYSTIQUE_220); } -#if defined(DEV_BRANCH) && defined(USE_MGA2) static int millennium_ii_available(void) { return rom_present(ROM_MILLENNIUM_II); } +#if defined(DEV_BRANCH) && defined(USE_MGA2) static int matrox_g100_available(void) { @@ -6603,7 +6613,6 @@ static const device_config_t mystique_config[] = { // clang-format on }; -#if defined(DEV_BRANCH) && defined(USE_MGA2) static const device_config_t millennium_ii_config[] = { // clang-format off { @@ -6635,7 +6644,6 @@ static const device_config_t millennium_ii_config[] = { } // clang-format on }; -#endif const device_t millennium_device = { .name = "Matrox Millennium", @@ -6679,7 +6687,6 @@ const device_t mystique_220_device = { .config = mystique_config }; -#if defined(DEV_BRANCH) && defined(USE_MGA2) const device_t millennium_ii_device = { .name = "Matrox Millennium II", .internal_name = "millennium_ii", @@ -6694,6 +6701,7 @@ const device_t millennium_ii_device = { .config = millennium_ii_config }; +#if defined(DEV_BRANCH) && defined(USE_MGA2) const device_t productiva_g100_device = { .name = "Matrox Productiva G100", .internal_name = "productiva_g100", diff --git a/src/video/vid_table.c b/src/video/vid_table.c index a44ba071f..889bfa5fc 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -209,9 +209,7 @@ video_cards[] = { { &s3_trio3d2x_pci_device }, { &chips_69000_device }, { &millennium_device }, -#if defined(DEV_BRANCH) && defined(USE_MGA2) { &millennium_ii_device }, -#endif { &mystique_device }, { &mystique_220_device }, { &tgui9440_pci_device }, From f5995a4719668a4fa71cebe315fc0d56ef37008f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 15 Feb 2024 00:31:51 +0600 Subject: [PATCH 519/936] vid_svga.c: Hardware cursors with negative Y values work properly now * Fixes cursor disappearing completely in Matrox cards in some cases. * Allows emulated video adapters allowing negative Y values for hardware cursor to render those properly --- src/video/vid_chips_69000.c | 8 +++----- src/video/vid_mga.c | 4 ++-- src/video/vid_svga.c | 12 ++++++------ 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index deabc2b6a..3852070b8 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -1529,16 +1529,14 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) chips->ext_regs[chips->ext_index] = val; chips->svga.hwcursor.y = val | (chips->ext_regs[0xA7] & 7) << 8; if (chips->ext_regs[0xA7] & 0x80) { - chips->svga.hwcursor.yoff = chips->svga.hwcursor.y; - chips->svga.hwcursor.y = 0; + chips->svga.hwcursor.y = -chips->svga.hwcursor.y; } break; case 0xA7: chips->ext_regs[chips->ext_index] = val; chips->svga.hwcursor.y = chips->ext_regs[0xA6] | (val & 7) << 8; - if (chips->ext_regs[0xA7] & 0x80){ - chips->svga.hwcursor.yoff = chips->svga.hwcursor.y; - chips->svga.hwcursor.y = 0; + if (chips->ext_regs[0xA7] & 0x80) { + chips->svga.hwcursor.y = -chips->svga.hwcursor.y; } break; case 0xC8: diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 767ec57a0..f9564366b 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5924,9 +5924,9 @@ mystique_hwcursor_draw(svga_t *svga, int displine) case XCURCTRL_CURMODE_XGA: for (uint8_t x = 0; x < 64; x++) { if (!(dat[1] & (1ULL << 63))) - svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, mystique->cursor.col[1]) : svga_lookup_lut_ram(svga, mystique->cursor.col[0]); + svga->monitor->target_buffer->line[displine][(offset + svga->x_add) & 2047] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, mystique->cursor.col[1]) : svga_lookup_lut_ram(svga, mystique->cursor.col[0]); else if (dat[0] & (1ULL << 63)) - svga->monitor->target_buffer->line[displine][offset + svga->x_add] ^= 0xffffff; + svga->monitor->target_buffer->line[displine][(offset + svga->x_add) & 2047] ^= 0xffffff; offset++; dat[0] <<= 1; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 81cc50bc4..0293ebeda 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -981,7 +981,7 @@ svga_do_render(svga_t *svga) if (svga->dac_hwcursor_on) { if (!svga->override && svga->dac_hwcursor_draw) - svga->dac_hwcursor_draw(svga, svga->displine + svga->y_add); + svga->dac_hwcursor_draw(svga, (svga->displine + svga->y_add + ((svga->dac_hwcursor_latch.y >= 0) ? 0 : svga->dac_hwcursor_latch.y)) & 2047); svga->dac_hwcursor_on--; if (svga->dac_hwcursor_on && svga->interlace) svga->dac_hwcursor_on--; @@ -989,7 +989,7 @@ svga_do_render(svga_t *svga) if (svga->hwcursor_on) { if (!svga->override && svga->hwcursor_draw) - svga->hwcursor_draw(svga, svga->displine + svga->y_add); + svga->hwcursor_draw(svga, (svga->displine + svga->y_add + ((svga->hwcursor_latch.y >= 0) ? 0 : svga->hwcursor_latch.y)) & 2047); svga->hwcursor_on--; if (svga->hwcursor_on && svga->interlace) svga->hwcursor_on--; @@ -1018,22 +1018,22 @@ svga_poll(void *priv) } if (!svga->linepos) { - if (svga->displine == svga->hwcursor_latch.y && svga->hwcursor_latch.ena) { + if (svga->displine == ((svga->hwcursor_latch.y < 0) ? 0 : svga->hwcursor_latch.y) && svga->hwcursor_latch.ena) { svga->hwcursor_on = svga->hwcursor_latch.cur_ysize - svga->hwcursor_latch.yoff; svga->hwcursor_oddeven = 0; } - if (svga->displine == (svga->hwcursor_latch.y + 1) && svga->hwcursor_latch.ena && svga->interlace) { + if (svga->displine == (((svga->hwcursor_latch.y < 0) ? 0 : svga->hwcursor_latch.y) + 1) && svga->hwcursor_latch.ena && svga->interlace) { svga->hwcursor_on = svga->hwcursor_latch.cur_ysize - (svga->hwcursor_latch.yoff + 1); svga->hwcursor_oddeven = 1; } - if (svga->displine == svga->dac_hwcursor_latch.y && svga->dac_hwcursor_latch.ena) { + if (svga->displine == ((svga->dac_hwcursor_latch.y < 0) ? 0 : svga->dac_hwcursor_latch.y) && svga->dac_hwcursor_latch.ena) { svga->dac_hwcursor_on = svga->dac_hwcursor_latch.cur_ysize - svga->dac_hwcursor_latch.yoff; svga->dac_hwcursor_oddeven = 0; } - if (svga->displine == (svga->dac_hwcursor_latch.y + 1) && svga->dac_hwcursor_latch.ena && svga->interlace) { + if (svga->displine == (((svga->dac_hwcursor_latch.y < 0) ? 0 : svga->dac_hwcursor_latch.y) + 1) && svga->dac_hwcursor_latch.ena && svga->interlace) { svga->dac_hwcursor_on = svga->dac_hwcursor_latch.cur_ysize - (svga->dac_hwcursor_latch.yoff + 1); svga->dac_hwcursor_oddeven = 1; } From 536f10c60ec470535ae5807aebdc0fcb4360d108 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 14 Feb 2024 20:36:43 +0100 Subject: [PATCH 520/936] S3 Pre-ViRGE 32bpp fixes: 32-bit toggleable regs are now written properly, fixes OS/2 32-bit color using S3 Pre-ViRGE drivers while keeping existing compatibility fine. --- src/video/vid_s3.c | 243 +++++++++++++++++++++++++++------------------ 1 file changed, 146 insertions(+), 97 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index ca737e7fe..41e21faa9 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -981,16 +981,16 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xa148: case 0xa2e8: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xff00ffff) | (val << 16); + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); else - s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xffffff00) | val; + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; break; case 0xa149: case 0xa2e9: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.bkgd_color = (s3->accel.bkgd_color & 0x00ffffff) | (val << 24); + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); else - s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xffff00ff) | (val << 8); + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; @@ -1001,34 +1001,41 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xa14a: case 0xa2ea: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xffffff00) | val; - else - s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xff00ffff) | (val << 16); + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; + } break; case 0xa14b: case 0xa2eb: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xffff00ff) | (val << 8); - else - s3->accel.bkgd_color = (s3->accel.bkgd_color & 0x00ffffff) | (val << 24); - if (!(s3->accel.multifunc[0xe] & 0x200)) + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); s3->accel.multifunc[0xe] ^= 0x10; + } break; case 0xa548: case 0xa6e8: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.frgd_color = (s3->accel.frgd_color & 0xff00ffff) | (val << 16); + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); else - s3->accel.frgd_color = (s3->accel.frgd_color & 0xffffff00) | val; + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; break; case 0xa549: case 0xa6e9: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.frgd_color = (s3->accel.frgd_color & 0x00ffffff) | (val << 24); + s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); else - s3->accel.frgd_color = (s3->accel.frgd_color & 0xffff00ff) | (val << 8); + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; @@ -1039,34 +1046,41 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xa54a: case 0xa6ea: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.frgd_color = (s3->accel.frgd_color & 0xffffff00) | val; - else - s3->accel.frgd_color = (s3->accel.frgd_color & 0xff00ffff) | (val << 16); + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); + else + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; + } break; case 0xa54b: case 0xa6eb: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.frgd_color = (s3->accel.frgd_color & 0xffff00ff) | (val << 8); - else - s3->accel.frgd_color = (s3->accel.frgd_color & 0x00ffffff) | (val << 24); - if (!(s3->accel.multifunc[0xe] & 0x200)) + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); + else + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); s3->accel.multifunc[0xe] ^= 0x10; + } break; case 0xa948: case 0xaae8: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xff00ffff) | (val << 16); + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); else - s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xffffff00) | val; + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; break; case 0xa949: case 0xaae9: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.wrt_mask = (s3->accel.wrt_mask & 0x00ffffff) | (val << 24); + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); else - s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xffff00ff) | (val << 8); + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; @@ -1077,85 +1091,106 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xa94a: case 0xaaea: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xffffff00) | val; - else - s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xff00ffff) | (val << 16); + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; + } break; case 0xa94b: case 0xaaeb: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xffff00ff) | (val << 8); - else - s3->accel.wrt_mask = (s3->accel.wrt_mask & 0x00ffffff) | (val << 24); - if (!(s3->accel.multifunc[0xe] & 0x200)) + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); s3->accel.multifunc[0xe] ^= 0x10; + } break; case 0xad48: case 0xaee8: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.rd_mask = (s3->accel.rd_mask & 0xff00ffff) | (val << 16); + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); else - s3->accel.rd_mask = (s3->accel.rd_mask & 0xffffff00) | val; + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; break; case 0xad49: case 0xaee9: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.rd_mask = (s3->accel.rd_mask & 0x00ffffff) | (val << 24); + s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); else - s3->accel.rd_mask = (s3->accel.rd_mask & 0xffff00ff) | (val << 8); + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; break; case 0xad4a: case 0xaeea: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.rd_mask = (s3->accel.rd_mask & 0xffffff00) | val; - else - s3->accel.rd_mask = (s3->accel.rd_mask & 0xff00ffff) | (val << 16); + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); + else + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; + } break; case 0xad4b: case 0xaeeb: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.rd_mask = (s3->accel.rd_mask & 0xffff00ff) | (val << 8); - else - s3->accel.rd_mask = (s3->accel.rd_mask & 0x00ffffff) | (val << 24); - if (!(s3->accel.multifunc[0xe] & 0x200)) + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); + else + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); s3->accel.multifunc[0xe] ^= 0x10; + } break; case 0xb148: case 0xb2e8: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.color_cmp = (s3->accel.color_cmp & 0xff00ffff) | (val << 16); + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); else - s3->accel.color_cmp = (s3->accel.color_cmp & 0xffffff00) | val; + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; break; case 0xb149: case 0xb2e9: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.color_cmp = (s3->accel.color_cmp & 0x00ffffff) | (val << 24); + s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); else - s3->accel.color_cmp = (s3->accel.color_cmp & 0xffff00ff) | (val << 8); + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; break; case 0xb14a: case 0xb2ea: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.color_cmp = (s3->accel.color_cmp & 0xffffff00) | val; - else - s3->accel.color_cmp = (s3->accel.color_cmp & 0xff00ffff) | (val << 16); + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); + else + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; + } break; case 0xb14b: case 0xb2eb: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.color_cmp = (s3->accel.color_cmp & 0xffff00ff) | (val << 8); - else - s3->accel.color_cmp = (s3->accel.color_cmp & 0x00ffffff) | (val << 24); - if (!(s3->accel.multifunc[0xe] & 0x200)) + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); + else + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); s3->accel.multifunc[0xe] ^= 0x10; + } break; case 0xb548: @@ -1189,34 +1224,41 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xe548: case 0xe6e8: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xff00ffff) | (val << 16); + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); else - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xffffff00) | val; + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x000000ff) | val; break; case 0xe549: case 0xe6e9: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0x00ffffff) | (val << 24); + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); else - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xffff00ff) | (val << 8); + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x0000ff00) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; break; case 0xe54a: case 0xe6ea: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xffffff00) | val; - else - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xff00ffff) | (val << 16); + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); + else + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x000000ff) | val; + } break; case 0xe54b: case 0xe6eb: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xffff00ff) | (val << 8); - else - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0x00ffffff) | (val << 24); - if (!(s3->accel.multifunc[0xe] & 0x200)) + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); + else + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x0000ff00) | (val << 8); s3->accel.multifunc[0xe] ^= 0x10; + } break; case 0xe948: case 0xeae8: @@ -1237,34 +1279,41 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xed48: case 0xeee8: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xff00ffff) | (val << 16); + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); else - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xffffff00) | val; + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x000000ff) | val; break; case 0xed49: case 0xeee9: if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0x00ffffff) | (val << 24); + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); else - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xffff00ff) | (val << 8); + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x0000ff00) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; break; case 0xed4a: case 0xeeea: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xffffff00) | val; - else - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xff00ffff) | (val << 16); + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); + else + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x000000ff) | val; + } break; case 0xed4b: case 0xeeeb: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xffff00ff) | (val << 8); - else - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0x00ffffff) | (val << 24); - if (!(s3->accel.multifunc[0xe] & 0x200)) + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); + else + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x0000ff00) | (val << 8); s3->accel.multifunc[0xe] ^= 0x10; + } break; case 0xe148: @@ -8009,8 +8058,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.cy &= 0xfff; } - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; + s3->accel.cur_x = s3->accel.cx & 0xfff; + s3->accel.cur_y = s3->accel.cy & 0xfff; } break; @@ -8103,8 +8152,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.cx &= 0xfff; s3->accel.cy &= 0xfff; } - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; + s3->accel.cur_x = s3->accel.cx & 0xfff; + s3->accel.cur_y = s3->accel.cy & 0xfff; } else { /*Bresenham*/ if (s3->accel.b2e8_pix && s3_cpu_src(s3) && (count == 16)) { /*Stupid undocumented 0xB2E8 on 911/924*/ count = s3->accel.maj_axis_pcnt + 1; @@ -8198,8 +8247,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.cx &= 0xfff; s3->accel.cy &= 0xfff; } - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; + s3->accel.cur_x = s3->accel.cx & 0xfff; + s3->accel.cur_y = s3->accel.cy & 0xfff; } break; From 8166af1b77db5f74107113b75b4337cf07f2e24e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 16 Feb 2024 00:59:25 +0600 Subject: [PATCH 521/936] C&T 69000: Fix VBIOS size --- src/video/vid_chips_69000.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 3852070b8..eb67e16de 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -1835,7 +1835,7 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) chips->pci_rom_enable = val & 0x1; mem_mapping_disable(&chips->bios_rom.mapping); if (chips->pci_rom_enable & 1) { - mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x40000); + mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x10000); } break; case 0x32: @@ -1843,7 +1843,7 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) chips->rom_addr &= ~0xFF; chips->rom_addr |= val & 0xFC; if (chips->pci_rom_enable & 1) { - mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x40000); + mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x10000); } break; case 0x33: @@ -1851,7 +1851,7 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) chips->rom_addr &= ~0xFF00; chips->rom_addr |= (val << 8); if (chips->pci_rom_enable & 1) { - mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x40000); + mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x10000); } break; case 0x6C: @@ -2333,7 +2333,7 @@ chips_69000_init(const device_t *info) /* Appears to have an odd VBIOS size. */ if (!info->local) { - rom_init(&chips->bios_rom, "roms/video/chips/69000.ROM", 0xc0000, 0x40000, 0x3ffff, 0x0000, MEM_MAPPING_EXTERNAL); + rom_init(&chips->bios_rom, "roms/video/chips/69000.ROM", 0xc0000, 0x10000, 0xffff, 0x0000, MEM_MAPPING_EXTERNAL); mem_mapping_disable(&chips->bios_rom.mapping); } From d37b72e251a00c006fe60307ff2ae2d699a9562e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 16 Feb 2024 01:24:35 +0600 Subject: [PATCH 522/936] vid_tvp3026_ramdac: Implement warp-around for hardware cursor buffer32 drawing Fixes crashes on Windows 2000 --- src/video/vid_tvp3026_ramdac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c index 4b63892de..625adfe41 100644 --- a/src/video/vid_tvp3026_ramdac.c +++ b/src/video/vid_tvp3026_ramdac.c @@ -649,7 +649,7 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine) comb = (b0 | (b1 << 1)); y_pos = displine; - x_pos = offset + svga->x_add; + x_pos = (offset + svga->x_add) & 2047; p = svga->monitor->target_buffer->line[y_pos]; if (offset >= svga->dac_hwcursor_latch.x) { From e9f0af21a05b659597e779fc52eb770db1e207a7 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 15 Feb 2024 23:10:05 +0100 Subject: [PATCH 523/936] MGA updates for the vram detection and stuff. 1. The Debian issue mystery lies around chain2_read/write being required when the LFB mapping is enabled too when MGA modes are set without blitting, however, when it is blitting, immediately tell chain2 to not interfere with the mapping. Fixes Debian once and for all as well as VRAM detection correctly while keeping existing compatibility fine. 2. Undev branch the G100 per above. (Revert if more bugs are revealed). 3. An AND with 0 is not tolerable as it nulls the LFB, fixes hang ups with Win2000 using the Millennium II and possibly the G100. 4. the Extended CRTCs now have a call for timing recalculation, fixes mode changes when blitting is going on. --- src/include/86box/video.h | 2 - src/video/vid_mga.c | 161 +++++++++++++++++++++++--------------- src/video/vid_table.c | 2 - 3 files changed, 96 insertions(+), 69 deletions(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index e1fa58b74..47d237b10 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -440,9 +440,7 @@ extern const device_t millennium_device; extern const device_t mystique_device; extern const device_t mystique_220_device; extern const device_t millennium_ii_device; -# if defined(DEV_BRANCH) && defined(USE_MGA2) extern const device_t productiva_g100_device; -# endif /* Oak OTI-0x7 */ extern const device_t oti037c_device; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index f9564366b..89b036ede 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -794,7 +794,7 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) } } - if (mystique->crtcext_idx == 4) { + if (mystique->crtcext_idx == 4) { if (svga->gdcreg[6] & 0xc) { /*64k banks*/ if (mystique->type >= MGA_2164W) { @@ -815,6 +815,7 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) } } } + svga_recalctimings(svga); break; default: @@ -2814,17 +2815,11 @@ mystique_readb_linear(uint32_t addr, void *priv) cycles -= svga->monitor->mon_video_timing_read_b; - if ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) { - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xff; - - return svga->vram[addr & svga->vram_mask]; - } else if (svga->chain4 && !svga->force_old_addr) { - addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); - } else if (svga->chain2_read) { - addr &= ~1; - addr <<= 2; + if (!svga->fast) { + if (svga->chain2_read) { + addr &= ~1; + addr <<= 2; + } } addr &= svga->decode_mask; @@ -2870,13 +2865,11 @@ mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv) cycles -= svga->monitor->mon_video_timing_write_b; - if (((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && (svga->writemode < 4)) { - addr &= ~3; - } else if (svga->chain4 && (svga->writemode < 4)) { - addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); - } else if (svga->chain2_write) { - addr &= ~1; - addr <<= 2; + if (!svga->fast) { + if (svga->chain2_write) { + addr &= ~1; + addr <<= 2; + } } addr &= svga->decode_mask; @@ -5835,9 +5828,14 @@ blit_iload_highv(mystique_t *mystique) static void mystique_start_blit(mystique_t *mystique) { + svga_t *svga = &mystique->svga; uint64_t start_time = plat_timer_read(); uint64_t end_time; + /*Make sure we don't get any artifacts.*/ + svga->chain2_write = 0; + svga->chain2_read = 0; + mystique->dwgreg.dwgctrl_running = mystique->dwgreg.dwgctrl; mystique->maccess_running = mystique->maccess; @@ -5969,15 +5967,6 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) mystique_t *mystique = (mystique_t *) priv; uint8_t ret = 0x00; - if (mystique->type >= MGA_1164SG) - { - /* Mystique 220, Millennium II and later Matrox cards swap MGABASE1 and 2. */ - if (addr >= 0x10 && addr <= 0x13) - addr += 0x4; - else if (addr >= 0x14 && addr <= 0x17) - addr -= 0x4; - } - if ((addr >= 0x30) && (addr <= 0x33) && !(mystique->pci_regs[0x43] & 0x40)) ret = 0x00; else @@ -6032,25 +6021,46 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) case 0x10: ret = 0x00; - break; /*Control aperture*/ + break; /*Control aperture for Millennium and Mystique, LFB for Mystique 220 and later*/ case 0x11: - ret = (mystique->ctrl_base >> 8) & 0xc0; + if (mystique->type >= MGA_1164SG) + ret = 0x00; + else + ret = (mystique->ctrl_base >> 8) & 0xc0; break; case 0x12: - ret = mystique->ctrl_base >> 16; + if (mystique->type >= MGA_1164SG) + ret = (mystique->type >= MGA_2164W) ? 0x00 : ((mystique->lfb_base >> 16) & 0x80); + else + ret = mystique->ctrl_base >> 16; break; case 0x13: - ret = mystique->ctrl_base >> 24; + if (mystique->type >= MGA_1164SG) + ret = mystique->lfb_base >> 24; + else + ret = mystique->ctrl_base >> 24; break; case 0x14: ret = 0x00; - break; /*Linear frame buffer*/ + break; /*LFB for Millennium and Mystique, Control aperture for Mystique 220 and later*/ + case 0x15: + if (mystique->type >= MGA_1164SG) + ret = (mystique->ctrl_base >> 8) & 0xc0; + else + ret = 0x00; + break; case 0x16: - ret = (mystique->type >= MGA_2164W) ? 0x00 : ((mystique->lfb_base >> 16) & 0x80); + if (mystique->type >= MGA_1164SG) + ret = mystique->ctrl_base >> 16; + else + ret = (mystique->lfb_base >> 16) & 0x80; break; case 0x17: - ret = mystique->lfb_base >> 24; + if (mystique->type >= MGA_1164SG) + ret = mystique->ctrl_base >> 24; + else + ret = mystique->lfb_base >> 24; break; case 0x18: @@ -6090,7 +6100,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) break; case 0x34: - ret = mystique->type == MGA_G100 ? 0xdc : 0x00; + ret = (mystique->type == MGA_G100) ? 0xdc : 0x00; break; case 0x3c: @@ -6193,15 +6203,6 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { mystique_t *mystique = (mystique_t *) priv; - if (mystique->type >= MGA_1164SG) - { - /* Mystique 220, Millennium II and later Matrox cards swap MGABASE1 and 2. */ - if (addr >= 0x10 && addr <= 0x13) - addr += 0x4; - else if (addr >= 0x14 && addr <= 0x17) - addr -= 0x4; - } - switch (addr) { case PCI_REG_COMMAND: mystique->pci_regs[PCI_REG_COMMAND] = (val & 0x27) | 0x80; @@ -6217,27 +6218,61 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) break; case 0x11: - mystique->ctrl_base = (mystique->ctrl_base & 0xffff0000) | ((val & 0xc0) << 8); - mystique_recalc_mapping(mystique); + if (mystique->type >= MGA_1164SG) + break; + else { + mystique->ctrl_base = (mystique->ctrl_base & 0xffff0000) | ((val & 0xc0) << 8); + mystique_recalc_mapping(mystique); + } break; case 0x12: - mystique->ctrl_base = (mystique->ctrl_base & 0xff00c000) | (val << 16); - mystique_recalc_mapping(mystique); + if (mystique->type >= MGA_1164SG) { + if (mystique->type >= MGA_2164W) + break; + mystique->lfb_base = (mystique->lfb_base & 0xff000000) | ((val & 0x80) << 16); + mystique_recalc_mapping(mystique); + } else { + mystique->ctrl_base = (mystique->ctrl_base & 0xff00c000) | (val << 16); + mystique_recalc_mapping(mystique); + } break; case 0x13: - mystique->ctrl_base = (mystique->ctrl_base & 0x00ffc000) | (val << 24); - mystique_recalc_mapping(mystique); + if (mystique->type >= MGA_1164SG) { + if (mystique->type >= MGA_2164W) + mystique->lfb_base = val << 24; + else + mystique->lfb_base = (mystique->lfb_base & 0x00800000) | (val << 24); + + mystique_recalc_mapping(mystique); + } else { + mystique->ctrl_base = (mystique->ctrl_base & 0x00ffc000) | (val << 24); + mystique_recalc_mapping(mystique); + } break; + case 0x15: + if (mystique->type >= MGA_1164SG) { + mystique->ctrl_base = (mystique->ctrl_base & 0xffff0000) | ((val & 0xc0) << 8); + mystique_recalc_mapping(mystique); + } + break; case 0x16: - if (mystique->type >= MGA_2164W) - break; - mystique->lfb_base = (mystique->lfb_base & 0xff000000) | ((val & 0x80) << 16); - mystique_recalc_mapping(mystique); + if (mystique->type >= MGA_1164SG) { + mystique->ctrl_base = (mystique->ctrl_base & 0xff00c000) | (val << 16); + mystique_recalc_mapping(mystique); + } else { + mystique->lfb_base = (mystique->lfb_base & 0xff000000) | ((val & 0x80) << 16); + mystique_recalc_mapping(mystique); + } break; case 0x17: - mystique->lfb_base = (mystique->lfb_base & ((mystique->type >= MGA_2164W) ? 0x00000000 : 0x00800000)) | (val << 24); - mystique_recalc_mapping(mystique); + if (mystique->type >= MGA_1164SG) { + mystique->ctrl_base = (mystique->ctrl_base & 0x00ffc000) | (val << 24); + mystique_recalc_mapping(mystique); + } else { + mystique->lfb_base = (mystique->lfb_base & 0x00800000) | (val << 24); + mystique_recalc_mapping(mystique); + } break; case 0x1a: @@ -6258,8 +6293,8 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) if (addr == 0x30) mystique->pci_regs[addr] &= 1; if (mystique->pci_regs[0x30] & 0x01) { - uint32_t addr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); - mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, (mystique->type == MGA_G100) ? 0x10000 : 0x8000); + uint32_t biosaddr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); + mem_mapping_set_addr(&mystique->bios_rom.mapping, biosaddr, (mystique->type == MGA_G100) ? 0x10000 : 0x8000); } else mem_mapping_disable(&mystique->bios_rom.mapping); return; @@ -6282,8 +6317,8 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) if (addr == 0x43) { if (val & 0x40) { if (mystique->pci_regs[0x30] & 0x01) { - uint32_t addr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); - mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, (mystique->type == MGA_G100) ? 0x10000 : 0x8000); + uint32_t biosaddr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); + mem_mapping_set_addr(&mystique->bios_rom.mapping, biosaddr, (mystique->type == MGA_G100) ? 0x10000 : 0x8000); } else mem_mapping_disable(&mystique->bios_rom.mapping); } else @@ -6557,13 +6592,11 @@ millennium_ii_available(void) return rom_present(ROM_MILLENNIUM_II); } -#if defined(DEV_BRANCH) && defined(USE_MGA2) static int matrox_g100_available(void) { return rom_present(ROM_G100); } -#endif static void mystique_speed_changed(void *priv) @@ -6701,7 +6734,6 @@ const device_t millennium_ii_device = { .config = millennium_ii_config }; -#if defined(DEV_BRANCH) && defined(USE_MGA2) const device_t productiva_g100_device = { .name = "Matrox Productiva G100", .internal_name = "productiva_g100", @@ -6715,4 +6747,3 @@ const device_t productiva_g100_device = { .force_redraw = mystique_force_redraw, .config = millennium_ii_config }; -#endif diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 889bfa5fc..1faa04783 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -260,9 +260,7 @@ video_cards[] = { { &s3_virge_357_agp_device }, { &s3_diamond_stealth_4000_agp_device }, { &s3_trio3d2x_agp_device }, -#if defined(DEV_BRANCH) && defined(USE_MGA2) { &productiva_g100_device, VIDEO_FLAG_TYPE_SPECIAL }, -#endif { &velocity_100_agp_device }, { &velocity_200_agp_device }, { &voodoo_3_1000_agp_device }, From 19b8dbb1d2e1afaef4c3d9a1e5fcce7f826eba87 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 16 Feb 2024 12:32:58 +0600 Subject: [PATCH 524/936] C&T: Clear bit 7 of CRTC register 0x40 on vertical blank start, fixes DirectDraw hangs --- src/video/vid_chips_69000.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index eb67e16de..88ff698c7 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -2202,6 +2202,7 @@ chips_69000_vblank_start(svga_t *svga) { chips_69000_t *chips = (chips_69000_t *) svga->priv; chips->mem_regs[1] |= 1 << 14; + chips->svga.crtc[0x40] &= ~0x80; chips_69000_interrupt(chips); } From f9aa97e1d3250dd46b624de3ceccd9066cbb9841 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 16 Feb 2024 14:05:50 +0600 Subject: [PATCH 525/936] Fix text drawing on defined quadword aligned modes with CPU source --- src/video/vid_chips_69000.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 88ff698c7..a37510190 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -1081,7 +1081,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) return; } -#if 0 +#if 1 if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { pclog("C&T: Monochrome blit (monochrome_source_alignment = %d, " "monochrome left clip = %d, " @@ -1107,6 +1107,9 @@ chips_69000_setup_bitblt(chips_69000_t* chips) } else { chips->bitblt_running.mono_bits_skip_left = chips->bitblt_running.bitblt.monochrome_source_left_clip; + if (chips->bitblt_running.bitblt.monochrome_source_alignment == 5) + chips->bitblt_running.bitblt.monochrome_source_alignment = 0; + if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0) { chips->bitblt_running.mono_bytes_pitch = ((chips->bitblt_running.actual_destination_width + chips->bitblt_running.bitblt.monochrome_source_left_clip + 63) & ~63) / 8; } @@ -1238,7 +1241,14 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { int orig_cycles = cycles; chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; - if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0 && chips->bitblt_running.mono_bytes_pitch && chips->bitblt_running.mono_bytes_pitch == chips->bitblt_running.bytes_written) { + if (chips->bitblt_running.bitblt.monochrome_source_alignment == 1) { + uint8_t val = chips->bitblt_running.bytes_port[0]; + int i = 0; + chips->bitblt_running.bytes_written = 0; + for (i = 0; i < 8; i++) { + chips_69000_process_mono_bit(chips, !!(val & (1 << (7 - i)))); + } + } else if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0 && chips->bitblt_running.mono_bytes_pitch && chips->bitblt_running.mono_bytes_pitch == chips->bitblt_running.bytes_written) { int orig_count_y = chips->bitblt_running.count_y; int i = 0, j = 0; chips->bitblt_running.bytes_written = 0; @@ -1254,8 +1264,7 @@ chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { } } else if ((chips->bitblt_running.bitblt.monochrome_source_alignment == 0 && !chips->bitblt_running.mono_bytes_pitch) - || chips->bitblt_running.bitblt.monochrome_source_alignment == 2 - || chips->bitblt_running.bitblt.monochrome_source_alignment == 1) { + || chips->bitblt_running.bitblt.monochrome_source_alignment == 2) { int orig_count_y = chips->bitblt_running.count_y; int i = 0; uint8_t val = chips->bitblt_running.bytes_port[0]; From 9b070310a029513eec54ec49a8df9d09acba237e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 16 Feb 2024 14:40:29 +0600 Subject: [PATCH 526/936] Disable logging --- src/video/vid_chips_69000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index a37510190..e7486a684 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -1081,7 +1081,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips) return; } -#if 1 +#if 0 if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { pclog("C&T: Monochrome blit (monochrome_source_alignment = %d, " "monochrome left clip = %d, " From 996e365a8ce1498cd940a66120a1c9dcaa42ecf0 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 16 Feb 2024 15:02:05 +0600 Subject: [PATCH 527/936] Implement missing ROPs --- src/video/vid_chips_69000.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index e7486a684..57871e33f 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -475,6 +475,9 @@ chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t pattern, uint8_t src, ui break; case 0xAA: break; /* No-op. */ + case 0xAC: + *dst = src ^ (pattern & (*dst ^ src)); + break; case 0xAF: *dst |= ~pattern; break; @@ -484,6 +487,9 @@ chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t pattern, uint8_t src, ui case 0xCA: *dst ^= (pattern & (src ^ *dst)); break; + case 0xE2: + *dst ^= (src & (pattern ^ *dst)); + break; case 0xDA: *dst ^= pattern & (~(src & *dst)); break; @@ -502,6 +508,9 @@ chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t pattern, uint8_t src, ui case 0xFF: *dst = 0xFF; break; + default: + pclog("Unknown ROP 0x%X\n", rop); + break; } } @@ -513,6 +522,9 @@ chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t pattern, uint16_t src } switch (rop) { + default: + pclog("Unknown ROP 0x%X\n", rop); + break; case 0x00: *dst = 0; break; @@ -572,6 +584,9 @@ chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t pattern, uint16_t src break; case 0xAA: break; /* No-op. */ + case 0xAC: + *dst = src ^ (pattern & (*dst ^ src)); + break; case 0xAF: *dst |= ~pattern; break; @@ -581,6 +596,9 @@ chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t pattern, uint16_t src case 0xCA: *dst ^= (pattern & (src ^ *dst)); break; + case 0xE2: + *dst ^= (src & (pattern ^ *dst)); + break; case 0xDA: *dst ^= pattern & (~(src & *dst)); break; @@ -612,6 +630,9 @@ chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t pattern, uint32_t src } switch (rop) { + default: + pclog("Unknown ROP 0x%X\n", rop); + break; case 0x00: *dst = 0; break; @@ -671,6 +692,9 @@ chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t pattern, uint32_t src break; case 0xAA: break; /* No-op. */ + case 0xAC: + *dst = src ^ (pattern & (*dst ^ src)); + break; case 0xAF: *dst |= ~pattern; break; @@ -683,6 +707,9 @@ chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t pattern, uint32_t src case 0xDA: *dst ^= pattern & (~(src & *dst)); break; + case 0xE2: + *dst ^= (src & (pattern ^ *dst)); + break; case 0xEA: *dst |= pattern & src; break; @@ -853,7 +880,7 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) if (chips->bitblt_running.bitblt.bitblt_control & (1 << 19)) pattern_data = 0; else - pattern_data = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + ((vert_pat_alignment + chips->bitblt_running.y) & 7), chips); + pattern_data = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + ((vert_pat_alignment + (chips->bitblt_running.y & 7)) & 7), chips); is_true = !!(pattern_data & (1 << (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7))); From edee5fd83950e352ac569fcd990a14c74f289407 Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Fri, 16 Feb 2024 20:45:37 +0300 Subject: [PATCH 528/936] More 486 machine changes that I missed --- src/machine/m_at_386dx_486.c | 14 +++++++++----- src/machine/machine_table.c | 22 +++++++++++----------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 5a47af620..415b7b442 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1961,19 +1961,22 @@ machine_at_actionpc2600_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 3); pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0E, PCI_CARD_VIDEO, 0, 0, 0, 0); pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); device_add(&umc_hb4_device); device_add(&umc_8886af_device); - device_add(&um8669f_device); + device_add(&fdc37c665_device); device_add(&intel_flash_bxt_device); device_add(&keyboard_ps2_tg_ami_device); + if (gfxcard[0] == VID_INTERNAL) + device_add(&tgui9440_onboard_pci_device); + return ret; } @@ -1992,14 +1995,15 @@ machine_at_actiontower8400_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - if (gfxcard[0] == VID_INTERNAL) - pci_register_slot(0x15, PCI_CARD_VIDEO, 0, 0, 0, 0); + pci_register_slot(0x15, PCI_CARD_VIDEO, 0, 0, 0, 0); + pci_register_slot(0x16, PCI_CARD_IDE, 0, 0, 0, 0); pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x14, PCI_CARD_NORMAL, 2, 3, 4, 1); device_add(&umc_hb4_device); device_add(&umc_8886af_device); device_add(&fdc37c665_device); + device_add(&ide_cmd640_pci_device); device_add(&intel_flash_bxt_device); // The ActionPC 2600 has this so I'm gonna assume this does too. device_add(&keyboard_ps2_ami_pci_device); if (gfxcard[0] == VID_INTERNAL) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 5b54dd506..00c776209 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -5941,7 +5941,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM | MACHINE_GAMEPORT, .ram = { .min = 4096, .max = 36864, @@ -6668,7 +6668,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_VLB, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_APM, /* Has internal video: Western Digital WD90C33-ZZ */ .ram = { .min = 1024, .max = 65536, @@ -6802,7 +6802,7 @@ const machine_t machines[] = { .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = &tgui9440_onboard_pci_device, + .vid_device = NULL, .snd_device = NULL, .net_device = NULL }, @@ -7160,7 +7160,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2, - .flags = MACHINE_SUPER_IO | MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_SUPER_IO | MACHINE_IDE | MACHINE_APM, /* Has onboard video: C&T F65545 */ .ram = { .min = 1024, .max = 32768, @@ -7843,7 +7843,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, .ram = { .min = 2048, .max = 261120, @@ -8003,7 +8003,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_VIDEO, .ram = { .min = 1024, .max = 262144, @@ -8204,7 +8204,7 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PCIV, + .bus_flags = MACHINE_PS2_PCIV, .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 1024, @@ -8245,7 +8245,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_PCIV, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, .ram = { .min = 1024, .max = 131072, @@ -8330,7 +8330,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal video: ST STPC Atlas */ .ram = { .min = 32768, .max = 163840, @@ -8371,7 +8371,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, /* Machine has internal video: ST STPC Atlas */ .ram = { .min = 32768, .max = 163840, @@ -8412,7 +8412,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_APM, /* Machine has internal video: ST STPC Atlas and NIC: Realtek RTL8139C+ */ .ram = { .min = 32768, .max = 131072, From cfa1e0d793fa30050b60d53c3ffdb7acacdcbd6e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 17 Feb 2024 15:43:52 +0600 Subject: [PATCH 529/936] C&T: Implement clock select and LCD panning properly --- src/video/vid_chips_69000.c | 55 +++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 57871e33f..f81029f57 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -205,11 +205,6 @@ chips_69000_read_flat_panel(chips_69000_t* chips) { switch (chips->flat_panel_index) { case 0: - /* Report no presence of flat panel module. */ - return 0; - case 1: - return 1; - case 0x10: return 1; default: return chips->flat_panel_regs[chips->flat_panel_index]; @@ -224,6 +219,13 @@ chips_69000_write_flat_panel(chips_69000_t* chips, uint8_t val) switch (chips->flat_panel_index) { case 0: return; + case 1: + case 0x20 ... 0x33: + case 0x35: + case 0x36: + chips->flat_panel_regs[chips->flat_panel_index] = val; + svga_recalctimings(&chips->svga); + return; default: chips->flat_panel_regs[chips->flat_panel_index] = val; break; @@ -735,6 +737,8 @@ chips_69000_recalctimings(svga_t *svga) { chips_69000_t *chips = (chips_69000_t *) svga->priv; + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((svga->miscout >> 2) & 3, svga->priv); + if (chips->ext_regs[0x81] & 0x10) { svga->htotal -= 5; } @@ -769,7 +773,7 @@ chips_69000_recalctimings(svga_t *svga) svga->htotal += 5; svga->hblank_end_val = ((svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00)) | (svga->crtc[0x3c] & 0b11000000); - svga->hblank_end_len = 0x100; + svga->hblank_end_mask = 0xff; svga->ma_latch |= (svga->crtc[0x40] & 0xF) << 16; svga->rowoffset |= (svga->crtc[0x41] & 0xF) << 8; @@ -806,8 +810,32 @@ chips_69000_recalctimings(svga_t *svga) svga->render = svga_render_32bpp_highres; break; } +#if 1 + if (chips->flat_panel_regs[0x01] & 0x2) { + /* TODO: Fix horizontal parameter calculations. */ + if (svga->hdisp > (((chips->flat_panel_regs[0x20] | ((chips->flat_panel_regs[0x25] & 0xF) << 8)) + 1) << 3)) { + svga->hdisp = ((chips->flat_panel_regs[0x20] | ((chips->flat_panel_regs[0x25] & 0xF) << 8)) + 1) << 3; + //svga->htotal = ((chips->flat_panel_regs[0x23] | ((chips->flat_panel_regs[0x26] & 0xF) << 8)) + 5) << 3; + //svga->hblank_end_val = svga->htotal - 1; + } + if (svga->dispend > (((chips->flat_panel_regs[0x30] | ((chips->flat_panel_regs[0x35] & 0xF) << 8)) + 1))) { + svga->dispend = svga->vsyncstart = svga->vblankstart = ((chips->flat_panel_regs[0x30] | ((chips->flat_panel_regs[0x35] & 0xF) << 8)) + 1); + } + //svga->hdisp = ((chips->flat_panel_regs[0x20] | ((chips->flat_panel_regs[0x25] & 0xF) << 8)) + 1) << 3; + //svga->htotal = ((chips->flat_panel_regs[0x23] | ((chips->flat_panel_regs[0x26] & 0xF) << 8)) + 5) << 3; + //svga->hblank_end_val = svga->htotal - 1; + //svga->dispend = svga->vsyncstart = svga->vblankstart = ((chips->flat_panel_regs[0x30] | ((chips->flat_panel_regs[0x35] & 0xF) << 8)) + 1); + //svga->vsyncstart = ((chips->flat_panel_regs[0x31] | ((chips->flat_panel_regs[0x35] & 0xF0) << 4)) + 1); + //svga->vtotal = ((chips->flat_panel_regs[0x33] | ((chips->flat_panel_regs[0x36] & 0xF) << 8)) + 2); + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((chips->flat_panel_regs[0x03] >> 2) & 3, svga->priv); + svga->hoverride = 1; + } else { + svga->hoverride = 0; + } +#endif } else { svga->bpp = 8; + svga->hoverride = 0; } } @@ -1790,7 +1818,9 @@ chips_69000_pci_read(int func, int addr, void *p) case 0x03: return 0x00; case 0x04: - return chips->pci_conf_status; + return (chips->pci_conf_status & 0b11100011) | 0x80; + case 0x06: + return 0x80; case 0x07: return 0x02; case 0x08: @@ -1840,14 +1870,12 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) { chips->pci_conf_status = val; io_removehandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips); - mem_mapping_disable(&chips->bios_rom.mapping); mem_mapping_disable(&chips->linear_mapping); mem_mapping_disable(&chips->svga.mapping); if (chips->pci_conf_status & PCI_COMMAND_IO) { io_sethandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips); } if (chips->pci_conf_status & PCI_COMMAND_MEM) { - if (!chips->on_board) mem_mapping_enable(&chips->bios_rom.mapping); mem_mapping_enable(&chips->svga.mapping); if (chips->linear_mapping.base) mem_mapping_enable(&chips->linear_mapping); @@ -2320,13 +2348,15 @@ chips_69000_getclock(int clock, void *priv) int m = chips->ext_regs[0xc8]; int n = chips->ext_regs[0xc9]; - int pl = (chips->ext_regs[0xcb] >> 4) & 7; + int pl = ((chips->ext_regs[0xcb] >> 4) & 7); float fvco = 14318181.0 * ((float)(m + 2) / (float)(n + 2)); if (chips->ext_regs[0xcb] & 4) fvco *= 4.0; float fo = fvco / (float)(1 << pl); + pclog("freq = %f\n", fo); + return fo; } @@ -2356,9 +2386,10 @@ chips_69000_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) static int chips_69000_line_compare(svga_t* svga) { - /* Line compare glitches out at 1600x1200 and above. Disable it. */ - if (svga->dispend >= 1200) + const chips_69000_t *chips = (chips_69000_t *) svga->priv; + if (chips->ext_regs[0x81] & 0xF) { return 0; + } return 1; } From fac527158c80c24cc98a77ca837904a29a426d21 Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Sat, 17 Feb 2024 15:22:56 +0300 Subject: [PATCH 530/936] The onboard Cirrus in the Epson ActionTower 8400 now gets loaded in the correct PCI slot --- src/machine/m_at_386dx_486.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 415b7b442..b6f2ec6d9 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -2007,7 +2007,7 @@ machine_at_actiontower8400_init(const machine_t *model) device_add(&intel_flash_bxt_device); // The ActionPC 2600 has this so I'm gonna assume this does too. device_add(&keyboard_ps2_ami_pci_device); if (gfxcard[0] == VID_INTERNAL) - device_add(&gd5430_pci_device); // VBIOS not included in BIOS ROM + device_add(&gd5430_onboard_pci_device); return ret; } From 451bc3d425ad9a568be6270d7b44baabd9051691 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 18 Feb 2024 02:39:14 +0600 Subject: [PATCH 531/936] C&T 69000: Patterns are no longer horizontally reversed Fixes mouse dragging glitches under Windows 2000 on 16+ bpp --- src/video/vid_chips_69000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index f81029f57..9ab6ba414 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -910,7 +910,7 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) else pattern_data = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + ((vert_pat_alignment + (chips->bitblt_running.y & 7)) & 7), chips); - is_true = !!(pattern_data & (1 << (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7))); + is_true = !!(pattern_data & (1 << (7 - ((chips->bitblt_running.bitblt.destination_addr + chips->bitblt_running.x) & 7)))); if (!is_true && (chips->bitblt_running.bitblt.bitblt_control & (1 << 17))) { return; From 29c7b80fcfcb923ffbea2cf405295cddeba253da Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 18 Feb 2024 02:43:56 +0600 Subject: [PATCH 532/936] Only skip hblank calculations when actually needed --- src/video/vid_chips_69000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 9ab6ba414..6a15e3a62 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -817,6 +817,7 @@ chips_69000_recalctimings(svga_t *svga) svga->hdisp = ((chips->flat_panel_regs[0x20] | ((chips->flat_panel_regs[0x25] & 0xF) << 8)) + 1) << 3; //svga->htotal = ((chips->flat_panel_regs[0x23] | ((chips->flat_panel_regs[0x26] & 0xF) << 8)) + 5) << 3; //svga->hblank_end_val = svga->htotal - 1; + svga->hoverride = 1; } if (svga->dispend > (((chips->flat_panel_regs[0x30] | ((chips->flat_panel_regs[0x35] & 0xF) << 8)) + 1))) { svga->dispend = svga->vsyncstart = svga->vblankstart = ((chips->flat_panel_regs[0x30] | ((chips->flat_panel_regs[0x35] & 0xF) << 8)) + 1); @@ -828,7 +829,6 @@ chips_69000_recalctimings(svga_t *svga) //svga->vsyncstart = ((chips->flat_panel_regs[0x31] | ((chips->flat_panel_regs[0x35] & 0xF0) << 4)) + 1); //svga->vtotal = ((chips->flat_panel_regs[0x33] | ((chips->flat_panel_regs[0x36] & 0xF) << 8)) + 2); svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((chips->flat_panel_regs[0x03] >> 2) & 3, svga->priv); - svga->hoverride = 1; } else { svga->hoverride = 0; } From 575317fa085acdd0a86d5a6f7f9c5d517a4607ed Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 18 Feb 2024 02:52:29 +0600 Subject: [PATCH 533/936] ...and don't otherwise --- src/video/vid_chips_69000.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 6a15e3a62..0490523c9 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -818,7 +818,9 @@ chips_69000_recalctimings(svga_t *svga) //svga->htotal = ((chips->flat_panel_regs[0x23] | ((chips->flat_panel_regs[0x26] & 0xF) << 8)) + 5) << 3; //svga->hblank_end_val = svga->htotal - 1; svga->hoverride = 1; - } + } else + svga->hoverride = 0; + if (svga->dispend > (((chips->flat_panel_regs[0x30] | ((chips->flat_panel_regs[0x35] & 0xF) << 8)) + 1))) { svga->dispend = svga->vsyncstart = svga->vblankstart = ((chips->flat_panel_regs[0x30] | ((chips->flat_panel_regs[0x35] & 0xF) << 8)) + 1); } From 4adb484184b813868b52c27c242444aad68e381b Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 18 Feb 2024 12:23:21 +0600 Subject: [PATCH 534/936] C&T 69000: Fix ROP 0xFF `WHITENESS` on 16+ bpp modes Fixes blue background on Write in Windows 3.11 drivers --- src/video/vid_chips_69000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 0490523c9..9e5e74370 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -351,7 +351,7 @@ chips_69000_do_rop_16bpp(uint16_t *dst, uint16_t src, uint8_t rop) *dst |= src; break; case 0xFF: - *dst = 0xFF; + *dst = 0xFFFF; break; } } @@ -405,7 +405,7 @@ chips_69000_do_rop_24bpp(uint32_t *dst, uint32_t src, uint8_t rop) *dst |= src; break; case 0xFF: - *dst = 0xFF; + *dst = 0xFFFFFF; break; } } From 2928e2cf7928e364debbccbaf15b07fb8f110f12 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 18 Feb 2024 16:35:32 +0600 Subject: [PATCH 535/936] C&T 69000: Make sure horizontal blank period does not exceed horizontal total Fixes machine freezes in certain circumstances --- src/video/vid_chips_69000.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 9e5e74370..d35e66361 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -775,6 +775,9 @@ chips_69000_recalctimings(svga_t *svga) svga->hblank_end_val = ((svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00)) | (svga->crtc[0x3c] & 0b11000000); svga->hblank_end_mask = 0xff; + if (svga->hblank_end_val >= svga->htotal) + svga->hblank_end_val = svga->htotal - 1; + svga->ma_latch |= (svga->crtc[0x40] & 0xF) << 16; svga->rowoffset |= (svga->crtc[0x41] & 0xF) << 8; From 26dcf9cb7336744025a3dfaf3e9aea890e93f5a6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 18 Feb 2024 11:54:11 +0100 Subject: [PATCH 536/936] Make the horizontal blanking loops no longer loop eternally. --- src/video/vid_svga.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 0293ebeda..b298fc4e1 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -797,7 +797,7 @@ svga_recalctimings(svga_t *svga) svga_log("Blank: %04i-%04i, Total: %04i, Mask: %02X\n", svga->hblankstart, svga->hblank_end_val, svga->htotal, eff_mask); - while (1) { + while (adj_dot < (svga->htotal << 1)) { if (dot == svga->htotal) dot = 0; @@ -820,7 +820,7 @@ svga_recalctimings(svga_t *svga) uint32_t eff_mask8514 = 0x0000003f; dev->hblank_sub = 0; - while (1) { + while (adj_dot8514 < (dev->h_total << 1)) { if (dot8514 == dev->h_total) dot = 0; From a0b984f79cc8a6054ca7e15be0254abfda352562 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 18 Feb 2024 16:57:30 +0600 Subject: [PATCH 537/936] Revert no-longer-needed horizontal blanking changes --- src/video/vid_chips_69000.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index d35e66361..9e5e74370 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -775,9 +775,6 @@ chips_69000_recalctimings(svga_t *svga) svga->hblank_end_val = ((svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00)) | (svga->crtc[0x3c] & 0b11000000); svga->hblank_end_mask = 0xff; - if (svga->hblank_end_val >= svga->htotal) - svga->hblank_end_val = svga->htotal - 1; - svga->ma_latch |= (svga->crtc[0x40] & 0xF) << 16; svga->rowoffset |= (svga->crtc[0x41] & 0xF) << 8; From d789292f6566a5168e4fd5e22c0d14a3a1a50fcc Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 18 Feb 2024 16:37:46 +0500 Subject: [PATCH 538/936] Joystick: Remove the leftover separate slider handling --- src/include/86box/gameport.h | 8 -------- src/qt/qt_joystickconfiguration.cpp | 7 ------- src/qt/qt_settingsinput.cpp | 14 ++++---------- src/win/win_joystick.cpp | 19 ++++++++----------- src/win/win_jsconf.c | 19 ++++--------------- 5 files changed, 16 insertions(+), 51 deletions(-) diff --git a/src/include/86box/gameport.h b/src/include/86box/gameport.h index ba3568464..d6e6f980a 100644 --- a/src/include/86box/gameport.h +++ b/src/include/86box/gameport.h @@ -36,7 +36,6 @@ #define POV_X 0x80000000 #define POV_Y 0x40000000 -#define SLIDER 0x20000000 #define AXIS_NOT_PRESENT -99999 @@ -50,7 +49,6 @@ typedef struct plat_joystick_t { int a[8]; int b[32]; int p[4]; - int s[2]; struct { char name[260]; @@ -67,15 +65,9 @@ typedef struct plat_joystick_t { int id; } pov[4]; - struct { - char name[260]; - int id; - } slider[2]; - int nr_axes; int nr_buttons; int nr_povs; - int nr_sliders; } plat_joystick_t; typedef struct joystick_t { diff --git a/src/qt/qt_joystickconfiguration.cpp b/src/qt/qt_joystickconfiguration.cpp index c363cd544..e03d57e09 100644 --- a/src/qt/qt_joystickconfiguration.cpp +++ b/src/qt/qt_joystickconfiguration.cpp @@ -118,19 +118,12 @@ JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) Models::AddEntry(model, QString("%1 (Y axis)").arg(plat_joystick_state[joystick].pov[d].name), 0); } - for (int d = 0; d < plat_joystick_state[joystick].nr_sliders; d++) { - Models::AddEntry(model, plat_joystick_state[joystick].slider[d].name, 0); - } - int nr_axes = plat_joystick_state[joystick].nr_axes; - int nr_povs = plat_joystick_state[joystick].nr_povs; int mapping = joystick_state[joystick_nr].axis_mapping[c]; if (mapping & POV_X) cbox->setCurrentIndex(nr_axes + (mapping & 3) * 2); else if (mapping & POV_Y) cbox->setCurrentIndex(nr_axes + (mapping & 3) * 2 + 1); - else if (mapping & SLIDER) - cbox->setCurrentIndex(nr_axes + nr_povs * 2 + (mapping & 3)); else cbox->setCurrentIndex(mapping); diff --git a/src/qt/qt_settingsinput.cpp b/src/qt/qt_settingsinput.cpp index 34d111e10..05e44c2c0 100644 --- a/src/qt/qt_settingsinput.cpp +++ b/src/qt/qt_settingsinput.cpp @@ -137,22 +137,16 @@ get_axis(JoystickConfiguration &jc, int axis, int joystick_nr) { int axis_sel = jc.selectedAxis(axis); int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_axes; - int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs; if (axis_sel < nr_axes) { return axis_sel; } axis_sel -= nr_axes; - if (axis_sel < nr_povs * 2) { - if (axis_sel & 1) - return POV_Y | (axis_sel >> 1); - else - return POV_X | (axis_sel >> 1); - } - axis_sel -= nr_povs; - - return SLIDER | (axis_sel >> 1); + if (axis_sel & 1) + return POV_Y | (axis_sel >> 1); + else + return POV_X | (axis_sel >> 1); } static int diff --git a/src/win/win_joystick.cpp b/src/win/win_joystick.cpp index df8a99a05..17756ea94 100644 --- a/src/win/win_joystick.cpp +++ b/src/win/win_joystick.cpp @@ -36,6 +36,7 @@ plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; joystick_t joystick_state[MAX_JOYSTICKS]; int joysticks_present = 0; +int has_slider = 0; static LPDIRECTINPUT8 lpdi; static LPDIRECTINPUTDEVICE8 lpdi_joystick[2] = { NULL, NULL }; @@ -98,6 +99,10 @@ DIEnumDeviceObjectsCallback( state->axis[state->nr_axes].id = 4; else if (lpddoi->guidType == GUID_RzAxis) state->axis[state->nr_axes].id = 5; + else if (lpddoi->guidType == GUID_Slider) { + state->axis[state->nr_axes].id = 6 + has_slider; + has_slider++; + } state->nr_axes++; } } else if (lpddoi->guidType == GUID_Button) { @@ -112,13 +117,6 @@ DIEnumDeviceObjectsCallback( joystick_log("POV %i : %s %x %x\n", state->nr_povs, state->pov[state->nr_povs].name, lpddoi->dwOfs, lpddoi->dwType); state->nr_povs++; } - } else if (lpddoi->guidType == GUID_Slider) { - if (state->nr_sliders < 2) { - memcpy(state->slider[state->nr_sliders].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1); - state->slider[state->nr_sliders].id = state->nr_sliders | SLIDER; - joystick_log("Slider %i : %s %x %x\n", state->nr_sliders, state->slider[state->nr_sliders].name, lpddoi->dwOfs, lpddoi->dwType); - state->nr_sliders++; - } } return DIENUM_CONTINUE; @@ -170,6 +168,7 @@ joystick_init() joystick_log(" Buttons = %i\n", devcaps.dwButtons); joystick_log(" POVs = %i\n", devcaps.dwPOVs); + has_slider = 0; lpdi_joystick[c]->EnumObjects(DIEnumDeviceObjectsCallback, &plat_joystick_state[c], DIDFT_ALL); if (FAILED(lpdi_joystick[c]->SetCooperativeLevel(hwndMain, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) @@ -234,8 +233,6 @@ joystick_get_axis(int joystick_nr, int mapping) return 0; else return -cos((2 * M_PI * (double) pov) / 36000.0) * 32767; - } else if (mapping & SLIDER) { - return plat_joystick_state[joystick_nr].s[mapping & 3]; } else return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; } @@ -269,8 +266,8 @@ joystick_process(void) plat_joystick_state[c].a[3] = joystate.lRx; plat_joystick_state[c].a[4] = joystate.lRy; plat_joystick_state[c].a[5] = joystate.lRz; - plat_joystick_state[c].s[0] = joystate.rglSlider[0]; - plat_joystick_state[c].s[1] = joystate.rglSlider[1]; + plat_joystick_state[c].a[6] = joystate.rglSlider[0]; + plat_joystick_state[c].a[7] = joystate.rglSlider[1]; for (b = 0; b < 16; b++) plat_joystick_state[c].b[b] = joystate.rgbButtons[b] & 0x80; diff --git a/src/win/win_jsconf.c b/src/win/win_jsconf.c index 66ad60c73..416e7858d 100644 --- a/src/win/win_jsconf.c +++ b/src/win/win_jsconf.c @@ -54,9 +54,6 @@ rebuild_axis_button_selections(HWND hdlg) sprintf(s, "%s (Y axis)", plat_joystick_state[joystick - 1].pov[d].name); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) s); } - for (d = 0; d < plat_joystick_state[joystick - 1].nr_sliders; d++) { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) plat_joystick_state[joystick - 1].slider[d].name); - } SendMessage(h, CB_SETCURSEL, sel, 0); EnableWindow(h, TRUE); } else @@ -111,21 +108,15 @@ get_axis(HWND hdlg, int id) HWND h = GetDlgItem(hdlg, id); int axis_sel = SendMessage(h, CB_GETCURSEL, 0, 0); int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_axes; - int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs; if (axis_sel < nr_axes) return axis_sel; axis_sel -= nr_axes; - if (axis_sel < nr_povs * 2) { - if (axis_sel & 1) - return POV_Y | (axis_sel >> 1); - else - return POV_X | (axis_sel >> 1); - } - axis_sel -= nr_povs; - - return SLIDER | (axis_sel >> 1); + if (axis_sel & 1) + return POV_Y | (axis_sel >> 1); + else + return POV_X | (axis_sel >> 1); } static int @@ -188,8 +179,6 @@ joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lPa SendMessage(h, CB_SETCURSEL, nr_axes + (mapping & 3) * 2, 0); else if (mapping & POV_Y) SendMessage(h, CB_SETCURSEL, nr_axes + (mapping & 3) * 2 + 1, 0); - else if (mapping & SLIDER) - SendMessage(h, CB_SETCURSEL, nr_axes + nr_povs * 2 + (mapping & 3), 0); else SendMessage(h, CB_SETCURSEL, mapping, 0); id += 2; From 394e07899105b4d8bd78769dc6b02c42c21e254f Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 18 Feb 2024 16:38:49 +0500 Subject: [PATCH 539/936] Joystick: Add support for more axis types to the Windows raw input backend --- src/qt/win_joystick_rawinput.c | 85 +++++++++++++++++++++++++++++---- src/win/win_joystick_rawinput.c | 63 +++++++++++++++++++++++- 2 files changed, 137 insertions(+), 11 deletions(-) diff --git a/src/qt/win_joystick_rawinput.c b/src/qt/win_joystick_rawinput.c index 7ee0e8227..1a419c3ba 100644 --- a/src/qt/win_joystick_rawinput.c +++ b/src/qt/win_joystick_rawinput.c @@ -35,6 +35,29 @@ #include <86box/gameport.h> #include <86box/win.h> +/* These are defined in hidusage.h in the Windows SDK, but not in mingw-w64. */ +#ifndef HID_USAGE_SIMULATION_AILERON +# define HID_USAGE_SIMULATION_AILERON ((USAGE) 0xb0) +#endif +#ifndef HID_USAGE_SIMULATION_ELEVATOR +# define HID_USAGE_SIMULATION_ELEVATOR ((USAGE) 0xb8) +#endif +#ifndef HID_USAGE_SIMULATION_ACCELLERATOR +# define HID_USAGE_SIMULATION_ACCELLERATOR ((USAGE) 0xc4) +#endif +#ifndef HID_USAGE_SIMULATION_BRAKE +# define HID_USAGE_SIMULATION_BRAKE ((USAGE) 0xc5) +#endif +#ifndef HID_USAGE_SIMULATION_CLUTCH +# define HID_USAGE_SIMULATION_CLUTCH ((USAGE) 0xc6) +#endif +#ifndef HID_USAGE_SIMULATION_SHIFTER +# define HID_USAGE_SIMULATION_SHIFTER ((USAGE) 0xc7) +#endif +#ifndef HID_USAGE_SIMULATION_STEERING +# define HID_USAGE_SIMULATION_STEERING ((USAGE) 0xc8) +#endif + #ifdef ENABLE_JOYSTICK_LOG int joystick_do_log = ENABLE_JOYSTICK_LOG; @@ -120,6 +143,42 @@ joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS case HID_USAGE_GENERIC_RZ: sprintf(joy->axis[joy->nr_axes].name, "RZ"); break; + case HID_USAGE_GENERIC_SLIDER: + sprintf(joy->axis[joy->nr_axes].name, "Slider"); + break; + case HID_USAGE_GENERIC_DIAL: + sprintf(joy->axis[joy->nr_axes].name, "Dial"); + break; + case HID_USAGE_GENERIC_WHEEL: + sprintf(joy->axis[joy->nr_axes].name, "Wheel"); + break; + case HID_USAGE_SIMULATION_AILERON: + sprintf(joy->axis[joy->nr_axes].name, "Aileron"); + break; + case HID_USAGE_SIMULATION_ELEVATOR: + sprintf(joy->axis[joy->nr_axes].name, "Elevator"); + break; + case HID_USAGE_SIMULATION_RUDDER: + sprintf(joy->axis[joy->nr_axes].name, "Rudder"); + break; + case HID_USAGE_SIMULATION_THROTTLE: + sprintf(joy->axis[joy->nr_axes].name, "Throttle"); + break; + case HID_USAGE_SIMULATION_ACCELLERATOR: + sprintf(joy->axis[joy->nr_axes].name, "Accelerator"); + break; + case HID_USAGE_SIMULATION_BRAKE: + sprintf(joy->axis[joy->nr_axes].name, "Brake"); + break; + case HID_USAGE_SIMULATION_CLUTCH: + sprintf(joy->axis[joy->nr_axes].name, "Clutch"); + break; + case HID_USAGE_SIMULATION_SHIFTER: + sprintf(joy->axis[joy->nr_axes].name, "Shifter"); + break; + case HID_USAGE_SIMULATION_STEERING: + sprintf(joy->axis[joy->nr_axes].name, "Steering"); + break; default: return; } @@ -367,10 +426,10 @@ win_joystick_handle(PRAWINPUT raw) /* Read axes */ for (int a = 0; a < plat_joystick_state[j].nr_axes; a++) { - struct raw_axis_t *axis = &raw_joystick_state[j].axis[a]; - ULONG uvalue = 0; - LONG value = 0; - LONG center = (axis->max - axis->min + 1) / 2; + const struct raw_axis_t *axis = &raw_joystick_state[j].axis[a]; + ULONG uvalue = 0; + LONG value = 0; + LONG center = (axis->max - axis->min + 1) / 2; r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, axis->link, axis->usage, &uvalue, raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid); @@ -395,14 +454,16 @@ win_joystick_handle(PRAWINPUT raw) } plat_joystick_state[j].a[a] = value; - // joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]); +#if 0 + joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]); +#endif } /* read povs */ for (int p = 0; p < plat_joystick_state[j].nr_povs; p++) { - struct raw_pov_t *pov = &raw_joystick_state[j].pov[p]; - ULONG uvalue = 0; - LONG value = -1; + const struct raw_pov_t *pov = &raw_joystick_state[j].pov[p]; + ULONG uvalue = 0; + LONG value = -1; r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, pov->link, pov->usage, &uvalue, raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid); @@ -415,9 +476,13 @@ win_joystick_handle(PRAWINPUT raw) plat_joystick_state[j].p[p] = value; - // joystick_log("%s %-3d ", plat_joystick_state[j].pov[p].name, plat_joystick_state[j].p[p]); +#if 0 + joystick_log("%s %-3d ", plat_joystick_state[j].pov[p].name, plat_joystick_state[j].p[p]); +#endif } - // joystick_log("\n"); +#if 0 + joystick_log("\n"); +#endif } static int diff --git a/src/win/win_joystick_rawinput.c b/src/win/win_joystick_rawinput.c index c5c2a3d6e..1a419c3ba 100644 --- a/src/win/win_joystick_rawinput.c +++ b/src/win/win_joystick_rawinput.c @@ -35,6 +35,29 @@ #include <86box/gameport.h> #include <86box/win.h> +/* These are defined in hidusage.h in the Windows SDK, but not in mingw-w64. */ +#ifndef HID_USAGE_SIMULATION_AILERON +# define HID_USAGE_SIMULATION_AILERON ((USAGE) 0xb0) +#endif +#ifndef HID_USAGE_SIMULATION_ELEVATOR +# define HID_USAGE_SIMULATION_ELEVATOR ((USAGE) 0xb8) +#endif +#ifndef HID_USAGE_SIMULATION_ACCELLERATOR +# define HID_USAGE_SIMULATION_ACCELLERATOR ((USAGE) 0xc4) +#endif +#ifndef HID_USAGE_SIMULATION_BRAKE +# define HID_USAGE_SIMULATION_BRAKE ((USAGE) 0xc5) +#endif +#ifndef HID_USAGE_SIMULATION_CLUTCH +# define HID_USAGE_SIMULATION_CLUTCH ((USAGE) 0xc6) +#endif +#ifndef HID_USAGE_SIMULATION_SHIFTER +# define HID_USAGE_SIMULATION_SHIFTER ((USAGE) 0xc7) +#endif +#ifndef HID_USAGE_SIMULATION_STEERING +# define HID_USAGE_SIMULATION_STEERING ((USAGE) 0xc8) +#endif + #ifdef ENABLE_JOYSTICK_LOG int joystick_do_log = ENABLE_JOYSTICK_LOG; @@ -120,6 +143,42 @@ joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS case HID_USAGE_GENERIC_RZ: sprintf(joy->axis[joy->nr_axes].name, "RZ"); break; + case HID_USAGE_GENERIC_SLIDER: + sprintf(joy->axis[joy->nr_axes].name, "Slider"); + break; + case HID_USAGE_GENERIC_DIAL: + sprintf(joy->axis[joy->nr_axes].name, "Dial"); + break; + case HID_USAGE_GENERIC_WHEEL: + sprintf(joy->axis[joy->nr_axes].name, "Wheel"); + break; + case HID_USAGE_SIMULATION_AILERON: + sprintf(joy->axis[joy->nr_axes].name, "Aileron"); + break; + case HID_USAGE_SIMULATION_ELEVATOR: + sprintf(joy->axis[joy->nr_axes].name, "Elevator"); + break; + case HID_USAGE_SIMULATION_RUDDER: + sprintf(joy->axis[joy->nr_axes].name, "Rudder"); + break; + case HID_USAGE_SIMULATION_THROTTLE: + sprintf(joy->axis[joy->nr_axes].name, "Throttle"); + break; + case HID_USAGE_SIMULATION_ACCELLERATOR: + sprintf(joy->axis[joy->nr_axes].name, "Accelerator"); + break; + case HID_USAGE_SIMULATION_BRAKE: + sprintf(joy->axis[joy->nr_axes].name, "Brake"); + break; + case HID_USAGE_SIMULATION_CLUTCH: + sprintf(joy->axis[joy->nr_axes].name, "Clutch"); + break; + case HID_USAGE_SIMULATION_SHIFTER: + sprintf(joy->axis[joy->nr_axes].name, "Shifter"); + break; + case HID_USAGE_SIMULATION_STEERING: + sprintf(joy->axis[joy->nr_axes].name, "Steering"); + break; default: return; } @@ -395,7 +454,9 @@ win_joystick_handle(PRAWINPUT raw) } plat_joystick_state[j].a[a] = value; - // joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]); +#if 0 + joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]); +#endif } /* read povs */ From e51f99c800dd8c3fe844d32b6421036bc78f858d Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 18 Feb 2024 17:08:26 +0500 Subject: [PATCH 540/936] Joystick: Replace magic numbers for maximum axes/buttons/POVs with macros --- src/include/86box/gameport.h | 34 ++++++++++++++++++--------------- src/qt/win_joystick_rawinput.c | 10 +++++----- src/win/win_joystick.cpp | 10 +++++----- src/win/win_joystick_rawinput.c | 10 +++++----- 4 files changed, 34 insertions(+), 30 deletions(-) diff --git a/src/include/86box/gameport.h b/src/include/86box/gameport.h index d6e6f980a..0fb4a0f36 100644 --- a/src/include/86box/gameport.h +++ b/src/include/86box/gameport.h @@ -24,6 +24,10 @@ #define MAX_PLAT_JOYSTICKS 8 #define MAX_JOYSTICKS 4 +#define MAX_JOY_AXES 8 +#define MAX_JOY_BUTTONS 32 +#define MAX_JOY_POVS 4 + #define JS_TYPE_NONE 0 #define JS_TYPE_2AXIS_4BUTTON 1 #define JS_TYPE_2AXIS_6BUTTON 2 @@ -46,24 +50,24 @@ typedef struct plat_joystick_t { char name[260]; - int a[8]; - int b[32]; - int p[4]; + int a[MAX_JOY_AXES]; + int b[MAX_JOY_BUTTONS]; + int p[MAX_JOY_POVS]; struct { char name[260]; int id; - } axis[8]; + } axis[MAX_JOY_AXES]; struct { char name[260]; int id; - } button[32]; + } button[MAX_JOY_BUTTONS]; struct { char name[260]; int id; - } pov[4]; + } pov[MAX_JOY_POVS]; int nr_axes; int nr_buttons; @@ -71,14 +75,14 @@ typedef struct plat_joystick_t { } plat_joystick_t; typedef struct joystick_t { - int axis[8]; - int button[32]; - int pov[4]; + int axis[MAX_JOY_AXES]; + int button[MAX_JOY_BUTTONS]; + int pov[MAX_JOY_POVS]; int plat_joystick_nr; - int axis_mapping[8]; - int button_mapping[32]; - int pov_mapping[4][2]; + int axis_mapping[MAX_JOY_AXES]; + int button_mapping[MAX_JOY_BUTTONS]; + int pov_mapping[MAX_JOY_POVS][2]; } joystick_t; typedef struct joystick_if_t { @@ -96,9 +100,9 @@ typedef struct joystick_if_t { int button_count; int pov_count; int max_joysticks; - const char *axis_names[8]; - const char *button_names[32]; - const char *pov_names[4]; + const char *axis_names[MAX_JOY_AXES]; + const char *button_names[MAX_JOY_BUTTONS]; + const char *pov_names[MAX_JOY_POVS]; } joystick_if_t; #ifdef __cplusplus diff --git a/src/qt/win_joystick_rawinput.c b/src/qt/win_joystick_rawinput.c index 1a419c3ba..bb05c3f5c 100644 --- a/src/qt/win_joystick_rawinput.c +++ b/src/qt/win_joystick_rawinput.c @@ -88,14 +88,14 @@ typedef struct { USHORT bitsize; LONG max; LONG min; - } axis[8]; + } axis[MAX_JOY_AXES]; struct raw_pov_t { USAGE usage; USHORT link; LONG max; LONG min; - } pov[4]; + } pov[MAX_JOY_POVS]; } raw_joystick_t; plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; @@ -108,7 +108,7 @@ raw_joystick_t raw_joystick_state[MAX_PLAT_JOYSTICKS]; void joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage) { - if (joy->nr_buttons >= 32) + if (joy->nr_buttons >= MAX_JOY_BUTTONS) return; if (usage < 1 || usage > 128) return; @@ -121,7 +121,7 @@ joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage) void joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop) { - if (joy->nr_axes >= 8) + if (joy->nr_axes >= MAX_JOY_AXES) return; switch (prop->Range.UsageMin) { @@ -206,7 +206,7 @@ joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS void joystick_add_pov(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop) { - if (joy->nr_povs >= 4) + if (joy->nr_povs >= MAX_JOY_POVS) return; sprintf(joy->pov[joy->nr_povs].name, "POV %d", joy->nr_povs + 1); diff --git a/src/win/win_joystick.cpp b/src/win/win_joystick.cpp index 17756ea94..9b264a700 100644 --- a/src/win/win_joystick.cpp +++ b/src/win/win_joystick.cpp @@ -84,7 +84,7 @@ DIEnumDeviceObjectsCallback( plat_joystick_t *state = (plat_joystick_t *) pvRef; if (lpddoi->guidType == GUID_XAxis || lpddoi->guidType == GUID_YAxis || lpddoi->guidType == GUID_ZAxis || lpddoi->guidType == GUID_RxAxis || lpddoi->guidType == GUID_RyAxis || lpddoi->guidType == GUID_RzAxis) { - if (state->nr_axes < 8) { + if (state->nr_axes < MAX_JOY_AXES) { memcpy(state->axis[state->nr_axes].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1); joystick_log("Axis %i : %s %x %x\n", state->nr_axes, state->axis[state->nr_axes].name, lpddoi->dwOfs, lpddoi->dwType); if (lpddoi->guidType == GUID_XAxis) @@ -106,13 +106,13 @@ DIEnumDeviceObjectsCallback( state->nr_axes++; } } else if (lpddoi->guidType == GUID_Button) { - if (state->nr_buttons < 32) { + if (state->nr_buttons < MAX_JOY_BUTTONS) { memcpy(state->button[state->nr_buttons].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1); joystick_log("Button %i : %s %x %x\n", state->nr_buttons, state->button[state->nr_buttons].name, lpddoi->dwOfs, lpddoi->dwType); state->nr_buttons++; } } else if (lpddoi->guidType == GUID_POV) { - if (state->nr_povs < 4) { + if (state->nr_povs < MAX_JOY_POVS) { memcpy(state->pov[state->nr_povs].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1); joystick_log("POV %i : %s %x %x\n", state->nr_povs, state->pov[state->nr_povs].name, lpddoi->dwOfs, lpddoi->dwType); state->nr_povs++; @@ -269,10 +269,10 @@ joystick_process(void) plat_joystick_state[c].a[6] = joystate.rglSlider[0]; plat_joystick_state[c].a[7] = joystate.rglSlider[1]; - for (b = 0; b < 16; b++) + for (b = 0; b < MAX_JOY_BUTTONS; b++) plat_joystick_state[c].b[b] = joystate.rgbButtons[b] & 0x80; - for (b = 0; b < 4; b++) + for (b = 0; b < MAX_JOY_POVS; b++) plat_joystick_state[c].p[b] = joystate.rgdwPOV[b]; // joystick_log("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", c, joystick_state[c].x, joystick_state[c].y, joystick_state[c].b[0], joystick_state[c].b[1], joysticks_present); } diff --git a/src/win/win_joystick_rawinput.c b/src/win/win_joystick_rawinput.c index 1a419c3ba..bb05c3f5c 100644 --- a/src/win/win_joystick_rawinput.c +++ b/src/win/win_joystick_rawinput.c @@ -88,14 +88,14 @@ typedef struct { USHORT bitsize; LONG max; LONG min; - } axis[8]; + } axis[MAX_JOY_AXES]; struct raw_pov_t { USAGE usage; USHORT link; LONG max; LONG min; - } pov[4]; + } pov[MAX_JOY_POVS]; } raw_joystick_t; plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; @@ -108,7 +108,7 @@ raw_joystick_t raw_joystick_state[MAX_PLAT_JOYSTICKS]; void joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage) { - if (joy->nr_buttons >= 32) + if (joy->nr_buttons >= MAX_JOY_BUTTONS) return; if (usage < 1 || usage > 128) return; @@ -121,7 +121,7 @@ joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage) void joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop) { - if (joy->nr_axes >= 8) + if (joy->nr_axes >= MAX_JOY_AXES) return; switch (prop->Range.UsageMin) { @@ -206,7 +206,7 @@ joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS void joystick_add_pov(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop) { - if (joy->nr_povs >= 4) + if (joy->nr_povs >= MAX_JOY_POVS) return; sprintf(joy->pov[joy->nr_povs].name, "POV %d", joy->nr_povs + 1); From 0fa364dec34dbbf9223fd8aeab66993f62842fbc Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 18 Feb 2024 19:12:57 +0500 Subject: [PATCH 541/936] MGA cleanup --- CMakeLists.txt | 1 - src/video/CMakeLists.txt | 4 ---- src/video/vid_mga.c | 2 -- src/win/Makefile.mingw | 10 ---------- 4 files changed, 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f13e91791..196952cb4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -153,7 +153,6 @@ cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF) cmake_dependent_option(LASERXT "VTech Laser XT" ON "DEV_BRANCH" OFF) -cmake_dependent_option(MGA2 "Matrox Millennium II and Productiva G100" ON "DEV_BRANCH" OFF) cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF) diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index dc0cac1ff..8fbd62e35 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -28,10 +28,6 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_mga.c vid_nga.c vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c) -if(MGA2) - target_compile_definitions(vid PRIVATE USE_MGA2) -endif() - if(VGAWONDER) target_compile_definitions(vid PRIVATE USE_VGAWONDER) endif() diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 89b036ede..b85eb5ad9 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -2811,7 +2811,6 @@ static uint8_t mystique_readb_linear(uint32_t addr, void *priv) { const svga_t *svga = (svga_t *) priv; - mystique_t *mystique = (mystique_t *) svga->priv; cycles -= svga->monitor->mon_video_timing_read_b; @@ -2861,7 +2860,6 @@ static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv) { svga_t *svga = (svga_t *) priv; - mystique_t *mystique = (mystique_t *) svga->priv; cycles -= svga->monitor->mon_video_timing_write_b; diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 94b8af74a..a80458938 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -64,9 +64,6 @@ ifeq ($(DEV_BUILD), y) ifndef LASERXT LASERXT := y endif - ifndef MGA2 - MGA2 := y - endif ifndef OLIVETTI OLIVETTI := y endif @@ -131,9 +128,6 @@ else ifndef LASERXT LASERXT := n endif - ifndef MGA2 - MGA2 := n - endif ifndef OLIVETTI OLIVETTI := n endif @@ -502,10 +496,6 @@ ifeq ($(DEV_BRANCH), y) DEVBROBJ += m_xt_laserxt.o endif - ifeq ($(MGA2), y) - OPTS += -DUSE_MGA2 - endif - ifeq ($(OPEN_AT), y) OPTS += -DUSE_OPEN_AT endif From f13cf419950deadd1e8dfd8b7d5931ee0f84f630 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 18 Feb 2024 17:26:28 +0500 Subject: [PATCH 542/936] Joystick: Properly limit maximum axes/buttons/POVs in the SDL backend Axes beyond 6 are now actually working --- src/qt/sdl_joystick.cpp | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/qt/sdl_joystick.cpp b/src/qt/sdl_joystick.cpp index cdbf102b8..4437bb696 100644 --- a/src/qt/sdl_joystick.cpp +++ b/src/qt/sdl_joystick.cpp @@ -36,19 +36,19 @@ joystick_init() int d; strncpy(plat_joystick_state[c].name, SDL_JoystickNameForIndex(c), 64); - plat_joystick_state[c].nr_axes = SDL_JoystickNumAxes(sdl_joy[c]); - plat_joystick_state[c].nr_buttons = SDL_JoystickNumButtons(sdl_joy[c]); - plat_joystick_state[c].nr_povs = SDL_JoystickNumHats(sdl_joy[c]); + plat_joystick_state[c].nr_axes = std::min(SDL_JoystickNumAxes(sdl_joy[c]), MAX_JOY_AXES); + plat_joystick_state[c].nr_buttons = std::min(SDL_JoystickNumButtons(sdl_joy[c]), MAX_JOY_BUTTONS); + plat_joystick_state[c].nr_povs = std::min(SDL_JoystickNumHats(sdl_joy[c]), MAX_JOY_POVS); - for (d = 0; d < std::min(plat_joystick_state[c].nr_axes, 8); d++) { + for (d = 0; d < plat_joystick_state[c].nr_axes; d++) { snprintf(plat_joystick_state[c].axis[d].name, sizeof(plat_joystick_state[c].axis[d].name), "Axis %i", d); plat_joystick_state[c].axis[d].id = d; } - for (d = 0; d < std::min(plat_joystick_state[c].nr_buttons, 8); d++) { + for (d = 0; d < plat_joystick_state[c].nr_buttons; d++) { snprintf(plat_joystick_state[c].button[d].name, sizeof(plat_joystick_state[c].button[d].name), "Button %i", d); plat_joystick_state[c].button[d].id = d; } - for (d = 0; d < std::min(plat_joystick_state[c].nr_povs, 4); d++) { + for (d = 0; d < plat_joystick_state[c].nr_povs; d++) { snprintf(plat_joystick_state[c].pov[d].name, sizeof(plat_joystick_state[c].pov[d].name), "POV %i", d); plat_joystick_state[c].pov[d].id = d; } @@ -116,17 +116,13 @@ joystick_process() for (c = 0; c < joysticks_present; c++) { int b; - plat_joystick_state[c].a[0] = SDL_JoystickGetAxis(sdl_joy[c], 0); - plat_joystick_state[c].a[1] = SDL_JoystickGetAxis(sdl_joy[c], 1); - plat_joystick_state[c].a[2] = SDL_JoystickGetAxis(sdl_joy[c], 2); - plat_joystick_state[c].a[3] = SDL_JoystickGetAxis(sdl_joy[c], 3); - plat_joystick_state[c].a[4] = SDL_JoystickGetAxis(sdl_joy[c], 4); - plat_joystick_state[c].a[5] = SDL_JoystickGetAxis(sdl_joy[c], 5); + for (b = 0; b < plat_joystick_state[c].nr_axes; b++) + plat_joystick_state[c].a[b] = SDL_JoystickGetAxis(sdl_joy[c], b); - for (b = 0; b < 16; b++) + for (b = 0; b < plat_joystick_state[c].nr_buttons; b++) plat_joystick_state[c].b[b] = SDL_JoystickGetButton(sdl_joy[c], b); - for (b = 0; b < 4; b++) + for (b = 0; b < plat_joystick_state[c].nr_povs; b++) plat_joystick_state[c].p[b] = SDL_JoystickGetHat(sdl_joy[c], b); // pclog("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", c, joystick_state[c].x, joystick_state[c].y, joystick_state[c].b[0], joystick_state[c].b[1], joysticks_present); } From c74ad5b4da570e95762cd47e122d7da0449cfc31 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 18 Feb 2024 17:34:40 +0500 Subject: [PATCH 543/936] Joystick: Increase the maximum number of supported axes to 16 --- src/include/86box/gameport.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/86box/gameport.h b/src/include/86box/gameport.h index 0fb4a0f36..48d639cf0 100644 --- a/src/include/86box/gameport.h +++ b/src/include/86box/gameport.h @@ -24,7 +24,7 @@ #define MAX_PLAT_JOYSTICKS 8 #define MAX_JOYSTICKS 4 -#define MAX_JOY_AXES 8 +#define MAX_JOY_AXES 16 #define MAX_JOY_BUTTONS 32 #define MAX_JOY_POVS 4 From 643979c0b7f8133c2d5e89f68c69fb30148e9caf Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 18 Feb 2024 17:28:29 +0500 Subject: [PATCH 544/936] Merge joystick_*.h into gameport.h Just like it was done to all headers with only device declarations years ago --- src/game/gameport.c | 4 -- src/game/joystick_ch_flightstick_pro.c | 1 - src/game/joystick_standard.c | 1 - src/game/joystick_sw_pad.c | 1 - src/game/joystick_tm_fcs.c | 1 - src/include/86box/gameport.h | 13 +++++ .../86box/joystick_ch_flightstick_pro.h | 43 ---------------- src/include/86box/joystick_standard.h | 49 ------------------- src/include/86box/joystick_sw_pad.h | 43 ---------------- src/include/86box/joystick_tm_fcs.h | 43 ---------------- 10 files changed, 13 insertions(+), 186 deletions(-) delete mode 100644 src/include/86box/joystick_ch_flightstick_pro.h delete mode 100644 src/include/86box/joystick_standard.h delete mode 100644 src/include/86box/joystick_sw_pad.h delete mode 100644 src/include/86box/joystick_tm_fcs.h diff --git a/src/game/gameport.c b/src/game/gameport.c index 323555984..58d9a446f 100644 --- a/src/game/gameport.c +++ b/src/game/gameport.c @@ -31,10 +31,6 @@ #include <86box/timer.h> #include <86box/isapnp.h> #include <86box/gameport.h> -#include <86box/joystick_ch_flightstick_pro.h> -#include <86box/joystick_standard.h> -#include <86box/joystick_sw_pad.h> -#include <86box/joystick_tm_fcs.h> #include <86box/plat_unused.h> typedef struct g_axis_t { diff --git a/src/game/joystick_ch_flightstick_pro.c b/src/game/joystick_ch_flightstick_pro.c index 49ce824bc..8ca51d531 100644 --- a/src/game/joystick_ch_flightstick_pro.c +++ b/src/game/joystick_ch_flightstick_pro.c @@ -43,7 +43,6 @@ #include <86box/device.h> #include <86box/timer.h> #include <86box/gameport.h> -#include <86box/joystick_standard.h> #include <86box/plat_unused.h> static void * diff --git a/src/game/joystick_standard.c b/src/game/joystick_standard.c index b9c449f99..1d1568738 100644 --- a/src/game/joystick_standard.c +++ b/src/game/joystick_standard.c @@ -43,7 +43,6 @@ #include <86box/device.h> #include <86box/timer.h> #include <86box/gameport.h> -#include <86box/joystick_standard.h> #include <86box/plat_unused.h> static void * diff --git a/src/game/joystick_sw_pad.c b/src/game/joystick_sw_pad.c index 5c91ee1e9..7962c38e3 100644 --- a/src/game/joystick_sw_pad.c +++ b/src/game/joystick_sw_pad.c @@ -64,7 +64,6 @@ #include <86box/device.h> #include <86box/timer.h> #include <86box/gameport.h> -#include <86box/joystick_sw_pad.h> #include <86box/plat_unused.h> typedef struct sw_data { diff --git a/src/game/joystick_tm_fcs.c b/src/game/joystick_tm_fcs.c index d54d0e37d..f5c1e64e6 100644 --- a/src/game/joystick_tm_fcs.c +++ b/src/game/joystick_tm_fcs.c @@ -43,7 +43,6 @@ #include <86box/device.h> #include <86box/timer.h> #include <86box/gameport.h> -#include <86box/joystick_standard.h> #include <86box/plat_unused.h> static void * diff --git a/src/include/86box/gameport.h b/src/include/86box/gameport.h index 48d639cf0..d9c702394 100644 --- a/src/include/86box/gameport.h +++ b/src/include/86box/gameport.h @@ -154,6 +154,19 @@ extern void gameport_update_joystick_type(void); extern void gameport_remap(void *priv, uint16_t address); extern void *gameport_add(const device_t *gameport_type); +extern const joystick_if_t joystick_2axis_2button; +extern const joystick_if_t joystick_2axis_4button; +extern const joystick_if_t joystick_3axis_2button; +extern const joystick_if_t joystick_3axis_4button; +extern const joystick_if_t joystick_4axis_4button; +extern const joystick_if_t joystick_2axis_6button; +extern const joystick_if_t joystick_2axis_8button; + +extern const joystick_if_t joystick_ch_flightstick_pro; + +extern const joystick_if_t joystick_sw_pad; + +extern const joystick_if_t joystick_tm_fcs; #ifdef __cplusplus } #endif diff --git a/src/include/86box/joystick_ch_flightstick_pro.h b/src/include/86box/joystick_ch_flightstick_pro.h deleted file mode 100644 index b49800ecb..000000000 --- a/src/include/86box/joystick_ch_flightstick_pro.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Definitions for the Flight Stick Pro driver. - * - * - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ - -#ifndef EMU_JOYSTICK_CH_FLIGHTSTICK_PRO_H -#define EMU_JOYSTICK_CH_FLIGHTSTICK_PRO_H - -extern const joystick_if_t joystick_ch_flightstick_pro; - -#endif /*EMU_JOYSTICK_CH_FLIGHTSTICK_PRO_H*/ diff --git a/src/include/86box/joystick_standard.h b/src/include/86box/joystick_standard.h deleted file mode 100644 index c874677ea..000000000 --- a/src/include/86box/joystick_standard.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Definitions for the joystick driver. - * - * - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ - -#ifndef EMU_JOYSTICK_STANDARD_H -#define EMU_JOYSTICK_STANDARD_H - -extern const joystick_if_t joystick_2axis_2button; -extern const joystick_if_t joystick_2axis_4button; -extern const joystick_if_t joystick_3axis_2button; -extern const joystick_if_t joystick_3axis_4button; -extern const joystick_if_t joystick_4axis_4button; -extern const joystick_if_t joystick_2axis_6button; -extern const joystick_if_t joystick_2axis_8button; - -#endif /*EMU_JOYSTICK_STANDARD_H*/ diff --git a/src/include/86box/joystick_sw_pad.h b/src/include/86box/joystick_sw_pad.h deleted file mode 100644 index a75d802de..000000000 --- a/src/include/86box/joystick_sw_pad.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Definitions for the Sidewinder Pro driver. - * - * - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ - -#ifndef EMU_JOYSTICK_SW_PAD_H -#define EMU_JOYSTICK_SW_PAD_H - -extern const joystick_if_t joystick_sw_pad; - -#endif /*EMU_JOYSTICK_SW_PAD_H*/ diff --git a/src/include/86box/joystick_tm_fcs.h b/src/include/86box/joystick_tm_fcs.h deleted file mode 100644 index 65e734a40..000000000 --- a/src/include/86box/joystick_tm_fcs.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Definitions for the Flight Control System driver. - * - * - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ - -#ifndef EMU_JOYSTICK_TM_FCS_H -#define EMU_JOYSTICK_TM_FCS_H - -extern const joystick_if_t joystick_tm_fcs; - -#endif /*EMU_JOYSTICK_TM_FCS_H*/ From 4c3cceec693ea1ac38e667e3d47530ee2522e05c Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 18 Feb 2024 17:54:14 +0100 Subject: [PATCH 545/936] Fixed off by one errors in (S)VGA horizontal blanking start calculation. --- src/video/vid_8514a.c | 2 +- src/video/vid_ati28800.c | 5 ++--- src/video/vid_ati_mach64.c | 2 +- src/video/vid_ati_mach8.c | 4 ++-- src/video/vid_chips_69000.c | 6 +++--- src/video/vid_cl54xx.c | 4 ++-- src/video/vid_et4000.c | 8 +++----- src/video/vid_et4000w32.c | 2 +- src/video/vid_ht216.c | 2 +- src/video/vid_mga.c | 2 +- src/video/vid_s3.c | 8 ++++---- src/video/vid_s3_virge.c | 4 ++-- src/video/vid_svga.c | 2 +- src/video/vid_voodoo_banshee.c | 11 ++++------- 14 files changed, 28 insertions(+), 34 deletions(-) diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 3505d1e0b..a94b974b0 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -914,7 +914,7 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) if (!(port & 1)) { if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { dev->hsync_start = val; - dev->hblankstart = (dev->hsync_start & 0x07) + 1; + dev->hblankstart = (dev->hsync_start & 0x07); } } ibm8514_log("IBM 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index be9654aca..368312fcb 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -408,7 +408,7 @@ ati28800_recalctimings(svga_t *svga) int clock_sel; if (ati28800->regs[0xad] & 0x08) - svga->hblankstart = ((ati28800->regs[0x0d] >> 2) << 8) + svga->crtc[2] + 1; + svga->hblankstart = ((ati28800->regs[0x0d] >> 2) << 8) + svga->crtc[2]; clock_sel = ((svga->miscout >> 2) & 3) | ((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1); @@ -492,8 +492,7 @@ ati28800_recalctimings(svga_t *svga) else { svga->render = svga_render_15bpp_highres; svga->hdisp >>= 1; - svga->hblankstart = ((svga->hblankstart - 1) >> 1) + 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; svga->rowoffset <<= 1; svga->ma_latch <<= 1; } diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index cdd906067..9aa396383 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -516,7 +516,7 @@ mach64_recalctimings(svga_t *svga) svga->htotal = (mach64->crtc_h_total_disp & 255) + 1; svga->hdisp_time = svga->hdisp = ((mach64->crtc_h_total_disp >> 16) & 255) + 1; svga->hblankstart = (mach64->crtc_h_sync_strt_wid & 255) + - ((mach64->crtc_h_sync_strt_wid >> 8) & 7) + 1; + ((mach64->crtc_h_sync_strt_wid >> 8) & 7); svga->hblank_end_val = (svga->hblankstart + ((mach64->crtc_h_sync_strt_wid >> 16) & 31) - 1) & 63; svga->vsyncstart = (mach64->crtc_v_sync_strt_wid & 2047) + 1; diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 5628e149a..b49806177 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2547,7 +2547,7 @@ mach_recalctimings(svga_t *svga) int clock_sel; if (mach->regs[0xad] & 0x08) - svga->hblankstart = ((mach->regs[0x0d] >> 2) << 8) + svga->crtc[2] + 1; + svga->hblankstart = ((mach->regs[0x0d] >> 2) << 8) + svga->crtc[2]; clock_sel = ((svga->miscout >> 2) & 3) | ((mach->regs[0xbe] & 0x10) >> 1) | ((mach->regs[0xb9] & 2) << 1); @@ -3636,7 +3636,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 if (!(port & 1)) { if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { dev->hsync_start = val; - dev->hblankstart = (dev->hsync_start & 0x07) + 1; + dev->hblankstart = (dev->hsync_start & 0x07); } } mach_log("ATI 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 9e5e74370..04a543884 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -1886,10 +1886,10 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) } case 0x13: { - if (!(chips->pci_conf_status & PCI_COMMAND_MEM)) { + // if (!(chips->pci_conf_status & PCI_COMMAND_MEM)) { chips->linear_mapping.base = val << 24; - break; - } + // break; + // } mem_mapping_set_addr(&chips->linear_mapping, val << 24, (1 << 24)); break; } diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 5d376effe..e83d4593f 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -1750,7 +1750,7 @@ gd54xx_recalctimings(svga_t *svga) uint8_t rdmask; uint8_t linedbl = svga->dispend * 9 / 10 >= svga->hdisp; - svga->hblankstart = svga->crtc[2] + 1; + svga->hblankstart = svga->crtc[2]; if (svga->crtc[0x1b] & ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5424) ? 0xa0 : 0x20)) { /* Special blanking mode: the blank start and end become components of the window generator, @@ -1763,7 +1763,7 @@ gd54xx_recalctimings(svga_t *svga) svga->hblank_end_mask = 0x000000ff; if (svga->crtc[0x1b] & 0x20) { - svga->hblankstart = svga->crtc[1]/* + ((svga->crtc[3] >> 5) & 3)*/ + 1; + svga->hblankstart = svga->crtc[1]/* + ((svga->crtc[3] >> 5) & 3) + 1*/; svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 6d52fc91b..fa671e2f6 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -650,7 +650,7 @@ et4000_recalctimings(svga_t *svga) svga->ma_latch |= (svga->crtc[0x33] & 3) << 16; - svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; + svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[2]; if (svga->crtc[0x35] & 1) svga->vblankstart += 0x400; @@ -690,14 +690,12 @@ et4000_recalctimings(svga_t *svga) case 15: case 16: svga->hdisp /= 2; - svga->hblankstart /= 2; - svga->hblank_end_val /= 2; + svga->dots_per_clock /= 2; break; case 24: svga->hdisp /= 3; - svga->hblankstart /= 3; - svga->hblank_end_val /= 3; + svga->dots_per_clock /= 3; break; default: diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 259fefffb..7adb6bc89 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -432,7 +432,7 @@ et4000w32p_recalctimings(svga_t *svga) svga->ma_latch |= (svga->crtc[0x33] & 0x7) << 16; - svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; + svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[2]; if (svga->crtc[0x35] & 0x01) svga->vblankstart += 0x400; diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index 35d335ed2..b87d93665 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -714,7 +714,7 @@ ht216_recalctimings(svga_t *svga) svga->vram_display_mask = (ht216->ht_regs[0xf6] & 0x40) ? ht216->vram_mask : 0x3ffff; if (ht216->ht_regs[0xe0] & 0x20) - svga->hblankstart = ((ht216->ht_regs[0xca] >> 2) << 8) + svga->crtc[4] + 1; + svga->hblankstart = ((ht216->ht_regs[0xca] >> 2) << 8) + svga->crtc[4]; } static void diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index b85eb5ad9..f40385fef 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -945,7 +945,7 @@ mystique_recalctimings(svga_t *svga) if (mystique->crtcext_regs[1] & CRTCX_R1_HTOTAL8) svga->htotal |= 0x100; - svga->hblankstart = (((mystique->crtcext_regs[1] & 0x02) >> 2) << 8) + svga->crtc[2] + 1; + svga->hblankstart = (((mystique->crtcext_regs[1] & 0x02) >> 2) << 8) + svga->crtc[2]; if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL10) svga->vtotal |= 0x400; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 41e21faa9..27c364898 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3312,7 +3312,7 @@ s3_recalctimings(svga_t *svga) if (svga->crtc[0x33] & 0x20) { /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1]/* + - ((svga->crtc[3] >> 5) & 3)*/ + 1; + ((svga->crtc[3] >> 5) & 3) + 1*/; svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; svga->monitor->mon_overscan_y = 0; @@ -3324,7 +3324,7 @@ s3_recalctimings(svga_t *svga) if (s3->chip >= S3_VISION964) svga->hblank_end_mask = 0x7f; } else if (s3->chip >= S3_86C801) { - svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2] + 1; + svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2]; if (s3->chip >= S3_VISION964) { /* NOTE: The S3 Trio64V+ datasheet says this is bit 7, but then where is bit 6? @@ -4160,7 +4160,7 @@ s3_trio64v_recalctimings(svga_t *svga) if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) { /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1]/* + - ((svga->crtc[3] >> 5) & 3)*/ + 1; + ((svga->crtc[3] >> 5) & 3) + 1*/; svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; svga->monitor->mon_overscan_y = 0; @@ -4169,7 +4169,7 @@ s3_trio64v_recalctimings(svga_t *svga) /* Also make sure vertical blanking starts on display end. */ svga->vblankstart = svga->dispend; } else { - svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2] + 1; + svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2]; /* NOTE: The S3 Trio64V+ datasheet says this is bit 7, but then where is bit 6? The datasheets for the pre-Trio64V+ cards say +64, which implies bit 6, diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 1cb6424fb..be6382ec9 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -827,7 +827,7 @@ s3_virge_recalctimings(svga_t *svga) if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) { /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1]/* + - ((svga->crtc[3] >> 5) & 3)*/ + 1; + ((svga->crtc[3] >> 5) & 3) + 1*/; svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; svga->monitor->mon_overscan_y = 0; @@ -836,7 +836,7 @@ s3_virge_recalctimings(svga_t *svga) /* Also make sure vertical blanking starts on display end. */ svga->vblankstart = svga->dispend; } else { - svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2] + 1; + svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2]; svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | (((svga->crtc[0x5d] & 0x08) >> 3) << 6); diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index b298fc4e1..d0f02929d 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -750,7 +750,7 @@ svga_recalctimings(svga_t *svga) } else svga->monitor->mon_overscan_x = 16; - svga->hblankstart = svga->crtc[2] + 1; + svga->hblankstart = svga->crtc[2]; svga->hblank_end_val = (svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00); svga->hblank_end_mask = 0x0000003f; diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index f03f6efd4..098e919d4 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -558,10 +558,10 @@ banshee_recalctimings(svga_t *svga) that is, no overscan and relying on display end to blank. */ if (banshee->vgaInit0 & 0x40) { svga->hblankstart = svga->crtc[1]/* + ((svga->crtc[3] >> 5) & 3)*/ + - (((svga->crtc[0x1a] & 0x04) >> 2) << 8) + 1; + (((svga->crtc[0x1a] & 0x04) >> 2) << 8); svga->hblank_end_mask = 0x0000007f; } else { - svga->hblankstart = svga->crtc[1]/* + ((svga->crtc[3] >> 5) & 3)*/ + 1; + svga->hblankstart = svga->crtc[1]/* + ((svga->crtc[3] >> 5) & 3)*/; svga->hblank_end_mask = 0x0000003f; } svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; @@ -579,12 +579,12 @@ banshee_recalctimings(svga_t *svga) svga->linedbl = 0; } else { if (banshee->vgaInit0 & 0x40) { - svga->hblankstart = (((svga->crtc[0x1a] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; + svga->hblankstart = (((svga->crtc[0x1a] & 0x10) >> 4) << 8) + svga->crtc[2]; svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | (((svga->crtc[0x1a] & 0x20) >> 5) << 6); svga->hblank_end_mask = 0x0000007f; } else { - svga->hblankstart = svga->crtc[2] + 1; + svga->hblankstart = svga->crtc[2]; svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5); svga->hblank_end_mask = 0x0000003f; } @@ -652,9 +652,6 @@ banshee_recalctimings(svga_t *svga) if (banshee->vidProcCfg & VIDPROCCFG_2X_MODE) { svga->hdisp *= 2; - // svga->htotal *= 2; - // svga->hblankstart *= 2; - // svga->hblank_end_val *= 2; svga->dots_per_clock *= 2; } From fc63c26e04447c0cff375bf9c01f47ac9a19765e Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Sun, 18 Feb 2024 20:02:01 +0300 Subject: [PATCH 546/936] Merge network device headers to network.h --- src/include/86box/net_3c501.h | 45 ----------------------------- src/include/86box/net_3c503.h | 49 ------------------------------- src/include/86box/net_ne2000.h | 9 ------ src/include/86box/net_pcnet.h | 8 ------ src/include/86box/net_plip.h | 26 ----------------- src/include/86box/net_rtl8139.h | 1 - src/include/86box/net_tulip.h | 4 --- src/include/86box/net_wd8003.h | 7 ----- src/include/86box/network.h | 51 +++++++++++++++++++++++++++++++++ src/lpt.c | 5 +++- src/machine/machine_table.c | 4 ++- src/network/net_3c501.c | 1 - src/network/net_3c503.c | 1 - src/network/net_plip.c | 1 - src/network/net_rtl8139.c | 1 - src/network/net_tulip.c | 1 - src/network/network.c | 5 ---- 17 files changed, 58 insertions(+), 161 deletions(-) delete mode 100644 src/include/86box/net_3c501.h delete mode 100644 src/include/86box/net_3c503.h delete mode 100644 src/include/86box/net_plip.h delete mode 100644 src/include/86box/net_rtl8139.h delete mode 100644 src/include/86box/net_tulip.h diff --git a/src/include/86box/net_3c501.h b/src/include/86box/net_3c501.h deleted file mode 100644 index c55151ab8..000000000 --- a/src/include/86box/net_3c501.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box Project. - * - * Implementation of the following network controller: - * - 3Com Etherlink 3c500/3c501 (ISA 8-bit). - * - * - * - * Based on @(#)Dev3C501.cpp Oracle (VirtualBox) - * - * Authors: TheCollector1995, - * Oracle - * - * Copyright 2022 TheCollector1995. - * Portions Copyright (C) 2022 Oracle and/or its affilitates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ -#ifndef NET_3C501_H -#define NET_3C501_H - -extern const device_t threec501_device; - -#endif /*NET_3C501_H*/ diff --git a/src/include/86box/net_3c503.h b/src/include/86box/net_3c503.h deleted file mode 100644 index 44024850f..000000000 --- a/src/include/86box/net_3c503.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implementation of the following network controllers: - * - 3Com Etherlink II 3c503 (ISA 8-bit). - * - * - * - * Based on @(#)3c503.cpp Carl (MAME) - * - * Authors: TheCollector1995, - * Miran Grca, - * Fred N. van Kempen, - * Carl, - * - * Copyright 2018 TheCollector1995. - * Copyright 2018 Miran Grca. - * Copyright 2017-2018 Fred N. van Kempen. - * Portions Copyright (C) 2018 MAME Project - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ -#ifndef NET_3C503_H -#define NET_3C503_H - -extern const device_t threec503_device; - -#endif /*NET_3C503_H*/ diff --git a/src/include/86box/net_ne2000.h b/src/include/86box/net_ne2000.h index 907f1e9c1..fe1a71934 100644 --- a/src/include/86box/net_ne2000.h +++ b/src/include/86box/net_ne2000.h @@ -48,13 +48,4 @@ enum { NE2K_RTL8029AS = 8 /* 32-bit PCI Realtek 8029AS */ }; -extern const device_t ne1000_device; -extern const device_t ne1000_compat_device; -extern const device_t ne2000_device; -extern const device_t ne2000_compat_device; -extern const device_t ethernext_mc_device; -extern const device_t rtl8019as_device; -extern const device_t de220p_device; -extern const device_t rtl8029as_device; - #endif /*NET_NE2000_H*/ diff --git a/src/include/86box/net_pcnet.h b/src/include/86box/net_pcnet.h index 23ee643ed..994d88c75 100644 --- a/src/include/86box/net_pcnet.h +++ b/src/include/86box/net_pcnet.h @@ -30,12 +30,4 @@ enum { DEV_AM79C973 = 6 /* PCnet-FAST III (PCI, 10/100 Mbps) */ }; -extern const device_t pcnet_am79c960_device; -extern const device_t pcnet_am79c960_eb_device; -extern const device_t pcnet_am79c960_vlb_device; -extern const device_t pcnet_am79c961_device; -extern const device_t pcnet_am79c970a_device; -extern const device_t pcnet_am79c973_device; -extern const device_t pcnet_am79c973_onboard_device; - #endif /*NET_PCNET_H*/ diff --git a/src/include/86box/net_plip.h b/src/include/86box/net_plip.h deleted file mode 100644 index 83c33e4c6..000000000 --- a/src/include/86box/net_plip.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Definitions for the PLIP parallel port network device. - * - * - * - * Authors: RichardG, - * - * Copyright 2020 RichardG. - */ - -#ifndef NET_PLIP_H -#define NET_PLIP_H -#include <86box/device.h> -#include <86box/lpt.h> - -extern const lpt_device_t lpt_plip_device; -extern const device_t plip_device; - -#endif /*NET_PLIP_H*/ diff --git a/src/include/86box/net_rtl8139.h b/src/include/86box/net_rtl8139.h deleted file mode 100644 index f44d0facb..000000000 --- a/src/include/86box/net_rtl8139.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t rtl8139c_plus_device; diff --git a/src/include/86box/net_tulip.h b/src/include/86box/net_tulip.h deleted file mode 100644 index 2ee7ec3c1..000000000 --- a/src/include/86box/net_tulip.h +++ /dev/null @@ -1,4 +0,0 @@ -extern const device_t dec_tulip_device; -extern const device_t dec_tulip_21140_device; -extern const device_t dec_tulip_21140_vpc_device; -extern const device_t dec_tulip_21040_device; diff --git a/src/include/86box/net_wd8003.h b/src/include/86box/net_wd8003.h index 726510cdb..6797c7d88 100644 --- a/src/include/86box/net_wd8003.h +++ b/src/include/86box/net_wd8003.h @@ -54,11 +54,4 @@ enum { WD8013EPA = 6 }; -extern const device_t wd8003e_device; -extern const device_t wd8003eb_device; -extern const device_t wd8013ebt_device; -extern const device_t wd8003eta_device; -extern const device_t wd8003ea_device; -extern const device_t wd8013epa_device; - #endif /*NET_WD8003_H*/ diff --git a/src/include/86box/network.h b/src/include/86box/network.h index e9b703ee0..d0af3f09b 100644 --- a/src/include/86box/network.h +++ b/src/include/86box/network.h @@ -192,12 +192,63 @@ extern int network_card_available(int); extern int network_card_has_config(int); extern const char *network_card_get_internal_name(int); extern int network_card_get_from_internal_name(char *); +#ifdef EMU_DEVICE_H extern const device_t *network_card_getdevice(int); +#endif extern int network_tx_pop(netcard_t *card, netpkt_t *out_pkt); extern int network_tx_popv(netcard_t *card, netpkt_t *pkt_vec, int vec_size); extern int network_rx_put(netcard_t *card, uint8_t *bufp, int len); extern int network_rx_put_pkt(netcard_t *card, netpkt_t *pkt); + +#ifdef EMU_DEVICE_H +/* 3Com Etherlink */ +extern const device_t threec501_device; +extern const device_t threec503_device; + +/* Novell NE2000 and compatibles */ +extern const device_t ne1000_device; +extern const device_t ne1000_compat_device; +extern const device_t ne2000_device; +extern const device_t ne2000_compat_device; +extern const device_t ethernext_mc_device; +extern const device_t rtl8019as_device; +extern const device_t de220p_device; +extern const device_t rtl8029as_device; + +/* AMD PCnet*/ +extern const device_t pcnet_am79c960_device; +extern const device_t pcnet_am79c960_eb_device; +extern const device_t pcnet_am79c960_vlb_device; +extern const device_t pcnet_am79c961_device; +extern const device_t pcnet_am79c970a_device; +extern const device_t pcnet_am79c973_device; +extern const device_t pcnet_am79c973_onboard_device; + +/* PLIP */ +#ifdef EMU_LPT_H +extern const lpt_device_t lpt_plip_device; +#endif +extern const device_t plip_device; + +/* Realtek RTL8139C+ */ +extern const device_t rtl8139c_plus_device; + +/* DEC Tulip */ +extern const device_t dec_tulip_device; +extern const device_t dec_tulip_21140_device; +extern const device_t dec_tulip_21140_vpc_device; +extern const device_t dec_tulip_21040_device; + +/* WD 80x3 */ +extern const device_t wd8003e_device; +extern const device_t wd8003eb_device; +extern const device_t wd8013ebt_device; +extern const device_t wd8003eta_device; +extern const device_t wd8003ea_device; +extern const device_t wd8013epa_device; +#endif + #ifdef __cplusplus } #endif diff --git a/src/lpt.c b/src/lpt.c index dd77b3516..419e5ad3d 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -11,7 +11,10 @@ #include <86box/pic.h> #include <86box/sound.h> #include <86box/prt_devs.h> -#include <86box/net_plip.h> +#include <86box/thread.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/network.h> lpt_port_t lpt_ports[PARALLEL_MAX]; diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 00c776209..d6849c7ac 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -33,7 +33,9 @@ #include <86box/sound.h> #include <86box/video.h> #include <86box/plat_unused.h> -#include <86box/net_pcnet.h> +#include <86box/thread.h> +#include <86box/timer.h> +#include <86box/network.h> // Temporarily here till we move everything out into the right files extern const device_t pcjr_device; diff --git a/src/network/net_3c501.c b/src/network/net_3c501.c index 5b9fc0cac..868ee036f 100644 --- a/src/network/net_3c501.c +++ b/src/network/net_3c501.c @@ -56,7 +56,6 @@ #include <86box/thread.h> #include <86box/timer.h> #include <86box/network.h> -#include <86box/net_3c501.h> #include <86box/bswap.h> #include <86box/plat_unused.h> diff --git a/src/network/net_3c503.c b/src/network/net_3c503.c index d01b423ae..11e823326 100644 --- a/src/network/net_3c503.c +++ b/src/network/net_3c503.c @@ -60,7 +60,6 @@ #include <86box/timer.h> #include <86box/network.h> #include <86box/net_dp8390.h> -#include <86box/net_3c503.h> #include <86box/bswap.h> #include <86box/plat_unused.h> diff --git a/src/network/net_plip.c b/src/network/net_plip.c index f622d455b..41e5502a6 100644 --- a/src/network/net_plip.c +++ b/src/network/net_plip.c @@ -34,7 +34,6 @@ #include <86box/thread.h> #include <86box/timer.h> #include <86box/network.h> -#include <86box/net_plip.h> #include <86box/plat_unused.h> enum { diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index 8afb7b4b8..a7c007115 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -43,7 +43,6 @@ #include <86box/bswap.h> #include <86box/nvr.h> #include "cpu.h" -#include <86box/net_rtl8139.h> #include <86box/plat_unused.h> #define PCI_PERIOD 30 /* 30 ns period = 33.333333 Mhz frequency */ diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index 5fed7f1d1..ffc342e81 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -32,7 +32,6 @@ #include <86box/thread.h> #include <86box/network.h> #include <86box/net_eeprom_nmc93cxx.h> -#include <86box/net_tulip.h> #include <86box/bswap.h> #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> diff --git a/src/network/network.c b/src/network/network.c index 6b3a9fd1c..9eb537e3a 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -67,14 +67,9 @@ #include <86box/ui.h> #include <86box/timer.h> #include <86box/network.h> -#include <86box/net_3c501.h> -#include <86box/net_3c503.h> #include <86box/net_ne2000.h> #include <86box/net_pcnet.h> -#include <86box/net_plip.h> #include <86box/net_wd8003.h> -#include <86box/net_tulip.h> -#include <86box/net_rtl8139.h> #ifdef _WIN32 # define WIN32_LEAN_AND_MEAN From 173007edce45050f19d2d2b7b55a36f289db54ab Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 18 Feb 2024 19:55:13 +0500 Subject: [PATCH 547/936] Remove libvncserver from dependencies on GHA It's useless since VNC renderer is disabled there anyway --- .github/workflows/c-cpp.yml | 1 - .github/workflows/cmake_linux.yml | 1 - .github/workflows/cmake_macos.yml | 1 - .github/workflows/cmake_windows_msys2.yml | 1 - .github/workflows/codeql_linux.yml | 1 - .github/workflows/codeql_macos.yml | 1 - .github/workflows/codeql_windows_msys2.yml | 1 - 7 files changed, 7 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 2a22a19cf..fd81701a7 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -94,7 +94,6 @@ jobs: rtmidi:p libslirp:p fluidsynth:p - libvncserver:p - name: Checkout repository uses: actions/checkout@v4 diff --git a/.github/workflows/cmake_linux.yml b/.github/workflows/cmake_linux.yml index c09789bfc..12cb21303 100644 --- a/.github/workflows/cmake_linux.yml +++ b/.github/workflows/cmake_linux.yml @@ -80,7 +80,6 @@ jobs: libopenal-dev libslirp-dev libfluidsynth-dev - libvncserver-dev ${{ matrix.ui.packages }} - name: Checkout repository diff --git a/.github/workflows/cmake_macos.yml b/.github/workflows/cmake_macos.yml index 7a6edcde9..e51c652a4 100644 --- a/.github/workflows/cmake_macos.yml +++ b/.github/workflows/cmake_macos.yml @@ -82,7 +82,6 @@ jobs: rtmidi openal-soft fluidsynth - libvncserver ${{ matrix.ui.packages }} - name: Checkout repository diff --git a/.github/workflows/cmake_windows_msys2.yml b/.github/workflows/cmake_windows_msys2.yml index 46fc25b67..c7d77307c 100644 --- a/.github/workflows/cmake_windows_msys2.yml +++ b/.github/workflows/cmake_windows_msys2.yml @@ -104,7 +104,6 @@ jobs: rtmidi:p libslirp:p fluidsynth:p - libvncserver:p ${{ matrix.ui.packages }} - name: Checkout repository diff --git a/.github/workflows/codeql_linux.yml b/.github/workflows/codeql_linux.yml index a97951abf..d92d11767 100644 --- a/.github/workflows/codeql_linux.yml +++ b/.github/workflows/codeql_linux.yml @@ -83,7 +83,6 @@ jobs: libopenal-dev libslirp-dev libfluidsynth-dev - libvncserver-dev ${{ matrix.ui.packages }} - name: Checkout repository diff --git a/.github/workflows/codeql_macos.yml b/.github/workflows/codeql_macos.yml index 724bdc6f6..cef8c4828 100644 --- a/.github/workflows/codeql_macos.yml +++ b/.github/workflows/codeql_macos.yml @@ -76,7 +76,6 @@ jobs: rtmidi openal-soft fluidsynth - libvncserver ${{ matrix.ui.packages }} - name: Checkout repository diff --git a/.github/workflows/codeql_windows_msys2.yml b/.github/workflows/codeql_windows_msys2.yml index 5b0c2485f..dc18544c7 100644 --- a/.github/workflows/codeql_windows_msys2.yml +++ b/.github/workflows/codeql_windows_msys2.yml @@ -110,7 +110,6 @@ jobs: rtmidi:p libslirp:p fluidsynth:p - libvncserver:p ${{ matrix.ui.packages }} - name: Checkout repository From 6cd80ade0138b655a0b45317a06872dbc147072e Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Sun, 18 Feb 2024 21:33:46 +0300 Subject: [PATCH 548/936] Fix ActionPC onboard PCI slots --- src/machine/m_at_386dx_486.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index b6f2ec6d9..63f59cb07 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1963,9 +1963,9 @@ machine_at_actionpc2600_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 3); pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_VIDEO, 0, 0, 0, 0); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0E, PCI_CARD_VIDEO, 0, 0, 0, 0); pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); device_add(&umc_hb4_device); From 873d8791e21b805c8053c68e3406bac347fbc2b7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 18 Feb 2024 21:34:13 +0100 Subject: [PATCH 549/936] Override the (S)VGA blanking calculation for the S3 Trio32, Trio64, Trio64V+, and Trio64 V2/DX. --- src/video/vid_s3.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 27c364898..e387245c9 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -4093,6 +4093,11 @@ s3_recalctimings(svga_t *svga) } } } + + if ((s3->chip == S3_TRIO32) || (s3->chip == S3_TRIO64)) + svga->hoverride = 1; + else + svga->hoverride = 0; } static void @@ -4271,6 +4276,8 @@ s3_trio64v_recalctimings(svga_t *svga) break; } } + + svga->hoverride = 1; } static void From cfebf4439b777036826d7a0c8eec321d801b779e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 19 Feb 2024 04:19:55 +0600 Subject: [PATCH 550/936] C&T 69000: avoid stale linear mappings --- src/video/vid_chips_69000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 04a543884..b649e41e5 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -1887,7 +1887,7 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) case 0x13: { // if (!(chips->pci_conf_status & PCI_COMMAND_MEM)) { - chips->linear_mapping.base = val << 24; + // chips->linear_mapping.base = val << 24; // break; // } mem_mapping_set_addr(&chips->linear_mapping, val << 24, (1 << 24)); From 91aa53d8a6bfda4fb43ee33c953d7c4edb942e66 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 19 Feb 2024 04:31:08 +0600 Subject: [PATCH 551/936] More correct linear mapping behaviour --- src/video/vid_chips_69000.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index b649e41e5..606001056 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -1886,10 +1886,10 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p) } case 0x13: { - // if (!(chips->pci_conf_status & PCI_COMMAND_MEM)) { - // chips->linear_mapping.base = val << 24; - // break; - // } + if (!chips->linear_mapping.enable) { + chips->linear_mapping.base = val << 24; + break; + } mem_mapping_set_addr(&chips->linear_mapping, val << 24, (1 << 24)); break; } From 6f22d58a4f4cbc10e4f513e8a9d32735def7d17e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 19 Feb 2024 16:01:49 +0600 Subject: [PATCH 552/936] C&T 69000: Fix pattern drawing in 16-bpp modes --- src/video/vid_chips_69000.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 606001056..0708c7bc5 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -881,6 +881,7 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) uint32_t dest_pixel = 0; uint32_t dest_addr = chips->bitblt_running.bitblt.destination_addr + (chips->bitblt_running.y * chips->bitblt_running.bitblt.destination_span) + (chips->bitblt_running.x * chips->bitblt_running.bytes_per_pixel); uint8_t vert_pat_alignment = (chips->bitblt_running.bitblt.bitblt_control >> 20) & 7; + uint8_t orig_dest_addr_bit = chips->bitblt_running.bitblt.destination_addr & 1; switch (chips->bitblt_running.bytes_per_pixel) { case 1: /* 8 bits-per-pixel. */ @@ -903,8 +904,9 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) } } - /* TODO: Find out from where it actually pulls the exact pattern x and y values. */ - /* Also: is horizontal pattern alignment a requirement? */ + if (chips->bitblt_running.bytes_per_pixel == 2) { + chips->bitblt_running.bitblt.destination_addr >>= 1; + } if (chips->bitblt_running.bitblt.bitblt_control & (1 << 18)) { uint8_t is_true = 0; if (chips->bitblt_running.bitblt.bitblt_control & (1 << 19)) @@ -915,6 +917,10 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) is_true = !!(pattern_data & (1 << (7 - ((chips->bitblt_running.bitblt.destination_addr + chips->bitblt_running.x) & 7)))); if (!is_true && (chips->bitblt_running.bitblt.bitblt_control & (1 << 17))) { + if (chips->bitblt_running.bytes_per_pixel == 2) { + chips->bitblt_running.bitblt.destination_addr <<= 1; + chips->bitblt_running.bitblt.destination_addr |= orig_dest_addr_bit; + } return; } @@ -928,9 +934,13 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) + (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7), chips); } if (chips->bitblt_running.bytes_per_pixel == 2) { - pattern_pixel = chips_69000_readw_linear(chips->bitblt_running.bitblt.pat_addr + pattern_pixel = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + (2 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + (2 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)), chips); + + pattern_pixel |= chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + + (2 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + + (2 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)) + 1, chips) << 8; } if (chips->bitblt_running.bytes_per_pixel == 3) { pattern_pixel = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr @@ -946,6 +956,10 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) + (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)) + 2, chips) << 16; } } + if (chips->bitblt_running.bytes_per_pixel == 2) { + chips->bitblt_running.bitblt.destination_addr <<= 1; + chips->bitblt_running.bitblt.destination_addr |= orig_dest_addr_bit; + } if (chips->bitblt_running.bitblt.bitblt_control & (1 << 14)) { switch ((chips->bitblt_running.bitblt.bitblt_control >> 15) & 3) { From 10c744d66547f7967d7b2642cab8bd0a45e45e48 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 19 Feb 2024 16:07:14 +0600 Subject: [PATCH 553/936] Remove frequency logging --- src/video/vid_chips_69000.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 0708c7bc5..0eee90486 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -2371,8 +2371,6 @@ chips_69000_getclock(int clock, void *priv) fvco *= 4.0; float fo = fvco / (float)(1 << pl); - pclog("freq = %f\n", fo); - return fo; } From 19f6954410ea21bcb19d834ff0b2994499fd546b Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 19 Feb 2024 15:20:59 +0100 Subject: [PATCH 554/936] Reverted some CPU-related changes. --- src/cpu/386_common.c | 10 ++++++++-- src/cpu/x86seg.c | 11 ++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 77d984048..beb6869e9 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -1539,7 +1539,10 @@ x86_int_sw(int num) } } - trap &= ~1; + if (cpu_use_exec) + trap = 0; + else + trap &= ~1; CPU_BLOCK_END(); } @@ -1582,7 +1585,10 @@ x86_int_sw_rm(int num) #endif cycles -= timing_int_rm; - trap &= ~1; + if (cpu_use_exec) + trap = 0; + else + trap &= ~1; CPU_BLOCK_END(); return 0; diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 245f3fa65..c50c97a39 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -2286,10 +2286,14 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) op_loadseg(new_fs, &cpu_state.seg_fs); op_loadseg(new_gs, &cpu_state.seg_gs); - rf_flag_no_clear = 1; + if (!cpu_use_exec) + rf_flag_no_clear = 1; if (t_bit) { - trap |= 2; + if (cpu_use_exec) + trap = 2; + else + trap |= 2; #ifdef USE_DYNAREC cpu_block_end = 1; #endif @@ -2469,7 +2473,8 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) tr.limit = limit; tr.access = segdat[2] >> 8; tr.ar_high = segdat[3] & 0xff; - dr[7] &= 0xFFFFFFAA; + if (!cpu_use_exec) + dr[7] &= 0xFFFFFFAA; } void From e3e30e7536683fa2cbe64b025efc877da0d67dd7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 19 Feb 2024 15:41:49 +0100 Subject: [PATCH 555/936] Fixed a very stupid typo in the 286/386 version of the LOCK instruction that was breaking OS/2 Warp 3.0. --- src/cpu/x86_ops_misc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index 8e9c9f785..dd05fb9d9 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -763,7 +763,7 @@ opLOCK(uint32_t fetchdat) legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ break; case 0xfe ... 0xff: - legal = lock_legal_f6[(fetch_dat.b[1] >> 3) & 0x07]; + legal = lock_legal_fe[(fetch_dat.b[1] >> 3) & 0x07]; if (legal == 1) legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ break; From 733c26d04a4aa2c62a14f0ff066a70267b53f0b6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 19 Feb 2024 19:09:35 +0100 Subject: [PATCH 556/936] Return no mask when the TSS type is 286, closes #4177. --- src/cpu/386_common.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index beb6869e9..847408ba8 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -1605,6 +1605,9 @@ checkio(uint32_t port, int mask) { uint32_t t; + if (!(tr.access & 0x08)) + return 0; + cpl_override = 1; t = readmemw(tr.base, 0x66); From 78dd6039518eb3fdd03ebd39852c1270eb433818 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 20 Feb 2024 07:26:44 +0100 Subject: [PATCH 557/936] Minor change to FDC37C6xx. --- src/sio/sio_fdc37c6xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sio/sio_fdc37c6xx.c b/src/sio/sio_fdc37c6xx.c index 22b88615d..c1fb2c1a5 100644 --- a/src/sio/sio_fdc37c6xx.c +++ b/src/sio/sio_fdc37c6xx.c @@ -396,7 +396,7 @@ const device_t fdc37c661_ide_device = { const device_t fdc37c661_ide_sec_device = { .name = "SMC FDC37C661 Super I/O (With Secondary IDE)", - .internal_name = "fdc37c661_ide", + .internal_name = "fdc37c661_ide_sec", .flags = 0, .local = 0x261, .init = fdc37c6xx_init, From 963b7eec042a048327edf740e06e6b553ab0e4b6 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 20 Feb 2024 18:41:51 +0100 Subject: [PATCH 558/936] Some temporary video changes regarding the horizontal display. S3 side: Temporary changes to match the release (due to tomorrow) of 86box. Said changes are about the horizontal display of the tvp3026-based S3 chips. IBM/ATI 8514-based: Temporarily commented out the hblank side of it due to htotal bugs. TVP3026 side: When the upper clock selection bits are 0 and when extended VGA modes are set, double the hdisp. --- src/video/vid_s3.c | 27 ++++++++++++--- src/video/vid_svga.c | 43 ++++++++++++----------- src/video/vid_tvp3026_ramdac.c | 63 ++++------------------------------ 3 files changed, 52 insertions(+), 81 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index e387245c9..0ef48fa0e 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3214,7 +3214,6 @@ s3_recalctimings(svga_t *svga) } svga->hdisp = svga->hdisp_old; - svga->ma_latch |= (s3->ma_ext << 16); if (s3->chip >= S3_86C928) { @@ -3222,7 +3221,7 @@ s3_recalctimings(svga_t *svga) svga->htotal |= 0x100; if (svga->crtc[0x5d] & 0x02) { svga->hdisp_time |= 0x100; - svga->hdisp |= 0x100 * svga->dots_per_clock; + svga->hdisp |= (0x100 * svga->dots_per_clock); } if (svga->crtc[0x5e] & 0x01) svga->vtotal |= 0x400; @@ -3442,8 +3441,13 @@ s3_recalctimings(svga_t *svga) break; case S3_VISION968: switch (s3->card_type) { - case S3_PHOENIX_VISION968: + case S3_MIROVIDEO40SV_ERGO_968: + if (svga->hdisp == 832) + svga->hdisp -= 32; + break; case S3_NUMBER9_9FX_771: + case S3_PHOENIX_VISION968: + case S3_SPEA_MERCURY_P64V: svga->hdisp <<= 1; svga->dots_per_clock <<= 1; if (svga->hdisp == 832) @@ -3619,8 +3623,13 @@ s3_recalctimings(svga_t *svga) break; case S3_VISION968: switch (s3->card_type) { + case S3_MIROVIDEO40SV_ERGO_968: + if (svga->hdisp == 832) + svga->hdisp -= 32; + break; case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: + case S3_SPEA_MERCURY_P64V: svga->hdisp <<= 1; svga->dots_per_clock <<= 1; /* TODO: Is this still needed? */ @@ -3801,8 +3810,13 @@ s3_recalctimings(svga_t *svga) break; case S3_VISION968: switch (s3->card_type) { + case S3_MIROVIDEO40SV_ERGO_968: + if (svga->hdisp == 832) + svga->hdisp -= 32; + break; case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: + case S3_SPEA_MERCURY_P64V: svga->hdisp <<= 1; svga->dots_per_clock <<= 1; /* TODO: Is this still needed? */ @@ -4003,8 +4017,13 @@ s3_recalctimings(svga_t *svga) break; case S3_VISION968: switch (s3->card_type) { + case S3_MIROVIDEO40SV_ERGO_968: + if (svga->hdisp == 832) + svga->hdisp -= 32; + break; case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: + case S3_SPEA_MERCURY_P64V: svga->hdisp <<= 1; svga->dots_per_clock <<= 1; /* TODO: Is this still needed? */ @@ -4165,7 +4184,7 @@ s3_trio64v_recalctimings(svga_t *svga) if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) { /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1]/* + - ((svga->crtc[3] >> 5) & 3) + 1*/; + ((svga->crtc[3] >> 5) & 3)*/; svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; svga->monitor->mon_overscan_y = 0; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index d0f02929d..d9c2ba892 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -794,8 +794,8 @@ svga_recalctimings(svga_t *svga) uint32_t eff_mask = (svga->hblank_end_val & ~0x0000003f) ? svga->hblank_end_mask : 0x0000003f; svga->hblank_sub = 0; - svga_log("Blank: %04i-%04i, Total: %04i, Mask: %02X\n", svga->hblankstart, svga->hblank_end_val, - svga->htotal, eff_mask); + svga_log("HDISP=%d, CRTC1+1=%d, Blank: %04i-%04i, Total: %04i, Mask: %02X, ADJ_DOT=%04i.\n", svga->hdisp, svga->crtc[1] + 1, svga->hblankstart, svga->hblank_end_val, + svga->htotal, eff_mask, adj_dot); while (adj_dot < (svga->htotal << 1)) { if (dot == svga->htotal) @@ -804,6 +804,7 @@ svga_recalctimings(svga_t *svga) if (adj_dot >= svga->htotal) svga->hblank_sub++; + svga_log("Loop: adjdot=%d, htotal=%d, dotmask=%02x, hblankendvalmask=%02x, blankendval=%02x.\n", adj_dot, svga->htotal, dot & eff_mask, svga->hblank_end_val & eff_mask, svga->hblank_end_val); if ((dot & eff_mask) == (svga->hblank_end_val & eff_mask)) break; @@ -812,32 +813,34 @@ svga_recalctimings(svga_t *svga) } svga->hdisp -= (svga->hblank_sub * svga->dots_per_clock); + } - if (ibm8514_active && (svga->dev8514 != NULL)) { - if (dev->on[0] || dev->on[1]) { - uint32_t dot8514 = dev->h_blankstart; - uint32_t adj_dot8514 = dev->h_blankstart; - uint32_t eff_mask8514 = 0x0000003f; - dev->hblank_sub = 0; +#ifdef TBD + if (ibm8514_active && (svga->dev8514 != NULL)) { + if (dev->on[0] || dev->on[1]) { + uint32_t dot8514 = dev->h_blankstart; + uint32_t adj_dot8514 = dev->h_blankstart; + uint32_t eff_mask8514 = 0x0000003f; + dev->hblank_sub = 0; - while (adj_dot8514 < (dev->h_total << 1)) { - if (dot8514 == dev->h_total) - dot = 0; + while (adj_dot8514 < (dev->h_total << 1)) { + if (dot8514 == dev->h_total) + dot8514 = 0; - if (adj_dot8514 >= dev->h_total) - dev->hblank_sub++; + if (adj_dot8514 >= dev->h_total) + dev->hblank_sub++; - if ((dot8514 & eff_mask8514) == (dev->h_blank_end_val & eff_mask8514)) - break; + if ((dot8514 & eff_mask8514) == (dev->h_blank_end_val & eff_mask8514)) + break; - dot8514++; - adj_dot8514++; - } - - dev->h_disp -= dev->hblank_sub; + dot8514++; + adj_dot8514++; } + + dev->h_disp -= dev->hblank_sub; } } +#endif if (svga->hdisp >= 2048) svga->monitor->mon_overscan_x = 0; diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c index 625adfe41..cd3ff7e8b 100644 --- a/src/video/vid_tvp3026_ramdac.c +++ b/src/video/vid_tvp3026_ramdac.c @@ -65,7 +65,7 @@ typedef struct tvp3026_ramdac_t { static void tvp3026_set_bpp(tvp3026_ramdac_t *ramdac, svga_t *svga) { - if ((ramdac->true_color & 0x80) == 0x80) { + if (ramdac->true_color & 0x80) { if (ramdac->mcr & 0x08) svga->bpp = 8; else @@ -514,67 +514,16 @@ tvp3026_recalctimings(void *priv, svga_t *svga) { const tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv; - svga->interlace = (ramdac->ccr & 0x40); + svga->interlace = !!(ramdac->ccr & 0x40); /* TODO: Figure out gamma correction for 15/16 bpp color. */ svga->lut_map = !!(svga->bpp >= 15 && (ramdac->true_color & 0xf0) != 0x00); - switch (ramdac->mcr) { - case 0x41: - case 0x4a: - case 0x61: + pclog("MCR=0x%02x, truecolor=0x%02x, crtc1=0x%02x, MCLK=0x%02x, ClockSel=%x.\n", ramdac->mcr, ramdac->true_color, svga->crtc[1] + 1, ramdac->mclk & 0x7f, ramdac->clock_sel); + if (!(ramdac->clock_sel & 0x70)) { + if (ramdac->mcr != 0x98) { svga->hdisp <<= 1; svga->dots_per_clock <<= 1; - break; - case 0x42: - case 0x4b: - case 0x62: - svga->hdisp <<= 2; - svga->dots_per_clock <<= 2; - break; - case 0x43: - case 0x4c: - case 0x63: - svga->hdisp <<= 3; - svga->dots_per_clock <<= 3; - break; - case 0x44: - case 0x64: - svga->hdisp <<= 4; - svga->dots_per_clock <<= 4; - break; - case 0x5b: - switch (ramdac->true_color) { - case 0x16: - case 0x17: - svga->hdisp = (svga->hdisp << 2) / 3; - svga->dots_per_clock = (svga->dots_per_clock << 2) / 3; - break; - case 0x1e: - case 0x1f: - svga->hdisp = (svga->hdisp * 5) >> 2; - svga->dots_per_clock = (svga->dots_per_clock * 5) >> 2; - break; - } - break; - case 0x5c: - switch (ramdac->true_color) { - case 0x06: - case 0x07: - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - break; - case 0x16: - case 0x17: - svga->hdisp = (svga->hdisp << 3) / 3; - svga->dots_per_clock = (svga->dots_per_clock << 3) / 3; - break; - case 0x1e: - case 0x1f: - svga->hdisp = (svga->hdisp * 5) >> 1; - svga->dots_per_clock = (svga->dots_per_clock * 5) >> 1; - break; - } - break; + } } } From 8b4fb1b2abb2b12603cef9ae3aac04e268914226 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 20 Feb 2024 19:11:47 +0100 Subject: [PATCH 559/936] TVP3026: remove excess logs. See above. --- src/video/vid_tvp3026_ramdac.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c index cd3ff7e8b..b50d0406b 100644 --- a/src/video/vid_tvp3026_ramdac.c +++ b/src/video/vid_tvp3026_ramdac.c @@ -518,7 +518,6 @@ tvp3026_recalctimings(void *priv, svga_t *svga) /* TODO: Figure out gamma correction for 15/16 bpp color. */ svga->lut_map = !!(svga->bpp >= 15 && (ramdac->true_color & 0xf0) != 0x00); - pclog("MCR=0x%02x, truecolor=0x%02x, crtc1=0x%02x, MCLK=0x%02x, ClockSel=%x.\n", ramdac->mcr, ramdac->true_color, svga->crtc[1] + 1, ramdac->mclk & 0x7f, ramdac->clock_sel); if (!(ramdac->clock_sel & 0x70)) { if (ramdac->mcr != 0x98) { svga->hdisp <<= 1; From 80adef5ee624a99fbc525e20674715efc9eef3e0 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 21 Feb 2024 01:43:36 +0600 Subject: [PATCH 560/936] C&T 69000: Fix black cursor on Red Hat Linux 8 --- src/video/vid_chips_69000.c | 65 ++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 0eee90486..f53f44754 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -2287,6 +2287,35 @@ chips_69000_vblank_start(svga_t *svga) chips_69000_interrupt(chips); } +static void +chips_69000_hwcursor_draw_64x64(svga_t *svga, int displine) +{ + chips_69000_t *chips = (chips_69000_t *) svga->priv; + uint64_t dat[2]; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 16; + + dat[1] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr])); + dat[0] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr + 8])); + svga->hwcursor_latch.addr += 16; + + for (uint8_t x = 0; x < 64; x++) { + if (!(dat[1] & (1ULL << 63))) + svga->monitor->target_buffer->line[displine][(offset + svga->x_add) & 2047] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[5]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[4]); + else if (dat[0] & (1ULL << 63)) + svga->monitor->target_buffer->line[displine][(offset + svga->x_add) & 2047] ^= 0xffffff; + + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 16; +} + static void chips_69000_hwcursor_draw(svga_t *svga, int displine) { @@ -2294,7 +2323,10 @@ chips_69000_hwcursor_draw(svga_t *svga, int displine) uint64_t dat[2]; int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - if (svga->interlace && (chips->ext_regs[0xa0] & 7) == 0b1) { + if ((chips->ext_regs[0xa0] & 7) == 0b101) + return chips_69000_hwcursor_draw_64x64(svga, displine); + + if (svga->interlace) { dat[1] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr])); dat[0] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr + 8])); svga->hwcursor_latch.addr += 16; @@ -2315,10 +2347,7 @@ chips_69000_hwcursor_draw(svga_t *svga, int displine) return; } - if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 16; - - if ((svga->hwcursor_on & 1) && (chips->ext_regs[0xa0] & 7) == 0b1) { + if ((svga->hwcursor_on & 1)) { dat[1] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr - 16])); dat[0] = bswap64(*(uint64_t *) (&svga->vram[(svga->hwcursor_latch.addr - 16) + 8])); dat[1] <<= 32ULL; @@ -2329,27 +2358,17 @@ chips_69000_hwcursor_draw(svga_t *svga, int displine) dat[0] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr + 8])); svga->hwcursor_latch.addr += 16; } - switch (chips->ext_regs[0xa0] & 7) { - case 0b1: - case 0b101: - for (uint8_t x = 0; x < (((chips->ext_regs[0xa0] & 7) == 0b1) ? 32 : 64); x++) { - if (!(dat[1] & (1ULL << 63))) - svga->monitor->target_buffer->line[displine & 2047][(offset + svga->x_add) & 2047] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[5]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[4]); - else if (dat[0] & (1ULL << 63)) - svga->monitor->target_buffer->line[displine & 2047][(offset + svga->x_add) & 2047] ^= 0xffffff; - offset++; - dat[0] <<= 1; - dat[1] <<= 1; - } - break; + for (uint8_t x = 0; x < 32; x++) { + if (!(dat[1] & (1ULL << 63))) + svga->monitor->target_buffer->line[displine & 2047][(offset + svga->x_add) & 2047] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[5]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[4]); + else if (dat[0] & (1ULL << 63)) + svga->monitor->target_buffer->line[displine & 2047][(offset + svga->x_add) & 2047] ^= 0xffffff; - default: - break; + offset++; + dat[0] <<= 1; + dat[1] <<= 1; } - - if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 16; } static float From 1b5d84f36607fa76acbdcf89ab53cc47e9700e92 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 21 Feb 2024 02:25:40 +0600 Subject: [PATCH 561/936] C&T 69000: DPMS Also draw black overscan when monitor is turned off via DPMS. --- src/video/vid_chips_69000.c | 7 +++++++ src/video/vid_svga.c | 13 +++++++++++-- src/video/video.c | 4 ++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index f53f44754..d91ab1a8b 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -743,6 +743,12 @@ chips_69000_recalctimings(svga_t *svga) svga->htotal -= 5; } + if (((chips->ext_regs[0x61] & 0x8) && !(chips->ext_regs[0x61] & 0x4)) + || ((chips->ext_regs[0x61] & 0x2) && !(chips->ext_regs[0x61] & 0x1))) { + svga->dpms = 1; + } else + svga->dpms = 0; + if (chips->ext_regs[0x09] & 0x1) { svga->vtotal -= 2; svga->vtotal &= 0xFF; @@ -1543,6 +1549,7 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) break; case 0x61: chips->ext_regs[chips->ext_index] = val & 0x7f; + svga_recalctimings(&chips->svga); break; case 0x62: chips->ext_regs[chips->ext_index] = val & 0x9C; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index d9c2ba892..d60a5de0e 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -947,6 +947,15 @@ svga_recalctimings(svga_t *svga) /* Inform the user interface of any DPMS mode changes. */ if (svga->dpms) { if (!svga->dpms_ui) { + /* Make sure to black out the entire screen to avoid lingering image. */ + int y_add = enable_overscan ? svga->monitor->mon_overscan_y : 0; + int x_add = enable_overscan ? svga->monitor->mon_overscan_x : 0; + int y_start = enable_overscan ? 0 : (svga->monitor->mon_overscan_y >> 1); + int x_start = enable_overscan ? 0 : (svga->monitor->mon_overscan_x >> 1); + video_wait_for_buffer_monitor(svga->monitor_index); + memset(svga->monitor->target_buffer->dat, 0, svga->monitor->target_buffer->w * svga->monitor->target_buffer->h * 4); + video_blit_memtoscreen_monitor(x_start, y_start, svga->monitor->mon_xsize + x_add, svga->monitor->mon_ysize + y_add, svga->monitor_index); + video_wait_for_buffer_monitor(svga->monitor_index); svga->dpms_ui = 1; ui_sb_set_text_w(plat_get_string(IDS_2143)); } @@ -1864,14 +1873,14 @@ svga_doblit(int wx, int wy, svga_t *svga) p = &svga->monitor->target_buffer->line[i & 0x7ff][0]; for (j = 0; j < (svga->monitor->mon_xsize + x_add); j++) - p[j] = svga->overscan_color; + p[j] = svga->dpms ? 0 : svga->overscan_color; } for (i = 0; i < bottom; i++) { p = &svga->monitor->target_buffer->line[(svga->monitor->mon_ysize + svga->y_add + i) & 0x7ff][0]; for (j = 0; j < (svga->monitor->mon_xsize + x_add); j++) - p[j] = svga->overscan_color; + p[j] = svga->dpms ? 0 : svga->overscan_color; } } diff --git a/src/video/video.c b/src/video/video.c index 710449746..01c398118 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -831,9 +831,9 @@ destroy_bitmap(bitmap_t *b) bitmap_t * create_bitmap(int x, int y) { - bitmap_t *b = malloc(sizeof(bitmap_t) + (y * sizeof(uint32_t *))); + bitmap_t *b = calloc(sizeof(bitmap_t), (y * sizeof(uint32_t *))); - b->dat = malloc((size_t) x * y * 4); + b->dat = calloc((size_t) x * y, 4); for (int c = 0; c < y; c++) b->line[c] = &(b->dat[c * x]); b->w = x; From 58a0c840c1d18845e8a7b71439bcaca4408491f8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Feb 2024 00:52:20 +0100 Subject: [PATCH 562/936] Added SiS 550x, 558x, 559x, (5)600, UMC UM8890, UMC UM8663 Super I/O Chips, UMC UM8673F and Winbond W83769F IDE Contollers, and a number of machines, and fixes to the UM888x 486 chipset. --- src/acpi.c | 910 ++++++++++++++++- src/chipset/CMakeLists.txt | 8 +- src/chipset/sis_5511.c | 878 +---------------- src/chipset/sis_5511_h2p.c | 461 +++++++++ src/chipset/sis_5513_ide.c | 501 ++++++++++ src/chipset/sis_5513_p2i.c | 1354 ++++++++++++++++++++++++++ src/chipset/sis_5571.c | 1151 +--------------------- src/chipset/sis_5571_h2p.c | 458 +++++++++ src/chipset/sis_5571_old.c | 772 +++++++++++++++ src/chipset/sis_5572_usb.c | 323 ++++++ src/chipset/sis_5581.c | 185 ++++ src/chipset/sis_5581_h2p.c | 553 +++++++++++ src/chipset/sis_5591.c | 210 ++++ src/chipset/sis_5591_h2p.c | 493 ++++++++++ src/chipset/sis_5595_pmu.c | 455 +++++++++ src/chipset/sis_55xx.c | 96 ++ src/chipset/sis_5600.c | 210 ++++ src/chipset/sis_5600_h2p.c | 434 +++++++++ src/chipset/sis_85c50x.c | 424 ++++++-- src/chipset/umc_8886.c | 264 ++--- src/chipset/umc_8890.c | 241 +++++ src/chipset/umc_hb4.c | 123 +-- src/device.c | 17 + src/device/CMakeLists.txt | 2 +- src/device/pci_bridge.c | 25 +- src/device/smbus_sis5595.c | 386 ++++++++ src/disk/CMakeLists.txt | 2 +- src/disk/hdc_ide_sff8038i.c | 11 +- src/disk/hdc_ide_um8673f.c | 212 ++++ src/disk/hdc_ide_w83769f.c | 460 +++++++++ src/include/86box/acpi.h | 62 +- src/include/86box/chipset.h | 10 + src/include/86box/device.h | 2 + src/include/86box/hdc.h | 12 +- src/include/86box/hdc_ide_sff8038i.h | 4 +- src/include/86box/machine.h | 19 + src/include/86box/nvr.h | 2 + src/include/86box/pci.h | 1 + src/include/86box/sio.h | 6 + src/include/86box/sis_55xx.h | 78 ++ src/include/86box/smbus.h | 46 +- src/include/86box/video.h | 4 +- src/machine/m_at_386dx_486.c | 15 +- src/machine/m_at_slot1.c | 34 + src/machine/m_at_socket5.c | 96 ++ src/machine/m_at_socket7.c | 115 ++- src/machine/m_at_socket7_3v.c | 28 + src/machine/machine_table.c | 375 +++++++ src/nvr_at.c | 24 + src/sio/CMakeLists.txt | 3 +- src/sio/sio_it86x1f.c | 4 +- src/sio/sio_um8663f.c | 366 +++++++ src/video/vid_cl54xx.c | 20 +- src/video/vid_tgui9440.c | 16 +- 54 files changed, 10672 insertions(+), 2289 deletions(-) create mode 100644 src/chipset/sis_5511_h2p.c create mode 100644 src/chipset/sis_5513_ide.c create mode 100644 src/chipset/sis_5513_p2i.c create mode 100644 src/chipset/sis_5571_h2p.c create mode 100644 src/chipset/sis_5571_old.c create mode 100644 src/chipset/sis_5572_usb.c create mode 100644 src/chipset/sis_5581.c create mode 100644 src/chipset/sis_5581_h2p.c create mode 100644 src/chipset/sis_5591.c create mode 100644 src/chipset/sis_5591_h2p.c create mode 100644 src/chipset/sis_5595_pmu.c create mode 100644 src/chipset/sis_55xx.c create mode 100644 src/chipset/sis_5600.c create mode 100644 src/chipset/sis_5600_h2p.c create mode 100644 src/chipset/umc_8890.c create mode 100644 src/device/smbus_sis5595.c create mode 100644 src/disk/hdc_ide_um8673f.c create mode 100644 src/disk/hdc_ide_w83769f.c create mode 100644 src/include/86box/sis_55xx.h create mode 100644 src/sio/sio_um8663f.c diff --git a/src/acpi.c b/src/acpi.c index ddd2ffbe7..93cb71542 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -39,6 +39,10 @@ #include <86box/machine.h> #include <86box/i2c.h> #include <86box/video.h> +#include <86box/smbus.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/sis_55xx.h> int acpi_rtc_status = 0; atomic_int acpi_pwrbut_pressed = 0; @@ -46,7 +50,9 @@ int acpi_enabled = 0; static double cpu_to_acpi; -static int acpi_power_on = 0; +static int acpi_power_on = 0; +static uint64_t acpi_last_clock = 0ULL; +static int acpi_count = 0; #ifdef ENABLE_ACPI_LOG int acpi_do_log = ENABLE_ACPI_LOG; @@ -82,65 +88,152 @@ acpi_timer_get(acpi_t *dev) return clock & 0xffffff; } +static uint8_t +acpi_gp_timer_get(acpi_t *dev) +{ + uint64_t clock = acpi_clock_get(); + clock -= acpi_last_clock; + if (clock >= acpi_count) + clock = 0x00; + else + clock &= 0xff; + return clock; +} + static double acpi_get_overflow_period(acpi_t *dev) { uint64_t timer = acpi_clock_get(); uint64_t overflow_time; - if (dev->regs.timer32) { + if (dev->regs.timer32) overflow_time = (timer + 0x80000000LL) & ~0x7fffffffLL; - } else { + else overflow_time = (timer + 0x800000LL) & ~0x7fffffLL; - } uint64_t time_to_overflow = overflow_time - timer; return ((double) time_to_overflow / (double) ACPI_TIMER_FREQ) * 1000000.0; } +static void +acpi_timer_update(acpi_t *dev, bool enable) +{ + if (enable) + timer_on_auto(&dev->timer, acpi_get_overflow_period(dev)); + else + timer_stop(&dev->timer); +} + static void acpi_timer_overflow(void *priv) { acpi_t *dev = (acpi_t *) priv; dev->regs.pmsts |= TMROF_STS; acpi_update_irq(dev); + acpi_timer_update(dev, (dev->regs.pmen & TMROF_EN) && !(dev->regs.pmsts & TMROF_STS)); } static void -acpi_timer_update(acpi_t *dev, bool enable) +acpi_gp_timer_update(acpi_t *dev, bool enable, int count) { if (enable) { - timer_on_auto(&dev->timer, acpi_get_overflow_period(dev)); - } else { + acpi_last_clock = acpi_clock_get(); + acpi_count = count; + timer_on_auto(&dev->gp_timer, (1000000.0 / (double) ACPI_TIMER_FREQ) * ((double) count)); + } else timer_stop(&dev->timer); +} + +void +acpi_sis5595_smi_raise(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + if (dev->regs.leg_en & 0x20) { + dev->regs.leg_sts |= 0x20; + smi_raise(); } } +static void +acpi_gp_timer(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + if (dev->vendor == VEN_SIS_5595_1997) { + dev->regs.gpe_sts |= 0x20000000; + dev->regs.leg_sts |= 0x20; + acpi_gp_timer_update(dev, (dev->regs.gpe_en & 0x20000000), acpi_count); + acpi_sis5595_smi_raise(dev); + } else if (dev->vendor == VEN_SIS_5595) { + dev->regs.gpe_sts |= 0x00000400; + dev->regs.leg_sts |= 0x20; + acpi_gp_timer_update(dev, (dev->regs.gpe_en & 0x00000400), acpi_count); + acpi_sis5595_smi_raise(dev); + } else { + dev->regs.reg_14 |= 0x2000; + acpi_gp_timer_update(dev, (dev->regs.reg_16 & 0x2000), acpi_count); + smi_raise(); + } +} + +static void +acpi_per_timer(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + if (dev->vendor >= VEN_SIS_5595_1997) { + dev->regs.leg_sts |= 0x04; + acpi_sis5595_smi_raise(dev); + } else { + dev->regs.reg_25 |= 0x04; + smi_raise(); + } + timer_on_auto(&dev->per_timer, 16000000.0); +} + void acpi_update_irq(acpi_t *dev) { int sci_level = (dev->regs.pmsts & dev->regs.pmen) & (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN); - if (dev->vendor == VEN_SMC) - sci_level |= (dev->regs.pmsts & BM_STS); + sis_55xx_common_t *sis = (sis_55xx_common_t *) dev->priv; - if ((dev->regs.pmcntrl & 0x01) && sci_level) { - if (dev->irq_mode == 1) - pci_set_irq(dev->slot, dev->irq_pin, &dev->irq_state); - else if (dev->irq_mode == 2) - pci_set_mirq(5, dev->mirq_is_level, &dev->irq_state); - else - picintlevel(1 << dev->irq_line, &dev->irq_state); - } else { - if (dev->irq_mode == 1) - pci_clear_irq(dev->slot, dev->irq_pin, &dev->irq_state); - else if (dev->irq_mode == 2) - pci_clear_mirq(5, dev->mirq_is_level, &dev->irq_state); - else - picintclevel(1 << dev->irq_line, &dev->irq_state); + switch (dev->vendor) { + case VEN_SMC: + sci_level |= (dev->regs.pmsts & BM_STS); + break; + case VEN_SIS_5595_1997: + case VEN_SIS_5595: + if ((sis != NULL) && (sis->pmu_regs != NULL)) { + sci_level |= (sis->pmu_regs[0x80] | sis->pmu_regs[0x81] | + sis->pmu_regs[0x82] | sis->pmu_regs[0x83]); + } + break; } - acpi_timer_update(dev, (dev->regs.pmen & TMROF_EN) && !(dev->regs.pmsts & TMROF_STS)); + if ((dev->regs.pmcntrl & 0x01) && sci_level) switch (dev->irq_mode) { + default: + picintlevel(1 << dev->irq_line, &dev->irq_state); + break; + case 1: + pci_set_irq(dev->slot, dev->irq_pin, &dev->irq_state); + break; + case 2: + pci_set_mirq(5, dev->mirq_is_level, &dev->irq_state); + break; + case -1: + break; + } else switch (dev->irq_mode) { + default: + picintclevel(1 << dev->irq_line, &dev->irq_state); + break; + case 1: + pci_clear_irq(dev->slot, dev->irq_pin, &dev->irq_state); + break; + case 2: + pci_clear_mirq(5, dev->mirq_is_level, &dev->irq_state); + break; + case -1: + break; + } } void @@ -652,6 +745,230 @@ acpi_aux_reg_read_smc(UNUSED(int size), uint16_t addr, void *priv) return ret; } +static uint32_t +acpi_reg_read_sis_5582(int size, uint16_t addr, void *priv) +{ + const acpi_t *dev = (acpi_t *) priv; + uint32_t ret = 0x00000000; + int shift16; + int shift32; + + addr &= 0x3f; + shift16 = (addr & 1) << 3; + shift32 = (addr & 3) << 3; + + switch (addr) { + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + ret = (dev->regs.reg_0c >> shift32) & 0xff; + break; + case 0x10: + ret = dev->regs.enter_c2_ps; + break; + case 0x11: + ret = dev->regs.enter_c3_ps; + break; + case 0x12: + ret = dev->regs.reg_12; + break; + case 0x13: + ret = acpi_gp_timer_get((acpi_t *) dev) & 0xff; +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + update_tsc(); +#endif + break; + case 0x14: + case 0x15: + ret = (dev->regs.reg_14 >> shift16) & 0xff; + break; + case 0x16: + case 0x17: + ret = (dev->regs.reg_16 >> shift16) & 0xff; + break; + case 0x18: + case 0x19: + ret = (dev->regs.reg_18 >> shift16) & 0xff; + break; + case 0x1a: + case 0x1b: + ret = (dev->regs.reg_18 >> shift16) & 0xff; + break; + case 0x1c: + case 0x1d: + ret = (dev->regs.reg_1c >> shift16) & 0xff; + break; + case 0x20: + ret = dev->regs.smi_cmd; + break; + case 0x24: + ret = dev->regs.reg_24; + break; + case 0x25: + ret = dev->regs.reg_25; + break; + case 0x26: + ret = dev->regs.reg_26; + break; + case 0x28: + ret = dev->regs.smi_en_val; + break; + case 0x29: + ret = dev->regs.smi_dis_val; + break; + case 0x2a: + ret = dev->regs.mail_box; + break; + case 0x2b: + ret = dev->regs.reg_2b; + break; + default: + ret = acpi_reg_read_common_regs(size, addr, priv); + break; + } + +#ifdef ENABLE_ACPI_LOG + // if (size != 1) + // acpi_log("(%i) ACPI Read (%i) %02X: %02X\n", in_smm, size, addr, ret); +#endif + return ret; +} + +static uint32_t +acpi_reg_read_sis_5595(int size, uint16_t addr, void *priv) +{ + const acpi_t *dev = (acpi_t *) priv; + uint32_t ret = 0x00000000; + int shift16; + int shift32; + + addr &= 0x3f; + shift16 = (addr & 1) << 3; + shift32 = (addr & 3) << 3; + + switch (addr) { + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + ret = (dev->regs.reg_0c >> shift32) & 0xff; + break; + case 0x10: + ret = dev->regs.enter_c2_ps; + break; + case 0x11: + ret = dev->regs.enter_c3_ps; + break; + case 0x12: + ret = dev->regs.reg_12; + break; + case 0x13: + ret = dev->regs.reg_13; + break; + case 0x14: + case 0x15: + case 0x16: + case 0x17: + ret = (dev->regs.gpe_sts >> shift32) & 0xff; + break; + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + ret = (dev->regs.gpe_en >> shift32) & 0xff; + break; + case 0x1c: + case 0x1d: + case 0x1e: + ret = (dev->regs.gpe_pin >> shift32) & 0xff; + break; + case 0x1f: + ret = acpi_gp_timer_get((acpi_t *) dev) & 0xff; +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + update_tsc(); +#endif + break; + case 0x20: + case 0x21: + case 0x22: + case 0x23: + ret = (dev->regs.gpe_io >> shift32) & 0xff; + break; + case 0x24: + case 0x25: + case 0x26: + case 0x27: + ret = (dev->regs.gpe_pol >> shift32) & 0xff; + break; + case 0x28: + case 0x29: + ret = (dev->regs.gpe_mul >> shift16) & 0xff; + break; + case 0x2a: + case 0x2b: + ret = (dev->regs.gpe_ctl >> shift16) & 0xff; + break; + case 0x2c: + case 0x2d: + ret = (dev->regs.gpe_smi >> shift16) & 0xff; + break; + case 0x2e: + case 0x2f: + ret = (dev->regs.gpe_rl >> shift16) & 0xff; + break; + case 0x30: + ret = dev->regs.leg_sts; + break; + case 0x31: + ret = dev->regs.leg_en; + break; + case 0x32: + if (dev->vendor == VEN_SIS_5595_1997) + ret = dev->regs.smi_cmd; + else + ret = 0x00; + break; + case 0x33: + ret = dev->regs.tst_ctl; + break; + case 0x34: + if (dev->vendor == VEN_SIS_5595_1997) + ret = dev->regs.smi_en_val; + else + ret = dev->regs.reg_34; + break; + case 0x35: + if (dev->vendor == VEN_SIS_5595_1997) + ret = dev->regs.smi_dis_val; + else + ret = dev->regs.smi_cmd; + break; + case 0x36: + ret = dev->regs.mail_box; + break; + case 0x38: + if (dev->vendor == VEN_SIS_5595) + ret = smbus_sis5595_read_index(dev->smbus); + break; + case 0x39: + if (dev->vendor == VEN_SIS_5595) + ret = smbus_sis5595_read_data(dev->smbus); + break; + default: + ret = acpi_reg_read_common_regs(size, addr, priv); + break; + } + +#ifdef ENABLE_ACPI_LOG + // if (size != 1) + // acpi_log("(%i) ACPI Read (%i) %02X: %02X\n", in_smm, size, addr, ret); +#endif + return ret; +} + static void acpi_reg_write_common_regs(UNUSED(int size), uint16_t addr, uint8_t val, void *priv) { @@ -1193,22 +1510,405 @@ acpi_aux_reg_write_smc(UNUSED(int size), uint16_t addr, uint8_t val, void *priv) } } +void +acpi_sis5582_pmu_event(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + + dev->regs.reg_25 |= 0x02; + if (dev->regs.reg_26 & 0x02) + smi_raise(); +} + +static void +acpi_reg_write_sis_5582(int size, uint16_t addr, uint8_t val, void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + int shift16; + int shift32; + uint8_t old; + + addr &= 0x3f; +#ifdef ENABLE_ACPI_LOG + if (size != 1) + acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val); +#endif + shift16 = (addr & 1) << 3; + shift32 = (addr & 3) << 3; + + switch (addr) { + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + dev->regs.reg_0c &= ~((val << shift32) & 0x007e); + break; + case 0x10: + dev->regs.enter_c2_ps = val; + break; + case 0x11: + dev->regs.enter_c3_ps = val; + break; + case 0x12: + dev->regs.reg_12 = val & 0x01; + break; + case 0x13: + dev->regs.reg_13 = val; + acpi_gp_timer_update(dev, (val != 0x00) && (dev->regs.reg_16 & 0x2000), val); + break; + case 0x14: + case 0x15: + dev->regs.reg_14 &= ~((val << shift32) & 0xff9f); + break; + case 0x16: + case 0x17: + dev->regs.reg_16 = ((dev->regs.reg_16 & ~(0xff << shift16)) | (val << shift16)) & 0xff1f; + break; + case 0x18: + case 0x19: + dev->regs.reg_18 = ((dev->regs.reg_18 & ~(0xff << shift16)) | (val << shift16)) & 0x07ff; + break; + case 0x1a: + case 0x1b: + dev->regs.reg_1a = ((dev->regs.reg_1a & ~(0xff << shift16)) | (val << shift16)) & 0x0387; + break; + case 0x1c: + case 0x1d: + dev->regs.reg_1c = ((dev->regs.reg_1c & ~(0xff << shift16)) | (val << shift16)) & 0x3f7f; + /* Setting BIOS_RLS also sets GBL_STS and generates SMI. */ + if (dev->regs.reg_1c & 0x0400) { + dev->regs.pmsts |= 0x20; + if (dev->regs.pmen & 0x20) + acpi_update_irq(dev); + } + break; + case 0x20: + /* SMI Command Port */ + dev->regs.smi_cmd = val; + if (val == dev->regs.smi_en_val) { + dev->regs.reg_25 |= 0x08; + if (dev->regs.reg_26 & 0x08) + smi_raise(); + } else if (val == dev->regs.smi_dis_val) { + dev->regs.reg_25 |= 0x10; + if (dev->regs.reg_26 & 0x10) + smi_raise(); + } + break; + case 0x24: + dev->regs.reg_24 = val & 0x43; + break; + case 0x25: + dev->regs.reg_25 &= ~(val & 0x1f); + break; + case 0x26: + old = dev->regs.reg_26; + dev->regs.reg_26 = val & 0x3f; + if (!(old & 0x04) && (val & 0x04)) + timer_on_auto(&dev->per_timer, 16000000.0); + else if ((old & 0x04) && !(val & 0x04)) + timer_stop(&dev->per_timer); + break; + case 0x28: + dev->regs.smi_en_val = val; + break; + case 0x29: + dev->regs.smi_dis_val = val; + break; + case 0x2a: + dev->regs.mail_box = val; + break; + case 0x2b: + dev->regs.reg_2b = val & 0x01; + break; + default: + acpi_reg_write_common_regs(size, addr, val, priv); + /* Setting GBL_RLS also sets BIOS_STS and generates SMI. */ + if ((addr == 0x00) && !(dev->regs.pmsts & 0x20)) + dev->regs.reg_1c &= ~0x0400; + else if ((addr == 0x04) && (dev->regs.pmcntrl & 0x0004)) { + dev->regs.reg_25 |= 0x01; + if (dev->regs.reg_26 & 0x01) + acpi_raise_smi(dev, 1); + } + break; + } +} + +void +acpi_sis5595_pmu_event(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + + if (dev->vendor == VEN_SIS_5595_1997) + acpi_sis5595_smi_raise(dev); + else if (dev->regs.gpe_en & 0x00001000) { + dev->regs.gpe_sts |= 0x00001000; + acpi_sis5595_smi_raise(dev); + } +} + +void +acpi_sis5595_smbus_event(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + + if (dev->regs.gpe_en & 0x00000800) { + dev->regs.gpe_sts |= 0x00000800; + acpi_sis5595_smi_raise(dev); + } +} + +void +acpi_sis5595_software_smi(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + + if (dev->regs.leg_en & 0x01) { + dev->regs.leg_sts |= 0x01; + acpi_sis5595_smi_raise(dev); + } +} + +static void +acpi_reg_write_sis_5595(int size, uint16_t addr, uint8_t val, void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + int shift16; + int shift32; + uint8_t old; + uint8_t do_smi = 0; + + addr &= 0x3f; +#ifdef ENABLE_ACPI_LOG + if (size != 1) + acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val); +#endif + shift16 = (addr & 1) << 3; + shift32 = (addr & 3) << 3; + + switch (addr) { + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + dev->regs.reg_0c &= ~((val << shift32) & 0x001e); + break; + case 0x10: + dev->regs.enter_c2_ps = val; + break; + case 0x11: + dev->regs.enter_c3_ps = val; + break; + case 0x12: + dev->regs.reg_12 = val & 0x01; + break; + case 0x13: + dev->regs.reg_13 = val; + /* Setting BIOS_RLS also sets GBL_STS and generates SMI. */ + if (dev->regs.reg_13 & 0x02) { + dev->regs.pmsts |= 0x20; + if (dev->regs.pmen & 0x20) + acpi_update_irq(dev); + } + break; + case 0x14: + case 0x15: + case 0x16: + case 0x17: + if (dev->vendor == VEN_SIS_5595_1997) + dev->regs.gpe_sts &= ~((val << shift32) & 0xff03ffbf); + else + dev->regs.gpe_sts &= ~((val << shift32) & 0xff83ffff); + break; + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + if (dev->vendor == VEN_SIS_5595_1997) + dev->regs.gpe_en = ((dev->regs.gpe_en & ~(0xff << shift32)) | (val << shift32)); + else + dev->regs.gpe_en = ((dev->regs.gpe_en & ~(0xff << shift32)) | + (val << shift32)) & 0xff83ffff; + break; + case 0x1c: + dev->regs.gpe_pin = ((dev->regs.gpe_pin & ~(0xff << shift32)) | ((val & 0xff) << shift32)); + break; + case 0x1d: + dev->regs.gpe_pin = ((dev->regs.gpe_pin & ~(0x0f << shift32)) | ((val & 0x0f) << shift32)); + break; + case 0x1e: + dev->regs.gpe_pin = ((dev->regs.gpe_pin & ~(0x03 << shift32)) | ((val & 0x03) << shift32)); + break; + case 0x1f: + dev->regs.gp_tmr = val; + acpi_gp_timer_update(dev, (val != 0x00) && (dev->regs.gpe_en & 0x00000400), val); + break; + case 0x20: + dev->regs.gpe_io = ((dev->regs.gpe_io & ~(0x9f << shift32)) | ((val & 0x9f) << shift32)); + break; + case 0x21: + dev->regs.gpe_io = ((dev->regs.gpe_io & ~(0x0f << shift32)) | ((val & 0x0f) << shift32)); + break; + case 0x22: + dev->regs.gpe_io = ((dev->regs.gpe_io & ~(0x03 << shift32)) | ((val & 0x03) << shift32)); + break; + case 0x24: + dev->regs.gpe_pol = ((dev->regs.gpe_pol & ~(0xbf << shift32)) | ((val & 0xbf) << shift32)); + break; + case 0x25: + dev->regs.gpe_pol = ((dev->regs.gpe_pol & ~(0x0f << shift32)) | ((val & 0x0f) << shift32)); + break; + case 0x26: + dev->regs.gpe_pol = ((dev->regs.gpe_pol & ~(0x03 << shift32)) | ((val & 0x03) << shift32)); + break; + case 0x27: + dev->regs.gpe_pol = ((dev->regs.gpe_pol & ~(0x10 << shift32)) | ((val & 0x10) << shift32)); + break; + case 0x28: + dev->regs.gpe_mul = ((dev->regs.gpe_mul & ~(0xf9 << shift16)) | ((val & 0xf9) << shift16)); + break; + case 0x29: + dev->regs.gpe_mul = ((dev->regs.gpe_mul & ~(0x13 << shift16)) | ((val & 0x13) << shift16)); + break; + case 0x2a: + case 0x2b: + dev->regs.gpe_ctl = ((dev->regs.gpe_ctl & ~(0xff << shift16)) | ((val & 0xff) << shift16)); + break; + case 0x2c: + case 0x2d: + dev->regs.gpe_smi = ((dev->regs.gpe_smi & ~(0xff << shift16)) | ((val & 0xff) << shift16)); + break; + case 0x2e: + case 0x2f: + dev->regs.gpe_rl = ((dev->regs.gpe_rl & ~(0xff << shift16)) | ((val & 0xff) << shift16)); + break; + case 0x30: + dev->regs.leg_sts &= ~val; + break; + case 0x31: + old = dev->regs.leg_en; + dev->regs.leg_en = val; + if (!(old & 0x04) && (val & 0x04)) + timer_on_auto(&dev->per_timer, 16000000.0); + else if ((old & 0x04) && !(val & 0x04)) + timer_stop(&dev->per_timer); + break; + case 0x32: + if (dev->vendor == VEN_SIS_5595_1997) { + /* SMI Command Port */ + dev->regs.smi_cmd = val; + if (val == dev->regs.smi_en_val) { + dev->regs.leg_sts |= 0x08; + if (dev->regs.leg_en & 0x08) + acpi_sis5595_smi_raise(dev); + } else if (val == dev->regs.smi_dis_val) { + dev->regs.leg_sts |= 0x10; + if (dev->regs.leg_en & 0x10) + acpi_sis5595_smi_raise(dev); + } + } + break; + case 0x33: + dev->regs.tst_ctl = val & 0x01; + break; + case 0x34: + if (dev->vendor == VEN_SIS_5595_1997) + dev->regs.smi_en_val = val; + else + dev->regs.reg_34 = val; + break; + case 0x35: + if (dev->vendor == VEN_SIS_5595_1997) + dev->regs.smi_dis_val = val; + else { + /* SMI Command Port */ + dev->regs.smi_cmd = val; + dev->regs.leg_sts |= 0x10; + if (dev->regs.leg_en & 0x10) + acpi_sis5595_smi_raise(dev); + } + break; + case 0x36: + dev->regs.mail_box = val; + break; + case 0x38: + if (dev->vendor == VEN_SIS_5595) { + dev->regs.index = val; + smbus_sis5595_write_index(dev->smbus, val); + } + break; + case 0x39: + if (dev->vendor == VEN_SIS_5595) { + dev->regs.reg_ff = val & 0x3f; + smbus_sis5595_write_data(dev->smbus, val); + if (val & 0x20) { /* Set GPIO5_STS of GPE_STS */ + dev->regs.gpe_sts |= 0x00000008; + do_smi |= (dev->regs.gpe_en & 0x00000004); + } else if (val & 0x10) { /* Set GPIO10_STS of GPE_STS */ + dev->regs.gpe_sts |= 0x00000004; + do_smi |= (dev->regs.gpe_en & 0x00000008); + } else if (val & 0x08) { /* Set RI_STS in GPE_STS */ + dev->regs.gpe_sts |= 0x00000002; + do_smi |= (dev->regs.gpe_en & 0x00000002); + } else if (val & 0x04) /* Set WAK_STS of PM1_STS */ + dev->regs.pmsts |= 0x8000; + else if (val & 0x02) { /* Set RTC_STS of PM1_STS */ + dev->regs.pmsts |= 0x0400; + do_smi |= (dev->regs.pmen & 0x0400); + } else if (val & 0x01) { /* Set PWRBTN_STS of PM1_STS */ + dev->regs.pmsts |= 0x0100; + do_smi |= (dev->regs.pmen & 0x0100); + } + + if (do_smi) + acpi_sis5595_smi_raise(dev); + } + break; + default: + acpi_reg_write_common_regs(size, addr, val, priv); + /* Setting GBL_RLS also sets BIOS_STS and generates SMI. */ + if ((addr == 0x00) && !(dev->regs.pmsts & 0x20)) + dev->regs.reg_13 &= ~0x02; + else if ((addr == 0x04) && (dev->regs.pmcntrl & 0x0004)) { + dev->regs.leg_sts |= 0x01; + if (dev->regs.leg_en & 0x01) + acpi_sis5595_smi_raise(dev); + } + break; + } +} + static uint32_t acpi_reg_read_common(int size, uint16_t addr, void *priv) { const acpi_t *dev = (acpi_t *) priv; uint8_t ret = 0xff; - if (dev->vendor == VEN_ALI) - ret = acpi_reg_read_ali(size, addr, priv); - else if (dev->vendor == VEN_VIA) - ret = acpi_reg_read_via(size, addr, priv); - else if (dev->vendor == VEN_VIA_596B) - ret = acpi_reg_read_via_596b(size, addr, priv); - else if (dev->vendor == VEN_INTEL) - ret = acpi_reg_read_intel(size, addr, priv); - else if (dev->vendor == VEN_SMC) - ret = acpi_reg_read_smc(size, addr, priv); + switch (dev->vendor) { + case VEN_ALI: + ret = acpi_reg_read_ali(size, addr, priv); + break; + case VEN_VIA: + ret = acpi_reg_read_via(size, addr, priv); + break; + case VEN_VIA_596B: + ret = acpi_reg_read_via_596b(size, addr, priv); + break; + case VEN_INTEL: + ret = acpi_reg_read_intel(size, addr, priv); + break; + case VEN_SMC: + ret = acpi_reg_read_smc(size, addr, priv); + break; + case VEN_SIS_5582: + ret = acpi_reg_read_sis_5582(size, addr, priv); + break; + case VEN_SIS_5595_1997: + case VEN_SIS_5595: + ret = acpi_reg_read_sis_5595(size, addr, priv); + break; + } return ret; } @@ -1218,16 +1918,30 @@ acpi_reg_write_common(int size, uint16_t addr, uint8_t val, void *priv) { const acpi_t *dev = (acpi_t *) priv; - if (dev->vendor == VEN_ALI) - acpi_reg_write_ali(size, addr, val, priv); - else if (dev->vendor == VEN_VIA) - acpi_reg_write_via(size, addr, val, priv); - else if (dev->vendor == VEN_VIA_596B) - acpi_reg_write_via_596b(size, addr, val, priv); - else if (dev->vendor == VEN_INTEL) - acpi_reg_write_intel(size, addr, val, priv); - else if (dev->vendor == VEN_SMC) - acpi_reg_write_smc(size, addr, val, priv); + switch (dev->vendor) { + case VEN_ALI: + acpi_reg_write_ali(size, addr, val, priv); + break; + case VEN_VIA: + acpi_reg_write_via(size, addr, val, priv); + break; + case VEN_VIA_596B: + acpi_reg_write_via_596b(size, addr, val, priv); + break; + case VEN_INTEL: + acpi_reg_write_intel(size, addr, val, priv); + break; + case VEN_SMC: + acpi_reg_write_smc(size, addr, val, priv); + break; + case VEN_SIS_5582: + acpi_reg_write_sis_5582(size, addr, val, priv); + break; + case VEN_SIS_5595_1997: + case VEN_SIS_5595: + acpi_reg_write_sis_5595(size, addr, val, priv); + break; + } } static uint32_t @@ -1396,6 +2110,9 @@ acpi_update_io_mapping(acpi_t *dev, uint32_t base, int chipset_en) default: case VEN_ALI: case VEN_INTEL: + case VEN_SIS_5582: + case VEN_SIS_5595_1997: + case VEN_SIS_5595: size = 0x040; break; case VEN_SMC: @@ -1677,6 +2394,20 @@ acpi_reset(void *priv) acpi_update_irq(dev); dev->irq_state = 0; + + timer_disable(&dev->gp_timer); + + acpi_last_clock = 0ULL; + acpi_count = 0; + + timer_disable(&dev->per_timer); + + if ((dev->vendor == VEN_SIS_5595_1997) || (dev->vendor == VEN_SIS_5595)) { + dev->regs.reg_13 = 0x20; + dev->regs.gp_tmr = 0xff; + dev->regs.gpe_io = 0x00030b9f; + dev->regs.gpe_mul = 0x1001; + } } static void @@ -1689,6 +2420,33 @@ acpi_speed_changed(void *priv) if (timer_enabled) timer_on_auto(&dev->timer, acpi_get_overflow_period(dev)); + + if ((dev->vendor & 0xffff) == 0x1039) { + if (timer_is_on(&dev->gp_timer)) { + timer_stop(&dev->gp_timer); + + if (dev->vendor == VEN_SIS_5595_1997) + acpi_gp_timer_update(dev, (dev->regs.gpe_en & 0x20000000), acpi_count); + else if (dev->vendor == VEN_SIS_5595) + acpi_gp_timer_update(dev, (dev->regs.gpe_en & 0x00000400), acpi_count); + else + acpi_gp_timer_update(dev, (dev->regs.reg_16 & 0x2000), acpi_count); + } + + if (timer_is_on(&dev->per_timer)) { + timer_stop(&dev->per_timer); + + timer_on_auto(&dev->per_timer, 16000000.0); + } + } +} + +void * +acpi_get_smbus(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + + return dev->smbus; } static void @@ -1767,6 +2525,28 @@ acpi_init(const device_t *info) dev->suspend_types[4] = SUS_SUSPEND; break; + case VEN_SIS_5582: + dev->suspend_types[0] = SUS_SUSPEND; /* S1 */ + dev->suspend_types[4] = SUS_POWER_OFF; /* S5 */ + + timer_add(&dev->gp_timer, acpi_gp_timer, dev, 0); + timer_add(&dev->per_timer, acpi_per_timer, dev, 0); + break; + + case VEN_SIS_5595_1997: + case VEN_SIS_5595: + dev->suspend_types[1] = SUS_SUSPEND; + dev->suspend_types[2] = SUS_SUSPEND; + dev->suspend_types[3] = SUS_SUSPEND | SUS_NVR | SUS_RESET_CPU | SUS_RESET_PCI; + dev->suspend_types[4] = SUS_POWER_OFF; + dev->suspend_types[5] = SUS_POWER_OFF; + + timer_add(&dev->gp_timer, acpi_gp_timer, dev, 0); + timer_add(&dev->per_timer, acpi_per_timer, dev, 0); + + dev->smbus = device_add(&sis5595_smbus_device); + break; + default: break; } @@ -1854,3 +2634,45 @@ const device_t acpi_smc_device = { .force_redraw = NULL, .config = NULL }; + +const device_t acpi_sis_5582_device = { + .name = "SiS 5582 ACPI", + .internal_name = "acpi_sis_5582", + .flags = DEVICE_PCI, + .local = VEN_SIS_5582, + .init = acpi_init, + .close = acpi_close, + .reset = acpi_reset, + { .available = NULL }, + .speed_changed = acpi_speed_changed, + .force_redraw = NULL, + .config = NULL +}; + +const device_t acpi_sis_5595_1997_device = { + .name = "SiS 5595 (1997) ACPI", + .internal_name = "acpi_sis_5595_1997", + .flags = DEVICE_PCI, + .local = VEN_SIS_5595_1997, + .init = acpi_init, + .close = acpi_close, + .reset = acpi_reset, + { .available = NULL }, + .speed_changed = acpi_speed_changed, + .force_redraw = NULL, + .config = NULL +}; + +const device_t acpi_sis_5595_device = { + .name = "SiS 5595 ACPI", + .internal_name = "acpi_sis_5595", + .flags = DEVICE_PCI, + .local = VEN_SIS_5595, + .init = acpi_init, + .close = acpi_close, + .reset = acpi_reset, + { .available = NULL }, + .speed_changed = acpi_speed_changed, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/CMakeLists.txt b/src/chipset/CMakeLists.txt index 0f3c78c84..0406ea0b8 100644 --- a/src/chipset/CMakeLists.txt +++ b/src/chipset/CMakeLists.txt @@ -18,9 +18,11 @@ add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1435.c ali14 compaq_386.c contaq_82c59x.c cs4031.c intel_420ex.c intel_4x0.c intel_i450kx.c intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c opti495.c opti602.c opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c - sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c via_vt82c49x.c via_vt82c505.c - sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c umc_8886.c - umc_hb4.c via_apollo.c via_pipc.c vl82c480.c wd76c10.c) + sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c sis_5581.c sis_5591.c sis_5600.c + sis_5511_h2p.c sis_5571_h2p.c sis_5581_h2p.c sis_5591_h2p.c sis_5600_h2p.c + sis_5513_p2i.c sis_5513_ide.c sis_5572_usb.c sis_5595_pmu.c sis_55xx.c via_vt82c49x.c + via_vt82c505.c sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c + umc_8886.c umc_hb4.c umc_8890.c via_apollo.c via_pipc.c vl82c480.c wd76c10.c) if(OLIVETTI) target_sources(chipset PRIVATE olivetti_eva.c) diff --git a/src/chipset/sis_5511.c b/src/chipset/sis_5511.c index e58066c95..aa841ed9c 100644 --- a/src/chipset/sis_5511.c +++ b/src/chipset/sis_5511.c @@ -25,9 +25,10 @@ #include <86box/device.h> #include <86box/io.h> #include <86box/timer.h> - #include <86box/mem.h> #include <86box/nvr.h> +#include <86box/apm.h> +#include <86box/acpi.h> #include <86box/hdd.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> @@ -41,7 +42,7 @@ #include <86box/port_92.h> #include <86box/smram.h> #include <86box/spd.h> - +#include <86box/sis_55xx.h> #include <86box/chipset.h> #ifdef ENABLE_SIS_5511_LOG @@ -63,573 +64,53 @@ sis_5511_log(const char *fmt, ...) #endif typedef struct sis_5511_t { - uint8_t index; - uint8_t nb_slot; - uint8_t sb_slot; - uint8_t pad; + uint8_t nb_slot; + uint8_t sb_slot; - uint8_t regs[16]; - uint8_t states[7]; + void *h2p; - uint8_t slic_regs[4096]; + void *p2i; + void *ide; - uint8_t pci_conf[256]; - uint8_t pci_conf_sb[2][256]; - - mem_mapping_t slic_mapping; - - sff8038i_t *bm[2]; - smram_t *smram; - port_92_t *port_92; - void *pit; - nvr_t *nvr; - - uint8_t (*pit_read_reg)(void *priv, uint8_t reg); + sis_55xx_common_t *sis; } sis_5511_t; static void -sis_5511_shadow_recalc(sis_5511_t *dev) +sis_5511_write(int func, int addr, uint8_t val, void *priv) { - int state; - uint32_t base; - - for (uint8_t i = 0x80; i <= 0x86; i++) { - if (i == 0x86) { - if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { - state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; - mem_set_mem_state_both(0xf0000, 0x10000, state); - sis_5511_log("000F0000-000FFFFF\n"); - } - } else { - base = ((i & 0x07) << 15) + 0xc0000; - - if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { - state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; - mem_set_mem_state_both(base, 0x4000, state); - sis_5511_log("%08X-%08X\n", base, base + 0x3fff); - } - - if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) { - state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; - mem_set_mem_state_both(base + 0x4000, 0x4000, state); - sis_5511_log("%08X-%08X\n", base + 0x4000, base + 0x7fff); - } - } - - dev->states[i & 0x0f] = dev->pci_conf[i]; - } - - flushmmucache_nopc(); -} - -static void -sis_5511_smram_recalc(sis_5511_t *dev) -{ - smram_disable_all(); - - switch (dev->pci_conf[0x65] >> 6) { - case 0: - smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); - break; - case 1: - smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); - break; - case 2: - smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); - break; - - default: - break; - } - - flushmmucache(); -} - -static void -sis_5511_write(UNUSED(int func), int addr, uint8_t val, void *priv) -{ - sis_5511_t *dev = (sis_5511_t *) priv; + const sis_5511_t *dev = (sis_5511_t *) priv; sis_5511_log("SiS 5511: [W] dev->pci_conf[%02X] = %02X\n", addr, val); - if (func == 0x00) switch (addr) { - case 0x07: /* Status - High Byte */ - dev->pci_conf[addr] &= 0xb0; - break; - - case 0x50: - dev->pci_conf[addr] = val; - cpu_cache_ext_enabled = !!(val & 0x40); - cpu_update_waitstates(); - break; - - case 0x51: - dev->pci_conf[addr] = val & 0xfe; - break; - - case 0x52: - dev->pci_conf[addr] = val & 0x3f; - break; - - case 0x53: - case 0x54: - dev->pci_conf[addr] = val; - break; - - case 0x55: - dev->pci_conf[addr] = val & 0xf8; - break; - - case 0x56 ... 0x59: - dev->pci_conf[addr] = val; - break; - - case 0x5a: - /* TODO: Fast Gate A20 Emulation and Fast Reset Emulation on the KBC. - The former (bit 7) means the chipset intercepts D1h to 64h and 00h to 60h. - The latter (bit 6) means the chipset intercepts all odd FXh to 64h. - Bit 5 sets fast reset latency. This should be fixed on the other SiS - chipsets as well. */ - dev->pci_conf[addr] = val; - break; - - case 0x5b: - dev->pci_conf[addr] = val & 0xf7; - break; - - case 0x5c: - dev->pci_conf[addr] = val & 0xcf; - break; - - case 0x5d: - dev->pci_conf[addr] = val; - break; - - case 0x5e: - dev->pci_conf[addr] = val & 0xfe; - break; - - case 0x5f: - dev->pci_conf[addr] = val & 0xfe; - break; - - case 0x60: - dev->pci_conf[addr] = val & 0x3e; - if ((dev->pci_conf[0x68] & 1) && (val & 2)) { - smi_raise(); - dev->pci_conf[0x69] |= 1; - } - break; - - case 0x61 ... 0x64: - dev->pci_conf[addr] = val; - break; - - case 0x65: - dev->pci_conf[addr] = val & 0xd0; - sis_5511_smram_recalc(dev); - break; - - case 0x66: - dev->pci_conf[addr] = val & 0x7f; - break; - - case 0x67: - case 0x68: - dev->pci_conf[addr] = val; - break; - - case 0x69: - dev->pci_conf[addr] &= val; - break; - - case 0x6a ... 0x6e: - dev->pci_conf[addr] = val; - break; - - case 0x6f: - dev->pci_conf[addr] = val & 0x3f; - break; - - case 0x70: /* DRAM Bank Register 0-0 */ - case 0x72: /* DRAM Bank Register 0-1 */ - case 0x74: /* DRAM Bank Register 1-0 */ - case 0x76: /* DRAM Bank Register 1-1 */ - case 0x78: /* DRAM Bank Register 2-0 */ - case 0x7a: /* DRAM Bank Register 2-1 */ - case 0x7c: /* DRAM Bank Register 3-0 */ - case 0x7e: /* DRAM Bank Register 3-1 */ - spd_write_drbs(dev->pci_conf, 0x70, 0x7e, 0x82); - break; - - case 0x71: /* DRAM Bank Register 0-0 */ - dev->pci_conf[addr] = val; - break; - - case 0x75: /* DRAM Bank Register 1-0 */ - case 0x79: /* DRAM Bank Register 2-0 */ - case 0x7d: /* DRAM Bank Register 3-0 */ - dev->pci_conf[addr] = val & 0x7f; - break; - - case 0x73: /* DRAM Bank Register 0-1 */ - case 0x77: /* DRAM Bank Register 1-1 */ - case 0x7b: /* DRAM Bank Register 2-1 */ - case 0x7f: /* DRAM Bank Register 3-1 */ - dev->pci_conf[addr] = val & 0x83; - break; - - case 0x80 ... 0x85: - dev->pci_conf[addr] = val & 0xee; - sis_5511_shadow_recalc(dev); - break; - case 0x86: - dev->pci_conf[addr] = val & 0xe8; - sis_5511_shadow_recalc(dev); - break; - - case 0x90 ... 0x93: /* 5512 General Purpose Register Index */ - dev->pci_conf[addr] = val; - break; - - default: - break; - } -} - -static void -sis_5511_slic_write(uint32_t addr, uint8_t val, void *priv) -{ - sis_5511_t *dev = (sis_5511_t *) priv; - - addr &= 0x00000fff; - - switch (addr) { - case 0x00000000: - case 0x00000008: /* 0x00000008 is a SiS 5512 register. */ - dev->slic_regs[addr] = val; - break; - case 0x00000010: - case 0x00000018: - case 0x00000028: - case 0x00000038: - dev->slic_regs[addr] = val & 0x01; - break; - case 0x00000030: - dev->slic_regs[addr] = val & 0x0f; - mem_mapping_set_addr(&dev->slic_mapping, - (((uint32_t) (val & 0x0f)) << 28) | 0x0fc00000, 0x00001000); - break; - } + if (func == 0x00) + sis_5511_host_to_pci_write(addr, val, dev->h2p); } static uint8_t -sis_5511_read(UNUSED(int func), int addr, void *priv) +sis_5511_read(int func, int addr, void *priv) { const sis_5511_t *dev = (sis_5511_t *) priv; uint8_t ret = 0xff; if (func == 0x00) - ret = dev->pci_conf[addr]; + ret = sis_5511_host_to_pci_read(addr, dev->h2p); sis_5511_log("SiS 5511: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); return ret; } -static uint8_t -sis_5511_slic_read(uint32_t addr, void *priv) -{ - sis_5511_t *dev = (sis_5511_t *) priv; - uint8_t ret = 0xff; - - addr &= 0x00000fff; - - switch (addr) { - case 0x00000008: /* 0x00000008 is a SiS 5512 register. */ - ret = dev->slic_regs[addr]; - break; - } - - return ret; -} - -void -sis_5513_pci_to_isa_write(int addr, uint8_t val, sis_5511_t *dev) -{ - sis_5511_log("SiS 5513 P2I: [W] dev->pci_conf_sb[0][%02X] = %02X\n", addr, val); - - switch (addr) { - case 0x04: /* Command */ - dev->pci_conf_sb[0][addr] = val & 0x0f; - break; - - case 0x07: /* Status */ - dev->pci_conf_sb[0][addr] = (dev->pci_conf_sb[0][addr] & 0x06) & ~(val & 0x30); - break; - - case 0x40: /* BIOS Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x3f; - break; - - case 0x41: /* INTA# Remapping Control Register */ - case 0x42: /* INTB# Remapping Control Register */ - case 0x43: /* INTC# Remapping Control Register */ - case 0x44: /* INTD# Remapping Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x8f; - pci_set_irq_routing(addr & 0x07, (val & 0x80) ? PCI_IRQ_DISABLED : (val & 0x0f)); - break; - - case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ - case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ - case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ - case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x60: /* MIRQ0 Remapping Control Register */ - case 0x61: /* MIRQ1 Remapping Control Register */ - sis_5511_log("Set MIRQ routing: MIRQ%i -> %02X\n", addr & 0x01, val); - dev->pci_conf_sb[0][addr] = val & 0xcf; - if (val & 0x80) - pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), PCI_IRQ_DISABLED); - else - pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf); - break; - - case 0x62: /* On-board Device DMA Control Register */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x63: /* IDEIRQ Remapping Control Register */ - sis_5511_log("Set MIRQ routing: IDEIRQ -> %02X\n", val); - dev->pci_conf_sb[0][addr] = val & 0x8f; - if (val & 0x80) - pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); - else - pci_set_mirq_routing(PCI_MIRQ2, val & 0xf); - break; - - case 0x64: /* GPIO0 Control Register */ - dev->pci_conf_sb[0][addr] = val & 0xef; - break; - - case 0x65: - dev->pci_conf_sb[0][addr] = val & 0x80; - break; - - case 0x66: /* GPIO0 Output Mode Control Register */ - case 0x67: /* GPIO0 Output Mode Control Register */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x6a: /* GPIO Status Register */ - dev->pci_conf_sb[0][addr] |= (val & 0x10); - dev->pci_conf_sb[0][addr] &= ~(val & 0x01); - break; - - default: - break; - } -} - -static void -sis_5513_ide_irq_handler(sis_5511_t *dev) -{ - if (dev->pci_conf_sb[1][0x09] & 0x01) { - /* Primary IDE is native. */ - sis_5511_log("Primary IDE IRQ mode: Native, Native\n"); - sff_set_irq_mode(dev->bm[0], IRQ_MODE_SIS_551X); - } else { - /* Primary IDE is legacy. */ - sis_5511_log("Primary IDE IRQ mode: IRQ14, IRQ15\n"); - sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); - } - - if (dev->pci_conf_sb[1][0x09] & 0x04) { - /* Secondary IDE is native. */ - sis_5511_log("Secondary IDE IRQ mode: Native, Native\n"); - sff_set_irq_mode(dev->bm[1], IRQ_MODE_SIS_551X); - } else { - /* Secondary IDE is legacy. */ - sis_5511_log("Secondary IDE IRQ mode: IRQ14, IRQ15\n"); - sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); - } -} - -static void -sis_5513_ide_handler(sis_5511_t *dev) -{ - uint8_t ide_io_on = dev->pci_conf_sb[1][0x04] & 0x01; - - uint16_t native_base_pri_addr = (dev->pci_conf_sb[1][0x11] | dev->pci_conf_sb[1][0x10] << 8) & 0xfffe; - uint16_t native_side_pri_addr = (dev->pci_conf_sb[1][0x15] | dev->pci_conf_sb[1][0x14] << 8) & 0xfffe; - uint16_t native_base_sec_addr = (dev->pci_conf_sb[1][0x19] | dev->pci_conf_sb[1][0x18] << 8) & 0xfffe; - uint16_t native_side_sec_addr = (dev->pci_conf_sb[1][0x1c] | dev->pci_conf_sb[1][0x1b] << 8) & 0xfffe; - - uint16_t current_pri_base; - uint16_t current_pri_side; - uint16_t current_sec_base; - uint16_t current_sec_side; - - /* Primary Channel Programming */ - current_pri_base = (!(dev->pci_conf_sb[1][0x09] & 1)) ? 0x01f0 : native_base_pri_addr; - current_pri_side = (!(dev->pci_conf_sb[1][0x09] & 1)) ? 0x03f6 : native_side_pri_addr; - - /* Secondary Channel Programming */ - current_sec_base = (!(dev->pci_conf_sb[1][0x09] & 4)) ? 0x0170 : native_base_sec_addr; - current_sec_side = (!(dev->pci_conf_sb[1][0x09] & 4)) ? 0x0376 : native_side_sec_addr; - - sis_5511_log("sis_5513_ide_handler(): Disabling primary IDE...\n"); - ide_pri_disable(); - sis_5511_log("sis_5513_ide_handler(): Disabling secondary IDE...\n"); - ide_sec_disable(); - - if (ide_io_on) { - /* Primary Channel Setup */ - if (dev->pci_conf_sb[1][0x4a] & 0x02) { - sis_5511_log("sis_5513_ide_handler(): Primary IDE base now %04X...\n", current_pri_base); - ide_set_base(0, current_pri_base); - sis_5511_log("sis_5513_ide_handler(): Primary IDE side now %04X...\n", current_pri_side); - ide_set_side(0, current_pri_side); - - sis_5511_log("sis_5513_ide_handler(): Enabling primary IDE...\n"); - ide_pri_enable(); - - sis_5511_log("SiS 5513 PRI: BASE %04x SIDE %04x\n", current_pri_base, current_pri_side); - } - - /* Secondary Channel Setup */ - if (dev->pci_conf_sb[1][0x4a] & 0x04) { - sis_5511_log("sis_5513_ide_handler(): Secondary IDE base now %04X...\n", current_sec_base); - ide_set_base(1, current_sec_base); - sis_5511_log("sis_5513_ide_handler(): Secondary IDE side now %04X...\n", current_sec_side); - ide_set_side(1, current_sec_side); - - sis_5511_log("sis_5513_ide_handler(): Enabling secondary IDE...\n"); - ide_sec_enable(); - - sis_5511_log("SiS 5513: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side); - } - } - - sff_bus_master_handler(dev->bm[0], ide_io_on, - ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + 0); - sff_bus_master_handler(dev->bm[1], ide_io_on, - ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + 8); -} - -void -sis_5513_ide_write(int addr, uint8_t val, sis_5511_t *dev) -{ - sis_5511_log("SiS 5513 IDE: [W] dev->pci_conf_sb[1][%02X] = %02X\n", addr, val); - - switch (addr) { - case 0x04: /* Command low byte */ - dev->pci_conf_sb[1][addr] = val & 0x05; - sis_5513_ide_handler(dev); - break; - case 0x06: /* Status low byte */ - dev->pci_conf_sb[1][addr] = val & 0x20; - break; - case 0x07: /* Status high byte */ - dev->pci_conf_sb[1][addr] = (dev->pci_conf_sb[1][addr] & 0x06) & ~(val & 0x38); - break; - case 0x09: /* Programming Interface Byte */ - dev->pci_conf_sb[1][addr] = (dev->pci_conf_sb[1][addr] & 0x8a) | (val & 0x05); - sis_5513_ide_irq_handler(dev); - sis_5513_ide_handler(dev); - break; - case 0x0d: /* Latency Timer */ - dev->pci_conf_sb[1][addr] = val; - break; - - /* Primary Base Address */ - case 0x10: - case 0x11: - case 0x14: - case 0x15: - fallthrough; - - /* Secondary Base Address */ - case 0x18: - case 0x19: - case 0x1c: - case 0x1d: - fallthrough; - - /* Bus Mastering Base Address */ - case 0x20: - case 0x21: - if (addr == 0x20) - dev->pci_conf_sb[1][addr] = (val & 0xe0) | 0x01; - else - dev->pci_conf_sb[1][addr] = val; - sis_5513_ide_handler(dev); - break; - - case 0x30: /* Expansion ROM Base Address */ - case 0x31: /* Expansion ROM Base Address */ - case 0x32: /* Expansion ROM Base Address */ - case 0x33: /* Expansion ROM Base Address */ - dev->pci_conf_sb[1][addr] = val; - break; - - case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */ - case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */ - case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */ - case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */ - case 0x48: /* IDE Command Recovery Time Control */ - dev->pci_conf_sb[1][addr] = val & 0x0f; - break; - - case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */ - case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */ - case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */ - case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */ - case 0x49: /* IDE Command Active Time Control */ - dev->pci_conf_sb[1][addr] = val & 0x07; - break; - - case 0x4a: /* IDE General Control Register 0 */ - dev->pci_conf_sb[1][addr] = val & 0x9e; - sis_5513_ide_handler(dev); - break; - - case 0x4b: /* IDE General Control Register 1 */ - dev->pci_conf_sb[1][addr] = val & 0xef; - break; - - case 0x4c: /* Prefetch Count of Primary Channel (Low Byte) */ - case 0x4d: /* Prefetch Count of Primary Channel (High Byte) */ - case 0x4e: /* Prefetch Count of Secondary Channel (Low Byte) */ - case 0x4f: /* Prefetch Count of Secondary Channel (High Byte) */ - dev->pci_conf_sb[1][addr] = val; - break; - - default: - break; - } -} - static void sis_5513_write(int func, int addr, uint8_t val, void *priv) { - sis_5511_t *dev = (sis_5511_t *) priv; + const sis_5511_t *dev = (sis_5511_t *) priv; - switch (func) { - default: - break; - case 0: - sis_5513_pci_to_isa_write(addr, val, dev); - break; - case 1: - sis_5513_ide_write(addr, val, dev); - break; - } + sis_5511_log("SiS 5513: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + if (func == 0x00) + sis_5513_pci_to_isa_write(addr, val, dev->p2i); + else if (func == 0x01) + sis_5513_ide_write(addr, val, dev->ide); } static uint8_t @@ -638,281 +119,21 @@ sis_5513_read(int func, int addr, void *priv) const sis_5511_t *dev = (sis_5511_t *) priv; uint8_t ret = 0xff; - if (func == 0x00) { - switch (addr) { - default: - ret = dev->pci_conf_sb[func][addr]; - break; - case 0x4c ... 0x4f: - ret = pic_read_icw(0, addr & 0x03); - break; - case 0x50 ... 0x53: - ret = pic_read_icw(1, addr & 0x03); - break; - case 0x54 ... 0x55: - ret = pic_read_ocw(0, addr & 0x01); - break; - case 0x56 ... 0x57: - ret = pic_read_ocw(1, addr & 0x01); - break; - case 0x58 ... 0x5f: - ret = dev->pit_read_reg(dev->pit, addr & 0x07); - break; - } + if (func == 0x00) + ret = sis_5513_pci_to_isa_read(addr, dev->p2i); + else if (func == 0x01) + ret = sis_5513_ide_read(addr, dev->ide); - sis_5511_log("SiS 5513 P2I: [R] dev->pci_conf_sb[0][%02X] = %02X\n", addr, ret); - } else if (func == 0x01) { - if (addr == 0x3d) - ret = (((dev->pci_conf_sb[0x01][0x4b] & 0xc0) == 0xc0) || - (dev->pci_conf_sb[0x01][0x09] & 0x05)) ? PCI_INTA : 0x00; - else - ret = dev->pci_conf_sb[func][addr]; - - sis_5511_log("SiS 5513 IDE: [R] dev->pci_conf_sb[1][%02X] = %02X\n", addr, ret); - } + sis_5511_log("SiS 5513: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); return ret; } -static void -sis_5513_isa_write(uint16_t addr, uint8_t val, void *priv) -{ - sis_5511_t *dev = (sis_5511_t *) priv; - - switch (addr) { - case 0x22: - dev->index = val - 0x50; - break; - case 0x23: - sis_5511_log("SiS 5513 ISA: [W] dev->regs[%02X] = %02X\n", dev->index + 0x50, val); - - switch (dev->index) { - case 0x00: - dev->regs[dev->index] = val & 0xed; - switch (val >> 6) { - case 0: - cpu_set_isa_speed(7159091); - break; - case 1: - cpu_set_isa_pci_div(4); - break; - case 2: - cpu_set_isa_pci_div(3); - break; - - default: - break; - } - nvr_bank_set(0, !!(val & 0x08), dev->nvr); - break; - case 0x01: - dev->regs[dev->index] = val & 0xf4; - break; - case 0x03: - dev->regs[dev->index] = val & 3; - break; - case 0x04: /* BIOS Register */ - dev->regs[dev->index] = val; - break; - case 0x05: - dev->regs[dev->index] = val; - outb(0x70, val); - break; - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - dev->regs[dev->index] = val; - break; - - default: - break; - } - break; - - default: - break; - } -} - -static uint8_t -sis_5513_isa_read(uint16_t addr, void *priv) -{ - const sis_5511_t *dev = (sis_5511_t *) priv; - uint8_t ret = 0xff; - - if (addr == 0x23) { - if (dev->index == 0x05) - ret = inb(0x70); - else - ret = dev->regs[dev->index]; - - sis_5511_log("SiS 5513 ISA: [R] dev->regs[%02X] = %02X\n", dev->index + 0x50, ret); - } - - return ret; -} - -static void -sis_5511_reset(void *priv) -{ - sis_5511_t *dev = (sis_5511_t *) priv; - - /* SiS 5511 */ - dev->pci_conf[0x00] = 0x39; - dev->pci_conf[0x01] = 0x10; - dev->pci_conf[0x02] = 0x11; - dev->pci_conf[0x03] = 0x55; - dev->pci_conf[0x04] = 0x07; - dev->pci_conf[0x05] = dev->pci_conf[0x06] = 0x00; - dev->pci_conf[0x07] = 0x02; - dev->pci_conf[0x08] = 0x00; - dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00; - dev->pci_conf[0x0b] = 0x06; - dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x00; - dev->pci_conf[0x52] = 0x20; - dev->pci_conf[0x53] = dev->pci_conf[0x54] = 0x00; - dev->pci_conf[0x55] = dev->pci_conf[0x56] = 0x00; - dev->pci_conf[0x57] = dev->pci_conf[0x58] = 0x00; - dev->pci_conf[0x59] = dev->pci_conf[0x5a] = 0x00; - dev->pci_conf[0x5b] = dev->pci_conf[0x5c] = 0x00; - dev->pci_conf[0x5d] = dev->pci_conf[0x5e] = 0x00; - dev->pci_conf[0x5f] = dev->pci_conf[0x60] = 0x00; - dev->pci_conf[0x61] = dev->pci_conf[0x62] = 0xff; - dev->pci_conf[0x63] = 0xff; - dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00; - dev->pci_conf[0x66] = 0x00; - dev->pci_conf[0x67] = 0xff; - dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00; - dev->pci_conf[0x6a] = 0x00; - dev->pci_conf[0x6b] = dev->pci_conf[0x6c] = 0xff; - dev->pci_conf[0x6d] = dev->pci_conf[0x6e] = 0xff; - dev->pci_conf[0x6f] = 0x00; - dev->pci_conf[0x70] = dev->pci_conf[0x72] = 0x04; - dev->pci_conf[0x74] = dev->pci_conf[0x76] = 0x04; - dev->pci_conf[0x78] = dev->pci_conf[0x7a] = 0x04; - dev->pci_conf[0x7c] = dev->pci_conf[0x7e] = 0x04; - dev->pci_conf[0x71] = dev->pci_conf[0x75] = 0x00; - dev->pci_conf[0x73] = dev->pci_conf[0x77] = 0x80; - dev->pci_conf[0x79] = dev->pci_conf[0x7d] = 0x00; - dev->pci_conf[0x7b] = dev->pci_conf[0x7f] = 0x80; - dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00; - dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00; - dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0x00; - dev->pci_conf[0x86] = 0x00; - - cpu_cache_ext_enabled = 0; - cpu_update_waitstates(); - - sis_5511_smram_recalc(dev); - sis_5511_shadow_recalc(dev); - - flushmmucache(); - - memset(dev->slic_regs, 0x00, 4096 * sizeof(uint8_t)); - dev->slic_regs[0x18] = 0x0f; - - mem_mapping_set_addr(&dev->slic_mapping, 0xffc00000, 0x00001000); - - /* SiS 5513 */ - dev->pci_conf_sb[0][0x00] = 0x39; - dev->pci_conf_sb[0][0x01] = 0x10; - dev->pci_conf_sb[0][0x02] = 0x08; - dev->pci_conf_sb[0][0x03] = 0x00; - dev->pci_conf_sb[0][0x04] = 0x07; - dev->pci_conf_sb[0][0x05] = dev->pci_conf_sb[0][0x06] = 0x00; - dev->pci_conf_sb[0][0x07] = 0x02; - dev->pci_conf_sb[0][0x08] = dev->pci_conf_sb[0][0x09] = 0x00; - dev->pci_conf_sb[0][0x0a] = 0x01; - dev->pci_conf_sb[0][0x0b] = 0x06; - dev->pci_conf_sb[0][0x0e] = 0x80; - dev->pci_conf_sb[0][0x40] = 0x00; - dev->pci_conf_sb[0][0x41] = dev->pci_conf_sb[0][0x42] = 0x80; - dev->pci_conf_sb[0][0x43] = dev->pci_conf_sb[0][0x44] = 0x80; - dev->pci_conf_sb[0][0x48] = dev->pci_conf_sb[0][0x49] = 0x00; - dev->pci_conf_sb[0][0x4a] = dev->pci_conf_sb[0][0x4b] = 0x00; - dev->pci_conf_sb[0][0x60] = dev->pci_conf_sb[0][0x61] = 0x80; - dev->pci_conf_sb[0][0x62] = 0x00; - dev->pci_conf_sb[0][0x63] = 0x80; - dev->pci_conf_sb[0][0x64] = 0x00; - dev->pci_conf_sb[0][0x65] = 0x00; - dev->pci_conf_sb[0][0x66] = dev->pci_conf_sb[0][0x67] = 0x00; - dev->pci_conf_sb[0][0x68] = dev->pci_conf_sb[0][0x69] = 0x00; - dev->pci_conf_sb[0][0x6a] = 0x04; - - pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); - - pci_set_mirq_routing(PCI_MIRQ0, PCI_IRQ_DISABLED); - pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED); - pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); - - dev->regs[0x00] = dev->regs[0x01] = 0x00; - dev->regs[0x03] = dev->regs[0x04] = 0x00; - dev->regs[0x05] = 0x00; - dev->regs[0x08] = dev->regs[0x09] = 0x00; - dev->regs[0x0a] = dev->regs[0x0b] = 0x00; - - cpu_set_isa_speed(7159091); - nvr_bank_set(0, 0, dev->nvr); - - /* SiS 5513 IDE Controller */ - dev->pci_conf_sb[1][0x00] = 0x39; - dev->pci_conf_sb[1][0x01] = 0x10; - dev->pci_conf_sb[1][0x02] = 0x13; - dev->pci_conf_sb[1][0x03] = 0x55; - dev->pci_conf_sb[1][0x04] = dev->pci_conf_sb[1][0x05] = 0x00; - dev->pci_conf_sb[1][0x06] = dev->pci_conf_sb[1][0x07] = 0x00; - dev->pci_conf_sb[1][0x08] = 0x00; - dev->pci_conf_sb[1][0x09] = 0x8a; - dev->pci_conf_sb[1][0x0a] = dev->pci_conf_sb[1][0x0b] = 0x01; - dev->pci_conf_sb[1][0x0c] = dev->pci_conf_sb[1][0x0d] = 0x00; - dev->pci_conf_sb[1][0x0e] = 0x80; - dev->pci_conf_sb[1][0x0f] = 0x00; - dev->pci_conf_sb[1][0x10] = 0xf1; - dev->pci_conf_sb[1][0x11] = 0x01; - dev->pci_conf_sb[1][0x14] = 0xf5; - dev->pci_conf_sb[1][0x15] = 0x03; - dev->pci_conf_sb[1][0x18] = 0x71; - dev->pci_conf_sb[1][0x19] = 0x01; - dev->pci_conf_sb[1][0x1c] = 0x75; - dev->pci_conf_sb[1][0x1d] = 0x03; - dev->pci_conf_sb[1][0x20] = 0x01; - dev->pci_conf_sb[1][0x21] = 0xf0; - dev->pci_conf_sb[1][0x22] = dev->pci_conf_sb[1][0x23] = 0x00; - dev->pci_conf_sb[1][0x24] = dev->pci_conf_sb[1][0x25] = 0x00; - dev->pci_conf_sb[1][0x26] = dev->pci_conf_sb[1][0x27] = 0x00; - dev->pci_conf_sb[1][0x28] = dev->pci_conf_sb[1][0x29] = 0x00; - dev->pci_conf_sb[1][0x2a] = dev->pci_conf_sb[1][0x2b] = 0x00; - dev->pci_conf_sb[1][0x2c] = dev->pci_conf_sb[1][0x2d] = 0x00; - dev->pci_conf_sb[1][0x2e] = dev->pci_conf_sb[1][0x2f] = 0x00; - dev->pci_conf_sb[1][0x30] = dev->pci_conf_sb[1][0x31] = 0x00; - dev->pci_conf_sb[1][0x32] = dev->pci_conf_sb[1][0x33] = 0x00; - dev->pci_conf_sb[1][0x40] = dev->pci_conf_sb[1][0x41] = 0x00; - dev->pci_conf_sb[1][0x42] = dev->pci_conf_sb[1][0x43] = 0x00; - dev->pci_conf_sb[1][0x44] = dev->pci_conf_sb[1][0x45] = 0x00; - dev->pci_conf_sb[1][0x46] = dev->pci_conf_sb[1][0x47] = 0x00; - dev->pci_conf_sb[1][0x48] = dev->pci_conf_sb[1][0x49] = 0x00; - dev->pci_conf_sb[1][0x4a] = 0x06; - dev->pci_conf_sb[1][0x4b] = 0x00; - dev->pci_conf_sb[1][0x4c] = dev->pci_conf_sb[1][0x4d] = 0x00; - dev->pci_conf_sb[1][0x4e] = dev->pci_conf_sb[1][0x4f] = 0x00; - - sis_5513_ide_irq_handler(dev); - sis_5513_ide_handler(dev); - - sff_bus_master_reset(dev->bm[0]); - sff_bus_master_reset(dev->bm[1]); -} - static void sis_5511_close(void *priv) { sis_5511_t *dev = (sis_5511_t *) priv; - smram_del(dev->smram); free(dev); } @@ -920,53 +141,18 @@ static void * sis_5511_init(UNUSED(const device_t *info)) { sis_5511_t *dev = (sis_5511_t *) calloc(1, sizeof(sis_5511_t)); - uint8_t pit_is_fast = (((pit_mode == -1) && is486) || (pit_mode == 1)); /* Device 0: SiS 5511 */ pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5511_read, sis_5511_write, dev, &dev->nb_slot); /* Device 1: SiS 5513 */ pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5513_read, sis_5513_write, dev, &dev->sb_slot); - /* SLiC Memory Mapped Registers */ - mem_mapping_add(&dev->slic_mapping, - 0xffc00000, 0x00001000, - sis_5511_slic_read, - NULL, - NULL, - sis_5511_slic_write, - NULL, - NULL, - NULL, MEM_MAPPING_EXTERNAL, - dev); + dev->sis = device_add(&sis_55xx_common_device); - /* Ports 22h-23h: SiS 5513 ISA */ - io_sethandler(0x0022, 0x0002, sis_5513_isa_read, NULL, NULL, sis_5513_isa_write, NULL, NULL, dev); + dev->h2p = device_add_linked(&sis_5511_h2p_device, dev->sis); - /* MIRQ */ - pci_enable_mirq(0); - pci_enable_mirq(1); - - /* IDEIRQ */ - pci_enable_mirq(2); - - /* Port 92h */ - dev->port_92 = device_add(&port_92_device); - - /* SFF IDE */ - dev->bm[0] = device_add_inst(&sff8038i_device, 1); - dev->bm[1] = device_add_inst(&sff8038i_device, 2); - - /* SMRAM */ - dev->smram = smram_add(); - - /* PIT */ - dev->pit = device_find_first_priv(DEVICE_PIT); - dev->pit_read_reg = pit_is_fast ? pitf_read_reg : pit_read_reg; - - /* NVR */ - dev->nvr = device_add(&at_mb_nvr_device); - - sis_5511_reset(dev); + dev->p2i = device_add_linked(&sis_5513_p2i_device, dev->sis); + dev->ide = device_add_linked(&sis_5513_ide_device, dev->sis); return dev; } @@ -978,7 +164,7 @@ const device_t sis_5511_device = { .local = 0, .init = sis_5511_init, .close = sis_5511_close, - .reset = sis_5511_reset, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, diff --git a/src/chipset/sis_5511_h2p.c b/src/chipset/sis_5511_h2p.c new file mode 100644 index 000000000..7916d6ae2 --- /dev/null +++ b/src/chipset/sis_5511_h2p.c @@ -0,0 +1,461 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 5511 Host to PCI bridge. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/spd.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> +#include <86box/agpgart.h> + +#ifdef ENABLE_SIS_5511_HOST_TO_PCI_LOG +int sis_5511_host_to_pci_do_log = ENABLE_SIS_5511_HOST_TO_PCI_LOG; + +static void +sis_5511_host_to_pci_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5511_host_to_pci_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5511_host_to_pci_log(fmt, ...) +#endif + +typedef struct sis_5511_host_to_pci_t { + uint8_t pci_conf[256]; + uint8_t states[7]; + + uint8_t slic_regs[4096]; + + sis_55xx_common_t *sis; + + smram_t *smram; + + mem_mapping_t slic_mapping; +} sis_5511_host_to_pci_t; + +static void +sis_5511_shadow_recalc(sis_5511_host_to_pci_t *dev) +{ + int state; + uint32_t base; + + for (uint8_t i = 0x80; i <= 0x86; i++) { + if (i == 0x86) { + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(0xf0000, 0x10000, state); + sis_5511_host_to_pci_log("000F0000-000FFFFF\n"); + } + } else { + base = ((i & 0x07) << 15) + 0xc0000; + + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base, 0x4000, state); + sis_5511_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff); + } + + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) { + state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base + 0x4000, 0x4000, state); + sis_5511_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff); + } + } + + dev->states[i & 0x0f] = dev->pci_conf[i]; + } + + flushmmucache_nopc(); +} + +static void +sis_5511_smram_recalc(sis_5511_host_to_pci_t *dev) +{ + smram_disable_all(); + + switch (dev->pci_conf[0x65] >> 6) { + case 0: + smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); + break; + case 1: + smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); + break; + case 2: + smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); + break; + + default: + break; + } + + flushmmucache(); +} + +void +sis_5511_host_to_pci_write(int addr, uint8_t val, void *priv) +{ + sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv; + + sis_5511_host_to_pci_log("SiS 5511 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (addr) { + default: + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf[addr] &= 0xb0; + break; + + case 0x50: + dev->pci_conf[addr] = val; + cpu_cache_ext_enabled = !!(val & 0x40); + cpu_update_waitstates(); + break; + + case 0x51: + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x52: + dev->pci_conf[addr] = val & 0x3f; + break; + + case 0x53: + case 0x54: + dev->pci_conf[addr] = val; + break; + + case 0x55: + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x56 ... 0x59: + dev->pci_conf[addr] = val; + break; + + case 0x5a: + /* TODO: Fast Gate A20 Emulation and Fast Reset Emulation on the KBC. + The former (bit 7) means the chipset intercepts D1h to 64h and 00h to 60h. + The latter (bit 6) means the chipset intercepts all odd FXh to 64h. + Bit 5 sets fast reset latency. This should be fixed on the other SiS + chipsets as well. */ + dev->pci_conf[addr] = val; + break; + + case 0x5b: + dev->pci_conf[addr] = val & 0xf7; + break; + + case 0x5c: + dev->pci_conf[addr] = val & 0xcf; + break; + + case 0x5d: + dev->pci_conf[addr] = val; + break; + + case 0x5e: + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x5f: + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x60: + dev->pci_conf[addr] = val & 0x3e; + if ((dev->pci_conf[0x68] & 1) && (val & 2)) { + smi_raise(); + dev->pci_conf[0x69] |= 1; + } + break; + + case 0x61 ... 0x64: + dev->pci_conf[addr] = val; + break; + + case 0x65: + dev->pci_conf[addr] = val & 0xd0; + sis_5511_smram_recalc(dev); + break; + + case 0x66: + dev->pci_conf[addr] = val & 0x7f; + break; + + case 0x67: + case 0x68: + dev->pci_conf[addr] = val; + break; + + case 0x69: + dev->pci_conf[addr] &= val; + break; + + case 0x6a ... 0x6e: + dev->pci_conf[addr] = val; + break; + + case 0x6f: + dev->pci_conf[addr] = val & 0x3f; + break; + + case 0x70: /* DRAM Bank Register 0-0 */ + case 0x72: /* DRAM Bank Register 0-1 */ + case 0x74: /* DRAM Bank Register 1-0 */ + case 0x76: /* DRAM Bank Register 1-1 */ + case 0x78: /* DRAM Bank Register 2-0 */ + case 0x7a: /* DRAM Bank Register 2-1 */ + case 0x7c: /* DRAM Bank Register 3-0 */ + case 0x7e: /* DRAM Bank Register 3-1 */ + spd_write_drbs(dev->pci_conf, 0x70, 0x7e, 0x82); + break; + + case 0x71: /* DRAM Bank Register 0-0 */ + dev->pci_conf[addr] = val; + break; + + case 0x75: /* DRAM Bank Register 1-0 */ + case 0x79: /* DRAM Bank Register 2-0 */ + case 0x7d: /* DRAM Bank Register 3-0 */ + dev->pci_conf[addr] = val & 0x7f; + break; + + case 0x73: /* DRAM Bank Register 0-1 */ + case 0x77: /* DRAM Bank Register 1-1 */ + case 0x7b: /* DRAM Bank Register 2-1 */ + case 0x7f: /* DRAM Bank Register 3-1 */ + dev->pci_conf[addr] = val & 0x83; + break; + + case 0x80 ... 0x85: + dev->pci_conf[addr] = val & 0xee; + sis_5511_shadow_recalc(dev); + break; + case 0x86: + dev->pci_conf[addr] = val & 0xe8; + sis_5511_shadow_recalc(dev); + break; + + case 0x90 ... 0x93: /* 5512 General Purpose Register Index */ + dev->pci_conf[addr] = val; + break; + } +} + +uint8_t +sis_5511_host_to_pci_read(int addr, void *priv) +{ + const sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv; + uint8_t ret = 0xff; + + ret = dev->pci_conf[addr]; + + sis_5511_host_to_pci_log("SiS 5511 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5511_slic_write(uint32_t addr, uint8_t val, void *priv) +{ + sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv; + + addr &= 0x00000fff; + + switch (addr) { + case 0x00000000: + case 0x00000008: /* 0x00000008 is a SiS 5512 register. */ + dev->slic_regs[addr] = val; + break; + case 0x00000010: + case 0x00000018: + case 0x00000028: + case 0x00000038: + dev->slic_regs[addr] = val & 0x01; + break; + case 0x00000030: + dev->slic_regs[addr] = val & 0x0f; + mem_mapping_set_addr(&dev->slic_mapping, + (((uint32_t) (val & 0x0f)) << 28) | 0x0fc00000, 0x00001000); + break; + } +} + +static uint8_t +sis_5511_slic_read(uint32_t addr, void *priv) +{ + sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv; + uint8_t ret = 0xff; + + addr &= 0x00000fff; + + switch (addr) { + case 0x00000008: /* 0x00000008 is a SiS 5512 register. */ + ret = dev->slic_regs[addr]; + break; + } + + return ret; +} + +static void +sis_5511_host_to_pci_reset(void *priv) +{ + sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x11; + dev->pci_conf[0x03] = 0x55; + dev->pci_conf[0x04] = 0x07; + dev->pci_conf[0x05] = dev->pci_conf[0x06] = 0x00; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = 0x00; + dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x00; + dev->pci_conf[0x52] = 0x20; + dev->pci_conf[0x53] = dev->pci_conf[0x54] = 0x00; + dev->pci_conf[0x55] = dev->pci_conf[0x56] = 0x00; + dev->pci_conf[0x57] = dev->pci_conf[0x58] = 0x00; + dev->pci_conf[0x59] = dev->pci_conf[0x5a] = 0x00; + dev->pci_conf[0x5b] = dev->pci_conf[0x5c] = 0x00; + dev->pci_conf[0x5d] = dev->pci_conf[0x5e] = 0x00; + dev->pci_conf[0x5f] = dev->pci_conf[0x60] = 0x00; + dev->pci_conf[0x61] = dev->pci_conf[0x62] = 0xff; + dev->pci_conf[0x63] = 0xff; + dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00; + dev->pci_conf[0x66] = 0x00; + dev->pci_conf[0x67] = 0xff; + dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00; + dev->pci_conf[0x6a] = 0x00; + dev->pci_conf[0x6b] = dev->pci_conf[0x6c] = 0xff; + dev->pci_conf[0x6d] = dev->pci_conf[0x6e] = 0xff; + dev->pci_conf[0x6f] = 0x00; + dev->pci_conf[0x70] = dev->pci_conf[0x72] = 0x04; + dev->pci_conf[0x74] = dev->pci_conf[0x76] = 0x04; + dev->pci_conf[0x78] = dev->pci_conf[0x7a] = 0x04; + dev->pci_conf[0x7c] = dev->pci_conf[0x7e] = 0x04; + dev->pci_conf[0x71] = dev->pci_conf[0x75] = 0x00; + dev->pci_conf[0x73] = dev->pci_conf[0x77] = 0x80; + dev->pci_conf[0x79] = dev->pci_conf[0x7d] = 0x00; + dev->pci_conf[0x7b] = dev->pci_conf[0x7f] = 0x80; + dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00; + dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0x00; + dev->pci_conf[0x86] = 0x00; + + cpu_cache_ext_enabled = 0; + cpu_update_waitstates(); + + sis_5511_smram_recalc(dev); + sis_5511_shadow_recalc(dev); + + flushmmucache(); + + memset(dev->slic_regs, 0x00, 4096 * sizeof(uint8_t)); + dev->slic_regs[0x18] = 0x0f; + + mem_mapping_set_addr(&dev->slic_mapping, 0xffc00000, 0x00001000); +} + +static void +sis_5511_host_to_pci_close(void *priv) +{ + sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv; + + smram_del(dev->smram); + free(dev); +} + +static void * +sis_5511_host_to_pci_init(UNUSED(const device_t *info)) +{ + sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) calloc(1, sizeof(sis_5511_host_to_pci_t)); + + dev->sis = device_get_common_priv(); + + /* SLiC Memory Mapped Registers */ + mem_mapping_add(&dev->slic_mapping, + 0xffc00000, 0x00001000, + sis_5511_slic_read, + NULL, + NULL, + sis_5511_slic_write, + NULL, + NULL, + NULL, MEM_MAPPING_EXTERNAL, + dev); + + /* SMRAM */ + dev->smram = smram_add(); + + sis_5511_host_to_pci_reset(dev); + + return dev; +} + +const device_t sis_5511_h2p_device = { + .name = "SiS 5511 Host to PCI bridge", + .internal_name = "sis_5511_host_to_pci", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5511_host_to_pci_init, + .close = sis_5511_host_to_pci_close, + .reset = sis_5511_host_to_pci_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5513_ide.c b/src/chipset/sis_5513_ide.c new file mode 100644 index 000000000..130f2abd5 --- /dev/null +++ b/src/chipset/sis_5513_ide.c @@ -0,0 +1,501 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 5513 IDE controller. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> + +#ifdef ENABLE_SIS_5513_IDE_LOG +int sis_5513_ide_do_log = ENABLE_SIS_5513_IDE_LOG; + +static void +sis_5513_ide_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5513_ide_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5513_ide_log(fmt, ...) +#endif + +typedef struct sis_5513_ide_t { + uint8_t rev; + + uint8_t pci_conf[256]; + + sis_55xx_common_t *sis; +} sis_5513_ide_t; + +static void +sis_5513_ide_irq_handler(sis_5513_ide_t *dev) +{ + if (dev->pci_conf[0x09] & 0x01) { + /* Primary IDE is native. */ + sis_5513_ide_log("Primary IDE IRQ mode: Native, Native\n"); + sff_set_irq_mode(dev->sis->bm[0], IRQ_MODE_SIS_551X); + } else { + /* Primary IDE is legacy. */ + sis_5513_ide_log("Primary IDE IRQ mode: IRQ14, IRQ15\n"); + sff_set_irq_mode(dev->sis->bm[0], IRQ_MODE_LEGACY); + } + + if (dev->pci_conf[0x09] & 0x04) { + /* Secondary IDE is native. */ + sis_5513_ide_log("Secondary IDE IRQ mode: Native, Native\n"); + sff_set_irq_mode(dev->sis->bm[1], IRQ_MODE_SIS_551X); + } else { + /* Secondary IDE is legacy. */ + sis_5513_ide_log("Secondary IDE IRQ mode: IRQ14, IRQ15\n"); + sff_set_irq_mode(dev->sis->bm[1], IRQ_MODE_LEGACY); + } +} + +static void +sis_5513_ide_handler(sis_5513_ide_t *dev) +{ + uint8_t ide_io_on = dev->pci_conf[0x04] & 0x01; + + uint16_t native_base_pri_addr = (dev->pci_conf[0x11] | dev->pci_conf[0x10] << 8) & 0xfffe; + uint16_t native_side_pri_addr = (dev->pci_conf[0x15] | dev->pci_conf[0x14] << 8) & 0xfffe; + uint16_t native_base_sec_addr = (dev->pci_conf[0x19] | dev->pci_conf[0x18] << 8) & 0xfffe; + uint16_t native_side_sec_addr = (dev->pci_conf[0x1c] | dev->pci_conf[0x1b] << 8) & 0xfffe; + + uint16_t current_pri_base; + uint16_t current_pri_side; + uint16_t current_sec_base; + uint16_t current_sec_side; + + /* Primary Channel Programming */ + current_pri_base = (!(dev->pci_conf[0x09] & 1)) ? 0x01f0 : native_base_pri_addr; + current_pri_side = (!(dev->pci_conf[0x09] & 1)) ? 0x03f6 : native_side_pri_addr; + + /* Secondary Channel Programming */ + current_sec_base = (!(dev->pci_conf[0x09] & 4)) ? 0x0170 : native_base_sec_addr; + current_sec_side = (!(dev->pci_conf[0x09] & 4)) ? 0x0376 : native_side_sec_addr; + + sis_5513_ide_log("sis_5513_ide_handler(): Disabling primary IDE...\n"); + ide_pri_disable(); + sis_5513_ide_log("sis_5513_ide_handler(): Disabling secondary IDE...\n"); + ide_sec_disable(); + + if (ide_io_on) { + /* Primary Channel Setup */ + if (dev->pci_conf[0x4a] & 0x02) { + sis_5513_ide_log("sis_5513_ide_handler(): Primary IDE base now %04X...\n", current_pri_base); + ide_set_base(0, current_pri_base); + sis_5513_ide_log("sis_5513_ide_handler(): Primary IDE side now %04X...\n", current_pri_side); + ide_set_side(0, current_pri_side); + + sis_5513_ide_log("sis_5513_ide_handler(): Enabling primary IDE...\n"); + ide_pri_enable(); + + sis_5513_ide_log("SiS 5513 PRI: BASE %04x SIDE %04x\n", current_pri_base, current_pri_side); + } + + /* Secondary Channel Setup */ + if (dev->pci_conf[0x4a] & 0x04) { + sis_5513_ide_log("sis_5513_ide_handler(): Secondary IDE base now %04X...\n", current_sec_base); + ide_set_base(1, current_sec_base); + sis_5513_ide_log("sis_5513_ide_handler(): Secondary IDE side now %04X...\n", current_sec_side); + ide_set_side(1, current_sec_side); + + sis_5513_ide_log("sis_5513_ide_handler(): Enabling secondary IDE...\n"); + ide_sec_enable(); + + sis_5513_ide_log("SiS 5513: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side); + } + } + + sff_bus_master_handler(dev->sis->bm[0], ide_io_on, + ((dev->pci_conf[0x20] & 0xf0) | (dev->pci_conf[0x21] << 8)) + 0); + sff_bus_master_handler(dev->sis->bm[1], ide_io_on, + ((dev->pci_conf[0x20] & 0xf0) | (dev->pci_conf[0x21] << 8)) + 8); +} + +void +sis_5513_ide_write(int addr, uint8_t val, void *priv) +{ + sis_5513_ide_t *dev = (sis_5513_ide_t *) priv; + + sis_5513_ide_log("SiS 5513 IDE: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (addr) { + case 0x04: /* Command low byte */ + dev->pci_conf[addr] = val & 0x05; + sis_5513_ide_handler(dev); + break; + case 0x06: /* Status low byte */ + dev->pci_conf[addr] = val & 0x20; + break; + case 0x07: /* Status high byte */ + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x06) & ~(val & 0x38); + break; + case 0x09: /* Programming Interface Byte */ + switch (dev->rev) { + case 0xd0: + if (dev->sis->ide_bits_1_3_writable) + val |= 0x0a; + fallthrough; + case 0x00: + case 0xd1: + val &= 0xbf; + fallthrough; + case 0xc0: + switch (val & 0x0a) { + case 0x00: + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x85) | (val & 0x4a); + break; + case 0x02: + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x84) | (val & 0x4b); + break; + case 0x08: + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x81) | (val & 0x4e); + break; + case 0x0a: + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x80) | (val & 0x4f); + break; + } + break; + } + sis_5513_ide_irq_handler(dev); + sis_5513_ide_handler(dev); + break; + case 0x0d: /* Latency Timer */ + dev->pci_conf[addr] = val; + break; + + /* Primary Base Address */ + case 0x10 ... 0x11: + case 0x14 ... 0x15: + fallthrough; + + /* Secondary Base Address */ + case 0x18 ... 0x19: + case 0x1c ... 0x1d: + fallthrough; + + /* Bus Mastering Base Address */ + case 0x20 ... 0x21: + if (addr == 0x20) + dev->pci_conf[addr] = (val & 0xe0) | 0x01; + else + dev->pci_conf[addr] = val; + sis_5513_ide_handler(dev); + break; + + case 0x2c ... 0x2f: + if (dev->rev >= 0xd0) + dev->pci_conf[addr] = val; + break; + + case 0x30 ... 0x33: /* Expansion ROM Base Address */ +#ifdef DATASHEET + dev->pci_conf[addr] = val; +#else + if (dev->rev == 0x00) + dev->pci_conf[addr] = val; +#endif + break; + + case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */ + if (dev->rev >= 0xd0) + dev->pci_conf[addr] = val & 0xcf; + else + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */ + case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */ + case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */ + case 0x48: /* IDE Command Recovery Time Control */ + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */ + case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */ + case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */ + case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */ + if (dev->rev >= 0xd0) + dev->pci_conf[addr] = val & 0xe7; + else + dev->pci_conf[addr] = val & 0x07; + break; + + case 0x49: /* IDE Command Active Time Control */ + dev->pci_conf[addr] = val & 0x07; + break; + + case 0x4a: /* IDE General Control Register 0 */ + switch (dev->rev) { + case 0x00: + dev->pci_conf[addr] = val & 0x9e; + break; + case 0xc0: + dev->pci_conf[addr] = val & 0xaf; + break; + case 0xd0: + dev->pci_conf[addr] = val; + break; + } + sis_5513_ide_handler(dev); + break; + + case 0x4b: /* IDE General Control Register 1 */ + if (dev->rev >= 0xc0) + dev->pci_conf[addr] = val; + else + dev->pci_conf[addr] = val & 0xef; + break; + + case 0x4c: /* Prefetch Count of Primary Channel (Low Byte) */ + case 0x4d: /* Prefetch Count of Primary Channel (High Byte) */ + case 0x4e: /* Prefetch Count of Secondary Channel (Low Byte) */ + case 0x4f: /* Prefetch Count of Secondary Channel (High Byte) */ + dev->pci_conf[addr] = val; + break; + + case 0x50: + case 0x51: + if (dev->rev >= 0xd0) + dev->pci_conf[addr] = val; + break; + + case 0x52: + if (dev->rev >= 0xd0) + dev->pci_conf[addr] = val & 0x0f; + break; + + default: + break; + } +} + +uint8_t +sis_5513_ide_read(int addr, void *priv) +{ + const sis_5513_ide_t *dev = (sis_5513_ide_t *) priv; + uint8_t ret = 0xff; + + switch (addr) { + default: + ret = dev->pci_conf[addr]; + break; + case 0x09: + ret = dev->pci_conf[addr]; + if (dev->rev >= 0xc0) { + if (dev->pci_conf[0x09] & 0x40) + ret |= ((dev->pci_conf[0x4a] & 0x06) << 3); + if ((dev->rev == 0xd0) && dev->sis->ide_bits_1_3_writable) + ret |= 0x0a; + } + break; + case 0x3d: + if (dev->rev >= 0xc0) + ret = (dev->pci_conf[0x09] & 0x05) ? PCI_INTA : 0x00; + else + ret = (((dev->pci_conf[0x4b] & 0xc0) == 0xc0) || + (dev->pci_conf[0x09] & 0x05)) ? PCI_INTA : 0x00; + break; + } + + sis_5513_ide_log("SiS 5513 IDE: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5513_ide_reset(void *priv) +{ + sis_5513_ide_t *dev = (sis_5513_ide_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x13; + dev->pci_conf[0x03] = 0x55; + dev->pci_conf[0x04] = dev->pci_conf[0x05] = 0x00; + dev->pci_conf[0x06] = dev->pci_conf[0x07] = 0x00; + dev->pci_conf[0x08] = (dev->rev == 0xd1) ? 0xd0 : dev->rev; + dev->pci_conf[0x09] = 0x8a; + dev->pci_conf[0x0a] = dev->pci_conf[0x0b] = 0x01; + dev->pci_conf[0x0c] = dev->pci_conf[0x0d] = 0x00; + dev->pci_conf[0x0e] = 0x80; + dev->pci_conf[0x0f] = 0x00; + dev->pci_conf[0x10] = 0xf1; + dev->pci_conf[0x11] = 0x01; + dev->pci_conf[0x14] = 0xf5; + dev->pci_conf[0x15] = 0x03; + dev->pci_conf[0x18] = 0x71; + dev->pci_conf[0x19] = 0x01; + dev->pci_conf[0x1c] = 0x75; + dev->pci_conf[0x1d] = 0x03; + dev->pci_conf[0x20] = 0x01; + dev->pci_conf[0x21] = 0xf0; + dev->pci_conf[0x22] = dev->pci_conf[0x23] = 0x00; + dev->pci_conf[0x24] = dev->pci_conf[0x25] = 0x00; + dev->pci_conf[0x26] = dev->pci_conf[0x27] = 0x00; + dev->pci_conf[0x28] = dev->pci_conf[0x29] = 0x00; + dev->pci_conf[0x2a] = dev->pci_conf[0x2b] = 0x00; + switch (dev->rev) { + case 0x00: + case 0xd0: + case 0xd1: + dev->pci_conf[0x2c] = dev->pci_conf[0x2d] = 0x00; + break; + case 0xc0: +#ifdef DATASHEET + dev->pci_conf[0x2c] = dev->pci_conf[0x2d] = 0x00; +#else + /* The only Linux lspci listing I could find of this chipset, + shows a subsystem of 0058:0000. */ + dev->pci_conf[0x2c] = 0x58; + dev->pci_conf[0x2d] = 0x00; +#endif + break; + } + dev->pci_conf[0x2e] = dev->pci_conf[0x2f] = 0x00; + dev->pci_conf[0x30] = dev->pci_conf[0x31] = 0x00; + dev->pci_conf[0x32] = dev->pci_conf[0x33] = 0x00; + dev->pci_conf[0x40] = dev->pci_conf[0x41] = 0x00; + dev->pci_conf[0x42] = dev->pci_conf[0x43] = 0x00; + dev->pci_conf[0x44] = dev->pci_conf[0x45] = 0x00; + dev->pci_conf[0x46] = dev->pci_conf[0x47] = 0x00; + dev->pci_conf[0x48] = dev->pci_conf[0x49] = 0x00; + dev->pci_conf[0x4a] = 0x06; + dev->pci_conf[0x4b] = 0x00; + dev->pci_conf[0x4c] = dev->pci_conf[0x4d] = 0x00; + dev->pci_conf[0x4e] = dev->pci_conf[0x4f] = 0x00; + + sis_5513_ide_irq_handler(dev); + sis_5513_ide_handler(dev); + + sff_bus_master_reset(dev->sis->bm[0]); + sff_bus_master_reset(dev->sis->bm[1]); +} + +static void +sis_5513_ide_close(void *priv) +{ + sis_5513_ide_t *dev = (sis_5513_ide_t *) priv; + + free(dev); +} + +static void * +sis_5513_ide_init(UNUSED(const device_t *info)) +{ + sis_5513_ide_t *dev = (sis_5513_ide_t *) calloc(1, sizeof(sis_5513_ide_t)); + + dev->rev = info->local; + + dev->sis = device_get_common_priv(); + + /* SFF IDE */ + dev->sis->bm[0] = device_add_inst(&sff8038i_device, 1); + dev->sis->bm[1] = device_add_inst(&sff8038i_device, 2); + + sis_5513_ide_reset(dev); + + return dev; +} + +const device_t sis_5513_ide_device = { + .name = "SiS 5513 IDE controller", + .internal_name = "sis_5513_ide", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5513_ide_init, + .close = sis_5513_ide_close, + .reset = sis_5513_ide_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5572_ide_device = { + .name = "SiS 5572 IDE controller", + .internal_name = "sis_5572_ide", + .flags = DEVICE_PCI, + .local = 0xc0, + .init = sis_5513_ide_init, + .close = sis_5513_ide_close, + .reset = sis_5513_ide_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5582_ide_device = { + .name = "SiS 5582 IDE controller", + .internal_name = "sis_5582_ide", + .flags = DEVICE_PCI, + .local = 0xd0, + .init = sis_5513_ide_init, + .close = sis_5513_ide_close, + .reset = sis_5513_ide_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5591_5600_ide_device = { + .name = "SiS 5591/(5)600 IDE controller", + .internal_name = "sis_5591_5600_ide", + .flags = DEVICE_PCI, + .local = 0xd1, /* D0, but we need to distinguish them. */ + .init = sis_5513_ide_init, + .close = sis_5513_ide_close, + .reset = sis_5513_ide_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5513_p2i.c b/src/chipset/sis_5513_p2i.c new file mode 100644 index 000000000..df18cc4b3 --- /dev/null +++ b/src/chipset/sis_5513_p2i.c @@ -0,0 +1,1354 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 5513 PCI to ISA bridge. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> + +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> + +#ifdef ENABLE_SIS_5513_PCI_TO_ISA_LOG +int sis_5513_pci_to_isa_do_log = ENABLE_SIS_5513_PCI_TO_ISA_LOG; + +static void +sis_5513_pci_to_isa_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5513_pci_to_isa_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5513_pci_to_isa_log(fmt, ...) +#endif + +typedef struct sis_5513_pci_to_isa_t { + uint8_t rev; + uint8_t index; + uint8_t dam_index; + uint8_t irq_state; + uint8_t dam_enable; + uint8_t dam_irq_enable; + uint8_t ddma_enable; + uint8_t pci_conf[256]; + uint8_t regs[16]; + uint8_t dam_regs[256]; + uint8_t apc_regs[256]; + + uint16_t dam_base; + uint16_t ddma_base; + uint16_t acpi_io_base; + + sis_55xx_common_t *sis; + port_92_t *port_92; + void *pit; + nvr_t *nvr; + ddma_t *ddma; + acpi_t *acpi; + void *smbus; + + uint8_t (*pit_read_reg)(void *priv, uint8_t reg); +} sis_5513_pci_to_isa_t; + +static void +sis_5595_acpi_recalc(sis_5513_pci_to_isa_t *dev) +{ + dev->acpi_io_base = (dev->pci_conf[0x91] << 8) | (dev->pci_conf[0x90] & 0xc0); + acpi_update_io_mapping(dev->sis->acpi, dev->acpi_io_base, (dev->pci_conf[0x40] & 0x80)); +} + +static void +sis_5513_apc_reset(sis_5513_pci_to_isa_t *dev) +{ + memset(dev->apc_regs, 0x00, sizeof(dev->apc_regs)); + + if (dev->rev == 0b0) { + dev->apc_regs[0x03] = 0x80; + dev->apc_regs[0x04] = 0x38; + dev->apc_regs[0x07] = 0x01; + } else + dev->apc_regs[0x04] = 0x08; +} + +static void +sis_5513_apc_write(uint16_t addr, uint8_t val, void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + uint8_t nvr_index = nvr_get_index(dev->nvr, 0); + + sis_5513_pci_to_isa_log("SiS 5595 APC: [W] %04X = %02X\n", addr, val); + + switch (nvr_index) { + case 0x02 ... 0x04: + dev->apc_regs[nvr_index] = val; + break; + case 0x05: + case 0x07 ... 0x08: + if (dev->rev == 0xb0) + dev->apc_regs[nvr_index] = val; + break; + } +} + +static uint8_t +sis_5513_apc_read(uint16_t addr, void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + uint8_t nvr_index = nvr_get_index(dev->nvr, 0); + uint8_t ret = 0xff; + + ret = dev->apc_regs[nvr_index]; + + if (nvr_index == 0x06) + dev->apc_regs[nvr_index] = 0x00; + + sis_5513_pci_to_isa_log("SiS 5595 APC: [R] %04X = %02X\n", addr, ret); + + return ret; +} + +void +sis_5513_apc_recalc(sis_5513_pci_to_isa_t *dev, uint8_t apc_on) +{ + nvr_at_data_port(!apc_on, dev->nvr); + io_removehandler(0x0071, 0x0001, + sis_5513_apc_read, NULL, NULL, sis_5513_apc_write, NULL, NULL, dev); + + if (apc_on) + io_removehandler(0x0071, 0x0001, + sis_5513_apc_read, NULL, NULL, sis_5513_apc_write, NULL, NULL, dev); +} + +static void +sis_5595_do_nmi(sis_5513_pci_to_isa_t *dev, int set) +{ + if (set) + nmi_raise(); + + dev->irq_state = set; +} + +static void +sis_5595_dam_reset(sis_5513_pci_to_isa_t *dev) +{ + if (dev->irq_state) { + if (dev->dam_regs[0x40] & 0x20) + sis_5595_do_nmi(dev, 0); + else if (dev->dam_irq_enable) + pci_clear_mirq(6, 1, &dev->irq_state); + } + + memset(dev->dam_regs, 0x00, sizeof(dev->dam_regs)); + + dev->dam_regs[0x40] = 0x08; + dev->dam_regs[0x47] = 0x50; +} + +static void +sis_5595_dam_write(uint16_t addr, uint8_t val, void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + uint16_t reg = addr - dev->dam_base; + uint8_t old; + + sis_5513_pci_to_isa_log("SiS 5595 DAM: [W] %04X = %02X\n", addr, val); + + switch (reg) { + case 0x05: + dev->dam_index = (dev->index & 0x80) | (val & 0x7f); + break; + case 0x06: + switch (dev->dam_index) { + case 0x40: + old = dev->dam_regs[0x40]; + dev->dam_regs[0x40] = val & 0xef; + if (val & 0x80) { + sis_5595_dam_reset(dev); + return; + } + if (dev->irq_state) { + if (!(old & 0x20) && (val & 0x20)) { + if (dev->dam_irq_enable) + pci_clear_mirq(6, 1, &dev->irq_state); + sis_5595_do_nmi(dev, 1); + } else if ((old & 0x20) && !(val & 0x20)) { + sis_5595_do_nmi(dev, 0); + if (dev->dam_irq_enable) + pci_set_mirq(6, 1, &dev->irq_state); + } + } + if ((val & 0x08) && dev->dam_irq_enable) + pci_clear_mirq(6, 1, &dev->irq_state); + break; + case 0x43 ... 0x47: + dev->dam_regs[dev->dam_index] = val; + break; + case 0x2b ... 0x34: + case 0x6b ... 0x74: + case 0x3b ... 0x3c: + case 0x7b ... 0x7c: + dev->dam_regs[dev->dam_index & 0x3f] = val; + break; + } + break; + } +} + +static uint8_t +sis_5595_dam_read(uint16_t addr, void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + uint16_t reg = addr - dev->dam_base; + uint8_t ret = 0xff; + + switch (reg) { + case 0x05: + ret = dev->dam_index; + break; + case 0x06: + switch (dev->dam_index) { + default: + ret = dev->dam_regs[dev->dam_index]; + break; + case 0x20 ... 0x29: + case 0x2b ... 0x3f: + ret = dev->dam_regs[dev->dam_index & 0x3f]; + break; + case 0x2a: + case 0x6a: + ret = dev->pci_conf[0x78]; + break; + } + break; + } + + sis_5513_pci_to_isa_log("SiS 5595 DAM: [R] %04X = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5595_dam_recalc(sis_5513_pci_to_isa_t *dev) +{ + if (dev->dam_enable && (dev->dam_base != 0x0000)) + io_removehandler(dev->dam_base, 0x0008, + sis_5595_dam_read, NULL, NULL, sis_5595_dam_write, NULL, NULL, dev); + + dev->dam_base = dev->pci_conf[0x68] | (dev->pci_conf[0x69] << 16); + dev->dam_enable = !!(dev->pci_conf[0x7b] & 0x80); + + if (dev->dam_enable && (dev->dam_base != 0x0000)) + io_sethandler(dev->dam_base, 0x0008, + sis_5595_dam_read, NULL, NULL, sis_5595_dam_write, NULL, NULL, dev); +} + +static void +sis_5595_ddma_recalc(sis_5513_pci_to_isa_t *dev) +{ + uint16_t ch_base; + + dev->ddma_base = (dev->pci_conf[0x80] & 0xf0) | (dev->pci_conf[0x81] << 16); + dev->ddma_enable = !!(dev->pci_conf[0x80] & 0x01); + + for (uint8_t i = 0; i < 8; i++) { + ch_base = dev->ddma_base + (i << 4); + ddma_update_io_mapping(dev->ddma, i, ch_base & 0xff, (ch_base >> 8), + dev->ddma_enable && (dev->pci_conf[0x84] & (1 << i)) && + (dev->ddma_base != 0x0000)); + } +} + +static void +sis_5513_00_pci_to_isa_write(int addr, uint8_t val, sis_5513_pci_to_isa_t *dev) +{ + switch (addr) { + case 0x60: /* MIRQ0 Remapping Control Register */ + case 0x61: /* MIRQ1 Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: MIRQ%i -> %02X\n", addr & 0x01, val); + dev->pci_conf[addr] = val & 0xcf; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf); + break; + + case 0x62: /* On-board Device DMA Control Register */ + dev->pci_conf[addr] = val; + break; + + case 0x63: /* IDEIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: IDEIRQ -> %02X\n", val); + dev->pci_conf[addr] = val & 0x8f; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ2, val & 0xf); + break; + + case 0x64: /* GPIO0 Control Register */ + dev->pci_conf[addr] = val & 0xef; + break; + + case 0x65: + dev->pci_conf[addr] = val & 0x80; + break; + + case 0x66: /* GPIO0 Output Mode Control Register */ + case 0x67: /* GPIO0 Output Mode Control Register */ + dev->pci_conf[addr] = val; + break; + + case 0x6a: /* GPIO Status Register */ + dev->pci_conf[addr] |= (val & 0x10); + dev->pci_conf[addr] &= ~(val & 0x01); + break; + + default: + break; + } +} + +static void +sis_5513_01_pci_to_isa_write(int addr, uint8_t val, sis_5513_pci_to_isa_t *dev) +{ + uint8_t old; + + switch (addr) { + /* Simply skip MIRQ0, so we can reuse the SiS 551x IDEIRQ infrastructure. */ + case 0x61: /* MIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: MIRQ%i -> %02X\n", addr & 0x01, val); + dev->pci_conf[addr] = val & 0xcf; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf); + break; + + case 0x62: /* On-board Device DMA Control Register */ + dev->pci_conf[addr] = val; + break; + + case 0x63: /* IDEIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: IDEIRQ -> %02X\n", val); + dev->pci_conf[addr] = val & 0x8f; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ2, val & 0xf); + break; + + case 0x64: /* GPIO Control Register */ + dev->pci_conf[addr] = val & 0xef; + break; + + case 0x65: + dev->pci_conf[addr] = val & 0x1b; + break; + + case 0x66: /* GPIO Output Mode Control Register */ + case 0x67: /* GPIO Output Mode Control Register */ + dev->pci_conf[addr] = val; + break; + + case 0x68: /* USBIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: USBIRQ -> %02X\n", val); + dev->pci_conf[addr] = val & 0xcf; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ3, val & 0xf); + break; + + case 0x69: + dev->pci_conf[addr] = val; + break; + + case 0x6a: + dev->pci_conf[addr] = val & 0xfc; + break; + + case 0x6b: + dev->pci_conf[addr] = val; + break; + + case 0x6c: + dev->pci_conf[addr] = val & 0x02; + break; + + case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */ + old = dev->pci_conf[addr]; + picint((val ^ old) & val); + picintc((val ^ old) & ~val); + dev->pci_conf[addr] = val; + break; + + case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */ + old = dev->pci_conf[addr]; + picint(((val ^ old) & val) << 8); + picintc(((val ^ old) & ~val) << 8); + dev->pci_conf[addr] = val; + break; + + case 0x70: + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x02) | (val & 0xdc); + break; + + case 0x71: /* Type-F DMA Control Register */ + dev->pci_conf[addr] = val & 0xef; + break; + + case 0x72: /* SMI Triggered By IRQ/GPIO Control */ + case 0x73: /* SMI Triggered By IRQ/GPIO Control */ + dev->pci_conf[addr] = val; + break; + + case 0x74: /* System Standby Timer Reload, + System Standby State Exit And Throttling State Exit Control */ + case 0x75: /* System Standby Timer Reload, + System Standby State Exit And Throttling State Exit Control */ + case 0x76: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */ + case 0x77: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */ + dev->pci_conf[addr] = val; + break; + + default: + break; + } +} + +static void +sis_5513_11_pci_to_isa_write(int addr, uint8_t val, sis_5513_pci_to_isa_t *dev) +{ + uint8_t old; + + switch (addr) { + case 0x61: /* IDEIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: IDEIRQ -> %02X\n", val); + dev->pci_conf[addr] = val & 0xcf; + dev->sis->ide_bits_1_3_writable = !!(val & 0x40); + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ2, val & 0xf); + break; + + case 0x62: /* USBIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: USBIRQ -> %02X\n", val); + dev->pci_conf[addr] = val; + dev->sis->usb_enabled = !!(val & 0x40); + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ3, val & 0xf); + break; + + case 0x63: /* GPCS0 Control Register */ + case 0x64: /* GPCS1 Control Register */ + case 0x65: /* GPCS0 Output Mode Control Register */ + case 0x66: /* GPCS0 Output Mode Control Register */ + case 0x67: /* GPCS1 Output Mode Control Register */ + case 0x68: /* GPCS1 Output Mode Control Register */ + case 0x6b: + case 0x6c: + dev->pci_conf[addr] = val; + break; + + case 0x69: /* GPCS0/1 De-Bounce Control Register */ + dev->pci_conf[addr] = val & 0xdf; + if ((dev->apc_regs[0x03] & 0x40) && (val & 0x10)) { + plat_power_off(); + return; + } + break; + + case 0x6a: /* ACPI/SCI IRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: ACPI/SCI IRQ -> %02X\n", val); + dev->pci_conf[addr] = val; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ5, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ5, val & 0xf); + break; + + case 0x6d: /* I2C Bus Control Register */ + dev->pci_conf[addr] = val; + /* TODO: Keyboard/mouse swapping and keyboard hot key. */ + break; + + case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */ + old = dev->pci_conf[addr]; + picint((val ^ old) & val); + picintc((val ^ old) & ~val); + dev->pci_conf[addr] = val; + break; + + case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */ + old = dev->pci_conf[addr]; + picint(((val ^ old) & val) << 8); + picintc(((val ^ old) & ~val) << 8); + dev->pci_conf[addr] = val; + break; + + case 0x70: /* Misc. Controller Register */ + dev->pci_conf[addr] = val; + /* TODO: Keyboard Lock Enable/Disable. */ + break; + + case 0x71: /* Type F DMA Control Register */ + dev->pci_conf[addr] = val & 0xef; + break; + + case 0x72: /* SMI Triggered By IRQ Control */ + dev->pci_conf[addr] = val & 0xfa; + break; + case 0x73: /* SMI Triggered By IRQ Control */ + case 0x75: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit */ + case 0x77: /* Monoitor Standby Timer Reload And Monoitor Standby State Exit Control */ + dev->pci_conf[addr] = val; + break; + + case 0x74: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit */ + case 0x76: /* Monoitor Standby Timer Reload And Monoitor Standby State Exit Control */ + dev->pci_conf[addr] = val & 0xfb; + break; + dev->pci_conf[addr] = val; + break; + + case 0x80: /* Distributed DMA Master Configuration Register */ + case 0x81: /* Distributed DMA Master Configuration Register */ + dev->pci_conf[addr] = val; + sis_5595_ddma_recalc(dev); + break; + + case 0x84: /* Individual Distributed DMA Channel Enable */ + dev->pci_conf[addr] = val; + sis_5595_ddma_recalc(dev); + break; + + case 0x88: /* Serial Interrupt Control Register */ + case 0x89: /* Serial Interrupt Enable Register 1 */ + case 0x8a: /* Serial Interrupt Enable Register 2 */ + dev->pci_conf[addr] = val; + break; + + case 0x90: /* ACPI Base Address Register */ + dev->pci_conf[addr] = val & 0xc0; + sis_5595_acpi_recalc(dev); + break; + case 0x91: /* ACPI Base Address Register */ + dev->pci_conf[addr] = val; + sis_5595_acpi_recalc(dev); + break; + + default: + break; + } +} + +static void +sis_5513_b0_pci_to_isa_write(int addr, uint8_t val, sis_5513_pci_to_isa_t *dev) +{ + uint8_t old; + + switch (addr) { + case 0x61: /* IDEIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: IDEIRQ -> %02X\n", val); + dev->pci_conf[addr] = val & 0xdf; + sff_set_mirq(dev->sis->bm[0], (val & 0x10) ? 7 : 2); + sff_set_mirq(dev->sis->bm[1], (val & 0x10) ? 2 : 7); + pci_set_mirq_routing(PCI_MIRQ7, 14 + (!!(val & 0x10))); + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ2, val & 0xf); + break; + + case 0x62: /* USBIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: USBIRQ -> %02X\n", val); + dev->pci_conf[addr] = val; + dev->sis->usb_enabled = !!(val & 0x40); + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ3, val & 0xf); + break; + + case 0x63: /* PCI OutputBuffer Current Strength Register */ + dev->pci_conf[addr] = val; + if ((dev->apc_regs[0x03] & 0x40) && (val & 0x04)) { + plat_power_off(); + return; + } + if ((val & 0x18) == 0x18) { + dma_reset(); + dma_set_at(1); + + device_reset_all(DEVICE_ALL); + + cpu_alt_reset = 0; + + pci_reset(); + + mem_a20_alt = 0; + mem_a20_recalc(); + + flushmmucache(); + + resetx86(); + } + break; + + case 0x64: /* INIT Enable Register */ + dev->pci_conf[addr] = val; + cpu_cpurst_on_sr = !(val & 0x20); + break; + + case 0x65: /* PHOLD# Timer */ + case 0x66: /* Priority Timer */ + case 0x67: /* Respond to C/D Segments Register */ + case 0x6b: /* Test Mode Register I */ + case 0x6c: /* Test Mode Register II */ + case 0x71: /* Reserved */ + case 0x72: /* Individual PC/PCI DMA Channel Enable */ + case 0x7c: /* Data Acquisition Module ADC Calibration */ + case 0x7d: /* Data Acquisition Module ADC Calibration */ + case 0x88: /* Serial Interrupt Control Register */ + case 0x89: /* Serial Interrupt Enable Register 1 */ + case 0x8a: /* Serial Interrupt Enable Register 2 */ + case 0x8c: /* Serial Interrupt Enable Register 3 */ + dev->pci_conf[addr] = val; + break; + + case 0x68: /* Data Acquistion Module Base Address */ + dev->pci_conf[addr] = val & 0xf8; + sis_5595_dam_recalc(dev); + break; + + case 0x6a: /* ACPI/SCI IRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: ACPI/SCI IRQ -> %02X\n", val); + dev->pci_conf[addr] = val & 0x8f; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ5, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ5, val & 0xf); + break; + + case 0x6d: /* I2C Bus Control Register */ + dev->pci_conf[addr] = val; + /* TODO: Keyboard/mouse swapping and keyboard hot key. */ + break; + + case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */ + old = dev->pci_conf[addr]; + picint((val ^ old) & val); + picintc((val ^ old) & ~val); + dev->pci_conf[addr] = val; + break; + + case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */ + old = dev->pci_conf[addr]; + picint(((val ^ old) & val) << 8); + picintc(((val ^ old) & ~val) << 8); + dev->pci_conf[addr] = val; + break; + + case 0x70: /* Misc. Controller Register */ + dev->pci_conf[addr] = val; + /* TODO: Keyboard Lock Enable/Disable. */ + break; + + case 0x73: + case 0x75 ... 0x79: + if (dev->rev == 0x81) + dev->pci_conf[addr] = val; + break; + + case 0x7a: /* Data Acquisition Module Function Selection Register */ + if (dev->rev == 0x81) + dev->pci_conf[addr] = val; + else + dev->pci_conf[addr] = val & 0x90; + break; + + case 0x7b: /* Data Acquisition Module Control Register */ + dev->pci_conf[addr] = val; + sis_5595_dam_recalc(dev); + break; + + case 0x7e: /* Data Acquisition Module and SMBUS IRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: DAM/SMBUS IRQ -> %02X\n", val); + if (dev->rev == 0x81) + dev->pci_conf[addr] = val & 0x8f; + else { + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x10) | (val & 0xef); + + dev->dam_irq_enable = ((val & 0xc0) == 0x40); + smbus_sis5595_irq_enable(dev->smbus, (val & 0xa0) == 0x20); + } + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ6, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ6, val & 0xf); + break; + + case 0x80: /* Distributed DMA Master Configuration Register */ + case 0x81: /* Distributed DMA Master Configuration Register */ + dev->pci_conf[addr] = val; + sis_5595_ddma_recalc(dev); + break; + + case 0x84: /* Individual Distributed DMA Channel Enable */ + dev->pci_conf[addr] = val; + sis_5595_ddma_recalc(dev); + break; + + case 0x90: /* ACPI Base Address Register */ + dev->pci_conf[addr] = val & 0xc0; + sis_5595_acpi_recalc(dev); + break; + case 0x91: /* ACPI Base Address Register */ + dev->pci_conf[addr] = val; + sis_5595_acpi_recalc(dev); + break; + + default: + break; + } +} + +void +sis_5513_pci_to_isa_write(int addr, uint8_t val, void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + + sis_5513_pci_to_isa_log("SiS 5513 P2I: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (addr) { + case 0x04: /* Command */ + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x07: /* Status */ + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x06) & ~(val & 0x30); + break; + + case 0x0d: /* Master Latency Timer */ + if (dev->rev >= 0x11) + dev->pci_conf[addr] = val; + break; + + case 0x40: /* BIOS Control Register */ + if (dev->rev >= 0x11) { + dev->pci_conf[addr] = val; + sis_5595_acpi_recalc(dev); + } else + dev->pci_conf[addr] = val & 0x3f; + break; + + case 0x41: /* INTA# Remapping Control Register */ + case 0x42: /* INTB# Remapping Control Register */ + case 0x43: /* INTC# Remapping Control Register */ + dev->pci_conf[addr] = val & 0x8f; + pci_set_irq_routing(addr & 0x07, (val & 0x80) ? PCI_IRQ_DISABLED : (val & 0x0f)); + break; + case 0x44: /* INTD# Remapping Control Register */ + if (dev->rev == 0x11) { + dev->pci_conf[addr] = val & 0xcf; + sis_5513_apc_recalc(dev, val & 0x10); + } else + dev->pci_conf[addr] = val & 0x8f; + pci_set_irq_routing(addr & 0x07, (val & 0x80) ? PCI_IRQ_DISABLED : (val & 0x0f)); + break; + + case 0x45: /* ISA Bus Control Register I */ + if (dev->rev >= 0x01) { + if (dev->rev == 0x01) + dev->pci_conf[addr] = val & 0xec; + else + dev->pci_conf[addr] = val; + switch (val >> 6) { + case 0: + cpu_set_isa_speed(7159091); + break; + case 1: + cpu_set_isa_pci_div(4); + break; + case 2: + cpu_set_isa_pci_div(3); + break; + + default: + break; + } + nvr_bank_set(0, !!(val & 0x08), dev->nvr); + if (dev->rev == 0xb0) + sis_5513_apc_recalc(dev, val & 0x02); + } + break; + case 0x46: /* ISA Bus Control Register II */ + if (dev->rev >= 0x11) + dev->pci_conf[addr] = val; + else if (dev->rev == 0x00) + dev->pci_conf[addr] = val & 0xec; + break; + case 0x47: /* DMA Clock and Wait State Control Register */ + switch (dev->rev) { + case 0x01: + dev->pci_conf[addr] = val & 0x3e; + break; + case 0x11: + dev->pci_conf[addr] = val & 0x7f; + break; + case 0xb0: + dev->pci_conf[addr] = val & 0xfd; + break; + } + break; + + case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ + case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ + case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ + case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ + dev->pci_conf[addr] = val; + break; + + default: + switch (dev->rev) { + case 0x00: + sis_5513_00_pci_to_isa_write(addr, val, priv); + break; + case 0x01: + sis_5513_01_pci_to_isa_write(addr, val, priv); + break; + case 0x11: + sis_5513_11_pci_to_isa_write(addr, val, priv); + break; + case 0x81: + case 0xb0: + sis_5513_b0_pci_to_isa_write(addr, val, priv); + break; + } + break; + } +} + +uint8_t +sis_5513_pci_to_isa_read(int addr, void *priv) +{ + const sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + uint8_t ret = 0xff; + + switch (addr) { + default: + ret = dev->pci_conf[addr]; + break; + case 0x4c ... 0x4f: + ret = pic_read_icw(0, addr & 0x03); + break; + case 0x50 ... 0x53: + ret = pic_read_icw(1, addr & 0x03); + break; + case 0x54 ... 0x55: + ret = pic_read_ocw(0, addr & 0x01); + break; + case 0x56 ... 0x57: + ret = pic_read_ocw(1, addr & 0x01); + break; + case 0x58 ... 0x5f: + ret = dev->pit_read_reg(dev->pit, addr & 0x07); + break; + case 0x60: + if (dev->rev >= 0x01) + ret = inb(0x0070); + else + ret = dev->pci_conf[addr]; + break; + } + + sis_5513_pci_to_isa_log("SiS 5513 P2I: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5513_isa_write(uint16_t addr, uint8_t val, void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + + switch (addr) { + case 0x22: + dev->index = val - 0x50; + break; + case 0x23: + sis_5513_pci_to_isa_log("SiS 5513 ISA: [W] dev->regs[%02X] = %02X\n", dev->index + 0x50, val); + + switch (dev->index) { + case 0x00: + dev->regs[dev->index] = val & 0xed; + switch (val >> 6) { + case 0: + cpu_set_isa_speed(7159091); + break; + case 1: + cpu_set_isa_pci_div(4); + break; + case 2: + cpu_set_isa_pci_div(3); + break; + + default: + break; + } + nvr_bank_set(0, !!(val & 0x08), dev->nvr); + break; + case 0x01: + dev->regs[dev->index] = val & 0xf4; + break; + case 0x03: + dev->regs[dev->index] = val & 3; + break; + case 0x04: /* BIOS Register */ + dev->regs[dev->index] = val; + break; + case 0x05: + dev->regs[dev->index] = val; + outb(0x70, val); + break; + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + dev->regs[dev->index] = val; + break; + + default: + break; + } + break; + + default: + break; + } +} + +static uint8_t +sis_5513_isa_read(uint16_t addr, void *priv) +{ + const sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + uint8_t ret = 0xff; + + if (addr == 0x23) { + if (dev->index == 0x05) + ret = inb(0x70); + else + ret = dev->regs[dev->index]; + + sis_5513_pci_to_isa_log("SiS 5513 ISA: [R] dev->regs[%02X] = %02X\n", dev->index + 0x50, ret); + } + + return ret; +} + +static void +sis_5513_00_pci_to_isa_reset(sis_5513_pci_to_isa_t *dev) +{ + dev->pci_conf[0x60] = dev->pci_conf[0x61] = 0x80; + dev->pci_conf[0x62] = 0x00; + dev->pci_conf[0x63] = 0x80; + dev->pci_conf[0x64] = 0x00; + dev->pci_conf[0x65] = 0x00; + dev->pci_conf[0x66] = dev->pci_conf[0x67] = 0x00; + dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00; + dev->pci_conf[0x6a] = 0x04; + + pci_set_mirq_routing(PCI_MIRQ0, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED); + + dev->regs[0x00] = dev->regs[0x01] = 0x00; + dev->regs[0x03] = dev->regs[0x04] = 0x00; + dev->regs[0x05] = 0x00; + dev->regs[0x08] = dev->regs[0x09] = 0x00; + dev->regs[0x0a] = dev->regs[0x0b] = 0x00; +} + +static void +sis_5513_01_pci_to_isa_reset(sis_5513_pci_to_isa_t *dev) +{ + dev->pci_conf[0x45] = dev->pci_conf[0x46] = 0x00; + dev->pci_conf[0x47] = 0x00; + + dev->pci_conf[0x61] = 0x80; + dev->pci_conf[0x62] = 0x00; + dev->pci_conf[0x63] = 0x80; + dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00; + dev->pci_conf[0x66] = dev->pci_conf[0x67] = 0x00; + dev->pci_conf[0x68] = 0x80; + dev->pci_conf[0x69] = dev->pci_conf[0x6a] = 0x00; + dev->pci_conf[0x6b] = 0x00; + dev->pci_conf[0x6c] = 0x02; + dev->pci_conf[0x6d] = 0x00; + dev->pci_conf[0x6e] = dev->pci_conf[0x6f] = 0x00; + dev->pci_conf[0x70] = dev->pci_conf[0x71] = 0x00; + dev->pci_conf[0x72] = dev->pci_conf[0x73] = 0x00; + dev->pci_conf[0x74] = dev->pci_conf[0x75] = 0x00; + dev->pci_conf[0x76] = dev->pci_conf[0x77] = 0x00; + + pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); +} + +static void +sis_5513_11_pci_to_isa_reset(sis_5513_pci_to_isa_t *dev) +{ + dev->pci_conf[0x45] = dev->pci_conf[0x46] = 0x00; + dev->pci_conf[0x47] = 0x00; + + dev->pci_conf[0x61] = dev->pci_conf[0x62] = 0x80; + dev->pci_conf[0x63] = dev->pci_conf[0x64] = 0x00; + dev->pci_conf[0x65] = dev->pci_conf[0x66] = 0x00; + dev->pci_conf[0x67] = dev->pci_conf[0x68] = 0x00; + dev->pci_conf[0x69] = 0x01; + dev->pci_conf[0x6a] = 0x80; + dev->pci_conf[0x6b] = 0x00; + dev->pci_conf[0x6c] = 0x20; + dev->pci_conf[0x6d] = 0x19; + dev->pci_conf[0x6e] = dev->pci_conf[0x6f] = 0x00; + dev->pci_conf[0x70] = 0x12; + dev->pci_conf[0x71] = dev->pci_conf[0x72] = 0x00; + dev->pci_conf[0x73] = dev->pci_conf[0x74] = 0x00; + dev->pci_conf[0x75] = dev->pci_conf[0x76] = 0x00; + dev->pci_conf[0x77] = 0x00; + dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x84] = dev->pci_conf[0x88] = 0x00; + dev->pci_conf[0x89] = dev->pci_conf[0x8a] = 0x00; + dev->pci_conf[0x90] = dev->pci_conf[0x91] = 0x00; + + pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ5, PCI_IRQ_DISABLED); + + picint_common(0xffff, 0, 0, NULL); + + sis_5595_ddma_recalc(dev); + sis_5595_acpi_recalc(dev); + + dev->sis->ide_bits_1_3_writable = 0; + dev->sis->usb_enabled = 0; + + sis_5513_apc_reset(dev); + sis_5513_apc_recalc(dev, 0); +} + +static void +sis_5513_b0_pci_to_isa_reset(sis_5513_pci_to_isa_t *dev) +{ + dev->pci_conf[0x45] = dev->pci_conf[0x46] = 0x00; + dev->pci_conf[0x47] = 0x00; + + dev->pci_conf[0x61] = dev->pci_conf[0x62] = 0x80; + dev->pci_conf[0x63] = dev->pci_conf[0x64] = 0x00; + dev->pci_conf[0x65] = 0x01; + dev->pci_conf[0x66] = dev->pci_conf[0x67] = 0x00; + dev->pci_conf[0x68] = 0x90; + dev->pci_conf[0x69] = 0x02; + dev->pci_conf[0x6a] = 0x80; + dev->pci_conf[0x6b] = 0x00; + dev->pci_conf[0x6c] = 0x20; + dev->pci_conf[0x6d] = 0x19; + dev->pci_conf[0x6e] = dev->pci_conf[0x6f] = 0x00; + dev->pci_conf[0x70] = 0x12; + dev->pci_conf[0x71] = dev->pci_conf[0x72] = 0x00; + dev->pci_conf[0x7a] = dev->pci_conf[0x7b] = 0x00; + dev->pci_conf[0x7c] = dev->pci_conf[0x7d] = 0x00; + dev->pci_conf[0x7e] = 0x80; + dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x84] = dev->pci_conf[0x88] = 0x00; + dev->pci_conf[0x89] = dev->pci_conf[0x8a] = 0x00; + dev->pci_conf[0x8b] = dev->pci_conf[0x8c] = 0x00; + dev->pci_conf[0x90] = dev->pci_conf[0x91] = 0x00; + + pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ5, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ6, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ7, 15); + + sff_set_mirq(dev->sis->bm[0], 2); + sff_set_mirq(dev->sis->bm[1], 7); + + picint_common(0xffff, 0, 0, NULL); + + sis_5595_ddma_recalc(dev); + sis_5595_acpi_recalc(dev); + + /* SiS 5595 Data Acquisition Module */ + sis_5595_dam_recalc(dev); + sis_5595_dam_reset(dev); + + dev->dam_irq_enable = 0; + + cpu_cpurst_on_sr = 1; + + dev->sis->usb_enabled = 0; + + sis_5513_apc_reset(dev); + sis_5513_apc_recalc(dev, 0); + + if (dev->rev == 0x81) + dev->dam_irq_enable = 1; +} + +static void +sis_5513_pci_to_isa_reset(void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x08; + dev->pci_conf[0x03] = 0x00; + dev->pci_conf[0x04] = 0x07; + dev->pci_conf[0x05] = dev->pci_conf[0x06] = 0x00; + dev->pci_conf[0x07] = 0x02; + if ((dev->rev == 0x11) || (dev->rev == 0x81)) + dev->pci_conf[0x08] = 0x01; + else + dev->pci_conf[0x08] = dev->rev; + dev->pci_conf[0x09] = 0x00; + dev->pci_conf[0x0a] = 0x01; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x0e] = 0x80; + dev->pci_conf[0x40] = 0x00; + dev->pci_conf[0x41] = dev->pci_conf[0x42] = 0x80; + dev->pci_conf[0x43] = dev->pci_conf[0x44] = 0x80; + dev->pci_conf[0x48] = dev->pci_conf[0x49] = 0x00; + dev->pci_conf[0x4a] = dev->pci_conf[0x4b] = 0x00; + + switch (dev->rev) { + case 0x00: + sis_5513_00_pci_to_isa_reset(dev); + break; + case 0x01: + sis_5513_01_pci_to_isa_reset(dev); + break; + case 0x11: + sis_5513_11_pci_to_isa_reset(dev); + break; + case 0x81: + case 0xb0: + sis_5513_b0_pci_to_isa_reset(dev); + break; + } + + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + + pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); + + cpu_set_isa_speed(7159091); + nvr_bank_set(0, 0, dev->nvr); +} + +static void +sis_5513_pci_to_isa_close(void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + + free(dev); +} + +static void * +sis_5513_pci_to_isa_init(UNUSED(const device_t *info)) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) calloc(1, sizeof(sis_5513_pci_to_isa_t)); + uint8_t pit_is_fast = (((pit_mode == -1) && is486) || (pit_mode == 1)); + + dev->rev = info->local; + + dev->sis = device_get_common_priv(); + + /* IDEIRQ */ + pci_enable_mirq(2); + + /* Port 92h */ + dev->port_92 = device_add(&port_92_device); + + /* PIT */ + dev->pit = device_find_first_priv(DEVICE_PIT); + dev->pit_read_reg = pit_is_fast ? pitf_read_reg : pit_read_reg; + + /* NVR */ + dev->nvr = device_add(&at_mb_nvr_device); + + switch (dev->rev) { + case 0x00: + /* MIRQ */ + pci_enable_mirq(0); + pci_enable_mirq(1); + + /* Ports 22h-23h: SiS 5513 ISA */ + io_sethandler(0x0022, 0x0002, + sis_5513_isa_read, NULL, NULL, sis_5513_isa_write, NULL, NULL, dev); + break; + case 0x01: + /* MIRQ */ + pci_enable_mirq(1); + break; + case 0x11: + case 0x81: + case 0xb0: + /* USBIRQ */ + pci_enable_mirq(3); + + /* ACPI/SCI IRQ */ + pci_enable_mirq(5); + + if (dev->rev == 0xb0) { + /* Data Acquisition Module and SMBUS IRQ */ + pci_enable_mirq(6); + + /* Non-remapped native IDE IRQ */ + pci_enable_mirq(7); + } + + dev->ddma = device_add(&ddma_device); + + switch (dev->rev) { + case 0x11: + dev->sis->acpi = device_add(&acpi_sis_5582_device); + break; + case 0x81: + dev->sis->acpi = device_add(&acpi_sis_5595_1997_device); + break; + case 0xb0: + dev->sis->acpi = device_add(&acpi_sis_5595_device); + dev->smbus = acpi_get_smbus(dev->sis->acpi); + break; + } + + dev->sis->acpi->priv = dev->sis; + acpi_set_slot(dev->sis->acpi, dev->sis->sb_pci_slot); + acpi_set_nvr(dev->sis->acpi, dev->nvr); + acpi_set_irq_mode(dev->sis->acpi, 2); + break; + } + + sis_5513_pci_to_isa_reset(dev); + + return dev; +} + +const device_t sis_5513_p2i_device = { + .name = "SiS 5513 PCI to ISA bridge", + .internal_name = "sis_5513_pci_to_isa", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5513_pci_to_isa_init, + .close = sis_5513_pci_to_isa_close, + .reset = sis_5513_pci_to_isa_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5572_p2i_device = { + .name = "SiS 5572 PCI to ISA bridge", + .internal_name = "sis_5572_pci_to_isa", + .flags = DEVICE_PCI, + .local = 0x01, + .init = sis_5513_pci_to_isa_init, + .close = sis_5513_pci_to_isa_close, + .reset = sis_5513_pci_to_isa_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5582_p2i_device = { + .name = "SiS 5582 PCI to ISA bridge", + .internal_name = "sis_5582_pci_to_isa", + .flags = DEVICE_PCI, + .local = 0x11, /* Actually, 0x01, but we need to somehow distinguish it + from SiS 5572 and SiS 5595 1997, which are also revision 0x01. */ + .init = sis_5513_pci_to_isa_init, + .close = sis_5513_pci_to_isa_close, + .reset = sis_5513_pci_to_isa_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5595_1997_p2i_device = { + .name = "SiS 5595 (1997) PCI to ISA bridge", + .internal_name = "sis_5595_1997_pci_to_isa", + .flags = DEVICE_PCI, + .local = 0x81, /* Actually, 0x01, but we need to somehow distinguish it + from SiS 5572 and SiS 5582, which are also revision 0x01. */ + .init = sis_5513_pci_to_isa_init, + .close = sis_5513_pci_to_isa_close, + .reset = sis_5513_pci_to_isa_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5595_p2i_device = { + .name = "SiS 5595 PCI to ISA bridge", + .internal_name = "sis_5595_pci_to_isa", + .flags = DEVICE_PCI, + .local = 0xb0, + .init = sis_5513_pci_to_isa_init, + .close = sis_5513_pci_to_isa_close, + .reset = sis_5513_pci_to_isa_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5571.c b/src/chipset/sis_5571.c index 007a96178..3fb111978 100644 --- a/src/chipset/sis_5571.c +++ b/src/chipset/sis_5571.c @@ -6,11 +6,11 @@ * * This file is part of the 86Box distribution. * - * Implementation of the SiS 5571 Pentium PCI/ISA Chipset. + * Implementation of the SiS 5571/5572 Pentium PCI/ISA Chipset. * * Authors: Miran Grca, * - * Copyright 2023-2024 Miran Grca. + * Copyright 2021-2023 Miran Grca. */ #include #include @@ -23,10 +23,10 @@ #include <86box/device.h> #include <86box/io.h> #include <86box/timer.h> - -// #include <86box/dma.h> #include <86box/mem.h> #include <86box/nvr.h> +#include <86box/apm.h> +#include <86box/acpi.h> #include <86box/hdd.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> @@ -40,8 +40,7 @@ #include <86box/port_92.h> #include <86box/smram.h> #include <86box/spd.h> -#include <86box/usb.h> - +#include <86box/sis_55xx.h> #include <86box/chipset.h> #ifdef ENABLE_SIS_5571_LOG @@ -63,1128 +62,90 @@ sis_5571_log(const char *fmt, ...) #endif typedef struct sis_5571_t { - uint8_t index; - uint8_t nb_slot; - uint8_t sb_slot; - uint8_t pad; + uint8_t nb_slot; + uint8_t sb_slot; - uint8_t regs[16]; - uint8_t states[7]; - uint8_t pad0; + void *h2p; + void *p2i; + void *ide; + void *usb; - uint8_t usb_unk_regs[8]; - - uint8_t pci_conf[256]; - uint8_t pci_conf_sb[3][256]; - - uint16_t usb_unk_base; - - sff8038i_t *bm[2]; - smram_t *smram; - port_92_t *port_92; - void *pit; - nvr_t *nvr; - usb_t *usb; - - uint8_t (*pit_read_reg)(void *priv, uint8_t reg); + sis_55xx_common_t *sis; } sis_5571_t; static void -sis_5571_shadow_recalc(sis_5571_t *dev) +sis_5571_write(int func, int addr, uint8_t val, void *priv) { - int state; - uint32_t base; + const sis_5571_t *dev = (sis_5571_t *) priv; - for (uint8_t i = 0x70; i <= 0x76; i++) { - if (i == 0x76) { - if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { - state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; - mem_set_mem_state_both(0xf0000, 0x10000, state); - sis_5571_log("000F0000-000FFFFF\n"); - } - } else { - base = ((i & 0x07) << 15) + 0xc0000; + sis_5571_log("SiS 5571: [W] dev->pci_conf[%02X] = %02X\n", addr, val); - if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { - state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; - mem_set_mem_state_both(base, 0x4000, state); - sis_5571_log("%08X-%08X\n", base, base + 0x3fff); - } - - if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) { - state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; - mem_set_mem_state_both(base + 0x4000, 0x4000, state); - sis_5571_log("%08X-%08X\n", base + 0x4000, base + 0x7fff); - } - } - - dev->states[i & 0x0f] = dev->pci_conf[i]; - } - - flushmmucache_nopc(); -} - -static void -sis_5571_smram_recalc(sis_5571_t *dev) -{ - smram_disable_all(); - - switch (dev->pci_conf[0xa3] >> 6) { - case 0: - smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); - break; - case 1: - smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); - break; - case 2: - smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); - break; - case 3: - smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0xa3] & 0x10, 1); - break; - - default: - break; - } - - flushmmucache(); -} - -static void -sis_5571_mem_to_pci_reset(sis_5571_t *dev) -{ - dev->pci_conf[0x00] = 0x39; - dev->pci_conf[0x01] = 0x10; - dev->pci_conf[0x02] = 0x71; - dev->pci_conf[0x03] = 0x55; - dev->pci_conf[0x04] = 0x05; - dev->pci_conf[0x05] = 0x00; - dev->pci_conf[0x06] = 0x00; - dev->pci_conf[0x07] = 0x02; - dev->pci_conf[0x08] = 0x00; - dev->pci_conf[0x09] = 0x00; - dev->pci_conf[0x0a] = 0x00; - dev->pci_conf[0x0b] = 0x06; - dev->pci_conf[0x0c] = 0x00; - dev->pci_conf[0x0d] = 0x00; - dev->pci_conf[0x0e] = 0x00; - dev->pci_conf[0x0f] = 0x00; - - dev->pci_conf[0x50] = 0x00; - dev->pci_conf[0x51] = 0x00; - dev->pci_conf[0x52] = 0x00; - dev->pci_conf[0x53] = 0x00; - dev->pci_conf[0x54] = 0x54; - dev->pci_conf[0x55] = 0x54; - dev->pci_conf[0x56] = 0x03; - dev->pci_conf[0x57] = 0x00; - dev->pci_conf[0x58] = 0x00; - dev->pci_conf[0x59] = 0x00; - dev->pci_conf[0x5a] = 0x00; - - /* Undocumented DRAM bank registers. */ - dev->pci_conf[0x60] = dev->pci_conf[0x62] = 0x04; - dev->pci_conf[0x64] = dev->pci_conf[0x66] = 0x04; - dev->pci_conf[0x68] = dev->pci_conf[0x6a] = 0x04; - dev->pci_conf[0x61] = dev->pci_conf[0x65] = 0x00; - dev->pci_conf[0x63] = dev->pci_conf[0x67] = 0x80; - dev->pci_conf[0x69] = 0x00; - dev->pci_conf[0x6b] = 0x80; - - dev->pci_conf[0x70] = 0x00; - dev->pci_conf[0x71] = 0x00; - dev->pci_conf[0x72] = 0x00; - dev->pci_conf[0x73] = 0x00; - dev->pci_conf[0x74] = 0x00; - dev->pci_conf[0x75] = 0x00; - dev->pci_conf[0x76] = 0x00; - - dev->pci_conf[0x77] = 0x00; - dev->pci_conf[0x78] = 0x00; - dev->pci_conf[0x79] = 0x00; - dev->pci_conf[0x7a] = 0x00; - dev->pci_conf[0x7b] = 0x00; - - dev->pci_conf[0x80] = 0x00; - dev->pci_conf[0x81] = 0x00; - dev->pci_conf[0x82] = 0x00; - dev->pci_conf[0x83] = 0x00; - dev->pci_conf[0x84] = 0x00; - dev->pci_conf[0x85] = 0x00; - dev->pci_conf[0x86] = 0x00; - dev->pci_conf[0x87] = 0x00; - - dev->pci_conf[0x8c] = 0x00; - dev->pci_conf[0x8d] = 0x00; - dev->pci_conf[0x8e] = 0x00; - dev->pci_conf[0x8f] = 0x00; - - dev->pci_conf[0x90] = 0x00; - dev->pci_conf[0x91] = 0x00; - dev->pci_conf[0x92] = 0x00; - dev->pci_conf[0x93] = 0x00; - dev->pci_conf[0x93] = 0x00; - dev->pci_conf[0x94] = 0x00; - dev->pci_conf[0x95] = 0x00; - dev->pci_conf[0x96] = 0x00; - dev->pci_conf[0x97] = 0x00; - dev->pci_conf[0x98] = 0x00; - dev->pci_conf[0x99] = 0x00; - dev->pci_conf[0x9a] = 0x00; - dev->pci_conf[0x9b] = 0x00; - dev->pci_conf[0x9c] = 0x00; - dev->pci_conf[0x9d] = 0x00; - dev->pci_conf[0x9e] = 0xff; - dev->pci_conf[0x9f] = 0xff; - - dev->pci_conf[0xa0] = 0xff; - dev->pci_conf[0xa1] = 0x00; - dev->pci_conf[0xa2] = 0xff; - dev->pci_conf[0xa3] = 0x00; - - cpu_cache_ext_enabled = 0; - cpu_update_waitstates(); - - sis_5571_smram_recalc(dev); - sis_5571_shadow_recalc(dev); - - flushmmucache(); -} - -static void -sis_5571_mem_to_pci_write(int func, int addr, uint8_t val, void *priv) -{ - sis_5571_t *dev = (sis_5571_t *) priv; - - if (func == 0) { - sis_5571_log("SiS 5571 M2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val); - - switch (addr) { - case 0x04: /* Command - low byte */ - case 0x05: /* Command - high byte */ - dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xfd) | (val & 0x02); - break; - - case 0x07: /* Status - High Byte */ - dev->pci_conf[addr] &= ~(val & 0xb8); - break; - - case 0x0d: /* Master latency timer */ - dev->pci_conf[addr] = val; - break; - - case 0x50: /* Host Interface and DRAM arbiter */ - dev->pci_conf[addr] = val & 0xec; - break; - - case 0x51: /* CACHE */ - dev->pci_conf[addr] = val; - cpu_cache_ext_enabled = !!(val & 0x40); - cpu_update_waitstates(); - break; - - case 0x52: - dev->pci_conf[addr] = val & 0xd0; - break; - - case 0x53: /* DRAM */ - dev->pci_conf[addr] = val & 0xfe; - break; - - case 0x54: /* FP/EDO */ - dev->pci_conf[addr] = val; - break; - - case 0x55: - dev->pci_conf[addr] = val & 0xe0; - break; - - case 0x56: /* MDLE delay */ - dev->pci_conf[addr] = val & 0x07; - break; - - case 0x57: /* SDRAM */ - dev->pci_conf[addr] = val & 0xf8; - break; - - case 0x59: /* Buffer strength and current rating */ - dev->pci_conf[addr] = val; - break; - - case 0x5a: - dev->pci_conf[addr] = val & 0x03; - break; - - /* Undocumented - DRAM bank registers, the exact layout is currently unknown. */ - case 0x60 ... 0x6b: - dev->pci_conf[addr] = val; - break; - - case 0x70 ... 0x75: - dev->pci_conf[addr] = val & 0xee; - sis_5571_shadow_recalc(dev); - break; - case 0x76: - dev->pci_conf[addr] = val & 0xe8; - sis_5571_shadow_recalc(dev); - break; - - case 0x77: /* Characteristics of non-cacheable area */ - dev->pci_conf[addr] = val & 0x0f; - break; - - case 0x78: /* Allocation of Non-Cacheable area #1 */ - case 0x79: /* NCA1REG2 */ - case 0x7a: /* Allocation of Non-Cacheable area #2 */ - case 0x7b: /* NCA2REG2 */ - dev->pci_conf[addr] = val; - break; - - case 0x80: /* PCI master characteristics */ - dev->pci_conf[addr] = val & 0xfe; - break; - - case 0x81: - dev->pci_conf[addr] = val & 0xcc; - break; - - case 0x82: - dev->pci_conf[addr] = val; - break; - - case 0x83: /* CPU to PCI characteristics */ - dev->pci_conf[addr] = val; - /* TODO: Implement Fast A20 and Fast reset stuff on the KBC already! */ - break; - - case 0x84 ... 0x86: - dev->pci_conf[addr] = val; - break; - - case 0x87: /* Miscellanea */ - dev->pci_conf[addr] = val & 0xf8; - break; - - case 0x90: /* PMU control register */ - case 0x91: /* Address trap for green function */ - case 0x92: - dev->pci_conf[addr] = val; - break; - - case 0x93: /* STPCLK# and APM SMI control */ - dev->pci_conf[addr] = val; - - if ((dev->pci_conf[0x9b] & 0x01) && (val & 0x02)) { - smi_raise(); - dev->pci_conf[0x9d] |= 0x01; - } - break; - - case 0x94: /* 6x86 and Green function control */ - dev->pci_conf[addr] = val & 0xf8; - break; - - case 0x95: /* Test mode control */ - case 0x96: /* Time slot and Programmable 10-bit I/O port definition */ - dev->pci_conf[addr] = val & 0xfb; - break; - - case 0x97: /* programmable 10-bit I/O port address */ - case 0x98: /* Programmable 16-bit I/O port */ - case 0x99 ... 0x9c: - dev->pci_conf[addr] = val; - break; - - case 0x9d: - dev->pci_conf[addr] &= val; - break; - - case 0x9e: /* STPCLK# Assertion Timer */ - case 0x9f: /* STPCLK# De-assertion Timer */ - case 0xa0 ... 0xa2: - dev->pci_conf[addr] = val; - break; - - case 0xa3: /* SMRAM access control and Power supply control */ - dev->pci_conf[addr] = val & 0xd0; - sis_5571_smram_recalc(dev); - break; - - default: - break; - } - } + if (func == 0x00) + sis_5571_host_to_pci_write(addr, val, dev->h2p); } static uint8_t -sis_5571_mem_to_pci_read(int func, int addr, void *priv) +sis_5571_read(int func, int addr, void *priv) { const sis_5571_t *dev = (sis_5571_t *) priv; uint8_t ret = 0xff; - if (func == 0x00) { - ret = dev->pci_conf[addr]; + if (func == 0x00) + ret = sis_5571_host_to_pci_read(addr, dev->h2p); - sis_5571_log("SiS 5571 M2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); - } + sis_5571_log("SiS 5571: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); return ret; } static void -sis_5571_pci_to_isa_reset(sis_5571_t *dev) -{ - /* PCI to ISA Bridge */ - dev->pci_conf_sb[0][0x00] = 0x39; - dev->pci_conf_sb[0][0x01] = 0x10; - dev->pci_conf_sb[0][0x02] = 0x08; - dev->pci_conf_sb[0][0x03] = 0x00; - dev->pci_conf_sb[0][0x04] = 0x07; - dev->pci_conf_sb[0][0x05] = 0x00; - dev->pci_conf_sb[0][0x06] = 0x00; - dev->pci_conf_sb[0][0x07] = 0x02; - dev->pci_conf_sb[0][0x08] = 0x01; - dev->pci_conf_sb[0][0x09] = 0x00; - dev->pci_conf_sb[0][0x0a] = 0x01; - dev->pci_conf_sb[0][0x0b] = 0x06; - dev->pci_conf_sb[0][0x0e] = 0x80; - - dev->pci_conf_sb[0][0x40] = 0x00; - dev->pci_conf_sb[0][0x41] = dev->pci_conf_sb[0][0x42] = 0x80; - dev->pci_conf_sb[0][0x43] = dev->pci_conf_sb[0][0x44] = 0x80; - dev->pci_conf_sb[0][0x45] = 0x00; - dev->pci_conf_sb[0][0x46] = 0x00; - dev->pci_conf_sb[0][0x47] = 0x00; - dev->pci_conf_sb[0][0x48] = dev->pci_conf_sb[0][0x49] = 0x00; - dev->pci_conf_sb[0][0x4a] = dev->pci_conf_sb[0][0x4b] = 0x00; - dev->pci_conf_sb[0][0x61] = 0x80; - dev->pci_conf_sb[0][0x62] = 0x00; - dev->pci_conf_sb[0][0x63] = 0x80; - dev->pci_conf_sb[0][0x64] = 0x00; - dev->pci_conf_sb[0][0x65] = 0x00; - dev->pci_conf_sb[0][0x66] = dev->pci_conf_sb[0][0x67] = 0x00; - dev->pci_conf_sb[0][0x68] = 0x80; - dev->pci_conf_sb[0][0x69] = dev->pci_conf_sb[0][0x6a] = 0x00; - dev->pci_conf_sb[0][0x6b] = 0x00; - dev->pci_conf_sb[0][0x6c] = 0x02; - dev->pci_conf_sb[0][0x6d] = 0x00; - dev->pci_conf_sb[0][0x6e] = dev->pci_conf_sb[0][0x6f] = 0x00; - dev->pci_conf_sb[0][0x70] = dev->pci_conf_sb[0][0x71] = 0x00; - dev->pci_conf_sb[0][0x72] = dev->pci_conf_sb[0][0x73] = 0x00; - dev->pci_conf_sb[0][0x74] = dev->pci_conf_sb[0][0x75] = 0x00; - dev->pci_conf_sb[0][0x76] = dev->pci_conf_sb[0][0x77] = 0x00; - - pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); - - pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED); - pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); - pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); - - cpu_set_isa_speed(7159091); - nvr_bank_set(0, 0, dev->nvr); -} - -static void -sis_5571_pci_to_isa_write(int addr, uint8_t val, void *priv) -{ - sis_5571_t *dev = (sis_5571_t *) priv; - uint8_t old; - - sis_5571_log("SiS 5571 P2I: [W] dev->pci_conf_sb[0][%02X] = %02X\n", addr, val); - - switch (addr) { - default: - break; - - case 0x04: /* Command */ - // dev->pci_conf_sb[0][addr] = val & 0x0f; - break; - - case 0x07: /* Status */ - dev->pci_conf_sb[0][addr] &= ~(val & 0x30); - break; - - case 0x40: /* BIOS Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x3f; - break; - - case 0x41: /* INTA# Remapping Control Register */ - case 0x42: /* INTB# Remapping Control Register */ - case 0x43: /* INTC# Remapping Control Register */ - case 0x44: /* INTD# Remapping Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x8f; - pci_set_irq_routing(addr & 0x07, (val & 0x80) ? PCI_IRQ_DISABLED : (val & 0x0f)); - break; - - case 0x45: - dev->pci_conf_sb[0][addr] = val & 0xec; - switch (val >> 6) { - case 0: - cpu_set_isa_speed(7159091); - break; - case 1: - cpu_set_isa_pci_div(4); - break; - case 2: - cpu_set_isa_pci_div(3); - break; - - default: - break; - } - nvr_bank_set(0, !!(val & 0x08), dev->nvr); - break; - - case 0x46: - dev->pci_conf_sb[0][addr] = val & 0xec; - break; - - case 0x47: /* DMA Clock and Wait State Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x3e; - break; - - case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ - case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ - case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ - case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x60: - outb(0x0070, val); - break; - - /* Simply skip MIRQ0, so we can reuse the SiS 551x IDEIRQ infrastructure. */ - case 0x61: /* MIRQ Remapping Control Register */ - sis_5571_log("Set MIRQ routing: MIRQ%i -> %02X\n", addr & 0x01, val); - dev->pci_conf_sb[0][addr] = val & 0xcf; - if (val & 0x80) - pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), PCI_IRQ_DISABLED); - else - pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf); - break; - - case 0x62: /* On-board Device DMA Control Register */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x63: /* IDEIRQ Remapping Control Register */ - sis_5571_log("Set MIRQ routing: IDEIRQ -> %02X\n", val); - dev->pci_conf_sb[0][addr] = val & 0x8f; - if (val & 0x80) - pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); - else - pci_set_mirq_routing(PCI_MIRQ2, val & 0xf); - break; - - case 0x64: /* GPIO Control Register */ - dev->pci_conf_sb[0][addr] = val & 0xef; - break; - - case 0x65: - dev->pci_conf_sb[0][addr] = val & 0x1b; - break; - - case 0x66: /* GPIO Output Mode Control Register */ - case 0x67: /* GPIO Output Mode Control Register */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x68: /* USBIRQ Remapping Control Register */ - sis_5571_log("Set MIRQ routing: USBIRQ -> %02X\n", val); - dev->pci_conf_sb[0][addr] = val & 0xcf; - if (val & 0x80) - pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); - else - pci_set_mirq_routing(PCI_MIRQ3, val & 0xf); - break; - - case 0x69: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x6a: - dev->pci_conf_sb[0][addr] = val & 0xfc; - break; - - case 0x6b: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x6c: - dev->pci_conf_sb[0][addr] = val & 0x02; - break; - - case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */ - old = dev->pci_conf_sb[0][addr]; - picint((val ^ old) & val); - picintc((val ^ old) & ~val); - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */ - old = dev->pci_conf_sb[0][addr]; - picint(((val ^ old) & val) << 8); - picintc(((val ^ old) & ~val) << 8); - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x70: - dev->pci_conf_sb[0][addr] = (dev->pci_conf_sb[0][addr] & 0x02) | (val & 0xdc); - break; - - case 0x71: /* Type-F DMA Control Register */ - dev->pci_conf_sb[0][addr] = val & 0xef; - break; - - case 0x72: /* SMI Triggered By IRQ/GPIO Control */ - case 0x73: /* SMI Triggered By IRQ/GPIO Control */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x74: /* System Standby Timer Reload, - System Standby State Exit And Throttling State Exit Control */ - case 0x75: /* System Standby Timer Reload, - System Standby State Exit And Throttling State Exit Control */ - case 0x76: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */ - case 0x77: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */ - dev->pci_conf_sb[0][addr] = val; - break; - } -} - -static uint8_t -sis_5571_pci_to_isa_read(int addr, void *priv) +sis_5572_write(int func, int addr, uint8_t val, void *priv) { const sis_5571_t *dev = (sis_5571_t *) priv; - uint8_t ret = 0xff; - switch (addr) { - default: - ret = dev->pci_conf_sb[0][addr]; - break; - case 0x4c ... 0x4f: - ret = pic_read_icw(0, addr & 0x03); - break; - case 0x50 ... 0x53: - ret = pic_read_icw(1, addr & 0x03); - break; - case 0x54 ... 0x55: - ret = pic_read_ocw(0, addr & 0x01); - break; - case 0x56 ... 0x57: - ret = pic_read_ocw(1, addr & 0x01); - break; - case 0x58 ... 0x5f: - ret = dev->pit_read_reg(dev->pit, addr & 0x07); - break; - case 0x60: - ret = inb(0x0070); - break; - } + sis_5571_log("SiS 5572: [W] dev->pci_conf[%02X] = %02X\n", addr, val); - sis_5571_log("SiS 5571 P2I: [R] dev->pci_conf_sb[0][%02X] = %02X\n", addr, ret); - - return ret; -} - -static void -sis_5571_ide_irq_handler(sis_5571_t *dev) -{ - if (dev->pci_conf_sb[1][0x09] & 0x01) { - /* Primary IDE is native. */ - sis_5571_log("Primary IDE IRQ mode: Native, Native\n"); - sff_set_irq_mode(dev->bm[0], IRQ_MODE_SIS_551X); - } else { - /* Primary IDE is legacy. */ - sis_5571_log("Primary IDE IRQ mode: IRQ14, IRQ15\n"); - sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); - } - - if (dev->pci_conf_sb[1][0x09] & 0x04) { - /* Secondary IDE is native. */ - sis_5571_log("Secondary IDE IRQ mode: Native, Native\n"); - sff_set_irq_mode(dev->bm[1], IRQ_MODE_SIS_551X); - } else { - /* Secondary IDE is legacy. */ - sis_5571_log("Secondary IDE IRQ mode: IRQ14, IRQ15\n"); - sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); - } -} - -static void -sis_5571_ide_handler(sis_5571_t *dev) -{ - uint8_t ide_io_on = dev->pci_conf_sb[1][0x04] & 0x01; - - uint16_t native_base_pri_addr = (dev->pci_conf_sb[1][0x11] | dev->pci_conf_sb[1][0x10] << 8) & 0xfffe; - uint16_t native_side_pri_addr = (dev->pci_conf_sb[1][0x15] | dev->pci_conf_sb[1][0x14] << 8) & 0xfffe; - uint16_t native_base_sec_addr = (dev->pci_conf_sb[1][0x19] | dev->pci_conf_sb[1][0x18] << 8) & 0xfffe; - uint16_t native_side_sec_addr = (dev->pci_conf_sb[1][0x1c] | dev->pci_conf_sb[1][0x1b] << 8) & 0xfffe; - - uint16_t current_pri_base; - uint16_t current_pri_side; - uint16_t current_sec_base; - uint16_t current_sec_side; - - /* Primary Channel Programming */ - current_pri_base = (!(dev->pci_conf_sb[1][0x09] & 1)) ? 0x01f0 : native_base_pri_addr; - current_pri_side = (!(dev->pci_conf_sb[1][0x09] & 1)) ? 0x03f6 : native_side_pri_addr; - - /* Secondary Channel Programming */ - current_sec_base = (!(dev->pci_conf_sb[1][0x09] & 4)) ? 0x0170 : native_base_sec_addr; - current_sec_side = (!(dev->pci_conf_sb[1][0x09] & 4)) ? 0x0376 : native_side_sec_addr; - - sis_5571_log("sis_5571_ide_handler(): Disabling primary IDE...\n"); - ide_pri_disable(); - sis_5571_log("sis_5571_ide_handler(): Disabling secondary IDE...\n"); - ide_sec_disable(); - - if (ide_io_on) { - /* Primary Channel Setup */ - if (dev->pci_conf_sb[1][0x4a] & 0x02) { - sis_5571_log("sis_5571_ide_handler(): Primary IDE base now %04X...\n", current_pri_base); - ide_set_base(0, current_pri_base); - sis_5571_log("sis_5571_ide_handler(): Primary IDE side now %04X...\n", current_pri_side); - ide_set_side(0, current_pri_side); - - sis_5571_log("sis_5571_ide_handler(): Enabling primary IDE...\n"); - ide_pri_enable(); - - sis_5571_log("SiS 5571 PRI: BASE %04x SIDE %04x\n", current_pri_base, current_pri_side); - } - - /* Secondary Channel Setup */ - if (dev->pci_conf_sb[1][0x4a] & 0x04) { - sis_5571_log("sis_5571_ide_handler(): Secondary IDE base now %04X...\n", current_sec_base); - ide_set_base(1, current_sec_base); - sis_5571_log("sis_5571_ide_handler(): Secondary IDE side now %04X...\n", current_sec_side); - ide_set_side(1, current_sec_side); - - sis_5571_log("sis_5571_ide_handler(): Enabling secondary IDE...\n"); - ide_sec_enable(); - - sis_5571_log("SiS 5571: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side); - } - } - - sff_bus_master_handler(dev->bm[0], ide_io_on, - ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + 0); - sff_bus_master_handler(dev->bm[1], ide_io_on, - ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + 8); -} - -static void -sis_5571_ide_reset(sis_5571_t *dev) -{ - /* PCI IDE */ - dev->pci_conf_sb[1][0x00] = 0x39; - dev->pci_conf_sb[1][0x01] = 0x10; - dev->pci_conf_sb[1][0x02] = 0x13; - dev->pci_conf_sb[1][0x03] = 0x55; - dev->pci_conf_sb[1][0x04] = dev->pci_conf_sb[1][0x05] = 0x00; - dev->pci_conf_sb[1][0x06] = dev->pci_conf_sb[1][0x07] = 0x00; - dev->pci_conf_sb[1][0x08] = 0xc0; - dev->pci_conf_sb[1][0x09] = 0x8a; - dev->pci_conf_sb[1][0x0a] = dev->pci_conf_sb[1][0x0b] = 0x01; - dev->pci_conf_sb[1][0x0c] = dev->pci_conf_sb[1][0x0d] = 0x00; - dev->pci_conf_sb[1][0x0e] = 0x80; - dev->pci_conf_sb[1][0x0f] = 0x00; - dev->pci_conf_sb[1][0x10] = 0xf1; - dev->pci_conf_sb[1][0x11] = 0x01; - dev->pci_conf_sb[1][0x14] = 0xf5; - dev->pci_conf_sb[1][0x15] = 0x03; - dev->pci_conf_sb[1][0x18] = 0x71; - dev->pci_conf_sb[1][0x19] = 0x01; - dev->pci_conf_sb[1][0x1c] = 0x75; - dev->pci_conf_sb[1][0x1d] = 0x03; - dev->pci_conf_sb[1][0x20] = 0x01; - dev->pci_conf_sb[1][0x21] = 0xf0; - dev->pci_conf_sb[1][0x22] = dev->pci_conf_sb[1][0x23] = 0x00; - dev->pci_conf_sb[1][0x24] = dev->pci_conf_sb[1][0x25] = 0x00; - dev->pci_conf_sb[1][0x26] = dev->pci_conf_sb[1][0x27] = 0x00; - dev->pci_conf_sb[1][0x28] = dev->pci_conf_sb[1][0x29] = 0x00; - dev->pci_conf_sb[1][0x2a] = dev->pci_conf_sb[1][0x2b] = 0x00; -#ifdef DATASHEET - dev->pci_conf_sb[1][0x2c] = dev->pci_conf_sb[1][0x2d] = 0x00; -#else - /* The only Linux lspci listing I could find of this chipset, - shows a subsystem of 0058:0000. */ - dev->pci_conf_sb[1][0x2c] = 0x58; - dev->pci_conf_sb[1][0x2d] = 0x00; -#endif - dev->pci_conf_sb[1][0x2e] = dev->pci_conf_sb[1][0x2f] = 0x00; - dev->pci_conf_sb[1][0x30] = dev->pci_conf_sb[1][0x31] = 0x00; - dev->pci_conf_sb[1][0x32] = dev->pci_conf_sb[1][0x33] = 0x00; - dev->pci_conf_sb[1][0x40] = dev->pci_conf_sb[1][0x41] = 0x00; - dev->pci_conf_sb[1][0x42] = dev->pci_conf_sb[1][0x43] = 0x00; - dev->pci_conf_sb[1][0x44] = dev->pci_conf_sb[1][0x45] = 0x00; - dev->pci_conf_sb[1][0x46] = dev->pci_conf_sb[1][0x47] = 0x00; - dev->pci_conf_sb[1][0x48] = dev->pci_conf_sb[1][0x49] = 0x00; - dev->pci_conf_sb[1][0x4a] = 0x06; - dev->pci_conf_sb[1][0x4b] = 0x00; - dev->pci_conf_sb[1][0x4c] = dev->pci_conf_sb[1][0x4d] = 0x00; - dev->pci_conf_sb[1][0x4e] = dev->pci_conf_sb[1][0x4f] = 0x00; - - sis_5571_ide_irq_handler(dev); - sis_5571_ide_handler(dev); - - sff_bus_master_reset(dev->bm[0]); - sff_bus_master_reset(dev->bm[1]); -} - -static void -sis_5571_ide_write(int addr, uint8_t val, void *priv) -{ - sis_5571_t *dev = (sis_5571_t *) priv; - - sis_5571_log("SiS 5571 IDE: [W] dev->pci_conf_sb[1][%02X] = %02X\n", addr, val); - - switch (addr) { - default: - break; - - case 0x04: /* Command low byte */ - dev->pci_conf_sb[1][addr] = val & 0x05; - sis_5571_ide_handler(dev); - break; - case 0x06: /* Status low byte */ - dev->pci_conf_sb[1][addr] = val & 0x20; - break; - case 0x07: /* Status high byte */ - dev->pci_conf_sb[1][addr] = (dev->pci_conf_sb[1][addr] & 0x06) & ~(val & 0x38); - break; - case 0x09: /* Programming Interface Byte */ - dev->pci_conf_sb[1][addr] = (dev->pci_conf_sb[1][addr] & 0x8a) | (val & 0x45); - sis_5571_ide_irq_handler(dev); - sis_5571_ide_handler(dev); - break; - case 0x0d: /* Latency Timer */ - dev->pci_conf_sb[1][addr] = val; - break; - - /* Primary Base Address */ - case 0x10: - case 0x11: - case 0x14: - case 0x15: - fallthrough; - - /* Secondary Base Address */ - case 0x18: - case 0x19: - case 0x1c: - case 0x1d: - fallthrough; - - /* Bus Mastering Base Address */ - case 0x20: - case 0x21: - if (addr == 0x20) - dev->pci_conf_sb[1][addr] = (val & 0xe0) | 0x01; - else - dev->pci_conf_sb[1][addr] = val; - sis_5571_ide_handler(dev); - break; - - /* The only Linux lspci listing I could find of this chipset, - does not show any BIOS bar, therefore writes to that are disabled. */ -#ifdef DATASHEET - case 0x30: /* Expansion ROM Base Address */ - case 0x31: /* Expansion ROM Base Address */ - case 0x32: /* Expansion ROM Base Address */ - case 0x33: /* Expansion ROM Base Address */ - dev->pci_conf_sb[1][addr] = val; - break; -#endif - - case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */ - case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */ - case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */ - case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */ - case 0x48: /* IDE Command Recovery Time Control */ - dev->pci_conf_sb[1][addr] = val & 0x0f; - break; - - case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */ - case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */ - case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */ - case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */ - case 0x49: /* IDE Command Active Time Control */ - dev->pci_conf_sb[1][addr] = val & 0x07; - break; - - case 0x4a: /* IDE General Control Register 0 */ - dev->pci_conf_sb[1][addr] = val & 0xaf; - sis_5571_ide_handler(dev); - break; - - case 0x4b: /* IDE General Control register 1 */ - dev->pci_conf_sb[1][addr] = val; - break; - - case 0x4c: /* Prefetch Count of Primary Channel (Low Byte) */ - case 0x4d: /* Prefetch Count of Primary Channel (High Byte) */ - case 0x4e: /* Prefetch Count of Secondary Channel (Low Byte) */ - case 0x4f: /* Prefetch Count of Secondary Channel (High Byte) */ - dev->pci_conf_sb[1][addr] = val; - break; - } -} - -static uint8_t -sis_5571_ide_read(int addr, void *priv) -{ - const sis_5571_t *dev = (sis_5571_t *) priv; - uint8_t ret = 0xff; - - switch (addr) { - default: - ret = dev->pci_conf_sb[1][addr]; - break; - - case 0x09: - ret = dev->pci_conf_sb[1][addr]; - if (dev->pci_conf_sb[1][0x09] & 0x40) - ret |= ((dev->pci_conf_sb[1][0x4a] & 0x06) << 3); - break; - - case 0x3d: - ret = (dev->pci_conf_sb[1][0x09] & 0x05) ? PCI_INTA : 0x00; - break; - } - - sis_5571_log("SiS 5571 IDE: [R] dev->pci_conf_sb[1][%02X] = %02X\n", addr, ret); - - return ret; -} - -/* SiS 5571 unknown I/O port (second USB PCI BAR). */ -static void -sis_5571_usb_unk_write(uint16_t addr, uint8_t val, void *priv) -{ - sis_5571_t *dev = (sis_5571_t *) priv; - - addr = (addr - dev->usb_unk_base) & 0x07; - - sis_5571_log("SiS 5571 USB UNK: [W] dev->usb_unk_regs[%02X] = %02X\n", addr, val); - - dev->usb_unk_regs[addr] = val; -} - -static uint8_t -sis_5571_usb_unk_read(uint16_t addr, void *priv) -{ - const sis_5571_t *dev = (sis_5571_t *) priv; - uint8_t ret = 0xff; - - addr = (addr - dev->usb_unk_base) & 0x07; - - ret = dev->usb_unk_regs[addr & 0x07]; - - sis_5571_log("SiS 5571 USB UNK: [R] dev->usb_unk_regs[%02X] = %02X\n", addr, ret); - - return ret; -} - -static void -sis_5571_usb_reset(sis_5571_t *dev) -{ - /* USB */ - dev->pci_conf_sb[2][0x00] = 0x39; - dev->pci_conf_sb[2][0x01] = 0x10; - dev->pci_conf_sb[2][0x02] = 0x01; - dev->pci_conf_sb[2][0x03] = 0x70; - dev->pci_conf_sb[2][0x04] = dev->pci_conf_sb[1][0x05] = 0x00; - dev->pci_conf_sb[2][0x06] = 0x00; - dev->pci_conf_sb[2][0x07] = 0x02; - dev->pci_conf_sb[2][0x08] = 0xb0; - dev->pci_conf_sb[2][0x09] = 0x10; - dev->pci_conf_sb[2][0x0a] = 0x03; - dev->pci_conf_sb[2][0x0b] = 0x0c; - dev->pci_conf_sb[2][0x0c] = dev->pci_conf_sb[1][0x0d] = 0x00; - dev->pci_conf_sb[2][0x0e] = 0x80 /* 0x10 - Datasheet erratum - header type 0x10 is invalid! */; - dev->pci_conf_sb[2][0x0f] = 0x00; - dev->pci_conf_sb[2][0x10] = 0x00; - dev->pci_conf_sb[2][0x11] = 0x00; - dev->pci_conf_sb[2][0x12] = 0x00; - dev->pci_conf_sb[2][0x13] = 0x00; - dev->pci_conf_sb[2][0x14] = 0x01; - dev->pci_conf_sb[2][0x15] = 0x00; - dev->pci_conf_sb[2][0x16] = 0x00; - dev->pci_conf_sb[2][0x17] = 0x00; - dev->pci_conf_sb[2][0x3c] = 0x00; - dev->pci_conf_sb[2][0x3d] = PCI_INTA; - dev->pci_conf_sb[2][0x3e] = 0x00; - dev->pci_conf_sb[2][0x3f] = 0x00; - - ohci_update_mem_mapping(dev->usb, - dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], - dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][0x04] & 0x02); - - if (dev->usb_unk_base != 0x0000) { - io_removehandler(dev->usb_unk_base, 0x0002, - sis_5571_usb_unk_read, NULL, NULL, - sis_5571_usb_unk_write, NULL, NULL, dev); - } - - dev->usb_unk_base = 0x0000; - - memset(dev->usb_unk_regs, 0x00, sizeof(dev->usb_unk_regs)); -} - -static void -sis_5571_usb_write(int addr, uint8_t val, void *priv) -{ - sis_5571_t *dev = (sis_5571_t *) priv; - - sis_5571_log("SiS 5571 USB: [W] dev->pci_conf_sb[2][%02X] = %02X\n", addr, val); - - if (dev->pci_conf_sb[0][0x68] & 0x40) switch (addr) { - default: - break; - - case 0x04: /* Command - Low Byte */ - dev->pci_conf_sb[2][addr] = val & 0x47; - if (dev->usb_unk_base != 0x0000) { - io_removehandler(dev->usb_unk_base, 0x0002, - sis_5571_usb_unk_read, NULL, NULL, - sis_5571_usb_unk_write, NULL, NULL, dev); - if (dev->pci_conf_sb[2][0x04] & 0x01) - io_sethandler(dev->usb_unk_base, 0x0002, - sis_5571_usb_unk_read, NULL, NULL, - sis_5571_usb_unk_write, NULL, NULL, dev); - } - ohci_update_mem_mapping(dev->usb, - dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], - dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][0x04] & 0x02); - break; - - case 0x05: /* Command - High Byte */ - dev->pci_conf_sb[2][addr] = val & 0x01; - break; - - case 0x07: /* Status - High Byte */ - dev->pci_conf_sb[2][addr] &= ~(val & 0xf9); - break; - - case 0x0d: /* Latency Timer */ - dev->pci_conf_sb[2][addr] = val; - break; - - case 0x11: /* Memory Space Base Address Register */ - case 0x12: /* Memory Space Base Address Register */ - case 0x13: /* Memory Space Base Address Register */ - dev->pci_conf_sb[2][addr] = val & ((addr == 0x11) ? 0xf0 : 0xff); - ohci_update_mem_mapping(dev->usb, - dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], - dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 0x02); - break; - - case 0x14: /* IO Space Base Address Register */ - case 0x15: /* IO Space Base Address Register */ - if (dev->usb_unk_base != 0x0000) { - io_removehandler(dev->usb_unk_base, 0x0002, - sis_5571_usb_unk_read, NULL, NULL, - sis_5571_usb_unk_write, NULL, NULL, dev); - } - dev->pci_conf_sb[2][addr] = val; - dev->usb_unk_base = (dev->pci_conf_sb[2][0x14] & 0xf8) | - (dev->pci_conf_sb[2][0x15] << 8); - if (dev->usb_unk_base != 0x0000) { - io_sethandler(dev->usb_unk_base, 0x0002, - sis_5571_usb_unk_read, NULL, NULL, - sis_5571_usb_unk_write, NULL, NULL, dev); - } - break; - - case 0x3c: /* Interrupt Line */ - dev->pci_conf_sb[2][addr] = val; - break; - } -} - -static uint8_t -sis_5571_usb_read(int addr, void *priv) -{ - const sis_5571_t *dev = (sis_5571_t *) priv; - uint8_t ret = 0xff; - - if (dev->pci_conf_sb[0][0x68] & 0x40) { - ret = dev->pci_conf_sb[2][addr]; - - sis_5571_log("SiS 5571 USB: [R] dev->pci_conf_sb[2][%02X] = %02X\n", addr, ret); - } - - return ret; -} - -static void -sis_5571_sb_write(int func, int addr, uint8_t val, void *priv) -{ switch (func) { case 0x00: - sis_5571_pci_to_isa_write(addr, val, priv); + sis_5513_pci_to_isa_write(addr, val, dev->p2i); break; case 0x01: - sis_5571_ide_write(addr, val, priv); + sis_5513_ide_write(addr, val, dev->ide); break; case 0x02: - sis_5571_usb_write(addr, val, priv); + sis_5572_usb_write(addr, val, dev->usb); break; } } static uint8_t -sis_5571_sb_read(int func, int addr, void *priv) +sis_5572_read(int func, int addr, void *priv) { + const sis_5571_t *dev = (sis_5571_t *) priv; uint8_t ret = 0xff; switch (func) { case 0x00: - ret = sis_5571_pci_to_isa_read(addr, priv); + ret = sis_5513_pci_to_isa_read(addr, dev->p2i); break; case 0x01: - ret = sis_5571_ide_read(addr, priv); + ret = sis_5513_ide_read(addr, dev->ide); break; case 0x02: - ret = sis_5571_usb_read(addr, priv); + ret = sis_5572_usb_read(addr, dev->usb); break; } + sis_5571_log("SiS 5572: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + return ret; } -static void -sis_5571_reset(void *priv) -{ - sis_5571_t *dev = (sis_5571_t *) priv; - - /* Memory/PCI Bridge */ - sis_5571_mem_to_pci_reset(dev); - - /* PCI to ISA bridge */ - sis_5571_pci_to_isa_reset(dev); - - /* IDE Controller */ - sis_5571_ide_reset(dev); - - /* USB Controller */ - sis_5571_usb_reset(dev); -} - static void sis_5571_close(void *priv) { sis_5571_t *dev = (sis_5571_t *) priv; - smram_del(dev->smram); free(dev); } @@ -1192,44 +153,18 @@ static void * sis_5571_init(UNUSED(const device_t *info)) { sis_5571_t *dev = (sis_5571_t *) calloc(1, sizeof(sis_5571_t)); - uint8_t pit_is_fast = (((pit_mode == -1) && is486) || (pit_mode == 1)); - /* Device 0: Memory/PCI Bridge */ - pci_add_card(PCI_ADD_NORTHBRIDGE, - sis_5571_mem_to_pci_read, sis_5571_mem_to_pci_write, dev, &dev->nb_slot); - /* Device 1: Southbridge */ - pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5571_sb_read, sis_5571_sb_write, dev, &dev->sb_slot); + /* Device 0: SiS 5571 */ + pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5571_read, sis_5571_write, dev, &dev->nb_slot); + /* Device 1: SiS 5572 */ + pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5572_read, sis_5572_write, dev, &dev->sb_slot); - /* MIRQ */ - pci_enable_mirq(1); + dev->sis = device_add(&sis_55xx_common_device); - /* IDEIRQ */ - pci_enable_mirq(2); - - /* USBIRQ */ - pci_enable_mirq(3); - - /* Port 92h */ - dev->port_92 = device_add(&port_92_device); - - /* SFF IDE */ - dev->bm[0] = device_add_inst(&sff8038i_device, 1); - dev->bm[1] = device_add_inst(&sff8038i_device, 2); - - /* SMRAM */ - dev->smram = smram_add(); - - /* PIT */ - dev->pit = device_find_first_priv(DEVICE_PIT); - dev->pit_read_reg = pit_is_fast ? pitf_read_reg : pit_read_reg; - - /* NVR */ - dev->nvr = device_add(&at_mb_nvr_device); - - /* USB */ - dev->usb = device_add(&usb_device); - - sis_5571_reset(dev); + dev->h2p = device_add_linked(&sis_5571_h2p_device, dev->sis); + dev->p2i = device_add_linked(&sis_5572_p2i_device, dev->sis); + dev->ide = device_add_linked(&sis_5572_ide_device, dev->sis); + dev->usb = device_add_linked(&sis_5572_usb_device, dev->sis); return dev; } @@ -1241,7 +176,7 @@ const device_t sis_5571_device = { .local = 0, .init = sis_5571_init, .close = sis_5571_close, - .reset = sis_5571_reset, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, diff --git a/src/chipset/sis_5571_h2p.c b/src/chipset/sis_5571_h2p.c new file mode 100644 index 000000000..26c74a3c0 --- /dev/null +++ b/src/chipset/sis_5571_h2p.c @@ -0,0 +1,458 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 5571 Host to PCI bridge. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/spd.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> +#include <86box/agpgart.h> + +#ifdef ENABLE_SIS_5571_HOST_TO_PCI_LOG +int sis_5571_host_to_pci_do_log = ENABLE_SIS_5571_HOST_TO_PCI_LOG; + +static void +sis_5571_host_to_pci_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5571_host_to_pci_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5571_host_to_pci_log(fmt, ...) +#endif + +typedef struct sis_5571_host_to_pci_t { + uint8_t pci_conf[256]; + uint8_t states[7]; + + sis_55xx_common_t *sis; + + smram_t *smram; +} sis_5571_host_to_pci_t; + +static void +sis_5571_shadow_recalc(sis_5571_host_to_pci_t *dev) +{ + int state; + uint32_t base; + + for (uint8_t i = 0x70; i <= 0x76; i++) { + if (i == 0x76) { + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(0xf0000, 0x10000, state); + sis_5571_host_to_pci_log("000F0000-000FFFFF\n"); + } + } else { + base = ((i & 0x07) << 15) + 0xc0000; + + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base, 0x4000, state); + sis_5571_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff); + } + + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) { + state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base + 0x4000, 0x4000, state); + sis_5571_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff); + } + } + + dev->states[i & 0x0f] = dev->pci_conf[i]; + } + + flushmmucache_nopc(); +} + +static void +sis_5571_smram_recalc(sis_5571_host_to_pci_t *dev) +{ + smram_disable_all(); + + switch (dev->pci_conf[0x68] >> 6) { + case 0: + smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + break; + case 1: + smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + break; + case 2: + smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + break; + case 3: + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0x68] & 0x10, 1); + break; + + default: + break; + } + + flushmmucache(); +} + +void +sis_5571_host_to_pci_write(int addr, uint8_t val, void *priv) +{ + sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) priv; + + sis_5571_host_to_pci_log("SiS 5571 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (addr) { + default: + break; + + case 0x04: /* Command - low byte */ + case 0x05: /* Command - high byte */ + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xfd) | (val & 0x02); + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf[addr] &= ~(val & 0xb8); + break; + + case 0x0d: /* Master latency timer */ + dev->pci_conf[addr] = val; + break; + + case 0x50: /* Host Interface and DRAM arbiter */ + dev->pci_conf[addr] = val & 0xec; + break; + + case 0x51: /* CACHE */ + dev->pci_conf[addr] = val; + cpu_cache_ext_enabled = !!(val & 0x40); + cpu_update_waitstates(); + break; + + case 0x52: + dev->pci_conf[addr] = val & 0xd0; + break; + + case 0x53: /* DRAM */ + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x54: /* FP/EDO */ + dev->pci_conf[addr] = val; + break; + + case 0x55: + dev->pci_conf[addr] = val & 0xe0; + break; + + case 0x56: /* MDLE delay */ + dev->pci_conf[addr] = val & 0x07; + break; + + case 0x57: /* SDRAM */ + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x59: /* Buffer strength and current rating */ + dev->pci_conf[addr] = val; + break; + + case 0x5a: + dev->pci_conf[addr] = val & 0x03; + break; + + /* Undocumented - DRAM bank registers, the exact layout is currently unknown. */ + case 0x60 ... 0x6b: + dev->pci_conf[addr] = val; + break; + + case 0x70 ... 0x75: + dev->pci_conf[addr] = val & 0xee; + sis_5571_shadow_recalc(dev); + break; + case 0x76: + dev->pci_conf[addr] = val & 0xe8; + sis_5571_shadow_recalc(dev); + break; + + case 0x77: /* Characteristics of non-cacheable area */ + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x78: /* Allocation of Non-Cacheable area #1 */ + case 0x79: /* NCA1REG2 */ + case 0x7a: /* Allocation of Non-Cacheable area #2 */ + case 0x7b: /* NCA2REG2 */ + dev->pci_conf[addr] = val; + break; + + case 0x80: /* PCI master characteristics */ + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x81: + dev->pci_conf[addr] = val & 0xcc; + break; + + case 0x82: + dev->pci_conf[addr] = val; + break; + + case 0x83: /* CPU to PCI characteristics */ + dev->pci_conf[addr] = val; + /* TODO: Implement Fast A20 and Fast reset stuff on the KBC already! */ + break; + + case 0x84 ... 0x86: + dev->pci_conf[addr] = val; + break; + + case 0x87: /* Miscellanea */ + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x90: /* PMU control register */ + case 0x91: /* Address trap for green function */ + case 0x92: + dev->pci_conf[addr] = val; + break; + + case 0x93: /* STPCLK# and APM SMI control */ + dev->pci_conf[addr] = val; + + if ((dev->pci_conf[0x9b] & 0x01) && (val & 0x02)) { + smi_raise(); + dev->pci_conf[0x9d] |= 0x01; + } + break; + + case 0x94: /* 6x86 and Green function control */ + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x95: /* Test mode control */ + case 0x96: /* Time slot and Programmable 10-bit I/O port definition */ + dev->pci_conf[addr] = val & 0xfb; + break; + + case 0x97: /* programmable 10-bit I/O port address */ + case 0x98: /* Programmable 16-bit I/O port */ + case 0x99 ... 0x9c: + dev->pci_conf[addr] = val; + break; + + case 0x9d: + dev->pci_conf[addr] &= val; + break; + + case 0x9e: /* STPCLK# Assertion Timer */ + case 0x9f: /* STPCLK# De-assertion Timer */ + case 0xa0 ... 0xa2: + dev->pci_conf[addr] = val; + break; + + case 0xa3: /* SMRAM access control and Power supply control */ + dev->pci_conf[addr] = val & 0xd0; + sis_5571_smram_recalc(dev); + break; + } +} + +uint8_t +sis_5571_host_to_pci_read(int addr, void *priv) +{ + const sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) priv; + uint8_t ret = 0xff; + + ret = dev->pci_conf[addr]; + + sis_5571_host_to_pci_log("SiS 5571 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5571_host_to_pci_reset(void *priv) +{ + sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x71; + dev->pci_conf[0x03] = 0x55; + dev->pci_conf[0x04] = 0x05; + dev->pci_conf[0x05] = 0x00; + dev->pci_conf[0x06] = 0x00; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = 0x00; + dev->pci_conf[0x09] = 0x00; + dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x0c] = 0x00; + dev->pci_conf[0x0d] = 0x00; + dev->pci_conf[0x0e] = 0x00; + dev->pci_conf[0x0f] = 0x00; + + dev->pci_conf[0x50] = 0x00; + dev->pci_conf[0x51] = 0x00; + dev->pci_conf[0x52] = 0x00; + dev->pci_conf[0x53] = 0x00; + dev->pci_conf[0x54] = 0x54; + dev->pci_conf[0x55] = 0x54; + dev->pci_conf[0x56] = 0x03; + dev->pci_conf[0x57] = 0x00; + dev->pci_conf[0x58] = 0x00; + dev->pci_conf[0x59] = 0x00; + dev->pci_conf[0x5a] = 0x00; + + /* Undocumented DRAM bank registers. */ + dev->pci_conf[0x60] = dev->pci_conf[0x62] = 0x04; + dev->pci_conf[0x64] = dev->pci_conf[0x66] = 0x04; + dev->pci_conf[0x68] = dev->pci_conf[0x6a] = 0x04; + dev->pci_conf[0x61] = dev->pci_conf[0x65] = 0x00; + dev->pci_conf[0x63] = dev->pci_conf[0x67] = 0x80; + dev->pci_conf[0x69] = 0x00; + dev->pci_conf[0x6b] = 0x80; + + dev->pci_conf[0x70] = 0x00; + dev->pci_conf[0x71] = 0x00; + dev->pci_conf[0x72] = 0x00; + dev->pci_conf[0x73] = 0x00; + dev->pci_conf[0x74] = 0x00; + dev->pci_conf[0x75] = 0x00; + dev->pci_conf[0x76] = 0x00; + + dev->pci_conf[0x77] = 0x00; + dev->pci_conf[0x78] = 0x00; + dev->pci_conf[0x79] = 0x00; + dev->pci_conf[0x7a] = 0x00; + dev->pci_conf[0x7b] = 0x00; + + dev->pci_conf[0x80] = 0x00; + dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x82] = 0x00; + dev->pci_conf[0x83] = 0x00; + dev->pci_conf[0x84] = 0x00; + dev->pci_conf[0x85] = 0x00; + dev->pci_conf[0x86] = 0x00; + dev->pci_conf[0x87] = 0x00; + + dev->pci_conf[0x8c] = 0x00; + dev->pci_conf[0x8d] = 0x00; + dev->pci_conf[0x8e] = 0x00; + dev->pci_conf[0x8f] = 0x00; + + dev->pci_conf[0x90] = 0x00; + dev->pci_conf[0x91] = 0x00; + dev->pci_conf[0x92] = 0x00; + dev->pci_conf[0x93] = 0x00; + dev->pci_conf[0x93] = 0x00; + dev->pci_conf[0x94] = 0x00; + dev->pci_conf[0x95] = 0x00; + dev->pci_conf[0x96] = 0x00; + dev->pci_conf[0x97] = 0x00; + dev->pci_conf[0x98] = 0x00; + dev->pci_conf[0x99] = 0x00; + dev->pci_conf[0x9a] = 0x00; + dev->pci_conf[0x9b] = 0x00; + dev->pci_conf[0x9c] = 0x00; + dev->pci_conf[0x9d] = 0x00; + dev->pci_conf[0x9e] = 0xff; + dev->pci_conf[0x9f] = 0xff; + + dev->pci_conf[0xa0] = 0xff; + dev->pci_conf[0xa1] = 0x00; + dev->pci_conf[0xa2] = 0xff; + dev->pci_conf[0xa3] = 0x00; + + cpu_cache_ext_enabled = 0; + cpu_update_waitstates(); + + sis_5571_smram_recalc(dev); + sis_5571_shadow_recalc(dev); + + flushmmucache(); +} + +static void +sis_5571_host_to_pci_close(void *priv) +{ + sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) priv; + + smram_del(dev->smram); + free(dev); +} + +static void * +sis_5571_host_to_pci_init(UNUSED(const device_t *info)) +{ + sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) calloc(1, sizeof(sis_5571_host_to_pci_t)); + + dev->sis = device_get_common_priv(); + + /* SMRAM */ + dev->smram = smram_add(); + + sis_5571_host_to_pci_reset(dev); + + return dev; +} + +const device_t sis_5571_h2p_device = { + .name = "SiS 5571 Host to PCI bridge", + .internal_name = "sis_5571_host_to_pci", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5571_host_to_pci_init, + .close = sis_5571_host_to_pci_close, + .reset = sis_5571_host_to_pci_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5571_old.c b/src/chipset/sis_5571_old.c new file mode 100644 index 000000000..f130ecd8a --- /dev/null +++ b/src/chipset/sis_5571_old.c @@ -0,0 +1,772 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 5571 Chipset. + * + * + * + * Authors: Tiseno100, + * + * Copyright 2021 Tiseno100. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> + +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/smram.h> +#include <86box/usb.h> + +#include <86box/chipset.h> + +/* Shadow RAM */ +#define LSB_READ ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) +#define LSB_WRITE ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY) +#define MSB_READ ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) +#define MSB_WRITE ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY) +#define SYSTEM_READ ((dev->pci_conf[0x76] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) +#define SYSTEM_WRITE ((dev->pci_conf[0x76] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY) + +/* IDE Flags (1 Native / 0 Compatibility)*/ +#define PRIMARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 1) +#define SECONDARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 4) +#define PRIMARY_NATIVE_BASE (dev->pci_conf_sb[1][0x11] << 8) | (dev->pci_conf_sb[1][0x10] & 0xf8) +#define PRIMARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x15] << 8) | (dev->pci_conf_sb[1][0x14] & 0xfc)) + 2) +#define SECONDARY_NATIVE_BASE (dev->pci_conf_sb[1][0x19] << 8) | (dev->pci_conf_sb[1][0x18] & 0xf8) +#define SECONDARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x1d] << 8) | (dev->pci_conf_sb[1][0x1c] & 0xfc)) + 2) +#define BUS_MASTER_BASE ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + +#ifdef ENABLE_SIS_5571_LOG +int sis_5571_do_log = ENABLE_SIS_5571_LOG; + +static void +sis_5571_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5571_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5571_log(fmt, ...) +#endif + +typedef struct sis_5571_t { + uint8_t nb_slot; + uint8_t sb_slot; + uint8_t pad; + uint8_t usb_irq_state; + + uint8_t pci_conf[256]; + uint8_t pci_conf_sb[3][256]; + + port_92_t *port_92; + sff8038i_t *ide_drive[2]; + smram_t *smram; + usb_t *usb; +} sis_5571_t; + +static void +sis_5571_shadow_recalc(int cur_reg, sis_5571_t *dev) +{ + if (cur_reg != 0x76) { + mem_set_mem_state_both(0xc0000 + (0x8000 * (cur_reg & 0x07)), 0x4000, LSB_READ | LSB_WRITE); + mem_set_mem_state_both(0xc4000 + (0x8000 * (cur_reg & 0x07)), 0x4000, MSB_READ | MSB_WRITE); + } else + mem_set_mem_state_both(0xf0000, 0x10000, SYSTEM_READ | SYSTEM_WRITE); + + flushmmucache_nopc(); +} + +static void +sis_5571_smm_recalc(sis_5571_t *dev) +{ + smram_disable_all(); + + switch ((dev->pci_conf[0xa3] & 0xc0) >> 6) { + case 0x00: + smram_enable(dev->smram, 0xe0000, 0xe0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1); + break; + case 0x01: + smram_enable(dev->smram, 0xe0000, 0xa0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1); + break; + case 0x02: + smram_enable(dev->smram, 0xe0000, 0xb0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1); + break; + case 0x03: + smram_enable(dev->smram, 0xa0000, 0xa0000, 0x10000, (dev->pci_conf[0xa3] & 0x10), 1); + break; + + default: + break; + } + + flushmmucache(); +} + +void +sis_5571_ide_handler(sis_5571_t *dev) +{ + ide_pri_disable(); + ide_sec_disable(); + if (dev->pci_conf_sb[1][4] & 1) { + if (dev->pci_conf_sb[1][0x4a] & 4) { + ide_set_base(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_BASE : 0x1f0); + ide_set_side(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_SIDE : 0x3f6); + ide_pri_enable(); + } + if (dev->pci_conf_sb[1][0x4a] & 2) { + ide_set_base(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_BASE : 0x170); + ide_set_side(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_SIDE : 0x376); + ide_sec_enable(); + } + } +} + +void +sis_5571_bm_handler(sis_5571_t *dev) +{ + sff_bus_master_handler(dev->ide_drive[0], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE); + sff_bus_master_handler(dev->ide_drive[1], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE + 8); +} + +static void +memory_pci_bridge_write(UNUSED(int func), int addr, uint8_t val, void *priv) +{ + sis_5571_t *dev = (sis_5571_t *) priv; + + switch (addr) { + case 0x04: /* Command - low byte */ + case 0x05: /* Command - high byte */ + dev->pci_conf[addr] |= val; + break; + + case 0x06: /* Status - Low Byte */ + dev->pci_conf[addr] &= val; + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf[addr] &= val & 0xbe; + break; + + case 0x0d: /* Master latency timer */ + dev->pci_conf[addr] = val; + break; + + case 0x50: /* Host Interface and DRAM arbiter */ + dev->pci_conf[addr] = val & 0xec; + break; + + case 0x51: /* CACHE */ + dev->pci_conf[addr] = val; + cpu_cache_ext_enabled = !!(val & 0x40); + cpu_update_waitstates(); + break; + + case 0x52: + dev->pci_conf[addr] = val & 0xd0; + break; + + case 0x53: /* DRAM */ + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x54: /* FP/EDO */ + dev->pci_conf[addr] = val; + break; + + case 0x55: + dev->pci_conf[addr] = val & 0xe0; + break; + + case 0x56: /* MDLE delay */ + case 0x57: /* SDRAM */ + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x59: /* Buffer strength and current rating */ + dev->pci_conf[addr] = val; + break; + + case 0x5a: + dev->pci_conf[addr] = val & 0x03; + break; + + case 0x60: /* Undocumented */ + case 0x61: /* Undocumented */ + case 0x62: /* Undocumented */ + case 0x63: /* Undocumented */ + case 0x64: /* Undocumented */ + case 0x65: /* Undocumented */ + case 0x66: /* Undocumented */ + case 0x67: /* Undocumented */ + case 0x68: /* Undocumented */ + case 0x69: /* Undocumented */ + case 0x6a: /* Undocumented */ + case 0x6b: /* Undocumented */ + dev->pci_conf[addr] = val; + break; + + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: /* Attribute of shadow RAM for BIOS area */ + dev->pci_conf[addr] = val & ((addr != 0x76) ? 0xee : 0xe8); + sis_5571_shadow_recalc(addr, dev); + sis_5571_smm_recalc(dev); + break; + + case 0x77: /* Characteristics of non-cacheable area */ + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x78: /* Allocation of Non-Cacheable area #1 */ + case 0x79: /* NCA1REG2 */ + case 0x7a: /* Allocation of Non-Cacheable area #2 */ + case 0x7b: /* NCA2REG2 */ + dev->pci_conf[addr] = val; + break; + + case 0x80: /* PCI master characteristics */ + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x81: + dev->pci_conf[addr] = val & 0xcc; + break; + + case 0x82: + dev->pci_conf[addr] = val; + break; + + case 0x83: /* CPU to PCI characteristics */ + dev->pci_conf[addr] = val; + port_92_set_features(dev->port_92, !!(val & 0x40), !!(val & 0x80)); + break; + + case 0x84: + case 0x85: + case 0x86: + dev->pci_conf[addr] = val; + break; + + case 0x87: /* Miscellanea */ + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x90: /* PMU control register */ + case 0x91: /* Address trap for green function */ + case 0x92: + dev->pci_conf[addr] = val; + break; + + case 0x93: /* STPCLK# and APM SMI control */ + dev->pci_conf[addr] = val; + + if ((dev->pci_conf[0x9b] & 1) && !!(val & 2)) { + smi_raise(); + dev->pci_conf[0x9d] |= 1; + } + break; + + case 0x94: /* 6x86 and Green function control */ + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x95: /* Test mode control */ + case 0x96: /* Time slot and Programmable 10-bit I/O port definition */ + dev->pci_conf[addr] = val & 0xfb; + break; + + case 0x97: /* programmable 10-bit I/O port address */ + case 0x98: /* Programmable 16-bit I/O port */ + case 0x99: + case 0x9a: + case 0x9b: + case 0x9c: + dev->pci_conf[addr] = val; + break; + + case 0x9d: + dev->pci_conf[addr] &= val; + break; + + case 0x9e: /* STPCLK# Assertion Timer */ + case 0x9f: /* STPCLK# De-assertion Timer */ + case 0xa0: + case 0xa1: + case 0xa2: + dev->pci_conf[addr] = val; + break; + + case 0xa3: /* SMRAM access control and Power supply control */ + dev->pci_conf[addr] = val & 0xd0; + sis_5571_smm_recalc(dev); + break; + + default: + break; + } + sis_5571_log("SiS5571: dev->pci_conf[%02x] = %02x\n", addr, val); +} + +static uint8_t +memory_pci_bridge_read(UNUSED(int func), int addr, void *priv) +{ + const sis_5571_t *dev = (sis_5571_t *) priv; + + sis_5571_log("SiS5571: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf[addr]); + return dev->pci_conf[addr]; +} + +static void +pci_isa_bridge_write(int func, int addr, uint8_t val, void *priv) +{ + sis_5571_t *dev = (sis_5571_t *) priv; + switch (func) { + case 0: /* Bridge */ + switch (addr) { + case 0x04: /* Command */ + dev->pci_conf_sb[0][addr] |= val & 0x0f; + break; + + case 0x06: /* Status */ + dev->pci_conf_sb[0][addr] &= val; + break; + + case 0x40: /* BIOS Control Register */ + dev->pci_conf_sb[0][addr] = val & 0x3f; + break; + + case 0x41: /* INTA# Remapping Control Register */ + case 0x42: /* INTB# Remapping Control Register */ + case 0x43: /* INTC# Remapping Control Register */ + case 0x44: /* INTD# Remapping Control Register */ + dev->pci_conf_sb[0][addr] = val & 0x8f; + pci_set_irq_routing((addr & 0x07), !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); + break; + + case 0x45: + dev->pci_conf_sb[0][addr] = val & 0xec; + switch ((val & 0xc0) >> 6) { + case 0: + cpu_set_isa_speed(7159091); + break; + case 1: + cpu_set_isa_pci_div(4); + break; + case 2: + cpu_set_isa_pci_div(3); + break; + + default: + break; + } + break; + + case 0x46: + dev->pci_conf_sb[0][addr] = val & 0xec; + break; + + case 0x47: /* DMA Clock and Wait State Control Register */ + dev->pci_conf_sb[0][addr] = val & 0x3e; + break; + + case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ + case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ + case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ + case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x4c: + case 0x4d: + case 0x4e: + case 0x4f: + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x54: + case 0x55: + case 0x56: + case 0x57: + case 0x58: + case 0x59: + case 0x5a: + case 0x5b: + case 0x5c: + case 0x5d: + case 0x5e: + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x5f: + dev->pci_conf_sb[0][addr] = val & 0x3f; + break; + + case 0x60: + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x61: /* MIRQ Remapping Control Register */ + dev->pci_conf_sb[0][addr] = val; + pci_set_mirq_routing(PCI_MIRQ0, !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); + break; + + case 0x62: /* On-board Device DMA Control Register */ + dev->pci_conf_sb[0][addr] = val & 0x0f; + dma_set_drq((val & 0x07), 1); + break; + + case 0x63: /* IDEIRQ Remapping Control Register */ + dev->pci_conf_sb[0][addr] = val & 0x8f; + if (val & 0x80) { + sff_set_irq_line(dev->ide_drive[0], val & 0x0f); + sff_set_irq_line(dev->ide_drive[1], val & 0x0f); + } + break; + + case 0x64: /* GPIO Control Register */ + dev->pci_conf_sb[0][addr] = val & 0xef; + break; + + case 0x65: + dev->pci_conf_sb[0][addr] = val & 0x1b; + break; + + case 0x66: /* GPIO Output Mode Control Register */ + case 0x67: /* GPIO Output Mode Control Register */ + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x68: /* USBIRQ Remapping Control Register */ + dev->pci_conf_sb[0][addr] = val & 0x1b; + break; + + case 0x69: + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x6a: + dev->pci_conf_sb[0][addr] = val & 0xfc; + break; + + case 0x6b: + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x6c: + dev->pci_conf_sb[0][addr] = val & 0x03; + break; + + case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */ + case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */ + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x70: + dev->pci_conf_sb[0][addr] = val & 0xde; + break; + + case 0x71: /* Type-F DMA Control Register */ + dev->pci_conf_sb[0][addr] = val & 0xfe; + break; + + case 0x72: /* SMI Triggered By IRQ/GPIO Control */ + case 0x73: /* SMI Triggered By IRQ/GPIO Control */ + dev->pci_conf_sb[0][addr] = (addr == 0x72) ? val & 0xfe : val; + break; + + case 0x74: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit Control */ + case 0x75: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit Control */ + case 0x76: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */ + case 0x77: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */ + dev->pci_conf_sb[0][addr] = val; + break; + + default: + break; + } + sis_5571_log("SiS5571-SB: dev->pci_conf[%02x] = %02x\n", addr, val); + break; + + case 1: /* IDE Controller */ + switch (addr) { + case 0x04: /* Command low byte */ + dev->pci_conf_sb[1][addr] = val & 0x05; + sis_5571_ide_handler(dev); + sis_5571_bm_handler(dev); + break; + + case 0x07: /* Status high byte */ + dev->pci_conf_sb[1][addr] &= val; + break; + + case 0x09: /* Programming Interface Byte */ + dev->pci_conf_sb[1][addr] = val & 0xcf; + sis_5571_ide_handler(dev); + break; + + case 0x0d: /* Latency Time */ + case 0x10: /* Primary Channel Base Address Register */ + case 0x11: /* Primary Channel Base Address Register */ + case 0x12: /* Primary Channel Base Address Register */ + case 0x13: /* Primary Channel Base Address Register */ + case 0x14: /* Primary Channel Base Address Register */ + case 0x15: /* Primary Channel Base Address Register */ + case 0x16: /* Primary Channel Base Address Register */ + case 0x17: /* Primary Channel Base Address Register */ + case 0x18: /* Secondary Channel Base Address Register */ + case 0x19: /* Secondary Channel Base Address Register */ + case 0x1a: /* Secondary Channel Base Address Register */ + case 0x1b: /* Secondary Channel Base Address Register */ + case 0x1c: /* Secondary Channel Base Address Register */ + case 0x1d: /* Secondary Channel Base Address Register */ + case 0x1e: /* Secondary Channel Base Address Register */ + case 0x1f: /* Secondary Channel Base Address Register */ + dev->pci_conf_sb[1][addr] = val; + sis_5571_ide_handler(dev); + break; + + case 0x20: /* Bus Master IDE Control Register Base Address */ + case 0x21: /* Bus Master IDE Control Register Base Address */ + case 0x22: /* Bus Master IDE Control Register Base Address */ + case 0x23: /* Bus Master IDE Control Register Base Address */ + dev->pci_conf_sb[1][addr] = val; + sis_5571_bm_handler(dev); + break; + + case 0x30: /* Expansion ROM Base Address */ + case 0x31: /* Expansion ROM Base Address */ + case 0x32: /* Expansion ROM Base Address */ + case 0x33: /* Expansion ROM Base Address */ + case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */ + case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */ + case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */ + case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */ + case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */ + case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */ + case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */ + case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */ + case 0x48: /* IDE Command Recovery Time Control */ + case 0x49: /* IDE Command Active Time Control */ + dev->pci_conf_sb[1][addr] = val; + break; + + case 0x4a: /* IDE General Control Register 0 */ + dev->pci_conf_sb[1][addr] = val & 0xaf; + sis_5571_ide_handler(dev); + break; + + case 0x4b: /* IDE General Control register 1 */ + case 0x4c: /* Prefetch Count of Primary Channel (Low Byte) */ + case 0x4d: /* Prefetch Count of Primary Channel (High Byte) */ + case 0x4e: /* Prefetch Count of Secondary Channel (Low Byte) */ + case 0x4f: /* Prefetch Count of Secondary Channel (High Byte) */ + dev->pci_conf_sb[1][addr] = val; + break; + + default: + break; + } + sis_5571_log("SiS5571-IDE: dev->pci_conf[%02x] = %02x\n", addr, val); + break; + + case 2: /* USB Controller */ + switch (addr) { + case 0x04: /* Command - Low Byte */ + dev->pci_conf_sb[2][addr] = val; + ohci_update_mem_mapping(dev->usb, dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 1); + break; + + case 0x05: /* Command - High Byte */ + dev->pci_conf_sb[2][addr] = val & 0x03; + break; + + case 0x06: /* Status - Low Byte */ + dev->pci_conf_sb[2][addr] &= val & 0xc0; + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf_sb[2][addr] &= val; + break; + + case 0x10: /* Memory Space Base Address Register */ + case 0x11: /* Memory Space Base Address Register */ + case 0x12: /* Memory Space Base Address Register */ + case 0x13: /* Memory Space Base Address Register */ + dev->pci_conf_sb[2][addr] = val & ((addr == 0x11) ? 0x0f : 0xff); + ohci_update_mem_mapping(dev->usb, dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 1); + break; + + case 0x14: /* IO Space Base Address Register */ + case 0x15: /* IO Space Base Address Register */ + case 0x16: /* IO Space Base Address Register */ + case 0x17: /* IO Space Base Address Register */ + case 0x3c: /* Interrupt Line */ + dev->pci_conf_sb[2][addr] = val; + break; + + default: + break; + } + sis_5571_log("SiS5571-USB: dev->pci_conf[%02x] = %02x\n", addr, val); + break; + + default: + break; + } +} + +static uint8_t +pci_isa_bridge_read(int func, int addr, void *priv) +{ + const sis_5571_t *dev = (sis_5571_t *) priv; + + switch (func) { + case 0: + sis_5571_log("SiS5571-SB: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[0][addr]); + return dev->pci_conf_sb[0][addr]; + case 1: + sis_5571_log("SiS5571-IDE: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[1][addr]); + return dev->pci_conf_sb[1][addr]; + case 2: + sis_5571_log("SiS5571-USB: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[2][addr]); + return dev->pci_conf_sb[2][addr]; + + default: + return 0xff; + } +} + +static void +sis_5571_reset(void *priv) +{ + sis_5571_t *dev = (sis_5571_t *) priv; + + /* Memory/PCI Bridge */ + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x71; + dev->pci_conf[0x03] = 0x55; + dev->pci_conf[0x04] = 0xfd; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x9e] = 0xff; + dev->pci_conf[0x9f] = 0xff; + dev->pci_conf[0xa2] = 0xff; + + /* PCI to ISA bridge */ + dev->pci_conf_sb[0][0x00] = 0x39; + dev->pci_conf_sb[0][0x01] = 0x10; + dev->pci_conf_sb[0][0x02] = 0x08; + dev->pci_conf_sb[0][0x04] = 0xfd; + dev->pci_conf_sb[0][0x08] = 0x01; + dev->pci_conf_sb[0][0x0a] = 0x01; + dev->pci_conf_sb[0][0x0b] = 0x06; + + /* IDE Controller */ + dev->pci_conf_sb[1][0x00] = 0x39; + dev->pci_conf_sb[1][0x01] = 0x10; + dev->pci_conf_sb[1][0x02] = 0x13; + dev->pci_conf_sb[1][0x03] = 0x55; + dev->pci_conf_sb[1][0x08] = 0xc0; + dev->pci_conf_sb[1][0x0a] = 0x01; + dev->pci_conf_sb[1][0x0b] = 0x01; + dev->pci_conf_sb[1][0x0e] = 0x80; + dev->pci_conf_sb[1][0x4a] = 0x06; + sff_set_slot(dev->ide_drive[0], dev->sb_slot); + sff_set_slot(dev->ide_drive[1], dev->sb_slot); + sff_bus_master_reset(dev->ide_drive[0]); + sff_bus_master_reset(dev->ide_drive[1]); + + /* USB Controller */ + dev->pci_conf_sb[2][0x00] = 0x39; + dev->pci_conf_sb[2][0x01] = 0x10; + dev->pci_conf_sb[2][0x02] = 0x01; + dev->pci_conf_sb[2][0x03] = 0x70; + dev->pci_conf_sb[2][0x08] = 0xb0; + dev->pci_conf_sb[2][0x09] = 0x10; + dev->pci_conf_sb[2][0x0a] = 0x03; + dev->pci_conf_sb[2][0x0b] = 0xc0; + dev->pci_conf_sb[2][0x0e] = 0x80; + dev->pci_conf_sb[2][0x14] = 0x01; + dev->pci_conf_sb[2][0x3d] = 0x01; +} + +static void +sis_5571_close(void *priv) +{ + sis_5571_t *dev = (sis_5571_t *) priv; + + smram_del(dev->smram); + free(dev); +} + +static void * +sis_5571_init(UNUSED(const device_t *info)) +{ + sis_5571_t *dev = (sis_5571_t *) malloc(sizeof(sis_5571_t)); + memset(dev, 0x00, sizeof(sis_5571_t)); + + pci_add_card(PCI_ADD_NORTHBRIDGE, memory_pci_bridge_read, memory_pci_bridge_write, dev, &dev->nb_slot); + pci_add_card(PCI_ADD_SOUTHBRIDGE, pci_isa_bridge_read, pci_isa_bridge_write, dev, &dev->sb_slot); + + /* MIRQ */ + pci_enable_mirq(0); + + /* Port 92 & SMRAM */ + dev->port_92 = device_add(&port_92_pci_device); + dev->smram = smram_add(); + + /* SFF IDE */ + dev->ide_drive[0] = device_add_inst(&sff8038i_device, 1); + dev->ide_drive[1] = device_add_inst(&sff8038i_device, 2); + + /* USB */ + dev->usb = device_add(&usb_device); + + sis_5571_reset(dev); + + return dev; +} + +const device_t sis_5571_device = { + .name = "SiS 5571", + .internal_name = "sis_5571", + .flags = DEVICE_PCI, + .local = 0, + .init = sis_5571_init, + .close = sis_5571_close, + .reset = sis_5571_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5572_usb.c b/src/chipset/sis_5572_usb.c new file mode 100644 index 000000000..250c32587 --- /dev/null +++ b/src/chipset/sis_5572_usb.c @@ -0,0 +1,323 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 5572 USB controller. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> + +#ifdef ENABLE_SIS_5572_USB_LOG +int sis_5572_usb_do_log = ENABLE_SIS_5572_USB_LOG; + +static void +sis_5572_usb_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5572_usb_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5572_usb_log(fmt, ...) +#endif + +typedef struct sis_5572_usb_t { + uint8_t rev; + + uint8_t usb_unk_regs[256]; + uint8_t pci_conf[256]; + + uint16_t usb_unk_base; + + usb_t *usb; + + sis_55xx_common_t *sis; +} sis_5572_usb_t; + +/* SiS 5572 unknown I/O port (second USB PCI BAR). */ +static void +sis_5572_usb_unk_write(uint16_t addr, uint8_t val, void *priv) +{ + sis_5572_usb_t *dev = (sis_5572_usb_t *) priv; + + addr = (addr - dev->usb_unk_base) & 0x07; + + sis_5572_usb_log("SiS 5572 USB UNK: [W] dev->usb_unk_regs[%02X] = %02X\n", addr, val); + + dev->usb_unk_regs[addr] = val; +} + +static uint8_t +sis_5572_usb_unk_read(uint16_t addr, void *priv) +{ + const sis_5572_usb_t *dev = (sis_5572_usb_t *) priv; + uint8_t ret = 0xff; + + addr = (addr - dev->usb_unk_base) & 0x07; + + ret = dev->usb_unk_regs[addr & 0x07]; + + sis_5572_usb_log("SiS 5572 USB UNK: [R] dev->usb_unk_regs[%02X] = %02X\n", addr, ret); + + return ret; +} + +void +sis_5572_usb_write(int addr, uint8_t val, void *priv) +{ + sis_5572_usb_t *dev = (sis_5572_usb_t *) priv; + + sis_5572_usb_log("SiS 5572 USB: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + if (dev->sis->usb_enabled) switch (addr) { + default: + break; + + case 0x04: /* Command - Low Byte */ + if (dev->rev == 0xb0) + dev->pci_conf[addr] = val & 0x47; + else + dev->pci_conf[addr] = val & 0x57; + if (dev->usb_unk_base != 0x0000) { + io_removehandler(dev->usb_unk_base, 0x0002, + sis_5572_usb_unk_read, NULL, NULL, + sis_5572_usb_unk_write, NULL, NULL, dev); + if (dev->pci_conf[0x04] & 0x01) + io_sethandler(dev->usb_unk_base, 0x0002, + sis_5572_usb_unk_read, NULL, NULL, + sis_5572_usb_unk_write, NULL, NULL, dev); + } + ohci_update_mem_mapping(dev->usb, + dev->pci_conf[0x11], dev->pci_conf[0x12], + dev->pci_conf[0x13], dev->pci_conf[0x04] & 0x02); + break; + + case 0x05: /* Command - High Byte */ + dev->pci_conf[addr] = val & 0x01; + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf[addr] &= ~(val & 0xf9); + break; + + case 0x0d: /* Latency Timer */ + dev->pci_conf[addr] = val; + break; + + case 0x11 ... 0x13: /* Memory Space Base Address Register */ + dev->pci_conf[addr] = val & ((addr == 0x11) ? 0xf0 : 0xff); + ohci_update_mem_mapping(dev->usb, + dev->pci_conf[0x11], dev->pci_conf[0x12], + dev->pci_conf[0x13], dev->pci_conf[4] & 0x02); + break; + + case 0x14 ... 0x15: /* IO Space Base Address Register */ + if (dev->rev == 0xb0) { + if (dev->usb_unk_base != 0x0000) { + io_removehandler(dev->usb_unk_base, 0x0002, + sis_5572_usb_unk_read, NULL, NULL, + sis_5572_usb_unk_write, NULL, NULL, dev); + } + dev->pci_conf[addr] = val; + dev->usb_unk_base = (dev->pci_conf[0x14] & 0xf8) | + (dev->pci_conf[0x15] << 8); + if (dev->usb_unk_base != 0x0000) { + io_sethandler(dev->usb_unk_base, 0x0002, + sis_5572_usb_unk_read, NULL, NULL, + sis_5572_usb_unk_write, NULL, NULL, dev); + } + } + break; + + case 0x2c ... 0x2f: + if (dev->rev == 0x11) + dev->pci_conf[addr] = val; + break; + + case 0x3c: /* Interrupt Line */ + dev->pci_conf[addr] = val; + break; + } +} + +uint8_t +sis_5572_usb_read(int addr, void *priv) +{ + const sis_5572_usb_t *dev = (sis_5572_usb_t *) priv; + uint8_t ret = 0xff; + + if (dev->sis->usb_enabled) { + ret = dev->pci_conf[addr]; + + sis_5572_usb_log("SiS 5572 USB: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + } + + return ret; +} + +static void +sis_5572_usb_reset(void *priv) +{ + sis_5572_usb_t *dev = (sis_5572_usb_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x01; + dev->pci_conf[0x03] = 0x70; + dev->pci_conf[0x04] = dev->pci_conf[0x05] = 0x00; + dev->pci_conf[0x06] = (dev->rev == 0xb0) ? 0x00 : 0x80; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = dev->rev; + dev->pci_conf[0x09] = 0x10; + dev->pci_conf[0x0a] = 0x03; + dev->pci_conf[0x0b] = 0x0c; + dev->pci_conf[0x0c] = dev->pci_conf[0x0d] = 0x00; + dev->pci_conf[0x0e] = 0x80 /* 0x10 - Datasheet erratum - header type 0x10 is invalid! */; + dev->pci_conf[0x0f] = 0x00; + dev->pci_conf[0x10] = 0x00; + dev->pci_conf[0x11] = 0x00; + dev->pci_conf[0x12] = 0x00; + dev->pci_conf[0x13] = 0x00; + if (dev->rev == 0xb0) { + dev->pci_conf[0x14] = 0x01; + dev->pci_conf[0x15] = 0x00; + dev->pci_conf[0x16] = 0x00; + dev->pci_conf[0x17] = 0x00; + } else if (dev->rev == 0x11) { + dev->pci_conf[0x2c] = 0x00; + dev->pci_conf[0x2d] = 0x00; + dev->pci_conf[0x2e] = 0x00; + dev->pci_conf[0x2f] = 0x00; + } + dev->pci_conf[0x3c] = 0x00; + dev->pci_conf[0x3d] = PCI_INTA; + dev->pci_conf[0x3e] = 0x00; + dev->pci_conf[0x3f] = 0x00; + + if (dev->rev == 0xb0) { + ohci_update_mem_mapping(dev->usb, + dev->pci_conf[0x11], dev->pci_conf[0x12], + dev->pci_conf[0x13], dev->pci_conf[0x04] & 0x02); + + if (dev->usb_unk_base != 0x0000) { + io_removehandler(dev->usb_unk_base, 0x0002, + sis_5572_usb_unk_read, NULL, NULL, + sis_5572_usb_unk_write, NULL, NULL, dev); + } + + dev->usb_unk_base = 0x0000; + + memset(dev->usb_unk_regs, 0x00, sizeof(dev->usb_unk_regs)); + } +} + +static void +sis_5572_usb_close(void *priv) +{ + sis_5572_usb_t *dev = (sis_5572_usb_t *) priv; + + free(dev); +} + +static void * +sis_5572_usb_init(UNUSED(const device_t *info)) +{ + sis_5572_usb_t *dev = (sis_5572_usb_t *) calloc(1, sizeof(sis_5572_usb_t)); + + dev->rev = info->local; + + dev->sis = device_get_common_priv(); + + /* USB */ + dev->usb = device_add(&usb_device); + + sis_5572_usb_reset(dev); + + return dev; +} + +const device_t sis_5572_usb_device = { + .name = "SiS 5572 USB controller", + .internal_name = "sis_5572_usb", + .flags = DEVICE_PCI, + .local = 0xb0, + .init = sis_5572_usb_init, + .close = sis_5572_usb_close, + .reset = sis_5572_usb_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5582_usb_device = { + .name = "SiS 5582 USB controller", + .internal_name = "sis_5582_usb", + .flags = DEVICE_PCI, + .local = 0xe0, + .init = sis_5572_usb_init, + .close = sis_5572_usb_close, + .reset = sis_5572_usb_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5595_usb_device = { + .name = "SiS 5595 USB controller", + .internal_name = "sis_5595_usb", + .flags = DEVICE_PCI, + .local = 0x11, + .init = sis_5572_usb_init, + .close = sis_5572_usb_close, + .reset = sis_5572_usb_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5581.c b/src/chipset/sis_5581.c new file mode 100644 index 000000000..98b37897c --- /dev/null +++ b/src/chipset/sis_5581.c @@ -0,0 +1,185 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 5581/5582 Pentium PCI/ISA Chipset. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/apm.h> +#include <86box/acpi.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> + +#define ENABLE_SIS_5581_LOG 1 +#ifdef ENABLE_SIS_5581_LOG +int sis_5581_do_log = ENABLE_SIS_5581_LOG; + +static void +sis_5581_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5581_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5581_log(fmt, ...) +#endif + +typedef struct sis_5581_t { + uint8_t nb_slot; + uint8_t sb_slot; + + void *h2p; + void *p2i; + void *ide; + void *usb; + + sis_55xx_common_t *sis; +} sis_5581_t; + +static void +sis_5581_write(int func, int addr, uint8_t val, void *priv) +{ + const sis_5581_t *dev = (sis_5581_t *) priv; + + sis_5581_log("SiS 5581: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + if (func == 0x00) + sis_5581_host_to_pci_write(addr, val, dev->h2p); +} + +static uint8_t +sis_5581_read(int func, int addr, void *priv) +{ + const sis_5581_t *dev = (sis_5581_t *) priv; + uint8_t ret = 0xff; + + if (func == 0x00) + ret = sis_5581_host_to_pci_read(addr, dev->h2p); + + sis_5581_log("SiS 5581: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5582_write(int func, int addr, uint8_t val, void *priv) +{ + const sis_5581_t *dev = (sis_5581_t *) priv; + + sis_5581_log("SiS 5582: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (func) { + case 0x00: + sis_5513_pci_to_isa_write(addr, val, dev->p2i); + break; + case 0x01: + sis_5513_ide_write(addr, val, dev->ide); + break; + case 0x02: + sis_5572_usb_write(addr, val, dev->usb); + break; + } +} + +static uint8_t +sis_5582_read(int func, int addr, void *priv) +{ + const sis_5581_t *dev = (sis_5581_t *) priv; + uint8_t ret = 0xff; + + switch (func) { + case 0x00: + ret = sis_5513_pci_to_isa_read(addr, dev->p2i); + break; + case 0x01: + ret = sis_5513_ide_read(addr, dev->ide); + break; + case 0x02: + ret = sis_5572_usb_read(addr, dev->usb); + break; + } + + sis_5581_log("SiS 5582: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5581_close(void *priv) +{ + sis_5581_t *dev = (sis_5581_t *) priv; + + free(dev); +} + +static void * +sis_5581_init(UNUSED(const device_t *info)) +{ + sis_5581_t *dev = (sis_5581_t *) calloc(1, sizeof(sis_5581_t)); + + /* Device 0: SiS 5581 */ + pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5581_read, sis_5581_write, dev, &dev->nb_slot); + /* Device 1: SiS 5582 */ + pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5582_read, sis_5582_write, dev, &dev->sb_slot); + + dev->sis = device_add(&sis_55xx_common_device); + + dev->p2i = device_add_linked(&sis_5582_p2i_device, dev->sis); + dev->h2p = device_add_linked(&sis_5581_h2p_device, dev->sis); + dev->ide = device_add_linked(&sis_5582_ide_device, dev->sis); + dev->usb = device_add_linked(&sis_5582_usb_device, dev->sis); + + return dev; +} + +const device_t sis_5581_device = { + .name = "SiS 5581", + .internal_name = "sis_5581", + .flags = DEVICE_PCI, + .local = 0, + .init = sis_5581_init, + .close = sis_5581_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5581_h2p.c b/src/chipset/sis_5581_h2p.c new file mode 100644 index 000000000..48d61f25e --- /dev/null +++ b/src/chipset/sis_5581_h2p.c @@ -0,0 +1,553 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 5581 Host to PCI bridge. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> + +#ifdef ENABLE_SIS_5581_HOST_TO_PCI_LOG +int sis_5581_host_to_pci_do_log = ENABLE_SIS_5581_HOST_TO_PCI_LOG; + +static void +sis_5581_host_to_pci_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5581_host_to_pci_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5581_host_to_pci_log(fmt, ...) +#endif + +typedef struct { + uint8_t installed; + uint8_t code; + uint32_t phys_size; +} ram_bank_t; + +typedef struct sis_5581_io_trap_t { + void *priv; + void *trap; + uint8_t flags, mask; + uint8_t *sts_reg, sts_mask; + uint16_t addr; +} sis_5581_io_trap_t; + +typedef struct sis_5581_host_to_pci_t { + uint8_t pci_conf[256]; + uint8_t states[7]; + + ram_bank_t ram_banks[3]; + + sis_5581_io_trap_t io_traps[10]; + + sis_55xx_common_t *sis; + + smram_t *smram; +} sis_5581_host_to_pci_t; + +static uint8_t bank_codes[7] = { 0x00, 0x20, 0x24, 0x22, 0x26, 0x2a, 0x2b }; + +static uint32_t bank_sizes[7] = { 0x00800000, /* 8 MB */ + 0x01000000, /* 16 MB */ + 0x02000000, /* 32 MB */ + 0x04000000, /* 64 MB */ + 0x08000000, /* 128 MB */ + 0x10000000, /* 256 MB */ + 0x20000000 }; /* 512 MB */ + +static void +sis_5581_shadow_recalc(sis_5581_host_to_pci_t *dev) +{ + int state; + uint32_t base; + + for (uint8_t i = 0x70; i <= 0x76; i++) { + if (i == 0x76) { + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(0xf0000, 0x10000, state); + sis_5581_host_to_pci_log("000F0000-000FFFFF\n"); + } + } else { + base = ((i & 0x07) << 15) + 0xc0000; + + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base, 0x4000, state); + sis_5581_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff); + } + + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) { + state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base + 0x4000, 0x4000, state); + sis_5581_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff); + } + } + + dev->states[i & 0x0f] = dev->pci_conf[i]; + } + + flushmmucache_nopc(); +} + +static void +sis_5581_trap_io(UNUSED(int size), UNUSED(uint16_t addr), UNUSED(uint8_t write), UNUSED(uint8_t val), + void *priv) +{ + sis_5581_io_trap_t *trap = (sis_5581_io_trap_t *) priv; + sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) trap->priv; + + trap->sts_reg[0x04] |= trap->sts_mask; + + if (trap->sts_reg[0x00] & trap->sts_mask) + acpi_sis5582_pmu_event(dev->sis->acpi); +} + +static void +sis_5581_trap_io_mask(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +{ + sis_5581_io_trap_t *trap = (sis_5581_io_trap_t *) priv; + + if ((addr & trap->mask) == (trap->addr & trap->mask)) + sis_5581_trap_io(size, addr, write, val, priv); +} + +static void +sis_5581_trap_update_devctl(sis_5581_host_to_pci_t *dev, uint8_t trap_id, uint8_t enable, + uint8_t flags, uint8_t mask, uint8_t *sts_reg, uint8_t sts_mask, + uint16_t addr, uint16_t size) +{ + sis_5581_io_trap_t *trap = &dev->io_traps[trap_id]; + enable = enable; + + /* Set up Device I/O traps dynamically. */ + if (enable && !trap->trap) { + trap->priv = (void *) dev; + trap->flags = flags; + trap->mask = mask; + trap->addr = addr; + if (flags & 0x08) + trap->trap = io_trap_add(sis_5581_trap_io_mask, trap); + else + trap->trap = io_trap_add(sis_5581_trap_io, trap); + trap->sts_reg = sts_reg; + trap->sts_mask = sts_mask; + } + + /* Remap I/O trap. */ + io_trap_remap(trap->trap, enable, addr, size); +} + +static void +sis_5581_trap_update(void *priv) +{ + sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv; + uint8_t trap_id = 0; + uint8_t *fregs = dev->pci_conf; + uint16_t temp; + uint8_t mask; + uint8_t on; + + on = fregs[0x9a]; + + temp = ((fregs[0x96] & 0x02) | (fregs[0x97] << 2)) & 0x03ff; + mask = ~((1 << ((fregs[0x96] >> 3) & 0x07)) - 1); + + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x40, 0x08, mask, &(fregs[0x9c]), 0x40, temp, 0x80); + + temp = fregs[0x98] | (fregs[0x99] << 8); + mask = 0xff; + + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x20, 0x08, mask, &(fregs[0x9c]), 0x20, temp, 0x80); + + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x10, 0x00, 0xff, &(fregs[0x9c]), 0x10, 0x378, 0x08); + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x10, 0x00, 0xff, &(fregs[0x9c]), 0x10, 0x278, 0x08); + + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x08, 0x00, 0xff, &(fregs[0x9c]), 0x08, 0x3f8, 0x08); + + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x04, 0x00, 0xff, &(fregs[0x9c]), 0x04, 0x2f8, 0x08); + + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x02, 0x00, 0xff, &(fregs[0x9c]), 0x02, 0x1f0, 0x08); + + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x01, 0x00, 0xff, &(fregs[0x9c]), 0x01, 0x170, 0x08); + + on = fregs[0x9b]; + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x08, 0x00, 0xff, &(fregs[0x9d]), 0x08, 0x064, 0x01); + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x08, 0x00, 0xff, &(fregs[0x9d]), 0x08, 0x060, 0x01); +} + +static void +sis_5581_smram_recalc(sis_5581_host_to_pci_t *dev) +{ + smram_disable_all(); + + switch (dev->pci_conf[0xa3] >> 6) { + case 0: + smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); + break; + case 1: + smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); + break; + case 2: + smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); + break; + case 3: + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0xa3] & 0x10, 1); + break; + + default: + break; + } + + flushmmucache(); +} + +void +sis_5581_host_to_pci_write(int addr, uint8_t val, void *priv) +{ + sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv; + + sis_5581_host_to_pci_log("SiS 5581 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (addr) { + default: + break; + + case 0x04: /* Command - Low Byte */ + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xfc) | (val & 0x03); + break; + case 0x05: /* Command - High Byte */ + dev->pci_conf[addr] = val & 0x02; + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf[addr] &= ~(val & 0xb8); + break; + + case 0x0d: /* Master latency timer */ + case 0x50: + case 0x54: + case 0x56 ... 0x57: + case 0x59: + dev->pci_conf[addr] = val; + break; + + case 0x51: + dev->pci_conf[addr] = val; + cpu_cache_ext_enabled = !!(val & 0x40); + cpu_update_waitstates(); + break; + + case 0x52: + dev->pci_conf[addr] = val & 0xeb; + break; + + case 0x53: + case 0x55: + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x58: + dev->pci_conf[addr] = val & 0xfc; + break; + + case 0x5a: + dev->pci_conf[addr] = val & 0x03; + break; + + case 0x60 ... 0x62: + dev->pci_conf[addr] = dev->ram_banks[addr & 0x0f].code | 0xc0; + break; + + case 0x63: + dev->pci_conf[addr] = dev->ram_banks[0].installed | + (dev->ram_banks[1].installed << 1) | + (dev->ram_banks[2].installed << 2); + break; + + case 0x70 ... 0x75: + dev->pci_conf[addr] = val & 0xee; + sis_5581_shadow_recalc(dev); + break; + case 0x76: + dev->pci_conf[addr] = val & 0xe8; + sis_5581_shadow_recalc(dev); + break; + + case 0x77: /* Characteristics of non-cacheable area */ + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x78: /* Allocation of Non-Cacheable area #1 */ + case 0x79: /* NCA1REG2 */ + case 0x7a: /* Allocation of Non-Cacheable area #2 */ + case 0x7b: /* NCA2REG2 */ + dev->pci_conf[addr] = val; + break; + + case 0x80: /* PCI master characteristics */ + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x81: + dev->pci_conf[addr] = val & 0xde; + break; + + case 0x82: + dev->pci_conf[addr] = val; + break; + + case 0x83: /* CPU to PCI characteristics */ + dev->pci_conf[addr] = val; + /* TODO: Implement Fast A20 and Fast reset stuff on the KBC already! */ + break; + + case 0x84 ... 0x86: + case 0x88 ... 0x8b: + dev->pci_conf[addr] = val; + break; + + case 0x87: /* Miscellanea */ + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x8c ... 0x92: + case 0x9e ... 0xa2: + dev->pci_conf[addr] = val; + break; + + case 0x93: + dev->pci_conf[addr] = val; + if (val & 0x02) { + dev->pci_conf[0x9d] |= 0x01; + if (dev->pci_conf[0x9b] & 0x01) + acpi_sis5582_pmu_event(dev->sis->acpi); + } + break; + + case 0x94: + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x95: + dev->pci_conf[addr] = val & 0xfb; + break; + + case 0x96: + dev->pci_conf[addr] = val & 0xfb; + sis_5581_trap_update(dev); + break; + case 0x97 ... 0x9b: + dev->pci_conf[addr] = val; + sis_5581_trap_update(dev); + break; + + case 0x9c ... 0x9d: + dev->pci_conf[addr] &= ~val; + break; + + case 0xa3: + dev->pci_conf[addr] = val; + sis_5581_smram_recalc(dev); + break; + } +} + +uint8_t +sis_5581_host_to_pci_read(int addr, void *priv) +{ + const sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv; + uint8_t ret = 0xff; + + ret = dev->pci_conf[addr]; + + sis_5581_host_to_pci_log("SiS 5581 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5581_host_to_pci_reset(void *priv) +{ + sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x97; + dev->pci_conf[0x03] = 0x55; + dev->pci_conf[0x04] = 0x05; + dev->pci_conf[0x05] = dev->pci_conf[0x06] = 0x00; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = 0x02; + dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x0c] = 0x00; + dev->pci_conf[0x0d] = 0xff; + dev->pci_conf[0x0e] = dev->pci_conf[0x0f] = 0x00; + dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x00; + dev->pci_conf[0x52] = 0x00; + dev->pci_conf[0x53] = 0x38; + dev->pci_conf[0x54] = 0x54; + dev->pci_conf[0x55] = 0x00; + dev->pci_conf[0x56] = 0x80; + dev->pci_conf[0x57] = dev->pci_conf[0x58] = 0x00; + dev->pci_conf[0x59] = dev->pci_conf[0x5a] = 0x00; + dev->pci_conf[0x60] = dev->pci_conf[0x61] = 0x00; + dev->pci_conf[0x62] = 0x00; + dev->pci_conf[0x63] = 0xff; + dev->pci_conf[0x70] = dev->pci_conf[0x71] = 0x00; + dev->pci_conf[0x72] = dev->pci_conf[0x73] = 0x00; + dev->pci_conf[0x74] = dev->pci_conf[0x75] = 0x00; + dev->pci_conf[0x76] = dev->pci_conf[0x77] = 0x00; + dev->pci_conf[0x78] = dev->pci_conf[0x79] = 0x00; + dev->pci_conf[0x7a] = dev->pci_conf[0x7b] = 0x00; + dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00; + dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0x00; + dev->pci_conf[0x86] = dev->pci_conf[0x87] = 0x00; + dev->pci_conf[0x88] = dev->pci_conf[0x89] = 0x00; + dev->pci_conf[0x8a] = dev->pci_conf[0x8b] = 0x00; + dev->pci_conf[0x90] = dev->pci_conf[0x91] = 0x00; + dev->pci_conf[0x92] = dev->pci_conf[0x93] = 0x00; + dev->pci_conf[0x94] = dev->pci_conf[0x95] = 0x00; + dev->pci_conf[0x96] = dev->pci_conf[0x97] = 0x00; + dev->pci_conf[0x98] = dev->pci_conf[0x99] = 0x00; + dev->pci_conf[0x9a] = dev->pci_conf[0x9b] = 0x00; + dev->pci_conf[0x9c] = dev->pci_conf[0x9d] = 0x00; + dev->pci_conf[0x9e] = dev->pci_conf[0x9f] = 0xff; + dev->pci_conf[0xa0] = 0xff; + dev->pci_conf[0xa1] = 0x00; + dev->pci_conf[0xa2] = 0xff; + dev->pci_conf[0xa3] = 0x00; + + cpu_cache_ext_enabled = 0; + cpu_update_waitstates(); + + sis_5581_shadow_recalc(dev); + + sis_5581_trap_update(dev); + + sis_5581_smram_recalc(dev); +} + +static void +sis_5581_host_to_pci_close(void *priv) +{ + sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv; + + smram_del(dev->smram); + free(dev); +} + +static void * +sis_5581_host_to_pci_init(UNUSED(const device_t *info)) +{ + sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) calloc(1, sizeof(sis_5581_host_to_pci_t)); + uint32_t total_mem = mem_size << 10; + ram_bank_t *rb; + + dev->sis = device_get_common_priv(); + + /* Calculate the physical RAM banks. */ + for (uint8_t i = 0; i < 3; i++) { + rb = &(dev->ram_banks[i]); + uint32_t size = 0x00000000; + uint8_t index = 0; + for (int8_t j = 6; j >= 0; j--) { + uint32_t *bs = &(bank_sizes[j]); + if (*bs <= total_mem) { + size = *bs; + index = j; + break; + } + } + if (size != 0x00000000) { + rb->installed = 1; + rb->code = bank_codes[index]; + rb->phys_size = size; + total_mem -= size; + } else + rb->installed = 0; + } + + /* SMRAM */ + dev->smram = smram_add(); + + sis_5581_host_to_pci_reset(dev); + + return dev; +} + +const device_t sis_5581_h2p_device = { + .name = "SiS 5581 Host to PCI bridge", + .internal_name = "sis_5581_host_to_pci", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5581_host_to_pci_init, + .close = sis_5581_host_to_pci_close, + .reset = sis_5581_host_to_pci_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5591.c b/src/chipset/sis_5591.c new file mode 100644 index 000000000..969fcb8dd --- /dev/null +++ b/src/chipset/sis_5591.c @@ -0,0 +1,210 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 5591/5592 Pentium PCI/ISA Chipset. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/apm.h> +#include <86box/acpi.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> + +#ifdef ENABLE_SIS_5591_LOG +int sis_5591_do_log = ENABLE_SIS_5591_LOG; + +static void +sis_5591_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5591_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5591_log(fmt, ...) +#endif + +typedef struct sis_5591_t { + uint8_t nb_slot; + uint8_t sb_slot; + + void *h2p; + void *p2i; + void *ide; + void *usb; + void *pmu; + + sis_55xx_common_t *sis; +} sis_5591_t; + +static void +sis_5591_write(int func, int addr, uint8_t val, void *priv) +{ + const sis_5591_t *dev = (sis_5591_t *) priv; + + sis_5591_log("SiS 5591: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + if (func == 0x00) + sis_5591_host_to_pci_write(addr, val, dev->h2p); + else if (func == 0x01) + sis_5513_ide_write(addr, val, dev->ide); +} + +static uint8_t +sis_5591_read(int func, int addr, void *priv) +{ + const sis_5591_t *dev = (sis_5591_t *) priv; + uint8_t ret = 0xff; + + if (func == 0x00) + ret = sis_5591_host_to_pci_read(addr, dev->h2p); + else if (func == 0x01) + ret = sis_5513_ide_read(addr, dev->ide); + + sis_5591_log("SiS 5591: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5595_write(int func, int addr, uint8_t val, void *priv) +{ + const sis_5591_t *dev = (sis_5591_t *) priv; + + sis_5591_log("SiS 5595: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (func) { + case 0x00: + sis_5513_pci_to_isa_write(addr, val, dev->p2i); + break; + case 0x01: + sis_5595_pmu_write(addr, val, dev->pmu); + break; + case 0x02: + sis_5572_usb_write(addr, val, dev->usb); + break; + } +} + +static uint8_t +sis_5595_read(int func, int addr, void *priv) +{ + const sis_5591_t *dev = (sis_5591_t *) priv; + uint8_t ret = 0xff; + + switch (func) { + case 0x00: + ret = sis_5513_pci_to_isa_read(addr, dev->p2i); + break; + case 0x01: + ret = sis_5595_pmu_read(addr, dev->pmu); + break; + case 0x02: + ret = sis_5572_usb_read(addr, dev->usb); + break; + } + + sis_5591_log("SiS 5592: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5591_close(void *priv) +{ + sis_5591_t *dev = (sis_5591_t *) priv; + + free(dev); +} + +static void * +sis_5591_init(UNUSED(const device_t *info)) +{ + sis_5591_t *dev = (sis_5591_t *) calloc(1, sizeof(sis_5591_t)); + + /* Device 0: SiS 5591 */ + pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5591_read, sis_5591_write, dev, &dev->nb_slot); + /* Device 1: SiS 5595 */ + pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5595_read, sis_5595_write, dev, &dev->sb_slot); + + dev->sis = device_add(&sis_55xx_common_device); + + dev->ide = device_add_linked(&sis_5591_5600_ide_device, dev->sis); + if (info->local) + dev->p2i = device_add_linked(&sis_5595_1997_p2i_device, dev->sis); + else + dev->p2i = device_add_linked(&sis_5595_p2i_device, dev->sis); + dev->h2p = device_add_linked(&sis_5591_h2p_device, dev->sis); + dev->usb = device_add_linked(&sis_5595_usb_device, dev->sis); + if (info->local) + dev->pmu = device_add_linked(&sis_5595_1997_pmu_device, dev->sis); + else + dev->pmu = device_add_linked(&sis_5595_pmu_device, dev->sis); + + return dev; +} + +const device_t sis_5591_1997_device = { + .name = "SiS 5591 (1997)", + .internal_name = "sis_5591_1997", + .flags = DEVICE_PCI, + .local = 1, + .init = sis_5591_init, + .close = sis_5591_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5591_device = { + .name = "SiS 5591", + .internal_name = "sis_5591", + .flags = DEVICE_PCI, + .local = 0, + .init = sis_5591_init, + .close = sis_5591_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5591_h2p.c b/src/chipset/sis_5591_h2p.c new file mode 100644 index 000000000..8fcbeeb6f --- /dev/null +++ b/src/chipset/sis_5591_h2p.c @@ -0,0 +1,493 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 5591 Host to PCI bridge. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> +#include <86box/agpgart.h> + +#ifdef ENABLE_SIS_5591_HOST_TO_PCI_LOG +int sis_5591_host_to_pci_do_log = ENABLE_SIS_5591_HOST_TO_PCI_LOG; + +static void +sis_5591_host_to_pci_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5591_host_to_pci_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5591_host_to_pci_log(fmt, ...) +#endif + +typedef struct { + uint8_t installed; + uint8_t code; + uint32_t phys_size; +} ram_bank_t; + +typedef struct sis_5591_host_to_pci_t { + uint8_t pci_conf[256]; + + uint8_t states[7]; + uint8_t states_bus[7]; + + ram_bank_t ram_banks[3]; + + sis_55xx_common_t *sis; + + smram_t *smram; + + agpgart_t *agpgart; +} sis_5591_host_to_pci_t; + +static uint8_t bank_codes[6] = { 0x00, 0x20, 0x24, 0x22, 0x26, 0x2a }; + +static uint32_t bank_sizes[6] = { 0x00800000, /* 8 MB */ + 0x01000000, /* 16 MB */ + 0x02000000, /* 32 MB */ + 0x04000000, /* 64 MB */ + 0x08000000, /* 128 MB */ + 0x10000000 }; /* 256 MB */ + +static void +sis_5591_shadow_recalc(sis_5591_host_to_pci_t *dev) +{ + uint32_t base; + uint32_t state; + uint8_t val; + + for (uint8_t i = 0x70; i <= 0x76; i++) { + if (i == 0x76) { + val = dev->pci_conf[i]; + if ((dev->states[i & 0x0f] ^ val) & 0xa0) { + state = (val & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (val & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_cpu_both(0xf0000, 0x10000, state); + sis_5591_host_to_pci_log("000F0000-000FFFFF\n"); + + dev->states[i & 0x0f] = val; + } + + if (!(dev->pci_conf[0x76] & 0x08)) + val &= 0x5f; + if ((dev->states_bus[i & 0x0f] ^ val) & 0xa0) { + state = (val & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (val & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_bus_both(0xf0000, 0x10000, state); + sis_5591_host_to_pci_log("000F0000-000FFFFF\n"); + + dev->states_bus[i & 0x0f] = val; + } + } else { + base = ((i & 0x07) << 15) + 0xc0000; + + val = dev->pci_conf[i]; + if ((dev->states[i & 0x0f] ^ val) & 0xa0) { + state = (val & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (val & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_cpu_both(base, 0x4000, state); + sis_5591_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff); + + dev->states[i & 0x0f] = (dev->states[i & 0x0f] & 0x0f) | (val & 0xf0); + } + if ((dev->states[i & 0x0f] ^ val) & 0x0a) { + state = (val & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (val & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_cpu_both(base + 0x4000, 0x4000, state); + sis_5591_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff); + + dev->states[i & 0x0f] = (dev->states[i & 0x0f] & 0xf0) | (val & 0x0f); + } + + if (!(dev->pci_conf[0x76] & 0x08)) + val &= 0x55; + if ((dev->states_bus[i & 0x0f] ^ val) & 0xa0) { + state = (val & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (val & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_bus_both(base, 0x4000, state); + sis_5591_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff); + + dev->states_bus[i & 0x0f] = (dev->states_bus[i & 0x0f] & 0x0f) | (val & 0xf0); + } + if ((dev->states_bus[i & 0x0f] ^ val) & 0x0a) { + state = (val & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (val & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_bus_both(base + 0x4000, 0x4000, state); + sis_5591_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff); + + dev->states_bus[i & 0x0f] = (dev->states_bus[i & 0x0f] & 0xf0) | (val & 0x0f); + } + } + } + + flushmmucache_nopc(); +} + +static void +sis_5591_smram_recalc(sis_5591_host_to_pci_t *dev) +{ + smram_disable_all(); + + switch (dev->pci_conf[0x68] >> 6) { + case 0: + smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + break; + case 1: + smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + break; + case 2: + smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + break; + case 3: + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0x68] & 0x10, 1); + break; + + default: + break; + } + + flushmmucache(); +} + +static void +sis_5591_mask_bar(uint8_t *regs, void *agpgart) +{ + uint32_t bar; + uint32_t sizes[8] = { 0x00400000, 0x00800000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x00000000 } ; + + /* Make sure the aperture's base is aligned to its size. */ + bar = (regs[0x13] << 24) | (regs[0x12] << 16); + bar &= (sizes[(regs[0x94] >> 4) & 0x07] | 0xf0000000); + regs[0x12] = (bar >> 16) & 0xff; + regs[0x13] = (bar >> 24) & 0xff; + + if (!agpgart) + return; + + /* Map aperture and GART. */ + agpgart_set_aperture(agpgart, + bar, + sizes[(regs[0x94] >> 4) & 0x07], + !!(regs[0x94] & 0x02)); + if (regs[0x94] & 0x01) + agpgart_set_gart(agpgart, (regs[0x91] << 8) | (regs[0x92] << 16) | (regs[0x93] << 24)); + else + agpgart_set_gart(agpgart, 0x00000000); +} + +void +sis_5591_host_to_pci_write(int addr, uint8_t val, void *priv) +{ + sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) priv; + + sis_5591_host_to_pci_log("SiS 5591 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (addr) { + default: + break; + + case 0x04: /* Command - Low Byte */ + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xfd) | (val & 0x02); + break; + case 0x05: /* Command - High Byte */ + dev->pci_conf[addr] = val & 0x03; + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf[addr] &= ~(val & 0xf0); + break; + + case 0x12: + dev->pci_conf[addr] = val & 0xc0; + sis_5591_mask_bar(dev->pci_conf, dev->agpgart); + break; + case 0x13: + dev->pci_conf[addr] = val; + sis_5591_mask_bar(dev->pci_conf, dev->agpgart); + break; + + case 0x51: + dev->pci_conf[addr] = val; + cpu_cache_ext_enabled = !!(val & 0x80); + cpu_update_waitstates(); + break; + + case 0x60 ... 0x62: + dev->pci_conf[addr] = dev->ram_banks[addr & 0x0f].code | 0xc0; + break; + + case 0x63: + dev->pci_conf[addr] = dev->ram_banks[0].installed | + (dev->ram_banks[1].installed << 1) | + (dev->ram_banks[2].installed << 2); + break; + + case 0x68: + dev->pci_conf[addr] = val; + sis_5591_smram_recalc(dev); + break; + + case 0x70 ... 0x75: + dev->pci_conf[addr] = val & 0xee; + sis_5591_shadow_recalc(dev); + break; + case 0x76: + dev->pci_conf[addr] = val & 0xe8; + sis_5591_shadow_recalc(dev); + break; + + case 0x0d: /* Master latency timer */ + case 0x50: + case 0x52: + case 0x54 ... 0x5a: + case 0x5c ... 0x5f: + case 0x64 ... 0x65: + case 0x69 ... 0x6c: + case 0x77 ... 0x7b: + case 0x80 ... 0x8d: + case 0x90: + case 0x97 ... 0xab: + case 0xb0: + case 0xc8 ... 0xcb: + case 0xd4 ... 0xda: + case 0xe0 ... 0xe3: + case 0xef: + dev->pci_conf[addr] = val; + break; + + case 0x91 ... 0x93: + dev->pci_conf[addr] = val; + sis_5591_mask_bar(dev->pci_conf, dev->agpgart); + break; + case 0x94: + dev->pci_conf[addr] = val & 0x7f; + sis_5591_mask_bar(dev->pci_conf, dev->agpgart); + break; + + case 0xb2: + dev->pci_conf[addr] &= ~(val & 0x01); + break; + } +} + +uint8_t +sis_5591_host_to_pci_read(int addr, void *priv) +{ + const sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) priv; + uint8_t ret = 0xff; + + ret = dev->pci_conf[addr]; + + sis_5591_host_to_pci_log("SiS 5591 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5591_host_to_pci_reset(void *priv) +{ + sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x91; + dev->pci_conf[0x03] = 0x55; + dev->pci_conf[0x04] = 0x05; + dev->pci_conf[0x05] = 0x00; + dev->pci_conf[0x06] = 0x10; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = 0x02; + dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x0c] = 0x00; + dev->pci_conf[0x0d] = 0xff; + dev->pci_conf[0x0e] = 0x80; + dev->pci_conf[0x0f] = 0x00; + dev->pci_conf[0x10] = dev->pci_conf[0x11] = 0x00; + dev->pci_conf[0x12] = dev->pci_conf[0x13] = 0x00; + dev->pci_conf[0x34] = 0xc0; + dev->pci_conf[0x50] = 0x00; + dev->pci_conf[0x51] = 0x18; + dev->pci_conf[0x52] = dev->pci_conf[0x54] = 0x00; + dev->pci_conf[0x55] = 0x0e; + dev->pci_conf[0x56] = 0x40; + dev->pci_conf[0x57] = 0x00; + dev->pci_conf[0x58] = 0x50; + dev->pci_conf[0x59] = dev->pci_conf[0x5a] = 0x00; + dev->pci_conf[0x5c] = dev->pci_conf[0x5d] = 0x00; + dev->pci_conf[0x5e] = dev->pci_conf[0x5f] = 0x00; + dev->pci_conf[0x60] = dev->pci_conf[0x61] = 0x00; + dev->pci_conf[0x62] = 0x00; + dev->pci_conf[0x63] = 0xff; + dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00; + dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00; + dev->pci_conf[0x6a] = dev->pci_conf[0x6b] = 0x00; + dev->pci_conf[0x6c] = 0x00; + dev->pci_conf[0x70] = dev->pci_conf[0x71] = 0x00; + dev->pci_conf[0x72] = dev->pci_conf[0x73] = 0x00; + dev->pci_conf[0x74] = dev->pci_conf[0x75] = 0x00; + dev->pci_conf[0x76] = dev->pci_conf[0x77] = 0x00; + dev->pci_conf[0x78] = dev->pci_conf[0x79] = 0x00; + dev->pci_conf[0x7a] = dev->pci_conf[0x7b] = 0x00; + dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00; + dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0xff; + dev->pci_conf[0x86] = 0xff; + dev->pci_conf[0x87] = 0x00; + dev->pci_conf[0x88] = dev->pci_conf[0x89] = 0x00; + dev->pci_conf[0x8a] = dev->pci_conf[0x8b] = 0x00; + dev->pci_conf[0x8c] = dev->pci_conf[0x8d] = 0x00; + dev->pci_conf[0x90] = dev->pci_conf[0x91] = 0x00; + dev->pci_conf[0x92] = dev->pci_conf[0x93] = 0x00; + dev->pci_conf[0x94] = dev->pci_conf[0x97] = 0x00; + dev->pci_conf[0x98] = dev->pci_conf[0x99] = 0x00; + dev->pci_conf[0x9a] = dev->pci_conf[0x9b] = 0x00; + dev->pci_conf[0x9c] = dev->pci_conf[0x9d] = 0x00; + dev->pci_conf[0x9e] = dev->pci_conf[0x9f] = 0x00; + dev->pci_conf[0xa0] = dev->pci_conf[0xa1] = 0x00; + dev->pci_conf[0xa2] = dev->pci_conf[0xa3] = 0x00; + dev->pci_conf[0xa4] = dev->pci_conf[0xa5] = 0x00; + dev->pci_conf[0xa6] = dev->pci_conf[0xa7] = 0x00; + dev->pci_conf[0xa8] = dev->pci_conf[0xa9] = 0x00; + dev->pci_conf[0xaa] = dev->pci_conf[0xab] = 0x00; + dev->pci_conf[0xb0] = dev->pci_conf[0xb2] = 0x00; + dev->pci_conf[0xc0] = 0x02; + dev->pci_conf[0xc1] = 0x00; + dev->pci_conf[0xc2] = 0x10; + dev->pci_conf[0xc3] = 0x00; + dev->pci_conf[0xc4] = 0x03; + dev->pci_conf[0xc5] = 0x02; + dev->pci_conf[0xc6] = 0x00; + dev->pci_conf[0xc7] = 0x1f; + dev->pci_conf[0xc8] = dev->pci_conf[0xc9] = 0x00; + dev->pci_conf[0xca] = dev->pci_conf[0xcb] = 0x00; + dev->pci_conf[0xd4] = dev->pci_conf[0xd5] = 0x00; + dev->pci_conf[0xd6] = dev->pci_conf[0xd7] = 0x00; + dev->pci_conf[0xd8] = dev->pci_conf[0xd9] = 0x00; + dev->pci_conf[0xda] = 0x00; + dev->pci_conf[0xe0] = dev->pci_conf[0xe1] = 0x00; + dev->pci_conf[0xe2] = dev->pci_conf[0xe3] = 0x00; + dev->pci_conf[0xef] = 0x00; + + sis_5591_mask_bar(dev->pci_conf, dev->agpgart); + + cpu_cache_ext_enabled = 0; + cpu_update_waitstates(); + + sis_5591_shadow_recalc(dev); + + sis_5591_smram_recalc(dev); +} + +static void +sis_5591_host_to_pci_close(void *priv) +{ + sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) priv; + + smram_del(dev->smram); + free(dev); +} + +static void * +sis_5591_host_to_pci_init(UNUSED(const device_t *info)) +{ + sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) calloc(1, sizeof(sis_5591_host_to_pci_t)); + uint32_t total_mem = mem_size << 10; + ram_bank_t *rb; + + dev->sis = device_get_common_priv(); + + /* Calculate the physical RAM banks. */ + for (uint8_t i = 0; i < 3; i++) { + rb = &(dev->ram_banks[i]); + uint32_t size = 0x00000000; + uint8_t index = 0; + for (int8_t j = 5; j >= 0; j--) { + uint32_t *bs = &(bank_sizes[j]); + if (*bs <= total_mem) { + size = *bs; + index = j; + break; + } + } + if (size != 0x00000000) { + rb->installed = 1; + rb->code = bank_codes[index]; + rb->phys_size = size; + total_mem -= size; + } else + rb->installed = 0; + } + + /* SMRAM */ + dev->smram = smram_add(); + + device_add(&sis_5xxx_agp_device); + dev->agpgart = device_add(&agpgart_device); + + sis_5591_host_to_pci_reset(dev); + + return dev; +} + +const device_t sis_5591_h2p_device = { + .name = "SiS 5591 Host to PCI bridge", + .internal_name = "sis_5591_host_to_pci", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5591_host_to_pci_init, + .close = sis_5591_host_to_pci_close, + .reset = sis_5591_host_to_pci_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5595_pmu.c b/src/chipset/sis_5595_pmu.c new file mode 100644 index 000000000..4c6dbf7c9 --- /dev/null +++ b/src/chipset/sis_5595_pmu.c @@ -0,0 +1,455 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 5572 USB controller. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> + +#ifdef ENABLE_SIS_5595_PMU_LOG +int sis_5595_pmu_do_log = ENABLE_SIS_5595_PMU_LOG; + +static void +sis_5595_pmu_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5595_pmu_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5595_pmu_log(fmt, ...) +#endif + +typedef struct sis_5595_pmu_io_trap_t { + void *priv; + void *trap; + uint8_t flags, mask; + uint8_t *sts_reg, sts_mask; + uint16_t addr; +} sis_5595_pmu_io_trap_t; + +typedef struct sis_5595_pmu_t { + uint8_t is_1997; + + uint8_t pci_conf[256]; + + sis_5595_pmu_io_trap_t io_traps[22]; + + sis_55xx_common_t *sis; +} sis_5595_pmu_t; + +static void +sis_5595_pmu_trap_io(UNUSED(int size), UNUSED(uint16_t addr), UNUSED(uint8_t write), UNUSED(uint8_t val), + void *priv) +{ + sis_5595_pmu_io_trap_t *trap = (sis_5595_pmu_io_trap_t *) priv; + sis_5595_pmu_t *dev = (sis_5595_pmu_t *) trap->priv; + + trap->sts_reg[0x04] |= trap->sts_mask; + + if (trap->sts_reg[0x00] & trap->sts_mask) + acpi_sis5595_pmu_event(dev->sis->acpi); + + if (trap->sts_reg[0x20] & trap->sts_mask) + acpi_update_irq(dev->sis->acpi); +} + +static void +sis_5595_pmu_trap_io_ide(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +{ + sis_5595_pmu_io_trap_t *trap = (sis_5595_pmu_io_trap_t *) priv; + + /* IDE traps are per drive, not per channel. */ + if (ide_drives[trap->flags & 0x03]->selected) + sis_5595_pmu_trap_io(size, addr, write, val, priv); +} + +static void +sis_5595_pmu_trap_io_mask(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +{ + sis_5595_pmu_io_trap_t *trap = (sis_5595_pmu_io_trap_t *) priv; + + if ((addr & trap->mask) == (trap->addr & trap->mask)) + sis_5595_pmu_trap_io(size, addr, write, val, priv); +} + +static void +sis_5595_pmu_trap_io_ide_bm(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +{ + sis_5595_pmu_io_trap_t *trap = (sis_5595_pmu_io_trap_t *) priv; + sis_5595_pmu_t *dev = (sis_5595_pmu_t *) trap->priv; + + if (trap->flags & 0x01) { + dev->pci_conf[0x67] |= 0x01; + dev->pci_conf[0x64] |= 0x08; + } else { + dev->pci_conf[0x67] |= 0x02; + dev->pci_conf[0x64] |= 0x10; + } + acpi_sis5595_pmu_event(dev->sis->acpi); +} + +static void +sis_5595_pmu_trap_update_devctl(sis_5595_pmu_t *dev, uint8_t trap_id, uint8_t enable, + uint8_t flags, uint8_t mask, uint8_t *sts_reg, uint8_t sts_mask, + uint16_t addr, uint16_t size) +{ + sis_5595_pmu_io_trap_t *trap = &dev->io_traps[trap_id]; + enable = enable; + + /* Set up Device I/O traps dynamically. */ + if (enable && !trap->trap) { + trap->priv = (void *) dev; + trap->flags = flags; + trap->mask = mask; + trap->addr = addr; + if (flags & 0x10) + trap->trap = io_trap_add(sis_5595_pmu_trap_io_ide_bm, trap); + else if (flags & 0x08) + trap->trap = io_trap_add(sis_5595_pmu_trap_io_mask, trap); + else if (flags & 0x04) + trap->trap = io_trap_add(sis_5595_pmu_trap_io_ide, trap); + else + trap->trap = io_trap_add(sis_5595_pmu_trap_io, trap); + trap->sts_reg = sts_reg; + trap->sts_mask = sts_mask; + } + + /* Remap I/O trap. */ + io_trap_remap(trap->trap, enable, addr, size); +} + +static void +sis_5595_pmu_trap_update(void *priv) +{ + sis_5595_pmu_t *dev = (sis_5595_pmu_t *) priv; + uint8_t trap_id = 0; + uint8_t *fregs = dev->pci_conf; + uint16_t temp; + uint8_t mask; + uint8_t on; + + temp = (fregs[0x7e] | (fregs[0x7f] << 8)) & 0xffe0; + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + fregs[0x7e] & 0x08, 0x10, 0xff, NULL, 0xff, temp, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + fregs[0x7e] & 0x04, 0x10, 0xff, NULL, 0xff, temp + 8, 0x08); + + on = fregs[0x63] | fregs[0x83]; + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x02, 0x04, 0xff, &(fregs[0x63]), 0x02, 0x1f0, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x01, 0x06, 0xff, &(fregs[0x63]), 0x01, 0x170, 0x08); + + on = fregs[0x62] | fregs[0x82]; + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x80, 0x00, 0xff, &(fregs[0x62]), 0x80, 0x064, 0x01); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x80, 0x00, 0xff, &(fregs[0x62]), 0x80, 0x060, 0x01); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x40, 0x00, 0xff, &(fregs[0x62]), 0x40, 0x3f8, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x20, 0x00, 0xff, &(fregs[0x62]), 0x20, 0x2f8, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x10, 0x00, 0xff, &(fregs[0x62]), 0x10, 0x378, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x10, 0x00, 0xff, &(fregs[0x62]), 0x10, 0x278, 0x08); + + temp = (fregs[0x5c] | (fregs[0x5d] << 8)) & 0x03ff; + mask = fregs[0x5d] >> 2; + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x04, 0x08, mask, &(fregs[0x62]), 0x04, temp, 0x40); + + temp = fregs[0x5e] | (fregs[0x5f] << 8); + + if (dev->is_1997) { + mask = fregs[0x4d] & 0x1f; + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x02, 0x08, mask, &(fregs[0x62]), 0x02, temp, 0x20); + } else { + mask = fregs[0x4d]; + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x02, 0x08, mask, &(fregs[0x62]), 0x02, temp, 0x100); + } + + on = fregs[0x61] | fregs[0x81]; + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x40, 0x00, 0xff, &(fregs[0x61]), 0x40, 0x3b0, 0x30); + + switch ((fregs[0x4c] >> 6) & 0x03) { + case 0x00: + temp = 0xf40; + break; + case 0x01: + temp = 0xe80; + break; + case 0x02: + temp = 0x604; + break; + default: + temp = 0x530; + break; + } + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x10, 0x00, 0xff, &(fregs[0x61]), 0x10, temp, 0x08); + + switch ((fregs[0x4c] >> 4) & 0x03) { + case 0x00: + temp = 0x280; + break; + case 0x01: + temp = 0x260; + break; + case 0x02: + temp = 0x240; + break; + default: + temp = 0x220; + break; + } + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x08, 0x00, 0xff, &(fregs[0x61]), 0x08, temp, 0x14); + + switch ((fregs[0x4c] >> 2) & 0x03) { + case 0x00: + temp = 0x330; + break; + case 0x01: + temp = 0x320; + break; + case 0x02: + temp = 0x310; + break; + default: + temp = 0x300; + break; + } + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x04, 0x00, 0xff, &(fregs[0x61]), 0x04, temp, 0x04); + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x02, 0x00, 0xff, &(fregs[0x61]), 0x02, 0x200, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x02, 0x00, 0xff, &(fregs[0x61]), 0x02, 0x388, 0x04); + + on = fregs[0x60] | fregs[0x80]; + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x20, 0x00, 0xff, &(fregs[0x60]), 0x20, 0x3f0, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x20, 0x00, 0xff, &(fregs[0x60]), 0x20, 0x370, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x10, 0x05, 0xff, &(fregs[0x60]), 0x10, 0x1f0, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x08, 0x07, 0xff, &(fregs[0x60]), 0x08, 0x170, 0x08); +} + +void +sis_5595_pmu_write(int addr, uint8_t val, void *priv) +{ + sis_5595_pmu_t *dev = (sis_5595_pmu_t *) priv; + + sis_5595_pmu_log("SiS 5595 PMU: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + if (dev->sis->usb_enabled) switch (addr) { + default: + break; + + case 0x40 ... 0x4b: + case 0x50 ... 0x5b: + case 0x68 ... 0x7b: + case 0x7d: + dev->pci_conf[addr] = val; + break; + case 0x4c ... 0x4d: + case 0x5c ... 0x63: + case 0x7e ... 0x7f: + case 0x80 ... 0x83: + dev->pci_conf[addr] = val; + sis_5595_pmu_trap_update(dev); + break; + case 0x64 ... 0x67: + dev->pci_conf[addr] &= ~val; + break; + case 0x7c: + dev->pci_conf[addr] = val; + if (val & 0x02) { + dev->pci_conf[0x64] |= 0x04; + if (dev->pci_conf[0x60] & 0x04) + acpi_sis5595_pmu_event(dev->sis->acpi); + } + break; + } +} + +uint8_t +sis_5595_pmu_read(int addr, void *priv) +{ + const sis_5595_pmu_t *dev = (sis_5595_pmu_t *) priv; + uint8_t ret = 0xff; + + ret = dev->pci_conf[addr]; + + sis_5595_pmu_log("SiS 5595 PMU: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5595_pmu_reset(void *priv) +{ + sis_5595_pmu_t *dev = (sis_5595_pmu_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x09; + dev->pci_conf[0x03] = 0x00; + dev->pci_conf[0x04] = dev->pci_conf[0x05] = 0x00; + dev->pci_conf[0x06] = 0x00; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = dev->pci_conf[0x09] = 0x00; + dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0xff; + dev->pci_conf[0x0c] = dev->pci_conf[0x0d] = 0x00; + dev->pci_conf[0x0e] = 0x80; + dev->pci_conf[0x0f] = 0x00; + dev->pci_conf[0x40] = dev->pci_conf[0x41] = 0x00; + dev->pci_conf[0x42] = dev->pci_conf[0x43] = 0x00; + dev->pci_conf[0x44] = dev->pci_conf[0x45] = 0x00; + dev->pci_conf[0x46] = dev->pci_conf[0x47] = 0x00; + dev->pci_conf[0x48] = dev->pci_conf[0x49] = 0x00; + dev->pci_conf[0x4a] = dev->pci_conf[0x4b] = 0x00; + dev->pci_conf[0x4c] = dev->pci_conf[0x4d] = 0x00; + dev->pci_conf[0x4e] = dev->pci_conf[0x4f] = 0x00; + dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x00; + dev->pci_conf[0x52] = dev->pci_conf[0x53] = 0x00; + dev->pci_conf[0x54] = dev->pci_conf[0x55] = 0x00; + dev->pci_conf[0x56] = dev->pci_conf[0x57] = 0x00; + dev->pci_conf[0x58] = dev->pci_conf[0x59] = 0x00; + dev->pci_conf[0x5a] = dev->pci_conf[0x5b] = 0x00; + dev->pci_conf[0x5c] = dev->pci_conf[0x5d] = 0x00; + dev->pci_conf[0x5e] = dev->pci_conf[0x5f] = 0x00; + dev->pci_conf[0x60] = dev->pci_conf[0x61] = 0x00; + dev->pci_conf[0x62] = dev->pci_conf[0x63] = 0x00; + dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00; + dev->pci_conf[0x66] = dev->pci_conf[0x67] = 0x00; + dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00; + dev->pci_conf[0x6a] = dev->pci_conf[0x6b] = 0x00; + dev->pci_conf[0x6c] = dev->pci_conf[0x6d] = 0x00; + dev->pci_conf[0x6e] = dev->pci_conf[0x6f] = 0x00; + dev->pci_conf[0x70] = dev->pci_conf[0x71] = 0x00; + dev->pci_conf[0x72] = dev->pci_conf[0x73] = 0x00; + dev->pci_conf[0x74] = dev->pci_conf[0x75] = 0x00; + dev->pci_conf[0x76] = dev->pci_conf[0x77] = 0x00; + dev->pci_conf[0x78] = dev->pci_conf[0x79] = 0x00; + dev->pci_conf[0x7a] = dev->pci_conf[0x7b] = 0x00; + dev->pci_conf[0x7c] = dev->pci_conf[0x7d] = 0x00; + dev->pci_conf[0x7e] = dev->pci_conf[0x7f] = 0x00; + dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00; + + sis_5595_pmu_trap_update(dev); + acpi_update_irq(dev->sis->acpi); +} + +static void +sis_5595_pmu_close(void *priv) +{ + sis_5595_pmu_t *dev = (sis_5595_pmu_t *) priv; + + free(dev); +} + +static void * +sis_5595_pmu_init(UNUSED(const device_t *info)) +{ + sis_5595_pmu_t *dev = (sis_5595_pmu_t *) calloc(1, sizeof(sis_5595_pmu_t)); + + dev->sis = device_get_common_priv(); + dev->sis->pmu_regs = dev->pci_conf; + + dev->is_1997 = info->local; + + sis_5595_pmu_reset(dev); + + return dev; +} + +const device_t sis_5595_1997_pmu_device = { + .name = "SiS 5595 (1997) PMU", + .internal_name = "sis_5595_1997_pmu", + .flags = DEVICE_PCI, + .local = 0x01, + .init = sis_5595_pmu_init, + .close = sis_5595_pmu_close, + .reset = sis_5595_pmu_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5595_pmu_device = { + .name = "SiS 5595 PMU", + .internal_name = "sis_5595_pmu", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5595_pmu_init, + .close = sis_5595_pmu_close, + .reset = sis_5595_pmu_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_55xx.c b/src/chipset/sis_55xx.c new file mode 100644 index 000000000..2cad21f22 --- /dev/null +++ b/src/chipset/sis_55xx.c @@ -0,0 +1,96 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 55xx common structure. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> + +#ifdef ENABLE_SIS_55XX_COMMON_LOG +int sis_55xx_common_do_log = ENABLE_SIS_55XX_COMMON_LOG; + +static void +sis_55xx_common_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_55xx_common_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_55xx_common_log(fmt, ...) +#endif + +static void +sis_55xx_common_close(void *priv) +{ + sis_55xx_common_t *dev = (sis_55xx_common_t *) priv; + + free(dev); +} + +static void * +sis_55xx_common_init(UNUSED(const device_t *info)) +{ + sis_55xx_common_t *dev = (sis_55xx_common_t *) calloc(1, sizeof(sis_55xx_common_t)); + + return dev; +} + +const device_t sis_55xx_common_device = { + .name = "SiS 55xx Common Structure", + .internal_name = "sis_55xx_common", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_55xx_common_init, + .close = sis_55xx_common_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5600.c b/src/chipset/sis_5600.c new file mode 100644 index 000000000..ed7384740 --- /dev/null +++ b/src/chipset/sis_5600.c @@ -0,0 +1,210 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS (5)600 Pentium PCI/ISA Chipset. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/apm.h> +#include <86box/acpi.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> + +#ifdef ENABLE_SIS_5600_LOG +int sis_5600_do_log = ENABLE_SIS_5600_LOG; + +static void +sis_5600_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5600_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5600_log(fmt, ...) +#endif + +typedef struct sis_5600_t { + uint8_t nb_slot; + uint8_t sb_slot; + + void *h2p; + void *p2i; + void *ide; + void *usb; + void *pmu; + + sis_55xx_common_t *sis; +} sis_5600_t; + +static void +sis_5600_write(int func, int addr, uint8_t val, void *priv) +{ + const sis_5600_t *dev = (sis_5600_t *) priv; + + sis_5600_log("SiS 5600: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + if (func == 0x00) + sis_5600_host_to_pci_write(addr, val, dev->h2p); + else if (func == 0x01) + sis_5513_ide_write(addr, val, dev->ide); +} + +static uint8_t +sis_5600_read(int func, int addr, void *priv) +{ + const sis_5600_t *dev = (sis_5600_t *) priv; + uint8_t ret = 0xff; + + if (func == 0x00) + ret = sis_5600_host_to_pci_read(addr, dev->h2p); + else if (func == 0x01) + ret = sis_5513_ide_read(addr, dev->ide); + + sis_5600_log("SiS 5600: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5595_write(int func, int addr, uint8_t val, void *priv) +{ + const sis_5600_t *dev = (sis_5600_t *) priv; + + sis_5600_log("SiS 5595: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (func) { + case 0x00: + sis_5513_pci_to_isa_write(addr, val, dev->p2i); + break; + case 0x01: + sis_5595_pmu_write(addr, val, dev->pmu); + break; + case 0x02: + sis_5572_usb_write(addr, val, dev->usb); + break; + } +} + +static uint8_t +sis_5595_read(int func, int addr, void *priv) +{ + const sis_5600_t *dev = (sis_5600_t *) priv; + uint8_t ret = 0xff; + + switch (func) { + case 0x00: + ret = sis_5513_pci_to_isa_read(addr, dev->p2i); + break; + case 0x01: + ret = sis_5595_pmu_read(addr, dev->pmu); + break; + case 0x02: + ret = sis_5572_usb_read(addr, dev->usb); + break; + } + + sis_5600_log("SiS 5602: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5600_close(void *priv) +{ + sis_5600_t *dev = (sis_5600_t *) priv; + + free(dev); +} + +static void * +sis_5600_init(UNUSED(const device_t *info)) +{ + sis_5600_t *dev = (sis_5600_t *) calloc(1, sizeof(sis_5600_t)); + + /* Device 0: SiS 5600 */ + pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5600_read, sis_5600_write, dev, &dev->nb_slot); + /* Device 1: SiS 5595 */ + pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5595_read, sis_5595_write, dev, &dev->sb_slot); + + dev->sis = device_add(&sis_55xx_common_device); + + dev->ide = device_add_linked(&sis_5591_5600_ide_device, dev->sis); + if (info->local) + dev->p2i = device_add_linked(&sis_5595_1997_p2i_device, dev->sis); + else + dev->p2i = device_add_linked(&sis_5595_p2i_device, dev->sis); + dev->h2p = device_add_linked(&sis_5600_h2p_device, dev->sis); + dev->usb = device_add_linked(&sis_5595_usb_device, dev->sis); + if (info->local) + dev->pmu = device_add_linked(&sis_5595_1997_pmu_device, dev->sis); + else + dev->pmu = device_add_linked(&sis_5595_pmu_device, dev->sis); + + return dev; +} + +const device_t sis_5600_1997_device = { + .name = "SiS (5)600 (1997)", + .internal_name = "sis_5600_1997", + .flags = DEVICE_PCI, + .local = 1, + .init = sis_5600_init, + .close = sis_5600_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5600_device = { + .name = "SiS (5)600", + .internal_name = "sis_5600", + .flags = DEVICE_PCI, + .local = 0, + .init = sis_5600_init, + .close = sis_5600_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5600_h2p.c b/src/chipset/sis_5600_h2p.c new file mode 100644 index 000000000..f6ee926da --- /dev/null +++ b/src/chipset/sis_5600_h2p.c @@ -0,0 +1,434 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS (5)600 Host to PCI bridge. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> +#include <86box/agpgart.h> + +#ifdef ENABLE_SIS_5600_HOST_TO_PCI_LOG +int sis_5600_host_to_pci_do_log = ENABLE_SIS_5600_HOST_TO_PCI_LOG; + +static void +sis_5600_host_to_pci_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5600_host_to_pci_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5600_host_to_pci_log(fmt, ...) +#endif + +typedef struct { + uint8_t installed; + uint8_t code; + uint32_t phys_size; +} ram_bank_t; + +typedef struct sis_5600_host_to_pci_t { + uint8_t pci_conf[256]; + uint8_t states[7]; + + ram_bank_t ram_banks[3]; + + sis_55xx_common_t *sis; + + smram_t *smram; + + agpgart_t *agpgart; +} sis_5600_host_to_pci_t; + +static uint8_t bank_codes[7] = { 0x00, 0x20, 0x24, 0x22, 0x26, 0x2a, 0x2b }; + +static uint32_t bank_sizes[7] = { 0x00800000, /* 8 MB */ + 0x01000000, /* 16 MB */ + 0x02000000, /* 32 MB */ + 0x04000000, /* 64 MB */ + 0x08000000, /* 128 MB */ + 0x10000000, /* 256 MB */ + 0x20000000 }; /* 512 MB */ + +static void +sis_5600_shadow_recalc(sis_5600_host_to_pci_t *dev) +{ + int state; + uint32_t base; + + for (uint8_t i = 0; i < 8; i++) { + base = 0x000c0000 + (i << 14); + state = (dev->pci_conf[0x70] & (1 << i)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[0x72] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + if (((dev->pci_conf[0x70] ^ dev->states[0]) & (1 << i)) || + ((dev->pci_conf[0x72] ^ dev->states[2]) & (1 << i))) { + mem_set_mem_state_both(base, 0x4000, state); + sis_5600_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff); + } + } + + for (uint8_t i = 0; i < 4; i++) { + base = 0x000e0000 + (i << 14); + state = (dev->pci_conf[0x71] & (1 << i)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[0x73] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + if (((dev->pci_conf[0x71] ^ dev->states[1]) & (1 << i)) || + ((dev->pci_conf[0x73] ^ dev->states[3]) & (1 << i))) { + mem_set_mem_state_both(base, 0x4000, state); + sis_5600_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff); + } + } + + base = 0x000f0000; + state = (dev->pci_conf[0x71] & (1 << 4)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[0x73] & (1 << 4)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + if (((dev->pci_conf[0x71] ^ dev->states[1]) & (1 << 4)) || + ((dev->pci_conf[0x73] ^ dev->states[3]) & (1 << 4))) { + mem_set_mem_state_both(base, 0x10000, state); + sis_5600_host_to_pci_log("%08X-%08X\n", base, base + 0xffff); + } + + for (uint8_t i = 0; i < 4; i++) + dev->states[i] = dev->pci_conf[0x70 + i]; + + flushmmucache_nopc(); +} + +static void +sis_5600_smram_recalc(sis_5600_host_to_pci_t *dev) +{ + smram_disable_all(); + + switch (dev->pci_conf[0x6a] >> 6) { + case 0: + smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x6a] & 0x10, 1); + break; + case 1: + smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x6a] & 0x10, 1); + break; + case 2: + smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x6a] & 0x10, 1); + break; + case 3: + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0x6a] & 0x10, 1); + break; + + default: + break; + } + + flushmmucache(); +} + +static void +sis_5600_mask_bar(uint8_t *regs, void *agpgart) +{ + uint32_t bar; + uint32_t sizes[8] = { 0x00400000, 0x00800000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x00000000 } ; + + /* Make sure the aperture's base is aligned to its size. */ + bar = (regs[0x13] << 24) | (regs[0x12] << 16); + bar &= (sizes[(regs[0x94] >> 4) & 0x07] | 0xf0000000); + regs[0x12] = (bar >> 16) & 0xff; + regs[0x13] = (bar >> 24) & 0xff; + + if (!agpgart) + return; + + /* Map aperture and GART. */ + agpgart_set_aperture(agpgart, + bar, + sizes[(regs[0x94] >> 4) & 0x07], + !!(regs[0x94] & 0x02)); + if (regs[0x94] & 0x01) + agpgart_set_gart(agpgart, (regs[0x91] << 8) | (regs[0x92] << 16) | (regs[0x93] << 24)); + else + agpgart_set_gart(agpgart, 0x00000000); +} + +void +sis_5600_host_to_pci_write(int addr, uint8_t val, void *priv) +{ + sis_5600_host_to_pci_t *dev = (sis_5600_host_to_pci_t *) priv; + + sis_5600_host_to_pci_log("SiS 5600 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (addr) { + default: + break; + + case 0x04: /* Command - Low Byte */ + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xfd) | (val & 0x02); + break; + case 0x05: /* Command - High Byte */ + dev->pci_conf[addr] = val & 0x03; + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf[addr] = (dev->pci_conf[addr] & ~(val & 0x70)) | (val & 0x01); + break; + + case 0x0d: /* Master latency timer */ + case 0x50 ... 0x5a: + case 0x64 ... 0x69: + case 0x6b ... 0x6c: + case 0x74 ... 0x75: + case 0x77 ... 0x80: + case 0x82 ... 0x8f: + case 0x97 ... 0x9b: + case 0xc8 ... 0xcb: + case 0xd4 ... 0xd8: + case 0xda: + case 0xe0: + case 0xe2 ... 0xe3: + dev->pci_conf[addr] = val; + break; + + case 0x12: + dev->pci_conf[addr] = val & 0xc0; + sis_5600_mask_bar(dev->pci_conf, dev->agpgart); + break; + case 0x13: + dev->pci_conf[addr] = val; + sis_5600_mask_bar(dev->pci_conf, dev->agpgart); + break; + + case 0x60 ... 0x62: + dev->pci_conf[addr] = dev->ram_banks[addr & 0x0f].code | 0xc0; + break; + + case 0x63: + dev->pci_conf[addr] = dev->ram_banks[0].installed | + (dev->ram_banks[1].installed << 1) | + (dev->ram_banks[2].installed << 2); + break; + + case 0x6a: + dev->pci_conf[addr] = val; + sis_5600_smram_recalc(dev); + break; + + case 0x70 ... 0x73: + dev->pci_conf[addr] = val; + sis_5600_shadow_recalc(dev); + break; + + case 0x91 ... 0x93: + dev->pci_conf[addr] = val; + sis_5600_mask_bar(dev->pci_conf, dev->agpgart); + break; + case 0x94: + dev->pci_conf[addr] = val & 0x7f; + sis_5600_mask_bar(dev->pci_conf, dev->agpgart); + break; + } +} + +uint8_t +sis_5600_host_to_pci_read(int addr, void *priv) +{ + const sis_5600_host_to_pci_t *dev = (sis_5600_host_to_pci_t *) priv; + uint8_t ret = 0xff; + + ret = dev->pci_conf[addr]; + + sis_5600_host_to_pci_log("SiS 5600 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5600_host_to_pci_reset(void *priv) +{ + sis_5600_host_to_pci_t *dev = (sis_5600_host_to_pci_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x00; + dev->pci_conf[0x03] = 0x56; + dev->pci_conf[0x04] = 0x05; + dev->pci_conf[0x05] = 0x00; + dev->pci_conf[0x06] = 0x10; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = 0x10; + dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x0c] = 0x00; + dev->pci_conf[0x0d] = 0xff; + dev->pci_conf[0x0e] = 0x80; + dev->pci_conf[0x0f] = 0x00; + dev->pci_conf[0x10] = dev->pci_conf[0x11] = 0x00; + dev->pci_conf[0x12] = dev->pci_conf[0x13] = 0x00; + dev->pci_conf[0x34] = 0xc0; + dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x02; + dev->pci_conf[0x52] = dev->pci_conf[0x53] = 0x00; + dev->pci_conf[0x54] = dev->pci_conf[0x55] = 0x00; + dev->pci_conf[0x56] = dev->pci_conf[0x57] = 0x00; + dev->pci_conf[0x58] = dev->pci_conf[0x59] = 0x00; + dev->pci_conf[0x5a] = 0x00; + dev->pci_conf[0x60] = dev->pci_conf[0x61] = 0x00; + dev->pci_conf[0x62] = 0x00; + dev->pci_conf[0x63] = 0xff; + dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00; + dev->pci_conf[0x66] = dev->pci_conf[0x67] = 0x00; + dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00; + dev->pci_conf[0x6a] = dev->pci_conf[0x6b] = 0x00; + dev->pci_conf[0x6c] = 0x00; + dev->pci_conf[0x70] = dev->pci_conf[0x71] = 0x00; + dev->pci_conf[0x72] = dev->pci_conf[0x73] = 0x00; + dev->pci_conf[0x74] = dev->pci_conf[0x75] = 0x00; + dev->pci_conf[0x77] = 0x00; + dev->pci_conf[0x78] = dev->pci_conf[0x79] = 0x00; + dev->pci_conf[0x7a] = dev->pci_conf[0x7b] = 0x00; + dev->pci_conf[0x7c] = dev->pci_conf[0x7d] = 0x00; + dev->pci_conf[0x7e] = dev->pci_conf[0x7f] = 0x00; + dev->pci_conf[0x80] = 0x00; + dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00; + dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0xff; + dev->pci_conf[0x86] = 0xff; + dev->pci_conf[0x87] = 0x00; + dev->pci_conf[0x88] = dev->pci_conf[0x89] = 0x00; + dev->pci_conf[0x8a] = dev->pci_conf[0x8b] = 0x00; + dev->pci_conf[0x8c] = 0x00; + dev->pci_conf[0x8d] = 0x62; + dev->pci_conf[0x8e] = dev->pci_conf[0x8f] = 0x00; + dev->pci_conf[0x90] = dev->pci_conf[0x91] = 0x00; + dev->pci_conf[0x92] = dev->pci_conf[0x93] = 0x00; + dev->pci_conf[0x94] = dev->pci_conf[0x97] = 0x00; + dev->pci_conf[0x98] = dev->pci_conf[0x99] = 0x00; + dev->pci_conf[0x9a] = dev->pci_conf[0x9b] = 0x00; + dev->pci_conf[0xc0] = 0x02; + dev->pci_conf[0xc1] = 0x00; + dev->pci_conf[0xc2] = 0x10; + dev->pci_conf[0xc3] = 0x00; + dev->pci_conf[0xc4] = 0x03; + dev->pci_conf[0xc5] = 0x02; + dev->pci_conf[0xc6] = 0x00; + dev->pci_conf[0xc7] = 0x1f; + dev->pci_conf[0xc8] = dev->pci_conf[0xc9] = 0x00; + dev->pci_conf[0xca] = dev->pci_conf[0xcb] = 0x00; + dev->pci_conf[0xd4] = dev->pci_conf[0xd5] = 0x00; + dev->pci_conf[0xd6] = dev->pci_conf[0xd7] = 0x00; + dev->pci_conf[0xd8] = dev->pci_conf[0xda] = 0x00; + dev->pci_conf[0xe0] = 0x00; + dev->pci_conf[0xe2] = dev->pci_conf[0xe3] = 0x00; + + sis_5600_mask_bar(dev->pci_conf, dev->agpgart); + + cpu_cache_ext_enabled = 1; + cpu_update_waitstates(); + + sis_5600_shadow_recalc(dev); + + sis_5600_smram_recalc(dev); +} + +static void +sis_5600_host_to_pci_close(void *priv) +{ + sis_5600_host_to_pci_t *dev = (sis_5600_host_to_pci_t *) priv; + + smram_del(dev->smram); + free(dev); +} + +static void * +sis_5600_host_to_pci_init(UNUSED(const device_t *info)) +{ + sis_5600_host_to_pci_t *dev = (sis_5600_host_to_pci_t *) calloc(1, sizeof(sis_5600_host_to_pci_t)); + uint32_t total_mem = mem_size << 10; + ram_bank_t *rb; + + dev->sis = device_get_common_priv(); + + /* Calculate the physical RAM banks. */ + for (uint8_t i = 0; i < 3; i++) { + rb = &(dev->ram_banks[i]); + uint32_t size = 0x00000000; + uint8_t index = 0; + for (int8_t j = 6; j >= 0; j--) { + uint32_t *bs = &(bank_sizes[j]); + if (*bs <= total_mem) { + size = *bs; + index = j; + break; + } + } + if (size != 0x00000000) { + rb->installed = 1; + rb->code = bank_codes[index]; + rb->phys_size = size; + total_mem -= size; + } else + rb->installed = 0; + } + + /* SMRAM */ + dev->smram = smram_add(); + + device_add(&sis_5xxx_agp_device); + dev->agpgart = device_add(&agpgart_device); + + sis_5600_host_to_pci_reset(dev); + + return dev; +} + +const device_t sis_5600_h2p_device = { + .name = "SiS (5)600 Host to PCI bridge", + .internal_name = "sis_5600_host_to_pci", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5600_host_to_pci_init, + .close = sis_5600_host_to_pci_close, + .reset = sis_5600_host_to_pci_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_85c50x.c b/src/chipset/sis_85c50x.c index 7f4aebb7c..8ec0498ff 100644 --- a/src/chipset/sis_85c50x.c +++ b/src/chipset/sis_85c50x.c @@ -6,15 +6,13 @@ * * This file is part of the 86Box distribution. * - * Implementation of the SiS 85C50x Chipset. + * Implementation of the SiS 85C50x and 550x Chipsets. * + * Authors: Miran Grca, + * Tiseno100, * - * - * Authors: Tiseno100, - * Miran Grca, - * - * Copyright 2020-2021 Tiseno100. - * Copyright 2020-2021 Miran Grca. + * Copyright 2020-2024 Miran Grca. + * Copyright 2020-2024 Tiseno100. */ #include #include @@ -27,16 +25,20 @@ #include <86box/device.h> #include <86box/io.h> #include <86box/timer.h> - #include <86box/apm.h> #include <86box/machine.h> #include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> #include <86box/plat_unused.h> #include <86box/mem.h> +#include <86box/nvr.h> #include <86box/smram.h> #include <86box/pci.h> #include <86box/port_92.h> - +#include <86box/spd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> #include <86box/chipset.h> #ifdef ENABLE_SIS_85C50X_LOG @@ -58,17 +60,23 @@ sis_85c50x_log(const char *fmt, ...) #endif typedef struct sis_85c50x_t { - uint8_t index; - uint8_t nb_slot; - uint8_t sb_slot; - uint8_t pad; + uint8_t index; + uint8_t nb_slot; + uint8_t sb_slot; + uint8_t type; - uint8_t pci_conf[256]; - uint8_t pci_conf_sb[256]; - uint8_t regs[256]; + uint8_t pci_conf[256]; + uint8_t pci_conf_sb[256]; + uint8_t pci_conf_ide[256]; + uint8_t regs[256]; + uint32_t states[13]; smram_t *smram[2]; port_92_t *port_92; + void *pit; + nvr_t *nvr; + + uint8_t (*pit_read_reg)(void *priv, uint8_t reg); } sis_85c50x_t; static void @@ -77,23 +85,59 @@ sis_85c50x_shadow_recalc(sis_85c50x_t *dev) uint32_t base; uint32_t can_read; uint32_t can_write; + uint32_t state; can_read = (dev->pci_conf[0x53] & 0x40) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; can_write = (dev->pci_conf[0x53] & 0x20) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL; - if (!can_read) - can_write = MEM_WRITE_EXTANY; - mem_set_mem_state_both(0xf0000, 0x10000, can_read | can_write); - shadowbios = 1; - shadowbios_write = 1; + state = can_read | can_write; + if (dev->states[12] != state) { + mem_set_mem_state_both(0x000f0000, 0x00010000, state); + sis_85c50x_log("F0000-FFFFF: R%c, W%c\n", + (dev->pci_conf[0x53] & 0x40) ? 'I' : 'E', + (dev->pci_conf[0x53] & 0x20) ? 'P' : 'I'); + dev->states[12] = state; + } for (uint8_t i = 0; i < 4; i++) { - base = 0xe0000 + (i << 14); - mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x54] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); - base = 0xd0000 + (i << 14); - mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x55] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); - base = 0xc0000 + (i << 14); - mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x56] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); + base = 0x000e0000 + (i << 14); + state = (dev->pci_conf[0x54] & (0x80 >> i)) ? + (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + if (dev->states[8 + i] != state) { + mem_set_mem_state_both(base, 0x00004000, state); + sis_85c50x_log("%05X-%05X: R%c, W%c\n", base, base + 0x3fff, + (dev->pci_conf[0x543 & (0x80 >> i)) ? + ((dev->pci_conf[0x54] & 0x40) ? 'I' : 'D') : 'E', + (dev->pci_conf[0x54] & (0x80 >> i)) ? + ((dev->pci_conf[0x53] & 0x20) ? 'P' : 'I') : 'E'); + dev->states[8 + i] = state; + } + + base = 0x000d0000 + (i << 14); + state = (dev->pci_conf[0x55] & (0x80 >> i)) ? + (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + if (dev->states[4 + i] != state) { + mem_set_mem_state_both(base, 0x00004000, state); + sis_85c50x_log("%05X-%05X: R%c, W%c\n", base, base + 0x3fff, + (dev->pci_conf[0x55] & (0x80 >> i)) ? + ((dev->pci_conf[0x53] & 0x40) ? 'I' : 'D') : 'E', + (dev->pci_conf[0x55] & (0x80 >> i)) ? + ((dev->pci_conf[0x53] & 0x20) ? 'P' : 'I') : 'E'); + dev->states[4 + i] = state; + } + + base = 0x000c0000 + (i << 14); + state = (dev->pci_conf[0x56] & (0x80 >> i)) ? + (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + if (dev->states[i] != state) { + mem_set_mem_state_both(base, 0x00004000, state); + sis_85c50x_log("%05X-%05X: R%c, W%c\n", base, base + 0x3fff, + (dev->pci_conf[0x56] & (0x80 >> i)) ? + ((dev->pci_conf[0x53] & 0x40) ? 'I' : 'D') : 'E', + (dev->pci_conf[0x56] & (0x80 >> i)) ? + ((dev->pci_conf[0x53] & 0x20) ? 'P' : 'I') : 'E'); + dev->states[i] = state; + } } flushmmucache_nopc(); @@ -117,27 +161,35 @@ sis_85c50x_smm_recalc(sis_85c50x_t *dev) break; case 0x01: host_base |= 0x000b0000; - sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000B0000-000BFFFF\n", host_base, host_base + 0x10000 - 1); + sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000B0000-000BFFFF\n", + host_base, host_base + 0x10000 - 1); smram_enable(dev->smram[0], host_base, 0xb0000, 0x10000, (dev->pci_conf[0x65] & 0x10), 1); - smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xb0000, 0x10000, (dev->pci_conf[0x65] & 0x10), 1); + smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xb0000, + 0x10000, (dev->pci_conf[0x65] & 0x10), 1); break; case 0x02: host_base |= 0x000a0000; - sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000A0000-000AFFFF\n", host_base, host_base + 0x10000 - 1); + sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000A0000-000AFFFF\n", + host_base, host_base + 0x10000 - 1); smram_enable(dev->smram[0], host_base, 0xa0000, 0x10000, (dev->pci_conf[0x65] & 0x10), 1); - smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000, 0x10000, (dev->pci_conf[0x65] & 0x10), 1); + smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000, + 0x10000, (dev->pci_conf[0x65] & 0x10), 1); break; case 0x04: host_base |= 0x000a0000; - sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000A0000-000AFFFF\n", host_base, host_base + 0x8000 - 1); + sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000A0000-000AFFFF\n", + host_base, host_base + 0x8000 - 1); smram_enable(dev->smram[0], host_base, 0xa0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1); - smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1); + smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000, + 0x8000, (dev->pci_conf[0x65] & 0x10), 1); break; case 0x06: host_base |= 0x000b0000; - sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000B0000-000BFFFF\n", host_base, host_base + 0x8000 - 1); + sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000B0000-000BFFFF\n", + host_base, host_base + 0x8000 - 1); smram_enable(dev->smram[0], host_base, 0xb0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1); - smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1); + smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000, + 0x8000, (dev->pci_conf[0x65] & 0x10), 1); break; default: break; @@ -160,7 +212,10 @@ sis_85c50x_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[addr] = ((dev->pci_conf[addr] & 0xf9) & ~(val & 0xf8)) | (val & 0x06); break; case 0x50: - dev->pci_conf[addr] = val; + if (dev->type & 1) + dev->pci_conf[addr] = val & 0xf7; + else + dev->pci_conf[addr] = val; break; case 0x51: /* Cache */ dev->pci_conf[addr] = val; @@ -176,8 +231,6 @@ sis_85c50x_write(int func, int addr, uint8_t val, void *priv) case 0x56: dev->pci_conf[addr] = val; sis_85c50x_shadow_recalc(dev); - if (addr == 0x54) - sis_85c50x_smm_recalc(dev); break; case 0x57: case 0x58: @@ -223,6 +276,31 @@ sis_85c50x_write(int func, int addr, uint8_t val, void *priv) case 0x69: dev->pci_conf[addr] &= ~val; break; + case 0x70 ... 0x77: + if (dev->type & 1) + spd_write_drbs(dev->pci_conf, 0x70, 0x77, 2); + break; + case 0x78: + case 0x7c ... 0x7e: + if (dev->type & 1) + dev->pci_conf[addr] = val; + break; + case 0x79: + if (dev->type & 1) { + spd_write_drbs(dev->pci_conf, 0xf8, 0xff, 4); + dev->pci_conf[addr] = 0x00; + for (uint8_t i = 0; i < 8; i++) + if (dev->pci_conf[0xf8 + i] & 0x80) dev->pci_conf[addr] |= (1 << i); + } + break; + case 0x7a: + if (dev->type & 1) + dev->pci_conf[addr] = val & 0xfe; + break; + case 0x7b: + if (dev->type & 1) + dev->pci_conf[addr] = val & 0xe0; + break; default: break; @@ -235,14 +313,33 @@ sis_85c50x_read(int func, int addr, void *priv) const sis_85c50x_t *dev = (sis_85c50x_t *) priv; uint8_t ret = 0xff; - if (func == 0x00) - ret = dev->pci_conf[addr]; + if (func == 0x00) { + if (addr >= 0xf8) + ret = 0x00; + else + ret = dev->pci_conf[addr]; + } sis_85c50x_log("85C501: [R] (%02X, %02X) = %02X\n", func, addr, ret); return ret; } +static void +sis_85c50x_ide_recalc(sis_85c50x_t *dev) +{ + ide_pri_disable(); + ide_set_base(0, (dev->pci_conf_ide[0x40] & 0x80) ? 0x0170 : 0x01f0); + ide_set_side(0, (dev->pci_conf_ide[0x40] & 0x80) ? 0x0376 : 0x03f6); + ide_pri_enable(); + + ide_sec_disable(); + ide_set_base(1, (dev->pci_conf_ide[0x40] & 0x80) ? 0x01f0 : 0x0170); + ide_set_side(1, (dev->pci_conf_ide[0x40] & 0x80) ? 0x03f6 : 0x0376); + if (dev->pci_conf_ide[0x41] & 0x01) + ide_sec_enable(); +} + static void sis_85c50x_sb_write(int func, int addr, uint8_t val, void *priv) { @@ -250,38 +347,46 @@ sis_85c50x_sb_write(int func, int addr, uint8_t val, void *priv) sis_85c50x_log("85C503: [W] (%02X, %02X) = %02X\n", func, addr, val); - if (func == 0x00) - switch (addr) { - case 0x04: /* Command */ - dev->pci_conf_sb[addr] = val & 0x0f; - break; - case 0x07: /* Status */ - dev->pci_conf_sb[addr] &= ~(val & 0x30); - break; - case 0x40: /* BIOS Control Register */ - dev->pci_conf_sb[addr] = val & 0x3f; - break; - case 0x41: - case 0x42: - case 0x43: - case 0x44: - /* INTA/B/C/D# Remapping Control Register */ - dev->pci_conf_sb[addr] = val & 0x8f; - if (val & 0x80) - pci_set_irq_routing(PCI_INTA + (addr - 0x41), PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTA + (addr - 0x41), val & 0xf); - break; - case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ - case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ - case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ - case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ - dev->pci_conf_sb[addr] = val; - break; + if (func == 0x00) switch (addr) { + case 0x04: /* Command */ + dev->pci_conf_sb[addr] = val & 0x0f; + break; + case 0x07: /* Status */ + dev->pci_conf_sb[addr] &= ~(val & 0x30); + break; + case 0x40: /* BIOS Control Register */ + dev->pci_conf_sb[addr] = val & 0x3f; + break; + case 0x41: + case 0x42: + case 0x43: + case 0x44: + /* INTA/B/C/D# Remapping Control Register */ + dev->pci_conf_sb[addr] = val & 0x8f; + if (val & 0x80) + pci_set_irq_routing(PCI_INTA + (addr - 0x41), PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTA + (addr - 0x41), val & 0xf); + break; + case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ + case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ + case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ + case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ + dev->pci_conf_sb[addr] = val; + break; - default: - break; - } + default: + break; + } else if ((dev->type & 2) && !(dev->regs[0x81] & 0x02) && (func == 0x01)) switch (addr) { + case 0x40: + case 0x41: + dev->pci_conf_ide[addr] = val; + sis_85c50x_ide_recalc(dev); + break; + + default: + break; + } } static uint8_t @@ -290,8 +395,42 @@ sis_85c50x_sb_read(int func, int addr, void *priv) const sis_85c50x_t *dev = (sis_85c50x_t *) priv; uint8_t ret = 0xff; - if (func == 0x00) - ret = dev->pci_conf_sb[addr]; + if (func == 0x00) switch (addr) { + default: + ret = dev->pci_conf_sb[addr]; + break; + case 0x4c ... 0x4f: + if (dev->type & 2) + ret = pic_read_icw(0, addr & 0x03); + else + ret = dev->pci_conf_sb[addr]; + break; + case 0x50 ... 0x53: + if (dev->type & 2) + ret = pic_read_icw(1, addr & 0x03); + else + ret = dev->pci_conf_sb[addr]; + break; + case 0x54 ... 0x55: + if (dev->type & 2) + ret = pic_read_ocw(0, addr & 0x01); + else + ret = dev->pci_conf_sb[addr]; + break; + case 0x56 ... 0x57: + if (dev->type & 2) + ret = pic_read_ocw(1, addr & 0x01); + else + ret = dev->pci_conf_sb[addr]; + break; + case 0x58 ... 0x5f: + if (dev->type & 2) + ret = dev->pit_read_reg(dev->pit, addr & 0x07); + else + ret = dev->pci_conf_sb[addr]; + break; + } else if ((dev->type & 2) && !(dev->regs[0x81] & 0x02) && (func == 0x01)) + ret = dev->pci_conf_ide[addr]; sis_85c50x_log("85C503: [W] (%02X, %02X) = %02X\n", func, addr, ret); @@ -313,10 +452,39 @@ sis_85c50x_isa_write(uint16_t addr, uint8_t val, void *priv) case 0x23: switch (dev->index) { case 0x80: - dev->regs[dev->index] = val & 0xe7; + if (dev->type & 2) { + dev->regs[dev->index] = val; + nvr_bank_set(0, !!(val & 0x08), dev->nvr); + } else + dev->regs[dev->index] = val & 0xe7; + switch (val >> 6) { + case 0: + cpu_set_isa_speed(7159091); + break; + case 1: + cpu_set_isa_pci_div(4); + break; + case 2: + cpu_set_isa_pci_div(3); + break; + + default: + break; + } break; case 0x81: - dev->regs[dev->index] = val & 0xf4; + if (dev->type & 2) + dev->regs[dev->index] = val & 0xf6; + else + dev->regs[dev->index] = val & 0xf4; + break; + case 0x82: + if (dev->type & 2) + dev->regs[dev->index] = val; + break; + case 0x83: + if (dev->type & 2) + dev->regs[dev->index] = val & 0x03; break; case 0x84: case 0x88: @@ -394,6 +562,12 @@ sis_85c50x_reset(void *priv) sis_85c50x_write(0, 0x68, 0x00, dev); sis_85c50x_write(0, 0x69, 0xff, dev); + if (dev->type & 1) { + for (uint8_t i = 0; i < 8; i++) + dev->pci_conf[0x70 + i] = 0x00; + dev->pci_conf[0x79] = 0x00; + } + /* South Bridge (SiS 85C503) */ dev->pci_conf_sb[0x00] = 0x39; dev->pci_conf_sb[0x01] = 0x10; @@ -407,10 +581,51 @@ sis_85c50x_reset(void *priv) dev->pci_conf_sb[0x09] = 0x00; dev->pci_conf_sb[0x0a] = 0x01; dev->pci_conf_sb[0x0b] = 0x06; + if (dev->type & 2) + dev->pci_conf_sb[0x0e] = 0x80; sis_85c50x_sb_write(0, 0x41, 0x80, dev); sis_85c50x_sb_write(0, 0x42, 0x80, dev); sis_85c50x_sb_write(0, 0x43, 0x80, dev); sis_85c50x_sb_write(0, 0x44, 0x80, dev); + + if (dev->type & 2) { + /* IDE (SiS 5503) */ + dev->pci_conf_ide[0x00] = 0x39; + dev->pci_conf_ide[0x01] = 0x10; + dev->pci_conf_ide[0x02] = 0x01; + dev->pci_conf_ide[0x03] = 0x06; + dev->pci_conf_ide[0x04] = 0x89; + dev->pci_conf_ide[0x05] = 0x00; + dev->pci_conf_ide[0x06] = 0x00; + dev->pci_conf_ide[0x07] = 0x00; + dev->pci_conf_ide[0x08] = 0x00; + dev->pci_conf_ide[0x09] = 0x00; + dev->pci_conf_ide[0x0a] = 0x01; + dev->pci_conf_ide[0x0b] = 0x01; + dev->pci_conf_ide[0x0c] = 0x00; + dev->pci_conf_ide[0x0d] = 0x00; + dev->pci_conf_ide[0x0e] = 0x80; + dev->pci_conf_ide[0x0f] = 0x00; + dev->pci_conf_ide[0x10] = 0x71; + dev->pci_conf_ide[0x11] = 0x01; + dev->pci_conf_ide[0x14] = 0xf1; + dev->pci_conf_ide[0x15] = 0x01; + dev->pci_conf_ide[0x18] = 0x71; + dev->pci_conf_ide[0x19] = 0x03; + dev->pci_conf_ide[0x1c] = 0xf1; + dev->pci_conf_ide[0x1d] = 0x03; + dev->pci_conf_ide[0x20] = 0x01; + dev->pci_conf_ide[0x24] = 0x01; + dev->pci_conf_ide[0x40] = 0x00; + dev->pci_conf_ide[0x41] = 0x40; + + sis_85c50x_ide_recalc(dev); + } + + cpu_set_isa_speed(7159091); + + if (dev->type & 2) + nvr_bank_set(0, 0, dev->nvr); } static void @@ -426,8 +641,10 @@ sis_85c50x_close(void *priv) static void * sis_85c50x_init(UNUSED(const device_t *info)) { - sis_85c50x_t *dev = (sis_85c50x_t *) malloc(sizeof(sis_85c50x_t)); - memset(dev, 0x00, sizeof(sis_85c50x_t)); + sis_85c50x_t *dev = (sis_85c50x_t *) calloc(1, sizeof(sis_85c50x_t)); + uint8_t pit_is_fast = (((pit_mode == -1) && is486) || (pit_mode == 1)); + + dev->type = info->local; /* 501/502 (Northbridge) */ pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c50x_read, sis_85c50x_write, dev, &dev->nb_slot); @@ -441,6 +658,17 @@ sis_85c50x_init(UNUSED(const device_t *info)) dev->port_92 = device_add(&port_92_device); + if (dev->type & 2) { + /* PIT */ + dev->pit = device_find_first_priv(DEVICE_PIT); + dev->pit_read_reg = pit_is_fast ? pitf_read_reg : pit_read_reg; + + /* NVR */ + dev->nvr = device_add(&at_mb_nvr_device); + + device_add(&ide_pci_2ch_device); + } + sis_85c50x_reset(dev); return dev; @@ -459,3 +687,45 @@ const device_t sis_85c50x_device = { .force_redraw = NULL, .config = NULL }; + +const device_t sis_550x_85c503_device = { + .name = "SiS 550x", + .internal_name = "sis_550x", + .flags = DEVICE_PCI, + .local = 1, + .init = sis_85c50x_init, + .close = sis_85c50x_close, + .reset = sis_85c50x_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_85c50x_5503_device = { + .name = "SiS 85C50x", + .internal_name = "sis_85c50x", + .flags = DEVICE_PCI, + .local = 2, + .init = sis_85c50x_init, + .close = sis_85c50x_close, + .reset = sis_85c50x_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_550x_device = { + .name = "SiS 550x", + .internal_name = "sis_550x", + .flags = DEVICE_PCI, + .local = 3, + .init = sis_85c50x_init, + .close = sis_85c50x_close, + .reset = sis_85c50x_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/umc_8886.c b/src/chipset/umc_8886.c index f6a923346..7a049b1cb 100644 --- a/src/chipset/umc_8886.c +++ b/src/chipset/umc_8886.c @@ -79,17 +79,14 @@ #include <86box/timer.h> #include <86box/io.h> #include <86box/device.h> - #include <86box/hdd.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/pic.h> #include <86box/pci.h> - +#include <86box/port_92.h> #include <86box/chipset.h> -#define IDE_BIT 0x01 - #ifdef ENABLE_UMC_8886_LOG int umc_8886_do_log = ENABLE_UMC_8886_LOG; @@ -108,18 +105,6 @@ umc_8886_log(const char *fmt, ...) # define umc_8886_log(fmt, ...) #endif -/* PCI IRQ Flags */ -#define INTA (PCI_INTA + (2 * !(addr & 1))) -#define INTB (PCI_INTB + (2 * !(addr & 1))) -#define IRQRECALCA (((val & 0xf0) != 0) ? ((val & 0xf0) >> 4) : PCI_IRQ_DISABLED) -#define IRQRECALCB (((val & 0x0f) != 0) ? (val & 0x0f) : PCI_IRQ_DISABLED) - -/* Disable Internal IDE Flag needed for the AF or BF Southbridge variant */ -#define HAS_IDE dev->has_ide - -/* Southbridge Revision */ -#define SB_ID dev->sb_id - typedef struct umc_8886_t { uint8_t max_func; /* Last function number */ uint8_t pci_slot; @@ -128,19 +113,24 @@ typedef struct umc_8886_t { uint8_t pci_conf_sb[2][256]; /* PCI Registers */ - uint16_t sb_id; /* Southbridge Revision */ - int has_ide; /* Check if Southbridge Revision is AF or F */ + uint16_t sb_id; /* Southbridge Revision */ + uint16_t ide_id; /* IDE Revision */ + + int has_ide; /* Check if Southbridge Revision is F, AF, or BF */ } umc_8886_t; static void -umc_8886_ide_handler(int status) +umc_8886_ide_handler(umc_8886_t *dev) { ide_pri_disable(); ide_sec_disable(); - if (status) { - ide_pri_enable(); - ide_sec_enable(); + if (dev->pci_conf_sb[1][0x04] & 0x01) { + if (dev->pci_conf_sb[1][0x40] & 0x80) + ide_pri_enable(); + + if (dev->pci_conf_sb[1][0x40] & 0x40) + ide_sec_enable(); } } @@ -148,6 +138,7 @@ static void umc_8886_write(int func, int addr, uint8_t val, void *priv) { umc_8886_t *dev = (umc_8886_t *) priv; + int irq_routing; if (func <= dev->max_func) switch (func) { @@ -155,8 +146,17 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) umc_8886_log("UM8886: dev->regs[%02x] = %02x POST %02x\n", addr, val, inb(0x80)); switch (addr) { - case 0x04: - case 0x05: + case 0x04 ... 0x05: + case 0x0c ... 0x0d: + case 0x40 ... 0x42: + case 0x45: + case 0x50 ... 0x55: + case 0x57: + case 0x70 ... 0x76: + case 0x80 ... 0x82: + case 0x90 ... 0x92: + case 0xa0 ... 0xa1: + case 0xa5 ... 0xa8: dev->pci_conf_sb[func][addr] = val; break; @@ -164,46 +164,31 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf_sb[func][addr] &= ~(val & 0xf9); break; - case 0x0c: - case 0x0d: - dev->pci_conf_sb[func][addr] = val; - break; - - case 0x40: - case 0x41: - case 0x42: - dev->pci_conf_sb[func][addr] = val; - break; - case 0x43: + dev->pci_conf_sb[func][addr] = val; + irq_routing = (dev->pci_conf_sb[func][0x46] & 0x01) ? (val >> 8) : + PCI_IRQ_DISABLED; + pci_set_irq_routing(PCI_INTA, irq_routing); + irq_routing = (dev->pci_conf_sb[func][0x46] & 0x02) ? (val & 0x0f) : + PCI_IRQ_DISABLED; + pci_set_irq_routing(PCI_INTB, irq_routing); + break; case 0x44: dev->pci_conf_sb[func][addr] = val; - pci_set_irq_routing(INTA, IRQRECALCA); - pci_set_irq_routing(INTB, IRQRECALCB); + irq_routing = (dev->pci_conf_sb[func][0x46] & 0x04) ? (val >> 8) : + PCI_IRQ_DISABLED; + pci_set_irq_routing(PCI_INTC, irq_routing); + irq_routing = (dev->pci_conf_sb[func][0x46] & 0x08) ? (val & 0x0f) : + PCI_IRQ_DISABLED; + pci_set_irq_routing(PCI_INTD, irq_routing); break; - case 0x45: - dev->pci_conf_sb[func][addr] = val; - break; - - case 0x46: + case 0x46: /* Bits 3-0 = 0 = IRQ disabled, 1 = IRQ enabled. */ + case 0x47: /* Bits 3-0 = 0 = IRQ edge-triggered, 1 = IRQ level-triggered. */ /* Bit 6 seems to be the IRQ/SMI# toggle, 1 = IRQ, 0 = SMI#. */ dev->pci_conf_sb[func][addr] = val; break; - case 0x47: - dev->pci_conf_sb[func][addr] = val; - break; - - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - dev->pci_conf_sb[func][addr] = val; - break; - case 0x56: dev->pci_conf_sb[func][addr] = val; @@ -220,16 +205,6 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) default: break; } - - break; - - case 0x57: - case 0x70 ... 0x76: - case 0x80: - case 0x81: - case 0x90 ... 0x92: - case 0xa0 ... 0xa1: - dev->pci_conf_sb[func][addr] = val; break; case 0xa2: @@ -243,7 +218,6 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) picint(1 << ((dev->pci_conf_sb[0][0x46] & 0x80) ? 15 : 10)); else smi_raise(); - dev->pci_conf_sb[0][0xa3] |= 0x04; } dev->pci_conf_sb[func][addr] = val; @@ -254,10 +228,6 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) cpu_set_pci_speed(cpu_busspeed / ((val & 1) ? 1 : 2)); break; - case 0xa5 ... 0xa8: - dev->pci_conf_sb[func][addr] = val; - break; - default: break; } @@ -269,7 +239,8 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) switch (addr) { case 0x04: dev->pci_conf_sb[func][addr] = val; - umc_8886_ide_handler(val & 1); + if (dev->ide_id == 0x673a) + umc_8886_ide_handler(dev); break; case 0x07: @@ -277,9 +248,17 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) break; case 0x3c: + case 0x41 ... 0x4b: + case 0x54 ... 0x59: + if (dev->ide_id == 0x673a) + dev->pci_conf_sb[func][addr] = val; + break; + case 0x40: - case 0x41: - dev->pci_conf_sb[func][addr] = val; + if (dev->ide_id == 0x673a) { + dev->pci_conf_sb[func][addr] = val; + umc_8886_ide_handler(dev); + } break; default: @@ -311,47 +290,73 @@ umc_8886_reset(void *priv) memset(dev->pci_conf_sb[0], 0x00, sizeof(dev->pci_conf_sb[0])); memset(dev->pci_conf_sb[1], 0x00, sizeof(dev->pci_conf_sb[1])); - dev->pci_conf_sb[0][0] = 0x60; /* UMC */ - dev->pci_conf_sb[0][1] = 0x10; - - dev->pci_conf_sb[0][2] = (SB_ID & 0xff); /* 8886xx */ - dev->pci_conf_sb[0][3] = ((SB_ID >> 8) & 0xff); - - dev->pci_conf_sb[0][4] = 0x0f; - dev->pci_conf_sb[0][7] = 2; - - dev->pci_conf_sb[0][8] = 0x0e; - + dev->pci_conf_sb[0][0x00] = 0x60; /* UMC */ + dev->pci_conf_sb[0][0x01] = 0x10; + dev->pci_conf_sb[0][0x02] = (dev->sb_id & 0xff); /* 8886xx */ + dev->pci_conf_sb[0][0x03] = ((dev->sb_id >> 8) & 0xff); + dev->pci_conf_sb[0][0x04] = 0x0f; + dev->pci_conf_sb[0][0x07] = 0x02; + dev->pci_conf_sb[0][0x08] = 0x0e; dev->pci_conf_sb[0][0x09] = 0x00; dev->pci_conf_sb[0][0x0a] = 0x01; dev->pci_conf_sb[0][0x0b] = 0x06; - - dev->pci_conf_sb[0][0x40] = 1; - dev->pci_conf_sb[0][0x41] = 6; - dev->pci_conf_sb[0][0x42] = 8; - dev->pci_conf_sb[0][0x43] = 0x9a; - dev->pci_conf_sb[0][0x44] = 0xbc; - dev->pci_conf_sb[0][0x45] = 4; + dev->pci_conf_sb[0][0x40] = 0x01; + dev->pci_conf_sb[0][0x41] = 0x06; + dev->pci_conf_sb[0][0x42] = 0x08; + dev->pci_conf_sb[0][0x43] = 0x00; + dev->pci_conf_sb[0][0x44] = 0x00; + dev->pci_conf_sb[0][0x45] = 0x04; + dev->pci_conf_sb[0][0x46] = 0x00; dev->pci_conf_sb[0][0x47] = 0x40; - dev->pci_conf_sb[0][0x50] = 1; - dev->pci_conf_sb[0][0x51] = 3; + dev->pci_conf_sb[0][0x50] = 0x01; + dev->pci_conf_sb[0][0x51] = 0x03; + dev->pci_conf_sb[0][0x56] = dev->pci_conf_sb[0][0x57] = 0x00; + dev->pci_conf_sb[0][0x70] = dev->pci_conf_sb[0][0x71] = 0x00; + dev->pci_conf_sb[0][0x72] = dev->pci_conf_sb[0][0x73] = 0x00; + dev->pci_conf_sb[0][0x74] = dev->pci_conf_sb[0][0x76] = 0x00; + dev->pci_conf_sb[0][0x82] = 0x00; + dev->pci_conf_sb[0][0x90] = dev->pci_conf_sb[0][0x91] = 0x00; + dev->pci_conf_sb[0][0xa0] = dev->pci_conf_sb[0][0xa2] = 0x00; + dev->pci_conf_sb[0][0xa4] = 0x00; dev->pci_conf_sb[0][0xa8] = 0x20; - if (HAS_IDE) { - dev->pci_conf_sb[1][0] = 0x60; /* UMC */ - dev->pci_conf_sb[1][1] = 0x10; + if (dev->has_ide) { + dev->pci_conf_sb[1][0x00] = 0x60; /* UMC */ + dev->pci_conf_sb[1][0x01] = 0x10; + dev->pci_conf_sb[1][0x02] = (dev->ide_id & 0xff); /* 8886xx IDE */ + dev->pci_conf_sb[1][0x03] = ((dev->ide_id >> 8) & 0xff); + dev->pci_conf_sb[1][0x04] = 0x05; /* Start with Internal IDE Enabled */ + dev->pci_conf_sb[1][0x08] = 0x10; + dev->pci_conf_sb[1][0x09] = 0x8f; + dev->pci_conf_sb[1][0x0a] = dev->pci_conf_sb[1][0x0b] = 0x01; + dev->pci_conf_sb[1][0x10] = 0xf1; + dev->pci_conf_sb[1][0x11] = 0x01; + dev->pci_conf_sb[1][0x14] = 0xf5; + dev->pci_conf_sb[1][0x15] = 0x03; + dev->pci_conf_sb[1][0x18] = 0x71; + dev->pci_conf_sb[1][0x19] = 0x01; + dev->pci_conf_sb[1][0x1c] = 0x75; + dev->pci_conf_sb[1][0x1d] = 0x03; + dev->pci_conf_sb[1][0x20] = 0x01; + dev->pci_conf_sb[1][0x21] = 0x10; - dev->pci_conf_sb[1][2] = 0x3a; /* 8886BF IDE */ - dev->pci_conf_sb[1][3] = 0x67; + if (dev->ide_id == 0x673a) { + dev->pci_conf_sb[1][0x40] = 0xc0; + dev->pci_conf_sb[1][0x41] = 0x00; + dev->pci_conf_sb[1][0x42] = dev->pci_conf_sb[1][0x43] = 0x00; + dev->pci_conf_sb[1][0x44] = dev->pci_conf_sb[1][0x45] = 0x00; + dev->pci_conf_sb[1][0x46] = dev->pci_conf_sb[1][0x47] = 0x00; + dev->pci_conf_sb[1][0x48] = dev->pci_conf_sb[1][0x49] = 0x00; + dev->pci_conf_sb[1][0x4a] = dev->pci_conf_sb[1][0x4b] = 0x00; + dev->pci_conf_sb[1][0x54] = dev->pci_conf_sb[1][0x55] = 0x00; + dev->pci_conf_sb[1][0x56] = dev->pci_conf_sb[1][0x57] = 0x00; + dev->pci_conf_sb[1][0x58] = dev->pci_conf_sb[1][0x59] = 0x00; - dev->pci_conf_sb[1][4] = 1; /* Start with Internal IDE Enabled */ + umc_8886_ide_handler(dev); - dev->pci_conf_sb[1][8] = 0x10; - - dev->pci_conf_sb[1][0x09] = 0x0f; - dev->pci_conf_sb[1][0x0a] = dev->pci_conf_sb[1][0x0b] = 1; - - umc_8886_ide_handler(1); + picintc(1 << 14); + picintc(1 << 15); + } } for (uint8_t i = 1; i < 5; i++) /* Disable all IRQ interrupts */ @@ -375,17 +380,28 @@ umc_8886_init(const device_t *info) umc_8886_t *dev = (umc_8886_t *) malloc(sizeof(umc_8886_t)); memset(dev, 0, sizeof(umc_8886_t)); - dev->has_ide = !!(info->local == 0x886a); - pci_add_card(PCI_ADD_SOUTHBRIDGE, umc_8886_read, umc_8886_write, dev, &dev->pci_slot); /* Device 12: UMC 8886xx */ - - /* Add IDE if UM8886AF variant */ - if (HAS_IDE) - device_add(&ide_pci_2ch_device); - - dev->max_func = (HAS_IDE) ? 1 : 0; + /* Device 12: UMC 8886xx */ + pci_add_card(PCI_ADD_SOUTHBRIDGE, umc_8886_read, umc_8886_write, dev, &dev->pci_slot); /* Get the Southbridge Revision */ - SB_ID = info->local; + dev->sb_id = info->local & 0xffff; + + /* IDE Revision */ + dev->ide_id = info->local >> 16; + + dev->has_ide = (dev->ide_id != 0x0000); + + dev->max_func = 0; + + /* Add IDE if this is the UM8886AF or UM8886BF. */ + if (dev->ide_id == 0x673a) { + /* UM8886BF */ + device_add(&ide_pci_2ch_device); + dev->max_func = 1; + } else if (dev->ide_id == 0x1001) { + /* UM8886AF */ + device_add(&ide_um8673f_device); + } umc_8886_reset(dev); @@ -396,7 +412,7 @@ const device_t umc_8886f_device = { .name = "UMC 8886F", .internal_name = "umc_8886f", .flags = DEVICE_PCI, - .local = 0x8886, + .local = 0x00008886, .init = umc_8886_init, .close = umc_8886_close, .reset = umc_8886_reset, @@ -407,10 +423,24 @@ const device_t umc_8886f_device = { }; const device_t umc_8886af_device = { - .name = "UMC 8886AF/8886BF", + .name = "UMC 8886AF", .internal_name = "umc_8886af", .flags = DEVICE_PCI, - .local = 0x886a, + .local = 0x1001886a, + .init = umc_8886_init, + .close = umc_8886_close, + .reset = umc_8886_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t umc_8886bf_device = { + .name = "UMC 8886BF", + .internal_name = "umc_8886bf", + .flags = DEVICE_PCI, + .local = 0x673a888a, .init = umc_8886_init, .close = umc_8886_close, .reset = umc_8886_reset, diff --git a/src/chipset/umc_8890.c b/src/chipset/umc_8890.c new file mode 100644 index 000000000..d515e1c97 --- /dev/null +++ b/src/chipset/umc_8890.c @@ -0,0 +1,241 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the UMC 8890 Chipset. + * + * Note: This chipset has no datasheet, everything were done via + * reverse engineering the BIOS of various machines using it. + * + * Authors: Tiseno100, + * Miran Grca, + * + * Copyright 2021 Tiseno100. + * Copyright 2021-2024 Miran Grca. + */ + +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> + +#include <86box/apm.h> +#include <86box/mem.h> +#include <86box/pci.h> +#include <86box/port_92.h> +#include <86box/smram.h> + +#include <86box/chipset.h> + +#ifdef ENABLE_UMC_8890_LOG +int umc_8890_do_log = ENABLE_UMC_8890_LOG; + +static void +umc_8890_log(const char *fmt, ...) +{ + va_list ap; + + if (umc_8890_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define umc_8890_log(fmt, ...) +#endif + +typedef struct umc_8890_t { + uint8_t pci_slot; + + uint8_t pci_conf[256]; /* PCI Registers */ + + int mem_state[2]; + + uint32_t smram_base; + + smram_t *smram; /* SMRAM Handler */ +} umc_8890_t; + +static void +um8890_shadow(umc_8890_t *dev) +{ + uint8_t flag; + uint16_t state; + + flag = (dev->pci_conf[0x5f] & 0x0c) >> 2; + state = (flag & 1) ? (MEM_READ_INTERNAL | ((flag & 2) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)) : + (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + + if ((dev->mem_state[1] ^ dev->pci_conf[0x5f]) & 0x0c) { + mem_set_mem_state_both(0xe0000, 0x10000, state); + dev->mem_state[1] = (dev->mem_state[2] & 0xf0) | (dev->pci_conf[0x5f] & 0x0f); + } + + flag = (dev->pci_conf[0x5f] & 0xc0) >> 6; + state = (flag & 1) ? (MEM_READ_INTERNAL | ((flag & 2) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)) : + (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + + if ((dev->mem_state[1] ^ dev->pci_conf[0x5f]) & 0xc0) { + mem_set_mem_state_both(0xf0000, 0x10000, state); + dev->mem_state[1] = (dev->mem_state[1] & 0x0f) | (dev->pci_conf[0x5f] & 0xf0); + } + + for (uint8_t i = 0; i < 8; i++) { + state = (dev->pci_conf[0x5d] & (1 << i)) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : + (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + + if ((dev->mem_state[0] ^ dev->pci_conf[0x5d]) & (1 << i)) { + mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, state); + dev->mem_state[0] = (dev->mem_state[0] & ~(1 << i)) | (dev->pci_conf[0x5d] & (1 << i)); + } + } + + flushmmucache_nopc(); +} + + +static void +um8890_smram(umc_8890_t *dev) +{ + smram_disable_all(); + + /* Bit 4, if set, enables SMRAM access outside SMM. SMRAM appears to be always enabled + in SMM, and is always set to A0000-BFFFF. */ + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x20000, dev->pci_conf[0x65] & 0x10, 1); +} + +static void +um8890_write(int func, int addr, uint8_t val, void *priv) +{ + umc_8890_t *dev = (umc_8890_t *)priv; + + if (func == 0) switch (addr) { + case 0x04 ... 0x05: + case 0x0c ... 0x0d: + case 0x40 ... 0x5b: + case 0x60 ... 0x63: + case 0x66 ... 0xff: + dev->pci_conf[addr] = val; + break; + + case 0x07: + dev->pci_conf[addr] &= ~(val & 0xf9); + break; + + case 0x5c ... 0x5f: + dev->pci_conf[addr] = val; + um8890_shadow(dev); + break; + + /* Register 64h, 16-bit: + Bit 12: SMRAM enabled outside SMM (1 = yes, 0 = no); + Bit 10: ???? (set by Award BIOS); + Bits 7- 0: SMM handler offset to SMBASE, shifted to the right by 14. + */ + case 0x64: case 0x65: + dev->pci_conf[addr] = val; + if (addr == 0x65) + um8890_smram(dev); + break; + } + + umc_8890_log("UM8890: dev->regs[%02x] = %02x POST: %02x\n", addr, dev->pci_conf[addr], inb(0x80)); +} + + +static uint8_t +um8890_read(int func, int addr, void *priv) +{ + umc_8890_t *dev = (umc_8890_t *)priv; + uint8_t ret = 0xff; + + if (func == 0) + ret = dev->pci_conf[addr]; + + return ret; +} + +static void +umc_8890_reset(void *priv) +{ + umc_8890_t *dev = (umc_8890_t *)priv; + + memset(dev->pci_conf, 0x00, sizeof(dev->pci_conf)); + + /* Defaults */ + dev->pci_conf[0x00] = 0x60; /* UMC */ + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x91; /* 8891F */ + dev->pci_conf[0x03] = 0x88; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = 0x01; + dev->pci_conf[0x09] = 0x00; + dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x5c] = 0x00; + dev->pci_conf[0x5d] = 0x00; + dev->pci_conf[0x5e] = 0x00; + dev->pci_conf[0x5f] = 0x00; + dev->pci_conf[0x64] = 0x00; + dev->pci_conf[0x65] = 0x00; + + um8890_shadow(dev); + + um8890_smram(dev); +} + + +static void +umc_8890_close(void *priv) +{ + umc_8890_t *dev = (umc_8890_t *)priv; + + smram_del(dev->smram); + free(dev); +} + + +static void * +umc_8890_init(const device_t *info) +{ + umc_8890_t *dev = (umc_8890_t *) calloc(1, sizeof(umc_8890_t)); + + /* Device 0: UMC 8890 */ + pci_add_card(PCI_ADD_NORTHBRIDGE, um8890_read, um8890_write, dev, &dev->pci_slot); + + /* Port 92 */ + device_add(&port_92_pci_device); + + dev->smram = smram_add(); + + umc_8890_reset(dev); + + return dev; +} + +const device_t umc_8890_device = { + .name = "UMC 8890(8891BF/8892BF)", + .internal_name = "umc_8890", + .flags = DEVICE_PCI, + .local = 0x886a, + .init = umc_8890_init, + .close = umc_8890_close, + .reset = umc_8890_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/umc_hb4.c b/src/chipset/umc_hb4.c index d5cce0fca..a7ed0b880 100644 --- a/src/chipset/umc_hb4.c +++ b/src/chipset/umc_hb4.c @@ -14,13 +14,11 @@ * Note 2: Additional information were also used from all * around the web. * - * - * * Authors: Tiseno100, * Miran Grca, * * Copyright 2021 Tiseno100. - * Copyright 2021 Miran Grca. + * Copyright 2021-2024 Miran Grca. */ /* @@ -75,15 +73,24 @@ Bit 3: CC000-CFFFF Read Enable Bit 2: C8000-CBFFF Read Enable Bit 1: C0000-C7FFF Read Enable - Bit 0: Enable C0000-DFFFF Shadow Segment Bits + Bit 0: E0000-EFFFF Read Enable Register 55: - Bit 7: E0000-FFFF Read Enable + Bit 7: F0000-FFFF Read Enable Bit 6: Shadow Write Status (1: Write Protect/0: Write) Register 56h & 57h: DRAM Bank 0 Configuration Register 58h & 59h: DRAM Bank 1 Configuration + Register 5A: + Bit 2: Detrubo + + Register 5C: + Bits 7-0: SMRAM base A27-A20 + + Register 5D: + Bits 3-0: SMRAM base A31-A28 + Register 60: Bit 5: If set and SMRAM is enabled, data cycles go to PCI and code cycles go to DRAM Bit 0: SMRAM Local Access Enable - if set, SMRAM is also enabled outside SMM @@ -129,14 +136,15 @@ hb4_log(const char *fmt, ...) #endif typedef struct hb4_t { - uint8_t shadow; - uint8_t shadow_read; - uint8_t shadow_write; uint8_t pci_slot; uint8_t pci_conf[256]; /* PCI Registers */ + int mem_state[9]; - smram_t *smram[3]; /* SMRAM Handlers */ + + uint32_t smram_base; + + smram_t *smram; /* SMRAM Handler */ } hb4_t; static int shadow_bios[4] = { (MEM_READ_EXTANY | MEM_WRITE_INTERNAL), (MEM_READ_EXTANY | MEM_WRITE_EXTANY), @@ -167,7 +175,8 @@ hb4_shadow_bios_low(hb4_t *dev) { int state; - state = shadow_bios[(dev->pci_conf[0x55] >> 6) & (dev->shadow | 0x01)]; + /* Erratum in Vogons' datasheet: Register 55h bit 7 in fact controls E0000-FFFFF. */ + state = shadow_bios[dev->pci_conf[0x55] >> 6]; if (state != dev->mem_state[7]) { mem_set_mem_state_both(0xe0000, 0x10000, state); @@ -185,7 +194,8 @@ hb4_shadow_main(hb4_t *dev) int n = 0; for (uint8_t i = 0; i < 6; i++) { - state = shadow_read[dev->shadow && ((dev->pci_conf[0x54] >> (i + 2)) & 0x01)] | shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01]; + state = shadow_read[(dev->pci_conf[0x54] >> (i + 2)) & 0x01] | + shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01]; if (state != dev->mem_state[i + 1]) { n++; @@ -202,7 +212,8 @@ hb4_shadow_video(hb4_t *dev) { int state; - state = shadow_read[dev->shadow && ((dev->pci_conf[0x54] >> 1) & 0x01)] | shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01]; + state = shadow_read[(dev->pci_conf[0x54] >> 1) & 0x01] | + shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01]; if (state != dev->mem_state[0]) { mem_set_mem_state_both(0xc0000, 0x8000, state); @@ -232,22 +243,26 @@ static void hb4_smram(hb4_t *dev) { smram_disable_all(); + if (dev->smram_base != 0x00000000) + umc_smram_recalc(dev->smram_base >> 12, 0); + + dev->smram_base = ((uint32_t) dev->pci_conf[0x5c]) << 20; + dev->smram_base |= ((uint32_t) (dev->pci_conf[0x5d] & 0x0f)) << 28; + dev->smram_base |= 0x000a0000; /* Bit 0, if set, enables SMRAM access outside SMM. SMRAM appears to be always enabled in SMM, and is always set to A0000-BFFFF. */ - smram_enable(dev->smram[0], 0x000a0000, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1); - /* There's a mirror of the SMRAM at 0E0A0000, mapped to A0000. */ - smram_enable(dev->smram[1], 0x0e0a0000, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1); - /* There's another mirror of the SMRAM at 4E0A0000, mapped to A0000. */ - smram_enable(dev->smram[2], 0x4e0a0000, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1); + smram_enable(dev->smram, dev->smram_base, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1); /* Bit 5 seems to set data to go to PCI and code to DRAM. The Samsung SPC7700P-LW uses this. */ if (dev->pci_conf[0x60] & 0x20) { if (dev->pci_conf[0x60] & 0x01) - mem_set_mem_state_smram_ex(0, 0x000a0000, 0x20000, 0x02); - mem_set_mem_state_smram_ex(1, 0x000a0000, 0x20000, 0x02); + mem_set_mem_state_smram_ex(0, dev->smram_base, 0x20000, 0x02); + mem_set_mem_state_smram_ex(1, dev->smram_base, 0x20000, 0x02); } + + umc_smram_recalc(dev->smram_base >> 12, 1); } static void @@ -278,38 +293,27 @@ hb4_write(UNUSED(int func), int addr, uint8_t val, void *priv) cpu_update_waitstates(); break; - case 0x51: - case 0x52: + case 0x51 ... 0x53: dev->pci_conf[addr] = val; break; - case 0x53: - dev->pci_conf[addr] = val; - hb4_log("HB53: %02X\n", val); - break; - - case 0x55: - dev->shadow_read = (val & 0x80); - dev->shadow_write = (val & 0x40); - dev->pci_conf[addr] = val; - hb4_shadow(dev); - break; - case 0x54: - dev->shadow = (val & 0x01) << 1; + case 0x54 ... 0x55: dev->pci_conf[addr] = val; hb4_shadow(dev); break; - case 0x56 ... 0x5f: + case 0x56 ... 0x5b: + case 0x5e ... 0x5f: dev->pci_conf[addr] = val; break; + case 0x5c ... 0x5d: case 0x60: dev->pci_conf[addr] = val; hb4_smram(dev); break; - case 0x61: + case 0x61 ... 0x62: dev->pci_conf[addr] = val; break; @@ -336,30 +340,35 @@ hb4_reset(void *priv) hb4_t *dev = (hb4_t *) priv; memset(dev->pci_conf, 0x00, sizeof(dev->pci_conf)); - dev->pci_conf[0] = 0x60; /* UMC */ - dev->pci_conf[1] = 0x10; - - dev->pci_conf[2] = 0x81; /* 8881x */ - dev->pci_conf[3] = 0x88; - - dev->pci_conf[7] = 2; - - dev->pci_conf[8] = 4; - + dev->pci_conf[0x00] = 0x60; /* UMC */ + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x81; /* 8881x */ + dev->pci_conf[0x03] = 0x88; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = 0x04; dev->pci_conf[0x09] = 0x00; dev->pci_conf[0x0a] = 0x00; dev->pci_conf[0x0b] = 0x06; - - dev->pci_conf[0x51] = 1; - dev->pci_conf[0x52] = 1; - dev->pci_conf[0x5a] = 4; - dev->pci_conf[0x5c] = 0xc0; + dev->pci_conf[0x50] = 0x00; + dev->pci_conf[0x51] = 0x00; + dev->pci_conf[0x52] = 0x01; + dev->pci_conf[0x53] = 0x00; + dev->pci_conf[0x54] = 0x00; + dev->pci_conf[0x55] = 0x00; + dev->pci_conf[0x56] = 0x00; + dev->pci_conf[0x57] = 0x00; + dev->pci_conf[0x58] = 0x00; + dev->pci_conf[0x59] = 0x00; + dev->pci_conf[0x5a] = 0x04; + dev->pci_conf[0x5c] = 0x00; dev->pci_conf[0x5d] = 0x20; dev->pci_conf[0x5f] = 0xff; + dev->pci_conf[0x60] = 0x00; + dev->pci_conf[0x61] = 0x00; + dev->pci_conf[0x62] = 0x00; - hb4_write(0, 0x54, 0x00, dev); - hb4_write(0, 0x55, 0x00, dev); - hb4_write(0, 0x60, 0x80, dev); + hb4_shadow(dev); + hb4_smram(dev); cpu_cache_ext_enabled = 0; cpu_update_waitstates(); @@ -372,6 +381,7 @@ hb4_close(void *priv) { hb4_t *dev = (hb4_t *) priv; + smram_del(dev->smram); free(dev); } @@ -387,10 +397,9 @@ hb4_init(UNUSED(const device_t *info)) device_add(&port_92_pci_device); /* SMRAM */ - dev->smram[0] = smram_add(); - dev->smram[1] = smram_add(); - dev->smram[2] = smram_add(); + dev->smram = smram_add(); + dev->smram_base = 0x000a0000; hb4_reset(dev); return dev; diff --git a/src/device.c b/src/device.c index 6125674db..b934e7246 100644 --- a/src/device.c +++ b/src/device.c @@ -62,6 +62,7 @@ static device_t *devices[DEVICE_MAX]; static void *device_priv[DEVICE_MAX]; static device_context_t device_current; static device_context_t device_prev; +static void *device_common_priv; #ifdef ENABLE_DEVICE_LOG int device_do_log = ENABLE_DEVICE_LOG; @@ -209,6 +210,16 @@ device_add(const device_t *dev) return device_add_common(dev, dev, NULL, NULL, 0); } +void * +device_add_linked(const device_t *dev, void *priv) +{ + void *ret; + device_common_priv = priv; + ret = device_add_common(dev, dev, NULL, NULL, 0); + device_common_priv = NULL; + return ret; +} + void * device_add_parameters(const device_t *dev, void *params) { @@ -305,6 +316,12 @@ device_cadd_inst_ex_parameters(const device_t *dev, const device_t *cd, void *pr device_add_common(dev, cd, priv, params, inst); } +void * +device_get_common_priv(void) +{ + return device_common_priv; +} + void device_close_all(void) { diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index 24a9d7ac4..9c5705325 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -18,7 +18,7 @@ add_library(dev OBJECT bugger.c cassette.c cartridge.c hasp.c hwm.c hwm_lm75.c hwm_lm78.c hwm_gl518sm.c hwm_vt82c686.c ibm_5161.c isamem.c isartc.c ../lpt.c pci_bridge.c postcard.c serial.c unittester.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c - smbus_piix4.c smbus_ali7101.c keyboard.c keyboard_xt.c + smbus_piix4.c smbus_ali7101.c smbus_sis5595.c keyboard.c keyboard_xt.c kbc_at.c kbc_at_dev.c keyboard_at.c mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c nec_mate_unk.c phoenix_486_jumper.c diff --git a/src/device/pci_bridge.c b/src/device/pci_bridge.c index 8183f8afa..c1f551162 100644 --- a/src/device/pci_bridge.c +++ b/src/device/pci_bridge.c @@ -41,11 +41,13 @@ #define AGP_BRIDGE_VIA_598 0x11068598 #define AGP_BRIDGE_VIA_691 0x11068691 #define AGP_BRIDGE_VIA_8601 0x11068601 +#define AGP_BRIDGE_SIS_5XXX 0x10390001 #define AGP_BRIDGE_ALI(x) (((x) >> 16) == 0x10b9) #define AGP_BRIDGE_INTEL(x) (((x) >> 16) == 0x8086) #define AGP_BRIDGE_VIA(x) (((x) >> 16) == 0x1106) -#define AGP_BRIDGE(x) ((x) >= AGP_BRIDGE_ALI_M5243) +#define AGP_BRIDGE_SIS(x) (((x) >> 16) == 0x1039) +#define AGP_BRIDGE(x) ((x) >= AGP_BRIDGE_SIS_5XXX) typedef struct pci_bridge_t { uint32_t local; @@ -134,6 +136,8 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) val |= 0x02; else if (dev->local == AGP_BRIDGE_ALI_M5247) val &= 0xc3; + else if (AGP_BRIDGE_SIS(dev->local)) + val &= 0x27; else val &= 0x67; break; @@ -194,7 +198,8 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) case 0x22: case 0x24: case 0x26: - val &= 0xf0; + val &= 0xf0; /* SiS datasheets say 0Fh for 1Ch but that's clearly an erratum since the + definition of the bits is identical to the other vendors' AGP bridges. */ break; case 0x3c: @@ -205,6 +210,8 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) case 0x3e: if (AGP_BRIDGE_VIA(dev->local)) val &= 0x0c; + else if (AGP_BRIDGE_SIS(dev->local)) + val &= 0x0e; else if (dev->local == AGP_BRIDGE_ALI_M5247) val &= 0x0f; else if (dev->local == AGP_BRIDGE_ALI_M5243) @@ -668,3 +675,17 @@ const device_t via_vt8601_agp_device = { .force_redraw = NULL, .config = NULL }; + +const device_t sis_5xxx_agp_device = { + .name = "SiS 5591/(5)600 AGP Bridge", + .internal_name = "via_5xxx_agp", + .flags = DEVICE_PCI, + .local = AGP_BRIDGE_SIS_5XXX, + .init = pci_bridge_init, + .close = NULL, + .reset = pci_bridge_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/device/smbus_sis5595.c b/src/device/smbus_sis5595.c new file mode 100644 index 000000000..b76b38e17 --- /dev/null +++ b/src/device/smbus_sis5595.c @@ -0,0 +1,386 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of a generic SiS 5595-compatible SMBus host + * controller. + * + * Authors: RichardG, + * Miran Grca, + * + * Copyright 2020-2021 RichardG. + * Copyright 2021 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/timer.h> +#include <86box/i2c.h> +#include <86box/pci.h> +#include <86box/smbus.h> +#include <86box/plat_fallthrough.h> + +#ifdef ENABLE_SMBUS_SIS5595_LOG +int smbus_sis5595_do_log = ENABLE_SMBUS_SIS5595_LOG; + +static void +smbus_sis5595_log(const char *fmt, ...) +{ + va_list ap; + + if (smbus_sis5595_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define smbus_sis5595_log(fmt, ...) +#endif + +static void +smbus_sis5595_irq(smbus_sis5595_t *dev, int raise) +{ + if (dev->irq_enable) { + if (raise) + pci_set_mirq(6, 1, &dev->irq_state); + else + pci_clear_mirq(6, 1, &dev->irq_state); + } +} + +void +smbus_sis5595_irq_enable(void *priv, uint8_t enable) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + + if (!enable && dev->irq_enable) + pci_clear_mirq(6, 1, &dev->irq_state); + + dev->irq_enable = enable; +} + +uint8_t +smbus_sis5595_read_index(void *priv) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + + return dev->index; +} + +uint8_t +smbus_sis5595_read_data(void *priv) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + uint8_t ret = 0x00; + + switch (dev->index) { + case 0x00: + ret = dev->stat & 0xff; + break; + case 0x01: + ret = dev->stat >> 8; + break; + + case 0x02: + ret = dev->ctl & 0xff; + break; + case 0x03: + ret = dev->ctl >> 8; + break; + + case 0x04: + ret = dev->addr; + break; + + case 0x05: + ret = dev->cmd; + break; + + case 0x06: + ret = dev->block_ptr; + break; + + case 0x07: + ret = dev->count; + break; + + case 0x08 ... 0x0f: + ret = dev->data[(dev->index & 0x07) + (dev->block_ptr << 3)]; + if (dev->index == 0x0f) { + dev->block_ptr = (dev->block_ptr + 1) & 3; + smbus_sis5595_irq(dev, dev->block_ptr != 0x00); + } + break; + + case 0x10: + ret = dev->saved_addr; + break; + + case 0x11: + ret = dev->data0; + break; + + case 0x12: + ret = dev->data1; + break; + + case 0x13: + ret = dev->alias; + break; + + case 0xff: + ret = dev->reg_ff & 0xc0; + break; + + default: + break; + } + + smbus_sis5595_log("SMBus SIS5595: read(%02X) = %02x\n", addr, ret); + + return ret; +} + +void +smbus_sis5595_write_index(void *priv, uint8_t val) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + + dev->index = val; +} + +void +smbus_sis5595_write_data(void *priv, uint8_t val) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + uint8_t smbus_addr; + uint8_t cmd; + uint8_t read; + uint16_t prev_stat; + uint16_t timer_bytes = 0; + + smbus_sis5595_log("SMBus SIS5595: write(%02X, %02X)\n", addr, val); + + prev_stat = dev->next_stat; + dev->next_stat = 0x0000; + switch (dev->index) { + case 0x00: + dev->stat &= ~(val & 0xf0); + /* Make sure IDLE is set if we're not busy or errored. */ + if (dev->stat == 0x04) + dev->stat = 0x00; + break; + case 0x01: + dev->stat &= ~(val & 0x07); + break; + + case 0x02: + dev->ctl = (dev->ctl & 0xff00) | val; + if (val & 0x20) { /* cancel an in-progress command if KILL is set */ + if (prev_stat) { /* cancel only if a command is in progress */ + timer_disable(&dev->response_timer); + dev->stat = 0x80; /* raise FAILED */ + } + } else if (val & 0x10) { + /* dispatch command if START is set */ + timer_bytes++; /* address */ + + smbus_addr = (dev->addr >> 1); + read = dev->addr & 0x01; + + cmd = (dev->ctl >> 1) & 0x7; + smbus_sis5595_log("SMBus SIS5595: addr=%02X read=%d protocol=%X cmd=%02X " + "data0=%02X data1=%02X\n", smbus_addr, read, cmd, dev->cmd, + dev->data0, dev->data1); + + /* Raise DEV_ERR if no device is at this address, or if the device returned + NAK when starting the transfer. */ + if (!i2c_start(i2c_smbus, smbus_addr, read)) { + dev->next_stat = 0x0020; + break; + } + + dev->next_stat = 0x0040; /* raise INTER (command completed) by default */ + + /* Decode the command protocol. */ + dev->block_ptr = 0x01; + switch (cmd) { + case 0x0: /* quick R/W */ + break; + + case 0x1: /* byte R/W */ + if (read) /* byte read */ + dev->data[0] = i2c_read(i2c_smbus, smbus_addr); + else /* byte write */ + i2c_write(i2c_smbus, smbus_addr, dev->data[0]); + timer_bytes++; + + break; + + case 0x2: /* byte data R/W */ + /* command write */ + i2c_write(i2c_smbus, smbus_addr, dev->cmd); + timer_bytes++; + + if (read) /* byte read */ + dev->data[0] = i2c_read(i2c_smbus, smbus_addr); + else /* byte write */ + i2c_write(i2c_smbus, smbus_addr, dev->data[0]); + timer_bytes++; + + break; + + case 0x3: /* word data R/W */ + /* command write */ + i2c_write(i2c_smbus, smbus_addr, dev->cmd); + timer_bytes++; + + if (read) { /* word read */ + dev->data[0] = i2c_read(i2c_smbus, smbus_addr); + dev->data[1] = i2c_read(i2c_smbus, smbus_addr); + } else { /* word write */ + i2c_write(i2c_smbus, smbus_addr, dev->data[0]); + i2c_write(i2c_smbus, smbus_addr, dev->data[1]); + } + timer_bytes += 2; + + break; + + case 0x5: /* block R/W */ + dev->block_ptr = 0x00; + timer_bytes++; /* count the SMBus length byte now */ + fallthrough; + + default: /* unknown */ + dev->next_stat = 0x0010; /* raise DEV_ERR */ + timer_bytes = 0; + break; + } + + /* Finish transfer. */ + i2c_stop(i2c_smbus, smbus_addr); + } + break; + case 0x03: + dev->ctl = (dev->ctl & 0x00ff) | (val << 8); + break; + + case 0x04: + dev->addr = val; + break; + + case 0x05: + dev->cmd = val; + break; + + case 0x08 ... 0x0f: + dev->data[dev->index & 0x07] = val; + break; + + case 0x10: + dev->saved_addr = val; + break; + + case 0x11: + dev->data0 = val; + break; + + case 0x12: + dev->data1 = val; + break; + + case 0x13: + dev->alias = val & 0xfe; + break; + + case 0xff: + dev->reg_ff = val & 0x3f; + break; + + default: + break; + } + + if (dev->next_stat != 0x04) { /* schedule dispatch of any pending status register update */ + dev->stat = 0x08; /* raise HOST_BUSY while waiting */ + timer_disable(&dev->response_timer); + /* delay = ((half clock for start + half clock for stop) + (bytes * (8 bits + ack))) * 60us period measured on real VIA 686B */ + timer_set_delay_u64(&dev->response_timer, (1 + (timer_bytes * 9)) * 60 * TIMER_USEC); + } +} + +static void +smbus_sis5595_response(void *priv) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + + /* Dispatch the status register update. */ + dev->stat = dev->next_stat; +} + +static void +smbus_sis5595_reset(void *priv) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + + timer_disable(&dev->response_timer); + dev->stat = 0x0000; + dev->block_ptr = 0x01; +} + +static void * +smbus_sis5595_init(const device_t *info) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) malloc(sizeof(smbus_sis5595_t)); + memset(dev, 0, sizeof(smbus_sis5595_t)); + + dev->local = info->local; + + /* We save the I2C bus handle on dev but use i2c_smbus for all operations because + dev and therefore dev->i2c will be invalidated if a device triggers a hard reset. */ + i2c_smbus = dev->i2c = i2c_addbus("smbus_sis5595"); + + timer_add(&dev->response_timer, smbus_sis5595_response, dev, 0); + + smbus_sis5595_reset(dev); + + return dev; +} + +static void +smbus_sis5595_close(void *priv) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + + if (i2c_smbus == dev->i2c) + i2c_smbus = NULL; + i2c_removebus(dev->i2c); + + free(dev); +} + +const device_t sis5595_smbus_device = { + .name = "SiS 5595-compatible SMBus Host Controller", + .internal_name = "sis5595_smbus", + .flags = DEVICE_AT, + .local = 0, + .init = smbus_sis5595_init, + .close = smbus_sis5595_close, + .reset = smbus_sis5595_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/disk/CMakeLists.txt b/src/disk/CMakeLists.txt index 00da385d4..310354ccf 100644 --- a/src/disk/CMakeLists.txt +++ b/src/disk/CMakeLists.txt @@ -16,7 +16,7 @@ add_library(hdd OBJECT hdd.c hdd_image.c hdd_table.c hdc.c hdc_st506_xt.c hdc_st506_at.c hdc_xta.c hdc_esdi_at.c hdc_esdi_mca.c hdc_xtide.c hdc_ide.c hdc_ide_ali5213.c hdc_ide_opti611.c hdc_ide_cmd640.c hdc_ide_cmd646.c - hdc_ide_sff8038i.c) + hdc_ide_sff8038i.c hdc_ide_um8673f.c hdc_ide_w83769f.c) add_library(zip OBJECT zip.c) diff --git a/src/disk/hdc_ide_sff8038i.c b/src/disk/hdc_ide_sff8038i.c index 3f43f80e6..631afa931 100644 --- a/src/disk/hdc_ide_sff8038i.c +++ b/src/disk/hdc_ide_sff8038i.c @@ -436,9 +436,9 @@ sff_bus_master_set_irq(uint8_t status, void *priv) case IRQ_MODE_SIS_551X: /* SiS 551x mode. */ if (irq) - pci_set_mirq(2, 1, &dev->irq_state); + pci_set_mirq(dev->mirq, 1, &dev->irq_state); else - pci_clear_mirq(2, 1, &dev->irq_state); + pci_clear_mirq(dev->mirq, 1, &dev->irq_state); break; } } @@ -554,6 +554,12 @@ sff_set_irq_pin(sff8038i_t *dev, int irq_pin) dev->irq_pin = irq_pin; } +void +sff_set_mirq(sff8038i_t *dev, uint8_t mirq) +{ + dev->mirq = mirq; +} + static void sff_close(void *priv) { @@ -586,6 +592,7 @@ sff_init(UNUSED(const device_t *info)) dev->pci_irq_line = 14; dev->irq_level = 0; dev->irq_state = 0; + dev->mirq = 2; dev->channel = next_id; next_id++; diff --git a/src/disk/hdc_ide_um8673f.c b/src/disk/hdc_ide_um8673f.c new file mode 100644 index 000000000..9ee149c7f --- /dev/null +++ b/src/disk/hdc_ide_um8673f.c @@ -0,0 +1,212 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the UMC UMF8673F IDE controller. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> + +#include <86box/hdc_ide.h> +#include <86box/hdc.h> +#include <86box/mem.h> +#include <86box/nmi.h> +#include <86box/pic.h> +#include <86box/pci.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> + +#include <86box/chipset.h> + +#ifdef ENABLE_UM8673F_LOG +int um8673f_do_log = ENABLE_UM8673F_LOG; + +static void +um8673f_log(const char *fmt, ...) +{ + va_list ap; + + if (um8673f_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define um8673f_log(fmt, ...) +#endif + +typedef struct um8673f_t { + uint8_t index; + uint8_t tries; + uint8_t unlocked; + + uint8_t regs[256]; +} um8673f_t; + +static void +um8673f_ide_handler(um8673f_t *dev) +{ + ide_pri_disable(); + ide_sec_disable(); + if (dev->regs[0xb0] & 0x80) + ide_pri_enable(); + if (dev->regs[0xb0] & 0x40) + ide_sec_enable(); +} + +static void +um8673f_write(uint16_t addr, uint8_t val, void *priv) +{ + um8673f_t *dev = (um8673f_t *) priv; + + um8673f_log("[%04X:%08X] [W] %02X = %02X (%i)\n", CS, cpu_state.pc, port, val, dev->tries); + + switch (addr) { + case 0x108: + if (dev->unlocked) { + if (dev->index == 0x34) { + dev->unlocked = 0; + dev->tries = 0; + } else + dev->index = val; + } else if (((dev->tries == 0) && (val == 0x4a)) || + ((dev->tries == 1) && (val == 0x6c))) { + dev->tries++; + if (dev->tries == 2) + dev->unlocked = 1; + } else + dev->tries = 0; + break; + + case 0x109: + switch (dev->index) { + case 0xb0: + dev->regs[dev->index] = val; + um8673f_ide_handler(dev); + break; + case 0xb1 ... 0xb8: + dev->regs[dev->index] = val; + break; + + default: + break; + } + break; + + default: + break; + } +} + +static uint8_t +um8673f_read(uint16_t addr, void *priv) +{ + um8673f_t *dev = (um8673f_t *) priv; + uint8_t ret = 0xff; + + switch (addr) { + case 0x108: + if (dev->unlocked) + ret = dev->index; + else + dev->tries = 0; + break; + case 0x109: + if ((dev->index >= 0xb0) && (dev->index <= 0xb8)) + ret = dev->regs[dev->index]; + break; + + default: + break; + } + + um8673f_log("[%04X:%08X] [R] %02X = %02X\n", CS, cpu_state.pc, port, ret); + + return ret; +} + +static void +um8673f_reset(void *priv) +{ + um8673f_t *dev = (um8673f_t *) priv; + + memset(dev->regs, 0x00, 256); + + ide_pri_disable(); + ide_sec_disable(); + + /* IDE registers */ + dev->regs[0xb0] = 0xc0; + + um8673f_ide_handler(dev); +} + +static void +um8673f_close(void *priv) +{ + um8673f_t *dev = (um8673f_t *) priv; + + free(dev); +} + +static void * +um8673f_init(UNUSED(const device_t *info)) +{ + um8673f_t *dev = (um8673f_t *) calloc(1, sizeof(um8673f_t)); + + io_sethandler(0x0108, 0x0002, um8673f_read, NULL, NULL, um8673f_write, NULL, NULL, dev); + + device_add(info->local ? &ide_pci_2ch_device : &ide_vlb_2ch_device); + + um8673f_reset(dev); + + return dev; +} + +const device_t ide_um8886af_device = { + .name = "UMC UM8886F IDE", + .internal_name = "um8886af_ide", + .flags = 0, + .local = 1, + .init = um8673f_init, + .close = um8673f_close, + .reset = um8673f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_um8673f_device = { + .name = "UMC UM8673F", + .internal_name = "um8673f", + .flags = 0, + .local = 0, + .init = um8673f_init, + .close = um8673f_close, + .reset = um8673f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/disk/hdc_ide_w83769f.c b/src/disk/hdc_ide_w83769f.c new file mode 100644 index 000000000..ed34bc9fc --- /dev/null +++ b/src/disk/hdc_ide_w83769f.c @@ -0,0 +1,460 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Winbond W83769F controller. + * + * Authors: Miran Grca, + * + * Copyright 2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/cdrom.h> +#include <86box/scsi_device.h> +#include <86box/scsi_cdrom.h> +#include <86box/dma.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/keyboard.h> +#include <86box/mem.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/timer.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/zip.h> +#include <86box/mo.h> + +typedef struct w83769f_t { + uint8_t vlb_idx; + uint8_t id; + uint8_t in_cfg; + uint8_t channels; + uint8_t pci; + uint8_t pci_slot; + uint8_t pad; + uint8_t pad0; + uint8_t regs[256]; +} w83769f_t; + +static int next_id = 0; + +#ifdef ENABLE_W83769F_LOG +int w83769f_do_log = ENABLE_W83769F_LOG; + +static void +w83769f_log(const char *fmt, ...) +{ + va_list ap; + + if (cmd640_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define w83769f_log(fmt, ...) +#endif + +void +w83769f_set_irq_0(uint8_t status, void *priv) +{ + w83769f_t *dev = (w83769f_t *) priv; + int irq = !!(status & 0x04); + + if (!(dev->regs[0x50] & 0x04) || (status & 0x04)) + dev->regs[0x50] = (dev->regs[0x50] & ~0x04) | status; + + if (!(dev->channels & 1)) + return; + + if (irq) + picint(1 << 14); + else + picintc(1 << 14); +} + +void +w83769f_set_irq_1(uint8_t status, void *priv) +{ + w83769f_t *dev = (w83769f_t *) priv; + int irq = !!(status & 0x04); + + if (!(dev->regs[0x50] & 0x04) || (status & 0x04)) + dev->regs[0x50] = (dev->regs[0x50] & ~0x04) | status; + + if (!(dev->channels & 2)) + return; + + if (irq) + picint(1 << 15); + else + picintc(1 << 15); +} + +static void +w83769f_ide_handlers(w83769f_t *dev) +{ + if (dev->channels & 0x01) { + ide_pri_disable(); + + if (!dev->pci || (dev->regs[0x04] & 0x01)) + ide_pri_enable(); + } + + if (dev->channels & 0x02) { + ide_sec_disable(); + + if ((!dev->pci || (dev->regs[0x04] & 0x01)) && (dev->regs[0x57] & 0x01)) + ide_sec_enable(); + } +} + +static void +w83769f_common_write(int addr, uint8_t val, w83769f_t *dev) +{ + switch (addr) { + case 0x50: + case 0x57: + dev->regs[0x57] = val & 0x01; + w83769f_ide_handlers(dev); + break; + case 0x51: + dev->regs[addr] = val & 0x7f; + break; + case 0x52: + case 0x54: + case 0x56: + case 0x58 ... 0x59: + dev->regs[addr] = val; + break; + case 0x53: + case 0x55: + dev->regs[addr] = val & 0xcf; + break; + + default: + break; + } +} + +static void +w83769f_vlb_write(uint16_t addr, uint8_t val, void *priv) +{ + w83769f_t *dev = (w83769f_t *) priv; + + switch (addr) { + case 0x0034: + case 0x00b4: + dev->vlb_idx = val; + break; + case 0x0038: + case 0x00b8: + w83769f_common_write(dev->vlb_idx, val, dev); + break; + + default: + break; + } +} + +static void +w83769f_vlb_writew(uint16_t addr, uint16_t val, void *priv) +{ + w83769f_vlb_write(addr, val & 0xff, priv); + w83769f_vlb_write(addr + 1, val >> 8, priv); +} + +static void +w83769f_vlb_writel(uint16_t addr, uint32_t val, void *priv) +{ + w83769f_vlb_writew(addr, val & 0xffff, priv); + w83769f_vlb_writew(addr + 2, val >> 16, priv); +} + +static uint8_t +w83769f_vlb_read(uint16_t addr, void *priv) +{ + uint8_t ret = 0xff; + w83769f_t *dev = (w83769f_t *) priv; + + switch (addr) { + case 0x0034: + case 0x00b4: + ret = dev->vlb_idx; + break; + case 0x0038: + case 0x00b8: + ret = dev->regs[dev->vlb_idx]; + if (dev->vlb_idx == 0x50) + dev->regs[0x50] &= ~0x04; + break; + + default: + break; + } + + return ret; +} + +static uint16_t +w83769f_vlb_readw(uint16_t addr, void *priv) +{ + uint16_t ret = 0xffff; + + ret = w83769f_vlb_read(addr, priv); + ret |= (w83769f_vlb_read(addr + 1, priv) << 8); + + return ret; +} + +static uint32_t +w83769f_vlb_readl(uint16_t addr, void *priv) +{ + uint32_t ret = 0xffffffff; + + ret = w83769f_vlb_readw(addr, priv); + ret |= (w83769f_vlb_readw(addr + 2, priv) << 16); + + return ret; +} + +static void +w83769f_pci_write(int func, int addr, uint8_t val, void *priv) +{ + w83769f_t *dev = (w83769f_t *) priv; + + w83769f_log("w83769f_pci_write(%i, %02X, %02X)\n", func, addr, val); + + if (func == 0x00) + switch (addr) { + case 0x04: + dev->regs[addr] = (dev->regs[addr] & 0xbf) | (val & 0x40); + w83769f_ide_handlers(dev); + break; + case 0x07: + dev->regs[addr] &= ~(val & 0x80); + break; + } +} + +static uint8_t +w83769f_pci_read(int func, int addr, void *priv) +{ + w83769f_t *dev = (w83769f_t *) priv; + uint8_t ret = 0xff; + + if (func == 0x00) + ret = dev->regs[addr]; + + w83769f_log("w83769f_pci_read(%i, %02X, %02X)\n", func, addr, ret); + + return ret; +} + +static void +w83769f_reset(void *priv) +{ + w83769f_t *dev = (w83769f_t *) priv; + int i = 0; + int min_channel; + int max_channel; + + switch (dev->channels) { + default: + case 0x00: + min_channel = max_channel = 0; + break; + case 0x01: + min_channel = 0; + max_channel = 1; + break; + case 0x02: + min_channel = 2; + max_channel = 3; + break; + case 0x03: + min_channel = 0; + max_channel = 3; + break; + } + + for (i = 0; i < CDROM_NUM; i++) { + if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel >= min_channel) && + (cdrom[i].ide_channel <= max_channel) && cdrom[i].priv) + scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv); + } + for (i = 0; i < ZIP_NUM; i++) { + if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel >= min_channel) && + (zip_drives[i].ide_channel <= max_channel) && zip_drives[i].priv) + zip_reset((scsi_common_t *) zip_drives[i].priv); + } + for (i = 0; i < MO_NUM; i++) { + if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel >= min_channel) && + (mo_drives[i].ide_channel <= max_channel) && mo_drives[i].priv) + mo_reset((scsi_common_t *) mo_drives[i].priv); + } + + if (dev->channels & 0x01) + w83769f_set_irq_0(0x00, priv); + + if (dev->channels & 0x02) + w83769f_set_irq_1(0x00, priv); + + memset(dev->regs, 0x00, sizeof(dev->regs)); + + dev->regs[0x50] = (dev->id << 3); /* Device ID: 00 = 60h, 01 = 61h, 10 = 62h, 11 = 63h */ + dev->regs[0x51] = 0x40; + dev->regs[0x57] = 0x01; /* Required by the MSI MS-5109 */ + dev->regs[0x59] = 0x40; + + if (dev->pci) { + dev->regs[0x00] = 0xad; /* Winbond */ + dev->regs[0x01] = 0x10; + dev->regs[0x02] = 0x01; /* W83769 */ + dev->regs[0x03] = 0x00; + dev->regs[0x04] = 0x01; + dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */ + dev->regs[0x08] = 0x02; /* 00h for Rev BB, 02h for Rev A3C */ + dev->regs[0x09] = 0x00; /* Programming interface */ + dev->regs[0x0a] = 0x01; /* IDE controller */ + dev->regs[0x0b] = 0x01; /* Mass storage controller */ + dev->regs[0x3c] = 0x0e; /* IRQ 14 */ + dev->regs[0x3d] = 0x01; /* INTA */ + } else + dev->regs[0x04] = 0x01; /* To make sure the two channels get enabled. */ + + w83769f_ide_handlers(dev); +} + +static void +w83769f_close(void *priv) +{ + w83769f_t *dev = (w83769f_t *) priv; + + free(dev); + + next_id = 0; +} + +static void * +w83769f_init(const device_t *info) +{ + w83769f_t *dev = (w83769f_t *) malloc(sizeof(w83769f_t)); + memset(dev, 0x00, sizeof(w83769f_t)); + + dev->id = next_id | 0x60; + + dev->pci = !!(info->flags & DEVICE_PCI); + + dev->channels = ((info->local & 0x60000) >> 17) & 0x03; + + if (info->flags & DEVICE_PCI) { + device_add(&ide_pci_2ch_device); + + if (info->local & 0x80000) + pci_add_card(PCI_ADD_NORMAL, w83769f_pci_read, w83769f_pci_write, dev, &dev->pci_slot); + else + pci_add_card(PCI_ADD_IDE, w83769f_pci_read, w83769f_pci_write, dev, &dev->pci_slot); + } else if (info->flags & DEVICE_VLB) + device_add(&ide_vlb_2ch_device); + + if (dev->channels & 0x01) + ide_set_bus_master(0, NULL, w83769f_set_irq_0, dev); + + if (dev->channels & 0x02) + ide_set_bus_master(1, NULL, w83769f_set_irq_1, dev); + + /* The CMD PCI-0640B IDE controller has no DMA capability, + so set our devices IDE devices to force ATA-3 (no DMA). */ + if (dev->channels & 0x01) + ide_board_set_force_ata3(0, 1); + + if (dev->channels & 0x02) + ide_board_set_force_ata3(1, 1); + + io_sethandler(info->local & 0xffff, 0x0001, + w83769f_vlb_read, w83769f_vlb_readw, w83769f_vlb_readl, + w83769f_vlb_write, w83769f_vlb_writew, w83769f_vlb_writel, + dev); + io_sethandler((info->local & 0xffff) + 0x0004, 0x0001, + w83769f_vlb_read, w83769f_vlb_readw, w83769f_vlb_readl, + w83769f_vlb_write, w83769f_vlb_writew, w83769f_vlb_writel, + dev); + + next_id++; + + w83769f_reset(dev); + + return dev; +} + +const device_t ide_w83769f_vlb_device = { + .name = "Winbond W83769F VLB", + .internal_name = "ide_w83769f_vlb", + .flags = DEVICE_VLB, + .local = 0x600b4, + .init = w83769f_init, + .close = w83769f_close, + .reset = w83769f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_w83769f_vlb_34_device = { + .name = "Winbond W83769F VLB (Port 34h)", + .internal_name = "ide_w83769f_vlb_34", + .flags = DEVICE_VLB, + .local = 0x60034, + .init = w83769f_init, + .close = w83769f_close, + .reset = w83769f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_w83769f_pci_device = { + .name = "Winbond W83769F PCI", + .internal_name = "ide_w83769f_pci", + .flags = DEVICE_PCI, + .local = 0x600b4, + .init = w83769f_init, + .close = w83769f_close, + .reset = w83769f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_w83769f_pci_34_device = { + .name = "Winbond W83769F PCI (Port 34h)", + .internal_name = "ide_w83769f_pci_34", + .flags = DEVICE_PCI, + .local = 0x60034, + .init = w83769f_init, + .close = w83769f_close, + .reset = w83769f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + diff --git a/src/include/86box/acpi.h b/src/include/86box/acpi.h index 2b8a6396f..5a3eb39ec 100644 --- a/src/include/86box/acpi.h +++ b/src/include/86box/acpi.h @@ -52,12 +52,14 @@ extern "C" { #define ACPI_ENABLE 0xf1 #define ACPI_DISABLE 0xf0 -#define VEN_ALI 0x010b9 -#define VEN_INTEL 0x08086 -#define VEN_SIS 0x01039 -#define VEN_SMC 0x01055 -#define VEN_VIA 0x01106 -#define VEN_VIA_596B 0x11106 +#define VEN_ALI 0x010b9 +#define VEN_INTEL 0x08086 +#define VEN_SIS_5582 0x01039 +#define VEN_SIS_5595_1997 0x11039 +#define VEN_SIS_5595 0x21039 +#define VEN_SMC 0x01055 +#define VEN_VIA 0x01106 +#define VEN_VIA_596B 0x11106 typedef struct acpi_regs_t { uint8_t acpitst; @@ -76,6 +78,25 @@ typedef struct acpi_regs_t { uint8_t gporeg[4]; uint8_t extiotrapsts; uint8_t extiotrapen; + uint8_t enter_c2_ps; + uint8_t enter_c3_ps; + uint8_t reg_12; + uint8_t reg_13; + uint8_t smi_cmd; + uint8_t reg_24; + uint8_t reg_25; + uint8_t reg_26; + uint8_t smi_en_val; + uint8_t smi_dis_val; + uint8_t mail_box; + uint8_t reg_2b; + uint8_t gp_tmr; + uint8_t leg_sts; + uint8_t leg_en; + uint8_t tst_ctl; + uint8_t reg_34; + uint8_t index; + uint8_t reg_ff; uint16_t pmsts; uint16_t pmen; uint16_t pmcntrl; @@ -91,6 +112,15 @@ typedef struct acpi_regs_t { uint16_t gpsmien; uint16_t pscntrl; uint16_t gpscists; + uint16_t reg_14; + uint16_t reg_16; + uint16_t reg_18; + uint16_t reg_1a; + uint16_t reg_1c; + uint16_t gpe_mul; + uint16_t gpe_ctl; + uint16_t gpe_smi; + uint16_t gpe_rl; int smi_lock; int smi_active; uint32_t pcntrl; @@ -107,7 +137,12 @@ typedef struct acpi_regs_t { uint32_t gpo_val; uint32_t gpi_val; uint32_t extsmi_val; - uint32_t pad0; + uint32_t reg_0c; + uint32_t gpe_sts; + uint32_t gpe_en; + uint32_t gpe_pin; + uint32_t gpe_io; + uint32_t gpe_pol; } acpi_regs_t; typedef struct acpi_t { @@ -128,11 +163,15 @@ typedef struct acpi_t { pc_timer_t timer; pc_timer_t resume_timer; pc_timer_t pwrbtn_timer; + pc_timer_t gp_timer; + pc_timer_t per_timer; nvr_t *nvr; apm_t *apm; void *i2c; void (*trap_update)(void *priv); void *trap_priv; + void *smbus; + void *priv; } acpi_t; /* Global variables. */ @@ -145,6 +184,9 @@ extern const device_t acpi_intel_device; extern const device_t acpi_smc_device; extern const device_t acpi_via_device; extern const device_t acpi_via_596b_device; +extern const device_t acpi_sis_5582_device; +extern const device_t acpi_sis_5595_1997_device; +extern const device_t acpi_sis_5595_device; /* Functions */ extern void acpi_update_irq(acpi_t *dev); @@ -163,6 +205,12 @@ extern void acpi_set_nvr(acpi_t *dev, nvr_t *nvr); extern void acpi_set_trap_update(acpi_t *dev, void (*update)(void *priv), void *priv); extern uint8_t acpi_ali_soft_smi_status_read(acpi_t *dev); extern void acpi_ali_soft_smi_status_write(acpi_t *dev, uint8_t soft_smi); +extern void * acpi_get_smbus(void *priv); +extern void acpi_sis5582_pmu_event(void *priv); +extern void acpi_sis5595_smi_raise(void *priv); +extern void acpi_sis5595_pmu_event(void *priv); +extern void acpi_sis5595_smbus_event(void *priv); +extern void acpi_sis5595_software_smi(void *priv); #ifdef __cplusplus } diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 4aa3ee3e9..d5a96baf9 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -130,8 +130,16 @@ extern const device_t sis_85c471_device; extern const device_t sis_85c496_device; extern const device_t sis_85c496_ls486e_device; extern const device_t sis_85c50x_device; +extern const device_t sis_550x_85c503_device; +extern const device_t sis_85c50x_5503_device; +extern const device_t sis_550x_device; extern const device_t sis_5511_device; extern const device_t sis_5571_device; +extern const device_t sis_5581_device; +extern const device_t sis_5591_1997_device; +extern const device_t sis_5591_device; +extern const device_t sis_5600_1997_device; +extern const device_t sis_5600_device; /* ST */ extern const device_t stpc_client_device; @@ -144,6 +152,8 @@ extern const device_t stpc_lpt_device; /* UMC */ extern const device_t umc_8886f_device; extern const device_t umc_8886af_device; +extern const device_t umc_8886bf_device; +extern const device_t umc_8890_device; extern const device_t umc_hb4_device; /* VIA */ diff --git a/src/include/86box/device.h b/src/include/86box/device.h index 71a76c6b1..bd39a02e4 100644 --- a/src/include/86box/device.h +++ b/src/include/86box/device.h @@ -202,6 +202,7 @@ extern void device_context(const device_t *dev); extern void device_context_inst(const device_t *dev, int inst); extern void device_context_restore(void); extern void *device_add(const device_t *d); +extern void *device_add_linked(const device_t *d, void *priv); extern void *device_add_parameters(const device_t *dev, void *params); extern void device_add_ex(const device_t *dev, void *priv); extern void device_add_ex_parameters(const device_t *dev, void *priv, void *params); @@ -217,6 +218,7 @@ extern void *device_cadd_inst(const device_t *dev, const device_t *cd, int inst) extern void *device_cadd_inst_parameters(const device_t *dev, const device_t *cd, int inst, void *params); extern void device_cadd_inst_ex(const device_t *dev, const device_t *cd, void *priv, int inst); extern void device_cadd_inst_ex_parameters(const device_t *dev, const device_t *cd, void *priv, int inst, void *params); +extern void *device_get_common_priv(void); extern void device_close_all(void); extern void device_reset_all(uint32_t match_flags); extern void *device_find_first_priv(uint32_t match_flags); diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h index 01f927185..a3d562b62 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -77,8 +77,16 @@ extern const device_t ide_cmd646_device; /* CMD PCI-646 * extern const device_t ide_cmd646_legacy_only_device; /* CMD PCI-646 (Legacy Mode Only) */ extern const device_t ide_cmd646_single_channel_device; /* CMD PCI-646 (Only primary channel) */ -extern const device_t ide_opti611_vlb_device; /* OPTi 82c611/611A VLB */ -extern const device_t ide_opti611_vlb_sec_device; /* OPTi 82c611/611A VLB (Secondary channel) */ +extern const device_t ide_opti611_vlb_device; /* OPTi 82c611/611A VLB */ +extern const device_t ide_opti611_vlb_sec_device; /* OPTi 82c611/611A VLB (Secondary channel) */ + +extern const device_t ide_um8673f_device; /* UMC UM8673F */ +extern const device_t ide_um8886af_device; /* UMC UM8886AF */ + +extern const device_t ide_w83769f_vlb_device; /* Winbond W83769F VLB */ +extern const device_t ide_w83769f_vlb_34_device; /* Winbond W83769F VLB (Port 34h) */ +extern const device_t ide_w83769f_pci_device; /* Winbond W83769F PCI */ +extern const device_t ide_w83769f_pci_34_device; /* Winbond W83769F PCI (Port 34h) */ extern const device_t ide_ter_device; extern const device_t ide_ter_pnp_device; diff --git a/src/include/86box/hdc_ide_sff8038i.h b/src/include/86box/hdc_ide_sff8038i.h index 2283497bb..3a69fdfac 100644 --- a/src/include/86box/hdc_ide_sff8038i.h +++ b/src/include/86box/hdc_ide_sff8038i.h @@ -43,6 +43,7 @@ typedef struct sff8038i_t uint8_t irq_state; uint8_t channel; uint8_t irq_line; + uint8_t mirq; uint16_t base; uint16_t pad; uint32_t ptr; @@ -72,10 +73,9 @@ extern void sff_bus_master_reset(sff8038i_t *dev); extern void sff_set_slot(sff8038i_t *dev, int slot); extern void sff_set_irq_line(sff8038i_t *dev, int irq_line); - extern void sff_set_irq_mode(sff8038i_t *dev, int irq_mode); extern void sff_set_irq_pin(sff8038i_t *dev, int irq_pin); - extern void sff_set_irq_level(sff8038i_t *dev, int irq_level); +extern void sff_set_mirq(sff8038i_t *dev, uint8_t mirq); #endif /*EMU_HDC_IDE_SFF8038I_H*/ diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 4fba180b2..6817a0de5 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -245,8 +245,12 @@ enum { MACHINE_CHIPSET_SIS_471, MACHINE_CHIPSET_SIS_496, MACHINE_CHIPSET_SIS_501, + MACHINE_CHIPSET_SIS_5501, MACHINE_CHIPSET_SIS_5511, MACHINE_CHIPSET_SIS_5571, + MACHINE_CHIPSET_SIS_5581, + MACHINE_CHIPSET_SIS_5591, + MACHINE_CHIPSET_SIS_5600, MACHINE_CHIPSET_SMSC_VICTORYBX_66, MACHINE_CHIPSET_STPC_CLIENT, MACHINE_CHIPSET_STPC_CONSUMER_II, @@ -641,6 +645,11 @@ extern int machine_at_p54sp4_init(const machine_t *); extern int machine_at_sq588_init(const machine_t *); extern int machine_at_p54sps_init(const machine_t *); +extern int machine_at_ms5109_init(const machine_t *); +extern int machine_at_torino_init(const machine_t *); + +extern int machine_at_hot539_init(const machine_t *); + /* m_at_socket7_3v.c */ extern int machine_at_p54tp4xe_init(const machine_t *); extern int machine_at_p54tp4xe_mr_init(const machine_t *); @@ -669,6 +678,8 @@ extern int machine_at_ms5124_init(const machine_t *); extern int machine_at_amis727_init(const machine_t *); extern int machine_at_vectra54_init(const machine_t *); +extern int machine_at_5sbm2_init(const machine_t *); + /* m_at_socket7.c */ extern int machine_at_acerv35n_init(const machine_t *); extern int machine_at_p55t2p4_init(const machine_t *); @@ -718,6 +729,12 @@ extern int machine_at_cb52xsi_init(const machine_t *); extern int machine_at_m560_init(const machine_t *); extern int machine_at_ms5164_init(const machine_t *); +extern int machine_at_sp97xv_init(const machine_t *); +extern int machine_at_sq578_init(const machine_t *); + +extern int machine_at_5sg100_init(const machine_t *); +extern int machine_at_ms5172_init(const machine_t *); + /* m_at_sockets7.c */ extern int machine_at_p5a_init(const machine_t *); extern int machine_at_m579_init(const machine_t *); @@ -780,6 +797,8 @@ extern int machine_at_vei8_init(const machine_t *); extern int machine_at_borapro_init(const machine_t *); extern int machine_at_ms6168_init(const machine_t *); +extern int machine_at_p6f99_init(const machine_t *); + /* m_at_slot2.c */ extern int machine_at_6gxu_init(const machine_t *); extern int machine_at_s2dge_init(const machine_t *); diff --git a/src/include/86box/nvr.h b/src/include/86box/nvr.h index d24ca903c..85e0954f0 100644 --- a/src/include/86box/nvr.h +++ b/src/include/86box/nvr.h @@ -122,6 +122,8 @@ extern void nvr_at_handler(int set, uint16_t base, nvr_t *nvr); extern void nvr_at_sec_handler(int set, uint16_t base, nvr_t *nvr); extern void nvr_at_index_read_handler(int set, uint16_t base, nvr_t *nvr); extern void nvr_read_addr_set(int set, nvr_t *nvr); +extern uint8_t nvr_get_index(void *priv, uint8_t addr_id); +extern void nvr_at_data_port(int set, nvr_t *nvr); extern void nvr_wp_set(int set, int h, nvr_t *nvr); extern void nvr_via_wp_set(int set, int reg, nvr_t *nvr); extern void nvr_bank_set(int base, uint8_t bank, nvr_t *nvr); diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index 2bcb6b3b8..8483eb417 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -286,6 +286,7 @@ extern const device_t via_vp3_agp_device; extern const device_t via_mvp3_agp_device; extern const device_t via_apro_agp_device; extern const device_t via_vt8601_agp_device; +extern const device_t sis_5xxx_agp_device; #endif #endif /*EMU_PCI_H*/ diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index b07e73e8e..31d5d12ae 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -75,6 +75,12 @@ extern const device_t ps1_m2133_sio; #if defined(DEV_BRANCH) && defined(USE_SIO_DETECT) extern const device_t sio_detect_device; #endif +extern const device_t um8663af_device; +extern const device_t um8663af_ide_device; +extern const device_t um8663af_sec_device; +extern const device_t um8663bf_device; +extern const device_t um8663bf_ide_device; +extern const device_t um8663bf_sec_device; extern const device_t um8669f_device; extern const device_t um8669f_ide_device; extern const device_t um8669f_ide_sec_device; diff --git a/src/include/86box/sis_55xx.h b/src/include/86box/sis_55xx.h new file mode 100644 index 000000000..99ccf7dfa --- /dev/null +++ b/src/include/86box/sis_55xx.h @@ -0,0 +1,78 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Header for the implementation of the SiS 55xx Pentium + * PCI/ISA Chipsets. + * + * Authors: Miran Grca, + * + * Copyright 2019-2020 Miran Grca. + */ +#ifndef EMU_SIS_55XX_H +#define EMU_SIS_55XX_H + +typedef struct +{ + uint8_t sb_pci_slot; + uint8_t ide_bits_1_3_writable; + uint8_t usb_enabled; + + uint8_t *pmu_regs; + + sff8038i_t *bm[2]; + acpi_t *acpi; +} sis_55xx_common_t; + +extern void sis_5511_host_to_pci_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5511_host_to_pci_read(int addr, void *priv); +extern void sis_5571_host_to_pci_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5571_host_to_pci_read(int addr, void *priv); +extern void sis_5581_host_to_pci_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5581_host_to_pci_read(int addr, void *priv); +extern void sis_5591_host_to_pci_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5591_host_to_pci_read(int addr, void *priv); +extern void sis_5600_host_to_pci_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5600_host_to_pci_read(int addr, void *priv); + +extern void sis_5513_pci_to_isa_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5513_pci_to_isa_read(int addr, void *priv); +extern void sis_5513_ide_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5513_ide_read(int addr, void *priv); +extern void sis_5572_usb_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5572_usb_read(int addr, void *priv); +extern void sis_5595_pmu_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5595_pmu_read(int addr, void *priv); + +extern const device_t sis_5511_h2p_device; +extern const device_t sis_5571_h2p_device; +extern const device_t sis_5581_h2p_device; +extern const device_t sis_5591_h2p_device; +extern const device_t sis_5600_h2p_device; + +extern const device_t sis_5513_p2i_device; +extern const device_t sis_5572_p2i_device; +extern const device_t sis_5582_p2i_device; +extern const device_t sis_5595_1997_p2i_device; +extern const device_t sis_5595_p2i_device; + +extern const device_t sis_5513_ide_device; +extern const device_t sis_5572_ide_device; +extern const device_t sis_5582_ide_device; +extern const device_t sis_5591_5600_ide_device; + +extern const device_t sis_5572_usb_device; +extern const device_t sis_5582_usb_device; +extern const device_t sis_5595_usb_device; + +extern const device_t sis_5595_pmu_device; +extern const device_t sis_5595_1997_pmu_device; + +extern const device_t sis_55xx_common_device; + + +#endif /*EMU_SIS_55XX_H*/ diff --git a/src/include/86box/smbus.h b/src/include/86box/smbus.h index 340d1d00e..2c06c3d4e 100644 --- a/src/include/86box/smbus.h +++ b/src/include/86box/smbus.h @@ -15,8 +15,8 @@ * Copyright 2020 RichardG. */ -#ifndef EMU_SMBUS_PIIX4_H -#define EMU_SMBUS_PIIX4_H +#ifndef EMU_SMBUS_H +#define EMU_SMBUS_H #define SMBUS_PIIX4_BLOCK_DATA_SIZE 32 #define SMBUS_PIIX4_BLOCK_DATA_MASK (SMBUS_PIIX4_BLOCK_DATA_SIZE - 1) @@ -24,6 +24,9 @@ #define SMBUS_ALI7101_BLOCK_DATA_SIZE 32 #define SMBUS_ALI7101_BLOCK_DATA_MASK (SMBUS_ALI7101_BLOCK_DATA_SIZE - 1) +#define SMBUS_SIS5595_BLOCK_DATA_SIZE 32 +#define SMBUS_SIS5595_BLOCK_DATA_MASK (SMBUS_ALI7101_BLOCK_DATA_SIZE - 1) + enum { SMBUS_PIIX4 = 0, SMBUS_VIA = 1 @@ -63,16 +66,47 @@ typedef struct smbus_ali7101_t { void *i2c; } smbus_ali7101_t; -extern void smbus_piix4_remap(smbus_piix4_t *dev, uint16_t new_io_base, uint8_t enable); -extern void smbus_piix4_setclock(smbus_piix4_t *dev, int clock); +typedef struct smbus_sis5595_t { + uint32_t local; + uint16_t stat; + uint16_t next_stat; + uint16_t ctl; + uint8_t cmd; + uint8_t addr; + uint8_t saved_addr; + uint8_t block_ptr; + uint8_t count; + uint8_t data0; + uint8_t data1; + uint8_t alias; + uint8_t reg_ff; + uint8_t index; + uint8_t irq_enable; + uint8_t irq_state; + uint8_t data[SMBUS_SIS5595_BLOCK_DATA_SIZE]; + pc_timer_t response_timer; + void *i2c; +} smbus_sis5595_t; -extern void smbus_ali7101_remap(smbus_ali7101_t *dev, uint16_t new_io_base, uint8_t enable); +extern void smbus_piix4_remap(smbus_piix4_t *dev, uint16_t new_io_base, uint8_t enable); +extern void smbus_piix4_setclock(smbus_piix4_t *dev, int clock); + +extern void smbus_ali7101_remap(smbus_ali7101_t *dev, uint16_t new_io_base, uint8_t enable); + +extern void smbus_sis5595_irq_enable(void *priv, uint8_t enable); + +extern uint8_t smbus_sis5595_read_index(void *priv); +extern uint8_t smbus_sis5595_read_data(void *priv); +extern void smbus_sis5595_write_index(void *priv, uint8_t val); +extern void smbus_sis5595_write_data(void *priv, uint8_t val); #ifdef EMU_DEVICE_H extern const device_t piix4_smbus_device; extern const device_t via_smbus_device; extern const device_t ali7101_smbus_device; + +extern const device_t sis5595_smbus_device; #endif -#endif /*EMU_SMBUS_PIIX4_H*/ +#endif /*EMU_SMBUS_H*/ diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 47d237b10..33375f765 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -368,8 +368,9 @@ extern const device_t gd5434_onboard_pci_device; extern const device_t gd5434_vlb_device; extern const device_t gd5434_pci_device; extern const device_t gd5436_pci_device; -extern const device_t gd5440_onboard_pci_device; +extern const device_t gd5436_onboard_pci_device; extern const device_t gd5440_pci_device; +extern const device_t gd5440_onboard_pci_device; extern const device_t gd5446_pci_device; extern const device_t gd5446_stb_pci_device; extern const device_t gd5480_pci_device; @@ -539,6 +540,7 @@ extern const device_t tgui9440_vlb_device; extern const device_t tgui9440_pci_device; extern const device_t tgui9440_onboard_pci_device; extern const device_t tgui9660_pci_device; +extern const device_t tgui9660_onboard_pci_device; extern const device_t tgui9680_pci_device; /* IBM PS/1 (S)VGA */ diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 63f59cb07..1dd63ce32 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1908,7 +1908,7 @@ machine_at_hot433a_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); device_add(&umc_hb4_device); - device_add(&umc_8886af_device); + device_add(&umc_8886bf_device); device_add(&um8669f_device); device_add(&winbond_flash_w29c010_device); device_add(&keyboard_at_ami_device); @@ -1937,7 +1937,7 @@ machine_at_atc1415_init(const machine_t *model) pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2); device_add(&umc_hb4_device); - device_add(&umc_8886af_device); + device_add(&umc_8886bf_device); device_add(&intel_flash_bxt_device); device_add(&keyboard_at_ami_device); @@ -1966,10 +1966,9 @@ machine_at_actionpc2600_init(const machine_t *model) pci_register_slot(0x0E, PCI_CARD_VIDEO, 0, 0, 0, 0); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); device_add(&umc_hb4_device); - device_add(&umc_8886af_device); + device_add(&umc_8886bf_device); device_add(&fdc37c665_device); device_add(&intel_flash_bxt_device); device_add(&keyboard_ps2_tg_ami_device); @@ -2001,7 +2000,7 @@ machine_at_actiontower8400_init(const machine_t *model) pci_register_slot(0x14, PCI_CARD_NORMAL, 2, 3, 4, 1); device_add(&umc_hb4_device); - device_add(&umc_8886af_device); + device_add(&umc_8886f_device); device_add(&fdc37c665_device); device_add(&ide_cmd640_pci_device); device_add(&intel_flash_bxt_device); // The ActionPC 2600 has this so I'm gonna assume this does too. @@ -2033,8 +2032,8 @@ machine_at_m919_init(const machine_t *model) pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); device_add(&umc_hb4_device); - device_add(&umc_8886af_device); - device_add(&um8669f_device); + device_add(&umc_8886af_device); /* AF is correct - the BIOS does IDE writes to ports 108h and 109h. */ + device_add(&um8663bf_device); device_add(&sst_flash_29ee010_device); device_add(&keyboard_at_ami_device); @@ -2226,7 +2225,7 @@ machine_at_ap4100aa_init(const machine_t *model) device_add(&ali1429g_device); device_add(&keyboard_ps2_ami_pci_device); device_add(&ide_vlb_device); - device_add(&um8669f_device); // needs um8663 + device_add(&um8663bf_device); return ret; } diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 12c84ffdf..d31d763d4 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -807,3 +807,37 @@ machine_at_m729_init(const machine_t *model) return ret; } + +int +machine_at_p6f99_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/p6f99/99-8.BIN", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0C, PCI_CARD_SOUND, 2, 3, 4, 1); + pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); + device_add(&sis_5600_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&it8661f_device); + device_add(&winbond_flash_w29c020_device); + + if (sound_card_current[0] == SOUND_INTERNAL) + device_add(&es1371_onboard_device); + + return ret; +} + diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 4a86c75d0..916f8490b 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -511,3 +511,99 @@ machine_at_p54sps_init(const machine_t *model) return ret; } + +int +machine_at_ms5109_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ms5109/A778.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + device_add(&ami_1994_nvr_device); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_IDE, 0, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 3, 2, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 1, 3, 4); + pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 3, 2, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&sis_550x_85c503_device); + device_add(&ide_w83769f_pci_device); + device_add(&keyboard_ps2_ami_device); + device_add(&w83787f_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + +int +machine_at_torino_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_inverted("roms/machines/torino/PER113.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + device_add(&ami_1994_nvr_device); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_VIDEO, 0, 0, 0, 0); + pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + + device_add(&sis_550x_85c503_device); + device_add(&ide_um8673f_device); + device_add(&keyboard_ps2_tg_ami_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + +int +machine_at_hot539_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/hot539/539_R17.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x15, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x16, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&umc_8890_device); + device_add(&umc_8886af_device); + device_add(&sst_flash_29ee010_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&um8663af_device); + + return ret; +} diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index fd453f9af..09441ad4f 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -1268,6 +1268,119 @@ machine_at_cb52xsi_init(const machine_t *model) return ret; } +int +machine_at_sp97xv_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/sp97xv/0109XVJ2.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x13, PCI_CARD_VIDEO, 1, 2, 3, 4); /* On-chip SiS graphics, absent here. */ + device_add(&sis_5581_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83877f_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + +int +machine_at_sq578_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/sq578/578b03.rom", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + device_add(&sis_5581_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83877tf_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + +int +machine_at_5sg100_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/5sg100/5sg.20g", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); + device_add(&sis_5591_1997_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83877tf_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + +int +machine_at_ms5172_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ms5172/A572MS15.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + device_add(&sis_5591_1997_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83877tf_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + int machine_at_m560_init(const machine_t *model) { @@ -1347,7 +1460,7 @@ machine_at_thunderbolt_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 1, 2, 3); /* PIIX4 */ + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 1, 2, 3); /* PIIX4 */ pci_register_slot(0x11, PCI_CARD_NORMAL, 0, 1, 2, 3); pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 0); pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 0, 1); diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index 2e642082d..676f50fb1 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -858,3 +858,31 @@ machine_at_vectra54_init(const machine_t *model) return ret; } + +int +machine_at_5sbm2_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/5sbm2/5SBM0717.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 1, 2); + + device_add(&keyboard_at_ami_device); + device_add(&sis_550x_device); + device_add(&um8663af_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index d6849c7ac..beac1cf6e 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -139,8 +139,12 @@ const machine_filter_t machine_chipsets[] = { { "SiS 471", MACHINE_CHIPSET_SIS_471 }, { "SiS 496", MACHINE_CHIPSET_SIS_496 }, { "SiS 501", MACHINE_CHIPSET_SIS_501 }, + { "SiS 5501", MACHINE_CHIPSET_SIS_5501 }, { "SiS 5511", MACHINE_CHIPSET_SIS_5511 }, { "SiS 5571", MACHINE_CHIPSET_SIS_5571 }, + { "SiS 5581", MACHINE_CHIPSET_SIS_5581 }, + { "SiS 5591", MACHINE_CHIPSET_SIS_5591 }, + { "SiS (5)600", MACHINE_CHIPSET_SIS_5600 }, { "SMSC VictoryBX-66", MACHINE_CHIPSET_SMSC_VICTORYBX_66 }, { "STPC Client", MACHINE_CHIPSET_STPC_CLIENT }, { "STPC Consumer-II", MACHINE_CHIPSET_STPC_CONSUMER_II }, @@ -9744,6 +9748,128 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[SiS 5501] MSI MS-5109", + .internal_name = "ms5109", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_SIS_5501, + .init = machine_at_ms5109_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + CPU_BLOCK(CPU_PENTIUMMMX), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3520, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 1.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMIKey Z(!) KBC firmware. */ + { + .name = "[SiS 5501] TriGem Torino", + .internal_name = "torino", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_SIS_5501, + .init = machine_at_torino_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + CPU_BLOCK(CPU_PENTIUMMMX), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3520, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 1.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &tgui9660_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL + }, + + /* UMC 889x */ + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[UMC 889x] Shuttle HOT-539", + .internal_name = "hot539", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_UMC_UM8890BF, + .init = machine_at_hot539_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86), + .min_bus = 40000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3600, + .min_multi = 1.5, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Socket 7 (Single Voltage) machines */ /* 430FX */ @@ -10528,6 +10654,48 @@ const machine_t machines[] = { .net_device = NULL }, + /* SiS 5501 */ + /* Has the Lance LT38C41 KBC. */ + { + .name = "[SiS 5501] Chaintech 5SBM2 (M103)", + .internal_name = "5sbm2", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_SIS_5501, + .init = machine_at_5sbm2_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 = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 262144, + .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 = NULL, + .net_device = NULL + }, + /* SiS 5511 */ /* Has AMIKey H KBC firmware (AMIKey-2). */ { @@ -12159,6 +12327,171 @@ const machine_t machines[] = { .net_device = NULL }, + /* SiS 5581 */ + /* Has the SiS 5581 chipset with on-chip KBC. */ + { + .name = "[SiS 5581] ASUS SP97-XV", + .internal_name = "sp97xv", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_SIS_5581, + .init = machine_at_sp97xv_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 = 75000000, + .min_voltage = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 1572864, + .step = 1024 + }, + .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 = NULL, + .net_device = NULL + }, + /* Has the SiS 5581 chipset with on-chip KBC. */ + { + .name = "[SiS 5581] BCM SQ-578", + .internal_name = "sq578", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_SIS_5581, + .init = machine_at_sq578_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 = 75000000, + .min_voltage = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 1572864, + .step = 1024 + }, + .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 = NULL, + .net_device = NULL + }, + + + /* SiS 5591 */ + /* Has the SiS 5591 chipset with on-chip KBC. */ + { + .name = "[SiS 5591] Gigabyte GA-5SG100", + .internal_name = "5sg100", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_SIS_5591, + .init = machine_at_5sg100_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 = 75000000, + .min_voltage = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 786432, + .step = 1024 + }, + .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 = NULL, + .net_device = NULL + }, + /* Has the SiS 5591 chipset with on-chip KBC. */ + { + .name = "[SiS 5591] MSI MS-5172", + .internal_name = "ms5172", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_SIS_5591, + .init = machine_at_ms5172_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 = 75000000, + .min_voltage = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 786432, + .step = 1024 + }, + .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 = NULL, + .net_device = NULL + }, + /* ALi ALADDiN IV+ */ /* Has the ALi M1543 southbridge with on-chip KBC. */ { @@ -14057,6 +14390,48 @@ const machine_t machines[] = { .net_device = NULL }, + /* SiS (5)600 */ + /* Has the SiS (5)600 chipset with on-chip KBC. */ + { + .name = "[SiS 5600] Freetech/Flexus P6F99", + .internal_name = "p6f99", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_SIS_5600, + .init = machine_at_p6f99_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: Ensoniq ES1373 */ + .ram = { + .min = 8192, + .max = 1572864, + .step = 1024 + }, + .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 = &es1371_onboard_device, /* ES1373 but we currently don't emulate that. */ + .net_device = NULL + }, + /* Slot 1/2 machines */ /* 440GX */ /* Has a National Semiconductors PC87309 Super I/O chip with on-chip KBC diff --git a/src/nvr_at.c b/src/nvr_at.c index 7e356f55d..4ddec729f 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -686,6 +686,19 @@ nvr_write(uint16_t addr, uint8_t val, void *priv) } } +/* Get the NVR register index (used for APC). */ +uint8_t +nvr_get_index(void *priv, uint8_t addr_id) +{ + nvr_t *nvr = (nvr_t *) priv; + local_t *local = (local_t *) nvr->data; + uint8_t ret; + + ret = local->addr[addr_id]; + + return ret; +} + /* Read from one of the NVR registers. */ static uint8_t nvr_read(uint16_t addr, void *priv) @@ -932,6 +945,17 @@ nvr_at_index_read_handler(int set, uint16_t base, nvr_t *nvr) } } +void +nvr_at_data_port(int set, nvr_t *nvr) +{ + io_handler(0, 0x71, 1, + nvr_read, NULL, NULL, nvr_write, NULL, NULL, nvr); + + if (set) + io_handler(1, 0x71, 1, + nvr_read, NULL, NULL, nvr_write, NULL, NULL, nvr); +} + void nvr_at_sec_handler(int set, uint16_t base, nvr_t *nvr) { diff --git a/src/sio/CMakeLists.txt b/src/sio/CMakeLists.txt index 3140a7181..dff0fcd0f 100644 --- a/src/sio/CMakeLists.txt +++ b/src/sio/CMakeLists.txt @@ -18,7 +18,8 @@ add_library(sio OBJECT sio_acc3221.c sio_ali5123.c sio_f82c710.c sio_82091aa.c sio_it86x1f.c sio_pc87306.c sio_pc87307.c sio_pc87309.c sio_pc87310.c sio_pc87311.c sio_pc87332.c sio_prime3b.c sio_prime3c.c - sio_w83787f.c sio_w83877f.c sio_w83977f.c sio_um8669f.c + sio_w83787f.c sio_w83877f.c sio_w83977f.c + sio_um8663f.c sio_um8669f.c sio_vt82c686.c) if(SIO_DETECT) diff --git a/src/sio/sio_it86x1f.c b/src/sio/sio_it86x1f.c index 74e79bbed..ece59501f 100644 --- a/src/sio/sio_it86x1f.c +++ b/src/sio/sio_it86x1f.c @@ -414,8 +414,10 @@ it86x1f_pnp_write_vendor_reg(uint8_t ld, uint8_t reg, uint8_t val, void *priv) case 0x23: val &= (1 << dev->gpio_ldn) - 1; dev->global_regs[reg & 0x0f] = val; +#ifdef ENABLE_IT86X1F_LOG if (val) - pclog("IT86x1F: Warning: ISAPnP mode enabled.\n"); + it86x1f_log("IT86x1F: Warning: ISAPnP mode enabled.\n"); +#endif break; case 0x24: diff --git a/src/sio/sio_um8663f.c b/src/sio/sio_um8663f.c new file mode 100644 index 000000000..7391b029f --- /dev/null +++ b/src/sio/sio_um8663f.c @@ -0,0 +1,366 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the UMC UMF8663F Super I/O chip. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/pci.h> +#include <86box/lpt.h> +#include <86box/serial.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/gameport.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/sio.h> +#include <86box/random.h> +#include <86box/plat_unused.h> + +#ifdef ENABLE_UM8663F_LOG +int um8663f_do_log = ENABLE_UM8663F_LOG; + +static void +um8663f_log(const char *fmt, ...) +{ + va_list ap; + + if (um8663f_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define um8663f_log(fmt, ...) +#endif + +typedef struct um8663f_t { + uint8_t max_reg; + uint8_t ide; + uint8_t locked; + uint8_t cur_reg; + uint8_t regs[5]; + + fdc_t *fdc; + serial_t *uart[2]; +} um8663f_t; + +static void +um8663f_fdc_handler(um8663f_t *dev) +{ + fdc_remove(dev->fdc); + if (dev->regs[0] & 0x01) + fdc_set_base(dev->fdc, (dev->regs[1] & 0x01) ? FDC_PRIMARY_ADDR : FDC_SECONDARY_ADDR); +} + +static void +um8663f_uart_handler(um8663f_t *dev, int port) +{ + uint8_t shift = (port + 1); + + serial_remove(dev->uart[port]); + if (dev->regs[0] & (2 << port)) { + switch ((dev->regs[1] >> shift) & 0x01) { + case 0x00: + if (port == 1) + serial_setup(dev->uart[port], COM4_ADDR, COM4_IRQ); + else + serial_setup(dev->uart[port], COM3_ADDR, COM1_IRQ); + break; + case 0x01: + if (port == 1) + serial_setup(dev->uart[port], COM2_ADDR, COM2_IRQ); + else + serial_setup(dev->uart[port], COM1_ADDR, COM1_IRQ); + break; + + default: + break; + } + } +} + +static void +um8663f_lpt_handler(um8663f_t *dev) +{ + lpt1_remove(); + if (dev->regs[0] & 0x08) { + switch ((dev->regs[1] >> 3) & 0x01) { + case 0x01: + lpt1_init(LPT1_ADDR); + lpt1_irq(7); + break; + case 0x00: + lpt1_init(LPT2_ADDR); + lpt1_irq(5); + break; + + default: + break; + } + } +} + +static void +um8663f_ide_handler(um8663f_t *dev) +{ + int board = dev->ide - 1; + + if (dev->ide > 0) { + ide_handlers(board, 0); + ide_set_base(board, (dev->regs[1] & 0x10) ? 0x01f0 : 0x0170); + ide_set_side(board, (dev->regs[1] & 0x10) ? 0x03f6 : 0x0376); + if (dev->regs[0] & 0x10) + ide_handlers(board, 1); + } +} + +static void +um8663f_write(uint16_t port, uint8_t val, void *priv) +{ + um8663f_t *dev = (um8663f_t *) priv; + uint8_t valxor; + + um8663f_log("UM8663F: write(%04X, %02X)\n", port, val); + + if (dev->locked) { + if ((port == 0x108) && (val == 0xaa)) + dev->locked = 0; + } else { + if (port == 0x108) { + if (val == 0x55) + dev->locked = 1; + else + dev->cur_reg = val; + } else if ((dev->cur_reg >= 0xc0) && (dev->cur_reg <= dev->max_reg)) { + valxor = (dev->regs[dev->cur_reg - 0xc0] ^ val); + dev->regs[dev->cur_reg - 0xc0] = val; + switch (dev->cur_reg - 0xc0) { + /* Port enable register. */ + case 0x00: + if (valxor & 0x10) + um8663f_ide_handler(dev); + if (valxor & 0x08) + um8663f_lpt_handler(dev); + if (valxor & 0x04) + um8663f_uart_handler(dev, 1); + if (valxor & 0x02) + um8663f_uart_handler(dev, 0); + if (valxor & 0x01) + um8663f_fdc_handler(dev); + break; + /* + Port configuration register: + - Bits 7, 6: + - 0, 0 = LPT 1 is none; + - 0, 1 = LPT 1 is EPP; + - 1, 0 = LPT 1 is SPP; + - 1, 1 = LPT 1 is ECP; + - Bit 4 = 0 = IDE is secondary, 1 = IDE is primary; + - Bit 3 = 0 = LPT 1 is 278h, 1 = LPT 1 is 378h; + - Bit 2 = 0 = UART 2 is COM4, 1 = UART 2 is COM2; + - Bit 1 = 0 = UART 1 is COM3, 1 = UART 2 is COM1; + - Bit 0 = 0 = FDC is 370h, 1 = UART 2 is 3f0h. + */ + case 0x01: + if (valxor & 0x10) + um8663f_ide_handler(dev); + if (valxor & 0x08) + um8663f_lpt_handler(dev); + if (valxor & 0x04) + um8663f_uart_handler(dev, 1); + if (valxor & 0x02) + um8663f_uart_handler(dev, 0); + if (valxor & 0x01) + um8663f_fdc_handler(dev); + break; + } + } + } +} + +static uint8_t +um8663f_read(uint16_t port, void *priv) +{ + const um8663f_t *dev = (um8663f_t *) priv; + uint8_t ret = 0xff; + + if (!dev->locked) { + if (port == 0x108) + ret = dev->cur_reg; /* ??? */ + else if ((dev->cur_reg >= 0xc0) && (dev->cur_reg <= dev->max_reg)) { + ret = dev->regs[dev->cur_reg - 0xc0]; + if (dev->cur_reg == 0xc0) + ret = (ret & 0x1f) | ((random_generate() & 0x07) << 5); + } + } + + um8663f_log("UM8663F: read(%04X) = %02X\n", port, ret); + + return ret; +} + +static void +um8663f_reset(void *priv) +{ + um8663f_t *dev = (um8663f_t *) priv; + + serial_remove(dev->uart[0]); + serial_setup(dev->uart[0], COM1_ADDR, COM1_IRQ); + + serial_remove(dev->uart[1]); + serial_setup(dev->uart[1], COM2_ADDR, COM2_IRQ); + + lpt1_remove(); + lpt1_init(LPT1_ADDR); + + fdc_reset(dev->fdc); + fdc_remove(dev->fdc); + + memset(dev->regs, 0x00, sizeof(dev->regs)); + + dev->regs[0x00] = (dev->ide > 0) ? 0x1f : 0x0f; + dev->regs[0x01] = (dev->ide == 2) ? 0x0f : 0x1f; + + um8663f_fdc_handler(dev); + um8663f_uart_handler(dev, 0); + um8663f_uart_handler(dev, 1); + um8663f_lpt_handler(dev); + um8663f_ide_handler(dev); + + dev->locked = 1; +} + +static void +um8663f_close(void *priv) +{ + um8663f_t *dev = (um8663f_t *) priv; + + free(dev); +} + +static void * +um8663f_init(UNUSED(const device_t *info)) +{ + um8663f_t *dev = (um8663f_t *) calloc(1, sizeof(um8663f_t)); + + dev->fdc = device_add(&fdc_at_smc_device); + + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + dev->ide = info->local & 0xff; + if (dev->ide < IDE_BUS_MAX) + device_add(&ide_isa_device); + + dev->max_reg = info->local >> 8; + + io_sethandler(0x0108, 0x0002, um8663f_read, NULL, NULL, um8663f_write, NULL, NULL, dev); + + um8663f_reset(dev); + + return dev; +} + +const device_t um8663af_device = { + .name = "UMC UM8663AF Super I/O", + .internal_name = "um8663af", + .flags = 0, + .local = 0xc300, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t um8663af_ide_device = { + .name = "UMC UM8663AF Super I/O (With IDE)", + .internal_name = "um8663af_ide", + .flags = 0, + .local = 0xc301, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t um8663af_ide_sec_device = { + .name = "UMC UM8663AF Super I/O (With Secondary IDE)", + .internal_name = "um8663af_ide_sec", + .flags = 0, + .local = 0xc302, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t um8663bf_device = { + .name = "UMC UM8663BF Super I/O", + .internal_name = "um8663bf", + .flags = 0, + .local = 0xc400, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t um8663bf_ide_device = { + .name = "UMC UM8663BF Super I/O (With IDE)", + .internal_name = "um8663bf_ide", + .flags = 0, + .local = 0xc401, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t um8663bf_ide_sec_device = { + .name = "UMC UM8663BF Super I/O (With Secondary IDE)", + .internal_name = "um8663bf_ide_sec", + .flags = 0, + .local = 0xc402, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index e83d4593f..bf27a700a 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -4132,7 +4132,11 @@ gd54xx_init(const device_t *info) break; case CIRRUS_ID_CLGD5436: - romfn = BIOS_GD5436_PATH; + if (info->local & 0x200) { + romfn = NULL; + gd54xx->has_bios = 0; + } else + romfn = BIOS_GD5436_PATH; break; case CIRRUS_ID_CLGD5430: @@ -5148,6 +5152,20 @@ const device_t gd5434_pci_device = { .config = gd5434_config }; +const device_t gd5436_onboard_pci_device = { + .name = "Cirrus Logic GD5436 (PCI) (On-Board)", + .internal_name = "cl_gd5436_onboard_pci", + .flags = DEVICE_PCI, + .local = CIRRUS_ID_CLGD5436 | 0x200, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, + { .available = NULL }, + .speed_changed = gd54xx_speed_changed, + .force_redraw = gd54xx_force_redraw, + .config = gd5434_config +}; + const device_t gd5436_pci_device = { .name = "Cirrus Logic GD5436 (PCI)", .internal_name = "cl_gd5436_pci", diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index 86159ed0a..490c724ce 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -3155,7 +3155,7 @@ tgui_init(const device_t *info) break; case TGUI_9660: case TGUI_9680: - bios_fn = ROM_TGUI_96xx; + bios_fn = (info->local & ONBOARD) ? NULL : ROM_TGUI_96xx; break; default: free(tgui); @@ -3402,6 +3402,20 @@ const device_t tgui9660_pci_device = { .config = tgui96xx_config }; +const device_t tgui9660_onboard_pci_device = { + .name = "Trident TGUI 9660XGi On-Board PCI", + .internal_name = "tgui9660_onboard_pci", + .flags = DEVICE_PCI, + .local = TGUI_9660 | ONBOARD, + .init = tgui_init, + .close = tgui_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = tgui_speed_changed, + .force_redraw = tgui_force_redraw, + .config = tgui96xx_config +}; + const device_t tgui9680_pci_device = { .name = "Trident TGUI 9680XGi PCI", .internal_name = "tgui9680_pci", From fcabd353d9bd13a06f008d7be4d689a22ed59da0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Feb 2024 00:56:28 +0100 Subject: [PATCH 563/936] Check IOPL on 286 task segments. --- src/cpu/386_common.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 847408ba8..0abf8e936 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -1605,8 +1605,12 @@ checkio(uint32_t port, int mask) { uint32_t t; - if (!(tr.access & 0x08)) + if (!(tr.access & 0x08)) { + if ((CPL) > (IOPL)) + return 1; + return 0; + } cpl_override = 1; t = readmemw(tr.base, 0x66); From 8cf8ccf3b3463306ea1edb4d489f5057d5c89c7a Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Feb 2024 01:08:21 +0100 Subject: [PATCH 564/936] Added the STB PowerGraph 64 Video (S3 Trio64V+ VLB). --- src/include/86box/video.h | 1 + src/video/vid_s3.c | 36 +++++++++++++++++++++++++++++++++++- src/video/vid_table.c | 1 + 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 33375f765..65d96a4b6 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -491,6 +491,7 @@ extern const device_t s3_spea_mirage_p64_vlb_device; extern const device_t s3_phoenix_trio64_vlb_device; extern const device_t s3_phoenix_trio64_onboard_pci_device; extern const device_t s3_phoenix_trio64_pci_device; +extern const device_t s3_stb_powergraph_64_video_vlb_device; extern const device_t s3_phoenix_trio64vplus_pci_device; extern const device_t s3_phoenix_trio64vplus_onboard_pci_device; extern const device_t s3_cardex_trio64vplus_pci_device; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 0ef48fa0e..46ed8eba0 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -63,6 +63,7 @@ #define ROM_PHOENIX_TRIO64 "roms/video/s3/86c764x1.bin" #define ROM_DIAMOND_STEALTH64_764 "roms/video/s3/stealt64.bin" #define ROM_TRIO64V2_DX_VBE20 "roms/video/s3/86c775_2.bin" +#define ROM_STB_POWERGRAPH_64_VIDEO "roms/video/s3/VBIOS.BIN" #define ROM_PHOENIX_TRIO64VPLUS "roms/video/s3/64V1506.ROM" #define ROM_CARDEX_TRIO64VPLUS "roms/video/s3/S3T64VP.VBI" #define ROM_DIAMOND_STEALTH_SE "roms/video/s3/DiamondStealthSE.VBI" @@ -94,6 +95,7 @@ enum { S3_AMI_86C924, S3_TRIO64V2_DX, S3_TRIO64V2_DX_ONBOARD, + S3_STB_POWERGRAPH_64_VIDEO, S3_PHOENIX_TRIO64VPLUS, S3_PHOENIX_TRIO64VPLUS_ONBOARD, S3_CARDEX_TRIO64VPLUS, @@ -3079,7 +3081,8 @@ s3_in(uint16_t addr, void *priv) temp = svga->seqregs[svga->seqaddr]; /* This is needed for the Intel Advanced/ATX's built-in S3 Trio64V+ BIOS to not get stuck in an infinite loop. */ - if (((s3->card_type == S3_PHOENIX_TRIO64VPLUS_ONBOARD) || + if (((s3->card_type == S3_STB_POWERGRAPH_64_VIDEO) || + (s3->card_type == S3_PHOENIX_TRIO64VPLUS_ONBOARD) || (s3->card_type == S3_CARDEX_TRIO64VPLUS)) && (svga->seqaddr == 0x17)) svga->seqregs[svga->seqaddr] ^= 0x01; return temp; @@ -9478,6 +9481,7 @@ s3_reset(void *priv) case S3_PHOENIX_TRIO64: case S3_PHOENIX_TRIO64_ONBOARD: + case S3_STB_POWERGRAPH_64_VIDEO: case S3_CARDEX_TRIO64VPLUS: case S3_PHOENIX_TRIO64VPLUS: case S3_PHOENIX_TRIO64VPLUS_ONBOARD: @@ -9721,6 +9725,14 @@ s3_init(const device_t *info) else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); break; + case S3_STB_POWERGRAPH_64_VIDEO: + bios_fn = ROM_STB_POWERGRAPH_64_VIDEO; + chip = S3_TRIO64V; + if (info->flags & DEVICE_PCI) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); + break; case S3_PHOENIX_TRIO64VPLUS: bios_fn = ROM_PHOENIX_TRIO64VPLUS; chip = S3_TRIO64V; @@ -10181,6 +10193,7 @@ s3_init(const device_t *info) case S3_PHOENIX_TRIO64: case S3_PHOENIX_TRIO64_ONBOARD: + case S3_STB_POWERGRAPH_64_VIDEO: case S3_PHOENIX_TRIO64VPLUS: case S3_PHOENIX_TRIO64VPLUS_ONBOARD: case S3_CARDEX_TRIO64VPLUS: @@ -10420,6 +10433,12 @@ s3_phoenix_trio64_available(void) return rom_present(ROM_PHOENIX_TRIO64); } +static int +s3_stb_powergraph_64_video_available(void) +{ + return rom_present(ROM_STB_POWERGRAPH_64_VIDEO); +} + static int s3_phoenix_trio64vplus_available(void) { @@ -11063,6 +11082,21 @@ const device_t s3_phoenix_trio64_pci_device = { .config = s3_standard_config }; +const device_t s3_stb_powergraph_64_video_vlb_device = { + .name = "S3 Trio64V+ (STB PowerGraph 64 Video) VLB", + .name = "S3 Trio64V+ PCI (Phoenix)", + .internal_name = "px_trio64vplus_pci", + .flags = DEVICE_VLB, + .local = S3_STB_POWERGRAPH_64_VIDEO, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + { .available = s3_stb_powergraph_64_video_available }, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_standard_config +}; + const device_t s3_phoenix_trio64vplus_onboard_pci_device = { .name = "S3 Trio64V+ PCI On-Board (Phoenix)", .internal_name = "px_trio64vplus_onboard_pci", diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 1faa04783..5b9c3f8f3 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -254,6 +254,7 @@ video_cards[] = { { &s3_spea_mirage_p64_vlb_device }, { &s3_phoenix_vision968_vlb_device }, { &s3_phoenix_vision868_vlb_device }, + { &s3_stb_powergraph_64_video_vlb_device }, { &ht216_32_standalone_device }, { &tgui9400cxi_device }, { &tgui9440_vlb_device }, From 2fe92a2f26a5d176bc21395b2885fed48af563f8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Feb 2024 12:22:07 +0100 Subject: [PATCH 565/936] Fixed a typo in chipset/umc_8890.c. --- src/chipset/umc_8890.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chipset/umc_8890.c b/src/chipset/umc_8890.c index d515e1c97..7de2ca1d0 100644 --- a/src/chipset/umc_8890.c +++ b/src/chipset/umc_8890.c @@ -81,7 +81,7 @@ um8890_shadow(umc_8890_t *dev) if ((dev->mem_state[1] ^ dev->pci_conf[0x5f]) & 0x0c) { mem_set_mem_state_both(0xe0000, 0x10000, state); - dev->mem_state[1] = (dev->mem_state[2] & 0xf0) | (dev->pci_conf[0x5f] & 0x0f); + dev->mem_state[1] = (dev->mem_state[1] & 0xf0) | (dev->pci_conf[0x5f] & 0x0f); } flag = (dev->pci_conf[0x5f] & 0xc0) >> 6; From 46fbb3bb9ecbb94ad044dcaf9004cef105500222 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 22 Feb 2024 13:35:04 +0100 Subject: [PATCH 566/936] Video related changes: IBM/ATI 8514/A side: Made mode switches more immediate when actually switching from VGA to 8514/A and viceversa. Tseng ET4000AX/W32 series side: Actually use bit 2 of index 0x3f for the horizontal blank start bit 8 instead of bit 4 (horizontal retrace start), fixes skew issues with the et4000w32i rev B. card with resolutions like 1024x768 at 15 or 16bpp and others. --- src/video/vid_8514a.c | 2 +- src/video/vid_ati_mach8.c | 2 +- src/video/vid_et4000.c | 14 +++++++------- src/video/vid_et4000w32.c | 19 ++++++++----------- src/video/vid_svga.c | 6 +++--- 5 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index a94b974b0..ff1470164 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -4454,7 +4454,7 @@ ibm8514_init(const device_t *info) } #endif - timer_add(&svga->timer8514, ibm8514_poll, svga, 0); + timer_add(&svga->timer8514, ibm8514_poll, svga, 1); return svga; } diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index b49806177..3888e9c26 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -6057,7 +6057,7 @@ mach8_init(const device_t *info) } else ati_eeprom_load_mach8(&mach->eeprom, "mach8.nvr"); - timer_add(&svga->timer8514, ibm8514_poll, svga, 0); + timer_add(&svga->timer8514, ibm8514_poll, svga, 1); return mach; } diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index fa671e2f6..ae6b7ae82 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -650,22 +650,22 @@ et4000_recalctimings(svga_t *svga) svga->ma_latch |= (svga->crtc[0x33] & 3) << 16; - svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[2]; + svga->hblankstart = (((svga->crtc[0x3f] & 0x4) >> 2) << 8) + svga->crtc[2]; if (svga->crtc[0x35] & 1) - svga->vblankstart += 0x400; + svga->vblankstart |= 0x400; if (svga->crtc[0x35] & 2) - svga->vtotal += 0x400; + svga->vtotal |= 0x400; if (svga->crtc[0x35] & 4) - svga->dispend += 0x400; + svga->dispend |= 0x400; if (svga->crtc[0x35] & 8) - svga->vsyncstart += 0x400; + svga->vsyncstart |= 0x400; if (svga->crtc[0x35] & 0x10) - svga->split += 0x400; + svga->split |= 0x400; if (!svga->rowoffset) svga->rowoffset = 0x100; if (svga->crtc[0x3f] & 1) - svga->htotal += 256; + svga->htotal |= 0x100; if (svga->attrregs[0x16] & 0x20) { svga->hdisp <<= 1; svga->dots_per_clock <<= 1; diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 7adb6bc89..39b5b9ecc 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -432,22 +432,22 @@ et4000w32p_recalctimings(svga_t *svga) svga->ma_latch |= (svga->crtc[0x33] & 0x7) << 16; - svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[2]; + svga->hblankstart = (((svga->crtc[0x3f] & 0x4) >> 2) << 8) + svga->crtc[2]; if (svga->crtc[0x35] & 0x01) - svga->vblankstart += 0x400; + svga->vblankstart |= 0x400; if (svga->crtc[0x35] & 0x02) - svga->vtotal += 0x400; + svga->vtotal |= 0x400; if (svga->crtc[0x35] & 0x04) - svga->dispend += 0x400; + svga->dispend |= 0x400; if (svga->crtc[0x35] & 0x08) - svga->vsyncstart += 0x400; + svga->vsyncstart |= 0x400; if (svga->crtc[0x35] & 0x10) - svga->split += 0x400; + svga->split |= 0x400; if (svga->crtc[0x3F] & 0x80) - svga->rowoffset += 0x100; + svga->rowoffset |= 0x100; if (svga->crtc[0x3F] & 0x01) - svga->htotal += 256; + svga->htotal |= 0x100; if (svga->attrregs[0x16] & 0x20) { svga->hdisp <<= 1; svga->dots_per_clock <<= 1; @@ -535,9 +535,6 @@ et4000w32p_recalctimings(svga_t *svga) } else { switch (svga->gdcreg[5] & 0x60) { case 0x00: - if (et4000->rev == 5) - svga->ma_latch++; - if (svga->seqregs[1] & 8) /* Low res (320) */ svga->render = svga_render_4bpp_lowres; else diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index d60a5de0e..cbb7f12e8 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -899,7 +899,7 @@ svga_recalctimings(svga_t *svga) if (ibm8514_active && (svga->dev8514 != NULL)) { if (dev->on[0] || dev->on[1]) { - disptime8514 = dev->htotal; + disptime8514 = dev->h_total ? dev->h_total : TIMER_USEC; _dispontime8514 = dev->hdisped; } } @@ -934,10 +934,10 @@ svga_recalctimings(svga_t *svga) dev->dispofftime = TIMER_USEC; timer_disable(&svga->timer); - timer_enable(&svga->timer8514); + timer_set_delay_u64(&svga->timer8514, TIMER_USEC); } else { timer_disable(&svga->timer8514); - timer_enable(&svga->timer); + timer_set_delay_u64(&svga->timer, TIMER_USEC); } } From 4ee4e8f2b7feb4361127a34c99321d621fa1092e Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 23 Feb 2024 06:41:02 +0100 Subject: [PATCH 567/936] Fixed the flags and classification of some SiS machines, closes #4192. --- src/include/86box/machine.h | 3 +- src/machine/m_at_socket7.c | 29 ----------- src/machine/m_at_sockets7.c | 29 +++++++++++ src/machine/machine_table.c | 97 +++++++++++++++++++------------------ 4 files changed, 80 insertions(+), 78 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 6817a0de5..e27a70d79 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -732,7 +732,6 @@ extern int machine_at_ms5164_init(const machine_t *); extern int machine_at_sp97xv_init(const machine_t *); extern int machine_at_sq578_init(const machine_t *); -extern int machine_at_5sg100_init(const machine_t *); extern int machine_at_ms5172_init(const machine_t *); /* m_at_sockets7.c */ @@ -747,6 +746,8 @@ extern int machine_at_mvp3_init(const machine_t *); extern int machine_at_ficva503a_init(const machine_t *); extern int machine_at_5emapro_init(const machine_t *); +extern int machine_at_5sg100_init(const machine_t *); + /* m_at_socket8.c */ extern int machine_at_ap61_init(const machine_t *); extern int machine_at_p6rp4_init(const machine_t *); diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 09441ad4f..9ab24b7c2 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -1324,35 +1324,6 @@ machine_at_sq578_init(const machine_t *model) return ret; } -int -machine_at_5sg100_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/5sg100/5sg.20g", - 0x000e0000, 131072, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); - device_add(&sis_5591_1997_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&w83877tf_device); - device_add(&sst_flash_29ee010_device); - - return ret; -} - int machine_at_ms5172_init(const machine_t *model) { diff --git a/src/machine/m_at_sockets7.c b/src/machine/m_at_sockets7.c index 8ff1a367d..32319e160 100644 --- a/src/machine/m_at_sockets7.c +++ b/src/machine/m_at_sockets7.c @@ -337,3 +337,32 @@ machine_at_5emapro_init(const machine_t *model) return ret; } + +int +machine_at_5sg100_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/5sg100/5sg.20g", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); + device_add(&sis_5591_1997_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83877tf_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index beac1cf6e..6251f171f 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -12349,8 +12349,8 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .bus_flags = MACHINE_PS2_AGP, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1572864, @@ -12389,8 +12389,8 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .bus_flags = MACHINE_PS2_AGP, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1572864, @@ -12409,49 +12409,8 @@ const machine_t machines[] = { .net_device = NULL }, - /* SiS 5591 */ /* Has the SiS 5591 chipset with on-chip KBC. */ - { - .name = "[SiS 5591] Gigabyte GA-5SG100", - .internal_name = "5sg100", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_SIS_5591, - .init = machine_at_5sg100_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 = 75000000, - .min_voltage = 2500, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 786432, - .step = 1024 - }, - .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 = NULL, - .net_device = NULL - }, - /* Has the SiS 5591 chipset with on-chip KBC. */ { .name = "[SiS 5591] MSI MS-5172", .internal_name = "ms5172", @@ -12472,8 +12431,8 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .bus_flags = MACHINE_PS2_AGP, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -12944,6 +12903,48 @@ const machine_t machines[] = { .net_device = NULL }, + /* SiS 5591 */ + /* Has the SiS 5591 chipset with on-chip KBC. */ + { + .name = "[SiS 5591] Gigabyte GA-5SG100", + .internal_name = "5sg100", + .type = MACHINE_TYPE_SOCKETS7, + .chipset = MACHINE_CHIPSET_SIS_5591, + .init = machine_at_5sg100_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 = 66666667, + .max_bus = 100000000, + .min_voltage = 2000, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_AGP, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 1024 + }, + .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 = NULL, + .net_device = NULL + }, + /* Socket 8 machines */ /* 450KX */ /* This has an AMIKey-2, which is an updated version of type 'H'. */ @@ -14412,7 +14413,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PS2_AGP, .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: Ensoniq ES1373 */ .ram = { .min = 8192, From 6de7c7cd5e5f5144486606143e1615b1c426fb83 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 23 Feb 2024 07:10:15 +0100 Subject: [PATCH 568/936] Fixed LOCK legality with prefixes, closes #4189. --- src/cpu/386.c | 3 + src/cpu/386_common.c | 50 ++++++++++- src/cpu/808x.c | 2 - src/cpu/cpu.h | 4 + src/cpu/x86.c | 4 + src/cpu/x86_ops_misc.h | 37 +-------- src/cpu/x86_ops_prefix_2386.h | 151 +++++++++++++++++++++++++++++----- 7 files changed, 193 insertions(+), 58 deletions(-) diff --git a/src/cpu/386.c b/src/cpu/386.c index ad310d31e..5379dccf9 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -280,7 +280,10 @@ exec386_2386(int32_t cycs) cpu_state.pc++; cpu_state.eflags &= ~(RF_FLAG); + if (opcode == 0xf0) + in_lock = 1; x86_2386_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + in_lock = 0; if (x86_was_reset) break; } diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 0abf8e936..5c1b95e0f 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -123,11 +123,11 @@ int opcode_length[256] = { 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, /* /* 0 = no, 1 = always, 2 = depends on second opcode, 3 = depends on mod/rm */ int lock_legal[256] = { 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 2, /* 0x0x */ 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, /* 0x1x */ - 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, /* 0x2x */ - 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x3x */ + 1, 1, 1, 1, 1, 1, 4, 0, 1, 1, 1, 1, 1, 1, 4, 0, /* 0x2x */ + 1, 1, 1, 1, 1, 1, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, /* 0x3x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x4x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x5x */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x6x */ + 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x6x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x7x */ 3, 3, 3, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x8x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9x */ @@ -423,6 +423,50 @@ x386_common_log(const char *fmt, ...) # define x386_common_log(fmt, ...) #endif +int +is_lock_legal(uint32_t fetchdat) +{ + int legal; + fetch_dat_t fetch_dat; + + fetch_dat.fd = fetchdat; + + legal = lock_legal[fetch_dat.b[0]]; + if (legal == 1) + legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + else if (legal == 2) { + legal = lock_legal_0f[fetch_dat.b[1]]; + if (legal == 1) + legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,reg is illegal */ + else if (legal == 3) { + legal = lock_legal_ba[(fetch_dat.b[2] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,imm is illegal */ + } + } else if (legal == 3) switch(fetch_dat.b[0]) { + case 0x80 ... 0x83: + legal = lock_legal_80[(fetch_dat.b[1] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + break; + case 0xf6 ... 0xf7: + legal = lock_legal_f6[(fetch_dat.b[1] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + break; + case 0xfe ... 0xff: + legal = lock_legal_fe[(fetch_dat.b[1] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + break; + default: + legal = 0; + break; + } + + return legal; +} + /*Prefetch emulation is a fairly simplistic model: - All instruction bytes must be fetched before it starts. - Cycles used for non-instruction memory accesses are counted and subtracted diff --git a/src/cpu/808x.c b/src/cpu/808x.c index 90563d9ab..caff0fa60 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -56,7 +56,6 @@ static uint32_t *opseg[4]; static x86seg *_opseg[4]; static int noint = 0; -static int in_lock = 0; static int cpu_alu_op, pfq_size; static uint32_t cpu_src = 0, cpu_dest = 0; @@ -545,7 +544,6 @@ reset_808x(int hard) { biu_cycles = 0; in_rep = 0; - in_lock = 0; completed = 1; repeating = 0; clear_lock = 0; diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 1456d2ee8..16a9eba10 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -829,4 +829,8 @@ extern int lock_legal_80[8]; extern int lock_legal_f6[8]; extern int lock_legal_fe[8]; +extern int in_lock; + +extern int is_lock_legal(uint32_t fetchdat); + #endif /*EMU_CPU_H*/ diff --git a/src/cpu/x86.c b/src/cpu/x86.c index 2c8c29d49..cf2867182 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -80,6 +80,8 @@ int hlt_reset_pending; int fpu_cycles = 0; +int in_lock = 0; + #ifdef ENABLE_X86_LOG void dumpregs(int); @@ -351,6 +353,8 @@ reset_common(int hard) if (!is286) reset_808x(hard); + in_lock = 0; + cpu_cpurst_on_sr = 0; } diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index dd05fb9d9..519bdbe3c 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -731,46 +731,15 @@ static int opLOCK(uint32_t fetchdat) { int legal; - fetch_dat_t fetch_dat; fetchdat = fastreadl_fetch(cs + cpu_state.pc); if (cpu_state.abrt) return 0; cpu_state.pc++; - fetch_dat.fd = fetchdat; + legal = is_lock_legal(fetchdat); - legal = lock_legal[fetch_dat.b[0]]; - if (legal == 1) - legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ - else if (legal == 2) { - legal = lock_legal_0f[fetch_dat.b[1]]; - if (legal == 1) - legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,reg is illegal */ - else if (legal == 3) { - legal = lock_legal_ba[(fetch_dat.b[2] >> 3) & 0x07]; - if (legal == 1) - legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,imm is illegal */ - } - } else if (legal == 3) switch(fetch_dat.b[0]) { - case 0x80 ... 0x83: - legal = lock_legal_80[(fetch_dat.b[1] >> 3) & 0x07]; - if (legal == 1) - legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ - break; - case 0xf6 ... 0xf7: - legal = lock_legal_f6[(fetch_dat.b[1] >> 3) & 0x07]; - if (legal == 1) - legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ - break; - case 0xfe ... 0xff: - legal = lock_legal_fe[(fetch_dat.b[1] >> 3) & 0x07]; - if (legal == 1) - legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ - break; - default: - legal = 0; - break; - } + if (legal == 4) + pclog("PREFIX: F0 %08X\n", fetchdat); ILLEGAL_ON(legal == 0); diff --git a/src/cpu/x86_ops_prefix_2386.h b/src/cpu/x86_ops_prefix_2386.h index 7c87f0bf3..87d114944 100644 --- a/src/cpu/x86_ops_prefix_2386.h +++ b/src/cpu/x86_ops_prefix_2386.h @@ -1,4 +1,110 @@ #define op_seg(name, seg, opcode_table, normal_opcode_table) \ + static int op##name##_w_a16(uint32_t fetchdat) \ + { \ + int legal; \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + if (in_lock) { \ + legal = is_lock_legal(fetchdat); \ + \ + ILLEGAL_ON(legal == 0); \ + } \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[fetchdat & 0xff]) \ + return opcode_table[fetchdat & 0xff](fetchdat >> 8); \ + return normal_opcode_table[fetchdat & 0xff](fetchdat >> 8); \ + } \ + \ + static int op##name##_l_a16(uint32_t fetchdat) \ + { \ + int legal; \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + if (in_lock) { \ + legal = is_lock_legal(fetchdat); \ + \ + ILLEGAL_ON(legal == 0); \ + } \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x100]) \ + return opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ + return normal_opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ + } \ + \ + static int op##name##_w_a32(uint32_t fetchdat) \ + { \ + int legal; \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + if (in_lock) { \ + legal = is_lock_legal(fetchdat); \ + \ + ILLEGAL_ON(legal == 0); \ + } \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x200]) \ + return opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ + return normal_opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ + } \ + \ + static int op##name##_l_a32(uint32_t fetchdat) \ + { \ + int legal; \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + if (in_lock) { \ + legal = is_lock_legal(fetchdat); \ + \ + ILLEGAL_ON(legal == 0); \ + } \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x300]) \ + return opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ + return normal_opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ + } + +// clang-format off +op_seg(CS, cpu_state.seg_cs, x86_2386_opcodes, x86_2386_opcodes) +op_seg(DS, cpu_state.seg_ds, x86_2386_opcodes, x86_2386_opcodes) +op_seg(ES, cpu_state.seg_es, x86_2386_opcodes, x86_2386_opcodes) +op_seg(FS, cpu_state.seg_fs, x86_2386_opcodes, x86_2386_opcodes) +op_seg(GS, cpu_state.seg_gs, x86_2386_opcodes, x86_2386_opcodes) +op_seg(SS, cpu_state.seg_ss, x86_2386_opcodes, x86_2386_opcodes) + // clang-format on + +#define op_srp(name, seg, opcode_table, normal_opcode_table) \ static int op##name##_w_a16(uint32_t fetchdat) \ { \ fetchdat = fastreadl(cs + cpu_state.pc); \ @@ -68,36 +174,36 @@ } // clang-format off -op_seg(CS, cpu_state.seg_cs, x86_2386_opcodes, x86_2386_opcodes) -op_seg(DS, cpu_state.seg_ds, x86_2386_opcodes, x86_2386_opcodes) -op_seg(ES, cpu_state.seg_es, x86_2386_opcodes, x86_2386_opcodes) -op_seg(FS, cpu_state.seg_fs, x86_2386_opcodes, x86_2386_opcodes) -op_seg(GS, cpu_state.seg_gs, x86_2386_opcodes, x86_2386_opcodes) -op_seg(SS, cpu_state.seg_ss, x86_2386_opcodes, x86_2386_opcodes) +op_srp(CS_REPE, cpu_state.seg_cs, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_srp(DS_REPE, cpu_state.seg_ds, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_srp(ES_REPE, cpu_state.seg_es, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_srp(FS_REPE, cpu_state.seg_fs, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_srp(GS_REPE, cpu_state.seg_gs, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_srp(SS_REPE, cpu_state.seg_ss, x86_2386_opcodes_REPE, x86_2386_opcodes) -op_seg(CS_REPE, cpu_state.seg_cs, x86_2386_opcodes_REPE, x86_2386_opcodes) -op_seg(DS_REPE, cpu_state.seg_ds, x86_2386_opcodes_REPE, x86_2386_opcodes) -op_seg(ES_REPE, cpu_state.seg_es, x86_2386_opcodes_REPE, x86_2386_opcodes) -op_seg(FS_REPE, cpu_state.seg_fs, x86_2386_opcodes_REPE, x86_2386_opcodes) -op_seg(GS_REPE, cpu_state.seg_gs, x86_2386_opcodes_REPE, x86_2386_opcodes) -op_seg(SS_REPE, cpu_state.seg_ss, x86_2386_opcodes_REPE, x86_2386_opcodes) - -op_seg(CS_REPNE, cpu_state.seg_cs, x86_2386_opcodes_REPNE, x86_2386_opcodes) -op_seg(DS_REPNE, cpu_state.seg_ds, x86_2386_opcodes_REPNE, x86_2386_opcodes) -op_seg(ES_REPNE, cpu_state.seg_es, x86_2386_opcodes_REPNE, x86_2386_opcodes) -op_seg(FS_REPNE, cpu_state.seg_fs, x86_2386_opcodes_REPNE, x86_2386_opcodes) -op_seg(GS_REPNE, cpu_state.seg_gs, x86_2386_opcodes_REPNE, x86_2386_opcodes) -op_seg(SS_REPNE, cpu_state.seg_ss, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_srp(CS_REPNE, cpu_state.seg_cs, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_srp(DS_REPNE, cpu_state.seg_ds, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_srp(ES_REPNE, cpu_state.seg_es, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_srp(FS_REPNE, cpu_state.seg_fs, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_srp(GS_REPNE, cpu_state.seg_gs, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_srp(SS_REPNE, cpu_state.seg_ss, x86_2386_opcodes_REPNE, x86_2386_opcodes) // clang-format on static int op_66(uint32_t fetchdat) /*Data size select*/ { + int legal; fetchdat = fastreadl(cs + cpu_state.pc); if (cpu_state.abrt) return 1; cpu_state.pc++; + if (in_lock) { + legal = is_lock_legal(fetchdat); + + ILLEGAL_ON(legal == 0); + } + cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); CLOCK_CYCLES(2); PREFETCH_PREFIX(); @@ -106,11 +212,18 @@ op_66(uint32_t fetchdat) /*Data size select*/ static int op_67(uint32_t fetchdat) /*Address size select*/ { + int legal; fetchdat = fastreadl(cs + cpu_state.pc); if (cpu_state.abrt) return 1; cpu_state.pc++; + if (in_lock) { + legal = is_lock_legal(fetchdat); + + ILLEGAL_ON(legal == 0); + } + cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); CLOCK_CYCLES(2); PREFETCH_PREFIX(); From 5c1cdb3c457d8b99d3ac0f65226d4bc3a4e18e85 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 23 Feb 2024 07:13:02 +0100 Subject: [PATCH 569/936] Bump version to 4.1.1. --- src/include_make/86box/version.h | 4 ++-- src/unix/assets/86Box.spec | 4 ++-- src/unix/assets/net.86box.86Box.metainfo.xml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/include_make/86box/version.h b/src/include_make/86box/version.h index 4004f58b3..4bb6c71d7 100644 --- a/src/include_make/86box/version.h +++ b/src/include_make/86box/version.h @@ -22,12 +22,12 @@ #define EMU_NAME "86Box" #define EMU_NAME_W LSTR(EMU_NAME) -#define EMU_VERSION "4.1" +#define EMU_VERSION "4.1.1" #define EMU_VERSION_W LSTR(EMU_VERSION) #define EMU_VERSION_EX "3.50" /* frozen due to IDE re-detection behavior on Windows */ #define EMU_VERSION_MAJ 4 #define EMU_VERSION_MIN 1 -#define EMU_VERSION_PATCH 0 +#define EMU_VERSION_PATCH 1 #define EMU_BUILD_NUM 0 diff --git a/src/unix/assets/86Box.spec b/src/unix/assets/86Box.spec index a7e4786be..99d01c594 100644 --- a/src/unix/assets/86Box.spec +++ b/src/unix/assets/86Box.spec @@ -15,7 +15,7 @@ %global romver 4.1 Name: 86Box -Version: 4.1 +Version: 4.1.1 Release: 1%{?dist} Summary: Classic PC emulator License: GPLv2+ @@ -121,5 +121,5 @@ popd %{_datadir}/%{name}/roms %changelog -* Mon Oct 16 2023 Robert de Rooy 4.1-1 +* Fri Feb 23 2024 Robert de Rooy 4.1.1-1 - Bump release diff --git a/src/unix/assets/net.86box.86Box.metainfo.xml b/src/unix/assets/net.86box.86Box.metainfo.xml index 9e2c5dc88..7602ffb11 100644 --- a/src/unix/assets/net.86box.86Box.metainfo.xml +++ b/src/unix/assets/net.86box.86Box.metainfo.xml @@ -10,7 +10,7 @@ net.86box.86Box.desktop - + From b55c7b91ddaca9962c060ef6f1d2c8f4100e5a84 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 23 Feb 2024 07:23:52 +0100 Subject: [PATCH 570/936] The forgotten version bumped files. --- CMakeLists.txt | 2 +- debian/changelog | 4 ++-- vcpkg.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 196952cb4..cacf1aaa4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,7 @@ if(MUNT_EXTERNAL) endif() project(86Box - VERSION 4.1 + VERSION 4.1.1 DESCRIPTION "Emulator of x86-based systems" HOMEPAGE_URL "https://86box.net" LANGUAGES C CXX) diff --git a/debian/changelog b/debian/changelog index 29ec6d3af..00179d466 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ -86box (4.1) UNRELEASED; urgency=medium +86box (4.1.1) UNRELEASED; urgency=medium * Bump release. - -- Jasmine Iwanek Mon, 16 Oct 2023 20:24:46 +0200 + -- Jasmine Iwanek Fri, 23 Feb 2024 07:23:12 +0100 diff --git a/vcpkg.json b/vcpkg.json index 5fdfc175b..d7d7ffd82 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,6 +1,6 @@ { "name": "86box", - "version-string": "4.1", + "version-string": "4.1.1", "homepage": "https://86box.net/", "documentation": "https://86box.readthedocs.io/", "license": "GPL-2.0-or-later", From a893aba1caa387f5c0045664f43c762ec38755cb Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 23 Feb 2024 14:27:26 +0600 Subject: [PATCH 571/936] S3 ViRGE: Respect blend control compose modes on pre-GX2 ViRGE Fixes video overlay staying on-screen on Linux. --- src/video/vid_s3_virge.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index be6382ec9..9277be24a 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -918,6 +918,10 @@ s3_virge_recalctimings(svga_t *svga) svga->overlay.v_acc = virge->streams.dda_vert_accumulator; svga->rowoffset = virge->streams.pri_stride >> 3; + if (virge->chip <= S3_VIRGEDX && svga->overlay.ena) { + svga->overlay.ena = (((virge->streams.blend_ctrl >> 24) & 7) == 0b000) || (((virge->streams.blend_ctrl >> 24) & 7) == 0b101); + } + switch ((virge->streams.pri_ctrl >> 24) & 0x7) { case 0: /*RGB-8 (CLUT)*/ svga->render = svga_render_8bpp_highres; @@ -1963,6 +1967,7 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) break; case 0x81a0: virge->streams.blend_ctrl = val; + svga_recalctimings(svga); break; case 0x81c0: virge->streams.pri_fb0 = val & 0x7fffff; From 45dff17d58c578791e0578486a5705cd3e2bed03 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 23 Feb 2024 16:25:50 +0600 Subject: [PATCH 572/936] S3 ViRGE/GX2: Fix screen overlay staying on Windows XP --- src/video/vid_s3_virge.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 9277be24a..398284d99 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -920,6 +920,10 @@ s3_virge_recalctimings(svga_t *svga) if (virge->chip <= S3_VIRGEDX && svga->overlay.ena) { svga->overlay.ena = (((virge->streams.blend_ctrl >> 24) & 7) == 0b000) || (((virge->streams.blend_ctrl >> 24) & 7) == 0b101); + } else if (virge->chip == S3_VIRGEGX2 && svga->overlay.ena) { + /* 0x20 = Secondary Stream enabled */ + /* 0x2000 = Primary Stream enabled */ + svga->overlay.ena = !!(virge->streams.blend_ctrl & 0x20) && (svga->crtc[0x67] & 0xC); } switch ((virge->streams.pri_ctrl >> 24) & 0x7) { From 181ffbcffb5da1a80ebf4f83662028e39ba31145 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 23 Feb 2024 20:47:27 +0600 Subject: [PATCH 573/936] S3 ViRGE: a bit of cleanup --- src/video/vid_s3_virge.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 398284d99..52184d88b 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -893,6 +893,7 @@ s3_virge_recalctimings(svga_t *svga) } } svga->vram_display_mask = (!(svga->crtc[0x31] & 0x08) && (svga->crtc[0x32] & 0x40)) ? 0x3ffff : virge->vram_mask; + svga->overlay.ena = 0; s3_virge_log("VGA mode\n"); } else /*Streams mode*/ { @@ -923,7 +924,7 @@ s3_virge_recalctimings(svga_t *svga) } else if (virge->chip == S3_VIRGEGX2 && svga->overlay.ena) { /* 0x20 = Secondary Stream enabled */ /* 0x2000 = Primary Stream enabled */ - svga->overlay.ena = !!(virge->streams.blend_ctrl & 0x20) && (svga->crtc[0x67] & 0xC); + svga->overlay.ena = !!(virge->streams.blend_ctrl & 0x20); } switch ((virge->streams.pri_ctrl >> 24) & 0x7) { From c57dfed4e7595102a83a6cacab3868544610ccb6 Mon Sep 17 00:00:00 2001 From: cartifanwlr Date: Fri, 23 Feb 2024 18:41:41 +0300 Subject: [PATCH 574/936] Fix the internal name of the S3 Trio64V+ VLB --- src/video/vid_s3.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 46ed8eba0..c526ecf62 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -11084,8 +11084,7 @@ const device_t s3_phoenix_trio64_pci_device = { const device_t s3_stb_powergraph_64_video_vlb_device = { .name = "S3 Trio64V+ (STB PowerGraph 64 Video) VLB", - .name = "S3 Trio64V+ PCI (Phoenix)", - .internal_name = "px_trio64vplus_pci", + .internal_name = "stb_trio64vplus_vlb", .flags = DEVICE_VLB, .local = S3_STB_POWERGRAPH_64_VIDEO, .init = s3_init, From 9124e8165b2f785689c3bc588acf767302665414 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 23 Feb 2024 17:02:42 +0100 Subject: [PATCH 575/936] Removed the incorrect usage of CRTC register 3 bits 5 and 6. --- src/video/vid_et4000.c | 2 +- src/video/vid_svga.c | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index ae6b7ae82..5fe524fd8 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -745,7 +745,7 @@ et4000_kasan_recalctimings(svga_t *svga) if (svga->render == svga_render_text_80 && (et4000->kasan_cfg_regs[0] & 8)) { svga->hdisp += svga->dots_per_clock; - svga->ma_latch -= 5; + svga->ma_latch -= 4; svga->ca_adj = (et4000->kasan_cfg_regs[0] >> 6) - 3; svga->ksc5601_sbyte_mask = (et4000->kasan_cfg_regs[0] & 4) << 5; if ((et4000->kasan_cfg_regs[0] & 0x23) == 0x20 && (et4000->kasan_cfg_regs[4] & 0x80) && ((svga->crtc[0x37] & 0x0B) == 0x0A)) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index cbb7f12e8..b20364689 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1158,9 +1158,9 @@ svga_poll(void *priv) if (ret) { if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = (svga->rowoffset << 1) + ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub; + svga->ma = svga->maback = (svga->rowoffset << 1) + svga->hblank_sub; else - svga->ma = svga->maback = ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub; + svga->ma = svga->maback = svga->hblank_sub; svga->ma = (svga->ma << 2); svga->maback = (svga->maback << 2); @@ -1230,10 +1230,9 @@ svga_poll(void *priv) svga->vslines = 0; if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + - ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub; + svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + svga->hblank_sub; else - svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub; + svga->ma = svga->maback = svga->ma_latch + svga->hblank_sub; svga->ca = ((svga->crtc[0xe] << 8) | svga->crtc[0xf]) + ((svga->crtc[0xb] & 0x60) >> 5) + svga->ca_adj; svga->ma = (svga->ma << 2); From 25203be56ad77b709a3cb7736a99fa9088e1e61b Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 23 Feb 2024 17:35:54 +0100 Subject: [PATCH 576/936] Change the default hard disk image format to fixed-size VHD. --- src/qt/qt_harddiskdialog.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/qt/qt_harddiskdialog.hpp b/src/qt/qt_harddiskdialog.hpp index 9de61c51b..300f1381d 100644 --- a/src/qt/qt_harddiskdialog.hpp +++ b/src/qt/qt_harddiskdialog.hpp @@ -55,7 +55,9 @@ private: QStringList filters; // "Dynamic-size VHD" is number 4 in the `filters` list and the // comboBoxFormat model - const uint8_t DEFAULT_DISK_FORMAT = 4; + // Temporary change to fixed-size VHD due to MiniVHD's handling of + // dynamic-size VHD being buggy. + const uint8_t DEFAULT_DISK_FORMAT = 3; bool checkAndAdjustCylinders(); bool checkAndAdjustHeads(); From f417a347a6075905402ed4c3dc1918a572811780 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 23 Feb 2024 18:13:52 +0100 Subject: [PATCH 577/936] Revert the default hard disk format change. --- src/qt/qt_harddiskdialog.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/qt/qt_harddiskdialog.hpp b/src/qt/qt_harddiskdialog.hpp index 300f1381d..9de61c51b 100644 --- a/src/qt/qt_harddiskdialog.hpp +++ b/src/qt/qt_harddiskdialog.hpp @@ -55,9 +55,7 @@ private: QStringList filters; // "Dynamic-size VHD" is number 4 in the `filters` list and the // comboBoxFormat model - // Temporary change to fixed-size VHD due to MiniVHD's handling of - // dynamic-size VHD being buggy. - const uint8_t DEFAULT_DISK_FORMAT = 3; + const uint8_t DEFAULT_DISK_FORMAT = 4; bool checkAndAdjustCylinders(); bool checkAndAdjustHeads(); From b49cd0baf42af4ad1dfd7264f869dfa292c53397 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 24 Feb 2024 02:51:42 +0600 Subject: [PATCH 578/936] S3 ViRGE: Buffer flips no longer trigger recalctimings --- src/video/vid_s3_virge.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 52184d88b..a4cec9c09 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -835,6 +835,7 @@ s3_virge_recalctimings(svga_t *svga) /* Also make sure vertical blanking starts on display end. */ svga->vblankstart = svga->dispend; + video_force_resize_set_monitor(1, svga->monitor_index); } else { svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2]; @@ -959,6 +960,27 @@ s3_virge_recalctimings(svga_t *svga) } } +static void +s3_virge_update_buffer(virge_t *virge) +{ + svga_t *svga = &virge->svga; + + if ((svga->crtc[0x67] & 0xc) != 0xc) + return; + + if (virge->streams.buffer_ctrl & 1) + svga->ma_latch = virge->streams.pri_fb1 >> 2; + else + svga->ma_latch = virge->streams.pri_fb0 >> 2; + + if (virge->streams.buffer_ctrl & 2) + svga->overlay.addr = virge->streams.sec_fb1; + else + svga->overlay.addr = virge->streams.sec_fb0; + + svga->rowoffset = virge->streams.pri_stride >> 3; +} + static void s3_virge_updatemapping(virge_t *virge) { @@ -1976,37 +1998,36 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) break; case 0x81c0: virge->streams.pri_fb0 = val & 0x7fffff; - svga_recalctimings(svga); + s3_virge_update_buffer(virge); svga->fullchange = changeframecount; break; case 0x81c4: virge->streams.pri_fb1 = val & 0x7fffff; - svga_recalctimings(svga); + s3_virge_update_buffer(virge); svga->fullchange = changeframecount; break; case 0x81c8: virge->streams.pri_stride = val & 0xfff; - svga_recalctimings(svga); + s3_virge_update_buffer(virge); svga->fullchange = changeframecount; break; case 0x81cc: virge->streams.buffer_ctrl = val; - svga_recalctimings(svga); + s3_virge_update_buffer(virge); svga->fullchange = changeframecount; break; case 0x81d0: virge->streams.sec_fb0 = val; - svga_recalctimings(svga); + s3_virge_update_buffer(virge); svga->fullchange = changeframecount; break; case 0x81d4: virge->streams.sec_fb1 = val; - svga_recalctimings(svga); + s3_virge_update_buffer(virge); svga->fullchange = changeframecount; break; case 0x81d8: virge->streams.sec_stride = val; - svga_recalctimings(svga); svga->fullchange = changeframecount; break; case 0x81dc: From 1d2f8937b76803e964798956177bd602a0bf1810 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 24 Feb 2024 04:57:35 +0100 Subject: [PATCH 579/936] SiS 5581 machines are not supposed to support AGP. --- src/machine/machine_table.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 6251f171f..da3dc01e4 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -12349,7 +12349,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_PCI, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, @@ -12389,7 +12389,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_AGP, + .bus_flags = MACHINE_PS2_PCI, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, From 6b435088f9dd3cdd70d2a33f4aca12ee6a3d36fd Mon Sep 17 00:00:00 2001 From: rilysh Date: Sat, 24 Feb 2024 13:59:14 +0530 Subject: [PATCH 580/936] unix_serial_passthrough.c: check errno for EWOULDBLOCK plat_serpt_write_vcon(): write() returns how much data it has written to the file descriptor, and in case an error, it returns -1. So the EWOULDBLOCK never really triggers, as in the following condition we're not checking the errno, but the return value of the write() function. --- src/unix/unix_serial_passthrough.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/unix/unix_serial_passthrough.c b/src/unix/unix_serial_passthrough.c index d80f8a1e7..646b77d6c 100644 --- a/src/unix/unix_serial_passthrough.c +++ b/src/unix/unix_serial_passthrough.c @@ -112,7 +112,7 @@ plat_serpt_write_vcon(serial_passthrough_t *dev, uint8_t data) if (dev->mode == SERPT_MODE_HOSTSER) { do { res = write(dev->master_fd, &data, 1); - } while (res == 0 || (res == -1 && (errno == EAGAIN || res == EWOULDBLOCK))); + } while (res == 0 || (res == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))); } else res = write(dev->master_fd, &data, 1); } From 52ffbe582fe5a252bc07d02996c21366a3c95423 Mon Sep 17 00:00:00 2001 From: AsciiWolf Date: Sat, 24 Feb 2024 14:08:26 +0100 Subject: [PATCH 581/936] Fix AppStream metainfo file --- src/unix/assets/net.86box.86Box.metainfo.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/unix/assets/net.86box.86Box.metainfo.xml b/src/unix/assets/net.86box.86Box.metainfo.xml index 7602ffb11..1f15f39a5 100644 --- a/src/unix/assets/net.86box.86Box.metainfo.xml +++ b/src/unix/assets/net.86box.86Box.metainfo.xml @@ -4,9 +4,10 @@ CC0-1.0 GPL-2.0-or-later 86Box + 86Box developers An emulator for classic IBM PC clones - Emulation + Emulator net.86box.86Box.desktop From 1dfb6fd111482173f43f44941545ffe240a434ed Mon Sep 17 00:00:00 2001 From: rilysh Date: Sat, 24 Feb 2024 23:19:32 +0530 Subject: [PATCH 582/936] bswap.h: fix GCC requirements for bswap* builtins 1. __builtin_bswap{32,64} were added in GCC 4.3, and __builtin_bswap16 was added in GCC 4.8, however, currently, the GCC requirements in bswap.h file has >= 10. This requirement of GCC version is false for bswap* but true for __has_builtin() (as it first was added in GCC 10.1). As bswap* builtins were added before GCC 10, the preprocessor check will always going to be true for bswap but will be false if GCC version is < 10 as __has_builtin() won't be present. Since the byteswap function, on x86-64, can boil down to a single bswap instruction, this optimization may left behind (unless GCC do some pattern matching). To avoid this, just use the compiler macros (for GCC: __GNUC__, clang: __GNUC__ or __clang__) and if the compiler is neither GCC or Clang, fall-back to native implementation. 2. Remove the useless casts (uint{16,32,64}_t) from the constants. These constants already has their own suffix, and casting to a different type will just get ignored as the return value already gets casts to it's appropriate type. 3. Previously, Clang couldn't able to use __builtin_bswap* (even if it was newer) as LLVM define __GNUC__ macro to a specific constant (usually lower than GCC's (__GNUC__) and on my system it's 4) which is indeed < 10. The first comment also fixes this issue. Link: Link: Link: --- src/include/86box/bswap.h | 94 ++++++++++++--------------------------- 1 file changed, 28 insertions(+), 66 deletions(-) diff --git a/src/include/86box/bswap.h b/src/include/86box/bswap.h index ac758b20a..78183d137 100644 --- a/src/include/86box/bswap.h +++ b/src/include/86box/bswap.h @@ -40,91 +40,55 @@ #include -#ifdef HAVE_BYTESWAP_H -# include -#else -# define bswap_16(x) \ - ( \ - ((uint16_t)( \ - (((uint16_t)(x) & (uint16_t)0x00ffU) << 8) | \ - (((uint16_t)(x) & (uint16_t)0xff00U) >> 8) )) \ - ) +#define bswap_16(x) \ + ((uint16_t)((((x) & 0x00ffu) << 8) | \ + (((x) & 0xff00u) >> 8))) -# define bswap_32(x) \ - ( \ - ((uint32_t)( \ - (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \ - (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \ - (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \ - (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24) )) \ - ) +#define bswap_32(x) \ + ((uint32_t)((((x) & 0x000000fful) << 24) | \ + (((x) & 0x0000ff00ul) << 8) | \ + (((x) & 0x00ff0000ul) >> 8) | \ + (((x) & 0xff000000ul) >> 24))) -# define bswap_64(x) \ - ( \ - ((uint64_t)( \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56) )) \ - ) -#endif /*HAVE_BYTESWAP_H*/ +# define bswap_64(x) \ + ((uint64_t)((((x) & 0x00000000000000ffull) << 56) | \ + (((x) & 0x000000000000ff00ull) << 40) | \ + (((x) & 0x0000000000ff0000ull) << 24) | \ + (((x) & 0x00000000ff000000ull) << 8) | \ + (((x) & 0x000000ff00000000ull) >> 8) | \ + (((x) & 0x0000ff0000000000ull) >> 24) | \ + (((x) & 0x00ff000000000000ull) >> 40) | \ + (((x) & 0xff00000000000000ull) >> 56))) -#if __GNUC__ >= 10 -#if defined __has_builtin && __has_builtin(__builtin_bswap16) -#define bswap16(x) __builtin_bswap16(x) -#else -static __inline uint16_t bswap16(uint16_t x) -{ - return bswap_16(x); -} -# endif -#else static __inline uint16_t bswap16(uint16_t x) { +#if defined (__GNUC__) || defined (__clang__) + return __builtin_bswap16(x); +#else return bswap_16(x); -} #endif +} -#if __GNUC__ >= 10 -# if defined __has_builtin && __has_builtin(__builtin_bswap32) -# define bswap32(x) __builtin_bswap32(x) -# else static __inline uint32_t bswap32(uint32_t x) { - return bswap_32(x); -} -# endif +#if defined (__GNUC__) || defined (__clang__) + return __builtin_bswap32(x); #else -static __inline uint32_t -bswap32(uint32_t x) -{ return bswap_32(x); -} #endif +} -#if __GNUC__ >= 10 -# if defined __has_builtin && __has_builtin(__builtin_bswap64) -# define bswap64(x) __builtin_bswap64(x) -# else static __inline uint64_t bswap64(uint64_t x) { - return bswap_64(x); -} -# endif +#if defined (__GNUC__) || defined (__clang__) + return __builtin_bswap64(x); #else -static __inline uint64_t -bswap64(uint64_t x) -{ - return bswap_64(x); -} + return bswap_16(x); #endif +} static __inline void bswap16s(uint16_t *s) @@ -198,12 +162,10 @@ CPU_CONVERT(le, 64, uint64_t) /* unaligned versions (optimized for frequent unaligned accesses)*/ #if defined(__i386__) || defined(__powerpc__) - # define cpu_to_le16wu(p, v) cpu_to_le16w(p, v) # define cpu_to_le32wu(p, v) cpu_to_le32w(p, v) # define le16_to_cpupu(p) le16_to_cpup(p) # define le32_to_cpupu(p) le32_to_cpup(p) - # define cpu_to_be16wu(p, v) cpu_to_be16w(p, v) # define cpu_to_be32wu(p, v) cpu_to_be32w(p, v) From 21230f933ebd4eafc9aeb375d93676b478716364 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 24 Feb 2024 21:50:01 +0100 Subject: [PATCH 583/936] Temporary solution to a 24bpp issue and hblank. So that 24bpp color is not discolored anymore as well as hblank bugs being nulled. --- src/video/vid_s3_virge.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index a4cec9c09..2c740819b 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -958,13 +958,15 @@ s3_virge_recalctimings(svga_t *svga) } svga->vram_display_mask = virge->vram_mask; } + + svga->hoverride = 1 } static void s3_virge_update_buffer(virge_t *virge) { svga_t *svga = &virge->svga; - + if ((svga->crtc[0x67] & 0xc) != 0xc) return; @@ -977,7 +979,7 @@ s3_virge_update_buffer(virge_t *virge) svga->overlay.addr = virge->streams.sec_fb1; else svga->overlay.addr = virge->streams.sec_fb0; - + svga->rowoffset = virge->streams.pri_stride >> 3; } From c00e854fce92c132dc802c8919e1a7d45001d174 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 24 Feb 2024 21:52:06 +0100 Subject: [PATCH 584/936] Fix compile. See above. --- src/video/vid_s3_virge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 2c740819b..56ddcec46 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -959,7 +959,7 @@ s3_virge_recalctimings(svga_t *svga) svga->vram_display_mask = virge->vram_mask; } - svga->hoverride = 1 + svga->hoverride = 1; } static void From 868beac26e80c53ecf776ddbdc6717e070d36e38 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 24 Feb 2024 17:58:58 -0500 Subject: [PATCH 585/936] Add 86BoxManagerX to README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 370bc940e..d56cbf19f 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ Performance may vary depending on both host and guest configuration. Most emulat It is also recommended to use a manager application with 86Box for easier handling of multiple virtual machines. * [86Box Manager](https://github.com/86Box/86BoxManager) by [Overdoze](https://github.com/daviunic) (Windows only) +* [86Box Manager X](https://github.com/RetBox/86BoxManagerX) by [xafero](https://github.com/xafero) (Cross platform Port of 86Box Manager using Avalonia) * [Linbox-qt5](https://github.com/Dungeonseeker/linbox-qt5) by Dungeonseeker (Linux focused, should work on Windows though untested) * [MacBox for 86Box](https://github.com/Moonif/MacBox) by [Moonif](https://github.com/Moonif) (MacOS only) From cf0e4edbb76a57f66a0cf934e95c0d5adeb55ad4 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 24 Feb 2024 18:00:49 -0500 Subject: [PATCH 586/936] Add sl86 to README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d56cbf19f..ff98742e1 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ It is also recommended to use a manager application with 86Box for easier handli * [86Box Manager](https://github.com/86Box/86BoxManager) by [Overdoze](https://github.com/daviunic) (Windows only) * [86Box Manager X](https://github.com/RetBox/86BoxManagerX) by [xafero](https://github.com/xafero) (Cross platform Port of 86Box Manager using Avalonia) +* [sl86](https://github.com/DDXofficial/sl86) by [DDX](https://github.com/DDXofficial) (Command-line 86Box machine manager written in Python) * [Linbox-qt5](https://github.com/Dungeonseeker/linbox-qt5) by Dungeonseeker (Linux focused, should work on Windows though untested) * [MacBox for 86Box](https://github.com/Moonif/MacBox) by [Moonif](https://github.com/Moonif) (MacOS only) From 31a5aad0f25100f1963026808ccad96f5f6fc480 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 24 Feb 2024 18:01:55 -0500 Subject: [PATCH 587/936] Link to Dungeonseekers github in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ff98742e1..b4b4142be 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ It is also recommended to use a manager application with 86Box for easier handli * [86Box Manager](https://github.com/86Box/86BoxManager) by [Overdoze](https://github.com/daviunic) (Windows only) * [86Box Manager X](https://github.com/RetBox/86BoxManagerX) by [xafero](https://github.com/xafero) (Cross platform Port of 86Box Manager using Avalonia) * [sl86](https://github.com/DDXofficial/sl86) by [DDX](https://github.com/DDXofficial) (Command-line 86Box machine manager written in Python) -* [Linbox-qt5](https://github.com/Dungeonseeker/linbox-qt5) by Dungeonseeker (Linux focused, should work on Windows though untested) +* [Linbox-qt5](https://github.com/Dungeonseeker/linbox-qt5) by [Dungeonseeker](https://github.com/Dungeonseeker/) (Linux focused, should work on Windows though untested) * [MacBox for 86Box](https://github.com/Moonif/MacBox) by [Moonif](https://github.com/Moonif) (MacOS only) It is also possible to use 86Box on its own with the `--vmpath`/`-P` command line option. From f6c66248e0f5f79e186bef9b34d86dc57d56e17b Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 25 Feb 2024 08:13:45 +0100 Subject: [PATCH 588/936] Moved the FDC FIFO implementation to fifo.c/h, fixes a few length masking bugs in fifo.c, and fixed FDC MSR register RQM bit behavior in DMA mode, which makes 386BSD work, fixes #530. --- src/fifo.c | 8 +-- src/floppy/fdc.c | 127 ++++++++++++++++------------------------ src/include/86box/fdc.h | 6 +- 3 files changed, 59 insertions(+), 82 deletions(-) diff --git a/src/fifo.c b/src/fifo.c index 72084e11b..f51809fd8 100644 --- a/src/fifo.c +++ b/src/fifo.c @@ -72,7 +72,7 @@ fifo_write(uint8_t val, void *priv) fifo->overrun = 1; else { fifo->buf[fifo->end] = val; - fifo->end = (fifo->end + 1) & 0x0f; + fifo->end = (fifo->end + 1) % fifo->len; if (fifo->end == fifo->start) fifo->full = 1; @@ -99,7 +99,7 @@ fifo_write_evt(uint8_t val, void *priv) fifo->d_overrun_evt(fifo->priv); } else { fifo->buf[fifo->end] = val; - fifo->end = (fifo->end + 1) & 0x0f; + fifo->end = (fifo->end + 1) % fifo->len; if (fifo->end == fifo->start) { fifo->d_full = (fifo->full != 1); @@ -131,7 +131,7 @@ fifo_read(void *priv) if (!fifo->empty) { ret = fifo->buf[fifo->start]; - fifo->start = (fifo->start + 1) & 0x0f; + fifo->start = (fifo->start + 1) % fifo->len; fifo->full = 0; @@ -160,7 +160,7 @@ fifo_read_evt(void *priv) if (!fifo->empty) { ret = fifo->buf[fifo->start]; - fifo->start = (fifo->start + 1) & 0x0f; + fifo->start = (fifo->start + 1) % fifo->len; fifo->d_full = (fifo->full != 0); fifo->full = 0; diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index f30d86168..8f8fd404e 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -38,6 +38,7 @@ #include <86box/fdc_ext.h> #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> +#include <86box/fifo.h> extern uint64_t motoron[FDD_NUM]; @@ -78,6 +79,7 @@ int floppyrate[4]; int fdc_type = 0; +// #define ENABLE_FDC_LOG 1 #ifdef ENABLE_FDC_LOG int fdc_do_log = ENABLE_FDC_LOG; @@ -309,7 +311,7 @@ fdc_request_next_sector_id(fdc_t *fdc) fdc->stat = 0xf0; else { dma_set_drq(fdc->dma_ch, 1); - fdc->stat = 0xd0; + fdc->stat = 0x50; } } @@ -337,39 +339,6 @@ fdc_get_format_sectors(fdc_t *fdc) return (int) fdc->format_sectors; } -static void -fdc_reset_fifo_buf(fdc_t *fdc) -{ - memset(fdc->fifobuf, 0, 16); - fdc->fifobufpos = 0; -} - -static void -fdc_fifo_buf_advance(fdc_t *fdc) -{ - if (fdc->fifobufpos == fdc->tfifo) - fdc->fifobufpos = 0; - else - fdc->fifobufpos++; -} - -static void -fdc_fifo_buf_write(fdc_t *fdc, uint8_t val) -{ - fdc->fifobuf[fdc->fifobufpos] = val; - fdc_fifo_buf_advance(fdc); -} - -static int -fdc_fifo_buf_read(fdc_t *fdc) -{ - int temp = fdc->fifobuf[fdc->fifobufpos]; - fdc_fifo_buf_advance(fdc); - if (!fdc->fifobufpos) - fdc->data_ready = 0; - return temp; -} - static void fdc_int(fdc_t *fdc, int set_fintr) { @@ -669,7 +638,7 @@ fdc_io_command_phase1(fdc_t *fdc, int out) pclog_toggle_suppr(); #endif - fdc_reset_fifo_buf(fdc); + fifo_reset(fdc->fifo_p); fdc_rate(fdc, fdc->drive); fdc->head = fdc->params[2]; fdd_set_head(real_drive(fdc, fdc->drive), (fdc->params[0] & 4) ? 1 : 0); @@ -687,7 +656,7 @@ fdc_io_command_phase1(fdc_t *fdc, int out) } ui_sb_update_icon(SB_FLOPPY | real_drive(fdc, fdc->drive), 1); - fdc->stat = out ? 0x90 : 0x50; + fdc->stat = out ? 0x10 : 0x50; if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma) fdc->stat |= 0x20; else @@ -825,8 +794,8 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->dat = val; fdc->stat &= ~0x80; } else { - fdc_fifo_buf_write(fdc, val); - if (fdc->fifobufpos == 0) + fifo_write(val, fdc->fifo_p); + if (fifo_get_full(fdc->fifo_p)) fdc->stat &= ~0x80; } break; @@ -849,7 +818,11 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc_log("Starting FDC command %02X\n", fdc->command); fdc->error = 0; - if (((fdc->command & 0x1f) == 0x02) || ((fdc->command & 0x1f) == 0x05) || ((fdc->command & 0x1f) == 0x06) || ((fdc->command & 0x1f) == 0x0a) || ((fdc->command & 0x1f) == 0x0c) || ((fdc->command & 0x1f) == 0x0d) || ((fdc->command & 0x1f) == 0x11) || ((fdc->command & 0x1f) == 0x16) || ((fdc->command & 0x1f) == 0x19) || ((fdc->command & 0x1f) == 0x1d)) + if (((fdc->command & 0x1f) == 0x02) || ((fdc->command & 0x1f) == 0x05) || + ((fdc->command & 0x1f) == 0x06) || ((fdc->command & 0x1f) == 0x0a) || + ((fdc->command & 0x1f) == 0x0c) || ((fdc->command & 0x1f) == 0x0d) || + ((fdc->command & 0x1f) == 0x11) || ((fdc->command & 0x1f) == 0x16) || + ((fdc->command & 0x1f) == 0x19) || ((fdc->command & 0x1f) == 0x1d)) fdc->processed_cmd = fdc->command & 0x1f; else fdc->processed_cmd = fdc->command; @@ -997,6 +970,7 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) } if (fdc->pnum == fdc->ptot) { fdc_log("Got all params %02X\n", fdc->command); + fifo_reset(fdc->fifo_p); fdc->interrupt = fdc->processed_cmd; fdc->reset_stat = 0; /* Disable timer if enabled. */ @@ -1386,11 +1360,11 @@ fdc_read(uint16_t addr, void *priv) fdc->data_ready = 0; ret = fdc->dat; } else - ret = fdc_fifo_buf_read(fdc); + ret = fifo_read(fdc->fifo_p); break; } - fdc->stat &= ~0x80; if (fdc->paramstogo) { + fdc->stat &= ~0x80; fdc_log("%i parameters to go\n", fdc->paramstogo); fdc->paramstogo--; ret = fdc->res[10 - fdc->paramstogo]; @@ -1398,7 +1372,11 @@ fdc_read(uint16_t addr, void *priv) fdc->stat = 0x80; else fdc->stat |= 0xC0; + } else if (fdc->dma) { + ret = fdc->dat; + break; } else { + fdc->stat &= ~0x80; if (lastbyte) fdc->stat = 0x80; lastbyte = 0; @@ -1689,7 +1667,7 @@ fdc_callback(void *priv) fdc->stat = 0xb0; else { dma_set_drq(fdc->dma_ch, 1); - fdc->stat = 0x90; + fdc->stat = 0x10; } break; case 6: @@ -1711,7 +1689,7 @@ fdc_callback(void *priv) fdc->stat = 0xb0; else { dma_set_drq(fdc->dma_ch, 1); - fdc->stat = 0x90; + fdc->stat = 0x10; } break; @@ -1802,6 +1780,9 @@ fdc_callback(void *priv) fdc->pretrk = fdc->params[2]; fdc->fifo = (fdc->params[1] & 0x20) ? 0 : 1; fdc->tfifo = (fdc->params[1] & 0xF); + fifo_reset(fdc->fifo_p); + fifo_set_len(fdc->fifo_p, fdc->tfifo + 1); + fifo_set_trigger_len(fdc->fifo_p, fdc->tfifo + 1); fdc->stat = 0x80; return; case 0x14: /*Unlock*/ @@ -1928,7 +1909,6 @@ int fdc_data(fdc_t *fdc, uint8_t data, int last) { int result = 0; - int n; if (fdc->deleted & 2) { /* We're in a VERIFY command, so return with 0. */ @@ -1950,8 +1930,8 @@ fdc_data(fdc_t *fdc, uint8_t data, int last) fdc->stat = 0xf0; } else { /* FIFO enabled */ - fdc_fifo_buf_write(fdc, data); - if (fdc->fifobufpos == 0) { + fifo_write(data, fdc->fifo_p); + if (fifo_get_full(fdc->fifo_p)) { /* We have wrapped around, means FIFO is over */ fdc->data_ready = 1; fdc->stat = 0xf0; @@ -1963,11 +1943,10 @@ fdc_data(fdc_t *fdc, uint8_t data, int last) if (!fdc->fifo || (fdc->tfifo < 1)) { fdc->data_ready = 1; - fdc->stat = 0xd0; + fdc->stat = 0x50; dma_set_drq(fdc->dma_ch, 1); - fdc->fifobufpos = 0; - + fdc->dat = data; result = dma_channel_write(fdc->dma_ch, data); if (result & DMA_OVER) { @@ -1978,19 +1957,15 @@ fdc_data(fdc_t *fdc, uint8_t data, int last) dma_set_drq(fdc->dma_ch, 0); } else { /* FIFO enabled */ - fdc_fifo_buf_write(fdc, data); - if (last || (fdc->fifobufpos == 0)) { + fifo_write(data, fdc->fifo_p); + if (last || fifo_get_full(fdc->fifo_p)) { /* We have wrapped around, means FIFO is over */ fdc->data_ready = 1; - fdc->stat = 0xd0; + fdc->stat = 0x50; dma_set_drq(fdc->dma_ch, 1); - n = (fdc->fifobufpos > 0) ? (fdc->fifobufpos - 1) : fdc->tfifo; - if (fdc->fifobufpos > 0) - fdc->fifobufpos = 0; - - for (int i = 0; i <= n; i++) { - result = dma_channel_write(fdc->dma_ch, fdc->fifobuf[i]); + while (!fifo_get_empty(fdc->fifo_p)) { + result = dma_channel_write(fdc->dma_ch, fifo_read(fdc->fifo_p)); if (result & DMA_OVER) { dma_set_drq(fdc->dma_ch, 0); @@ -2101,9 +2076,9 @@ fdc_getdata(fdc_t *fdc, int last) if (!last) fdc->stat = 0xb0; } else { - data = fdc_fifo_buf_read(fdc); + data = fifo_read(fdc->fifo_p); - if (!last && (fdc->fifobufpos == 0)) + if (!last && fifo_get_empty(fdc->fifo_p)) fdc->stat = 0xb0; } } else { @@ -2115,14 +2090,14 @@ fdc_getdata(fdc_t *fdc, int last) fdc->tc = 1; if (!last) { - fdc->stat = 0x90; dma_set_drq(fdc->dma_ch, 1); + fdc->stat = 0x10; } } else { - if (fdc->fifobufpos == 0) { - for (int i = 0; i <= fdc->tfifo; i++) { + if (fifo_get_empty(fdc->fifo_p)) { + while (!fifo_get_full(fdc->fifo_p)) { data = dma_channel_read(fdc->dma_ch); - fdc->fifobuf[i] = data; + fifo_write(data, fdc->fifo_p); if (data & DMA_OVER) { dma_set_drq(fdc->dma_ch, 0); @@ -2133,11 +2108,11 @@ fdc_getdata(fdc_t *fdc, int last) dma_set_drq(fdc->dma_ch, 0); } - data = fdc_fifo_buf_read(fdc); + data = fifo_read(fdc->fifo_p); - if (!last && (fdc->fifobufpos == 0)) { + if (!last && fifo_get_empty(fdc->fifo_p)) { dma_set_drq(fdc->dma_ch, 1); - fdc->stat = 0x90; + fdc->stat = 0x10; } } } @@ -2335,15 +2310,14 @@ fdc_reset(void *priv) fdc->max_track = (fdc->flags & FDC_FLAG_MORE_TRACKS) ? 85 : 79; fdc_remove(fdc); - if (fdc->flags & FDC_FLAG_SEC) { + if (fdc->flags & FDC_FLAG_SEC) fdc_set_base(fdc, FDC_SECONDARY_ADDR); - } else if (fdc->flags & FDC_FLAG_TER) { + else if (fdc->flags & FDC_FLAG_TER) fdc_set_base(fdc, FDC_TERTIARY_ADDR); - } else if (fdc->flags & FDC_FLAG_QUA) { + else if (fdc->flags & FDC_FLAG_QUA) fdc_set_base(fdc, FDC_QUATERNARY_ADDR); - } else { + else fdc_set_base(fdc, (fdc->flags & FDC_FLAG_PCJR) ? FDC_PRIMARY_PCJR_ADDR : FDC_PRIMARY_ADDR); - } current_drive = 0; @@ -2358,10 +2332,11 @@ fdc_close(void *priv) { fdc_t *fdc = (fdc_t *) priv; - fdc_reset(fdc); - /* Stop timers. */ - fdc->watchdog_count = 0; + timer_disable(&fdc->watchdog_timer); + timer_disable(&fdc->timer); + + fifo_close(fdc->fifo_p); free(fdc); } @@ -2396,6 +2371,8 @@ fdc_init(const device_t *info) fdc_log("FDC added: %04X (flags: %08X)\n", fdc->base_address, fdc->flags); + fdc->fifo_p = (void *) fifo16_init(); + timer_add(&fdc->timer, fdc_callback, fdc, 0); d86f_set_fdc(fdc); diff --git a/src/include/86box/fdc.h b/src/include/86box/fdc.h index 09c9c4578..37c992a1b 100644 --- a/src/include/86box/fdc.h +++ b/src/include/86box/fdc.h @@ -115,14 +115,12 @@ typedef struct fdc_t { uint8_t rw_drive; uint8_t lock; + uint8_t specify[2]; - uint8_t res[11]; - uint8_t eot[4]; uint8_t rwc[4]; uint8_t params[8]; - uint8_t fifobuf[16]; uint16_t pcn[4]; @@ -145,6 +143,8 @@ typedef struct fdc_t { int drvrate[4]; + void *fifo_p; + sector_id_t read_track_sector; sector_id_t format_sector_id; From a0ef980a2cef663f21b7b7c8823c9bfd9223cc25 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 25 Feb 2024 14:20:39 +0600 Subject: [PATCH 589/936] S3 ViRGE/GX2: Fix frozen display when stream processors are enabled --- src/video/vid_s3_virge.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 56ddcec46..4d64dffbd 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -842,9 +842,11 @@ s3_virge_recalctimings(svga_t *svga) svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | (((svga->crtc[0x5d] & 0x08) >> 3) << 6); svga->hblank_end_mask = 0x7f; + video_force_resize_set_monitor(1, svga->monitor_index); } - if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ + /* ViRGE/GX2 and later does not use primary stream registers. */ + if ((svga->crtc[0x67] & 0xc) != 0xc || virge->chip >= S3_VIRGEGX2) /*VGA mode*/ { svga->ma_latch |= (virge->ma_ext << 16); if (svga->crtc[0x51] & 0x30) @@ -896,6 +898,22 @@ s3_virge_recalctimings(svga_t *svga) svga->vram_display_mask = (!(svga->crtc[0x31] & 0x08) && (svga->crtc[0x32] & 0x40)) ? 0x3ffff : virge->vram_mask; svga->overlay.ena = 0; s3_virge_log("VGA mode\n"); + if (virge->chip >= S3_VIRGEGX2 && (svga->crtc[0x67] & 0xc) == 0xc) { + /* ViRGE/GX2 and later does not use primary stream registers. */ + svga->overlay.x = virge->streams.sec_x; + svga->overlay.y = virge->streams.sec_y; + svga->overlay.cur_ysize = virge->streams.sec_h; + + if (virge->streams.buffer_ctrl & 2) + svga->overlay.addr = virge->streams.sec_fb1; + else + svga->overlay.addr = virge->streams.sec_fb0; + + svga->overlay.ena = (svga->overlay.x >= 0) && !!(virge->streams.blend_ctrl & 0x20); + svga->overlay.v_acc = virge->streams.dda_vert_accumulator; + svga->rowoffset = virge->streams.pri_stride >> 3; + svga->vram_display_mask = virge->vram_mask; + } } else /*Streams mode*/ { if (virge->streams.buffer_ctrl & 1) @@ -970,10 +988,12 @@ s3_virge_update_buffer(virge_t *virge) if ((svga->crtc[0x67] & 0xc) != 0xc) return; - if (virge->streams.buffer_ctrl & 1) - svga->ma_latch = virge->streams.pri_fb1 >> 2; - else - svga->ma_latch = virge->streams.pri_fb0 >> 2; + if (virge->chip < S3_VIRGEGX2) { + if (virge->streams.buffer_ctrl & 1) + svga->ma_latch = virge->streams.pri_fb1 >> 2; + else + svga->ma_latch = virge->streams.pri_fb0 >> 2; + } if (virge->streams.buffer_ctrl & 2) svga->overlay.addr = virge->streams.sec_fb1; From c13272ec48bb9860105cbd359428080b22f51111 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 25 Feb 2024 14:06:25 +0100 Subject: [PATCH 590/936] S3 80x cursor fixes: 1. The SPEA specific cards using the 801/5 chip apparently have an ID that's not 0xa0, rather, they either use 0xa2 or greater for the stepping. Fixes wrong colors in 800x600 modes and greater in 8bpp mode. 2. HWCursor addresses for 8bpp are now properly implemented if the 8bpp mode bit (CRTC3a bit 4) is checked, no longer relaying on GDCREG5 bit 6). Fixes garbage cursor in the SPEA 80x cards drivers (BigWin) using 8bpp mode. --- src/video/vid_s3.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index c526ecf62..fe06f05f5 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -2128,8 +2128,8 @@ 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[0x45] & 0x10)) { - if ((svga->gdcreg[5] & 0x60) >= 0x40) + 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) return ((svga->hwcursor_latch.addr & 0xfffff0ff) | ((svga->hwcursor_latch.addr & 0x300) << 2)) | 0x300; @@ -10002,14 +10002,14 @@ s3_init(const device_t *info) case S3_SPEA_MIRAGE_86C801: case S3_SPEA_MIRAGE_86C805: svga->decode_mask = (2 << 20) - 1; - stepping = 0xa0; /*86C801/86C805*/ + stepping = 0xa2; /*86C801/86C805*/ s3->id = stepping; s3->id_ext = stepping; s3->id_ext_pci = 0; s3->packed_mmio = 0; svga->crtc[0x5a] = 0x0a; - svga->ramdac = device_add(&att490_ramdac_device); + svga->ramdac = device_add(&att491_ramdac_device); svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; break; From 74e9bcd0844fcee308688d7f2f9c39cdba665977 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 26 Feb 2024 03:15:44 +0600 Subject: [PATCH 591/936] Add Novell NetWare 2.x Card Key emulation --- src/86box.c | 4 + src/config.c | 12 ++- src/device/CMakeLists.txt | 3 +- src/device/novell_cardkey.c | 115 +++++++++++++++++++++++++ src/include/86box/86box.h | 1 + src/include/86box/novell_cardkey.h | 37 ++++++++ src/qt/qt_settingsotherperipherals.cpp | 24 +++++- src/qt/qt_settingsotherperipherals.hpp | 4 + src/qt/qt_settingsotherperipherals.ui | 70 +++++++++++---- 9 files changed, 244 insertions(+), 26 deletions(-) create mode 100644 src/device/novell_cardkey.c create mode 100644 src/include/86box/novell_cardkey.h diff --git a/src/86box.c b/src/86box.c index 8218c208c..9e3bc9dca 100644 --- a/src/86box.c +++ b/src/86box.c @@ -66,6 +66,7 @@ #include <86box/bugger.h> #include <86box/postcard.h> #include <86box/unittester.h> +#include <86box/novell_cardkey.h> #include <86box/isamem.h> #include <86box/isartc.h> #include <86box/lpt.h> @@ -173,6 +174,7 @@ char video_shader[512] = { '\0' }; /* (C) video * bool serial_passthrough_enabled[SERIAL_MAX] = { 0, 0, 0, 0 }; /* (C) activation and kind of pass-through for serial ports */ int bugger_enabled = 0; /* (C) enable ISAbugger */ +int novell_keycard_enabled = 0; /* (C) enable Novell NetWare 2.x key card emulation. */ int postcard_enabled = 0; /* (C) enable POST card */ int unittester_enabled = 0; /* (C) enable unit tester device */ int isamem_type[ISAMEM_MAX] = { 0, 0, 0, 0 }; /* (C) enable ISA mem cards */ @@ -1226,6 +1228,8 @@ pc_reset_hard_init(void) device_add(&postcard_device); if (unittester_enabled) device_add(&unittester_device); + if (novell_keycard_enabled) + device_add(&novell_keycard_device); if (IS_ARCH(machine, MACHINE_BUS_PCI)) { pci_register_cards(); diff --git a/src/config.c b/src/config.c index 3e4fd7222..e4a86d7bd 100644 --- a/src/config.c +++ b/src/config.c @@ -1568,9 +1568,10 @@ load_other_peripherals(void) char *p; char temp[512]; - bugger_enabled = !!ini_section_get_int(cat, "bugger_enabled", 0); - postcard_enabled = !!ini_section_get_int(cat, "postcard_enabled", 0); - unittester_enabled = !!ini_section_get_int(cat, "unittester_enabled", 0); + bugger_enabled = !!ini_section_get_int(cat, "bugger_enabled", 0); + postcard_enabled = !!ini_section_get_int(cat, "postcard_enabled", 0); + unittester_enabled = !!ini_section_get_int(cat, "unittester_enabled", 0); + novell_keycard_enabled = !!ini_section_get_int(cat, "novell_keycard_enabled", 0); for (uint8_t c = 0; c < ISAMEM_MAX; c++) { sprintf(temp, "isamem%d_type", c); @@ -2365,6 +2366,11 @@ save_other_peripherals(void) else ini_section_set_int(cat, "unittester_enabled", unittester_enabled); + if (novell_keycard_enabled == 0) + ini_section_delete_var(cat, "novell_keycard_enabled"); + else + ini_section_set_int(cat, "novell_keycard_enabled", novell_keycard_enabled); + for (uint8_t c = 0; c < ISAMEM_MAX; c++) { sprintf(temp, "isamem%d_type", c); if (isamem_type[c] == 0) diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index 9c5705325..c0719af2a 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -22,7 +22,8 @@ add_library(dev OBJECT bugger.c cassette.c cartridge.c hasp.c hwm.c hwm_lm75.c h kbc_at.c kbc_at_dev.c keyboard_at.c mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c nec_mate_unk.c phoenix_486_jumper.c - serial_passthrough.c) + serial_passthrough.c + novell_cardkey.c) if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") target_link_libraries(86Box atomic) diff --git a/src/device/novell_cardkey.c b/src/device/novell_cardkey.c new file mode 100644 index 000000000..ad3f0a5ea --- /dev/null +++ b/src/device/novell_cardkey.c @@ -0,0 +1,115 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Novell NetWare 2.x Key Card, which + * was used for anti-piracy protection. + * + * + * Authors: Cacodemon345 + * + * Copyright 2024 Cacodemon345. + */ + +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/timer.h> +#include <86box/plat.h> +#include <86box/novell_cardkey.h> + +typedef struct novell_cardkey_t +{ + char serial_number_str[13]; +} novell_cardkey_t; + +static uint8_t +novell_cardkey_read(uint16_t port, void *priv) +{ + novell_cardkey_t* cardkey = (novell_cardkey_t*)priv; + uint8_t val = 0x00; + switch (port) { + case 0x23A: + val = ((cardkey->serial_number_str[11] - '0') << 4) | ((cardkey->serial_number_str[9] - '0')); + break; + case 0x23B: + val = ((cardkey->serial_number_str[10] - '0') << 4) | ((cardkey->serial_number_str[8] - '0')); + break; + + case 0x23C: + val = ((cardkey->serial_number_str[4] - '0') << 4) | ((cardkey->serial_number_str[2] - '0')); + break; + case 0x23D: + val = ((cardkey->serial_number_str[1] - '0') << 4) | ((cardkey->serial_number_str[6] - '0')); + break; + case 0x23E: + val = ((cardkey->serial_number_str[0] - '0') << 4) | ((cardkey->serial_number_str[7] - '0')); + break; + case 0x23F: + val = ((cardkey->serial_number_str[3] - '0') << 4) | ((cardkey->serial_number_str[5] - '0')); + break; + } + return val ^ 0xFF; +} + +void* novell_cardkey_init(const device_t* info) +{ + char sernumstr[13] = { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 0 }; + int i = 0; + novell_cardkey_t* cardkey = calloc(1, sizeof(novell_cardkey_t)); + + strncpy(sernumstr, device_get_config_string("serial_number"), sizeof(sernumstr) - 1); + + for (i = 0; i < sizeof(sernumstr); i++) { + if (sernumstr[i] > '8' || sernumstr[i] < '0') + sernumstr[i] = '0'; + } + sernumstr[12] = 0; + strncpy(cardkey->serial_number_str, sernumstr, sizeof(sernumstr)); + io_sethandler(NOVELL_KEYCARD_ADDR, NOVELL_KEYCARD_ADDRLEN, novell_cardkey_read, NULL, NULL, NULL, NULL, NULL, cardkey); + return cardkey; +} + +void novell_cardkey_close(void* priv) +{ + free(priv); +} + +static const device_config_t keycard_config[] = { + // clang-format off + { + .name = "serial_number", + .description = "Serial Number", + .type = CONFIG_STRING, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .selection = { 0 } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t novell_keycard_device = { + .name = "Novell Netware 2.x Key Card", + .internal_name = "mssystems", + .flags = DEVICE_ISA, + .local = 0, + .init = novell_cardkey_init, + .close = novell_cardkey_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = keycard_config +}; \ No newline at end of file diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index 20f3fffcc..8a11cc610 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -124,6 +124,7 @@ extern int video_framerate; /* (C) video */ extern int gfxcard[2]; /* (C) graphics/video card */ extern char video_shader[512]; /* (C) video */ extern int bugger_enabled; /* (C) enable ISAbugger */ +extern int novell_keycard_enabled; /* (C) enable Novell NetWare 2.x key card emulation. */ extern int postcard_enabled; /* (C) enable POST card */ extern int unittester_enabled; /* (C) enable unit tester device */ extern int isamem_type[]; /* (C) enable ISA mem cards */ diff --git a/src/include/86box/novell_cardkey.h b/src/include/86box/novell_cardkey.h new file mode 100644 index 000000000..8ad3eabab --- /dev/null +++ b/src/include/86box/novell_cardkey.h @@ -0,0 +1,37 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Novell NetWare 2.x Key Card, which + * was used for anti-piracy protection. + * + * + * Authors: Cacodemon345 + * + * Copyright 2024 Cacodemon345. + */ +#ifndef NOVELL_KEYCARD_H +#define NOVELL_KEYCARD_H + +/* I/O port range used. */ +#define NOVELL_KEYCARD_ADDR 0x23a +#define NOVELL_KEYCARD_ADDRLEN 6 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Global variables. */ +extern const device_t novell_keycard_device; + +/* Functions. */ + +#ifdef __cplusplus +} +#endif + +#endif /*BUGGER_H*/ \ No newline at end of file diff --git a/src/qt/qt_settingsotherperipherals.cpp b/src/qt/qt_settingsotherperipherals.cpp index f662b644c..3904b653a 100644 --- a/src/qt/qt_settingsotherperipherals.cpp +++ b/src/qt/qt_settingsotherperipherals.cpp @@ -24,6 +24,7 @@ extern "C" { #include <86box/isamem.h> #include <86box/isartc.h> #include <86box/unittester.h> +#include <86box/novell_cardkey.h> } #include "qt_deviceconfig.hpp" @@ -46,7 +47,10 @@ SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) ui->checkBoxISABugger->setChecked((machineHasIsa && (bugger_enabled > 0)) ? true : false); ui->checkBoxPOSTCard->setChecked(postcard_enabled > 0 ? true : false); ui->checkBoxUnitTester->setChecked(unittester_enabled > 0 ? true : false); + ui->checkBoxKeyCard->setChecked((machineHasIsa && (novell_keycard_enabled > 0)) ? true : false); ui->checkBoxISABugger->setEnabled(machineHasIsa); + ui->checkBoxKeyCard->setEnabled(machineHasIsa); + ui->pushButtonConfigureKeyCard->setEnabled(novell_keycard_enabled > 0); ui->pushButtonConfigureUT->setEnabled(unittester_enabled > 0); ui->comboBoxRTC->setEnabled(machineHasIsa); ui->pushButtonConfigureRTC->setEnabled(machineHasIsa); @@ -115,10 +119,11 @@ void SettingsOtherPeripherals::save() { /* Other peripherals category */ - bugger_enabled = ui->checkBoxISABugger->isChecked() ? 1 : 0; - postcard_enabled = ui->checkBoxPOSTCard->isChecked() ? 1 : 0; - unittester_enabled = ui->checkBoxUnitTester->isChecked() ? 1 : 0; - isartc_type = ui->comboBoxRTC->currentData().toInt(); + bugger_enabled = ui->checkBoxISABugger->isChecked() ? 1 : 0; + postcard_enabled = ui->checkBoxPOSTCard->isChecked() ? 1 : 0; + unittester_enabled = ui->checkBoxUnitTester->isChecked() ? 1 : 0; + novell_keycard_enabled = ui->checkBoxKeyCard->isChecked() ? 1 : 0; + isartc_type = ui->comboBoxRTC->currentData().toInt(); /* ISA memory boards. */ for (int i = 0; i < ISAMEM_MAX; i++) { @@ -213,3 +218,14 @@ SettingsOtherPeripherals::on_pushButtonConfigureUT_clicked() { DeviceConfig::ConfigureDevice(&unittester_device); } + +void SettingsOtherPeripherals::on_pushButtonConfigureKeyCard_clicked() +{ + DeviceConfig::ConfigureDevice(&novell_keycard_device); +} + +void SettingsOtherPeripherals::on_checkBoxKeyCard_stateChanged(int arg1) +{ + ui->pushButtonConfigureKeyCard->setEnabled(arg1 != 0); +} + diff --git a/src/qt/qt_settingsotherperipherals.hpp b/src/qt/qt_settingsotherperipherals.hpp index feaa7a001..d5804a68b 100644 --- a/src/qt/qt_settingsotherperipherals.hpp +++ b/src/qt/qt_settingsotherperipherals.hpp @@ -33,6 +33,10 @@ private slots: void on_checkBoxUnitTester_stateChanged(int arg1); void on_pushButtonConfigureUT_clicked(); + void on_pushButtonConfigureKeyCard_clicked(); + + void on_checkBoxKeyCard_stateChanged(int arg1); + private: Ui::SettingsOtherPeripherals *ui; int machineId { 0 }; diff --git a/src/qt/qt_settingsotherperipherals.ui b/src/qt/qt_settingsotherperipherals.ui index af953a984..41df2deac 100644 --- a/src/qt/qt_settingsotherperipherals.ui +++ b/src/qt/qt_settingsotherperipherals.ui @@ -37,15 +37,15 @@ - - 30 - 0 0 + + 30 + @@ -72,15 +72,15 @@ - - 30 - 0 0 + + 30 + @@ -113,15 +113,15 @@ - - 30 - 0 0 + + 30 + @@ -133,28 +133,28 @@ - - 30 - 0 0 + + 30 + - - 30 - 0 0 + + 30 + @@ -196,15 +196,15 @@ - - 86Box Unit Tester - 0 0 + + 86Box Unit Tester + @@ -216,6 +216,40 @@ + + + + 0 + + + + + Novell NetWare 2.x Key Card + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Configure + + + + + From 1be08f9a9f5d4419ff2a28767de2077911f949f5 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 26 Feb 2024 13:43:35 +0600 Subject: [PATCH 592/936] Handle Application Number part correctly --- src/device/novell_cardkey.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/device/novell_cardkey.c b/src/device/novell_cardkey.c index ad3f0a5ea..54b716cc3 100644 --- a/src/device/novell_cardkey.c +++ b/src/device/novell_cardkey.c @@ -39,10 +39,10 @@ novell_cardkey_read(uint16_t port, void *priv) uint8_t val = 0x00; switch (port) { case 0x23A: - val = ((cardkey->serial_number_str[11] - '0') << 4) | ((cardkey->serial_number_str[9] - '0')); + val = (((cardkey->serial_number_str[11] > 'A') ? ((cardkey->serial_number_str[11] - 'A') + 10) : (cardkey->serial_number_str[11] - '0')) << 4) | (((cardkey->serial_number_str[9] > 'A') ? ((cardkey->serial_number_str[9] - 'A') + 10) : (cardkey->serial_number_str[9] - '0')) << 4); break; case 0x23B: - val = ((cardkey->serial_number_str[10] - '0') << 4) | ((cardkey->serial_number_str[8] - '0')); + val = (((cardkey->serial_number_str[10] > 'A') ? ((cardkey->serial_number_str[10] - 'A') + 10) : (cardkey->serial_number_str[10] - '0')) << 4) | (((cardkey->serial_number_str[8] > 'A') ? ((cardkey->serial_number_str[8] - 'A') + 10) : (cardkey->serial_number_str[8] - '0')) << 4); break; case 0x23C: @@ -69,7 +69,7 @@ void* novell_cardkey_init(const device_t* info) strncpy(sernumstr, device_get_config_string("serial_number"), sizeof(sernumstr) - 1); - for (i = 0; i < sizeof(sernumstr); i++) { + for (i = 0; i < sizeof(sernumstr) - 4; i++) { if (sernumstr[i] > '8' || sernumstr[i] < '0') sernumstr[i] = '0'; } From 8363144dbf9b8d7c2333ab4d62d08d454ea890b3 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 26 Feb 2024 13:49:13 +0600 Subject: [PATCH 593/936] More validation --- src/device/novell_cardkey.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/device/novell_cardkey.c b/src/device/novell_cardkey.c index 54b716cc3..9f489cad7 100644 --- a/src/device/novell_cardkey.c +++ b/src/device/novell_cardkey.c @@ -73,6 +73,14 @@ void* novell_cardkey_init(const device_t* info) if (sernumstr[i] > '8' || sernumstr[i] < '0') sernumstr[i] = '0'; } + if (sernumstr[8] > 'F' || sernumstr[8] < '0') + sernumstr[8] = '0'; + if (sernumstr[9] > 'F' || sernumstr[9] < '0') + sernumstr[9] = '0'; + if (sernumstr[10] > 'F' || sernumstr[10] < '0') + sernumstr[10] = '0'; + if (sernumstr[11] > 'F' || sernumstr[11] < '0') + sernumstr[11] = '0'; sernumstr[12] = 0; strncpy(cardkey->serial_number_str, sernumstr, sizeof(sernumstr)); io_sethandler(NOVELL_KEYCARD_ADDR, NOVELL_KEYCARD_ADDRLEN, novell_cardkey_read, NULL, NULL, NULL, NULL, NULL, cardkey); From 0275ff352311d4f5bc9d5edbcc12f6cab7fea61e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 27 Feb 2024 16:16:06 +0600 Subject: [PATCH 594/936] MGA: Implement BPLAN for BITBLT operations --- src/video/vid_mga.c | 86 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index f40385fef..87e267eb4 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -315,6 +315,7 @@ #define DWGCTRL_TRANS_MASK (0xf << DWGCTRL_TRANS_SHIFT) #define DWGCTRL_BLTMOD_MASK (0xf << 25) #define DWGCTRL_BLTMOD_BMONOLEF (0x0 << 25) +#define DWGCTRL_BLTMOD_BPLAN (0x1 << 25) #define DWGCTRL_BLTMOD_BFCOL (0x2 << 25) #define DWGCTRL_BLTMOD_BU32BGR (0x3 << 25) #define DWGCTRL_BLTMOD_BMONOWF (0x4 << 25) @@ -5371,6 +5372,91 @@ blit_bitblt(mystique_t *mystique) switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { case DWGCTRL_ATYPE_BLK: switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + /* TODO: This isn't exactly perfect. */ + case DWGCTRL_BLTMOD_BPLAN: + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) + fatal("BITBLT RPL/RSTR BPLAN with pattern\n"); + + src_addr = mystique->dwgreg.ar[3]; + + for (y = 0; y < mystique->dwgreg.length; y++) { + uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + int16_t x = x_start; + + while (1) { + uint32_t byte_addr = src_addr & mystique->vram_mask; + + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && ((svga->vram[byte_addr] & 1) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && trans[x & 3]) { + uint32_t src = (svga->vram[byte_addr] & 1) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + uint32_t dst; + uint32_t old_dst; + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_16: + dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + + dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); // & DWGCTRL_BOP_MASK + + *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_32: + dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("BITBLT RPL BPLAN PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } + + if (src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + src_addr = mystique->dwgreg.ar[3]; + } else + src_addr += x_dir; + + if (x != x_end) { + if ((x > x_end) && (x_dir == 1)) + x--; + else if ((x < x_end) && (x_dir == -1)) + x++; + else + x += x_dir; + } else + break; + } + + if (mystique->dwgreg.sgn.sdy) + mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + } + break; case DWGCTRL_BLTMOD_BMONOLEF: case DWGCTRL_BLTMOD_BMONOWF: src_addr = mystique->dwgreg.ar[3]; From e68b062ca0cb0683712fee3c416f45beaf9f279e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B2=99=E6=B2=99=E5=AE=AE=E7=B4=97=E5=A4=9C?= <117635969+kzmidze@users.noreply.github.com> Date: Tue, 27 Feb 2024 20:38:04 +0800 Subject: [PATCH 595/936] Add files via upload --- src/win/languages/ja-JP.rc | 4 ++-- src/win/languages/ko-KR.rc | 2 +- src/win/languages/zh-CN.rc | 4 ++-- src/win/languages/zh-TW.rc | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/win/languages/ja-JP.rc b/src/win/languages/ja-JP.rc index 4090abf00..74ae06092 100644 --- a/src/win/languages/ja-JP.rc +++ b/src/win/languages/ja-JP.rc @@ -43,7 +43,7 @@ BEGIN MENUITEM "SDL (ソフトウェア)(&S)", IDM_VID_SDL_SW MENUITEM "SDL (ハードウェア)(&H)", IDM_VID_SDL_HW MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL - MENUITEM "OpenGL (3.0コア)(&G)", IDM_VID_OPENGL_CORE + MENUITEM "OpenGL (3.0 Core)(&G)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "VNC(&V)", IDM_VID_VNC #endif @@ -514,7 +514,7 @@ BEGIN IDS_2151 "カートリッジ %i: %ls" IDS_2152 "カートリッジ イメージ (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0すべてのファイル (*.*)\0*.*\0" IDS_2153 "レンダラーの初期化エラー" - IDS_2154 "OpenGL (3.0コア) レンダラーが初期化できません。別のレンダラーを使用してください。" + IDS_2154 "OpenGL (3.0 Core) レンダラーが初期化できません。別のレンダラーを使用してください。" IDS_2155 "実行を再開" IDS_2156 "実行を一時停止" IDS_2157 "Ctrl+Alt+DELを押す" diff --git a/src/win/languages/ko-KR.rc b/src/win/languages/ko-KR.rc index 7550e0779..a63090c9b 100644 --- a/src/win/languages/ko-KR.rc +++ b/src/win/languages/ko-KR.rc @@ -43,7 +43,7 @@ BEGIN MENUITEM "SDL (소프트웨어)(&S)", IDM_VID_SDL_SW MENUITEM "SDL (하드웨어)(&H)", IDM_VID_SDL_HW MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL - MENUITEM "OpenGL (3.0 코어)(&G)", IDM_VID_OPENGL_CORE + MENUITEM "OpenGL (3.0 Core)(&G)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "VNC(&V)", IDM_VID_VNC #endif diff --git a/src/win/languages/zh-CN.rc b/src/win/languages/zh-CN.rc index 1139de4ea..676574720 100644 --- a/src/win/languages/zh-CN.rc +++ b/src/win/languages/zh-CN.rc @@ -43,7 +43,7 @@ BEGIN MENUITEM "SDL (软件)(&S)", IDM_VID_SDL_SW MENUITEM "SDL (硬件)(&H)", IDM_VID_SDL_HW MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL - MENUITEM "OpenGL (3.0 核心)(&G)", IDM_VID_OPENGL_CORE + MENUITEM "OpenGL (3.0 Core)(&G)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "VNC(&V)", IDM_VID_VNC #endif @@ -514,7 +514,7 @@ BEGIN IDS_2151 "卡带 %i: %ls" IDS_2152 "卡带映像 (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0所有文件 (*.*)\0*.*\0" IDS_2153 "初始化渲染器时出错" - IDS_2154 "无法初始化 OpenGL (3.0 核心) 渲染器。请使用其他渲染器。" + IDS_2154 "无法初始化 OpenGL (3.0 Core) 渲染器。请使用其他渲染器。" IDS_2155 "恢复执行" IDS_2156 "暂停执行" IDS_2157 "按下 Ctrl+Alt+Del" diff --git a/src/win/languages/zh-TW.rc b/src/win/languages/zh-TW.rc index 58324442d..171d8e3f6 100644 --- a/src/win/languages/zh-TW.rc +++ b/src/win/languages/zh-TW.rc @@ -43,7 +43,7 @@ BEGIN MENUITEM "SDL (軟體)(&S)", IDM_VID_SDL_SW MENUITEM "SDL (硬體)(&H)", IDM_VID_SDL_HW MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL - MENUITEM "OpenGL (3.0 核心)(&G)", IDM_VID_OPENGL_CORE + MENUITEM "OpenGL (3.0 Core)(&G)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "VNC(&V)", IDM_VID_VNC #endif @@ -514,7 +514,7 @@ BEGIN IDS_2151 "卡帶 %i: %ls" IDS_2152 "卡帶映像 (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0所有檔案 (*.*)\0*.*\0" IDS_2153 "初始化渲染器時出錯" - IDS_2154 "無法初始化 OpenGL (3.0 核心) 渲染器。請使用其他渲染器。" + IDS_2154 "無法初始化 OpenGL (3.0 Core) 渲染器。請使用其他渲染器。" IDS_2155 "恢復執行" IDS_2156 "暫停執行" IDS_2157 "按下 Ctrl+Alt+Del" From fd3b29a5d077e3352255f7173c05e00558da5305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B2=99=E6=B2=99=E5=AE=AE=E7=B4=97=E5=A4=9C?= <117635969+kzmidze@users.noreply.github.com> Date: Tue, 27 Feb 2024 20:43:14 +0800 Subject: [PATCH 596/936] Add files via upload --- src/qt/languages/ja-JP.po | 4 ++-- src/qt/languages/ko-KR.po | 2 +- src/qt/languages/zh-CN.po | 4 ++-- src/qt/languages/zh-TW.po | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index d0f206dc9..ebcaf9cfb 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -50,7 +50,7 @@ msgid "SDL (&OpenGL)" msgstr "SDL (OpenGL)(&O)" msgid "Open&GL (3.0 Core)" -msgstr "OpenGL (3.0コア)(&G)" +msgstr "OpenGL (3.0 Core)(&G)" msgid "&VNC" msgstr "VNC(&V)" @@ -938,7 +938,7 @@ msgid "Error initializing renderer" msgstr "レンダラーの初期化エラー" msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "OpenGL (3.0コア) レンダラーが初期化できません。別のレンダラーを使用してください。" +msgstr "OpenGL (3.0 Core) レンダラーが初期化できません。別のレンダラーを使用してください。" msgid "Resume execution" msgstr "実行を再開" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index f5d1502b0..949548ed1 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -50,7 +50,7 @@ msgid "SDL (&OpenGL)" msgstr "SDL (OpenGL)(&O)" msgid "Open&GL (3.0 Core)" -msgstr "OpenGL (3.0 코어)(&G)" +msgstr "OpenGL (3.0 Core)(&G)" msgid "&VNC" msgstr "VNC(&V)" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index 94c468d80..dd819deb0 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -50,7 +50,7 @@ msgid "SDL (&OpenGL)" msgstr "SDL (OpenGL)(&O)" msgid "Open&GL (3.0 Core)" -msgstr "OpenGL (3.0 核心)(&G)" +msgstr "OpenGL (3.0 Core)(&G)" msgid "&VNC" msgstr "VNC(&V)" @@ -938,7 +938,7 @@ msgid "Error initializing renderer" msgstr "初始化渲染器时出错" msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "无法初始化 OpenGL (3.0 核心) 渲染器。请使用其他渲染器。" +msgstr "无法初始化 OpenGL (3.0 Core) 渲染器。请使用其他渲染器。" msgid "Resume execution" msgstr "恢复执行" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 7836f7ef8..aef164704 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -50,7 +50,7 @@ msgid "SDL (&OpenGL)" msgstr "SDL (OpenGL)(&O)" msgid "Open&GL (3.0 Core)" -msgstr "OpenGL (3.0 核心)(&G)" +msgstr "OpenGL (3.0 Core)(&G)" msgid "&VNC" msgstr "VNC(&V)" @@ -938,7 +938,7 @@ msgid "Error initializing renderer" msgstr "初始化渲染器時出錯" msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "無法初始化 OpenGL (3.0 核心) 渲染器。請使用其他渲染器。" +msgstr "無法初始化 OpenGL (3.0 Core) 渲染器。請使用其他渲染器。" msgid "Resume execution" msgstr "恢復執行" From 9d4f4f0a70277d3efda10c422489ddd01ef78046 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 28 Feb 2024 14:08:55 +0600 Subject: [PATCH 597/936] MGA: Move BPLAN handling to the right place --- src/video/vid_mga.c | 170 ++++++++++++++++++++++---------------------- 1 file changed, 85 insertions(+), 85 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 87e267eb4..6b0c563b2 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5372,91 +5372,6 @@ blit_bitblt(mystique_t *mystique) switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { case DWGCTRL_ATYPE_BLK: switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - /* TODO: This isn't exactly perfect. */ - case DWGCTRL_BLTMOD_BPLAN: - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) - fatal("BITBLT RPL/RSTR BPLAN with pattern\n"); - - src_addr = mystique->dwgreg.ar[3]; - - for (y = 0; y < mystique->dwgreg.length; y++) { - uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - int16_t x = x_start; - - while (1) { - uint32_t byte_addr = src_addr & mystique->vram_mask; - - if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && ((svga->vram[byte_addr] & 1) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && trans[x & 3]) { - uint32_t src = (svga->vram[byte_addr] & 1) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - uint32_t dst; - uint32_t old_dst; - - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8: - dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; - - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - - svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; - break; - - case MACCESS_PWIDTH_16: - dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; - - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - - ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; - break; - - case MACCESS_PWIDTH_24: - old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; - - dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); // & DWGCTRL_BOP_MASK - - *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); - svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; - break; - - case MACCESS_PWIDTH_32: - dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; - - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - - ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; - break; - - default: - fatal("BITBLT RPL BPLAN PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); - } - } - - if (src_addr == mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; - src_addr = mystique->dwgreg.ar[3]; - } else - src_addr += x_dir; - - if (x != x_end) { - if ((x > x_end) && (x_dir == 1)) - x--; - else if ((x < x_end) && (x_dir == -1)) - x++; - else - x += x_dir; - } else - break; - } - - if (mystique->dwgreg.sgn.sdy) - mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); - else - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - } - break; case DWGCTRL_BLTMOD_BMONOLEF: case DWGCTRL_BLTMOD_BMONOWF: src_addr = mystique->dwgreg.ar[3]; @@ -5564,6 +5479,91 @@ blit_bitblt(mystique_t *mystique) } case DWGCTRL_ATYPE_RSTR: switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + /* TODO: This isn't exactly perfect. */ + case DWGCTRL_BLTMOD_BPLAN: + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) + fatal("BITBLT RPL/RSTR BPLAN with pattern\n"); + + src_addr = mystique->dwgreg.ar[3]; + + for (y = 0; y < mystique->dwgreg.length; y++) { + uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + int16_t x = x_start; + + while (1) { + uint32_t byte_addr = src_addr & mystique->vram_mask; + + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && ((svga->vram[byte_addr] & 1) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && trans[x & 3]) { + uint32_t src = (svga->vram[byte_addr] & 1) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + uint32_t dst; + uint32_t old_dst; + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_16: + dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + + dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); // & DWGCTRL_BOP_MASK + + *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_32: + dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("BITBLT RPL BPLAN PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } + + if (src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + src_addr = mystique->dwgreg.ar[3]; + } else + src_addr += x_dir; + + if (x != x_end) { + if ((x > x_end) && (x_dir == 1)) + x--; + else if ((x < x_end) && (x_dir == -1)) + x++; + else + x += x_dir; + } else + break; + } + + if (mystique->dwgreg.sgn.sdy) + mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + } + break; case DWGCTRL_BLTMOD_BMONOLEF: case DWGCTRL_BLTMOD_BMONOWF: if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) From 901e2568fe382115e7aac711b5f52ba6501645b7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 29 Feb 2024 06:46:37 +0100 Subject: [PATCH 598/936] Mask out serial passthrough MSR bits when in loopback mode, fixes #4217. --- src/device/serial.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/device/serial.c b/src/device/serial.c index 37aadf8fe..dcdffb71c 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -686,7 +686,10 @@ serial_read(uint16_t addr, void *priv) serial_update_ints(dev); break; case 6: - ret = dev->msr | dev->msr_set; + if (dev->mctrl & 0x10) + ret = dev->msr; + else + ret = dev->msr | dev->msr_set; dev->msr &= ~0x0f; dev->int_status &= ~SERIAL_INT_MSR; serial_update_ints(dev); From 5af0ccd145bbfcfafd456640c8bcc0442db124e1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 29 Feb 2024 06:48:16 +0100 Subject: [PATCH 599/936] Assorted Voodoo and warning fixes. --- src/network/net_pcnet.c | 3 +- src/video/vid_voodoo_banshee.c | 3 ++ src/video/vid_voodoo_banshee_blitter.c | 48 ++++++++++++++++++++++++++ src/video/vid_voodoo_render.c | 4 ++- 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/network/net_pcnet.c b/src/network/net_pcnet.c index 9ddcfe29d..1e28c5846 100644 --- a/src/network/net_pcnet.c +++ b/src/network/net_pcnet.c @@ -787,8 +787,9 @@ static int ladr_match(nic_t *dev, const uint8_t *buf, UNUSED(size_t size)) { const struct ether_header *hdr = (const struct ether_header *) buf; + uint64_t *p = (uint64_t *) &dev->aCSR[8]; - if ((hdr->ether_dhost[0] & 0x01) && ((uint64_t *) &dev->aCSR[8])[0] != 0LL) { + if ((hdr->ether_dhost[0] & 0x01) && p[0] != 0LL) { int index; uint8_t ladr[8]; ladr[0] = dev->aCSR[8] & 0xff; diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 098e919d4..a333062e1 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -510,6 +510,9 @@ banshee_render_16bpp_tiled(svga_t *svga) else addr = banshee->desktop_addr + (banshee->desktop_y & 31) * 128 + ((banshee->desktop_y >> 5) * banshee->desktop_stride_tiled); + if (addr >= svga->vram_max) + return; + for (int x = 0; x <= svga->hdisp; x += 64) { if (svga->hwcursor_on || svga->overlay_on) svga->changedvram[addr >> 12] = 2; diff --git a/src/video/vid_voodoo_banshee_blitter.c b/src/video/vid_voodoo_banshee_blitter.c index 33ee602b5..b8809d3fd 100644 --- a/src/video/vid_voodoo_banshee_blitter.c +++ b/src/video/vid_voodoo_banshee_blitter.c @@ -216,6 +216,9 @@ PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t pattern_mask, uint32_t dest = voodoo->vram[addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern8[(pat_x & 7) + (pat_y & 7) * 8]; + if (addr > voodoo->fb_mask) + break; + voodoo->vram[addr] = MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_8); voodoo->changedvram[addr >> 12] = changeframecount; break; @@ -226,6 +229,9 @@ PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t pattern_mask, uint32_t dest = *(uint16_t *) &voodoo->vram[addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern16[(pat_x & 7) + (pat_y & 7) * 8]; + if (addr > voodoo->fb_mask) + break; + *(uint16_t *) &voodoo->vram[addr] = MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_16); voodoo->changedvram[addr >> 12] = changeframecount; break; @@ -236,6 +242,9 @@ PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t pattern_mask, uint32_t dest = *(uint32_t *) &voodoo->vram[addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern24[(pat_x & 7) + (pat_y & 7) * 8]; + if (addr > voodoo->fb_mask) + break; + *(uint32_t *) &voodoo->vram[addr] = (MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_32) & 0xffffff) | (dest & 0xff000000); voodoo->changedvram[addr >> 12] = changeframecount; break; @@ -246,6 +255,9 @@ PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t pattern_mask, uint32_t dest = *(uint32_t *) &voodoo->vram[addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; + if (addr > voodoo->fb_mask) + break; + *(uint32_t *) &voodoo->vram[addr] = MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_32); voodoo->changedvram[addr >> 12] = changeframecount; break; @@ -265,6 +277,9 @@ PLOT_LINE(voodoo_t *voodoo, int x, int y, UNUSED(uint8_t rop), uint32_t pattern, uint32_t addr = get_addr(voodoo, x, y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + x + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t dest = voodoo->vram[addr]; + if (addr > voodoo->fb_mask) + break; + voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_8); voodoo->changedvram[addr >> 12] = changeframecount; break; @@ -274,6 +289,9 @@ PLOT_LINE(voodoo_t *voodoo, int x, int y, UNUSED(uint8_t rop), uint32_t pattern, uint32_t addr = get_addr(voodoo, x * 2, y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + x*2 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t dest = *(uint16_t *) &voodoo->vram[addr]; + if (addr > voodoo->fb_mask) + break; + *(uint16_t *) &voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_16); voodoo->changedvram[addr >> 12] = changeframecount; break; @@ -283,6 +301,9 @@ PLOT_LINE(voodoo_t *voodoo, int x, int y, UNUSED(uint8_t rop), uint32_t pattern, uint32_t addr = get_addr(voodoo, x * 3, y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + x*3 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t dest = *(uint32_t *) &voodoo->vram[addr]; + if (addr > voodoo->fb_mask) + break; + *(uint32_t *) &voodoo->vram[addr] = (MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_32) & 0xffffff) | (dest & 0xff000000); voodoo->changedvram[addr >> 12] = changeframecount; break; @@ -292,6 +313,9 @@ PLOT_LINE(voodoo_t *voodoo, int x, int y, UNUSED(uint8_t rop), uint32_t pattern, uint32_t addr = get_addr(voodoo, x * 4, y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + x*4 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t dest = *(uint32_t *) &voodoo->vram[addr]; + if (addr > voodoo->fb_mask) + break; + *(uint32_t *) &voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_32); voodoo->changedvram[addr >> 12] = changeframecount; break; @@ -573,6 +597,9 @@ do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int sr uint32_t dest = voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern8[(pat_x & 7) + (pat_y & 7) * 8]; + if (dst_addr > voodoo->fb_mask) + break; + voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_8, COLORKEY_8); voodoo->changedvram[dst_addr >> 12] = changeframecount; break; @@ -584,6 +611,9 @@ do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int sr uint32_t dest = *(uint16_t *) &voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern16[(pat_x & 7) + (pat_y & 7) * 8]; + if (dst_addr > voodoo->fb_mask) + break; + *(uint16_t *) &voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_16, COLORKEY_16); voodoo->changedvram[dst_addr >> 12] = changeframecount; break; @@ -595,6 +625,9 @@ do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int sr uint32_t dest = *(uint32_t *) &voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern24[(pat_x & 7) + (pat_y & 7) * 8]; + if (dst_addr > voodoo->fb_mask) + break; + *(uint32_t *) &voodoo->vram[dst_addr] = (MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32) & 0xffffff) | (dest & 0xff000000); voodoo->changedvram[dst_addr >> 12] = changeframecount; break; @@ -606,6 +639,9 @@ do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int sr uint32_t dest = *(uint32_t *) &voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; + if (dst_addr > voodoo->fb_mask) + break; + *(uint32_t *) &voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32); voodoo->changedvram[dst_addr >> 12] = changeframecount; break; @@ -904,6 +940,9 @@ do_screen_to_screen_stretch_line(voodoo_t *voodoo, uint8_t *src_p, int src_x, in uint32_t dest = voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; + if (dst_addr > voodoo->fb_mask) + break; + voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_8, COLORKEY_8); #if 0 bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]); @@ -918,6 +957,9 @@ do_screen_to_screen_stretch_line(voodoo_t *voodoo, uint8_t *src_p, int src_x, in uint32_t dest = *(uint16_t *) &voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; + if (dst_addr > voodoo->fb_mask) + break; + *(uint16_t *) &voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_16, COLORKEY_16); #if 0 bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, *(uint16_t *)&voodoo->vram[dst_addr]); @@ -932,6 +974,9 @@ do_screen_to_screen_stretch_line(voodoo_t *voodoo, uint8_t *src_p, int src_x, in uint32_t dest = *(uint32_t *) &voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; + if (dst_addr > voodoo->fb_mask) + break; + *(uint32_t *) &voodoo->vram[dst_addr] = (MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32) & 0xffffff) | (*(uint32_t *) &voodoo->vram[dst_addr] & 0xff000000); #if 0 bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]); @@ -946,6 +991,9 @@ do_screen_to_screen_stretch_line(voodoo_t *voodoo, uint8_t *src_p, int src_x, in uint32_t dest = *(uint32_t *) &voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; + if (dst_addr > voodoo->fb_mask) + break; + *(uint32_t *) &voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32); #if 0 bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]); diff --git a/src/video/vid_voodoo_render.c b/src/video/vid_voodoo_render.c index 42426744a..0f31fbc9f 100644 --- a/src/video/vid_voodoo_render.c +++ b/src/video/vid_voodoo_render.c @@ -1394,7 +1394,7 @@ next_line: void voodoo_triangle(voodoo_t *voodoo, voodoo_params_t *params, int odd_even) { - voodoo_state_t state; + voodoo_state_t state = { 0 }; int vertexAy_adjusted; int vertexCy_adjusted; int dx; @@ -1406,6 +1406,8 @@ voodoo_triangle(voodoo_t *voodoo, voodoo_params_t *params, int odd_even) int LOD; int lodbias; + state.dx1 = state.dx2 = 0; + voodoo->tri_count++; dx = 8 - (params->vertexAx & 0xf); From 71ecdc1b55b31a81cf64c3358a5c56fe222a2e8b Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 29 Feb 2024 06:52:45 +0100 Subject: [PATCH 600/936] No longer raise TS# when (CS & 0xFFF8) is zero and (CS & 0x0004) is not, fixes #4214. --- src/cpu/x86seg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index c50c97a39..d912a755b 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -2401,7 +2401,7 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) ldt.base |= (readmemb(0, templ + 7) << 24); } - if (!(new_cs & 0xfff8)) { + if (!(new_cs & 0xfff8) && !(new_cs & 0x0004)) { x86ts(NULL, 0); return; } From fd31aba2a1e2ffe8c67efe42363d09c470ffcd7b Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 29 Feb 2024 13:58:05 +0600 Subject: [PATCH 601/936] MGA: Implement X11 hardware cursor --- src/video/vid_mga.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 6b0c563b2..074303553 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -6016,6 +6016,17 @@ mystique_hwcursor_draw(svga_t *svga, int displine) } break; + case XCURCTRL_CURMODE_XWIN: + for (uint8_t x = 0; x < 64; x++) { + if ((dat[1] & (1ULL << 63))) + svga->monitor->target_buffer->line[displine][(offset + svga->x_add) & 2047] = (dat[0] & (1ULL << 63)) ? (mystique->cursor.col[1]) : (mystique->cursor.col[0]); + + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + break; + default: break; } From e0d80aefb4be625d2a26dbb3e7e8ffa52ce4b9c8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 1 Mar 2024 06:52:48 +0100 Subject: [PATCH 602/936] Moved OPL2 and OPL3 to a new 49716 Hz source so resampling is no longer needed, also fixed SB OPL and PC Speaker filtering (OPL was being downsampled to the selected DSP sample rate, which is incorrect, and the PC Speaker filter was using the wrong filter index in some liens). --- src/include/86box/filters.h | 66 +++---- src/include/86box/snd_sb.h | 2 +- src/include/86box/snd_sb_dsp.h | 4 + src/include/86box/sound.h | 10 + src/sound/openal.c | 46 +++-- src/sound/snd_adlib.c | 2 +- src/sound/snd_adlibgold.c | 130 ++++++++++++- src/sound/snd_azt2316a.c | 3 + src/sound/snd_cs423x.c | 25 ++- src/sound/snd_opl_nuked.c | 22 ++- src/sound/snd_opl_ymfm.cpp | 45 +++-- src/sound/snd_optimc.c | 8 +- src/sound/snd_pas16.c | 16 +- src/sound/snd_sb.c | 342 ++++++++++++++++++++++++--------- src/sound/snd_sb_dsp.c | 16 +- src/sound/snd_wss.c | 29 ++- src/sound/sound.c | 91 +++++++++ src/sound/xaudio2.c | 19 +- 18 files changed, 683 insertions(+), 193 deletions(-) diff --git a/src/include/86box/filters.h b/src/include/86box/filters.h index dfe19c654..16c9c7221 100644 --- a/src/include/86box/filters.h +++ b/src/include/86box/filters.h @@ -5,7 +5,7 @@ /* fc=150Hz */ static inline float -adgold_highpass_iir(int i, float NewSample) +adgold_highpass_iir(int c, int i, float NewSample) { float ACoef[NCoef + 1] = { 0.98657437157334349000, @@ -19,28 +19,28 @@ adgold_highpass_iir(int i, float NewSample) 0.97261396931534050000 }; - static float y[2][NCoef + 1]; /* output samples */ - static float x[2][NCoef + 1]; /* input samples */ + static float y[2][2][NCoef + 1]; /* output samples */ + static float x[2][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ for (n = NCoef; n > 0; n--) { - x[i][n] = x[i][n - 1]; - y[i][n] = y[i][n - 1]; + x[c][i][n] = x[c][i][n - 1]; + y[c][i][n] = y[c][i][n - 1]; } /* Calculate the new output */ - x[i][0] = NewSample; - y[i][0] = ACoef[0] * x[i][0]; + x[c][i][0] = NewSample; + y[c][i][0] = ACoef[0] * x[c][i][0]; for (n = 1; n <= NCoef; n++) - y[i][0] += ACoef[n] * x[i][n] - BCoef[n] * y[i][n]; + y[c][i][0] += ACoef[n] * x[c][i][n] - BCoef[n] * y[c][i][n]; - return y[i][0]; + return y[c][i][0]; } /* fc=150Hz */ static inline float -adgold_lowpass_iir(int i, float NewSample) +adgold_lowpass_iir(int c, int i, float NewSample) { float ACoef[NCoef + 1] = { 0.00009159473951071446, @@ -54,23 +54,23 @@ adgold_lowpass_iir(int i, float NewSample) 0.97261396931306277000 }; - static float y[2][NCoef + 1]; /* output samples */ - static float x[2][NCoef + 1]; /* input samples */ + static float y[2][2][NCoef + 1]; /* output samples */ + static float x[2][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ for (n = NCoef; n > 0; n--) { - x[i][n] = x[i][n - 1]; - y[i][n] = y[i][n - 1]; + x[c][i][n] = x[c][i][n - 1]; + y[c][i][n] = y[c][i][n - 1]; } /* Calculate the new output */ - x[i][0] = NewSample; - y[i][0] = ACoef[0] * x[i][0]; + x[c][i][0] = NewSample; + y[c][i][0] = ACoef[0] * x[c][i][0]; for (n = 1; n <= NCoef; n++) - y[i][0] += ACoef[n] * x[i][n] - BCoef[n] * y[i][n]; + y[c][i][0] += ACoef[n] * x[c][i][n] - BCoef[n] * y[c][i][n]; - return y[i][0]; + return y[c][i][0]; } /* fc=56Hz */ @@ -197,8 +197,8 @@ low_iir(int c, int i, double NewSample) 0.93726236021404663000 }; - static double y[3][2][NCoef + 1]; /* output samples */ - static double x[3][2][NCoef + 1]; /* input samples */ + static double y[4][2][NCoef + 1]; /* output samples */ + static double x[4][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -232,8 +232,8 @@ low_cut_iir(int c, int i, double NewSample) 0.93726236021916731000 }; - static double y[3][2][NCoef + 1]; /* output samples */ - static double x[3][2][NCoef + 1]; /* input samples */ + static double y[4][2][NCoef + 1]; /* output samples */ + static double x[4][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -266,8 +266,8 @@ high_iir(int c, int i, double NewSample) -1.36640781670578510000, 0.52352474706139873000 }; - static double y[3][2][NCoef + 1]; /* output samples */ - static double x[3][2][NCoef + 1]; /* input samples */ + static double y[4][2][NCoef + 1]; /* output samples */ + static double x[4][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -300,8 +300,8 @@ high_cut_iir(int c, int i, double NewSample) -1.36640781666419950000, 0.52352474703279628000 }; - static double y[3][2][NCoef + 1]; /* output samples */ - static double x[3][2][NCoef + 1]; /* input samples */ + static double y[4][2][NCoef + 1]; /* output samples */ + static double x[4][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -334,8 +334,8 @@ deemph_iir(int i, double NewSample) -1.05429146278569141337, 0.26412280202756849290 }; - static double y[3][NCoef + 1]; /* output samples */ - static double x[3][NCoef + 1]; /* input samples */ + static double y[4][NCoef + 1]; /* output samples */ + static double x[4][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -372,8 +372,8 @@ sb_iir(int c, int i, double NewSample) 0.55326988968868285000 }; - static double y[3][2][NCoef + 1]; /* output samples */ - static double x[3][2][NCoef + 1]; /* input samples */ + static double y[4][2][NCoef + 1]; /* output samples */ + static double x[4][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -395,13 +395,13 @@ sb_iir(int c, int i, double NewSample) #define NCoef 1 #define SB16_NCoef 51 -extern double low_fir_sb16_coef[3][SB16_NCoef]; +extern double low_fir_sb16_coef[4][SB16_NCoef]; static inline double low_fir_sb16(int c, int i, double NewSample) { - static double x[3][2][SB16_NCoef + 1]; // input samples - static int pos[3] = { 0, 0 }; + static double x[4][2][SB16_NCoef + 1]; // input samples + static int pos[4] = { 0, 0, 0, 0 }; double out = 0.0; int n; diff --git a/src/include/86box/snd_sb.h b/src/include/86box/snd_sb.h index f433dd107..621cb4ade 100644 --- a/src/include/86box/snd_sb.h +++ b/src/include/86box/snd_sb.h @@ -143,7 +143,6 @@ typedef struct sb_t { emu8k_t emu8k; void *gameport; - int pos; int pnp; uint8_t pos_regs[8]; @@ -165,6 +164,7 @@ extern uint8_t sb_ct1745_mixer_read(uint16_t addr, void *priv); extern void sb_ct1745_mixer_reset(sb_t *sb); extern void sb_get_buffer_sbpro(int32_t *buffer, int len, void *priv); +extern void sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv); extern void sbpro_filter_cd_audio(int channel, double *buffer, void *priv); extern void sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv); extern void sb_close(void *priv); diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index ecabe426d..3e0e40e80 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -97,6 +97,8 @@ typedef struct sb_dsp_t { int sb_irqm16; int sb_irqm401; + uint8_t sb_has_real_opl; + uint8_t sb_asp_regs[256]; uint8_t sb_asp_mode; @@ -158,6 +160,8 @@ extern void sb_dsp_speed_changed(sb_dsp_t *dsp); extern void sb_dsp_poll(sb_dsp_t *dsp, int16_t *l, int16_t *r); +extern void sb_dsp_set_real_opl(sb_dsp_t *dsp, uint8_t has_real_opl); + extern void sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo); extern void sb_dsp_update(sb_dsp_t *dsp); diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index 60628ece8..b8f9be5b2 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -33,6 +33,9 @@ extern int sound_gain; #define SOUND_FREQ FREQ_48000 #define SOUNDBUFLEN (SOUND_FREQ / 50) +#define MUSIC_FREQ FREQ_49716 +#define MUSICBUFLEN (MUSIC_FREQ / 36) + #define CD_FREQ FREQ_44100 #define CD_BUFLEN (CD_FREQ / 10) @@ -47,12 +50,18 @@ extern int speakval; extern int speakon; extern int sound_pos_global; +extern int music_pos_global; + extern int sound_card_current[SOUND_CARD_MAX]; extern void sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *priv), void *priv); +extern void music_add_handler(void (*get_buffer)(int32_t *buffer, + int len, void *priv), + void *priv); + extern void sound_set_cd_audio_filter(void (*filter)(int channel, double *buffer, void *priv), void *priv); @@ -86,6 +95,7 @@ extern void sound_cd_thread_reset(void); extern void closeal(void); extern void inital(void); extern void givealbuffer(void *buf); +extern void givealbuffer_music(void *buf); extern void givealbuffer_cd(void *buf); #define sb_vibra16c_onboard_relocate_base sb_vibra16s_onboard_relocate_base diff --git a/src/sound/openal.c b/src/sound/openal.c index 76656c66e..98f87855e 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -38,10 +38,11 @@ #define FREQ SOUND_FREQ #define BUFLEN SOUNDBUFLEN -ALuint buffers[4]; /* front and back buffers */ -ALuint buffers_cd[4]; /* front and back buffers */ -ALuint buffers_midi[4]; /* front and back buffers */ -static ALuint source[3]; /* audio source */ +ALuint buffers[4]; /* front and back buffers */ +ALuint buffers_music[4]; /* front and back buffers */ +ALuint buffers_cd[4]; /* front and back buffers */ +ALuint buffers_midi[4]; /* front and back buffers */ +static ALuint source[4]; /* audio source */ static int midi_freq = 44100; static int midi_buf_size = 4410; @@ -99,9 +100,10 @@ closeal(void) alSourceStopv(sources, source); alDeleteSources(sources, source); - if (sources == 3) + if (sources == 4) alDeleteBuffers(4, buffers_midi); alDeleteBuffers(4, buffers_cd); + alDeleteBuffers(4, buffers_music); alDeleteBuffers(4, buffers); alutExit(); @@ -132,16 +134,18 @@ inital(void) if (strcmp(mdn, "none") && strcmp(mdn, SYSTEM_MIDI_INTERNAL_NAME)) init_midi = 1; /* If the device is neither none, nor system MIDI, initialize the MIDI buffer and source, otherwise, do not. */ - sources = 2 + !!init_midi; + sources = 3 + !!init_midi; if (sound_is_float) { - buf = (float *) calloc((BUFLEN << 1), sizeof(float)); - cd_buf = (float *) calloc((CD_BUFLEN << 1), sizeof(float)); + buf = (float *) calloc((BUFLEN << 1), sizeof(float)); + music_buf = (float *) calloc((MUSIC_BUFLEN << 1), sizeof(float)); + cd_buf = (float *) calloc((CD_BUFLEN << 1), sizeof(float)); if (init_midi) midi_buf = (float *) calloc(midi_buf_size, sizeof(float)); } else { - buf_int16 = (int16_t *) calloc((BUFLEN << 1), sizeof(int16_t)); - cd_buf_int16 = (int16_t *) calloc((CD_BUFLEN << 1), sizeof(int16_t)); + buf_int16 = (int16_t *) calloc((BUFLEN << 1), sizeof(int16_t)); + music_buf_int16 = (int16_t *) calloc((MUSIC_BUFLEN << 1), sizeof(int16_t)); + cd_buf_int16 = (int16_t *) calloc((CD_BUFLEN << 1), sizeof(int16_t)); if (init_midi) midi_buf_int16 = (int16_t *) calloc(midi_buf_size, sizeof(int16_t)); } @@ -189,11 +193,13 @@ inital(void) for (uint8_t c = 0; c < 4; c++) { if (sound_is_float) { alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN * 2 * sizeof(float), FREQ); + alBufferData(buffers_music[c], AL_FORMAT_STEREO_FLOAT32, buf, MUSIC_BUFLEN * 2 * sizeof(float), MUSIC_FREQ); alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, cd_buf, CD_BUFLEN * 2 * sizeof(float), CD_FREQ); if (init_midi) alBufferData(buffers_midi[c], AL_FORMAT_STEREO_FLOAT32, midi_buf, midi_buf_size * sizeof(float), midi_freq); } else { alBufferData(buffers[c], AL_FORMAT_STEREO16, buf_int16, BUFLEN * 2 * sizeof(int16_t), FREQ); + alBufferData(buffers_music[c], AL_FORMAT_STEREO16, buf_int16, MUSIC_BUFLEN * 2 * sizeof(int16_t), MUSIC_FREQ); alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, cd_buf_int16, CD_BUFLEN * 2 * sizeof(int16_t), CD_FREQ); if (init_midi) alBufferData(buffers_midi[c], AL_FORMAT_STEREO16, midi_buf_int16, midi_buf_size * sizeof(int16_t), midi_freq); @@ -201,23 +207,27 @@ inital(void) } alSourceQueueBuffers(source[0], 4, buffers); - alSourceQueueBuffers(source[1], 4, buffers_cd); + alSourceQueueBuffers(source[1], 4, buffers_music); + alSourceQueueBuffers(source[2], 4, buffers_cd); if (init_midi) - alSourceQueueBuffers(source[2], 4, buffers_midi); + alSourceQueueBuffers(source[3], 4, buffers_midi); alSourcePlay(source[0]); alSourcePlay(source[1]); + alSourcePlay(source[2]); if (init_midi) - alSourcePlay(source[2]); + alSourcePlay(source[3]); if (sound_is_float) { if (init_midi) free(midi_buf); free(cd_buf); + free(music_buf); free(buf); } else { if (init_midi) free(midi_buf_int16); free(cd_buf_int16); + free(music_buf_int16); free(buf_int16); } @@ -263,14 +273,20 @@ givealbuffer(void *buf) givealbuffer_common(buf, 0, BUFLEN << 1, FREQ); } +void +givealbuffer_music(void *buf) +{ + givealbuffer_common(buf, 1, MUSIC_BUFLEN << 1, MUSIC_FREQ); +} + void givealbuffer_cd(void *buf) { - givealbuffer_common(buf, 1, CD_BUFLEN << 1, CD_FREQ); + givealbuffer_common(buf, 2, CD_BUFLEN << 1, CD_FREQ); } void givealbuffer_midi(void *buf, uint32_t size) { - givealbuffer_common(buf, 2, size, midi_freq); + givealbuffer_common(buf, 3, size, midi_freq); } diff --git a/src/sound/snd_adlib.c b/src/sound/snd_adlib.c index 5d0d7c7aa..f5eae9b93 100644 --- a/src/sound/snd_adlib.c +++ b/src/sound/snd_adlib.c @@ -112,7 +112,7 @@ adlib_init(UNUSED(const device_t *info)) adlib->opl.read, NULL, NULL, adlib->opl.write, NULL, NULL, adlib->opl.priv); - sound_add_handler(adlib_get_buffer, adlib); + music_add_handler(adlib_get_buffer, adlib); return adlib; } diff --git a/src/sound/snd_adlibgold.c b/src/sound/snd_adlibgold.c index 71cbbcaa6..488dcb8a6 100644 --- a/src/sound/snd_adlibgold.c +++ b/src/sound/snd_adlibgold.c @@ -788,13 +788,10 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv) int c; - const int32_t *opl_buf = adgold->opl.update(adgold->opl.priv); adgold_update(adgold); for (c = 0; c < len * 2; c += 2) { - adgold_buffer[c] = ((opl_buf[c] * adgold->fm_vol_l) >> 7) / 2; adgold_buffer[c] += ((adgold->mma_buffer[0][c >> 1] * adgold->samp_vol_l) >> 7) / 4; - adgold_buffer[c + 1] = ((opl_buf[c + 1] * adgold->fm_vol_r) >> 7) / 2; adgold_buffer[c + 1] += ((adgold->mma_buffer[1][c >> 1] * adgold->samp_vol_r) >> 7) / 4; } @@ -857,8 +854,8 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv) /*Output is deliberately halved to avoid clipping*/ temp = ((int32_t) adgold_buffer[c] * adgold->vol_l) >> 17; - lowpass = adgold_lowpass_iir(0, temp); - highpass = adgold_highpass_iir(0, temp); + lowpass = adgold_lowpass_iir(0, 0, temp); + highpass = adgold_highpass_iir(0, 0, temp); if (adgold->bass > 6) temp += (lowpass * bass_attenuation[adgold->bass]) >> 14; else if (adgold->bass < 6) @@ -874,8 +871,124 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv) buffer[c] += temp; temp = ((int32_t) adgold_buffer[c + 1] * adgold->vol_r) >> 17; - lowpass = adgold_lowpass_iir(1, temp); - highpass = adgold_highpass_iir(1, temp); + lowpass = adgold_lowpass_iir(0, 1, temp); + highpass = adgold_highpass_iir(0, 1, temp); + if (adgold->bass > 6) + temp += (lowpass * bass_attenuation[adgold->bass]) >> 14; + else if (adgold->bass < 6) + temp = highpass + ((temp * bass_cut[adgold->bass]) >> 14); + if (adgold->treble > 6) + temp += (highpass * treble_attenuation[adgold->treble]) >> 14; + else if (adgold->treble < 6) + temp = lowpass + ((temp * treble_cut[adgold->treble]) >> 14); + if (temp < -32768) + temp = -32768; + if (temp > 32767) + temp = 32767; + buffer[c + 1] += temp; + } + + adgold->pos = 0; + + free(adgold_buffer); +} + +static void +adgold_get_music_buffer(int32_t *buffer, int len, void *priv) +{ + adgold_t *adgold = (adgold_t *) priv; + int16_t *adgold_buffer = malloc(sizeof(int16_t) * len * 2); + if (adgold_buffer == NULL) + fatal("adgold_buffer = NULL"); + + int c; + + const int32_t *opl_buf = adgold->opl.update(adgold->opl.priv); + adgold_update(adgold); + + for (c = 0; c < len * 2; c += 2) { + adgold_buffer[c] = ((opl_buf[c] * adgold->fm_vol_l) >> 7) / 2; + adgold_buffer[c + 1] = ((opl_buf[c + 1] * adgold->fm_vol_r) >> 7) / 2; + } + + if (adgold->surround_enabled) + ym7128_apply(&adgold->ym7128, adgold_buffer, len); + + switch (adgold->adgold_38x_regs[0x8] & 6) { + case 0: + for (c = 0; c < len * 2; c++) + adgold_buffer[c] = 0; + break; + case 2: /*Left channel only*/ + for (c = 0; c < len * 2; c += 2) + adgold_buffer[c + 1] = adgold_buffer[c]; + break; + case 4: /*Right channel only*/ + for (c = 0; c < len * 2; c += 2) + adgold_buffer[c] = adgold_buffer[c + 1]; + break; + case 6: /*Left and right channels*/ + break; + + default: + break; + } + + switch (adgold->adgold_38x_regs[0x8] & 0x18) { + case 0x00: /*Forced mono*/ + for (c = 0; c < len * 2; c += 2) + adgold_buffer[c] = adgold_buffer[c + 1] = ((int32_t) adgold_buffer[c] + (int32_t) adgold_buffer[c + 1]) / 2; + break; + case 0x08: /*Linear stereo*/ + break; + case 0x10: /*Pseudo stereo*/ + /*Filter left channel, leave right channel unchanged*/ + /*Filter cutoff is largely a guess*/ + for (c = 0; c < len * 2; c += 2) + adgold_buffer[c] += adgold_pseudo_stereo_iir(adgold_buffer[c]); + break; + case 0x18: /*Spatial stereo*/ + /*Quite probably wrong, I only have the diagram in the TDA8425 datasheet + and a very vague understanding of how op-amps work to go on*/ + for (c = 0; c < len * 2; c += 2) { + int16_t l = adgold_buffer[c]; + int16_t r = adgold_buffer[c + 1]; + + adgold_buffer[c] += (r / 3) + ((l * 2) / 3); + adgold_buffer[c + 1] += (l / 3) + ((r * 2) / 3); + } + break; + + default: + break; + } + + for (c = 0; c < len * 2; c += 2) { + int32_t temp; + int32_t lowpass; + int32_t highpass; + + /*Output is deliberately halved to avoid clipping*/ + temp = ((int32_t) adgold_buffer[c] * adgold->vol_l) >> 17; + lowpass = adgold_lowpass_iir(1, 0, temp); + highpass = adgold_highpass_iir(1, 0, temp); + if (adgold->bass > 6) + temp += (lowpass * bass_attenuation[adgold->bass]) >> 14; + else if (adgold->bass < 6) + temp = highpass + ((temp * bass_cut[adgold->bass]) >> 14); + if (adgold->treble > 6) + temp += (highpass * treble_attenuation[adgold->treble]) >> 14; + else if (adgold->treble < 6) + temp = lowpass + ((temp * treble_cut[adgold->treble]) >> 14); + if (temp < -32768) + temp = -32768; + if (temp > 32767) + temp = 32767; + buffer[c] += temp; + + temp = ((int32_t) adgold_buffer[c + 1] * adgold->vol_r) >> 17; + lowpass = adgold_lowpass_iir(1, 1, temp); + highpass = adgold_highpass_iir(1, 1, temp); if (adgold->bass > 6) temp += (lowpass * bass_attenuation[adgold->bass]) >> 14; else if (adgold->bass < 6) @@ -892,7 +1005,6 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv) } adgold->opl.reset_buffer(adgold->opl.priv); - adgold->pos = 0; free(adgold_buffer); } @@ -1054,6 +1166,8 @@ adgold_init(UNUSED(const device_t *info)) timer_add(&adgold->adgold_mma_timer_count, adgold_timer_poll, adgold, 1); sound_add_handler(adgold_get_buffer, adgold); + music_add_handler(adgold_get_music_buffer, adgold); + sound_set_cd_audio_filter(adgold_filter_cd_audio, adgold); if (device_get_config_int("receive_input")) diff --git a/src/sound/snd_azt2316a.c b/src/sound/snd_azt2316a.c index 80d668599..28ab2b7ac 100644 --- a/src/sound/snd_azt2316a.c +++ b/src/sound/snd_azt2316a.c @@ -1237,6 +1237,7 @@ azt_init(const device_t *info) if (azt2316a->sb->opl_enabled) fm_driver_get(FM_YMF262, &azt2316a->sb->opl); + sb_dsp_set_real_opl(&azt2316a->sb->dsp, 1); sb_dsp_init(&azt2316a->sb->dsp, SBPRO2, azt2316a->type, azt2316a); sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr); sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq); @@ -1253,6 +1254,8 @@ azt_init(const device_t *info) azt2316a_create_config_word(azt2316a); sound_add_handler(azt2316a_get_buffer, azt2316a); + if (azt2316a->sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sbpro, azt2316a->sb); sound_set_cd_audio_filter(sbpro_filter_cd_audio, azt2316a->sb); if (azt2316a->cur_mpu401_enabled) { diff --git a/src/sound/snd_cs423x.c b/src/sound/snd_cs423x.c index fad1d76b9..90aa0b0dd 100644 --- a/src/sound/snd_cs423x.c +++ b/src/sound/snd_cs423x.c @@ -543,13 +543,31 @@ cs423x_ctxswitch_write(uint16_t addr, UNUSED(uint8_t val), void *priv) static void cs423x_get_buffer(int32_t *buffer, int len, void *priv) +{ + cs423x_t *dev = (cs423x_t *) priv; + + /* Output audio from the WSS codec, and also the OPL if we're in charge of it. */ + ad1848_update(&dev->ad1848); + + /* Don't output anything if the analog section is powered down. */ + if (!(dev->indirect_regs[2] & 0xa4)) { + for (int c = 0; c < len * 2; c += 2) { + buffer[c] += dev->ad1848.buffer[c] / 2; + buffer[c + 1] += dev->ad1848.buffer[c + 1] / 2; + } + } + + dev->ad1848.pos = 0; +} + +static void +cs423x_get_music_buffer(int32_t *buffer, int len, void *priv) { cs423x_t *dev = (cs423x_t *) priv; int opl_wss = dev->opl_wss; const int32_t *opl_buf = NULL; /* Output audio from the WSS codec, and also the OPL if we're in charge of it. */ - ad1848_update(&dev->ad1848); if (opl_wss) opl_buf = dev->sb->opl.update(dev->sb->opl.priv); @@ -560,13 +578,9 @@ cs423x_get_buffer(int32_t *buffer, int len, void *priv) buffer[c] += (opl_buf[c] * dev->ad1848.fm_vol_l) >> 16; buffer[c + 1] += (opl_buf[c + 1] * dev->ad1848.fm_vol_r) >> 16; } - - buffer[c] += dev->ad1848.buffer[c] / 2; - buffer[c + 1] += dev->ad1848.buffer[c + 1] / 2; } } - dev->ad1848.pos = 0; if (opl_wss) dev->sb->opl.reset_buffer(dev->sb->opl.priv); } @@ -846,6 +860,7 @@ cs423x_init(const device_t *info) /* Initialize RAM, registers and WSS codec. */ cs423x_reset(dev); sound_add_handler(cs423x_get_buffer, dev); + music_add_handler(cs423x_get_music_buffer, dev); /* Add Control/RAM backdoor handlers for CS4235. */ dev->ad1848.cram_priv = dev; diff --git a/src/sound/snd_opl_nuked.c b/src/sound/snd_opl_nuked.c index d8281ba1d..95b61638e 100644 --- a/src/sound/snd_opl_nuked.c +++ b/src/sound/snd_opl_nuked.c @@ -55,7 +55,8 @@ #define WRBUF_DELAY 1 #define RSM_FRAC 10 -#define OPL_FREQ FREQ_48000 +// #define OPL_FREQ FREQ_48000 +#define OPL_FREQ FREQ_49716 // Channel types enum { @@ -189,7 +190,7 @@ typedef struct { pc_timer_t timers[2]; int pos; - int32_t buffer[SOUNDBUFLEN * 2]; + int32_t buffer[MUSICBUFLEN * 2]; } nuked_drv_t; enum { @@ -1381,11 +1382,20 @@ nuked_generate_resampled(nuked_t *dev, int32_t *bufp) dev->samplecnt += 1 << RSM_FRAC; } +void +nuked_generate_raw(nuked_t *dev, int32_t *bufp) +{ + nuked_generate(dev, dev->samples); + + bufp[0] = (int32_t) dev->samples[0]; + bufp[1] = (int32_t) dev->samples[1]; +} + void nuked_generate_stream(nuked_t *dev, int32_t *sndptr, uint32_t num) { for (uint32_t i = 0; i < num; i++) { - nuked_generate_resampled(dev, sndptr); + nuked_generate_raw(dev, sndptr); sndptr += 2; } } @@ -1533,14 +1543,14 @@ nuked_drv_update(void *priv) { nuked_drv_t *dev = (nuked_drv_t *) priv; - if (dev->pos >= sound_pos_global) + if (dev->pos >= music_pos_global) return dev->buffer; nuked_generate_stream(&dev->opl, &dev->buffer[dev->pos * 2], - sound_pos_global - dev->pos); + music_pos_global - dev->pos); - for (; dev->pos < sound_pos_global; dev->pos++) { + for (; dev->pos < music_pos_global; dev->pos++) { dev->buffer[dev->pos * 2] /= 2; dev->buffer[(dev->pos * 2) + 1] /= 2; } diff --git a/src/sound/snd_opl_ymfm.cpp b/src/sound/snd_opl_ymfm.cpp index 0f996f6bc..55e7f1984 100644 --- a/src/sound/snd_opl_ymfm.cpp +++ b/src/sound/snd_opl_ymfm.cpp @@ -51,10 +51,11 @@ enum { class YMFMChipBase { public: - YMFMChipBase(UNUSED(uint32_t clock), fm_type type, UNUSED(uint32_t samplerate)) + YMFMChipBase(UNUSED(uint32_t clock), fm_type type, uint32_t samplerate) : m_buf_pos(0) , m_flags(0) , m_type(type) + , m_samplerate(samplerate) { memset(m_buffer, 0, sizeof(m_buffer)); } @@ -79,10 +80,11 @@ public: virtual void set_clock(uint32_t clock) = 0; protected: - int32_t m_buffer[SOUNDBUFLEN * 2]; - int m_buf_pos; - int8_t m_flags; - fm_type m_type; + int32_t m_buffer[MUSICBUFLEN * 2]; + int m_buf_pos; + int8_t m_flags; + fm_type m_type; + uint32_t m_samplerate; }; template @@ -170,6 +172,11 @@ public: virtual void generate_resampled(int32_t *data, uint32_t num_samples) override { + if (m_samplerate == FREQ_49716) { + generate(data, num_samples); + return; + } + for (uint32_t i = 0; i < num_samples; i++) { while (m_samplecnt >= m_rateratio) { m_oldsamples[0] = m_samples[0]; @@ -206,14 +213,26 @@ public: virtual int32_t *update() override { - if (m_buf_pos >= sound_pos_global) - return m_buffer; + if (m_samplerate == FREQ_49716) { + if (m_buf_pos >= music_pos_global) + return m_buffer; - generate_resampled(&m_buffer[m_buf_pos * 2], sound_pos_global - m_buf_pos); + generate(&m_buffer[m_buf_pos * 2], music_pos_global - m_buf_pos); - for (; m_buf_pos < sound_pos_global; m_buf_pos++) { - m_buffer[m_buf_pos * 2] /= 2; - m_buffer[(m_buf_pos * 2) + 1] /= 2; + for (; m_buf_pos < music_pos_global; m_buf_pos++) { + m_buffer[m_buf_pos * 2] /= 2; + m_buffer[(m_buf_pos * 2) + 1] /= 2; + } + } else { + if (m_buf_pos >= sound_pos_global) + return m_buffer; + + generate_resampled(&m_buffer[m_buf_pos * 2], sound_pos_global - m_buf_pos); + + for (; m_buf_pos < sound_pos_global; m_buf_pos++) { + m_buffer[m_buf_pos * 2] /= 2; + m_buffer[(m_buf_pos * 2) + 1] /= 2; + } } return m_buffer; @@ -314,11 +333,11 @@ ymfm_drv_init(const device_t *info) switch (info->local) { default: case FM_YM3812: - fm = (YMFMChipBase *) new YMFMChip(3579545, FM_YM3812, OPL_FREQ); + fm = (YMFMChipBase *) new YMFMChip(3579545, FM_YM3812, FREQ_49716); break; case FM_YMF262: - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF262, OPL_FREQ); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF262, FREQ_49716); break; case FM_YMF289B: diff --git a/src/sound/snd_optimc.c b/src/sound/snd_optimc.c index d7afca382..245d9590e 100644 --- a/src/sound/snd_optimc.c +++ b/src/sound/snd_optimc.c @@ -391,6 +391,9 @@ optimc_init(const device_t *info) optimc->sb = calloc(1, sizeof(sb_t)); optimc->sb->opl_enabled = 1; + optimc->fm_type = (info->local & OPTIMC_OPL4) ? FM_YMF278B : FM_YMF262; + + sb_dsp_set_real_opl(&optimc->sb->dsp, optimc->fm_type != FM_YMF278B); sb_dsp_init(&optimc->sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, optimc); sb_dsp_setaddr(&optimc->sb->dsp, optimc->cur_addr); sb_dsp_setirq(&optimc->sb->dsp, optimc->cur_irq); @@ -400,7 +403,6 @@ optimc_init(const device_t *info) optimc->sb->opl_mixer = optimc; optimc->sb->opl_mix = optimc_filter_opl; - optimc->fm_type = (info->local & OPTIMC_OPL4) ? FM_YMF278B : FM_YMF262; fm_driver_get(optimc->fm_type, &optimc->sb->opl); io_sethandler(optimc->cur_addr + 0, 0x0004, optimc->sb->opl.read, NULL, NULL, optimc->sb->opl.write, NULL, NULL, optimc->sb->opl.priv); io_sethandler(optimc->cur_addr + 8, 0x0002, optimc->sb->opl.read, NULL, NULL, optimc->sb->opl.write, NULL, NULL, optimc->sb->opl.priv); @@ -411,6 +413,10 @@ optimc_init(const device_t *info) io_sethandler(optimc->cur_addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, optimc->sb); sound_add_handler(optimc_get_buffer, optimc); + if (optimc->fm_type == FM_YMF278B) + sound_add_handler(sb_get_music_buffer_sbpro, optimc->sb); + else + music_add_handler(sb_get_music_buffer_sbpro, optimc->sb); sound_set_cd_audio_filter(sbpro_filter_cd_audio, optimc->sb); /* CD audio filter for the default context */ optimc->mpu = (mpu_t *) malloc(sizeof(mpu_t)); diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 674acfcbb..3ce9b5c4c 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -728,20 +728,29 @@ pas16_get_buffer(int32_t *buffer, int len, void *priv) { pas16_t *pas16 = (pas16_t *) priv; - const int32_t *opl_buf = pas16->opl.update(pas16->opl.priv); sb_dsp_update(&pas16->dsp); pas16_update(pas16); for (int c = 0; c < len * 2; c++) { - buffer[c] += opl_buf[c]; buffer[c] += (int16_t) (sb_iir(0, c & 1, (double) pas16->dsp.buffer[c]) / 1.3) / 2; buffer[c] += (pas16->pcm_buffer[c & 1][c >> 1] / 2); } pas16->pos = 0; - pas16->opl.reset_buffer(pas16->opl.priv); pas16->dsp.pos = 0; } +void +pas16_get_music_buffer(int32_t *buffer, int len, void *priv) +{ + pas16_t *pas16 = (pas16_t *) priv; + + const int32_t *opl_buf = pas16->opl.update(pas16->opl.priv); + for (int c = 0; c < len * 2; c++) + buffer[c] += opl_buf[c]; + + pas16->opl.reset_buffer(pas16->opl.priv); +} + static void * pas16_init(UNUSED(const device_t *info)) { @@ -756,6 +765,7 @@ pas16_init(UNUSED(const device_t *info)) timer_add(&pas16->pit.timer[0], pas16_pcm_poll, pas16, 0); sound_add_handler(pas16_get_buffer, pas16); + music_add_handler(pas16_get_music_buffer, pas16); return pas16; } diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 3aa152b8f..98b17e3f0 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -185,10 +185,6 @@ sb_get_buffer_sb2(int32_t *buffer, int len, void *priv) double out_mono = 0.0; double out_l = 0.0; double out_r = 0.0; - const int32_t *opl_buf = NULL; - - if (sb->opl_enabled) - opl_buf = sb->opl.update(sb->opl.priv); sb_dsp_update(&sb->dsp); @@ -200,17 +196,12 @@ sb_get_buffer_sb2(int32_t *buffer, int len, void *priv) out_l = 0.0; out_r = 0.0; - if (sb->opl_enabled) - out_mono = ((double) opl_buf[c]) * 0.7171630859375; - if (sb->cms_enabled) { out_l += sb->cms.buffer[c]; out_r += sb->cms.buffer[c + 1]; } - out_l += out_mono; - out_r += out_mono; - if (((sb->opl_enabled) || (sb->cms_enabled)) && sb->mixer_enabled) { + if (sb->cms_enabled && sb->mixer_enabled) { out_l *= mixer->fm; out_r *= mixer->fm; } @@ -234,17 +225,55 @@ sb_get_buffer_sb2(int32_t *buffer, int len, void *priv) buffer[c + 1] += (int32_t) out_r; } - sb->pos = 0; - - if (sb->opl_enabled) - sb->opl.reset_buffer(sb->opl.priv); - sb->dsp.pos = 0; if (sb->cms_enabled) sb->cms.pos = 0; } +static void +sb_get_music_buffer_sb2(int32_t *buffer, int len, void *priv) +{ + sb_t *sb = (sb_t *) priv; + const sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; + double out_mono = 0.0; + double out_l = 0.0; + double out_r = 0.0; + const int32_t *opl_buf = NULL; + + if (!sb->opl_enabled) + return; + + opl_buf = sb->opl.update(sb->opl.priv); + + for (int c = 0; c < len * 2; c += 2) { + out_mono = 0.0; + out_l = 0.0; + out_r = 0.0; + + if (sb->opl_enabled) + out_mono = ((double) opl_buf[c]) * 0.7171630859375; + + out_l += out_mono; + out_r += out_mono; + + if (sb->mixer_enabled) { + out_l *= mixer->fm; + out_r *= mixer->fm; + } + + if (sb->mixer_enabled) { + out_l *= mixer->master; + out_r *= mixer->master; + } + + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; + } + + sb->opl.reset_buffer(sb->opl.priv); +} + static void sb2_filter_cd_audio(UNUSED(int channel), double *buffer, void *priv) { @@ -253,10 +282,10 @@ sb2_filter_cd_audio(UNUSED(int channel), double *buffer, void *priv) double c; if (sb->mixer_enabled) { - c = ((sb_iir(1, 0, *buffer) / 1.3) * mixer->cd) / 3.0; + c = ((sb_iir(2, 0, *buffer) / 1.3) * mixer->cd) / 3.0; *buffer = c * mixer->master; } else { - c = (((sb_iir(1, 0, (*buffer)) / 1.3) * 65536) / 3.0) / 65536.0; + c = (((sb_iir(2, 0, (*buffer)) / 1.3) * 65536) / 3.0) / 65536.0; *buffer = c; } } @@ -268,16 +297,6 @@ sb_get_buffer_sbpro(int32_t *buffer, int len, void *priv) const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; double out_l = 0.0; double out_r = 0.0; - const int32_t *opl_buf = NULL; - const int32_t *opl2_buf = NULL; - - if (sb->opl_enabled) { - if (sb->dsp.sb_type == SBPRO) { - opl_buf = sb->opl.update(sb->opl.priv); - opl2_buf = sb->opl2.update(sb->opl2.priv); - } else - opl_buf = sb->opl.update(sb->opl.priv); - } sb_dsp_update(&sb->dsp); @@ -285,21 +304,6 @@ sb_get_buffer_sbpro(int32_t *buffer, int len, void *priv) out_l = 0.0; out_r = 0.0; - if (sb->opl_enabled) { - if (sb->dsp.sb_type == SBPRO) { - /* Two chips for LEFT and RIGHT channels. - Each chip stores data into the LEFT channel only (no sample alternating.) */ - out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; - out_r = (((double) opl2_buf[c]) * mixer->fm_r) * 0.7171630859375; - } else { - out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; - out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; - if (sb->opl_mix && sb->opl_mixer) { - sb->opl_mix(sb->opl_mixer, &out_l, &out_r); - } - } - } - /* TODO: Implement the stereo switch on the mixer instead of on the dsp? */ if (mixer->output_filter) { out_l += (sb_iir(0, 0, (double) sb->dsp.buffer[c]) * mixer->voice_l) / 3.9; @@ -317,15 +321,57 @@ sb_get_buffer_sbpro(int32_t *buffer, int len, void *priv) buffer[c + 1] += (int32_t) out_r; } - sb->pos = 0; + sb->dsp.pos = 0; +} - if (sb->opl_enabled) { - sb->opl.reset_buffer(sb->opl.priv); - if (sb->dsp.sb_type == SBPRO) - sb->opl2.reset_buffer(sb->opl2.priv); +void +sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) +{ + sb_t *sb = (sb_t *) priv; + const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; + double out_l = 0.0; + double out_r = 0.0; + const int32_t *opl_buf = NULL; + const int32_t *opl2_buf = NULL; + + if (!sb->opl_enabled) + return; + + if (sb->dsp.sb_type == SBPRO) { + opl_buf = sb->opl.update(sb->opl.priv); + opl2_buf = sb->opl2.update(sb->opl2.priv); + } else + opl_buf = sb->opl.update(sb->opl.priv); + + sb_dsp_update(&sb->dsp); + + for (int c = 0; c < len * 2; c += 2) { + out_l = 0.0; + out_r = 0.0; + + if (sb->dsp.sb_type == SBPRO) { + /* Two chips for LEFT and RIGHT channels. + Each chip stores data into the LEFT channel only (no sample alternating.) */ + out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; + out_r = (((double) opl2_buf[c]) * mixer->fm_r) * 0.7171630859375; + } else { + out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; + out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; + if (sb->opl_mix && sb->opl_mixer) + sb->opl_mix(sb->opl_mixer, &out_l, &out_r); + } + + /* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */ + out_l *= mixer->master_l; + out_r *= mixer->master_r; + + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; } - sb->dsp.pos = 0; + sb->opl.reset_buffer(sb->opl.priv); + if (sb->dsp.sb_type == SBPRO) + sb->opl2.reset_buffer(sb->opl2.priv); } void @@ -338,7 +384,7 @@ sbpro_filter_cd_audio(int channel, double *buffer, void *priv) double master = channel ? mixer->master_r : mixer->master_l; if (mixer->output_filter) - c = (sb_iir(1, channel, *buffer) * cd) / 3.9; + c = (sb_iir(2, channel, *buffer) * cd) / 3.9; else c = (*buffer * cd) / 3.0; *buffer = c * master; @@ -349,21 +395,9 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) { sb_t *sb = (sb_t *) priv; const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - int dsp_rec_pos = sb->dsp.record_pos_write; - int c_emu8k = 0; - int c_record; - int32_t in_l; - int32_t in_r; double out_l = 0.0; double out_r = 0.0; double bass_treble; - const int32_t *opl_buf = NULL; - - if (sb->opl_enabled) - opl_buf = sb->opl.update(sb->opl.priv); - - if (sb->dsp.sb_type > SB16) - emu8k_update(&sb->emu8k); sb_dsp_update(&sb->dsp); @@ -371,25 +405,6 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) out_l = 0.0; out_r = 0.0; - if (sb->dsp.sb_type > SB16) - c_emu8k = ((((c / 2) * FREQ_44100) / SOUND_FREQ) * 2); - - if (sb->opl_enabled) { - out_l = ((double) opl_buf[c]) * mixer->fm_l * 0.7171630859375; - out_r = ((double) opl_buf[c + 1]) * mixer->fm_r * 0.7171630859375; - } - - if (sb->dsp.sb_type > SB16) { - out_l += (((double) sb->emu8k.buffer[c_emu8k]) * mixer->fm_l); - out_r += (((double) sb->emu8k.buffer[c_emu8k + 1]) * mixer->fm_r); - } - - /* TODO: Multi-recording mic with agc/+20db, CD, and line in with channel inversion */ - in_l = (mixer->input_selector_left & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_left & INPUT_MIDI_R) ? ((int32_t) out_r) - : 0; - in_r = (mixer->input_selector_right & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_right & INPUT_MIDI_R) ? ((int32_t) out_r) - : 0; - if (mixer->output_filter) { /* We divide by 3 to get the volume down to normal. */ out_l += (low_fir_sb16(0, 0, (double) sb->dsp.buffer[c]) * mixer->voice_l) / 3.0; @@ -440,8 +455,100 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) out_r = (out_l *bass_treble + high_cut_iir(0, 1, out_r) * (1.0 - bass_treble)); } + buffer[c] += (int32_t) (out_l * mixer->output_gain_L); + buffer[c + 1] += (int32_t) (out_r * mixer->output_gain_R); + } + + sb->dsp.pos = 0; +} + +static void +sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) +{ + sb_t *sb = (sb_t *) priv; + const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; + int dsp_rec_pos = sb->dsp.record_pos_write; + int c_emu8k = 0; + int c_record; + int32_t in_l; + int32_t in_r; + double out_l = 0.0; + double out_r = 0.0; + double bass_treble; + const int32_t *opl_buf = NULL; + + if (sb->opl_enabled) + opl_buf = sb->opl.update(sb->opl.priv); + + if (sb->dsp.sb_type > SB16) + emu8k_update(&sb->emu8k); + + for (int c = 0; c < len * 2; c += 2) { + out_l = 0.0; + out_r = 0.0; + + if (sb->dsp.sb_type > SB16) + c_emu8k = ((((c / 2) * FREQ_44100) / MUSIC_FREQ) * 2); + + if (sb->opl_enabled) { + out_l = ((double) opl_buf[c]) * mixer->fm_l * 0.7171630859375; + out_r = ((double) opl_buf[c + 1]) * mixer->fm_r * 0.7171630859375; + } + + if (sb->dsp.sb_type > SB16) { + out_l += (((double) sb->emu8k.buffer[c_emu8k]) * mixer->fm_l); + out_r += (((double) sb->emu8k.buffer[c_emu8k + 1]) * mixer->fm_r); + } + + /* TODO: Multi-recording mic with agc/+20db, CD, and line in with channel inversion */ + in_l = (mixer->input_selector_left & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_left & INPUT_MIDI_R) ? ((int32_t) out_r) + : 0; + in_r = (mixer->input_selector_right & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_right & INPUT_MIDI_R) ? ((int32_t) out_r) + : 0; + + out_l *= mixer->master_l; + out_r *= mixer->master_r; + + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (mixer->bass_l != 8) { + bass_treble = sb_bass_treble_4bits[mixer->bass_l]; + + if (mixer->bass_l > 8) + out_l += (low_iir(1, 0, out_l) * bass_treble); + else if (mixer->bass_l < 8) + out_l = (out_l *bass_treble + low_cut_iir(1, 0, out_l) * (1.0 - bass_treble)); + } + + if (mixer->bass_r != 8) { + bass_treble = sb_bass_treble_4bits[mixer->bass_r]; + + if (mixer->bass_r > 8) + out_r += (low_iir(1, 1, out_r) * bass_treble); + else if (mixer->bass_r < 8) + out_r = (out_r *bass_treble + low_cut_iir(1, 1, out_r) * (1.0 - bass_treble)); + } + + if (mixer->treble_l != 8) { + bass_treble = sb_bass_treble_4bits[mixer->treble_l]; + + if (mixer->treble_l > 8) + out_l += (high_iir(1, 0, out_l) * bass_treble); + else if (mixer->treble_l < 8) + out_l = (out_l *bass_treble + high_cut_iir(1, 0, out_l) * (1.0 - bass_treble)); + } + + if (mixer->treble_r != 8) { + bass_treble = sb_bass_treble_4bits[mixer->treble_r]; + + if (mixer->treble_r > 8) + out_r += (high_iir(1, 1, out_r) * bass_treble); + else if (mixer->treble_r < 8) + out_r = (out_l *bass_treble + high_cut_iir(1, 1, out_r) * (1.0 - bass_treble)); + } + if (sb->dsp.sb_enable_i) { - c_record = dsp_rec_pos + ((c * sb->dsp.sb_freq) / SOUND_FREQ); + c_record = dsp_rec_pos + ((c * sb->dsp.sb_freq) / MUSIC_FREQ); in_l <<= mixer->input_gain_L; in_r <<= mixer->input_gain_R; @@ -467,13 +574,9 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) sb->dsp.record_pos_write += ((len * sb->dsp.sb_freq) / 24000); sb->dsp.record_pos_write &= 0xffff; - sb->pos = 0; - if (sb->opl_enabled) sb->opl.reset_buffer(sb->opl.priv); - sb->dsp.pos = 0; - if (sb->dsp.sb_type > SB16) sb->emu8k.pos = 0; } @@ -492,7 +595,7 @@ sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv) double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L); if (mixer->output_filter) - c = (low_fir_sb16(1, channel, *buffer) * cd) / 3.0; + c = (low_fir_sb16(2, channel, *buffer) * cd) / 3.0; else c = ((*buffer) * cd) / 3.0; c *= master; @@ -503,18 +606,18 @@ sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv) bass_treble = sb_bass_treble_4bits[bass]; if (bass > 8) - c += (low_iir(1, channel, c) * bass_treble); + c += (low_iir(2, channel, c) * bass_treble); else if (bass < 8) - c = (c * bass_treble + low_cut_iir(1, channel, c) * (1.0 - bass_treble)); + c = (c * bass_treble + low_cut_iir(2, channel, c) * (1.0 - bass_treble)); } if (treble != 8) { bass_treble = sb_bass_treble_4bits[treble]; if (treble > 8) - c += (high_iir(1, channel, c) * bass_treble); + c += (high_iir(2, channel, c) * bass_treble); else if (treble < 8) - c = (c * bass_treble + high_cut_iir(1, channel, c) * (1.0 - bass_treble)); + c = (c * bass_treble + high_cut_iir(2, channel, c) * (1.0 - bass_treble)); } *buffer = c * output_gain; @@ -534,7 +637,7 @@ sb16_awe32_filter_pc_speaker(int channel, double *buffer, void *priv) double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L); if (mixer->output_filter) - c = (low_fir_sb16(2, channel, *buffer) * spk) / 3.0; + c = (low_fir_sb16(3, channel, *buffer) * spk) / 3.0; else c = ((*buffer) * spk) / 3.0; c *= master; @@ -545,18 +648,18 @@ sb16_awe32_filter_pc_speaker(int channel, double *buffer, void *priv) bass_treble = sb_bass_treble_4bits[bass]; if (bass > 8) - c += (low_iir(2, channel, c) * bass_treble); + c += (low_iir(3, channel, c) * bass_treble); else if (bass < 8) - c = (c * bass_treble + low_cut_iir(1, channel, c) * (1.0 - bass_treble)); + c = (c * bass_treble + low_cut_iir(3, channel, c) * (1.0 - bass_treble)); } if (treble != 8) { bass_treble = sb_bass_treble_4bits[treble]; if (treble > 8) - c += (high_iir(2, channel, c) * bass_treble); + c += (high_iir(3, channel, c) * bass_treble); else if (treble < 8) - c = (c * bass_treble + high_cut_iir(1, channel, c) * (1.0 - bass_treble)); + c = (c * bass_treble + high_cut_iir(3, channel, c) * (1.0 - bass_treble)); } *buffer = c * output_gain; @@ -1706,6 +1809,7 @@ sb_1_init(UNUSED(const device_t *info)) if (sb->opl_enabled) fm_driver_get(FM_YM3812, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, SB1, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); @@ -1731,6 +1835,8 @@ sb_1_init(UNUSED(const device_t *info)) sb->mixer_enabled = 0; sound_add_handler(sb_get_buffer_sb2, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb2, sb); sound_set_cd_audio_filter(sb2_filter_cd_audio, sb); if (device_get_config_int("receive_input")) @@ -1754,6 +1860,7 @@ sb_15_init(UNUSED(const device_t *info)) if (sb->opl_enabled) fm_driver_get(FM_YM3812, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); @@ -1781,6 +1888,8 @@ sb_15_init(UNUSED(const device_t *info)) sb->mixer_enabled = 0; sound_add_handler(sb_get_buffer_sb2, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb2, sb); sound_set_cd_audio_filter(sb2_filter_cd_audio, sb); if (device_get_config_int("receive_input")) @@ -1802,6 +1911,7 @@ sb_mcv_init(UNUSED(const device_t *info)) if (sb->opl_enabled) fm_driver_get(FM_YM3812, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, 0); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); @@ -1809,6 +1919,8 @@ sb_mcv_init(UNUSED(const device_t *info)) sb->mixer_enabled = 0; sound_add_handler(sb_get_buffer_sb2, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb2, sb); sound_set_cd_audio_filter(sb2_filter_cd_audio, sb); /* I/O handlers activated in sb_mcv_write */ @@ -1847,6 +1959,7 @@ sb_2_init(UNUSED(const device_t *info)) if (sb->opl_enabled) fm_driver_get(FM_YM3812, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, SB2, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); @@ -1890,6 +2003,8 @@ sb_2_init(UNUSED(const device_t *info)) } else sb->mixer_enabled = 0; sound_add_handler(sb_get_buffer_sb2, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb2, sb); sound_set_cd_audio_filter(sb2_filter_cd_audio, sb); if (device_get_config_int("receive_input")) @@ -1939,6 +2054,7 @@ sb_pro_v1_init(UNUSED(const device_t *info)) sb->opl2.set_do_cycles(sb->opl2.priv, 0); } + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, SBPRO, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); @@ -1970,6 +2086,8 @@ sb_pro_v1_init(UNUSED(const device_t *info)) sb_ct1345_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_sbpro, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sbpro, sb); sound_set_cd_audio_filter(sbpro_filter_cd_audio, sb); if (device_get_config_int("receive_input")) @@ -1995,6 +2113,7 @@ sb_pro_v2_init(UNUSED(const device_t *info)) if (sb->opl_enabled) fm_driver_get(FM_YMF262, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); @@ -2022,6 +2141,8 @@ sb_pro_v2_init(UNUSED(const device_t *info)) sb_ct1345_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_sbpro, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sbpro, sb); sound_set_cd_audio_filter(sbpro_filter_cd_audio, sb); if (device_get_config_int("receive_input")) @@ -2044,11 +2165,14 @@ sb_pro_mcv_init(UNUSED(const device_t *info)) sb->opl_enabled = 1; fm_driver_get(FM_YMF262, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb); sb_ct1345_mixer_reset(sb); sb->mixer_enabled = 1; sound_add_handler(sb_get_buffer_sbpro, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sbpro, sb); sound_set_cd_audio_filter(sbpro_filter_cd_audio, sb); /* I/O handlers activated in sb_pro_mcv_write */ @@ -2070,11 +2194,14 @@ sb_pro_compat_init(UNUSED(const device_t *info)) fm_driver_get(FM_YMF262, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb); sb_ct1345_mixer_reset(sb); sb->mixer_enabled = 1; sound_add_handler(sb_get_buffer_sbpro, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sbpro, sb); sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); memset(sb->mpu, 0, sizeof(mpu_t)); @@ -2097,6 +2224,7 @@ sb_16_init(UNUSED(const device_t *info)) if (sb->opl_enabled) fm_driver_get(info->local, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, (info->local != FM_YMF289B)); sb_dsp_init(&sb->dsp, (info->local == FM_YMF289B) ? SBAWE32PNP : SB16, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); @@ -2126,6 +2254,12 @@ sb_16_init(UNUSED(const device_t *info)) io_sethandler(addr + 4, 0x0002, sb_ct1745_mixer_read, NULL, NULL, sb_ct1745_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_sb16_awe32, sb); + if (sb->opl_enabled) { + if (info->local == FM_YMF289B) + sound_add_handler(sb_get_music_buffer_sb16_awe32, sb); + else + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); + } sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); @@ -2157,6 +2291,7 @@ sb_16_reply_mca_init(UNUSED(const device_t *info)) sb->opl_enabled = 1; fm_driver_get(FM_YMF262, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setdma16_supported(&sb->dsp, 1); sb_dsp_setdma16_enabled(&sb->dsp, 1); @@ -2165,6 +2300,8 @@ sb_16_reply_mca_init(UNUSED(const device_t *info)) sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); @@ -2207,6 +2344,8 @@ sb_16_pnp_init(UNUSED(const device_t *info)) sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); @@ -2225,6 +2364,7 @@ sb_16_pnp_init(UNUSED(const device_t *info)) isapnp_add_card(sb_16_pnp_rom, sizeof(sb_16_pnp_rom), sb_16_pnp_config_changed, NULL, NULL, NULL, sb); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_setaddr(&sb->dsp, 0); sb_dsp_setirq(&sb->dsp, 0); sb_dsp_setdma8(&sb->dsp, ISAPNP_DMA_DISABLED); @@ -2262,6 +2402,7 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info)) sb->opl_enabled = 1; fm_driver_get(FM_YMF262, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, (info->local == 0) ? SBAWE64 : SBAWE32PNP, SB_SUBTYPE_DEFAULT, sb); /* The ViBRA 16XV does 16-bit DMA through 8-bit DMA. */ sb_dsp_setdma16_supported(&sb->dsp, info->local != 0); @@ -2270,6 +2411,8 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info)) sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); @@ -2340,6 +2483,7 @@ sb_16_compat_init(const device_t *info) fm_driver_get(FM_YMF262, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setdma16_supported(&sb->dsp, 1); sb_dsp_setdma16_enabled(&sb->dsp, 1); @@ -2347,6 +2491,8 @@ sb_16_compat_init(const device_t *info) sb->mixer_enabled = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); memset(sb->mpu, 0, sizeof(mpu_t)); @@ -2411,6 +2557,7 @@ sb_awe32_init(UNUSED(const device_t *info)) if (sb->opl_enabled) fm_driver_get(FM_YMF262, &sb->opl); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, SBAWE32, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); @@ -2440,6 +2587,8 @@ sb_awe32_init(UNUSED(const device_t *info)) io_sethandler(addr + 4, 0x0002, sb_ct1745_mixer_read, NULL, NULL, sb_ct1745_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_sb16_awe32, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); @@ -2482,9 +2631,12 @@ sb_awe32_pnp_init(const device_t *info) sb_dsp_setdma16_supported(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); + sb_dsp_set_real_opl(&sb->dsp, 1); sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 6fc7815ab..cf4498b4b 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -115,7 +115,7 @@ uint8_t adjustMap2[24] = { 252, 0, 252, 0 }; -double low_fir_sb16_coef[3][SB16_NCoef]; +double low_fir_sb16_coef[4][SB16_NCoef]; #ifdef ENABLE_SB_DSP_LOG int sb_dsp_do_log = ENABLE_SB_DSP_LOG; @@ -1256,8 +1256,12 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) /* Initialise SB16 filter to same cutoff as 8-bit SBs (3.2 kHz). This will be recalculated when a set frequency command is sent. */ recalc_sb16_filter(0, 3200 * 2); - recalc_sb16_filter(1, FREQ_44100); - recalc_sb16_filter(2, 18939); + if (dsp->sb_has_real_opl) + recalc_sb16_filter(1, FREQ_49716); + else + recalc_sb16_filter(1, FREQ_48000); + recalc_sb16_filter(2, FREQ_44100); + recalc_sb16_filter(3, 18939); /* Initialize SB16 8051 RAM and ASP internal RAM */ memset(dsp->sb_8051_ram, 0x00, sizeof(dsp->sb_8051_ram)); @@ -1283,6 +1287,12 @@ sb_dsp_setaddr(sb_dsp_t *dsp, uint16_t addr) } } +void +sb_dsp_set_real_opl(sb_dsp_t *dsp, uint8_t has_real_opl) +{ + dsp->sb_has_real_opl = has_real_opl; +} + void sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo) { diff --git a/src/sound/snd_wss.c b/src/sound/snd_wss.c index a69d746da..da88b29e9 100644 --- a/src/sound/snd_wss.c +++ b/src/sound/snd_wss.c @@ -80,21 +80,28 @@ static void wss_get_buffer(int32_t *buffer, int len, void *priv) { wss_t *wss = (wss_t *) priv; - const int32_t *opl_buf = NULL; - - if (wss->opl_enabled) - opl_buf = wss->opl.update(wss->opl.priv); ad1848_update(&wss->ad1848); + for (int c = 0; c < len * 2; c++) + buffer[c] += wss->ad1848.buffer[c] / 2; + + wss->ad1848.pos = 0; +} + +static void +wss_get_music_buffer(int32_t *buffer, int len, void *priv) +{ + wss_t *wss = (wss_t *) priv; + const int32_t *opl_buf = NULL; + + opl_buf = wss->opl.update(wss->opl.priv); + for (int c = 0; c < len * 2; c++) { if (opl_buf) buffer[c] += opl_buf[c]; - buffer[c] += wss->ad1848.buffer[c] / 2; } - if (wss->opl_enabled) - wss->opl.reset_buffer(wss->opl.priv); - wss->ad1848.pos = 0; + wss->opl.reset_buffer(wss->opl.priv); } void * @@ -131,6 +138,9 @@ wss_init(UNUSED(const device_t *info)) sound_add_handler(wss_get_buffer, wss); + if (wss->opl_enabled) + music_add_handler(wss_get_music_buffer, wss); + return wss; } @@ -214,6 +224,9 @@ ncr_audio_init(UNUSED(const device_t *info)) sound_add_handler(wss_get_buffer, wss); + if (wss->opl_enabled) + music_add_handler(wss_get_music_buffer, wss); + return wss; } diff --git a/src/sound/sound.c b/src/sound/sound.c index ed7f821e0..81f70d921 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -53,9 +53,11 @@ typedef struct { int sound_card_current[SOUND_CARD_MAX] = { 0, 0, 0, 0 }; int sound_pos_global = 0; +int music_pos_global = 0; int sound_gain = 0; static sound_handler_t sound_handlers[8]; +static sound_handler_t music_handlers[8]; static thread_t *sound_cd_thread_h; static event_t *sound_cd_event; @@ -63,9 +65,15 @@ static event_t *sound_cd_start_event; static int32_t *outbuffer; static float *outbuffer_ex; static int16_t *outbuffer_ex_int16; +static int32_t *outbuffer_m; +static float *outbuffer_m_ex; +static int16_t *outbuffer_m_ex_int16; static int sound_handlers_num; +static int music_handlers_num; static pc_timer_t sound_poll_timer; static uint64_t sound_poll_latch; +static pc_timer_t music_poll_timer; +static uint64_t music_poll_latch; static int16_t cd_buffer[CDROM_NUM][CD_BUFLEN * 2]; static float cd_out_buffer[CD_BUFLEN * 2]; @@ -395,6 +403,28 @@ sound_realloc_buffers(void) } } +static void +music_realloc_buffers(void) +{ + if (outbuffer_m_ex != NULL) { + free(outbuffer_m_ex); + outbuffer_m_ex = NULL; + } + + if (outbuffer_m_ex_int16 != NULL) { + free(outbuffer_m_ex_int16); + outbuffer_m_ex_int16 = NULL; + } + + if (sound_is_float) { + outbuffer_m_ex = calloc(MUSICBUFLEN * 2, sizeof(float)); + memset(outbuffer_m_ex, 0x00, MUSICBUFLEN * 2 * sizeof(float)); + } else { + outbuffer_m_ex_int16 = calloc(MUSICBUFLEN * 2, sizeof(int16_t)); + memset(outbuffer_m_ex_int16, 0x00, MUSICBUFLEN * 2 * sizeof(int16_t)); + } +} + void sound_init(void) { @@ -403,10 +433,18 @@ sound_init(void) outbuffer_ex = NULL; outbuffer_ex_int16 = NULL; + outbuffer_m_ex = NULL; + outbuffer_m_ex_int16 = NULL; + outbuffer = NULL; outbuffer = calloc(SOUNDBUFLEN * 2, sizeof(int32_t)); memset(outbuffer, 0x00, SOUNDBUFLEN * 2 * sizeof(int32_t)); + outbuffer_m = NULL; + outbuffer_m = calloc(MUSICBUFLEN * 2, sizeof(int32_t)); + memset(outbuffer_m, 0x00, MUSICBUFLEN * 2 * sizeof(int32_t)); + + for (uint8_t i = 0; i < CDROM_NUM; i++) { if (cdrom[i].bus_type != CDROM_BUS_DISABLED) available_cdrom_drives++; @@ -438,6 +476,14 @@ sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *priv), void sound_handlers_num++; } +void +music_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *priv), void *priv) +{ + music_handlers[music_handlers_num].get_buffer = get_buffer; + music_handlers[music_handlers_num].priv = priv; + music_handlers_num++; +} + void sound_set_cd_audio_filter(void (*filter)(int channel, double *buffer, void *priv), void *priv) { @@ -502,10 +548,48 @@ sound_poll(UNUSED(void *priv)) } } +void +music_poll(UNUSED(void *priv)) +{ + timer_advance_u64(&music_poll_timer, music_poll_latch); + + music_pos_global++; + if (music_pos_global == MUSICBUFLEN) { + int c; + + memset(outbuffer_m, 0x00, MUSICBUFLEN * 2 * sizeof(int32_t)); + + for (c = 0; c < music_handlers_num; c++) + music_handlers[c].get_buffer(outbuffer_m, MUSICBUFLEN, music_handlers[c].priv); + + for (c = 0; c < MUSICBUFLEN * 2; c++) { + if (sound_is_float) + outbuffer_m_ex[c] = ((float) outbuffer_m[c]) / (float) 32768.0; + else { + if (outbuffer_m[c] > 32767) + outbuffer_m[c] = 32767; + if (outbuffer_m[c] < -32768) + outbuffer_m[c] = -32768; + + outbuffer_m_ex_int16[c] = outbuffer_m[c]; + } + } + + if (sound_is_float) + givealbuffer_music(outbuffer_m_ex); + else + givealbuffer_music(outbuffer_m_ex_int16); + + music_pos_global = 0; + } +} + void sound_speed_changed(void) { sound_poll_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) SOUND_FREQ)); + + music_poll_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) MUSIC_FREQ)); } void @@ -513,6 +597,8 @@ sound_reset(void) { sound_realloc_buffers(); + music_realloc_buffers(); + midi_out_device_init(); midi_in_device_init(); @@ -523,6 +609,11 @@ sound_reset(void) sound_handlers_num = 0; memset(sound_handlers, 0x00, 8 * sizeof(sound_handler_t)); + timer_add(&music_poll_timer, music_poll, NULL, 1); + + music_handlers_num = 0; + memset(music_handlers, 0x00, 8 * sizeof(sound_handler_t)); + filter_cd_audio = NULL; filter_cd_audio_p = NULL; diff --git a/src/sound/xaudio2.c b/src/sound/xaudio2.c index 0d9e7d909..78c3e2d35 100644 --- a/src/sound/xaudio2.c +++ b/src/sound/xaudio2.c @@ -51,6 +51,7 @@ static int initialized = 0; static IXAudio2 *xaudio2 = NULL; static IXAudio2MasteringVoice *mastervoice = NULL; static IXAudio2SourceVoice *srcvoice = NULL; +static IXAudio2SourceVoice *srcvoicemusic = NULL; static IXAudio2SourceVoice *srcvoicemidi = NULL; static IXAudio2SourceVoice *srcvoicecd = NULL; @@ -164,6 +165,12 @@ inital(void) return; } + fmt.nSamplesPerSec = MUSIC_FREQ; + fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; + fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; + + IXAudio2_CreateSourceVoice(xaudio2, &srcvoicemusic, &fmt, 0, 2.0f, &callbacks, NULL, NULL); + fmt.nSamplesPerSec = CD_FREQ; fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; @@ -173,6 +180,7 @@ inital(void) IXAudio2SourceVoice_SetVolume(srcvoice, 1, XAUDIO2_COMMIT_NOW); IXAudio2SourceVoice_Start(srcvoice, 0, XAUDIO2_COMMIT_NOW); IXAudio2SourceVoice_Start(srcvoicecd, 0, XAUDIO2_COMMIT_NOW); + IXAudio2SourceVoice_Start(srcvoicemusic, 0, XAUDIO2_COMMIT_NOW); const char *mdn = midi_out_device_get_internal_name(midi_output_device_current); @@ -196,6 +204,8 @@ closeal(void) initialized = 0; IXAudio2SourceVoice_Stop(srcvoice, 0, XAUDIO2_COMMIT_NOW); IXAudio2SourceVoice_FlushSourceBuffers(srcvoice); + IXAudio2SourceVoice_Stop(srcvoicemusic, 0, XAUDIO2_COMMIT_NOW); + IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemusic); IXAudio2SourceVoice_Stop(srcvoicecd, 0, XAUDIO2_COMMIT_NOW); IXAudio2SourceVoice_FlushSourceBuffers(srcvoicecd); if (srcvoicemidi) { @@ -203,8 +213,9 @@ closeal(void) IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemidi); IXAudio2SourceVoice_DestroyVoice(srcvoicemidi); } - IXAudio2SourceVoice_DestroyVoice(srcvoice); IXAudio2SourceVoice_DestroyVoice(srcvoicecd); + IXAudio2SourceVoice_DestroyVoice(srcvoicemusic); + IXAudio2SourceVoice_DestroyVoice(srcvoice); IXAudio2MasteringVoice_DestroyVoice(mastervoice); IXAudio2_Release(xaudio2); srcvoice = srcvoicecd = srcvoicemidi = NULL; @@ -249,6 +260,12 @@ givealbuffer(void *buf) givealbuffer_common(buf, srcvoice, BUFLEN << 1); } +void +givealbuffer_music(void *buf) +{ + givealbuffer_common(buf, srcvoicemusic, MUSICBUFLEN << 1); +} + void givealbuffer_cd(void *buf) { From c7028f1e35d12feb90ee4568db5d4c61da25253b Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 1 Mar 2024 07:13:29 +0100 Subject: [PATCH 603/936] Fixed some compile-breaking mistakes in sound/openal.c. --- src/sound/openal.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/sound/openal.c b/src/sound/openal.c index 98f87855e..234db5ca3 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -114,12 +114,14 @@ closeal(void) void inital(void) { - float *buf = NULL; - float *cd_buf = NULL; - float *midi_buf = NULL; - int16_t *buf_int16 = NULL; - int16_t *cd_buf_int16 = NULL; - int16_t *midi_buf_int16 = NULL; + float *buf = NULL; + float *music_buf = NULL; + float *cd_buf = NULL; + float *midi_buf = NULL; + int16_t *buf_int16 = NULL; + int16_t *music_buf_int16 = NULL; + int16_t *cd_buf_int16 = NULL; + int16_t *midi_buf_int16 = NULL; const char *mdn; int init_midi = 0; @@ -276,7 +278,7 @@ givealbuffer(void *buf) void givealbuffer_music(void *buf) { - givealbuffer_common(buf, 1, MUSIC_BUFLEN << 1, MUSIC_FREQ); + givealbuffer_common(buf, 1, MUSICBUFLEN << 1, MUSIC_FREQ); } void From 742b80c6b3d8b48dcbfe82e9a80b9feddd44be6a Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 1 Mar 2024 08:01:36 +0100 Subject: [PATCH 604/936] And another one. --- src/sound/openal.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sound/openal.c b/src/sound/openal.c index 234db5ca3..1e47cccd7 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -140,13 +140,13 @@ inital(void) if (sound_is_float) { buf = (float *) calloc((BUFLEN << 1), sizeof(float)); - music_buf = (float *) calloc((MUSIC_BUFLEN << 1), sizeof(float)); + music_buf = (float *) calloc((MUSICBUFLEN << 1), sizeof(float)); cd_buf = (float *) calloc((CD_BUFLEN << 1), sizeof(float)); if (init_midi) midi_buf = (float *) calloc(midi_buf_size, sizeof(float)); } else { buf_int16 = (int16_t *) calloc((BUFLEN << 1), sizeof(int16_t)); - music_buf_int16 = (int16_t *) calloc((MUSIC_BUFLEN << 1), sizeof(int16_t)); + music_buf_int16 = (int16_t *) calloc((MUSICBUFLEN << 1), sizeof(int16_t)); cd_buf_int16 = (int16_t *) calloc((CD_BUFLEN << 1), sizeof(int16_t)); if (init_midi) midi_buf_int16 = (int16_t *) calloc(midi_buf_size, sizeof(int16_t)); @@ -195,13 +195,13 @@ inital(void) for (uint8_t c = 0; c < 4; c++) { if (sound_is_float) { alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN * 2 * sizeof(float), FREQ); - alBufferData(buffers_music[c], AL_FORMAT_STEREO_FLOAT32, buf, MUSIC_BUFLEN * 2 * sizeof(float), MUSIC_FREQ); + alBufferData(buffers_music[c], AL_FORMAT_STEREO_FLOAT32, buf, MUSICBUFLEN * 2 * sizeof(float), MUSIC_FREQ); alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, cd_buf, CD_BUFLEN * 2 * sizeof(float), CD_FREQ); if (init_midi) alBufferData(buffers_midi[c], AL_FORMAT_STEREO_FLOAT32, midi_buf, midi_buf_size * sizeof(float), midi_freq); } else { alBufferData(buffers[c], AL_FORMAT_STEREO16, buf_int16, BUFLEN * 2 * sizeof(int16_t), FREQ); - alBufferData(buffers_music[c], AL_FORMAT_STEREO16, buf_int16, MUSIC_BUFLEN * 2 * sizeof(int16_t), MUSIC_FREQ); + alBufferData(buffers_music[c], AL_FORMAT_STEREO16, buf_int16, MUSICBUFLEN * 2 * sizeof(int16_t), MUSIC_FREQ); alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, cd_buf_int16, CD_BUFLEN * 2 * sizeof(int16_t), CD_FREQ); if (init_midi) alBufferData(buffers_midi[c], AL_FORMAT_STEREO16, midi_buf_int16, midi_buf_size * sizeof(int16_t), midi_freq); From 26d0079ab88d91faa7782c309e085138d8b6cac8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 1 Mar 2024 08:03:10 +0100 Subject: [PATCH 605/936] Removed a pointless line from chipset/sis5581_h2p.c. --- src/chipset/sis_5581_h2p.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/chipset/sis_5581_h2p.c b/src/chipset/sis_5581_h2p.c index 48d61f25e..30bd70bfe 100644 --- a/src/chipset/sis_5581_h2p.c +++ b/src/chipset/sis_5581_h2p.c @@ -168,7 +168,6 @@ sis_5581_trap_update_devctl(sis_5581_host_to_pci_t *dev, uint8_t trap_id, uint8_ uint16_t addr, uint16_t size) { sis_5581_io_trap_t *trap = &dev->io_traps[trap_id]; - enable = enable; /* Set up Device I/O traps dynamically. */ if (enable && !trap->trap) { From 95f95d8481cfc106285de6a0cc407e227bea6466 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 1 Mar 2024 15:55:19 +0600 Subject: [PATCH 606/936] Fix OPL audio not playing --- src/sound/openal.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/sound/openal.c b/src/sound/openal.c index 1e47cccd7..ddcbf7849 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -154,13 +154,14 @@ inital(void) alGenBuffers(4, buffers); alGenBuffers(4, buffers_cd); + alGenBuffers(4, buffers_music); if (init_midi) alGenBuffers(4, buffers_midi); if (init_midi) - alGenSources(3, source); + alGenSources(4, source); else - alGenSources(2, source); + alGenSources(3, source); alSource3f(source[0], AL_POSITION, 0.0, 0.0, 0.0); alSource3f(source[0], AL_VELOCITY, 0.0, 0.0, 0.0); @@ -172,22 +173,29 @@ inital(void) alSource3f(source[1], AL_DIRECTION, 0.0, 0.0, 0.0); alSourcef(source[1], AL_ROLLOFF_FACTOR, 0.0); alSourcei(source[1], AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f(source[2], AL_POSITION, 0.0, 0.0, 0.0); + alSource3f(source[2], AL_VELOCITY, 0.0, 0.0, 0.0); + alSource3f(source[2], AL_DIRECTION, 0.0, 0.0, 0.0); + alSourcef(source[2], AL_ROLLOFF_FACTOR, 0.0); + alSourcei(source[2], AL_SOURCE_RELATIVE, AL_TRUE); if (init_midi) { - alSource3f(source[2], AL_POSITION, 0.0, 0.0, 0.0); - alSource3f(source[2], AL_VELOCITY, 0.0, 0.0, 0.0); - alSource3f(source[2], AL_DIRECTION, 0.0, 0.0, 0.0); - alSourcef(source[2], AL_ROLLOFF_FACTOR, 0.0); - alSourcei(source[2], AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f(source[3], AL_POSITION, 0.0, 0.0, 0.0); + alSource3f(source[3], AL_VELOCITY, 0.0, 0.0, 0.0); + alSource3f(source[3], AL_DIRECTION, 0.0, 0.0, 0.0); + alSourcef(source[3], AL_ROLLOFF_FACTOR, 0.0); + alSourcei(source[3], AL_SOURCE_RELATIVE, AL_TRUE); } if (sound_is_float) { memset(buf, 0, BUFLEN * 2 * sizeof(float)); memset(cd_buf, 0, BUFLEN * 2 * sizeof(float)); + memset(music_buf, 0, MUSICBUFLEN * 2 * sizeof(float)); if (init_midi) memset(midi_buf, 0, midi_buf_size * sizeof(float)); } else { memset(buf_int16, 0, BUFLEN * 2 * sizeof(int16_t)); memset(cd_buf_int16, 0, BUFLEN * 2 * sizeof(int16_t)); + memset(music_buf_int16, 0, MUSICBUFLEN * 2 * sizeof(int16_t)); if (init_midi) memset(midi_buf_int16, 0, midi_buf_size * sizeof(int16_t)); } @@ -195,13 +203,13 @@ inital(void) for (uint8_t c = 0; c < 4; c++) { if (sound_is_float) { alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN * 2 * sizeof(float), FREQ); - alBufferData(buffers_music[c], AL_FORMAT_STEREO_FLOAT32, buf, MUSICBUFLEN * 2 * sizeof(float), MUSIC_FREQ); + alBufferData(buffers_music[c], AL_FORMAT_STEREO_FLOAT32, music_buf, MUSICBUFLEN * 2 * sizeof(float), MUSIC_FREQ); alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, cd_buf, CD_BUFLEN * 2 * sizeof(float), CD_FREQ); if (init_midi) alBufferData(buffers_midi[c], AL_FORMAT_STEREO_FLOAT32, midi_buf, midi_buf_size * sizeof(float), midi_freq); } else { alBufferData(buffers[c], AL_FORMAT_STEREO16, buf_int16, BUFLEN * 2 * sizeof(int16_t), FREQ); - alBufferData(buffers_music[c], AL_FORMAT_STEREO16, buf_int16, MUSICBUFLEN * 2 * sizeof(int16_t), MUSIC_FREQ); + alBufferData(buffers_music[c], AL_FORMAT_STEREO16, music_buf_int16, MUSICBUFLEN * 2 * sizeof(int16_t), MUSIC_FREQ); alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, cd_buf_int16, CD_BUFLEN * 2 * sizeof(int16_t), CD_FREQ); if (init_midi) alBufferData(buffers_midi[c], AL_FORMAT_STEREO16, midi_buf_int16, midi_buf_size * sizeof(int16_t), midi_freq); From 3f04b60e3d460266581487c08092c1930280ac96 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 1 Mar 2024 16:21:30 +0600 Subject: [PATCH 607/936] memset cd_buf correctly --- src/sound/openal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sound/openal.c b/src/sound/openal.c index ddcbf7849..f015205f6 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -188,13 +188,13 @@ inital(void) if (sound_is_float) { memset(buf, 0, BUFLEN * 2 * sizeof(float)); - memset(cd_buf, 0, BUFLEN * 2 * sizeof(float)); + memset(cd_buf, 0, CD_BUFLEN * 2 * sizeof(float)); memset(music_buf, 0, MUSICBUFLEN * 2 * sizeof(float)); if (init_midi) memset(midi_buf, 0, midi_buf_size * sizeof(float)); } else { memset(buf_int16, 0, BUFLEN * 2 * sizeof(int16_t)); - memset(cd_buf_int16, 0, BUFLEN * 2 * sizeof(int16_t)); + memset(cd_buf_int16, 0, CD_BUFLEN * 2 * sizeof(int16_t)); memset(music_buf_int16, 0, MUSICBUFLEN * 2 * sizeof(int16_t)); if (init_midi) memset(midi_buf_int16, 0, midi_buf_size * sizeof(int16_t)); From 046a8655b5cb8cd96411e594d2680505f16070cb Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 1 Mar 2024 12:34:44 +0100 Subject: [PATCH 608/936] Moved E-MU 8000 handling to the non-music handler. --- src/sound/snd_sb.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 98b17e3f0..9e50f438f 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -395,6 +395,7 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) { sb_t *sb = (sb_t *) priv; const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; + int c_emu8k = 0; double out_l = 0.0; double out_r = 0.0; double bass_treble; @@ -405,6 +406,14 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) out_l = 0.0; out_r = 0.0; + if (sb->dsp.sb_type > SB16) + c_emu8k = ((((c / 2) * FREQ_44100) / MUSIC_FREQ) * 2); + + if (sb->dsp.sb_type > SB16) { + out_l += (((double) sb->emu8k.buffer[c_emu8k]) * mixer->fm_l); + out_r += (((double) sb->emu8k.buffer[c_emu8k + 1]) * mixer->fm_r); + } + if (mixer->output_filter) { /* We divide by 3 to get the volume down to normal. */ out_l += (low_fir_sb16(0, 0, (double) sb->dsp.buffer[c]) * mixer->voice_l) / 3.0; @@ -460,6 +469,9 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) } sb->dsp.pos = 0; + + if (sb->dsp.sb_type > SB16) + sb->emu8k.pos = 0; } static void @@ -468,7 +480,6 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) sb_t *sb = (sb_t *) priv; const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; int dsp_rec_pos = sb->dsp.record_pos_write; - int c_emu8k = 0; int c_record; int32_t in_l; int32_t in_r; @@ -487,19 +498,11 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) out_l = 0.0; out_r = 0.0; - if (sb->dsp.sb_type > SB16) - c_emu8k = ((((c / 2) * FREQ_44100) / MUSIC_FREQ) * 2); - if (sb->opl_enabled) { out_l = ((double) opl_buf[c]) * mixer->fm_l * 0.7171630859375; out_r = ((double) opl_buf[c + 1]) * mixer->fm_r * 0.7171630859375; } - if (sb->dsp.sb_type > SB16) { - out_l += (((double) sb->emu8k.buffer[c_emu8k]) * mixer->fm_l); - out_r += (((double) sb->emu8k.buffer[c_emu8k + 1]) * mixer->fm_r); - } - /* TODO: Multi-recording mic with agc/+20db, CD, and line in with channel inversion */ in_l = (mixer->input_selector_left & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_left & INPUT_MIDI_R) ? ((int32_t) out_r) : 0; @@ -576,9 +579,6 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) if (sb->opl_enabled) sb->opl.reset_buffer(sb->opl.priv); - - if (sb->dsp.sb_type > SB16) - sb->emu8k.pos = 0; } void From 45d1e35a7a939ff20fd677af82e6c44acf085462 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 1 Mar 2024 12:35:59 +0100 Subject: [PATCH 609/936] Fixed E-MU 8000 frequency. --- src/sound/snd_sb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 9e50f438f..2b9432b4e 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -407,7 +407,7 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) out_r = 0.0; if (sb->dsp.sb_type > SB16) - c_emu8k = ((((c / 2) * FREQ_44100) / MUSIC_FREQ) * 2); + c_emu8k = ((((c / 2) * FREQ_44100) / SOUND_FREQ) * 2); if (sb->dsp.sb_type > SB16) { out_l += (((double) sb->emu8k.buffer[c_emu8k]) * mixer->fm_l); From 3727dd9981adbd95fa7165f2f672993d916d7aac Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 1 Mar 2024 13:45:23 +0100 Subject: [PATCH 610/936] SiS 496/497: Implement the reset control bits. --- src/chipset/sis_85c496.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/chipset/sis_85c496.c b/src/chipset/sis_85c496.c index b9b2544c8..1e9b74f41 100644 --- a/src/chipset/sis_85c496.c +++ b/src/chipset/sis_85c496.c @@ -480,6 +480,8 @@ sis_85c49x_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) break; case 0xc6: /* 85C497 Post / INIT Configuration */ dev->pci_conf[addr] = val & 0x0f; + cpu_cpurst_on_sr = !(val & 0x08); + soft_reset_pci = !!(val & 0x04); break; case 0xc8: case 0xc9: @@ -614,6 +616,9 @@ sis_85c496_reset(void *priv) nvr_bank_set(0, 0, dev->nvr); sis_85c497_isa_reset(dev); + + cpu_cpurst_on_sr = 1; + soft_reset_pci = 0; } static void From d77fc474080d97920efff0486cd09f8702757cb5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 1 Mar 2024 13:46:54 +0100 Subject: [PATCH 611/936] E-MU 8000: Update in the correct handler. --- src/sound/snd_sb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 2b9432b4e..fb9157dfd 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -402,6 +402,9 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) sb_dsp_update(&sb->dsp); + if (sb->dsp.sb_type > SB16) + emu8k_update(&sb->emu8k); + for (int c = 0; c < len * 2; c += 2) { out_l = 0.0; out_r = 0.0; @@ -491,9 +494,6 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) if (sb->opl_enabled) opl_buf = sb->opl.update(sb->opl.priv); - if (sb->dsp.sb_type > SB16) - emu8k_update(&sb->emu8k); - for (int c = 0; c < len * 2; c += 2) { out_l = 0.0; out_r = 0.0; From 4335c3e085c248147a4843546f0b9e183859e860 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 1 Mar 2024 19:27:46 +0500 Subject: [PATCH 612/936] Fix ACPI poweroffs disabling exit confirmations Use confirm_exit_cmdl to skip the confirmation prompt without saving it in the config --- src/qt/qt_platform.cpp | 2 +- src/unix/unix.c | 2 +- src/win/win_ui.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 356334bac..46d50672e 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -413,7 +413,7 @@ void plat_power_off(void) { plat_mouse_capture(0); - confirm_exit = 0; + confirm_exit_cmdl = 0; nvr_save(); config_save(); diff --git a/src/unix/unix.c b/src/unix/unix.c index 6c21bfa45..2a9324307 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -697,7 +697,7 @@ plat_get_exe_name(char *s, int size) void plat_power_off(void) { - confirm_exit = 0; + confirm_exit_cmdl = 0; nvr_save(); config_save(); diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 207158b29..ec4a785ab 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -383,7 +383,7 @@ win_notify_dlg_closed(void) void plat_power_off(void) { - confirm_exit = 0; + confirm_exit_cmdl = 0; nvr_save(); config_save(); From f9ae162e5d7bc6cbf62dd95cddd0d4564bf6312d Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 1 Mar 2024 19:29:09 +0500 Subject: [PATCH 613/936] Move the EMU8000 ROM path to a macro --- src/include/86box/snd_emu8k.h | 2 ++ src/sound/snd_emu8k.c | 2 +- src/sound/snd_sb.c | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/include/86box/snd_emu8k.h b/src/include/86box/snd_emu8k.h index 090ab662a..d226ed8db 100644 --- a/src/include/86box/snd_emu8k.h +++ b/src/include/86box/snd_emu8k.h @@ -406,6 +406,8 @@ void emu8k_close(emu8k_t *emu8k); void emu8k_update(emu8k_t *emu8k); +#define EMU8K_ROM_PATH "roms/sound/creative/awe32.raw" + /* Section E - Introduction to the EMU8000 Chip diff --git a/src/sound/snd_emu8k.c b/src/sound/snd_emu8k.c index 22435c065..793f8bcb7 100644 --- a/src/sound/snd_emu8k.c +++ b/src/sound/snd_emu8k.c @@ -2172,7 +2172,7 @@ emu8k_init(emu8k_t *emu8k, uint16_t emu_addr, int onboard_ram) int c; double out; - fp = rom_fopen("roms/sound/creative/awe32.raw", "rb"); + fp = rom_fopen(EMU8K_ROM_PATH, "rb"); if (!fp) fatal("AWE32.RAW not found\n"); diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index fb9157dfd..2e63e99c0 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -2509,7 +2509,7 @@ sb_16_compat_init(const device_t *info) static int sb_awe32_available(void) { - return rom_present("roms/sound/creative/awe32.raw"); + return rom_present(EMU8K_ROM_PATH); } static int From 9a67f05a8f494ace6c5303ec09ad0740bc696157 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 1 Mar 2024 19:31:34 +0500 Subject: [PATCH 614/936] Move the Sound Blaster PnP ROM paths to macros --- src/sound/snd_sb.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 2e63e99c0..5d59d2577 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -43,6 +43,14 @@ #include <86box/snd_sb.h> #include <86box/plat_unused.h> +#define PNP_ROM_SB_VIBRA16XV "roms/sound/creative/CT4170 PnP.BIN" +#define PNP_ROM_SB_VIBRA16C "roms/sound/creative/CT4180 PnP.BIN" +#define PNP_ROM_SB_32_PNP "roms/sound/creative/CT3600 PnP.BIN" +#define PNP_ROM_SB_AWE32_PNP "roms/sound/creative/CT3980 PnP.BIN" +#define PNP_ROM_SB_AWE64_VALUE "roms/sound/creative/CT4520 PnP.BIN" +#define PNP_ROM_SB_AWE64 PNP_ROM_SB_AWE64_VALUE +#define PNP_ROM_SB_AWE64_GOLD "roms/sound/creative/CT4540 PnP.BIN" + /* 0 to 7 -> -14dB to 0dB i 2dB steps. 8 to 15 -> 0 to +14dB in 2dB steps. Note that for positive dB values, this is not amplitude, it is amplitude - 1. */ static const double sb_bass_treble_4bits[] = { @@ -2382,13 +2390,13 @@ sb_16_pnp_init(UNUSED(const device_t *info)) static int sb_vibra16xv_available(void) { - return rom_present("roms/sound/creative/CT4170 PnP.BIN"); + return rom_present(PNP_ROM_SB_VIBRA16XV); } static int sb_vibra16c_available(void) { - return rom_present("roms/sound/creative/CT4180 PnP.BIN"); + return rom_present(PNP_ROM_SB_VIBRA16C); } static void * @@ -2430,11 +2438,11 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info)) const char *pnp_rom_file = NULL; switch (info->local) { case 0: - pnp_rom_file = "roms/sound/creative/CT4170 PnP.BIN"; + pnp_rom_file = PNP_ROM_SB_VIBRA16XV; break; case 1: - pnp_rom_file = "roms/sound/creative/CT4180 PnP.BIN"; + pnp_rom_file = PNP_ROM_SB_VIBRA16C; break; default: @@ -2515,31 +2523,31 @@ sb_awe32_available(void) static int sb_32_pnp_available(void) { - return sb_awe32_available() && rom_present("roms/sound/creative/CT3600 PnP.BIN"); + return sb_awe32_available() && rom_present(PNP_ROM_SB_32_PNP); } static int sb_awe32_pnp_available(void) { - return sb_awe32_available() && rom_present("roms/sound/creative/CT3980 PnP.BIN"); + return sb_awe32_available() && rom_present(PNP_ROM_SB_AWE32_PNP); } static int sb_awe64_value_available(void) { - return sb_awe32_available() && rom_present("roms/sound/creative/CT4520 PnP.BIN"); + return sb_awe32_available() && rom_present(PNP_ROM_SB_AWE64_VALUE); } static int sb_awe64_available(void) { - return sb_awe32_available() && rom_present("roms/sound/creative/CT4520 PnP.BIN"); + return sb_awe32_available() && rom_present(PNP_ROM_SB_AWE64); } static int sb_awe64_gold_available(void) { - return sb_awe32_available() && rom_present("roms/sound/creative/CT4540 PnP.BIN"); + return sb_awe32_available() && rom_present(PNP_ROM_SB_AWE64_GOLD); } static void * @@ -2659,20 +2667,23 @@ sb_awe32_pnp_init(const device_t *info) const char *pnp_rom_file = NULL; switch (info->local) { case 0: - pnp_rom_file = "roms/sound/creative/CT3600 PnP.BIN"; + pnp_rom_file = PNP_ROM_SB_32_PNP; break; case 1: - pnp_rom_file = "roms/sound/creative/CT3980 PnP.BIN"; + pnp_rom_file = PNP_ROM_SB_AWE32_PNP; break; case 2: + pnp_rom_file = PNP_ROM_SB_AWE64_VALUE; + break; + case 3: - pnp_rom_file = "roms/sound/creative/CT4520 PnP.BIN"; + pnp_rom_file = PNP_ROM_SB_AWE64; break; case 4: - pnp_rom_file = "roms/sound/creative/CT4540 PnP.BIN"; + pnp_rom_file = PNP_ROM_SB_AWE64_GOLD; break; default: From 938fa5bde59616701d881437a0a70fde9e9026d7 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 1 Mar 2024 19:34:59 +0500 Subject: [PATCH 615/936] Add a correct PnP ROM for the CT4380 SB AWE64 Add a correct PnP ROM for the CT4380 "regular" Sound Blaster AWE64 and add quarternary IDE to it to match the new ROM --- src/sound/snd_sb.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 5d59d2577..a82ee21d3 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -48,7 +48,7 @@ #define PNP_ROM_SB_32_PNP "roms/sound/creative/CT3600 PnP.BIN" #define PNP_ROM_SB_AWE32_PNP "roms/sound/creative/CT3980 PnP.BIN" #define PNP_ROM_SB_AWE64_VALUE "roms/sound/creative/CT4520 PnP.BIN" -#define PNP_ROM_SB_AWE64 PNP_ROM_SB_AWE64_VALUE +#define PNP_ROM_SB_AWE64 "roms/sound/creative/CTL009DA.BIN" #define PNP_ROM_SB_AWE64_GOLD "roms/sound/creative/CT4540 PnP.BIN" /* 0 to 7 -> -14dB to 0dB i 2dB steps. 8 to 15 -> 0 to +14dB in 2dB steps. @@ -1782,6 +1782,27 @@ sb_awe32_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *pr } } +static void +sb_awe64_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) +{ + sb_t *sb = (sb_t *) priv; + + switch (ld) { + case 0: /* Audio */ + case 2: /* WaveTable */ + sb_16_pnp_config_changed(ld, config, sb); + break; + + case 1: /* Game */ + case 3: /* IDE */ + sb_16_pnp_config_changed(ld ^ 2, config, sb); + break; + + default: + break; + } +} + static void sb_awe64_gold_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) { @@ -2661,7 +2682,7 @@ sb_awe32_pnp_init(const device_t *info) sb->gameport = gameport_add(&gameport_pnp_device); - if ((info->local != 2) && (info->local != 3) && (info->local != 4)) + if ((info->local != 2) && (info->local != 4)) device_add(&ide_qua_pnp_device); const char *pnp_rom_file = NULL; @@ -2709,8 +2730,11 @@ sb_awe32_pnp_init(const device_t *info) isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_awe32_pnp_config_changed, NULL, NULL, NULL, sb); break; - case 2: case 3: + isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_awe64_pnp_config_changed, NULL, NULL, NULL, sb); + break; + + case 2: case 4: isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_awe64_gold_pnp_config_changed, NULL, NULL, NULL, sb); break; @@ -2725,7 +2749,7 @@ sb_awe32_pnp_init(const device_t *info) sb_dsp_setdma16(&sb->dsp, ISAPNP_DMA_DISABLED); mpu401_change_addr(sb->mpu, 0); - if ((info->local != 2) && (info->local != 3) && (info->local != 4)) + if ((info->local != 2) && (info->local != 4)) ide_remove_handlers(3); emu8k_change_addr(&sb->emu8k, 0); From ff6964f73d2b65915866560ba0cf179aa5546d73 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 1 Mar 2024 19:26:32 +0100 Subject: [PATCH 616/936] ESDI/MFM AT changes: Make sure they IRQ activations are more IDE-like and correct. --- src/disk/hdc_esdi_at.c | 26 ++++++++++++++------------ src/disk/hdc_st506_at.c | 32 +++++++++++++++++--------------- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/disk/hdc_esdi_at.c b/src/disk/hdc_esdi_at.c index 65184094a..042a6020a 100644 --- a/src/disk/hdc_esdi_at.c +++ b/src/disk/hdc_esdi_at.c @@ -129,23 +129,24 @@ esdi_at_log(const char *fmt, ...) static __inline void irq_raise(esdi_t *esdi) { - if (!(esdi->fdisk & 2)) - picint(1 << 14); - esdi->irqstat = 1; + if (!(esdi->fdisk & 2)) + picint_common(1 << 14, PIC_IRQ_EDGE, 1, NULL); } static __inline void -irq_lower(UNUSED(esdi_t *esdi)) +irq_lower(esdi_t *esdi) { - picintc(1 << 14); + esdi->irqstat = 0; + if (!(esdi->fdisk & 2)) + picint_common(1 << 14, PIC_IRQ_EDGE, 0, NULL); } static __inline void -irq_update(UNUSED(esdi_t *esdi)) +irq_update(esdi_t *esdi) { - if (esdi->irqstat && !((pic2.irr | pic2.isr) & 0x40) && !(esdi->fdisk & 2)) - picint(1 << 14); + uint8_t set = !(esdi->fdisk & 2) && esdi->irqstat; + picint_common(1 << 14, PIC_IRQ_EDGE, set, NULL); } static void @@ -263,6 +264,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv) double seek_time; double xfer_time; off64_t addr; + uint8_t old; esdi_at_log("WD1007 write(%04x, %02x)\n", port, val); @@ -411,15 +413,15 @@ esdi_write(uint16_t port, uint8_t val, void *priv) esdi_set_callback(esdi, 500 * HDC_TIME); esdi->reset = 1; esdi->status = STAT_BUSY; - } - - if (val & 0x04) { + } else if (!(esdi->fdisk & 0x04) && (val & 0x04)) { /* Drive held in reset. */ esdi_set_callback(esdi, 0); esdi->status = STAT_BUSY; } + old = esdi->fdisk; esdi->fdisk = val; - irq_update(esdi); + if (!(val & 0x02) && (old & 0x02)) + irq_update(esdi); break; default: diff --git a/src/disk/hdc_st506_at.c b/src/disk/hdc_st506_at.c index 41499591d..c8c35d7d5 100644 --- a/src/disk/hdc_st506_at.c +++ b/src/disk/hdc_st506_at.c @@ -134,26 +134,27 @@ st506_at_log(const char *fmt, ...) # define st506_at_log(fmt, ...) #endif -static inline void +static __inline void irq_raise(mfm_t *mfm) { - if (!(mfm->fdisk & 2)) - picint(1 << 14); - mfm->irqstat = 1; + if (!(mfm->fdisk & 2)) + picint_common(1 << 14, PIC_IRQ_EDGE, 1, NULL); } -static inline void -irq_lower(UNUSED(mfm_t *mfm)) +static __inline void +irq_lower(mfm_t *mfm) { - picintc(1 << 14); + mfm->irqstat = 0; + if (!(mfm->fdisk & 2)) + picint_common(1 << 14, PIC_IRQ_EDGE, 0, NULL); } -static void +static __inline void irq_update(mfm_t *mfm) { - if (mfm->irqstat && !((pic2.irr | pic2.isr) & 0x40) && !(mfm->fdisk & 2)) - picint(1 << 14); + uint8_t set = !(mfm->fdisk & 2) && mfm->irqstat; + picint_common(1 << 14, PIC_IRQ_EDGE, set, NULL); } /* @@ -378,6 +379,7 @@ static void mfm_write(uint16_t port, uint8_t val, void *priv) { mfm_t *mfm = (mfm_t *) priv; + uint8_t old; st506_at_log("WD1003 write(%04x, %02x)\n", port, val); @@ -408,7 +410,7 @@ mfm_write(uint16_t port, uint8_t val, void *priv) case 0x01f6: /* drive/head */ mfm->head = val & 0xF; - mfm->drvsel = (val & 0x10) ? 1 : 0; + mfm->drvsel = !!(val & 0x10); if (mfm->drives[mfm->drvsel].present) mfm->status = STAT_READY | STAT_DSC; else @@ -425,15 +427,15 @@ mfm_write(uint16_t port, uint8_t val, void *priv) timer_set_delay_u64(&mfm->callback_timer, 500 * MFM_TIME); mfm->reset = 1; mfm->status = STAT_BUSY; - } - - if (val & 0x04) { + } else if (!(mfm->fdisk & 0x04) && (val & 0x04)) { /* Drive held in reset. */ timer_disable(&mfm->callback_timer); mfm->status = STAT_BUSY; } + old = mfm->fdisk; mfm->fdisk = val; - irq_update(mfm); + if (!(val & 0x02) && (old & 0x02)) + irq_update(mfm); break; default: From 929fa7328d59d1085787c71e91f29cc6461617d9 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 1 Mar 2024 19:50:23 +0100 Subject: [PATCH 617/936] Mach8/32 horizontal display changes. Make sure for the 9001st time to display correctly the horizontal side of the display (looking at you, ATI 1992 set for win3.1x and Mach8/32 drivers for OS/2 1.2x). --- src/video/vid_ati_mach8.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 3888e9c26..2613de767 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2596,15 +2596,16 @@ mach_recalctimings(svga_t *svga) mach_log("ON[0]=%d, ON[1]=%d, exton[0]=%d, exton[1]=%d, vendormode0=%d, vendormode1=%d.\n", dev->on[0], dev->on[1], mach->ext_on[0], mach->ext_on[1], dev->vendor_mode[0], dev->vendor_mode[1]); if (dev->on[0] || dev->on[1]) { mach_log("8514/A ON.\n"); - dev->h_disp = dev->hdisp; dev->h_total = dev->htotal + 1; dev->h_blankstart = dev->hblankstart; dev->h_blank_end_val = dev->hblank_end_val; dev->v_total = dev->vtotal; dev->v_syncstart = dev->vsyncstart; - dev->dispend = dev->vdisp; dev->rowcount = !!(dev->disp_cntl & 0x08); + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; + if (dev->dispend == 766) dev->dispend += 2; @@ -2636,6 +2637,7 @@ mach_recalctimings(svga_t *svga) dev->v_total >>= 1; } + mach_log("HDISP=%d.\n", dev->h_disp); dev->pitch = dev->ext_pitch; dev->rowoffset = dev->ext_crt_pitch; if ((mach->accel.ext_ge_config & 0x800) || (!(mach->accel.ext_ge_config & 0x8000) && !(mach->accel.ext_ge_config & 0x800))) { @@ -3626,9 +3628,21 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { dev->hdisped = val; dev->hdisp = (dev->hdisped + 1) << 3; + if ((dev->hdisp == 640) && ((mach->shadow_set & 0x03) == 0x02) && (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) + svga_recalctimings(svga); + else if ((dev->hdisp == 1024) && !(mach->accel.clock_sel & 0x01) && ((dev->disp_cntl & 0x60) == 0x40)) { + if (dev->accel.advfunc_cntl & 0x04) { + dev->hdisp = 1024; + dev->vdisp = 768; + } else { + dev->hdisp = 640; + dev->vdisp = 480; + } + svga_recalctimings(svga); + } } } - mach_log("[%04X:%08X]: ATI 8514/A: H_DISP write 06E8 = %d, actual val=%d, set lock=%x, shadow set=%x, advfunc=%x, dispcntl=%02x.\n", CS, cpu_state.pc, dev->hdisp, ((val + 1) << 3), mach->shadow_cntl, mach->shadow_set, dev->accel.advfunc_cntl & 4, dev->disp_cntl & 0x60); + mach_log("[%04X:%08X]: ATI 8514/A: H_DISP write 06E8 = %d, actual val=%d, set lock=%x, shadow set=%x, advfunc bit 2=%x, dispcntl=%02x, clocksel bit 0=%x.\n", CS, cpu_state.pc, dev->hdisp, ((val + 1) << 3), mach->shadow_cntl, mach->shadow_set, dev->accel.advfunc_cntl & 0x04, dev->disp_cntl & 0x60, mach->accel.clock_sel & 0x01); break; case 0xae8: @@ -3733,7 +3747,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 mach->ext_on[port & 1] = dev->on[port & 1]; mach32_updatemapping(mach, svga); dev->vendor_mode[port & 1] = 0; - mach_log("ATI 8514/A: (0x%04x): ON=%d, shadow crt=%x.\n", port, dev->on[port & 1], dev->accel.advfunc_cntl & 4); + mach_log("ATI 8514/A: (0x%04x): ON=%d, shadow crt=%x, hdisp=%d.\n", port, dev->on[port & 1], dev->accel.advfunc_cntl & 4, dev->hdisp); svga_recalctimings(svga); break; From af786bec0a597b9b6e893f7aa3eee496bb588fa3 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 1 Mar 2024 22:54:31 +0100 Subject: [PATCH 618/936] IDE changes (now for MCA). Added McIDE (MCA IDE) controller for MCA machines that don't have it (PS/2 models 50+). --- src/disk/hdc.c | 1 + src/disk/hdc_ide.c | 298 ++++++++++++++++++++++++++++++++++++++-- src/include/86box/hdc.h | 2 + 3 files changed, 292 insertions(+), 9 deletions(-) diff --git a/src/disk/hdc.c b/src/disk/hdc.c index 7bfb7e05a..034b8890e 100644 --- a/src/disk/hdc.c +++ b/src/disk/hdc.c @@ -109,6 +109,7 @@ static const struct { { &ide_pci_2ch_device }, { &ide_vlb_device }, { &ide_vlb_2ch_device }, + { &mcide_device }, { NULL } // clang-format on }; diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 39031138f..dbb283407 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -30,8 +30,10 @@ #include "cpu.h" #include <86box/machine.h> #include <86box/io.h> +#include <86box/mca.h> #include <86box/mem.h> #include <86box/pic.h> +#include <86box/rom.h> #include <86box/pci.h> #include <86box/rom.h> #include <86box/timer.h> @@ -112,6 +114,8 @@ #define IDE_ATAPI_IS_EARLY ide->sc->pad0 +#define ROM_PATH_MCIDE "roms/hdd/xtide/ide_ps2 R1.1.bin" + typedef struct ide_bm_t { int (*dma)(uint8_t *data, int transfer_length, int out, void *priv); void (*set_irq)(uint8_t status, void *priv); @@ -135,6 +139,12 @@ typedef struct ide_board_t { ide_bm_t *bm; } ide_board_t; +typedef struct mcide_t { + uint8_t pos_regs[8]; + uint32_t bios_addr; + rom_t bios_rom; +} mcide_t; + ide_board_t *ide_boards[IDE_BUS_MAX]; static uint8_t ide_ter_pnp_rom[] = { @@ -2764,9 +2774,9 @@ ide_board_setup(int board) } static void -ide_board_init(int board, int irq, int base_main, int side_main, int type) +ide_board_init(int board, int irq, int base_main, int side_main, int type, int bus) { - ide_log("ide_board_init(%i, %i, %04X, %04X, %i)\n", board, irq, base_main, side_main, type); + ide_log("ide_board_init(%i, %i, %04X, %04X, %i, %i)\n", board, irq, base_main, side_main, type, bus); if ((ide_boards[board] != NULL) && ide_boards[board]->inited) return; @@ -2782,6 +2792,7 @@ ide_board_init(int board, int irq, int base_main, int side_main, int type) ide_boards[board]->bit32 = 1; ide_boards[board]->base[0] = base_main; ide_boards[board]->base[1] = side_main; + ide_set_handlers(board); timer_add(&ide_boards[board]->timer, ide_board_callback, ide_boards[board], 0); @@ -2834,12 +2845,12 @@ ide_ter_init(const device_t *info) irq = device_get_config_int("irq"); if (irq < 0) { - ide_board_init(2, -1, 0, 0, 0); + ide_board_init(2, -1, 0, 0, 0, 0); if (irq == -1) isapnp_add_card(ide_ter_pnp_rom, sizeof(ide_ter_pnp_rom), ide_pnp_config_changed, NULL, NULL, NULL, (void *) 2); } else { - ide_board_init(2, irq, HDC_TERTIARY_BASE, HDC_TERTIARY_SIDE, 0); + ide_board_init(2, irq, HDC_TERTIARY_BASE, HDC_TERTIARY_SIDE, 0, 0); } return (ide_boards[2]); @@ -2866,12 +2877,12 @@ ide_qua_init(const device_t *info) irq = device_get_config_int("irq"); if (irq < 0) { - ide_board_init(3, -1, 0, 0, 0); + ide_board_init(3, -1, 0, 0, 0, 0); if (irq == -1) isapnp_add_card(ide_qua_pnp_rom, sizeof(ide_qua_pnp_rom), ide_pnp_config_changed, NULL, NULL, NULL, (void *) 3); } else - ide_board_init(3, irq, HDC_QUATERNARY_BASE, HDC_QUATERNARY_SIDE, 0); + ide_board_init(3, irq, HDC_QUATERNARY_BASE, HDC_QUATERNARY_SIDE, 0, 0); return (ide_boards[3]); } @@ -2886,7 +2897,7 @@ ide_qua_close(UNUSED(void *priv)) void * ide_xtide_init(void) { - ide_board_init(0, -1, 0, 0, 0); + ide_board_init(0, -1, 0, 0, 0, 0); return ide_boards[0]; } @@ -2922,10 +2933,10 @@ ide_init(const device_t *info) switch (info->local) { case 0 ... 5: - ide_board_init(0, 14, 0x1f0, 0x3f6, info->local); + ide_board_init(0, 14, 0x1f0, 0x3f6, info->local, info->flags); if (info->local & 1) - ide_board_init(1, 15, 0x170, 0x376, info->local); + ide_board_init(1, 15, 0x170, 0x376, info->local, info->flags); break; default: @@ -3026,6 +3037,260 @@ ide_close(UNUSED(void *priv)) } } +static uint8_t +mcide_mca_read(int port, void *priv) +{ + const mcide_t *dev = (mcide_t *) priv; + + ide_log("IDE: mcard(%04x)\n", port); + + return (dev->pos_regs[port & 7]); +} + +static void +mcide_mca_write(int port, uint8_t val, void *priv) +{ + mcide_t *dev = (mcide_t *) priv; + + ide_log("IDE: mcawr(%04x, %02x) pos[2]=%02x pos[3]=%02x\n", + port, val, dev->pos_regs[2], dev->pos_regs[3]); + + if (port < 0x102) + return; + + /* Save the new value. */ + dev->pos_regs[port & 7] = val; + + io_handler(0, ide_boards[0]->base[0], 8, + ide_readb, ide_readw, ide_readl, + ide_writeb, ide_writew, ide_writel, + ide_boards[0]); + io_handler(0, ide_boards[1]->base[0], 8, + ide_readb, ide_readw, ide_readl, + ide_writeb, ide_writew, ide_writel, + ide_boards[1]); + mem_mapping_disable(&dev->bios_rom.mapping); + + if (dev->pos_regs[2] & 0x80) { + switch ((dev->pos_regs[2] >> 4) & 7) { + case 0: + dev->bios_addr = 0xc0000; + break; + case 1: + dev->bios_addr = 0xc4000; + break; + case 2: + dev->bios_addr = 0xc8000; + break; + case 3: + dev->bios_addr = 0xcc000; + break; + case 4: + dev->bios_addr = 0xd0000; + break; + case 5: + dev->bios_addr = 0xd4000; + break; + case 6: + dev->bios_addr = 0xd8000; + break; + case 7: + dev->bios_addr = 0xd8000; + break; + default: + break; + } + } else { + dev->bios_addr = 0; + } + + if (dev->pos_regs[3] & 0x08) { + switch ((dev->pos_regs[3] & 3)) { + case 0: + ide_boards[0]->base[0] = 0x1f0; + break; + case 1: + ide_boards[0]->base[0] = 0x170; + break; + case 2: + ide_boards[0]->base[0] = 0x1e8; + break; + case 3: + ide_boards[0]->base[0] = 0x168; + break; + default: + break; + } + } else + ide_boards[0]->base[0] = 0; + + if (dev->pos_regs[3] & 0x80) { + switch ((dev->pos_regs[3] >> 5) & 3) { + case 0: + ide_boards[0]->irq = 10; + break; + case 1: + ide_boards[0]->irq = 11; + break; + case 2: + ide_boards[0]->irq = 14; + break; + case 3: + ide_boards[0]->irq = 15; + break; + + default: + break; + } + } else + ide_boards[0]->irq = -1; + + if (dev->pos_regs[4] & 0x08) { + switch ((dev->pos_regs[4] & 3)) { + case 0: + ide_boards[1]->base[0] = 0x1f0; + break; + case 1: + ide_boards[1]->base[0] = 0x170; + break; + case 2: + ide_boards[1]->base[0] = 0x1e8; + break; + case 3: + ide_boards[1]->base[0] = 0x168; + break; + default: + break; + } + } else + ide_boards[1]->base[0] = 0; + + if (dev->pos_regs[4] & 0x80) { + switch ((dev->pos_regs[4] >> 5) & 3) { + case 0: + ide_boards[1]->irq = 10; + break; + case 1: + ide_boards[1]->irq = 11; + break; + case 2: + ide_boards[1]->irq = 14; + break; + case 3: + ide_boards[1]->irq = 15; + break; + + default: + break; + } + } else + ide_boards[1]->irq = -1; + + if (dev->pos_regs[2] & 1) { + if ((dev->pos_regs[3] & 0x88) == 0x88) + io_handler(1, ide_boards[0]->base[0], 8, + ide_readb, ide_readw, ide_readl, + ide_writeb, ide_writew, ide_writel, + ide_boards[0]); + + if ((dev->pos_regs[4] & 0x88) == 0x88) + io_handler(1, ide_boards[1]->base[0], 8, + ide_readb, ide_readw, ide_readl, + ide_writeb, ide_writew, ide_writel, + ide_boards[1]); + + if (dev->pos_regs[2] & 0x80) { + mem_mapping_enable(&dev->bios_rom.mapping); + mem_mapping_set_addr(&dev->bios_rom.mapping, + dev->bios_addr, 0x2000); + } + + /* Say hello. */ + ide_log("McIDE: Primary I/O=%03x, Primary IRQ=%i, Secondary I/O=%03x, Secondary IRQ=%d, BIOS @%05X\n", + ide_boards[0]->base[0], ide_boards[0]->irq, ide_boards[1]->base[0], ide_boards[1]->irq, dev->bios_addr); + } +} + +static uint8_t +mcide_mca_feedb(void *priv) +{ + const mcide_t *dev = (mcide_t *) priv; + + return (dev->pos_regs[2] & 1); +} + +static void +mcide_mca_reset(void *priv) +{ + mcide_t *dev = (mcide_t *) priv; + + for (uint8_t i = 0; i < 2; i++) { + if (ide_boards[i] != NULL) + ide_board_reset(i); + } + + ide_log("McIDE: MCA Reset.\n"); + mem_mapping_disable(&dev->bios_rom.mapping); + mcide_mca_write(0x102, 0, dev); +} + +static void +mcide_reset(void *priv) +{ + mcide_t *dev = (mcide_t *) priv; + + for (uint8_t i = 0; i < 2; i++) { + if (ide_boards[i] != NULL) + ide_board_reset(i); + } + + ide_log("McIDE: Reset.\n"); +} + +static void * +mcide_init(const device_t *info) +{ + ide_log("Initializing McIDE...\n"); + mcide_t *dev = (mcide_t *) calloc(1, sizeof(mcide_t)); + + ide_board_init(0, -1, 0, 0, info->local, info->flags); + ide_board_init(1, -1, 0, 0, info->local, info->flags); + + rom_init(&dev->bios_rom, ROM_PATH_MCIDE, + 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_disable(&dev->bios_rom.mapping); + + /* Set the MCA ID for this controller, 0xF171. */ + dev->pos_regs[0] = 0xf1; + dev->pos_regs[1] = 0x71; + + /* Enable the device. */ + mca_add(mcide_mca_read, mcide_mca_write, mcide_mca_feedb, mcide_mca_reset, dev); + + return dev; +} + +static int +mcide_available(void) +{ + return (rom_present(ROM_PATH_MCIDE)); +} + +static void +mcide_close(void *priv) +{ + mcide_t *dev = (mcide_t *) priv; + + for (uint8_t i = 0; i < 2; i++) { + if (ide_boards[i] != NULL) { + ide_board_close(i); + ide_boards[i] = NULL; + } + } + + free(dev); +} + const device_t ide_isa_device = { .name = "ISA PC/AT IDE Controller", .internal_name = "ide_isa", @@ -3110,6 +3375,21 @@ const device_t ide_pci_2ch_device = { .config = NULL }; +const device_t mcide_device = { + .name = "MCA McIDE Controller", + .internal_name = "mcide", + .flags = DEVICE_MCA, + .local = 0, + .init = mcide_init, + .close = mcide_close, + .reset = mcide_reset, + { .available = mcide_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + + // clang-format off static const device_config_t ide_ter_config[] = { { diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h index a3d562b62..4f65399bb 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -93,6 +93,8 @@ extern const device_t ide_ter_pnp_device; extern const device_t ide_qua_device; extern const device_t ide_qua_pnp_device; +extern const device_t mcide_device; + extern const device_t xta_wdxt150_device; /* xta_wdxt150 */ extern const device_t xta_hd20_device; /* EuroPC internal */ From 98fa92557063a047c7d8c842ceaf81b2a006cc0f Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 2 Mar 2024 05:25:27 +0100 Subject: [PATCH 619/936] SB PRO and 16: Do not use the low FIR output filter for CD Audio. --- src/sound/snd_sb.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index fb9157dfd..466e96a54 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -383,10 +383,7 @@ sbpro_filter_cd_audio(int channel, double *buffer, void *priv) double cd = channel ? mixer->cd_r : mixer->cd_l; double master = channel ? mixer->master_r : mixer->master_l; - if (mixer->output_filter) - c = (sb_iir(2, channel, *buffer) * cd) / 3.9; - else - c = (*buffer * cd) / 3.0; + c = (*buffer * cd) / 3.0; *buffer = c * master; } @@ -594,10 +591,7 @@ sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv) double bass_treble; double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L); - if (mixer->output_filter) - c = (low_fir_sb16(2, channel, *buffer) * cd) / 3.0; - else - c = ((*buffer) * cd) / 3.0; + c = ((*buffer) * cd) / 3.0; c *= master; /* This is not exactly how one does bass/treble controls, but the end result is like it. From 1d5a2aaa0f5be5398fad0862a1f44921bc288e91 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 2 Mar 2024 12:50:06 +0100 Subject: [PATCH 620/936] QT UI: Recognize the MCA McIDE as an IDE controller. --- src/qt/qt_machinestatus.cpp | 42 +++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/src/qt/qt_machinestatus.cpp b/src/qt/qt_machinestatus.cpp index d7b115a64..59ea960f8 100644 --- a/src/qt/qt_machinestatus.cpp +++ b/src/qt/qt_machinestatus.cpp @@ -297,9 +297,14 @@ MachineStatus::iterateCDROM(const std::function &cb) auto hdc_name = QString(hdc_get_internal_name(hdc_current)); for (size_t i = 0; i < CDROM_NUM; i++) { /* Could be Internal or External IDE.. */ - if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && !hasIDE() && hdc_name.left(3) != QStringLiteral("ide") && hdc_name.left(5) != QStringLiteral("xtide")) + if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && !hasIDE() && + (hdc_name.left(3) != QStringLiteral("ide")) && + (hdc_name.left(5) != QStringLiteral("xtide")) && + (hdc_name.left(5) != QStringLiteral("mcide"))) continue; - if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !hasSCSI() && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) + if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !hasSCSI() && + (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && + (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) continue; if ((cdrom[i].bus_type == CDROM_BUS_MITSUMI) && (cdrom_interface_current == 0)) continue; @@ -315,9 +320,14 @@ MachineStatus::iterateZIP(const std::function &cb) auto hdc_name = QString(hdc_get_internal_name(hdc_current)); for (size_t i = 0; i < ZIP_NUM; i++) { /* Could be Internal or External IDE.. */ - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && !hasIDE() && hdc_name.left(3) != QStringLiteral("ide") && hdc_name.left(5) != QStringLiteral("xtide")) + if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && !hasIDE() && + (hdc_name.left(3) != QStringLiteral("ide")) && + (hdc_name.left(5) != QStringLiteral("xtide")) && + (hdc_name.left(5) != QStringLiteral("mcide"))) continue; - if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !hasSCSI() && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) + if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !hasSCSI() && + (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && + (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) continue; if (zip_drives[i].bus_type != 0) { cb(i); @@ -331,9 +341,14 @@ MachineStatus::iterateMO(const std::function &cb) auto hdc_name = QString(hdc_get_internal_name(hdc_current)); for (size_t i = 0; i < MO_NUM; i++) { /* Could be Internal or External IDE.. */ - if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && !hasIDE() && hdc_name.left(3) != QStringLiteral("ide") && hdc_name.left(5) != QStringLiteral("xtide")) + if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && !hasIDE() && + (hdc_name.left(3) != QStringLiteral("ide")) && + (hdc_name.left(5) != QStringLiteral("xtide")) && + (hdc_name.left(5) != QStringLiteral("mcide"))) continue; - if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !hasSCSI() && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) + if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !hasSCSI() && + (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && + (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) continue; if (mo_drives[i].bus_type != 0) { cb(i); @@ -577,28 +592,30 @@ MachineStatus::refresh(QStatusBar *sbar) }); auto hdc_name = QString(hdc_get_internal_name(hdc_current)); - if ((has_mfm || hdc_name.left(5) == QStringLiteral("st506")) && c_mfm > 0) { + if ((has_mfm || (hdc_name.left(5) == QStringLiteral("st506"))) && (c_mfm > 0)) { d->hdds[HDD_BUS_MFM].label = std::make_unique(); d->hdds[HDD_BUS_MFM].setActive(false); d->hdds[HDD_BUS_MFM].refresh(); d->hdds[HDD_BUS_MFM].label->setToolTip(tr("Hard disk (%s)").replace("%s", "MFM/RLL")); sbar->addWidget(d->hdds[HDD_BUS_MFM].label.get()); } - if ((has_esdi || hdc_name.left(4) == QStringLiteral("esdi")) && c_esdi > 0) { + if ((has_esdi || (hdc_name.left(4) == QStringLiteral("esdi"))) && (c_esdi > 0)) { d->hdds[HDD_BUS_ESDI].label = std::make_unique(); d->hdds[HDD_BUS_ESDI].setActive(false); d->hdds[HDD_BUS_ESDI].refresh(); d->hdds[HDD_BUS_ESDI].label->setToolTip(tr("Hard disk (%s)").replace("%s", "ESDI")); sbar->addWidget(d->hdds[HDD_BUS_ESDI].label.get()); } - if ((has_xta || hdc_name.left(3) == QStringLiteral("xta")) && c_xta > 0) { + if ((has_xta || (hdc_name.left(3) == QStringLiteral("xta"))) && (c_xta > 0)) { d->hdds[HDD_BUS_XTA].label = std::make_unique(); d->hdds[HDD_BUS_XTA].setActive(false); d->hdds[HDD_BUS_XTA].refresh(); d->hdds[HDD_BUS_XTA].label->setToolTip(tr("Hard disk (%s)").replace("%s", "XTA")); sbar->addWidget(d->hdds[HDD_BUS_XTA].label.get()); } - if (hasIDE() || hdc_name.left(5) == QStringLiteral("xtide") || hdc_name.left(3) == QStringLiteral("ide")) { + if (hasIDE() || (hdc_name.left(5) == QStringLiteral("xtide")) || + (hdc_name.left(5) == QStringLiteral("mcide")) || + (hdc_name.left(3) == QStringLiteral("ide"))) { if (c_ide > 0) { d->hdds[HDD_BUS_IDE].label = std::make_unique(); d->hdds[HDD_BUS_IDE].setActive(false); @@ -614,7 +631,10 @@ MachineStatus::refresh(QStatusBar *sbar) sbar->addWidget(d->hdds[HDD_BUS_ATAPI].label.get()); } } - if ((hasSCSI() || (scsi_card_current[0] != 0) || (scsi_card_current[1] != 0) || (scsi_card_current[2] != 0) || (scsi_card_current[3] != 0)) && c_scsi > 0) { + if ((hasSCSI() || + (scsi_card_current[0] != 0) || (scsi_card_current[1] != 0) || + (scsi_card_current[2] != 0) || (scsi_card_current[3] != 0)) && + (c_scsi > 0)) { d->hdds[HDD_BUS_SCSI].label = std::make_unique(); d->hdds[HDD_BUS_SCSI].setActive(false); d->hdds[HDD_BUS_SCSI].refresh(); From 12e367fac6ec4d5547c4492d7d2dacd47619ebd2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 2 Mar 2024 12:51:50 +0100 Subject: [PATCH 621/936] Fixed a warning in disk/hdc_ide.c. --- src/disk/hdc_ide.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index dbb283407..d8df384f1 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -3237,8 +3237,6 @@ mcide_mca_reset(void *priv) static void mcide_reset(void *priv) { - mcide_t *dev = (mcide_t *) priv; - for (uint8_t i = 0; i < 2; i++) { if (ide_boards[i] != NULL) ide_board_reset(i); From 8c6d544d5de7c4a91007ed9dbad136071b477e6f Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 2 Mar 2024 15:46:12 +0100 Subject: [PATCH 622/936] IDE/ATAPI port/irq changes for MCA: The ADF is a bit misleading, for pos3 and pos4, the right bits are bits 5-4, not 6-5. Fixes IRQ and added the secondary addresses without conflicting with the FDC, now ATAPI drives work fine. --- src/disk/hdc_ide.c | 73 +++++++++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 21 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index dbb283407..833ef4f39 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -2793,7 +2793,8 @@ ide_board_init(int board, int irq, int base_main, int side_main, int type, int b ide_boards[board]->base[0] = base_main; ide_boards[board]->base[1] = side_main; - ide_set_handlers(board); + if (!(bus & DEVICE_MCA)) + ide_set_handlers(board); timer_add(&ide_boards[board]->timer, ide_board_callback, ide_boards[board], 0); @@ -3065,10 +3066,18 @@ mcide_mca_write(int port, uint8_t val, void *priv) ide_readb, ide_readw, ide_readl, ide_writeb, ide_writew, ide_writel, ide_boards[0]); + io_handler(0, ide_boards[0]->base[1], 1, + ide_read_alt_status, NULL, NULL, + ide_write_devctl, NULL, NULL, + ide_boards[0]); io_handler(0, ide_boards[1]->base[0], 8, ide_readb, ide_readw, ide_readl, ide_writeb, ide_writew, ide_writel, ide_boards[1]); + io_handler(0, ide_boards[1]->base[1], 1, + ide_read_alt_status, NULL, NULL, + ide_write_devctl, NULL, NULL, + ide_boards[1]); mem_mapping_disable(&dev->bios_rom.mapping); if (dev->pos_regs[2] & 0x80) { @@ -3105,37 +3114,43 @@ mcide_mca_write(int port, uint8_t val, void *priv) } if (dev->pos_regs[3] & 0x08) { - switch ((dev->pos_regs[3] & 3)) { + switch (dev->pos_regs[3] & 3) { case 0: ide_boards[0]->base[0] = 0x1f0; + ide_boards[0]->base[1] = 0x3f6; break; case 1: ide_boards[0]->base[0] = 0x170; + ide_boards[0]->base[1] = 0x376; break; case 2: ide_boards[0]->base[0] = 0x1e8; + ide_boards[0]->base[1] = 0x3ee; break; case 3: ide_boards[0]->base[0] = 0x168; + ide_boards[0]->base[1] = 0x36e; break; default: break; } - } else + } else { ide_boards[0]->base[0] = 0; + ide_boards[0]->base[1] = 0; + } if (dev->pos_regs[3] & 0x80) { - switch ((dev->pos_regs[3] >> 5) & 3) { - case 0: + switch (dev->pos_regs[3] & 0x30) { + case 0x00: ide_boards[0]->irq = 10; break; - case 1: + case 0x10: ide_boards[0]->irq = 11; break; - case 2: + case 0x20: ide_boards[0]->irq = 14; break; - case 3: + case 0x30: ide_boards[0]->irq = 15; break; @@ -3149,34 +3164,40 @@ mcide_mca_write(int port, uint8_t val, void *priv) switch ((dev->pos_regs[4] & 3)) { case 0: ide_boards[1]->base[0] = 0x1f0; + ide_boards[1]->base[1] = 0x3f6; break; case 1: ide_boards[1]->base[0] = 0x170; + ide_boards[1]->base[1] = 0x376; break; case 2: ide_boards[1]->base[0] = 0x1e8; + ide_boards[1]->base[1] = 0x3ee; break; case 3: ide_boards[1]->base[0] = 0x168; + ide_boards[1]->base[1] = 0x36e; break; default: break; } - } else + } else { ide_boards[1]->base[0] = 0; + ide_boards[1]->base[1] = 0; + } if (dev->pos_regs[4] & 0x80) { - switch ((dev->pos_regs[4] >> 5) & 3) { - case 0: + switch (dev->pos_regs[4] & 0x30) { + case 0x00: ide_boards[1]->irq = 10; break; - case 1: + case 0x10: ide_boards[1]->irq = 11; break; - case 2: + case 0x20: ide_boards[1]->irq = 14; break; - case 3: + case 0x30: ide_boards[1]->irq = 15; break; @@ -3187,26 +3208,36 @@ mcide_mca_write(int port, uint8_t val, void *priv) ide_boards[1]->irq = -1; if (dev->pos_regs[2] & 1) { - if ((dev->pos_regs[3] & 0x88) == 0x88) + if (ide_boards[0]->base[0] && ide_boards[0]->base[1]) { io_handler(1, ide_boards[0]->base[0], 8, ide_readb, ide_readw, ide_readl, ide_writeb, ide_writew, ide_writel, ide_boards[0]); + io_handler(1, ide_boards[0]->base[1], 1, + ide_read_alt_status, NULL, NULL, + ide_write_devctl, NULL, NULL, + ide_boards[0]); + } - if ((dev->pos_regs[4] & 0x88) == 0x88) + if (ide_boards[1]->base[0] && ide_boards[1]->base[1]) { io_handler(1, ide_boards[1]->base[0], 8, ide_readb, ide_readw, ide_readl, ide_writeb, ide_writew, ide_writel, ide_boards[1]); + io_handler(1, ide_boards[1]->base[1], 1, + ide_read_alt_status, NULL, NULL, + ide_write_devctl, NULL, NULL, + ide_boards[1]); + } - if (dev->pos_regs[2] & 0x80) { + if (dev->bios_addr) { mem_mapping_enable(&dev->bios_rom.mapping); mem_mapping_set_addr(&dev->bios_rom.mapping, - dev->bios_addr, 0x2000); + dev->bios_addr, 0x4000); } /* Say hello. */ - ide_log("McIDE: Primary I/O=%03x, Primary IRQ=%i, Secondary I/O=%03x, Secondary IRQ=%d, BIOS @%05X\n", + ide_log("McIDE: Primary Master I/O=%03x, Primary IRQ=%i, Secondary Master I/O=%03x, Secondary IRQ=%d, BIOS @%05X\n", ide_boards[0]->base[0], ide_boards[0]->irq, ide_boards[1]->base[0], ide_boards[1]->irq, dev->bios_addr); } } @@ -3257,7 +3288,7 @@ mcide_init(const device_t *info) ide_board_init(1, -1, 0, 0, info->local, info->flags); rom_init(&dev->bios_rom, ROM_PATH_MCIDE, - 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); + 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); mem_mapping_disable(&dev->bios_rom.mapping); /* Set the MCA ID for this controller, 0xF171. */ @@ -3377,7 +3408,7 @@ const device_t ide_pci_2ch_device = { const device_t mcide_device = { .name = "MCA McIDE Controller", - .internal_name = "mcide", + .internal_name = "ide_mcide", .flags = DEVICE_MCA, .local = 0, .init = mcide_init, From e2018775d530b600ad4bacaf19c5aa6bc3a2f9b0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 3 Mar 2024 18:19:00 +0100 Subject: [PATCH 623/936] Implement correct DSR behavior, fixes #3715. --- src/floppy/fdc.c | 27 ++++++++++++++++++++++----- src/include/86box/fdc.h | 3 ++- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 8f8fd404e..e16da138d 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -79,7 +79,6 @@ int floppyrate[4]; int fdc_type = 0; -// #define ENABLE_FDC_LOG 1 #ifdef ENABLE_FDC_LOG int fdc_do_log = ENABLE_FDC_LOG; @@ -781,12 +780,27 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) } return; case 4: - if (val & 0x80) { + if (!(val & 0x80)) { timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC); - fdc->interrupt = -1; - fdc->perp &= 0xfc; - fdc_ctrl_reset(fdc); + fdc->interrupt = -6; } + if (fdc->power_down || ((val & 0x80) && !(fdc->dsr & 0x80))) { + if (fdc->power_down) { + timer_set_delay_u64(&fdc->timer, 1000 * TIMER_USEC); + fdc->interrupt = -5; + } else { + timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC); + fdc->interrupt = -1; + + fdc->perp &= 0xfc; + + for (i = 0; i < FDD_NUM; i++) + ui_sb_update_icon(SB_FLOPPY | i, 0); + + fdc_ctrl_reset(fdc); + } + } + fdc->dsr = val; return; case 5: /*Command register*/ if ((fdc->stat & 0xf0) == 0xb0) { @@ -1532,6 +1546,9 @@ fdc_callback(void *priv) memset(fdc->pcn, 0x00, 4 * sizeof(uint16_t)); fdc->reset_stat = 4; return; + case -6: /*DSR Reset clear*/ + fdc->dsr |= 0x80; + return; case 0x01: /* Mode */ fdc->stat = 0x80; fdc->densel_force = (fdc->params[2] & 0xC0) >> 6; diff --git a/src/include/86box/fdc.h b/src/include/86box/fdc.h index 37c992a1b..00de511f3 100644 --- a/src/include/86box/fdc.h +++ b/src/include/86box/fdc.h @@ -115,12 +115,13 @@ typedef struct fdc_t { uint8_t rw_drive; uint8_t lock; + uint8_t dsr; + uint8_t params[15]; uint8_t specify[2]; uint8_t res[11]; uint8_t eot[4]; uint8_t rwc[4]; - uint8_t params[8]; uint16_t pcn[4]; From dc7a105ef2c57cd81da6956db2fd54ff894e0af8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 3 Mar 2024 20:14:24 +0100 Subject: [PATCH 624/936] Give the Compaq Portable III 386 the Compaq 386 chipset and keyboard controller. --- src/machine/m_at_compaq.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index 428199de7..cd8c68764 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -795,7 +795,6 @@ machine_at_compaq_init(const machine_t *model, int type) break; case COMPAQ_PORTABLEIII: - case COMPAQ_PORTABLEIII386: if (hdc_current == 1) device_add(&ide_isa_device); if (gfxcard[0] == VID_INTERNAL) @@ -803,6 +802,16 @@ machine_at_compaq_init(const machine_t *model, int type) machine_at_init(model); break; + case COMPAQ_PORTABLEIII386: + if (hdc_current == 1) + device_add(&ide_isa_device); + if (gfxcard[0] == VID_INTERNAL) + device_add(&compaq_plasma_device); + device_add(&compaq_386_device); + machine_at_common_init(model); + device_add(&keyboard_at_compaq_device); + break; + case COMPAQ_DESKPRO386: case COMPAQ_DESKPRO386_05_1988: device_add(&compaq_386_device); From 244038b84cf8ebd38814b53cf15f3461c6d0c34f Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 3 Mar 2024 21:24:00 +0100 Subject: [PATCH 625/936] LOCK: It is sometimes legal when cpu_mod == 3, fixes hangs with Compaq Portable III 386 TEST. --- src/cpu/386_common.c | 2 +- src/cpu/x86_ops_misc.h | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 5c1b95e0f..f3926f170 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -433,7 +433,7 @@ is_lock_legal(uint32_t fetchdat) legal = lock_legal[fetch_dat.b[0]]; if (legal == 1) - legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + legal = 1; // ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ else if (legal == 2) { legal = lock_legal_0f[fetch_dat.b[1]]; if (legal == 1) diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index 519bdbe3c..073327c9c 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -738,9 +738,6 @@ opLOCK(uint32_t fetchdat) legal = is_lock_legal(fetchdat); - if (legal == 4) - pclog("PREFIX: F0 %08X\n", fetchdat); - ILLEGAL_ON(legal == 0); CLOCK_CYCLES(4); From 2fff98423beb9619bff643cac7f70297409db38d Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 5 Mar 2024 20:36:33 +0100 Subject: [PATCH 626/936] Added the Everex Maxi Magic EV-165A, closes #2956. --- src/device/isamem.c | 123 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/src/device/isamem.c b/src/device/isamem.c index 5b880d6eb..8eb4b55f6 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -97,6 +97,7 @@ #define ISAMEM_RAMPAGEXT_CARD 11 #define ISAMEM_ABOVEBOARD_CARD 12 #define ISAMEM_BRAT_CARD 13 +#define ISAMEM_EV165A_CARD 14 #define ISAMEM_DEBUG 0 @@ -452,6 +453,18 @@ isamem_init(const device_t *info) dev->frame_addr = 0xE0000; break; + case ISAMEM_EV165A_CARD: /* Everex Maxi Magic EV-165A */ + dev->base_addr = device_get_config_hex16("base"); + dev->total_size = device_get_config_int("size"); + dev->start_addr = device_get_config_int("start"); + tot = device_get_config_int("length"); + if (!!device_get_config_int("speed")) + dev->flags |= FLAG_FAST; + if (!!device_get_config_int("ems")) + dev->flags |= FLAG_EMS; + dev->frame_addr = 0xE0000; + break; + case ISAMEM_RAMPAGEXT_CARD: /* AST RAMpage/XT */ case ISAMEM_ABOVEBOARD_CARD: /* Intel AboveBoard */ case ISAMEM_BRAT_CARD: /* BocaRAM/AT */ @@ -1238,6 +1251,115 @@ static const device_t ev159_device = { .config = ev159_config }; +static const device_config_t ev165a_config[] = { + // clang-format off + { + .name = "size", + .description = "Memory Size", + .type = CONFIG_SPINNER, + .default_string = "", + .default_int = 512, + .file_filter = "", + .spinner = { + .min = 0, + .max = 2048, + .step = 512 + }, + .selection = { { 0 } } + }, + { + .name = "start", + .description = "Start Address", + .type = CONFIG_SPINNER, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { + .min = 0, + .max = 896, + .step = 128 + }, + .selection = { { 0 } } + }, + { + .name = "length", + .description = "Contiguous Size", + .type = CONFIG_SPINNER, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { + .min = 0, + .max = 16384, + .step = 128 + }, + .selection = { { 0 } } + }, + { + .name = "speed", + .description = "Transfer Speed", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "Standard (150ns)", .value = 0 }, + { .description = "High-Speed (120ns)", .value = 1 }, + { .description = "" } + } + }, + { + .name = "ems", + .description = "EMS mode", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0 }, + { .description = "Enabled", .value = 1 }, + { .description = "" } + }, + }, + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x0258, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "208H", .value = 0x0208 }, + { .description = "218H", .value = 0x0218 }, + { .description = "258H", .value = 0x0258 }, + { .description = "268H", .value = 0x0268 }, + { .description = "2A8H", .value = 0x02A8 }, + { .description = "2B8H", .value = 0x02B8 }, + { .description = "2E8H", .value = 0x02E8 }, + { .description = "" } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +static const device_t ev165a_device = { + .name = "Everex Magi Magic EV-165A", + .internal_name = "ev159", + .flags = DEVICE_ISA, + .local = ISAMEM_EV165A_CARD, + .init = isamem_init, + .close = isamem_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ev165a_config +}; + #if defined(DEV_BRANCH) && defined(USE_ISAMEM_BRAT) static const device_config_t brat_config[] = { // clang-format off @@ -1560,6 +1682,7 @@ static const struct { { &a6pak_device }, { &ems5150_device }, { &ev159_device }, + { &ev165a_device }, #if defined(DEV_BRANCH) && defined(USE_ISAMEM_BRAT) { &brat_device }, #endif From 1bfe1bbf7a5dbcc3434ef3b6343139c23f1d101b Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 6 Mar 2024 01:27:25 +0100 Subject: [PATCH 627/936] Removed the speed setting from the Everex 165A. --- src/device/isamem.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index 8eb4b55f6..1237a9891 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -458,8 +458,6 @@ isamem_init(const device_t *info) dev->total_size = device_get_config_int("size"); dev->start_addr = device_get_config_int("start"); tot = device_get_config_int("length"); - if (!!device_get_config_int("speed")) - dev->flags |= FLAG_FAST; if (!!device_get_config_int("ems")) dev->flags |= FLAG_EMS; dev->frame_addr = 0xE0000; @@ -1295,20 +1293,6 @@ static const device_config_t ev165a_config[] = { }, .selection = { { 0 } } }, - { - .name = "speed", - .description = "Transfer Speed", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "Standard (150ns)", .value = 0 }, - { .description = "High-Speed (120ns)", .value = 1 }, - { .description = "" } - } - }, { .name = "ems", .description = "EMS mode", From 5d486f5faa2f6ab17df6c49271b2ef391fb4f563 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 6 Mar 2024 06:46:53 +0100 Subject: [PATCH 628/936] EV-165A: Fix internal name. --- src/device/isamem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index 1237a9891..70f51ce8d 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -1332,7 +1332,7 @@ static const device_config_t ev165a_config[] = { static const device_t ev165a_device = { .name = "Everex Magi Magic EV-165A", - .internal_name = "ev159", + .internal_name = "ev165a", .flags = DEVICE_ISA, .local = ISAMEM_EV165A_CARD, .init = isamem_init, From 6d1c91c8cefc9a7e85f75f1616ab35e8c5548d20 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 6 Mar 2024 15:10:51 +0600 Subject: [PATCH 629/936] Add Vision Systems LBA Enhancer --- src/86box.c | 4 + src/config.c | 7 ++ src/disk/CMakeLists.txt | 2 +- src/disk/lba_enhancer.c | 97 ++++++++++++++++++++++++ src/include/86box/86box.h | 1 + src/include/86box/hdc.h | 3 + src/qt/qt_settingsstoragecontrollers.cpp | 16 ++++ src/qt/qt_settingsstoragecontrollers.hpp | 4 + src/qt/qt_settingsstoragecontrollers.ui | 85 +++++++++++++++------ 9 files changed, 194 insertions(+), 25 deletions(-) create mode 100644 src/disk/lba_enhancer.c diff --git a/src/86box.c b/src/86box.c index 8218c208c..ca0f8b0ff 100644 --- a/src/86box.c +++ b/src/86box.c @@ -181,6 +181,7 @@ int gfxcard[2] = { 0, 0 }; /* (C) graphic int show_second_monitors = 1; /* (C) show non-primary monitors */ int sound_is_float = 1; /* (C) sound uses FP values */ int voodoo_enabled = 0; /* (C) video option */ +int lba_enhancer_enabled = 0; /* (C) enable Vision Systems LBA Enhancer */ int ibm8514_standalone_enabled = 0; /* (C) video option */ int xga_standalone_enabled = 0; /* (C) video option */ uint32_t mem_size = 0; /* (C) memory size (Installed on @@ -1226,6 +1227,9 @@ pc_reset_hard_init(void) device_add(&postcard_device); if (unittester_enabled) device_add(&unittester_device); + + if (lba_enhancer_enabled) + device_add(&lba_enhancer_device); if (IS_ARCH(machine, MACHINE_BUS_PCI)) { pci_register_cards(); diff --git a/src/config.c b/src/config.c index 3e4fd7222..9ca148289 100644 --- a/src/config.c +++ b/src/config.c @@ -876,6 +876,8 @@ load_storage_controllers(void) path_normalize(cart_fns[c]); } } + + lba_enhancer_enabled = !!ini_section_get_int(cat, "lba_enhancer_enabled", 0); } /* Load "Hard Disks" section. */ @@ -2341,6 +2343,11 @@ save_storage_controllers(void) else ini_section_set_string(cat, temp, cart_fns[c]); } + + if (lba_enhancer_enabled == 0) + ini_section_delete_var(cat, "lba_enhancer_enabled"); + else + ini_section_set_int(cat, "lba_enhancer_enabled", 1); } /* Save "Other Peripherals" section. */ diff --git a/src/disk/CMakeLists.txt b/src/disk/CMakeLists.txt index 310354ccf..87b9593fa 100644 --- a/src/disk/CMakeLists.txt +++ b/src/disk/CMakeLists.txt @@ -16,7 +16,7 @@ add_library(hdd OBJECT hdd.c hdd_image.c hdd_table.c hdc.c hdc_st506_xt.c hdc_st506_at.c hdc_xta.c hdc_esdi_at.c hdc_esdi_mca.c hdc_xtide.c hdc_ide.c hdc_ide_ali5213.c hdc_ide_opti611.c hdc_ide_cmd640.c hdc_ide_cmd646.c - hdc_ide_sff8038i.c hdc_ide_um8673f.c hdc_ide_w83769f.c) + hdc_ide_sff8038i.c hdc_ide_um8673f.c hdc_ide_w83769f.c lba_enhancer.c) add_library(zip OBJECT zip.c) diff --git a/src/disk/lba_enhancer.c b/src/disk/lba_enhancer.c new file mode 100644 index 000000000..07b958b2e --- /dev/null +++ b/src/disk/lba_enhancer.c @@ -0,0 +1,97 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Vision Systems LBA Enhancer emulation. + * + * + * + * Authors: Cacodemon345 + * + * Copyright 2024 Cacodemon345 + */ + +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/plat_unused.h> + +typedef struct lba_enhancer_t +{ + rom_t rom; +} lba_enhancer_t; + +#define BIOS_LBA_ENHANCER "roms/hdd/misc/lbaenhancer.bin" + +void* lba_enhancer_init(const device_t* info) +{ + lba_enhancer_t* lba_enhancer = (lba_enhancer_t*)calloc(1, sizeof(lba_enhancer_t)); + + rom_init(&lba_enhancer->rom, BIOS_LBA_ENHANCER, device_get_config_hex20("bios_addr"), 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + return lba_enhancer; +} + +void lba_enhancer_close(void* priv) +{ + lba_enhancer_t* lba_enhancer = (lba_enhancer_t*)priv; + + free(lba_enhancer->rom.rom); + free(priv); + return; +} + +static int +lba_enhancer_available(void) +{ + return rom_present(BIOS_LBA_ENHANCER); +} + +// clang-format off +static const device_config_t lba_enhancer_config[] = { + { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = "", + .default_int = 0xc8000, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "C800H", .value = 0xc8000 }, + { .description = "CC00H", .value = 0xcc000 }, + { .description = "D000H", .value = 0xd0000 }, + { .description = "D400H", .value = 0xd4000 }, + { .description = "D800H", .value = 0xd8000 }, + { .description = "DC00H", .value = 0xdc000 }, + { .description = "" } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + +const device_t lba_enhancer_device = { + .name = "Vision Systems LBA Enhancer", + .internal_name = "lba_enhancer", + .flags = DEVICE_AT, + .local = 0, + .init = lba_enhancer_init, + .close = lba_enhancer_close, + .reset = NULL, + { .available = lba_enhancer_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = lba_enhancer_config +}; diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index 20f3fffcc..d44e3b007 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -140,6 +140,7 @@ extern int fpu_type; /* (C) fpu type */ extern int fpu_softfloat; /* (C) fpu uses softfloat */ extern int time_sync; /* (C) enable time sync */ extern int hdd_format_type; /* (C) hard disk file format */ +extern int lba_enhancer_enabled; /* (C) enable Vision Systems LBA Enhancer */ extern int confirm_reset; /* (C) enable reset confirmation */ extern int confirm_exit; /* (C) enable exit confirmation */ extern int confirm_save; /* (C) enable save confirmation */ diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h index 4f65399bb..38c0a6e9a 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -103,6 +103,9 @@ extern const device_t xtide_at_device; /* xtide_at */ extern const device_t xtide_acculogic_device; /* xtide_ps2 */ extern const device_t xtide_at_ps2_device; /* xtide_at_ps2 */ +/* Miscellaneous */ +extern const device_t lba_enhancer_device; + extern void hdc_init(void); extern void hdc_reset(void); diff --git a/src/qt/qt_settingsstoragecontrollers.cpp b/src/qt/qt_settingsstoragecontrollers.cpp index 30949de3a..0f19d46fc 100644 --- a/src/qt/qt_settingsstoragecontrollers.cpp +++ b/src/qt/qt_settingsstoragecontrollers.cpp @@ -62,6 +62,7 @@ SettingsStorageControllers::save() ide_ter_enabled = ui->checkBoxTertiaryIDE->isChecked() ? 1 : 0; ide_qua_enabled = ui->checkBoxQuaternaryIDE->isChecked() ? 1 : 0; cassette_enable = ui->checkBoxCassette->isChecked() ? 1 : 0; + lba_enhancer_enabled = ui->checkBoxLbaEnhancer->isChecked() ? 1 : 0; } void @@ -204,6 +205,9 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId) ui->checkBoxCassette->setChecked(false); ui->checkBoxCassette->setEnabled(false); } + + ui->checkBoxLbaEnhancer->setChecked(lba_enhancer_enabled > 0 && device_available(&lba_enhancer_device)); + ui->pushButtonConfigureLbaEnhancer->setEnabled(ui->checkBoxLbaEnhancer->isChecked()); } void @@ -333,3 +337,15 @@ SettingsStorageControllers::on_pushButtonSCSI4_clicked() { DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI4->currentData().toInt()), 4, qobject_cast(Settings::settings)); } + +void SettingsStorageControllers::on_checkBoxLbaEnhancer_stateChanged(int arg1) +{ + ui->pushButtonConfigureLbaEnhancer->setEnabled(arg1 != 0); +} + + +void SettingsStorageControllers::on_pushButtonConfigureLbaEnhancer_clicked() +{ + DeviceConfig::ConfigureDevice(&lba_enhancer_device); +} + diff --git a/src/qt/qt_settingsstoragecontrollers.hpp b/src/qt/qt_settingsstoragecontrollers.hpp index 5641889e4..c50a94574 100644 --- a/src/qt/qt_settingsstoragecontrollers.hpp +++ b/src/qt/qt_settingsstoragecontrollers.hpp @@ -39,6 +39,10 @@ private slots: void on_comboBoxHD_currentIndexChanged(int index); void on_comboBoxCDInterface_currentIndexChanged(int index); + void on_checkBoxLbaEnhancer_stateChanged(int arg1); + + void on_pushButtonConfigureLbaEnhancer_clicked(); + private: Ui::SettingsStorageControllers *ui; int machineId = 0; diff --git a/src/qt/qt_settingsstoragecontrollers.ui b/src/qt/qt_settingsstoragecontrollers.ui index d67127e2d..16d6e2494 100644 --- a/src/qt/qt_settingsstoragecontrollers.ui +++ b/src/qt/qt_settingsstoragecontrollers.ui @@ -51,45 +51,45 @@ - - CD-ROM Controller: - false + + CD-ROM Controller: + - - 30 - false + + 30 + - - Configure - false + + Configure + - - 30 - 0 0 + + 30 + @@ -171,15 +171,15 @@ - - 30 - 0 0 + + 30 + @@ -191,41 +191,41 @@ - - 30 - 0 0 + + 30 + - - 30 - 0 0 + + 30 + - - 30 - 0 0 + + 30 + @@ -266,6 +266,43 @@ + + + + 0 + + + 0 + + + + + Vision Systems LBA Enhancer + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Configure + + + + + From 7c241ec64adb10fb346bed58fd6b33648c90ddef Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 6 Mar 2024 22:49:58 +0100 Subject: [PATCH 630/936] Hyundai SUPER-16T: Increase maximum CPU speed to 8 MHz. --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index da3dc01e4..d620357d6 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -807,7 +807,7 @@ const machine_t machines[] = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, .min_bus = 4772728, - .max_bus = 7159092, + .max_bus = 8000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, From 3e6b4aa9e198dbca29fa5437a66e97e4fc0258e2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 6 Mar 2024 22:51:24 +0100 Subject: [PATCH 631/936] S3 Trio64V+ VLB: Limit to a maximum of 2 MB video memory. --- src/video/vid_s3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index fe06f05f5..a971c2f65 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -11093,7 +11093,7 @@ const device_t s3_stb_powergraph_64_video_vlb_device = { { .available = s3_stb_powergraph_64_video_available }, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, - .config = s3_standard_config + .config = s3_phoenix_trio32_config }; const device_t s3_phoenix_trio64vplus_onboard_pci_device = { From 2e10c5a870b6c3221b40c7b43d20aecffde128bf Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Thu, 7 Mar 2024 18:20:55 +0500 Subject: [PATCH 632/936] CMake: Move DirectInput backend option to Win32 UI --- CMakeLists.txt | 1 - src/qt/CMakeLists.txt | 8 +------- src/win/CMakeLists.txt | 1 + 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cacf1aaa4..ae39fbccf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,7 +131,6 @@ option(RTMIDI "RtMidi" option(FLUIDSYNTH "FluidSynth" ON) option(MUNT "MUNT" ON) option(VNC "VNC renderer" OFF) -option(DINPUT "DirectInput" OFF) option(CPPTHREADS "C++11 threads" ON) option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF) option(MINITRACE "Enable Chrome tracing using the modified minitrace library" OFF) diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 4f073cf4a..23c5964b3 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -190,13 +190,7 @@ endif() if(WIN32) enable_language(RC) target_sources(86Box PUBLIC ../win/86Box-qt.rc) - target_sources(plat PRIVATE win_dynld.c) - if(DINPUT) - target_sources(plat PRIVATE win_joystick.cpp) - target_link_libraries(86Box dinput8) - else() - target_sources(plat PRIVATE win_joystick_rawinput.c) - endif() + target_sources(plat PRIVATE win_dynld.c win_joystick_rawinput.c) target_link_libraries(86Box hid) # CMake 3.22 messed this up for clang/clang++ diff --git a/src/win/CMakeLists.txt b/src/win/CMakeLists.txt index 604ba9bb0..dc8c53e45 100644 --- a/src/win/CMakeLists.txt +++ b/src/win/CMakeLists.txt @@ -51,6 +51,7 @@ if(NOT MINGW) target_sources(plat PRIVATE win_opendir.c) endif() +option(DINPUT "Use DirectInput joystick backend instead of raw input" OFF) if(DINPUT) target_sources(plat PRIVATE win_joystick.cpp) target_link_libraries(86Box dinput8) From 1019953ba5907255d3b314d99602c15d4410a430 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Thu, 7 Mar 2024 23:10:38 +0500 Subject: [PATCH 633/936] Add an option to build with SDL joystick backend on Windows --- src/qt/CMakeLists.txt | 12 +++- src/qt/{sdl_joystick.cpp => sdl_joystick.c} | 62 ++++++++++++++++----- 2 files changed, 57 insertions(+), 17 deletions(-) rename src/qt/{sdl_joystick.cpp => sdl_joystick.c} (76%) diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 23c5964b3..5dc6f8a07 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -190,8 +190,7 @@ endif() if(WIN32) enable_language(RC) target_sources(86Box PUBLIC ../win/86Box-qt.rc) - target_sources(plat PRIVATE win_dynld.c win_joystick_rawinput.c) - target_link_libraries(86Box hid) + target_sources(plat PRIVATE win_dynld.c) # CMake 3.22 messed this up for clang/clang++ # See https://gitlab.kitware.com/cmake/cmake/-/issues/22611 @@ -206,8 +205,15 @@ if(WIN32) if (MINGW) add_compile_definitions(NTDDI_VERSION=0x06010000) endif() + + option(SDL_JOYSTICK "Use SDL2 joystick backend instead of raw input" OFF) +endif() + +if(WIN32 AND NOT SDL_JOYSTICK) + target_sources(plat PRIVATE win_joystick_rawinput.c) + target_link_libraries(86Box hid) else() - target_sources(plat PRIVATE sdl_joystick.cpp) + target_sources(plat PRIVATE sdl_joystick.c) endif() if(WIN32 AND NOT MINGW) diff --git a/src/qt/sdl_joystick.cpp b/src/qt/sdl_joystick.c similarity index 76% rename from src/qt/sdl_joystick.cpp rename to src/qt/sdl_joystick.c index 4437bb696..d56612872 100644 --- a/src/qt/sdl_joystick.cpp +++ b/src/qt/sdl_joystick.c @@ -1,28 +1,53 @@ -// Lifted from wx-sdl2-joystick.c in PCem - +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * SDL2 joystick interface. + * + * + * + * Authors: Sarah Walker, + * Joakim L. Gilje + * + * Copyright 2017-2021 Sarah Walker + * Copyright 2021 Joakim L. Gilje + */ #include -#include - -extern "C" { +#include +#include +#include +#include +#include +#define _USE_MATH_DEFINES +#include +/* This #undef is needed because a SDL include header redefines HAVE_STDARG_H. */ +#undef HAVE_STDARG_H +#define HAVE_STDARG_H +#include <86box/86box.h> #include <86box/device.h> #include <86box/gameport.h> +#include <86box/plat_unused.h> int joysticks_present; joystick_t joystick_state[MAX_JOYSTICKS]; plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; static SDL_Joystick *sdl_joy[MAX_PLAT_JOYSTICKS]; -} - -#include #ifndef M_PI # define M_PI 3.14159265358979323846 #endif void -joystick_init() +joystick_init(void) { + /* This is needed for SDL's Windows raw input backend to work properly without SDL video. */ + SDL_SetHint(SDL_HINT_JOYSTICK_THREAD, "1"); + if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) { return; } @@ -36,9 +61,9 @@ joystick_init() int d; strncpy(plat_joystick_state[c].name, SDL_JoystickNameForIndex(c), 64); - plat_joystick_state[c].nr_axes = std::min(SDL_JoystickNumAxes(sdl_joy[c]), MAX_JOY_AXES); - plat_joystick_state[c].nr_buttons = std::min(SDL_JoystickNumButtons(sdl_joy[c]), MAX_JOY_BUTTONS); - plat_joystick_state[c].nr_povs = std::min(SDL_JoystickNumHats(sdl_joy[c]), MAX_JOY_POVS); + plat_joystick_state[c].nr_axes = MIN(SDL_JoystickNumAxes(sdl_joy[c]), MAX_JOY_AXES); + plat_joystick_state[c].nr_buttons = MIN(SDL_JoystickNumButtons(sdl_joy[c]), MAX_JOY_BUTTONS); + plat_joystick_state[c].nr_povs = MIN(SDL_JoystickNumHats(sdl_joy[c]), MAX_JOY_POVS); for (d = 0; d < plat_joystick_state[c].nr_axes; d++) { snprintf(plat_joystick_state[c].axis[d].name, sizeof(plat_joystick_state[c].axis[d].name), "Axis %i", d); @@ -57,7 +82,7 @@ joystick_init() } void -joystick_close() +joystick_close(void) { int c; @@ -103,8 +128,9 @@ joystick_get_axis(int joystick_nr, int mapping) } else return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; } + void -joystick_process() +joystick_process(void) { int c; int d; @@ -160,3 +186,11 @@ joystick_process() } } } + +#ifdef _WIN32 +void +win_joystick_handle(UNUSED(void *raw)) +{ + /* Nothing to be done here, atleast currently */ +} +#endif From 9488078c5ab8c3c76878809fcb49698f7a08212b Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 8 Mar 2024 16:45:17 +0600 Subject: [PATCH 634/936] Work-In-Progress modem emulation --- src/86box.c | 7 +- src/device/serial.c | 40 +++ src/include/86box/serial.h | 8 + src/network/CMakeLists.txt | 2 +- src/network/net_modem.c | 706 +++++++++++++++++++++++++++++++++++++ 5 files changed, 759 insertions(+), 4 deletions(-) create mode 100644 src/network/net_modem.c diff --git a/src/86box.c b/src/86box.c index ca0f8b0ff..9cdb5f4e5 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1168,13 +1168,14 @@ pc_reset_hard_init(void) /* note: PLIP LPT side has to be initialized before the network side */ lpt_devices_init(); - /* Reset and reconfigure the Network Card layer. */ - network_reset(); - /* Reset and reconfigure the serial ports. */ + /* note: SLIP COM side has to be initialized before the network side */ serial_standalone_init(); serial_passthrough_init(); + /* Reset and reconfigure the Network Card layer. */ + network_reset(); + /* * Reset the mouse, this will attach it to any port needed. */ diff --git a/src/device/serial.c b/src/device/serial.c index dcdffb71c..0ef959cdd 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -432,6 +432,25 @@ serial_set_dcd(serial_t *dev, uint8_t enabled) } } +void +serial_set_ri(serial_t *dev, uint8_t enabled) +{ + uint8_t prev_state = !!(dev->msr & 0x40); + if (dev->mctrl & 0x10) + return; + + dev->msr &= ~0x40; + dev->msr |= (!!enabled) << 6; + dev->msr_set &= ~0x40; + dev->msr_set |= (!!enabled) << 6; + + if (prev_state == 0 && (!!enabled) == 1) { + dev->msr |= 0x4; + dev->int_status |= SERIAL_INT_MSR; + serial_update_ints(dev); + } +} + void serial_set_clock_src(serial_t *dev, double clock_src) { @@ -570,6 +589,8 @@ serial_write(uint16_t addr, uint8_t val, void *priv) serial_do_irq(dev, 0); if ((val ^ dev->mctrl) & 0x10) serial_reset_fifo(dev); + if (dev->sd && dev->sd->dtr_callback) + dev->sd->dtr_callback(dev, val, dev->sd->priv); dev->mctrl = val; if (val & 0x10) { new_msr = (val & 0x0c) << 4; @@ -797,6 +818,25 @@ serial_attach_ex(int port, return sd->serial; } +serial_t * +serial_attach_ex_2(int port, + void (*rcr_callback)(struct serial_s *serial, void *priv), + void (*dev_write)(struct serial_s *serial, void *priv, uint8_t data), + void (*dtr_callback)(struct serial_s *serial, int status, void *priv), + void *priv) +{ + serial_device_t *sd = &serial_devices[port]; + + sd->rcr_callback = rcr_callback; + sd->dtr_callback = dtr_callback; + sd->dev_write = dev_write; + sd->transmit_period_callback = NULL; + sd->lcr_callback = NULL; + sd->priv = priv; + + return sd->serial; +} + static void serial_speed_changed(void *priv) { diff --git a/src/include/86box/serial.h b/src/include/86box/serial.h index 08f77ea13..99b39f56b 100644 --- a/src/include/86box/serial.h +++ b/src/include/86box/serial.h @@ -92,6 +92,7 @@ typedef struct serial_s { typedef struct serial_device_s { void (*rcr_callback)(struct serial_s *serial, void *priv); + void (*dtr_callback)(struct serial_s *serial, int status, void *priv); void (*dev_write)(struct serial_s *serial, void *priv, uint8_t data); void (*lcr_callback)(struct serial_s *serial, void *priv, uint8_t lcr); void (*transmit_period_callback)(struct serial_s *serial, void *priv, double transmit_period); @@ -112,6 +113,12 @@ extern serial_t *serial_attach_ex(int port, void (*lcr_callback)(struct serial_s *serial, void *priv, uint8_t data_bits), void *priv); +extern serial_t *serial_attach_ex_2(int port, + void (*rcr_callback)(struct serial_s *serial, void *priv), + void (*dev_write)(struct serial_s *serial, void *priv, uint8_t data), + void (*dtr_callback)(struct serial_s *serial, int status, void *priv), + void *priv); + #define serial_attach(port, rcr_callback, dev_write, priv) \ serial_attach_ex(port, rcr_callback, dev_write, NULL, NULL, priv); @@ -129,6 +136,7 @@ extern void serial_device_timeout(void *priv); extern void serial_set_cts(serial_t *dev, uint8_t enabled); extern void serial_set_dsr(serial_t *dev, uint8_t enabled); extern void serial_set_dcd(serial_t *dev, uint8_t enabled); +extern void serial_set_ri(serial_t *dev, uint8_t enabled); extern const device_t ns8250_device; extern const device_t ns8250_pcjr_device; diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index b0ba913d5..5eb091d58 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -15,7 +15,7 @@ set(net_sources) list(APPEND net_sources network.c net_pcap.c net_slirp.c net_dp8390.c net_3c501.c net_3c503.c net_ne2000.c net_pcnet.c net_wd8003.c net_plip.c net_event.c net_null.c - net_eeprom_nmc93cxx.c net_tulip.c net_rtl8139.c net_l80225.c) + net_eeprom_nmc93cxx.c net_tulip.c net_rtl8139.c net_l80225.c net_modem.c) find_package(PkgConfig REQUIRED) pkg_check_modules(SLIRP REQUIRED IMPORTED_TARGET slirp) diff --git a/src/network/net_modem.c b/src/network/net_modem.c new file mode 100644 index 000000000..0137aa9bb --- /dev/null +++ b/src/network/net_modem.c @@ -0,0 +1,706 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/thread.h> +#include <86box/fifo.h> +#include <86box/fifo8.h> +#include <86box/timer.h> +#include <86box/serial.h> +#include <86box/network.h> +#include <86box/plat_unused.h> + +/* From RFC 1055. */ +#define END 0300 /* indicates end of packet */ +#define ESC 0333 /* indicates byte stuffing */ +#define ESC_END 0334 /* ESC ESC_END means END data byte */ +#define ESC_ESC 0335 /* ESC ESC_ESC means ESC data byte */ + +typedef enum ResTypes { + ResNONE, + ResOK, + ResERROR, + ResCONNECT, + ResRING, + ResBUSY, + ResNODIALTONE, + ResNOCARRIER, + ResNOANSWER +} ResTypes; + +enum modem_types +{ + MODEM_TYPE_SLIP = 1, + MODEM_TYPE_PPP = 2, + MODEM_TYPE_TCPIP = 3 +}; + +typedef enum modem_mode_t +{ + MODEM_MODE_COMMAND = 0, + MODEM_MODE_DATA = 1 +} modem_mode_t; + +typedef struct modem_t +{ + uint8_t mac[6]; + serial_t *serial; + double baudrate; + + modem_mode_t mode; + + uint8_t esc_character_expected; + pc_timer_t host_to_serial_timer; + pc_timer_t dtr_timer; + + uint8_t tx_pkt_ser_line[0x10000]; /* SLIP-encoded. */ + uint32_t tx_count; + + Fifo8 rx_data; /* Data received from the network. */ + uint8_t reg[100]; + + Fifo8 data_pending; /* Data yet to be sent to the host. */ + + char cmdbuf[512]; + uint32_t cmdpos; + int plusinc, flowcontrol; + int in_warmup; + + bool connected, ringing; + bool echo, numericresponse; + + int doresponse; + + netcard_t *card; +} modem_t; + +static modem_t *instance; + +#define MREG_AUTOANSWER_COUNT 0 +#define MREG_RING_COUNT 1 +#define MREG_ESCAPE_CHAR 2 +#define MREG_CR_CHAR 3 +#define MREG_LF_CHAR 4 +#define MREG_BACKSPACE_CHAR 5 +#define MREG_GUARD_TIME 12 +#define MREG_DTR_DELAY 25 + +static uint32_t +modem_scan_number(char **scan) +{ + char c = 0; + uint32_t ret = 0; + while (1) { + c = **scan; + if (c == 0) + break; + if (c >= '0' && c <= '9') { + ret*=10; + ret+=c-'0'; + *scan = *scan + 1; + } else + break; + } + return ret; +} + +static uint8_t +modem_fetch_character(char **scan) +{ + uint8_t c = **scan; + *scan = *scan + 1; + return c; +} + +static void +modem_speed_changed(void *priv) +{ + modem_t *dev = (modem_t *) priv; + if (!dev) + return; + + timer_stop(&dev->host_to_serial_timer); + /* FIXME: do something to dev->baudrate */ + timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / dev->baudrate) * 9); +#if 0 + serial_clear_fifo(dev->serial); +#endif +} + +static void +modem_send_line(modem_t* modem, const char* line) +{ + fifo8_push(&modem->data_pending, modem->reg[MREG_CR_CHAR]); + fifo8_push(&modem->data_pending, modem->reg[MREG_LF_CHAR]); + fifo8_push_all(&modem->data_pending, (uint8_t*)line, strlen(line)); + fifo8_push(&modem->data_pending, modem->reg[MREG_CR_CHAR]); + fifo8_push(&modem->data_pending, modem->reg[MREG_LF_CHAR]); +} + + +static void +modem_send_number(modem_t* modem, uint32_t val) +{ + fifo8_push(&modem->data_pending, modem->reg[MREG_CR_CHAR]); + fifo8_push(&modem->data_pending, modem->reg[MREG_LF_CHAR]); + + fifo8_push(&modem->data_pending, val / 100 + '0'); + val = val%100; + fifo8_push(&modem->data_pending, val / 10 + '0'); + val = val%10; + fifo8_push(&modem->data_pending, val + '0'); + + fifo8_push(&modem->data_pending, modem->reg[MREG_CR_CHAR]); + fifo8_push(&modem->data_pending, modem->reg[MREG_LF_CHAR]); +} + +static void +process_tx_packet(modem_t *modem, uint8_t *p, uint32_t len) +{ + int received = 0; + uint32_t pos = 0; + uint8_t *processed_tx_packet = calloc(len, 1); + uint8_t c = 0; + + while (pos < len) { + c = p[pos]; + pos++; + switch (c) { + case END: + if (received) + goto send_tx_packet; + else + break; + + case ESC: + { + c = p[pos]; + pos++; + + switch (c) { + case ESC_END: + c = END; + break; + case ESC_ESC: + c = ESC; + break; + } + } + + default: + if (received < len) + processed_tx_packet[received++] = c; + break; + } + } + +send_tx_packet: + network_tx(modem->card, processed_tx_packet, received); + return; +} + +static void +modem_data_mode_process_byte(modem_t* modem, uint8_t data) +{ + if (modem->reg[MREG_ESCAPE_CHAR] <= 127) { + if (modem->reg[MREG_ESCAPE_CHAR] == data) { + return; + } + } + + if (data == END) { + process_tx_packet(modem, modem->tx_pkt_ser_line, (uint32_t)modem->tx_count + 1ul); + } + else if (modem->tx_count < 0x10000) + modem->tx_pkt_ser_line[modem->tx_count++] = data; +} + +static void +host_to_modem_cb(void *priv) +{ + modem_t* modem = (modem_t*)priv; + + if ((modem->serial->type >= SERIAL_16550) && modem->serial->fifo_enabled) { + if (fifo_get_full(modem->serial->rcvr_fifo)) { + goto no_write_to_machine; + } + } else { + if (modem->serial->lsr & 1) { + goto no_write_to_machine; + } + } + + if (modem->mode == MODEM_MODE_DATA && fifo8_num_used(&modem->rx_data)) { + serial_write_fifo(modem->serial, fifo8_pop(&modem->rx_data)); + } else if (fifo8_num_used(&modem->data_pending)) { + serial_write_fifo(modem->serial, fifo8_pop(&modem->data_pending)); + } + +no_write_to_machine: + timer_on_auto(&modem->host_to_serial_timer, (1000000.0 / modem->baudrate) * (double)9); +} + +static void +modem_write(UNUSED(serial_t *s), void *priv, uint8_t val) +{ + modem_t* modem = (modem_t*)priv; +} + +void modem_send_res(modem_t* modem, const ResTypes response) { + const char* response_str = NULL; + uint32_t code = -1; + switch (response) { + case ResOK: code = 0; response_str = "OK"; break; + case ResCONNECT: code = 1; response_str = "CONNECT 33600"; break; + case ResRING: code = 2; response_str = "RING"; break; + case ResNOCARRIER: code = 3; response_str = "NO CARRIER"; break; + case ResERROR: code = 4; response_str = "ERROR"; break; + case ResNODIALTONE: code = 6; response_str = "NO DIALTONE"; break; + case ResBUSY: code = 7; response_str = "BUSY"; break; + case ResNOANSWER: code = 8; response_str = "NO ANSWER"; break; + case ResNONE: return; + } + + if (modem->doresponse != 1) { + if (modem->doresponse == 2 && (response == ResRING || + response == ResCONNECT || response == ResNOCARRIER)) { + return; + } + if (modem->numericresponse && code != ~0) { + modem_send_number(modem, code); + } else if (response_str != NULL) { + modem_send_line(modem, response_str); + } + + // if(CSerial::CanReceiveByte()) // very fast response + // if(rqueue->inuse() && CSerial::getRTS()) + // { uint8_t rbyte =rqueue->getb(); + // CSerial::receiveByte(rbyte); + // LOG_MSG("SERIAL: Port %" PRIu8 " modem sending byte %2x back to UART2", + // GetPortNumber(), rbyte); + // } + } +} + +void +modem_enter_idle_state(modem_t* modem) +{ + timer_disable(&modem->dtr_timer); + modem->connected = false; + modem->ringing = false; + modem->mode = MODEM_MODE_COMMAND; + modem->in_warmup = 0; + serial_set_cts(modem->serial, 1); + serial_set_dsr(modem->serial, 1); + serial_set_dcd(modem->serial, 0); + serial_set_ri(modem->serial, 0); +} + +void +modem_enter_connected_state(modem_t* modem) +{ + modem_send_res(modem, ResCONNECT); + modem->mode = MODEM_MODE_DATA; + modem->ringing = false; + modem->connected = true; + serial_set_dcd(modem->serial, 1); + serial_set_ri(modem->serial, 0); +} + +void +modem_reset(modem_t* modem) +{ + modem_enter_idle_state(modem); + modem->cmdpos = 0; + modem->cmdbuf[0] = 0; + modem->flowcontrol = 0; + modem->plusinc = 0; + + memset(&modem->reg,0,sizeof(modem->reg)); + modem->reg[MREG_AUTOANSWER_COUNT] = 0; // no autoanswer + modem->reg[MREG_RING_COUNT] = 1; + modem->reg[MREG_ESCAPE_CHAR] = '+'; + modem->reg[MREG_CR_CHAR] = '\r'; + modem->reg[MREG_LF_CHAR] = '\n'; + modem->reg[MREG_BACKSPACE_CHAR] = '\b'; + modem->reg[MREG_GUARD_TIME] = 50; + modem->reg[MREG_DTR_DELAY] = 5; + + modem->echo = true; + modem->doresponse = 0; + modem->numericresponse = false; +} + +void +modem_dial(modem_t* modem, const char* str) +{ + /* TODO: Port TCP/IP support from DOSBox. */ + if (!strncmp(str, "0.0.0.0", sizeof("0.0.0.0") - 1)) { + modem_enter_connected_state(modem); + } else { + modem_send_res(modem, ResNOCARRIER); + modem_enter_idle_state(modem); + } +} + +static bool +is_next_token(const char* a, size_t N, const char *b) +{ + // Is 'b' at least as long as 'a'? + size_t N_without_null = N - 1; + if (strnlen(b, N) < N_without_null) + return false; + return (strncmp(a, b, N_without_null) == 0); +} + +// https://stackoverflow.com/a/122974 +char *trim(char *str) +{ + size_t len = 0; + char *frontp = str; + char *endp = NULL; + + if( str == NULL ) { return NULL; } + if( str[0] == '\0' ) { return str; } + + len = strlen(str); + endp = str + len; + + /* Move the front and back pointers to address the first non-whitespace + * characters from each end. + */ + while( isspace((unsigned char) *frontp) ) { ++frontp; } + if( endp != frontp ) + { + while( isspace((unsigned char) *(--endp)) && endp != frontp ) {} + } + + if( frontp != str && endp == frontp ) + *str = '\0'; + else if( str + len - 1 != endp ) + *(endp + 1) = '\0'; + + /* Shift the string so that it starts at str so that if it's dynamically + * allocated, we can still free it on the returned pointer. Note the reuse + * of endp to mean the front of the string buffer now. + */ + endp = str; + if( frontp != str ) + { + while( *frontp ) { *endp++ = *frontp++; } + *endp = '\0'; + } + + return str; +} + +static void +modem_do_command(modem_t* modem) +{ + int i = 0; + char *scanbuf = NULL; + modem->cmdbuf[modem->cmdpos] = 0; + modem->cmdpos = 0; + for (i = 0; i < sizeof(modem->cmdbuf); i++) { + modem->cmdbuf[i] = toupper(modem->cmdbuf[i]); + } + + /* AT command set interpretation */ + if ((modem->cmdbuf[0] != 'A') || (modem->cmdbuf[1] != 'T')) { + modem_send_res(modem, ResERROR); + return; + } + + scanbuf = &modem->cmdbuf[2]; + + while (1) { + char chr = modem_fetch_character(&scanbuf); + switch (chr) { + case '+': + /* None supported yet. */ + modem_send_res(modem, ResERROR); + return; + case 'D': { // Dial. + char buffer[128]; + char obuffer[128]; + char * foundstr = &scanbuf[0]; + size_t i = 0; + if (*foundstr == 'T' || *foundstr == 'P') + foundstr++; + + if ((!foundstr[0]) || (strlen(foundstr) > 253)) { + modem_send_res(modem, ResERROR); + return; + } + + foundstr = trim(foundstr); + if (strlen(foundstr) >= 12) { + // Check if supplied parameter only consists of digits + bool isNum = true; + size_t fl = strlen(foundstr); + for (i = 0; i < fl; i++) + if (foundstr[i] < '0' || foundstr[i] > '9') + isNum = false; + if (isNum) { + // Parameter is a number with at least 12 digits => this cannot + // be a valid IP/name + // Transform by adding dots + size_t j = 0; + const size_t foundlen = strlen(foundstr); + for (i = 0; i < foundlen; i++) { + buffer[j++] = foundstr[i]; + // Add a dot after the third, sixth and ninth number + if (i == 2 || i == 5 || i == 8) + buffer[j++] = '.'; + // If the string is longer than 12 digits, + // interpret the rest as port + if (i == 11 && foundlen > 12) + buffer[j++] = ':'; + } + buffer[j] = 0; + foundstr = buffer; + + // Remove Zeros from beginning of octets + size_t k = 0; + size_t foundlen2 = strlen(foundstr); + for (i = 0; i < foundlen2; i++) { + if (i == 0 && foundstr[0] == '0') continue; + if (i == 1 && foundstr[0] == '0' && foundstr[1] == '0') continue; + if (foundstr[i] == '0' && foundstr[i-1] == '.') continue; + if (foundstr[i] == '0' && foundstr[i-1] == '0' && foundstr[i-2] == '.') continue; + obuffer[k++] = foundstr[i]; + } + obuffer[k] = 0; + foundstr = obuffer; + } + } + modem_dial(modem, foundstr); + } + case 'I': // Some strings about firmware + switch (modem_scan_number(&scanbuf)) { + case 3: modem_send_line(modem, "86Box Emulated Modem Firmware V1.00"); break; + case 4: modem_send_line(modem, "Modem compiled for 86Box"); break; + } + break; + case 'E': // Echo on/off + switch (modem_scan_number(&scanbuf)) { + case 0: modem->echo = false; break; + case 1: modem->echo = true; break; + } + break; + case 'V': + switch (modem_scan_number(&scanbuf)) { + case 0: modem->numericresponse = true; break; + case 1: modem->numericresponse = false; break; + } + break; + case 'H': // Hang up + switch (modem_scan_number(&scanbuf)) { + case 0: + if (modem->connected) { + modem_send_res(modem, ResNOCARRIER); + modem_enter_idle_state(modem); + return; + } + // else return ok + } + break; + case 'O': // Return to data mode + switch (modem_scan_number(&scanbuf)) { + case 0: + if (modem->connected) { + modem->mode = MODEM_MODE_DATA; + return; + } else { + modem_send_res(modem, ResERROR); + return; + } + } + break; + case 'T': // Tone Dial + case 'P': // Pulse Dial + break; + case 'M': // Monitor + case 'L': // Volume + modem_scan_number(&scanbuf); + break; + case 'A': // Answer call + { + modem_send_res(modem, ResERROR); + return; + } + return; + case 'Z': { // Reset and load profiles + // scan the number away, if any + modem_scan_number(&scanbuf); + if (modem->connected) + modem_send_res(modem, ResNOCARRIER); + modem_reset(modem); + break; + } + case ' ': // skip space + break; + case 'Q': { + // Response options + // 0 = all on, 1 = all off, + // 2 = no ring and no connect/carrier in answermode + const uint32_t val = modem_scan_number(&scanbuf); + if (!(val > 2)) { + modem->doresponse = val; + break; + } else { + modem_send_res(modem, ResERROR); + return; + } + } + } + } +} + +void +modem_dtr_callback(serial_t* serial, int status, void *priv) +{ + modem_t *dev = (modem_t *) priv; + if (status == 1) + timer_disable(&dev->dtr_timer); + else if (!timer_is_enabled(&dev->dtr_timer)) + timer_enable(&dev->dtr_timer); +} + +static void +fifo8_resize_2x(Fifo8* fifo) +{ + uint32_t pos = 0; + uint32_t size = fifo->capacity * 2; + uint32_t used = fifo8_num_used(fifo); + if (!used) + return; + + uint8_t* temp_buf = calloc(fifo->capacity * 2, 1); + if (!temp_buf) { + fatal("net_modem: Out Of Memory!\n"); + } + while (!fifo8_is_empty(fifo)) { + temp_buf[pos] = fifo8_pop(fifo); + pos++; + } + pos = 0; + fifo8_destroy(fifo); + fifo8_create(fifo, size); + fifo8_push_all(fifo, temp_buf, used); + free(temp_buf); +} + + +static int +modem_rx(void *priv, uint8_t *buf, int io_len) +{ + modem_t* modem = (modem_t*)priv; + uint8_t c = 0; + uint32_t i = 0; + + if ((io_len) < (fifo8_num_free(&modem->rx_data) / 2)) { + fifo8_resize_2x(&modem->rx_data); + } + + fifo8_push(&modem->rx_data, END); + for (i = 0; i < io_len; i++) { + switch (buf[i]) { + case END: + fifo8_push(&modem->rx_data, ESC); + fifo8_push(&modem->rx_data, ESC_END); + break; + case ESC: + fifo8_push(&modem->rx_data, ESC); + fifo8_push(&modem->rx_data, ESC_ESC); + break; + default: + fifo8_push(&modem->rx_data, buf[i]); + break; + } + } + fifo8_push(&modem->rx_data, END); + return 1; +} + +static void +modem_rcr_cb(UNUSED(struct serial_s *serial), void *priv) +{ + modem_t *dev = (modem_t *) priv; + + timer_stop(&dev->host_to_serial_timer); + /* FIXME: do something to dev->baudrate */ + timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / dev->baudrate) * (double) 9); +#if 0 + serial_clear_fifo(dev->serial); +#endif +} + +/* Initialize the device for use by the user. */ +static void * +modem_init(const device_t *info) +{ + modem_t* modem = (modem_t*)calloc(1, sizeof(modem_t)); + memset(modem->mac, 0xfc, 6); + + modem->card = network_attach(instance, instance->mac, modem_rx, NULL); + return modem; +} + +void modem_close(void *priv) +{ + free(priv); +} + +static const device_config_t modem_config[] = { + { + .name = "baudrate", + .description = "Baud Rate", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 115200, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { +#if 0 + { .description = "256000", .value = 256000 }, + { .description = "128000", .value = 128000 }, +#endif + { .description = "115200", .value = 115200 }, + { .description = "57600", .value = 57600 }, + { .description = "56000", .value = 56000 }, + { .description = "38400", .value = 38400 }, + { .description = "19200", .value = 19200 }, + { .description = "14400", .value = 14400 }, + { .description = "9600", .value = 9600 }, + { .description = "7200", .value = 7200 }, + { .description = "4800", .value = 4800 }, + { .description = "2400", .value = 2400 }, + { .description = "1800", .value = 1800 }, + { .description = "1200", .value = 1200 }, + { .description = "600", .value = 600 }, + { .description = "300", .value = 300 }, + } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +const device_t modem_device = { + .name = "Standard Hayes-compliant Modem", + .flags = 0, + .local = 0, + .init = modem_init, + .close = modem_close, + .reset = NULL, + { .poll = NULL }, + .speed_changed = modem_speed_changed, + .force_redraw = NULL, + .config = modem_config +}; From ec8b8f2a920657e2fe9490a6d0bd148057c1b3fc Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 9 Mar 2024 01:37:13 +0600 Subject: [PATCH 635/936] Somewhat finish initial modem emulation --- src/device/serial.c | 4 +- src/include/86box/network.h | 3 + src/network/net_modem.c | 265 +++++++++++++++++++++++++++++++++--- src/network/network.c | 1 + 4 files changed, 252 insertions(+), 21 deletions(-) diff --git a/src/device/serial.c b/src/device/serial.c index 0ef959cdd..b61c8304a 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -589,8 +589,8 @@ serial_write(uint16_t addr, uint8_t val, void *priv) serial_do_irq(dev, 0); if ((val ^ dev->mctrl) & 0x10) serial_reset_fifo(dev); - if (dev->sd && dev->sd->dtr_callback) - dev->sd->dtr_callback(dev, val, dev->sd->priv); + if (dev->sd && dev->sd->dtr_callback && (val ^ dev->mctrl) & 1) + dev->sd->dtr_callback(dev, val & 1, dev->sd->priv); dev->mctrl = val; if (val & 0x10) { new_msr = (val & 0x0c) << 4; diff --git a/src/include/86box/network.h b/src/include/86box/network.h index d0af3f09b..9588de86a 100644 --- a/src/include/86box/network.h +++ b/src/include/86box/network.h @@ -225,6 +225,9 @@ extern const device_t pcnet_am79c970a_device; extern const device_t pcnet_am79c973_device; extern const device_t pcnet_am79c973_onboard_device; +/* Modem */ +extern const device_t modem_device; + /* PLIP */ #ifdef EMU_LPT_H extern const lpt_device_t lpt_plip_device; diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 0137aa9bb..4127158bd 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -52,13 +52,14 @@ typedef struct modem_t { uint8_t mac[6]; serial_t *serial; - double baudrate; + uint32_t baudrate; modem_mode_t mode; uint8_t esc_character_expected; pc_timer_t host_to_serial_timer; pc_timer_t dtr_timer; + pc_timer_t cmdpause_timer; uint8_t tx_pkt_ser_line[0x10000]; /* SLIP-encoded. */ uint32_t tx_count; @@ -70,13 +71,25 @@ typedef struct modem_t char cmdbuf[512]; uint32_t cmdpos; + uint32_t port; int plusinc, flowcontrol; - int in_warmup; + int in_warmup, dtrmode; bool connected, ringing; bool echo, numericresponse; int doresponse; + int cmdpause; + + struct { + bool binary[2]; + bool echo[2]; + bool supressGA[2]; + bool timingMark[2]; + bool inIAC; + bool recCommand; + uint8_t command; + } telClient; netcard_t *card; } modem_t; @@ -92,6 +105,14 @@ static modem_t *instance; #define MREG_GUARD_TIME 12 #define MREG_DTR_DELAY 25 +static void modem_do_command(modem_t* modem); + +static void +modem_echo(modem_t* modem, uint8_t c) +{ + if (modem->echo && fifo8_num_free(&modem->data_pending)) fifo8_push(&modem->data_pending, c); +} + static uint32_t modem_scan_number(char **scan) { @@ -128,7 +149,7 @@ modem_speed_changed(void *priv) timer_stop(&dev->host_to_serial_timer); /* FIXME: do something to dev->baudrate */ - timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / dev->baudrate) * 9); + timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / (double)dev->baudrate) * 9); #if 0 serial_clear_fifo(dev->serial); #endif @@ -210,16 +231,20 @@ static void modem_data_mode_process_byte(modem_t* modem, uint8_t data) { if (modem->reg[MREG_ESCAPE_CHAR] <= 127) { - if (modem->reg[MREG_ESCAPE_CHAR] == data) { - return; + if (modem->plusinc >= 1 && modem->plusinc <= 3 && modem->reg[MREG_ESCAPE_CHAR] == data) { + modem->plusinc++; + } else { + modem->plusinc = 0; } } - if (data == END) { - process_tx_packet(modem, modem->tx_pkt_ser_line, (uint32_t)modem->tx_count + 1ul); - } - else if (modem->tx_count < 0x10000) + if (modem->tx_count < 0x10000 && modem->connected) { modem->tx_pkt_ser_line[modem->tx_count++] = data; + if (data == END) { + process_tx_packet(modem, modem->tx_pkt_ser_line, (uint32_t)modem->tx_count); + modem->tx_count = 0; + } + } } static void @@ -237,6 +262,9 @@ host_to_modem_cb(void *priv) } } + if (!((modem->serial->mctrl & 2) || modem->flowcontrol != 3)) + goto no_write_to_machine; + if (modem->mode == MODEM_MODE_DATA && fifo8_num_used(&modem->rx_data)) { serial_write_fifo(modem->serial, fifo8_pop(&modem->rx_data)); } else if (fifo8_num_used(&modem->data_pending)) { @@ -244,13 +272,55 @@ host_to_modem_cb(void *priv) } no_write_to_machine: - timer_on_auto(&modem->host_to_serial_timer, (1000000.0 / modem->baudrate) * (double)9); + timer_on_auto(&modem->host_to_serial_timer, (1000000.0 / (double)modem->baudrate) * (double)9); } static void -modem_write(UNUSED(serial_t *s), void *priv, uint8_t val) +modem_write(UNUSED(serial_t *s), void *priv, uint8_t txval) { modem_t* modem = (modem_t*)priv; + + if (modem->mode == MODEM_MODE_COMMAND) { + if (modem->cmdpos < 2) { + // Ignore everything until we see "AT" sequence. + if (modem->cmdpos == 0 && toupper(txval) != 'A') { + return; + } + + if (modem->cmdpos == 1 && toupper(txval) != 'T') { + modem_echo(modem, modem->reg[MREG_BACKSPACE_CHAR]); + modem->cmdpos = 0; + return; + } + } else { + // Now entering command. + if (txval == modem->reg[MREG_BACKSPACE_CHAR]) { + if (modem->cmdpos > 2) { + modem_echo(modem, txval); + modem->cmdpos--; + } + return; + } + + if (txval == modem->reg[MREG_LF_CHAR]) { + return; // Real modem doesn't seem to skip this? + } + + if (txval == modem->reg[MREG_CR_CHAR]) { + modem_echo(modem, txval); + modem_do_command(modem); + return; + } + + if (modem->cmdpos < 99) { + modem_echo(modem, txval); + modem->cmdbuf[modem->cmdpos] = txval; + modem->cmdpos++; + } + } + } else { + modem_data_mode_process_byte(modem, txval); + } } void modem_send_res(modem_t* modem, const ResTypes response) { @@ -310,6 +380,7 @@ modem_enter_connected_state(modem_t* modem) modem->mode = MODEM_MODE_DATA; modem->ringing = false; modem->connected = true; + memset(&modem->telClient, 0, sizeof(modem->telClient)); serial_set_dcd(modem->serial, 1); serial_set_ri(modem->serial, 0); } @@ -322,6 +393,7 @@ modem_reset(modem_t* modem) modem->cmdbuf[0] = 0; modem->flowcontrol = 0; modem->plusinc = 0; + modem->dtrmode = 2; memset(&modem->reg,0,sizeof(modem->reg)); modem->reg[MREG_AUTOANSWER_COUNT] = 0; // no autoanswer @@ -560,6 +632,107 @@ modem_do_command(modem_t* modem) return; } } + + case 'S': { // Registers + const uint32_t index = modem_scan_number(&scanbuf); + if (index >= 100) { + modem_send_res(modem, ResERROR); + return; //goto ret_none; + } + + while (scanbuf[0] == ' ') + scanbuf++; // skip spaces + + if (scanbuf[0] == '=') { // set register + scanbuf++; + while (scanbuf[0] == ' ') + scanbuf++; // skip spaces + const uint32_t val = modem_scan_number(&scanbuf); + modem->reg[index] = val; + break; + } + else if (scanbuf[0] == '?') { // get register + modem_send_number(modem, modem->reg[index]); + scanbuf++; + break; + } + // else + // LOG_MSG("SERIAL: Port %" PRIu8 " print reg %" PRIu32 + // " with %" PRIu8 ".", + // GetPortNumber(), index, reg[index]); + } + break; + case '&': { // & escaped commands + char cmdchar = modem_fetch_character(&scanbuf); + switch(cmdchar) { + case 'K': { + const uint32_t val = modem_scan_number(&scanbuf); + if (val < 5) + modem->flowcontrol = val; + else { + modem_send_res(modem, ResERROR); + return; + } + break; + } + case 'D': { + const uint32_t val = modem_scan_number(&scanbuf); + if (val < 4) + modem->dtrmode = val; + else { + modem_send_res(modem, ResERROR); + return; + } + break; + } + case '\0': + // end of string + modem_send_res(modem, ResERROR); + return; + } + break; + } + case '\\': { // \ escaped commands + char cmdchar = modem_fetch_character(&scanbuf); + switch (cmdchar) { + case 'N': + // error correction stuff - not emulated + if (modem_scan_number(&scanbuf) > 5) { + modem_send_res(modem, ResERROR); + return; + } + break; + case '\0': + // end of string + modem_send_res(modem, ResERROR); + return; + } + break; + } + case '\0': + modem_send_res(modem, ResOK); + return; + } + } +} + +void +modem_dtr_callback_timer(void* priv) +{ + modem_t *dev = (modem_t *) priv; + if (dev->connected) { + switch (dev->dtrmode) { + case 1: + dev->mode = MODEM_MODE_COMMAND; + break; + case 2: + modem_send_res(dev, ResNOCARRIER); + modem_enter_idle_state(dev); + break; + case 3: + modem_send_res(dev, ResNOCARRIER); + modem_reset(dev); + break; } } } @@ -571,7 +744,7 @@ modem_dtr_callback(serial_t* serial, int status, void *priv) if (status == 1) timer_disable(&dev->dtr_timer); else if (!timer_is_enabled(&dev->dtr_timer)) - timer_enable(&dev->dtr_timer); + timer_on_auto(&dev->dtr_timer, 1000000); } static void @@ -606,7 +779,12 @@ modem_rx(void *priv, uint8_t *buf, int io_len) uint8_t c = 0; uint32_t i = 0; - if ((io_len) < (fifo8_num_free(&modem->rx_data) / 2)) { + if (!modem->connected) { + /* Drop packet. */ + return 0; + } + + if ((io_len) <= (fifo8_num_free(&modem->rx_data) / 2)) { fifo8_resize_2x(&modem->rx_data); } @@ -637,12 +815,31 @@ modem_rcr_cb(UNUSED(struct serial_s *serial), void *priv) timer_stop(&dev->host_to_serial_timer); /* FIXME: do something to dev->baudrate */ - timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / dev->baudrate) * (double) 9); + timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / (double)dev->baudrate) * (double) 9); #if 0 serial_clear_fifo(dev->serial); #endif } +static void +modem_cmdpause_timer_callback(void *priv) +{ + modem_t *dev = (modem_t *) priv; + uint32_t guard_threashold = 0; + + dev->cmdpause++; + guard_threashold = (uint32_t)(dev->reg[MREG_GUARD_TIME] * 20); + if (dev->cmdpause > guard_threashold) { + if (dev->plusinc == 0) { + dev->plusinc = 1; + } else if (dev->plusinc == 4) { + dev->mode = MODEM_MODE_COMMAND; + modem_send_res(dev, ResOK); + dev->plusinc = 0; + } + } +} + /* Initialize the device for use by the user. */ static void * modem_init(const device_t *info) @@ -650,16 +847,50 @@ modem_init(const device_t *info) modem_t* modem = (modem_t*)calloc(1, sizeof(modem_t)); memset(modem->mac, 0xfc, 6); + + modem->port = device_get_config_int("port"); + modem->baudrate = device_get_config_int("baudrate"); + + fifo8_create(&modem->data_pending, 0x10000); + fifo8_create(&modem->rx_data, 0x10000); + + timer_add(&modem->dtr_timer, modem_dtr_callback_timer, modem, 0); + timer_add(&modem->host_to_serial_timer, host_to_modem_cb, modem, 0); + timer_add(&modem->cmdpause_timer, modem_cmdpause_timer_callback, modem, 0); + timer_on_auto(&modem->cmdpause_timer, 1000); + modem->serial = serial_attach_ex_2(modem->port, modem_rcr_cb, modem_write, modem_dtr_callback, modem); + + modem_reset(modem); modem->card = network_attach(instance, instance->mac, modem_rx, NULL); return modem; } void modem_close(void *priv) { + modem_t* modem = (modem_t*)priv; + fifo8_destroy(&modem->data_pending); + fifo8_destroy(&modem->rx_data); + netcard_close(modem->card); free(priv); } static const device_config_t modem_config[] = { + { + .name = "port", + .description = "Serial Port", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "COM1", .value = 0 }, + { .description = "COM2", .value = 1 }, + { .description = "COM3", .value = 2 }, + { .description = "COM4", .value = 3 }, + { .description = "" } + } + }, { .name = "baudrate", .description = "Baud Rate", @@ -669,10 +900,6 @@ static const device_config_t modem_config[] = { .file_filter = NULL, .spinner = { 0 }, .selection = { -#if 0 - { .description = "256000", .value = 256000 }, - { .description = "128000", .value = 128000 }, -#endif { .description = "115200", .value = 115200 }, { .description = "57600", .value = 57600 }, { .description = "56000", .value = 56000 }, @@ -694,7 +921,7 @@ static const device_config_t modem_config[] = { const device_t modem_device = { .name = "Standard Hayes-compliant Modem", - .flags = 0, + .flags = DEVICE_COM, .local = 0, .init = modem_init, .close = modem_close, diff --git a/src/network/network.c b/src/network/network.c index 9eb537e3a..94403c2f4 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -136,6 +136,7 @@ static const device_t *net_cards[] = { &dec_tulip_21140_vpc_device, &dec_tulip_21040_device, &pcnet_am79c960_vlb_device, + &modem_device, NULL }; From a45d26807001c208b0d44c01867645a3ce5a4dda Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 8 Mar 2024 22:36:48 +0100 Subject: [PATCH 636/936] LBA Enhancer: Coding style. --- src/disk/lba_enhancer.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/disk/lba_enhancer.c b/src/disk/lba_enhancer.c index 07b958b2e..f0ce6b700 100644 --- a/src/disk/lba_enhancer.c +++ b/src/disk/lba_enhancer.c @@ -30,25 +30,29 @@ typedef struct lba_enhancer_t { - rom_t rom; + rom_t rom; } lba_enhancer_t; #define BIOS_LBA_ENHANCER "roms/hdd/misc/lbaenhancer.bin" -void* lba_enhancer_init(const device_t* info) +void * +lba_enhancer_init(const device_t *info) { - lba_enhancer_t* lba_enhancer = (lba_enhancer_t*)calloc(1, sizeof(lba_enhancer_t)); + lba_enhancer_t *lba_enhancer = (lba_enhancer_t *) calloc(1, sizeof(lba_enhancer_t)); + + rom_init(&lba_enhancer->rom, BIOS_LBA_ENHANCER, + device_get_config_hex20("bios_addr"), 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - rom_init(&lba_enhancer->rom, BIOS_LBA_ENHANCER, device_get_config_hex20("bios_addr"), 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); return lba_enhancer; } -void lba_enhancer_close(void* priv) +void +lba_enhancer_close(void* priv) { - lba_enhancer_t* lba_enhancer = (lba_enhancer_t*)priv; + lba_enhancer_t *lba_enhancer = (lba_enhancer_t *) priv; - free(lba_enhancer->rom.rom); free(priv); + return; } From 01d066ce4c48173e03009d5f917495993240d2b6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 8 Mar 2024 22:37:18 +0100 Subject: [PATCH 637/936] MiniVHD: Some initialization sanitizations. --- src/disk/hdd_image.c | 4 +- src/disk/minivhd/create.c | 2 +- src/disk/minivhd/manage.c | 39 ++++------ src/disk/minivhd/minivhd_io.c | 133 ++++++++++++++++---------------- src/disk/minivhd/minivhd_util.c | 4 +- 5 files changed, 85 insertions(+), 97 deletions(-) diff --git a/src/disk/hdd_image.c b/src/disk/hdd_image.c index df473d7d9..db56d5b78 100644 --- a/src/disk/hdd_image.c +++ b/src/disk/hdd_image.c @@ -327,7 +327,7 @@ hdd_image_load(int id) hdd_images[id].type = HDD_IMAGE_HDX; } else if (is_vhd[0]) { fclose(hdd_images[id].file); - MVHDGeom geometry; + MVHDGeom geometry = { 0 }; geometry.cyl = hdd[id].tracks; geometry.heads = hdd[id].hpc; geometry.spt = hdd[id].spt; @@ -335,7 +335,7 @@ hdd_image_load(int id) hdd_images[id].last_sector = (full_size >> 9LL) - 1; if (hdd[id].vhd_blocksize || hdd[id].vhd_parent[0]) { - MVHDCreationOptions options; + MVHDCreationOptions options = { 0 }; retry_vhd: options.block_size_in_sectors = hdd[id].vhd_blocksize; options.path = fn; diff --git a/src/disk/minivhd/create.c b/src/disk/minivhd/create.c index d06382ef9..1fcfc8682 100644 --- a/src/disk/minivhd/create.c +++ b/src/disk/minivhd/create.c @@ -315,7 +315,7 @@ create_sparse_diff(const char* path, const char* par_path, uint64_t size_in_byte { uint8_t footer_buff[MVHD_FOOTER_SIZE] = {0}; uint8_t sparse_buff[MVHD_SPARSE_SIZE] = {0}; - uint8_t bat_sect[MVHD_SECTOR_SIZE]; + uint8_t bat_sect[MVHD_SECTOR_SIZE] = {0}; MVHDGeom par_geom = {0}; memset(bat_sect, 0xffffffff, sizeof bat_sect); MVHDMeta* vhdm = NULL; diff --git a/src/disk/minivhd/manage.c b/src/disk/minivhd/manage.c index 7ac3989e6..fdf3d8e79 100644 --- a/src/disk/minivhd/manage.c +++ b/src/disk/minivhd/manage.c @@ -92,7 +92,7 @@ read_footer(MVHDMeta* vhdm) static void read_sparse_header(MVHDMeta* vhdm) { - uint8_t buffer[MVHD_SPARSE_SIZE]; + uint8_t buffer[MVHD_SPARSE_SIZE] = { 0 }; mvhd_fseeko64(vhdm->f, vhdm->footer.data_offset, SEEK_SET); (void) !fread(buffer, sizeof buffer, 1, vhdm->f); @@ -438,17 +438,15 @@ mvhd_version_id(void) MVHDAPI int mvhd_file_is_vhd(FILE* f) { - uint8_t con_str[8]; + uint8_t con_str[8] = { 0 }; - if (f == NULL) { + if (f == NULL) return 0; - } mvhd_fseeko64(f, -MVHD_FOOTER_SIZE, SEEK_END); (void) !fread(con_str, sizeof con_str, 1, f); - if (mvhd_is_conectix_str(con_str)) { + if (mvhd_is_conectix_str(con_str)) return 1; - } return 0; } @@ -457,13 +455,12 @@ mvhd_file_is_vhd(FILE* f) MVHDAPI MVHDGeom mvhd_calculate_geometry(uint64_t size) { - MVHDGeom chs; + MVHDGeom chs = { 0 }; uint32_t ts = (uint32_t)(size / MVHD_SECTOR_SIZE); uint32_t spt, heads, cyl, cth; - if (ts > 65535 * 16 * 255) { + if (ts > 65535 * 16 * 255) ts = 65535 * 16 * 255; - } if (ts >= 65535 * 16 * 63) { spt = 255; @@ -473,9 +470,8 @@ mvhd_calculate_geometry(uint64_t size) spt = 17; cth = ts / spt; heads = (cth + 1023) / 1024; - if (heads < 4) { + if (heads < 4) heads = 4; - } if (cth >= (heads * 1024) || heads > 16) { spt = 31; heads = 16; @@ -500,7 +496,7 @@ mvhd_calculate_geometry(uint64_t size) MVHDAPI MVHDMeta* mvhd_open(const char* path, int readonly, int* err) { - MVHDError open_err; + MVHDError open_err = { 0 }; MVHDMeta *vhdm = calloc(sizeof *vhdm, 1); if (vhdm == NULL) { @@ -516,11 +512,10 @@ mvhd_open(const char* path, int readonly, int* err) //This is safe, as we've just checked for potential overflow above strcpy(vhdm->filename, path); - if (readonly) { + if (readonly) vhdm->f = mvhd_fopen((const char*)vhdm->filename, "rb", err); - } else { + else vhdm->f = mvhd_fopen((const char*)vhdm->filename, "rb+", err); - } if (vhdm->f == NULL) { /* note, mvhd_fopen sets err for us */ goto cleanup_vhdm; @@ -567,14 +562,12 @@ mvhd_open(const char* path, int readonly, int* err) vhdm->format_buffer.sector_count = 64; if (vhdm->footer.disk_type == MVHD_TYPE_DIFF) { char* par_path = get_diff_parent_path(vhdm, err); - if (par_path == NULL) { + if (par_path == NULL) goto cleanup_format_buff; - } uint32_t par_mod_ts = mvhd_file_mod_timestamp(par_path, err); - if (*err != 0) { + if (*err != 0) goto cleanup_format_buff; - } if (vhdm->sparse.par_timestamp != par_mod_ts) { /* The last-modified timestamp is to fragile to make this a fatal error. @@ -582,9 +575,8 @@ mvhd_open(const char* path, int readonly, int* err) *err = MVHD_ERR_TIMESTAMP; } vhdm->parent = mvhd_open(par_path, true, err); - if (vhdm->parent == NULL) { + if (vhdm->parent == NULL) goto cleanup_format_buff; - } if (memcmp(vhdm->sparse.par_uuid, vhdm->parent->footer.uuid, sizeof vhdm->sparse.par_uuid) != 0) { *err = MVHD_ERR_INVALID_PAR_UUID; @@ -629,9 +621,8 @@ mvhd_close(MVHDMeta* vhdm) if (vhdm == NULL) return; - if (vhdm->parent != NULL) { + if (vhdm->parent != NULL) mvhd_close(vhdm->parent); - } fclose(vhdm->f); @@ -655,7 +646,7 @@ mvhd_close(MVHDMeta* vhdm) MVHDAPI int mvhd_diff_update_par_timestamp(MVHDMeta* vhdm, int* err) { - uint8_t sparse_buff[1024]; + uint8_t sparse_buff[1024] = { 0 }; if (vhdm == NULL || err == NULL) { *err = MVHD_ERR_INVALID_PARAMS; diff --git a/src/disk/minivhd/minivhd_io.c b/src/disk/minivhd/minivhd_io.c index ff86a8337..2912cf5b2 100644 --- a/src/disk/minivhd/minivhd_io.c +++ b/src/disk/minivhd/minivhd_io.c @@ -46,7 +46,6 @@ #include "minivhd.h" #include "internal.h" - /* * The following bit array macros adapted from: * @@ -56,7 +55,6 @@ #define VHD_CLEARBIT(A,k) ( A[(k>>3)] &= ~(0x80 >> (k&7)) ) #define VHD_TESTBIT(A,k) ( A[(k>>3)] & (0x80 >> (k&7)) ) - /** * \brief Check that we will not be overflowing buffers * @@ -68,29 +66,26 @@ * \param [out] trunc_sectors The number of sectors truncated if transfer_sectors < num_sectors */ static inline void -check_sectors(uint32_t offset, int num_sectors, uint32_t total_sectors, int* transfer_sect, int* trunc_sect) +check_sectors(uint32_t offset, int num_sectors, uint32_t total_sectors, int *transfer_sect, int *trunc_sect) { *transfer_sect = num_sectors; *trunc_sect = 0; - if ((total_sectors - offset) < (uint32_t)*transfer_sect) { + if ((total_sectors - offset) < ((uint32_t) *transfer_sect)) { *transfer_sect = total_sectors - offset; *trunc_sect = num_sectors - *transfer_sect; } } - void -mvhd_write_empty_sectors(FILE* f, int sector_count) +mvhd_write_empty_sectors(FILE *f, int sector_count) { uint8_t zero_bytes[MVHD_SECTOR_SIZE] = {0}; - for (int i = 0; i < sector_count; i++) { + for (int i = 0; i < sector_count; i++) fwrite(zero_bytes, sizeof zero_bytes, 1, f); - } } - /** * \brief Read the sector bitmap for a block. * @@ -101,19 +96,17 @@ mvhd_write_empty_sectors(FILE* f, int sector_count) * \param [in] blk The block for which to read the sector bitmap from */ static void -read_sect_bitmap(MVHDMeta* vhdm, int blk) +read_sect_bitmap(MVHDMeta *vhdm, int blk) { if (vhdm->block_offset[blk] != MVHD_SPARSE_BLK) { mvhd_fseeko64(vhdm->f, (uint64_t)vhdm->block_offset[blk] * MVHD_SECTOR_SIZE, SEEK_SET); (void) !fread(vhdm->bitmap.curr_bitmap, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE, 1, vhdm->f); - } else { + } else memset(vhdm->bitmap.curr_bitmap, 0, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE); - } vhdm->bitmap.curr_block = blk; } - /** * \brief Write the current sector bitmap in memory to file * @@ -129,7 +122,6 @@ write_curr_sect_bitmap(MVHDMeta* vhdm) } } - /** * \brief Write block offset from memory into file * @@ -137,7 +129,7 @@ write_curr_sect_bitmap(MVHDMeta* vhdm) * \param [in] blk The block for which to write the offset for */ static void -write_bat_entry(MVHDMeta* vhdm, int blk) +write_bat_entry(MVHDMeta *vhdm, int blk) { uint64_t table_offset = vhdm->sparse.bat_offset + ((uint64_t)blk * sizeof *vhdm->block_offset); uint32_t offset = mvhd_to_be32(vhdm->block_offset[blk]); @@ -146,7 +138,6 @@ write_bat_entry(MVHDMeta* vhdm, int blk) fwrite(&offset, sizeof offset, 1, vhdm->f); } - /** * \brief Create an empty block in a sparse or differencing VHD image * @@ -162,9 +153,9 @@ write_bat_entry(MVHDMeta* vhdm, int blk) * \param [in] blk The block number to create */ static void -create_block(MVHDMeta* vhdm, int blk) +create_block(MVHDMeta *vhdm, int blk) { - uint8_t footer[MVHD_FOOTER_SIZE]; + uint8_t footer[MVHD_FOOTER_SIZE] = { 0 }; /* Seek to where the footer SHOULD be */ mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_END); @@ -179,13 +170,12 @@ create_block(MVHDMeta* vhdm, int blk) } int64_t abs_offset = mvhd_ftello64(vhdm->f); - if (abs_offset % MVHD_SECTOR_SIZE != 0) { + if ((abs_offset % MVHD_SECTOR_SIZE) != 0) { /* Yikes! We're supposed to be on a sector boundary. Add some padding */ - int64_t padding_amount = (int64_t)MVHD_SECTOR_SIZE - (abs_offset % MVHD_SECTOR_SIZE); + int64_t padding_amount = ((int64_t) MVHD_SECTOR_SIZE) - (abs_offset % MVHD_SECTOR_SIZE); uint8_t zero_byte = 0; - for (int i = 0; i < padding_amount; i++) { + for (int i = 0; i < padding_amount; i++) fwrite(&zero_byte, sizeof zero_byte, 1, vhdm->f); - } abs_offset += padding_amount; } @@ -204,37 +194,39 @@ create_block(MVHDMeta* vhdm, int blk) write_bat_entry(vhdm, blk); } - int -mvhd_fixed_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff) { - int64_t addr; - int transfer_sectors, truncated_sectors; +mvhd_fixed_read(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *out_buff) { + int64_t addr = 0ULL; + int transfer_sectors = 0; + int truncated_sectors = 0; uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); - addr = (int64_t)offset * MVHD_SECTOR_SIZE; + addr = ((int64_t) offset) * MVHD_SECTOR_SIZE; mvhd_fseeko64(vhdm->f, addr, SEEK_SET); - (void) !fread(out_buff, transfer_sectors*MVHD_SECTOR_SIZE, 1, vhdm->f); + (void) !fread(out_buff, transfer_sectors * MVHD_SECTOR_SIZE, 1, vhdm->f); return truncated_sectors; } - int -mvhd_sparse_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff) +mvhd_sparse_read(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *out_buff) { - int transfer_sectors, truncated_sectors; + int transfer_sectors = 0; + int truncated_sectors; uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); uint8_t* buff = (uint8_t*)out_buff; - int64_t addr; - uint32_t s, ls; - int blk, prev_blk, sib; + int64_t addr = 0ULL; + uint32_t s = 0; + uint32_t ls = 0; + int blk = 0; + int prev_blk = -1; + int sib = 0; ls = offset + transfer_sectors; - prev_blk = -1; for (s = offset; s < ls; s++) { blk = s / vhdm->sect_per_block; @@ -245,14 +237,15 @@ mvhd_sparse_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buf read_sect_bitmap(vhdm, blk); mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR); } else { - addr = ((int64_t)vhdm->block_offset[blk] + vhdm->bitmap.sector_count + sib) * MVHD_SECTOR_SIZE; + addr = (((int64_t) vhdm->block_offset[blk]) + vhdm->bitmap.sector_count + sib) * + MVHD_SECTOR_SIZE; mvhd_fseeko64(vhdm->f, addr, SEEK_SET); } } - if (VHD_TESTBIT(vhdm->bitmap.curr_bitmap, sib)) { + if (VHD_TESTBIT(vhdm->bitmap.curr_bitmap, sib)) (void) !fread(buff, MVHD_SECTOR_SIZE, 1, vhdm->f); - } else { + else { memset(buff, 0, MVHD_SECTOR_SIZE); mvhd_fseeko64(vhdm->f, MVHD_SECTOR_SIZE, SEEK_CUR); } @@ -262,19 +255,21 @@ mvhd_sparse_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buf return truncated_sectors; } - int -mvhd_diff_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff) +mvhd_diff_read(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *out_buff) { - int transfer_sectors, truncated_sectors; + int transfer_sectors = 0; + int truncated_sectors = 0; uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); - uint8_t* buff = (uint8_t*)out_buff; - MVHDMeta* curr_vhdm = vhdm; - uint32_t s, ls; - int blk, sib; + uint8_t *buff = (uint8_t*)out_buff; + MVHDMeta *curr_vhdm = vhdm; + uint32_t s = 0; + uint32_t ls = 0; + int blk = 0; + int sib = 0; ls = offset + transfer_sectors; for (s = offset; s < ls; s++) { @@ -291,11 +286,11 @@ mvhd_diff_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff) /* We handle actual sector reading using the fixed or sparse functions, as a differencing VHD is also a sparse VHD */ - if (curr_vhdm->footer.disk_type == MVHD_TYPE_DIFF || curr_vhdm->footer.disk_type == MVHD_TYPE_DYNAMIC) { + if ((curr_vhdm->footer.disk_type == MVHD_TYPE_DIFF) || + (curr_vhdm->footer.disk_type == MVHD_TYPE_DYNAMIC)) mvhd_sparse_read(curr_vhdm, s, 1, buff); - } else { + else mvhd_fixed_read(curr_vhdm, s, 1, buff); - } curr_vhdm = vhdm; buff += MVHD_SECTOR_SIZE; @@ -304,38 +299,40 @@ mvhd_diff_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff) return truncated_sectors; } - int -mvhd_fixed_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff) +mvhd_fixed_write(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *in_buff) { - int64_t addr; - int transfer_sectors, truncated_sectors; + int64_t addr = 0ULL; + int transfer_sectors = 0; + int truncated_sectors = 0; uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); addr = (int64_t)offset * MVHD_SECTOR_SIZE; mvhd_fseeko64(vhdm->f, addr, SEEK_SET); - fwrite(in_buff, transfer_sectors*MVHD_SECTOR_SIZE, 1, vhdm->f); + fwrite(in_buff, transfer_sectors * MVHD_SECTOR_SIZE, 1, vhdm->f); return truncated_sectors; } - int -mvhd_sparse_diff_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff) +mvhd_sparse_diff_write(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *in_buff) { - int transfer_sectors, truncated_sectors; + int transfer_sectors = 0; + int truncated_sectors = 0; uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); - uint8_t* buff = (uint8_t*)in_buff; - int64_t addr; - uint32_t s, ls; - int blk, prev_blk, sib; + uint8_t* buff = (uint8_t *) in_buff; + int64_t addr = 0ULL; + uint32_t s = 0; + uint32_t ls = 0; + int blk = 0; + int prev_blk = -1; + int sib = 0; ls = offset + transfer_sectors; - prev_blk = -1; for (s = offset; s < ls; s++) { blk = s / vhdm->sect_per_block; @@ -357,7 +354,8 @@ mvhd_sparse_diff_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* i read_sect_bitmap(vhdm, blk); mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR); } else { - addr = ((int64_t)vhdm->block_offset[blk] + vhdm->bitmap.sector_count + sib) * MVHD_SECTOR_SIZE; + addr = (((int64_t) vhdm->block_offset[blk]) + vhdm->bitmap.sector_count + sib) * + MVHD_SECTOR_SIZE; mvhd_fseeko64(vhdm->f, addr, SEEK_SET); } prev_blk = blk; @@ -374,14 +372,13 @@ mvhd_sparse_diff_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* i return truncated_sectors; } - int -mvhd_noop_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff) +mvhd_noop_write(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *in_buff) { - (void)vhdm; - (void)offset; - (void)num_sectors; - (void)in_buff; + (void) vhdm; + (void) offset; + (void) num_sectors; + (void) in_buff; return 0; } diff --git a/src/disk/minivhd/minivhd_util.c b/src/disk/minivhd/minivhd_util.c index dd3244322..4901e5841 100644 --- a/src/disk/minivhd/minivhd_util.c +++ b/src/disk/minivhd/minivhd_util.c @@ -462,7 +462,7 @@ mvhd_file_mod_timestamp(const char* path, int *err) { *err = 0; #ifdef _WIN32 - struct _stat file_stat; + struct _stat file_stat = { 0 }; size_t path_len = strlen(path); mvhd_utf16 new_path[260] = {0}; int new_path_len = (sizeof new_path) - 2; @@ -485,7 +485,7 @@ mvhd_file_mod_timestamp(const char* path, int *err) return 0; } #else - struct stat file_stat; + struct stat file_stat = { 0 }; int stat_res = stat(path, &file_stat); if (stat_res != 0) { From 50d7340d01d664df8a38706e1f654eb35ed24f3a Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 8 Mar 2024 23:11:35 +0100 Subject: [PATCH 638/936] Added the 1.02 German and 1.03 English versions of the AHA-1542CP BIOS. --- src/scsi/scsi_aha154x.c | 62 +++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 12 deletions(-) diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index 05b8b2726..8ff0aaa32 100644 --- a/src/scsi/scsi_aha154x.c +++ b/src/scsi/scsi_aha154x.c @@ -70,6 +70,9 @@ uint16_t aha_ports[] = { static uint8_t *aha1542cp_pnp_rom = NULL; +// static char *aha1542cp_rev = "F001"; +static char aha1542cp_rev[16] = { 0 }; + #pragma pack(push, 1) typedef struct aha_setup_t { uint8_t CustomerSignature[20]; @@ -851,6 +854,9 @@ aha_setmcode(x54x_t *dev) return; } + fseek(fp, 0x3136, SEEK_SET); + (void) !fread(dev->fw_rev, 4, 1, fp); + /* Allocate the buffer and then read the real PnP ROM into it. */ if (aha1542cp_pnp_rom != NULL) { free(aha1542cp_pnp_rom); @@ -892,7 +898,7 @@ aha_initnvr(x54x_t *dev) EE2_EXT1G | EE2_RMVOK); /* Imm return on seek */ dev->nvr[3] = SPEED_50; /* speed 5.0 MB/s */ dev->nvr[6] = (EE6_TERM | /* host term enable */ - EE6_RSTBUS); /* reset SCSI bus on boot*/ + EE6_RSTBUS); /* reset SCSI bus on boot */ } /* Initialize the board's EEPROM (NVR.) */ @@ -942,6 +948,7 @@ static void * aha_init(const device_t *info) { x54x_t *dev; + const char *bios_rev = NULL; /* Call common initializer. */ dev = x54x_init(info); @@ -987,7 +994,8 @@ aha_init(const device_t *info) strcpy(dev->name, "AHA-154xA"); dev->fw_rev = "A003"; /* The 3.07 microcode says A006. */ dev->bios_path = "roms/scsi/adaptec/aha1540a307.bin"; /*Only for port 0x330*/ - /* This is configurable from the configuration for the 154xB, the rest of the controllers read it from the EEPROM. */ + /* This is configurable from the configuration for the 154xB, the rest of the controllers read + it from the EEPROM. */ dev->HostID = device_get_config_int("hostid"); dev->rom_shram = 0x3F80; /* shadow RAM address base */ dev->rom_shramsz = 128; /* size of shadow RAM */ @@ -1009,7 +1017,8 @@ aha_init(const device_t *info) break; } dev->fw_rev = "A005"; /* The 3.2 microcode says A012. */ - /* This is configurable from the configuration for the 154xB, the rest of the controllers read it from the EEPROM. */ + /* This is configurable from the configuration for the 154xB, the rest of the controllers read + it from the EEPROM. */ dev->HostID = device_get_config_int("hostid"); dev->rom_shram = 0x3F80; /* shadow RAM address base */ dev->rom_shramsz = 128; /* size of shadow RAM */ @@ -1053,10 +1062,11 @@ aha_init(const device_t *info) case AHA_154xCP: strcpy(dev->name, "AHA-154xCP"); - dev->bios_path = "roms/scsi/adaptec/aha1542cp102.bin"; - dev->mcode_path = "roms/scsi/adaptec/908301-00_f_mcode_17c9.u12"; + bios_rev = (char *) device_get_config_bios("bios_rev"); + dev->bios_path = (char *) device_get_bios_file(info, bios_rev, 0); + dev->mcode_path = (char *) device_get_bios_file(info, bios_rev, 1); dev->nvr_path = "aha1542cp.nvr"; - dev->fw_rev = "F001"; + dev->fw_rev = aha1542cp_rev; dev->rom_shram = 0x3F80; /* shadow RAM address base */ dev->rom_shramsz = 128; /* size of shadow RAM */ dev->rom_ioaddr = 0x3F7E; /* [2:0] idx into addr table */ @@ -1069,11 +1079,14 @@ aha_init(const device_t *info) dev->ven_get_dma = aha_get_dma; /* function to return DMA channel from EEPROM */ dev->ha_bps = 10000000.0; /* fast SCSI */ dev->pnp_len = 0x00be; /* length of the PnP ROM */ - dev->pnp_offset = 0x533d; /* offset of the PnP ROM in the microcode ROM */ - dev->cmd_33_len = 0x06dc; /* length of the SCSISelect code expansion routine returned by - SCSI controller command 0x33 */ - dev->cmd_33_offset = 0x7000; /* offset of the SCSISelect code expansion routine in the - microcode ROM */ + if (!strcmp(bios_rev, "v1_02_en")) + dev->pnp_offset = 0x533d; /* offset of the PnP ROM in the microcode ROM */ + else + dev->pnp_offset = 0x5345; /* offset of the PnP ROM in the microcode ROM */ + dev->cmd_33_len = 0x06dc; /* length of the SCSISelect code expansion routine + returned by SCSI controller command 0x33 */ + dev->cmd_33_offset = 0x7000; /* offset of the SCSISelect code expansion routine + in the microcode ROM */ aha_setmcode(dev); if (aha1542cp_pnp_rom) isapnp_add_card(aha1542cp_pnp_rom, dev->pnp_len + 7, aha_pnp_config_changed, NULL, NULL, NULL, dev); @@ -1384,6 +1397,31 @@ static const device_config_t aha_154xcf_config[] = { }, { .name = "", .description = "", .type = CONFIG_END } }; + +static const device_config_t aha_154xcp_config[] = { + { + .name = "bios_rev", + .description = "BIOS Revision", + .type = CONFIG_BIOS, + .default_string = "v1_02_en", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, /*W1*/ + .bios = { + { .name = "Version 1.02 (English)", .internal_name = "v1_02_en", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 32768, .files = { "roms/scsi/adaptec/aha1542cp102.bin", + "roms/scsi/adaptec/908301-00_f_mcode_17c9.u12", "" } }, + { .name = "Version 1.02 (German)", .internal_name = "v1_02_de", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 32768, .files = { "roms/scsi/adaptec/buff_1-0_bios.bin", + "roms/scsi/adaptec/buff_1-0_mcode.bin", "" } }, + { .name = "Version 1.03 (English)", .internal_name = "v1_03_en", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 32768, .files = { "roms/scsi/adaptec/aha1542cp103.bin", + "roms/scsi/adaptec/908301-00_g_mcode_144c.u12.bin", "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } +}; // clang-format on const device_t aha154xa_device = { @@ -1453,7 +1491,7 @@ const device_t aha154xcp_device = { { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, - .config = NULL + .config = aha_154xcp_config }; const device_t aha1640_device = { From 27734a872873739113b40e4d582cece686f74686 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 9 Mar 2024 00:42:13 +0100 Subject: [PATCH 639/936] AHA-1542CP: Return the correct firmware checksum. --- src/scsi/scsi_aha154x.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index 8ff0aaa32..2927d797c 100644 --- a/src/scsi/scsi_aha154x.c +++ b/src/scsi/scsi_aha154x.c @@ -73,6 +73,8 @@ static uint8_t *aha1542cp_pnp_rom = NULL; // static char *aha1542cp_rev = "F001"; static char aha1542cp_rev[16] = { 0 }; +static uint16_t fw_chksum = 0x0000; + #pragma pack(push, 1) typedef struct aha_setup_t { uint8_t CustomerSignature[20]; @@ -469,8 +471,10 @@ aha_setup_data(void *priv) ReplyISI->fParityCheckingEnabled = dev->parity & 1; U32_TO_ADDR(aha_setup->BIOSMailboxAddress, dev->BIOSMailboxOutAddr); - aha_setup->uChecksum = 0xA3; - aha_setup->uUnknown = 0xC2; + // aha_setup->uChecksum = 0xA3; + // aha_setup->uUnknown = 0xC2; + aha_setup->uChecksum = fw_chksum >> 8; + aha_setup->uUnknown = fw_chksum & 0xff; } static void @@ -825,6 +829,7 @@ aha_setmcode(x54x_t *dev) { uint32_t temp; FILE *fp; + uint16_t tempb = 0x00; /* Only if this device has a BIOS ROM. */ if (dev->mcode_path == NULL) @@ -880,6 +885,14 @@ aha_setmcode(x54x_t *dev) fseek(fp, dev->cmd_33_offset, SEEK_SET); (void) !fread(dev->cmd_33_buf, dev->cmd_33_len, 1, fp); + fw_chksum = 0x0000; + + for (uint16_t i = 0; i < 32768; i++) { + (void) fseek(fp, i, SEEK_SET); + (void) !fread(&tempb, 1, 1, fp); + fw_chksum += tempb; + } + (void) fclose(fp); } @@ -988,6 +1001,8 @@ aha_init(const device_t *info) strcpy(dev->vendor, "Adaptec"); + fw_chksum = 0xa3c2; + /* Perform per-board initialization. */ switch (dev->type) { case AHA_154xA: From b5db53368ff71b6ea4bfeeaf4180baa70b99f505 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 9 Mar 2024 14:58:12 +0600 Subject: [PATCH 640/936] Logging and crash fixes --- src/network/net_modem.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 4127158bd..b845896d3 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -268,7 +268,9 @@ host_to_modem_cb(void *priv) if (modem->mode == MODEM_MODE_DATA && fifo8_num_used(&modem->rx_data)) { serial_write_fifo(modem->serial, fifo8_pop(&modem->rx_data)); } else if (fifo8_num_used(&modem->data_pending)) { - serial_write_fifo(modem->serial, fifo8_pop(&modem->data_pending)); + uint8_t val = fifo8_pop(&modem->data_pending); + fprintf(stderr, "%c", val); + serial_write_fifo(modem->serial, val); } no_write_to_machine: @@ -281,6 +283,7 @@ modem_write(UNUSED(serial_t *s), void *priv, uint8_t txval) modem_t* modem = (modem_t*)priv; if (modem->mode == MODEM_MODE_COMMAND) { + fprintf(stderr, "%c", txval); if (modem->cmdpos < 2) { // Ignore everything until we see "AT" sequence. if (modem->cmdpos == 0 && toupper(txval) != 'A') { @@ -861,7 +864,7 @@ modem_init(const device_t *info) modem->serial = serial_attach_ex_2(modem->port, modem_rcr_cb, modem_write, modem_dtr_callback, modem); modem_reset(modem); - modem->card = network_attach(instance, instance->mac, modem_rx, NULL); + modem->card = network_attach(modem, modem->mac, modem_rx, NULL); return modem; } @@ -921,6 +924,7 @@ static const device_config_t modem_config[] = { const device_t modem_device = { .name = "Standard Hayes-compliant Modem", + .internal_name = "modem", .flags = DEVICE_COM, .local = 0, .init = modem_init, From af30550d946b097116143f440253410a71b3c601 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 9 Mar 2024 15:49:08 +0600 Subject: [PATCH 641/936] Fix command mode --- src/network/net_modem.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index b845896d3..97f038157 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -267,9 +267,9 @@ host_to_modem_cb(void *priv) if (modem->mode == MODEM_MODE_DATA && fifo8_num_used(&modem->rx_data)) { serial_write_fifo(modem->serial, fifo8_pop(&modem->rx_data)); + fprintf(stderr, "(data)\n"); } else if (fifo8_num_used(&modem->data_pending)) { uint8_t val = fifo8_pop(&modem->data_pending); - fprintf(stderr, "%c", val); serial_write_fifo(modem->serial, val); } @@ -283,7 +283,6 @@ modem_write(UNUSED(serial_t *s), void *priv, uint8_t txval) modem_t* modem = (modem_t*)priv; if (modem->mode == MODEM_MODE_COMMAND) { - fprintf(stderr, "%c", txval); if (modem->cmdpos < 2) { // Ignore everything until we see "AT" sequence. if (modem->cmdpos == 0 && toupper(txval) != 'A') { @@ -314,12 +313,12 @@ modem_write(UNUSED(serial_t *s), void *priv, uint8_t txval) modem_do_command(modem); return; } + } - if (modem->cmdpos < 99) { - modem_echo(modem, txval); - modem->cmdbuf[modem->cmdpos] = txval; - modem->cmdpos++; - } + if (modem->cmdpos < 99) { + modem_echo(modem, txval); + modem->cmdbuf[modem->cmdpos] = txval; + modem->cmdpos++; } } else { modem_data_mode_process_byte(modem, txval); @@ -493,6 +492,8 @@ modem_do_command(modem_t* modem) return; } + pclog("Command received: %s (doresponse = %d)\n", modem->cmdbuf, modem->doresponse); + scanbuf = &modem->cmdbuf[2]; while (1) { From 10c7ee2aeff940b7b19cf5c41b9fed7bd70d7788 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 9 Mar 2024 11:38:18 +0100 Subject: [PATCH 642/936] Fixed some warnings. --- src/codegen/codegen_ops_fpu.h | 3 ++- src/disk/lba_enhancer.c | 24 +++++++++++------------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/codegen/codegen_ops_fpu.h b/src/codegen/codegen_ops_fpu.h index 1021cc742..242743dee 100644 --- a/src/codegen/codegen_ops_fpu.h +++ b/src/codegen/codegen_ops_fpu.h @@ -671,9 +671,10 @@ ropFCHS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb ropFLD##name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ { \ static double fp_imm = v; \ + static uint64_t *fptr = (uint64_t *) &fp_imm; \ \ FP_ENTER(); \ - FP_LOAD_IMM_Q(*(uint64_t *) &fp_imm); \ + FP_LOAD_IMM_Q(*fptr); \ \ return op_pc; \ } diff --git a/src/disk/lba_enhancer.c b/src/disk/lba_enhancer.c index f0ce6b700..35c845c16 100644 --- a/src/disk/lba_enhancer.c +++ b/src/disk/lba_enhancer.c @@ -35,27 +35,25 @@ typedef struct lba_enhancer_t #define BIOS_LBA_ENHANCER "roms/hdd/misc/lbaenhancer.bin" -void * -lba_enhancer_init(const device_t *info) -{ - lba_enhancer_t *lba_enhancer = (lba_enhancer_t *) calloc(1, sizeof(lba_enhancer_t)); - - rom_init(&lba_enhancer->rom, BIOS_LBA_ENHANCER, - device_get_config_hex20("bios_addr"), 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - return lba_enhancer; -} - void lba_enhancer_close(void* priv) { - lba_enhancer_t *lba_enhancer = (lba_enhancer_t *) priv; - free(priv); return; } +void * +lba_enhancer_init(const device_t *info) +{ + lba_enhancer_t *dev = (lba_enhancer_t *) calloc(1, sizeof(lba_enhancer_t)); + + rom_init(&dev->rom, BIOS_LBA_ENHANCER, + device_get_config_hex20("bios_addr"), 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + return dev; +} + static int lba_enhancer_available(void) { From ca2492e893423f171982e769d97f8bdf88fee34b Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 9 Mar 2024 13:18:31 +0100 Subject: [PATCH 643/936] Added the Trident TVGA 8900 D-R. --- src/include/86box/video.h | 1 + src/video/vid_table.c | 1 + src/video/vid_tvga.c | 26 +++++++++++++++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 65d96a4b6..e56498807 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -550,6 +550,7 @@ extern const device_t ibm_ps1_2121_device; /* Trident TVGA 8900 */ extern const device_t tvga8900b_device; extern const device_t tvga8900d_device; +extern const device_t tvga8900dr_device; extern const device_t tvga9000b_device; extern const device_t nec_sv9000_device; diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 5b9c3f8f3..9992eff45 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -144,6 +144,7 @@ video_cards[] = { { &sigma_device }, { &tvga8900b_device }, { &tvga8900d_device }, + { &tvga8900dr_device }, { &tvga9000b_device }, { &nec_sv9000_device }, { &et4000k_isa_device }, diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index 591851016..babd909be 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -37,6 +37,7 @@ #define ROM_TVGA_8900B "roms/video/tvga/tvga8900b.vbi" #define ROM_TVGA_8900CLD "roms/video/tvga/trident.bin" +#define ROM_TVGA_8900DR "roms/video/tvga/8900DR.VBI" #define ROM_TVGA_9000B "roms/video/tvga/tvga9000b.bin" #define ROM_TVGA_9000B_NEC_SV9000 "roms/video/tvga/SV9000.VBI" @@ -428,7 +429,10 @@ tvga_init(const device_t *info) bios_fn = ROM_TVGA_8900B; break; case TVGA8900CLD_ID: - bios_fn = ROM_TVGA_8900CLD; + if (info->local & 0x0100) + bios_fn = ROM_TVGA_8900DR; + else + bios_fn = ROM_TVGA_8900CLD; break; case TVGA9000B_ID: bios_fn = (info->local & 0x100) ? ROM_TVGA_9000B_NEC_SV9000 : ROM_TVGA_9000B; @@ -466,6 +470,12 @@ tvga8900d_available(void) return rom_present(ROM_TVGA_8900CLD); } +static int +tvga8900dr_available(void) +{ + return rom_present(ROM_TVGA_8900DR); +} + static int tvga9000b_available(void) { @@ -564,6 +574,20 @@ const device_t tvga8900d_device = { .config = tvga_config }; +const device_t tvga8900dr_device = { + .name = "Trident TVGA 8900D-R", + .internal_name = "tvga8900dr", + .flags = DEVICE_ISA, + .local = TVGA8900CLD_ID | 0x0100, + .init = tvga_init, + .close = tvga_close, + .reset = NULL, + { .available = tvga8900dr_available }, + .speed_changed = tvga_speed_changed, + .force_redraw = tvga_force_redraw, + .config = tvga_config +}; + const device_t tvga9000b_device = { .name = "Trident TVGA 9000B", .internal_name = "tvga9000b", From 3061e9343c768272860ad3a9810aae3dc686df60 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 9 Mar 2024 13:30:13 +0100 Subject: [PATCH 644/936] Give the TVGA 8900D-R faster timings. --- src/video/vid_tvga.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index babd909be..e97805beb 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -418,7 +418,10 @@ tvga_init(const device_t *info) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga9000); tvga->vram_size = 512 << 10; } else { - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga8900); + if (info->local & 0x0100) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga9000); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga8900); tvga->vram_size = device_get_config_int("memory") << 10; } From cb8b6b68a749496b44fbf488cf7d4ae5ce1935cb Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 9 Mar 2024 13:31:42 +0100 Subject: [PATCH 645/936] And made them on par with the Tseng ET4000AX, as the available data suggests. --- src/video/vid_tvga.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index e97805beb..cd5714d04 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -60,6 +60,7 @@ typedef struct tvga_t { } tvga_t; video_timings_t timing_tvga8900 = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 8, .read_w = 8, .read_l = 12 }; +video_timings_t timing_tvga8900dr = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 }; video_timings_t timing_tvga9000 = { .type = VIDEO_ISA, .write_b = 7, .write_w = 7, .write_l = 12, .read_b = 7, .read_w = 7, .read_l = 12 }; static uint8_t crtc_mask[0x40] = { @@ -419,7 +420,7 @@ tvga_init(const device_t *info) tvga->vram_size = 512 << 10; } else { if (info->local & 0x0100) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga9000); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga8900dr); else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga8900); tvga->vram_size = device_get_config_int("memory") << 10; From 567d66b788355e903fba2a3f9c780ce5da5f0e55 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 9 Mar 2024 13:43:59 +0100 Subject: [PATCH 646/936] Added the IBM Aptiva CM (Japanese PC 330). --- src/include/86box/machine.h | 1 + src/machine/m_at_386dx_486.c | 44 +++++++++++++++++++++++++++--------- src/machine/machine_table.c | 40 ++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 11 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index e27a70d79..765279257 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -521,6 +521,7 @@ extern int machine_at_403tg_d_init(const machine_t *); extern int machine_at_403tg_d_mr_init(const machine_t *); extern int machine_at_pb450_init(const machine_t *); extern int machine_at_pb450_init(const machine_t *); +extern int machine_at_aptiva_cm_init(const machine_t *); extern int machine_at_pc330_6573_init(const machine_t *); extern int machine_at_mvi486_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 1dd63ce32..7d843aece 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -693,17 +693,9 @@ machine_at_pb450_init(const machine_t *model) return ret; } -int -machine_at_pc330_6573_init(const machine_t *model) /* doesn't like every CPU other than the iDX4 and the Intel OverDrive, hangs without a PS/2 mouse */ +static void +machine_at_pc330_6573_common_init(const machine_t *model) { - int ret; - - ret = bios_load_linear("roms/machines/pc330_6573/$IMAGES.USF", - 0x000e0000, 131072, 0); - - if (bios_only || !ret) - return ret; - machine_at_common_init_ex(model, 2); device_add(&ide_vlb_2ch_device); @@ -718,7 +710,7 @@ machine_at_pc330_6573_init(const machine_t *model) /* doesn't like every CPU oth pci_register_slot(0x0E, PCI_CARD_VIDEO, 13, 14, 15, 16); if (gfxcard[0] == VID_INTERNAL) - device_add(&gd5430_onboard_vlb_device); + device_add(machine_get_vid_device(machine)); device_add(&opti602_device); device_add(&opti802g_device); @@ -727,6 +719,36 @@ machine_at_pc330_6573_init(const machine_t *model) /* doesn't like every CPU oth device_add(&fdc37c665_ide_device); device_add(&ide_opti611_vlb_device); device_add(&intel_flash_bxt_device); +} + +int +machine_at_aptiva_cm_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/aptiva_cm/$IMAGES.USF", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_pc330_6573_common_init(model); + + return ret; +} + +int +machine_at_pc330_6573_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/pc330_6573/$IMAGES.USF", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_pc330_6573_common_init(model); return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index d620357d6..1426dbcb3 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -7185,6 +7185,46 @@ const machine_t machines[] = { .net_device = NULL }, /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[OPTi 802G] IBM Aptiva CM", + .internal_name = "aptiva_cm", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_OPTI_895_802G, + .init = machine_at_aptiva_cm_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3_PC330, + .block = CPU_BLOCK_NONE, + .min_bus = 25000000, + .max_bus = 33333333, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 2.0, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5430_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 1 KBC firmware. */ { .name = "[OPTi 802G] IBM PC 330 (type 6573)", .internal_name = "pc330_6573", From 9006f31f45de2c40d8d73b009a23b1d73e656b32 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 9 Mar 2024 14:46:33 +0100 Subject: [PATCH 647/936] Added the NEC Mate NX MA23C. --- src/include/86box/machine.h | 1 + src/machine/m_at_socket7.c | 31 ++++++++++++++++++++++++++ src/machine/machine_table.c | 43 ++++++++++++++++++++++++++++++++++++- 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 765279257..c13b423b0 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -706,6 +706,7 @@ extern int machine_at_pb810_init(const machine_t *); extern int machine_at_mb520n_init(const machine_t *); extern int machine_at_i430vx_init(const machine_t *); +extern int machine_at_ma23c_init(const machine_t *); extern int machine_at_nupro592_init(const machine_t *); extern int machine_at_tx97_init(const machine_t *); #if defined(DEV_BRANCH) && defined(USE_AN430TX) diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 9ab24b7c2..ce21c6437 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -798,6 +798,37 @@ machine_at_i430vx_init(const machine_t *model) return ret; } +int +machine_at_ma23c_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ma23c/BIOS.ROM", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_VIDEO, 3, 4, 1, 2); + device_add(&i430tx_device); + device_add(&piix4_device); + device_add(&nec_mate_unk_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c67x_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + + return ret; +} + int machine_at_nupro592_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 1426dbcb3..810597899 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -11997,6 +11997,47 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has a SM(S)C FDC37C67x Super I/O chip with on-chip KBC with Phoenix or + AMIKey-2 KBC firmware. */ + { + .name = "[i430TX] NEC Mate NX MA23C", + .internal_name = "ma23c", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_ma23c_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 = 60000000, + .max_bus = 66666667, + .min_voltage = 2700, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .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 = NULL, + .net_device = NULL + }, /* The BIOS sends KBC command BB and expects it to output a byte, which is AMI KBC behavior. A picture shows a VIA VT82C42N KBC though, so it could be a case of that KBC with AMI firmware. */ { @@ -13683,7 +13724,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has a SM(S)C FDC37M60x Super I/O chip with on-chip KBC with Phoenix or + /* Has a SM(S)C FDC37C67x Super I/O chip with on-chip KBC with Phoenix or AMIKey-2 KBC firmware. */ { .name = "[i440LX] NEC Mate NX MA30D/23D", From d4fa99648e9a0f6adbcb943a85312df4bb074cf8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 9 Mar 2024 18:56:42 +0100 Subject: [PATCH 648/936] SiS 5595 fixes, added the PC Chips M747, and corrected the name of the Aptiva. --- src/acpi.c | 3 +++ src/chipset/sis_5513_p2i.c | 32 +++++++++++++++++++++++-- src/include/86box/machine.h | 3 ++- src/machine/m_at_386dx_486.c | 4 ++-- src/machine/m_at_slot1.c | 27 +++++++++++++++++++++ src/machine/machine_table.c | 46 +++++++++++++++++++++++++++++++++--- 6 files changed, 107 insertions(+), 8 deletions(-) diff --git a/src/acpi.c b/src/acpi.c index 93cb71542..339ea7dcf 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -1733,6 +1733,9 @@ acpi_reg_write_sis_5595(int size, uint16_t addr, uint8_t val, void *priv) break; case 0x1c: dev->regs.gpe_pin = ((dev->regs.gpe_pin & ~(0xff << shift32)) | ((val & 0xff) << shift32)); + if (!strcmp(machine_get_internal_name(), "m747") && (val & 0x10) && + !(dev->regs.gpe_io & 0x00000010)) + resetx86(); break; case 0x1d: dev->regs.gpe_pin = ((dev->regs.gpe_pin & ~(0x0f << shift32)) | ((val & 0x0f) << shift32)); diff --git a/src/chipset/sis_5513_p2i.c b/src/chipset/sis_5513_p2i.c index df18cc4b3..d0c423a8e 100644 --- a/src/chipset/sis_5513_p2i.c +++ b/src/chipset/sis_5513_p2i.c @@ -86,6 +86,7 @@ typedef struct sis_5513_pci_to_isa_t { port_92_t *port_92; void *pit; nvr_t *nvr; + char *fn; ddma_t *ddma; acpi_t *acpi; void *smbus; @@ -1077,7 +1078,6 @@ sis_5513_11_pci_to_isa_reset(sis_5513_pci_to_isa_t *dev) dev->sis->ide_bits_1_3_writable = 0; dev->sis->usb_enabled = 0; - sis_5513_apc_reset(dev); sis_5513_apc_recalc(dev, 0); } @@ -1132,7 +1132,6 @@ sis_5513_b0_pci_to_isa_reset(sis_5513_pci_to_isa_t *dev) dev->sis->usb_enabled = 0; - sis_5513_apc_reset(dev); sis_5513_apc_recalc(dev, 0); if (dev->rev == 0x81) @@ -1196,6 +1195,17 @@ static void sis_5513_pci_to_isa_close(void *priv) { sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + FILE *fp = NULL; + + fp = nvr_fopen(dev->fn, "wb"); + + if (fp != NULL) { + (void) fwrite(dev->apc_regs, 256, 1, fp); + fclose(fp); + } + + if (dev->fn != NULL) + free(dev->fn); free(dev); } @@ -1205,6 +1215,8 @@ sis_5513_pci_to_isa_init(UNUSED(const device_t *info)) { sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) calloc(1, sizeof(sis_5513_pci_to_isa_t)); uint8_t pit_is_fast = (((pit_mode == -1) && is486) || (pit_mode == 1)); + FILE *fp = NULL; + int c; dev->rev = info->local; @@ -1272,6 +1284,22 @@ sis_5513_pci_to_isa_init(UNUSED(const device_t *info)) dev->sis->acpi->priv = dev->sis; acpi_set_slot(dev->sis->acpi, dev->sis->sb_pci_slot); acpi_set_nvr(dev->sis->acpi, dev->nvr); + + /* Set up the NVR file's name. */ + c = strlen(machine_get_internal_name()) + 9; + dev->fn = (char *) malloc(c + 1); + sprintf(dev->fn, "%s_apc.nvr", machine_get_internal_name()); + + fp = nvr_fopen(dev->fn, "rb"); + + memset(dev->apc_regs, 0x00, sizeof(dev->apc_regs)); + sis_5513_apc_reset(dev); + if (fp != NULL) { + if (fread(dev->apc_regs, 1, 256, fp) != 256) + fatal("sis_5513_pci_to_isa_init(): Error reading APC data\n"); + fclose(fp); + } + acpi_set_irq_mode(dev->sis->acpi, 2); break; } diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index c13b423b0..18abf9ea9 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -521,7 +521,7 @@ extern int machine_at_403tg_d_init(const machine_t *); extern int machine_at_403tg_d_mr_init(const machine_t *); extern int machine_at_pb450_init(const machine_t *); extern int machine_at_pb450_init(const machine_t *); -extern int machine_at_aptiva_cm_init(const machine_t *); +extern int machine_at_aptiva_510_init(const machine_t *); extern int machine_at_pc330_6573_init(const machine_t *); extern int machine_at_mvi486_init(const machine_t *); @@ -801,6 +801,7 @@ extern int machine_at_borapro_init(const machine_t *); extern int machine_at_ms6168_init(const machine_t *); extern int machine_at_p6f99_init(const machine_t *); +extern int machine_at_m747_init(const machine_t *); /* m_at_slot2.c */ extern int machine_at_6gxu_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 7d843aece..4cfa7447e 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -722,11 +722,11 @@ machine_at_pc330_6573_common_init(const machine_t *model) } int -machine_at_aptiva_cm_init(const machine_t *model) +machine_at_aptiva_510_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/aptiva_cm/$IMAGES.USF", + ret = bios_load_linear("roms/machines/aptiva_510/$IMAGES.USF", 0x000e0000, 131072, 0); if (bios_only || !ret) diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index d31d763d4..a3c25d12b 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -841,3 +841,30 @@ machine_at_p6f99_init(const machine_t *model) return ret; } +int +machine_at_m747_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/m747/990521.rom", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); + device_add(&sis_5600_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&it8661f_device); + device_add(&winbond_flash_w29c020_device); + + return ret; +} diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 810597899..04cc59043 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -7186,11 +7186,11 @@ const machine_t machines[] = { }, /* Has IBM PS/2 Type 1 KBC firmware. */ { - .name = "[OPTi 802G] IBM Aptiva CM", - .internal_name = "aptiva_cm", + .name = "[OPTi 802G] IBM Aptiva 510/710/Vision", + .internal_name = "aptiva_510", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_OPTI_895_802G, - .init = machine_at_aptiva_cm_init, + .init = machine_at_aptiva_510_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, @@ -14513,6 +14513,46 @@ const machine_t machines[] = { .snd_device = &es1371_onboard_device, /* ES1373 but we currently don't emulate that. */ .net_device = NULL }, + /* Has the SiS (5)600 chipset with on-chip KBC. */ + { + .name = "[SiS 5600] PC Chips M747", + .internal_name = "m747", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_SIS_5600, + .init = machine_at_m747_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1572864, + .step = 1024 + }, + .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 = NULL, + .net_device = NULL + }, /* Slot 1/2 machines */ /* 440GX */ From f4a7fd7190122f121ea00cfe2dbed2d04d969d41 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 9 Mar 2024 19:07:54 +0100 Subject: [PATCH 649/936] Added two more ET4000AX BIOS'es. --- src/video/vid_et4000.c | 82 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 71 insertions(+), 11 deletions(-) diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 5fe524fd8..7ceacb823 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -63,7 +63,9 @@ #define ET4000_TYPE_KASAN 5 /* Kasan ET4000 */ #define BIOS_ROM_PATH "roms/video/et4000/ET4000.BIN" +#define V8_06_BIOS_ROM_PATH "roms/video/et4000/ET4000_V8_06.BIN" #define TC6058AF_BIOS_ROM_PATH "roms/video/et4000/Tseng_Labs_VGA-4000_BIOS_V1.1.bin" +#define V1_21_BIOS_ROM_PATH "roms/video/et4000/Tseng_Labs_VGA-4000_BIOS_V1.21.bin" #define KOREAN_BIOS_ROM_PATH "roms/video/et4000/tgkorvga.bin" #define KOREAN_FONT_ROM_PATH "roms/video/et4000/tg_ksc5601.rom" #define KASAN_BIOS_ROM_PATH "roms/video/et4000/et4000_kasan16.bin" @@ -783,6 +785,7 @@ et4000_mca_feedb(UNUSED(void *priv)) static void * et4000_init(const device_t *info) { + const char *bios_ver = NULL; const char *fn; et4000_t *dev; int i; @@ -803,8 +806,8 @@ et4000_init(const device_t *info) NULL, NULL); io_sethandler(0x03c0, 32, et4000_in, NULL, NULL, et4000_out, NULL, NULL, dev); - if (dev->type == ET4000_TYPE_TC6058AF) - fn = TC6058AF_BIOS_ROM_PATH; + bios_ver = (char *) device_get_config_bios("bios_ver"); + fn = (char *) device_get_bios_file(info, bios_ver, 0); break; case ET4000_TYPE_MCA: /* MCA ET4000AX */ @@ -925,12 +928,6 @@ et4000_force_redraw(void *priv) dev->svga.fullchange = changeframecount; } -static int -et4000_tc6058af_available(void) -{ - return rom_present(TC6058AF_BIOS_ROM_PATH); -} - static int et4000_available(void) { @@ -970,12 +967,75 @@ static const device_config_t et4000_tc6058af_config[] = { } } }, + { + .name = "bios_ver", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "v1_10", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, /*W1*/ + .bios = { + { .name = "Version 1.10", .internal_name = "v1_10", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 32768, .files = { TC6058AF_BIOS_ROM_PATH, "" } }, + { .name = "Version 1.21", .internal_name = "v1_21", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 32768, .files = { V1_21_BIOS_ROM_PATH, "" } }, + { .files_no = 0 } + }, + }, { .type = CONFIG_END } // clang-format on }; +static const device_config_t et4000_bios_config[] = { + // clang-format off + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 1024, + .selection = { + { + .description = "256 KB", + .value = 256 + }, + { + .description = "512 KB", + .value = 512 + }, + { + .description = "1 MB", + .value = 1024 + }, + { + .description = "" + } + } + }, + { + .name = "bios_ver", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "v8_01", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, /*W1*/ + .bios = { + { .name = "Version 8.01", .internal_name = "v8_01", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 32768, .files = { BIOS_ROM_PATH, "" } }, + { .name = "Version 8.06", .internal_name = "v8_06", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 32768, .files = { V8_06_BIOS_ROM_PATH, "" } }, + { .files_no = 0 } + }, + }, + { + .type = CONFIG_END + } + // clang-format on +}; + static const device_config_t et4000_config[] = { // clang-format off { @@ -1015,7 +1075,7 @@ const device_t et4000_tc6058af_isa_device = { .init = et4000_init, .close = et4000_close, .reset = NULL, - { .available = et4000_tc6058af_available }, + { .available = NULL }, .speed_changed = et4000_speed_changed, .force_redraw = et4000_force_redraw, .config = et4000_tc6058af_config @@ -1029,10 +1089,10 @@ const device_t et4000_isa_device = { .init = et4000_init, .close = et4000_close, .reset = NULL, - { .available = et4000_available }, + { .available = NULL }, .speed_changed = et4000_speed_changed, .force_redraw = et4000_force_redraw, - .config = et4000_config + .config = et4000_bios_config }; const device_t et4000_mca_device = { From bc6b659e02b976430321c053f9d78a5c64759bc3 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 11 Mar 2024 01:49:58 +0600 Subject: [PATCH 650/936] SLIP works properly now Preparation for modem phonebook files --- src/network/CMakeLists.txt | 2 +- src/network/net_modem.c | 101 +++++++++++++++++++++++++++++++++--- src/network/net_slirp.c | 50 ++++++++++++++++++ src/network/network.c | 8 ++- src/network/utils/getline.c | 81 +++++++++++++++++++++++++++++ 5 files changed, 234 insertions(+), 8 deletions(-) create mode 100644 src/network/utils/getline.c diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 5eb091d58..e407d4364 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -15,7 +15,7 @@ set(net_sources) list(APPEND net_sources network.c net_pcap.c net_slirp.c net_dp8390.c net_3c501.c net_3c503.c net_ne2000.c net_pcnet.c net_wd8003.c net_plip.c net_event.c net_null.c - net_eeprom_nmc93cxx.c net_tulip.c net_rtl8139.c net_l80225.c net_modem.c) + net_eeprom_nmc93cxx.c net_tulip.c net_rtl8139.c net_l80225.c net_modem.c utils/getline.c) find_package(PkgConfig REQUIRED) pkg_check_modules(SLIRP REQUIRED IMPORTED_TARGET slirp) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 97f038157..2396863bd 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -1,3 +1,6 @@ + +/* TODO: SLIP support. */ + #include #include #include @@ -14,6 +17,7 @@ #include <86box/fifo8.h> #include <86box/timer.h> #include <86box/serial.h> +#include <86box/plat.h> #include <86box/network.h> #include <86box/plat_unused.h> @@ -48,6 +52,18 @@ typedef enum modem_mode_t MODEM_MODE_DATA = 1 } modem_mode_t; +typedef enum modem_slip_stage_t +{ + MODEM_SLIP_STAGE_USERNAME, + MODEM_SLIP_STAGE_PASSWORD +} modem_slip_stage_t; + +typedef struct modem_phonebook_entry_t +{ + char phone[1024]; + char address[1024]; +} modem_phonebook_entry_t; + typedef struct modem_t { uint8_t mac[6]; @@ -90,6 +106,9 @@ typedef struct modem_t bool recCommand; uint8_t command; } telClient; + + modem_phonebook_entry_t entries[20]; + uint32_t entries_num; netcard_t *card; } modem_t; @@ -107,6 +126,43 @@ static modem_t *instance; static void modem_do_command(modem_t* modem); +extern ssize_t local_getline(char **buf, size_t *bufsiz, FILE *fp); + +static void +modem_read_phonebook_file(modem_t* modem, const char* path) +{ + FILE* file = plat_fopen(path, "r"); + char* buf = NULL; + size_t size = 0; + if (!file) + return; + + modem->entries_num = 0; + + while (local_getline(&buf, &size, file) != -1) { + modem_phonebook_entry_t entry = { { 0 }, { 0 } }; + int res = 0; + buf[strcspn(buf, "\r\n")] = 0; + + res = sscanf(buf, "%s %s", entry.phone, entry.address); + + if (res == 0 || res == 1) { + /* Appears to be a bad line. */ + continue; + } + + if (strspn(entry.phone, "01234567890*=,;#+>") != strlen(entry.phone)) { + /* Invalid characters. */ + continue; + } + + modem->entries[modem->entries_num++] = entry; + if (modem->entries_num >= 20) + break; + } + fclose(file); +} + static void modem_echo(modem_t* modem, uint8_t c) { @@ -190,6 +246,8 @@ process_tx_packet(modem_t *modem, uint8_t *p, uint32_t len) uint8_t *processed_tx_packet = calloc(len, 1); uint8_t c = 0; + pclog("Processing SLIP packet of %u bytes\n", len); + while (pos < len) { c = p[pos]; pos++; @@ -223,7 +281,18 @@ process_tx_packet(modem_t *modem, uint8_t *p, uint32_t len) } send_tx_packet: - network_tx(modem->card, processed_tx_packet, received); + if (received) + { + uint8_t* buf = calloc(received + 14, 1); + buf[0] = buf[1] = buf[2] = buf[3] = buf[4] = buf[5] = 0xFF; + buf[6] = buf[7] = buf[8] = buf[9] = buf[10] = buf[11] = 0xFC; + buf[12] = 0x08; + buf[13] = 0x00; + memcpy(buf + 14, processed_tx_packet, received); + network_tx(modem->card, buf, received + 14); + free(processed_tx_packet); + free(buf); + } return; } @@ -267,7 +336,6 @@ host_to_modem_cb(void *priv) if (modem->mode == MODEM_MODE_DATA && fifo8_num_used(&modem->rx_data)) { serial_write_fifo(modem->serial, fifo8_pop(&modem->rx_data)); - fprintf(stderr, "(data)\n"); } else if (fifo8_num_used(&modem->data_pending)) { uint8_t val = fifo8_pop(&modem->data_pending); serial_write_fifo(modem->serial, val); @@ -326,11 +394,15 @@ modem_write(UNUSED(serial_t *s), void *priv, uint8_t txval) } void modem_send_res(modem_t* modem, const ResTypes response) { + char response_str_connect[256] = { 0 }; const char* response_str = NULL; uint32_t code = -1; + + snprintf(response_str_connect, sizeof(response_str_connect), "CONNECT %u", modem->baudrate); + switch (response) { case ResOK: code = 0; response_str = "OK"; break; - case ResCONNECT: code = 1; response_str = "CONNECT 33600"; break; + case ResCONNECT: code = 1; response_str = response_str_connect; break; case ResRING: code = 2; response_str = "RING"; break; case ResNOCARRIER: code = 3; response_str = "NO CARRIER"; break; case ResERROR: code = 4; response_str = "ERROR"; break; @@ -416,9 +488,13 @@ void modem_dial(modem_t* modem, const char* str) { /* TODO: Port TCP/IP support from DOSBox. */ - if (!strncmp(str, "0.0.0.0", sizeof("0.0.0.0") - 1)) { + if (!strncmp(str, "0.0.0.0", sizeof("0.0.0.0") - 1)) + { + pclog("Turning on SLIP\n"); modem_enter_connected_state(modem); - } else { + } + else + { modem_send_res(modem, ResNOCARRIER); modem_enter_idle_state(modem); } @@ -779,19 +855,31 @@ fifo8_resize_2x(Fifo8* fifo) static int modem_rx(void *priv, uint8_t *buf, int io_len) { +#if 1 modem_t* modem = (modem_t*)priv; uint8_t c = 0; uint32_t i = 0; if (!modem->connected) { /* Drop packet. */ + pclog("Dropping %d bytes\n", io_len - 14); return 0; } - if ((io_len) <= (fifo8_num_free(&modem->rx_data) / 2)) { + if ((io_len) >= (fifo8_num_free(&modem->rx_data))) { fifo8_resize_2x(&modem->rx_data); } + if (!(buf[12] == 0x08 && buf[13] == 0x00)) { + pclog("Dropping %d bytes (non-IP packet (ethtype 0x%02X%02X))\n", io_len - 14, buf[12], buf[13]); + return 0; + } + + pclog("Receiving %d bytes\n", io_len - 14); + /* Strip the Ethernet header. */ + io_len -= 14; + buf += 14; + fifo8_push(&modem->rx_data, END); for (i = 0; i < io_len; i++) { switch (buf[i]) { @@ -810,6 +898,7 @@ modem_rx(void *priv, uint8_t *buf, int io_len) } fifo8_push(&modem->rx_data, END); return 1; +#endif } static void diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index 6aff76a90..599ee896d 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -37,6 +37,7 @@ #include <86box/ini.h> #include <86box/config.h> #include <86box/video.h> +#include <86box/bswap.h> #define _SSIZE_T_DEFINED #include @@ -76,6 +77,29 @@ typedef struct net_slirp_t { #endif } net_slirp_t; +/* Pulled off from libslirp code. This is only needed for modem. */ +#pragma pack(push, 1) +struct arphdr_local { + unsigned char h_dest[6]; /* destination eth addr */ + unsigned char h_source[6]; /* source ether addr */ + unsigned short h_proto; /* packet type ID field */ + + unsigned short ar_hrd; /* format of hardware address */ + unsigned short ar_pro; /* format of protocol address */ + unsigned char ar_hln; /* length of hardware address */ + unsigned char ar_pln; /* length of protocol address */ + unsigned short ar_op; /* ARP opcode (command) */ + + /* + * Ethernet looks like this : This bit is variable sized however... + */ + uint8_t ar_sha[6]; /* sender hardware address */ + uint32_t ar_sip; /* sender IP address */ + uint8_t ar_tha[6]; /* target hardware address */ + uint32_t ar_tip; /* target IP address */ +}; +#pragma pack(pop) + #ifdef ENABLE_SLIRP_LOG int slirp_do_log = ENABLE_SLIRP_LOG; @@ -455,6 +479,32 @@ net_slirp_init(const netcard_t *card, const uint8_t *mac_addr, UNUSED(void *priv #ifdef _WIN32 slirp->sock_event = CreateEvent(NULL, FALSE, FALSE, NULL); #endif + + if (!strcmp(network_card_get_internal_name(net_cards_conf[net_card_current].device_num), "modem")) { + /* Send a gratuitous ARP here to make SLiRP work properly with SLIP connections. */ + struct arphdr_local arphdr; + /* ARP part. */ + arphdr.ar_hrd = bswap16(1); + arphdr.ar_pro = bswap16(0x0800); + arphdr.ar_hln = 6; + arphdr.ar_pln = 4; + arphdr.ar_op = bswap16(1); + memcpy(&arphdr.ar_sha, mac_addr, 6); + memcpy(&arphdr.ar_tha, mac_addr, 6); + arphdr.ar_sip = dhcp.s_addr; + arphdr.ar_tip = dhcp.s_addr; + + /* Ethernet header part. */ + arphdr.h_proto = bswap16(0x0806); + memset(arphdr.h_dest, 0xff, 6); + memset(arphdr.h_source, 0x52, 6); + arphdr.h_source[2] = 0x0a; + arphdr.h_source[3] = 0x00; + arphdr.h_source[4] = slirp_card_num; + arphdr.h_source[5] = 2; + slirp_input(slirp->slirp, (const uint8_t *)&arphdr, sizeof(struct arphdr_local)); + } + slirp_log("SLiRP: creating thread...\n"); slirp->poll_tid = thread_create(net_slirp_thread, slirp); diff --git a/src/network/network.c b/src/network/network.c index 94403c2f4..fe3bf8489 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -454,6 +454,7 @@ netcard_t * network_attach(void *card_drv, uint8_t *mac, NETRXCB rx, NETSETLINKSTATE set_link_state) { netcard_t *card = calloc(1, sizeof(netcard_t)); + int net_type = net_cards_conf[net_card_current].net_type; card->queued_pkt.data = calloc(1, NET_MAX_FRAME); card->card_drv = card_drv; card->rx = rx; @@ -470,7 +471,12 @@ network_attach(void *card_drv, uint8_t *mac, NETRXCB rx, NETSETLINKSTATE set_lin network_queue_init(&card->queues[i]); } - switch (net_cards_conf[net_card_current].net_type) { + if (!strcmp(network_card_get_internal_name(net_cards_conf[net_card_current].device_num), "modem") && net_type >= NET_TYPE_PCAP) { + /* Force SLiRP here. Modem only operates on non-Ethernet frames. */ + net_type = NET_TYPE_SLIRP; + } + + switch (net_type) { case NET_TYPE_SLIRP: card->host_drv = net_slirp_drv; card->host_drv.priv = card->host_drv.init(card, mac, NULL, net_drv_error); diff --git a/src/network/utils/getline.c b/src/network/utils/getline.c new file mode 100644 index 000000000..69ee258fd --- /dev/null +++ b/src/network/utils/getline.c @@ -0,0 +1,81 @@ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +ssize_t +local_getdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp) +{ + char *ptr, *eptr; + + + if (*buf == NULL || *bufsiz == 0) { + *bufsiz = BUFSIZ; + if ((*buf = malloc(*bufsiz)) == NULL) + return -1; + } + + for (ptr = *buf, eptr = *buf + *bufsiz;;) { + int c = fgetc(fp); + if (c == -1) { + if (feof(fp)) { + ssize_t diff = (ssize_t)(ptr - *buf); + if (diff != 0) { + *ptr = '\0'; + return diff; + } + } + return -1; + } + *ptr++ = c; + if (c == delimiter) { + *ptr = '\0'; + return ptr - *buf; + } + if (ptr + 2 >= eptr) { + char *nbuf; + size_t nbufsiz = *bufsiz * 2; + ssize_t d = ptr - *buf; + if ((nbuf = realloc(*buf, nbufsiz)) == NULL) + return -1; + *buf = nbuf; + *bufsiz = nbufsiz; + eptr = nbuf + nbufsiz; + ptr = nbuf + d; + } + } +} + +ssize_t +local_getline(char **buf, size_t *bufsiz, FILE *fp) +{ + return local_getdelim(buf, bufsiz, '\n', fp); +} From 8fd35fccb8316328ca8a3a11408812cf19456584 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 11 Mar 2024 02:02:49 +0600 Subject: [PATCH 651/936] Make fifo8 resizing code more reliable --- src/network/net_modem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 2396863bd..131b87653 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -866,7 +866,7 @@ modem_rx(void *priv, uint8_t *buf, int io_len) return 0; } - if ((io_len) >= (fifo8_num_free(&modem->rx_data))) { + if ((io_len) >= (fifo8_num_free(&modem->rx_data) / 2)) { fifo8_resize_2x(&modem->rx_data); } From e0c5eb49f1f5a186d83e5903f3f551f633aeb393 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 10 Mar 2024 18:01:09 -0300 Subject: [PATCH 652/936] DDC: EDID data improvements, hopefully fixes 1600x1200 on older OSes --- src/qt/languages/ca-ES.po | 6 ++++++ src/qt/languages/cs-CZ.po | 6 ++++++ src/qt/languages/de-DE.po | 6 ++++++ src/qt/languages/en-GB.po | 6 ++++++ src/qt/languages/en-US.po | 6 ++++++ src/qt/languages/es-ES.po | 6 ++++++ src/qt/languages/fi-FI.po | 6 ++++++ src/qt/languages/fr-FR.po | 5 +++++ src/qt/languages/hr-HR.po | 6 ++++++ src/qt/languages/hu-HU.po | 6 ++++++ src/qt/languages/it-IT.po | 6 ++++++ src/qt/languages/ja-JP.po | 6 ++++++ src/qt/languages/ko-KR.po | 6 ++++++ src/qt/languages/pl-PL.po | 6 ++++++ src/qt/languages/pt-BR.po | 6 ++++++ src/qt/languages/pt-PT.po | 6 ++++++ src/qt/languages/ru-RU.po | 6 ++++++ src/qt/languages/sk-SK.po | 6 ++++++ src/qt/languages/sl-SI.po | 6 ++++++ src/qt/languages/tr-TR.po | 6 ++++++ src/qt/languages/uk-UA.po | 6 ++++++ src/qt/languages/zh-CN.po | 5 +++++ src/qt/languages/zh-TW.po | 6 ++++++ src/qt/qt_main.cpp | 23 +++++++++++++++++++++++ src/video/vid_ddc.c | 14 +++++++------- 25 files changed, 166 insertions(+), 7 deletions(-) diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po index 483e6ee53..cba27b839 100644 --- a/src/qt/languages/ca-ES.po +++ b/src/qt/languages/ca-ES.po @@ -1224,3 +1224,9 @@ msgstr "Ràpid" msgid "&Auto-pause on focus loss" msgstr "&Pausa automàtica en la pèrdua del focus" + +msgid "WinBox is no longer supported" +msgstr "WinBox is no longer supported" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index 84c795092..31388ca54 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -1224,3 +1224,9 @@ msgstr "Rychlý" msgid "&Auto-pause on focus loss" msgstr "&Automatická pauza při ztrátě zaměření okna" + +msgid "WinBox is no longer supported" +msgstr "WinBox již není podporován" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Vývoj správce WinBox byl zastaven v roce 2022 z důvodu nedostatku správců. Vzhledem k tomu, že naše úsilí směřujeme k tomu, abychom 86Box ještě vylepšili, rozhodli jsme se WinBox jako správce již nepodporovat.\n\nProstřednictvím WinBoxu nebudou poskytovány žádné další aktualizace a pokud jej budete nadále používat s novějšími verzemi 86Boxu, můžete se setkat s nesprávným chováním. Veškerá hlášení o chybách souvisejících s chováním WinBoxu budou uzavřena jako neplatná.\n\nSeznam dalších správců, které můžete používat, najdete na webu 86box.net." diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index 4a4fde3c2..86289507c 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -1224,3 +1224,9 @@ msgstr "Schnell" msgid "&Auto-pause on focus loss" msgstr "&Auto-Pause bei Fokusverlust" + +msgid "WinBox is no longer supported" +msgstr "WinBox wird nicht mehr unterstützt" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Die Entwicklung des WinBox-Managers wurde im Jahr 2022 eingestellt, da es an Betreuern mangelte. Da wir unsere Bemühungen darauf richten, 86Box noch besser zu machen, haben wir uns entschlossen, WinBox nicht mehr als Manager zu unterstützen.\n\nEs werden keine weiteren Updates für WinBox zur Verfügung gestellt, und es kann zu fehlerhaftem Verhalten kommen, wenn Sie WinBox weiterhin mit neueren Versionen von 86Box verwenden. Alle Fehlerberichte, die sich auf das Verhalten von WinBox beziehen, werden als ungültig geschlossen.\n\nAuf 86box.net finden Sie eine Liste anderer Manager, die Sie verwenden können." diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index 031a365c0..cff4be3ef 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -1224,3 +1224,9 @@ msgstr "Fast" msgid "&Auto-pause on focus loss" msgstr "&Auto-pause on focus loss" + +msgid "WinBox is no longer supported" +msgstr "WinBox is no longer supported" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index 06a4b60f1..f3bca870f 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -1224,3 +1224,9 @@ msgstr "Fast" msgid "&Auto-pause on focus loss" msgstr "&Auto-pause on focus loss" + +msgid "WinBox is no longer supported" +msgstr "WinBox is no longer supported" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index 60ac5fb5c..e41a94947 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -1224,3 +1224,9 @@ msgstr "Rápida" msgid "&Auto-pause on focus loss" msgstr "&Pausa automática al perder el foco" + +msgid "WinBox is no longer supported" +msgstr "WinBox ya no recibe soporte" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "El desarrollo del gestor WinBox se detuvo en 2022 debido a la falta de mantenedores. Como dirigimos nuestros esfuerzos a hacer 86Box aún mejor, hemos tomado la decisión de dejar de dar soporte a WinBox como gestor.\n\nNo se proporcionarán más actualizaciones a través de WinBox, y puede encontrar un comportamiento incorrecto si continúa usándolo con versiones más nuevas de 86Box. Cualquier informe de error relacionado con el comportamiento de WinBox será cerrado como inválido.\n\nVaya a 86box.net para una lista de otros gestores que puede utilizar." diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index 50ebffccb..ddf6a0683 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -1224,3 +1224,9 @@ msgstr "Nopea" msgid "&Auto-pause on focus loss" msgstr "&Automaattinen tauko tarkennuksen hävitessä" + +msgid "WinBox is no longer supported" +msgstr "WinBoxia ei enää tueta" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "WinBox-managerin kehitys lopetettiin vuonna 2022, koska ylläpitäjiä ei ollut riittävästi. Koska suuntaamme ponnistuksemme 86Boxin parantamiseen entisestään, olemme päättäneet olla enää tukematta WinBoxia managerina.\n\nWinBoxin kautta ei enää toimiteta päivityksiä, ja saatat kohdata virheellistä käyttäytymistä, jos jatkat sen käyttöä 86Boxin uudemmissa versioissa. Kaikki WinBoxin käyttäytymiseen liittyvät vikailmoitukset suljetaan virheellisinä.\n\nSiirry osoitteeseen 86box.net saadaksesi luettelon muista käyttämistäsi hallintaohjelmista." diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index 52bccebd2..c443a881d 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -1225,3 +1225,8 @@ msgstr "Rapide" msgid "&Auto-pause on focus loss" msgstr "&Pause automatique à perte de mise au point" +msgid "WinBox is no longer supported" +msgstr "WinBox n'est plus pris en charge" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Le développement du gestionnaire WinBox s'est arrêté en 2022 en raison d'un manque de mainteneurs. Comme nous concentrons nos efforts sur l'amélioration de 86Box, nous avons pris la décision de ne plus supporter WinBox en tant que gestionnaire.\n\nAucune mise à jour ne sera fournie par WinBox, et vous pourriez rencontrer des comportements incorrects si vous continuez à l'utiliser avec des versions plus récentes de 86Box. Tous les rapports de bogues relatifs au comportement de WinBox seront classés comme non valides.\n\nAllez sur 86box.net pour une liste d'autres gestionnaires que vous pouvez utiliser." diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index 19b6a6e85..28db9e32d 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -1224,3 +1224,9 @@ msgstr "Brzi" msgid "&Auto-pause on focus loss" msgstr "&Automatska pauza pri gubitku fokusa" + +msgid "WinBox is no longer supported" +msgstr "WinBox is no longer supported" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index 338d2ff5e..07770c077 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -1224,3 +1224,9 @@ msgstr "Gyors" msgid "&Auto-pause on focus loss" msgstr "&Automatikus szünet fókuszvesztéskor" + +msgid "WinBox is no longer supported" +msgstr "A WinBox már nem támogatott" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "A WinBox menedzser fejlesztése 2022-ben leállt karbantartók hiányában. Mivel erőfeszítéseinket a 86Box még jobbá tételére irányítjuk, úgy döntöttünk, hogy a WinBox-ot mint menedzsert nem támogatjuk tovább.\n\nA WinBoxon keresztül nem lesznek további frissítések, és hibás viselkedéssel találkozhat, ha továbbra is a 86Box újabb verzióival használja. A WinBox viselkedésével kapcsolatos hibajelentéseket érvénytelennek nyilvánítjuk.\n\nA 86box.net oldalon talál egy listát más kezelőkről, amelyeket használhat." diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index 20c15c656..39ecd7e89 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -1224,3 +1224,9 @@ msgstr "Veloce" msgid "&Auto-pause on focus loss" msgstr "&Pausa automatica alla perdita della messa a fuoco" + +msgid "WinBox is no longer supported" +msgstr "WinBox non è più supportato" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Lo sviluppo del gestore WinBox si è interrotto nel 2022 per mancanza di manutentori. Poiché i nostri sforzi sono rivolti a rendere 86Box ancora migliore, abbiamo deciso di non supportare più WinBox come gestore.\n\nNon saranno forniti ulteriori aggiornamenti tramite WinBox e si potrebbe riscontrare un comportamento non corretto se si continua a utilizzarlo con versioni più recenti di 86Box. Tutte le segnalazioni di bug relative al comportamento di WinBox saranno chiuse in quanto non valide.\n\nPer un elenco di altri gestori utilizzabili, visitare 86box.net." diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index ebcaf9cfb..5eb5d23c1 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -1224,3 +1224,9 @@ msgstr "速い" msgid "&Auto-pause on focus loss" msgstr "フォーカスが奪われると自動停止(&A)" + +msgid "WinBox is no longer supported" +msgstr "WinBoxはサポート終了" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "WinBoxマネージャーの開発は、メンテナ不足のため2022年に停止しました。86Boxをより良いものにするため、WinBoxをマネージャーとしてサポートしないことを決定しました。\n\nWinBoxを使ったアップデートは今後提供されませんし、86Boxの新しいバージョンでWinBoxを使い続けると、正しくない動作に遭遇するかもしれません。WinBoxの動作に関連するバグレポートは無効としてクローズされます。\n\n86box.netに他のマネージャのリストがあります。" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index 949548ed1..2eaf53b2e 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -1224,3 +1224,9 @@ msgstr "빠른" msgid "&Auto-pause on focus loss" msgstr "집중력 저하 시 자동 일시 중지(&A)" + +msgid "WinBox is no longer supported" +msgstr "WinBox는 더 이상 지원되지 않습니다" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "WinBox 매니저의 개발은 유지 관리자의 부족으로 인해 2022년에 중단되었습니다. 86Box를 더욱 개선하기 위한 노력의 일환으로 WinBox 매니저를 더 이상 지원하지 않기로 결정했습니다.\n\nWinBox를 통해 더 이상의 업데이트는 제공되지 않으며, 최신 버전의 86Box를 계속 사용할 경우 잘못된 동작이 발생할 수 있습니다. WinBox 동작과 관련된 모든 버그 보고는 유효하지 않은 것으로 종료됩니다.\n\n사용할 수 있는 다른 관리자 목록을 보려면 86box.net으로 이동하세요." diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index eb7a13e4e..583774ab4 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -1224,3 +1224,9 @@ msgstr "Szybki" msgid "&Auto-pause on focus loss" msgstr "&Automatyczna pauza po utracie fokusu" + +msgid "WinBox is no longer supported" +msgstr "WinBox nie jest już wspierany" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Rozwój menedżera WinBox został zatrzymany w 2022 roku z powodu braku opiekunów. Ponieważ kierujemy nasze wysiłki na uczynienie 86Box jeszcze lepszym, podjęliśmy decyzję o zaprzestaniu wspierania WinBox jako menedżera.\n\nŻadne dalsze aktualizacje nie będą dostarczane za pośrednictwem WinBox i możesz napotkać nieprawidłowe zachowanie, jeśli będziesz go nadal używać z nowszymi wersjami 86Box. Wszelkie zgłoszenia błędów związane z działaniem WinBox zostaną zamknięte jako nieważne.\n\nLista innych menedżerów, z których można korzystać, znajduje się na stronie 86box.net." diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 148ca716c..8ee668a1d 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -1224,3 +1224,9 @@ msgstr "Rápido" msgid "&Auto-pause on focus loss" msgstr "Pausa &automática ao perder o foco" + +msgid "WinBox is no longer supported" +msgstr "O WinBox não é mais suportado" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "O desenvolvimento do gerenciador WinBox foi interrompido em 2022 devido à falta de mantenedores. Conforme direcionamos nossos esforços para tornar o 86Box ainda melhor, tomamos a decisão de não oferecer mais suporte ao WinBox como gerenciador.\n\nAtualizações não serão mais fornecidas através do WinBox, e você poderá encontrar comportamentos incorretos caso continue a usá-lo com versões mais recentes do 86Box. Quaisquer relatórios de bugs relacionados ao comportamento do WinBox serão fechados como inválidos.\n\nAcesse 86box.net para obter uma lista de outros gerenciadores que você pode usar." diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index e309d91bf..6ae146eaf 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -1224,3 +1224,9 @@ msgstr "Rápido" msgid "&Auto-pause on focus loss" msgstr "Pausa &automática na perda de focagem" + +msgid "WinBox is no longer supported" +msgstr "O WinBox não é mais suportado" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "O desenvolvimento do gerenciador WinBox parou em 2022 devido à falta de mantenedores. Como direcionamos nossos esforços para tornar o 86Box ainda melhor, tomamos a decisão de não mais suportar o WinBox como um gerenciador.\n\nNão serão fornecidas mais actualizações através do WinBox, e poderá encontrar um comportamento incorreto se continuar a usá-lo com versões mais recentes do 86Box. Quaisquer relatórios de erros relacionados com o comportamento do WinBox serão fechados como inválidos.\n\nVá a 86box.net para uma lista de outros gestores que pode utilizar." diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index 4aa99eb87..cbeeafdd5 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -1314,3 +1314,9 @@ msgstr "Быстрый" msgid "&Auto-pause on focus loss" msgstr "&Автопауза при потере фокуса" + +msgid "WinBox is no longer supported" +msgstr "WinBox больше не поддерживается" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Разработка менеджера WinBox прекратилась в 2022 году из-за отсутствия сопровождающих. Поскольку мы направляем наши усилия на то, чтобы сделать 86Box еще лучше, мы приняли решение больше не поддерживать WinBox в качестве менеджера.\n\nWinBox больше не будет обновляться, и вы можете столкнуться с некорректным поведением, если продолжите использовать его с новыми версиями 86Box. Любые сообщения об ошибках, связанных с поведением WinBox, будут закрыты как недействительные.\n\nПерейдите на сайт 86box.net для получения списка других менеджеров, которые вы можете использовать." diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index 376723efa..cdcfcbfe8 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -1224,3 +1224,9 @@ msgstr "Rýchly" msgid "&Auto-pause on focus loss" msgstr "&Automatická pauza pri strate fokusu okna" + +msgid "WinBox is no longer supported" +msgstr "WinBox už nie je podporovaný" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Vývoj správcu WinBox sa zastavil v roku 2022 z dôvodu nedostatku správcov. Keďže naše úsilie smerujeme k ešte lepšiemu systému 86Box, rozhodli sme sa, že správca WinBox už nebude podporovaný.\n\nProstredníctvom WinBoxu nebudú poskytované žiadne ďalšie aktualizácie a v prípade, že ho budete naďalej používať s novšími verziami programu 86Box, môžete sa stretnúť s nesprávnym správaním. Všetky hlásenia o chybách týkajúce sa správania WinBoxu budú uzavreté ako neplatné.\n\nNa stránke 86box.net nájdete zoznam iných správcov, ktoré môžete používať." diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index cde1011d1..d56318aed 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -1224,3 +1224,9 @@ msgstr "Hitri" msgid "&Auto-pause on focus loss" msgstr "&Samodejni premor ob izgubi fokusa" + +msgid "WinBox is no longer supported" +msgstr "WinBox ni več podprt" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Razvoj upravitelja WinBox se je leta 2022 ustavil zaradi pomanjkanja vzdrževalcev. Ker svoja prizadevanja usmerjamo v še boljše delovanje programa 86Box, smo se odločili, da programa WinBox kot upravitelja ne bomo več podpirali.\n\nWinBox ne bo več zagotavljal posodobitev, če ga boste še naprej uporabljali z novejšimi različicami programa 86Box, pa lahko naletite na nepravilno obnašanje. Vsa poročila o napakah, povezana z obnašanjem programa WinBox, bodo zaprta kot neveljavna.\n\nZa seznam drugih upraviteljev, ki jih lahko uporabite, obiščite spletno stran 86box.net." diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index 0989218e5..1af206659 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -1224,3 +1224,9 @@ msgstr "Hızlı" msgid "&Auto-pause on focus loss" msgstr "&Odak kaybında otomatik duraklatma" + +msgid "WinBox is no longer supported" +msgstr "WinBox artık desteklenmiyor" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "WinBox yöneticisinin geliştirilmesi, bakımcı eksikliği nedeniyle 2022 yılında durduruldu. Çabalarımızı 86Box'ı daha da iyi hale getirmeye yönlendirdiğimiz için, WinBox'ı artık bir yönetici olarak desteklememe kararı aldık.\n\nWinBox aracılığıyla daha fazla güncelleme sağlanmayacak ve 86Box'ın daha yeni sürümleriyle kullanmaya devam ederseniz hatalı davranışlarla karşılaşabilirsiniz. WinBox davranışıyla ilgili tüm hata raporları geçersiz olarak kapatılacaktır.\n\nKullanabileceğiniz diğer yöneticilerin bir listesi için 86box.net adresine gidin." diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index 76796a57a..860116fe8 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -1224,3 +1224,9 @@ msgstr "Швидкий" msgid "&Auto-pause on focus loss" msgstr "&Автопауза при втраті фокусу" + +msgid "WinBox is no longer supported" +msgstr "WinBox більше не підтримується" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Розробку менеджера WinBox було припинено у 2022 році через брак супровідників. Оскільки ми спрямовуємо наші зусилля на те, щоб зробити 86Box ще кращим, ми прийняли рішення більше не підтримувати WinBox як менеджер.\n\nБільше ніяких оновлень не буде надаватися через WinBox, і ви можете зіткнутися з некоректною поведінкою, якщо продовжите використовувати його з новими версіями 86Box. Будь-які повідомлення про помилки, пов'язані з поведінкою WinBox, будуть закриті як недійсні.\n\nПерейдіть на 86box.net для отримання списку інших менеджерів, які ви можете використовувати." diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index dd819deb0..eade3f77e 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -1225,3 +1225,8 @@ msgstr "快" msgid "&Auto-pause on focus loss" msgstr "失去焦点时自动暂停(&A)" +msgid "WinBox is no longer supported" +msgstr "WinBox 不再受支持" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "由于缺乏维护者,WinBox 管理器的开发工作于 2022 年停止。由于我们正努力将 86Box 做得更好,因此决定不再支持 WinBox 作为管理器。\n\nWinBox将不再提供更新,如果你继续在86Box的新版本中使用WinBox,可能会遇到不正确的行为。任何与 WinBox 行为相关的错误报告都将被视为无效而关闭。\n\n请访问 86box.net,查看你可以使用的其他管理器列表。" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index aef164704..0e61363f4 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -1224,3 +1224,9 @@ msgstr "快" msgid "&Auto-pause on focus loss" msgstr "失去焦點時自動暫停(&A)" + +msgid "WinBox is no longer supported" +msgstr "WinBox is no longer supported" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index cafd4fd8e..197ca980c 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -58,6 +58,7 @@ extern "C" { # include <86box/discord.h> #endif #include <86box/gdbstub.h> +#include <86box/version.h> } #include @@ -217,6 +218,28 @@ main(int argc, char *argv[]) return 6; } +#ifdef Q_OS_WINDOWS +# if !defined(EMU_BUILD_NUM) || (EMU_BUILD_NUM != 5624) + HWND winbox = FindWindow("TWinBoxMain", NULL); + if (winbox && + FindWindowEx(winbox, NULL, "TToolBar", NULL) && + FindWindowEx(winbox, NULL, "TListBox", NULL) && + FindWindowEx(winbox, NULL, "TStatusBar", NULL) && + (winbox = FindWindowEx(winbox, NULL, "TPageControl", NULL)) && /* holds a TTabSheet even on VM pages */ + FindWindowEx(winbox, NULL, "TTabSheet", NULL)) +# endif + { + QMessageBox warningbox(QMessageBox::Icon::Warning, QObject::tr("WinBox is no longer supported"), + QObject::tr("Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use."), + QMessageBox::NoButton); + warningbox.addButton(QObject::tr("Continue"), QMessageBox::AcceptRole); + warningbox.addButton(QObject::tr("Exit"), QMessageBox::RejectRole); + warningbox.exec(); + if (warningbox.result() == QDialog::Accepted) + return 0; + } +#endif + if (settings_only) { Settings settings; if (settings.exec() == QDialog::Accepted) { diff --git a/src/video/vid_ddc.c b/src/video/vid_ddc.c index 387edaeb8..c51093319 100644 --- a/src/video/vid_ddc.c +++ b/src/video/vid_ddc.c @@ -169,7 +169,7 @@ ddc_init(void *i2c) STANDARD_TIMING(standard_timings[2], 1366, STD_ASPECT_16_9, 60); /* 1360x768 (closest to 1366x768) */ STANDARD_TIMING(standard_timings[3], 1440, STD_ASPECT_16_10, 60); /* 1440x900 */ STANDARD_TIMING(standard_timings[4], 1600, STD_ASPECT_16_9, 60); /* 1600x900 */ - STANDARD_TIMING(standard_timings[5], 1680, STD_ASPECT_16_10, 60); /* 1680x1050 */ + STANDARD_TIMING(standard_timings[5], 1600, STD_ASPECT_4_3, 60); /* 1600x1200 */ STANDARD_TIMING(standard_timings[6], 1920, STD_ASPECT_16_9, 60); /* 1920x1080 */ STANDARD_TIMING(standard_timings[7], 2048, STD_ASPECT_4_3, 60); /* 2048x1536 */ @@ -210,12 +210,12 @@ ddc_init(void *i2c) /* High refresh rate timings (VGA is limited to 85 Hz) */ edid->ext_descriptors[1].tag = 0xfa; /* standard timing identifiers */ #define ext_standard_timings0 ext_descriptors[1].ext_standard_timings.timings - STANDARD_TIMING(ext_standard_timings0[0], 640, STD_ASPECT_4_3, 90); /* 640x480 @ 90 Hz */ - STANDARD_TIMING(ext_standard_timings0[1], 640, STD_ASPECT_4_3, 120); /* 640x480 @ 120 Hz */ - STANDARD_TIMING(ext_standard_timings0[2], 800, STD_ASPECT_4_3, 90); /* 800x600 @ 90 Hz */ - STANDARD_TIMING(ext_standard_timings0[3], 800, STD_ASPECT_4_3, 120); /* 800x600 @ 120 Hz */ - STANDARD_TIMING(ext_standard_timings0[4], 1024, STD_ASPECT_4_3, 90); /* 1024x768 @ 90 Hz */ - STANDARD_TIMING(ext_standard_timings0[5], 1280, STD_ASPECT_5_4, 90); /* 1280x1024 @ 90 Hz */ + STANDARD_TIMING(ext_standard_timings0[0], 640, STD_ASPECT_4_3, 85); /* 640x480 @ 85 Hz */ + STANDARD_TIMING(ext_standard_timings0[1], 800, STD_ASPECT_4_3, 85); /* 800x600 @ 85 Hz */ + STANDARD_TIMING(ext_standard_timings0[2], 1024, STD_ASPECT_4_3, 85); /* 1024x768 @ 85 Hz */ + STANDARD_TIMING(ext_standard_timings0[3], 1280, STD_ASPECT_5_4, 85); /* 1280x1024 @ 85 Hz */ + STANDARD_TIMING(ext_standard_timings0[4], 1600, STD_ASPECT_4_3, 85); /* 1600x1200 @ 85 Hz */ + STANDARD_TIMING(ext_standard_timings0[5], 1680, STD_ASPECT_16_10, 60); /* 1680x1050 @ 60 Hz (previously in standard timings) */ edid->ext_descriptors[1].ext_standard_timings.padding = 0x0a; for (uint8_t c = 128; c < 255; c++) From a3b8e0f1b2dfaf4d9815780a1d75ff53ecb8a9c7 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 10 Mar 2024 18:17:32 -0300 Subject: [PATCH 653/936] DDC: Clarify some comments --- src/video/vid_ddc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/video/vid_ddc.c b/src/video/vid_ddc.c index c51093319..787e7560e 100644 --- a/src/video/vid_ddc.c +++ b/src/video/vid_ddc.c @@ -138,12 +138,12 @@ ddc_init(void *i2c) memset(&edid->magic[1], 0xff, sizeof(edid->magic) - 2); - edid->mfg[0] = 0x09; /* manufacturer "BOX" (apparently unassigned by UEFI) */ + edid->mfg[0] = 0x09; /* manufacturer "BOX" (currently unassigned by UEFI) */ edid->mfg[1] = 0xf8; edid->mfg_week = 48; edid->mfg_year = 2020 - 1990; edid->edid_version = 0x01; - edid->edid_rev = 0x04; /* EDID 1.4, required for Xorg on Linux to use the preferred mode timing */ + edid->edid_rev = 0x04; /* EDID 1.4, required for Xorg on newer Linux to use the preferred mode timing instead of maxing out */ edid->input_params = 0x0e; /* analog input; separate sync; composite sync; sync on green */ edid->horiz_size = round(horiz_mm / 10.0); @@ -207,7 +207,7 @@ ddc_init(void *i2c) /* Detailed timing for 1366x768 */ DETAILED_TIMING(ext_detailed_timings[0], 85500, 1366, 768, 426, 30, 70, 143, 3, 3); - /* High refresh rate timings (VGA is limited to 85 Hz) */ + /* High refresh rate timings (within the standard 85 Hz VGA limit) */ edid->ext_descriptors[1].tag = 0xfa; /* standard timing identifiers */ #define ext_standard_timings0 ext_descriptors[1].ext_standard_timings.timings STANDARD_TIMING(ext_standard_timings0[0], 640, STD_ASPECT_4_3, 85); /* 640x480 @ 85 Hz */ From 9f5d2a46bdb21a1ed5ee5a8e692f199b6d1a9742 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 11 Mar 2024 16:35:57 +0600 Subject: [PATCH 654/936] Platform-specific netwok sockets --- src/include/86box/plat_netsocket.h | 24 +++++ src/qt/CMakeLists.txt | 2 +- src/win/win_netsocket.c | 148 +++++++++++++++++++++++++++++ 3 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 src/include/86box/plat_netsocket.h create mode 100644 src/win/win_netsocket.c diff --git a/src/include/86box/plat_netsocket.h b/src/include/86box/plat_netsocket.h new file mode 100644 index 000000000..269f399ff --- /dev/null +++ b/src/include/86box/plat_netsocket.h @@ -0,0 +1,24 @@ +#ifndef _WIN32 +#define SOCKET int +#else +#include +#include +#endif + +enum net_socket_types +{ + /* Only TCP is supported for now. */ + NET_SOCKET_TCP +}; + +SOCKET plat_netsocket_create(int type); +SOCKET plat_netsocket_create_server(int type, unsigned short port); +void plat_netsocket_close(SOCKET socket); + +SOCKET plat_netsocket_accept(SOCKET socket); +int plat_netsocket_connected(SOCKET socket); +int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short port); + +/* Returns 0 in case of inability to send. -1 in case of errors. */ +int plat_netsocket_send(SOCKET socket, const unsigned char* data, unsigned int size, int *wouldblock); +int plat_netsocket_receive(SOCKET socket, unsigned char* data, unsigned int size, int *wouldblock); \ No newline at end of file diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 4f073cf4a..48b377044 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -221,7 +221,7 @@ if(WIN32 AND NOT MINGW) endif() if(WIN32) - target_sources(plat PRIVATE ../win/win_serial_passthrough.c) + target_sources(plat PRIVATE ../win/win_serial_passthrough.c ../win/win_netsocket.c) else() target_sources(plat PRIVATE ../unix/unix_serial_passthrough.c) endif() diff --git a/src/win/win_netsocket.c b/src/win/win_netsocket.c new file mode 100644 index 000000000..45ca1f760 --- /dev/null +++ b/src/win/win_netsocket.c @@ -0,0 +1,148 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include +#include +#include + +#include <86box/86box.h> +#include <86box/log.h> +#include <86box/timer.h> +#include <86box/plat.h> +#include <86box/device.h> +#include <86box/plat_netsocket.h> +#include <86box/ui.h> + +#include +#include +#include + +SOCKET plat_netsocket_create(int type) +{ + SOCKET socket = -1; + u_long yes = 1; + + if (type != NET_SOCKET_TCP) + return -1; + + socket = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); + if (socket == INVALID_SOCKET) + return -1; + + ioctlsocket(socket, FIONBIO, &yes); + + return socket; +} + +SOCKET plat_netsocket_create_server(int type, unsigned short port) +{ + struct sockaddr_in sock_addr; + SOCKET socket = plat_netsocket_create(type); + if (socket == INVALID_SOCKET) + return (SOCKET)-1; + + memset(&sock_addr, 0, sizeof(struct sockaddr_in)); + + sock_addr.sin_family = AF_INET; + sock_addr.sin_addr.s_addr = INADDR_ANY; + sock_addr.sin_port = port; + + if (bind(socket, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { + plat_netsocket_close(socket); + return (SOCKET)-1; + } + + if (listen(socket, 5) == SOCKET_ERROR) { + plat_netsocket_close(socket); + return (SOCKET)-1; + } + + return socket; +} + +void plat_netsocket_close(SOCKET socket) +{ + closesocket((SOCKET)socket); +} + +SOCKET plat_netsocket_accept(SOCKET socket) +{ + SOCKET clientsocket = accept(socket, NULL, NULL); + + if (clientsocket == INVALID_SOCKET) + return -1; + + return clientsocket; +} + +int plat_netsocket_connected(SOCKET socket) +{ + struct sockaddr addr; + socklen_t len = sizeof(struct sockaddr); + if (getpeername(socket, &addr, &len) == SOCKET_ERROR) + return 0; + + return 1; +} + +int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short port) +{ + struct sockaddr_in sock_addr; + int res = -1; + + sock_addr.sin_family = AF_INET; + sock_addr.sin_addr.s_addr = inet_addr(hostname); + sock_addr.sin_port = htons(port); + + if (sock_addr.sin_addr.s_addr == -1 || sock_addr.sin_addr.s_addr == 0) { + struct hostent *hp; + + hp = gethostbyname(hostname); + + if (hp) + memcpy(&sock_addr.sin_addr.s_addr, hp->h_addr_list[0], hp->h_length); + else + return -1; + } + + res = connect(socket, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)); + + if (res == SOCKET_ERROR) { + int error = WSAGetLastError(); + + if (error == WSAEISCONN) + return 0; + } + return res; +} + +int plat_netsocket_send(SOCKET socket, const unsigned char* data, unsigned int size, int *wouldblock) +{ + int res = send(socket, (const char*)data, size, 0); + + if (res == SOCKET_ERROR) { + int error = WSAGetLastError(); + + if (wouldblock) + *wouldblock = !!(error == WSAEWOULDBLOCK); + + return -1; + } + return res; +} + +int plat_netsocket_receive(SOCKET socket, unsigned char* data, unsigned int size, int *wouldblock) +{ + int res = recv(socket, (char*)data, size, 0); + + if (res == SOCKET_ERROR) { + int error = WSAGetLastError(); + + if (wouldblock) + *wouldblock = !!(error == WSAEWOULDBLOCK); + + return -1; + } + return res; +} From 45e76af96fc298e9f1695dd33d9ffb6d2d24d1ba Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 11 Mar 2024 19:25:13 +0500 Subject: [PATCH 655/936] Disable the LBA Enhancer checkbox when the ROM isn't available --- src/qt/qt_settingsstoragecontrollers.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt/qt_settingsstoragecontrollers.cpp b/src/qt/qt_settingsstoragecontrollers.cpp index 0f19d46fc..bc2be70cd 100644 --- a/src/qt/qt_settingsstoragecontrollers.cpp +++ b/src/qt/qt_settingsstoragecontrollers.cpp @@ -206,6 +206,7 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId) ui->checkBoxCassette->setEnabled(false); } + ui->checkBoxLbaEnhancer->setEnabled(device_available(&lba_enhancer_device)); ui->checkBoxLbaEnhancer->setChecked(lba_enhancer_enabled > 0 && device_available(&lba_enhancer_device)); ui->pushButtonConfigureLbaEnhancer->setEnabled(ui->checkBoxLbaEnhancer->isChecked()); } From 8f9f5b2efbb56255ef28d256d17040403e932c44 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 11 Mar 2024 19:25:45 +0500 Subject: [PATCH 656/936] Disable the XGA checkbox when ROMs aren't available --- src/qt/qt_settingsdisplay.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/qt/qt_settingsdisplay.cpp b/src/qt/qt_settingsdisplay.cpp index fcb70f8c5..4d8919a73 100644 --- a/src/qt/qt_settingsdisplay.cpp +++ b/src/qt/qt_settingsdisplay.cpp @@ -159,15 +159,16 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) bool videoCardHas8514 = ((videoCard[0] == VID_INTERNAL) ? machine_has_flags(machineId, MACHINE_VIDEO_8514A) : (video_card_get_flags(videoCard[0]) == VIDEO_FLAG_TYPE_8514)); bool videoCardHasXga = ((videoCard[0] == VID_INTERNAL) ? machine_has_flags(machineId, MACHINE_VIDEO_XGA) : (video_card_get_flags(videoCard[0]) == VIDEO_FLAG_TYPE_XGA)); - ui->checkBox8514->setEnabled((machineHasIsa16 || machineHasMca) && !videoCardHas8514); - if (machineHasIsa16 || machineHasMca) - ui->checkBox8514->setChecked(ibm8514_standalone_enabled && !videoCardHas8514); + bool machineSupports8514 = ((machineHasIsa16 || machineHasMca) && !videoCardHas8514); + bool machineSupportsXga = (((machineHasIsa16 && device_available(&xga_isa_device)) || (machineHasMca && device_available(&xga_device))) && !videoCardHasXga); - ui->checkBoxXga->setEnabled((machineHasIsa16 || machineHasMca) && !videoCardHasXga); - if (machineHasIsa16 || machineHasMca) - ui->checkBoxXga->setChecked(xga_standalone_enabled && !videoCardHasXga); + ui->checkBox8514->setEnabled(machineSupports8514); + ui->checkBox8514->setChecked(ibm8514_standalone_enabled && machineSupports8514); - ui->pushButtonConfigureXga->setEnabled((machineHasIsa16 || machineHasMca) && ui->checkBoxXga->isChecked() && !videoCardHasXga); + ui->checkBoxXga->setEnabled(machineSupportsXga); + ui->checkBoxXga->setChecked(xga_standalone_enabled && machineSupportsXga); + + ui->pushButtonConfigureXga->setEnabled(ui->checkBoxXga->isEnabled() && ui->checkBoxXga->isChecked()); int c = 2; From 10e0dbaafa4e735ca48f2fff33be4f934ccd683d Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 01:55:17 +0600 Subject: [PATCH 657/936] Netsocket changes --- src/include/86box/plat_netsocket.h | 2 +- src/win/win_netsocket.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/include/86box/plat_netsocket.h b/src/include/86box/plat_netsocket.h index 269f399ff..9a2181ae1 100644 --- a/src/include/86box/plat_netsocket.h +++ b/src/include/86box/plat_netsocket.h @@ -16,7 +16,7 @@ SOCKET plat_netsocket_create_server(int type, unsigned short port); void plat_netsocket_close(SOCKET socket); SOCKET plat_netsocket_accept(SOCKET socket); -int plat_netsocket_connected(SOCKET socket); +int plat_netsocket_connected(SOCKET socket); /* Returns -1 on trouble. */ int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short port); /* Returns 0 in case of inability to send. -1 in case of errors. */ diff --git a/src/win/win_netsocket.c b/src/win/win_netsocket.c index 45ca1f760..044a59860 100644 --- a/src/win/win_netsocket.c +++ b/src/win/win_netsocket.c @@ -80,6 +80,9 @@ int plat_netsocket_connected(SOCKET socket) { struct sockaddr addr; socklen_t len = sizeof(struct sockaddr); + + + if (getpeername(socket, &addr, &len) == SOCKET_ERROR) return 0; @@ -113,6 +116,8 @@ int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short p if (error == WSAEISCONN) return 0; + + res = -1; } return res; } From 3aa81066d3c01b69bf546521d72045a1617d3543 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 11 Mar 2024 21:39:16 +0100 Subject: [PATCH 658/936] Solved the IRQ mess of ESDI MCA. This should also fix the timing/fatal's on ramdisk speeds using said controller on NT and OS/2 on MCA. --- src/disk/hdc_esdi_mca.c | 95 ++++++++++++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 26 deletions(-) diff --git a/src/disk/hdc_esdi_mca.c b/src/disk/hdc_esdi_mca.c index 02f054ca2..3714f93d4 100644 --- a/src/disk/hdc_esdi_mca.c +++ b/src/disk/hdc_esdi_mca.c @@ -92,7 +92,7 @@ #define BIOS_FILE_L "roms/hdd/esdi/90x8969.bin" #define BIOS_FILE_H "roms/hdd/esdi/90x8970.bin" -#define ESDI_TIME 512.0 +#define ESDI_TIME 500.0 #define CMD_ADAPTER 0 typedef struct esdi_drive_t { @@ -113,6 +113,7 @@ typedef struct esdi_t { uint8_t basic_ctrl; uint8_t status; uint8_t irq_status; + int irq_ena_disable; int irq_in_progress; int cmd_req_in_progress; int cmd_pos; @@ -218,14 +219,26 @@ esdi_mca_log(const char *fmt, ...) static __inline void set_irq(esdi_t *dev) { + dev->irq_ena_disable = 1; + esdi_mca_log("Set IRQ 14: bit=%x, cmd=%02x.\n", dev->basic_ctrl & CTRL_IRQ_ENA, dev->command); if (dev->basic_ctrl & CTRL_IRQ_ENA) - picint(1 << 14); + picint_common(1 << ESDI_IRQCHAN, PIC_IRQ_EDGE, 1, NULL); } static __inline void -clear_irq(UNUSED(esdi_t *dev)) +clear_irq(esdi_t *dev) { - picintc(1 << 14); + dev->irq_ena_disable = 0; + esdi_mca_log("Clear IRQ 14: bit=%x, cmd=%02x.\n", dev->basic_ctrl & CTRL_IRQ_ENA, dev->command); + if (dev->basic_ctrl & CTRL_IRQ_ENA) + picint_common(1 << ESDI_IRQCHAN, PIC_IRQ_EDGE, 0, NULL); +} + +static __inline void +update_irq(esdi_t *dev) +{ + uint8_t set = (dev->basic_ctrl & CTRL_IRQ_ENA) && dev->irq_ena_disable; + picint_common(1 << ESDI_IRQCHAN, PIC_IRQ_EDGE, set, NULL); } static void @@ -235,10 +248,11 @@ esdi_mca_set_callback(esdi_t *dev, double callback) return; } - if (callback) { - timer_on_auto(&dev->timer, callback); - } else { + if (callback == 0.0) { + esdi_mca_log("Callback Stopped.\n"); timer_stop(&dev->timer); + } else { + timer_on_auto(&dev->timer, callback); } } @@ -317,9 +331,9 @@ complete_command_status(esdi_t *dev) { dev->status_len = 7; if (dev->cmd_dev == ATTN_DEVICE_0) - dev->status_data[0] = CMD_READ | STATUS_LEN(7) | STATUS_DEVICE(0); + dev->status_data[0] = dev->command | STATUS_LEN(7) | STATUS_DEVICE(0); else - dev->status_data[0] = CMD_READ | STATUS_LEN(7) | STATUS_DEVICE(1); + dev->status_data[0] = dev->command | STATUS_LEN(7) | STATUS_DEVICE(1); dev->status_data[1] = 0x0000; /*Error bits*/ dev->status_data[2] = 0x1900; /*Device status*/ dev->status_data[3] = 0; /*Number of blocks left to do*/ @@ -330,15 +344,12 @@ complete_command_status(esdi_t *dev) } #define ESDI_ADAPTER_ONLY() \ - do { \ if (dev->cmd_dev != ATTN_HOST_ADAPTER) { \ cmd_unsupported(dev); \ return; \ - } \ - } while (0) + } #define ESDI_DRIVE_ONLY() \ - do { \ if (dev->cmd_dev != ATTN_DEVICE_0 && dev->cmd_dev != ATTN_DEVICE_1) { \ cmd_unsupported(dev); \ return; \ @@ -346,8 +357,7 @@ complete_command_status(esdi_t *dev) if (dev->cmd_dev == ATTN_DEVICE_0) \ drive = &dev->drives[0]; \ else \ - drive = &dev->drives[1]; \ - } while (0) + drive = &dev->drives[1]; static void esdi_callback(void *priv) @@ -357,19 +367,19 @@ esdi_callback(void *priv) int val; double cmd_time = 0.0; - esdi_mca_set_callback(dev, 0); - /* If we are returning from a RESET, handle this first. */ if (dev->in_reset) { + esdi_mca_log("ESDI reset.\n"); dev->in_reset = 0; dev->status = STATUS_IRQ; dev->irq_status = IRQ_HOST_ADAPTER | IRQ_RESET_COMPLETE; - return; } + esdi_mca_log("Command=%02x.\n", dev->command); switch (dev->command) { case CMD_READ: + case 0x15: ESDI_DRIVE_ONLY(); if (!drive->present) { @@ -379,7 +389,8 @@ esdi_callback(void *priv) switch (dev->cmd_state) { case 0: - dev->rba = (dev->cmd_data[2] | (dev->cmd_data[3] << 16)) & 0x0fffffff; + if (dev->command == CMD_READ) + dev->rba = (dev->cmd_data[2] | (dev->cmd_data[3] << 16)) & 0x0fffffff; dev->sector_pos = 0; dev->sector_count = dev->cmd_data[1]; @@ -873,7 +884,7 @@ static uint8_t esdi_read(uint16_t port, void *priv) { esdi_t *dev = (esdi_t *) priv; - uint8_t ret = 0xff; + uint8_t ret = 0x00; switch (port & 7) { case 2: /*Basic status register*/ @@ -890,6 +901,7 @@ esdi_read(uint16_t port, void *priv) break; } + esdi_mca_log("ESDI: rr(%04x, %02x)\n", port & 7, ret); return ret; } @@ -897,6 +909,7 @@ static void esdi_write(uint16_t port, uint8_t val, void *priv) { esdi_t *dev = (esdi_t *) priv; + uint8_t old; esdi_mca_log("ESDI: wr(%04x, %02x)\n", port & 7, val); @@ -906,11 +919,14 @@ esdi_write(uint16_t port, uint8_t val, void *priv) dev->in_reset = 1; esdi_mca_set_callback(dev, ESDI_TIME * 50); dev->status = STATUS_BUSY; + } else if (!(dev->basic_ctrl & CTRL_RESET) && (val & CTRL_RESET)) { + esdi_mca_set_callback(dev, 0.0); + dev->status = STATUS_BUSY; } + old = dev->basic_ctrl; dev->basic_ctrl = val; - - if (!(dev->basic_ctrl & CTRL_IRQ_ENA)) - picintc(1 << 14); + if ((val & CTRL_IRQ_ENA) && !(old & CTRL_IRQ_ENA)) + update_irq(dev); break; case 3: /*Attention register*/ @@ -945,6 +961,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv) break; case ATTN_DEVICE_0: + esdi_mca_log("ATTN Device 0.\n"); switch (val & ATTN_REQ_MASK) { case ATTN_CMD_REQ: if (dev->cmd_req_in_progress) @@ -957,6 +974,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv) break; case ATTN_EOI: + esdi_mca_log("EOI.\n"); dev->irq_in_progress = 0; dev->status &= ~STATUS_IRQ; clear_irq(dev); @@ -1112,15 +1130,40 @@ esdi_mca_write(int port, uint8_t val, void *priv) break; } + if (!(dev->pos_regs[3] & 8)) { + switch (dev->pos_regs[3] & 7) { + case 2: + dev->bios = 0xc8000; + break; + case 3: + dev->bios = 0xcc000; + break; + case 4: + dev->bios = 0xd0000; + break; + case 5: + dev->bios = 0xd4000; + break; + case 6: + dev->bios = 0xd8000; + break; + case 7: + dev->bios = 0xdc000; + break; + default: + break; + } + } else + dev->bios = 0; + if (dev->pos_regs[2] & 1) { io_sethandler(ESDI_IOADDR_PRI, 8, esdi_read, esdi_readw, NULL, esdi_write, esdi_writew, NULL, dev); - if (!(dev->pos_regs[3] & 8)) { + if (dev->bios) { mem_mapping_enable(&dev->bios_rom.mapping); - mem_mapping_set_addr(&dev->bios_rom.mapping, - ((dev->pos_regs[3] & 7) * 0x4000) + 0xc0000, 0x4000); + mem_mapping_set_addr(&dev->bios_rom.mapping, dev->bios, 0x4000); } /* Say hello. */ From d51ba85814a3e4e6aee0782dd2ce71c248d33f98 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 14:27:19 +0600 Subject: [PATCH 659/936] TCP/IP support --- src/device/serial.c | 6 + src/include/86box/serial.h | 1 + src/network/net_modem.c | 241 ++++++++++++++++++++++++++++++++++++- src/qt/CMakeLists.txt | 2 +- src/unix/unix_netsocket.c | 194 +++++++++++++++++++++++++++++ src/win/win_netsocket.c | 45 ++++++- 6 files changed, 479 insertions(+), 10 deletions(-) create mode 100644 src/unix/unix_netsocket.c diff --git a/src/device/serial.c b/src/device/serial.c index b61c8304a..ab26fc622 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -451,6 +451,12 @@ serial_set_ri(serial_t *dev, uint8_t enabled) } } +int +serial_get_ri(serial_t *dev) +{ + return !!(dev->msr & (1 << 6)); +} + void serial_set_clock_src(serial_t *dev, double clock_src) { diff --git a/src/include/86box/serial.h b/src/include/86box/serial.h index 99b39f56b..c2312f562 100644 --- a/src/include/86box/serial.h +++ b/src/include/86box/serial.h @@ -137,6 +137,7 @@ extern void serial_set_cts(serial_t *dev, uint8_t enabled); extern void serial_set_dsr(serial_t *dev, uint8_t enabled); extern void serial_set_dcd(serial_t *dev, uint8_t enabled); extern void serial_set_ri(serial_t *dev, uint8_t enabled); +extern int serial_get_ri(serial_t *dev); extern const device_t ns8250_device; extern const device_t ns8250_pcjr_device; diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 131b87653..6e6635ed8 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -20,6 +20,7 @@ #include <86box/plat.h> #include <86box/network.h> #include <86box/plat_unused.h> +#include <86box/plat_netsocket.h> /* From RFC 1055. */ #define END 0300 /* indicates end of packet */ @@ -93,9 +94,17 @@ typedef struct modem_t bool connected, ringing; bool echo, numericresponse; + bool tcpIpMode, tcpIpConnInProgress; + uint32_t tcpIpConnCounter; int doresponse; int cmdpause; + int listen_port; + int ringtimer; + + SOCKET serversocket; + SOCKET clientsocket; + SOCKET waitingclientsocket; struct { bool binary[2]; @@ -309,7 +318,7 @@ modem_data_mode_process_byte(modem_t* modem, uint8_t data) if (modem->tx_count < 0x10000 && modem->connected) { modem->tx_pkt_ser_line[modem->tx_count++] = data; - if (data == END) { + if (data == END && !modem->tcpIpMode) { process_tx_packet(modem, modem->tx_pkt_ser_line, (uint32_t)modem->tx_count); modem->tx_count = 0; } @@ -321,6 +330,9 @@ host_to_modem_cb(void *priv) { modem_t* modem = (modem_t*)priv; + if (modem->in_warmup) + goto no_write_to_machine; + if ((modem->serial->type >= SERIAL_16550) && modem->serial->fifo_enabled) { if (fifo_get_full(modem->serial->rcvr_fifo)) { goto no_write_to_machine; @@ -441,6 +453,37 @@ modem_enter_idle_state(modem_t* modem) modem->ringing = false; modem->mode = MODEM_MODE_COMMAND; modem->in_warmup = 0; + modem->tcpIpConnInProgress = 0; + modem->tcpIpConnCounter = 0; + + if (modem->waitingclientsocket != -1) + plat_netsocket_close(modem->waitingclientsocket); + + if (modem->clientsocket != -1) + plat_netsocket_close(modem->clientsocket); + + modem->clientsocket = modem->waitingclientsocket = -1; + if (modem->serversocket != -1) { + modem->waitingclientsocket = plat_netsocket_accept(modem->serversocket); + while (modem->waitingclientsocket != -1) { + plat_netsocket_close(modem->waitingclientsocket); + modem->waitingclientsocket = plat_netsocket_accept(modem->serversocket); + } + plat_netsocket_close(modem->serversocket); + modem->serversocket = -1; + } + + if (modem->waitingclientsocket != -1) + plat_netsocket_close(modem->waitingclientsocket); + + modem->waitingclientsocket = -1; + modem->tcpIpMode = false; + modem->tcpIpConnInProgress = false; + + if (modem->listen_port) { + modem->serversocket = plat_netsocket_create_server(NET_SOCKET_TCP, modem->listen_port); + } + serial_set_cts(modem->serial, 1); serial_set_dsr(modem->serial, 1); serial_set_dcd(modem->serial, 0); @@ -454,6 +497,9 @@ modem_enter_connected_state(modem_t* modem) modem->mode = MODEM_MODE_DATA; modem->ringing = false; modem->connected = true; + modem->tcpIpMode = true; + plat_netsocket_close(modem->serversocket); + modem->serversocket = -1; memset(&modem->telClient, 0, sizeof(modem->telClient)); serial_set_dcd(modem->serial, 1); serial_set_ri(modem->serial, 0); @@ -488,15 +534,40 @@ void modem_dial(modem_t* modem, const char* str) { /* TODO: Port TCP/IP support from DOSBox. */ + modem->tcpIpConnCounter = 0; + modem->tcpIpMode = false; if (!strncmp(str, "0.0.0.0", sizeof("0.0.0.0") - 1)) { pclog("Turning on SLIP\n"); modem_enter_connected_state(modem); + modem->tcpIpMode = false; } else { - modem_send_res(modem, ResNOCARRIER); - modem_enter_idle_state(modem); + char buf[128] = ""; + const char *destination = buf; + strcpy(buf, str); + // Scan host for port + uint16_t port; + char * hasport = strrchr(buf,':'); + if (hasport) { + *hasport++ = 0; + port = (uint16_t)atoi(hasport); + } + else { + port = 23; + } + + modem->clientsocket = plat_netsocket_create(NET_SOCKET_TCP); + if (modem->clientsocket == -1) { + modem_send_res(modem, ResNOCARRIER); + modem_enter_idle_state(modem); + return; + } + + plat_netsocket_connect(modem->clientsocket, buf, port); + modem->tcpIpConnInProgress = 1; + modem->tcpIpConnCounter = 0; } } @@ -551,6 +622,16 @@ char *trim(char *str) return str; } +static const char *modem_get_address_from_phonebook(modem_t* modem, const char *input) { + int i = 0; + for (i = 0; i < modem->entries_num; i++) { + if (strcmp(input, modem->entries[i].phone) == 0) + return modem->entries[i].address; + } + + return NULL; +} + static void modem_do_command(modem_t* modem) { @@ -583,7 +664,9 @@ modem_do_command(modem_t* modem) char buffer[128]; char obuffer[128]; char * foundstr = &scanbuf[0]; + const char *mappedaddr = NULL; size_t i = 0; + if (*foundstr == 'T' || *foundstr == 'P') foundstr++; @@ -593,6 +676,13 @@ modem_do_command(modem_t* modem) } foundstr = trim(foundstr); + + mappedaddr = modem_get_address_from_phonebook(modem, foundstr); + if (mappedaddr) { + modem_dial(modem, mappedaddr); + return; + } + if (strlen(foundstr) >= 12) { // Check if supplied parameter only consists of digits bool isNum = true; @@ -860,6 +950,9 @@ modem_rx(void *priv, uint8_t *buf, int io_len) uint8_t c = 0; uint32_t i = 0; + if (modem->tcpIpMode) + return 0; + if (!modem->connected) { /* Drop packet. */ pclog("Dropping %d bytes\n", io_len - 14); @@ -914,12 +1007,127 @@ modem_rcr_cb(UNUSED(struct serial_s *serial), void *priv) #endif } +static void +modem_accept_incoming_call(modem_t* modem) +{ + if (modem->waitingclientsocket != -1) { + modem->clientsocket = modem->waitingclientsocket; + modem->waitingclientsocket = -1; + modem_enter_connected_state(modem); + modem->in_warmup = 250; + } else { + modem_enter_idle_state(modem); + } +} + static void modem_cmdpause_timer_callback(void *priv) { modem_t *dev = (modem_t *) priv; uint32_t guard_threashold = 0; + if (dev->tcpIpConnInProgress) { + int status = plat_netsocket_connected(dev->clientsocket); + + if (status == -1) { + plat_netsocket_close(dev->clientsocket); + dev->clientsocket = -1; + modem_enter_idle_state(dev); + modem_send_res(dev, ResNOCARRIER); + dev->tcpIpConnInProgress = 0; + } else if (status == 1) { + modem_enter_connected_state(dev); + dev->tcpIpConnInProgress = 0; + } + + dev->tcpIpConnCounter++; + + if (status <= 0 && dev->tcpIpConnCounter >= 5000) { + plat_netsocket_close(dev->clientsocket); + dev->clientsocket = -1; + modem_enter_idle_state(dev); + modem_send_res(dev, ResNOANSWER); + dev->tcpIpConnInProgress = 0; + dev->tcpIpMode = 0; + } + } + + if (!dev->connected && dev->waitingclientsocket == -1 && dev->serversocket != -1) { + dev->waitingclientsocket = plat_netsocket_accept(dev->serversocket); + if (dev->waitingclientsocket != -1) { + if (!(dev->serial->mctrl & 1) && dev->dtrmode != 0) { + modem_enter_idle_state(dev); + } else { + dev->ringing = true; + modem_send_res(dev, ResRING); + serial_set_ri(dev->serial, !serial_get_ri(dev->serial)); + dev->ringtimer = 3000; + dev->reg[MREG_RING_COUNT] = 0; + } + } + } + if (dev->ringing) { + if (dev->ringtimer <= 0) { + dev->reg[MREG_RING_COUNT]++; + if ((dev->reg[MREG_AUTOANSWER_COUNT] > 0) && + (dev->reg[MREG_RING_COUNT] >= dev->reg[MREG_AUTOANSWER_COUNT])) { + modem_accept_incoming_call(dev); + return; + } + modem_send_res(dev, ResRING); + serial_set_ri(dev->serial, !serial_get_ri(dev->serial)); + + //MIXER_Enable(mhd.chan,true); + dev->ringtimer = 3000; + } + --dev->ringtimer; + } + + if (dev->in_warmup) { + dev->in_warmup--; + if (dev->in_warmup == 0) { + dev->tx_count = 0; + fifo8_reset(&dev->rx_data); + } + } + else if (dev->connected && dev->tcpIpMode) { + if (dev->tx_count) { + int wouldblock = 0; + int res = plat_netsocket_send(dev->clientsocket, dev->tx_pkt_ser_line, dev->tx_count, &wouldblock); + + if (res <= 0 && !wouldblock) { + /* No bytes sent or error. */ + dev->tx_count = 0; + modem_enter_idle_state(dev); + modem_send_res(dev, ResNOCARRIER); + } else if (res > 0) { + if (res == dev->tx_count) { + dev->tx_count = 0; + } else { + memmove(dev->tx_pkt_ser_line, &dev->tx_pkt_ser_line[res], dev->tx_count - res); + dev->tx_count -= res; + } + } + } + if (dev->connected) { + uint8_t buffer[16]; + int wouldblock = 0; + int res = plat_netsocket_receive(dev->clientsocket, buffer, sizeof(buffer), &wouldblock); + + if (res > 0) { + fifo8_push_all(&dev->rx_data, buffer, res); + } else if (res == 0) { + dev->tx_count = 0; + modem_enter_idle_state(dev); + modem_send_res(dev, ResNOCARRIER); + } else if (!wouldblock) { + dev->tx_count = 0; + modem_enter_idle_state(dev); + modem_send_res(dev, ResNOCARRIER); + } + } + } + dev->cmdpause++; guard_threashold = (uint32_t)(dev->reg[MREG_GUARD_TIME] * 20); if (dev->cmdpause > guard_threashold) { @@ -938,11 +1146,13 @@ static void * modem_init(const device_t *info) { modem_t* modem = (modem_t*)calloc(1, sizeof(modem_t)); + const char* phonebook_file = NULL; memset(modem->mac, 0xfc, 6); modem->port = device_get_config_int("port"); modem->baudrate = device_get_config_int("baudrate"); + modem->listen_port = device_get_config_int("listen_port"); fifo8_create(&modem->data_pending, 0x10000); fifo8_create(&modem->rx_data, 0x10000); @@ -955,12 +1165,20 @@ modem_init(const device_t *info) modem_reset(modem); modem->card = network_attach(modem, modem->mac, modem_rx, NULL); + + phonebook_file = device_get_config_string("phonebook_file"); + if (phonebook_file && phonebook_file[0] != 0) { + modem_read_phonebook_file(modem, phonebook_file); + } + return modem; } void modem_close(void *priv) { modem_t* modem = (modem_t*)priv; + modem->listen_port = 0; + modem_reset(modem); fifo8_destroy(&modem->data_pending); fifo8_destroy(&modem->rx_data); netcard_close(modem->card); @@ -1009,6 +1227,23 @@ static const device_config_t modem_config[] = { { .description = "300", .value = 300 }, } }, + { + .name = "listen_port", + .description = "TCP/IP listening port", + .type = CONFIG_INT, + .default_string = "", + .default_int = 5000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = {} + }, + { + .name = "phonebook_file", + .description = "Phonebook File", + .type = CONFIG_FNAME, + .default_string = "", + .file_filter = "Text files (*.txt)|*.txt" + }, { .name = "", .description = "", .type = CONFIG_END } }; diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 48b377044..7133093b6 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -223,7 +223,7 @@ endif() if(WIN32) target_sources(plat PRIVATE ../win/win_serial_passthrough.c ../win/win_netsocket.c) else() - target_sources(plat PRIVATE ../unix/unix_serial_passthrough.c) + target_sources(plat PRIVATE ../unix/unix_serial_passthrough.c ../unix/unix_netsocket.c) endif() if (APPLE) diff --git a/src/unix/unix_netsocket.c b/src/unix/unix_netsocket.c new file mode 100644 index 000000000..bf0dd45da --- /dev/null +++ b/src/unix/unix_netsocket.c @@ -0,0 +1,194 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include +#include +#include + +#include <86box/86box.h> +#include <86box/log.h> +#include <86box/timer.h> +#include <86box/plat.h> +#include <86box/device.h> +#include <86box/plat_netsocket.h> +#include <86box/ui.h> + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +SOCKET plat_netsocket_create(int type) +{ + SOCKET fd = -1; + u_long yes = 1; + + if (type != NET_SOCKET_TCP) + return -1; + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd == -1) + return -1; + + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); + + return fd; +} + +SOCKET plat_netsocket_create_server(int type, unsigned short port) +{ + struct sockaddr_in sock_addr; + SOCKET fd = -1; + u_long yes = 1; + + if (type != NET_SOCKET_TCP) + return -1; + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd == -1) + return -1; + + memset(&sock_addr, 0, sizeof(struct sockaddr_in)); + + sock_addr.sin_family = AF_INET; + sock_addr.sin_addr.s_addr = INADDR_ANY; + sock_addr.sin_port = port; + + if (bind(fd, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)) == -1) { + plat_netsocket_close(fd); + return (SOCKET)-1; + } + + if (listen(fd, 5) == -1) { + plat_netsocket_close(fd); + return (SOCKET)-1; + } + + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); + + return fd; +} + +void plat_netsocket_close(SOCKET socket) +{ + close((SOCKET)socket); +} + +SOCKET plat_netsocket_accept(SOCKET socket) +{ + SOCKET clientsocket = accept(socket, NULL, NULL); + + if (clientsocket == -1) + return -1; + + return clientsocket; +} + +int plat_netsocket_connected(SOCKET socket) +{ + struct sockaddr addr; + socklen_t len = sizeof(struct sockaddr); + fd_set wrfds; + struct timeval tv; + int res = -1; + int status = 0; + int optlen = 4; + + FD_ZERO(&wrfds); + FD_SET(socket, &wrfds); + + tv.tv_sec = 0; + tv.tv_usec = 0; + + res = select(socket + 1, NULL, &wrfds, NULL, &tv); + + if (res == -1) + return -1; + + if (res == 0 || !(res >= 1 && FD_ISSET(socket, &wrfds))) + return 0; + + res = getsockopt(socket, SOL_SOCKET, SO_ERROR, (char*)&status, &optlen); + + if (res == -1) + return -1; + + if (status != 0) + return -1; + + if (getpeername(socket, &addr, &len) == -1) + return -1; + + return 1; +} + +int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short port) +{ + struct sockaddr_in sock_addr; + int res = -1; + + sock_addr.sin_family = AF_INET; + sock_addr.sin_addr.s_addr = inet_addr(hostname); + sock_addr.sin_port = htons(port); + + if (sock_addr.sin_addr.s_addr == INADDR_ANY || sock_addr.sin_addr.s_addr == INADDR_NONE) { + struct hostent *hp; + + hp = gethostbyname(hostname); + + if (hp) + memcpy(&sock_addr.sin_addr.s_addr, hp->h_addr_list[0], hp->h_length); + else + return -1; + } + + res = connect(socket, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)); + + if (res == -1) { + int error = errno; + + if (error == EISCONN) + return 0; + + res = -1; + } + return res; +} + +int plat_netsocket_send(SOCKET socket, const unsigned char* data, unsigned int size, int *wouldblock) +{ + int res = send(socket, (const char*)data, size, 0); + + if (res == -1) { + int error = errno; + + if (wouldblock) + *wouldblock = !!(error == EWOULDBLOCK || error == EAGAIN); + + return -1; + } + return res; +} + +int plat_netsocket_receive(SOCKET socket, unsigned char* data, unsigned int size, int *wouldblock) +{ + int res = recv(socket, (char*)data, size, 0); + + if (res == -1) { + int error = errno; + + if (wouldblock) + *wouldblock = !!(error == EWOULDBLOCK || error == EAGAIN); + + return -1; + } + return res; +} diff --git a/src/win/win_netsocket.c b/src/win/win_netsocket.c index 044a59860..6bbd7aafb 100644 --- a/src/win/win_netsocket.c +++ b/src/win/win_netsocket.c @@ -38,9 +38,15 @@ SOCKET plat_netsocket_create(int type) SOCKET plat_netsocket_create_server(int type, unsigned short port) { struct sockaddr_in sock_addr; - SOCKET socket = plat_netsocket_create(type); + SOCKET socket = -1; + u_long yes = 1; + + if (type != NET_SOCKET_TCP) + return -1; + + socket = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); if (socket == INVALID_SOCKET) - return (SOCKET)-1; + return -1; memset(&sock_addr, 0, sizeof(struct sockaddr_in)); @@ -58,6 +64,8 @@ SOCKET plat_netsocket_create_server(int type, unsigned short port) return (SOCKET)-1; } + ioctlsocket(socket, FIONBIO, &yes); + return socket; } @@ -79,13 +87,38 @@ SOCKET plat_netsocket_accept(SOCKET socket) int plat_netsocket_connected(SOCKET socket) { struct sockaddr addr; - socklen_t len = sizeof(struct sockaddr); + socklen_t len = sizeof(struct sockaddr); + fd_set wrfds; + struct timeval tv; + int res = SOCKET_ERROR; + int status = 0; + int optlen = 4; + FD_ZERO(&wrfds); + FD_SET(socket, &wrfds); + + tv.tv_sec = 0; + tv.tv_usec = 0; + + res = select(1, NULL, &wrfds, NULL, &tv); + + if (res == SOCKET_ERROR) + return -1; - - if (getpeername(socket, &addr, &len) == SOCKET_ERROR) + if (res == 0 || !(res >= 1 && FD_ISSET(socket, &wrfds))) return 0; + res = getsockopt(socket, SOL_SOCKET, SO_ERROR, (char*)&status, &optlen); + + if (res == SOCKET_ERROR) + return -1; + + if (status != 0) + return -1; + + if (getpeername(socket, &addr, &len) == SOCKET_ERROR) + return -1; + return 1; } @@ -98,7 +131,7 @@ int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short p sock_addr.sin_addr.s_addr = inet_addr(hostname); sock_addr.sin_port = htons(port); - if (sock_addr.sin_addr.s_addr == -1 || sock_addr.sin_addr.s_addr == 0) { + if (sock_addr.sin_addr.s_addr == INADDR_ANY || sock_addr.sin_addr.s_addr == INADDR_NONE) { struct hostent *hp; hp = gethostbyname(hostname); From fb8ff563b2f37583554ebcfa3f10f8931a7d2f35 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 14:29:24 +0600 Subject: [PATCH 660/936] Oversight --- 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 6e6635ed8..c584ae820 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -1154,6 +1154,8 @@ modem_init(const device_t *info) modem->baudrate = device_get_config_int("baudrate"); modem->listen_port = device_get_config_int("listen_port"); + modem->clientsocket = modem->serversocket = modem->waitingclientsocket = -1; + fifo8_create(&modem->data_pending, 0x10000); fifo8_create(&modem->rx_data, 0x10000); From 59466a74f44a3b0cb9d8b631551bc5ed54fddcc0 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 16:01:00 +0600 Subject: [PATCH 661/936] More TCP/IP related changes --- src/network/net_modem.c | 198 ++++++++++++++++++++------------------ src/unix/unix_netsocket.c | 2 +- src/win/win_netsocket.c | 15 ++- 3 files changed, 120 insertions(+), 95 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index c584ae820..64e16d920 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -456,32 +456,35 @@ modem_enter_idle_state(modem_t* modem) modem->tcpIpConnInProgress = 0; modem->tcpIpConnCounter = 0; - if (modem->waitingclientsocket != -1) + if (modem->waitingclientsocket != (SOCKET)-1) plat_netsocket_close(modem->waitingclientsocket); - if (modem->clientsocket != -1) + if (modem->clientsocket != (SOCKET)-1) plat_netsocket_close(modem->clientsocket); - modem->clientsocket = modem->waitingclientsocket = -1; - if (modem->serversocket != -1) { + modem->clientsocket = modem->waitingclientsocket = (SOCKET)-1; + if (modem->serversocket != (SOCKET)-1) { modem->waitingclientsocket = plat_netsocket_accept(modem->serversocket); - while (modem->waitingclientsocket != -1) { + while (modem->waitingclientsocket != (SOCKET)-1) { plat_netsocket_close(modem->waitingclientsocket); modem->waitingclientsocket = plat_netsocket_accept(modem->serversocket); } plat_netsocket_close(modem->serversocket); - modem->serversocket = -1; + modem->serversocket = (SOCKET)-1; } - if (modem->waitingclientsocket != -1) + if (modem->waitingclientsocket != (SOCKET)-1) plat_netsocket_close(modem->waitingclientsocket); - modem->waitingclientsocket = -1; + modem->waitingclientsocket = (SOCKET)-1; modem->tcpIpMode = false; modem->tcpIpConnInProgress = false; if (modem->listen_port) { modem->serversocket = plat_netsocket_create_server(NET_SOCKET_TCP, modem->listen_port); + if (modem->serversocket == (SOCKET)-1) { + pclog("Failed to set up server on port %d\n", modem->listen_port); + } } serial_set_cts(modem->serial, 1); @@ -560,12 +563,18 @@ modem_dial(modem_t* modem, const char* str) modem->clientsocket = plat_netsocket_create(NET_SOCKET_TCP); if (modem->clientsocket == -1) { + pclog("Failed to create client socket\n"); modem_send_res(modem, ResNOCARRIER); modem_enter_idle_state(modem); return; } - plat_netsocket_connect(modem->clientsocket, buf, port); + if (-1 == plat_netsocket_connect(modem->clientsocket, buf, port)) { + pclog("Failed to connect to %s\n", buf); + modem_send_res(modem, ResNOCARRIER); + modem_enter_idle_state(modem); + return; + } modem->tcpIpConnInProgress = 1; modem->tcpIpConnCounter = 0; } @@ -724,6 +733,7 @@ modem_do_command(modem_t* modem) } } modem_dial(modem, foundstr); + break; } case 'I': // Some strings about firmware switch (modem_scan_number(&scanbuf)) { @@ -1023,120 +1033,125 @@ modem_accept_incoming_call(modem_t* modem) static void modem_cmdpause_timer_callback(void *priv) { - modem_t *dev = (modem_t *) priv; + modem_t *modem = (modem_t *) priv; uint32_t guard_threashold = 0; + timer_on_auto(&modem->cmdpause_timer, 1000); - if (dev->tcpIpConnInProgress) { - int status = plat_netsocket_connected(dev->clientsocket); + if (modem->tcpIpConnInProgress) { + do { + int status = plat_netsocket_connected(modem->clientsocket); - if (status == -1) { - plat_netsocket_close(dev->clientsocket); - dev->clientsocket = -1; - modem_enter_idle_state(dev); - modem_send_res(dev, ResNOCARRIER); - dev->tcpIpConnInProgress = 0; - } else if (status == 1) { - modem_enter_connected_state(dev); - dev->tcpIpConnInProgress = 0; - } + if (status == -1) { + plat_netsocket_close(modem->clientsocket); + modem->clientsocket = -1; + modem_enter_idle_state(modem); + modem_send_res(modem, ResNOCARRIER); + modem->tcpIpConnInProgress = 0; + break; + } else if (status == 1) { + modem_enter_connected_state(modem); + modem->tcpIpConnInProgress = 0; + break; + } - dev->tcpIpConnCounter++; + modem->tcpIpConnCounter++; - if (status <= 0 && dev->tcpIpConnCounter >= 5000) { - plat_netsocket_close(dev->clientsocket); - dev->clientsocket = -1; - modem_enter_idle_state(dev); - modem_send_res(dev, ResNOANSWER); - dev->tcpIpConnInProgress = 0; - dev->tcpIpMode = 0; - } + if (status < 0 || (status == 0 && modem->tcpIpConnCounter >= 5000)) { + plat_netsocket_close(modem->clientsocket); + modem->clientsocket = -1; + modem_enter_idle_state(modem); + modem_send_res(modem, ResNOANSWER); + modem->tcpIpConnInProgress = 0; + modem->tcpIpMode = 0; + break; + } + } while (0); } - if (!dev->connected && dev->waitingclientsocket == -1 && dev->serversocket != -1) { - dev->waitingclientsocket = plat_netsocket_accept(dev->serversocket); - if (dev->waitingclientsocket != -1) { - if (!(dev->serial->mctrl & 1) && dev->dtrmode != 0) { - modem_enter_idle_state(dev); + if (!modem->connected && modem->waitingclientsocket == -1 && modem->serversocket != -1) { + modem->waitingclientsocket = plat_netsocket_accept(modem->serversocket); + if (modem->waitingclientsocket != -1) { + if (!(modem->serial->mctrl & 1) && modem->dtrmode != 0) { + modem_enter_idle_state(modem); } else { - dev->ringing = true; - modem_send_res(dev, ResRING); - serial_set_ri(dev->serial, !serial_get_ri(dev->serial)); - dev->ringtimer = 3000; - dev->reg[MREG_RING_COUNT] = 0; + modem->ringing = true; + modem_send_res(modem, ResRING); + serial_set_ri(modem->serial, !serial_get_ri(modem->serial)); + modem->ringtimer = 3000; + modem->reg[MREG_RING_COUNT] = 0; } } } - if (dev->ringing) { - if (dev->ringtimer <= 0) { - dev->reg[MREG_RING_COUNT]++; - if ((dev->reg[MREG_AUTOANSWER_COUNT] > 0) && - (dev->reg[MREG_RING_COUNT] >= dev->reg[MREG_AUTOANSWER_COUNT])) { - modem_accept_incoming_call(dev); + if (modem->ringing) { + if (modem->ringtimer <= 0) { + modem->reg[MREG_RING_COUNT]++; + if ((modem->reg[MREG_AUTOANSWER_COUNT] > 0) && + (modem->reg[MREG_RING_COUNT] >= modem->reg[MREG_AUTOANSWER_COUNT])) { + modem_accept_incoming_call(modem); return; } - modem_send_res(dev, ResRING); - serial_set_ri(dev->serial, !serial_get_ri(dev->serial)); + modem_send_res(modem, ResRING); + serial_set_ri(modem->serial, !serial_get_ri(modem->serial)); - //MIXER_Enable(mhd.chan,true); - dev->ringtimer = 3000; + modem->ringtimer = 3000; } - --dev->ringtimer; + --modem->ringtimer; } - if (dev->in_warmup) { - dev->in_warmup--; - if (dev->in_warmup == 0) { - dev->tx_count = 0; - fifo8_reset(&dev->rx_data); + if (modem->in_warmup) { + modem->in_warmup--; + if (modem->in_warmup == 0) { + modem->tx_count = 0; + fifo8_reset(&modem->rx_data); } } - else if (dev->connected && dev->tcpIpMode) { - if (dev->tx_count) { + else if (modem->connected && modem->tcpIpMode) { + if (modem->tx_count) { int wouldblock = 0; - int res = plat_netsocket_send(dev->clientsocket, dev->tx_pkt_ser_line, dev->tx_count, &wouldblock); + int res = plat_netsocket_send(modem->clientsocket, modem->tx_pkt_ser_line, modem->tx_count, &wouldblock); if (res <= 0 && !wouldblock) { /* No bytes sent or error. */ - dev->tx_count = 0; - modem_enter_idle_state(dev); - modem_send_res(dev, ResNOCARRIER); + modem->tx_count = 0; + modem_enter_idle_state(modem); + modem_send_res(modem, ResNOCARRIER); } else if (res > 0) { - if (res == dev->tx_count) { - dev->tx_count = 0; + if (res == modem->tx_count) { + modem->tx_count = 0; } else { - memmove(dev->tx_pkt_ser_line, &dev->tx_pkt_ser_line[res], dev->tx_count - res); - dev->tx_count -= res; + memmove(modem->tx_pkt_ser_line, &modem->tx_pkt_ser_line[res], modem->tx_count - res); + modem->tx_count -= res; } } } - if (dev->connected) { + if (modem->connected) { uint8_t buffer[16]; int wouldblock = 0; - int res = plat_netsocket_receive(dev->clientsocket, buffer, sizeof(buffer), &wouldblock); + int res = plat_netsocket_receive(modem->clientsocket, buffer, sizeof(buffer), &wouldblock); if (res > 0) { - fifo8_push_all(&dev->rx_data, buffer, res); + fifo8_push_all(&modem->rx_data, buffer, res); } else if (res == 0) { - dev->tx_count = 0; - modem_enter_idle_state(dev); - modem_send_res(dev, ResNOCARRIER); + modem->tx_count = 0; + modem_enter_idle_state(modem); + modem_send_res(modem, ResNOCARRIER); } else if (!wouldblock) { - dev->tx_count = 0; - modem_enter_idle_state(dev); - modem_send_res(dev, ResNOCARRIER); + modem->tx_count = 0; + modem_enter_idle_state(modem); + modem_send_res(modem, ResNOCARRIER); } } } - dev->cmdpause++; - guard_threashold = (uint32_t)(dev->reg[MREG_GUARD_TIME] * 20); - if (dev->cmdpause > guard_threashold) { - if (dev->plusinc == 0) { - dev->plusinc = 1; - } else if (dev->plusinc == 4) { - dev->mode = MODEM_MODE_COMMAND; - modem_send_res(dev, ResOK); - dev->plusinc = 0; + modem->cmdpause++; + guard_threashold = (uint32_t)(modem->reg[MREG_GUARD_TIME] * 20); + if (modem->cmdpause > guard_threashold) { + if (modem->plusinc == 0) { + modem->plusinc = 1; + } else if (modem->plusinc == 4) { + modem->mode = MODEM_MODE_COMMAND; + modem_send_res(modem, ResOK); + modem->plusinc = 0; } } } @@ -1232,12 +1247,13 @@ static const device_config_t modem_config[] = { { .name = "listen_port", .description = "TCP/IP listening port", - .type = CONFIG_INT, - .default_string = "", - .default_int = 5000, - .file_filter = NULL, - .spinner = { 0 }, - .selection = {} + .type = CONFIG_SPINNER, + .spinner = + { + .min = 0, + .max = 32767 + }, + .default_int = 0 }, { .name = "phonebook_file", diff --git a/src/unix/unix_netsocket.c b/src/unix/unix_netsocket.c index bf0dd45da..e0353a463 100644 --- a/src/unix/unix_netsocket.c +++ b/src/unix/unix_netsocket.c @@ -155,7 +155,7 @@ int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short p if (res == -1) { int error = errno; - if (error == EISCONN) + if (error == EISCONN || error == EWOULDBLOCK || error == EAGAIN || error == EINPROGRESS) return 0; res = -1; diff --git a/src/win/win_netsocket.c b/src/win/win_netsocket.c index 6bbd7aafb..0f8c5f87a 100644 --- a/src/win/win_netsocket.c +++ b/src/win/win_netsocket.c @@ -17,6 +17,7 @@ #include #include #include +#include SOCKET plat_netsocket_create(int type) { @@ -88,23 +89,31 @@ int plat_netsocket_connected(SOCKET socket) { struct sockaddr addr; socklen_t len = sizeof(struct sockaddr); - fd_set wrfds; + fd_set wrfds, exfds; struct timeval tv; int res = SOCKET_ERROR; int status = 0; int optlen = 4; FD_ZERO(&wrfds); + FD_ZERO(&exfds); FD_SET(socket, &wrfds); + FD_SET(socket, &exfds); tv.tv_sec = 0; tv.tv_usec = 0; - res = select(1, NULL, &wrfds, NULL, &tv); + res = select(socket + 1, NULL, &wrfds, &exfds, &tv); if (res == SOCKET_ERROR) return -1; + if (res >= 1 && FD_ISSET(socket, &exfds)) { + res = getsockopt(socket, SOL_SOCKET, SO_ERROR, (char*)&status, &optlen); + pclog("Socket error %d\n", status); + return -1; + } + if (res == 0 || !(res >= 1 && FD_ISSET(socket, &wrfds))) return 0; @@ -147,7 +156,7 @@ int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short p if (res == SOCKET_ERROR) { int error = WSAGetLastError(); - if (error == WSAEISCONN) + if (error == WSAEISCONN || error == WSAEWOULDBLOCK) return 0; res = -1; From 6be8ada352e732056803a2837b7eae8caf90de9f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 16:04:29 +0600 Subject: [PATCH 662/936] Copyright text --- src/network/net_modem.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 64e16d920..b79669da7 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -1,5 +1,22 @@ -/* TODO: SLIP support. */ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Hayes AT-compliant modem emulation. + * + * + * + * Authors: Cacodemon345 + * The DOSBox Team + * + * Copyright 2024 Cacodemon345 + * Copyright 2002-2021 The DOSBox Team + */ #include #include From babadfb5c28c1533fa67030caa5de1b0993af161 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 16:23:35 +0600 Subject: [PATCH 663/936] Handle large packets being sent --- src/network/net_modem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 131b87653..120887bcc 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -866,7 +866,7 @@ modem_rx(void *priv, uint8_t *buf, int io_len) return 0; } - if ((io_len) >= (fifo8_num_free(&modem->rx_data) / 2)) { + while ((io_len) >= (fifo8_num_free(&modem->rx_data) / 2)) { fifo8_resize_2x(&modem->rx_data); } From 074de35653d7c72598a81b8163324fb4d0905cd5 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 19:34:01 +0600 Subject: [PATCH 664/936] Telnet emulation --- src/network/net_modem.c | 131 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 2 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 95247ad80..d35172ada 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -112,6 +112,7 @@ typedef struct modem_t bool connected, ringing; bool echo, numericresponse; bool tcpIpMode, tcpIpConnInProgress; + bool telnet_mode; uint32_t tcpIpConnCounter; int doresponse; @@ -683,7 +684,22 @@ modem_do_command(modem_t* modem) char chr = modem_fetch_character(&scanbuf); switch (chr) { case '+': - /* None supported yet. */ + if (is_next_token("NET", sizeof("NET"), scanbuf)) { + // only walk the pointer ahead if the command matches + scanbuf += 3; + const uint32_t requested_mode = modem_scan_number(&scanbuf); + + // If the mode isn't valid then stop parsing + if (requested_mode != 1 && requested_mode != 0) { + modem_send_res(modem, ResERROR); + return; + } + // Inform the user on changes + if (modem->telnet_mode != !!requested_mode) { + modem->telnet_mode = !!requested_mode; + } + break; + } modem_send_res(modem, ResERROR); return; case 'D': { // Dial. @@ -968,6 +984,106 @@ fifo8_resize_2x(Fifo8* fifo) free(temp_buf); } +#define TEL_CLIENT 0 +#define TEL_SERVER 1 +void modem_process_telnet(modem_t* modem, uint8_t *data, uint32_t size) +{ + uint32_t i = 0; + for (i = 0; i < size; i++) { + uint8_t c = data[i]; + if (modem->telClient.inIAC) { + if (modem->telClient.recCommand) { + if ((c != 0) && (c != 1) && (c != 3)) { + if (modem->telClient.command > 250) { + /* Reject anything we don't recognize */ + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 252); + modem_data_mode_process_byte(modem, c); /* We won't do crap! */ + } + } + switch (modem->telClient.command) { + case 251: /* Will */ + if (c == 0) modem->telClient.binary[TEL_SERVER] = true; + if (c == 1) modem->telClient.echo[TEL_SERVER] = true; + if (c == 3) modem->telClient.supressGA[TEL_SERVER] = true; + break; + case 252: /* Won't */ + if (c == 0) modem->telClient.binary[TEL_SERVER] = false; + if (c == 1) modem->telClient.echo[TEL_SERVER] = false; + if (c == 3) modem->telClient.supressGA[TEL_SERVER] = false; + break; + case 253: /* Do */ + if (c == 0) { + modem->telClient.binary[TEL_CLIENT] = true; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 251); + modem_data_mode_process_byte(modem, 0); /* Will do binary transfer */ + } + if (c == 1) { + modem->telClient.echo[TEL_CLIENT] = false; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 252); + modem_data_mode_process_byte(modem, 1); /* Won't echo (too lazy) */ + } + if (c == 3) { + modem->telClient.supressGA[TEL_CLIENT] = true; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 251); + modem_data_mode_process_byte(modem, 3); /* Will Suppress GA */ + } + break; + case 254: /* Don't */ + if (c == 0) { + modem->telClient.binary[TEL_CLIENT] = false; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 252); + modem_data_mode_process_byte(modem, 0); /* Won't do binary transfer */ + } + if (c == 1) { + modem->telClient.echo[TEL_CLIENT] = false; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 252); + modem_data_mode_process_byte(modem, 1); /* Won't echo (fine by me) */ + } + if (c == 3) { + modem->telClient.supressGA[TEL_CLIENT] = true; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 251); + modem_data_mode_process_byte(modem, 3); /* Will Suppress GA (too lazy) */ + } + break; + default: + break; + } + modem->telClient.inIAC = false; + modem->telClient.recCommand = false; + continue; + } else { + if (c == 249) { + /* Go Ahead received */ + modem->telClient.inIAC = false; + continue; + } + modem->telClient.command = c; + modem->telClient.recCommand = true; + + if ((modem->telClient.binary[TEL_SERVER]) && (c == 0xff)) { + /* Binary data with value of 255 */ + modem->telClient.inIAC = false; + modem->telClient.recCommand = false; + fifo8_push(&modem->rx_data, 0xff); + continue; + } + } + } else { + if (c == 0xff) { + modem->telClient.inIAC = true; + continue; + } + fifo8_push(&modem->rx_data, c); + } + } +} static int modem_rx(void *priv, uint8_t *buf, int io_len) @@ -1147,7 +1263,10 @@ modem_cmdpause_timer_callback(void *priv) int res = plat_netsocket_receive(modem->clientsocket, buffer, sizeof(buffer), &wouldblock); if (res > 0) { - fifo8_push_all(&modem->rx_data, buffer, res); + if (modem->telnet_mode) + modem_process_telnet(modem, buffer, res); + else + fifo8_push_all(&modem->rx_data, buffer, res); } else if (res == 0) { modem->tx_count = 0; modem_enter_idle_state(modem); @@ -1185,6 +1304,7 @@ modem_init(const device_t *info) modem->port = device_get_config_int("port"); modem->baudrate = device_get_config_int("baudrate"); modem->listen_port = device_get_config_int("listen_port"); + modem->telnet_mode = device_get_config_int("telnet_mode"); modem->clientsocket = modem->serversocket = modem->waitingclientsocket = -1; @@ -1279,6 +1399,13 @@ static const device_config_t modem_config[] = { .default_string = "", .file_filter = "Text files (*.txt)|*.txt" }, + { + .name = "telnet_mode", + .description = "Telnet emulation", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, { .name = "", .description = "", .type = CONFIG_END } }; From 7d28e7727367677c6e5e8675afd80f98c089422d Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 19:37:16 +0600 Subject: [PATCH 665/936] EOF handling --- src/network/net_modem.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index d35172ada..bbcef00d1 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -178,6 +178,9 @@ modem_read_phonebook_file(modem_t* modem, const char* path) continue; } + if (res == EOF) + break; + if (strspn(entry.phone, "01234567890*=,;#+>") != strlen(entry.phone)) { /* Invalid characters. */ continue; From dbd875285f39f27b3709088c71bf90d398112db4 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 19:38:52 +0600 Subject: [PATCH 666/936] Fix SDL2 builds --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 48a5950b9..5a43dffdb 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,6 @@ CMakeLists.txt.user # MacOS Finder stuff .DS_Store + +# clangd +.cache From 097c9b4169427e3c24fae928ccf791fda1a24f8d Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 19:41:12 +0600 Subject: [PATCH 667/936] Fix SDL2 builds --- src/unix/CMakeLists.txt | 2 +- src/unix/unix_netsocket.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/unix/CMakeLists.txt b/src/unix/CMakeLists.txt index 43c730315..aa4cc84e2 100644 --- a/src/unix/CMakeLists.txt +++ b/src/unix/CMakeLists.txt @@ -17,7 +17,7 @@ # Copyright 2021-2022 Jasmine Iwanek. # -add_library(plat OBJECT unix.c unix_serial_passthrough.c) +add_library(plat OBJECT unix.c unix_serial_passthrough.c unix_netsocket.c) if (NOT CPPTHREADS) target_sources(plat PRIVATE unix_thread.c) diff --git a/src/unix/unix_netsocket.c b/src/unix/unix_netsocket.c index e0353a463..76ae0831b 100644 --- a/src/unix/unix_netsocket.c +++ b/src/unix/unix_netsocket.c @@ -22,14 +22,16 @@ #include #include #include +#include #include #include +#include #include SOCKET plat_netsocket_create(int type) { SOCKET fd = -1; - u_long yes = 1; + int yes = 1; if (type != NET_SOCKET_TCP) return -1; @@ -47,7 +49,7 @@ SOCKET plat_netsocket_create_server(int type, unsigned short port) { struct sockaddr_in sock_addr; SOCKET fd = -1; - u_long yes = 1; + int yes = 1; if (type != NET_SOCKET_TCP) return -1; From 3e623c88f49f6b173e0a6486dcd409fae9b581bf Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 19:43:11 +0600 Subject: [PATCH 668/936] More type fixes --- src/unix/unix_netsocket.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/unix/unix_netsocket.c b/src/unix/unix_netsocket.c index 76ae0831b..1e3282555 100644 --- a/src/unix/unix_netsocket.c +++ b/src/unix/unix_netsocket.c @@ -1,3 +1,4 @@ +#include #define _XOPEN_SOURCE 500 #include #include @@ -102,7 +103,7 @@ int plat_netsocket_connected(SOCKET socket) struct timeval tv; int res = -1; int status = 0; - int optlen = 4; + socklen_t optlen = 4; FD_ZERO(&wrfds); FD_SET(socket, &wrfds); From 515a69b318f524f15b6a64089298f56e75ea7f69 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 19:49:17 +0600 Subject: [PATCH 669/936] Deal with accidental includes --- src/unix/unix_netsocket.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/unix/unix_netsocket.c b/src/unix/unix_netsocket.c index 1e3282555..7e7163801 100644 --- a/src/unix/unix_netsocket.c +++ b/src/unix/unix_netsocket.c @@ -1,4 +1,3 @@ -#include #define _XOPEN_SOURCE 500 #include #include From 324299a6f3a9f52e7b6112376ba81da8e369eed2 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 12 Mar 2024 21:01:46 +0600 Subject: [PATCH 670/936] unix_netsocket.c: Unused variables cleanup --- src/unix/unix_netsocket.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/unix/unix_netsocket.c b/src/unix/unix_netsocket.c index 7e7163801..e65b53bee 100644 --- a/src/unix/unix_netsocket.c +++ b/src/unix/unix_netsocket.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,7 @@ SOCKET plat_netsocket_create(int type) return -1; fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); + setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&yes, sizeof(yes)); return fd; } @@ -75,6 +77,7 @@ SOCKET plat_netsocket_create_server(int type, unsigned short port) } fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); + setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&yes, sizeof(yes)); return fd; } @@ -141,7 +144,7 @@ int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short p sock_addr.sin_addr.s_addr = inet_addr(hostname); sock_addr.sin_port = htons(port); - if (sock_addr.sin_addr.s_addr == INADDR_ANY || sock_addr.sin_addr.s_addr == INADDR_NONE) { + if (sock_addr.sin_addr.s_addr == INADDR_ANY || sock_addr.sin_addr.s_addr == 0) { struct hostent *hp; hp = gethostbyname(hostname); From 42e062143b3d441c6fbeb5d9a88e53e0a6fea567 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 13 Mar 2024 01:29:21 +0600 Subject: [PATCH 671/936] Fix brace warning --- src/device/novell_cardkey.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/device/novell_cardkey.c b/src/device/novell_cardkey.c index 9f489cad7..4730b6bb4 100644 --- a/src/device/novell_cardkey.c +++ b/src/device/novell_cardkey.c @@ -102,7 +102,7 @@ static const device_config_t keycard_config[] = { .default_int = 0, .file_filter = "", .spinner = { 0 }, - .selection = { 0 } + .selection = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -120,4 +120,4 @@ const device_t novell_keycard_device = { .speed_changed = NULL, .force_redraw = NULL, .config = keycard_config -}; \ No newline at end of file +}; From b2a4d7457e6152243524a56e965d3629379663d6 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 13 Mar 2024 16:38:32 +0600 Subject: [PATCH 672/936] netsockets: Swap port number --- src/network/net_modem.c | 4 +++- src/unix/unix_netsocket.c | 2 +- src/win/win_netsocket.c | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index bbcef00d1..fe8ebfc57 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -113,6 +113,7 @@ typedef struct modem_t bool echo, numericresponse; bool tcpIpMode, tcpIpConnInProgress; bool telnet_mode; + bool dtrstate; uint32_t tcpIpConnCounter; int doresponse; @@ -957,6 +958,7 @@ void modem_dtr_callback(serial_t* serial, int status, void *priv) { modem_t *dev = (modem_t *) priv; + dev->dtrstate = !!status; if (status == 1) timer_disable(&dev->dtr_timer); else if (!timer_is_enabled(&dev->dtr_timer)) @@ -1207,7 +1209,7 @@ modem_cmdpause_timer_callback(void *priv) if (!modem->connected && modem->waitingclientsocket == -1 && modem->serversocket != -1) { modem->waitingclientsocket = plat_netsocket_accept(modem->serversocket); if (modem->waitingclientsocket != -1) { - if (!(modem->serial->mctrl & 1) && modem->dtrmode != 0) { + if (modem->dtrstate == 0 && modem->dtrmode != 0) { modem_enter_idle_state(modem); } else { modem->ringing = true; diff --git a/src/unix/unix_netsocket.c b/src/unix/unix_netsocket.c index e65b53bee..9e9ac2f49 100644 --- a/src/unix/unix_netsocket.c +++ b/src/unix/unix_netsocket.c @@ -64,7 +64,7 @@ SOCKET plat_netsocket_create_server(int type, unsigned short port) sock_addr.sin_family = AF_INET; sock_addr.sin_addr.s_addr = INADDR_ANY; - sock_addr.sin_port = port; + sock_addr.sin_port = htons(port); if (bind(fd, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)) == -1) { plat_netsocket_close(fd); diff --git a/src/win/win_netsocket.c b/src/win/win_netsocket.c index 0f8c5f87a..902d5e6ff 100644 --- a/src/win/win_netsocket.c +++ b/src/win/win_netsocket.c @@ -53,7 +53,7 @@ SOCKET plat_netsocket_create_server(int type, unsigned short port) sock_addr.sin_family = AF_INET; sock_addr.sin_addr.s_addr = INADDR_ANY; - sock_addr.sin_port = port; + sock_addr.sin_port = htons(port); if (bind(socket, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { plat_netsocket_close(socket); From 7f68245eae59fdd26ddd94d26287354a88ac8511 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 13 Mar 2024 17:46:36 +0600 Subject: [PATCH 673/936] unix_netsocket.c: Fix comparison value --- src/unix/unix_netsocket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/unix/unix_netsocket.c b/src/unix/unix_netsocket.c index 9e9ac2f49..e6ec6285f 100644 --- a/src/unix/unix_netsocket.c +++ b/src/unix/unix_netsocket.c @@ -144,7 +144,7 @@ int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short p sock_addr.sin_addr.s_addr = inet_addr(hostname); sock_addr.sin_port = htons(port); - if (sock_addr.sin_addr.s_addr == INADDR_ANY || sock_addr.sin_addr.s_addr == 0) { + if (sock_addr.sin_addr.s_addr == ((in_addr_t)-1) || sock_addr.sin_addr.s_addr == 0) { struct hostent *hp; hp = gethostbyname(hostname); From 607f66a1f83925c0f7824022392482f8a3ac9a7f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 13 Mar 2024 19:14:00 +0600 Subject: [PATCH 674/936] net_modem: Implement answer command --- src/network/net_modem.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index fe8ebfc57..372b39123 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -153,6 +153,7 @@ static modem_t *instance; #define MREG_DTR_DELAY 25 static void modem_do_command(modem_t* modem); +static void modem_answer_incoming_call(modem_t* modem); extern ssize_t local_getline(char **buf, size_t *bufsiz, FILE *fp); @@ -822,8 +823,12 @@ modem_do_command(modem_t* modem) break; case 'A': // Answer call { - modem_send_res(modem, ResERROR); - return; + if (modem->waitingclientsocket == -1) { + modem_send_res(modem, ResERROR); + return; + } + modem_answer_incoming_call(modem); + break; } return; case 'Z': { // Reset and load profiles From 53baaeece7679572df8cfa99f7d240f74e7433c3 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 13 Mar 2024 19:21:16 +0600 Subject: [PATCH 675/936] Comments cleanup and function name fixes --- src/network/net_modem.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 372b39123..c7d0aea2c 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -153,7 +153,7 @@ static modem_t *instance; #define MREG_DTR_DELAY 25 static void modem_do_command(modem_t* modem); -static void modem_answer_incoming_call(modem_t* modem); +static void modem_accept_incoming_call(modem_t* modem); extern ssize_t local_getline(char **buf, size_t *bufsiz, FILE *fp); @@ -559,7 +559,6 @@ modem_reset(modem_t* modem) void modem_dial(modem_t* modem, const char* str) { - /* TODO: Port TCP/IP support from DOSBox. */ modem->tcpIpConnCounter = 0; modem->tcpIpMode = false; if (!strncmp(str, "0.0.0.0", sizeof("0.0.0.0") - 1)) @@ -827,7 +826,7 @@ modem_do_command(modem_t* modem) modem_send_res(modem, ResERROR); return; } - modem_answer_incoming_call(modem); + modem_accept_incoming_call(modem); break; } return; From 7c9e94fb9bd09c1047680a52a9b5d2884a0262a5 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 14 Mar 2024 01:10:29 +0600 Subject: [PATCH 676/936] net_modem.c: Make sure the CONNECT response gets through --- src/network/net_modem.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index c7d0aea2c..4c2985bda 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -112,6 +112,7 @@ typedef struct modem_t bool connected, ringing; bool echo, numericresponse; bool tcpIpMode, tcpIpConnInProgress; + bool cooldown; bool telnet_mode; bool dtrstate; uint32_t tcpIpConnCounter; @@ -369,13 +370,17 @@ host_to_modem_cb(void *priv) if (!((modem->serial->mctrl & 2) || modem->flowcontrol != 3)) goto no_write_to_machine; - if (modem->mode == MODEM_MODE_DATA && fifo8_num_used(&modem->rx_data)) { + if (modem->mode == MODEM_MODE_DATA && fifo8_num_used(&modem->rx_data) && !modem->cooldown) { serial_write_fifo(modem->serial, fifo8_pop(&modem->rx_data)); } else if (fifo8_num_used(&modem->data_pending)) { uint8_t val = fifo8_pop(&modem->data_pending); serial_write_fifo(modem->serial, val); } + if (fifo8_num_used(&modem->data_pending) == 0) { + modem->cooldown = false; + } + no_write_to_machine: timer_on_auto(&modem->host_to_serial_timer, (1000000.0 / (double)modem->baudrate) * (double)9); } @@ -524,6 +529,7 @@ modem_enter_connected_state(modem_t* modem) modem->ringing = false; modem->connected = true; modem->tcpIpMode = true; + modem->cooldown = true; plat_netsocket_close(modem->serversocket); modem->serversocket = -1; memset(&modem->telClient, 0, sizeof(modem->telClient)); From e1180a77df2c605b93b3f1325bba86a54850adf8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 14 Mar 2024 01:06:12 +0100 Subject: [PATCH 677/936] NCR 53c8xx: Implement the readout of SODL via SBDL when STEST2 bit 7 is set, v3.04 BIOS'es now work. --- src/scsi/scsi_ncr53c8xx.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/scsi/scsi_ncr53c8xx.c b/src/scsi/scsi_ncr53c8xx.c index 42925338d..ad1b31fe8 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -280,6 +280,7 @@ typedef struct ncr53c8xx_t { uint8_t swide; uint8_t gpcntl; uint8_t last_command; + uint8_t sodl; int command_complete; ncr53c8xx_request *current; @@ -1704,6 +1705,8 @@ ncr53c8xx_reg_writeb(ncr53c8xx_t *dev, uint32_t offset, uint8_t val) dev->stest3 = val; break; case 0x54: + dev->sodl = val; + break; case 0x55: break; CASE_SET_REG32(scratchb, 0x5c) @@ -1989,6 +1992,9 @@ ncr53c8xx_reg_readb(ncr53c8xx_t *dev, uint32_t offset) if ((dev->sstat1 & PHASE_MASK) == PHASE_MI) { ncr53c8xx_log("NCR 810: Read SBDL %02X\n", dev->msg[0]); return dev->msg[0]; + } else if (dev->stest2 & 0x80) { + ncr53c8xx_log("NCR 810: Read SBDL %02X\n", dev->sodl); + return dev->sodl; } ncr53c8xx_log("NCR 810: Read SBDL 00\n"); return 0; From 6e87964b28c2dbd61f8942315bc607b9fb4fbfea Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 14 Mar 2024 16:14:06 +0600 Subject: [PATCH 678/936] net_modem: process '&' escaped commands properly --- src/network/net_modem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 4c2985bda..bbbe2e37a 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -919,6 +919,7 @@ modem_do_command(modem_t* modem) } break; } + break; case '\\': { // \ escaped commands char cmdchar = modem_fetch_character(&scanbuf); switch (cmdchar) { From 0ce889e9ad0e8b54f8d88ebc58f79c50023cdc2b Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 15 Mar 2024 02:46:00 +0600 Subject: [PATCH 679/936] net_modem.c: Fix memory leak --- src/network/net_modem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index bbbe2e37a..b1b6a2eca 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -1,4 +1,3 @@ - /* * 86Box A hypervisor and IBM PC system emulator that specializes in * running old operating systems and software designed for IBM @@ -323,9 +322,9 @@ send_tx_packet: buf[13] = 0x00; memcpy(buf + 14, processed_tx_packet, received); network_tx(modem->card, buf, received + 14); - free(processed_tx_packet); free(buf); } + free(processed_tx_packet); return; } @@ -530,6 +529,7 @@ modem_enter_connected_state(modem_t* modem) modem->connected = true; modem->tcpIpMode = true; modem->cooldown = true; + modem->tx_count = 0; plat_netsocket_close(modem->serversocket); modem->serversocket = -1; memset(&modem->telClient, 0, sizeof(modem->telClient)); From 64f343049fc5c1ba10b8ba58b084f48e756c9bde Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 15 Mar 2024 14:01:12 +0500 Subject: [PATCH 680/936] Fix Novell NE2000's default IRQ being out of range --- src/network/net_ne2000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/net_ne2000.c b/src/network/net_ne2000.c index 03327ac0c..ee32119ba 100644 --- a/src/network/net_ne2000.c +++ b/src/network/net_ne2000.c @@ -1329,7 +1329,7 @@ static const device_config_t ne2000_config[] = { .description = "IRQ", .type = CONFIG_SELECTION, .default_string = "", - .default_int = 10, + .default_int = 3, .file_filter = "", .spinner = { 0 }, .selection = { From 474df94008b1de603c6d8eabdaaa5dc0e8027e79 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 15 Mar 2024 14:01:46 +0500 Subject: [PATCH 681/936] Correct a typo in the comment --- src/include/86box/net_ne2000.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/86box/net_ne2000.h b/src/include/86box/net_ne2000.h index fe1a71934..75185cf90 100644 --- a/src/include/86box/net_ne2000.h +++ b/src/include/86box/net_ne2000.h @@ -39,7 +39,7 @@ enum { NE2K_NONE = 0, NE2K_NE1000 = 1, /* 8-bit ISA NE1000 */ - NE2K_NE1000_COMPAT = 2, /* 16-bit ISA NE2000-Compatible */ + NE2K_NE1000_COMPAT = 2, /* 8-bit ISA NE1000-Compatible */ NE2K_NE2000 = 3, /* 16-bit ISA NE2000 */ NE2K_NE2000_COMPAT = 4, /* 16-bit ISA NE2000-Compatible */ NE2K_ETHERNEXT_MC = 5, /* 16-bit MCA EtherNext/MC */ From e34a66a4f6f60398f22451f973d2530f80ac3493 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Fri, 15 Mar 2024 13:06:54 -0400 Subject: [PATCH 682/936] GHA: Disable win32 in CodeQL --- .github/workflows/codeql_windows_msys2.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/codeql_windows_msys2.yml b/.github/workflows/codeql_windows_msys2.yml index dc18544c7..dda14a182 100644 --- a/.github/workflows/codeql_windows_msys2.yml +++ b/.github/workflows/codeql_windows_msys2.yml @@ -61,9 +61,6 @@ jobs: new: on slug: -NDR ui: - - name: Win32 GUI - qt: off - static: on - name: Qt GUI qt: on static: off From 2c5a460d2315c1c72e247db9013b9e0ed10d781c Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 15 Mar 2024 18:16:21 +0100 Subject: [PATCH 683/936] Removed the Win32 UI and the legacy makefiles. --- src/Makefile.local | 200 - src/{win => qt}/86Box-qt.rc | 0 src/{win => qt}/86Box.manifest | 0 src/qt/CMakeLists.txt | 10 +- src/{win => qt}/assets/86Box-green.png | Bin src/{win => qt}/assets/86box-rb.png | Bin src/{win => qt}/assets/86box-red.png | Bin src/{win => qt}/assets/86box-yellow.png | Bin src/{win => qt}/assets/86box.png | Bin src/{win => qt}/assets/status-paused.png | Bin src/{win => qt}/assets/status-running.png | Bin src/{win => qt}/icons/86Box-gray.ico | Bin src/{win => qt}/icons/86Box-green.ico | Bin src/{win => qt}/icons/86Box-red.ico | Bin src/{win => qt}/icons/86Box-yellow.ico | Bin src/{win => qt}/icons/acpi_shutdown.ico | Bin src/{win => qt}/icons/cartridge.ico | Bin src/{win => qt}/icons/cartridge_empty.ico | Bin src/{win => qt}/icons/cassette.ico | Bin src/{win => qt}/icons/cassette_active.ico | Bin src/{win => qt}/icons/cassette_empty.ico | Bin .../icons/cassette_empty_active.ico | Bin src/{win => qt}/icons/cdrom.ico | Bin src/{win => qt}/icons/cdrom_active.ico | Bin src/{win => qt}/icons/cdrom_disabled.ico | Bin src/{win => qt}/icons/cdrom_empty.ico | Bin src/{win => qt}/icons/cdrom_empty_active.ico | Bin src/{win => qt}/icons/display.ico | Bin src/{win => qt}/icons/floppy_35.ico | Bin src/{win => qt}/icons/floppy_35_active.ico | Bin src/{win => qt}/icons/floppy_35_empty.ico | Bin .../icons/floppy_35_empty_active.ico | Bin src/{win => qt}/icons/floppy_525.ico | Bin src/{win => qt}/icons/floppy_525_active.ico | Bin src/{win => qt}/icons/floppy_525_empty.ico | Bin .../icons/floppy_525_empty_active.ico | Bin .../icons/floppy_and_cdrom_drives.ico | Bin src/{win => qt}/icons/floppy_disabled.ico | Bin src/{win => qt}/icons/hard_disk.ico | Bin src/{win => qt}/icons/hard_disk_active.ico | Bin src/{win => qt}/icons/hard_reset.ico | Bin src/{win => qt}/icons/input_devices.ico | Bin src/{win => qt}/icons/machine.ico | Bin src/{win => qt}/icons/mo.ico | Bin src/{win => qt}/icons/mo_active.ico | Bin src/{win => qt}/icons/mo_disabled.ico | Bin src/{win => qt}/icons/mo_empty.ico | Bin src/{win => qt}/icons/mo_empty_active.ico | Bin src/{win => qt}/icons/network.ico | Bin src/{win => qt}/icons/network_active.ico | Bin src/{win => qt}/icons/network_empty.ico | Bin src/{win => qt}/icons/other_peripherals.ico | Bin .../icons/other_removable_devices.ico | Bin src/{win => qt}/icons/pause.ico | Bin src/{win => qt}/icons/ports.ico | Bin src/{win => qt}/icons/run.ico | Bin src/{win => qt}/icons/send_cad.ico | Bin src/{win => qt}/icons/send_cae.ico | Bin src/{win => qt}/icons/settings.ico | Bin src/{win => qt}/icons/sound.ico | Bin src/{win => qt}/icons/storage_controllers.ico | Bin src/{win => qt}/icons/zip.ico | Bin src/{win => qt}/icons/zip_active.ico | Bin src/{win => qt}/icons/zip_disabled.ico | Bin src/{win => qt}/icons/zip_empty.ico | Bin src/{win => qt}/icons/zip_empty_active.ico | Bin src/qt/qt_main.cpp | 8 +- src/qt/qt_mainwindow.cpp | 10 +- src/qt/qt_mainwindow.ui | 12 +- src/qt/qt_progsettings.cpp | 2 +- src/qt/qt_settingsstoragecontrollers.cpp | 1 - src/{win => qt}/win_netsocket.c | 0 src/{win => qt}/win_opendir.c | 0 src/{win => qt}/win_serial_passthrough.c | 0 src/qt_resources.qrc | 110 +- src/win/86Box.rc | 365 -- src/win/CMakeLists.txt | 63 - src/win/Makefile.mingw | 988 --- src/win/glad.c | 1047 --- src/win/languages/cs-CZ.rc | 636 -- src/win/languages/de-DE.rc | 636 -- src/win/languages/dialogs.rc | 1143 ---- src/win/languages/en-GB.rc | 636 -- src/win/languages/en-US.rc | 636 -- src/win/languages/es-ES.rc | 636 -- src/win/languages/fi-FI.rc | 636 -- src/win/languages/fr-FR.rc | 636 -- src/win/languages/hr-HR.rc | 636 -- src/win/languages/hu-HU.rc | 640 -- src/win/languages/it-IT.rc | 637 -- src/win/languages/ja-JP.rc | 636 -- src/win/languages/ko-KR.rc | 636 -- src/win/languages/pl-PL.rc | 636 -- src/win/languages/pt-BR.rc | 639 -- src/win/languages/pt-PT.rc | 636 -- src/win/languages/ru-RU.rc | 636 -- src/win/languages/sl-SI.rc | 636 -- src/win/languages/tr-TR.rc | 636 -- src/win/languages/uk-UA.rc | 636 -- src/win/languages/zh-CN.rc | 636 -- src/win/languages/zh-TW.rc | 636 -- src/win/pcap_if.rc | 54 - src/win/win.c | 1346 ---- src/win/win_about.c | 80 - src/win/win_cdrom.c | 258 - src/win/win_devconf.c | 832 --- src/win/win_dialog.c | 256 - src/win/win_dynld.c | 83 - src/win/win_icon.c | 168 - src/win/win_joystick.cpp | 321 - src/win/win_joystick_rawinput.c | 551 -- src/win/win_joystick_xinput.c | 268 - src/win/win_jsconf.c | 527 -- src/win/win_keyboard.c | 198 - src/win/win_media_menu.c | 766 --- src/win/win_mouse.c | 125 - src/win/win_new_floppy.c | 842 --- src/win/win_opengl.c | 1002 --- src/win/win_opengl_glslp.c | 270 - src/win/win_preferences.c | 290 - src/win/win_sdl.c | 626 -- src/win/win_settings.c | 5708 ----------------- src/win/win_snd_gain.c | 90 - src/win/win_specify_dim.c | 188 - src/win/win_stbar.c | 1058 --- src/win/win_thread.c | 180 - src/win/win_toolbar.c | 208 - src/win/win_ui.c | 1662 ----- 128 files changed, 76 insertions(+), 35204 deletions(-) delete mode 100644 src/Makefile.local rename src/{win => qt}/86Box-qt.rc (100%) rename src/{win => qt}/86Box.manifest (100%) rename src/{win => qt}/assets/86Box-green.png (100%) rename src/{win => qt}/assets/86box-rb.png (100%) rename src/{win => qt}/assets/86box-red.png (100%) rename src/{win => qt}/assets/86box-yellow.png (100%) rename src/{win => qt}/assets/86box.png (100%) rename src/{win => qt}/assets/status-paused.png (100%) rename src/{win => qt}/assets/status-running.png (100%) rename src/{win => qt}/icons/86Box-gray.ico (100%) rename src/{win => qt}/icons/86Box-green.ico (100%) rename src/{win => qt}/icons/86Box-red.ico (100%) rename src/{win => qt}/icons/86Box-yellow.ico (100%) rename src/{win => qt}/icons/acpi_shutdown.ico (100%) rename src/{win => qt}/icons/cartridge.ico (100%) rename src/{win => qt}/icons/cartridge_empty.ico (100%) rename src/{win => qt}/icons/cassette.ico (100%) rename src/{win => qt}/icons/cassette_active.ico (100%) rename src/{win => qt}/icons/cassette_empty.ico (100%) rename src/{win => qt}/icons/cassette_empty_active.ico (100%) rename src/{win => qt}/icons/cdrom.ico (100%) rename src/{win => qt}/icons/cdrom_active.ico (100%) rename src/{win => qt}/icons/cdrom_disabled.ico (100%) rename src/{win => qt}/icons/cdrom_empty.ico (100%) rename src/{win => qt}/icons/cdrom_empty_active.ico (100%) rename src/{win => qt}/icons/display.ico (100%) rename src/{win => qt}/icons/floppy_35.ico (100%) rename src/{win => qt}/icons/floppy_35_active.ico (100%) rename src/{win => qt}/icons/floppy_35_empty.ico (100%) rename src/{win => qt}/icons/floppy_35_empty_active.ico (100%) rename src/{win => qt}/icons/floppy_525.ico (100%) rename src/{win => qt}/icons/floppy_525_active.ico (100%) rename src/{win => qt}/icons/floppy_525_empty.ico (100%) rename src/{win => qt}/icons/floppy_525_empty_active.ico (100%) rename src/{win => qt}/icons/floppy_and_cdrom_drives.ico (100%) rename src/{win => qt}/icons/floppy_disabled.ico (100%) rename src/{win => qt}/icons/hard_disk.ico (100%) rename src/{win => qt}/icons/hard_disk_active.ico (100%) rename src/{win => qt}/icons/hard_reset.ico (100%) rename src/{win => qt}/icons/input_devices.ico (100%) rename src/{win => qt}/icons/machine.ico (100%) rename src/{win => qt}/icons/mo.ico (100%) rename src/{win => qt}/icons/mo_active.ico (100%) rename src/{win => qt}/icons/mo_disabled.ico (100%) rename src/{win => qt}/icons/mo_empty.ico (100%) rename src/{win => qt}/icons/mo_empty_active.ico (100%) rename src/{win => qt}/icons/network.ico (100%) rename src/{win => qt}/icons/network_active.ico (100%) rename src/{win => qt}/icons/network_empty.ico (100%) rename src/{win => qt}/icons/other_peripherals.ico (100%) rename src/{win => qt}/icons/other_removable_devices.ico (100%) rename src/{win => qt}/icons/pause.ico (100%) rename src/{win => qt}/icons/ports.ico (100%) rename src/{win => qt}/icons/run.ico (100%) rename src/{win => qt}/icons/send_cad.ico (100%) rename src/{win => qt}/icons/send_cae.ico (100%) rename src/{win => qt}/icons/settings.ico (100%) rename src/{win => qt}/icons/sound.ico (100%) rename src/{win => qt}/icons/storage_controllers.ico (100%) rename src/{win => qt}/icons/zip.ico (100%) rename src/{win => qt}/icons/zip_active.ico (100%) rename src/{win => qt}/icons/zip_disabled.ico (100%) rename src/{win => qt}/icons/zip_empty.ico (100%) rename src/{win => qt}/icons/zip_empty_active.ico (100%) rename src/{win => qt}/win_netsocket.c (100%) rename src/{win => qt}/win_opendir.c (100%) rename src/{win => qt}/win_serial_passthrough.c (100%) delete mode 100644 src/win/86Box.rc delete mode 100644 src/win/CMakeLists.txt delete mode 100644 src/win/Makefile.mingw delete mode 100644 src/win/glad.c delete mode 100644 src/win/languages/cs-CZ.rc delete mode 100644 src/win/languages/de-DE.rc delete mode 100644 src/win/languages/dialogs.rc delete mode 100644 src/win/languages/en-GB.rc delete mode 100644 src/win/languages/en-US.rc delete mode 100644 src/win/languages/es-ES.rc delete mode 100644 src/win/languages/fi-FI.rc delete mode 100644 src/win/languages/fr-FR.rc delete mode 100644 src/win/languages/hr-HR.rc delete mode 100644 src/win/languages/hu-HU.rc delete mode 100644 src/win/languages/it-IT.rc delete mode 100644 src/win/languages/ja-JP.rc delete mode 100644 src/win/languages/ko-KR.rc delete mode 100644 src/win/languages/pl-PL.rc delete mode 100644 src/win/languages/pt-BR.rc delete mode 100644 src/win/languages/pt-PT.rc delete mode 100644 src/win/languages/ru-RU.rc delete mode 100644 src/win/languages/sl-SI.rc delete mode 100644 src/win/languages/tr-TR.rc delete mode 100644 src/win/languages/uk-UA.rc delete mode 100644 src/win/languages/zh-CN.rc delete mode 100644 src/win/languages/zh-TW.rc delete mode 100644 src/win/pcap_if.rc delete mode 100644 src/win/win.c delete mode 100644 src/win/win_about.c delete mode 100644 src/win/win_cdrom.c delete mode 100644 src/win/win_devconf.c delete mode 100644 src/win/win_dialog.c delete mode 100644 src/win/win_dynld.c delete mode 100644 src/win/win_icon.c delete mode 100644 src/win/win_joystick.cpp delete mode 100644 src/win/win_joystick_rawinput.c delete mode 100644 src/win/win_joystick_xinput.c delete mode 100644 src/win/win_jsconf.c delete mode 100644 src/win/win_keyboard.c delete mode 100644 src/win/win_media_menu.c delete mode 100644 src/win/win_mouse.c delete mode 100644 src/win/win_new_floppy.c delete mode 100644 src/win/win_opengl.c delete mode 100644 src/win/win_opengl_glslp.c delete mode 100644 src/win/win_preferences.c delete mode 100644 src/win/win_sdl.c delete mode 100644 src/win/win_settings.c delete mode 100644 src/win/win_snd_gain.c delete mode 100644 src/win/win_specify_dim.c delete mode 100644 src/win/win_stbar.c delete mode 100644 src/win/win_thread.c delete mode 100644 src/win/win_toolbar.c delete mode 100644 src/win/win_ui.c diff --git a/src/Makefile.local b/src/Makefile.local deleted file mode 100644 index fdb2dcab3..000000000 --- a/src/Makefile.local +++ /dev/null @@ -1,200 +0,0 @@ -# -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. -# -# This file is part of the 86Box distribution. -# -# Prefix for localizing the general Makefile.mingw for local -# settings, so we can avoid changing the main one for all of -# our local setups. -# -# Authors: Fred N. van Kempen, -# - -######################################################################### -# Anything here will override defaults in Makefile.MinGW. # -######################################################################### - - -# Name of the executable. -#PROG := 86box.exe - - -# Various compile-time options. -# -DROM_TRACE=0xc800 traces ROM access from segment C800 -# -DIO_TRACE=0x66 traces I/O on port 0x66 -# -DIO_CATCH enables I/O range catch logs -STUFF := - -# Add feature selections here. -# -DANSI_CFG forces the config file to ANSI encoding. -# Root logging: -# -DENABLE_ACPI_LOG=N sets logging level at N. -# -DENABLE_APM_LOG=N sets logging level at N. -# -DENABLE_BUGGER_LOG=N sets logging level at N. -# -DENABLE_CONFIG_LOG=N sets logging level at N. -# -DENABLE_DDMA_LOG=N sets logging level at N. -# -DENABLE_DEVICE_LOG=N sets logging level at N. -# -DENABLE_DMA_LOG=N sets logging level at N. -# -DENABLE_IO_LOG=N sets logging level at N. -# -DENABLE_IOAPIC_LOG=N sets logging level at N. -# -DENABLE_ISAMEM_LOG=N sets logging level at N. -# -DENABLE_ISARTC_LOG=N sets logging level at N. -# -DENABLE_KEYBOARD_AT_LOG=N sets logging level at N. -# -DENABLE_KEYBOARD_XT_LOG=N sets logging level at N. -# -DENABLE_LM75_LOG=N sets logging level at N. -# -DENABLE_LM78_LOG=N sets logging level at N. -# -DENABLE_MEM_LOG=N sets logging level at N. -# -DENABLE_MOUSE_LOG=N sets logging level at N. -# -DENABLE_MOUSE_BUS_LOG=N sets logging level at N. -# -DENABLE_MOUSE_PS2_LOG=N sets logging level at N. -# -DENABLE_MOUSE_SERIAL_LOG=N sets logging level at N. -# -DENABLE_NVR_LOG=N sets logging level at N. -# -DENABLE_PC_LOG=N sets logging level at N. -# -DENABLE_PCI_LOG=N sets logging level at N. -# -DENABLE_PIC_LOG=N sets logging level at N. -# -DENABLE_PIT_LOG=N sets logging level at N. -# -DENABLE_POSTCARD_LOG=N sets logging level at N. -# -DENABLE_ROM_LOG=N sets logging level at N. -# -DENABLE_SERIAL_LOG=N sets logging level at N. -# -DENABLE_SMBUS_LOG=N sets logging level at N. -# -DENABLE_SMBUS_PIIX4_LOG=N sets logging level at N. -# -DENABLE_SPD_LOG=N sets logging level at N. -# -DENABLE_USB_LOG=N sets logging level at N. -# -DENABLE_VNC_LOG=N sets logging level at N. -# -DENABLE_VNC_KEYMAP_LOG=N sets logging level at N. -# cdrom/ logging: -# -DENABLE_CDROM_LOG=N sets logging level at N. -# -DENABLE_CDROM_IMAGE_LOG=N sets logging level at N. -# -DENABLE_CDROM_IMAGE_BACKEND_LOG=N sets logging level at N. -# chipset/ logging: -# -DENABLE_I420EX_LOG=N sets logging level at N. -# -DENABLE_NEAT_LOG=N sets logging level at N. -# -DENABLE_OPTI495_LOG=N sets logging level at N. -# -DENABLE_OPTI895_LOG=N sets logging level at N. -# -DENABLE_PIIX_LOG=N sets logging level at N. -# -DENABLE_SIO_LOG=N sets logging level at N. -# -DENABLE_SIS_85C496_LOG=N sets logging level at N. -# codegen/, codegen_new/, cpu/ logging: -# -DENABLE_X86SEG_LOG=N sets logging level at N. -# cpu/ logging: -# -DENABLE_386_LOG=N sets logging level at N. -# -DENABLE_386_COMMON_LOG=N sets logging level at N. -# -DENABLE_386_DYNAREC_LOG=N sets logging level at N. -# -DENABLE_808X_LOG=N sets logging level at N. -# -DENABLE_CPU_LOG=N sets logging level at N. -# -DENABLE_FPU_LOG=N sets logging level at N. -# disk/ logging: -# -DENABLE_ESDI_AT_LOG=N sets logging level at N. -# -DENABLE_ESDI_MCA_LOG=N sets logging level at N. -# -DENABLE_HDC_LOG=N sets logging level at N. -# -DENABLE_HDD_IMAGE_LOG=N sets logging level at N. -# -DENABLE_IDE_LOG=N sets logging level at N. -# -DENABLE_MO_LOG=N sets logging level at N. -# -DENABLE_SFF_LOG=N sets logging level at N. -# -DENABLE_ST506_AT_LOG=N sets logging level at N. -# -DENABLE_ST506_XT_LOG=N sets logging level at N. -# -DENABLE_XTA_LOG=N sets logging level at N. -# -DENABLE_ZIP_LOG=N sets logging level at N. -# floppy/ logging: -# -DENABLE_D86F_LOG=N sets logging level at N. -# -DENABLE_FDC_LOG=N sets logging level at N. -# -DENABLE_FDD_LOG=N sets logging level at N. -# -DENABLE_FDI_LOG=N sets logging level at N. -# -DENABLE_FDI2RAW_LOG=N sets logging level at N. -# -DENABLE_IMD_LOG=N sets logging level at N. -# -DENABLE_IMG_LOG=N sets logging level at N. -# -DENABLE_JSON_LOG=N sets logging level at N. -# -DENABLE_MFM_LOG=N sets logging level at N. -# -DENABLE_TD0_LOG=N sets logging level at N. -# machine/ logging: -# -DENABLE_AMSTRAD_LOG=N sets logging level at N. -# -DENABLE_EUROPC_LOG=N sets logging level at N. -# -DENABLE_M24VID_LOG=N sets logging level at N. -# -DENABLE_MACHINE_LOG=N sets logging level at N. -# -DENABLE_PS1_HDC_LOG=N sets logging level at N. -# -DENABLE_PS2_MCA_LOG=N sets logging level at N. -# -DENABLE_TANDY_LOG=N sets logging level at N. -# -DENABLE_T1000_LOG=N sets logging level at N. -# -DENABLE_T3100E_LOG=N sets logging level at N. -# network/ logging: -# -DENABLE_3COM503_LOG=N sets logging level at N. -# -DENABLE_DP8390_LOG=N sets logging level at N. -# -DENABLE_NETWORK_LOG=N sets logging level at N. -# -DENABLE_NE2K_LOG=N sets logging level at N. -# -DENABLE_PCAP_LOG=N sets logging level at N. -# -DENABLE_PCNET_LOG=N sets logging level at N. -# -DENABLE_SLIRP_LOG=N sets logging level at N. -# -DENABLE_WD_LOG=N sets logging level at N. -# printer/ logging: -# -DENABLE_ESCP_LOG=N sets logging level at N. -# scsi/ logging: -# -DENABLE_AHA154X_LOG=N sets logging level at N. -# -DENABLE_BUSLOGIC_LOG=N sets logging level at N. -# -DENABLE_NCR5380_LOG=N sets logging level at N. -# -DENABLE_NCR53C8XX_LOG=N sets logging level at N. -# -DENABLE_SCSI_CDROM_LOG=N sets logging level at N. -# -DENABLE_SCSI_DISK_LOG=N sets logging level at N. -# -DENABLE_SPOCK_LOG=N sets logging level at N. -# -DENABLE_X54X_LOG=N sets logging level at N. -# sound/ logging: -# -DENABLE_ADLIB_LOG=N sets logging level at N. -# -DENABLE_AUDIOPCI_LOG=N sets logging level at N. -# -DENABLE_EMU8K_LOG=N sets logging level at N. -# -DENABLE_MPU401_LOG=N sets logging level at N. -# -DENABLE_PAS16_LOG=N sets logging level at N. -# -DENABLE_SB_LOG=N sets logging level at N. -# -DENABLE_SB_DSP_LOG=N sets logging level at N. -# -DENABLE_SOUND_LOG=N sets logging level at N. -# video/ logging: -# -DENABLE_ATI28800_LOG=N sets logging level at N. -# -DENABLE_MACH64_LOG=N sets logging level at N. -# -DENABLE_COMPAQ_CGA_LOG=N sets logging level at N. -# -DENABLE_ET4000W32_LOG=N sets logging level at N. -# -DENABLE_HT216_LOG=N sets logging level at N. -# -DENABLE_ICD2061_LOG=N sets logging level at N. -# -DENABLE_IM1024_LOG=N sets logging level at N. -# -DENABLE_PGC_LOG=N sets logging level at N. -# -DENABLE_S3_VIRGE_LOG=N sets logging level at N. -# -DENABLE_VID_TABLE_LOG=N sets logging level at N. -# -DENABLE_VIDEO_LOG=N sets logging level at N. -# -DENABLE_VOODOO_LOG=N sets logging level at N. -# win/ logging: -# -DENABLE_WIN_LOG=N sets logging level at N. -# -DENABLE_DISCORD_LOG=N sets logging level at N. -# -DENABLE_DYNLD_LOG=N sets logging level at N. -# -DENABLE_JOYSTICK_LOG=N sets logging level at N. -# -DENABLE_SDL_LOG=N sets logging level at N. -# -DENABLE_SETTINGS_LOG=N sets logging level at N. -EXTRAS := - - -AUTODEP := n -DEBUG := n -OPTIM := n -X64 := n -RELEASE := n -USB := n -VNC := n -RDP := n -DEV_BUILD := n -DEV_BRANCH := n -CIRRUS := n -NE1000 := n -NV_RIVA := n -OPENAL := y -FLUIDSYNTH := y -MUNT := y -PAS16 := n -DYNAREC := y - - -######################################################################### -# Include the master Makefile.MinGW for the rest. # -######################################################################### -include win/Makefile.mingw - - -# End of Makefile.local. diff --git a/src/win/86Box-qt.rc b/src/qt/86Box-qt.rc similarity index 100% rename from src/win/86Box-qt.rc rename to src/qt/86Box-qt.rc diff --git a/src/win/86Box.manifest b/src/qt/86Box.manifest similarity index 100% rename from src/win/86Box.manifest rename to src/qt/86Box.manifest diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 23cf865a0..e189ec569 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -189,7 +189,7 @@ endif() if(WIN32) enable_language(RC) - target_sources(86Box PUBLIC ../win/86Box-qt.rc) + target_sources(86Box PUBLIC 86Box-qt.rc) target_sources(plat PRIVATE win_dynld.c) # CMake 3.22 messed this up for clang/clang++ @@ -198,8 +198,8 @@ if(WIN32) # MSVC linker adds its own manifest to the executable, which fails if # we include ours in 86Box.rc. We therefore need to pass the manifest # directly as as a source file, so the linker can use that instead. - set_property(SOURCE ../win/86Box-qt.rc DIRECTORY .. PROPERTY COMPILE_DEFINITIONS NO_INCLUDE_MANIFEST) - target_sources(86Box PRIVATE ../win/86Box.manifest) + set_property(SOURCE 86Box-qt.rc DIRECTORY .. PROPERTY COMPILE_DEFINITIONS NO_INCLUDE_MANIFEST) + target_sources(86Box PRIVATE 86Box.manifest) endif() if (MINGW) @@ -217,11 +217,11 @@ else() endif() if(WIN32 AND NOT MINGW) - target_sources(plat PRIVATE ../win/win_opendir.c) + target_sources(plat PRIVATE win_opendir.c) endif() if(WIN32) - target_sources(plat PRIVATE ../win/win_serial_passthrough.c ../win/win_netsocket.c) + target_sources(plat PRIVATE win_serial_passthrough.c win_netsocket.c) else() target_sources(plat PRIVATE ../unix/unix_serial_passthrough.c ../unix/unix_netsocket.c) endif() diff --git a/src/win/assets/86Box-green.png b/src/qt/assets/86Box-green.png similarity index 100% rename from src/win/assets/86Box-green.png rename to src/qt/assets/86Box-green.png diff --git a/src/win/assets/86box-rb.png b/src/qt/assets/86box-rb.png similarity index 100% rename from src/win/assets/86box-rb.png rename to src/qt/assets/86box-rb.png diff --git a/src/win/assets/86box-red.png b/src/qt/assets/86box-red.png similarity index 100% rename from src/win/assets/86box-red.png rename to src/qt/assets/86box-red.png diff --git a/src/win/assets/86box-yellow.png b/src/qt/assets/86box-yellow.png similarity index 100% rename from src/win/assets/86box-yellow.png rename to src/qt/assets/86box-yellow.png diff --git a/src/win/assets/86box.png b/src/qt/assets/86box.png similarity index 100% rename from src/win/assets/86box.png rename to src/qt/assets/86box.png diff --git a/src/win/assets/status-paused.png b/src/qt/assets/status-paused.png similarity index 100% rename from src/win/assets/status-paused.png rename to src/qt/assets/status-paused.png diff --git a/src/win/assets/status-running.png b/src/qt/assets/status-running.png similarity index 100% rename from src/win/assets/status-running.png rename to src/qt/assets/status-running.png diff --git a/src/win/icons/86Box-gray.ico b/src/qt/icons/86Box-gray.ico similarity index 100% rename from src/win/icons/86Box-gray.ico rename to src/qt/icons/86Box-gray.ico diff --git a/src/win/icons/86Box-green.ico b/src/qt/icons/86Box-green.ico similarity index 100% rename from src/win/icons/86Box-green.ico rename to src/qt/icons/86Box-green.ico diff --git a/src/win/icons/86Box-red.ico b/src/qt/icons/86Box-red.ico similarity index 100% rename from src/win/icons/86Box-red.ico rename to src/qt/icons/86Box-red.ico diff --git a/src/win/icons/86Box-yellow.ico b/src/qt/icons/86Box-yellow.ico similarity index 100% rename from src/win/icons/86Box-yellow.ico rename to src/qt/icons/86Box-yellow.ico diff --git a/src/win/icons/acpi_shutdown.ico b/src/qt/icons/acpi_shutdown.ico similarity index 100% rename from src/win/icons/acpi_shutdown.ico rename to src/qt/icons/acpi_shutdown.ico diff --git a/src/win/icons/cartridge.ico b/src/qt/icons/cartridge.ico similarity index 100% rename from src/win/icons/cartridge.ico rename to src/qt/icons/cartridge.ico diff --git a/src/win/icons/cartridge_empty.ico b/src/qt/icons/cartridge_empty.ico similarity index 100% rename from src/win/icons/cartridge_empty.ico rename to src/qt/icons/cartridge_empty.ico diff --git a/src/win/icons/cassette.ico b/src/qt/icons/cassette.ico similarity index 100% rename from src/win/icons/cassette.ico rename to src/qt/icons/cassette.ico diff --git a/src/win/icons/cassette_active.ico b/src/qt/icons/cassette_active.ico similarity index 100% rename from src/win/icons/cassette_active.ico rename to src/qt/icons/cassette_active.ico diff --git a/src/win/icons/cassette_empty.ico b/src/qt/icons/cassette_empty.ico similarity index 100% rename from src/win/icons/cassette_empty.ico rename to src/qt/icons/cassette_empty.ico diff --git a/src/win/icons/cassette_empty_active.ico b/src/qt/icons/cassette_empty_active.ico similarity index 100% rename from src/win/icons/cassette_empty_active.ico rename to src/qt/icons/cassette_empty_active.ico diff --git a/src/win/icons/cdrom.ico b/src/qt/icons/cdrom.ico similarity index 100% rename from src/win/icons/cdrom.ico rename to src/qt/icons/cdrom.ico diff --git a/src/win/icons/cdrom_active.ico b/src/qt/icons/cdrom_active.ico similarity index 100% rename from src/win/icons/cdrom_active.ico rename to src/qt/icons/cdrom_active.ico diff --git a/src/win/icons/cdrom_disabled.ico b/src/qt/icons/cdrom_disabled.ico similarity index 100% rename from src/win/icons/cdrom_disabled.ico rename to src/qt/icons/cdrom_disabled.ico diff --git a/src/win/icons/cdrom_empty.ico b/src/qt/icons/cdrom_empty.ico similarity index 100% rename from src/win/icons/cdrom_empty.ico rename to src/qt/icons/cdrom_empty.ico diff --git a/src/win/icons/cdrom_empty_active.ico b/src/qt/icons/cdrom_empty_active.ico similarity index 100% rename from src/win/icons/cdrom_empty_active.ico rename to src/qt/icons/cdrom_empty_active.ico diff --git a/src/win/icons/display.ico b/src/qt/icons/display.ico similarity index 100% rename from src/win/icons/display.ico rename to src/qt/icons/display.ico diff --git a/src/win/icons/floppy_35.ico b/src/qt/icons/floppy_35.ico similarity index 100% rename from src/win/icons/floppy_35.ico rename to src/qt/icons/floppy_35.ico diff --git a/src/win/icons/floppy_35_active.ico b/src/qt/icons/floppy_35_active.ico similarity index 100% rename from src/win/icons/floppy_35_active.ico rename to src/qt/icons/floppy_35_active.ico diff --git a/src/win/icons/floppy_35_empty.ico b/src/qt/icons/floppy_35_empty.ico similarity index 100% rename from src/win/icons/floppy_35_empty.ico rename to src/qt/icons/floppy_35_empty.ico diff --git a/src/win/icons/floppy_35_empty_active.ico b/src/qt/icons/floppy_35_empty_active.ico similarity index 100% rename from src/win/icons/floppy_35_empty_active.ico rename to src/qt/icons/floppy_35_empty_active.ico diff --git a/src/win/icons/floppy_525.ico b/src/qt/icons/floppy_525.ico similarity index 100% rename from src/win/icons/floppy_525.ico rename to src/qt/icons/floppy_525.ico diff --git a/src/win/icons/floppy_525_active.ico b/src/qt/icons/floppy_525_active.ico similarity index 100% rename from src/win/icons/floppy_525_active.ico rename to src/qt/icons/floppy_525_active.ico diff --git a/src/win/icons/floppy_525_empty.ico b/src/qt/icons/floppy_525_empty.ico similarity index 100% rename from src/win/icons/floppy_525_empty.ico rename to src/qt/icons/floppy_525_empty.ico diff --git a/src/win/icons/floppy_525_empty_active.ico b/src/qt/icons/floppy_525_empty_active.ico similarity index 100% rename from src/win/icons/floppy_525_empty_active.ico rename to src/qt/icons/floppy_525_empty_active.ico diff --git a/src/win/icons/floppy_and_cdrom_drives.ico b/src/qt/icons/floppy_and_cdrom_drives.ico similarity index 100% rename from src/win/icons/floppy_and_cdrom_drives.ico rename to src/qt/icons/floppy_and_cdrom_drives.ico diff --git a/src/win/icons/floppy_disabled.ico b/src/qt/icons/floppy_disabled.ico similarity index 100% rename from src/win/icons/floppy_disabled.ico rename to src/qt/icons/floppy_disabled.ico diff --git a/src/win/icons/hard_disk.ico b/src/qt/icons/hard_disk.ico similarity index 100% rename from src/win/icons/hard_disk.ico rename to src/qt/icons/hard_disk.ico diff --git a/src/win/icons/hard_disk_active.ico b/src/qt/icons/hard_disk_active.ico similarity index 100% rename from src/win/icons/hard_disk_active.ico rename to src/qt/icons/hard_disk_active.ico diff --git a/src/win/icons/hard_reset.ico b/src/qt/icons/hard_reset.ico similarity index 100% rename from src/win/icons/hard_reset.ico rename to src/qt/icons/hard_reset.ico diff --git a/src/win/icons/input_devices.ico b/src/qt/icons/input_devices.ico similarity index 100% rename from src/win/icons/input_devices.ico rename to src/qt/icons/input_devices.ico diff --git a/src/win/icons/machine.ico b/src/qt/icons/machine.ico similarity index 100% rename from src/win/icons/machine.ico rename to src/qt/icons/machine.ico diff --git a/src/win/icons/mo.ico b/src/qt/icons/mo.ico similarity index 100% rename from src/win/icons/mo.ico rename to src/qt/icons/mo.ico diff --git a/src/win/icons/mo_active.ico b/src/qt/icons/mo_active.ico similarity index 100% rename from src/win/icons/mo_active.ico rename to src/qt/icons/mo_active.ico diff --git a/src/win/icons/mo_disabled.ico b/src/qt/icons/mo_disabled.ico similarity index 100% rename from src/win/icons/mo_disabled.ico rename to src/qt/icons/mo_disabled.ico diff --git a/src/win/icons/mo_empty.ico b/src/qt/icons/mo_empty.ico similarity index 100% rename from src/win/icons/mo_empty.ico rename to src/qt/icons/mo_empty.ico diff --git a/src/win/icons/mo_empty_active.ico b/src/qt/icons/mo_empty_active.ico similarity index 100% rename from src/win/icons/mo_empty_active.ico rename to src/qt/icons/mo_empty_active.ico diff --git a/src/win/icons/network.ico b/src/qt/icons/network.ico similarity index 100% rename from src/win/icons/network.ico rename to src/qt/icons/network.ico diff --git a/src/win/icons/network_active.ico b/src/qt/icons/network_active.ico similarity index 100% rename from src/win/icons/network_active.ico rename to src/qt/icons/network_active.ico diff --git a/src/win/icons/network_empty.ico b/src/qt/icons/network_empty.ico similarity index 100% rename from src/win/icons/network_empty.ico rename to src/qt/icons/network_empty.ico diff --git a/src/win/icons/other_peripherals.ico b/src/qt/icons/other_peripherals.ico similarity index 100% rename from src/win/icons/other_peripherals.ico rename to src/qt/icons/other_peripherals.ico diff --git a/src/win/icons/other_removable_devices.ico b/src/qt/icons/other_removable_devices.ico similarity index 100% rename from src/win/icons/other_removable_devices.ico rename to src/qt/icons/other_removable_devices.ico diff --git a/src/win/icons/pause.ico b/src/qt/icons/pause.ico similarity index 100% rename from src/win/icons/pause.ico rename to src/qt/icons/pause.ico diff --git a/src/win/icons/ports.ico b/src/qt/icons/ports.ico similarity index 100% rename from src/win/icons/ports.ico rename to src/qt/icons/ports.ico diff --git a/src/win/icons/run.ico b/src/qt/icons/run.ico similarity index 100% rename from src/win/icons/run.ico rename to src/qt/icons/run.ico diff --git a/src/win/icons/send_cad.ico b/src/qt/icons/send_cad.ico similarity index 100% rename from src/win/icons/send_cad.ico rename to src/qt/icons/send_cad.ico diff --git a/src/win/icons/send_cae.ico b/src/qt/icons/send_cae.ico similarity index 100% rename from src/win/icons/send_cae.ico rename to src/qt/icons/send_cae.ico diff --git a/src/win/icons/settings.ico b/src/qt/icons/settings.ico similarity index 100% rename from src/win/icons/settings.ico rename to src/qt/icons/settings.ico diff --git a/src/win/icons/sound.ico b/src/qt/icons/sound.ico similarity index 100% rename from src/win/icons/sound.ico rename to src/qt/icons/sound.ico diff --git a/src/win/icons/storage_controllers.ico b/src/qt/icons/storage_controllers.ico similarity index 100% rename from src/win/icons/storage_controllers.ico rename to src/qt/icons/storage_controllers.ico diff --git a/src/win/icons/zip.ico b/src/qt/icons/zip.ico similarity index 100% rename from src/win/icons/zip.ico rename to src/qt/icons/zip.ico diff --git a/src/win/icons/zip_active.ico b/src/qt/icons/zip_active.ico similarity index 100% rename from src/win/icons/zip_active.ico rename to src/qt/icons/zip_active.ico diff --git a/src/win/icons/zip_disabled.ico b/src/qt/icons/zip_disabled.ico similarity index 100% rename from src/win/icons/zip_disabled.ico rename to src/qt/icons/zip_disabled.ico diff --git a/src/win/icons/zip_empty.ico b/src/qt/icons/zip_empty.ico similarity index 100% rename from src/win/icons/zip_empty.ico rename to src/qt/icons/zip_empty.ico diff --git a/src/win/icons/zip_empty_active.ico b/src/qt/icons/zip_empty_active.ico similarity index 100% rename from src/win/icons/zip_empty_active.ico rename to src/qt/icons/zip_empty_active.ico diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 197ca980c..f87f8b6a9 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -199,13 +199,13 @@ main(int argc, char *argv[]) #ifndef Q_OS_MACOS # ifdef RELEASE_BUILD - app.setWindowIcon(QIcon(":/settings/win/icons/86Box-green.ico")); + app.setWindowIcon(QIcon(":/settings/qt/icons/86Box-green.ico")); # elif defined ALPHA_BUILD - app.setWindowIcon(QIcon(":/settings/win/icons/86Box-red.ico")); + app.setWindowIcon(QIcon(":/settings/qt/icons/86Box-red.ico")); # elif defined BETA_BUILD - app.setWindowIcon(QIcon(":/settings/win/icons/86Box-yellow.ico")); + app.setWindowIcon(QIcon(":/settings/qt/icons/86Box-yellow.ico")); # else - app.setWindowIcon(QIcon(":/settings/win/icons/86Box-gray.ico")); + app.setWindowIcon(QIcon(":/settings/qt/icons/86Box-gray.ico")); # endif # ifdef Q_OS_UNIX diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index f24ab0788..f0d2cf431 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -1704,13 +1704,13 @@ MainWindow::on_actionAbout_86Box_triggered() QDesktopServices::openUrl(QUrl("https://" EMU_SITE)); }); #ifdef RELEASE_BUILD - msgBox.setIconPixmap(QIcon(":/settings/win/icons/86Box-green.ico").pixmap(32, 32)); + msgBox.setIconPixmap(QIcon(":/settings/qt/icons/86Box-green.ico").pixmap(32, 32)); #elif defined ALPHA_BUILD - msgBox.setIconPixmap(QIcon(":/settings/win/icons/86Box-red.ico").pixmap(32, 32)); + msgBox.setIconPixmap(QIcon(":/settings/qt/icons/86Box-red.ico").pixmap(32, 32)); #elif defined BETA_BUILD - msgBox.setIconPixmap(QIcon(":/settings/win/icons/86Box-yellow.ico").pixmap(32, 32)); + msgBox.setIconPixmap(QIcon(":/settings/qt/icons/86Box-yellow.ico").pixmap(32, 32)); #else - msgBox.setIconPixmap(QIcon(":/settings/win/icons/86Box-gray.ico").pixmap(32, 32)); + msgBox.setIconPixmap(QIcon(":/settings/qt/icons/86Box-gray.ico").pixmap(32, 32)); #endif msgBox.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint); msgBox.exec(); @@ -1869,7 +1869,7 @@ MainWindow::setSendKeyboardInput(bool enabled) void MainWindow::updateUiPauseState() { - auto pause_icon = dopause ? QIcon(":/menuicons/win/icons/run.ico") : QIcon(":/menuicons/win/icons/pause.ico"); + auto pause_icon = dopause ? QIcon(":/menuicons/qt/icons/run.ico") : QIcon(":/menuicons/qt/icons/pause.ico"); auto tooltip_text = dopause ? QString(tr("Resume execution")) : QString(tr("Pause execution")); ui->actionPause->setIcon(pause_icon); ui->actionPause->setToolTip(tooltip_text); diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index 08d8bbf63..90dbfdab7 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -292,7 +292,7 @@ - :/menuicons/win/icons/hard_reset.ico:/menuicons/win/icons/hard_reset.ico + :/menuicons/qt/icons/hard_reset.ico:/menuicons/qt/icons/hard_reset.ico &Hard Reset... @@ -304,7 +304,7 @@ - :/menuicons/win/icons/send_cad.ico:/menuicons/win/icons/send_cad.ico + :/menuicons/qt/icons/send_cad.ico:/menuicons/qt/icons/send_cad.ico &Ctrl+Alt+Del @@ -325,7 +325,7 @@ - :/menuicons/win/icons/send_cae.ico:/menuicons/win/icons/send_cae.ico + :/menuicons/qt/icons/send_cae.ico:/menuicons/qt/icons/send_cae.ico Ctrl+Alt+&Esc @@ -340,7 +340,7 @@ - :/menuicons/win/icons/pause.ico:/menuicons/win/icons/pause.ico + :/menuicons/qt/icons/pause.ico:/menuicons/qt/icons/pause.ico &Pause @@ -357,7 +357,7 @@ - :/menuicons/win/icons/settings.ico:/menuicons/win/icons/settings.ico + :/menuicons/qt/icons/settings.ico:/menuicons/qt/icons/settings.ico &Settings... @@ -768,7 +768,7 @@ - :/menuicons/win/icons/acpi_shutdown.ico:/menuicons/win/icons/acpi_shutdown.ico + :/menuicons/qt/icons/acpi_shutdown.ico:/menuicons/qt/icons/acpi_shutdown.ico ACPI shutdown diff --git a/src/qt/qt_progsettings.cpp b/src/qt/qt_progsettings.cpp index 4dda901d7..35466e667 100644 --- a/src/qt/qt_progsettings.cpp +++ b/src/qt/qt_progsettings.cpp @@ -46,7 +46,7 @@ ProgSettings::getIconSetPath() { if (iconset_to_qt.isEmpty()) { // Always include default bundled icons - iconset_to_qt.insert("", ":/settings/win/icons"); + iconset_to_qt.insert("", ":/settings/qt/icons"); // Walk rom_paths to get the candidates for (rom_path_t *emu_rom_path = &rom_paths; emu_rom_path != nullptr; emu_rom_path = emu_rom_path->next) { // Check for icons subdir in each candidate diff --git a/src/qt/qt_settingsstoragecontrollers.cpp b/src/qt/qt_settingsstoragecontrollers.cpp index bc2be70cd..0f19d46fc 100644 --- a/src/qt/qt_settingsstoragecontrollers.cpp +++ b/src/qt/qt_settingsstoragecontrollers.cpp @@ -206,7 +206,6 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId) ui->checkBoxCassette->setEnabled(false); } - ui->checkBoxLbaEnhancer->setEnabled(device_available(&lba_enhancer_device)); ui->checkBoxLbaEnhancer->setChecked(lba_enhancer_enabled > 0 && device_available(&lba_enhancer_device)); ui->pushButtonConfigureLbaEnhancer->setEnabled(ui->checkBoxLbaEnhancer->isChecked()); } diff --git a/src/win/win_netsocket.c b/src/qt/win_netsocket.c similarity index 100% rename from src/win/win_netsocket.c rename to src/qt/win_netsocket.c diff --git a/src/win/win_opendir.c b/src/qt/win_opendir.c similarity index 100% rename from src/win/win_opendir.c rename to src/qt/win_opendir.c diff --git a/src/win/win_serial_passthrough.c b/src/qt/win_serial_passthrough.c similarity index 100% rename from src/win/win_serial_passthrough.c rename to src/qt/win_serial_passthrough.c diff --git a/src/qt_resources.qrc b/src/qt_resources.qrc index 67f9cadac..265fb6376 100644 --- a/src/qt_resources.qrc +++ b/src/qt_resources.qrc @@ -1,62 +1,62 @@ - win/icons/cartridge.ico - win/icons/cartridge_empty.ico - win/icons/cassette.ico - win/icons/cassette_active.ico - win/icons/cassette_empty.ico - win/icons/cassette_empty_active.ico - win/icons/cdrom.ico - win/icons/cdrom_active.ico - win/icons/cdrom_disabled.ico - win/icons/cdrom_empty.ico - win/icons/cdrom_empty_active.ico - win/icons/display.ico - win/icons/floppy_35.ico - win/icons/floppy_35_active.ico - win/icons/floppy_35_empty.ico - win/icons/floppy_35_empty_active.ico - win/icons/floppy_525.ico - win/icons/floppy_525_active.ico - win/icons/floppy_525_empty.ico - win/icons/floppy_525_empty_active.ico - win/icons/floppy_and_cdrom_drives.ico - win/icons/floppy_disabled.ico - win/icons/hard_disk.ico - win/icons/hard_disk_active.ico - win/icons/input_devices.ico - win/icons/machine.ico - win/icons/mo.ico - win/icons/mo_active.ico - win/icons/mo_disabled.ico - win/icons/mo_empty.ico - win/icons/mo_empty_active.ico - win/icons/network.ico - win/icons/network_active.ico - win/icons/network_empty.ico - win/icons/other_peripherals.ico - win/icons/other_removable_devices.ico - win/icons/ports.ico - win/icons/sound.ico - win/icons/storage_controllers.ico - win/icons/zip.ico - win/icons/zip_active.ico - win/icons/zip_disabled.ico - win/icons/zip_empty.ico - win/icons/zip_empty_active.ico - win/icons/86Box-gray.ico - win/icons/86Box-green.ico - win/icons/86Box-red.ico - win/icons/86Box-yellow.ico + qt/icons/cartridge.ico + qt/icons/cartridge_empty.ico + qt/icons/cassette.ico + qt/icons/cassette_active.ico + qt/icons/cassette_empty.ico + qt/icons/cassette_empty_active.ico + qt/icons/cdrom.ico + qt/icons/cdrom_active.ico + qt/icons/cdrom_disabled.ico + qt/icons/cdrom_empty.ico + qt/icons/cdrom_empty_active.ico + qt/icons/display.ico + qt/icons/floppy_35.ico + qt/icons/floppy_35_active.ico + qt/icons/floppy_35_empty.ico + qt/icons/floppy_35_empty_active.ico + qt/icons/floppy_525.ico + qt/icons/floppy_525_active.ico + qt/icons/floppy_525_empty.ico + qt/icons/floppy_525_empty_active.ico + qt/icons/floppy_and_cdrom_drives.ico + qt/icons/floppy_disabled.ico + qt/icons/hard_disk.ico + qt/icons/hard_disk_active.ico + qt/icons/input_devices.ico + qt/icons/machine.ico + qt/icons/mo.ico + qt/icons/mo_active.ico + qt/icons/mo_disabled.ico + qt/icons/mo_empty.ico + qt/icons/mo_empty_active.ico + qt/icons/network.ico + qt/icons/network_active.ico + qt/icons/network_empty.ico + qt/icons/other_peripherals.ico + qt/icons/other_removable_devices.ico + qt/icons/ports.ico + qt/icons/sound.ico + qt/icons/storage_controllers.ico + qt/icons/zip.ico + qt/icons/zip_active.ico + qt/icons/zip_disabled.ico + qt/icons/zip_empty.ico + qt/icons/zip_empty_active.ico + qt/icons/86Box-gray.ico + qt/icons/86Box-green.ico + qt/icons/86Box-red.ico + qt/icons/86Box-yellow.ico - win/icons/acpi_shutdown.ico - win/icons/hard_reset.ico - win/icons/pause.ico - win/icons/run.ico - win/icons/send_cad.ico - win/icons/send_cae.ico - win/icons/settings.ico + qt/icons/acpi_shutdown.ico + qt/icons/hard_reset.ico + qt/icons/pause.ico + qt/icons/run.ico + qt/icons/send_cad.ico + qt/icons/send_cae.ico + qt/icons/settings.ico qt/texture_vert.spv diff --git a/src/win/86Box.rc b/src/win/86Box.rc deleted file mode 100644 index 2932b7d62..000000000 --- a/src/win/86Box.rc +++ /dev/null @@ -1,365 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Application resource script for Windows. - * - * - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * David Hrdlička, - * - * Copyright 2016-2019 Miran Grca. - * Copyright 2018-2019 David Hrdlička. - * Copyright 2021 Laci bá' - */ -#define IN_RESOURCE_H -#include <86box/resource.h> -#include <86box/language.h> -#include <86box/version.h> -#undef IN_RESOURCE_H - -#define APSTUDIO_READONLY_SYMBOLS -#define APSTUDIO_HIDDEN_SYMBOLS -#include -#undef APSTUDIO_HIDDEN_SYMBOLS -#undef APSTUDIO_READONLY_SYMBOLS - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) - -///////////////////////////////////////////////////////////////////////////// -// -// Accelerator -// - -MainAccel ACCELERATORS MOVEABLE PURE -BEGIN -#ifdef MTR_ENABLED - "T", IDM_ACTION_TRACE, CONTROL, VIRTKEY -#endif - // VK_PRIOR,IDM_VID_FULLSCREEN, VIRTKEY, CONTROL , ALT - VK_F11, IDM_ACTION_SCREENSHOT, VIRTKEY, CONTROL - VK_F12, IDM_ACTION_RESET_CAD, VIRTKEY, CONTROL - VK_PAUSE,IDM_ACTION_PAUSE, VIRTKEY -END - - -#ifndef NO_INCLUDE_MANIFEST -///////////////////////////////////////////////////////////////////////////// -// -// 24 -// - -1 24 MOVEABLE PURE "86Box.manifest" -#endif - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -#ifdef CMAKE -#define ICON_PATH -#else -#define ICON_PATH "win/" -#endif - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -// defining the icons depending on the build status -#ifdef RELEASE_BUILD -/* Icon by OBattler and laciba96 (green for release builds)*/ - 10 ICON DISCARDABLE ICON_PATH "icons/86Box-green.ico" -#elif BETA_BUILD -/* Icon by OBattler and laciba96 (yellow for beta builds done by Jenkins)*/ - 10 ICON DISCARDABLE ICON_PATH "icons/86Box-yellow.ico" -#elif ALPHA_BUILD -/* Icon by OBattler and laciba96 (red for alpha builds done by Jenkins)*/ - 10 ICON DISCARDABLE ICON_PATH "icons/86Box-red.ico" -#else -/* Icon by OBattler and laciba96 (gray for builds of branches and from the git master)*/ - 10 ICON DISCARDABLE ICON_PATH "icons/86Box-gray.ico" -#endif - 16 ICON DISCARDABLE ICON_PATH "icons/floppy_525.ico" - 17 ICON DISCARDABLE ICON_PATH "icons/floppy_525_active.ico" - 24 ICON DISCARDABLE ICON_PATH "icons/floppy_35.ico" - 25 ICON DISCARDABLE ICON_PATH "icons/floppy_35_active.ico" - 32 ICON DISCARDABLE ICON_PATH "icons/cdrom.ico" - 33 ICON DISCARDABLE ICON_PATH "icons/cdrom_active.ico" - 48 ICON DISCARDABLE ICON_PATH "icons/zip.ico" - 49 ICON DISCARDABLE ICON_PATH "icons/zip_active.ico" - 56 ICON DISCARDABLE ICON_PATH "icons/mo.ico" - 57 ICON DISCARDABLE ICON_PATH "icons/mo_active.ico" - 64 ICON DISCARDABLE ICON_PATH "icons/cassette.ico" - 65 ICON DISCARDABLE ICON_PATH "icons/cassette_active.ico" - 80 ICON DISCARDABLE ICON_PATH "icons/hard_disk.ico" - 81 ICON DISCARDABLE ICON_PATH "icons/hard_disk_active.ico" - 96 ICON DISCARDABLE ICON_PATH "icons/network.ico" - 97 ICON DISCARDABLE ICON_PATH "icons/network_active.ico" -104 ICON DISCARDABLE ICON_PATH "icons/cartridge.ico" -144 ICON DISCARDABLE ICON_PATH "icons/floppy_525_empty.ico" -145 ICON DISCARDABLE ICON_PATH "icons/floppy_525_empty_active.ico" -152 ICON DISCARDABLE ICON_PATH "icons/floppy_35_empty.ico" -153 ICON DISCARDABLE ICON_PATH "icons/floppy_35_empty_active.ico" -160 ICON DISCARDABLE ICON_PATH "icons/cdrom_empty.ico" -161 ICON DISCARDABLE ICON_PATH "icons/cdrom_empty_active.ico" -176 ICON DISCARDABLE ICON_PATH "icons/zip_empty.ico" -177 ICON DISCARDABLE ICON_PATH "icons/zip_empty_active.ico" -184 ICON DISCARDABLE ICON_PATH "icons/mo_empty.ico" -185 ICON DISCARDABLE ICON_PATH "icons/mo_empty_active.ico" -192 ICON DISCARDABLE ICON_PATH "icons/cassette_empty.ico" -193 ICON DISCARDABLE ICON_PATH "icons/cassette_empty_active.ico" -200 ICON DISCARDABLE ICON_PATH "icons/run.ico" -201 ICON DISCARDABLE ICON_PATH "icons/pause.ico" -202 ICON DISCARDABLE ICON_PATH "icons/send_cad.ico" -203 ICON DISCARDABLE ICON_PATH "icons/send_cae.ico" -204 ICON DISCARDABLE ICON_PATH "icons/hard_reset.ico" -205 ICON DISCARDABLE ICON_PATH "icons/acpi_shutdown.ico" -206 ICON DISCARDABLE ICON_PATH "icons/settings.ico" -232 ICON DISCARDABLE ICON_PATH "icons/cartridge_empty.ico" -240 ICON DISCARDABLE ICON_PATH "icons/machine.ico" -241 ICON DISCARDABLE ICON_PATH "icons/display.ico" -242 ICON DISCARDABLE ICON_PATH "icons/input_devices.ico" -243 ICON DISCARDABLE ICON_PATH "icons/sound.ico" -244 ICON DISCARDABLE ICON_PATH "icons/ports.ico" -245 ICON DISCARDABLE ICON_PATH "icons/other_peripherals.ico" -246 ICON DISCARDABLE ICON_PATH "icons/floppy_and_cdrom_drives.ico" -247 ICON DISCARDABLE ICON_PATH "icons/other_removable_devices.ico" -248 ICON DISCARDABLE ICON_PATH "icons/floppy_disabled.ico" -249 ICON DISCARDABLE ICON_PATH "icons/cdrom_disabled.ico" -250 ICON DISCARDABLE ICON_PATH "icons/zip_disabled.ico" -251 ICON DISCARDABLE ICON_PATH "icons/mo_disabled.ico" -252 ICON DISCARDABLE ICON_PATH "icons/storage_controllers.ico" - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE DISCARDABLE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE DISCARDABLE -BEGIN - "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" - "#include ""windows.h""\r\n" - "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" - "#include ""resources.h""\r\n" - "\0" -END - -3 TEXTINCLUDE DISCARDABLE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO DISCARDABLE -BEGIN - DLG_SND_GAIN, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 167 - TOPMARGIN, 7 - BOTTOMMARGIN, 129 - END - - DLG_NEW_FLOPPY, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 219 - TOPMARGIN, 7 - BOTTOMMARGIN, 79 - END - - DLG_CFG_MAIN, DIALOG - BEGIN - RIGHTMARGIN, 365 - END - - ABOUTDLG, DIALOG - BEGIN - RIGHTMARGIN, 208 - END - - DLG_CFG_MACHINE, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 300 - TOPMARGIN, 7 -#ifdef USE_DYNAREC - BOTTOMMARGIN, 87 -#else - BOTTOMMARGIN, 72 -#endif - END - - DLG_CFG_VIDEO, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 300 - TOPMARGIN, 7 - BOTTOMMARGIN, 38 - END - - DLG_CFG_INPUT, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 300 - TOPMARGIN, 7 - BOTTOMMARGIN, 58 - END - - DLG_CFG_SOUND, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 300 - TOPMARGIN, 7 - BOTTOMMARGIN, 109 - END - - DLG_CFG_NETWORK, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 300 - TOPMARGIN, 7 - BOTTOMMARGIN, 56 - END - - DLG_CFG_PORTS, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 300 - TOPMARGIN, 7 - BOTTOMMARGIN, 48 - END - - DLG_CFG_PERIPHERALS, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 300 - TOPMARGIN, 7 - BOTTOMMARGIN, 85 - END - - DLG_CFG_HARD_DISKS, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 300 - TOPMARGIN, 7 - BOTTOMMARGIN, 137 - END - - DLG_CFG_FLOPPY_DRIVES, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 300 - TOPMARGIN, 7 - BOTTOMMARGIN, 96 - END - - DLG_CFG_OTHER_REMOVABLE_DEVICES, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 300 - TOPMARGIN, 7 - BOTTOMMARGIN, 214 - END -END -#endif // APSTUDIO_INVOKED - - -#ifndef _MAC -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION EMU_VERSION_MAJ,EMU_VERSION_MIN,EMU_VERSION_PATCH,EMU_BUILD_NUM - PRODUCTVERSION EMU_VERSION_MAJ,EMU_VERSION_MIN,EMU_VERSION_PATCH,EMU_BUILD_NUM - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "CompanyName", EMU_NAME "\0" - VALUE "FileDescription", EMU_NAME "\0" - VALUE "FileVersion", EMU_VERSION "\0" - VALUE "InternalName", EMU_NAME "\0" - VALUE "LegalCopyright", "Copyright \xa9 2007-" COPYRIGHT_YEAR " " EMU_NAME " contributors\0" - VALUE "OriginalFilename", EMU_NAME ".exe\0" - VALUE "ProductName", EMU_NAME "\0" - VALUE "ProductVersion", EMU_VERSION "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -#endif // !_MAC - -#endif - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - - -#include "languages/zh-CN.rc" -#include "languages/cs-CZ.rc" -#include "languages/de-DE.rc" -#include "languages/en-US.rc" -#include "languages/en-GB.rc" -#include "languages/fr-FR.rc" -#include "languages/hr-HR.rc" -#include "languages/fi-FI.rc" -#include "languages/hu-HU.rc" -#include "languages/it-IT.rc" -#include "languages/ja-JP.rc" -#include "languages/ko-KR.rc" -#include "languages/pl-PL.rc" -#include "languages/pt-BR.rc" -#include "languages/pt-PT.rc" -#include "languages/ru-RU.rc" -#include "languages/sl-SI.rc" -#include "languages/es-ES.rc" -#include "languages/tr-TR.rc" -#include "languages/uk-UA.rc" -#include "languages/zh-TW.rc" diff --git a/src/win/CMakeLists.txt b/src/win/CMakeLists.txt deleted file mode 100644 index dc8c53e45..000000000 --- a/src/win/CMakeLists.txt +++ /dev/null @@ -1,63 +0,0 @@ -# -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. -# -# This file is part of the 86Box distribution. -# -# CMake build script. -# -# Authors: David Hrdlička, -# -# Copyright 2020,2021 David Hrdlička. -# Copyright 2021-2022 Jasmine Iwanek. -# - -enable_language(RC) - -add_library(plat OBJECT win.c win_dynld.c win_cdrom.c win_keyboard.c - win_mouse.c win_serial_passthrough.c) - -add_library(ui OBJECT win_ui.c win_icon.c win_stbar.c win_sdl.c win_dialog.c win_about.c - win_settings.c win_devconf.c win_snd_gain.c win_specify_dim.c win_new_floppy.c - win_jsconf.c win_media_menu.c win_preferences.c glad.c win_opengl.c - win_opengl_glslp.c win_toolbar.c 86Box.rc) - -if(NOT CPPTHREADS) - target_sources(plat PRIVATE win_thread.c) -endif() - -if(RTMIDI) - target_compile_definitions(ui PRIVATE USE_RTMIDI) -endif() - -# CMake 3.22 messed this up for clang/clang++ -# See https://gitlab.kitware.com/cmake/cmake/-/issues/23066 -if(MSVC OR (NOT MINGW AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.22)) - # MSVC linker adds its own manifest to the executable, which fails if - # we include ours in 86Box.rc. We therefore need to pass the manifest - # directly as as a source file, so the linker can use that instead. - set_property(SOURCE 86Box.rc PROPERTY COMPILE_DEFINITIONS NO_INCLUDE_MANIFEST) - target_sources(86Box PRIVATE 86Box.manifest) -endif() - -if(NOT MINGW) - # Append null to resource strings (fixes file dialogs) - set_property(SOURCE 86Box.rc PROPERTY COMPILE_FLAGS -n) - - # `opendir` is only included in MinGW, so include an implementation - # for other builds. - target_sources(plat PRIVATE win_opendir.c) -endif() - -option(DINPUT "Use DirectInput joystick backend instead of raw input" OFF) -if(DINPUT) - target_sources(plat PRIVATE win_joystick.cpp) - target_link_libraries(86Box dinput8) -else() - target_sources(plat PRIVATE win_joystick_rawinput.c) -endif() - -target_link_libraries(86Box advapi32 comctl32 comdlg32 gdi32 shell32 iphlpapi - dxguid imm32 hid setupapi uxtheme version winmm psapi ws2_32) diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw deleted file mode 100644 index a80458938..000000000 --- a/src/win/Makefile.mingw +++ /dev/null @@ -1,988 +0,0 @@ -# -# -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. -# -# This file is part of the 86Box distribution. -# -# Makefile for Win32 (MinGW32) environment. -# -# Authors: Miran Grca, -# Fred N. van Kempen, -# - -# Various compile-time options. -ifndef STUFF - STUFF := -endif - -# Add feature selections here. -ifndef EXTRAS - EXTRAS := -endif - -ifndef DEV_BUILD - DEV_BUILD := n -endif - -ifeq ($(DEV_BUILD), y) - ifndef DEBUG - DEBUG := y - endif - ifndef GDBSTUB - GDBSTUB := n - endif - ifndef DEV_BRANCH - DEV_BRANCH := y - endif - ifndef AMD_K5 - AMD_K5 := y - endif - ifndef AN430TX - AN430TX := y - endif - ifndef CYRIX_6X86 - CYRIX_6X86 := y - endif - ifndef DESKPRO386 - DESKPRO386 := y - endif - ifndef GUSMAX - GUSMAX := y - endif - ifndef ISAMEM_RAMPAGE - ISAMEM_RAMPAGE := y - endif - ifndef ISAMEM_IAB - ISAMEM_IAB := y - endif - ifndef ISAMEM_BRAT - ISAMEM_BRAT := y - endif - ifndef LASERXT - LASERXT := y - endif - ifndef OLIVETTI - OLIVETTI := y - endif - ifndef OPEN_AT - OPEN_AT := y - endif - ifndef OPL4ML - OPL4ML := y - endif - ifndef PAS16 - PAS16 := y - endif - ifndef PCI_DUMMY - PCI_DUMMY := y - endif - ifndef SIO_DETECT - SIO_DETECT := y - endif - ifndef VGAWONDER - VGAWONDER := y - endif - ifndef XL24 - XL24 := y - endif - ifndef NEW_KBC - NEW_KBC := n - endif -else - ifndef DEBUG - DEBUG := n - endif - ifndef GDBSTUB - GDBSTUB := n - endif - ifndef DEV_BRANCH - DEV_BRANCH := n - endif - ifndef AMD_K5 - AMD_K5 := n - endif - ifndef AN430TX - AN430TX := n - endif - ifndef CYRIX_6X86 - CYRIX_6X86 := n - endif - ifndef DESKPRO386 - DESKPRO386 := n - endif - ifndef GUSMAX - GUSMAX := n - endif - ifndef ISAMEM_RAMPAGE - ISAMEM_RAMPAGE := n - endif - ifndef ISAMEM_IAB - ISAMEM_IAB := n - endif - ifndef ISAMEM_BRAT - ISAMEM_BRAT := n - endif - ifndef LASERXT - LASERXT := n - endif - ifndef OLIVETTI - OLIVETTI := n - endif - ifndef OPEN_AT - OPEN_AT := n - endif - ifndef OPL4ML - OPL4ML := n - endif - ifndef PAS16 - PAS16 := n - endif - ifndef PCI_DUMMY - PCI_DUMMY := n - endif - ifndef SIO_DETECT - SIO_DETECT := n - endif - ifndef VGAWONDER - VGAWONDER := n - endif - ifndef XL24 - XL24 := n - endif - ifndef NEW_KBC - NEW_KBC := n - endif -endif - -# Defaults for several build options (possibly defined in a chained file.) -ifndef AUTODEP - AUTODEP := n -endif -ifndef OPTIM - OPTIM := n -endif -ifndef RELEASE - RELEASE := n -endif -ifndef X64 - X64 := n -endif -ifndef ARM - ARM := n -endif -ifndef ARM64 - ARM64 := n -endif -ifndef DINPUT - DINPUT := n -endif -ifndef FAUDIO - FAUDIO := n -endif -ifndef OPENAL - OPENAL := y -endif -ifndef FLUIDSYNTH - FLUIDSYNTH := y -endif -ifndef MUNT - MUNT := y -endif -ifndef VNC - VNC := n -endif -ifndef NEW_DYNAREC - NEW_DYNAREC := n -endif -ifndef DYNAREC - DYNAREC := y -endif -ifndef CPPTHREADS - CPPTHREADS := y -endif -ifndef RTMIDI - RTMIDI := y -endif -ifndef MINITRACE - MINITRACE := n -endif -ifndef AVX - AVX := n -endif -ifeq ($(DYNAREC), y) - ifeq ($(ARM), y) - ifeq ($(NEW_DYNAREC), n) - DYNAREC := n - endif - endif - ifeq ($(ARM64), y) - ifeq ($(NEW_DYNAREC), n) - DYNAREC := n - endif - endif -endif - - -# Path to the dynamic recompiler code. -ifeq ($(NEW_DYNAREC), y) - CODEGEN := codegen_new -else - CODEGEN := codegen -endif - - -# Name of the executable. -PROG := 86Box - - -######################################################################### -# Nothing should need changing from here on.. # -######################################################################### -VPATH := $(EXPATH) . $(CODEGEN) minitrace cpu cpu/softfloat \ - cpu/808x cdrom chipset device disk disk/minivhd floppy \ - game machine mem printer \ - sio sound \ - sound/munt sound/munt/c_interface sound/munt/sha1 \ - sound/munt/srchelper sound/munt/srchelper/srctools/src \ - sound/resid-fp sound/ymfm \ - scsi video network win - -WINDRES := windres -STRIP := strip -ifeq ($(X64), y) - TOOL_PREFIX := x86_64-w64-mingw32- -else - ifeq ($(ARM64), y) - TOOL_PREFIX := aarch64-w64-mingw32- - WINDRES := ${TOOL_PREFIX}windres - STRIP := ${TOOL_PREFIX}strip - endif - ifeq ($(ARM), y) - TOOL_PREFIX := armv7-w64-mingw32- - WINDRES := ${TOOL_PREFIX}windres - STRIP := ${TOOL_PREFIX}strip - endif - TOOL_PREFIX := i686-w64-mingw32- -endif - -ifeq ($(CLANG), y) - CPP := clang++ - CC := clang -else - CPP := ${TOOL_PREFIX}g++ - CC := ${TOOL_PREFIX}gcc -endif - -DEPS = -MMD -MF $*.d -c $< -DEPFILE := win/.depends - -# Set up the correct toolchain flags. -OPTS := $(EXTRAS) $(STUFF) -OPTS += -Iinclude -Iinclude_make \ - -iquote $(CODEGEN) -iquote cpu -ifdef EXFLAGS - OPTS += $(EXFLAGS) -endif -ifdef EXINC - OPTS += -I$(EXINC) -endif -ifeq ($(OPTIM), y) - DFLAGS := -march=native -else - ifeq ($(X64), y) - DFLAGS := - else - DFLAGS := -march=i686 - endif -endif -ifeq ($(DEBUG), y) - DFLAGS += -ggdb -DDEBUG - AOPTIM := - ifndef COPTIM - COPTIM := -Og - endif - ifndef CXXOPTIM - ifeq ($(CLANG), y) - CXXOPTIM := -Os - else - CXXOPTIM := -Og - endif - endif -else - DFLAGS += -g0 - ifeq ($(OPTIM), y) - AOPTIM := -mtune=native - ifndef COPTIM - CXXOPTIM := -O3 -ffp-contract=fast -flto - endif - ifndef CXXOPTIM - ifeq ($(CLANG), y) - CXXOPTIM := -Os -ffp-contract=fast -flto - else - CXXOPTIM := -O3 -ffp-contract=fast -flto - endif - endif - else - ifndef COPTIM - COPTIM := -O3 - endif - ifndef CXXOPTIM - ifeq ($(CLANG), y) - CXXOPTIM := -Os - else - CXXOPTIM := -O3 - endif - endif - endif -endif -ifeq ($(AVX), y) - AFLAGS := -msse2 -msse3 -mssse3 -msse4 -msse4a -mavx -mavx2 -mfpmath=sse -else - AFLAGS := -msse2 -mfpmath=sse -endif -ifeq ($(ARM), y) - DFLAGS := -march=armv7-a - AOPTIM := - AFLAGS := -mfloat-abi=hard -endif -ifeq ($(ARM64), y) - DFLAGS := -march=armv8-a - AOPTIM := - AFLAGS := -mfloat-abi=hard -endif -RFLAGS := --input-format=rc -O coff -Iinclude -Iinclude_make -ifeq ($(RELEASE), y) - OPTS += -DRELEASE_BUILD - RFLAGS += -DRELEASE_BUILD -endif - - -# Optional modules. -ifeq ($(DYNAREC), y) - OPTS += -DUSE_DYNAREC - RFLAGS += -DUSE_DYNAREC - - ifeq ($(NEW_DYNAREC), y) - OPTS += -DUSE_NEW_DYNAREC - RFLAGS += -DUSE_NEW_DYNAREC - - ifeq ($(X64), y) - PLATCG := codegen_backend_x86-64.o codegen_backend_x86-64_ops.o codegen_backend_x86-64_ops_sse.o \ - codegen_backend_x86-64_uops.o - else ifeq ($(ARM64), y) - PLATCG := codegen_backend_arm64.o codegen_backend_arm64_ops.o codegen_backend_arm64_uops.o \ - codegen_backend_arm64_imm.o - else ifeq ($(ARM), y) - PLATCG := codegen_backend_arm.o codegen_backend_arm_ops.o codegen_backend_arm_uops.o - else - PLATCG := codegen_backend_x86.o codegen_backend_x86_ops.o codegen_backend_x86_ops_fpu.o \ - codegen_backend_x86_ops_sse.o codegen_backend_x86_uops.o - endif - - DYNARECOBJ := codegen.o codegen_accumulate.o codegen_allocator.o codegen_block.o codegen_ir.o codegen_ops.o \ - codegen_ops_3dnow.o codegen_ops_branch.o codegen_ops_arith.o codegen_ops_fpu_arith.o \ - codegen_ops_fpu_constant.o codegen_ops_fpu_loadstore.o codegen_ops_fpu_misc.o codegen_ops_helpers.o \ - codegen_ops_jump.o codegen_ops_logic.o codegen_ops_misc.o codegen_ops_mmx_arith.o codegen_ops_mmx_cmp.o \ - codegen_ops_mmx_loadstore.o codegen_ops_mmx_logic.o codegen_ops_mmx_pack.o codegen_ops_mmx_shift.o \ - codegen_ops_mov.o codegen_ops_shift.o codegen_ops_stack.o codegen_reg.o $(PLATCG) - else - ifeq ($(X64), y) - PLATCG := codegen_x86-64.o codegen_accumulate_x86-64.o - else - PLATCG := codegen_x86.o codegen_accumulate_x86.o - endif - - DYNARECOBJ := codegen.o \ - codegen_ops.o $(PLATCG) - endif - - CGTOBJ := codegen_timing_486.o \ - codegen_timing_686.o codegen_timing_common.o codegen_timing_k6.o codegen_timing_pentium.o \ - codegen_timing_p6.o codegen_timing_winchip.o codegen_timing_winchip2.o -else - ifeq ($(NEW_DYNAREC), y) - OPTS += -DUSE_NEW_DYNAREC - RFLAGS += -DUSE_NEW_DYNAREC - endif -endif - -ifeq ($(FLUIDSYNTH), y) - OPTS += -DUSE_FLUIDSYNTH - FSYNTHOBJ := midi_fluidsynth.o -endif - -ifeq ($(MUNT), y) - OPTS += -DUSE_MUNT - MUNTOBJ := midi_mt32.o \ - Analog.o BReverbModel.o Display.o File.o FileStream.o LA32Ramp.o \ - LA32FloatWaveGenerator.o LA32WaveGenerator.o \ - MidiStreamParser.o Part.o Partial.o PartialManager.o \ - Poly.o ROMInfo.o SampleRateConverter.o \ - FIRResampler.o IIR2xResampler.o LinearResampler.o ResamplerModel.o \ - SincResampler.o InternalResampler.o \ - Synth.o Tables.o TVA.o TVF.o TVP.o sha1.o c_interface.o -endif - -ifeq ($(CPPTHREADS), y) - THREADOBJ := thread.o -else - THREADOBJ := win_thread.o -endif - -ifeq ($(VNC), y) - OPTS += -DUSE_VNC - RFLAGS += -DUSE_VNC - ifneq ($(VNC_PATH), ) - OPTS += -I$(VNC_PATH)\INCLUDE - VNCLIB := -L$(VNC_PATH)\LIB - endif - VNCLIB += -lvncserver.dll - VNCOBJ := vnc.o vnc_keymap.o -endif - -ifeq ($(MINITRACE), y) - OPTS += -DMTR_ENABLED - RFLAGS += -DMTR_ENABLED - MINITRACEOBJ := minitrace.o -endif - -ifeq ($(FAUDIO), y) - OPTS += -DUSE_FAUDIO -endif - -# Options for the DEV branch. -ifeq ($(DEV_BRANCH), y) - OPTS += -DDEV_BRANCH - RFLAGS += -DDEV_BRANCH - DEVBROBJ := - - ifeq ($(AMD_K5), y) - OPTS += -DUSE_AMD_K5 - endif - - ifeq ($(AN430TX), y) - OPTS += -DUSE_AN430TX - endif - - ifeq ($(CYRIX_6X86), y) - OPTS += -DUSE_CYRIX_6X86 - endif - - ifeq ($(DESKPRO386), y) - OPTS += -DUSE_DESKPRO386 - endif - - ifeq ($(GUSMAX), y) - OPTS += -DUSE_GUSMAX - endif - - ifeq ($(ISAMEM_RAMPAGE), y) - OPTS += -DUSE_ISAMEM_RAMPAGE - endif - - ifeq ($(ISAMEM_IAB), y) - OPTS += -DUSE_ISAMEM_IAB - endif - - ifeq ($(ISAMEM_BRAT), y) - OPTS += -DUSE_ISAMEM_BRAT - endif - - ifeq ($(LASERXT), y) - OPTS += -DUSE_LASERXT - DEVBROBJ += m_xt_laserxt.o - endif - - ifeq ($(OPEN_AT), y) - OPTS += -DUSE_OPEN_AT - endif - - ifeq ($(OPL4ML), y) - OPTS += -DUSE_OPL4ML - DEVBROBJ += midi_opl4.o midi_opl4_yrw801.o - endif - - ifeq ($(PAS16), y) - OPTS += -DUSE_PAS16 - DEVBROBJ += snd_pas16.o - endif - - ifeq ($(PCI_DUMMY), y) - OPTS += -DUSE_PCI_DUMMY - DEVBROBJ += pci_dummy.o - endif - - ifeq ($(SIO_DETECT), y) - OPTS += -DUSE_SIO_DETECT - DEVBROBJ += sio_detect.o - endif - - ifeq ($(VGAWONDER), y) - OPTS += -DUSE_VGAWONDER - endif - - ifeq ($(XL24), y) - OPTS += -DUSE_XL24 - endif - - ifeq ($(OLIVETTI), y) - OPTS += -DUSE_OLIVETTI - DEVBROBJ += olivetti_eva.o - endif - - ifeq ($(GDBSTUB), y) - OPTS += -DUSE_GDBSTUB - DEVBROBJ += gdbstub.o - endif -endif - -ifeq ($(RTMIDI), y) - OPTS += -DUSE_RTMIDI -endif - - -# Final versions of the toolchain flags. -CFLAGS := $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) \ - $(AFLAGS) -fomit-frame-pointer -mstackrealign -Wall \ - -fno-strict-aliasing - -# Add freetyp2 references through pkgconfig -CFLAGS := $(CFLAGS) `pkg-config --cflags freetype2` - -CXXFLAGS := $(OPTS) $(DFLAGS) $(CXXOPTIM) $(AOPTIM) \ - $(AFLAGS) -fomit-frame-pointer -mstackrealign -Wall \ - -fno-strict-aliasing - -CFLAGS += -Werror=implicit-int -Werror=implicit-function-declaration \ - -Werror=int-conversion -Werror=strict-prototypes -Werror=old-style-definition - - -######################################################################### -# Create the (final) list of objects to build. # -######################################################################### -MAINOBJ := 86box.o config.o log.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \ - nmi.o pic.o pit.o pit_fast.o port_6x.o port_92.o ppi.o pci.o mca.o fifo.o \ - fifo8.o usb.o device.o nvr.o nvr_at.o nvr_ps2.o machine_status.o ini.o \ - $(VNCOBJ) - -MEMOBJ := catalyst_flash.o i2c_eeprom.o intel_flash.o mem.o mmu_2386.o rom.o row.o \ - smram.o spd.o sst_flash.o - -CPUOBJ := $(DYNARECOBJ) \ - $(CGTOBJ) \ - cpu.o cpu_table.o fpu.o x86.o \ - 8080.o 808x.o 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o \ - x86_ops_mmx.o x86seg_common.o x86seg_2386.o x86seg.o x87.o x87_timings.o \ - f2xm1.o fpatan.o fprem.o fsincos.o fyl2x.o softfloat_poly.o softfloat.o softfloat16.o \ - softfloat-muladd.o softfloat-round-pack.o softfloat-specialize.o softfloatx80.o - -CHIPSETOBJ := 82c100.o acc2168.o \ - compaq_386.o \ - contaq_82c59x.o \ - cs4031.o cs8230.o \ - ali1429.o ali1435.o ali1489.o ali1531.o ali1541.o ali1543.o ali1621.o ali6117.o \ - gc100.o headland.o \ - ims8848.o intel_82335.o intel_420ex.o intel_4x0.o intel_i450kx.o intel_sio.o intel_piix.o \ - ioapic.o \ - neat.o \ - opti283.o opti291.o opti391.o opti495.o opti602.o opti822.o opti895.o opti5x7.o \ - scamp.o scat.o \ - stpc.o \ - wd76c10.o vl82c480.o \ - umc_8886.o umc_hb4.o \ - via_vt82c49x.o via_vt82c505.o via_apollo.o via_pipc.o \ - sis_85c310.o sis_85c4xx.o sis_85c496.o sis_85c50x.o sis_5511.o sis_5571.o - -MCHOBJ := machine.o machine_table.o \ - m_xt.o m_xt_compaq.o \ - m_xt_philips.o \ - m_xt_t1000.o m_xt_t1000_vid.o \ - m_xt_xi8088.o m_xt_zenith.o \ - m_pcjr.o \ - m_amstrad.o m_europc.o \ - m_elt.o \ - m_xt_olivetti.o m_tandy.o m_v86p.o \ - m_at.o m_at_commodore.o \ - m_at_t3100e.o m_at_t3100e_vid.o \ - m_ps1.o m_ps1_hdc.o \ - m_ps2_isa.o m_ps2_mca.o \ - m_at_compaq.o \ - m_at_286_386sx.o m_at_386dx_486.o \ - m_at_socket4.o m_at_socket5.o m_at_socket7_3v.o m_at_socket7.o m_at_sockets7.o \ - m_at_socket8.o m_at_slot1.o m_at_slot2.o m_at_socket370.o \ - m_at_misc.o - -KBCOBJ := kbc_at.o kbc_at_dev.o \ - keyboard_at.o - -DEVOBJ := bugger.o cartridge.o cassette.o hasp.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c686.o \ - ibm_5161.o isamem.o isartc.o lpt.o pci_bridge.o postcard.o serial.o \ - clock_ics9xxx.o isapnp.o \ - i2c.o i2c_gpio.o smbus_ali7101.o smbus_piix4.o \ - keyboard.o \ - keyboard_xt.o $(KBCOBJ) \ - mouse.o \ - mouse_bus.o \ - mouse_serial.o mouse_ps2.o \ - mouse_wacom_tablet.o \ - nec_mate_unk.o phoenix_486_jumper.o \ - serial_passthrough.o \ - unittester.o - -SIOOBJ := sio_acc3221.o sio_ali5123.o \ - sio_f82c710.o sio_82091aa.o sio_fdc37c6xx.o \ - sio_fdc37c67x.o sio_fdc37c669.o sio_fdc37c93x.o sio_fdc37m60x.o \ - sio_it86x1f.o \ - sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87310.o sio_pc87311.o sio_pc87332.o \ - sio_prime3b.o sio_prime3c.o \ - sio_w83787f.o \ - sio_w83877f.o sio_w83977f.o \ - sio_um8669f.o \ - sio_vt82c686.o - -FDDOBJ := fdd.o fdc.o fdc_magitronic.o fdc_monster.o fdc_pii15xb.o \ - fdi2raw.o \ - fdd_common.o fdd_86f.o \ - fdd_fdi.o fdd_imd.o fdd_img.o fdd_json.o \ - fdd_mfm.o fdd_td0.o - -GAMEOBJ := gameport.o \ - joystick_standard.o joystick_ch_flightstick_pro.o \ - joystick_sw_pad.o joystick_tm_fcs.o - -HDDOBJ := hdd.o \ - hdd_image.o hdd_table.o \ - hdc.o \ - hdc_st506_xt.o hdc_st506_at.o \ - hdc_xta.o \ - hdc_esdi_at.o hdc_esdi_mca.o \ - hdc_xtide.o hdc_ide.o \ - hdc_ide_ali5213.o \ - hdc_ide_opti611.o \ - hdc_ide_cmd640.o hdc_ide_cmd646.o \ - hdc_ide_sff8038i.o - -MINIVHDOBJ := cwalk.o xml2_encoding.o convert.o \ - create.o minivhd_io.o manage.o struct_rw.o minivhd_util.o - -CDROMOBJ := cdrom.o \ - cdrom_image_backend.o cdrom_image_viso.o cdrom_image.o cdrom_mitsumi.o - -ZIPOBJ := zip.o - -MOOBJ := mo.o - -SCSIOBJ := scsi.o scsi_device.o \ - scsi_cdrom.o scsi_disk.o \ - scsi_x54x.o \ - scsi_aha154x.o scsi_buslogic.o \ - scsi_ncr5380.o scsi_ncr53c8xx.o \ - scsi_pcscsi.o scsi_spock.o - -NETOBJ := network.o \ - net_pcap.o \ - net_slirp.o \ - net_dp8390.o net_3c501.o \ - net_3c503.o net_ne2000.o \ - net_pcnet.o net_wd8003.o \ - net_plip.o net_event.o \ - net_null.o \ - net_eeprom_nmc93cxx.o \ - net_tulip.o \ - net_rtl8139.o \ - net_l80225.o - -PRINTOBJ := png.o prt_cpmap.o \ - prt_escp.o prt_text.o prt_ps.o - -SNDOBJ := sound.o \ - snd_opl.o snd_opl_nuked.o snd_opl_ymfm.o \ - ymfm_adpcm.o ymfm_misc.o ymfm_opl.o ymfm_opm.o \ - ymfm_opn.o ymfm_opq.o ymfm_opz.o ymfm_pcm.o ymfm_ssg.o \ - snd_resid.o \ - convolve.o convolve-sse.o envelope.o extfilt.o \ - filter.o pot.o sid.o voice.o wave6581__ST.o \ - wave6581_P_T.o wave6581_PS_.o wave6581_PST.o \ - wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ - wave8580_PST.o wave.o \ - midi.o \ - snd_speaker.o \ - snd_pssj.o \ - snd_ps1.o \ - snd_lpt_dac.o snd_lpt_dss.o \ - snd_adlib.o snd_adlibgold.o snd_ad1848.o snd_audiopci.o \ - snd_ac97_codec.o snd_ac97_via.o \ - snd_azt2316a.o snd_cs423x.o \ - snd_optimc.o snd_cmi8x38.o \ - snd_cms.o \ - snd_gus.o \ - snd_sb.o snd_sb_dsp.o \ - snd_emu8k.o snd_mpu401.o \ - snd_sn76489.o snd_ssi2001.o \ - snd_wss.o \ - snd_ym7128.o - -VIDOBJ := agpgart.o video.o \ - vid_table.o \ - vid_cga.o vid_cga_comp.o \ - vid_compaq_cga.o \ - vid_mda.o \ - vid_hercules.o vid_herculesplus.o vid_incolor.o \ - vid_colorplus.o \ - vid_genius.o \ - vid_pgc.o vid_im1024.o \ - vid_sigma.o \ - vid_wy700.o \ - vid_ega.o vid_ega_render.o \ - vid_svga.o vid_svga_render.o \ - vid_8514a.o \ - vid_ddc.o \ - vid_vga.o \ - vid_ati_eeprom.o \ - vid_ati18800.o vid_ati28800.o \ - vid_ati_mach8.o \ - vid_ati68875_ramdac.o \ - vid_ati_mach64.o vid_ati68860_ramdac.o \ - vid_bt48x_ramdac.o \ - vid_chips_69000.o \ - vid_av9194.o vid_icd2061.o vid_ics2494.o vid_ics2595.o \ - vid_cl54xx.o \ - vid_et3000.o \ - vid_et4000.o vid_sc1148x_ramdac.o \ - vid_sc1502x_ramdac.o \ - vid_et4000w32.o vid_stg_ramdac.o \ - vid_ht216.o \ - vid_oak_oti.o \ - vid_paradise.o \ - vid_rtg310x.o \ - vid_ti_cf62011.o \ - vid_f82c425.o \ - vid_tvga.o \ - vid_tgui9440.o vid_tkd8001_ramdac.o \ - vid_att20c49x_ramdac.o \ - vid_att2xc498_ramdac.o \ - vid_s3.o vid_s3_virge.o \ - vid_ibm_rgb528_ramdac.o vid_sdac_ramdac.o \ - vid_ogc.o \ - vid_mga.o \ - vid_nga.o \ - vid_tvp3026_ramdac.o \ - vid_xga.o - -VOODOOOBJ := vid_voodoo.o vid_voodoo_banshee.o \ - vid_voodoo_banshee_blitter.o \ - vid_voodoo_blitter.o \ - vid_voodoo_display.o vid_voodoo_fb.o \ - vid_voodoo_fifo.o vid_voodoo_reg.o \ - vid_voodoo_render.o vid_voodoo_setup.o \ - vid_voodoo_texture.o - -PLATOBJ := win.o \ - win_dynld.o \ - win_cdrom.o win_keyboard.o \ - win_mouse.o win_serial_passthrough.o - -UIOBJ := win_ui.o win_icon.o win_stbar.o discord.o \ - win_sdl.o win_opengl.o win_opengl_glslp.o glad.o \ - win_dialog.o win_about.o \ - win_settings.o win_devconf.o win_snd_gain.o win_specify_dim.o win_preferences.o \ - win_new_floppy.o win_jsconf.o \ - win_media_menu.o win_toolbar.o - -ifeq ($(DINPUT), y) - PLATOBJ += win_joystick.o -else - PLATOBJ += win_joystick_rawinput.o -endif - -ifeq ($(OPENAL), y) - SNDOBJ += openal.o -else - SNDOBJ += xaudio2.o -endif - -ifeq ($(RTMIDI), y) - SNDOBJ += midi_rtmidi.o -endif - -OBJ := $(MAINOBJ) $(CPUOBJ) $(CHIPSETOBJ) $(MCHOBJ) $(DEVOBJ) $(MEMOBJ) \ - $(FDDOBJ) $(GAMEOBJ) $(CDROMOBJ) $(ZIPOBJ) $(MOOBJ) $(HDDOBJ) $(MINIVHDOBJ) \ - $(NETOBJ) $(PRINTOBJ) $(SCSIOBJ) $(SIOOBJ) $(SNDOBJ) $(VIDOBJ) $(VOODOOOBJ) \ - $(PLATOBJ) $(UIOBJ) $(FSYNTHOBJ) $(MUNTOBJ) $(DEVBROBJ) $(MINITRACEOBJ) $(THREADOBJ) -ifdef EXOBJ - OBJ += $(EXOBJ) -endif - -ifeq ($(LOG), y) - MWIN := -lcomdlg32 -else - MWIN := -mwindows -endif - -LIBS := -lfreetype -lfluidsynth -lslirp -lbz2 -lharfbuzz -lgraphite2 -lbrotlidec \ - -lbrotlicommon -lusp10 -lrpcrt4 -lgomp -lsndfile -lflac -lmp3lame -lmpg123 \ - -lopus -lvorbis -lvorbisenc -logg -ldsound -lshlwapi -lksuser -lreadline \ - -ltermcap -lportaudio -lgmodule-2.0 -lglib-2.0 -lintl -liconv - -ifeq ($(OPENAL), y) - LIBS += $(MWIN) -lopenal -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 \ - -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion \ - -luuid -lws2_32 -else - ifeq ($(FAUDIO), y) - LIBS += $(MWIN) -lfaudio -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 \ - -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion \ - -luuid -lws2_32 - else - LIBS += $(MWIN) -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 -luser32 \ - -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid \ - -lws2_32 - endif -endif - -ifeq ($(RTMIDI), y) - ifeq ($(CLANG), y) - LIBS += -lrtmidi.dll -lwinmm - else - LIBS += -lrtmidi -lwinmm - endif -endif - -ifeq ($(VNC), y) - LIBS += $(VNCLIB) -lws2_32 -endif -ifeq ($(CLANG), y) - LIBS += -lpng -lz -lwsock32 -liphlpapi -lpsapi -lhid -lsetupapi -luxtheme -static -lstdc++.dll -else - LIBS += -lpng -lz -lwsock32 -liphlpapi -lpsapi -lhid -lsetupapi -luxtheme -static -lstdc++ -endif -ifneq ($(X64), y) - ifneq ($(ARM64), y) - LIBS += -Wl,--large-address-aware - endif -endif -ifeq ($(ARM64), y) - LIBS += -lgcc -endif -ifeq ($(DINPUT), y) - LIBS += -ldinput8 -endif - -LIBS += -static - -# Build module rules. -ifeq ($(AUTODEP), y) -%.o: %.c - @echo $< - @$(CC) $(CFLAGS) $(DEPS) -c $< - -%.o: %.cc - @echo $< - @$(CPP) $(CXXFLAGS) $(DEPS) -c $< - -%.o: %.cpp - @echo $< - @$(CPP) $(CXXFLAGS) $(DEPS) -c $< -else -%.o: %.c - @echo $< - @$(CC) $(CFLAGS) -c $< - -%.o: %.cc - @echo $< - @$(CPP) $(CXXFLAGS) -c $< - -%.o: %.cpp - @echo $< - @$(CPP) $(CXXFLAGS) -c $< - -%.d: %.c $(wildcard $*.d) - @echo $< - @$(CC) $(CFLAGS) $(DEPS) -E $< >/dev/null - -%.d: %.cc $(wildcard $*.d) - @echo $< - @$(CPP) $(CXXFLAGS) $(DEPS) -E $< >/dev/null - -%.d: %.cpp $(wildcard $*.d) - @echo $< - @$(CPP) $(CXXFLAGS) $(DEPS) -E $< >/dev/null -endif - -# Suppress false positive warnings in vid_voodoo_codegen_x86[-64].h -# that cause ~3000 lines to be output into the logs each time. -ifneq ($(CLANG), y) - $(VOODOOOBJ): CFLAGS += -Wstringop-overflow=0 -endif - -all: $(PROG).exe - - -86Box.res: 86Box.rc - @echo Processing $< - @$(WINDRES) -v $(RFLAGS) $(EXTRAS) -i $< -o 86Box.res - -$(PROG).exe: $(OBJ) 86Box.res - @echo Linking $(PROG).exe .. - @$(CC) $(LDFLAGS) -o $(PROG).exe $(OBJ) 86Box.res $(LIBS) -pipe -ifneq ($(DEBUG), y) - @$(STRIP) $(PROG).exe -endif - -pcap_if.res: pcap_if.rc - @echo Processing $< - @$(WINDRES) $(RFLAGS) -i $< -o pcap_if.res - -pcap_if.exe: pcap_if.o win_dynld.o pcap_if.res - @echo Linking pcap_if.exe .. - @$(CC) $(LDFLAGS) -o pcap_if.exe pcap_if.o win_dynld.o pcap_if.res -ifneq ($(DEBUG), y) - @$(STRIP) pcap_if.exe -endif - -hello.exe: hello.o - $(CXX) $(LDFLAGS) -o hello.exe hello.o $(LIBS) -ifneq ($(DEBUG), y) - @$(STRIP) hello.exe -endif - - -clean: - @echo Cleaning objects.. - @-rm -f *.o 2>/dev/null - @-rm -f *.res 2>/dev/null - -clobber: clean - @echo Cleaning executables.. - @-rm -f *.d 2>/dev/null - @-rm -f *.exe 2>/dev/null -# @-rm -f $(DEPFILE) 2>/dev/null - -ifneq ($(AUTODEP), y) -depclean: - @-rm -f $(DEPFILE) 2>/dev/null - @echo Creating dependencies.. - @echo # Run "make depends" to re-create this file. >$(DEPFILE) - -depends: DEPOBJ=$(OBJ:%.o=%.d) -depends: depclean $(OBJ:%.o=%.d) - @-cat $(DEPOBJ) >>$(DEPFILE) - @-rm -f $(DEPOBJ) - -$(DEPFILE): -endif - - -# Module dependencies. -ifeq ($(AUTODEP), y) -#-include $(OBJ:%.o=%.d) (better, but sloooowwwww) --include *.d -else -include $(wildcard $(DEPFILE)) -endif - - -# End of Makefile.mingw. diff --git a/src/win/glad.c b/src/win/glad.c deleted file mode 100644 index 7c282ebee..000000000 --- a/src/win/glad.c +++ /dev/null @@ -1,1047 +0,0 @@ -/* - - OpenGL loader generated by glad 0.1.36 on Sat Jan 7 18:24:33 2023. - - Language/Generator: C/C++ - Specification: gl - APIs: gl=3.0 - Profile: core - Extensions: - GL_ARB_buffer_storage, - GL_ARB_debug_output, - GL_ARB_sync - Loader: True - Local files: False - Omit khrplatform: False - Reproducible: False - - Commandline: - --profile="core" --api="gl=3.0" --generator="c" --spec="gl" --extensions="GL_ARB_buffer_storage,GL_ARB_debug_output,GL_ARB_sync" - Online: - https://glad.dav1d.de/#profile=core&language=c&specification=gl&loader=on&api=gl%3D3.0&extensions=GL_ARB_buffer_storage&extensions=GL_ARB_debug_output&extensions=GL_ARB_sync -*/ - -#include -#include -#include -#include - -static void *get_proc(const char *namez); - -#if defined(_WIN32) || defined(__CYGWIN__) -# ifndef _WINDOWS_ -# undef APIENTRY -# endif -# include -static HMODULE libGL; - -typedef void *(APIENTRYP PFNWGLGETPROCADDRESSPROC_PRIVATE)(const char *); -static PFNWGLGETPROCADDRESSPROC_PRIVATE gladGetProcAddressPtr; - -# ifdef _MSC_VER -# ifdef __has_include -# if __has_include() -# define HAVE_WINAPIFAMILY 1 -# endif -# elif _MSC_VER >= 1700 && !_USING_V110_SDK71_ -# define HAVE_WINAPIFAMILY 1 -# endif -# endif - -# ifdef HAVE_WINAPIFAMILY -# include -# if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) -# define IS_UWP 1 -# endif -# endif - -static int -open_gl(void) -{ -# ifndef IS_UWP - libGL = LoadLibraryW(L"opengl32.dll"); - if (libGL != NULL) { - void (*tmp)(void); - tmp = (void (*)(void)) GetProcAddress(libGL, "wglGetProcAddress"); - gladGetProcAddressPtr = (PFNWGLGETPROCADDRESSPROC_PRIVATE) tmp; - return gladGetProcAddressPtr != NULL; - } -# endif - - return 0; -} - -static void -close_gl(void) -{ - if (libGL != NULL) { - FreeLibrary((HMODULE) libGL); - libGL = NULL; - } -} -#else -# include -static void *libGL; - -# if !defined(__APPLE__) && !defined(__HAIKU__) -typedef void *(APIENTRYP PFNGLXGETPROCADDRESSPROC_PRIVATE)(const char *); -static PFNGLXGETPROCADDRESSPROC_PRIVATE gladGetProcAddressPtr; -# endif - -static int -open_gl(void) -{ -# ifdef __APPLE__ - static const char *NAMES[] = { - "../Frameworks/OpenGL.framework/OpenGL", - "/Library/Frameworks/OpenGL.framework/OpenGL", - "/System/Library/Frameworks/OpenGL.framework/OpenGL", - "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL" - }; -# else - static const char *NAMES[] = { "libGL.so.1", "libGL.so" }; -# endif - - unsigned int index = 0; - for (index = 0; index < (sizeof(NAMES) / sizeof(NAMES[0])); index++) { - libGL = dlopen(NAMES[index], RTLD_NOW | RTLD_GLOBAL); - - if (libGL != NULL) { -# if defined(__APPLE__) || defined(__HAIKU__) - return 1; -# else - gladGetProcAddressPtr = (PFNGLXGETPROCADDRESSPROC_PRIVATE) dlsym(libGL, - "glXGetProcAddressARB"); - return gladGetProcAddressPtr != NULL; -# endif - } - } - - return 0; -} - -static void -close_gl(void) -{ - if (libGL != NULL) { - dlclose(libGL); - libGL = NULL; - } -} -#endif - -static void * -get_proc(const char *namez) -{ - void *result = NULL; - if (libGL == NULL) - return NULL; - -#if !defined(__APPLE__) && !defined(__HAIKU__) - if (gladGetProcAddressPtr != NULL) { - result = gladGetProcAddressPtr(namez); - } -#endif - if (result == NULL) { -#if defined(_WIN32) || defined(__CYGWIN__) - result = (void *) GetProcAddress((HMODULE) libGL, namez); -#else - result = dlsym(libGL, namez); -#endif - } - - return result; -} - -int -gladLoadGL(void) -{ - int status = 0; - - if (open_gl()) { - status = gladLoadGLLoader(&get_proc); - close_gl(); - } - - return status; -} - -struct gladGLversionStruct GLVersion = { 0, 0 }; - -#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) -# define _GLAD_IS_SOME_NEW_VERSION 1 -#endif - -static int max_loaded_major; -static int max_loaded_minor; - -static const char *exts = NULL; -static int num_exts_i = 0; -static char **exts_i = NULL; - -static int -get_exts(void) -{ -#ifdef _GLAD_IS_SOME_NEW_VERSION - if (max_loaded_major < 3) { -#endif - exts = (const char *) glGetString(GL_EXTENSIONS); -#ifdef _GLAD_IS_SOME_NEW_VERSION - } else { - unsigned int index; - - num_exts_i = 0; - glGetIntegerv(GL_NUM_EXTENSIONS, &num_exts_i); - if (num_exts_i > 0) { - exts_i = (char **) malloc((size_t) num_exts_i * (sizeof *exts_i)); - } - - if (exts_i == NULL) { - return 0; - } - - for (index = 0; index < (unsigned) num_exts_i; index++) { - const char *gl_str_tmp = (const char *) glGetStringi(GL_EXTENSIONS, index); - size_t len = strlen(gl_str_tmp); - - char *local_str = (char *) malloc((len + 1) * sizeof(char)); - if (local_str != NULL) { - memcpy(local_str, gl_str_tmp, (len + 1) * sizeof(char)); - } - exts_i[index] = local_str; - } - } -#endif - return 1; -} - -static void -free_exts(void) -{ - if (exts_i != NULL) { - int index; - for (index = 0; index < num_exts_i; index++) { - free((char *) exts_i[index]); - } - free((void *) exts_i); - exts_i = NULL; - } -} - -static int -has_ext(const char *ext) -{ -#ifdef _GLAD_IS_SOME_NEW_VERSION - if (max_loaded_major < 3) { -#endif - const char *extensions; - const char *loc; - const char *terminator; - extensions = exts; - if (extensions == NULL || ext == NULL) { - return 0; - } - - while (1) { - loc = strstr(extensions, ext); - if (loc == NULL) { - return 0; - } - - terminator = loc + strlen(ext); - if ((loc == extensions || *(loc - 1) == ' ') && (*terminator == ' ' || *terminator == '\0')) { - return 1; - } - extensions = terminator; - } -#ifdef _GLAD_IS_SOME_NEW_VERSION - } else { - int index; - if (exts_i == NULL) - return 0; - for (index = 0; index < num_exts_i; index++) { - const char *e = exts_i[index]; - - if (exts_i[index] != NULL && strcmp(e, ext) == 0) { - return 1; - } - } - } -#endif - - return 0; -} -int GLAD_GL_VERSION_1_0 = 0; -int GLAD_GL_VERSION_1_1 = 0; -int GLAD_GL_VERSION_1_2 = 0; -int GLAD_GL_VERSION_1_3 = 0; -int GLAD_GL_VERSION_1_4 = 0; -int GLAD_GL_VERSION_1_5 = 0; -int GLAD_GL_VERSION_2_0 = 0; -int GLAD_GL_VERSION_2_1 = 0; -int GLAD_GL_VERSION_3_0 = 0; -PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL; -PFNGLATTACHSHADERPROC glad_glAttachShader = NULL; -PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender = NULL; -PFNGLBEGINQUERYPROC glad_glBeginQuery = NULL; -PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback = NULL; -PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL; -PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL; -PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase = NULL; -PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange = NULL; -PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation = NULL; -PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL; -PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL; -PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL; -PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL; -PFNGLBLENDCOLORPROC glad_glBlendColor = NULL; -PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL; -PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL; -PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL; -PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL; -PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer = NULL; -PFNGLBUFFERDATAPROC glad_glBufferData = NULL; -PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL; -PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL; -PFNGLCLAMPCOLORPROC glad_glClampColor = NULL; -PFNGLCLEARPROC glad_glClear = NULL; -PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi = NULL; -PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv = NULL; -PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv = NULL; -PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv = NULL; -PFNGLCLEARCOLORPROC glad_glClearColor = NULL; -PFNGLCLEARDEPTHPROC glad_glClearDepth = NULL; -PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL; -PFNGLCOLORMASKPROC glad_glColorMask = NULL; -PFNGLCOLORMASKIPROC glad_glColorMaski = NULL; -PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL; -PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D = NULL; -PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL; -PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D = NULL; -PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D = NULL; -PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL; -PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D = NULL; -PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL; -PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D = NULL; -PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL; -PFNGLCREATESHADERPROC glad_glCreateShader = NULL; -PFNGLCULLFACEPROC glad_glCullFace = NULL; -PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL; -PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL; -PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL; -PFNGLDELETEQUERIESPROC glad_glDeleteQueries = NULL; -PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL; -PFNGLDELETESHADERPROC glad_glDeleteShader = NULL; -PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL; -PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = NULL; -PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL; -PFNGLDEPTHMASKPROC glad_glDepthMask = NULL; -PFNGLDEPTHRANGEPROC glad_glDepthRange = NULL; -PFNGLDETACHSHADERPROC glad_glDetachShader = NULL; -PFNGLDISABLEPROC glad_glDisable = NULL; -PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL; -PFNGLDISABLEIPROC glad_glDisablei = NULL; -PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL; -PFNGLDRAWBUFFERPROC glad_glDrawBuffer = NULL; -PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL; -PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL; -PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL; -PFNGLENABLEPROC glad_glEnable = NULL; -PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL; -PFNGLENABLEIPROC glad_glEnablei = NULL; -PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender = NULL; -PFNGLENDQUERYPROC glad_glEndQuery = NULL; -PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL; -PFNGLFINISHPROC glad_glFinish = NULL; -PFNGLFLUSHPROC glad_glFlush = NULL; -PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL; -PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL; -PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D = NULL; -PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL; -PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D = NULL; -PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer = NULL; -PFNGLFRONTFACEPROC glad_glFrontFace = NULL; -PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL; -PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL; -PFNGLGENQUERIESPROC glad_glGenQueries = NULL; -PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL; -PFNGLGENTEXTURESPROC glad_glGenTextures = NULL; -PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL; -PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL; -PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL; -PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL; -PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL; -PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL; -PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v = NULL; -PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL; -PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL; -PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv = NULL; -PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData = NULL; -PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage = NULL; -PFNGLGETDOUBLEVPROC glad_glGetDoublev = NULL; -PFNGLGETERRORPROC glad_glGetError = NULL; -PFNGLGETFLOATVPROC glad_glGetFloatv = NULL; -PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation = NULL; -PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL; -PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL; -PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL; -PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL; -PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL; -PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv = NULL; -PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv = NULL; -PFNGLGETQUERYIVPROC glad_glGetQueryiv = NULL; -PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL; -PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL; -PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL; -PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL; -PFNGLGETSTRINGPROC glad_glGetString = NULL; -PFNGLGETSTRINGIPROC glad_glGetStringi = NULL; -PFNGLGETTEXIMAGEPROC glad_glGetTexImage = NULL; -PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv = NULL; -PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv = NULL; -PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv = NULL; -PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv = NULL; -PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL; -PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL; -PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying = NULL; -PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL; -PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL; -PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL; -PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv = NULL; -PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv = NULL; -PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv = NULL; -PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL; -PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv = NULL; -PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL; -PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL; -PFNGLHINTPROC glad_glHint = NULL; -PFNGLISBUFFERPROC glad_glIsBuffer = NULL; -PFNGLISENABLEDPROC glad_glIsEnabled = NULL; -PFNGLISENABLEDIPROC glad_glIsEnabledi = NULL; -PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL; -PFNGLISPROGRAMPROC glad_glIsProgram = NULL; -PFNGLISQUERYPROC glad_glIsQuery = NULL; -PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL; -PFNGLISSHADERPROC glad_glIsShader = NULL; -PFNGLISTEXTUREPROC glad_glIsTexture = NULL; -PFNGLISVERTEXARRAYPROC glad_glIsVertexArray = NULL; -PFNGLLINEWIDTHPROC glad_glLineWidth = NULL; -PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL; -PFNGLLOGICOPPROC glad_glLogicOp = NULL; -PFNGLMAPBUFFERPROC glad_glMapBuffer = NULL; -PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange = NULL; -PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays = NULL; -PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements = NULL; -PFNGLPIXELSTOREFPROC glad_glPixelStoref = NULL; -PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL; -PFNGLPOINTPARAMETERFPROC glad_glPointParameterf = NULL; -PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv = NULL; -PFNGLPOINTPARAMETERIPROC glad_glPointParameteri = NULL; -PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv = NULL; -PFNGLPOINTSIZEPROC glad_glPointSize = NULL; -PFNGLPOLYGONMODEPROC glad_glPolygonMode = NULL; -PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL; -PFNGLREADBUFFERPROC glad_glReadBuffer = NULL; -PFNGLREADPIXELSPROC glad_glReadPixels = NULL; -PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL; -PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL; -PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL; -PFNGLSCISSORPROC glad_glScissor = NULL; -PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL; -PFNGLSTENCILFUNCPROC glad_glStencilFunc = NULL; -PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate = NULL; -PFNGLSTENCILMASKPROC glad_glStencilMask = NULL; -PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate = NULL; -PFNGLSTENCILOPPROC glad_glStencilOp = NULL; -PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL; -PFNGLTEXIMAGE1DPROC glad_glTexImage1D = NULL; -PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL; -PFNGLTEXIMAGE3DPROC glad_glTexImage3D = NULL; -PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv = NULL; -PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv = NULL; -PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL; -PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL; -PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL; -PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL; -PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D = NULL; -PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL; -PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D = NULL; -PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings = NULL; -PFNGLUNIFORM1FPROC glad_glUniform1f = NULL; -PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL; -PFNGLUNIFORM1IPROC glad_glUniform1i = NULL; -PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL; -PFNGLUNIFORM1UIPROC glad_glUniform1ui = NULL; -PFNGLUNIFORM1UIVPROC glad_glUniform1uiv = NULL; -PFNGLUNIFORM2FPROC glad_glUniform2f = NULL; -PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL; -PFNGLUNIFORM2IPROC glad_glUniform2i = NULL; -PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL; -PFNGLUNIFORM2UIPROC glad_glUniform2ui = NULL; -PFNGLUNIFORM2UIVPROC glad_glUniform2uiv = NULL; -PFNGLUNIFORM3FPROC glad_glUniform3f = NULL; -PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL; -PFNGLUNIFORM3IPROC glad_glUniform3i = NULL; -PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL; -PFNGLUNIFORM3UIPROC glad_glUniform3ui = NULL; -PFNGLUNIFORM3UIVPROC glad_glUniform3uiv = NULL; -PFNGLUNIFORM4FPROC glad_glUniform4f = NULL; -PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL; -PFNGLUNIFORM4IPROC glad_glUniform4i = NULL; -PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL; -PFNGLUNIFORM4UIPROC glad_glUniform4ui = NULL; -PFNGLUNIFORM4UIVPROC glad_glUniform4uiv = NULL; -PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL; -PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv = NULL; -PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv = NULL; -PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL; -PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv = NULL; -PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv = NULL; -PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL; -PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv = NULL; -PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv = NULL; -PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer = NULL; -PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL; -PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL; -PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d = NULL; -PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv = NULL; -PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f = NULL; -PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv = NULL; -PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s = NULL; -PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv = NULL; -PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d = NULL; -PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv = NULL; -PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f = NULL; -PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv = NULL; -PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s = NULL; -PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv = NULL; -PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d = NULL; -PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv = NULL; -PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f = NULL; -PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv = NULL; -PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s = NULL; -PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv = NULL; -PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv = NULL; -PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv = NULL; -PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv = NULL; -PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub = NULL; -PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv = NULL; -PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv = NULL; -PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv = NULL; -PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv = NULL; -PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d = NULL; -PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv = NULL; -PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f = NULL; -PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv = NULL; -PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv = NULL; -PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s = NULL; -PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv = NULL; -PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv = NULL; -PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv = NULL; -PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv = NULL; -PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i = NULL; -PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv = NULL; -PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui = NULL; -PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv = NULL; -PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i = NULL; -PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv = NULL; -PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui = NULL; -PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv = NULL; -PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i = NULL; -PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv = NULL; -PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui = NULL; -PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv = NULL; -PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv = NULL; -PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i = NULL; -PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv = NULL; -PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv = NULL; -PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv = NULL; -PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui = NULL; -PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv = NULL; -PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv = NULL; -PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer = NULL; -PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL; -PFNGLVIEWPORTPROC glad_glViewport = NULL; -int GLAD_GL_ARB_buffer_storage = 0; -int GLAD_GL_ARB_debug_output = 0; -int GLAD_GL_ARB_sync = 0; -PFNGLBUFFERSTORAGEPROC glad_glBufferStorage = NULL; -PFNGLDEBUGMESSAGECONTROLARBPROC glad_glDebugMessageControlARB = NULL; -PFNGLDEBUGMESSAGEINSERTARBPROC glad_glDebugMessageInsertARB = NULL; -PFNGLDEBUGMESSAGECALLBACKARBPROC glad_glDebugMessageCallbackARB = NULL; -PFNGLGETDEBUGMESSAGELOGARBPROC glad_glGetDebugMessageLogARB = NULL; -PFNGLFENCESYNCPROC glad_glFenceSync = NULL; -PFNGLISSYNCPROC glad_glIsSync = NULL; -PFNGLDELETESYNCPROC glad_glDeleteSync = NULL; -PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL; -PFNGLWAITSYNCPROC glad_glWaitSync = NULL; -PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL; -PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL; -static void -load_GL_VERSION_1_0(GLADloadproc load) -{ - if (!GLAD_GL_VERSION_1_0) - return; - glad_glCullFace = (PFNGLCULLFACEPROC) load("glCullFace"); - glad_glFrontFace = (PFNGLFRONTFACEPROC) load("glFrontFace"); - glad_glHint = (PFNGLHINTPROC) load("glHint"); - glad_glLineWidth = (PFNGLLINEWIDTHPROC) load("glLineWidth"); - glad_glPointSize = (PFNGLPOINTSIZEPROC) load("glPointSize"); - glad_glPolygonMode = (PFNGLPOLYGONMODEPROC) load("glPolygonMode"); - glad_glScissor = (PFNGLSCISSORPROC) load("glScissor"); - glad_glTexParameterf = (PFNGLTEXPARAMETERFPROC) load("glTexParameterf"); - glad_glTexParameterfv = (PFNGLTEXPARAMETERFVPROC) load("glTexParameterfv"); - glad_glTexParameteri = (PFNGLTEXPARAMETERIPROC) load("glTexParameteri"); - glad_glTexParameteriv = (PFNGLTEXPARAMETERIVPROC) load("glTexParameteriv"); - glad_glTexImage1D = (PFNGLTEXIMAGE1DPROC) load("glTexImage1D"); - glad_glTexImage2D = (PFNGLTEXIMAGE2DPROC) load("glTexImage2D"); - glad_glDrawBuffer = (PFNGLDRAWBUFFERPROC) load("glDrawBuffer"); - glad_glClear = (PFNGLCLEARPROC) load("glClear"); - glad_glClearColor = (PFNGLCLEARCOLORPROC) load("glClearColor"); - glad_glClearStencil = (PFNGLCLEARSTENCILPROC) load("glClearStencil"); - glad_glClearDepth = (PFNGLCLEARDEPTHPROC) load("glClearDepth"); - glad_glStencilMask = (PFNGLSTENCILMASKPROC) load("glStencilMask"); - glad_glColorMask = (PFNGLCOLORMASKPROC) load("glColorMask"); - glad_glDepthMask = (PFNGLDEPTHMASKPROC) load("glDepthMask"); - glad_glDisable = (PFNGLDISABLEPROC) load("glDisable"); - glad_glEnable = (PFNGLENABLEPROC) load("glEnable"); - glad_glFinish = (PFNGLFINISHPROC) load("glFinish"); - glad_glFlush = (PFNGLFLUSHPROC) load("glFlush"); - glad_glBlendFunc = (PFNGLBLENDFUNCPROC) load("glBlendFunc"); - glad_glLogicOp = (PFNGLLOGICOPPROC) load("glLogicOp"); - glad_glStencilFunc = (PFNGLSTENCILFUNCPROC) load("glStencilFunc"); - glad_glStencilOp = (PFNGLSTENCILOPPROC) load("glStencilOp"); - glad_glDepthFunc = (PFNGLDEPTHFUNCPROC) load("glDepthFunc"); - glad_glPixelStoref = (PFNGLPIXELSTOREFPROC) load("glPixelStoref"); - glad_glPixelStorei = (PFNGLPIXELSTOREIPROC) load("glPixelStorei"); - glad_glReadBuffer = (PFNGLREADBUFFERPROC) load("glReadBuffer"); - glad_glReadPixels = (PFNGLREADPIXELSPROC) load("glReadPixels"); - glad_glGetBooleanv = (PFNGLGETBOOLEANVPROC) load("glGetBooleanv"); - glad_glGetDoublev = (PFNGLGETDOUBLEVPROC) load("glGetDoublev"); - glad_glGetError = (PFNGLGETERRORPROC) load("glGetError"); - glad_glGetFloatv = (PFNGLGETFLOATVPROC) load("glGetFloatv"); - glad_glGetIntegerv = (PFNGLGETINTEGERVPROC) load("glGetIntegerv"); - glad_glGetString = (PFNGLGETSTRINGPROC) load("glGetString"); - glad_glGetTexImage = (PFNGLGETTEXIMAGEPROC) load("glGetTexImage"); - glad_glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) load("glGetTexParameterfv"); - glad_glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) load("glGetTexParameteriv"); - glad_glGetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC) load("glGetTexLevelParameterfv"); - glad_glGetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC) load("glGetTexLevelParameteriv"); - glad_glIsEnabled = (PFNGLISENABLEDPROC) load("glIsEnabled"); - glad_glDepthRange = (PFNGLDEPTHRANGEPROC) load("glDepthRange"); - glad_glViewport = (PFNGLVIEWPORTPROC) load("glViewport"); -} -static void -load_GL_VERSION_1_1(GLADloadproc load) -{ - if (!GLAD_GL_VERSION_1_1) - return; - glad_glDrawArrays = (PFNGLDRAWARRAYSPROC) load("glDrawArrays"); - glad_glDrawElements = (PFNGLDRAWELEMENTSPROC) load("glDrawElements"); - glad_glPolygonOffset = (PFNGLPOLYGONOFFSETPROC) load("glPolygonOffset"); - glad_glCopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC) load("glCopyTexImage1D"); - glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) load("glCopyTexImage2D"); - glad_glCopyTexSubImage1D = (PFNGLCOPYTEXSUBIMAGE1DPROC) load("glCopyTexSubImage1D"); - glad_glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) load("glCopyTexSubImage2D"); - glad_glTexSubImage1D = (PFNGLTEXSUBIMAGE1DPROC) load("glTexSubImage1D"); - glad_glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) load("glTexSubImage2D"); - glad_glBindTexture = (PFNGLBINDTEXTUREPROC) load("glBindTexture"); - glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC) load("glDeleteTextures"); - glad_glGenTextures = (PFNGLGENTEXTURESPROC) load("glGenTextures"); - glad_glIsTexture = (PFNGLISTEXTUREPROC) load("glIsTexture"); -} -static void -load_GL_VERSION_1_2(GLADloadproc load) -{ - if (!GLAD_GL_VERSION_1_2) - return; - glad_glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC) load("glDrawRangeElements"); - glad_glTexImage3D = (PFNGLTEXIMAGE3DPROC) load("glTexImage3D"); - glad_glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) load("glTexSubImage3D"); - glad_glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) load("glCopyTexSubImage3D"); -} -static void -load_GL_VERSION_1_3(GLADloadproc load) -{ - if (!GLAD_GL_VERSION_1_3) - return; - glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC) load("glActiveTexture"); - glad_glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC) load("glSampleCoverage"); - glad_glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC) load("glCompressedTexImage3D"); - glad_glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) load("glCompressedTexImage2D"); - glad_glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC) load("glCompressedTexImage1D"); - glad_glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) load("glCompressedTexSubImage3D"); - glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) load("glCompressedTexSubImage2D"); - glad_glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) load("glCompressedTexSubImage1D"); - glad_glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC) load("glGetCompressedTexImage"); -} -static void -load_GL_VERSION_1_4(GLADloadproc load) -{ - if (!GLAD_GL_VERSION_1_4) - return; - glad_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) load("glBlendFuncSeparate"); - glad_glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC) load("glMultiDrawArrays"); - glad_glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC) load("glMultiDrawElements"); - glad_glPointParameterf = (PFNGLPOINTPARAMETERFPROC) load("glPointParameterf"); - glad_glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC) load("glPointParameterfv"); - glad_glPointParameteri = (PFNGLPOINTPARAMETERIPROC) load("glPointParameteri"); - glad_glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC) load("glPointParameteriv"); - glad_glBlendColor = (PFNGLBLENDCOLORPROC) load("glBlendColor"); - glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC) load("glBlendEquation"); -} -static void -load_GL_VERSION_1_5(GLADloadproc load) -{ - if (!GLAD_GL_VERSION_1_5) - return; - glad_glGenQueries = (PFNGLGENQUERIESPROC) load("glGenQueries"); - glad_glDeleteQueries = (PFNGLDELETEQUERIESPROC) load("glDeleteQueries"); - glad_glIsQuery = (PFNGLISQUERYPROC) load("glIsQuery"); - glad_glBeginQuery = (PFNGLBEGINQUERYPROC) load("glBeginQuery"); - glad_glEndQuery = (PFNGLENDQUERYPROC) load("glEndQuery"); - glad_glGetQueryiv = (PFNGLGETQUERYIVPROC) load("glGetQueryiv"); - glad_glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC) load("glGetQueryObjectiv"); - glad_glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC) load("glGetQueryObjectuiv"); - glad_glBindBuffer = (PFNGLBINDBUFFERPROC) load("glBindBuffer"); - glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) load("glDeleteBuffers"); - glad_glGenBuffers = (PFNGLGENBUFFERSPROC) load("glGenBuffers"); - glad_glIsBuffer = (PFNGLISBUFFERPROC) load("glIsBuffer"); - glad_glBufferData = (PFNGLBUFFERDATAPROC) load("glBufferData"); - glad_glBufferSubData = (PFNGLBUFFERSUBDATAPROC) load("glBufferSubData"); - glad_glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC) load("glGetBufferSubData"); - glad_glMapBuffer = (PFNGLMAPBUFFERPROC) load("glMapBuffer"); - glad_glUnmapBuffer = (PFNGLUNMAPBUFFERPROC) load("glUnmapBuffer"); - glad_glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) load("glGetBufferParameteriv"); - glad_glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC) load("glGetBufferPointerv"); -} -static void -load_GL_VERSION_2_0(GLADloadproc load) -{ - if (!GLAD_GL_VERSION_2_0) - return; - glad_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) load("glBlendEquationSeparate"); - glad_glDrawBuffers = (PFNGLDRAWBUFFERSPROC) load("glDrawBuffers"); - glad_glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) load("glStencilOpSeparate"); - glad_glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) load("glStencilFuncSeparate"); - glad_glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) load("glStencilMaskSeparate"); - glad_glAttachShader = (PFNGLATTACHSHADERPROC) load("glAttachShader"); - glad_glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) load("glBindAttribLocation"); - glad_glCompileShader = (PFNGLCOMPILESHADERPROC) load("glCompileShader"); - glad_glCreateProgram = (PFNGLCREATEPROGRAMPROC) load("glCreateProgram"); - glad_glCreateShader = (PFNGLCREATESHADERPROC) load("glCreateShader"); - glad_glDeleteProgram = (PFNGLDELETEPROGRAMPROC) load("glDeleteProgram"); - glad_glDeleteShader = (PFNGLDELETESHADERPROC) load("glDeleteShader"); - glad_glDetachShader = (PFNGLDETACHSHADERPROC) load("glDetachShader"); - glad_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) load("glDisableVertexAttribArray"); - glad_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) load("glEnableVertexAttribArray"); - glad_glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC) load("glGetActiveAttrib"); - glad_glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) load("glGetActiveUniform"); - glad_glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) load("glGetAttachedShaders"); - glad_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) load("glGetAttribLocation"); - glad_glGetProgramiv = (PFNGLGETPROGRAMIVPROC) load("glGetProgramiv"); - glad_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) load("glGetProgramInfoLog"); - glad_glGetShaderiv = (PFNGLGETSHADERIVPROC) load("glGetShaderiv"); - glad_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) load("glGetShaderInfoLog"); - glad_glGetShaderSource = (PFNGLGETSHADERSOURCEPROC) load("glGetShaderSource"); - glad_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) load("glGetUniformLocation"); - glad_glGetUniformfv = (PFNGLGETUNIFORMFVPROC) load("glGetUniformfv"); - glad_glGetUniformiv = (PFNGLGETUNIFORMIVPROC) load("glGetUniformiv"); - glad_glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC) load("glGetVertexAttribdv"); - glad_glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC) load("glGetVertexAttribfv"); - glad_glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC) load("glGetVertexAttribiv"); - glad_glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC) load("glGetVertexAttribPointerv"); - glad_glIsProgram = (PFNGLISPROGRAMPROC) load("glIsProgram"); - glad_glIsShader = (PFNGLISSHADERPROC) load("glIsShader"); - glad_glLinkProgram = (PFNGLLINKPROGRAMPROC) load("glLinkProgram"); - glad_glShaderSource = (PFNGLSHADERSOURCEPROC) load("glShaderSource"); - glad_glUseProgram = (PFNGLUSEPROGRAMPROC) load("glUseProgram"); - glad_glUniform1f = (PFNGLUNIFORM1FPROC) load("glUniform1f"); - glad_glUniform2f = (PFNGLUNIFORM2FPROC) load("glUniform2f"); - glad_glUniform3f = (PFNGLUNIFORM3FPROC) load("glUniform3f"); - glad_glUniform4f = (PFNGLUNIFORM4FPROC) load("glUniform4f"); - glad_glUniform1i = (PFNGLUNIFORM1IPROC) load("glUniform1i"); - glad_glUniform2i = (PFNGLUNIFORM2IPROC) load("glUniform2i"); - glad_glUniform3i = (PFNGLUNIFORM3IPROC) load("glUniform3i"); - glad_glUniform4i = (PFNGLUNIFORM4IPROC) load("glUniform4i"); - glad_glUniform1fv = (PFNGLUNIFORM1FVPROC) load("glUniform1fv"); - glad_glUniform2fv = (PFNGLUNIFORM2FVPROC) load("glUniform2fv"); - glad_glUniform3fv = (PFNGLUNIFORM3FVPROC) load("glUniform3fv"); - glad_glUniform4fv = (PFNGLUNIFORM4FVPROC) load("glUniform4fv"); - glad_glUniform1iv = (PFNGLUNIFORM1IVPROC) load("glUniform1iv"); - glad_glUniform2iv = (PFNGLUNIFORM2IVPROC) load("glUniform2iv"); - glad_glUniform3iv = (PFNGLUNIFORM3IVPROC) load("glUniform3iv"); - glad_glUniform4iv = (PFNGLUNIFORM4IVPROC) load("glUniform4iv"); - glad_glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) load("glUniformMatrix2fv"); - glad_glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) load("glUniformMatrix3fv"); - glad_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) load("glUniformMatrix4fv"); - glad_glValidateProgram = (PFNGLVALIDATEPROGRAMPROC) load("glValidateProgram"); - glad_glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC) load("glVertexAttrib1d"); - glad_glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC) load("glVertexAttrib1dv"); - glad_glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC) load("glVertexAttrib1f"); - glad_glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC) load("glVertexAttrib1fv"); - glad_glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC) load("glVertexAttrib1s"); - glad_glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC) load("glVertexAttrib1sv"); - glad_glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC) load("glVertexAttrib2d"); - glad_glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC) load("glVertexAttrib2dv"); - glad_glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC) load("glVertexAttrib2f"); - glad_glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC) load("glVertexAttrib2fv"); - glad_glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC) load("glVertexAttrib2s"); - glad_glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC) load("glVertexAttrib2sv"); - glad_glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC) load("glVertexAttrib3d"); - glad_glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC) load("glVertexAttrib3dv"); - glad_glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) load("glVertexAttrib3f"); - glad_glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC) load("glVertexAttrib3fv"); - glad_glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC) load("glVertexAttrib3s"); - glad_glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC) load("glVertexAttrib3sv"); - glad_glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC) load("glVertexAttrib4Nbv"); - glad_glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC) load("glVertexAttrib4Niv"); - glad_glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC) load("glVertexAttrib4Nsv"); - glad_glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC) load("glVertexAttrib4Nub"); - glad_glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC) load("glVertexAttrib4Nubv"); - glad_glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC) load("glVertexAttrib4Nuiv"); - glad_glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC) load("glVertexAttrib4Nusv"); - glad_glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC) load("glVertexAttrib4bv"); - glad_glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC) load("glVertexAttrib4d"); - glad_glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC) load("glVertexAttrib4dv"); - glad_glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC) load("glVertexAttrib4f"); - glad_glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC) load("glVertexAttrib4fv"); - glad_glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC) load("glVertexAttrib4iv"); - glad_glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC) load("glVertexAttrib4s"); - glad_glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC) load("glVertexAttrib4sv"); - glad_glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC) load("glVertexAttrib4ubv"); - glad_glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC) load("glVertexAttrib4uiv"); - glad_glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC) load("glVertexAttrib4usv"); - glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) load("glVertexAttribPointer"); -} -static void -load_GL_VERSION_2_1(GLADloadproc load) -{ - if (!GLAD_GL_VERSION_2_1) - return; - glad_glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC) load("glUniformMatrix2x3fv"); - glad_glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC) load("glUniformMatrix3x2fv"); - glad_glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC) load("glUniformMatrix2x4fv"); - glad_glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC) load("glUniformMatrix4x2fv"); - glad_glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) load("glUniformMatrix3x4fv"); - glad_glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC) load("glUniformMatrix4x3fv"); -} -static void -load_GL_VERSION_3_0(GLADloadproc load) -{ - if (!GLAD_GL_VERSION_3_0) - return; - glad_glColorMaski = (PFNGLCOLORMASKIPROC) load("glColorMaski"); - glad_glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC) load("glGetBooleani_v"); - glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load("glGetIntegeri_v"); - glad_glEnablei = (PFNGLENABLEIPROC) load("glEnablei"); - glad_glDisablei = (PFNGLDISABLEIPROC) load("glDisablei"); - glad_glIsEnabledi = (PFNGLISENABLEDIPROC) load("glIsEnabledi"); - glad_glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) load("glBeginTransformFeedback"); - glad_glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) load("glEndTransformFeedback"); - glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load("glBindBufferRange"); - glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) load("glBindBufferBase"); - glad_glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) load("glTransformFeedbackVaryings"); - glad_glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) load("glGetTransformFeedbackVarying"); - glad_glClampColor = (PFNGLCLAMPCOLORPROC) load("glClampColor"); - glad_glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC) load("glBeginConditionalRender"); - glad_glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC) load("glEndConditionalRender"); - glad_glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) load("glVertexAttribIPointer"); - glad_glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC) load("glGetVertexAttribIiv"); - glad_glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC) load("glGetVertexAttribIuiv"); - glad_glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC) load("glVertexAttribI1i"); - glad_glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC) load("glVertexAttribI2i"); - glad_glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC) load("glVertexAttribI3i"); - glad_glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC) load("glVertexAttribI4i"); - glad_glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC) load("glVertexAttribI1ui"); - glad_glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC) load("glVertexAttribI2ui"); - glad_glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC) load("glVertexAttribI3ui"); - glad_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC) load("glVertexAttribI4ui"); - glad_glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC) load("glVertexAttribI1iv"); - glad_glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC) load("glVertexAttribI2iv"); - glad_glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC) load("glVertexAttribI3iv"); - glad_glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC) load("glVertexAttribI4iv"); - glad_glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC) load("glVertexAttribI1uiv"); - glad_glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC) load("glVertexAttribI2uiv"); - glad_glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC) load("glVertexAttribI3uiv"); - glad_glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC) load("glVertexAttribI4uiv"); - glad_glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC) load("glVertexAttribI4bv"); - glad_glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC) load("glVertexAttribI4sv"); - glad_glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC) load("glVertexAttribI4ubv"); - glad_glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC) load("glVertexAttribI4usv"); - glad_glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC) load("glGetUniformuiv"); - glad_glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC) load("glBindFragDataLocation"); - glad_glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC) load("glGetFragDataLocation"); - glad_glUniform1ui = (PFNGLUNIFORM1UIPROC) load("glUniform1ui"); - glad_glUniform2ui = (PFNGLUNIFORM2UIPROC) load("glUniform2ui"); - glad_glUniform3ui = (PFNGLUNIFORM3UIPROC) load("glUniform3ui"); - glad_glUniform4ui = (PFNGLUNIFORM4UIPROC) load("glUniform4ui"); - glad_glUniform1uiv = (PFNGLUNIFORM1UIVPROC) load("glUniform1uiv"); - glad_glUniform2uiv = (PFNGLUNIFORM2UIVPROC) load("glUniform2uiv"); - glad_glUniform3uiv = (PFNGLUNIFORM3UIVPROC) load("glUniform3uiv"); - glad_glUniform4uiv = (PFNGLUNIFORM4UIVPROC) load("glUniform4uiv"); - glad_glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC) load("glTexParameterIiv"); - glad_glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC) load("glTexParameterIuiv"); - glad_glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC) load("glGetTexParameterIiv"); - glad_glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC) load("glGetTexParameterIuiv"); - glad_glClearBufferiv = (PFNGLCLEARBUFFERIVPROC) load("glClearBufferiv"); - glad_glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC) load("glClearBufferuiv"); - glad_glClearBufferfv = (PFNGLCLEARBUFFERFVPROC) load("glClearBufferfv"); - glad_glClearBufferfi = (PFNGLCLEARBUFFERFIPROC) load("glClearBufferfi"); - glad_glGetStringi = (PFNGLGETSTRINGIPROC) load("glGetStringi"); - glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) load("glIsRenderbuffer"); - glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) load("glBindRenderbuffer"); - glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) load("glDeleteRenderbuffers"); - glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) load("glGenRenderbuffers"); - glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) load("glRenderbufferStorage"); - glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) load("glGetRenderbufferParameteriv"); - glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) load("glIsFramebuffer"); - glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) load("glBindFramebuffer"); - glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) load("glDeleteFramebuffers"); - glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) load("glGenFramebuffers"); - glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) load("glCheckFramebufferStatus"); - glad_glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC) load("glFramebufferTexture1D"); - glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) load("glFramebufferTexture2D"); - glad_glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC) load("glFramebufferTexture3D"); - glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) load("glFramebufferRenderbuffer"); - glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load("glGetFramebufferAttachmentParameteriv"); - glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) load("glGenerateMipmap"); - glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) load("glBlitFramebuffer"); - glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) load("glRenderbufferStorageMultisample"); - glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) load("glFramebufferTextureLayer"); - glad_glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) load("glMapBufferRange"); - glad_glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) load("glFlushMappedBufferRange"); - glad_glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) load("glBindVertexArray"); - glad_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) load("glDeleteVertexArrays"); - glad_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) load("glGenVertexArrays"); - glad_glIsVertexArray = (PFNGLISVERTEXARRAYPROC) load("glIsVertexArray"); -} -static void -load_GL_ARB_buffer_storage(GLADloadproc load) -{ - if (!GLAD_GL_ARB_buffer_storage) - return; - glad_glBufferStorage = (PFNGLBUFFERSTORAGEPROC) load("glBufferStorage"); -} -static void -load_GL_ARB_debug_output(GLADloadproc load) -{ - if (!GLAD_GL_ARB_debug_output) - return; - glad_glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC) load("glDebugMessageControlARB"); - glad_glDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC) load("glDebugMessageInsertARB"); - glad_glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC) load("glDebugMessageCallbackARB"); - glad_glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC) load("glGetDebugMessageLogARB"); -} -static void -load_GL_ARB_sync(GLADloadproc load) -{ - if (!GLAD_GL_ARB_sync) - return; - glad_glFenceSync = (PFNGLFENCESYNCPROC) load("glFenceSync"); - glad_glIsSync = (PFNGLISSYNCPROC) load("glIsSync"); - glad_glDeleteSync = (PFNGLDELETESYNCPROC) load("glDeleteSync"); - glad_glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) load("glClientWaitSync"); - glad_glWaitSync = (PFNGLWAITSYNCPROC) load("glWaitSync"); - glad_glGetInteger64v = (PFNGLGETINTEGER64VPROC) load("glGetInteger64v"); - glad_glGetSynciv = (PFNGLGETSYNCIVPROC) load("glGetSynciv"); -} -static int -find_extensionsGL(void) -{ - if (!get_exts()) - return 0; - GLAD_GL_ARB_buffer_storage = has_ext("GL_ARB_buffer_storage"); - GLAD_GL_ARB_debug_output = has_ext("GL_ARB_debug_output"); - GLAD_GL_ARB_sync = has_ext("GL_ARB_sync"); - free_exts(); - return 1; -} - -static void -find_coreGL(void) -{ - - /* Thank you @elmindreda - * https://github.com/elmindreda/greg/blob/master/templates/greg.c.in#L176 - * https://github.com/glfw/glfw/blob/master/src/context.c#L36 - */ - int i, major, minor; - - const char *version; - const char *prefixes[] = { - "OpenGL ES-CM ", - "OpenGL ES-CL ", - "OpenGL ES ", - NULL - }; - - version = (const char *) glGetString(GL_VERSION); - if (!version) - return; - - for (i = 0; prefixes[i]; i++) { - const size_t length = strlen(prefixes[i]); - if (strncmp(version, prefixes[i], length) == 0) { - version += length; - break; - } - } - -/* PR #18 */ -#ifdef _MSC_VER - sscanf_s(version, "%d.%d", &major, &minor); -#else - sscanf(version, "%d.%d", &major, &minor); -#endif - - GLVersion.major = major; - GLVersion.minor = minor; - max_loaded_major = major; - max_loaded_minor = minor; - GLAD_GL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; - GLAD_GL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; - GLAD_GL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; - GLAD_GL_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; - GLAD_GL_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; - GLAD_GL_VERSION_1_5 = (major == 1 && minor >= 5) || major > 1; - GLAD_GL_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; - GLAD_GL_VERSION_2_1 = (major == 2 && minor >= 1) || major > 2; - GLAD_GL_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; - if (GLVersion.major > 3 || (GLVersion.major >= 3 && GLVersion.minor >= 0)) { - max_loaded_major = 3; - max_loaded_minor = 0; - } -} - -int -gladLoadGLLoader(GLADloadproc load) -{ - GLVersion.major = 0; - GLVersion.minor = 0; - glGetString = (PFNGLGETSTRINGPROC) load("glGetString"); - if (glGetString == NULL) - return 0; - if (glGetString(GL_VERSION) == NULL) - return 0; - find_coreGL(); - load_GL_VERSION_1_0(load); - load_GL_VERSION_1_1(load); - load_GL_VERSION_1_2(load); - load_GL_VERSION_1_3(load); - load_GL_VERSION_1_4(load); - load_GL_VERSION_1_5(load); - load_GL_VERSION_2_0(load); - load_GL_VERSION_2_1(load); - load_GL_VERSION_3_0(load); - - if (!find_extensionsGL()) - return 0; - load_GL_ARB_buffer_storage(load); - load_GL_ARB_debug_output(load); - load_GL_ARB_sync(load); - return GLVersion.major != 0 || GLVersion.minor != 0; -} diff --git a/src/win/languages/cs-CZ.rc b/src/win/languages/cs-CZ.rc deleted file mode 100644 index cbda41e7e..000000000 --- a/src/win/languages/cs-CZ.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Czech (Czech Republic) resources - -#ifdef _WIN32 -LANGUAGE LANG_CZECH, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Akce" - BEGIN - MENUITEM "&Klávesnice vyžaduje záběr", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Pravý Ctrl je levý Alt", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Resetovat", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "P&ozastavit", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "&Ukončit", IDM_ACTION_EXIT - END - POPUP "&Zobrazení" - BEGIN - MENUITEM "&Schovat stavový řádek", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Schovat panel &nástrojů", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Měnitelná velikost okna", IDM_VID_RESIZE - MENUITEM "&Pamatovat velikost a pozici", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "&Renderer" - BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "&Zadat velikost...", IDM_VID_SPECIFY_DIM - MENUITEM "&Dodržovat poměr stran 4:3", IDM_VID_FORCE43 - POPUP "&Násobek zvětšení okna" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Metoda &filtrování" - BEGIN - MENUITEM "&Nejbližší", IDM_VID_FILTER_NEAREST - MENUITEM "&Lineární", IDM_VID_FILTER_LINEAR - END - MENUITEM "Š&kálování HiDPI", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Celá obrazovka\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Režím roztá&hnutí při celé obrazovce" - BEGIN - MENUITEM "&Roztáhnout", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Zachovat poměr stran", IDM_VID_FS_KEEPRATIO - MENUITEM "&Celočíselné škálování", IDM_VID_FS_INT - END - POPUP "Nastavení pro E&GA a (S)VGA" - BEGIN - MENUITEM "&Převrátit barvy", IDM_VID_INVERT - POPUP "&Typ VGA monitoru" - BEGIN - MENUITEM "RGB &barevný", IDM_VID_GRAY_RGB - MENUITEM "&Odstíny šedi", IDM_VID_GRAY_MONO - MENUITEM "&Jantarová obrazovka", IDM_VID_GRAY_AMBER - MENUITEM "&Zelená obrazovka", IDM_VID_GRAY_GREEN - MENUITEM "&Bílá obrazovka", IDM_VID_GRAY_WHITE - END - POPUP "Převod na &odstíny šedi" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Průměr", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "Přesah obrazu CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN - MENUITEM "&Upravit kontrast černobílé obrazovky", IDM_VID_CGACON - END - MENUITEM "&Média", IDM_MEDIA - POPUP "&Nástroje" - BEGIN - MENUITEM "&Nastavení...", IDM_CONFIG - MENUITEM "&Aktualizovat ikony stavového řádku", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Pořídit &screenshot\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Předvolby...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Povolit integraci s &Discordem", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Zesílení zvuku", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Začít trace\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Zastavit trace\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "Ná&pověda" - BEGIN - MENUITEM "&Dokumentace", IDM_DOCS - MENUITEM "&O programu 86Box", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nový obraz...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existující obraz...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Existující obraz (&ochrana proti zápisu)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Nahrávat", IDM_CASSETTE_RECORD - MENUITEM "&Přehrát", IDM_CASSETTE_PLAY - MENUITEM "Přetočit na &začátek", IDM_CASSETTE_REWIND - MENUITEM "Přetočit na &konec", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "&Vyjmout", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Obraz...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "&Vyjmout", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nový obraz...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existující obraz...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Existující obraz (&ochrana proti zápisu)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&xportovat do 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "&Vyjmout", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Ztišit", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "&Vyjmout", IDM_CDROM_EMPTY - MENUITEM "&Načíst znova předchozí obraz", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Obraz...", IDM_CDROM_IMAGE - MENUITEM "&Složka...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nový obraz...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existující obraz...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Existující obraz (&ochrana proti zápisu)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Vyjmout", IDM_ZIP_EJECT - MENUITEM "&Načíst znova předchozí obraz", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nový obraz...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existující obraz...", IDM_MO_IMAGE_EXISTING - MENUITEM "Existující obraz (&ochrana proti zápisu)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Vyjmout", IDM_MO_EJECT - MENUITEM "&Načíst znova předchozí obraz", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "&Cílová snímková frekvence" - BEGIN - MENUITEM "&Synchronizovat s obrazem", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 fps", IDM_VID_GL_FPS_25 - MENUITEM "&30 fps", IDM_VID_GL_FPS_30 - MENUITEM "&50 fps", IDM_VID_GL_FPS_50 - MENUITEM "&60 fps", IDM_VID_GL_FPS_60 - MENUITEM "&75 fps", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Zvolit shader...", IDM_VID_GL_SHADER - MENUITEM "&Odebrat shader", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Předvolby" -#define STR_SND_GAIN "Zesílení zvuku" -#define STR_NEW_FLOPPY "Nový obraz" -#define STR_CONFIG "Nastavení" -#define STR_SPECIFY_DIM "Zadat rozměry hlavního okna" - -#define STR_OK "OK" -#define STR_CANCEL "Storno" -#define STR_GLOBAL "Uložit toto nastavení jako &globální výchozí stav" -#define STR_DEFAULT "&Výchozí" -#define STR_LANGUAGE "Jazyk:" -#define STR_ICONSET "Sada ikon:" - -#define STR_GAIN "Zesílení" - -#define STR_FILE_NAME "Název souboru:" -#define STR_DISK_SIZE "Velikost disku:" -#define STR_RPM_MODE "Režím ot./m:" -#define STR_PROGRESS "Průběh:" - -#define STR_WIDTH "Šířka:" -#define STR_HEIGHT "Výška:" -#define STR_LOCK_TO_SIZE "Uzamknout na tyto rozměry" - -#define STR_MACHINE_TYPE "Typ počítače:" -#define STR_MACHINE "Počítač:" -#define STR_CONFIGURE "Nastavit" -#define STR_CPU_TYPE "Procesor:" -#define STR_CPU_SPEED "Rychlost:" -#define STR_FPU "Koprocesor:" -#define STR_WAIT_STATES "Čekací stavy:" -#define STR_MB "MB" -#define STR_MEMORY "Pamět:" -#define STR_TIME_SYNC "Synchronizace času" -#define STR_DISABLED "Vypnuta" -#define STR_ENABLED_LOCAL "Zapnuta (místní čas)" -#define STR_ENABLED_UTC "Zapnuta (UTC)" -#define STR_DYNAREC "Dynamický překladač" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Grafika:" -#define STR_VIDEO_2 "Grafika 2:" -#define STR_VOODOO "Použít grafický akcelerátor Voodoo" -#define STR_IBM8514 "Grafika IBM 8514/A" -#define STR_XGA "Grafika XGA" - -#define STR_MOUSE "Myš:" -#define STR_JOYSTICK "Joystick:" -#define STR_JOY1 "Joystick 1..." -#define STR_JOY2 "Joystick 2..." -#define STR_JOY3 "Joystick 3..." -#define STR_JOY4 "Joystick 4..." - -#define STR_SOUND1 "Zvuková karta 1:" -#define STR_SOUND2 "Zvuková karta 2:" -#define STR_SOUND3 "Zvuková karta 3:" -#define STR_SOUND4 "Zvuková karta 4:" -#define STR_MIDI_OUT "MIDI výstup:" -#define STR_MIDI_IN "MIDI vstup:" -#define STR_MPU401 "Samostatný MPU-401" -#define STR_FLOAT "Použít zvuk FLOAT32" -#define STR_FM_DRIVER "FM synth driver" -#define STR_FM_DRV_NUKED "Nuked (přesnější)" -#define STR_FM_DRV_YMFM "YMFM (rychlejší)" - -#define STR_NET_TYPE "Druh sítě:" -#define STR_PCAP "PCap zařízení:" -#define STR_NET "Síťový adaptér:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "Zařízení na COM1:" -#define STR_COM2 "Zařízení na COM2:" -#define STR_COM3 "Zařízení na COM3:" -#define STR_COM4 "Zařízení na COM4:" -#define STR_LPT1 "Zařízení na LPT1:" -#define STR_LPT2 "Zařízení na LPT2:" -#define STR_LPT3 "Zařízení na LPT3:" -#define STR_LPT4 "Zařízení na LPT4:" -#define STR_SERIAL1 "Povolit port COM1" -#define STR_SERIAL2 "Povolit port COM2" -#define STR_SERIAL3 "Povolit port COM3" -#define STR_SERIAL4 "Povolit port COM4" -#define STR_PARALLEL1 "Povolit port LPT1" -#define STR_PARALLEL2 "Povolit port LPT2" -#define STR_PARALLEL3 "Povolit port LPT3" -#define STR_PARALLEL4 "Povolit port LPT4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Řadič disku:" -#define STR_FDC "Disketový řadič:" -#define STR_IDE_TER "Třetí řadič IDE" -#define STR_IDE_QUA "Čtvrtý řadič IDE" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Řadič 1:" -#define STR_SCSI_2 "Řadič 2:" -#define STR_SCSI_3 "Řadič 3:" -#define STR_SCSI_4 "Řadič 4:" -#define STR_CASSETTE "Kazeta" - -#define STR_HDD "Pevné disky:" -#define STR_NEW "&Nový..." -#define STR_EXISTING "&Existující..." -#define STR_REMOVE "&Odebrat" -#define STR_BUS "Sběrnice:" -#define STR_CHANNEL "Kanál:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Zadat..." -#define STR_SECTORS "Sektory:" -#define STR_HEADS "Hlavy:" -#define STR_CYLS "Cylindry:" -#define STR_SIZE_MB "Velikost (MB):" -#define STR_TYPE "Typ:" -#define STR_IMG_FORMAT "Formát obrazu:" -#define STR_BLOCK_SIZE "Velikost bloků:" - -#define STR_FLOPPY_DRIVES "Disketové mechaniky:" -#define STR_TURBO "Turbo časování" -#define STR_CHECKBPB "Kontrola BPB" -#define STR_CDROM_DRIVES "Mechaniky CD-ROM:" -#define STR_CD_SPEED "Rychlost:" - -#define STR_MO_DRIVES "Magnetooptické mechaniky:" -#define STR_ZIP_DRIVES "Mechaniky ZIP:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA hodiny:" -#define STR_ISAMEM "ISA rozšíření paměti" -#define STR_ISAMEM_1 "Karta 1:" -#define STR_ISAMEM_2 "Karta 2:" -#define STR_ISAMEM_3 "Karta 3:" -#define STR_ISAMEM_4 "Karta 4:" -#define STR_BUGGER "Zařízení ISABugger" -#define STR_POSTCARD "Karta pro kódy POST" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Chyba" - IDS_2050 "Kritická chyba" - IDS_2051 " - PAUSED" - IDS_2052 "Stiskněte Ctrl+Alt+PgDn pro návrat z režimu celé obrazovky." - IDS_2053 "Rychlost" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "Obrazy ZIP disků (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box nenalezl žádné použitelné image pamětí ROM.\n\nStáhněte sadu obrazů ROM a extrahujte ji do složky ""roms""." - IDS_2057 "(prázdné)" - IDS_2058 "Obrazy ZIP disků (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0All files (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "Zap." - IDS_2061 "Vyp." - IDS_2062 "Všechny obrazy disků (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Základní sektorové obrazy (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Obrazy povrchu (*.86F)\0*.86F\0" - IDS_2063 "Počítač ""%hs"" není dostupný, jelikož chybí obraz jeho paměti ROM ve složce ""roms/machines"". Konfigurace se přepne na jiný dostupný počítač." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "Video adaptér ""%hs"" není dostupný, jelikož chybí obraz jeho paměti ROM ve složce ""roms/video"". Konfigurace se přepne na jiný dostupný adaptér." - IDS_2065 "Počítač" - IDS_2066 "Obraz" - IDS_2067 "Vstupní zařízení" - IDS_2068 "Zvuk" - IDS_2069 "Síť" - IDS_2070 "COM a LPT porty" - IDS_2071 "Řadiče úložiště" - IDS_2072 "Pevné disky" - IDS_2073 "Disketové a CD-ROM mechaniky" - IDS_2074 "Další vyměnitelná zařízení" - IDS_2075 "Jiné příslušenství" - IDS_2076 "Obrazy povrchu (*.86F)\0*.86F\0" - IDS_2077 "Klikněte pro zabraní myši" - IDS_2078 "Stiskněte F8+F12 pro uvolnění myši" - IDS_2079 "Stiskněte F8+F12 nebo prostřední tlačítko pro uvolnění myši" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Sběrnice" - IDS_2082 "Soubor" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "Kontrola BPB" - IDS_2089 "KB" - IDS_2090 "Nastala chyba při inicializaci video rendereru." - IDS_2091 "Výchozí" - IDS_2092 "%i čekací stav(y)" - IDS_2093 "Typ" - IDS_2094 "Nastala chyba při inicializaci knihovny PCap" - IDS_2095 "Nebyla nalezena žádná PCap zařízení" - IDS_2096 "Neplatné PCap zařízení" - IDS_2097 "Standardní 2tlačítkový joystick" - IDS_2098 "Standardní 4tlačítkový joystick" - IDS_2099 "Standardní 6tlačítkový joystick" - IDS_2100 "Standardní 8tlačítkový joystick" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "Žadné" - IDS_2105 "Nebylo možné nahrát klávesnicové zkratky." - IDS_2106 "Nebylo možné zaregistrovat raw input." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Disketová mechanika %i (%s): %ls" - IDS_2110 "Všechny obrazy (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Rozšířené sektorové obrazy (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Základní sektorové obrazy (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Obrazy magnetického toku (*.FDI)\0*.FDI\0Obrazy povrchu (*.86F;*.MFM)\0*.86F;*.MFM\0Všechny soubory (*.*)\0*.*\0" - IDS_2113 "Opravdu chcete resetovat emulovaný počítač?" - IDS_2114 "Opravdu chcete ukončit 86Box?" - IDS_2115 "Nastala chyba při inicializaci knihovny Ghostscript" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "Obrazy MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0Všechny soubory (*.*)\0*.*\0" - IDS_2118 "Vítejte v programu 86Box!" - IDS_2119 "Vestavěný řadič" - IDS_2120 "Ukončit" - IDS_2121 "Nebyly nalezeny žádné obrazy ROM" - IDS_2122 "Chcete uložit nastavení?" - IDS_2123 "Pokračováním se resetuje emulovaný počítač." - IDS_2124 "Uložit" - IDS_2125 "O programu 86Box" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "Emulátor starých počítačů\n\nAutoři: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nZveřejněno pod licencí GNU General Public License verze 2 nebo novější. Viz soubor LICENSE pro více informací." - IDS_2128 "OK" - IDS_2129 "Hardware není dostupný" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Ujistěte se, že je nainstalován " LIB_NAME_PCAP " a používáte síťové připojení s ním kompatibilní." - IDS_2131 "Neplatná konfigurace" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " je potřeba pro automatický převod PostScript dokumentů do PDF.\n\nJakékoliv dokumenty vytisknuté přes obecnou PostScriptovou tiskárnu budou uloženy jako PostScript (.ps) soubory." - IDS_2135 "Vstup do režimu celé obrazovky" - IDS_2136 "Nezobrazovat dále tuto zprávu" - IDS_2137 "Neukončovat" - IDS_2138 "Resetovat" - IDS_2139 "Neresetovat" - IDS_2140 "Obraz magnetooptického disku (*.IM?;*.MDI)\0*.IM?;*.MDI\0Všechny soubory (*.*)\0*.*\0" - IDS_2141 "Obraz CD-ROM disku (*.ISO;*.CUE)\0*.ISO;*.CUE\0Všechny soubory (*.*)\0*.*\0" - IDS_2142 "Konfigurace zařízení %hs" - IDS_2143 "Monitor je v režimu spánku" - IDS_2144 "Shadery OpenGL (*.GLSL)\0*.GLSL\0All files (*.*)\0*.*\0" - IDS_2145 "Možnosti OpenGL" - IDS_2146 "Pokoušíte se spustit nepodporovanou konfiguraci" - IDS_2147 "Pro tuto konfiguraci bylo vypnuto filtrování procesorů podle zvoleného počítače.\n\nToto umožňuje zvolit procesor, který by jinak se zvoleným počítačem nebyl kompatibilní. Můžou však nastat potíže s BIOSem nebo jiným softwarem.\n\nPovolení tohoto nastavení není oficiálně podporováno a jakákoliv hlášení o chybách mohou být uzavřeny jako neplatné." - IDS_2148 "Pokračovat" - IDS_2149 "Kazeta: %s" - IDS_2150 "Kazetové nahrávky (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Všechny soubory (*.*)\0*.*\0" - IDS_2151 "Cartridge %i: %ls" - IDS_2152 "Obrazy cartridge (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Všechny soubory (*.*)\0*.*\0" - IDS_2153 "Error initializing renderer" - IDS_2154 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." - IDS_2155 "Obnovit" - IDS_2156 "Pozastavit" - IDS_2157 "Stisknout Ctrl+Alt+Delete" - IDS_2158 "Stisknout Ctrl+Alt+Esc" - IDS_2159 "Resetovat" - IDS_2160 "Vypnout skrze rozhraní ACPI" - IDS_2161 "Nastavení" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Pevný disk (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "CD-ROM mechaniky pro rozhraní MFM/RLL nebo ESDI nikdy neexistovaly" - IDS_4100 "Vlastní..." - IDS_4101 "Vlastní (velký)..." - IDS_4102 "Přidat nový pevný disk" - IDS_4103 "Přidat existující pevný disk" - IDS_4104 "Obraz disku formátu HDI nemůžou být větší než 4 GB." - IDS_4105 "Obraz disku nemůžou být větší než 127 GB." - IDS_4106 "Obrazy pevného disku (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Všechny soubory (*.*)\0*.*\0" - IDS_4107 "Nebylo možné přečíst soubor" - IDS_4108 "Nebylo možné zapisovat do souboru" - IDS_4109 "Obraz disku ve formátu HDI nebo HDX s velikostí sektoru jinou než 512 bajtů nejsou podporovány." - IDS_4110 "USB zatím není podporováno." - IDS_4111 "Soubor obrazu disku již existuje" - IDS_4112 "Zadejte platný název souboru." - IDS_4113 "Obraz disku byl vytvořen" - IDS_4114 "Ujistěte se, že soubor existuje a lze jej přečíst." - IDS_4115 "Ujistěte se, že se do složky, kde se má soubor uložit, dá zapisovat." - IDS_4116 "Obraz disku je příliš velký" - IDS_4117 "Nezapomeňte nově vytvořený disk rozdělit a naformátovat." - IDS_4118 "Zvolený soubor bude přepsán. Opravdu jej chcete použít?" - IDS_4119 "Nepodporovaný obraz disku" - IDS_4120 "Přepsat" - IDS_4121 "Nepřepisovat" - IDS_4122 "Surový obraz (.img)" - IDS_4123 "HDI obraz (.hdi)" - IDS_4124 "HDX obraz (.hdx)" - IDS_4125 "VHD s pevnou velikostí (.vhd)" - IDS_4126 "VHD s dynamickou velikostí (.vhd)" - IDS_4127 "Rozdílový VHD (.vhd)" - IDS_4128 "Velké bloky (2 MB)" - IDS_4129 "Malé bloky (512 KB)" - IDS_4130 "Soubory VHD (*.VHD)\0*.VHD\0Všechny soubory (*.*)\0*.*\0" - IDS_4131 "Vyberte nadřazený virtuální disk" - IDS_4132 "To může znamenat, že se obsahy nadřazeného disku změnily po vytvoření rozdílového disku.\n\nTato chyba také může nastat, pokud byl obraz disku kopírován nebo přesunut, nebo kvůli chybě v programu, který jej vytvořil.\n\nChcete časová razítka opravit?" - IDS_4133 "Časová razítka nadřazeného a podřazeného disku nesouhlasí" - IDS_4134 "Nebylo možné opravit časové razítko VHD." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Vypnuto" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Vypnuto" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (cluster 1024)" - IDS_5898 "DMF (cluster 2048)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "Dokonalé otáčky za minutu" - IDS_6145 "1% pod dokonalými ot./m" - IDS_6146 "1.5% pod dokonalými ot./m" - IDS_6147 "2% pod dokonalými ot./m" - - IDS_7168 "(Výchozí nastavení systému)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Czech (Czech Republic) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/de-DE.rc b/src/win/languages/de-DE.rc deleted file mode 100644 index 9859d3d26..000000000 --- a/src/win/languages/de-DE.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// German (de-DE) resources - -#ifdef _WIN32 -LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Aktionen" - BEGIN - MENUITEM "&Tastatur benötigt das Einfangen des Mauszeigers", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Die rechte Strg-Taste ist die Linke Alt-Taste", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Hard-Reset...", IDM_ACTION_HRESET - MENUITEM "&Strg+Alt+Entf\tStrg+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Strg+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Pause", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "Be&enden...", IDM_ACTION_EXIT - END - POPUP "&Ansicht" - BEGIN - MENUITEM "&Statusleiste ausblenden", IDM_VID_HIDE_STATUS_BAR - MENUITEM "&Werkzeugleiste ausblenden", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Größenverstellbares Fenster", IDM_VID_RESIZE - MENUITEM "&Größe && Position merken", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "Re&nderer" - BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0-Kern)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "Fenstergröße einstellen...", IDM_VID_SPECIFY_DIM - MENUITEM "&4:3-Seitenverhältnis erzwingen", IDM_VID_FORCE43 - POPUP "&Fensterskalierungsfaktor" - BEGIN - MENUITEM "&0,5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1,&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Filteringmethode" - BEGIN - MENUITEM "&Nearest", IDM_VID_FILTER_NEAREST - MENUITEM "&Linear", IDM_VID_FILTER_LINEAR - END - MENUITEM "Hi&DPI-Skalierung", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Vollbild\tStrg+Alt+Bild auf", IDM_VID_FULLSCREEN - POPUP "&Stretching-Modus im Vollbildmodus" - BEGIN - MENUITEM "&Vollbild-Stretching", IDM_VID_FS_FULL - MENUITEM "&4:3-Seitenverhältnis erzwingen", IDM_VID_FS_43 - MENUITEM "&Quadratische Pixel (Seitenverhältnis beibehalten)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Integer-Skalierung", IDM_VID_FS_INT - END - POPUP "E&GA/(S)VGA-Einstellungen" - BEGIN - MENUITEM "&Invertierte VGA-Anzeige", IDM_VID_INVERT - POPUP "&VGA-Bildschirmtyp" - BEGIN - MENUITEM "&RGB-Farbe", IDM_VID_GRAY_RGB - MENUITEM "&RGB-Graustufen", IDM_VID_GRAY_MONO - MENUITEM "&Bernstein-Monitor", IDM_VID_GRAY_AMBER - MENUITEM "&Grüner Monitor", IDM_VID_GRAY_GREEN - MENUITEM "&Weißer Monitor", IDM_VID_GRAY_WHITE - END - POPUP "Methode zur &Graustufenkonversion" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Durchschnittsmethode", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "Overscan für CGA/PCjr/Tandy/E&GA/(S)VGA-Displays", IDM_VID_OVERSCAN - MENUITEM "Kontrast für &monochrome Displays ändern", IDM_VID_CGACON - END - MENUITEM "&Medien", IDM_MEDIA - POPUP "&Werkzeuge" - BEGIN - MENUITEM "&Optionen...", IDM_CONFIG - MENUITEM "&Statusleistenicons aktualisieren", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "S&creenshot aufnehmen\tStrg+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Einstellungen...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "&Discord-Integration aktivieren", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Klangverstärkung...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Tracing starten\tStrg+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Tracing beenden\tStrg+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Hilfe" - BEGIN - MENUITEM "&Dokumentation...", IDM_DOCS - MENUITEM "&Über 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Neues Image...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Bestehendes Image...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Bestehendes Image (&schreibgeschützt)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Aufnehmen", IDM_CASSETTE_RECORD - MENUITEM "&Abspielen", IDM_CASSETTE_PLAY - MENUITEM "&An den Anfang zurückspulen", IDM_CASSETTE_REWIND - MENUITEM "&An das Ende vorspulen", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "A&uswerfen", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Cartridgeimage...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "A&uswerfen", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Neues Image...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Bestehendes Image...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Bestehendes Image (&schreibgeschützt)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&In das 86F-Format e&xportieren...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "&Auswerfen", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Stummschalten", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "L&eer", IDM_CDROM_EMPTY - MENUITEM "&Voriges Image neu laden", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_IMAGE - MENUITEM "&Verzeichnis...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Neues Image...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Bestehendes Image...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Bestehendes Image (&schreibgeschützt)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "A&uswerfen", IDM_ZIP_EJECT - MENUITEM "&Voriges Image neu laden", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Neues Image...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Bestehendes Image...", IDM_MO_IMAGE_EXISTING - MENUITEM "Bestehendes Image (&schreibgeschützt)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Auswerfen", IDM_MO_EJECT - MENUITEM "&Bestehendes Image erneut laden", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "Ziel&framerate" - BEGIN - MENUITEM "&Mit Videoausgabe synchronisieren", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 fps", IDM_VID_GL_FPS_25 - MENUITEM "&30 fps", IDM_VID_GL_FPS_30 - MENUITEM "&50 fps", IDM_VID_GL_FPS_50 - MENUITEM "&60 fps", IDM_VID_GL_FPS_60 - MENUITEM "&75 fps", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Shader auswählen...", IDM_VID_GL_SHADER - MENUITEM "&Shader entfernen", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Einstellungen" -#define STR_SND_GAIN "Klangverstärkung" -#define STR_NEW_FLOPPY "Neues Image" -#define STR_CONFIG "Optionen" -#define STR_SPECIFY_DIM "Fenstergröße einstellen" - -#define STR_OK "OK" -#define STR_CANCEL "Abbrechen" -#define STR_GLOBAL "Einstellungen als &globalen Standard speichern" -#define STR_DEFAULT "&Standard" -#define STR_LANGUAGE "Sprache:" -#define STR_ICONSET "Icon-Satz:" - -#define STR_GAIN "Verstärkung" - -#define STR_FILE_NAME "Dateiname:" -#define STR_DISK_SIZE "Plattengröße:" -#define STR_RPM_MODE "Drehzahlmodus:" -#define STR_PROGRESS "Fortschritt:" - -#define STR_WIDTH "Breite:" -#define STR_HEIGHT "Höhe:" -#define STR_LOCK_TO_SIZE "Feste Größe" - -#define STR_MACHINE_TYPE "Systemtyp:" -#define STR_MACHINE "System:" -#define STR_CONFIGURE "Einstellen" -#define STR_CPU_TYPE "CPU-Typ:" -#define STR_CPU_SPEED "Takt:" -#define STR_FPU "FPU-Einheit:" -#define STR_WAIT_STATES "Wartezustände:" -#define STR_MB "MB" -#define STR_MEMORY "Hauptspeicher:" -#define STR_TIME_SYNC "Zeitsynchronisierung" -#define STR_DISABLED "Deaktiviert" -#define STR_ENABLED_LOCAL "Aktiviert (Lokale Uhrzeit)" -#define STR_ENABLED_UTC "Aktiviert (UTC)" -#define STR_DYNAREC "Dynamischer Recompiler" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Videokarte:" -#define STR_VIDEO_2 "Videokarte 2:" -#define STR_VOODOO "Voodoo-Grafik" -#define STR_IBM8514 "IBM 8514/A-Grafik" -#define STR_XGA "XGA-Grafik" - -#define STR_MOUSE "Maus:" -#define STR_JOYSTICK "Joystick:" -#define STR_JOY1 "Joystick 1..." -#define STR_JOY2 "Joystick 2..." -#define STR_JOY3 "Joystick 3..." -#define STR_JOY4 "Joystick 4..." - -#define STR_SOUND1 "Soundkarte 1:" -#define STR_SOUND2 "Soundkarte 2:" -#define STR_SOUND3 "Soundkarte 3:" -#define STR_SOUND4 "Soundkarte 4:" -#define STR_MIDI_OUT "MIDI Out-Gerät:" -#define STR_MIDI_IN "MIDI In-Gerät:" -#define STR_MPU401 "Standalone-MPU-401-Gerät" -#define STR_FLOAT "FLOAT32-Wiedergabe benutzen" -#define STR_FM_DRIVER "FM-Synth-Treiber" -#define STR_FM_DRV_NUKED "Nuked (genauer)" -#define STR_FM_DRV_YMFM "YMFM (schneller)" - -#define STR_NET_TYPE "Netzwerktyp:" -#define STR_PCAP "PCap-Gerät:" -#define STR_NET "Netzwerkadapter:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "COM1-Gerät:" -#define STR_COM2 "COM2-Gerät:" -#define STR_COM3 "COM3-Gerät:" -#define STR_COM4 "COM4-Gerät:" -#define STR_LPT1 "LPT1-Gerät:" -#define STR_LPT2 "LPT2-Gerät:" -#define STR_LPT3 "LPT3-Gerät:" -#define STR_LPT4 "LPT4-Gerät:" -#define STR_SERIAL1 "Serielle Schnittstelle 1" -#define STR_SERIAL2 "Serielle Schnittstelle 2" -#define STR_SERIAL3 "Serielle Schnittstelle 3" -#define STR_SERIAL4 "Serielle Schnittstelle 4" -#define STR_PARALLEL1 "Parallelport 1" -#define STR_PARALLEL2 "Parallelport 2" -#define STR_PARALLEL3 "Parallelport 3" -#define STR_PARALLEL4 "Parallelport 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "HDD-Controller:" -#define STR_FDC "FD-Controller:" -#define STR_IDE_TER "Tertiärer IDE-Controller" -#define STR_IDE_QUA "Quartärer IDE-Controller" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Controller 1:" -#define STR_SCSI_2 "Controller 2:" -#define STR_SCSI_3 "Controller 3:" -#define STR_SCSI_4 "Controller 4:" -#define STR_CASSETTE "Kassette" - -#define STR_HDD "Festplatten:" -#define STR_NEW "&Neu..." -#define STR_EXISTING "&Vorhanden..." -#define STR_REMOVE "&Entfernen" -#define STR_BUS "Bus:" -#define STR_CHANNEL "Kanal:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Festlegen..." -#define STR_SECTORS "Sektoren:" -#define STR_HEADS "Köpfe:" -#define STR_CYLS "Zylinder:" -#define STR_SIZE_MB "Größe (MB):" -#define STR_TYPE "Typ:" -#define STR_IMG_FORMAT "Imageformat:" -#define STR_BLOCK_SIZE "Blockgröße:" - -#define STR_FLOPPY_DRIVES "Diskettenlaufwerke:" -#define STR_TURBO "Turbo-Timings" -#define STR_CHECKBPB "BPB überprüfen" -#define STR_CDROM_DRIVES "CD-ROM-Laufwerke:" -#define STR_CD_SPEED "Geschwindigkeit:" - -#define STR_MO_DRIVES "MO-Laufwerke:" -#define STR_ZIP_DRIVES "ZIP-Laufwerke:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA-Echtzeituhr:" -#define STR_ISAMEM "ISA-Speichererweiterung:" -#define STR_ISAMEM_1 "Steckkarte 1:" -#define STR_ISAMEM_2 "Steckkarte 2:" -#define STR_ISAMEM_3 "Steckkarte 3:" -#define STR_ISAMEM_4 "Steckkarte 4:" -#define STR_BUGGER "ISABugger-Gerät" -#define STR_POSTCARD "POST-Code-Karte" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Fehler" - IDS_2050 "Fataler Fehler" - IDS_2051 " - PAUSED" - IDS_2052 "Bitte Strg+Alt+Bild ab zur Rückkehr in den Fenstermodus drücken." - IDS_2053 "Geschwindigkeit" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIP-Images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box konnte keine nutzbaren ROM-Dateien finden.\n\nBitte besuchen Sie download, laden ein ROM-Set herunter und extrahieren dies in das ""roms""-Verzeichnis." - IDS_2057 "(leer)" - IDS_2058 "ZIP-Images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Alle Dateien (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "An" - IDS_2061 "Aus" - IDS_2062 "Alle Images (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Basissektorimages (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Oberflächenimages (*.86F)\0*.86F\0" - IDS_2063 "Das System ""%hs"" ist aufgrund von fehlenden ROMs im Verzeichnis roms/machines nicht verfügbar. Es wird auf ein verfügbares System gewechselt." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "Die Videokarte ""%hs"" ist aufgrund von fehlenden ROMs im Verzeichnis roms/video nicht verfügbar. Es wird auf eine verfügbare Videokarte gewechselt." - IDS_2065 "System" - IDS_2066 "Anzeige" - IDS_2067 "Eingabegeräte" - IDS_2068 "Multimedia" - IDS_2069 "Netzwerk" - IDS_2070 "Anschlüsse (COM & LPT)" - IDS_2071 "Speichercontroller" - IDS_2072 "Festplatten" - IDS_2073 "Disketten- & CD-ROM-Laufwerke" - IDS_2074 "Andere Wechsellaufwerke" - IDS_2075 "Andere Peripheriegeräte" - IDS_2076 "Oberflächenimages (*.86F)\0*.86F\0" - IDS_2077 "Zum Einfangen des Mauszeigers bitte klicken" - IDS_2078 "Bitte F8+F12 zur Mausfreigabe drücken" - IDS_2079 "Bitte F8+F12 oder die mittlere Maustaste zur Mausfreigabe drücken" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Bus" - IDS_2082 "Datei" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "BPB prüfen" - IDS_2089 "KB" - IDS_2090 "Der Videorenderer konnte nicht initialisiert werden." - IDS_2091 "Standard" - IDS_2092 "%i Wartezustände" - IDS_2093 "Typ" - IDS_2094 "PCap konnte nicht eingerichtet werden" - IDS_2095 "Keine PCap-Geräte gefunden" - IDS_2096 "Ungültiges PCap-Gerät" - IDS_2097 "Standard 2-Tasten-Joystick(s)" - IDS_2098 "Standard 4-Tasten-Joystick" - IDS_2099 "Standard 6-Tasten-Joystick" - IDS_2100 "Standard 8-Tasten-Joystick" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "Ohne" - IDS_2105 "Tastaturbeschleuniger konnten nicht geladen werden." - IDS_2106 "Roheingaben konnten nicht registriert werden." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Diskette %i (%s): %ls" - IDS_2110 "Alle Images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Fortgeschrittene Sektorimages (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basissektorimages (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Fluximages (*.FDI)\0*.FDI\0Oberflächenimages (*.86F;*.MFM)\0*.86F;*.MFM\0Alle Dateien (*.*)\0*.*\0" - IDS_2113 "Sind Sie sich sicher, dass Sie einen Hard-Reset für das emulierte System durchführen wollen?" - IDS_2114 "Sind Sie sich sicher, dass Sie 86Box beenden wollen?" - IDS_2115 "Ghostscript konnte nicht initialisiert werden" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "MO-Images (*.IM?;*.MDI)\0*.IM?;*.MDI\0Alle Dateien (*.*)\0*.*\0" - IDS_2118 "Willkommen bei 86Box!" - IDS_2119 "Interner Controller" - IDS_2120 "Beenden" - IDS_2121 "Keine ROMs gefunden" - IDS_2122 "Möchten Sie die Einstellungen speichern?" - IDS_2123 "Dies wird zu einem Hard-Reset des emulierten Systems führen." - IDS_2124 "Speichern" - IDS_2125 "Über 86Box" - IDS_2126 "86Box Version " EMU_VERSION - - IDS_2127 "Ein Emulator für alte Computer\n\nAutoren: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne sowie andere.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho sowie andere.\n\nÜbersetzt von: dob205\n\nVeröffentlicht unter der GNU General Public License in der Version 2 oder neuer. Siehe LICENSE für mehr Informationen." - IDS_2128 "OK" - IDS_2129 "Hardware nicht verfügbar" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Bitte stellen Sie sicher, dass " LIB_NAME_PCAP " installiert ist und sie eine " LIB_NAME_PCAP "-kompatible Netzwerkverbindung nutzen." - IDS_2131 "Ungültige Konfiguration" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " wird zur automatischen Konversion von PostScript-Dateien in das PDF-Format benötigt.\n\nSämtliche an den generischen PostScript-Drucker gesendete Dateien werden als PostScript (.ps)-Dateien gesichert." - IDS_2135 "Vollbildmodus wird aktiviert" - IDS_2136 "Diese Nachricht nicht mehr anzeigen" - IDS_2137 "Nicht beenden" - IDS_2138 "Zurücksetzen" - IDS_2139 "Nicht zurücksetzen" - IDS_2140 "MO-Images (*.IM?;*.MDI)\0*.IM?;*.MDI\0Alle Dateien (*.*)\0*.*\0" - IDS_2141 "CD-ROM-Images (*.ISO;*.CUE)\0*.ISO;*.CUE\0Alle Dateien (*.*)\0*.*\0" - IDS_2142 "%hs-Gerätekonfiguration" - IDS_2143 "Monitor im Standbymodus" - IDS_2144 "OpenGL-Shader (*.GLSL)\0*.GLSL\0Alle Dateien (*.*)\0*.*\0" - IDS_2145 "OpenGL-Optionen" - IDS_2146 "Sie laden gerade eine nicht unterstützte Konfiguration" - IDS_2147 "Das Filtern der CPU-Typen basierend auf dem ausgewählten System ist für dieses System deaktiviert.\n\nDies ermöglicht es, dass man eine sonst nicht mit dem ausgewählten System inkompatible CPU auswählen kann. Allerdings kann dies zu Inkompatiblilitäten mit dem BIOS des Systems oder anderen Programmen kommen.\n\nDas Aktivieren dieser Einstellung wird nicht unterstützt und sämtliche Bugreports können als ""invalid"" geschlossen werden." - IDS_2148 "Fortfahren" - IDS_2149 "Kassette: %s" - IDS_2150 "Kassettenimages (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Alle Dateien (*.*)\0*.*\0" - IDS_2151 "Cartridge %i: %ls" - IDS_2152 "Cartridgeimages (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Alle Dateien (*.*)\0*.*\0" - IDS_2153 "Fehler bei der Rendererinitialisierung" - IDS_2154 "Der OpenGL (3.0-Kern)-Renderer konnte nicht initialisiert werden. Bitte benutzen Sie einen anderen Renderer." - IDS_2155 "Fortsetzen" - IDS_2156 "Pausieren" - IDS_2157 "Strg+Alt+Entf drücken" - IDS_2158 "Strg+Alt+Esc drücken" - IDS_2159 "Hard-Reset" - IDS_2160 "ACPI-basiertes Herunterfahren" - IDS_2161 "Optionen" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Festplatte (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLL- oder ESDI CD-ROM-Laufwerke hat es niemals gegeben" - IDS_4100 "Angepasst..." - IDS_4101 "Angepasst (Groß)..." - IDS_4102 "Neue Festplatte hinzufügen" - IDS_4103 "Bestehende Festplatte hinzufügen" - IDS_4104 "HDI-Diskimages können nicht größer als 4 GB groß sein." - IDS_4105 "Festplattenimages können nicht größer als 127 GB groß sein." - IDS_4106 "Festplattenimages (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Alle Dateien (*.*)\0*.*\0" - IDS_4107 "Die Datei konnte nicht gelesen werden" - IDS_4108 "Die Datei konnte nicht beschrieben werden" - IDS_4109 "HDI- oder HDX-Images mit einer Sektorgröße größer als 512 kB werden nicht unterstützt." - IDS_4110 "USB wird noch nicht unterstützt" - IDS_4111 "Die Festplattenimagedatei existiert bereits" - IDS_4112 "Bitte geben Sie einen gültigen Dateinamen ein." - IDS_4113 "Disk-Image wurde erstellt" - IDS_4114 "Bitte stellen Sie sicher, dass die Datei existiert und lesbar ist." - IDS_4115 "Bitte stellen Sie sicher, dass die Datei in ein Verzeichnis mit Schreibberechtigungen gespeichert wird." - IDS_4116 "Festplattenimage ist zu groß" - IDS_4117 "Bitte denken Sie an das Partitionieren und Formatieren des neu erstellten Laufwerks." - IDS_4118 "Die ausgewählte Datei wird überschrieben. Möchten Sie diese Datei nutzen?" - IDS_4119 "Nicht unterstütztes Festplattenimage" - IDS_4120 "Überschreiben" - IDS_4121 "Nicht überschreiben" - IDS_4122 "Rohdatenimages (.img)" - IDS_4123 "HDI-Images (.hdi)" - IDS_4124 "HDX-Images (.hdx)" - IDS_4125 "VHD mit fester Größe (.vhd)" - IDS_4126 "VHD mit dynamischer Größe (.vhd)" - IDS_4127 "Differenzierende VHD (.vhd)" - IDS_4128 "Große Blöcke (2 MB)" - IDS_4129 "Kleine Blöcke (512 KB)" - IDS_4130 "VHD-Dateien (*.VHD)\0*.VHD\0Alle Dateien (*.*)\0*.*\0" - IDS_4131 "Eltern-VHD-Datei bitte auswählen" - IDS_4132 "Dies bedeutet, dass das Elternimage nach der Erstellung des differenzierenden Images erzeugt wurde.\n\nDies kann auch passieren, falls die Image-Dateien verschoben oder kopiert wurden. Ebenso kann auch dies durch einen Bug im Programm, welches das Image erstellt hat, passieren.\n\nMöchten Sie die Zeitstempel korrigieren?" - IDS_4133 "Die Zeitstempel der Eltern- und der Kindesplatte stimmen nicht überein" - IDS_4134 "Der Zeitstempel der VHD konnte nicht korrigiert werden." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Deaktiviert" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Deaktiviert" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1,2 MB" - IDS_5895 "1,25 MB" - IDS_5896 "1,44 MB" - IDS_5897 "DMF (1024 Cluster)" - IDS_5898 "DMF (2048 Cluster)" - IDS_5899 "2,88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3,5-Zoll 128 MB (ISO 10090)" - IDS_5903 "3,5-Zoll 230 MB (ISO 13963)" - IDS_5904 "3,5-Zoll 540 MB (ISO 15498)" - IDS_5905 "3,5-Zoll 640 MB (ISO 15498)" - IDS_5906 "3,5-Zoll 1,3 GB (GigaMO)" - IDS_5907 "3,5-Zoll 2,3 GB (GigaMO 2)" - IDS_5908 "5,25-Zoll 600 MB" - IDS_5909 "5,25-Zoll 650 MB" - IDS_5910 "5,25-Zoll 1 GB" - IDS_5911 "5,25-Zoll 1,3 GB" - - IDS_6144 "Perfekte Drehzahl" - IDS_6145 "1% unterhalb der perfekten Drehzahl" - IDS_6146 "1,5% unterhalb der perfekten Drehzahl" - IDS_6147 "2% unterhalb der perfekten Drehzahl" - - IDS_7168 "(Systemstandard)" -END -#define IDS_LANG_ENUS IDS_7168 - -// German (de-DE) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/dialogs.rc b/src/win/languages/dialogs.rc deleted file mode 100644 index 1daf46b4c..000000000 --- a/src/win/languages/dialogs.rc +++ /dev/null @@ -1,1143 +0,0 @@ -#define CFG_CHECKBOX_PRI_WIDTH 94 -#define CFG_CHECKBOX_HEIGHT 10 -#define CFG_BTN_WIDTH 46 -#define CFG_BTN_HEIGHT 14 -#define CFG_PANE_LTEXT_PRI_WIDTH 85 -#define CFG_PANE_LTEXT_PRI_WIDTH_2 170 -#define CFG_PANE_LTEXT_PRI_WIDTH_3 255 -#define CFG_PANE_LTEXT_HEIGHT 10 -#define CFG_COMBO_BTN_WIDTH 212 -#define CFG_COMBO_NOBTN_WIDTH CFG_COMBO_BTN_WIDTH + CFG_BTN_WIDTH + 8 -#define CFG_COMBO_BOX_LEFT CFG_PANE_LTEXT_PRI_WIDTH + 10 -#define CFG_COMBO_BTN_LEFT CFG_COMBO_BOX_LEFT + CFG_COMBO_BTN_WIDTH + 8 -#define CFG_COMBO_HEIGHT 120 -#define CFG_LIST_WIDTH 123 -#define CFG_LIST_HEIGHT 212 -#define CFG_PANE_TOP 0 -#define CFG_PANE_LEFT CFG_LIST_WIDTH + 8 -#define CFG_PANE_WIDTH CFG_COMBO_BOX_LEFT + CFG_COMBO_NOBTN_WIDTH -#define CFG_PANE_HEIGHT 221 -#define CFG_HMARGIN 7 -#define CFG_VMARGIN 9 -#define CFG_SYSLISTVIEW32_WIDTH CFG_PANE_WIDTH - 7 - -DLG_PREFERENCES DIALOG DISCARDABLE 0, 0, 240, 118 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION STR_PREFERENCES -FONT FONT_SIZE, FONT_NAME -BEGIN - DEFPUSHBUTTON STR_OK, IDOK, - 123, 97, 50, CFG_BTN_HEIGHT - - PUSHBUTTON STR_CANCEL, IDCANCEL, - 179, 97, 50, CFG_BTN_HEIGHT - - LTEXT STR_LANGUAGE, - 2000, 13, 8, 100, 8 - COMBOBOX IDC_COMBO_LANG, - 13, 18, 213, 22, - CBS_DROPDOWNLIST | CBS_HASSTRINGS - PUSHBUTTON STR_DEFAULT, IDC_BUTTON_DEFAULT, - 162, 32, 60, CFG_BTN_HEIGHT - - LTEXT STR_ICONSET, - 2001, 13, 40, 100, 8 - COMBOBOX IDC_COMBO_ICON, - 13, 50, 213, 22, - CBS_DROPDOWNLIST | CBS_HASSTRINGS - PUSHBUTTON STR_DEFAULT, IDC_BUTTON_DEFICON, - 162, 64, 60, CFG_BTN_HEIGHT - - AUTOCHECKBOX STR_GLOBAL, IDC_CHECKBOX_GLOBAL, - 13, 82, 217, 8, - WS_DISABLED -END - -DLG_SND_GAIN DIALOG DISCARDABLE 0, 0, 113, 136 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION STR_SND_GAIN -FONT FONT_SIZE, FONT_NAME -BEGIN - DEFPUSHBUTTON STR_OK, IDOK, - 57, 7, 50, CFG_BTN_HEIGHT - - PUSHBUTTON STR_CANCEL, IDCANCEL, - 57, 24, 50, CFG_BTN_HEIGHT - - CONTROL STR_GAIN, IDC_SLIDER_GAIN, - "msctls_trackbar32", - TBS_VERT | TBS_BOTH | TBS_AUTOTICKS | WS_TABSTOP, - 15, 20, 20, 109 - CTEXT STR_GAIN,IDT_GAIN, - 10, 7, 32, 9, - SS_CENTERIMAGE -END - -DLG_NEW_FLOPPY DIALOG DISCARDABLE 0, 0, 226, 86 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION STR_NEW_FLOPPY -FONT FONT_SIZE, FONT_NAME -BEGIN - DEFPUSHBUTTON STR_OK, IDOK, - 104, 65, 50, CFG_BTN_HEIGHT - - PUSHBUTTON STR_CANCEL, IDCANCEL, - 162, 65, 50, CFG_BTN_HEIGHT - - LTEXT STR_FILE_NAME, IDT_FLP_FILE_NAME, - 7, 6, 44, 12, - SS_CENTERIMAGE - EDITTEXT IDC_EDIT_FILE_NAME, - 53, 5, 150, 14, - ES_AUTOHSCROLL | ES_READONLY - - LTEXT STR_DISK_SIZE, IDT_FLP_DISK_SIZE, - 7, 25, 44, 12, - SS_CENTERIMAGE - COMBOBOX IDC_COMBO_DISK_SIZE, - 53, 25, 166, 14, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "...", IDC_CFILE, - 206, 5, 13, CFG_BTN_HEIGHT - - LTEXT STR_RPM_MODE, IDT_FLP_RPM_MODE, - 7, 45, 44, 12, - SS_CENTERIMAGE - COMBOBOX IDC_COMBO_RPM_MODE, - 53, 45, 166, 14, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_PROGRESS, IDT_FLP_PROGRESS, - 7, 45, 44, 12, - SS_CENTERIMAGE - CONTROL "IMGCreateProgress", IDC_PBAR_IMG_CREATE, - "msctls_progress32", - PBS_SMOOTH | WS_BORDER, - 53, 45, 166, 14 -END - -DLG_SPECIFY_DIM DIALOG DISCARDABLE 0, 0, 175, 66 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION STR_SPECIFY_DIM -FONT FONT_SIZE, FONT_NAME -BEGIN - LTEXT STR_WIDTH, IDT_WIDTH, - 7, 9, 24, 12 - EDITTEXT IDC_EDIT_WIDTH, - 33, 7, 45, 12, - ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_WIDTHSPIN, - "msctls_updown32", - UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS, - 76, 6, 12, 12 - - LTEXT STR_HEIGHT, IDT_HEIGHT, - 97, 9, 24, 12 - EDITTEXT IDC_EDIT_HEIGHT, - 123, 7, 45, 12, - ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_HEIGHTSPIN, - "msctls_updown32", - UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS, - 166, 6, 12, 12 - - CONTROL STR_LOCK_TO_SIZE,IDC_CHECK_LOCK_SIZE, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - 7, 26, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - DEFPUSHBUTTON STR_OK,IDOK, - 30, 45, 50, CFG_BTN_HEIGHT - - PUSHBUTTON STR_CANCEL, IDCANCEL, - 99, 45, 50, CFG_BTN_HEIGHT -END - -DLG_CONFIG DIALOG DISCARDABLE 0, 0, CFG_LIST_WIDTH + CFG_PANE_WIDTH + 18, 256 -STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION STR_CONFIG -FONT FONT_SIZE, FONT_NAME -BEGIN - DEFPUSHBUTTON STR_OK, IDOK, - CFG_LIST_WIDTH + CFG_PANE_WIDTH - 108, 235, 50, CFG_BTN_HEIGHT - - PUSHBUTTON STR_CANCEL, IDCANCEL, - CFG_LIST_WIDTH + CFG_PANE_WIDTH - 48 , 235, 50, CFG_BTN_HEIGHT - - CONTROL "List2", IDC_SETTINGSCATLIST, - "SysListView32", - LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_SHOWSELALWAYS | LVS_SINGLESEL | - WS_BORDER | WS_TABSTOP, - CFG_HMARGIN, CFG_VMARGIN, CFG_LIST_WIDTH, CFG_LIST_HEIGHT - - CONTROL "",-1, - "Static", SS_BLACKFRAME | SS_SUNKEN, - 1, 226, CFG_LIST_WIDTH + CFG_PANE_WIDTH + 16, 1 -END - -DLG_CFG_MACHINE DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT -STYLE DS_CONTROL | WS_CHILD -FONT FONT_SIZE, FONT_NAME -BEGIN - LTEXT STR_MACHINE_TYPE,IDT_MACHINE_TYPE, - CFG_HMARGIN, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_MACHINE_TYPE, - CFG_COMBO_BOX_LEFT, 7, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_MACHINE, IDT_MACHINE, - CFG_HMARGIN, 28, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_MACHINE, - CFG_COMBO_BOX_LEFT, 26, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_MACHINE, - CFG_COMBO_BTN_LEFT, 25, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_CPU_TYPE, IDT_CPU_TYPE, - CFG_HMARGIN, 47, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_CPU_TYPE, - CFG_COMBO_BOX_LEFT, 45, 110, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_CPU_SPEED, IDT_CPU_SPEED, - 216, 47, 34, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_CPU_SPEED, - 252, 45, 109, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_FPU,IDT_FPU, - CFG_HMARGIN, 66, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_FPU, - CFG_COMBO_BOX_LEFT, 64, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_WAIT_STATES, IDT_WAIT_STATES, - CFG_HMARGIN, 85, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_WS, - CFG_COMBO_BOX_LEFT, 83, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_MEMORY, IDT_MEMORY, - CFG_HMARGIN, 104, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - EDITTEXT IDC_MEMTEXT, - CFG_COMBO_BOX_LEFT, 102, 45, 12, - ES_AUTOHSCROLL | ES_NUMBER - CONTROL "", IDC_MEMSPIN, - "msctls_updown32", - UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS, - 138, 101, 12, 12 - LTEXT STR_MB, IDT_MB, - 148, 104, 12, CFG_PANE_LTEXT_HEIGHT - -#ifdef USE_DYNAREC - CONTROL STR_DYNAREC, IDC_CHECK_DYNAREC, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 120, 120, CFG_CHECKBOX_HEIGHT -#endif - - CONTROL STR_SOFTFLOAT, IDC_CHECK_SOFTFLOAT, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 135, 120, CFG_CHECKBOX_HEIGHT - - - GROUPBOX STR_TIME_SYNC, IDC_TIME_SYNC, - CFG_HMARGIN, 150, 110, 56 - - CONTROL STR_DISABLED, IDC_RADIO_TS_DISABLED, - "Button", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, - 14, 162, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_ENABLED_LOCAL, IDC_RADIO_TS_LOCAL, - "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, - 14, 176, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_ENABLED_UTC, IDC_RADIO_TS_UTC, - "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, - 14, 190, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT -END - -DLG_CFG_VIDEO DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT -STYLE DS_CONTROL | WS_CHILD -FONT FONT_SIZE, FONT_NAME -BEGIN - LTEXT STR_VIDEO, IDT_VIDEO, - CFG_HMARGIN, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_VIDEO, - CFG_COMBO_BOX_LEFT, 7, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_VID, - CFG_COMBO_BTN_LEFT, 6, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_VIDEO_2, IDT_VIDEO_2, - CFG_HMARGIN, 28, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_VIDEO_2, - CFG_COMBO_BOX_LEFT, 26, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_VID_2, - CFG_COMBO_BTN_LEFT, 25, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - CONTROL STR_VOODOO, IDC_CHECK_VOODOO, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 47, 199, CFG_CHECKBOX_HEIGHT - PUSHBUTTON STR_CONFIGURE, IDC_BUTTON_VOODOO, - CFG_COMBO_BTN_LEFT, 45, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - CONTROL STR_IBM8514, IDC_CHECK_IBM8514, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 66, 199, CFG_CHECKBOX_HEIGHT - - CONTROL STR_XGA, IDC_CHECK_XGA, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 85, 199, CFG_CHECKBOX_HEIGHT - PUSHBUTTON STR_CONFIGURE, IDC_BUTTON_XGA, - CFG_COMBO_BTN_LEFT, 84, CFG_BTN_WIDTH, CFG_BTN_HEIGHT -END - -DLG_CFG_INPUT DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT -STYLE DS_CONTROL | WS_CHILD -FONT FONT_SIZE, FONT_NAME -BEGIN - LTEXT STR_MOUSE, IDT_MOUSE, - CFG_HMARGIN, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_MOUSE, - CFG_COMBO_BOX_LEFT, 7, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_MOUSE, - CFG_COMBO_BTN_LEFT, 6, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_JOYSTICK, IDT_JOYSTICK, - CFG_HMARGIN, 27, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_JOYSTICK, - CFG_COMBO_BOX_LEFT, 25, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - PUSHBUTTON STR_JOY1, IDC_JOY1, - CFG_HMARGIN, 44, 84, CFG_BTN_HEIGHT - - PUSHBUTTON STR_JOY2, IDC_JOY2, - 96, 44, 84, CFG_BTN_HEIGHT - - PUSHBUTTON STR_JOY3, IDC_JOY3, - 187, 44, 84, CFG_BTN_HEIGHT - - PUSHBUTTON STR_JOY4, IDC_JOY4, - 277, 44, 84, CFG_BTN_HEIGHT -END - -DLG_CFG_SOUND DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT -STYLE DS_CONTROL | WS_CHILD -FONT FONT_SIZE, FONT_NAME -BEGIN - LTEXT STR_SOUND1, IDT_SOUND1, - CFG_HMARGIN, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_SOUND1, - CFG_COMBO_BOX_LEFT, 7, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SND1, - CFG_COMBO_BTN_LEFT, 6, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_SOUND2, IDT_SOUND2, - CFG_HMARGIN, 28, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_SOUND2, - CFG_COMBO_BOX_LEFT, 26, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SND2, - CFG_COMBO_BTN_LEFT, 25, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_SOUND3, IDT_SOUND3, - CFG_HMARGIN, 48, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_SOUND3, - CFG_COMBO_BOX_LEFT, 46, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SND3, - CFG_COMBO_BTN_LEFT, 45, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_SOUND4, IDT_SOUND4, - CFG_HMARGIN, 68, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_SOUND4, - CFG_COMBO_BOX_LEFT, 66, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SND4, - CFG_COMBO_BTN_LEFT, 65, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_MIDI_OUT, IDT_MIDI_OUT, - CFG_HMARGIN, 88, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_MIDI_OUT, - CFG_COMBO_BOX_LEFT, 86, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, - IDC_CONFIGURE_MIDI_OUT, - CFG_COMBO_BTN_LEFT, 85, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_MIDI_IN, IDT_MIDI_IN, - CFG_HMARGIN, 108, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_MIDI_IN, - CFG_COMBO_BOX_LEFT, 105, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_MIDI_IN, - CFG_COMBO_BTN_LEFT, 105, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - CONTROL STR_MPU401,IDC_CHECK_MPU401, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 126, 199, CFG_CHECKBOX_HEIGHT - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_MPU401, - CFG_COMBO_BTN_LEFT, 125, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - CONTROL STR_FLOAT, IDC_CHECK_FLOAT, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 138, 194, CFG_CHECKBOX_HEIGHT - - GROUPBOX STR_FM_DRIVER, IDC_FM_DRIVER, - CFG_HMARGIN, 154, 110, 42 - - CONTROL STR_FM_DRV_NUKED, IDC_RADIO_FM_DRV_NUKED, - "Button", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, - 14, 166, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_FM_DRV_YMFM, IDC_RADIO_FM_DRV_YMFM, - "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, - 14, 180, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT -END - -DLG_CFG_NETWORK DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT -STYLE DS_CONTROL | WS_CHILD -FONT FONT_SIZE, FONT_NAME -BEGIN - LTEXT STR_NET_TYPE, IDT_NET_TYPE, - CFG_HMARGIN, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - LTEXT STR_PCAP, IDT_PCAP, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH - 10, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - LTEXT STR_NET, IDT_NET, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH_2 + 20, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - - COMBOBOX IDC_COMBO_NET1_TYPE, - CFG_HMARGIN, 28, 48, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - COMBOBOX IDC_COMBO_PCAP1, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH - 10, 28, 110, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - COMBOBOX IDC_COMBO_NET1, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH_2 + 20, 28, 110, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_NET1, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH_3 + 50, 27, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - COMBOBOX IDC_COMBO_NET2_TYPE, - CFG_HMARGIN, 49, 48, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - COMBOBOX IDC_COMBO_PCAP2, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH - 10, 49, 110, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - COMBOBOX IDC_COMBO_NET2, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH_2 + 20, 49, 110, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_NET2, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH_3 + 50, 48, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - COMBOBOX IDC_COMBO_NET3_TYPE, - CFG_HMARGIN, 70, 48, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - COMBOBOX IDC_COMBO_PCAP3, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH - 10, 70, 110, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - COMBOBOX IDC_COMBO_NET3, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH_2 + 20, 70, 110, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_NET3, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH_3 + 50, 69, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - COMBOBOX IDC_COMBO_NET4_TYPE, - CFG_HMARGIN, 91, 48, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - COMBOBOX IDC_COMBO_PCAP4, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH - 10, 91, 110, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - COMBOBOX IDC_COMBO_NET4, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH_2 + 20, 91, 110, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_NET4, - CFG_HMARGIN + CFG_PANE_LTEXT_PRI_WIDTH_3 + 50, 90, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - -END - -DLG_CFG_PORTS DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT -STYLE DS_CONTROL | WS_CHILD -FONT FONT_SIZE, FONT_NAME -BEGIN -/* - LTEXT STR_COM1, IDT_COM1, - CFG_HMARGIN, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_COM1, - CFG_COMBO_BOX_LEFT, 7, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_COM2, IDT_COM2, - CFG_HMARGIN, 28, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_COM2, - CFG_COMBO_BOX_LEFT, 26, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_COM3, IDT_COM3, - CFG_HMARGIN, 47, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_COM3, - CFG_COMBO_BOX_LEFT, 45, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_COM4, IDT_COM4, - CFG_HMARGIN, 66, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_COM4, - CFG_COMBO_BOX_LEFT, 45, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP -*/ - - LTEXT STR_LPT1, IDT_LPT1, - CFG_HMARGIN, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_LPT1, - CFG_COMBO_BOX_LEFT, 7, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_LPT2, IDT_LPT2, - CFG_HMARGIN, 24, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_LPT2, - CFG_COMBO_BOX_LEFT, 22, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_LPT3, IDT_LPT3, - CFG_HMARGIN, 39, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_LPT3, - CFG_COMBO_BOX_LEFT, 37, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_LPT4, IDT_LPT4, - CFG_HMARGIN, 54, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_LPT4, - CFG_COMBO_BOX_LEFT, 52, CFG_COMBO_NOBTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - CONTROL STR_SERIAL1, IDC_CHECK_SERIAL1, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 71, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_SERIAL2, IDC_CHECK_SERIAL2, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 86, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_SERIAL3, IDC_CHECK_SERIAL3, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 101, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_SERIAL4, IDC_CHECK_SERIAL4, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 116, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_PARALLEL1, IDC_CHECK_PARALLEL1, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - 167, 71, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_PARALLEL2, IDC_CHECK_PARALLEL2, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - 167, 86, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_PARALLEL3, IDC_CHECK_PARALLEL3, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - 167, 101, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_PARALLEL4, IDC_CHECK_PARALLEL4, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - 167, 116, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_SERIAL_PASS1, IDC_CHECK_SERIAL_PASS1, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 134, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SERIAL_PASS1, - CFG_COMBO_BTN_LEFT, 131, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - CONTROL STR_SERIAL_PASS2, IDC_CHECK_SERIAL_PASS2, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 150, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SERIAL_PASS2, - CFG_COMBO_BTN_LEFT, 147, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - CONTROL STR_SERIAL_PASS3, IDC_CHECK_SERIAL_PASS3, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 165, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SERIAL_PASS3, - CFG_COMBO_BTN_LEFT, 162, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - CONTROL STR_SERIAL_PASS4, IDC_CHECK_SERIAL_PASS4, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 180, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SERIAL_PASS4, - CFG_COMBO_BTN_LEFT, 177, CFG_BTN_WIDTH, CFG_BTN_HEIGHT -END - -DLG_CFG_STORAGE DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT -STYLE DS_CONTROL | WS_CHILD -FONT FONT_SIZE, FONT_NAME -BEGIN - LTEXT STR_HDC, IDT_HDC, - CFG_HMARGIN, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_HDC, - CFG_COMBO_BOX_LEFT, 7, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_HDC, - CFG_COMBO_BTN_LEFT, 6, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_FDC, IDT_FDC, - CFG_HMARGIN, 28, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_FDC, - CFG_COMBO_BOX_LEFT, 26, CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_FDC, - CFG_COMBO_BTN_LEFT, 25, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - CONTROL STR_IDE_TER,IDC_CHECK_IDE_TER, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 47, 239, 10 - PUSHBUTTON STR_CONFIGURE, IDC_BUTTON_IDE_TER, - CFG_COMBO_BTN_LEFT, 45, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - CONTROL STR_IDE_QUA, IDC_CHECK_IDE_QUA, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 66, 239, 10 - PUSHBUTTON STR_CONFIGURE, IDC_BUTTON_IDE_QUA, - CFG_COMBO_BTN_LEFT, 64, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - GROUPBOX STR_SCSI, IDC_GROUP_SCSI, - CFG_HMARGIN, 85, CFG_SYSLISTVIEW32_WIDTH, 93 - - LTEXT STR_SCSI_1, IDT_SCSI_1, - 16, 102, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_SCSI_1, - CFG_COMBO_BOX_LEFT, 100, CFG_COMBO_BTN_WIDTH - 10, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SCSI_1, - CFG_COMBO_BTN_LEFT - 10, 99, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_SCSI_2, IDT_SCSI_2, - 16, 121, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_SCSI_2, - CFG_COMBO_BOX_LEFT, 119, CFG_COMBO_BTN_WIDTH - 10, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SCSI_2, - CFG_COMBO_BTN_LEFT - 10, 118, CFG_BTN_WIDTH,CFG_BTN_HEIGHT - - LTEXT STR_SCSI_3,IDT_SCSI_3, - 16, 140, 64, 10 - COMBOBOX IDC_COMBO_SCSI_3, - CFG_COMBO_BOX_LEFT, 138, CFG_COMBO_BTN_WIDTH - 10, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SCSI_3, - CFG_COMBO_BTN_LEFT - 10, 137, CFG_BTN_WIDTH,CFG_BTN_HEIGHT - - LTEXT STR_SCSI_4, IDT_SCSI_4, - 16, 159, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_SCSI_4, - CFG_COMBO_BOX_LEFT, 157, CFG_COMBO_BTN_WIDTH - 10, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_SCSI_4, - CFG_COMBO_BTN_LEFT - 10, 156, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - CONTROL STR_CASSETTE,IDC_CHECK_CASSETTE, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 185, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT -END - -DLG_CFG_HARD_DISKS DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT -STYLE DS_CONTROL | WS_CHILD -FONT FONT_SIZE, FONT_NAME -BEGIN - LTEXT STR_HDD, IDT_HDD, - CFG_HMARGIN, CFG_VMARGIN, 258, CFG_PANE_LTEXT_HEIGHT - CONTROL "List1", IDC_LIST_HARD_DISKS, - "SysListView32", - LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SINGLESEL | - WS_BORDER | WS_TABSTOP, - CFG_HMARGIN, 18, CFG_SYSLISTVIEW32_WIDTH, 162 - - LTEXT STR_BUS,IDT_BUS, - CFG_HMARGIN, 188, 24, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_HD_BUS, - 33, 186, 40, 12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - - LTEXT STR_CHANNEL, IDT_CHANNEL, - 91, 188, 38, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_HD_CHANNEL, - 131, 186, 40, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBO_HD_CHANNEL_IDE, - 131, 186, 40, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_ID, IDT_ID, - 91, 188, 38, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_HD_ID, - 131, 186, 70, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_SPEED, IDT_SPEED, - 201, 188, 38, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_HD_SPEED, - 241, 186, 70, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - PUSHBUTTON STR_NEW, IDC_BUTTON_HDD_ADD_NEW, - CFG_HMARGIN, 207, 112, CFG_BTN_HEIGHT - - PUSHBUTTON STR_EXISTING, IDC_BUTTON_HDD_ADD, - 128, 207, 112, CFG_BTN_HEIGHT - - PUSHBUTTON STR_REMOVE, IDC_BUTTON_HDD_REMOVE, - 249, 207, 112, CFG_BTN_HEIGHT - -END - -DLG_CFG_HARD_DISKS_ADD DIALOG DISCARDABLE 0, 0, 239, 151 -STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Add Hard Disk" -FONT FONT_SIZE, FONT_NAME -BEGIN - LTEXT STR_FILE_NAME, IDT_FILE_NAME, - 7, 7, 204, 12 - EDITTEXT IDC_EDIT_HD_FILE_NAME, - 7, 18, 173, 12 - PUSHBUTTON STR_SPECIFY, IDC_CFILE, - 187, 18, 44, CFG_BTN_HEIGHT - - LTEXT STR_CYLS, IDT_CYLS, - 7, 37, 42, 12 - EDITTEXT IDC_EDIT_HD_CYL, - 50, 36, 28, 12 - - LTEXT STR_HEADS, IDT_HEADS, - 86, 37, 29, 12 - EDITTEXT IDC_EDIT_HD_HPC, - 122, 36, 28, 12 - - LTEXT STR_SECTORS, IDT_SECTORS, - 164, 37, 33, 12 - EDITTEXT IDC_EDIT_HD_SPT, - 197, 36, 28, 12 - - LTEXT STR_SIZE_MB, IDT_SIZE_MB, - 7, 56, 48, 12 - EDITTEXT IDC_EDIT_HD_SIZE, - 50, 54, 28, 12 - - LTEXT STR_TYPE, IDT_TYPE, - 86, 56, 24, 12 - COMBOBOX IDC_COMBO_HD_TYPE, - 133, 54, 98, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_BUS,IDT_BUS, - 7, 75, 24, 12 - COMBOBOX IDC_COMBO_HD_BUS, - 43, 73, 58, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_CHANNEL, IDT_CHANNEL, - 109, 75, 34, 12 - COMBOBOX IDC_COMBO_HD_CHANNEL, - 144, 73, 87, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBO_HD_CHANNEL_IDE, - 144, 73, 87, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_ID, IDT_ID, - 109, 75, 34, 12 - COMBOBOX IDC_COMBO_HD_ID, - 144, 73, 87, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_IMG_FORMAT, IDT_IMG_FORMAT, - 7, 94, 70, 12 - COMBOBOX IDC_COMBO_HD_IMG_FORMAT, - 78, 92, 153, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_BLOCK_SIZE, IDT_BLOCK_SIZE, - 7, 113, 50, 12 - COMBOBOX IDC_COMBO_HD_BLOCK_SIZE, - 58, 111, 153, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_PROGRESS, IDT_PROGRESS, - 7, 7, 204, 12 - CONTROL "IMGCreateProgress", IDC_PBAR_IMG_CREATE, - "msctls_progress32", - PBS_SMOOTH | WS_BORDER, - 7, 16, 204, 12 - - DEFPUSHBUTTON STR_OK, IDOK, - 75, 129, 50, CFG_BTN_HEIGHT - PUSHBUTTON STR_CANCEL, IDCANCEL, - 132, 129, 50, CFG_BTN_HEIGHT -END - -DLG_CFG_FLOPPY_AND_CDROM_DRIVES DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT -STYLE DS_CONTROL | WS_CHILD -FONT FONT_SIZE, FONT_NAME -BEGIN - LTEXT STR_FLOPPY_DRIVES, IDT_FLOPPY_DRIVES, - CFG_HMARGIN, CFG_VMARGIN, 258, CFG_PANE_LTEXT_HEIGHT - CONTROL "List1", IDC_LIST_FLOPPY_DRIVES, - "SysListView32", - LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SINGLESEL | - WS_BORDER | WS_TABSTOP, - CFG_HMARGIN, 18, CFG_SYSLISTVIEW32_WIDTH, 60 - - LTEXT STR_TYPE, IDT_FDD_TYPE, - CFG_HMARGIN, 87, 24, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_FD_TYPE, - 33, 85, 140, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - CONTROL STR_TURBO, IDC_CHECKTURBO, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - 186, 86, 84, CFG_CHECKBOX_HEIGHT - - CONTROL STR_CHECKBPB, IDC_CHECKBPB, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - 272, 86, 84, CFG_CHECKBOX_HEIGHT - - LTEXT STR_CDROM_DRIVES, IDT_CD_DRIVES, - CFG_HMARGIN, 107, 258, CFG_PANE_LTEXT_HEIGHT - CONTROL "List1", IDC_LIST_CDROM_DRIVES, - "SysListView32", - LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SINGLESEL | - WS_BORDER | WS_TABSTOP, - CFG_HMARGIN, 117, CFG_SYSLISTVIEW32_WIDTH, 60 - - LTEXT STR_BUS, IDT_CD_BUS, - CFG_HMARGIN, 187, 24, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_CD_BUS, - 33, 185, 140, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_CHANNEL, IDT_CD_CHANNEL, - 181, 187, 38, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_CD_CHANNEL_IDE, - 221, 185, 140, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_ID, IDT_CD_ID, - 181, 187, 38, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_CD_ID, - 221, 185, 140, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_CD_SPEED, IDT_CD_SPEED, - CFG_HMARGIN, 207, 34, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_CD_SPEED, - 33, 205, 140, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_TYPE, IDT_CD_TYPE, - 181, 207, 34, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_CD_TYPE, - 221, 205, 140, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - -END - -DLG_CFG_OTHER_REMOVABLE_DEVICES DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT -STYLE DS_CONTROL | WS_CHILD -FONT FONT_SIZE, FONT_NAME -BEGIN - - LTEXT STR_MO_DRIVES, IDT_MO_DRIVES, - CFG_HMARGIN, CFG_VMARGIN, 258, CFG_PANE_LTEXT_HEIGHT - CONTROL "List1", IDC_LIST_MO_DRIVES, - "SysListView32", - LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SINGLESEL | - WS_BORDER | WS_TABSTOP, - CFG_HMARGIN, 17, CFG_SYSLISTVIEW32_WIDTH, 60 - - LTEXT STR_BUS, IDT_MO_BUS, - CFG_HMARGIN, 87, 24, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_MO_BUS, - 33, 85, 140, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_ID, IDT_MO_ID, - 181, 87, 38, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_MO_ID, - 221, 85, 140, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_CHANNEL, IDT_MO_CHANNEL, - 181, 87, 38, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_MO_CHANNEL_IDE, - 221, 85, 140, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_TYPE, IDT_MO_TYPE, - CFG_HMARGIN, 107, 24, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_MO_TYPE, - 33, 105, 328, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_ZIP_DRIVES, IDT_ZIP_DRIVES, - CFG_HMARGIN, 127, 258, CFG_PANE_LTEXT_HEIGHT - CONTROL "List1", IDC_LIST_ZIP_DRIVES, - "SysListView32", - LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SINGLESEL | - WS_BORDER | WS_TABSTOP, - CFG_HMARGIN, 137, CFG_SYSLISTVIEW32_WIDTH, 60 - - LTEXT STR_BUS, IDT_ZIP_BUS, - CFG_HMARGIN, 207, 24, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_ZIP_BUS, - 33, 205, 140, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_CHANNEL, IDT_ZIP_CHANNEL, - 181, 207, 38, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_ZIP_CHANNEL_IDE, - 221, 205, 105, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - LTEXT STR_ID, IDT_ZIP_ID, - 181, 207, 38, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_ZIP_ID, - 221, 205, 105, 12, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - CONTROL STR_250, IDC_CHECK250, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - 329, 206, 44, CFG_CHECKBOX_HEIGHT -END - -DLG_CFG_PERIPHERALS DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT -STYLE DS_CONTROL | WS_CHILD -FONT FONT_SIZE, FONT_NAME -BEGIN - LTEXT STR_ISARTC, IDT_ISARTC, - CFG_HMARGIN, CFG_VMARGIN, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_ISARTC, - CFG_COMBO_BOX_LEFT, 7,CFG_COMBO_BTN_WIDTH, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_ISARTC, - CFG_COMBO_BTN_LEFT, 6, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - GROUPBOX STR_ISAMEM, IDC_GROUP_ISAMEM, - CFG_HMARGIN, 28, CFG_SYSLISTVIEW32_WIDTH, 93 - - LTEXT STR_ISAMEM_1, IDT_ISAMEM_1, - 16, 45, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_ISAMEM_1, - CFG_COMBO_BOX_LEFT, 43, CFG_COMBO_BTN_WIDTH - 10, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_ISAMEM_1, - CFG_COMBO_BTN_LEFT - 10, 42, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_ISAMEM_2,IDT_ISAMEM_2, - 16, 64, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_ISAMEM_2, - CFG_COMBO_BOX_LEFT, 62, CFG_COMBO_BTN_WIDTH - 10, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_ISAMEM_2, - CFG_COMBO_BTN_LEFT - 10, 61, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_ISAMEM_3, IDT_ISAMEM_3, - 16, 83, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_ISAMEM_3, - CFG_COMBO_BOX_LEFT, 81, CFG_COMBO_BTN_WIDTH - 10, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_ISAMEM_3, - CFG_COMBO_BTN_LEFT - 10, 80, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - LTEXT STR_ISAMEM_4, IDT_ISAMEM_4, - 16, 102, CFG_PANE_LTEXT_PRI_WIDTH, CFG_PANE_LTEXT_HEIGHT - COMBOBOX IDC_COMBO_ISAMEM_4, - CFG_COMBO_BOX_LEFT, 100, CFG_COMBO_BTN_WIDTH - 10, CFG_COMBO_HEIGHT, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON STR_CONFIGURE, IDC_CONFIGURE_ISAMEM_4, - CFG_COMBO_BTN_LEFT - 10, 99, CFG_BTN_WIDTH, CFG_BTN_HEIGHT - - CONTROL STR_BUGGER, IDC_CHECK_BUGGER, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 128, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT - - CONTROL STR_POSTCARD,IDC_CHECK_POSTCARD, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - CFG_HMARGIN, 146, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT -END - -#undef CFG_CHECKBOX_PRI_WIDTH -#undef CFG_CHECKBOX_HEIGHT -#undef CFG_BTN_WIDTH -#undef CFG_BTN_HEIGHT -#undef CFG_PANE_LTEXT_PRI_WIDTH -#undef CFG_PANE_LTEXT_HEIGHT -#undef CFG_COMBO_BTN_WIDTH -#undef CFG_COMBO_NOBTN_WIDTH -#undef CFG_COMBO_BOX_LEFT -#undef CFG_COMBO_BTN_LEFT -#undef CFG_COMBO_HEIGHT -#undef CFG_LIST_WIDTH -#undef CFG_LIST_HEIGHT -#undef CFG_PANE_TOP -#undef CFG_PANE_LEFT -#undef CFG_PANE_WIDTH -#undef CFG_PANE_HEIGHT -#undef CFG_HMARGIN -#undef CFG_VMARGIN -#undef CFG_SYSLISTVIEW32_WIDTH - - -#undef STR_PREFERENCES -#undef STR_SND_GAIN -#undef STR_NEW_FLOPPY -#undef STR_CONFIG -#undef STR_SPECIFY_DIM - -#undef STR_OK -#undef STR_CANCEL -#undef STR_GLOBAL -#undef STR_DEFAULT -#undef STR_LANGUAGE -#undef STR_ICONSET - -#undef STR_GAIN - -#undef STR_FILE_NAME -#undef STR_DISK_SIZE -#undef STR_RPM_MODE -#undef STR_PROGRESS - -#undef STR_WIDTH -#undef STR_HEIGHT -#undef STR_LOCK_TO_SIZE - -#undef STR_MACHINE_TYPE -#undef STR_MACHINE -#undef STR_CONFIGURE -#undef STR_CPU_TYPE -#undef STR_CPU_SPEED -#undef STR_FPU -#undef STR_WAIT_STATES -#undef STR_MB -#undef STR_MEMORY -#undef STR_TIME_SYNC -#undef STR_DISABLED -#undef STR_ENABLED_LOCAL -#undef STR_ENABLED_UTC -#undef STR_DYNAREC -#undef STR_SOFTFLOAT - -#undef STR_VIDEO -#undef STR_VIDEO_2 -#undef STR_VOODOO -#undef STR_IBM8514 -#undef STR_XGA - -#undef STR_MOUSE -#undef STR_JOYSTICK -#undef STR_JOY1 -#undef STR_JOY2 -#undef STR_JOY3 -#undef STR_JOY4 - -#undef STR_SOUND1 -#undef STR_SOUND2 -#undef STR_SOUND3 -#undef STR_SOUND4 -#undef STR_MIDI_OUT -#undef STR_MIDI_IN -#undef STR_MPU401 -#undef STR_FLOAT -#undef STR_FM_DRIVER -#undef STR_FM_DRV_NUKED -#undef STR_FM_DRV_YMFM - -#undef STR_NET_TYPE -#undef STR_PCAP -#undef STR_NET -#undef STR_NET1 -#undef STR_NET2 -#undef STR_NET3 -#undef STR_NET4 - -#undef STR_COM1 -#undef STR_COM2 -#undef STR_COM3 -#undef STR_COM4 -#undef STR_LPT1 -#undef STR_LPT2 -#undef STR_LPT3 -#undef STR_LPT4 -#undef STR_SERIAL1 -#undef STR_SERIAL2 -#undef STR_SERIAL3 -#undef STR_SERIAL4 -#undef STR_PARALLEL1 -#undef STR_PARALLEL2 -#undef STR_PARALLEL3 -#undef STR_PARALLEL4 -#undef STR_SERIAL_PASS1 -#undef STR_SERIAL_PASS2 -#undef STR_SERIAL_PASS3 -#undef STR_SERIAL_PASS4 - -#undef STR_HDC -#undef STR_FDC -#undef STR_IDE_TER -#undef STR_IDE_QUA -#undef STR_SCSI -#undef STR_SCSI_1 -#undef STR_SCSI_2 -#undef STR_SCSI_3 -#undef STR_SCSI_4 -#undef STR_CASSETTE - -#undef STR_HDD -#undef STR_NEW -#undef STR_EXISTING -#undef STR_REMOVE -#undef STR_BUS -#undef STR_CHANNEL -#undef STR_ID -#undef STR_SPEED - -#undef STR_SPECIFY -#undef STR_SECTORS -#undef STR_HEADS -#undef STR_CYLS -#undef STR_SIZE_MB -#undef STR_TYPE -#undef STR_IMG_FORMAT -#undef STR_BLOCK_SIZE - -#undef STR_FLOPPY_DRIVES -#undef STR_TURBO -#undef STR_CHECKBPB -#undef STR_CDROM_DRIVES -#undef STR_CD_SPEED -#undef STR_EARLY - -#undef STR_MO_DRIVES -#undef STR_ZIP_DRIVES -#undef STR_250 - -#undef STR_ISARTC -#undef STR_ISAMEM -#undef STR_ISAMEM_1 -#undef STR_ISAMEM_2 -#undef STR_ISAMEM_3 -#undef STR_ISAMEM_4 -#undef STR_BUGGER -#undef STR_POSTCARD - -#undef FONT_SIZE -#undef FONT_NAME diff --git a/src/win/languages/en-GB.rc b/src/win/languages/en-GB.rc deleted file mode 100644 index a974b1862..000000000 --- a/src/win/languages/en-GB.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// English (U.K.) resources - -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Action" - BEGIN - MENUITEM "&Keyboard requires capture", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Right CTRL is left ALT", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Hard Reset...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Pause", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "E&xit...", IDM_ACTION_EXIT - END - POPUP "&View" - BEGIN - MENUITEM "&Hide status bar", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Resizeable window", IDM_VID_RESIZE - MENUITEM "R&emember size && position", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "Re&nderer" - BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "Specify dimensions...", IDM_VID_SPECIFY_DIM - MENUITEM "F&orce 4:3 display ratio", IDM_VID_FORCE43 - POPUP "&Window scale factor" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Filter method" - BEGIN - MENUITEM "&Nearest", IDM_VID_FILTER_NEAREST - MENUITEM "&Linear", IDM_VID_FILTER_LINEAR - END - MENUITEM "Hi&DPI scaling", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Fullscreen\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Fullscreen &stretch mode" - BEGIN - MENUITEM "&Full screen stretch", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Square pixels (Keep ratio)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Integer scale", IDM_VID_FS_INT - END - POPUP "E&GA/(S)VGA settings" - BEGIN - MENUITEM "&Inverted VGA monitor", IDM_VID_INVERT - POPUP "VGA screen &type" - BEGIN - MENUITEM "RGB &Colour", IDM_VID_GRAY_RGB - MENUITEM "&RGB Greyscale", IDM_VID_GRAY_MONO - MENUITEM "&Amber monitor", IDM_VID_GRAY_AMBER - MENUITEM "&Green monitor", IDM_VID_GRAY_GREEN - MENUITEM "&White monitor", IDM_VID_GRAY_WHITE - END - POPUP "Grayscale &conversion type" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Average", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/E&GA/(S)VGA overscan", IDM_VID_OVERSCAN - MENUITEM "Change contrast for &monochrome display", IDM_VID_CGACON - END - MENUITEM "&Media", IDM_MEDIA - POPUP "&Tools" - BEGIN - MENUITEM "&Settings...", IDM_CONFIG - MENUITEM "&Update status bar icons", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Take s&creenshot\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Preferences...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Enable &Discord integration", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "Sound &gain...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Begin trace\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "End trace\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Help" - BEGIN - MENUITEM "&Documentation...", IDM_DOCS - MENUITEM "&About 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&New image...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existing image...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Existing image (&Write-protected)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Record", IDM_CASSETTE_RECORD - MENUITEM "&Play", IDM_CASSETTE_PLAY - MENUITEM "&Rewind to the beginning", IDM_CASSETTE_REWIND - MENUITEM "&Fast forward to the end", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Image...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&New image...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existing image...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Existing image (&Write-protected)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&xport to 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Mute", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "E&mpty", IDM_CDROM_EMPTY - MENUITEM "&Reload previous image", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_IMAGE - MENUITEM "&Folder...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&New image...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existing image...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Existing image (&Write-protected)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_ZIP_EJECT - MENUITEM "&Reload previous image", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&New image...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existing image...", IDM_MO_IMAGE_EXISTING - MENUITEM "Existing image (&Write-protected)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_MO_EJECT - MENUITEM "&Reload previous image", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "Target &framerate" - BEGIN - MENUITEM "&Sync with video", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 fps", IDM_VID_GL_FPS_25 - MENUITEM "&30 fps", IDM_VID_GL_FPS_30 - MENUITEM "&50 fps", IDM_VID_GL_FPS_50 - MENUITEM "&60 fps", IDM_VID_GL_FPS_60 - MENUITEM "&75 fps", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Select shader...", IDM_VID_GL_SHADER - MENUITEM "&Remove shader", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Preferences" -#define STR_SND_GAIN "Sound Gain" -#define STR_NEW_FLOPPY "New Image" -#define STR_CONFIG "Settings" -#define STR_SPECIFY_DIM "Specify Main Window Dimensions" - -#define STR_OK "OK" -#define STR_CANCEL "Cancel" -#define STR_GLOBAL "Save these settings as &global defaults" -#define STR_DEFAULT "&Default" -#define STR_LANGUAGE "Language:" -#define STR_ICONSET "Icon set:" - -#define STR_GAIN "Gain" - -#define STR_FILE_NAME "File name:" -#define STR_DISK_SIZE "Disk size:" -#define STR_RPM_MODE "RPM mode:" -#define STR_PROGRESS "Progress:" - -#define STR_WIDTH "Width:" -#define STR_HEIGHT "Height:" -#define STR_LOCK_TO_SIZE "Lock to this size" - -#define STR_MACHINE_TYPE "Machine type:" -#define STR_MACHINE "Machine:" -#define STR_CONFIGURE "Configure" -#define STR_CPU_TYPE "CPU type:" -#define STR_CPU_SPEED "Speed:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Wait states:" -#define STR_MB "MB" -#define STR_MEMORY "Memory:" -#define STR_TIME_SYNC "Time synchronization" -#define STR_DISABLED "Disabled" -#define STR_ENABLED_LOCAL "Enabled (local time)" -#define STR_ENABLED_UTC "Enabled (UTC)" -#define STR_DYNAREC "Dynamic Recompiler" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Video:" -#define STR_VIDEO_2 "Video 2:" -#define STR_VOODOO "Voodoo Graphics" -#define STR_IBM8514 "IBM 8514/A Graphics" -#define STR_XGA "XGA Graphics" - -#define STR_MOUSE "Mouse:" -#define STR_JOYSTICK "Joystick:" -#define STR_JOY1 "Joystick 1..." -#define STR_JOY2 "Joystick 2..." -#define STR_JOY3 "Joystick 3..." -#define STR_JOY4 "Joystick 4..." - -#define STR_SOUND1 "Sound card #1:" -#define STR_SOUND2 "Sound card #2:" -#define STR_SOUND3 "Sound card #3:" -#define STR_SOUND4 "Sound card #4:" -#define STR_MIDI_OUT "MIDI Out Device:" -#define STR_MIDI_IN "MIDI In Device:" -#define STR_MPU401 "Standalone MPU-401" -#define STR_FLOAT "Use FLOAT32 sound" -#define STR_FM_DRIVER "FM synth driver" -#define STR_FM_DRV_NUKED "Nuked (more accurate)" -#define STR_FM_DRV_YMFM "YMFM (faster)" - -#define STR_NET_TYPE "Network type:" -#define STR_PCAP "PCap device:" -#define STR_NET "Network adapter:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "COM1 Device:" -#define STR_COM2 "COM2 Device:" -#define STR_COM3 "COM3 Device:" -#define STR_COM4 "COM4 Device:" -#define STR_LPT1 "LPT1 Device:" -#define STR_LPT2 "LPT2 Device:" -#define STR_LPT3 "LPT3 Device:" -#define STR_LPT4 "LPT4 Device:" -#define STR_SERIAL1 "Serial port 1" -#define STR_SERIAL2 "Serial port 2" -#define STR_SERIAL3 "Serial port 3" -#define STR_SERIAL4 "Serial port 4" -#define STR_PARALLEL1 "Parallel port 1" -#define STR_PARALLEL2 "Parallel port 2" -#define STR_PARALLEL3 "Parallel port 3" -#define STR_PARALLEL4 "Parallel port 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "HD Controller:" -#define STR_FDC "FD Controller:" -#define STR_IDE_TER "Tertiary IDE Controller" -#define STR_IDE_QUA "Quaternary IDE Controller" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Controller 1:" -#define STR_SCSI_2 "Controller 2:" -#define STR_SCSI_3 "Controller 3:" -#define STR_SCSI_4 "Controller 4:" -#define STR_CASSETTE "Cassette" - -#define STR_HDD "Hard disks:" -#define STR_NEW "&New..." -#define STR_EXISTING "&Existing..." -#define STR_REMOVE "&Remove" -#define STR_BUS "Bus:" -#define STR_CHANNEL "Channel:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Specify..." -#define STR_SECTORS "Sectors:" -#define STR_HEADS "Heads:" -#define STR_CYLS "Cylinders:" -#define STR_SIZE_MB "Size (MB):" -#define STR_TYPE "Type:" -#define STR_IMG_FORMAT "Image Format:" -#define STR_BLOCK_SIZE "Block Size:" - -#define STR_FLOPPY_DRIVES "Floppy drives:" -#define STR_TURBO "Turbo timings" -#define STR_CHECKBPB "Check BPB" -#define STR_CDROM_DRIVES "CD-ROM drives:" -#define STR_CD_SPEED "Speed:" - -#define STR_MO_DRIVES "MO drives:" -#define STR_ZIP_DRIVES "ZIP drives:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA RTC:" -#define STR_ISAMEM "ISA Memory Expansion" -#define STR_ISAMEM_1 "Card 1:" -#define STR_ISAMEM_2 "Card 2:" -#define STR_ISAMEM_3 "Card 3:" -#define STR_ISAMEM_4 "Card 4:" -#define STR_BUGGER "ISABugger device" -#define STR_POSTCARD "POST card" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Error" - IDS_2050 "Fatal error" - IDS_2051 " - PAUSED" - IDS_2052 "Press Ctrl+Alt+PgDn to return to windowed mode." - IDS_2053 "Speed" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIP images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the ""roms"" directory." - IDS_2057 "(empty)" - IDS_2058 "ZIP images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0All files (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "On" - IDS_2061 "Off" - IDS_2062 "All images (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Basic sector images (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Surface images (*.86F)\0*.86F\0" - IDS_2063 "Machine ""%hs"" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "Video card ""%hs"" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." - IDS_2065 "Machine" - IDS_2066 "Display" - IDS_2067 "Input devices" - IDS_2068 "Sound" - IDS_2069 "Network" - IDS_2070 "Ports (COM & LPT)" - IDS_2071 "Storage controllers" - IDS_2072 "Hard disks" - IDS_2073 "Floppy & CD-ROM drives" - IDS_2074 "Other removable devices" - IDS_2075 "Other peripherals" - IDS_2076 "Surface images (*.86F)\0*.86F\0" - IDS_2077 "Click to capture mouse" - IDS_2078 "Press F8+F12 to release mouse" - IDS_2079 "Press F8+F12 or middle button to release mouse" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Bus" - IDS_2082 "File" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "Check BPB" - IDS_2089 "KB" - IDS_2090 "Could not initialize the video renderer." - IDS_2091 "Default" - IDS_2092 "%i Wait state(s)" - IDS_2093 "Type" - IDS_2094 "Failed to set up PCap" - IDS_2095 "No PCap devices found" - IDS_2096 "Invalid PCap device" - IDS_2097 "Standard 2-button joystick(s)" - IDS_2098 "Standard 4-button joystick" - IDS_2099 "Standard 6-button joystick" - IDS_2100 "Standard 8-button joystick" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "None" - IDS_2105 "Unable to load keyboard accelerators." - IDS_2106 "Unable to register raw input." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Floppy %i (%s): %ls" - IDS_2110 "All images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2113 "Are you sure you want to hard reset the emulated machine?" - IDS_2114 "Are you sure you want to exit 86Box?" - IDS_2115 "Unable to initialize Ghostscript" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "MO images (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2118 "Welcome to 86Box!" - IDS_2119 "Internal controller" - IDS_2120 "Exit" - IDS_2121 "No ROMs found" - IDS_2122 "Do you want to save the settings?" - IDS_2123 "This will hard reset the emulated machine." - IDS_2124 "Save" - IDS_2125 "About 86Box" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." - IDS_2128 "OK" - IDS_2129 "Hardware not available" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Make sure " LIB_NAME_PCAP " is installed and that you are on a " LIB_NAME_PCAP "-compatible network connection." - IDS_2131 "Invalid configuration" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." - IDS_2135 "Entering fullscreen mode" - IDS_2136 "Don't show this message again" - IDS_2137 "Don't exit" - IDS_2138 "Reset" - IDS_2139 "Don't reset" - IDS_2140 "MO images (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2141 "CD-ROM images (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" - IDS_2142 "%hs Device Configuration" - IDS_2143 "Monitor in sleep mode" - IDS_2144 "OpenGL Shaders (*.GLSL)\0*.GLSL\0All files (*.*)\0*.*\0" - IDS_2145 "OpenGL options" - IDS_2146 "You are loading an unsupported configuration" - IDS_2147 "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." - IDS_2148 "Continue" - IDS_2149 "Cassette: %s" - IDS_2150 "Cassette images (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0All files (*.*)\0*.*\0" - IDS_2151 "Cartridge %i: %ls" - IDS_2152 "Cartridge images (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0All files (*.*)\0*.*\0" - IDS_2153 "Error initializing renderer" - IDS_2154 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." - IDS_2155 "Resume execution" - IDS_2156 "Pause execution" - IDS_2157 "Press Ctrl+Alt+Del" - IDS_2158 "Press Ctrl+Alt+Esc" - IDS_2159 "Hard reset" - IDS_2160 "ACPI shutdown" - IDS_2161 "Settings" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Hard disk (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLL or ESDI CD-ROM drives never existed" - IDS_4100 "Custom..." - IDS_4101 "Custom (large)..." - IDS_4102 "Add New Hard Disk" - IDS_4103 "Add Existing Hard Disk" - IDS_4104 "HDI disk images cannot be larger than 4 GB." - IDS_4105 "Disk images cannot be larger than 127 GB." - IDS_4106 "Hard disk images (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0All files (*.*)\0*.*\0" - IDS_4107 "Unable to read file" - IDS_4108 "Unable to write file" - IDS_4109 "HDI or HDX images with a sector size other than 512 are not supported." - IDS_4110 "USB is not yet supported" - IDS_4111 "Disk image file already exists" - IDS_4112 "Please specify a valid file name." - IDS_4113 "Disk image created" - IDS_4114 "Make sure the file exists and is readable." - IDS_4115 "Make sure the file is being saved to a writable directory." - IDS_4116 "Disk image too large" - IDS_4117 "Remember to partition and format the newly-created drive." - IDS_4118 "The selected file will be overwritten. Are you sure you want to use it?" - IDS_4119 "Unsupported disk image" - IDS_4120 "Overwrite" - IDS_4121 "Don't overwrite" - IDS_4122 "Raw image (.img)" - IDS_4123 "HDI image (.hdi)" - IDS_4124 "HDX image (.hdx)" - IDS_4125 "Fixed-size VHD (.vhd)" - IDS_4126 "Dynamic-size VHD (.vhd)" - IDS_4127 "Differencing VHD (.vhd)" - IDS_4128 "Large blocks (2 MB)" - IDS_4129 "Small blocks (512 KB)" - IDS_4130 "VHD files (*.VHD)\0*.VHD\0All files (*.*)\0*.*\0" - IDS_4131 "Select the parent VHD" - IDS_4132 "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" - IDS_4133 "Parent and child disk timestamps do not match" - IDS_4134 "Could not fix VHD timestamp." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Disabled" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Disabled" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (cluster 1024)" - IDS_5898 "DMF (cluster 2048)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "Perfect RPM" - IDS_6145 "1% below perfect RPM" - IDS_6146 "1.5% below perfect RPM" - IDS_6147 "2% below perfect RPM" - - IDS_7168 "(System Default)" -END -#define IDS_LANG_ENUS IDS_7168 - -// English (U.K.) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/en-US.rc b/src/win/languages/en-US.rc deleted file mode 100644 index c12fb4a45..000000000 --- a/src/win/languages/en-US.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Action" - BEGIN - MENUITEM "&Keyboard requires capture", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Right CTRL is left ALT", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Hard Reset...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Pause", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "E&xit...", IDM_ACTION_EXIT - END - POPUP "&View" - BEGIN - MENUITEM "&Hide status bar", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Resizeable window", IDM_VID_RESIZE - MENUITEM "R&emember size && position", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "Re&nderer" - BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "Specify dimensions...", IDM_VID_SPECIFY_DIM - MENUITEM "F&orce 4:3 display ratio", IDM_VID_FORCE43 - POPUP "&Window scale factor" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Filter method" - BEGIN - MENUITEM "&Nearest", IDM_VID_FILTER_NEAREST - MENUITEM "&Linear", IDM_VID_FILTER_LINEAR - END - MENUITEM "Hi&DPI scaling", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Fullscreen\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Fullscreen &stretch mode" - BEGIN - MENUITEM "&Full screen stretch", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Square pixels (Keep ratio)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Integer scale", IDM_VID_FS_INT - END - POPUP "E&GA/(S)VGA settings" - BEGIN - MENUITEM "&Inverted VGA monitor", IDM_VID_INVERT - POPUP "VGA screen &type" - BEGIN - MENUITEM "RGB &Color", IDM_VID_GRAY_RGB - MENUITEM "&RGB Grayscale", IDM_VID_GRAY_MONO - MENUITEM "&Amber monitor", IDM_VID_GRAY_AMBER - MENUITEM "&Green monitor", IDM_VID_GRAY_GREEN - MENUITEM "&White monitor", IDM_VID_GRAY_WHITE - END - POPUP "Grayscale &conversion type" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Average", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/E&GA/(S)VGA overscan", IDM_VID_OVERSCAN - MENUITEM "Change contrast for &monochrome display", IDM_VID_CGACON - END - MENUITEM "&Media", IDM_MEDIA - POPUP "&Tools" - BEGIN - MENUITEM "&Settings...", IDM_CONFIG - MENUITEM "&Update status bar icons", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Take s&creenshot\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Preferences...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Enable &Discord integration", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "Sound &gain...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Begin trace\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "End trace\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Help" - BEGIN - MENUITEM "&Documentation...", IDM_DOCS - MENUITEM "&About 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&New image...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existing image...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Existing image (&Write-protected)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Record", IDM_CASSETTE_RECORD - MENUITEM "&Play", IDM_CASSETTE_PLAY - MENUITEM "&Rewind to the beginning", IDM_CASSETTE_REWIND - MENUITEM "&Fast forward to the end", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Image...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&New image...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existing image...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Existing image (&Write-protected)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&xport to 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Mute", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "E&mpty", IDM_CDROM_EMPTY - MENUITEM "&Reload previous image", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_IMAGE - MENUITEM "&Folder...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&New image...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existing image...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Existing image (&Write-protected)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_ZIP_EJECT - MENUITEM "&Reload previous image", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&New image...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Existing image...", IDM_MO_IMAGE_EXISTING - MENUITEM "Existing image (&Write-protected)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_MO_EJECT - MENUITEM "&Reload previous image", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "Target &framerate" - BEGIN - MENUITEM "&Sync with video", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 fps", IDM_VID_GL_FPS_25 - MENUITEM "&30 fps", IDM_VID_GL_FPS_30 - MENUITEM "&50 fps", IDM_VID_GL_FPS_50 - MENUITEM "&60 fps", IDM_VID_GL_FPS_60 - MENUITEM "&75 fps", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Select shader...", IDM_VID_GL_SHADER - MENUITEM "&Remove shader", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Preferences" -#define STR_SND_GAIN "Sound Gain" -#define STR_NEW_FLOPPY "New Image" -#define STR_CONFIG "Settings" -#define STR_SPECIFY_DIM "Specify Main Window Dimensions" - -#define STR_OK "OK" -#define STR_CANCEL "Cancel" -#define STR_GLOBAL "Save these settings as &global defaults" -#define STR_DEFAULT "&Default" -#define STR_LANGUAGE "Language:" -#define STR_ICONSET "Icon set:" - -#define STR_GAIN "Gain" - -#define STR_FILE_NAME "File name:" -#define STR_DISK_SIZE "Disk size:" -#define STR_RPM_MODE "RPM mode:" -#define STR_PROGRESS "Progress:" - -#define STR_WIDTH "Width:" -#define STR_HEIGHT "Height:" -#define STR_LOCK_TO_SIZE "Lock to this size" - -#define STR_MACHINE_TYPE "Machine type:" -#define STR_MACHINE "Machine:" -#define STR_CONFIGURE "Configure" -#define STR_CPU_TYPE "CPU type:" -#define STR_CPU_SPEED "Speed:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Wait states:" -#define STR_MB "MB" -#define STR_MEMORY "Memory:" -#define STR_TIME_SYNC "Time synchronization" -#define STR_DISABLED "Disabled" -#define STR_ENABLED_LOCAL "Enabled (local time)" -#define STR_ENABLED_UTC "Enabled (UTC)" -#define STR_DYNAREC "Dynamic Recompiler" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Video:" -#define STR_VIDEO_2 "Video 2:" -#define STR_VOODOO "Voodoo Graphics" -#define STR_IBM8514 "IBM 8514/A Graphics" -#define STR_XGA "XGA Graphics" - -#define STR_MOUSE "Mouse:" -#define STR_JOYSTICK "Joystick:" -#define STR_JOY1 "Joystick 1..." -#define STR_JOY2 "Joystick 2..." -#define STR_JOY3 "Joystick 3..." -#define STR_JOY4 "Joystick 4..." - -#define STR_SOUND1 "Sound card #1:" -#define STR_SOUND2 "Sound card #2:" -#define STR_SOUND3 "Sound card #3:" -#define STR_SOUND4 "Sound card #4:" -#define STR_MIDI_OUT "MIDI Out Device:" -#define STR_MIDI_IN "MIDI In Device:" -#define STR_MPU401 "Standalone MPU-401" -#define STR_FLOAT "Use FLOAT32 sound" -#define STR_FM_DRIVER "FM synth driver" -#define STR_FM_DRV_NUKED "Nuked (more accurate)" -#define STR_FM_DRV_YMFM "YMFM (faster)" - -#define STR_NET_TYPE "Network type:" -#define STR_PCAP "PCap device:" -#define STR_NET "Network adapter:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "COM1 Device:" -#define STR_COM2 "COM2 Device:" -#define STR_COM3 "COM3 Device:" -#define STR_COM4 "COM4 Device:" -#define STR_LPT1 "LPT1 Device:" -#define STR_LPT2 "LPT2 Device:" -#define STR_LPT3 "LPT3 Device:" -#define STR_LPT4 "LPT4 Device:" -#define STR_SERIAL1 "Serial port 1" -#define STR_SERIAL2 "Serial port 2" -#define STR_SERIAL3 "Serial port 3" -#define STR_SERIAL4 "Serial port 4" -#define STR_PARALLEL1 "Parallel port 1" -#define STR_PARALLEL2 "Parallel port 2" -#define STR_PARALLEL3 "Parallel port 3" -#define STR_PARALLEL4 "Parallel port 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "HD Controller:" -#define STR_FDC "FD Controller:" -#define STR_IDE_TER "Tertiary IDE Controller" -#define STR_IDE_QUA "Quaternary IDE Controller" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Controller 1:" -#define STR_SCSI_2 "Controller 2:" -#define STR_SCSI_3 "Controller 3:" -#define STR_SCSI_4 "Controller 4:" -#define STR_CASSETTE "Cassette" - -#define STR_HDD "Hard disks:" -#define STR_NEW "&New..." -#define STR_EXISTING "&Existing..." -#define STR_REMOVE "&Remove" -#define STR_BUS "Bus:" -#define STR_CHANNEL "Channel:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Specify..." -#define STR_SECTORS "Sectors:" -#define STR_HEADS "Heads:" -#define STR_CYLS "Cylinders:" -#define STR_SIZE_MB "Size (MB):" -#define STR_TYPE "Type:" -#define STR_IMG_FORMAT "Image Format:" -#define STR_BLOCK_SIZE "Block Size:" - -#define STR_FLOPPY_DRIVES "Floppy drives:" -#define STR_TURBO "Turbo timings" -#define STR_CHECKBPB "Check BPB" -#define STR_CDROM_DRIVES "CD-ROM drives:" -#define STR_CD_SPEED "Speed:" - -#define STR_MO_DRIVES "MO drives:" -#define STR_ZIP_DRIVES "ZIP drives:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA RTC:" -#define STR_ISAMEM "ISA Memory Expansion" -#define STR_ISAMEM_1 "Card 1:" -#define STR_ISAMEM_2 "Card 2:" -#define STR_ISAMEM_3 "Card 3:" -#define STR_ISAMEM_4 "Card 4:" -#define STR_BUGGER "ISABugger device" -#define STR_POSTCARD "POST card" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Error" - IDS_2050 "Fatal error" - IDS_2051 " - PAUSED" - IDS_2052 "Press Ctrl+Alt+PgDn to return to windowed mode." - IDS_2053 "Speed" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIP images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the ""roms"" directory." - IDS_2057 "(empty)" - IDS_2058 "ZIP images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0All files (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "On" - IDS_2061 "Off" - IDS_2062 "All images (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Basic sector images (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Surface images (*.86F)\0*.86F\0" - IDS_2063 "Machine ""%hs"" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "Video card ""%hs"" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." - IDS_2065 "Machine" - IDS_2066 "Display" - IDS_2067 "Input devices" - IDS_2068 "Sound" - IDS_2069 "Network" - IDS_2070 "Ports (COM & LPT)" - IDS_2071 "Storage controllers" - IDS_2072 "Hard disks" - IDS_2073 "Floppy & CD-ROM drives" - IDS_2074 "Other removable devices" - IDS_2075 "Other peripherals" - IDS_2076 "Surface images (*.86F)\0*.86F\0" - IDS_2077 "Click to capture mouse" - IDS_2078 "Press F8+F12 to release mouse" - IDS_2079 "Press F8+F12 or middle button to release mouse" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Bus" - IDS_2082 "File" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "Check BPB" - IDS_2089 "KB" - IDS_2090 "Could not initialize the video renderer." - IDS_2091 "Default" - IDS_2092 "%i Wait state(s)" - IDS_2093 "Type" - IDS_2094 "Failed to set up PCap" - IDS_2095 "No PCap devices found" - IDS_2096 "Invalid PCap device" - IDS_2097 "Standard 2-button joystick(s)" - IDS_2098 "Standard 4-button joystick" - IDS_2099 "Standard 6-button joystick" - IDS_2100 "Standard 8-button joystick" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "None" - IDS_2105 "Unable to load keyboard accelerators." - IDS_2106 "Unable to register raw input." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Floppy %i (%s): %ls" - IDS_2110 "All images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2113 "Are you sure you want to hard reset the emulated machine?" - IDS_2114 "Are you sure you want to exit 86Box?" - IDS_2115 "Unable to initialize Ghostscript" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "MO images (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2118 "Welcome to 86Box!" - IDS_2119 "Internal controller" - IDS_2120 "Exit" - IDS_2121 "No ROMs found" - IDS_2122 "Do you want to save the settings?" - IDS_2123 "This will hard reset the emulated machine." - IDS_2124 "Save" - IDS_2125 "About 86Box" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." - IDS_2128 "OK" - IDS_2129 "Hardware not available" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Make sure " LIB_NAME_PCAP " is installed and that you are on a " LIB_NAME_PCAP "-compatible network connection." - IDS_2131 "Invalid configuration" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." - IDS_2135 "Entering fullscreen mode" - IDS_2136 "Don't show this message again" - IDS_2137 "Don't exit" - IDS_2138 "Reset" - IDS_2139 "Don't reset" - IDS_2140 "MO images (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2141 "CD-ROM images (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" - IDS_2142 "%hs Device Configuration" - IDS_2143 "Monitor in sleep mode" - IDS_2144 "OpenGL Shaders (*.GLSL)\0*.GLSL\0All files (*.*)\0*.*\0" - IDS_2145 "OpenGL options" - IDS_2146 "You are loading an unsupported configuration" - IDS_2147 "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." - IDS_2148 "Continue" - IDS_2149 "Cassette: %s" - IDS_2150 "Cassette images (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0All files (*.*)\0*.*\0" - IDS_2151 "Cartridge %i: %ls" - IDS_2152 "Cartridge images (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0All files (*.*)\0*.*\0" - IDS_2153 "Error initializing renderer" - IDS_2154 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." - IDS_2155 "Resume execution" - IDS_2156 "Pause execution" - IDS_2157 "Press Ctrl+Alt+Del" - IDS_2158 "Press Ctrl+Alt+Esc" - IDS_2159 "Hard reset" - IDS_2160 "ACPI shutdown" - IDS_2161 "Settings" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Hard disk (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLL or ESDI CD-ROM drives never existed" - IDS_4100 "Custom..." - IDS_4101 "Custom (large)..." - IDS_4102 "Add New Hard Disk" - IDS_4103 "Add Existing Hard Disk" - IDS_4104 "HDI disk images cannot be larger than 4 GB." - IDS_4105 "Disk images cannot be larger than 127 GB." - IDS_4106 "Hard disk images (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0All files (*.*)\0*.*\0" - IDS_4107 "Unable to read file" - IDS_4108 "Unable to write file" - IDS_4109 "HDI or HDX images with a sector size other than 512 are not supported." - IDS_4110 "USB is not yet supported" - IDS_4111 "Disk image file already exists" - IDS_4112 "Please specify a valid file name." - IDS_4113 "Disk image created" - IDS_4114 "Make sure the file exists and is readable." - IDS_4115 "Make sure the file is being saved to a writable directory." - IDS_4116 "Disk image too large" - IDS_4117 "Remember to partition and format the newly-created drive." - IDS_4118 "The selected file will be overwritten. Are you sure you want to use it?" - IDS_4119 "Unsupported disk image" - IDS_4120 "Overwrite" - IDS_4121 "Don't overwrite" - IDS_4122 "Raw image (.img)" - IDS_4123 "HDI image (.hdi)" - IDS_4124 "HDX image (.hdx)" - IDS_4125 "Fixed-size VHD (.vhd)" - IDS_4126 "Dynamic-size VHD (.vhd)" - IDS_4127 "Differencing VHD (.vhd)" - IDS_4128 "Large blocks (2 MB)" - IDS_4129 "Small blocks (512 KB)" - IDS_4130 "VHD files (*.VHD)\0*.VHD\0All files (*.*)\0*.*\0" - IDS_4131 "Select the parent VHD" - IDS_4132 "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" - IDS_4133 "Parent and child disk timestamps do not match" - IDS_4134 "Could not fix VHD timestamp." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Disabled" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Disabled" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (cluster 1024)" - IDS_5898 "DMF (cluster 2048)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "Perfect RPM" - IDS_6145 "1% below perfect RPM" - IDS_6146 "1.5% below perfect RPM" - IDS_6147 "2% below perfect RPM" - - IDS_7168 "(System Default)" -END -#define IDS_LANG_ENUS IDS_7168 - -// English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/es-ES.rc b/src/win/languages/es-ES.rc deleted file mode 100644 index 4888c09f4..000000000 --- a/src/win/languages/es-ES.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Spanish (Spain) resources - -#ifdef _WIN32 -LANGUAGE LANG_SPANISH, SUBLANG_SPANISH -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Acción" - BEGIN - MENUITEM "&Teclado requiere captura", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "CTRL &derecho es ALT izquierdo", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Hard Reset...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Pausa", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "&Salir...", IDM_ACTION_EXIT - END - POPUP "&Vista" - BEGIN - MENUITEM "&Ocultar barra de estado", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Ventana redimensionable", IDM_VID_RESIZE - MENUITEM "&Recordar tamaño y posición", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "Re&nderizador" - BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "E&specificar dimensiones...", IDM_VID_SPECIFY_DIM - MENUITEM "F&orzar ratio 4:3", IDM_VID_FORCE43 - POPUP "&Factor de escalado de ventana" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "&Método de filtrado" - BEGIN - MENUITEM "&Más cercano", IDM_VID_FILTER_NEAREST - MENUITEM "&Lineal", IDM_VID_FILTER_LINEAR - END - MENUITEM "&Escalado alta densidad", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Pantalla completa\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Escalado pantalla completa" - BEGIN - MENUITEM "&Estirar", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Píxeles cuadrados (Mant. aspecto)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Escalado valor entero", IDM_VID_FS_INT - END - POPUP "&Ajustes EGA/(S)VGA" - BEGIN - MENUITEM "&Monitor VGA invertido", IDM_VID_INVERT - POPUP "&Tipo de pantalla VGA" - BEGIN - MENUITEM "RGB &Color", IDM_VID_GRAY_RGB - MENUITEM "RGB &Grises", IDM_VID_GRAY_MONO - MENUITEM "Monitor &Ámbar", IDM_VID_GRAY_AMBER - MENUITEM "Monitor &Verde", IDM_VID_GRAY_GREEN - MENUITEM "Monitor &Blanco", IDM_VID_GRAY_WHITE - END - POPUP "&Conversión a grises" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Media", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "&Overscan CGA/PCjr/Tandy/EGA/(S)VGA", IDM_VID_OVERSCAN - MENUITEM "Cambiar contraste para pantalla &monocroma", IDM_VID_CGACON - END - MENUITEM "&Medios", IDM_MEDIA - POPUP "&Herramientas" - BEGIN - MENUITEM "&Ajustes...", IDM_CONFIG - MENUITEM "&Actualizar iconos en barra de estado", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Tomar c&aptura\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Preferencias...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Habilitar integración con &Discord", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Ganancia de sonido...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Comenzar traza\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Terminar traza\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Ayuda" - BEGIN - MENUITEM "&Documentación...", IDM_DOCS - MENUITEM "&Acerca de 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nueva imagen...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Imagen &Existente...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Imagen Existente (&Sólo-lectura)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Grabar", IDM_CASSETTE_RECORD - MENUITEM "&Reproducir", IDM_CASSETTE_PLAY - MENUITEM "&Rebobinar al inicio", IDM_CASSETTE_REWIND - MENUITEM "&Avance rápido al final", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "E&xtraer", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Imagen...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "E&xtraer", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nueva imagen...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Imagen &existente...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Imagen existente (&sólo-lectura)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&xportar a 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "E&xtraer", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Silenciar", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "E&xtraer disco", IDM_CDROM_EMPTY - MENUITEM "&Recargar imagen previa", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Imagen...", IDM_CDROM_IMAGE - MENUITEM "&Carpeta...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nueva imagen...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Imagen &existente...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Imagen existente (&sólo-lectura)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&xtraer", IDM_ZIP_EJECT - MENUITEM "&Recargar imagen previa", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nueva imagen...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Imagen &existente...", IDM_MO_IMAGE_EXISTING - MENUITEM "Imagen existente (&sólo-lectura)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&xtraer", IDM_MO_EJECT - MENUITEM "&Recargar imagen previa", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "&Tasa de refresco objetivo" - BEGIN - MENUITEM "&Sincronizar con vídeo", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 fps", IDM_VID_GL_FPS_25 - MENUITEM "&30 fps", IDM_VID_GL_FPS_30 - MENUITEM "&50 fps", IDM_VID_GL_FPS_50 - MENUITEM "&60 fps", IDM_VID_GL_FPS_60 - MENUITEM "&75 fps", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Seleccionar shader...", IDM_VID_GL_SHADER - MENUITEM "&Eliminar shader", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Preferencias" -#define STR_SND_GAIN "Ganancia de Sonido" -#define STR_NEW_FLOPPY "Nueva Imagen" -#define STR_CONFIG "Ajustes" -#define STR_SPECIFY_DIM "Especificar Dimensiones de la Ventana Principal" - -#define STR_OK "Aceptar" -#define STR_CANCEL "Cancelar" -#define STR_GLOBAL "Salvar estos ajustes como por &defecto globalmente" -#define STR_DEFAULT "&Por defecto" -#define STR_LANGUAGE "Idioma:" -#define STR_ICONSET "Juego de iconos:" - -#define STR_GAIN "Ganancia" - -#define STR_FILE_NAME "Nombre de archivo:" -#define STR_DISK_SIZE "Tamaño de disco:" -#define STR_RPM_MODE "Modo RPM:" -#define STR_PROGRESS "Progreso:" - -#define STR_WIDTH "Ancho:" -#define STR_HEIGHT "Alto:" -#define STR_LOCK_TO_SIZE "Bloquear a este tamaño" - -#define STR_MACHINE_TYPE "Tipo de máquina:" -#define STR_MACHINE "Máquina:" -#define STR_CONFIGURE "Configurar" -#define STR_CPU_TYPE "Tipo de CPU:" -#define STR_CPU_SPEED "Velocidad:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Estados en espera:" -#define STR_MB "MB" -#define STR_MEMORY "Memoria:" -#define STR_TIME_SYNC "Sincronización horaria" -#define STR_DISABLED "Deshabilitado" -#define STR_ENABLED_LOCAL "Habilitado (hora local)" -#define STR_ENABLED_UTC "Habilitado (UTC)" -#define STR_DYNAREC "Recompilador Dinámico" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Vídeo:" -#define STR_VIDEO_2 "Vídeo 2:" -#define STR_VOODOO "Voodoo Graphics" -#define STR_IBM8514 "IBM 8514/A Graphics" -#define STR_XGA "XGA Graphics" - -#define STR_MOUSE "Ratón:" -#define STR_JOYSTICK "Mando:" -#define STR_JOY1 "Mando 1..." -#define STR_JOY2 "Mando 2..." -#define STR_JOY3 "Mando 3..." -#define STR_JOY4 "Mando 4..." - -#define STR_SOUND1 "Tarjeta de sonido 1:" -#define STR_SOUND2 "Tarjeta de sonido 2:" -#define STR_SOUND3 "Tarjeta de sonido 3:" -#define STR_SOUND4 "Tarjeta de sonido 4:" -#define STR_MIDI_OUT "Dispositivo MIDI de salida:" -#define STR_MIDI_IN "Dispositivo MIDI de entrada:" -#define STR_MPU401 "MPU-401 independiente" -#define STR_FLOAT "Usar sonido FLOAT32" -#define STR_FM_DRIVER "Controlador de sintet. FM" -#define STR_FM_DRV_NUKED "Nuked (más preciso)" -#define STR_FM_DRV_YMFM "YMFM (más rápido)" - -#define STR_NET_TYPE "Tipo de red:" -#define STR_PCAP "Dispositivo PCap:" -#define STR_NET "Adaptador de red:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "Dispositivo COM1:" -#define STR_COM2 "Dispositivo COM2:" -#define STR_COM3 "Dispositivo COM3:" -#define STR_COM4 "Dispositivo COM4:" -#define STR_LPT1 "Dispositivo LPT1:" -#define STR_LPT2 "Dispositivo LPT2:" -#define STR_LPT3 "Dispositivo LPT3:" -#define STR_LPT4 "Dispositivo LPT4:" -#define STR_SERIAL1 "Puerto serie 1" -#define STR_SERIAL2 "Puerto serie 2" -#define STR_SERIAL3 "Puerto serie 3" -#define STR_SERIAL4 "Puerto serie 4" -#define STR_PARALLEL1 "Puerto paralelo 1" -#define STR_PARALLEL2 "Puerto paralelo 2" -#define STR_PARALLEL3 "Puerto paralelo 3" -#define STR_PARALLEL4 "Puerto paralelo 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Controladora HD:" -#define STR_FDC "Controladora FD:" -#define STR_IDE_TER "Tercera controladora IDE" -#define STR_IDE_QUA "Cuarta controladora IDE" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Controladora 1:" -#define STR_SCSI_2 "Controladora 2:" -#define STR_SCSI_3 "Controladora 3:" -#define STR_SCSI_4 "Controladora 4:" -#define STR_CASSETTE "Cassette" - -#define STR_HDD "Discos duros:" -#define STR_NEW "&Nuevo..." -#define STR_EXISTING "&Existente..." -#define STR_REMOVE "E&liminar" -#define STR_BUS "Bus:" -#define STR_CHANNEL "Canal:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "E&specificar..." -#define STR_SECTORS "Sectores:" -#define STR_HEADS "Cabezas:" -#define STR_CYLS "Cilindros:" -#define STR_SIZE_MB "Tamaño (MB):" -#define STR_TYPE "Tipo:" -#define STR_IMG_FORMAT "Formato de imagen:" -#define STR_BLOCK_SIZE "Tamaño de bloque:" - -#define STR_FLOPPY_DRIVES "Unidades de disquete:" -#define STR_TURBO "Temporizaciones Turbo" -#define STR_CHECKBPB "Chequear BPB" -#define STR_CDROM_DRIVES "Unidades de CD-ROM:" -#define STR_CD_SPEED "Velocidad:" - -#define STR_MO_DRIVES "Unidades MO:" -#define STR_ZIP_DRIVES "Unidades ZIP:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA RTC:" -#define STR_ISAMEM "Expansión de Memoria ISA" -#define STR_ISAMEM_1 "Tarjeta 1:" -#define STR_ISAMEM_2 "Tarjeta 2:" -#define STR_ISAMEM_3 "Tarjeta 3:" -#define STR_ISAMEM_4 "Tarjeta 4:" -#define STR_BUGGER "Dispositivo ISABugger" -#define STR_POSTCARD "Tarjeta POST" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Error" - IDS_2050 "Error fatal" - IDS_2051 " - PAUSED" - IDS_2052 "Pulsa Ctrl+Alt+PgDn para volver a modo ventana." - IDS_2053 "Velocidad" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "Imagenes ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box no pudo encontrar ninguna imagen ROM usable.\n\nPor favor descarga un grupo de imágenes y extráelas en el directorio ""roms""." - IDS_2057 "(vacío)" - IDS_2058 "Imagenes ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0All files (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "On" - IDS_2061 "Off" - IDS_2062 "Todas las imagenes (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Basic sector images (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Surface images (*.86F)\0*.86F\0" - IDS_2063 "La máquina ""%hs"" no está disponible debido a ROMs faltantes en el directorio roms/machines. Cambiando a una máquina disponible." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "La tarjeta de vídeo ""%hs"" no está disponible debido a ROMs faltantes en el directorio roms/machines. Cambiando a una tarjeta de vídeo disponible." - IDS_2065 "Máquina" - IDS_2066 "Vídeo" - IDS_2067 "Dispositivos de Entrada" - IDS_2068 "Sonido" - IDS_2069 "Red" - IDS_2070 "Puertos (COM y LPT)" - IDS_2071 "Controladoras de Almacenamiento" - IDS_2072 "Discos Duros" - IDS_2073 "Disquetes y unidades de CD-ROM" - IDS_2074 "Otros dispositivos extraíbles" - IDS_2075 "Otros periféricos" - IDS_2076 "Imágenes de superficie (*.86F)\0*.86F\0" - IDS_2077 "Haz click para capturar el ratón" - IDS_2078 "Pulsa F8+F12 para liberar el ratón" - IDS_2079 "Pulsa F8+F12 o el botón central para liberar el ratón" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Bus" - IDS_2082 "Archivo" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "Chequear BPB" - IDS_2089 "KB" - IDS_2090 "Incapaz de inicializar el renderizador de vídeo." - IDS_2091 "Por defecto" - IDS_2092 "%i estado(s) de Espera" - IDS_2093 "Tipo" - IDS_2094 "Incapaz de configurar PCap" - IDS_2095 "No se encontraron dispositivos PCap" - IDS_2096 "Dispositivo PCap inválido" - IDS_2097 "Mando(s) de 2 botones estándar" - IDS_2098 "Mando de 4 botones estándar" - IDS_2099 "Mando de 6 botones estándar" - IDS_2100 "Mando de 8 botones estándar" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "Ninguno" - IDS_2105 "Incapaz de cargar aceleradores de teclado." - IDS_2106 "Incapaz de registrar entrada directa." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Disquete %i (%s): %ls" - IDS_2110 "Todas las Imágenes (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2113 "¿Seguro que quieres resetear la máquina emulada?" - IDS_2114 "¿Seguro que quieres cerrar 86Box?" - IDS_2115 "Incapaz de inicializar Ghostscript" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "Imágenes de MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2118 "¡Bienvenido a 86Box!" - IDS_2119 "Controladora interna" - IDS_2120 "Salir" - IDS_2121 "No se encontraron ROMs" - IDS_2122 "¿Quieres guardar los ajustes?" - IDS_2123 "Se hará hard reset de la máquina emulada." - IDS_2124 "Guardar" - IDS_2125 "Acerca de 86Box" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "Un emulador de ordenadores antigüos\n\nAutores: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, y otros.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, y otros.\n\nLiberado bajo la GNU General Public License versión 2 o posterior. Ver LICENSE para más información." - IDS_2128 "Aceptar" - IDS_2129 "Hardware no disponible" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Asegúrate de que " LIB_NAME_PCAP " está instalado y de que estás en una conexión de red compatible con " LIB_NAME_PCAP "." - IDS_2131 "Configuración inválida" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " es necesaria para la conversión automática de archivos PostScript a PDF.\n\nCualquier documento enviado a la impresora genérica postScript se guardará como archivo PostScript (.ps)." - IDS_2135 "Entrando en modo pantalla completa" - IDS_2136 "No mostrar más este mensaje" - IDS_2137 "No salir" - IDS_2138 "Resetear" - IDS_2139 "No resetear" - IDS_2140 "Imágenes de MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2141 "Imágenes de CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" - IDS_2142 "%hs Configuración de Dispositivo" - IDS_2143 "Monitor en modo ahorro" - IDS_2144 "Shaders OpenGL (*.GLSL)\0*.GLSL\0All files (*.*)\0*.*\0" - IDS_2145 "Opciones OpenGL" - IDS_2146 "Estás cargando una configuración no soportada" - IDS_2147 "El Filtrado de tipo de CPU basado en máquina seleccionada está deshabilitado para la esta máquina.\n\nEsto hace posible seleccionar una CPU que sea incompatible con esta máquina. Por ello, pueden aparecer incompatibilidader con la BIOS de la máquina u otro software.\n\nActivar este ajuste no está oficialmente soportado y cualquier reporte de fallo puede ser cerrado como inválido." - IDS_2148 "Continuar" - IDS_2149 "Cassette: %s" - IDS_2150 "Imágenes de Cassette (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0All files (*.*)\0*.*\0" - IDS_2151 "Cartucho %i: %ls" - IDS_2152 "Imágenes de Cartucho (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0All files (*.*)\0*.*\0" - IDS_2153 "Error initializing renderer" - IDS_2154 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." - IDS_2155 "Resume execution" - IDS_2156 "Pause execution" - IDS_2157 "Press Ctrl+Alt+Del" - IDS_2158 "Press Ctrl+Alt+Esc" - IDS_2159 "Hard reset" - IDS_2160 "ACPI shutdown" - IDS_2161 "Settings" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Disco duro (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "Nunca hubo unidades de CD-ROM MFM/RLL o ESDI" - IDS_4100 "A medida..." - IDS_4101 "A medida (grande)..." - IDS_4102 "Añadir Nuevo Disco Duro" - IDS_4103 "Añadir Disco Duro Existente" - IDS_4104 "Las imágenes de disco HDI no pueden superar los 4 GB." - IDS_4105 "Las imágenes de disco no pueden superar los 127 GB." - IDS_4106 "Imágenes de Disco Duro (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0All files (*.*)\0*.*\0" - IDS_4107 "No se pudo leer el archivo" - IDS_4108 "No se pudo escribir el archivo" - IDS_4109 "No se soportan las imágenes HDI o HDX con un tamaño de sector diferente a 512." - IDS_4110 "No se soporta aún el USB" - IDS_4111 "La imagen de disco ya existe" - IDS_4112 "Por favor especifique un nombre de archivo válido." - IDS_4113 "Imagen de disco creada" - IDS_4114 "Asegúrese de que el archivo existe y es leíble." - IDS_4115 "Asegúrese de que el archivo en un directorio con permiso de escritura." - IDS_4116 "Imagen de disco demasiado grande" - IDS_4117 "Recuerde particionar y formatear la nueva unidad." - IDS_4118 "El archivo selecionado será sobreescrito. ¿Está seguro de querer usarlo?" - IDS_4119 "Imagen de disco no soportada" - IDS_4120 "Sobreescribir" - IDS_4121 "No sobreescribir" - IDS_4122 "Imagen plana (.img)" - IDS_4123 "Imagen HDI (.hdi)" - IDS_4124 "Imagen HDX (.hdx)" - IDS_4125 "VHD de tamaño fijo (.vhd)" - IDS_4126 "VHD de tamaño dinámico (.vhd)" - IDS_4127 "VHD diferencial (.vhd)" - IDS_4128 "Bloques grandes (2 MB)" - IDS_4129 "Bloques pequeños (512 KB)" - IDS_4130 "Archivos VHD (*.VHD)\0*.VHD\0All files (*.*)\0*.*\0" - IDS_4131 "Seleccione el VHD padre" - IDS_4132 "Esto puede deberse a que la imagen padre se modificó después de que la imagen diferencial se crease.\n\nTambién puede ocurrir si las imágenes fueron movidas o copiadas, o por un fallo en el programa que creó este disco.\n\n¿Quiere corregir los registros de tiempo?" - IDS_4133 "Las marcas de tiempo del padre e hijo no coinciden" - IDS_4134 "No se pudo corregir la marca de tiempo del VHD." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Deshabilitado" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Deshabilitado" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (cluster 1024)" - IDS_5898 "DMF (cluster 2048)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "RPM perfectas" - IDS_6145 "1% por debajo de RPM perfectas" - IDS_6146 "1.5% por debajo de RPM perfectas" - IDS_6147 "2% por debajo de RPM perfectas" - - IDS_7168 "(Por defecto del sistema)" -END -#define IDS_LANG_ESES IDS_7168 - -// Spanish (Spain) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/fi-FI.rc b/src/win/languages/fi-FI.rc deleted file mode 100644 index 029cce6c0..000000000 --- a/src/win/languages/fi-FI.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Finnish resources - -#ifdef _WIN32 -LANGUAGE LANG_FINNISH, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Toiminto" - BEGIN - MENUITEM "&Vaadi näppäimistön kaappaus", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Oikea CTRL on vasen ALT", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Uudelleenkäynnistys (kylmä)...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Tauko", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "&Poistu...", IDM_ACTION_EXIT - END - POPUP "&Näytä" - BEGIN - MENUITEM "&Piilota tilapalkki", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Piilota &työkalupalkki", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Salli koon muuttaminen", IDM_VID_RESIZE - MENUITEM "&Muista koko ja sijainti", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "&Renderöijä" - BEGIN - MENUITEM "&SDL (ohjelmistopohjainen)", IDM_VID_SDL_SW - MENUITEM "SDL (&laitteistokiihdytetty)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "&Määritä koko...", IDM_VID_SPECIFY_DIM - MENUITEM "Pakota 4:3-näyttösuhde", IDM_VID_FORCE43 - POPUP "&Ikkunan kokokerroin" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "&Suodatusmetodi" - BEGIN - MENUITEM "&Lähin naapuri", IDM_VID_FILTER_NEAREST - MENUITEM "Li&neaarinen interpolaatio", IDM_VID_FILTER_LINEAR - END - MENUITEM "&Suuri DPI-skaalaus", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Koko näytön tila\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Koko näytön &skaalaustila" - BEGIN - MENUITEM "&Venytä koko näyttöön", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Tasasivuiset kuvapisteet (säilytä kuvasuhde)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Kokonaislukuskaalaus", IDM_VID_FS_INT - END - POPUP "&EGA/(S)VGA-asetukset" - BEGIN - MENUITEM "&VGA-näyttö käänteisillä väreillä", IDM_VID_INVERT - POPUP "VGA-näytön &tyyppi" - BEGIN - MENUITEM "RGB, &värit", IDM_VID_GRAY_RGB - MENUITEM "&RGB, harmaasävy", IDM_VID_GRAY_MONO - MENUITEM "&Meripihkanvärinen", IDM_VID_GRAY_AMBER - MENUITEM "V&ihreä", IDM_VID_GRAY_GREEN - MENUITEM "V&alkoinen", IDM_VID_GRAY_WHITE - END - POPUP "&Harmaasävymuunnoksen tyyppi" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Keskiarvo", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/E&GA/(S)VGA &yliskannaus", IDM_VID_OVERSCAN - MENUITEM "&Muuta harmaavärinäytön kontrastia", IDM_VID_CGACON - END - MENUITEM "&Media", IDM_MEDIA - POPUP "Työ&kalut" - BEGIN - MENUITEM "&Kokoonpano...", IDM_CONFIG - MENUITEM "&Päivitä tilapalkin kuvakkeita", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Ota &kuvakaappaus\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Sovellusasetukset...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Käytä &Discord-integraatiota", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Äänitasot...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Aloita jäljitys\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Lopeta jäljitys\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Ohje" - BEGIN - MENUITEM "&Ohjekirja...", IDM_DOCS - MENUITEM "&Tietoja 86Boxista...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Uusi kasettikuva...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Olemassaoleva kasettikuva...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Olemassaoleva kasettikuva (&kirjoitussuojattu)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Nauhoita", IDM_CASSETTE_RECORD - MENUITEM "&Toista", IDM_CASSETTE_PLAY - MENUITEM "Kelaa &alkuun", IDM_CASSETTE_REWIND - MENUITEM "Kelaa &loppuun", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "&Poista kasettipesästä", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&ROM-moduulikuva...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "&Irrota", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Uusi levykekuva...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Olemassaoleva levykekuva...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Olemassaoleva levykekuva (&kirjoitussuojattu)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Vie 86F-tiedostoon...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "&Poista asemasta", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Mykistä", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "&Tyhjä", IDM_CDROM_EMPTY - MENUITEM "&Lataa edellinen levykuva uudelleen", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "L&evykuva...", IDM_CDROM_IMAGE - MENUITEM "&Kansio...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Uusi levykuva...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Olemassaoleva levykuva...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Olemassaoleva levykuva (&kirjoitussuojattu)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Poista asemasta", IDM_ZIP_EJECT - MENUITEM "&Lataa edellinen levykuva uudelleen", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Uusi levykuva...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Olemassaoleva levykuva...", IDM_MO_IMAGE_EXISTING - MENUITEM "Olemassaoleva levykuva (&kirjoitussuojattu)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Poista asemasta", IDM_MO_EJECT - MENUITEM "&Lataa edellinen levykuva uudelleen", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "&Kuvataajuustavoite" - BEGIN - MENUITEM "&Synkronisoi videoon", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 ruutua/s", IDM_VID_GL_FPS_25 - MENUITEM "&30 ruutua/s", IDM_VID_GL_FPS_30 - MENUITEM "&50 ruutua/s", IDM_VID_GL_FPS_50 - MENUITEM "&60 ruutua/s", IDM_VID_GL_FPS_60 - MENUITEM "&75 ruutua/s", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "Valitse varjostin&ohjelma...", IDM_VID_GL_SHADER - MENUITEM "&Poista varjostinohjelma", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Sovellusasetukset" -#define STR_SND_GAIN "Äänen taso" -#define STR_NEW_FLOPPY "Uusi levykuva" -#define STR_CONFIG "Kokoonpano" -#define STR_SPECIFY_DIM "Määritä pääikkunan koko" - -#define STR_OK "OK" -#define STR_CANCEL "Peruuta" -#define STR_GLOBAL "Tallenna nämä asetukset &globaaleiksi oletuksiksi" -#define STR_DEFAULT "&Oletus" -#define STR_LANGUAGE "Kieli:" -#define STR_ICONSET "Kuvakkeet:" - -#define STR_GAIN "Taso" - -#define STR_FILE_NAME "Tiedostonimi:" -#define STR_DISK_SIZE "Levyn koko:" -#define STR_RPM_MODE "Kierroslukutila:" -#define STR_PROGRESS "Edistyminen:" - -#define STR_WIDTH "Leveys:" -#define STR_HEIGHT "Korkeus:" -#define STR_LOCK_TO_SIZE "Lukitse tähän kokoon" - -#define STR_MACHINE_TYPE "Tietokoneen tyyppi:" -#define STR_MACHINE "Tietokone:" -#define STR_CONFIGURE "Määritys" -#define STR_CPU_TYPE "Suorittimen tyyppi:" -#define STR_CPU_SPEED "Nopeus:" -#define STR_FPU "Apusuoritin:" -#define STR_WAIT_STATES "Odotustilat:" -#define STR_MB "Mt" -#define STR_MEMORY "Muisti:" -#define STR_TIME_SYNC "Kellon synkronointi" -#define STR_DISABLED "Ei käytössä" -#define STR_ENABLED_LOCAL "Käytössä (paikallinen)" -#define STR_ENABLED_UTC "Käytössä (UTC)" -#define STR_DYNAREC "Dynaaminen uudelleenkääntäjä" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Näytönohjain:" -#define STR_VIDEO_2 "Näytönohjain 2:" -#define STR_VOODOO "Voodoo-grafiikkasuoritin" -#define STR_IBM8514 "IBM 8514/A-grafiikkasuoritin" -#define STR_XGA "XGA-grafiikkasuoritin" - -#define STR_MOUSE "Hiiri:" -#define STR_JOYSTICK "Peliohjain:" -#define STR_JOY1 "Peliohjain 1..." -#define STR_JOY2 "Peliohjain 2..." -#define STR_JOY3 "Peliohjain 3..." -#define STR_JOY4 "Peliohjain 4..." - -#define STR_SOUND1 "Äänikortti 1:" -#define STR_SOUND2 "Äänikortti 2:" -#define STR_SOUND3 "Äänikortti 3:" -#define STR_SOUND4 "Äänikortti 4:" -#define STR_MIDI_OUT "MIDI-ulostulo:" -#define STR_MIDI_IN "MIDI-sisääntulo:" -#define STR_MPU401 "Erillinen MPU-401" -#define STR_FLOAT "Käytä FLOAT32-ääntä" -#define STR_FM_DRIVER "FM-syntetisaattoriohjain" -#define STR_FM_DRV_NUKED "Nuked (tarkempi)" -#define STR_FM_DRV_YMFM "YMFM (nopeampi)" - -#define STR_NET_TYPE "Verkon tyyppi:" -#define STR_PCAP "PCap-laite:" -#define STR_NET "Verkkokortti:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "COM1-laite:" -#define STR_COM2 "COM2-laite:" -#define STR_COM3 "COM3-laite:" -#define STR_COM4 "COM4-laite:" -#define STR_LPT1 "LPT1-laite:" -#define STR_LPT2 "LPT2-laite:" -#define STR_LPT3 "LPT3-laite:" -#define STR_LPT4 "LPT4-laite:" -#define STR_SERIAL1 "Sarjaportti 1" -#define STR_SERIAL2 "Sarjaportti 2" -#define STR_SERIAL3 "Sarjaportti 3" -#define STR_SERIAL4 "Sarjaportti 4" -#define STR_PARALLEL1 "Rinnakkaisportti 1" -#define STR_PARALLEL2 "Rinnakkaisportti 2" -#define STR_PARALLEL3 "Rinnakkaisportti 3" -#define STR_PARALLEL4 "Rinnakkaisportti 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Kiintolevyohjain:" -#define STR_FDC "Levykeohjain:" -#define STR_IDE_TER "Kolmas IDE-ohjain" -#define STR_IDE_QUA "Neljäs IDE-ohjain" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Ohjain 1:" -#define STR_SCSI_2 "Ohjain 2:" -#define STR_SCSI_3 "Ohjain 3:" -#define STR_SCSI_4 "Ohjain 4:" -#define STR_CASSETTE "Kasettiasema" - -#define STR_HDD "Kiintolevyt:" -#define STR_NEW "&Uusi..." -#define STR_EXISTING "&Olemassaoleva..." -#define STR_REMOVE "&Poista" -#define STR_BUS "Väylä:" -#define STR_CHANNEL "Kanava:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Määritä..." -#define STR_SECTORS "Sektorit:" -#define STR_HEADS "Lukupäät:" -#define STR_CYLS "Sylinterit:" -#define STR_SIZE_MB "Koko (Mt):" -#define STR_TYPE "Tyyppi:" -#define STR_IMG_FORMAT "Tiedostomuoto:" -#define STR_BLOCK_SIZE "Lohkon koko:" - -#define STR_FLOPPY_DRIVES "Levykeasemat:" -#define STR_TURBO "Turbo-ajoitukset" -#define STR_CHECKBPB "Tarkista BPB" -#define STR_CDROM_DRIVES "CD-ROM-asemat:" -#define STR_CD_SPEED "Nopeus:" - -#define STR_MO_DRIVES "Magneettisoptiset asemat (MO):" -#define STR_ZIP_DRIVES "ZIP-asemat:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA-RTC (kello):" -#define STR_ISAMEM "ISA-muistilaajennus" -#define STR_ISAMEM_1 "Kortti 1:" -#define STR_ISAMEM_2 "Kortti 2:" -#define STR_ISAMEM_3 "Kortti 3:" -#define STR_ISAMEM_4 "Kortti 4:" -#define STR_BUGGER "ISABugger-laite" -#define STR_POSTCARD "POST-kortti" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Virhe" - IDS_2050 "Vakava virhe" - IDS_2051 " - TAUKO" - IDS_2052 "Paina Ctrl+Alt+PgDn palataksesi ikkunoituun tilaan." - IDS_2053 "Nopeus" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIP-levykuvat (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box ei löytänyt käyttökelpoisia ROM-tiedostoja.\n\nVoit ladata ROM-paketin ja purkaa sen ""roms""-hakemistoon." - IDS_2057 "(tyhjä)" - IDS_2058 "ZIP-levykuvat (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "Päällä" - IDS_2061 "Pois" - IDS_2062 "Kaikki levykuvat (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Perussektorilevykuvat (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Pintalevykuvat (*.86F)\0*.86F\0" - IDS_2063 "Konetta ""%hs"" ei voi käyttää puuttuvien ROM-tiedostojen vuoksi. Vaihdetaan käyttökelpoiseen koneeseen." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "Näytönohjainta ""%hs"" ei voi käyttää puuttuvien ROM-tiedostojen vuoksi. Vaihdetaan käyttökelpoiseen näytönohjaimeen." - IDS_2065 "Tietokone" - IDS_2066 "Näyttö" - IDS_2067 "Syöttölaitteet" - IDS_2068 "Ääni" - IDS_2069 "Verkko" - IDS_2070 "Portit (COM & LPT)" - IDS_2071 "Tallennusohjaimet" - IDS_2072 "Kiintolevyt" - IDS_2073 "Levyke ja CD-ROM" - IDS_2074 "Muut tallennuslaitteet" - IDS_2075 "Muut oheislaitteet" - IDS_2076 "Pintalevykuvat (*.86F)\0*.86F\0" - IDS_2077 "Kaappaa hiiri klikkaamalla" - IDS_2078 "Paina F8+F12 vapauttaaksesi hiiren" - IDS_2079 "Paina F8+F12 tai keskipainiketta vapauttaaksesi hiiren" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Väylä" - IDS_2082 "Tiedosto" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "Mt" - IDS_2087 "Speed" - IDS_2088 "Tarkista BPB" - IDS_2089 "kt" - IDS_2090 "Videorenderöijän alustus epäonnistui" - IDS_2091 "Oletus" - IDS_2092 "%i odotustilaa" - IDS_2093 "Tyyppi" - IDS_2094 "PCap-asennus epäonnistui" - IDS_2095 "PCap-laitteita ei löytynyt" - IDS_2096 "Virheellinen PCap-laite" - IDS_2097 "Standardi 2-painikkeinen peliohjain/-ohjaimet" - IDS_2098 "Standardi 4-painikkeinen peliohjain" - IDS_2099 "Standardi 6-painikkeinen peliohjain" - IDS_2100 "Standardi 8-painikkeinen peliohjain" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "Ei mikään" - IDS_2105 "Näppäinkiihdyttimien lataus epäonnistui" - IDS_2106 "Raakasyötteen rekisteröinti epäonnistui" - IDS_2107 "%u" - IDS_2108 "%u Mt (CHS: %i, %i, %i)" - IDS_2109 "Levyke %i (%s): %ls" - IDS_2110 "Kaikki levykuvat (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Kehittyneet sektorilevykuvat (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Perussektorilevykuvat (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux-levykuvat (*.FDI)\0*.FDI\0Pintalevykuvat (*.86F;*.MFM)\0*.86F;*.MFM\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2113 "Haluatko varmasti käynnistää emuloidun tietokoneen uudelleen?" - IDS_2114 "Haluatko varmasti sulkea 86Boxin?" - IDS_2115 "Ghostscriptin alustus epäonnistui" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "MO-levykuvat (*.IM?;*.MDI)\0*.IM?;*.MDI\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2118 "Tervetuloa 86Boxiin!" - IDS_2119 "Sisäinen ohjain" - IDS_2120 "Poistu" - IDS_2121 "ROM-tiedostoja ei löytynyt" - IDS_2122 "Tallennetaanko asetukset?" - IDS_2123 "Tämä käynnistää emuloidun tietokoneen uudelleen." - IDS_2124 "Tallenna" - IDS_2125 "Tietoja 86Box:sta" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "Vanhojen tietokoneiden emulaattori\n\nTekijät: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne ja muut.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho ja muut.\n\nJulkaistu GNU General Public License 2. version tai myöhemmän alaisena. Tarkempia tietoja LICENSE-tiedostossa." - IDS_2128 "OK" - IDS_2129 "Laitteisto ei ole saatavilla" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Varmista, että " LIB_NAME_PCAP " on asennettu ja että verkkoyhteytesi on " LIB_NAME_PCAP "-yhteensopiva." - IDS_2131 "Virheelliset määritykset" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " vaaditaan PostScript-tiedostojen automaattiseen muuntamiseen PDF-tiedostoiksi.\n\nKaikki geneeriselle PostScript-tulostimelle lähetetyt asiakirjat tallennetaan PostScript (.ps) -tiedostoina." - IDS_2135 "Siirrytään koko näytön tilaan" - IDS_2136 "Älä näytä tätä viestiä uudelleen" - IDS_2137 "Älä poistu" - IDS_2138 "Käynnistä uudelleen" - IDS_2139 "Älä käynnistä uudelleen" - IDS_2140 "MO-levykuvat (*.IM?;*.MDI)\0*.IM?;*.MDI\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2141 "CD-ROM-levykuvat (*.ISO;*.CUE)\0*.ISO;*.CUE\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2142 "%hs - Laitteen määritykset" - IDS_2143 "Näyttö lepotilassa" - IDS_2144 "OpenGL-varjostinohjelmat (*.GLSL)\0*.GLSL\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2145 "OpenGL-asetukset" - IDS_2146 "Olet lataamassa ei-tuettuja määrittelyjä" - IDS_2147 "Valittuun tietokoneeseen perustuva suoritintyypin suodatus ei ole käytössä tällä emuloidulla koneella.\n\nTämä mahdollistaa muutoin yhteensopimattoman suorittimen valinnan kyseisen tietokoneen kanssa. Voit kuitenkin kohdata ongelmia tietokoneen BIOS:in tai muun ohjelmiston kanssa.\n\nTämän asetuksen käyttö ei ole virallisesti tuettua ja kaikki tehdyt virheraportit voidaan sulkea epäpätevinä." - IDS_2148 "Jatka" - IDS_2149 "Kasetti: %s" - IDS_2150 "Kasettitiedostot (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2151 "ROM-moduuli %i: %ls" - IDS_2152 "ROM-moduulikuvat (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2153 "Virhe renderöijän alustuksessa" - IDS_2154 "OpenGL (3.0 Core) -renderöijän alustus epäonnistui. Käytä toista renderöijää." - IDS_2155 "Jatka suoritusta" - IDS_2156 "Pysäytä suoritus" - IDS_2157 "Paina Ctrl+Alt+Del" - IDS_2158 "Paina Ctrl+Alt+Esc" - IDS_2159 "Kylmä uudelleenkäynnistys" - IDS_2160 "ACPI-sammutus" - IDS_2161 "Asetukset" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Kiintolevy (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLL- tai ESDI-CD-ROM-asemia ei ole koskaan ollut olemassa" - IDS_4100 "Mukautettu..." - IDS_4101 "Mukautettu (suuri)..." - IDS_4102 "Lisää uusi kiintolevy" - IDS_4103 "Lisää olemassaoleva kiintolevy" - IDS_4104 "HDI-levykuvan suurin mahdollinen koko on 4 Gt." - IDS_4105 "Levykuvien suurin mahdollinen koko on 127 Gt." - IDS_4106 "Kiintolevykuvat (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_4107 "Tiedostoa ei voi lukea" - IDS_4108 "Tiedostoon ei voi kirjoittaa" - IDS_4109 "HDI- ja HDX-levykuvien ainoa tuettu sektorikoko on 512" - IDS_4110 "USB-tukea ei vielä ole" - IDS_4111 "Levykuva on jo olemassa" - IDS_4112 "Anna kelvollinen tiedostonimi." - IDS_4113 "Levykuva luotu" - IDS_4114 "Varmista, että tiedosto on olemassa ja lukukelpoinen" - IDS_4115 "Varmista, että tiedoston tallennuskansioon on kirjoitusoikeus" - IDS_4116 "Liian suuri levykuva" - IDS_4117 "Muista osioida ja alustaa juuri luomasi asema." - IDS_4118 "Valittu tiedosto korvataan. Oletko varma, että haluat käyttää sitä?" - IDS_4119 "Levykuvaa ei tueta" - IDS_4120 "Korvaa" - IDS_4121 "Älä korvaa" - IDS_4122 "Raaka levykuva (.img)" - IDS_4123 "HDI-levykuva (.hdi)" - IDS_4124 "HDX-levykuva (.hdx)" - IDS_4125 "Kiinteä VHD (.vhd)" - IDS_4126 "Dynaaminen VHD (.vhd)" - IDS_4127 "Differentiaalinen VHD (.vhd)" - IDS_4128 "Suuret lohkot (2 Mt)" - IDS_4129 "Pienet lohkot (512 kt)" - IDS_4130 "VHD-tiedostot (*.VHD)\0*.VHD\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_4131 "Valitse ylätason VHD" - IDS_4132 "Tämä saattaa tarkoittaa, että ylätason levykuvaa on muokattu differentiaalisen levykuvan luonnin jälkeen.\n\nNäin voi käydä myös, jos levykuvatiedostoja on siirretty tai kopioitu. Lisäksi syynä voi olla levyn luoneessa sovelluksessa oleva ohjelmistovirhe.\n\nKorjataanko aikaleimat?" - IDS_4133 "Ylä- ja alatason levyjen aikaleimat eivät täsmää" - IDS_4134 "VHD aikaleimaa ei pystytty korjaamaan." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Ei käytössä" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Ei käytössä" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kt" - IDS_5889 "180 kt" - IDS_5890 "320 kt" - IDS_5891 "360 kt" - IDS_5892 "640 kt" - IDS_5893 "720 kt" - IDS_5894 "1.2 Mt" - IDS_5895 "1.25 Mt" - IDS_5896 "1.44 Mt" - IDS_5897 "DMF (lohko 1024)" - IDS_5898 "DMF (lohko 2048)" - IDS_5899 "2.88 Mt" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 Mt (ISO 10090)" - IDS_5903 "3.5"" 230 Mt (ISO 13963)" - IDS_5904 "3.5"" 540 Mt (ISO 15498)" - IDS_5905 "3.5"" 640 Mt (ISO 15498)" - IDS_5906 "3.5"" 1.3 Gt (GigaMO)" - IDS_5907 "3.5"" 2.3 Gt (GigaMO 2)" - IDS_5908 "5.25"" 600 Mt" - IDS_5909 "5.25"" 650 Mt" - IDS_5910 "5.25"" 1 Gt" - IDS_5911 "5.25"" 1.3 Gt" - - IDS_6144 "Täydellinen RPM" - IDS_6145 "1% alle täydellisen RPM:n" - IDS_6146 "1.5% alle täydellisen RPM:n" - IDS_6147 "2% alle täydellisen RPM:n" - - IDS_7168 "(Järjestelmän oletus)" -END -#define IDS_LANG_ENUS IDS_7168 - -// English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/fr-FR.rc b/src/win/languages/fr-FR.rc deleted file mode 100644 index 425656c28..000000000 --- a/src/win/languages/fr-FR.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// French (fr-FR) resources - -#ifdef _WIN32 -LANGUAGE LANG_FRENCH, SUBLANG_FRENCH -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Action" - BEGIN - MENUITEM "&Capturer le clavier", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "CTRL &Droite devient ALT Gauche", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Hard Reset...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Pause", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "&Quitter...", IDM_ACTION_EXIT - END - POPUP "&Vue" - BEGIN - MENUITEM "&Masquer la barre de status", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "Fenètre &Retaillable", IDM_VID_RESIZE - MENUITEM "S&auvegarder taille && position", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "Moteur de &rendu vidéo" - BEGIN - MENUITEM "&SDL (Logiciel)", IDM_VID_SDL_SW - MENUITEM "SDL (&Materiel)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "Specifier dimensions...", IDM_VID_SPECIFY_DIM - MENUITEM "F&orcer 4:3", IDM_VID_FORCE43 - POPUP "&Echelle facteur" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Methode Filtre" - BEGIN - MENUITEM "&Plus proche", IDM_VID_FILTER_NEAREST - MENUITEM "&Lineaire", IDM_VID_FILTER_LINEAR - END - MENUITEM "Mise à l'échelle Hi&DPI", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Plein Ecran\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Mode &Elargi plein écran" - BEGIN - MENUITEM "&Plein écran étiré", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "pixels &Carrés(Keep ratio)", IDM_VID_FS_KEEPRATIO - MENUITEM "Echelle &Entière", IDM_VID_FS_INT - END - POPUP "Réglages E&GA/(S)VGA" - BEGIN - MENUITEM "Moniteur VGA &Inversé", IDM_VID_INVERT - POPUP "&Type Ecran VGA" - BEGIN - MENUITEM "RGB &Couleur", IDM_VID_GRAY_RGB - MENUITEM "&RGB Ton de Gris", IDM_VID_GRAY_MONO - MENUITEM "Moniteur &Ambre", IDM_VID_GRAY_AMBER - MENUITEM "Moniteur &Vert", IDM_VID_GRAY_GREEN - MENUITEM "Moniteur &Blanc", IDM_VID_GRAY_WHITE - END - POPUP "Grayscale &conversion type" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Moyenne", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/E&GA/(S)VGA overscan", IDM_VID_OVERSCAN - MENUITEM "Modifier contraste affichage &monochrome", IDM_VID_CGACON - END - MENUITEM "&Media", IDM_MEDIA - POPUP "Ou&tils" - BEGIN - MENUITEM "&Réglages...", IDM_CONFIG - MENUITEM "Mettre à jour la barre de stat&us", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Copie &Ecran\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Préférences...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Activer intégration &Discord", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Gain Son...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Démarrer traces\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Finir traces\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Aide" - BEGIN - MENUITEM "&Documentation...", IDM_DOCS - MENUITEM "&A Propos de 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nouvelle image...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Image &Existante...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Image Existante(&Lecture seule)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "En®istrer", IDM_CASSETTE_RECORD - MENUITEM "&Jouer", IDM_CASSETTE_PLAY - MENUITEM "&Revenir au debut", IDM_CASSETTE_REWIND - MENUITEM "Aller à la &Fin", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "E&jecter", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Image...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "E&jecter", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nouvelle image...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Image &Existante...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Image Existante(&Lecture seule)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&xport vers 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "E&jecter", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Couper", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "E&jecter", IDM_CDROM_EMPTY - MENUITEM "&Recharger image précedente", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_IMAGE - MENUITEM "&Dossier...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nouvelle image...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Image &Existante...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Image Existante (&Lecture Seule)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&jecter", IDM_ZIP_EJECT - MENUITEM "&Recharger image précédente", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nouvelle image...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Image &Existante...", IDM_MO_IMAGE_EXISTING - MENUITEM "Image Existante (&Lecture Seule)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&jecter", IDM_MO_EJECT - MENUITEM "&Recharger image précédente", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "&Taux de rafraîchissement cible" - BEGIN - MENUITEM "&Synchronisation avec la vidéo", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 images par seconde", IDM_VID_GL_FPS_25 - MENUITEM "&30 images par seconde", IDM_VID_GL_FPS_30 - MENUITEM "&50 images par seconde", IDM_VID_GL_FPS_50 - MENUITEM "&60 images par seconde", IDM_VID_GL_FPS_60 - MENUITEM "&75 images par seconde", IDM_VID_GL_FPS_75 - END - MENUITEM "Synchronisation &verticale", IDM_VID_GL_VSYNC - MENUITEM "Sé&lectionnez le shader...", IDM_VID_GL_SHADER - MENUITEM "S&upprimer le shader", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Préférences" -#define STR_SND_GAIN "Gain son" -#define STR_NEW_FLOPPY "Nouvelle image" -#define STR_CONFIG "Réglages" -#define STR_SPECIFY_DIM "Spécifier le détournement de la fenêtre principale" - -#define STR_OK "OK" -#define STR_CANCEL "Annuler" -#define STR_GLOBAL "Sauvegarder ces paramètres comme valeurs par défaut &globales" -#define STR_DEFAULT "&Défaut" -#define STR_LANGUAGE "Langue:" -#define STR_ICONSET "Ensemble d'icônes:" - -#define STR_GAIN "Gain" - -#define STR_FILE_NAME "Nom fichier:" -#define STR_DISK_SIZE "Taille disque:" -#define STR_RPM_MODE "Mode RPM:" -#define STR_PROGRESS "Progrès:" - -#define STR_WIDTH "Largeur:" -#define STR_HEIGHT "Hauteur:" -#define STR_LOCK_TO_SIZE "Verrouiller à cette taille" - -#define STR_MACHINE_TYPE "Type de machine:" -#define STR_MACHINE "Machine:" -#define STR_CONFIGURE "Configurer" -#define STR_CPU_TYPE "Type du processeur:" -#define STR_CPU_SPEED "Vitesse:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "États d'attente:" -#define STR_MB "Mo" -#define STR_MEMORY "Mémoire:" -#define STR_TIME_SYNC "Synchronisation du temps" -#define STR_DISABLED "Désactivé" -#define STR_ENABLED_LOCAL "Activé (heure locale)" -#define STR_ENABLED_UTC "Activé (UTC)" -#define STR_DYNAREC "Recompilateur dynamique" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Vidéo:" -#define STR_VIDEO_2 "Vidéo 2:" -#define STR_VOODOO "Graphique Voodoo" -#define STR_IBM8514 "Graphique IBM 8514/A" -#define STR_XGA "Graphique XGA" - -#define STR_MOUSE "Souris:" -#define STR_JOYSTICK "Manette de commande:" -#define STR_JOY1 "Manette 1..." -#define STR_JOY2 "Manette 2..." -#define STR_JOY3 "Manette 3..." -#define STR_JOY4 "Manette 4..." - -#define STR_SOUND1 "Carte son 1:" -#define STR_SOUND2 "Carte son 2:" -#define STR_SOUND3 "Carte son 3:" -#define STR_SOUND4 "Carte son 4:" -#define STR_MIDI_OUT "Sortie MIDI:" -#define STR_MIDI_IN "Entrée MIDI:" -#define STR_MPU401 "MPU-401 autonome" -#define STR_FLOAT "Utiliser le son FLOAT32" -#define STR_FM_DRIVER "Pilote de synthétiseur FM" -#define STR_FM_DRV_NUKED "Nuked (plus précis)" -#define STR_FM_DRV_YMFM "YMFM (plus rapide)" - -#define STR_NET_TYPE "Type de réseau:" -#define STR_PCAP "Dispositif PCap:" -#define STR_NET "Adaptateur de réseau:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "Dispositif COM1:" -#define STR_COM2 "Dispositif COM2:" -#define STR_COM3 "Dispositif COM3:" -#define STR_COM4 "Dispositif COM4:" -#define STR_LPT1 "Dispositif LPT1:" -#define STR_LPT2 "Dispositif LPT2:" -#define STR_LPT3 "Dispositif LPT3:" -#define STR_LPT4 "Dispositif LPT4:" -#define STR_SERIAL1 "Port série 1" -#define STR_SERIAL2 "Port série 2" -#define STR_SERIAL3 "Port série 3" -#define STR_SERIAL4 "Port série 4" -#define STR_PARALLEL1 "Port parallèle 1" -#define STR_PARALLEL2 "Port parallèle 2" -#define STR_PARALLEL3 "Port parallèle 3" -#define STR_PARALLEL4 "Port parallèle 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Contrôleur HD:" -#define STR_FDC "Contrôleur FD:" -#define STR_IDE_TER "Contrôleur IDE tertiaire" -#define STR_IDE_QUA "Contrôleur IDE quaternair" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Contrôleur 1:" -#define STR_SCSI_2 "Contrôleur 2:" -#define STR_SCSI_3 "Contrôleur 3:" -#define STR_SCSI_4 "Contrôleur 4:" -#define STR_CASSETTE "Cassette" - -#define STR_HDD "Disques durs:" -#define STR_NEW "&Nouveau..." -#define STR_EXISTING "&Existant..." -#define STR_REMOVE "&Supprimer" -#define STR_BUS "Bus:" -#define STR_CHANNEL "Canal:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Spécifier..." -#define STR_SECTORS "Secteurs:" -#define STR_HEADS "Têtes:" -#define STR_CYLS "Cylindres:" -#define STR_SIZE_MB "Taille (Mo):" -#define STR_TYPE "Type:" -#define STR_IMG_FORMAT "Format Image:" -#define STR_BLOCK_SIZE "Taille du bloc:" - -#define STR_FLOPPY_DRIVES "Lecteurs de disquettes:" -#define STR_TURBO "Turbo" -#define STR_CHECKBPB "Vérifier BPB" -#define STR_CDROM_DRIVES "Lecterus CD-ROM:" -#define STR_CD_SPEED "Vitesse:" - -#define STR_MO_DRIVES "Lecteurs magnéto-optiques:" -#define STR_ZIP_DRIVES "Lecteurs ZIP:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "Horloge temps réel ISA:" -#define STR_ISAMEM "Expansion de la mémoire ISA" -#define STR_ISAMEM_1 "Carte 1:" -#define STR_ISAMEM_2 "Carte 2:" -#define STR_ISAMEM_3 "Carte 3:" -#define STR_ISAMEM_4 "Carte 4:" -#define STR_BUGGER "Dispositif ISABugger" -#define STR_POSTCARD "Carte POST" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Erreur" - IDS_2050 "Erreur fatale" - IDS_2051 " - PAUSED" - IDS_2052 "Appuyez sur Ctrl+Alt+PgDn pour revenir au mode fenêtré." - IDS_2053 "Vitesse" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "Images ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box n'a pas pu trouver d'images ROM utilisables.\n\nS'il vous plait, téléchargez un ensemble ROM et extrayez-le dans le répertoire ""roms""." - IDS_2057 "(vide)" - IDS_2058 "Images ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Tous les fichiers (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "Activé" - IDS_2061 "Désactivé" - IDS_2062 "Tous les images (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Images basiques du secteur (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Images de la surface (*.86F)\0*.86F\0" - IDS_2063 "La machine ""%hs"" n'est pas disponible en raison de l'absence de ROMs dans le répertoire roms/machines. Basculer vers une machine disponible." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "La carte vidéo ""%hs"" n'est pas disponible en raison de l'absence de ROMs dans le répertoire roms/video. Basculer vers une carte vidéo disponible." - IDS_2065 "Machine" - IDS_2066 "Affichage" - IDS_2067 "Dispositifs d'entrée" - IDS_2068 "Son" - IDS_2069 "Réseau" - IDS_2070 "Ports (COM et LPT)" - IDS_2071 "Contrôleurs de stockage" - IDS_2072 "Disques durs" - IDS_2073 "Lecteurs de disquette et CD-ROM" - IDS_2074 "Autres dispositifs amovibles" - IDS_2075 "Autres périfériques" - IDS_2076 "Images de surface (*.86F)\0*.86F\0" - IDS_2077 "Cliquer pour capturer la souris" - IDS_2078 "Appuyer sur F8+F12 pour libérer la souris" - IDS_2079 "Appuyer sur F8+F12 ou le bouton central pour libérer la souris" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Bus" - IDS_2082 "File" - IDS_2083 "C" - IDS_2084 "T" - IDS_2085 "S" - IDS_2086 "Mo" - IDS_2087 "Speed" - IDS_2088 "Vérifier BPB" - IDS_2089 "Ko" - IDS_2090 "Impossible d'initialiser le moteur de rendu vidéo." - IDS_2091 "Défaut" - IDS_2092 "%i état(s) d'attente" - IDS_2093 "Type" - IDS_2094 "Impossible d'initialiser PCap" - IDS_2095 "Aucun dispositif PCap trouvé" - IDS_2096 "Dispositif PCap non valide" - IDS_2097 "Manette(s) standard avec 2 boutons" - IDS_2098 "Manette standard avec 4 boutons" - IDS_2099 "Manette standard avec 6 boutons" - IDS_2100 "Manette standard avec 6 boutons" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Système de contrôle de vol Thrustmaster" - IDS_2104 "Aucun" - IDS_2105 "Impossible de charger les accélérateurs de clavier." - IDS_2106 "Impossible de charger l'entrée raw." - IDS_2107 "%u" - IDS_2108 "%u Mo (CTS: %i, %i, %i)" - IDS_2109 "Disquette %i (%s): %ls" - IDS_2110 "Toutes les images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Images du secteur avancés (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Images du secteur basiques (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Images du flux (*.FDI)\0*.FDI\0Images de surface (*.86F;*.MFM)\0*.86F;*.MFM\0Tous les fichiers (*.*)\0*.*\0" - IDS_2113 "Etes-vous sûr de vouloir réinitialiser la machine émulée ?" - IDS_2114 "Etes-vous sûr de vouloir quitter 86Box?" - IDS_2115 "Impossible d'initialiser Ghostscript" - IDS_2116 "Magnéto-optique %i (%ls): %ls" - IDS_2117 "Images magnéto-optiques (*.IM?;*.MDI)\0*.IM?;*.MDI\0Tous les fichiers (*.*)\0*.*\0" - IDS_2118 "Bienvenue dans 86Box !" - IDS_2119 "Côntrolleur interne" - IDS_2120 "Sortir" - IDS_2121 "Pas de ROMs trouvées" - IDS_2122 "Voulez-vous sauvegarder les paramètres ?" - IDS_2123 "Cela entraînera la réinitialisation complète de la machine émulée." - IDS_2124 "Sauvegarder" - IDS_2125 "À propos de 86Box" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "Un émulateur de vieux ordinateurs\n\nAuteurs: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nLibéré sous la licence GNU General Public License version 2 ou ultérieure. Pour plus d'informations, voir le fichier LICENSE." - IDS_2128 "OK" - IDS_2129 "Matériel non disponible" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Assurez-vous que " LIB_NAME_PCAP " est installé et que vou utilisez une connexion réseau compatible avec " LIB_NAME_PCAP "." - IDS_2131 "Configuration non valide" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " est nécessair pour la conversion automatique des fichiers PostScript dans PDF.\n\nTous les documents envoyés à l'imprimante générique PostScript seront sauvés comme des fichiers PostScript (.ps)." - IDS_2135 "Entrer en mode plein écran" - IDS_2136 "Ne pas montrer ce message à nouveau" - IDS_2137 "Ne pas sortir" - IDS_2138 "Réinitialiser" - IDS_2139 "Ne pas réinitialiser" - IDS_2140 "Images magnéto-optiques (*.IM?;*.MDI)\0*.IM?;*.MDI\0Tous les fichiers (*.*)\0*.*\0" - IDS_2141 "Images CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Tous les fichiers (*.*)\0*.*\0" - IDS_2142 "Configuration du dispositif %hs" - IDS_2143 "Moniteur en mode veille" - IDS_2144 "Shaders OpenGL (*.GLSL)\0*.GLSL\0Tous les fichiers (*.*)\0*.*\0" - IDS_2145 "Options OpenGL" - IDS_2146 "Vous chargez une configuration non prise en charge" - IDS_2147 "La filtrage du type du processeur sur la base de la machine sélectionné est désactivé pur cette machine émulée.\n\nCela permet de sélectionner une processeur que est sinon incompatible avec la machine sélectionné. Cependant, il pourrait y avoir des incompatibilités avec le BIOS de la machine ou autres logiciels.\n\nL'activatione de cette configuration non est officiellement prise en charge et tout rapport de bogue peut être fermé comme étant invalide." - IDS_2148 "Continuer" - IDS_2149 "Cassette: %s" - IDS_2150 "Images cassette (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Tous les fichiers (*.*)\0*.*\0" - IDS_2151 "Cartouche %i: %ls" - IDS_2152 "Images cartouche (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Tous les fichiers (*.*)\0*.*\0" - IDS_2153 "Error initializing renderer" - IDS_2154 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." - IDS_2155 "Resume execution" - IDS_2156 "Pause execution" - IDS_2157 "Press Ctrl+Alt+Del" - IDS_2158 "Press Ctrl+Alt+Esc" - IDS_2159 "Hard reset" - IDS_2160 "ACPI shutdown" - IDS_2161 "Settings" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Disque dur (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "Les lecteurs de CD-ROM MFM/RLL ou ESDI n'ont jamais existé" - IDS_4100 "Personnalisé..." - IDS_4101 "Personnalisé (grand)..." - IDS_4102 "Ajouter un nouveau disque dur" - IDS_4103 "Ajouter un disque dur existant" - IDS_4104 "Les images de disque HDI ne peuvent pas avoir une taille supériure à Go." - IDS_4105 "Les images de disque ne peuvent pas avoir un taille supérieure à 127 Go." - IDS_4106 "Images de dique dur (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Tous les fichiers (*.*)\0*.*\0" - IDS_4107 "Impossible de lire le fichier" - IDS_4108 "Impossible d'écrire le fichier" - IDS_4109 "Les images HDI ou HDX avec une taille de secteur différente de 512 non sont pas prises en charge." - IDS_4110 "USB n'est pas encore pris en charge." - IDS_4111 "Le fichier de l'image disque existe déjà." - IDS_4112 "Veuillez spécifier un nom de fichier valide." - IDS_4113 "Image de disque créée" - IDS_4114 "Assurez-vous que le fichier existe et est lisible." - IDS_4115 "Assurez-vous que le fichier en cours d'enregistrement se trouve dans un répertoire accessible en écriture." - IDS_4116 "Image disque trop grande" - IDS_4117 "N'oubliez pas de partitionner et de formater le nouveau disque créé." - IDS_4118 "Le fichier sélectionné sera écrasé. Etes-vous sûr de vouloir l'utiliser?" - IDS_4119 "Image disque non prise en charge" - IDS_4120 "Écraser" - IDS_4121 "Ne pas écraser" - IDS_4122 "Image brute (.img)" - IDS_4123 "Image HDI (.hdi)" - IDS_4124 "Image HDX (.hdx)" - IDS_4125 "VHD à taille fixe (.vhd)" - IDS_4126 "VHD à taille dynamique (.vhd)" - IDS_4127 "VHD à différenciation (.vhd)" - IDS_4128 "Blocs grands (2 Mo)" - IDS_4129 "Blocs petits (512 Ko)" - IDS_4130 "Fichiers VHD (*.VHD)\0*.VHD\0Tous les fichiers (*.*)\0*.*\0" - IDS_4131 "Sélectionnez le VHD parent" - IDS_4132 "Il est possible que l'image parente a été modifié après la création de l'image à différenciation.\n\nIl est même possible que les fichiers de l'mage ont été déplacés ou copiés ou il existe un bogue dans le programme que a créé ce disque.\n\nVoulez-vous réparer l'horodatage?" - IDS_4133 "Les horodatages des disques parent et enfant ne correspondent pas" - IDS_4134 "Impossible de réparer l'horodatage du VHD." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Désactivé" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Désactivé" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 Ko" - IDS_5889 "180 Ko" - IDS_5890 "320 Ko" - IDS_5891 "360 Ko" - IDS_5892 "640 Ko" - IDS_5893 "720 Ko" - IDS_5894 "1.2 Mo" - IDS_5895 "1.25 Mo" - IDS_5896 "1.44 Mo" - IDS_5897 "DMF (cluster 1024)" - IDS_5898 "DMF (cluster 2048)" - IDS_5899 "2.88 Mo" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 Mo (ISO 10090)" - IDS_5903 "3.5"" 230 Mo (ISO 13963)" - IDS_5904 "3.5"" 540 Mo (ISO 15498)" - IDS_5905 "3.5"" 640 Mo (ISO 15498)" - IDS_5906 "3.5"" 1.3 Go (GigaMO)" - IDS_5907 "3.5"" 2.3 Go (GigaMO 2)" - IDS_5908 "5.25"" 600 Mo" - IDS_5909 "5.25"" 650 Mo" - IDS_5910 "5.25"" 1 Go" - IDS_5911 "5.25"" 1.3 Go" - - IDS_6144 "RPM précis" - IDS_6145 "Précision RPM de moins 1%" - IDS_6146 "Précision RPM de moins 1.5%" - IDS_6147 "Précision RPM de moins 2%" - - IDS_7168 "(Défaut du système)" -END -#define IDS_LANG_ENUS IDS_7168 - -// French (F.R.) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/hr-HR.rc b/src/win/languages/hr-HR.rc deleted file mode 100644 index f01b2a881..000000000 --- a/src/win/languages/hr-HR.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Croatian (hr-HR) resources - -#ifdef _WIN32 -LANGUAGE LANG_CROATIAN, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Radnje" - BEGIN - MENUITEM "&Tipkovnica zahtijeva hvatanje miša", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Desni CTRL je lijevi ALT", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Ponovno pokretanje...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Pauza", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "Iz&laz...", IDM_ACTION_EXIT - END - POPUP "&Pogled" - BEGIN - MENUITEM "&Sakrij statusni redak", IDM_VID_HIDE_STATUS_BAR - MENUITEM "&Sakrij alatni redak", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Prozor s promjenjivim veličinama", IDM_VID_RESIZE - MENUITEM "&Zapamtite veličinu i položaj", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "&Renderer" - BEGIN - MENUITEM "&SDL (Softver)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardver)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 jezgra)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "Odrediti veličinu...", IDM_VID_SPECIFY_DIM - MENUITEM "&4:3 omjer prikaza", IDM_VID_FORCE43 - POPUP "&Faktor skaliranja prozora" - BEGIN - MENUITEM "&0,5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1,&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Metoda filtriranja" - BEGIN - MENUITEM "&Najbliža", IDM_VID_FILTER_NEAREST - MENUITEM "&Linearna", IDM_VID_FILTER_LINEAR - END - MENUITEM "&HiDPI skaliranje", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Cijelozaslonski način\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "&Način cijelozaslonskog rastezanja" - BEGIN - MENUITEM "&Razvuci na cijeli zaslona", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Kvadratni pikseli (zadrži omjer)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Cijelobrojno skaliranje", IDM_VID_FS_INT - END - POPUP "E&GA/(S)VGA postavke" - BEGIN - MENUITEM "&Obrni boje zaslona VGA", IDM_VID_INVERT - POPUP "&Tip zaslona VGA" - BEGIN - MENUITEM "RGB u &boji", IDM_VID_GRAY_RGB - MENUITEM "&RGB u nijansama sive boje", IDM_VID_GRAY_MONO - MENUITEM "&Jantarni zaslon", IDM_VID_GRAY_AMBER - MENUITEM "&Zeleni zaslon", IDM_VID_GRAY_GREEN - MENUITEM "&Bijeli zaslon", IDM_VID_GRAY_WHITE - END - POPUP "&Vrsta konverzije nijansa sive boje" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Prosjek", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "&Višak slike CGA/PCjr/Tandy/EGA/(S)VGA", IDM_VID_OVERSCAN - MENUITEM "&Promjeni kontrast za crno-bijeli zaslon", IDM_VID_CGACON - END - MENUITEM "&Mediji", IDM_MEDIA - POPUP "&Alati" - BEGIN - MENUITEM "&Opcije...", IDM_CONFIG - MENUITEM "&Ažuriraj ikone statusnog redka", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Napravi &snimku zaslona\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Postavke...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Omogući integraciju sa programom &Discord", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Pojačanje zvuka...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Z&apočni praćenje\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "&Svrši praćenje\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Pomoć" - BEGIN - MENUITEM "&Dokumentacija...", IDM_DOCS - MENUITEM "&O programu 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova slika...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Postojeća slika...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Postojeća slika (&zaštićena od pisanja)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Snimi", IDM_CASSETTE_RECORD - MENUITEM "&Pokreni", IDM_CASSETTE_PLAY - MENUITEM "P&remotaj na početak", IDM_CASSETTE_REWIND - MENUITEM "&Preskoči do kraja", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "&Izbaci", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Slika...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "&Izbaci", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova slika...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Postojeća slika...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Postojeća slika (&zaštićena od pisanja)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Izvozi u 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "&Izbaci", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Isključi zvuk", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "&Prazno", IDM_CDROM_EMPTY - MENUITEM "&Ponovo učitaj prethodnu sliku", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Slika...", IDM_CDROM_IMAGE - MENUITEM "&Mapa...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova slika...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Postojeća slika...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Postojeća slika (&zaštićena od pisanja)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Izbaci", IDM_ZIP_EJECT - MENUITEM "&Ponovo učitaj prethodnu sliku", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova slika...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Postojeća slika...", IDM_MO_IMAGE_EXISTING - MENUITEM "Postojeća slika (&zaštićena od pisanja)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Izbaci", IDM_MO_EJECT - MENUITEM "&Ponovo učitaj prethodnu sliku", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "&Ciljni broj okvira u sekundi" - BEGIN - MENUITEM "&Sinkroniziraj s videom", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 fps", IDM_VID_GL_FPS_25 - MENUITEM "&30 fps", IDM_VID_GL_FPS_30 - MENUITEM "&50 fps", IDM_VID_GL_FPS_50 - MENUITEM "&60 fps", IDM_VID_GL_FPS_60 - MENUITEM "&75 fps", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Odaberi shader...", IDM_VID_GL_SHADER - MENUITEM "&Ukloni shader", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Postavke" -#define STR_SND_GAIN "Pojačavanje zvuka" -#define STR_NEW_FLOPPY "Nova slika" -#define STR_CONFIG "Opcije" -#define STR_SPECIFY_DIM "Odredite glavne dimenzije prozora" - -#define STR_OK "U redu" -#define STR_CANCEL "Otkaži" -#define STR_GLOBAL "Spremite ove postavke kao &globalne zadane postavke" -#define STR_DEFAULT "Zadano" -#define STR_LANGUAGE "Jezik:" -#define STR_ICONSET "Paket ikona:" - -#define STR_GAIN "Pojačavanje" - -#define STR_FILE_NAME "Ime datoteke:" -#define STR_DISK_SIZE "Veličina diska:" -#define STR_RPM_MODE "Način broja okretaja:" -#define STR_PROGRESS "Napredak:" - -#define STR_WIDTH "Širina:" -#define STR_HEIGHT "Visina:" -#define STR_LOCK_TO_SIZE "Zaključajte na ovu veličinu" - -#define STR_MACHINE_TYPE "Tip sistema:" -#define STR_MACHINE "Sistem:" -#define STR_CONFIGURE "Namjesti" -#define STR_CPU_TYPE "Tip procesora:" -#define STR_CPU_SPEED "Brzina:" -#define STR_FPU "FPU uređaj:" -#define STR_WAIT_STATES "Stanja čekanja:" -#define STR_MB "MB" -#define STR_MEMORY "Memorija:" -#define STR_TIME_SYNC "Sinkronizacija vremena" -#define STR_DISABLED "Isključeno" -#define STR_ENABLED_LOCAL "Uključeno (lokalno vrijeme)" -#define STR_ENABLED_UTC "Uključeno (UTC)" -#define STR_DYNAREC "Dinamički rekompilator" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Video:" -#define STR_VIDEO_2 "Video 2:" -#define STR_VOODOO "Voodoo grafika" -#define STR_IBM8514 "IBM 8514/A grafika" -#define STR_XGA "XGA grafika" - -#define STR_MOUSE "Miš:" -#define STR_JOYSTICK "Palica za igru:" -#define STR_JOY1 "Palica za igru 1..." -#define STR_JOY2 "Palica za igru 2..." -#define STR_JOY3 "Palica za igru 3..." -#define STR_JOY4 "Palica za igru 4..." - -#define STR_SOUND1 "Zvučna kartica 1:" -#define STR_SOUND2 "Zvučna kartica 2:" -#define STR_SOUND3 "Zvučna kartica 3:" -#define STR_SOUND4 "Zvučna kartica 4:" -#define STR_MIDI_OUT "Izlazni uređaj MIDI:" -#define STR_MIDI_IN "Ulazni uređaj MIDI:" -#define STR_MPU401 "Samostalni MPU-401" -#define STR_FLOAT "Koristi FLOAT32 za zvuk" -#define STR_FM_DRIVER "Drajver za FM sintisajzer" -#define STR_FM_DRV_NUKED "Nuked (precizniji)" -#define STR_FM_DRV_YMFM "YMFM (brži)" - -#define STR_NET_TYPE "Tip mreže:" -#define STR_PCAP "Uređaj PCap:" -#define STR_NET "Mrežna kartica:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "Uređaj COM1:" -#define STR_COM2 "Uređaj COM2:" -#define STR_COM3 "Uređaj COM3:" -#define STR_COM4 "Uređaj COM4:" -#define STR_LPT1 "Uređaj LPT1:" -#define STR_LPT2 "Uređaj LPT2:" -#define STR_LPT3 "Uređaj LPT3:" -#define STR_LPT4 "Uređaj LPT4:" -#define STR_SERIAL1 "Serijska vrata 1" -#define STR_SERIAL2 "Serijska vrata 2" -#define STR_SERIAL3 "Serijska vrata 3" -#define STR_SERIAL4 "Serijska vrata 4" -#define STR_PARALLEL1 "Paralelna vrata 1" -#define STR_PARALLEL2 "Paralelna vrata 2" -#define STR_PARALLEL3 "Paralelna vrata 3" -#define STR_PARALLEL4 "Paralelna vrata 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Kontroler tvrdog diska:" -#define STR_FDC "Kontroler diskete:" -#define STR_IDE_TER "Tercijarni IDE kontroler" -#define STR_IDE_QUA "Kvaternarni IDE kontroler" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Kontroler 1:" -#define STR_SCSI_2 "Kontroler 2:" -#define STR_SCSI_3 "Kontroler 3:" -#define STR_SCSI_4 "Kontroler 4:" -#define STR_CASSETTE "Audio kaseta" - -#define STR_HDD "Tvrdi diskovi:" -#define STR_NEW "&Novi..." -#define STR_EXISTING "&Postojeći..." -#define STR_REMOVE "&Ukloni" -#define STR_BUS "Sabirnica:" -#define STR_CHANNEL "Kanal:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Odredi..." -#define STR_SECTORS "Sektori:" -#define STR_HEADS "Glave:" -#define STR_CYLS "Cilindri:" -#define STR_SIZE_MB "Veličina (MB):" -#define STR_TYPE "Tip:" -#define STR_IMG_FORMAT "Format slike:" -#define STR_BLOCK_SIZE "Veličina slike:" - -#define STR_FLOPPY_DRIVES "Disketni pogoni:" -#define STR_TURBO "Turbo vrijemena" -#define STR_CHECKBPB "Provjeraj BPB" -#define STR_CDROM_DRIVES "CD-ROM pogoni:" -#define STR_CD_SPEED "Brzina:" - -#define STR_MO_DRIVES "MO pogoni:" -#define STR_ZIP_DRIVES "ZIP pogoni:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "Sat stvarnog vremena (RTC):" -#define STR_ISAMEM "Proširenje memorije ISA" -#define STR_ISAMEM_1 "Kartica 1:" -#define STR_ISAMEM_2 "Kartica 2:" -#define STR_ISAMEM_3 "Kartica 3:" -#define STR_ISAMEM_4 "Kartica 4:" -#define STR_BUGGER "Uređaj ISABugger" -#define STR_POSTCARD "Kartica POST" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Greška" - IDS_2050 "Fatalna greška" - IDS_2051 " - PAUSED" - IDS_2052 "Pritisnite Ctrl+Alt+PgDn za povratak u prozorski način rada." - IDS_2053 "Brzina" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIP slike (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box nije mogao pronaći upotrebljive ROM datoteke.\n\nMolimte posjetite sknite paket s ROM datotekama i ekstrahirajte paket u ""roms"" mapu." - IDS_2057 "(prazno)" - IDS_2058 "ZIP slike (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Sve datoteke (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "Uključeno" - IDS_2061 "Isključeno" - IDS_2062 "Sve slike (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0BOsnovne sektorske slike (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Površinske slike (*.86F)\0*.86F\0" - IDS_2063 "Sistem ""%hs"" nije dostupan jer ne postoje potrebni ROM-ovi u mapu roms/machines. Prebacivanje na dostupno računalo." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "Video kartica ""%hs"" nije dostupna jer ne postoje potrebni ROM-ovi u mapu roms/video. Prebacivanje na dostupnu video karticu." - IDS_2065 "Sistem" - IDS_2066 "Video" - IDS_2067 "Ulazni uređaji" - IDS_2068 "Zvuk" - IDS_2069 "Mreža" - IDS_2070 "Vrata (COM & LPT)" - IDS_2071 "Kontroleri za diskove" - IDS_2072 "Tvrdi diskovi" - IDS_2073 "Floppy & CD-ROM pogoni" - IDS_2074 "Ostali uklonjivi uređaji" - IDS_2075 "Ostali periferni uređaji" - IDS_2076 "Površinske slike (*.86F)\0*.86F\0" - IDS_2077 "Kliknite da uhvatite miš" - IDS_2078 "Pritisnite F8+F12 za otpustanje miša" - IDS_2079 "Pritisnite F8+F12 ili srednji gumb miša za otpuštanje miša" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Bus" - IDS_2082 "Datoteka" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "Provjeri BPB" - IDS_2089 "KB" - IDS_2090 "Nije moguće inicijalizirati renderer." - IDS_2091 "Standard" - IDS_2092 "%i stanje čekanja" - IDS_2093 "Tip" - IDS_2094 "Postavljanje PCap-a nije uspjelo" - IDS_2095 "Nema PCap uređaja" - IDS_2096 "Nevažeći PCap uređaj" - IDS_2097 "Standardna palica za igru s 2 tipke" - IDS_2098 "Standardna palica za igru s 4 tipke" - IDS_2099 "Standardna palica za igru s 6 tipke" - IDS_2100 "Standardna palica za igru s 8 tipke" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "Bez" - IDS_2105 "Nije moguće učitati ubrzivače tipkovnice." - IDS_2106 "Nije moguće registrirati neobrađeni unos." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Disketa %i (%s): %ls" - IDS_2110 "Sve slike (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Napredne sektorske slike (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Osnovne sektorske slike (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux slike (*.FDI)\0*.FDI\0Površinske slike (*.86F;*.MFM)\0*.86F;*.MFM\0Sve datoteke (*.*)\0*.*\0" - IDS_2113 "Jeste li sigurni da želite hard resetirati emulirani sistem?" - IDS_2114 "Jeste li sigurni da želite zatvoriti 86Box?" - IDS_2115 "Nije moguće inicijalizirati GhostScript" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "MO slike (*.IM?;*.MDI)\0*.IM?;*.MDI\0Svi datoteke (*.*)\0*.*\0" - IDS_2118 "Dobrodošli u 86Box!" - IDS_2119 "Uunutarnji kontroler" - IDS_2120 "Izlazi" - IDS_2121 "Nisu pronađene ROM datoteke" - IDS_2122 "Želite li spremiti postavke?" - IDS_2123 "Ovo će napraviti hard resetiranje emuliranog sistema." - IDS_2124 "Spremaj" - IDS_2125 "O programu 86Box" - IDS_2126 "86Box verzija " EMU_VERSION - - IDS_2127 "Emulator starih računala\n\nAutori: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, i drugi.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, i drugi.\n\nPreveo: dob205\n\nObjavljeno pod licencom GNU General Public License, verzija 2 ili novije. Za više informacija pogledajte datoteku LICENCE." - IDS_2128 "U redu" - IDS_2129 "Hardver nije dostupan" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Provjerite je li " LIB_NAME_PCAP " instaliran i jeste li na mreži, kompadibilnoj s " LIB_NAME_PCAP "." - IDS_2131 "Nevažeća konfiguracija" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " je potrebno za automatsku konverziju PostScript datoteke u PDF datoteke.\n\nSvi dokumenti poslani na generički PostScript pisač bit će spremljeni kao PostScript (.ps) datoteke." - IDS_2135 "Ulazim u cijelozaslonski način" - IDS_2136 "Ne pokazi više ovu poruku" - IDS_2137 "Ne izlazi" - IDS_2138 "Resetiraj" - IDS_2139 "Ne resetiraj" - IDS_2140 "MO slike (*.IM?;*.MDI)\0*.IM?;*.MDI\0Sve datoteke (*.*)\0*.*\0" - IDS_2141 "CD-ROM slike (*.ISO;*.CUE)\0*.ISO;*.CUE\0Sve datoteke (*.*)\0*.*\0" - IDS_2142 "Konfiguracija uređaja %hs " - IDS_2143 "Ekran u stanju mirovanja" - IDS_2144 "OpenGL shaderi (*.GLSL)\0*.GLSL\0Sve datoteke (*.*)\0*.*\0" - IDS_2145 "OpenGL opcije" - IDS_2146 "Učitavate nepodržanu konfiguraciju" - IDS_2147 "Filtriranje tipa CPU-a na temelju odabranog sistema onemogućeno je za ovaj emulirani sistem.\n\nOvo omogućuje odabir procesora koji inače nisu kompatibilne s odabranog sistem. Međutim, možete naići na na nekompatibilnosti s BIOS-om sustava ili drugim softverom.\n\nOmogućavanje ove postavke nije službeno podržano i sva prijava o greškama mogu biti zatvorena kao ""invalid""." - IDS_2148 "Nastavi" - IDS_2149 "Audio kaseta: %s" - IDS_2150 "Slike audio kasete (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Sve datoteke (*.*)\0*.*\0" - IDS_2151 "Kaseta %i: %ls" - IDS_2152 "Slike kasete (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Sve datoteke (*.*)\0*.*\0" - IDS_2153 "Nije moguće inicijalizirati renderer" - IDS_2154 "Nije moguće inicijalizirati OpenGL (3.0 jezgra) renderer. Molimte koristite drugi renderer." - IDS_2155 "Nastavi" - IDS_2156 "Pauziraj" - IDS_2157 "Stisni Ctrl+Alt+Del" - IDS_2158 "Stisni Ctrl+Alt+Esc" - IDS_2159 "Ponovno pokretanje" - IDS_2160 "ACPI bazirano gašenje" - IDS_2161 "Postavke" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Tvrdi disk (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLL ili ESDI CD-ROM pogoni nisu nikada postojali" - IDS_4100 "Prilagođeno..." - IDS_4101 "Prilagođeno (veliko)..." - IDS_4102 "Dodajte novi tvrdi disk" - IDS_4103 "Dodajte postojeći tvrdi disk" - IDS_4104 "HDI disk image datoteke ne mogu biti veće od 4 GB." - IDS_4105 "Slike tvrdog diska ne mogu biti veće od 127 GB." - IDS_4106 "Slike za tvrde diskove (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Sve datoteke (*.*)\0*.*\0" - IDS_4107 "Nije moguće pročitati datoteku" - IDS_4108 "Nije moguće napisati datoteku" - IDS_4109 "HDI ili HDX slike s veličinom sektora koja nije 512 kB nisu podržane." - IDS_4110 "USB nije još podržano" - IDS_4111 "Slika diska već postoji" - IDS_4112 "Molimte unesite važeći naziv datoteke." - IDS_4113 "Slika je stvorena" - IDS_4114 "Provjerite je li postoji datoteka i je li čitljiva." - IDS_4115 "Provjerite je li se datoteka sprema u mapu s dopuštenjima za pisanje." - IDS_4116 "Slika diska je prevelika" - IDS_4117 "Ne zaboravite stvoriti particije i formatirati ih na novom disku." - IDS_4118 "Odabrana datoteka bit će prebrisana. Jeste li sigurni da želite koristiti ovu daoteku?" - IDS_4119 "Nepodržana slika diska" - IDS_4120 "Prepiši" - IDS_4121 "Ne prepiši" - IDS_4122 "Slika neobrađenih podataka (.img)" - IDS_4123 "HDI slika (.hdi)" - IDS_4124 "HDX slika (.hdx)" - IDS_4125 "VHD fiksne veličine (.vhd)" - IDS_4126 "VHD dinamičke veličine (.vhd)" - IDS_4127 "Različiti VHD (.vhd)" - IDS_4128 "Veliki blokovi (2 MB)" - IDS_4129 "Mali blokovi (512 KB)" - IDS_4130 "VHD slike (*.VHD)\0*.VHD\0Sve datoteke (*.*)\0*.*\0" - IDS_4131 "Izaberi matičnu sliku VHD" - IDS_4132 "To bi moglo značiti da je matična slika promijenjena nakon što je stvorena različita slika.\n\nTo se također može dogoditi ako su slike premještene ili kopirane, ili greška u programu koji je stvorio ovaj disk.\n\nŽelite li popraviti vremenske oznake?" - IDS_4133 "Vremenske ozanke matične i poređenog diska ne odgovaraju." - IDS_4134 "Ne mogu popraviti vremensku oznaku slike VHD." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Deaktivirano" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Deaktivirano" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1,2 MB" - IDS_5895 "1,25 MB" - IDS_5896 "1,44 MB" - IDS_5897 "DMF (1024 clusteri)" - IDS_5898 "DMF (2048 clusteri)" - IDS_5899 "2,88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3,5"" 128 MB (ISO 10090)" - IDS_5903 "3,5"" 230 MB (ISO 13963)" - IDS_5904 "3,5"" 540 MB (ISO 15498)" - IDS_5905 "3,5"" 640 MB (ISO 15498)" - IDS_5906 "3,5"" 1.3 GB (GigaMO)" - IDS_5907 "3,5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5,25"" 600 MB" - IDS_5909 "5,25"" 650 MB" - IDS_5910 "5,25"" 1 GB" - IDS_5911 "5,25"" 1.3 GB" - - IDS_6144 "Savršeni broj okretaja u minuti" - IDS_6145 "1% ispod savršenog broja okretaja" - IDS_6146 "1,5% ispod savršenog broja okretaja" - IDS_6147 "2% ispod savršenog broja okretaja" - - IDS_7168 "(Zadana postavka operativnog sustava)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Croatian (hr-HR) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/hu-HU.rc b/src/win/languages/hu-HU.rc deleted file mode 100644 index 52189426a..000000000 --- a/src/win/languages/hu-HU.rc +++ /dev/null @@ -1,640 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Hungarian resources -// -// Translated by Laci bá', 2021 -// - -//#define TRANSLATORS_NAME "Laci bá'" - -#ifdef _WIN32 -LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Művelet" - BEGIN - MENUITEM "A &billentyűzet elfogást igényel", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "A &jobb oldali CTRL a bal ALT", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "Hardveres &újraindítás...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Szüneteltetés", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "&Kilépés...", IDM_ACTION_EXIT - END - POPUP "&Nézet" - BEGIN - MENUITEM "Állapotsor &elrejtése", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Átméretezhető ablak", IDM_VID_RESIZE - MENUITEM "Méret és pozíció &megjegyzése", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "&Megjelenítő" - BEGIN - MENUITEM "&SDL (Szoftveres)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardveres)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "Méretek kézi megadása...", IDM_VID_SPECIFY_DIM - MENUITEM "&Rögzített 4:3 képarány", IDM_VID_FORCE43 - POPUP "&Ablak méretezési tényező" - BEGIN - MENUITEM "&0,5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1,&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Szűrési mód" - BEGIN - MENUITEM "&Szomszédos", IDM_VID_FILTER_NEAREST - MENUITEM "&Lineáris", IDM_VID_FILTER_LINEAR - END - MENUITEM "Hi&DPI méretezés", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Teljes képernyő\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Teljes képernyős &méretezés" - BEGIN - MENUITEM "&Nyújtás a teljes képernyőre", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Négyzetes képpontok (aránytartás)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Egész tényezős nagyítás", IDM_VID_FS_INT - END - POPUP "E&GA/(S)VGA beállítások" - BEGIN - MENUITEM "&Invertált VGA kijelző", IDM_VID_INVERT - POPUP "VGA képernyő &típusa" - BEGIN - MENUITEM "RGB &színes", IDM_VID_GRAY_RGB - MENUITEM "&RGB szürkeárnyalatos", IDM_VID_GRAY_MONO - MENUITEM "&Gyömbér kijelző", IDM_VID_GRAY_AMBER - MENUITEM "&Zöld kijelző", IDM_VID_GRAY_GREEN - MENUITEM "&Fehér kijelző", IDM_VID_GRAY_WHITE - END - POPUP "Szürkéskála &konzerziós eljárás" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Átlag szerint", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/E&GA/(S)VGA túlpásztázás", IDM_VID_OVERSCAN - MENUITEM "Kontraszt illesztése &monokróm kijelzőhöz", IDM_VID_CGACON - END - MENUITEM "&Média", IDM_MEDIA - POPUP "&Eszközök" - BEGIN - MENUITEM "&Konfigurálás...", IDM_CONFIG - MENUITEM "Állapotsori ikonok &frissítése", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "&Képernyőkép készítése\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Beállítások...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "&Discord integráció engedélyezése", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Hangerőszabályzó...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Nyomkövetés megkezdése\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Nyomkövetés befejezése\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Súgó" - BEGIN - MENUITEM "&Dokumentáció...", IDM_DOCS - MENUITEM "A 86Box &névjegye...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Új képfájl létrehozása...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Meglévő képfájl &megnyitása...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Meglévő képfájl megnyitása (&írásvédett)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Felvétel", IDM_CASSETTE_RECORD - MENUITEM "&Lejátszás", IDM_CASSETTE_PLAY - MENUITEM "&Visszatekerés az elejére", IDM_CASSETTE_REWIND - MENUITEM "&Előretekerés a végére", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "&Kiadás", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "Kép&fájl...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "&Kiadás", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Új képfájl létrehozása...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Meglévő képfájl &megnyitása...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Meglévő képfájl megnyitása (&írásvédett)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&xportálás 86F formátumba...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "&Kiadás", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Némítás", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "&Kiadás", IDM_CDROM_EMPTY - MENUITEM "Előző képfájl &újratöltése", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Meglévő képfájl &megnyitása...", IDM_CDROM_IMAGE - MENUITEM "&Mappa...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Új képfájl létrehozása...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Meglévő képfájl &megnyitása...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Meglévő képfájl megnyitása (&írásvédett)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "Kiadás", IDM_ZIP_EJECT - MENUITEM "Előző képfájl &újratöltése", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Új képfájl létrehozása...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Meglévő képfájl &megnyitása...", IDM_MO_IMAGE_EXISTING - MENUITEM "Meglévő képfájl megnyitása (&írásvédett)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "Kiadás", IDM_MO_EJECT - MENUITEM "Előző képfájl &újratöltése", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "Cél &képkockasebesség" - BEGIN - MENUITEM "&Szinkronizálás a videóval ", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 fps", IDM_VID_GL_FPS_25 - MENUITEM "&30 fps", IDM_VID_GL_FPS_30 - MENUITEM "&50 fps", IDM_VID_GL_FPS_50 - MENUITEM "&60 fps", IDM_VID_GL_FPS_60 - MENUITEM "&75 fps", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "Shader &kiválasztása...", IDM_VID_GL_SHADER - MENUITEM "Shader &eltávolítása", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Beállítások" -#define STR_SND_GAIN "Hangerőszabályzó" -#define STR_NEW_FLOPPY "Új képfájl létrehozása" -#define STR_CONFIG "Konfigurálás" -#define STR_SPECIFY_DIM "Főablak méreteinek megadása" - -#define STR_OK "OK" -#define STR_CANCEL "Mégse" -#define STR_GLOBAL "Beállítások mentése &globális alapértékként" -#define STR_DEFAULT "&Alapértelmezett" -#define STR_LANGUAGE "Nyelv:" -#define STR_ICONSET "Ikonkészlet:" - -#define STR_GAIN "Hangerő" - -#define STR_FILE_NAME "Fájlnév:" -#define STR_DISK_SIZE "Méret:" -#define STR_RPM_MODE "RPM-mód:" -#define STR_PROGRESS "Folyamat:" - -#define STR_WIDTH "Szélesség:" -#define STR_HEIGHT "Magasság:" -#define STR_LOCK_TO_SIZE "Rögzítés a megadott méretre" - -#define STR_MACHINE_TYPE "Géptípus:" -#define STR_MACHINE "Számítógép:" -#define STR_CONFIGURE "Beállítások..." -#define STR_CPU_TYPE "Processzor:" -#define STR_CPU_SPEED "Seb.:" -#define STR_FPU "FPU-egység:" -#define STR_WAIT_STATES "Várak. ciklusok:" -#define STR_MB "MB" -#define STR_MEMORY "Memória:" -#define STR_TIME_SYNC "Idő szinkronizáció" -#define STR_DISABLED "Letiltva" -#define STR_ENABLED_LOCAL "Engedélyezve (helyi idő)" -#define STR_ENABLED_UTC "Engedélyezve (UTC)" -#define STR_DYNAREC "Dinamikus újrafordítás" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Videokártya:" -#define STR_VIDEO_2 "Videokártya 2:" -#define STR_VOODOO "Voodoo-gyorsítókártya" -#define STR_IBM8514 "IBM 8514/A-gyorsítókártya" -#define STR_XGA "XGA-gyorsítókártya" - -#define STR_MOUSE "Egér:" -#define STR_JOYSTICK "Játékvezérlő:" -#define STR_JOY1 "Játékvez. 1..." -#define STR_JOY2 "Játékvez. 2..." -#define STR_JOY3 "Játékvez. 3..." -#define STR_JOY4 "Játékvez. 4..." - -#define STR_SOUND1 "Hangkártya 1:" -#define STR_SOUND2 "Hangkártya 2:" -#define STR_SOUND3 "Hangkártya 3:" -#define STR_SOUND4 "Hangkártya 4:" -#define STR_MIDI_OUT "MIDI-kimenet:" -#define STR_MIDI_IN "MIDI-bemenet:" -#define STR_MPU401 "Különálló MPU-401" -#define STR_FLOAT "FLOAT32 használata" -#define STR_FM_DRIVER "FM szintetizátor meghajtó" -#define STR_FM_DRV_NUKED "Nuked (pontosabb)" -#define STR_FM_DRV_YMFM "YMFM (gyorsabb)" - -#define STR_NET_TYPE "Hálózati típusa:" -#define STR_PCAP "PCap eszköz:" -#define STR_NET "Hálózati kártya:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "COM1 eszköz:" -#define STR_COM2 "COM2 eszköz:" -#define STR_COM3 "COM3 eszköz:" -#define STR_COM4 "COM4 eszköz:" -#define STR_LPT1 "LPT1 eszköz:" -#define STR_LPT2 "LPT2 eszköz:" -#define STR_LPT3 "LPT3 eszköz:" -#define STR_LPT4 "LPT4 eszköz:" -#define STR_SERIAL1 "Soros port 1" -#define STR_SERIAL2 "Soros port 2" -#define STR_SERIAL3 "Soros port 3" -#define STR_SERIAL4 "Soros port 4" -#define STR_PARALLEL1 "Párhuzamos port 1" -#define STR_PARALLEL2 "Párhuzamos port 2" -#define STR_PARALLEL3 "Párhuzamos port 3" -#define STR_PARALLEL4 "Párhuzamos port 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Merevl.-vezérlő:" -#define STR_FDC "Floppy-vezérlő:" -#define STR_IDE_TER "Harmadlagos IDE-vezérlő" -#define STR_IDE_QUA "Negyedleges IDE-vezérlő" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Gazdaadapt. 1:" -#define STR_SCSI_2 "Gazdaadapt. 2:" -#define STR_SCSI_3 "Gazdaadapt. 3:" -#define STR_SCSI_4 "Gazdaadapt. 4:" -#define STR_CASSETTE "Magnókazetta" - -#define STR_HDD "Merevlemezek:" -#define STR_NEW "&Új..." -#define STR_EXISTING "&Megnyitás..." -#define STR_REMOVE "&Eltávolítás" -#define STR_BUS "Busz:" -#define STR_CHANNEL "Csatorna:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Kiválasztás..." -#define STR_SECTORS "Szektor:" -#define STR_HEADS "Fej:" -#define STR_CYLS "Cilinder:" -#define STR_SIZE_MB "Méret (MB):" -#define STR_TYPE "Típus:" -#define STR_IMG_FORMAT "Formátum:" -#define STR_BLOCK_SIZE "Blokkméret:" - -#define STR_FLOPPY_DRIVES "Floppy-meghajtók:" -#define STR_TURBO "Turbó időzítés" -#define STR_CHECKBPB "BPB ellenőrzés" -#define STR_CDROM_DRIVES "CD-ROM meghajtók:" -#define STR_CD_SPEED "Seb.:" - -#define STR_MO_DRIVES "MO-meghajtók:" -#define STR_ZIP_DRIVES "ZIP-meghajtók:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA RTC (óra):" -#define STR_ISAMEM "ISA memóriabővítők" -#define STR_ISAMEM_1 "Kártya 1:" -#define STR_ISAMEM_2 "Kártya 2:" -#define STR_ISAMEM_3 "Kártya 3:" -#define STR_ISAMEM_4 "Kártya 4:" -#define STR_BUGGER "ISABugger eszköz" -#define STR_POSTCARD "POST kártya" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Hiba" - IDS_2050 "Végzetes hiba" - IDS_2051 " - PAUSED" - IDS_2052 "Használja a Ctrl+Alt+PgDn gombokat az ablakhoz való visszatéréshez." - IDS_2053 "Sebesség" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIP-lemezképek (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "A 86Box nem talált használható ROM-képeket\n\nKérem töltse le a ROM készletet és bontsa ki a ""roms"" könyvtárba." - IDS_2057 "(üres)" - IDS_2058 "ZIP-lemezképek (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Minden fájl (*.*)\0*.*\0" - IDS_2059 "Turbó" - IDS_2060 "Bekapcsolva" - IDS_2061 "Kikapcsolva" - IDS_2062 "Minden képfájl (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Alapvető szektor képfájlok (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Felületi képfájlok (*.86F)\0*.86F\0" - IDS_2063 "A számítógép ""%hs"" nem elérhető a ""roms/machines"" mappából hiányzó ROM-képek miatt. Ehelyett egy másik gép kerül futtatásra." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "A videokártya ""%hs"" nem elérhető a ""roms/video"" mappából hiányzó ROM-képek miatt. Ehelyett egy másik kártya kerül futtatásra." - IDS_2065 "Számítógép" - IDS_2066 "Megjelenítő" - IDS_2067 "Beviteli eszközök" - IDS_2068 "Hang" - IDS_2069 "Hálózat" - IDS_2070 "Portok (COM és LPT)" - IDS_2071 "Tárolóvezérlők" - IDS_2072 "Merevlemezek" - IDS_2073 "Floppy és CD-ROM meghajtók" - IDS_2074 "Egyéb cserélhető tárolók" - IDS_2075 "Egyéb perifériák" - IDS_2076 "Felületi képfájlok (*.86F)\0*.86F\0" - IDS_2077 "Kattintson az egér elfogásához" - IDS_2078 "Nyomja meg az F8+F12-t az egér elengédéséhez" - IDS_2079 "Nyomja meg az F8+F12-t vagy a középső gombot az egér elengédéséhez" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Busz" - IDS_2082 "Fájl" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "BPB ellenőrzése" - IDS_2089 "KB" - IDS_2090 "Nem sikerült inicializálni a videó megjelenítőt." - IDS_2091 "Alapértelmezett" - IDS_2092 "%i várakozási ciklus(ok)" - IDS_2093 "Típus" - IDS_2094 "Nem sikerült a PCap beállítása" - IDS_2095 "Nem találhatóak PCap eszközök" - IDS_2096 "Érvénytelen PCap eszköz" - IDS_2097 "Szabványos 2-gombos játékvezérlő(k)" - IDS_2098 "Szabványos 4-gombos játékvezérlő" - IDS_2099 "Szabványos 6-gombos játékvezérlő" - IDS_2100 "Szabványos 8-gombos játékvezérlő" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "Nincs" - IDS_2105 "Nem lehet betölteni a billentyűzetgyorsítókat." - IDS_2106 "A közvetlen nyers bevitel regisztrálása nem sikerült." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Floppy %i (%s): %ls" - IDS_2110 "Minden képfájl (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Továbbfejlesztett szektor képek (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Alapvető szektor képek (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux képekfájlok (*.FDI)\0*.FDI\0Felületi képfájlok (*.86F;*.MFM)\0*.86F;*.MFM\0Minden fájl (*.*)\0*.*\0" - IDS_2113 "Biztosan szeretné újraindítani az emulált gépet?" - IDS_2114 "Biztos benne, hogy ki szeretne lépni a 86Box-ból?" - IDS_2115 "Nem sikerült inicializálni a Ghostscript-et" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "MO-képfájlok (*.IM?;*.MDI)\0*.IM?;*.MDI\0Minden fájl (*.*)\0*.*\0" - IDS_2118 "Üdvözli önt az 86Box!" - IDS_2119 "Integrált vezérlő" - IDS_2120 "Kilépés" - IDS_2121 "Nem találhatóak meg a ROM-képek" - IDS_2122 "Szeretné menteni a beállításokat?" - IDS_2123 "Ezzel hardveresen újraindítja az emulált gépet." - IDS_2124 "Mentés" - IDS_2125 "A 86Box névjegye" - IDS_2126 "86Box v" EMU_VERSION - IDS_2127 "Régi számítógépek emulátora\n\nFejlesztők: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nFordította: Laci bá'\n\nMegjelent a GNU General Public License v2 vagy újabb alatt. További információért lásd a LICENSE fájlt." - IDS_2128 "OK" - IDS_2129 "Hardver nem elérhető" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Győződjön meg hogy a(z) " LIB_NAME_PCAP " telepítve van és jelenleg a " LIB_NAME_PCAP "-kompatibilis kapcsolatot használja." - IDS_2131 "Érvénytelen konfiguráció" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " szükséges a PostScript fájlok PDF formátumba való automatikus konvertálásához.\n\nAz általános PostScript nyomtatóra küldött dokumentumok PostScript (.ps) fájlként kerülnek mentésre." - IDS_2135 "Teljes képernyős módra váltás" - IDS_2136 "Ne jelenítse meg újra ezt az üzenetet " - IDS_2137 "Ne lépjen ki" - IDS_2138 "Újraindítás" - IDS_2139 "Ne indítsa újra" - IDS_2140 "MO-képfájlok (*.IM?;*.MDI)\0*.IM?;*.MDI\0Minden fájl (*.*)\0*.*\0" - IDS_2141 "CD-ROM-képek (*.ISO;*.CUE)\0*.ISO;*.CUE\0Minden fájl (*.*)\0*.*\0" - IDS_2142 "%hs eszközkonfiguráció" - IDS_2143 "Képernyő alvó módban" - IDS_2144 "OpenGL Shaderek (*.GLSL)\0*.GLSL\0Minden fájl (*.*)\0*.*\0" - IDS_2145 "OpenGL beállítások" - IDS_2146 "Egy nem támogatott konfigurációt tölt be" - IDS_2147 "A kiválasztott gépen alapuló CPU-típusszűrés le van tiltva ezen az emulált gépen.\n\nEz lehetővé teszi olyan CPU kiválasztását, amely egyébként nem kompatibilis a kiválasztott géppel. Előfordulhat azonban, hogy nem kompatibilis a gép BIOS-ával vagy más szoftverekkel.\n\nA beállítás engedélyezése hivatalosan nem támogatott, és a benyújtott hibajelentéseket érvénytelenként lezárhatjuk." - IDS_2148 "Folytatás" - IDS_2149 "Magnókazetta: %s" - IDS_2150 "Magnókazetta-képek (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Minden fájl (*.*)\0*.*\0" - IDS_2151 "ROM-kazetta %i: %ls" - IDS_2152 "ROM-kazetta képek (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Minden fájl (*.*)\0*.*\0" - IDS_2153 "Hiba történt a renderelő inicializálásakor" - IDS_2154 "Az OpenGL (3.0 Core) megjelenítő-motort nem sikerült inicializálni. Kérem használjon másik renderelőt." - IDS_2155 "Resume execution" - IDS_2156 "Pause execution" - IDS_2157 "Press Ctrl+Alt+Del" - IDS_2158 "Press Ctrl+Alt+Esc" - IDS_2159 "Hard reset" - IDS_2160 "ACPI shutdown" - IDS_2161 "Settings" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Merevlemez (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLL vagy ESDI CD-ROM meghajtók soha nem léteztek" - IDS_4100 "Egyéni..." - IDS_4101 "Egyéni (nagy)..." - IDS_4102 "Új merevlemez hozzáadása" - IDS_4103 "Meglévő merevlemez hozzáadása" - IDS_4104 "A HDI lemezképek nem lehetnek nagyobbak 4 GB-nál." - IDS_4105 "A lemezképek mérete nem haladhatja meg a 127 GB-ot." - IDS_4106 "Merevlemez-képfájlok (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Minden fájl (*.*)\0*.*\0" - IDS_4107 "A fájl nem olvasható" - IDS_4108 "A fájl nem írható" - IDS_4109 "Az 512-től eltérő szektorméretű HDI vagy HDX képek nem támogatottak." - IDS_4110 "Az USB még nem támogatott" - IDS_4111 "A lemezképfájl már létezik" - IDS_4112 "Adjon meg egy érvényes fájlnevet." - IDS_4113 "A lemezképfájl létrehozásra került" - IDS_4114 "Győződjön meg arról, hogy a fájl létezik és olvasható." - IDS_4115 "Győződjön meg arról, hogy a fájlt egy írható könyvtárba menti." - IDS_4116 "A lemezképfájl túl nagy" - IDS_4117 "Ne felejtse el particionálni és formázni az újonnan létrehozott meghajtót." - IDS_4118 "A kiválasztott fájl felülírásra kerül. Biztos, hogy ezt kívánja használni?" - IDS_4119 "Nem támogatott lemezkép" - IDS_4120 "Felülírás" - IDS_4121 "Ne írja felül" - IDS_4122 "Nyers lemezkép (.img)" - IDS_4123 "HDI-lemezkép (.hdi)" - IDS_4124 "HDX-lemezkép (.hdx)" - IDS_4125 "Rögzített méretű VHD (.vhd)" - IDS_4126 "Dinamikusan bővülő VHD (.vhd)" - IDS_4127 "Különbség-VHD (.vhd)" - IDS_4128 "Nagy blokkméret (2 MB)" - IDS_4129 "Kis blokkméret (512 KB)" - IDS_4130 "VHD fájlok (*.VHD)\0*.VHD\0Minden fájl (*.*)\0*.*\0" - IDS_4131 "Válassza ki a szülő VHD-t" - IDS_4132 "Ez azt jelentheti, hogy a szülőkép módosult az eltérő kép létrehozása után.\n\nEz akkor is előfordulhat, ha a képfájlokat áthelyezték vagy másolták, vagy a lemezt létrehozó program hibája miatt.\n\nSzeretné kijavítani az időbélyegeket?" - IDS_4133 "A szülő- és a gyermeklemez időbélyegei nem egyeznek" - IDS_4134 "Nem sikerült kijavítani a VHD időbélyegét." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Letiltva" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Letiltva" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (1024 klaszter)" - IDS_5898 "DMF (2048 klaszter)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "Tökéletes RPM" - IDS_6145 "1%-kal a tökéletes RPM alatt" - IDS_6146 "1.5%-kal a tökéletes RPM alatt" - IDS_6147 "2%-kal a tökéletes RPM alatt" - - IDS_7168 "(A rendszer nyelve)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Hungarian resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/it-IT.rc b/src/win/languages/it-IT.rc deleted file mode 100644 index e5868caa0..000000000 --- a/src/win/languages/it-IT.rc +++ /dev/null @@ -1,637 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Italian (IT-it) resources - -#ifdef _WIN32 -LANGUAGE LANG_ITALIAN, SUBLANG_ITALIAN -#pragma code_page(65001) -#endif //_WIN32 - -// explorerdotexe -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Azione" - BEGIN - MENUITEM "&Tastiera richiede la cattura", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&CTRL destro è ALT sinistro", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Riavvia...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Pausa", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "E&sci...", IDM_ACTION_EXIT - END - POPUP "&Visualizza" - BEGIN - MENUITEM "&Nascondi barra di stato", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Finestra ridimensionabile", IDM_VID_RESIZE - MENUITEM "R&icorda dimensioni e posizione", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "Re&nderer" - BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "Specifica dimensioni...", IDM_VID_SPECIFY_DIM - MENUITEM "F&orza display 4:3", IDM_VID_FORCE43 - POPUP "&Fattore scalare della finestra" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Metodo filtro" - BEGIN - MENUITEM "&Dal più vicino", IDM_VID_FILTER_NEAREST - MENUITEM "&Lineare", IDM_VID_FILTER_LINEAR - END - MENUITEM "Scala Hi&DPI", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Schermo intero\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Modalità adattamento &schermo intero" - BEGIN - MENUITEM "&Adatta a schermo intero", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Pixel quadrati (mantiene l'aspetto)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Scala intera", IDM_VID_FS_INT - END - POPUP "Impostazioni E&GA/(S)VGA" - BEGIN - MENUITEM "&Invertire monitor VGA", IDM_VID_INVERT - POPUP "Schermi VGA &" - BEGIN - MENUITEM "RGB &Color", IDM_VID_GRAY_RGB - MENUITEM "&RGB Monocroma", IDM_VID_GRAY_MONO - MENUITEM "&Monitor ambra", IDM_VID_GRAY_AMBER - MENUITEM "&Monitor verde", IDM_VID_GRAY_GREEN - MENUITEM "&Monitor bianco", IDM_VID_GRAY_WHITE - END - POPUP "Conversione &scala grigia" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&AMedia", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "Sovrascansione CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN - MENUITEM "Cambia il contrasto per &display monocromatici", IDM_VID_CGACON - END - MENUITEM "&Dispositivi", IDM_MEDIA - POPUP "&Strumenti" - BEGIN - MENUITEM "&Impostazioni...", IDM_CONFIG - MENUITEM "&Aggiorna icone della barra di stato", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Cattura schermata\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Preferenze...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Abilita &integrazione Discord", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "Guadagno &suono...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Inizia traccia\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Ferma traccia\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&?" - BEGIN - MENUITEM "&Documentazione...", IDM_DOCS - MENUITEM "&Informazioni su 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nuova immagine...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Immagine esistente...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Immagine esistente (&protezione contro scrittura)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Registra", IDM_CASSETTE_RECORD - MENUITEM "R&iproduci", IDM_CASSETTE_PLAY - MENUITEM "Ri&avvolgi all'inizio", IDM_CASSETTE_REWIND - MENUITEM "A&vanti veloce alla fine", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "&Espelli", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Immagine...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "&Espelli", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nuova immagine...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Immagine esistente...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Immagine esistente (&protezione contro scrittura)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&sporta in 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "&Espelli", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Muto", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "&Espelli", IDM_CDROM_EMPTY - MENUITEM "&Ricarica l'immagine precedente", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Immagine...", IDM_CDROM_IMAGE - MENUITEM "&Cartella...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nuova immagine...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Immagine esistente...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Immagine esistente (&protezione contro scrittura)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Espelli", IDM_ZIP_EJECT - MENUITEM "&Ricarica l'immagine precedente", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nuova immagine...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Immagine esistente...", IDM_MO_IMAGE_EXISTING - MENUITEM "Immagine esistente (&protezione contro scrittura)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Espelli", IDM_MO_EJECT - MENUITEM "&Ricarica l'immagine precedente", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "Imposta obiettivo &fotogrammi" - BEGIN - MENUITEM "&Sincronizza col video", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 FPS", IDM_VID_GL_FPS_25 - MENUITEM "&30 FPS", IDM_VID_GL_FPS_30 - MENUITEM "&50 FPS", IDM_VID_GL_FPS_50 - MENUITEM "&60 FPS", IDM_VID_GL_FPS_60 - MENUITEM "&75 FPS", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Seleziona shader...", IDM_VID_GL_SHADER - MENUITEM "&Rimuovi shader", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Preferenze" -#define STR_SND_GAIN "Guadagno del suono" -#define STR_NEW_FLOPPY "Nuova immagine" -#define STR_CONFIG "Impostazioni" -#define STR_SPECIFY_DIM "Specifica dimensioni della finestra principale" - -#define STR_OK "OK" -#define STR_CANCEL "Annulla" -#define STR_GLOBAL "Salva queste impostazioni come &predefinite globali" -#define STR_DEFAULT "&Predefinito" -#define STR_LANGUAGE "Lingua:" -#define STR_ICONSET "Pacchetto di icone:" - -#define STR_GAIN "Guadagno" - -#define STR_FILE_NAME "Nome file:" -#define STR_DISK_SIZE "Dimensioni disco:" -#define STR_RPM_MODE "Modalità RPM:" -#define STR_PROGRESS "Progresso:" - -#define STR_WIDTH "Larghezza:" -#define STR_HEIGHT "Altezza:" -#define STR_LOCK_TO_SIZE "Blocca in queste dimensioni" - -#define STR_MACHINE_TYPE "Tipo di piastra madre:" -#define STR_MACHINE "Piastra madre:" -#define STR_CONFIGURE "Configura" -#define STR_CPU_TYPE "Tipo del CPU:" -#define STR_CPU_SPEED "Veloc.:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Stati di attesa:" -#define STR_MB "MB" -#define STR_MEMORY "Memoria:" -#define STR_TIME_SYNC "Sincronizzazione dell'ora" -#define STR_DISABLED "Disabilitata" -#define STR_ENABLED_LOCAL "Abilitata (ora locale)" -#define STR_ENABLED_UTC "Abilitata (UTC)" -#define STR_DYNAREC "Ricompilatore dinamico" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Video:" -#define STR_VIDEO_2 "Video 2:" -#define STR_VOODOO "Grafica Voodoo" -#define STR_IBM8514 "Grafica IBM 8514/A" -#define STR_XGA "Grafica XGA" - -#define STR_MOUSE "Mouse:" -#define STR_JOYSTICK "Joystick:" -#define STR_JOY1 "Joystick 1..." -#define STR_JOY2 "Joystick 2..." -#define STR_JOY3 "Joystick 3..." -#define STR_JOY4 "Joystick 4..." - -#define STR_SOUND1 "Scheda audio 1:" -#define STR_SOUND2 "Scheda audio 2:" -#define STR_SOUND3 "Scheda audio 3:" -#define STR_SOUND4 "Scheda audio 4:" -#define STR_MIDI_OUT "Uscita MIDI:" -#define STR_MIDI_IN "Entrata MIDI:" -#define STR_MPU401 "MPU-401 autonomo" -#define STR_FLOAT "Usa suono FLOAT32" -#define STR_FM_DRIVER "Driver sint. FM" -#define STR_FM_DRV_NUKED "Nuked (più accurato)" -#define STR_FM_DRV_YMFM "YMFM (più veloce)" - -#define STR_NET_TYPE "Tipo di rete:" -#define STR_PCAP "Dispositivo PCap:" -#define STR_NET "Scheda di rete:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "Dispositivo COM1:" -#define STR_COM2 "Dispositivo COM2:" -#define STR_COM3 "Dispositivo COM3:" -#define STR_COM4 "Dispositivo COM4:" -#define STR_LPT1 "Dispositivo LPT1:" -#define STR_LPT2 "Dispositivo LPT2:" -#define STR_LPT3 "Dispositivo LPT3:" -#define STR_LPT4 "Dispositivo LPT4:" -#define STR_SERIAL1 "Porta seriale 1" -#define STR_SERIAL2 "Porta seriale 2" -#define STR_SERIAL3 "Porta seriale 3" -#define STR_SERIAL4 "Porta seriale 4" -#define STR_PARALLEL1 "Porta parallela 1" -#define STR_PARALLEL2 "Porta parallela 2" -#define STR_PARALLEL3 "Porta parallela 3" -#define STR_PARALLEL4 "Porta parallela 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Controller HD:" -#define STR_FDC "Controller FD:" -#define STR_IDE_TER "Controller IDE terziario" -#define STR_IDE_QUA "Controller IDE quaternario" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Controller 1:" -#define STR_SCSI_2 "Controller 2:" -#define STR_SCSI_3 "Controller 3:" -#define STR_SCSI_4 "Controller 4:" -#define STR_CASSETTE "Cassetta" - -#define STR_HDD "Hard disk:" -#define STR_NEW "&Nuovo..." -#define STR_EXISTING "&Esistente..." -#define STR_REMOVE "&Rimouvi" -#define STR_BUS "Bus:" -#define STR_CHANNEL "Canale:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Specifica..." -#define STR_SECTORS "Settori:" -#define STR_HEADS "Testine:" -#define STR_CYLS "Cilindri:" -#define STR_SIZE_MB "Dimensioni (MB):" -#define STR_TYPE "Tipo:" -#define STR_IMG_FORMAT "Formato immagine:" -#define STR_BLOCK_SIZE "Dimensioni blocco:" - -#define STR_FLOPPY_DRIVES "Unità floppy:" -#define STR_TURBO "Turbo" -#define STR_CHECKBPB "Verifica BPB" -#define STR_CDROM_DRIVES "Unità CD-ROM:" -#define STR_CD_SPEED "Veloc.:" - -#define STR_MO_DRIVES "Unità magneto-ottiche:" -#define STR_ZIP_DRIVES "Unità ZIP:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "RTC ISA:" -#define STR_ISAMEM "Espansione memoria ISA" -#define STR_ISAMEM_1 "Scheda 1:" -#define STR_ISAMEM_2 "Scheda 2:" -#define STR_ISAMEM_3 "Scheda 3:" -#define STR_ISAMEM_4 "Scheda 4:" -#define STR_BUGGER "Dispositivo ISABugger" -#define STR_POSTCARD "Scheda POST" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Errore" - IDS_2050 "Errore fatale" - IDS_2051 " - PAUSED" - IDS_2052 "Usa Ctrl+Alt+PgDn per tornare alla modalità finestra." - IDS_2053 "Velocità" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "Immagini ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box non può trovare immagini ROM utilizzabili.\n\nPlease download a ROM set and extract it into the ""roms"" directory." - IDS_2057 "(empty)" - IDS_2058 "Immagini ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Tutti i file (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "Acceso" - IDS_2061 "Spento" - IDS_2062 "Tutte le immagini (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Immagini di settori base (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Immagini di superficie (*.86F)\0*.86F\0" - IDS_2063 "La macchina ""%hs"" non è disponibile a causa di immagini ROM mancanti nella directory roms/machines. Cambiando ad una macchina disponibile." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "La scheda video ""%hs"" non è disponibile a causa di immagini ROM mancanti nella directory roms/video. Cambiando ad una scheda video disponibile." - IDS_2065 "Piastra madre" - IDS_2066 "Schermo" - IDS_2067 "Dispositivi di entrata" - IDS_2068 "Audio" - IDS_2069 "Rete" - IDS_2070 "Porte (COM & LPT)" - IDS_2071 "Controller memoria" - IDS_2072 "Hard disk" - IDS_2073 "Unità CD-ROM e Floppy" - IDS_2074 "Altri dispositivi rimuovibili" - IDS_2075 "Altre periferiche" - IDS_2076 "Immagini di superficie (*.86F)\0*.86F\0" - IDS_2077 "Fare clic per catturare mouse" - IDS_2078 "Premi F8+F12 per rilasciare il mouse" - IDS_2079 "Premi F8+F12 o pulsante centrale per rilasciare il mouse" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Bus" - IDS_2082 "File" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "Verifica BPB" - IDS_2089 "KB" - IDS_2090 "Impossibile inizializzare il renderer video." - IDS_2091 "Predefinito" - IDS_2092 "%i stati d'attesa" - IDS_2093 "Tipo" - IDS_2094 "Impossibile impostare PCap" - IDS_2095 "Nessun dispositivo PCap trovato" - IDS_2096 "Dispositivo PCap invalido" - IDS_2097 "Joystick comune da 2 pulsanti" - IDS_2098 "Joystick comune da 4 pulsanti" - IDS_2099 "Joystick comune da 6 pulsanti" - IDS_2100 "Joystick comune da 8 pulsanti" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "Nessuno" - IDS_2105 "Impossibile caricare gli acceleratori da tastiera." - IDS_2106 "Impossibile registrare input raw." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Floppy %i (%s): %ls" - IDS_2110 "Tutte le immagini (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Immagini da settori avanzati (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Imagini da settori basilari (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Immagini flusso (*.FDI)\0*.FDI\0Immagini da superficie (*.86F;*.MFM)\0*.86F;*.MFM\0Tutti i file (*.*)\0*.*\0" - IDS_2113 "Sei sicuro di voler riavviare la macchina emulata?" - IDS_2114 "Sei sicuro di voler uscire da 86Box?" - IDS_2115 "Impossibile inizializzare Ghostscript" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "Immagini MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0Tutti i file (*.*)\0*.*\0" - IDS_2118 "Benvenuti in 86Box!" - IDS_2119 "Controller interno" - IDS_2120 "Esci" - IDS_2121 "Nessune immagini ROM trovate" - IDS_2122 "Vuole salvare queste impostazioni?" - IDS_2123 "Questo riavvierà la macchina emulata." - IDS_2124 "Salva" - IDS_2125 "Informazioni su 86Box" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "Un emulatore di computer vecchi\n\nAutori: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nTradotto da: explorerdotexe\n\nRilasciato sotto la Licenza Pubblica GNU versione 2 o dopo. Vedi LICENSE per maggior informazioni." - IDS_2128 "OK" - IDS_2129 "Hardware non disponibile" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Controlla se " LIB_NAME_PCAP " è installato e che tu sia connesso ad una connessione " LIB_NAME_PCAP " compatibile." - IDS_2131 "Configurazione invalida" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " è richiesto per la conversione automatica di file PostScript a file PDF.\n\nQualsiasi documento mandato alla stampante generica PostScript sarà salvato come file PostScript. (.ps)" - IDS_2135 "Entrando nella modalità schermo intero" - IDS_2136 "Non mostrare più questo messaggio" - IDS_2137 "Non uscire" - IDS_2138 "Riavvia" - IDS_2139 "Non riavviare" - IDS_2140 "Immagini MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0Tutti i file (*.*)\0*.*\0" - IDS_2141 "Immagini CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Tutti i file (*.*)\0*.*\0" - IDS_2142 "Configurazione del dispositivo %hs" - IDS_2143 "Monitor in modalità riposo" - IDS_2144 "Shader OpenGL (*.GLSL)\0*.GLSL\0Tutti i file (*.*)\0*.*\0" - IDS_2145 "Impostazioni OpenGL" - IDS_2146 "Stai caricando una configurazione non supportata" - IDS_2147 "Il filtraggio della tipologia di CPU è disabilitato per la macchina selezionata.\n\nQuesto lo rende possibile scegliere un CPU che è altrimenti incompatibile con la macchina selezionata. Tuttavia, portresti incorrere in incompatibilità con il BIOS della macchina o altri programmi. \n\nL'abilitare di questa impostazione non è ufficialmente supportato e tutte le segnalazioni di errori saranno considerate invalide." - IDS_2148 "Continua" - IDS_2149 "Cassetta: %s" - IDS_2150 "Immagini cassetta (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Tutti i file (*.*)\0*.*\0" - IDS_2151 "Cartuccia %i: %ls" - IDS_2152 "Immagini cartuccia (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Tutti i file (*.*)\0*.*\0" - IDS_2153 "Error initializing renderer" - IDS_2154 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." - IDS_2155 "Resume execution" - IDS_2156 "Pause execution" - IDS_2157 "Press Ctrl+Alt+Del" - IDS_2158 "Press Ctrl+Alt+Esc" - IDS_2159 "Hard reset" - IDS_2160 "ACPI shutdown" - IDS_2161 "Settings" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Hard disk (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "Le unità CD-ROM MFM/RLL o ESDI non sono mai esistite." - IDS_4100 "Personalizzata..." - IDS_4101 "Personalizzata (grande)..." - IDS_4102 "Aggiungi un nuovo disco rigido" - IDS_4103 "Aggiungi un disco rigido esistente" - IDS_4104 "Le immagini HDI non possono essere più grandi di 4 GB." - IDS_4105 "Le immmagini disco non possono essere più grandi di 127 GB." - IDS_4106 "Immagini disco rigido (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Tutti i file (*.*)\0*.*\0" - IDS_4107 "Impossibile leggere il file" - IDS_4108 "Impossibile scrivere al file" - IDS_4109 "Le immagini HDI o HDX con settori di dimensioni diverse da 512 non sono supportati." - IDS_4110 "USB non è ancora supportato" - IDS_4111 "Immagine disco già esiste" - IDS_4112 "Specifica un nome file valido." - IDS_4113 "Immagine disco creata" - IDS_4114 "Controlla che il file esiste e che sia leggibile." - IDS_4115 "Controlla che il file viene salvato ad un percorso con diritti di scrittura" - IDS_4116 "Immagine disco troppo grande" - IDS_4117 "Ricordati di partizionare e formattare il disco appena creato." - IDS_4118 "Il file selezionato sarà sovrascritto, sei sicuro di volerlo usare?" - IDS_4119 "Immagine disco non supportata" - IDS_4120 "Sovrascrivi" - IDS_4121 "Non sovrascrivere" - IDS_4122 "Immagine raw (.img)" - IDS_4123 "Immagine HDI (.hdi)" - IDS_4124 "Immagine HDX (.hdx)" - IDS_4125 "VHD di dimensioni fisse (.vhd)" - IDS_4126 "VHD di dimensioni dinamiche (.vhd)" - IDS_4127 "VHD differenziato (.vhd)" - IDS_4128 "Blocchi larghi (2 MB)" - IDS_4129 "Blocchi piccoli (512 KB)" - IDS_4130 "File VHD (*.VHD)\0*.VHD\0Tutti i file (*.*)\0*.*\0" - IDS_4131 "Seleziona il VHD padre." - IDS_4132 "Questo potrebbe significare che l'immagine padre sia stata modificata dopo la creazione dell'immagine di differenziazione.\n\nPuò anche succedere se i file immagini sono stati spostati o copiati, o da un errore nel programma che ha creato questo disco.\n\nVuoi aggiustare le marcature di tempo?" - IDS_4133 "Le marcature di tempo padre e figlio non corrispondono" - IDS_4134 "Impossibile aggiustare marcature di tempo VHD." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Disabilitato" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Disabilitato" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (cluster 1024)" - IDS_5898 "DMF (cluster 2048)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "RPM perfette" - IDS_6145 "RPM 1% sotto perfezione" - IDS_6146 "RPM 1.5% sotto perfezione" - IDS_6147 "RPM 2% sotto perfezione" - - IDS_7168 "(Predefinito del sistema)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Italian (IT-it) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/ja-JP.rc b/src/win/languages/ja-JP.rc deleted file mode 100644 index 74ae06092..000000000 --- a/src/win/languages/ja-JP.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Japanese resources - -#ifdef _WIN32 -LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "操作(&A)" - BEGIN - MENUITEM "キーボードはキャプチャが必要(&K)", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "右CTRLを左ALTへ変換(&R)", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "ハード リセット(&H)...", IDM_ACTION_HRESET - MENUITEM "Ctrl+Alt+Del(&C)\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+Esc(&E)", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "一時停止(&P)", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "終了(&X)...", IDM_ACTION_EXIT - END - POPUP "表示(&V)" - BEGIN - MENUITEM "ステータスバーを隠す(&H)", IDM_VID_HIDE_STATUS_BAR - MENUITEM "ツールバーを隠す(&T)", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "プライマリ以外のモニターを表示(&S)", IDM_VID_MONITORS - MENUITEM "ウィンドウのサイズを変更可能(&R)", IDM_VID_RESIZE - MENUITEM "ウィンドウのサイズと位置を保存(&E)", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "レンダラー(&N)" - BEGIN - MENUITEM "SDL (ソフトウェア)(&S)", IDM_VID_SDL_SW - MENUITEM "SDL (ハードウェア)(&H)", IDM_VID_SDL_HW - MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL - MENUITEM "OpenGL (3.0 Core)(&G)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "VNC(&V)", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "ディメンションを指定...", IDM_VID_SPECIFY_DIM - MENUITEM "4:3の縦横比を強制表示(&O)", IDM_VID_FORCE43 - POPUP "ウィンドウの表示倍率(&W)" - BEGIN - MENUITEM "0.5x(&0)", IDM_VID_SCALE_1X - MENUITEM "1x(&1)", IDM_VID_SCALE_2X - MENUITEM "1.5x(&5)", IDM_VID_SCALE_3X - MENUITEM "2x(&2)", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "フィルター方式" - BEGIN - MENUITEM "最近傍補間(&N)", IDM_VID_FILTER_NEAREST - MENUITEM "線形補間(&L)", IDM_VID_FILTER_LINEAR - END - MENUITEM "HiDPIスケーリング(&D)", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "全画面表示(&F)\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "全画面の拡大表示モード(&S)" - BEGIN - MENUITEM "ストレッチ モード(&F)", IDM_VID_FS_FULL - MENUITEM "4:3(&4)", IDM_VID_FS_43 - MENUITEM "正方形ピクセル(アスペクト比を維持)(&S)", IDM_VID_FS_KEEPRATIO - MENUITEM "整数倍(&I)", IDM_VID_FS_INT - END - POPUP "E&GA/(S)VGAの設定" - BEGIN - MENUITEM "色反転(&I)", IDM_VID_INVERT - POPUP "画面タイプ(&T)" - BEGIN - MENUITEM "RGB(カラー)(&C)", IDM_VID_GRAY_RGB - MENUITEM "RGB(グレースケール)(&R)", IDM_VID_GRAY_MONO - MENUITEM "モニター(黄色)(&A)", IDM_VID_GRAY_AMBER - MENUITEM "モニター(緑色)(&G)", IDM_VID_GRAY_GREEN - MENUITEM "モニター(白色)(&W)", IDM_VID_GRAY_WHITE - END - POPUP "グレースケール変換タイプ(&C)" - BEGIN - MENUITEM "BT601 (NTSC/PAL)(&6)", IDM_VID_GRAYCT_601 - MENUITEM "BT709 (HDTV)(&7)", IDM_VID_GRAYCT_709 - MENUITEM "平均(&A)", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/EGA/(S)VGAオーバースキャン(&G)", IDM_VID_OVERSCAN - MENUITEM "単色モニター用コントラストを変更(&M)", IDM_VID_CGACON - END - MENUITEM "メディア(&M)", IDM_MEDIA - POPUP "ツール(&T)" - BEGIN - MENUITEM "設定(&S)...", IDM_CONFIG - MENUITEM "ステータスバーのアイコンを更新(&U)", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "スクリーンショットを撮る(&C)\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "環境設定(&P)...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Discord連携機能(&D)", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "音量調整(&G)...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "トレース開始\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "トレース終了\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "ヘルプ(&H)" - BEGIN - MENUITEM "文書(&D)...", IDM_DOCS - MENUITEM "86Boxのバージョン情報(&A)...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新規イメージ(&N)...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "既存のイメージを開く(&E)...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "既存のイメージを開く(書き込み禁止)(&W)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "記録(&R)", IDM_CASSETTE_RECORD - MENUITEM "再生(&P)", IDM_CASSETTE_PLAY - MENUITEM "先頭まで巻き戻す(&R)", IDM_CASSETTE_REWIND - MENUITEM "最後まで早送り(&F)", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "取り出す(&J)", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "イメージ(&I)...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "取り出す(&J)", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新規イメージ(&N)...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "既存のイメージを開く(&E)...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "既存のイメージを開く(書き込み禁止)(&W)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "86Fイメージにエクスポート(&X)...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "取り出す(&J)", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "ミュート(&M)", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "空(&M)", IDM_CDROM_EMPTY - MENUITEM "前のイメージを再読み込み(&R)", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "イメージ(&I)...", IDM_CDROM_IMAGE - MENUITEM "フォルダ(&F)...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新規イメージ(&N)...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "既存のイメージを開く(&E)...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "既存のイメージを開く(書き込み禁止)(&W)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "取り出す(&J)", IDM_ZIP_EJECT - MENUITEM "前のイメージを再読み込み(&R)", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新規イメージ(&N)...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "既存のイメージを開く(&E)...", IDM_MO_IMAGE_EXISTING - MENUITEM "既存のイメージを開く(書き込み禁止)(&W)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "取り出す(&J)", IDM_MO_EJECT - MENUITEM "前のイメージを再読み込み(&R)", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "目標フレームレート(&F)" - BEGIN - MENUITEM "ビデオと同期(&S)", IDM_VID_GL_FPS_BLITTER - MENUITEM "25 fps(&2)", IDM_VID_GL_FPS_25 - MENUITEM "30 fps(&3)", IDM_VID_GL_FPS_30 - MENUITEM "50 fps(&5)", IDM_VID_GL_FPS_50 - MENUITEM "60 fps(&6)", IDM_VID_GL_FPS_60 - MENUITEM "75 fps(&7)", IDM_VID_GL_FPS_75 - END - MENUITEM "垂直同期(VSync)(&V)", IDM_VID_GL_VSYNC - MENUITEM "シェーダーを選択(&S)...", IDM_VID_GL_SHADER - MENUITEM "シェーダーを削除(&R)", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "環境設定" -#define STR_SND_GAIN "音量調整" -#define STR_NEW_FLOPPY "新規のイメージ" -#define STR_CONFIG "設定" -#define STR_SPECIFY_DIM "メイン ウィンドウのサイズ指定" - -#define STR_OK "OK" -#define STR_CANCEL "キャンセル" -#define STR_GLOBAL "これらの設定をグローバル既定値として保存(&G)" -#define STR_DEFAULT "既定値(&D)" -#define STR_LANGUAGE "言語:" -#define STR_ICONSET "アイコン セット:" - -#define STR_GAIN "音量" - -#define STR_FILE_NAME "ファイル名:" -#define STR_DISK_SIZE "ディスク サイズ:" -#define STR_RPM_MODE "RPMモード:" -#define STR_PROGRESS "進行状況:" - -#define STR_WIDTH "幅:" -#define STR_HEIGHT "高さ:" -#define STR_LOCK_TO_SIZE "サイズを固定" - -#define STR_MACHINE_TYPE "マシン タイプ:" -#define STR_MACHINE "マシン:" -#define STR_CONFIGURE "設定" -#define STR_CPU_TYPE "CPUタイプ:" -#define STR_CPU_SPEED "速度:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "ウェイト ステート:" -#define STR_MB "MB" -#define STR_MEMORY "メモリ:" -#define STR_TIME_SYNC "時刻同期機能" -#define STR_DISABLED "無効" -#define STR_ENABLED_LOCAL "有効(現地時間)" -#define STR_ENABLED_UTC "有効(UTC)" -#define STR_DYNAREC "動的再コンパイル" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "ビデオカード:" -#define STR_VIDEO_2 "ビデオカード2:" -#define STR_VOODOO "Voodooグラフィック" -#define STR_IBM8514 "IBM 8514/Aグラフィック" -#define STR_XGA "XGAグラフィック" - -#define STR_MOUSE "マウス:" -#define STR_JOYSTICK "ジョイスティック:" -#define STR_JOY1 "ジョイスティック1..." -#define STR_JOY2 "ジョイスティック2..." -#define STR_JOY3 "ジョイスティック3..." -#define STR_JOY4 "ジョイスティック4..." - -#define STR_SOUND1 "サウンド カード1:" -#define STR_SOUND2 "サウンド カード2:" -#define STR_SOUND3 "サウンド カード3:" -#define STR_SOUND4 "サウンド カード4:" -#define STR_MIDI_OUT "MIDI出力デバイス:" -#define STR_MIDI_IN "MIDI入力デバイス:" -#define STR_MPU401 "独立型MPU-401" -#define STR_FLOAT "FLOAT32サウンドを使用" -#define STR_FM_DRIVER "FMシンセドライバー" -#define STR_FM_DRV_NUKED "Nuked(高精度化)" -#define STR_FM_DRV_YMFM "YMFM(より速く)" - -#define STR_NET_TYPE "ネットワークタイプ:" -#define STR_PCAP "PCapデバイス:" -#define STR_NET "ネットワークアダプター:" -#define STR_NET1 "ネットワーク カード1:" -#define STR_NET2 "ネットワーク カード2:" -#define STR_NET3 "ネットワーク カード3:" -#define STR_NET4 "ネットワーク カード4:" - -#define STR_COM1 "COM1デバイス:" -#define STR_COM2 "COM2デバイス:" -#define STR_COM3 "COM3デバイス:" -#define STR_COM4 "COM4デバイス:" -#define STR_LPT1 "LPT1デバイス:" -#define STR_LPT2 "LPT2デバイス:" -#define STR_LPT3 "LPT3デバイス:" -#define STR_LPT4 "LPT4デバイス:" -#define STR_SERIAL1 "シリアル ポート1" -#define STR_SERIAL2 "シリアル ポート2" -#define STR_SERIAL3 "シリアル ポート3" -#define STR_SERIAL4 "シリアル ポート4" -#define STR_PARALLEL1 "パラレル ポート1" -#define STR_PARALLEL2 "パラレル ポート2" -#define STR_PARALLEL3 "パラレル ポート3" -#define STR_PARALLEL4 "パラレル ポート4" -#define STR_SERIAL_PASS1 "シリアル ポート パススルー対応1" -#define STR_SERIAL_PASS2 "シリアル ポート パススルー対応2" -#define STR_SERIAL_PASS3 "シリアル ポート パススルー対応3" -#define STR_SERIAL_PASS4 "シリアル ポート パススルー対応4" - -#define STR_HDC "HDDコントローラー:" -#define STR_FDC "FDDコントローラー:" -#define STR_IDE_TER "第三IDEコントローラー" -#define STR_IDE_QUA "第四IDEコントローラー" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "コントローラー1:" -#define STR_SCSI_2 "コントローラー2:" -#define STR_SCSI_3 "コントローラー3:" -#define STR_SCSI_4 "コントローラー4:" -#define STR_CASSETTE "カセット" - -#define STR_HDD "ハード ディスク:" -#define STR_NEW "新規(&N)..." -#define STR_EXISTING "既定(&E)..." -#define STR_REMOVE "除去(&R)" -#define STR_BUS "バス:" -#define STR_CHANNEL "チャンネル:" -#define STR_ID "ID:" -#define STR_SPEED "速度:" - -#define STR_SPECIFY "参照(&S)..." -#define STR_SECTORS "セクター:" -#define STR_HEADS "ヘッド:" -#define STR_CYLS "シリンダー:" -#define STR_SIZE_MB "サイズ(MB):" -#define STR_TYPE "タイプ:" -#define STR_IMG_FORMAT "イメージ形式:" -#define STR_BLOCK_SIZE "ブロック サイズ:" - -#define STR_FLOPPY_DRIVES "フロッピー ドライブ:" -#define STR_TURBO "高速タイミング" -#define STR_CHECKBPB "BPBチェック" -#define STR_CDROM_DRIVES "CD-ROMドライブ:" -#define STR_CD_SPEED "速度:" - -#define STR_MO_DRIVES "光磁気ドライブ:" -#define STR_ZIP_DRIVES "ZIPドライブ:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA RTCカード:" -#define STR_ISAMEM "ISAメモリ拡張カード" -#define STR_ISAMEM_1 "カード1:" -#define STR_ISAMEM_2 "カード2:" -#define STR_ISAMEM_3 "カード3:" -#define STR_ISAMEM_4 "カード4:" -#define STR_BUGGER "ISABuggerデバイス" -#define STR_POSTCARD "POSTカード" - -#define FONT_SIZE 9 -#define FONT_NAME "Meiryo UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "エラー" - IDS_2050 "致命的なエラー" - IDS_2051 " - 一時停止" - IDS_2052 "Ctrl+Alt+PgDnでウィンドウモードに戻ります。" - IDS_2053 "速度" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIPイメージ (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Boxで使用可能なROMイメージが見つかりません。\n\nROMセットをダウンロードして、「roms」ディレクトリに解凍してください。" - IDS_2057 "(空)" - IDS_2058 "ZIPイメージ (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0すべてのファイル (*.*)\0*.*\0" - IDS_2059 "高速" - IDS_2060 "オン" - IDS_2061 "オフ" - IDS_2062 "すべてのイメージ (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0ベーシック セクター イメージ (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0サーフェス イメージ (*.86F)\0*.86F\0" - IDS_2063 "roms/machines ディレクトリにROMがないため、マシン「%hs」は使用できません。使用可能なマシンに切り替えます。" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "roms/video ディレクトリにROMがないため、ビデオカード「%hs」は使用できません。使用可能なビデオカードに切り替えます。" - IDS_2065 "マシン" - IDS_2066 "ディスプレイ" - IDS_2067 "入力デバイス" - IDS_2068 "サウンド" - IDS_2069 "ネットワーク" - IDS_2070 "ポート (COM/LPT)" - IDS_2071 "ストレージ コントローラ" - IDS_2072 "ハード ディスク" - IDS_2073 "フロッピー/CD-ROMドライブ" - IDS_2074 "他のリムーバブル デバイス" - IDS_2075 "他の周辺デバイス" - IDS_2076 "サーフェス イメージ (*.86F)\0*.86F\0" - IDS_2077 "左クリックでマウスをキャプチャします" - IDS_2078 "F8+F12キーを押してマウスを解放します" - IDS_2079 "F8+F12キーまたは中クリックでマウスを解放します" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "バス" - IDS_2082 "ファイル" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "BPBチェック" - IDS_2089 "KB" - IDS_2090 "ビデオレンダラーが初期化できません。" - IDS_2091 "既定値" - IDS_2092 "%iつのウェイト ステート" - IDS_2093 "タイプ" - IDS_2094 "PCapのセットアップに失敗しました" - IDS_2095 "PCapデバイスがありません" - IDS_2096 "不正なPCapデバイス" - IDS_2097 "標準ジョイスティック(2ボタン)" - IDS_2098 "標準ジョイスティック(4ボタン)" - IDS_2099 "標準ジョイスティック(6ボタン)" - IDS_2100 "標準ジョイスティック(8ボタン)" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinderパッド" - IDS_2103 "Thrustmaster飛行制御システム" - IDS_2104 "なし" - IDS_2105 "キーボード アクセラレータを読み込めません。" - IDS_2106 "生入力が登録できません。" - IDS_2107 "%u" - IDS_2108 "%u MB (CHS値: %i、%i、%i)" - IDS_2109 "フロッピー %i (%s): %ls" - IDS_2110 "すべてのイメージ (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0アドバンスド セクター イメージ (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0ベーシック セクター イメージ (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0フラックスイメージ (*.FDI)\0*.FDI\0サーフェス イメージ (*.86F;*.MFM)\0*.86F;*.MFM\0すべてのファイル (*.*)\0*.*\0" - IDS_2113 "使用中のマシンをハードリ セットしますか?" - IDS_2114 "86Boxを終了しますか?" - IDS_2115 "Ghostscriptが初期化できません" - IDS_2116 "光磁気 %i (%ls): %ls" - IDS_2117 "光磁気イメージ (*.IM?;*.MDI)\0*.IM?;*.MDI\0すべてのファイル (*.*)\0*.*\0" - IDS_2118 "86Boxへようこそ!" - IDS_2119 "内蔵コントローラー" - IDS_2120 "終了" - IDS_2121 "ROMが見つかりません" - IDS_2122 "設定を保存しますか?" - IDS_2123 "使用中のマシンがハードリ セットされます。" - IDS_2124 "保存" - IDS_2125 "86Boxのバージョン情報" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "古いパソコンのエミュレーター\n\n著者: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nGNU General Public License version 2以降でリリースされています。詳しくは LICENSE をご覧ください。" - IDS_2128 "OK" - IDS_2129 "ハードウェアが利用できません" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 LIB_NAME_PCAP "がインストールされてるか、" LIB_NAME_PCAP "に対応したネットワークに接続されてるか確認してください。" - IDS_2131 "無効な設定" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 "PostScriptファイルをPDFに自動変換するには" LIB_NAME_GS "が必要です。\n\n汎用PostScriptプリンターに送信された文書は、PostScript (.ps) ファイルとして保存されます。" - IDS_2135 "全画面モードを入力" - IDS_2136 "今後、このメッセージを表示しない" - IDS_2137 "終了しない" - IDS_2138 "リセット" - IDS_2139 "リセットしない" - IDS_2140 "光磁気イメージ (*.IM?;*.MDI)\0*.IM?;*.MDI\0すべてのファイル (*.*)\0*.*\0" - IDS_2141 "CD-ROMイメージ (*.ISO;*.CUE)\0*.ISO;*.CUE\0すべてのファイル (*.*)\0*.*\0" - IDS_2142 "%hs のデバイス設定" - IDS_2143 "モニターのスリープ モード" - IDS_2144 "OpenGLシェーダー (*.GLSL)\0*.GLSL\0すべてのファイル (*.*)\0*.*\0" - IDS_2145 "OpenGL設定" - IDS_2146 "読み込んでいる設定がサポートされません" - IDS_2147 "選択したマシンに基づくCPUタイプのフィルター機能は、使用中のマシンでは無効になっています。\n\nこれにより、選択したマシンと互換性のないCPUが選択できます。しかし、マシンのBIOSや他のソフトウェアと互換性がない場合があります。\n\nこの設定を有効にすることは公式にはサポートされておらず、バグレポートは無効として中止される可能性があります。" - IDS_2148 "続行" - IDS_2149 "カセット: %s" - IDS_2150 "カセット イメージ (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0すべてのファイル (*.*)\0*.*\0" - IDS_2151 "カートリッジ %i: %ls" - IDS_2152 "カートリッジ イメージ (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0すべてのファイル (*.*)\0*.*\0" - IDS_2153 "レンダラーの初期化エラー" - IDS_2154 "OpenGL (3.0 Core) レンダラーが初期化できません。別のレンダラーを使用してください。" - IDS_2155 "実行を再開" - IDS_2156 "実行を一時停止" - IDS_2157 "Ctrl+Alt+DELを押す" - IDS_2158 "Ctrl+Alt+Escを押す" - IDS_2159 "ハードリセット" - IDS_2160 "ACPIシャットダウン" - IDS_2161 "設定" - IDS_2162 "タイプ" - IDS_2163 "動的再コンパイル禁止" - IDS_2164 "旧型の動的再コンパイル" - IDS_2165 "新型の動的再コンパイル" - IDS_2166 "「roms/video」ディレクトリにROMがないため、ビデオカード#2「%hs」は使用できません。2枚目のビデオカードを無効にします。" - IDS_2167 "ネットワーク ドライバの初期化に失敗しました。" - IDS_2168 "ネットワーク設定がヌル ドライバに切り替えられます" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "ハード ディスク (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLLやESDI CD-ROMドライブが存在しません" - IDS_4100 "カスタム..." - IDS_4101 "カスタム (大容量)..." - IDS_4102 "新規のディスクを追加" - IDS_4103 "既定のディスクを追加" - IDS_4104 "HDIディスク イメージは4GBを超えることはできません。" - IDS_4105 "ディスク イメージは127GBを超えることはできません。" - IDS_4106 "ハード ディスク イメージ (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0すべてのファイル (*.*)\0*.*\0" - IDS_4107 "ファイルの読み込みができません" - IDS_4108 "ファイルの書き込みができません" - IDS_4109 "512以外のセクタ サイズを持つHDIまたはHDXイメージは対応していません。" - IDS_4110 "USBはまだ非対応です" - IDS_4111 "ディスク イメージ ファイルが既に存在します" - IDS_4112 "有効なファイル名を指定してください。" - IDS_4113 "ディスク イメージが作成されました" - IDS_4114 "ファイルが存在し、読み取り可能であることを確認してください。" - IDS_4115 "ファイルが書き込み可能なディレクトリに保存されていることを確認してください。" - IDS_4116 "ディスク イメージのサイズが大きすぎます" - IDS_4117 "新規ドライブをパーティション分割し、フォーマットを必ずしといてください。" - IDS_4118 "選択したファイルは上書きされます。よろしいですか?" - IDS_4119 "非対応のディスク イメージ" - IDS_4120 "上書き" - IDS_4121 "上書きしない" - IDS_4122 "Rawイメージ (.img)" - IDS_4123 "HDIイメージ (.hdi)" - IDS_4124 "HDXイメージ (.hdx)" - IDS_4125 "VHD (容量固定) (.vhd)" - IDS_4126 "VHD (容量可変) (.vhd)" - IDS_4127 "VHD (差分) (.vhd)" - IDS_4128 "大型ブロック (2 MB)" - IDS_4129 "小型ブロック (512 KB)" - IDS_4130 "VHDファイル (*.VHD)\0*.VHD\0すべてのファイル (*.*)\0*.*\0" - IDS_4131 "親VHDの選択" - IDS_4132 "親イメージが差分イメージの作成の後に変更される可能性があります。\n\nイメージ ファイルが移動またはコピーされたか、イメージ ファイルを作成したプログラムにバグが発生した可能性があります。\n\nタイム スタンプを修正しますか?" - IDS_4133 "親ディスクと子ディスクのタイム スタンプが一致しません" - IDS_4134 "VHD のタイム スタンプを修正できません。" - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "使用しない" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "使用しない" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (クラスター1024)" - IDS_5898 "DMF (クラスター2048)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "既定RPM" - IDS_6145 "1%低いRPM" - IDS_6146 "1.5%低いRPM" - IDS_6147 "2%低いRPM" - - IDS_7168 "(システム既定値)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Japanese resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/ko-KR.rc b/src/win/languages/ko-KR.rc deleted file mode 100644 index a63090c9b..000000000 --- a/src/win/languages/ko-KR.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Korean resources - -#ifdef _WIN32 -LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "동작(&A)" - BEGIN - MENUITEM "키보드는 캡쳐가 필요함(&K)", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "우측 CTRL로 좌측 ALT 입력(&R)", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "재시작(&H)...", IDM_ACTION_HRESET - MENUITEM "Ctrl+Alt+Del(&C)\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+Esc(&E)", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "일시정지(&P)", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "끝내기(&X)...", IDM_ACTION_EXIT - END - POPUP "표시(&V)" - BEGIN - MENUITEM "상태 바 숨기기(&H)", IDM_VID_HIDE_STATUS_BAR - MENUITEM "툴바 숨기기", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "기본 모니터가 아닌 모니터 표시", IDM_VID_MONITORS - MENUITEM "창 크기 조절 가능하게 하기(&R)", IDM_VID_RESIZE - MENUITEM "창 크기와 위치를 기억하기(&E)", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "렌더러(&N)" - BEGIN - MENUITEM "SDL (소프트웨어)(&S)", IDM_VID_SDL_SW - MENUITEM "SDL (하드웨어)(&H)", IDM_VID_SDL_HW - MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL - MENUITEM "OpenGL (3.0 Core)(&G)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "VNC(&V)", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "창 크기 지정하기...", IDM_VID_SPECIFY_DIM - MENUITEM "화면 비율을 4:3으로 맞추기(&O)", IDM_VID_FORCE43 - POPUP "창 표시 배율(&W)" - BEGIN - MENUITEM "0.5배(&0)", IDM_VID_SCALE_1X - MENUITEM "1배(&1)", IDM_VID_SCALE_2X - MENUITEM "1.5배(&5)", IDM_VID_SCALE_3X - MENUITEM "2배(&2)", IDM_VID_SCALE_4X - MENUITEM "&3배", IDM_VID_SCALE_5X - MENUITEM "&4배", IDM_VID_SCALE_6X - MENUITEM "&5배", IDM_VID_SCALE_7X - MENUITEM "&6배", IDM_VID_SCALE_8X - MENUITEM "&7배", IDM_VID_SCALE_9X - MENUITEM "&8배", IDM_VID_SCALE_10X - END - POPUP "필터 형식" - BEGIN - MENUITEM "최근방 이웃 보간법(&N)", IDM_VID_FILTER_NEAREST - MENUITEM "선형 보간법(&L)", IDM_VID_FILTER_LINEAR - END - MENUITEM "HiDPI 스케일링(&D)", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "전체 화면(&F)\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "전체 화면 비율(&S)" - BEGIN - MENUITEM "전체 화면으로 확대(&F)", IDM_VID_FS_FULL - MENUITEM "4:3(&4)", IDM_VID_FS_43 - MENUITEM "정사각형 픽셀 (비율 유지)(&S)", IDM_VID_FS_KEEPRATIO - MENUITEM "정수배 확대(&I)", IDM_VID_FS_INT - END - POPUP "E&GA/(S)VGA 설정" - BEGIN - MENUITEM "색상 반전된 VGA 모니터(&I)", IDM_VID_INVERT - POPUP "VGA 화면 종류(&T)" - BEGIN - MENUITEM "RGB 천연색(&C)", IDM_VID_GRAY_RGB - MENUITEM "RGB 회색조(&R)", IDM_VID_GRAY_MONO - MENUITEM "주황색 모니터(&A)", IDM_VID_GRAY_AMBER - MENUITEM "녹색 모니터(&G)", IDM_VID_GRAY_GREEN - MENUITEM "흰색 모니터(&W)", IDM_VID_GRAY_WHITE - END - POPUP "회색조 표현방식(&C)" - BEGIN - MENUITEM "BT601 (NTSC/PAL)(&6)", IDM_VID_GRAYCT_601 - MENUITEM "BT709 (HDTV)(&7)", IDM_VID_GRAYCT_709 - MENUITEM "평균값(&A)", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/EGA/(S)VGA 오버스캔(&G)", IDM_VID_OVERSCAN - MENUITEM "흑백 표시를 위한 밝기 조정(&M)", IDM_VID_CGACON - END - MENUITEM "미디어(&M)", IDM_MEDIA - POPUP "도구(&T)" - BEGIN - MENUITEM "설정(&S)...", IDM_CONFIG - MENUITEM "상태 바 아이콘 갱신하기(&U)", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "스크린샷 찍기(&C)\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "환경설정(&P)...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "디스코드 연동 활성화하기(&D)", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "음량 증폭(&G)...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "추적 시작하기\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "추적 끝내기\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "도움말(&H)" - BEGIN - MENUITEM "문서(&D)...", IDM_DOCS - MENUITEM "86Box에 대해(&A)...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "새 이미지(&N)...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "이미지 불러오기(&E)...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "이미지 불러오기 (쓰기방지)(&W)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "녹음하기(&R)", IDM_CASSETTE_RECORD - MENUITEM "재생하기(&P)", IDM_CASSETTE_PLAY - MENUITEM "맨앞으로 되감기(&R)", IDM_CASSETTE_REWIND - MENUITEM "맨끝으로 빨리감기(&F)", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "꺼내기(&J)", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "이미지(&I)...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "꺼내기(&J)", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "새 이미지(&N)...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "이미지 불러오기(&E)...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "이미지 불러오기 (쓰기방지)(&W)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "86F로 보내기(&X)...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "꺼내기(&J)", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "음소거(&M)", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "비었음(&M)", IDM_CDROM_EMPTY - MENUITEM "이전 이미지 다시 불러오기(&R)", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "이미지(&I)...", IDM_CDROM_IMAGE - MENUITEM "폴더(&F)...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "새 이미지(&N)...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "이미지 불러오기(&E)...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "이미지 불러오기 (쓰기방지)(&W)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "꺼내기(&J)", IDM_ZIP_EJECT - MENUITEM "이전 이미지 다시 불러오기(&R)", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "새 이미지(&N)...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "이미지 불러오기(&E)...", IDM_MO_IMAGE_EXISTING - MENUITEM "이미지 불러오기 (쓰기방지)(&W)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "꺼내기(&J)", IDM_MO_EJECT - MENUITEM "이전 이미지 다시 불러오기(&R)", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "목표 프레임 레이트(&F)" - BEGIN - MENUITEM "비디오와 동기(&S)", IDM_VID_GL_FPS_BLITTER - MENUITEM "25 fps(&2)", IDM_VID_GL_FPS_25 - MENUITEM "30 fps(&3)", IDM_VID_GL_FPS_30 - MENUITEM "50 fps(&5)", IDM_VID_GL_FPS_50 - MENUITEM "60 fps(&6)", IDM_VID_GL_FPS_60 - MENUITEM "75 fps(&7)", IDM_VID_GL_FPS_75 - END - MENUITEM "수직 동기화(&V)", IDM_VID_GL_VSYNC - MENUITEM "쉐이더 불러오기(&S)...", IDM_VID_GL_SHADER - MENUITEM "쉐이더 끄기(&R)", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "환경설정" -#define STR_SND_GAIN "음량 증폭" -#define STR_NEW_FLOPPY "새 이미지" -#define STR_CONFIG "설정" -#define STR_SPECIFY_DIM "창 크기 지정" - -#define STR_OK "확인" -#define STR_CANCEL "취소" -#define STR_GLOBAL "이 설정들을 전역 기본값으로 저장하기(&G)" -#define STR_DEFAULT "기본값(&D)" -#define STR_LANGUAGE "언어:" -#define STR_ICONSET "아이콘셋:" - -#define STR_GAIN "증가값" - -#define STR_FILE_NAME "파일명:" -#define STR_DISK_SIZE "디스크 용량:" -#define STR_RPM_MODE "RPM 모드:" -#define STR_PROGRESS "진행:" - -#define STR_WIDTH "가로:" -#define STR_HEIGHT "세로:" -#define STR_LOCK_TO_SIZE "크기 고정" - -#define STR_MACHINE_TYPE "머신 종류:" -#define STR_MACHINE "기종:" -#define STR_CONFIGURE "설정" -#define STR_CPU_TYPE "CPU 종류:" -#define STR_CPU_SPEED "속도:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "대기 상태:" -#define STR_MB "MB" -#define STR_MEMORY "메모리:" -#define STR_TIME_SYNC "시간 동기화" -#define STR_DISABLED "사용하지 않음" -#define STR_ENABLED_LOCAL "사용 (현지 시간)" -#define STR_ENABLED_UTC "사용 (UTC)" -#define STR_DYNAREC "동적 재컴파일" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "비디오 카드:" -#define STR_VIDEO_2 "비디오 카드 2:" -#define STR_VOODOO "Voodoo 그래픽" -#define STR_IBM8514 "IBM 8514/A 그래픽" -#define STR_XGA "XGA 그래픽" - -#define STR_MOUSE "마우스:" -#define STR_JOYSTICK "조이스틱:" -#define STR_JOY1 "조이스틱 1..." -#define STR_JOY2 "조이스틱 2..." -#define STR_JOY3 "조이스틱 3..." -#define STR_JOY4 "조이스틱 4..." - -#define STR_SOUND1 "사운드 카드 1:" -#define STR_SOUND2 "사운드 카드 2:" -#define STR_SOUND3 "사운드 카드 3:" -#define STR_SOUND4 "사운드 카드 4:" -#define STR_MIDI_OUT "MIDI 출력 장치:" -#define STR_MIDI_IN "MIDI 입력 장치:" -#define STR_MPU401 "MPU-401 단독 사용" -#define STR_FLOAT "FLOAT32 사운드 사용" -#define STR_FM_DRIVER "FM 신디사이저 드라이버" -#define STR_FM_DRV_NUKED "Nuked (더 정확한)" -#define STR_FM_DRV_YMFM "YMFM (더 빠르게)" - -#define STR_NET_TYPE "네트워크 종류:" -#define STR_PCAP "PCap 장치:" -#define STR_NET "네트워크 어댑터:" -#define STR_NET1 "네트워크 카드 1:" -#define STR_NET2 "네트워크 카드 2:" -#define STR_NET3 "네트워크 카드 3:" -#define STR_NET4 "네트워크 카드 4:" - -#define STR_COM1 "COM1 장치:" -#define STR_COM2 "COM2 장치:" -#define STR_COM3 "COM3 장치:" -#define STR_COM4 "COM4 장치:" -#define STR_LPT1 "LPT1 장치:" -#define STR_LPT2 "LPT2 장치:" -#define STR_LPT3 "LPT3 장치:" -#define STR_LPT4 "LPT4 장치:" -#define STR_SERIAL1 "직렬 포트 1" -#define STR_SERIAL2 "직렬 포트 2" -#define STR_SERIAL3 "직렬 포트 3" -#define STR_SERIAL4 "직렬 포트 4" -#define STR_PARALLEL1 "병렬 포트 1" -#define STR_PARALLEL2 "병렬 포트 2" -#define STR_PARALLEL3 "병렬 포트 3" -#define STR_PARALLEL4 "병렬 포트 4" -#define STR_SERIAL_PASS1 "직렬 포트 패스쓰루 1" -#define STR_SERIAL_PASS2 "직렬 포트 패스쓰루 2" -#define STR_SERIAL_PASS3 "직렬 포트 패스쓰루 3" -#define STR_SERIAL_PASS4 "직렬 포트 패스쓰루 4" - -#define STR_HDC "HD 컨트롤러:" -#define STR_FDC "FD 컨트롤러:" -#define STR_IDE_TER "제3의 IDE 컨트롤러" -#define STR_IDE_QUA "제4의 IDE 컨트롤러" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "컨트롤러 1:" -#define STR_SCSI_2 "컨트롤러 2:" -#define STR_SCSI_3 "컨트롤러 3:" -#define STR_SCSI_4 "컨트롤러 4:" -#define STR_CASSETTE "카세트 테이프" - -#define STR_HDD "하드 디스크:" -#define STR_NEW "새로 만들기(&N)..." -#define STR_EXISTING "불러오기(&E)..." -#define STR_REMOVE "목록에서 제거(&R)" -#define STR_BUS "버스:" -#define STR_CHANNEL "채널:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "열기(&S)..." -#define STR_SECTORS "섹터:" -#define STR_HEADS "헤드:" -#define STR_CYLS "실린더:" -#define STR_SIZE_MB "용량(MB):" -#define STR_TYPE "형식:" -#define STR_IMG_FORMAT "이미지 포맷:" -#define STR_BLOCK_SIZE "블록 크기:" - -#define STR_FLOPPY_DRIVES "플로피 드라이브:" -#define STR_TURBO "고속 동작" -#define STR_CHECKBPB "BPB 확인" -#define STR_CDROM_DRIVES "CD-ROM 드라이브:" -#define STR_CD_SPEED "속도:" - -#define STR_MO_DRIVES "광자기 드라이브:" -#define STR_ZIP_DRIVES "ZIP 드라이브:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA RTC 카드:" -#define STR_ISAMEM "ISA 메모리 확장 카드" -#define STR_ISAMEM_1 "카드 1:" -#define STR_ISAMEM_2 "카드 2:" -#define STR_ISAMEM_3 "카드 3:" -#define STR_ISAMEM_4 "카드 4:" -#define STR_BUGGER "ISABugger 장치" -#define STR_POSTCARD "POST 카드" - -#define FONT_SIZE 9 -#define FONT_NAME "Malgun Gothic" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "오류" - IDS_2050 "치명적인 오류" - IDS_2051 " - 일시중지" - IDS_2052 "Ctrl+Alt+PgDn 키를 누르면 창 모드로 전환합니다." - IDS_2053 "속도" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIP 이미지 (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box에서 사용 가능한 ROM 이미지를 찾을 수 없습니다.\n\nROM 세트를다운로드 후 ""roms"" 디렉토리에 압축을 풀어 주세요." - IDS_2057 "(비었음)" - IDS_2058 "ZIP 이미지 (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0모든 파일 (*.*)\0*.*\0" - IDS_2059 "터보" - IDS_2060 "켜짐" - IDS_2061 "꺼짐" - IDS_2062 "모든 이미지 (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0기본 섹터 이미지 (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0표면 이미지 (*.86F)\0*.86F\0" - IDS_2063 "roms/machines 디렉토리에 필요한 롬파일이 없어 기종 ""%hs""을(를) 사용할 수 없습니다. 사용 가능한 기종으로 변경합니다." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "roms/video 디렉토리에 필요한 롬파일이 없어 비디오 카드 ""%hs""을(를) 사용할 수 없습니다. 사용 가능한 기종으로 변경합니다." - IDS_2065 "기종" - IDS_2066 "디스플레이" - IDS_2067 "입력 장치" - IDS_2068 "사운드" - IDS_2069 "네트워크" - IDS_2070 "포트 (COM & LPT)" - IDS_2071 "장치 컨트롤러" - IDS_2072 "하드 디스크" - IDS_2073 "플로피 / CD-ROM" - IDS_2074 "기타 이동식 저장장치" - IDS_2075 "기타 주변기기" - IDS_2076 "표면 이미지 (*.86F)\0*.86F\0" - IDS_2077 "이 창을 클릭하면 마우스를 사용합니다" - IDS_2078 "F12+F8키를 누르면 마우스를 해제합니다" - IDS_2079 "F12+F8키 또는 가운데 버튼을 클릭하면 마우스를 해제합니다" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "버스" - IDS_2082 "파일" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "BPB 확인" - IDS_2089 "KB" - IDS_2090 "비디오 렌더러를 초기화할 수 없습니다." - IDS_2091 "기본값" - IDS_2092 "%i 대기 상태" - IDS_2093 "형식" - IDS_2094 "PCap 설정에 실패했습니다" - IDS_2095 "PCap 장치가 없습니다" - IDS_2096 "PCap 장치가 올바르지 않습니다" - IDS_2097 "표준 2버튼 조이스틱" - IDS_2098 "표준 4버튼 조이스틱" - IDS_2099 "표준 6버튼 조이스틱" - IDS_2100 "표준 8버튼 조이스틱" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "없음" - IDS_2105 "키보드 가속기를 불러올 수 없습니다." - IDS_2106 "Raw 입력을 등록할 수 없습니다." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "플로피 %i (%s): %ls" - IDS_2110 "모든 이미지 (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0어드밴스드 섹터 이미지 (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0기본 섹터 이미지 (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0플럭스 이미지 (*.FDI)\0*.FDI\0표면 이미지 (*.86F;*.MFM)\0*.86F;*.MFM\0모든 파일 (*.*)\0*.*\0" - IDS_2113 "실행중인 머신을 재시작하시겠습니까?" - IDS_2114 "86Box를 끝내시겠습니까?" - IDS_2115 "Ghostscript를 초기화할 수 없습니다" - IDS_2116 "광자기 %i (%ls): %ls" - IDS_2117 "광자기 이미지 (*.IM?;*.MDI)\0*.IM?;*.MDI\0모든 파일 (*.*)\0*.*\0" - IDS_2118 "86Box에 어서오세요!" - IDS_2119 "내부 컨트롤러" - IDS_2120 "끝내기" - IDS_2121 "ROM을 불러올 수 없습니다" - IDS_2122 "설정을 저장하시겠습니까?" - IDS_2123 "사용중인 머신이 재부팅됩니다." - IDS_2124 "저장" - IDS_2125 "86Box에 대해" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "고전 컴퓨터 에뮬레이터\n\n저자: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nGNU General Public 라이선스 (버전 2 이상)에 의해 배포되었습니다. 자세한 내용은 LICENSE 파일을 읽어 주세요." - IDS_2128 "확인" - IDS_2129 "하드웨어를 이용할 수 없습니다" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 LIB_NAME_PCAP "이 설치되었는지 " LIB_NAME_PCAP "에 대응하는 네트워크에 접속되어 있는지 확인해 주세요." - IDS_2131 "올바르지 않은 설정입니다" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS "은(는) PostScript 파일을 PDF로 자동변환하는 데에 필요합니다.\n\n표준 PostScript 프린터로 보내신 임의의 문서는 PostScript (.ps) 파일로 저장됩니다." - IDS_2135 "전체 화면으로 전환" - IDS_2136 "이 메시지 그만 보기" - IDS_2137 "끝내지 않기" - IDS_2138 "재시작" - IDS_2139 "재시작 안함" - IDS_2140 "광자기 이미지 (*.IM?;*.MDI)\0*.IM?;*.MDI\0모든 파일 (*.*)\0*.*\0" - IDS_2141 "CD-ROM 이미지 (*.ISO;*.CUE)\0*.ISO;*.CUE\0모든 파일 (*.*)\0*.*\0" - IDS_2142 "%hs 장치 설정" - IDS_2143 "모니터 절전 모드" - IDS_2144 "OpenGL 쉐이더 (*.GLSL)\0*.GLSL\0모든 파일 (*.*)\0*.*\0" - IDS_2145 "OpenGL 설정" - IDS_2146 "지원하지 않는 설정입니다" - IDS_2147 "이 에뮬레이트된 기종에 대해 선택한 기종을 기반으로 하는 CPU 종류 필터링이 사용되지 않도록 설정되었습니다.\n\n따라서 선택된 머신과 호환되지 않는 CPU를 선택하실 수 있습니다. 하지만 BIOS 또는 다른 소프트웨어와 호환되지 않을 수 있습니다.\n\n이 설정을 활성화하는 것은 공식적으로 지원되지 않으며, 제출된 버그 보고서는 유효하지 않음으로 닫힐 수 있습니다." - IDS_2148 "계속" - IDS_2149 "카세트: %s" - IDS_2150 "카세트 이미지 (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0모든 파일 (*.*)\0*.*\0" - IDS_2151 "카트리지 %i: %ls" - IDS_2152 "카트리지 이미지 (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0모든 파일 (*.*)\0*.*\0" - IDS_2153 "렌더러 초기화 오류" - IDS_2154 "OpenGL (3.0 Core) 렌더러를 초기화할 수 없습니다. 다른 렌더러를 사용하십시오." - IDS_2155 "실행 재개" - IDS_2156 "실행 일시 중지" - IDS_2157 "Ctrl+Alt+Del" - IDS_2158 "Ctrl+Alt+Esc" - IDS_2159 "재시작" - IDS_2160 "ACPI 종료" - IDS_2161 "설정" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "두번째 비디오카드 ""%hs""는 roms/video 디렉토리에서 ROM이 누락되어 사용할 수 없습니다. 두번째 비디오 카드를 비활성화 합니다." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "하드 디스크 (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLL 또는 ESDI CD-ROM 드라이브가 존재하지 않습니다" - IDS_4100 "사용자 설정..." - IDS_4101 "사용자 설정 (대용량)..." - IDS_4102 "새로 생성" - IDS_4103 "기존 이미지 사용" - IDS_4104 "HDI 디스크 이미지는 4GB 이상으로 지정할 수 없습니다" - IDS_4105 "디스크 이미지는 127GB 이상으로 지정할 수 없습니다" - IDS_4106 "하드 디스크 이미지 (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0모든 파일 (*.*)\0*.*\0" - IDS_4107 "파일을 읽을 수 없습니다" - IDS_4108 "파일을 저장할 수 없습니다" - IDS_4109 "512 바이트 이외의 섹터 크기를 가진 HDI 또는 HDX 형식의 이미지를 생성할 수 없습니다" - IDS_4110 "USB는 아직 지원하지 않습니다" - IDS_4111 "디스크 이미지 파일이 이미 존재합니다" - IDS_4112 "올바른 파일명을 지정해 주세요." - IDS_4113 "디스크 이미지가 생성되었습니다" - IDS_4114 "파일이 존재하며 읽을 수 있는지 확인합니다." - IDS_4115 "파일이 쓰기 가능한 디렉토리에 저장되고 있는지 확인합니다." - IDS_4116 "디스크 이미지가 너무 큽니다" - IDS_4117 "새로 생성한 드라이브의 파티션 설정과 포맷을 꼭 해주세요." - IDS_4118 "선택하신 파일을 덮어씌웁니다. 사용하시겠습니까?" - IDS_4119 "지원하지 않는 디스크 이미지입니다" - IDS_4120 "덮어쓰기" - IDS_4121 "덮어쓰지 않음" - IDS_4122 "Raw 이미지 (.img)" - IDS_4123 "HDI 이미지 (.hdi)" - IDS_4124 "HDX 이미지 (.hdx)" - IDS_4125 "고정 사이즈 VHD (.vhd)" - IDS_4126 "동적 사이즈 VHD (.vhd)" - IDS_4127 "디퍼런싱 VHD (.vhd)" - IDS_4128 "대형 블록 (2 MB)" - IDS_4129 "소형 블록 (512 KB)" - IDS_4130 "VHD 파일 (*.VHD)\0*.VHD\0모든 파일 (*.*)\0*.*\0" - IDS_4131 "부모 VHD 선택" - IDS_4132 "이는 디퍼런싱 이미지가 생성된 후 부모 이미지가 수정되었음을 의미할 수 있습니다.\n\n이미지 파일이 이동 또는 복사된 경우 또는 이 디스크를 만든 프로그램의 버그로 인해 발생할 수도 있습니다.\n\n타임스탬프를 수정하시겠습니까?" - IDS_4133 "부모 디스크와 자식 디스크의 타임스탬프가 일치하지 않습니다" - IDS_4134 "VHD 타임스탬프를 고칠 수 없습니다" - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "사용하지 않음" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "사용하지 않음" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (클러스터 1024)" - IDS_5898 "DMF (클러스터 2048)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "완벽한 회전수" - IDS_6145 "1% 낮은 회전수" - IDS_6146 "1.5% 낮은 회전수" - IDS_6147 "2% 낮은 회전수" - - IDS_7168 "(시스템 기본값)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Korean resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/pl-PL.rc b/src/win/languages/pl-PL.rc deleted file mode 100644 index 623415045..000000000 --- a/src/win/languages/pl-PL.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Polish (pl-PL) resources - -#ifdef _WIN32 -LANGUAGE LANG_POLISH, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Akcje" - BEGIN - MENUITEM "&Klawaitura wymaga przechwytu myszy", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Prawy CTRL to lewy Alt", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Twardy reset...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Pauza", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "W&yjdź...", IDM_ACTION_EXIT - END - POPUP "&Widok" - BEGIN - MENUITEM "&Ukryj pasek statusu", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Ukryj &pasek narzędzi", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Okno o zmiennym rozmiarze", IDM_VID_RESIZE - MENUITEM "P&amiętaj rozmiar &i pozycję", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "Re&nderer" - BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "Określ rozmiary...", IDM_VID_SPECIFY_DIM - MENUITEM "&Wymuś proporcje wyświetlania 4:3", IDM_VID_FORCE43 - POPUP "&Czynnik skalowania okna" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Metoda filtrowania" - BEGIN - MENUITEM "&Nearest", IDM_VID_FILTER_NEAREST - MENUITEM "&Linear", IDM_VID_FILTER_LINEAR - END - MENUITEM "Skalowanie Hi&DPI", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Pełny ekran\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Fullscreen &stretch mode" - BEGIN - MENUITEM "&Tryb rozciągania na pełnym ekranie", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Kwadratowe piksele (Zachowaj proporcje)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Skalowanie całkowite", IDM_VID_FS_INT - END - POPUP "Ustawienia E&GA/(S)VGA" - BEGIN - MENUITEM "&Odwrócony monitor VGA", IDM_VID_INVERT - POPUP "Rodzaj ekranu &VGA" - BEGIN - MENUITEM "RGB - &Kolorowy", IDM_VID_GRAY_RGB - MENUITEM "&RGB - Skala szarości", IDM_VID_GRAY_MONO - MENUITEM "&Bursztynowy monitor", IDM_VID_GRAY_AMBER - MENUITEM "&Zielony monitor", IDM_VID_GRAY_GREEN - MENUITEM "&Biały monitor", IDM_VID_GRAY_WHITE - END - POPUP "Typ konwersji &w skali szarości" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Średni", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "Overscan dla CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN - MENUITEM "Zmień kontrast dla &monochromatycznego ekranu", IDM_VID_CGACON - END - MENUITEM "&Nośnik", IDM_MEDIA - POPUP "&Narzędzia" - BEGIN - MENUITEM "&Ustawienia...", IDM_CONFIG - MENUITEM "&Aktualizuj ikony na pasku statusu", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Zrób &zrzut ekranu\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Preferencje...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Włącz integrację z &Discord", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "Wzmocnienie &dźwięku...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Rozpocznij śledzenie\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Zakończ śledzenie\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Pomoc" - BEGIN - MENUITEM "&Dokumentacja...", IDM_DOCS - MENUITEM "&O 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nowy obraz...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Istniejący obraz...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Istniejący obraz (&Chroniony przed zapisem)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Nagraj", IDM_CASSETTE_RECORD - MENUITEM "&Odtwórz", IDM_CASSETTE_PLAY - MENUITEM "&Przewiń do początku", IDM_CASSETTE_REWIND - MENUITEM "&Przewiń do końca", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "W&yjmij", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Obraz...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "W&yjmij", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nowy obraz...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Istniejący obraz...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Istniejący obraz (&Chroniony przed zapisem)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&ksportuj do 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "W&yjmij", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Ścisz", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "P&usty", IDM_CDROM_EMPTY - MENUITEM "&Przeładuj poprzedni obraz", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Obraz...", IDM_CDROM_IMAGE - MENUITEM "&Teczka...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nowy obraz...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Istniejący obraz...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Istniejący obraz (&Chroniony przed zapisem)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "W&yjmij", IDM_ZIP_EJECT - MENUITEM "&Przeładuj poprzedni obraz", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nowy obraz...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Istniejący obraz...", IDM_MO_IMAGE_EXISTING - MENUITEM "Istniejący obraz (&Chroniony przed zapisem)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "W&yjmij", IDM_MO_EJECT - MENUITEM "&Przeładuj poprzedni obraz", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "Docelowa &liczba klatek na sekundę" - BEGIN - MENUITEM "&Zsynchronizuj z wideo", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 fps", IDM_VID_GL_FPS_25 - MENUITEM "&30 fps", IDM_VID_GL_FPS_30 - MENUITEM "&50 fps", IDM_VID_GL_FPS_50 - MENUITEM "&60 fps", IDM_VID_GL_FPS_60 - MENUITEM "&75 fps", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Wybierz shader...", IDM_VID_GL_SHADER - MENUITEM "&Usuń shader", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Preferencje" -#define STR_SND_GAIN "Wzmocnienie dźwięku" -#define STR_NEW_FLOPPY "Nowy obraz" -#define STR_CONFIG "Ustawienia" -#define STR_SPECIFY_DIM "Określ rozmiary okna" - -#define STR_OK "OK" -#define STR_CANCEL "Anuluj" -#define STR_GLOBAL "Zapisz ustawienia jako &globalne ustawienia domyślne" -#define STR_DEFAULT "&Domyślny" -#define STR_LANGUAGE "Język:" -#define STR_ICONSET "Zestaw ikon:" - -#define STR_GAIN "Wzmacniacz" - -#define STR_FILE_NAME "Nazwa pliku:" -#define STR_DISK_SIZE "Rozmiar dysku:" -#define STR_RPM_MODE "Tryb RPM:" -#define STR_PROGRESS "Postęp:" - -#define STR_WIDTH "Szerokość:" -#define STR_HEIGHT "Wysokość:" -#define STR_LOCK_TO_SIZE "Stały rozmiar" - -#define STR_MACHINE_TYPE "Rodzaj maszyny:" -#define STR_MACHINE "Maszyna:" -#define STR_CONFIGURE "Konfiguruj" -#define STR_CPU_TYPE "Rodzaj procesora:" -#define STR_CPU_SPEED "Szybkość:" -#define STR_FPU "Jednostka FPU:" -#define STR_WAIT_STATES "Stany oczekiwania:" -#define STR_MB "MB" -#define STR_MEMORY "Pamięć:" -#define STR_TIME_SYNC "Synchronizacja czasu" -#define STR_DISABLED "Wyłączona" -#define STR_ENABLED_LOCAL "Włączona (czas lokalny)" -#define STR_ENABLED_UTC "Włączona (UTC)" -#define STR_DYNAREC "Dynamiczny rekompilator" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Wideo:" -#define STR_VIDEO_2 "Wideo 2:" -#define STR_VOODOO "Grafika Voodoo" -#define STR_IBM8514 "Grafika IBM 8514/A" -#define STR_XGA "Grafika XGA" - -#define STR_MOUSE "Mysz:" -#define STR_JOYSTICK "Joystick:" -#define STR_JOY1 "Joystick 1..." -#define STR_JOY2 "Joystick 2..." -#define STR_JOY3 "Joystick 3..." -#define STR_JOY4 "Joystick 4..." - -#define STR_SOUND1 "Karta dźwiękowa 1:" -#define STR_SOUND2 "Karta dźwiękowa 2:" -#define STR_SOUND3 "Karta dźwiękowa 3:" -#define STR_SOUND4 "Karta dźwiękowa 4:" -#define STR_MIDI_OUT "Urządzenie wyjściowe MIDI:" -#define STR_MIDI_IN "Urządzenie wejściowe MIDI:" -#define STR_MPU401 "Samodzielne urządzenie MPU-401" -#define STR_FLOAT "Użyj dźwięku FLOAT32" -#define STR_FM_DRIVER "Sterownik syntezy FM" -#define STR_FM_DRV_NUKED "Nuked (dokładniejszy)" -#define STR_FM_DRV_YMFM "YMFM (szybszy)" - -#define STR_NET_TYPE "Rodzaj sieci:" -#define STR_PCAP "Urządzenie PCap:" -#define STR_NET "Karta sieciowa:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "Urządzenie COM1:" -#define STR_COM2 "Urządzenie COM2:" -#define STR_COM3 "Urządzenie COM3:" -#define STR_COM4 "Urządzenie COM4:" -#define STR_LPT1 "Urządzenie LPT1:" -#define STR_LPT2 "Urządzenie LPT2:" -#define STR_LPT3 "Urządzenie LPT3:" -#define STR_LPT4 "Urządzenie LPT4:" -#define STR_SERIAL1 "Port szeregowy 1" -#define STR_SERIAL2 "Port szeregowy 2" -#define STR_SERIAL3 "Port szeregowy 3" -#define STR_SERIAL4 "Port Szeregowy 4" -#define STR_PARALLEL1 "Port równoległy 1" -#define STR_PARALLEL2 "Port równoległy 2" -#define STR_PARALLEL3 "Port równoległy 3" -#define STR_PARALLEL4 "Port równoległy 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Kontroler dysku twardego:" -#define STR_FDC "Kontroler dyskietek:" -#define STR_IDE_TER "Trzeciorzędowy kontroler IDE" -#define STR_IDE_QUA "Czwartorzędowy kontroler IDE" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Kontroler 1:" -#define STR_SCSI_2 "Kontroler 2:" -#define STR_SCSI_3 "Kontroler 3:" -#define STR_SCSI_4 "Kontroler 4:" -#define STR_CASSETTE "Kaseta" - -#define STR_HDD "Dyski twarde:" -#define STR_NEW "&Nowy..." -#define STR_EXISTING "&Istniejący..." -#define STR_REMOVE "&Usuń" -#define STR_BUS "Magistrala:" -#define STR_CHANNEL "Kanał:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Określ..." -#define STR_SECTORS "Sektory:" -#define STR_HEADS "Głowice:" -#define STR_CYLS "Cylindry:" -#define STR_SIZE_MB "Rozmiar (MB):" -#define STR_TYPE "Rodzaj:" -#define STR_IMG_FORMAT "Format obrazu:" -#define STR_BLOCK_SIZE "Rozmiar bloku:" - -#define STR_FLOPPY_DRIVES "Napędy dyskietek:" -#define STR_TURBO "Rozrządy Turbo" -#define STR_CHECKBPB "Sprawdzaj BPB" -#define STR_CDROM_DRIVES "Napędy CD-ROM:" -#define STR_CD_SPEED "Szybkość:" - -#define STR_MO_DRIVES "Napędy MO:" -#define STR_ZIP_DRIVES "Napędy ZIP:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA RTC:" -#define STR_ISAMEM "Rozszerzenie pamięci ISA" -#define STR_ISAMEM_1 "Karta 1:" -#define STR_ISAMEM_2 "Karta 2:" -#define STR_ISAMEM_3 "Karta 3:" -#define STR_ISAMEM_4 "Karta 4:" -#define STR_BUGGER "Urządzenie ISABugger" -#define STR_POSTCARD "Karta POST" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Błąd" - IDS_2050 "Fatalny błąd" - IDS_2051 " - PAUSED" - IDS_2052 "Naciśnij klawisze Ctrl+Alt+PgDn aby wrócić to trybu okna." - IDS_2053 "Szybkość" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "Obrazy ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box nie może znaleźć obrazów ROM nadających się do użytku.\n\nProszę pobrać zestaw obrazów ROM ze strony download, i rozpakować je do katalogu ""roms""." - IDS_2057 "(pusty)" - IDS_2058 "Obrazy ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Wszystkie pliki (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "Włącz" - IDS_2061 "Wyłącz" - IDS_2062 "Wszystkie obrazy (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Podstawowe obrazy sektorów(*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Obrazy powierzchniowe (*.86F)\0*.86F\0" - IDS_2063 "Maszyna ""%hs"" nie jest dostępna, ponieważ brakuje obrazów ROM w katalogu roms/machines. Przełączanie na dostępną maszynę." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "Karta wideo ""%hs"" nie jest dostępna, ponieważ brakuje obrazów ROM w katalogu roms/video. Przełączanie na dostępną kartę wideo." - IDS_2065 "Maszyna" - IDS_2066 "Ekran" - IDS_2067 "Urządzenia wejściowe" - IDS_2068 "Dźwięk" - IDS_2069 "Sieć" - IDS_2070 "Porty (COM & LPT)" - IDS_2071 "Kontrolery pamięci" - IDS_2072 "Dyski twarde" - IDS_2073 "Napędy dyskietek i CD-ROM" - IDS_2074 "Inne urządzenia wymienne" - IDS_2075 "Inne urządzenia peryferyjne" - IDS_2076 "Obrazy powierzchniowe (*.86F)\0*.86F\0" - IDS_2077 "Kliknij w celu przechwycenia myszy" - IDS_2078 "Naciśnij klawisze F8+F12 w celu uwolnienia myszy" - IDS_2079 "Naciśnij klawisze F8+F12 lub środkowy przycisk w celu uwolnienia myszy" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Magistrala" - IDS_2082 "Plik" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "Sprawdzaj BPB" - IDS_2089 "KB" - IDS_2090 "Nie można zainicjować renderera wideo." - IDS_2091 "Domyślny" - IDS_2092 "%i Stany oczekiwania" - IDS_2093 "Rodzaj" - IDS_2094 "Nie udało się ustawić PCap" - IDS_2095 "Nie znaleziono urządzeń PCap" - IDS_2096 "Nieprawidłowe urządzenie PCap" - IDS_2097 "Standardowe joysticki 2-przyciskowe" - IDS_2098 "Standardowy joystick 4-przyciskowy" - IDS_2099 "Standardowy joystick 6-przyciskowy" - IDS_2100 "Standardowy joystick 8-przyciskowy" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "Żaden" - IDS_2105 "Nie można załadować akceleratorów klawiaturowych." - IDS_2106 "Nie można zarejestrować surowych danych wejściowych." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Dyskietka %i (%s): %ls" - IDS_2110 "Wszystkie obrazy (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Zaawansowane obrazy sektorów (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Podstawowe obrazy sektorów (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Obrazy powierzchniowe (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2113 "Jesteś pewien że chcesz wykonać twardy reset emulowanej maszyny?" - IDS_2114 "Jesteś pewien że chcesz zakończyć 86Box?" - IDS_2115 "Nie można zainicjować Ghostscript" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "Obrazy MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2118 "Witamy w 86Box!" - IDS_2119 "Kontroler wewnętrzny" - IDS_2120 "Zakończ" - IDS_2121 "Nie znaleziono obrazów ROM" - IDS_2122 "Czy chcesz zapisać ustawienia?" - IDS_2123 "To spowoduje twardy reset wirtualnej maszyny." - IDS_2124 "Zapisz" - IDS_2125 "O 86Box" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "Emulator starych komputerów\n\nAutorzy: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, i inni.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, i inni.\n\nPrzetłumaczony przez: Fanta-Shokata\n\nWydany na licencji GNU General Public License w wersji 2 lub nowszej. Zobacz LICENSE aby uzyskać więcej informacji." - IDS_2128 "OK" - IDS_2129 "Sprzęt niedostępny" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Sprawdź, czy " LIB_NAME_PCAP " jest zainstalowany i czy posiadasz połączenie sieciowe kompatybilne z " LIB_NAME_PCAP "." - IDS_2131 "Nieprawidłowa konfiguracja" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " jest wymagany do automatycznej konwersji plików PostScript do PDF.\n\nDokumenty wysłane do ogólnej drukarki PostScript zostaną zapisane jako pliki PostScript (.ps)." - IDS_2135 "Przechodzenie do trybu pełnoekranowego" - IDS_2136 "Nie pokazuj więcej tego komunikatu" - IDS_2137 "Nie kończ" - IDS_2138 "Przywróć" - IDS_2139 "Nie przywracaj" - IDS_2140 "Obrazy MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2141 "Obrazy CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" - IDS_2142 "Konfiguracja urządzenia %hs" - IDS_2143 "Monitor w trybie czuwania" - IDS_2144 "Shadery OpenGL (*.GLSL)\0*.GLSL\0Wszystkie pliki (*.*)\0*.*\0" - IDS_2145 "Opcje OpenGL" - IDS_2146 "Ładujesz nieobsługiwaną konfigurację" - IDS_2147 "Wybór rodzaju procesora oparty na wybranej maszynie jest wyłączony dla tej emulowanej maszyny.\n\nPozwala to na wybór procesora który jest niekompatybilny z wybraną maszyną. Jednak możesz napotkać niezgodności z BIOS-em maszyny lub innym oprogramowaniem.\n\nAktywacja tego ustawienia nie jest wspierana i każde zgłoszenie błędu może zostać zamknięte jako nieważne." - IDS_2148 "Kontynuuj" - IDS_2149 "Kaseta: %s" - IDS_2150 "Obrazy kaset (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Wszystkie pliki (*.*)\0*.*\0" - IDS_2151 "Kartrydż %i: %ls" - IDS_2152 "Obrazy kartrydżu (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Wszystkie pliki (*.*)\0*.*\0" - IDS_2153 "Błąd inicjalizacji renderera" - IDS_2154 "Nie można zainicjować renderera OpenGL (3.0 Core). Użyj innego." - IDS_2155 "Wznów wykonywanie" - IDS_2156 "Zatrzymaj wykonywanie" - IDS_2157 "Naciśnij Ctrl+Alt+Del" - IDS_2158 "Naciśnij Ctrl+Alt+Esc" - IDS_2159 "Twardy reset" - IDS_2160 "Wyłączenie ACPI" - IDS_2161 "Ustawienia" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Dysk twardy (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "Napędy CD-ROM MFM/RLL lub ESDI nigdy nie istniały" - IDS_4100 "Niestandardowy..." - IDS_4101 "Niestandardowy (duży)..." - IDS_4102 "Dodaj nowy dysk twardy" - IDS_4103 "Dodaj istniejący dysk twardy" - IDS_4104 "Obrazy dysków HDI nie mogą być większe niż 4 GB." - IDS_4105 "Obrazy dysków nie mogą być większe niż 127 GB." - IDS_4106 "Obrazy dysku twardego (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Wszystkie pliki (*.*)\0*.*\0" - IDS_4107 "Nie można odczytać pliku" - IDS_4108 "Nie można zapisać pliku" - IDS_4109 "Obrazy HDI lub HDX z rozmiarem sektora innym niż 512 nie są wspierane." - IDS_4110 "USB nie jest jeszcze wspierane" - IDS_4111 "Plik obrazu dysku już istnieje" - IDS_4112 "Określ prawidłową nazwę pliku." - IDS_4113 "Utworzono obraz dysku" - IDS_4114 "Sprawdź, czy plik istnieje i nadaje się do odczytu." - IDS_4115 "Sprawdź, czy plik jest zapiyswany w katalogu z możliwością zapisu." - IDS_4116 "Obraz dysku jest za duży" - IDS_4117 "Nie zapomnij o partycjonowaniu i sformatowaniu nowo utworzego dysku" - IDS_4118 "Wybrany plik zostanie nadpisany. Czy na pewno chcesz użyć tego pliku?" - IDS_4119 "Niewspierany obraz dysku" - IDS_4120 "Nadpisz" - IDS_4121 "Nie nadpisuj" - IDS_4122 "Obraz surowy (.img)" - IDS_4123 "Obraz HDI (.hdi)" - IDS_4124 "Obraz HDX (.hdx)" - IDS_4125 "VHD o stałym rozmiarze (.vhd)" - IDS_4126 "VHD o dynamicznym rozmiarze (.vhd)" - IDS_4127 "VHD różnicujący (.vhd)" - IDS_4128 "Duże bloki (2 MB)" - IDS_4129 "Małe bloki (512 KB)" - IDS_4130 "Pliki VHD (*.VHD)\0*.VHD\0Wszystkie pliki (*.*)\0*.*\0" - IDS_4131 "Wybierz nadrzędny plik VHD" - IDS_4132 "Może to oznaczać, że obraz nadrzędny został zmodyfikowany po utworzeniu obrazu różnicującego.\n\nMoże się to również zdarzyć, jeśli pliki obrazów zostały przeniesione lub skopiowane, lub wystąpił błąd w programie, który utworzył ten dysk\n\nCzy chcesz naprawić sygnatury czasowe?" - IDS_4133 "Sygnatury czasowe dysku nadrzędnego i podrzędnego nie zgadzają się" - IDS_4134 "Nie można naprawić sygnatury czasowej VHD." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Wyłączony" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Wyłączony" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1,2 MB" - IDS_5895 "1,25 MB" - IDS_5896 "1,44 MB" - IDS_5897 "DMF (klaster 1024)" - IDS_5898 "DMF (klaster 2048)" - IDS_5899 "2,88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1,3 GB (GigaMO)" - IDS_5907 "3.5"" 2,3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1,3 GB" - - IDS_6144 "Idealne obroty" - IDS_6145 "1% poniżej idealnych obrotów" - IDS_6146 "1.5% poniżej idealnych obrotów" - IDS_6147 "2% poniżej idealnych obrotów" - - IDS_7168 "(Domyślne ustawienie systemowe)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Polish (pl-PL) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/pt-BR.rc b/src/win/languages/pt-BR.rc deleted file mode 100644 index 4f72a41a4..000000000 --- a/src/win/languages/pt-BR.rc +++ /dev/null @@ -1,639 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Portuguese (pt-BR) resources -// -// Translated by Altieres Lima da Silva, 2021 -// - -#ifdef _WIN32 -LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Ação" - BEGIN - MENUITEM "&Teclado requer captura", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "CTRL &direito é o ALT esquerdo", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Reinicialização completa...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Pausar", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "&Sair...", IDM_ACTION_EXIT - END - POPUP "&Exibir" - BEGIN - MENUITEM "&Ocultar barra de status", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Ocultar &barra de ferramenta", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Mostrar monitores não-primários", IDM_VID_MONITORS - MENUITEM "&Janela redimensionável", IDM_VID_RESIZE - MENUITEM "&Lembrar tamanho e posição", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "&Renderizador" - BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (Núcleo 3.0)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "Especificar as dimensões...", IDM_VID_SPECIFY_DIM - MENUITEM "F&orçar proporção de tela em 4:3", IDM_VID_FORCE43 - POPUP "&Fator de redimensionamento da janela" - BEGIN - MENUITEM "&0,5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1,&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Método de filtragem" - BEGIN - MENUITEM "&Mais próximo", IDM_VID_FILTER_NEAREST - MENUITEM "&Linear", IDM_VID_FILTER_LINEAR - END - MENUITEM "Escala Hi&DPI", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Tela cheia\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Modo de &redimensionamento da tela cheia" - BEGIN - MENUITEM "&Tela cheia esticada", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "Pixel&s quadrados (manter proporção)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Redimensionamento com valores inteiros", IDM_VID_FS_INT - END - POPUP "Configurações E&GA/(S)VGA" - BEGIN - MENUITEM "Monitor VGA &invertido", IDM_VID_INVERT - POPUP "&Tipo de tela VGA" - BEGIN - MENUITEM "&Cores RGB", IDM_VID_GRAY_RGB - MENUITEM "Tons de cinza &RGB", IDM_VID_GRAY_MONO - MENUITEM "Monitor &âmbar", IDM_VID_GRAY_AMBER - MENUITEM "Monitor &verde", IDM_VID_GRAY_GREEN - MENUITEM "Monitor &branco", IDM_VID_GRAY_WHITE - END - POPUP "Tipo de &conversão de tons de cinza" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Média", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "Overscan do CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN - MENUITEM "Alterar contraste para exibição &monocromática", IDM_VID_CGACON - END - MENUITEM "&Mídia", IDM_MEDIA - POPUP "&Ferramentas" - BEGIN - MENUITEM "&Configurações...", IDM_CONFIG - MENUITEM "&Atualizar ícones da barra de status", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Capturar &tela\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Preferências...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Ativar integração com o &Discord", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Ganho de som...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Inicio do rastreamento\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Fim do rastreamento\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Ajuda" - BEGIN - MENUITEM "&Documentação...", IDM_DOCS - MENUITEM "&Sobre o 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova imagem...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Imagem existente...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Imagem existente (&protegida contra escrita)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Gravar", IDM_CASSETTE_RECORD - MENUITEM "&Reproduzir", IDM_CASSETTE_PLAY - MENUITEM "&Rebobinar até o começo", IDM_CASSETTE_REWIND - MENUITEM "&Avançar até o fim", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Imagem...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova imagem...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Imagem existente...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Imagem existente (&protegida contra escrita)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&xportar para 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Sem som", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "&Vazio", IDM_CDROM_EMPTY - MENUITEM "&Recarregar imagem anterior", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Imagem...", IDM_CDROM_IMAGE - MENUITEM "&Pasta...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova imagem...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Imagem existente...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Imagem existente (&protegida contra escrita)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_ZIP_EJECT - MENUITEM "&Recarregar imagem anterior", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova imagem...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Imagem existente...", IDM_MO_IMAGE_EXISTING - MENUITEM "Imagem existente (&protegida contra escrita)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_MO_EJECT - MENUITEM "&Recarregar imagem anterior", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "&Taxa de quadro pretendida" - BEGIN - MENUITEM "&Sincronizar com vídeo", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 qps", IDM_VID_GL_FPS_25 - MENUITEM "&30 qps", IDM_VID_GL_FPS_30 - MENUITEM "&50 qps", IDM_VID_GL_FPS_50 - MENUITEM "&60 qps", IDM_VID_GL_FPS_60 - MENUITEM "&75 qps", IDM_VID_GL_FPS_75 - END - MENUITEM "Sincronização &vertical", IDM_VID_GL_VSYNC - MENUITEM "&Selecionar shader...", IDM_VID_GL_SHADER - MENUITEM "&Remover shader", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Preferências" -#define STR_SND_GAIN "Ganho de som" -#define STR_NEW_FLOPPY "Nova imagem de disquete" -#define STR_CONFIG "Configurações" -#define STR_SPECIFY_DIM "Especifique as dimensões da janela principal" - -#define STR_OK "OK" -#define STR_CANCEL "Cancelar" -#define STR_GLOBAL "Usar estas configurações como &padrões globais" -#define STR_DEFAULT "&Padrão" -#define STR_LANGUAGE "Idioma:" -#define STR_ICONSET "Pacote de ícones:" - -#define STR_GAIN "Ganho" - -#define STR_FILE_NAME "Nome:" -#define STR_DISK_SIZE "Tamanho:" -#define STR_RPM_MODE "Modo RPM:" -#define STR_PROGRESS "Progresso:" - -#define STR_WIDTH "Largura:" -#define STR_HEIGHT "Altura:" -#define STR_LOCK_TO_SIZE "Travar nesse tamanho" - -#define STR_MACHINE_TYPE "Tipo de máquina:" -#define STR_MACHINE "Máquina:" -#define STR_CONFIGURE "Configurar" -#define STR_CPU_TYPE "Tipo de CPU:" -#define STR_CPU_SPEED "Veloc.:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Estados de espera:" -#define STR_MB "MB" -#define STR_MEMORY "Memória:" -#define STR_TIME_SYNC "Sincronização da hora" -#define STR_DISABLED "Desativar" -#define STR_ENABLED_LOCAL "Ativar (hora local)" -#define STR_ENABLED_UTC "Ativar (UTC)" -#define STR_DYNAREC "Recompilador dinâmico" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Vídeo:" -#define STR_VIDEO_2 "Vídeo 2:" -#define STR_VOODOO "3DFX Voodoo" -#define STR_IBM8514 "Gráficos IBM 8514/A" -#define STR_XGA "Gráficos XGA" - -#define STR_MOUSE "Mouse:" -#define STR_JOYSTICK "Joystick:" -#define STR_JOY1 "Joystick 1..." -#define STR_JOY2 "Joystick 2..." -#define STR_JOY3 "Joystick 3..." -#define STR_JOY4 "Joystick 4..." - -#define STR_SOUND1 "Placa de som 1:" -#define STR_SOUND2 "Placa de som 2:" -#define STR_SOUND3 "Placa de som 3:" -#define STR_SOUND4 "Placa de som 4:" -#define STR_MIDI_OUT "Disp. saída MIDI:" -#define STR_MIDI_IN "Disp. entrada MIDI:" -#define STR_MPU401 "MPU-401 autônomo" -#define STR_FLOAT "Usar som FLOAT32" -#define STR_FM_DRIVER "Controlador de sint. FM" -#define STR_FM_DRV_NUKED "Nuked (mais preciso)" -#define STR_FM_DRV_YMFM "YMFM (mais rápido)" - -#define STR_NET_TYPE "Tipo de rede:" -#define STR_PCAP "Dispositivo PCap:" -#define STR_NET "Adaptador de rede:" -#define STR_NET1 "Placa de rede 1:" -#define STR_NET2 "Placa de rede 2:" -#define STR_NET3 "Placa de rede 3:" -#define STR_NET4 "Placa de rede 4:" - -#define STR_COM1 "Dispositivo COM1:" -#define STR_COM2 "Dispositivo COM2:" -#define STR_COM3 "Dispositivo COM3:" -#define STR_COM4 "Dispositivo COM4:" -#define STR_LPT1 "Dispositivo LPT1:" -#define STR_LPT2 "Dispositivo LPT2:" -#define STR_LPT3 "Dispositivo LPT3:" -#define STR_LPT4 "Dispositivo LPT4:" -#define STR_SERIAL1 "Porta serial 1" -#define STR_SERIAL2 "Porta serial 2" -#define STR_SERIAL3 "Porta serial 3" -#define STR_SERIAL4 "Porta serial 4" -#define STR_PARALLEL1 "Porta paralela 1" -#define STR_PARALLEL2 "Porta paralela 2" -#define STR_PARALLEL3 "Porta paralela 3" -#define STR_PARALLEL4 "Porta paralela 4" -#define STR_SERIAL_PASS1 "Encaminhamento de porta serial 1" -#define STR_SERIAL_PASS2 "Encaminhamento de porta serial 2" -#define STR_SERIAL_PASS3 "Encaminhamento de porta serial 3" -#define STR_SERIAL_PASS4 "Encaminhamento de porta serial 4" - -#define STR_HDC "Controlador HD:" -#define STR_FDC "Controlador FD:" -#define STR_IDE_TER "Controlador IDE terciário" -#define STR_IDE_QUA "Controlador IDE quaternário" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Controlador 1:" -#define STR_SCSI_2 "Controlador 2:" -#define STR_SCSI_3 "Controlador 3:" -#define STR_SCSI_4 "Controlador 4:" -#define STR_CASSETTE "Cassete" - -#define STR_HDD "Discos rígidos:" -#define STR_NEW "&Novo..." -#define STR_EXISTING "&Existente..." -#define STR_REMOVE "&Remover" -#define STR_BUS "Bar.:" -#define STR_CHANNEL "Canal:" -#define STR_ID "ID:" -#define STR_SPEED "Velocidade:" - -#define STR_SPECIFY "&Especificar..." -#define STR_SECTORS "Setores:" -#define STR_HEADS "Cabeças:" -#define STR_CYLS "Cilindros:" -#define STR_SIZE_MB "Tamanho (MB):" -#define STR_TYPE "Tipo:" -#define STR_IMG_FORMAT "Formato:" -#define STR_BLOCK_SIZE "Blocos:" - -#define STR_FLOPPY_DRIVES "Unidades de disquete:" -#define STR_TURBO "Turbo" -#define STR_CHECKBPB "Verificar BPB" -#define STR_CDROM_DRIVES "Unidades de CD-ROM:" -#define STR_CD_SPEED "Veloc.:" - -#define STR_MO_DRIVES "Unidades magneto-ópticas:" -#define STR_ZIP_DRIVES "Unidades ZIP:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "RTC ISA:" -#define STR_ISAMEM "Expansão de memória ISA" -#define STR_ISAMEM_1 "Placa 1:" -#define STR_ISAMEM_2 "Placa 2:" -#define STR_ISAMEM_3 "Placa 3:" -#define STR_ISAMEM_4 "Placa 4:" -#define STR_BUGGER "Dispositivo ISABugger" -#define STR_POSTCARD "Placa de diagnóstico" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Erro" - IDS_2050 "Erro fatal" - IDS_2051 " - PAUSADO" - IDS_2052 "Use Ctrl+Alt+PgDn para retornar ao modo janela" - IDS_2053 "Velocidade" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "Imagens ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "O 86Box não conseguiu encontrar nenhuma imagem de ROM utilizável.\n\nPor favor, baixe um conjunto de ROM e extraia no diretório ""roms""." - IDS_2057 "(vazio)" - IDS_2058 "Imagens ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Todos os arquivos (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "Lig." - IDS_2061 "Desl." - IDS_2062 "Todas as imagens (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Imagens de setor básico (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Imagens de superfície (*.86F)\0*.86F\0" - IDS_2063 "A máquina ""%hs"" não está disponível devido à falta de ROMs no diretório roms/machines. Mudando para uma máquina disponível." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "A placa de vídeo ""%hs"" não está disponível devido à falta de ROMs no diretório roms/video. Mudando para uma placa de vídeo disponível." - IDS_2065 "Máquina" - IDS_2066 "Vídeo" - IDS_2067 "Dispositivos de entrada" - IDS_2068 "Som" - IDS_2069 "Rede" - IDS_2070 "Portas (COM & LPT)" - IDS_2071 "Controladores de armaz." - IDS_2072 "Discos rígidos" - IDS_2073 "Disquete & CD-ROM" - IDS_2074 "Dispos. removíveis" - IDS_2075 "Outros periféricos" - IDS_2076 "Imagens de superfície (*.86F)\0*.86F\0" - IDS_2077 "Clique para capturar o mouse" - IDS_2078 "Aperte F8+F12 para liberar o mouse" - IDS_2079 "Aperte F8+F12 ou botão do meio para liberar o mouse" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Barramento" - IDS_2082 "Arquivo" - IDS_2083 "CI" - IDS_2084 "CA" - IDS_2085 "SE" - IDS_2086 "MB" - IDS_2087 "Velocidade" - IDS_2088 "Verificar BPB" - IDS_2089 "KB" - IDS_2090 "Não foi possível inicializar o renderizador de vídeo." - IDS_2091 "Padrão" - IDS_2092 "%i estado(s) de espera" - IDS_2093 "Tipo" - IDS_2094 "Não foi possível configurar o PCap" - IDS_2095 "Nenhum dispositivo PCap encontrado" - IDS_2096 "Dispositivo PCap inválido" - IDS_2097 "Joystick padrão de 2 botões" - IDS_2098 "Joystick padrão de 4 botões" - IDS_2099 "Joystick padrão de 6 botões" - IDS_2100 "Joystick padrão de 8 botões" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Sistema de Controle de Voo Thrustmaster" - IDS_2104 "Nada" - IDS_2105 "Não foi possível carregar os aceleradores do teclado." - IDS_2106 "Não foi possível registrar a entrada bruta." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Disquete %i (%s): %ls" - IDS_2110 "Todas as imagens (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Imagens de setor avançado (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Imagens de setor básico (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Imagens de fluxo (*.FDI)\0*.FDI\0Imagens de superfície (*.86F;*.MFM)\0*.86F;*.MFM\0Todos os arquivos (*.*)\0*.*\0" - IDS_2113 "Tem certeza de que deseja reiniciar completamente a máquina emulada?" - IDS_2114 "Tem certeza de que deseja sair do 86Box?" - IDS_2115 "Não é possível inicializar o Ghostscript" - IDS_2116 "Magneto-óptico %i (%ls): %ls" - IDS_2117 "Imagens magneto-ópticas (*.IM?;*.MDI)\0*.IM?;*.MDI\0Todos os arquivos (*.*)\0*.*\0" - IDS_2118 "Bem-vindo ao 86Box!" - IDS_2119 "Controlador interno" - IDS_2120 "Sair" - IDS_2121 "Nenhum ROM encontrada" - IDS_2122 "Você deseja salvar as configurações?" - IDS_2123 "Isto fará com que a máquina emulada seja reinicializada." - IDS_2124 "Salvar" - IDS_2125 "Sobre o 86Box" - IDS_2126 "86Box versão" EMU_VERSION - - IDS_2127 "Um emulador de computadores antigos\n\nAutores: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, e outros.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, e outros.\n\nTraduzido por: Altieres Lima da Silva\n\nLançado sob a Licença Pública Geral GNU versão 2 ou posterior. Veja o arquivo LICENSE para mais informações." - IDS_2128 "OK" - IDS_2129 "Hardware não disponível" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Certifique-se de que " LIB_NAME_PCAP " esteja instalado e que você tenha uma conexão de rede compatível com " LIB_NAME_PCAP "." - IDS_2131 "Configuração inválida" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " é necessário para a conversão automática de arquivos PostScript para PDF.\n\nQualquer documento enviado para a impressora genérica PostScript será salvo como arquivos PostScript (.ps)." - IDS_2135 "Entrando no modo de tela cheia" - IDS_2136 "Não exibir esta mensagem novamente" - IDS_2137 "Não sair" - IDS_2138 "Reiniciar" - IDS_2139 "Não reiniciar" - IDS_2140 "Imagens magneto-ópticas (*.IM?;*.MDI)\0*.IM?;*.MDI\0Todos os arquivos (*.*)\0*.*\0" - IDS_2141 "Imagens de CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Todos os arquivos (*.*)\0*.*\0" - IDS_2142 "Configuração do dispositivo %hs" - IDS_2143 "Monitor em modo de suspensão" - IDS_2144 "Shaders OpenGL (*.GLSL)\0*.GLSL\0Todos os arquivos (*.*)\0*.*\0" - IDS_2145 "Opções do OpenGL" - IDS_2146 "Você está carregando uma configuração não suportada" - IDS_2147 "A filtragem do tipo CPU baseada na máquina selecionada é desativada para esta máquina emulada.\n\nIsto torna possível escolher uma CPU que de outra forma seria incompatível com a máquina selecionada. Entretanto, você pode encontrar incompatibilidades com a BIOS da máquina ou outro software.\n\nA ativação desta configuração não é oficialmente suportada e qualquer relatório de erro arquivado pode ser fechado como inválido." - IDS_2148 "Continuar" - IDS_2149 "Cassete: %s" - IDS_2150 "Imagens de cassete (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Todos os arquivos (*.*)\0*.*\0" - IDS_2151 "Cartucho %i: %ls" - IDS_2152 "Imagens de cartucho (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Todos os arquivos (*.*)\0*.*\0" - IDS_2153 "Erro ao inicializar o renderizador" - IDS_2154 "O renderizador OpenGL (Núcleo 3.0) não pôde ser inicializado. Use outro renderizador." - IDS_2155 "Continuar a execução" - IDS_2156 "Pausar a execução" - IDS_2157 "Pressionar Ctrl+Alt+Del" - IDS_2158 "Pressionar Ctrl+Alt+Esc" - IDS_2159 "Reinicialização completa" - IDS_2160 "Desligamento por ACPI" - IDS_2161 "Configurações" - IDS_2162 "Tipo" - IDS_2163 "Sem recompilador dinâmico" - IDS_2164 "Recompilador dinâmico antigo" - IDS_2165 "Novo recompilador dinâmico" - IDS_2166 "A placa de vídeo #2 ""%hs"" não está disponível devido à ausência de ROMs no diretório roms/video. Desabilitando a segunda placa de vídeo." - IDS_2167 "Falha ao inicializar o driver de rede" - IDS_2168 "A configuração de rede será alterada para o driver nulo" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Disco rígido (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "As unidades de CD-ROM MFM/RLL ou ESDI nunca existiram" - IDS_4100 "Personalizado..." - IDS_4101 "Personalizado (grande)..." - IDS_4102 "Adicionar novo disco rígido" - IDS_4103 "Adicionar disco rígido existente" - IDS_4104 "As imagens de disco HDI não podem ser maiores do que 4GB." - IDS_4105 "As imagens de disco não podem ser maiores do que 127GB." - IDS_4106 "Imagens de disco rígido (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Todos os arquivos (*.*)\0*.*\0" - IDS_4107 "Não foi possível ler o arquivo" - IDS_4108 "Não foi possível escrever o arquivo" - IDS_4109 "Imagens HDI ou HDX com um tamanho de setor que não seja 512 não são suportadas." - IDS_4110 "O USB ainda não é suportado" - IDS_4111 "Esta imagem existe" - IDS_4112 "Digite um nome de arquivo válido." - IDS_4113 "A imagem foi criada com sucesso" - IDS_4114 "Certifique-se de que o arquivo existe e é legível." - IDS_4115 "Certifique-se de que o arquivo está sendo salvo em um diretório gravável." - IDS_4116 "A imagem do disco é muito grande" - IDS_4117 "Lembre-se de particionar e formatar a unidade recém-criada." - IDS_4118 "O arquivo selecionado será sobrescrito. Você tem certeza de que deseja usá-lo?" - IDS_4119 "Imagem de disco sem suporte" - IDS_4120 "Sobrescrever" - IDS_4121 "Não sobrescrever" - IDS_4122 "Imagem bruta (.img)" - IDS_4123 "Imagem HDI (.hdi)" - IDS_4124 "Imagem HDX (.hdx)" - IDS_4125 "VHD de tamanho fixo (.vhd)" - IDS_4126 "VHD de tamanho dinâmico (.vhd)" - IDS_4127 "VHD diferencial (.vhd)" - IDS_4128 "Blocos grandes (2 MB)" - IDS_4129 "Blocos pequenos (512 KB)" - IDS_4130 "Arquivos VHD (*.VHD)\0*.VHD\0Todos os arquivos (*.*)\0*.*\0" - IDS_4131 "Selecione o VHD pai" - IDS_4132 "Isto pode significar que a imagem de origem foi modificada após a criação da imagem diferencial.\n\nTambém pode acontecer caso os arquivos de imagem tenham sido movidos ou copiados, ou por um erro no programa que criou este disco.\n\nVocê quer consertar os marcadores de tempo?" - IDS_4133 "A data/hora dos arquivos de pais e filhos não correspondem" - IDS_4134 "Não foi possível consertar o carimbo de data/hora da VHD." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Desativado" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Desativado" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (cluster 1024)" - IDS_5898 "DMF (cluster 2048)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "RPM perfeita" - IDS_6145 "1% abaixo das RPM perfeita" - IDS_6146 "1.5% abaixo das RPM perfeita" - IDS_6147 "2% abaixo das RPM perfeita" - - IDS_7168 "(Padrão do sistema)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Portuguese (pt-BR) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/pt-PT.rc b/src/win/languages/pt-PT.rc deleted file mode 100644 index c17cfe362..000000000 --- a/src/win/languages/pt-PT.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Portuguese (Portugal) resources - -#ifdef _WIN32 -LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Ação" - BEGIN - MENUITEM "&Teclado requere captura", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&CTRL direito é ALT esquerdo",IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Reinicialização completa...",IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Pausa", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "&Sair...", IDM_ACTION_EXIT - END - POPUP "&Ver" - BEGIN - MENUITEM "&Ocultar barra de estado", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Janela redimensionável", IDM_VID_RESIZE - MENUITEM "&Lembrar tamanho e posição", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "&Renderizador" - BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (Núcleo 3.0)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "&Especificar dimensões...", IDM_VID_SPECIFY_DIM - MENUITEM "&Forçar rácio de visualização 4:3", IDM_VID_FORCE43 - POPUP "F&actor de escala de janela" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Método de filtragem" - BEGIN - MENUITEM "&Mais próximo", IDM_VID_FILTER_NEAREST - MENUITEM "&Linear", IDM_VID_FILTER_LINEAR - END - MENUITEM "Escala Hi&DPI", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "E&crã cheio\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Modo &de estiramento em ecrã cheio" - BEGIN - MENUITEM "&Estiramento em ecrã cheio", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "Pixels &quadrados (Manter rácio)", IDM_VID_FS_KEEPRATIO - MENUITEM "Escala &inteira", IDM_VID_FS_INT - END - POPUP "Definições E&GA/(S)VGA" - BEGIN - MENUITEM "Monitor VGA &invertido", IDM_VID_INVERT - POPUP "&Tipo de ecrã VGA" - BEGIN - MENUITEM "&Cores RGB", IDM_VID_GRAY_RGB - MENUITEM "&RGB em escala de cinzentos", IDM_VID_GRAY_MONO - MENUITEM "Monitor âmb&ar", IDM_VID_GRAY_AMBER - MENUITEM "Monitor &verde", IDM_VID_GRAY_GREEN - MENUITEM "Monitor &branco", IDM_VID_GRAY_WHITE - END - POPUP "Tipo de &conversão para escala de cinzentos" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Media", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "Overscan de CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN - MENUITEM "Mudar &contraste para ecrã monocromático", IDM_VID_CGACON - END - MENUITEM "&Media", IDM_MEDIA - POPUP "&Ferramentas" - BEGIN - MENUITEM "&Definições...", IDM_CONFIG - MENUITEM "&Atualizar ícones da barra de estado", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Gravar imagem de ecrã\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Preferências...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Ativar integração com &Discord", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Ganho de som...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Iniciar o rastreio\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Terminar o rastreio\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Ajuda" - BEGIN - MENUITEM "&Documentação...", IDM_DOCS - MENUITEM "&Acerca do 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova imagem...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Imagem &existente...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Imagem existente (&Proteção contra escrita)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Gravar", IDM_CASSETTE_RECORD - MENUITEM "&Reproduzir", IDM_CASSETTE_PLAY - MENUITEM "Re&bobinar para o início", IDM_CASSETTE_REWIND - MENUITEM "&Avanço rápido para o fim", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Imagem...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova imagem...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Imagem &existente...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Imagem existente (&Proteção contra escrita)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&xportar para 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Mute", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "&CDROM vazio", IDM_CDROM_EMPTY - MENUITEM "&Recarregar imagem anterior", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Imagem...", IDM_CDROM_IMAGE - MENUITEM "&Pasta...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova imagem...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Imagem &existente...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Imagem existente (&Proteção contra escrita)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_ZIP_EJECT - MENUITEM "&Recarregar imagem anterior", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova imagem...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "Imagem &existente...", IDM_MO_IMAGE_EXISTING - MENUITEM "Imagem existente (&Proteção contra escrita)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_MO_EJECT - MENUITEM "&Recarregar imagem anterior", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "&Taxa de quadros de destino" - BEGIN - MENUITEM "&Sincronizar com vídeo", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 q/s", IDM_VID_GL_FPS_25 - MENUITEM "&30 q/s", IDM_VID_GL_FPS_30 - MENUITEM "&50 q/s", IDM_VID_GL_FPS_50 - MENUITEM "&60 q/s", IDM_VID_GL_FPS_60 - MENUITEM "&75 q/s", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Selecionar shader...", IDM_VID_GL_SHADER - MENUITEM "&Remover shader", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Preferências" -#define STR_SND_GAIN "Ganho de som" -#define STR_NEW_FLOPPY "Nova imagem" -#define STR_CONFIG "Definições" -#define STR_SPECIFY_DIM "Especificar dimensões da janela principal" - -#define STR_OK "OK" -#define STR_CANCEL "Cancelar" -#define STR_GLOBAL "Guardar estas definições como padrões &globais" -#define STR_DEFAULT "&Padrão" -#define STR_LANGUAGE "Idioma:" -#define STR_ICONSET "Pacote de ícones:" - -#define STR_GAIN "Ganho" - -#define STR_FILE_NAME "Nome:" -#define STR_DISK_SIZE "Tamanho:" -#define STR_RPM_MODE "Modo RPM:" -#define STR_PROGRESS "Progresso:" - -#define STR_WIDTH "Largura:" -#define STR_HEIGHT "Altura:" -#define STR_LOCK_TO_SIZE "Fixar neste tamanho" - -#define STR_MACHINE_TYPE "Tipo de máquina:" -#define STR_MACHINE "Máquina:" -#define STR_CONFIGURE "Configurar" -#define STR_CPU_TYPE "Tipo do CPU:" -#define STR_CPU_SPEED "Velocidade:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Estados de espera:" -#define STR_MB "MB" -#define STR_MEMORY "Memória:" -#define STR_TIME_SYNC "Sincronização da hora" -#define STR_DISABLED "Desativada" -#define STR_ENABLED_LOCAL "Ativada (hora local)" -#define STR_ENABLED_UTC "Ativada (UTC)" -#define STR_DYNAREC "Recompilador dinâmico" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Vídeo:" -#define STR_VIDEO_2 "Vídeo 2:" -#define STR_VOODOO "Gráficos Voodoo" -#define STR_IBM8514 "Gráficos IBM 8514/A" -#define STR_XGA "Gráficos XGA" - -#define STR_MOUSE "Rato:" -#define STR_JOYSTICK "Joystick:" -#define STR_JOY1 "Joystick 1..." -#define STR_JOY2 "Joystick 2..." -#define STR_JOY3 "Joystick 3..." -#define STR_JOY4 "Joystick 4..." - -#define STR_SOUND1 "Placa de som 1:" -#define STR_SOUND2 "Placa de som 2:" -#define STR_SOUND3 "Placa de som 3:" -#define STR_SOUND4 "Placa de som 4:" -#define STR_MIDI_OUT "Disp. saída MIDI:" -#define STR_MIDI_IN "Disp. entrada MIDI:" -#define STR_MPU401 "MPU-401 autónomo" -#define STR_FLOAT "Utilizar som FLOAT32" -#define STR_FM_DRIVER "Controlador de sint. FM" -#define STR_FM_DRV_NUKED "Nuked (mais exacto)" -#define STR_FM_DRV_YMFM "YMFM (mais rápido)" - -#define STR_NET_TYPE "Tipo de rede:" -#define STR_PCAP "Dispositivo PCap:" -#define STR_NET "Placa de rede:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "Dispositivo COM1:" -#define STR_COM2 "Dispositivo COM2:" -#define STR_COM3 "Dispositivo COM3:" -#define STR_COM4 "Dispositivo COM4:" -#define STR_LPT1 "Dispositivo LPT1:" -#define STR_LPT2 "Dispositivo LPT2:" -#define STR_LPT3 "Dispositivo LPT3:" -#define STR_LPT4 "Dispositivo LPT4:" -#define STR_SERIAL1 "Porta de série 1" -#define STR_SERIAL2 "Porta de série 2" -#define STR_SERIAL3 "Porta de série 3" -#define STR_SERIAL4 "Porta de série 4" -#define STR_PARALLEL1 "Porta paralela 1" -#define STR_PARALLEL2 "Porta paralela 2" -#define STR_PARALLEL3 "Porta paralela 3" -#define STR_PARALLEL4 "Porta paralela 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Controlador HD:" -#define STR_FDC "Controlador FD:" -#define STR_IDE_TER "Controlador IDE terciário" -#define STR_IDE_QUA "Controlador IDE quaternário" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Controlador 1:" -#define STR_SCSI_2 "Controlador 2:" -#define STR_SCSI_3 "Controlador 3:" -#define STR_SCSI_4 "Controlador 4:" -#define STR_CASSETTE "Cassete" - -#define STR_HDD "Discos rígidos:" -#define STR_NEW "&Novo..." -#define STR_EXISTING "&Existente..." -#define STR_REMOVE "&Remover" -#define STR_BUS "Barram.:" -#define STR_CHANNEL "Canal:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Especificar..." -#define STR_SECTORS "Sectores:" -#define STR_HEADS "Cabeças:" -#define STR_CYLS "Cilindros:" -#define STR_SIZE_MB "Tamanho (MB):" -#define STR_TYPE "Tipo:" -#define STR_IMG_FORMAT "Formato de imagem:" -#define STR_BLOCK_SIZE "Tamanho de bloco:" - -#define STR_FLOPPY_DRIVES "Unidades de disquete:" -#define STR_TURBO "Velocidade turbo" -#define STR_CHECKBPB "Verificar BPB" -#define STR_CDROM_DRIVES "Unidades CD-ROM:" -#define STR_CD_SPEED "Velocidade:" - -#define STR_MO_DRIVES "Unidades magneto-ópticas:" -#define STR_ZIP_DRIVES "Unidades ZIP:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA RTC:" -#define STR_ISAMEM "Expansão de memória ISA" -#define STR_ISAMEM_1 "Placa 1:" -#define STR_ISAMEM_2 "Placa 2:" -#define STR_ISAMEM_3 "Placa 3:" -#define STR_ISAMEM_4 "Placa 4:" -#define STR_BUGGER "Dispositivo ISABugger" -#define STR_POSTCARD "Placa POST" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Erro" - IDS_2050 "Erro fatal" - IDS_2051 " - PAUSED" - IDS_2052 "Pressione Ctrl+Alt+PgDn para voltar ao modo de janela." - IDS_2053 "Velocidade" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "Imagens ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "O 86Box não conseguiu encontrar nenhuma imagem ROM utilizável.\n\nPor favor, vá a href=""https://github.com/86Box/roms/releases/latest"">descarregue um pacote ROM e instale-o na pasta ""roms""." - IDS_2057 "(empty)" - IDS_2058 "Imagens ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Todos os ficheiros (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "Ativado" - IDS_2061 "Desativado" - IDS_2062 "Todas as imagens (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Imagens básicas de sector (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Imagens de superfície (*.86F)\0*.86F\0" - IDS_2063 "A máquina ""%hs"" não está disponível devido à falta de ROMs na pasta roms/machines. A mudar para uma máquina disponível." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "A placa vídeo ""%hs"" não está disponível devido à falta de ROMs na pasta roms/video. A mudar para uma placa vídeo disponível." - IDS_2065 "Máquina" - IDS_2066 "Apresentação" - IDS_2067 "Dispositivos de entrada" - IDS_2068 "Som" - IDS_2069 "Rede" - IDS_2070 "Portas (COM e LPT)" - IDS_2071 "Dispositivos de armazenamento" - IDS_2072 "Discos rígidos" - IDS_2073 "Unidades de disquete e CD-ROM" - IDS_2074 "Outros dispostivos removíveis" - IDS_2075 "Outros dispositivos" - IDS_2076 "Imagens de superfície (*.86F)\0*.86F\0" - IDS_2077 "Clique para capturar o rato" - IDS_2078 "Pressione F8+F12 para soltar o rato" - IDS_2079 "Pressione F8+F12 ou tecla média para soltar o rato" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Barramento" - IDS_2082 "Ficheiro" - IDS_2083 "C" - IDS_2084 "C" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "Verificar BPB" - IDS_2089 "KB" - IDS_2090 "Não foi possível inicializar o renderizador vídeo." - IDS_2091 "Padrão" - IDS_2092 "%i estado(s) de espera" - IDS_2093 "Tipo" - IDS_2094 "Falha na configuração de PCap" - IDS_2095 "Não foi encontrado um dispositivo PCap" - IDS_2096 "Dispositivo PCap inválido" - IDS_2097 "Joystick(s) standard de 2 botões" - IDS_2098 "Joystick(s) standard de 4 botões" - IDS_2099 "Joystick(s) standard de 6 botões" - IDS_2100 "Joystick(s) standard de 8 botões" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "Nenhum" - IDS_2105 "Não foi possível inicializar os aceleradores de teclado." - IDS_2106 "Não foi possível registar a entrada bruta." - IDS_2107 "%u" - IDS_2108 "%u MB (CCS: %i, %i, %i)" - IDS_2109 "Disquete %i (%s): %ls" - IDS_2110 "Todas as imagens (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Imagens avançadas de sector (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Imagens básicas de sector (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Imagens de fluxo (*.FDI)\0*.FDI\0Imagens de superfície (*.86F;*.MFM)\0*.86F;*.MFM\0Todos os ficheiros (*.*)\0*.*\0" - IDS_2113 "Tem a certeza de que quer um reinício completo da máquina emulada?" - IDS_2114 "Tem a certeza de que quer sair do 86Box?" - IDS_2115 "Não foi possível inicializar o Ghostscript" - IDS_2116 "Magneto-óptico %i (%ls): %ls" - IDS_2117 "Imagens magneto-ópticas (*.IM?;*.MDI)\0*.IM?;*.MDI\0Todas as imagens (*.*)\0*.*\0" - IDS_2118 "Bem-vindos ao 86Box!" - IDS_2119 "Controlador interno" - IDS_2120 "Sair" - IDS_2121 "Não foi encontrada nenhuma ROM" - IDS_2122 "Deseja guardar as definições?" - IDS_2123 "Isto irá causar um reinício completo da máquina emulada." - IDS_2124 "Guardar" - IDS_2125 "Acerca do 86Box" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "Um emulador de computadores antigos\n\nAutores: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nUsado sob a licença GNU General Public License versão 2 ou posterior. Veja o ficheiro LICENSE para mais informações." - IDS_2128 "OK" - IDS_2129 "Hardware não disponível" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Certifique-se de que a biblioteca " LIB_NAME_PCAP " está instalada e de que está a utilizar uma ligação de rede compatível com a biblioteca " LIB_NAME_PCAP "." - IDS_2131 "Configuração inválida" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " é requerido para a conversão automática de ficheiros PostScript para ficheiros PDF.\n\nQualquer documento enviado para a impressora PostScript genérica será gravado como um ficheiro PostScript (.ps)." - IDS_2135 "A entrar no modo de ecrã cheio" - IDS_2136 "Não mostrar mais esta mensagem" - IDS_2137 "Não sair" - IDS_2138 "Reiniciar" - IDS_2139 "Não reiniciar" - IDS_2140 "Imagens magneto-ópticas (*.IM?;*.MDI)\0*.IM?;*.MDI\0Todos os ficheiros (*.*)\0*.*\0" - IDS_2141 "Imagens CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Todos os ficheiros (*.*)\0*.*\0" - IDS_2142 "Configuração de dispositivo %hs" - IDS_2143 "Ecrã em modo de sono" - IDS_2144 "Shaders OpenGL (*.GLSL)\0*.GLSL\0Todos os ficheiros (*.*)\0*.*\0" - IDS_2145 "Opções de OpenGL" - IDS_2146 "Está a carregar uma configuração sem suporte!" - IDS_2147 "A filtragem do tipo de CPU baseada na máquina escolhida está desativada para esta máquina emulada.\n\nIsto torna possível escolher um CPU que, de outra forma, não seria compatível com a máquina escolhida. No entanto, pode não ser compatível com a BIOS da máquina ou outros programas.\n\nA activação desta definição não tem suporte oficial e qualquer relatório de erros pode ser fechado como inválido." - IDS_2148 "Continuar" - IDS_2149 "Cassete: %s" - IDS_2150 "Imagens de cassete (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Todos os ficheiros (*.*)\0*.*\0" - IDS_2151 "Cartucho %i: %ls" - IDS_2152 "Imagens de cartucho (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Todos os ficheiros (*.*)\0*.*\0" - IDS_2153 "Erro na inicialização do renderizador" - IDS_2154 "Não foi possível inicializar o renderizador OpenGL (3.0 Core). Utilize outro renderizador." - IDS_2155 "Retomar execução" - IDS_2156 "Pausar execução" - IDS_2157 "Ctrl+Alt+Del" - IDS_2158 "Ctrl+Alt+Esc" - IDS_2159 "Reinicialização completa" - IDS_2160 "Encerramento ACPI" - IDS_2161 "Definições" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Disco rígido (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "Unidades CD-ROM com barramento MFM/RLL ou ESDI nunca existiram!" - IDS_4100 "Personalizado..." - IDS_4101 "Personalizado (grande)..." - IDS_4102 "Adicionar novo disco rígido" - IDS_4103 "Adicionar disco rígido existente" - IDS_4104 "As imagens de disco HDI não podem ter mais de 4 GB." - IDS_4105 "As imagens de disco não podem ter mais de 127 GB." - IDS_4106 "Imagens de disco rígido (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Todos os ficheiros (*.*)\0*.*\0" - IDS_4107 "Não foi possível ler o ficheiro" - IDS_4108 "Não foi possível escrever o ficheiro" - IDS_4109 "Imagens HDI ou HDX com um tamanho de sector diferente de 512 não são suportadas." - IDS_4110 "O barramento USB ainda não tem suporte" - IDS_4111 "A imagem de disco já existe" - IDS_4112 "Por favor, especifique um nome de ficheiro válido." - IDS_4113 "Imagem de disco criada" - IDS_4114 "Certifique-se de que o ficheiro existe e é legível." - IDS_4115 "Certifique-se de que o ficheiro está a ser guardado numa pasta editável." - IDS_4116 "Imagem de disco muito grande" - IDS_4117 "Lembre-se de particionar e formatar o novo disco criado." - IDS_4118 "O ficheiro selecionado será sobrescrito. Tem a certeza de que quer utilizá-lo?" - IDS_4119 "Imagem de disco sem suporte" - IDS_4120 "Sobrescrever" - IDS_4121 "Não sobrescrever" - IDS_4122 "Imagem bruta (.img)" - IDS_4123 "Imagem HDI (.hdi)" - IDS_4124 "Imagem HDX (.hdx)" - IDS_4125 "VHD com tamanho fixo (.vhd)" - IDS_4126 "VHD com tamanho dinâmico (.vhd)" - IDS_4127 "VHD diferenciador (.vhd)" - IDS_4128 "Blocos grandes (2 MB)" - IDS_4129 "Blocos pequenos (512 KB)" - IDS_4130 "Ficheiros VHD (*.VHD)\0*.VHD\0Todos os ficheiros (*.*)\0*.*\0" - IDS_4131 "Seleccione o VHD pai" - IDS_4132 "Isto pode significar que a imagem pai foi modificada depois da criação da imagem diferenciadora.\n\nTambém pode acontecer se os ficheiros da imagem foram movidos ou copiados ou por causa de um erro no programa que criou este disco.\n\nQuer corrigir os carimbos de data/hora?" - IDS_4133 "Os carimbos de data/hora dos discos pai e filho não correspondem!" - IDS_4134 "Não foi possível corrigir o carimbo de data/hora do VHD." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Desativado" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Desativado" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (cluster 1024)" - IDS_5898 "DMF (cluster 2048)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "RPM perfeito" - IDS_6145 "RPM 1% abaixo do RPM perfeito" - IDS_6146 "RPM 1.5% abaixo do RPM perfeito" - IDS_6147 "RPM 2% abaixo do RPM perfeito" - - IDS_7168 "(Padrão do sistema)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Portuguese (Portugal) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/ru-RU.rc b/src/win/languages/ru-RU.rc deleted file mode 100644 index 719dd5a35..000000000 --- a/src/win/languages/ru-RU.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Russian resources - -#ifdef _WIN32 -LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Действие" - BEGIN - MENUITEM "&Клавиатура требует захвата", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Правый CTRL - это левый ALT", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Холодная перезагрузка...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Пауза", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "&Выход...", IDM_ACTION_EXIT - END - POPUP "&Вид" - BEGIN - MENUITEM "&Скрыть строку состояния", IDM_VID_HIDE_STATUS_BAR - MENUITEM "С&крыть панель инструментов", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Изменяемый размер окна", IDM_VID_RESIZE - MENUITEM "&Запомнить размер и положение", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "&Рендеринг" - BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "&Указать размеры...", IDM_VID_SPECIFY_DIM - MENUITEM "У&становить соотношение сторон 4:3", IDM_VID_FORCE43 - POPUP "&Масштаб окна" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Метод фильтрации" - BEGIN - MENUITEM "&Ближайший", IDM_VID_FILTER_NEAREST - MENUITEM "&Линейный", IDM_VID_FILTER_LINEAR - END - MENUITEM "Масштабирование Hi&DPI", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Полноэкранный режим\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "&Растягивание в полноэкранном режиме" - BEGIN - MENUITEM "&На весь экран", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Квадратные пиксели (сохранить соотношение)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Целочисленное масштабирование", IDM_VID_FS_INT - END - POPUP "Настройки E&GA/(S)VGA" - BEGIN - MENUITEM "&Инвертировать цвета VGA", IDM_VID_INVERT - POPUP "&Тип экрана VGA" - BEGIN - MENUITEM "RGB &цветной", IDM_VID_GRAY_RGB - MENUITEM "&RGB монохромный", IDM_VID_GRAY_MONO - MENUITEM "&Янтарный оттенок", IDM_VID_GRAY_AMBER - MENUITEM "&Зелёный оттенок", IDM_VID_GRAY_GREEN - MENUITEM "&Белый оттенок", IDM_VID_GRAY_WHITE - END - POPUP "Тип монохромного &конвертирования" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Усреднённый", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "Вылеты развёртки CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN - MENUITEM "Изменить контрастность &монохромного дисплея", IDM_VID_CGACON - END - MENUITEM "&Носители", IDM_MEDIA - POPUP "&Инструменты" - BEGIN - MENUITEM "&Настройки машины...", IDM_CONFIG - MENUITEM "&Обновление значков строки состояния", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Сделать с&криншот\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Параметры...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Включить интеграцию &Discord", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Усиление звука...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Начать трассировку\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Завершить трассировку\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Помощь" - BEGIN - MENUITEM "&Документация...", IDM_DOCS - MENUITEM "&О программе 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Новый образ...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Выбрать образ...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Выбрать образ (&Защита от записи)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Запись", IDM_CASSETTE_RECORD - MENUITEM "&Воспроизведение", IDM_CASSETTE_PLAY - MENUITEM "&Перемотка на начало", IDM_CASSETTE_REWIND - MENUITEM "&Перемотка в конец", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "И&звлечь", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Образ...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "И&звлечь", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Новый образ...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Выбрать образ...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Выбрать образ (&Защита от записи)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "Э&кспорт в 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "И&звлечь", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "О&тключить звук", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "П&устой", IDM_CDROM_EMPTY - MENUITEM "&Снова загрузить предыдущий образ", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Образ...", IDM_CDROM_IMAGE - MENUITEM "&Папка...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Новый образ...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Выбрать образ...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Выбрать образ (&Защита от записи)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "И&звлечь", IDM_ZIP_EJECT - MENUITEM "&Снова загрузить предыдущий образ", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Новый образ...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Выбрать образ...", IDM_MO_IMAGE_EXISTING - MENUITEM "Выбрать образ (&Защита от записи)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "И&звлечь", IDM_MO_EJECT - MENUITEM "&Снова загрузить предыдущий образ", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "Целевая &частота кадров" - BEGIN - MENUITEM "&Синхронизация с видео", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 кадров в секунду", IDM_VID_GL_FPS_25 - MENUITEM "&30 кадров в секунду", IDM_VID_GL_FPS_30 - MENUITEM "&50 кадров в секунду", IDM_VID_GL_FPS_50 - MENUITEM "&60 кадров в секунду", IDM_VID_GL_FPS_60 - MENUITEM "&75 кадров в секунду", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Выбрать шейдер...", IDM_VID_GL_SHADER - MENUITEM "&Удалить шейдер", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Параметры" -#define STR_SND_GAIN "Усиление звука" -#define STR_NEW_FLOPPY "Новый образ" -#define STR_CONFIG "Настройки" -#define STR_SPECIFY_DIM "Указать размеры главного окна" - -#define STR_OK "OK" -#define STR_CANCEL "Отмена" -#define STR_GLOBAL "Сохранить эти параметры как &глобальные по умолчанию" -#define STR_DEFAULT "&По умолчанию" -#define STR_LANGUAGE "Язык:" -#define STR_ICONSET "Набор иконок:" - -#define STR_GAIN "Усиление" - -#define STR_FILE_NAME "Имя файла:" -#define STR_DISK_SIZE "Размер диска:" -#define STR_RPM_MODE "RPM режим:" -#define STR_PROGRESS "Прогресс:" - -#define STR_WIDTH "Ширина:" -#define STR_HEIGHT "Высота:" -#define STR_LOCK_TO_SIZE "Зафиксировать размер" - -#define STR_MACHINE_TYPE "Тип машины:" -#define STR_MACHINE "Системная плата:" -#define STR_CONFIGURE "Настройка" -#define STR_CPU_TYPE "Тип ЦП:" -#define STR_CPU_SPEED "Скорость:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Циклы ожидания:" -#define STR_MB "МБ" -#define STR_MEMORY "Память:" -#define STR_TIME_SYNC "Синхронизация времени" -#define STR_DISABLED "Отключить" -#define STR_ENABLED_LOCAL "Включить (местное)" -#define STR_ENABLED_UTC "Включить (UTC)" -#define STR_DYNAREC "Динамический рекомпилятор" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Видеокарта:" -#define STR_VIDEO_2 "Видеокарта 2:" -#define STR_VOODOO "Ускоритель Voodoo" -#define STR_IBM8514 "Ускоритель IBM 8514/A" -#define STR_XGA "Ускоритель XGA" - -#define STR_MOUSE "Мышь:" -#define STR_JOYSTICK "Джойстик:" -#define STR_JOY1 "Джойстик 1..." -#define STR_JOY2 "Джойстик 2..." -#define STR_JOY3 "Джойстик 3..." -#define STR_JOY4 "Джойстик 4..." - -#define STR_SOUND1 "Звуковая карта 1:" -#define STR_SOUND2 "Звуковая карта 2:" -#define STR_SOUND3 "Звуковая карта 3:" -#define STR_SOUND4 "Звуковая карта 4:" -#define STR_MIDI_OUT "MIDI Out устр-во:" -#define STR_MIDI_IN "MIDI In устр-во:" -#define STR_MPU401 "Отдельный MPU-401" -#define STR_FLOAT "FLOAT32 звук" -#define STR_FM_DRIVER "Драйвер FM-синтезатора" -#define STR_FM_DRV_NUKED "Nuked (более точный)" -#define STR_FM_DRV_YMFM "YMFM (быстрей)" - -#define STR_NET_TYPE "Тип сети:" -#define STR_PCAP "Устройство PCap:" -#define STR_NET "Сетевая карта:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "Устройство COM1:" -#define STR_COM2 "Устройство COM2:" -#define STR_COM3 "Устройство COM3:" -#define STR_COM4 "Устройство COM4:" -#define STR_LPT1 "Устройство LPT1:" -#define STR_LPT2 "Устройство LPT2:" -#define STR_LPT3 "Устройство LPT3:" -#define STR_LPT4 "Устройство LPT4:" -#define STR_SERIAL1 "Последов. порт COM1" -#define STR_SERIAL2 "Последов. порт COM2" -#define STR_SERIAL3 "Последов. порт COM3" -#define STR_SERIAL4 "Последов. порт COM4" -#define STR_PARALLEL1 "Параллельный порт LPT1" -#define STR_PARALLEL2 "Параллельный порт LPT2" -#define STR_PARALLEL3 "Параллельный порт LPT3" -#define STR_PARALLEL4 "Параллельный порт LPT4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Контроллер HD:" -#define STR_FDC "Контроллер FD:" -#define STR_IDE_TER "Третичный IDE контроллер" -#define STR_IDE_QUA "Четвертичный IDE контроллер" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Контроллер 1:" -#define STR_SCSI_2 "Контроллер 2:" -#define STR_SCSI_3 "Контроллер 3:" -#define STR_SCSI_4 "Контроллер 4:" -#define STR_CASSETTE "Кассета" - -#define STR_HDD "Жёсткие диски:" -#define STR_NEW "&Создать..." -#define STR_EXISTING "&Выбрать..." -#define STR_REMOVE "&Убрать" -#define STR_BUS "Шина:" -#define STR_CHANNEL "Канал:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Указать..." -#define STR_SECTORS "Сектора:" -#define STR_HEADS "Головки:" -#define STR_CYLS "Цилиндры:" -#define STR_SIZE_MB "Размер (МБ):" -#define STR_TYPE "Тип:" -#define STR_IMG_FORMAT "Тип образа:" -#define STR_BLOCK_SIZE "Размер блока:" - -#define STR_FLOPPY_DRIVES "Гибкие диски:" -#define STR_TURBO "Турбо тайминги" -#define STR_CHECKBPB "Проверять BPB" -#define STR_CDROM_DRIVES "Дисководы CD-ROM:" -#define STR_CD_SPEED "Скорость:" - -#define STR_MO_DRIVES "Магнитооптические дисководы:" -#define STR_ZIP_DRIVES "ZIP дисководы:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA RTC:" -#define STR_ISAMEM "Карта расширения памяти (ISA)" -#define STR_ISAMEM_1 "Карта 1:" -#define STR_ISAMEM_2 "Карта 2:" -#define STR_ISAMEM_3 "Карта 3:" -#define STR_ISAMEM_4 "Карта 4:" -#define STR_BUGGER "Устройство ISABugger" -#define STR_POSTCARD "Карта POST" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Ошибка" - IDS_2050 "Неустранимая ошибка" - IDS_2051 " - ПАУЗА" - IDS_2052 "Нажмите Ctrl+Alt+PgDn для возврата в оконный режим." - IDS_2053 "Скорость" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "Образы ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box не смог найти ни одного подходящего для использования файла с ПЗУ.\n\nПожалуйста скачайте набор ПЗУ и извлеките его в каталог ""roms""." - IDS_2057 "(пусто)" - IDS_2058 "Образы ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Все файлы (*.*)\0*.*\0" - IDS_2059 "Турбо" - IDS_2060 "Вкл" - IDS_2061 "Выкл" - IDS_2062 "Все образы (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Простые посекторные образы (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Surface образы (*.86F)\0*.86F\0" - IDS_2063 "Системная плата ""%hs"" недоступна из-за отсутствия файла её ПЗУ в каталоге roms/machines. Переключение на доступную системную плату." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "Видеокарта ""%hs"" недоступна из-за отсутствия файла её ПЗУ в каталоге roms/video. Переключение на доступную видеокарту." - IDS_2065 "Компьютер" - IDS_2066 "Дисплей" - IDS_2067 "Устройства ввода" - IDS_2068 "Звук" - IDS_2069 "Сеть" - IDS_2070 "Порты (COM и LPT)" - IDS_2071 "Контроллеры дисков" - IDS_2072 "Жёсткие диски" - IDS_2073 "Гибкие диски и CD-ROM" - IDS_2074 "Другие съёмные устр-ва" - IDS_2075 "Другая периферия" - IDS_2076 "Образы Surface (*.86F)\0*.86F\0" - IDS_2077 "Щёлкните мышью для захвата курсора" - IDS_2078 "Нажмите F8+F12 чтобы освободить курсор" - IDS_2079 "Нажмите F8+F12 или среднюю кнопку мыши чтобы освободить курсор" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Шина" - IDS_2082 "Файл" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "МБ" - IDS_2087 "Speed" - IDS_2088 "Проверять BPB" - IDS_2089 "КБ" - IDS_2090 "Не удалось инициализировать рендерер видео." - IDS_2091 "По умолчанию" - IDS_2092 "%i WS" - IDS_2093 "Тип" - IDS_2094 "Не удалось настроить PCap" - IDS_2095 "Устройства PCap не найдены" - IDS_2096 "Неверное устройство PCap" - IDS_2097 "Стандартный 2-кнопочный джойстик" - IDS_2098 "Стандартный 4-кнопочный джойстик" - IDS_2099 "Стандартный 6-кнопочный джойстик" - IDS_2100 "Стандартный 8-кнопочный джойстик" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Система управления полетом Thrustmaster" - IDS_2104 "Нет" - IDS_2105 "Невозможно загрузить ускорители клавиатуры." - IDS_2106 "Невозможно зарегистрировать необработанный (RAW) ввод." - IDS_2107 "%u" - IDS_2108 "%u МБ (CHS: %i, %i, %i)" - IDS_2109 "Дисковод %i (%s): %ls" - IDS_2110 "Все образы (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Расширенные образы секторов (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Основные образы секторов (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Образы Flux (*.FDI)\0*.FDI\0Образы Surface (*.86F;*.MFM)\0*.86F;*.MFM\0Все файлы (*.*)\0*.*\0" - IDS_2113 "Вы уверены, что хотите выполнить холодную перезагрузку эмулируемой машины?" - IDS_2114 "Вы уверены, что хотите выйти из 86Box?" - IDS_2115 "Невозможно инициализировать Ghostscript" - IDS_2116 "Магнитооптический %i (%ls): %ls" - IDS_2117 "Образы магнитооптических дисков (*.IM?;*.MDI)\0*.IM?;*.MDI\0Все файлы (*.*)\0*.*\0" - IDS_2118 "Добро пожаловать в 86Box!" - IDS_2119 "Встроенный контроллер" - IDS_2120 "Выход" - IDS_2121 "ПЗУ не найдены" - IDS_2122 "Хотите ли вы сохранить настройки?" - IDS_2123 "Это приведет к холодной перезагрузке эмулируемой машины." - IDS_2124 "Сохранить" - IDS_2125 "О 86Box" - IDS_2126 "86Box v." EMU_VERSION - - IDS_2127 "Эмулятор старых компьютеров\n\nАвторы: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nВыпускается под лицензией GNU General Public License версии 2 или более поздней. Дополнительную информацию см. в файле LICENSE." - IDS_2128 "OK" - IDS_2129 "Оборудование недоступно" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Убедитесь, что " LIB_NAME_PCAP " установлен и ваше сетевое соединение, совместимо с " LIB_NAME_PCAP "." - IDS_2131 "Недопустимая конфигурация" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " требуется для автоматического преобразования файлов PostScript в PDF.\n\nВсе документы, отправленные на общий принтер PostScript, будут сохранены в виде файлов PostScript (.ps)." - IDS_2135 "Вход в полноэкранный режим" - IDS_2136 "Больше не показывать это сообщение" - IDS_2137 "Не выходить" - IDS_2138 "Перезагрузить" - IDS_2139 "Не перезагружать" - IDS_2140 "Образы магнитооптических дисков (*.IM?;*.MDI)\0*.IM?;*.MDI\0Все файлы (*.*)\0*.*\0" - IDS_2141 "Образы CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Все файлы (*.*)\0*.*\0" - IDS_2142 "Конфигурация устройства %hs" - IDS_2143 "Монитор в спящем режиме" - IDS_2144 "Шейдеры OpenGL (*.GLSL)\0*.GLSL\0Все файлы (*.*)\0*.*\0" - IDS_2145 "Параметры OpenGL" - IDS_2146 "Вы загружаете неподдерживаемую конфигурацию" - IDS_2147 "Выбор типов ЦП для этой системной платы на данной эмулируемой машине отключен.\n\nЭто позволяет выбрать процессор, который в противном случае несовместим с выбранной материнской платой. Однако, вы можете столкнуться с несовместимостью с BIOS материнской платы или другим ПО.\n\nВключение этого параметра официально не поддерживается, и все поданные отчеты об ошибках могут быть закрыты как недействительные." - IDS_2148 "Продолжить" - IDS_2149 "Кассета: %s" - IDS_2150 "Образы кассет (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Все файлы (*.*)\0*.*\0" - IDS_2151 "Картридж %i: %ls" - IDS_2152 "Образы картриджей (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Все файлы (*.*)\0*.*\0" - IDS_2153 "Ошибка инициализации рендерера" - IDS_2154 "Невозможно инициализировать рендерер OpenGL (3.0). Пожалуйста, используйте другой рендерер." - IDS_2155 "Возобновить выполнение" - IDS_2156 "Приостановить выполнение" - IDS_2157 "Нажать Ctrl+Alt+Del" - IDS_2158 "Нажать Ctrl+Alt+Esc" - IDS_2159 "Холодная перезагрузка" - IDS_2160 "Сигнал завершения ACPI" - IDS_2161 "Настройки машины" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Жёсткий диск (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLL или ESDI дисководов CD-ROM никогда не существовало" - IDS_4100 "Задать вручную..." - IDS_4101 "Задать вручную (large)..." - IDS_4102 "Создать новый жёсткий диск" - IDS_4103 "Выбрать существующий жёсткий диск" - IDS_4104 "Размер образов дисков HDI не может превышать 4 ГБ." - IDS_4105 "Размер образов дисков не может превышать 127 ГБ." - IDS_4106 "Образы жёстких дисков (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Все файлы (*.*)\0*.*\0" - IDS_4107 "Невозможно прочитать файл" - IDS_4108 "Невозможно записать файл" - IDS_4109 "Образы HDI или HDX с размером сектора, отличным от 512, не поддерживаются." - IDS_4110 "USB пока не поддерживается" - IDS_4111 "Файл образа диска уже существует" - IDS_4112 "Пожалуйста, укажите правильное имя файла." - IDS_4113 "Образ диска создан" - IDS_4114 "Убедитесь, что файл существует и доступен для чтения." - IDS_4115 "Убедитесь, что файл сохраняется в директории доступной для записи." - IDS_4116 "Слишком большой образ диска" - IDS_4117 "Не забудьте разметить и отформатировать вновь созданный диск." - IDS_4118 "Выбранный файл будет перезаписан. Вы уверены, что хотите использовать его?" - IDS_4119 "Неподдерживаемый образ диска" - IDS_4120 "Перезаписать" - IDS_4121 "Не перезаписывать" - IDS_4122 "RAW образ (.img)" - IDS_4123 "Образ HDI (.hdi)" - IDS_4124 "Образ HDX (.hdx)" - IDS_4125 "VHD фиксированного размера (.vhd)" - IDS_4126 "VHD динамического размера (.vhd)" - IDS_4127 "Дифференцированный образ VHD (.vhd)" - IDS_4128 "Большие блоки (2 МБ)" - IDS_4129 "Маленькие блоки (512 КБ)" - IDS_4130 "Файлы VHD (*.VHD)\0*.VHD\0Все файлы (*.*)\0*.*\0" - IDS_4131 "Выберите родительский VHD" - IDS_4132 "Это может означать, что родительский образ был изменён после того, как был создан дифференцированный образ.\n\nЭто также может произойти, если файлы образа были перемещены или скопированы, или из-за ошибки в программе, создавшей этот диск.\n\nВы хотите исправить временные метки?" - IDS_4133 "Временные метки родительского и дочернего дисков не совпадают" - IDS_4134 "Не удалось исправить временную метку VHD." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Отключён" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Отключён" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 кБ" - IDS_5889 "180 кБ" - IDS_5890 "320 кБ" - IDS_5891 "360 кБ" - IDS_5892 "640 кБ" - IDS_5893 "720 кБ" - IDS_5894 "1.2 МБ" - IDS_5895 "1.25 МБ" - IDS_5896 "1.44 МБ" - IDS_5897 "DMF (кластер 1024)" - IDS_5898 "DMF (кластер 2048)" - IDS_5899 "2.88 МБ" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 МБ (ISO 10090)" - IDS_5903 "3.5"" 230 МБ (ISO 13963)" - IDS_5904 "3.5"" 540 МБ (ISO 15498)" - IDS_5905 "3.5"" 640 МБ (ISO 15498)" - IDS_5906 "3.5"" 1.3 ГБ (GigaMO)" - IDS_5907 "3.5"" 2.3 ГБ (GigaMO 2)" - IDS_5908 "5.25"" 600 МБ" - IDS_5909 "5.25"" 650 МБ" - IDS_5910 "5.25"" 1 ГБ" - IDS_5911 "5.25"" 1.3 ГБ" - - IDS_6144 "Точный RPM" - IDS_6145 "На 1% медленнее точного RPM" - IDS_6146 "На 1.5% медленнее точного RPM" - IDS_6147 "На 2% медленнее точного RPM" - - IDS_7168 "(Системный)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Russian resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/sl-SI.rc b/src/win/languages/sl-SI.rc deleted file mode 100644 index 3a8b12dbb..000000000 --- a/src/win/languages/sl-SI.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Slovenian resources - -#ifdef _WIN32 -LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Dejanja" - BEGIN - MENUITEM "&Tipkovnica potrebuje zajem", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Desni CTRL je levi ALT", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Ponovni zagon...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Premor", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "Iz&hod...", IDM_ACTION_EXIT - END - POPUP "&Pogled" - BEGIN - MENUITEM "&Skrij statusno vrstico", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "S&premenljiva velikost okna", IDM_VID_RESIZE - MENUITEM "&Zapomni si velikost in položaj", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "&Upodabljanje" - BEGIN - MENUITEM "&SDL (programsko)", IDM_VID_SDL_SW - MENUITEM "SDL (s&trojno)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (Jedro 3.0)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "&Določi velikost...", IDM_VID_SPECIFY_DIM - MENUITEM "&Vsili 4:3 razmerje zaslona", IDM_VID_FORCE43 - POPUP "&Faktor velikosti okna" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "&Metoda filtriranja" - BEGIN - MENUITEM "&Najbližja", IDM_VID_FILTER_NEAREST - MENUITEM "&Linearna", IDM_VID_FILTER_LINEAR - END - MENUITEM "&Raztezanje za visok DPI", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Celozaslonski način\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "&Način celozaslonskega raztezanja" - BEGIN - MENUITEM "&Raztegni na celoten zaslon", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Kvadratni piksli (ohrani razmerje)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Celoštevilsko raztezanje", IDM_VID_FS_INT - END - POPUP "Nastavitve E&GA/(S)VGA" - BEGIN - MENUITEM "&Obrni barve zaslona VGA", IDM_VID_INVERT - POPUP "&Vrsta zaslona VGA" - BEGIN - MENUITEM "&Barvni RGB", IDM_VID_GRAY_RGB - MENUITEM "&Sivinski RGB", IDM_VID_GRAY_MONO - MENUITEM "&Rumeni zaslon", IDM_VID_GRAY_AMBER - MENUITEM "&Zeleni zaslon", IDM_VID_GRAY_GREEN - MENUITEM "B&eli zaslon", IDM_VID_GRAY_WHITE - END - POPUP "V&rsta pretvorbe sivin" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Povprečje", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "&Presežek slike CGA/PCjr/Tandy/EGA/(S)VGA", IDM_VID_OVERSCAN - MENUITEM "&Spremeni contrast za črno-beli zaslon", IDM_VID_CGACON - END - MENUITEM "&Mediji", IDM_MEDIA - POPUP "&Orodja" - BEGIN - MENUITEM "&Nastavitve...", IDM_CONFIG - MENUITEM "&Posodabljaj ikone statusne vrstice", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "&Zajemi posnetek zaslona\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Možnosti...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Omogoči integracijo s programom &Discord", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Ojačanje zvoka...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Z&ačni sledenje\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "&Končaj sledenje\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Pomoč" - BEGIN - MENUITEM "&Dokumentacija...", IDM_DOCS - MENUITEM "&O programu 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova slika...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Obstoječa slika...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Obstoječa slika (&samo za branje)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "Snemaj", IDM_CASSETTE_RECORD - MENUITEM "Predvajaj", IDM_CASSETTE_PLAY - MENUITEM "Previj na začetek", IDM_CASSETTE_REWIND - MENUITEM "Preskoči na konec", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "Izvrzi", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "Slika...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "Izvrzi", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova slika...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Obstoječa slika...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Obstoječa slika (&samo za branje)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Izvozi v 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "I&zvrzi", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Utišaj", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "&Prazen", IDM_CDROM_EMPTY - MENUITEM "&Naloži zadnjo sliko", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Slika...", IDM_CDROM_IMAGE - MENUITEM "&Mapa...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova slika...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Obstoječa slika...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Obstoječa slika (&samo za branje)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "I&zvrzi", IDM_ZIP_EJECT - MENUITEM "&Naloži zadnjo sliko", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Nova slika...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Obstoječa slika...", IDM_MO_IMAGE_EXISTING - MENUITEM "Obstoječa slika (&samo za branje)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "I&zvrzi", IDM_MO_EJECT - MENUITEM "&Naloži zadnjo sliko", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "&Ciljno št. sličic na sekundo" - BEGIN - MENUITEM "&Sinhroniziraj z videom", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 fps", IDM_VID_GL_FPS_25 - MENUITEM "&30 fps", IDM_VID_GL_FPS_30 - MENUITEM "&50 fps", IDM_VID_GL_FPS_50 - MENUITEM "&60 fps", IDM_VID_GL_FPS_60 - MENUITEM "&75 fps", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Izberi senčilnik...", IDM_VID_GL_SHADER - MENUITEM "&Odstrani senčilnik", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Možnosti" -#define STR_SND_GAIN "Ojačanje zvoka" -#define STR_NEW_FLOPPY "Nova slika" -#define STR_CONFIG "Nastavitve" -#define STR_SPECIFY_DIM "Določi velikost glavnega okna" - -#define STR_OK "V redu" -#define STR_CANCEL "Prekliči" -#define STR_GLOBAL "Shrani te nastavitve kot globalne privzete" -#define STR_DEFAULT "Privzeto" -#define STR_LANGUAGE "Jezik:" -#define STR_ICONSET "Komplet ikon:" - -#define STR_GAIN "Ojačanje" - -#define STR_FILE_NAME "Ime datoteke:" -#define STR_DISK_SIZE "Velikost diska:" -#define STR_RPM_MODE "Način števila obratov:" -#define STR_PROGRESS "Napredek:" - -#define STR_WIDTH "Širina:" -#define STR_HEIGHT "Višina:" -#define STR_LOCK_TO_SIZE "Zakleni na to velikost" - -#define STR_MACHINE_TYPE "Vrsta sistema:" -#define STR_MACHINE "Sistem:" -#define STR_CONFIGURE "Nastavi" -#define STR_CPU_TYPE "Vrsta procesorja:" -#define STR_CPU_SPEED "Hitrost:" -#define STR_FPU "Procesor plavajoče vejice:" -#define STR_WAIT_STATES "Čakalna stanja:" -#define STR_MB "MB" -#define STR_MEMORY "Spomin:" -#define STR_TIME_SYNC "Sinhronizacija časa" -#define STR_DISABLED "Onemogočeno" -#define STR_ENABLED_LOCAL "Omogočeno (lokalni čas)" -#define STR_ENABLED_UTC "Omogočeno (UTC)" -#define STR_DYNAREC "Dinamični prevajalnik" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Video:" -#define STR_VIDEO_2 "Video 2:" -#define STR_VOODOO "Voodoo grafika" -#define STR_IBM8514 "IBM 8514/A grafika" -#define STR_XGA "XGA grafika" - -#define STR_MOUSE "Miška:" -#define STR_JOYSTICK "Igralna palica:" -#define STR_JOY1 "Igralna palica 1..." -#define STR_JOY2 "Igralna palica 2..." -#define STR_JOY3 "Igralna palica 3..." -#define STR_JOY4 "Igralna palica 4..." - -#define STR_SOUND1 "Zvočna kartica 1:" -#define STR_SOUND2 "Zvočna kartica 2:" -#define STR_SOUND3 "Zvočna kartica 3:" -#define STR_SOUND4 "Zvočna kartica 4:" -#define STR_MIDI_OUT "Izhodna naprava MIDI:" -#define STR_MIDI_IN "Vhodna naprava MIDI:" -#define STR_MPU401 "Samostojen MPU-401" -#define STR_FLOAT "Uporabi FLOAT32 za zvok" -#define STR_FM_DRIVER "Gonilnik sintetizacije FM" -#define STR_FM_DRV_NUKED "Nuked (točnejši)" -#define STR_FM_DRV_YMFM "YMFM (hitrejši)" - -#define STR_NET_TYPE "Vrsta omrežja:" -#define STR_PCAP "Naprava PCap:" -#define STR_NET "Omrežna kartica:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "Naprava COM1:" -#define STR_COM2 "Naprava COM2:" -#define STR_COM3 "Naprava COM3:" -#define STR_COM4 "Naprava COM4:" -#define STR_LPT1 "Naprava LPT1:" -#define STR_LPT2 "Naprava LPT2:" -#define STR_LPT3 "Naprava LPT3:" -#define STR_LPT4 "Naprava LPT4:" -#define STR_SERIAL1 "Serijska vrata 1" -#define STR_SERIAL2 "Serijska vrata 2" -#define STR_SERIAL3 "Serijska vrata 3" -#define STR_SERIAL4 "Serijska vrata 4" -#define STR_PARALLEL1 "Paralelna vrata 1" -#define STR_PARALLEL2 "Paralelna vrata 2" -#define STR_PARALLEL3 "Paralelna vrata 3" -#define STR_PARALLEL4 "Paralelna vrata 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Krmilnik trdega diska:" -#define STR_FDC "Krmilnik disketnika:" -#define STR_IDE_TER "Terciarni krmilnik IDE" -#define STR_IDE_QUA "Kvartarni krmilnik IDE" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Krmilnik 1:" -#define STR_SCSI_2 "Krmilnik 2:" -#define STR_SCSI_3 "Krmilnik 3:" -#define STR_SCSI_4 "Krmilnik 4:" -#define STR_CASSETTE "Kasetnik" - -#define STR_HDD "Trdi diski:" -#define STR_NEW "Nov..." -#define STR_EXISTING "Obstoječ..." -#define STR_REMOVE "Odstrani" -#define STR_BUS "Vodilo:" -#define STR_CHANNEL "Kanal:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "Določi..." -#define STR_SECTORS "Sektorji:" -#define STR_HEADS "Glave:" -#define STR_CYLS "Cilindri:" -#define STR_SIZE_MB "Velikost (MB):" -#define STR_TYPE "Vrsta:" -#define STR_IMG_FORMAT "Format slike:" -#define STR_BLOCK_SIZE "Velikost bloka:" - -#define STR_FLOPPY_DRIVES "Disketni pogoni:" -#define STR_TURBO "Turbo časovniki" -#define STR_CHECKBPB "Preverjaj BPB" -#define STR_CDROM_DRIVES "Pogoni CD-ROM:" -#define STR_CD_SPEED "Hitrost:" - -#define STR_MO_DRIVES "Magnetno-optični pogoni:" -#define STR_ZIP_DRIVES "Pogoni ZIP:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "Ura v realnem času ISA:" -#define STR_ISAMEM "Razširitev spomina ISA" -#define STR_ISAMEM_1 "Kartica 1:" -#define STR_ISAMEM_2 "Kartica 2:" -#define STR_ISAMEM_3 "Kartica 3:" -#define STR_ISAMEM_4 "Kartica 4:" -#define STR_BUGGER "Naprava ISABugger" -#define STR_POSTCARD "Kartica POST" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Napaka" - IDS_2050 "Kritična napaka" - IDS_2051 " - PAUSED" - IDS_2052 "Pritisnite Ctrl+Alt+PgDn za povratek iz celozaslonskega načina." - IDS_2053 "Hitrost" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIP slike (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box ni našel nobenih uporabnih ROM slik.\n\nProsim prenesite set ROM-ov in ga razširite v mapo ""roms""." - IDS_2057 "(prazno)" - IDS_2058 "ZIP slike (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Vse datoteke (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "Vključeno" - IDS_2061 "Izključeno" - IDS_2062 "Vse slike (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Osnovne sektorske slike (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Površinske slike (*.86F)\0*.86F\0" - IDS_2063 "Sistem ""%hs"" ni na voljo zaradi manjkajočih ROM-ov v mapi roms/machines. Preklapljam na drug sistem, ki je na voljo." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "Grafična kartica ""%hs"" ni na voljo zaradi manjkajočih ROM-ov v mapi roms/video. Preklapljam na drugo grafično kartico, ki je na voljo.." - IDS_2065 "Sistem" - IDS_2066 "Zaslon" - IDS_2067 "Vhodne naprave" - IDS_2068 "Zvok" - IDS_2069 "Omrežje" - IDS_2070 "Vrata (COM & LPT)" - IDS_2071 "Krmilniki shrambe" - IDS_2072 "Trdi diski" - IDS_2073 "Disketni in CD-ROM pogoni" - IDS_2074 "Druge odstranljive naprave" - IDS_2075 "Druga periferija" - IDS_2076 "Površinske slike (*.86F)\0*.86F\0" - IDS_2077 "Kliknite za zajem miške" - IDS_2078 "Pritisnite F8+F12 za izpust miške" - IDS_2079 "Pritisnite F8+F12 ali srednji gumb za izpust miške" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Vodilo" - IDS_2082 "Datoteka" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "Preveri BPB" - IDS_2089 "KB" - IDS_2090 "Ne morem inicializirati pogona upodabljanja." - IDS_2091 "Privzeto" - IDS_2092 "%i stanj čakanja" - IDS_2093 "Vrsta" - IDS_2094 "Nastavitev PCap ni uspela" - IDS_2095 "Nobena naprava PCap ni bila najdena" - IDS_2096 "Neveljavna naprava PCap" - IDS_2097 "Standardna krmilna palica z 2 gumboma" - IDS_2098 "Standardna krmilna palica s 4 gumbi" - IDS_2099 "Standardna krmilna palica s 6 gumbi" - IDS_2100 "Standardna krmilna palica z 8 gumbi" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "Brez" - IDS_2105 "Ne morem naložiti pospeševalnikov tipkovnice." - IDS_2106 "Ne morem registrirati neobdelanega vnosa." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Disketa %i (%s): %ls" - IDS_2110 "Vse slike (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Napredne sektorske slike (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Osnovne sektorske slike (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Tokovne slike (*.FDI)\0*.FDI\0Površinske slike (*.86F;*.MFM)\0*.86F;*.MFM\0Vse datoteke (*.*)\0*.*\0" - IDS_2113 "Ste prepričani, da želite ponovno zagnati emulirani sistem?" - IDS_2114 "Ste prepričani, da želite zapreti 86Box?" - IDS_2115 "Ne morem inicializirati Ghostscript" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "Slike MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0Vse datoteke (*.*)\0*.*\0" - IDS_2118 "Dobrodošli v 86Box!" - IDS_2119 "Notranji krmilnik" - IDS_2120 "Izhod" - IDS_2121 "Nobeni ROM-i niso bili najdeni" - IDS_2122 "Želite shraniti nastavitve?" - IDS_2123 "To bo ponovno zagnalo emuliran sistem." - IDS_2124 "Shrani" - IDS_2125 "O programu 86Box" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "Emulator starih računalnikov\n\nAvtorji: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne in drugi.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho in drugi.\n\nIzdano pod licenco GNU General Public License različica 2 ali novejša. Glej datoteko LICENSE za več informacij." - IDS_2128 "V redu" - IDS_2129 "Strojna oprema ni na voljo" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Prepičajte se, da je nameščen " LIB_NAME_PCAP " in da ste na omrežni povezavi, združljivi z " LIB_NAME_PCAP - IDS_2131 "Neveljavna konfiguracija" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " je potreben za samodejno pretvorbo PostScript datotek v PDF.\n\nVsi dokumenti, poslani generičnemu PostScript tiskalniku bodo shranjeni kot PostScript (.ps) datoteke." - IDS_2135 "Preklapljam v celozaslonski način" - IDS_2136 "Ne pokaži več tega sporočila" - IDS_2137 "Prekliči izhod" - IDS_2138 "Resetiraj" - IDS_2139 "Ne resetiraj" - IDS_2140 "Slike MO (*.IM?;*.MDI)\0*.IM?;*.MDI\0Vse datoteke (*.*)\0*.*\0" - IDS_2141 "Slike CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Vse datoteke (*.*)\0*.*\0" - IDS_2142 "Konfiguracija naprave %hs" - IDS_2143 "Zaslon v načinu spanja" - IDS_2144 "Senčilniki OpenGL (*.GLSL)\0*.GLSL\0Vse datoteke (*.*)\0*.*\0" - IDS_2145 "Možnosti OpenGL" - IDS_2146 "Nalagate nepodprto konfiguracijo" - IDS_2147 "Filtriranje vrste procesorja glede na izbran sistem je onemogočeno za ta emuliran sistem.\n\nTako lahko izberete procesor, ki je sicer nezdružljiv z izbranim sistemom. Vendar lahko naletite na nezdružljivosti z BIOS-om sistema ali drugo programsko opremo\n\nOmogočanje te nastavitve ni uradno podprto, vsa poročila o hroščih iz tega naslova pa bodo zaprta kot neveljavna." - IDS_2148 "Nadaljuj" - IDS_2149 "Kaseta: %s" - IDS_2150 "Slike kaset (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Vse datoteke (*.*)\0*.*\0" - IDS_2151 "Spominski vložek %i: %ls" - IDS_2152 "Slike spominskega vložka (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Vse datoteke (*.*)\0*.*\0" - IDS_2153 "Napaka pri zagonu sistema za upodabljanje" - IDS_2154 "Sistema za upodabljanje OpenGL (3.0 Core) ni bilo mogoče zagnati. Uporabite drug sistem za upodabljanje." - IDS_2155 "Nadaljuj izvajanje" - IDS_2156 "Prekini izvajanje" - IDS_2157 "Press Ctrl+Alt+Del" - IDS_2158 "Press Ctrl+Alt+Esc" - IDS_2159 "Ponovni zagon" - IDS_2160 "Zaustavitev ACPI" - IDS_2161 "Nastavitve" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Trdi disk (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLL ali ESDI pogoni CD-ROM niso nikoli obstajali" - IDS_4100 "Po meri..." - IDS_4101 "Po meri (velik)..." - IDS_4102 "Dodaj nov trdi disk" - IDS_4103 "Dodaj obstoječ trdi disk" - IDS_4104 "Slike diska HDI ne morejo biti večje od 4 GB." - IDS_4105 "Slike diska ne morejo biti večje od 127 GB." - IDS_4106 "Slike trdega diska (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Vse datoteke (*.*)\0*.*\0" - IDS_4107 "Ne morem prebrati datoteke" - IDS_4108 "Ne morem pisati v datoteko" - IDS_4109 "Slike HDI ali HDX, ki nimajo sektorjev velikosti 512 bajtov, niso podprte." - IDS_4110 "USB še ni podprt" - IDS_4111 "Datoteka s sliko diska že obstaja" - IDS_4112 "Prosim, navedite veljavno ime datoteke." - IDS_4113 "Slika diska ustvarjena" - IDS_4114 "Prepričajte se, da datoteka obstaja in je berljiva." - IDS_4115 "Prepričajte se, da datoteko shranjujete v zapisljivo mapo." - IDS_4116 "Slika diska je prevelika" - IDS_4117 "Ne pozabite na novem disku ustvariti particij in jih formatirati." - IDS_4118 "Izbrana datoteka bo prepisana. Ali jo res želite uporabiti?" - IDS_4119 "Nepodprta slika diska" - IDS_4120 "Prepiši" - IDS_4121 "Ne prepiši" - IDS_4122 "Surova slika (.img)" - IDS_4123 "Slika HDI (.hdi)" - IDS_4124 "Slika HDX (.hdx)" - IDS_4125 "VHD fiksne velikosti (.vhd)" - IDS_4126 "Dinamičen VHD (.vhd)" - IDS_4127 "Diferencialni VHD (.vhd)" - IDS_4128 "Veliki bloki (2 MB)" - IDS_4129 "Mali bloki (512 KB)" - IDS_4130 "Datoteke VHD (*.VHD)\0*.VHD\0Vse datoteke (*.*)\0*.*\0" - IDS_4131 "Izberite starševsko sliko VHD" - IDS_4132 "To lahko pomeni, da je bila starševska slika spremenjena potem, ko je že bila ustvarjena diferencialna slika.\n\nDo tega lahko pride tudi kadar so datoteke slik diska premaknjene ali kopirane, ali pa gre za hrošča v programu, ki je ustvaril ta disk.\n\nŽelite popraviti časovni žig?" - IDS_4133 "Časovna žiga starševske slike diska in slike diska otroka se ne ujemata" - IDS_4134 "Ne morem popraviti časovnega žiga slike VHD." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Onemogočeno" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Onemogočeno" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (grozd 1024)" - IDS_5898 "DMF (grozd 2048)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "Popolni obrati na minuto" - IDS_6145 "1% pod popolnimi obrati" - IDS_6146 "1.5% pod popolnimi obrati" - IDS_6147 "2% pod popolnimi obrati" - - IDS_7168 "(Sistemsko privzeto)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Slovenian resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/tr-TR.rc b/src/win/languages/tr-TR.rc deleted file mode 100644 index 80a436c5d..000000000 --- a/src/win/languages/tr-TR.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Turkish (TR) resources - -#ifdef _WIN32 -LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Komutlar" - BEGIN - MENUITEM "&Klavye sadece fare yakalandığında çalışsın", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Sağ CTRL tuşunu sol ALT tuşu olarak ayarla", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Makineyi yeniden başlat...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Duraklat", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "Emülatörden &çık...", IDM_ACTION_EXIT - END - POPUP "&Görüntüleme" - BEGIN - MENUITEM "&Durum çubuğunu gizle", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Yeniden boyutlandırılabilir pencere", IDM_VID_RESIZE - MENUITEM "&Pencere boyut ve pozisyonunu hatırla", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "&İşleyici" - BEGIN - MENUITEM "&SDL (Yazılım)", IDM_VID_SDL_SW - MENUITEM "SDL (&Donanım)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "Pencere &boyutunu belirle...", IDM_VID_SPECIFY_DIM - MENUITEM "&4:3 görüntüleme oranına zorla", IDM_VID_FORCE43 - POPUP "Pencere &ölçek çarpanı" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "&Filtre metodu" - BEGIN - MENUITEM "&Nearest (En yakın)", IDM_VID_FILTER_NEAREST - MENUITEM "&Linear (Doğrusal)", IDM_VID_FILTER_LINEAR - END - MENUITEM "Hi&DPI ölçeklemesi", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Tam ekran\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "Tam ekran &germe modu" - BEGIN - MENUITEM "&Tam ekrana ger", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Kare piksel (ölçeği koru)", IDM_VID_FS_KEEPRATIO - MENUITEM "Tam &sayı ölçeklemesi", IDM_VID_FS_INT - END - POPUP "EGA/&(S)VGA ayarları" - BEGIN - MENUITEM "Ters &renk VGA monitör", IDM_VID_INVERT - POPUP "VGA ekran &tipi" - BEGIN - MENUITEM "RGB (&renkli)", IDM_VID_GRAY_RGB - MENUITEM "RGB (&gri tonlama)", IDM_VID_GRAY_MONO - MENUITEM "&Kehribar rengi monitör", IDM_VID_GRAY_AMBER - MENUITEM "&Yeşil renk monitör", IDM_VID_GRAY_GREEN - MENUITEM "&Beyaz renk monitör", IDM_VID_GRAY_WHITE - END - POPUP "&Gri tonlama dönüştürme tipi" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Ortalama", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/E&GA/(S)VGA aşırı taraması", IDM_VID_OVERSCAN - MENUITEM "Gri to&nlamalı görüntü için kontrastı değiştir", IDM_VID_CGACON - END - MENUITEM "&Medya", IDM_MEDIA - POPUP "&Araçlar" - BEGIN - MENUITEM "&Ayarlar...", IDM_CONFIG - MENUITEM "Durum &çubuğu ikonlarını güncelle", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "&Ekran görüntüsü al\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Tercihler...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "&Discord entegrasyonunu etkinleştir", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Ses yükseltici...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Begin trace\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "End trace\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Yardım" - BEGIN - MENUITEM "&Dökümanlar...", IDM_DOCS - MENUITEM "&86Box Hakkında...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Yeni imaj oluştur...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&İmaj seç...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "İmaj &seç (Yazma-korumalı)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Kaydet", IDM_CASSETTE_RECORD - MENUITEM "&Oynat", IDM_CASSETTE_PLAY - MENUITEM "&Başlangıca geri sar", IDM_CASSETTE_REWIND - MENUITEM "Sona doğru &ileri sar", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "&Çıkar", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&İmaj...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "&Çıkar", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Yeni imaj oluştur...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&İmaj seç...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "İmaj &seç (Yazma-korumalı)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&86F dosyası olarak aktar...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "&Çıkar", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Sesi kapat", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "İmajı &çıkar", IDM_CDROM_EMPTY - MENUITEM "&Önceki imajı seç", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&İmaj seç...", IDM_CDROM_IMAGE - MENUITEM "&Klasör...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Yeni imaj...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&İmaj seç...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "İmaj &seç (Yazma-korumalı)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Çıkar", IDM_ZIP_EJECT - MENUITEM "&Önceki imajı seç", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Yeni imaj...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&İmaj seç...", IDM_MO_IMAGE_EXISTING - MENUITEM "İmaj &seç (Yazma-korumalı)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Çıkar", IDM_MO_EJECT - MENUITEM "&Önceki imajı seç", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "Hedef &kare oranı" - BEGIN - MENUITEM "Video ile &senkronize et", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 fps", IDM_VID_GL_FPS_25 - MENUITEM "&30 fps", IDM_VID_GL_FPS_30 - MENUITEM "&50 fps", IDM_VID_GL_FPS_50 - MENUITEM "&60 fps", IDM_VID_GL_FPS_60 - MENUITEM "&75 fps", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "Gölgelendirici &seç...", IDM_VID_GL_SHADER - MENUITEM "&Gölgelendiriciyi kaldır", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Tercihler" -#define STR_SND_GAIN "Ses Artırma" -#define STR_NEW_FLOPPY "Yeni İmaj" -#define STR_CONFIG "Ayarlar" -#define STR_SPECIFY_DIM "Ana Pencere Boyutunu Belirle" - -#define STR_OK "Tamam" -#define STR_CANCEL "İptal et" -#define STR_GLOBAL "Bu ayarları &varsayılan olarak kaydet" -#define STR_DEFAULT "&Varsayılan" -#define STR_LANGUAGE "Dil:" -#define STR_ICONSET "Simge seti:" - -#define STR_GAIN "Artırma" - -#define STR_FILE_NAME "Dosya adı:" -#define STR_DISK_SIZE "Disk boyutu:" -#define STR_RPM_MODE "RPM modu:" -#define STR_PROGRESS "İşlem:" - -#define STR_WIDTH "Genişlik:" -#define STR_HEIGHT "Yükseklik:" -#define STR_LOCK_TO_SIZE "Bu boyuta kilitle" - -#define STR_MACHINE_TYPE "Makine türü:" -#define STR_MACHINE "Makine:" -#define STR_CONFIGURE "Ayarla" -#define STR_CPU_TYPE "CPU türü:" -#define STR_CPU_SPEED "Hız:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Bekleme süreleri:" -#define STR_MB "MB" -#define STR_MEMORY "Bellek:" -#define STR_TIME_SYNC "Zaman senkronizasyonu" -#define STR_DISABLED "Devre dışı" -#define STR_ENABLED_LOCAL "Etkin (yerel zaman)" -#define STR_ENABLED_UTC "Etkin (UTC)" -#define STR_DYNAREC "Dinamik Derleyici" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Ekran kartı:" -#define STR_VIDEO_2 "Ekran kartı 2:" -#define STR_VOODOO "Voodoo Grafikleri" -#define STR_IBM8514 "IBM 8514/A Grafikleri" -#define STR_XGA "XGA Grafikleri" - -#define STR_MOUSE "Fare:" -#define STR_JOYSTICK "Oyun kolu:" -#define STR_JOY1 "Oyun kolu 1..." -#define STR_JOY2 "Oyun kolu 2..." -#define STR_JOY3 "Oyun kolu 3..." -#define STR_JOY4 "Oyun kolu 4..." - -#define STR_SOUND1 "Ses kartı 1:" -#define STR_SOUND2 "Ses kartı 2:" -#define STR_SOUND3 "Ses kartı 3:" -#define STR_SOUND4 "Ses kartı 4:" -#define STR_MIDI_OUT "MIDI Çıkış Cihazı:" -#define STR_MIDI_IN "MIDI Giriş Cihazı:" -#define STR_MPU401 "Bağımsız MPU-401" -#define STR_FLOAT "FLOAT32 ses kullan" -#define STR_FM_DRIVER "FM sentez sürücüsü" -#define STR_FM_DRV_NUKED "Nuked (daha doğru)" -#define STR_FM_DRV_YMFM "YMFM (daha hızlı)" - -#define STR_NET_TYPE "Ağ tipi:" -#define STR_PCAP "PCap cihazı:" -#define STR_NET "Ağ cihazı:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" - -#define STR_COM1 "COM1 Cihazı:" -#define STR_COM2 "COM2 Cihazı:" -#define STR_COM3 "COM3 Cihazı:" -#define STR_COM4 "COM4 Cihazı:" -#define STR_LPT1 "LPT1 Cihazı:" -#define STR_LPT2 "LPT2 Cihazı:" -#define STR_LPT3 "LPT3 Cihazı:" -#define STR_LPT4 "LPT4 Cihazı:" -#define STR_SERIAL1 "Seri port 1" -#define STR_SERIAL2 "Seri port 2" -#define STR_SERIAL3 "Seri port 3" -#define STR_SERIAL4 "Seri port 4" -#define STR_PARALLEL1 "Paralel port 1" -#define STR_PARALLEL2 "Paralel port 2" -#define STR_PARALLEL3 "Paralel port 3" -#define STR_PARALLEL4 "Paralel port 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "HD Kontrolcüsü:" -#define STR_FDC "FD Kontrolcüsü:" -#define STR_IDE_TER "Üçlü IDE Kontrolcüsü" -#define STR_IDE_QUA "Dörtlü IDE Kontrolcüsü" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Kontrolcü 1:" -#define STR_SCSI_2 "Kontrolcü 2:" -#define STR_SCSI_3 "Kontrolcü 3:" -#define STR_SCSI_4 "Kontrolcü 4:" -#define STR_CASSETTE "Kaset" - -#define STR_HDD "Hard diskler:" -#define STR_NEW "&Yeni..." -#define STR_EXISTING "&Var olan..." -#define STR_REMOVE "&Kaldır" -#define STR_BUS "Veri yolu:" -#define STR_CHANNEL "Kanal:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Belirle..." -#define STR_SECTORS "Sektörler:" -#define STR_HEADS "Veri Kafaları:" -#define STR_CYLS "Silindirler:" -#define STR_SIZE_MB "Boyut (MB):" -#define STR_TYPE "Tip:" -#define STR_IMG_FORMAT "İmaj Düzeni:" -#define STR_BLOCK_SIZE "Blok Boyutu:" - -#define STR_FLOPPY_DRIVES "Disket sürücüleri:" -#define STR_TURBO "Turbo zamanlamaları" -#define STR_CHECKBPB "BPB'yi denetle" -#define STR_CDROM_DRIVES "CD-ROM sürücüleri:" -#define STR_CD_SPEED "Hız:" - -#define STR_MO_DRIVES "MO sürücüleri:" -#define STR_ZIP_DRIVES "ZIP sürücüleri:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA RTC:" -#define STR_ISAMEM "ISA Bellek Artırma" -#define STR_ISAMEM_1 "Kart 1:" -#define STR_ISAMEM_2 "Kart 2:" -#define STR_ISAMEM_3 "Kart 3:" -#define STR_ISAMEM_4 "Kart 4:" -#define STR_BUGGER "ISABugger cihazı" -#define STR_POSTCARD "POST kartı" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Hata" - IDS_2050 "Kritik hata" - IDS_2051 " - PAUSED" - IDS_2052 "Pencere moduna geri dönmek için Ctrl+Alt+PgDn tuşlarına basın." - IDS_2053 "Hız" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIP imajları (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box hiç bir kullanılabilir ROM imajı bulamadı.\n\nLütfen ROM setini indirin ve onu ""Roms"" klasörüne çıkarın." - IDS_2057 "(empty)" - IDS_2058 "ZIP imajları (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0All files (*.*)\0*.*\0" - IDS_2059 "Turbo" - IDS_2060 "Açık" - IDS_2061 "Kapalı" - IDS_2062 "Tüm imajlar (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Basit sektör imajları (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Yüzey imajları (*.86F)\0*.86F\0" - IDS_2063 """%hs"" makinesi roms/machines klasöründe mevcut olmayan ROM imajı yüzünden mevcut değil. Mevcut olan bir makineye geçiş yapılıyor." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 """%hs"" ekran kartı roms/video klasöründe mevcut olmayan ROM imajı yüzünden mevcut değil. Mevcut olan bir ekran kartına geçiş yapılıyor." - IDS_2065 "Makine" - IDS_2066 "Görüntü" - IDS_2067 "Giriş aygıtları" - IDS_2068 "Ses" - IDS_2069 "Ağ" - IDS_2070 "Portlar (COM & LPT)" - IDS_2071 "Depolama kontrolcüleri" - IDS_2072 "Hard diskler" - IDS_2073 "Disket & CD-ROM sürücüleri" - IDS_2074 "Diğer kaldırılabilir cihazlar" - IDS_2075 "Diğer cihazlar" - IDS_2076 "Yüzey imajları (*.86F)\0*.86F\0" - IDS_2077 "Farenin yakalanması için tıklayın" - IDS_2078 "Farenin bırakılması için F8+F12 tuşlarına basın" - IDS_2079 "Farenin bırakılması için F8+F12 veya farenin orta tuşuna basın" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Veri yolu" - IDS_2082 "Dosya" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "BPB'yi kontrol et" - IDS_2089 "KB" - IDS_2090 "Video işleyici başlatılamadı." - IDS_2091 "Varsayılan" - IDS_2092 "%i Bekleme durumları" - IDS_2093 "Tür" - IDS_2094 "PCap ayarlanamadı" - IDS_2095 "Herhangi bir PCap cihazı bulunamadı" - IDS_2096 "Geçersiz PCap cihazı" - IDS_2097 "Standart 2-button oyun kolları" - IDS_2098 "Standart 4-button oyun kolu" - IDS_2099 "Standart 6-button oyun kolu" - IDS_2100 "Standart 8-button oyun kolu" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Kontrol Sistemi" - IDS_2104 "Hiçbiri" - IDS_2105 "Klavye ivdirgeçleri yüklenemedi." - IDS_2106 "Ham girdi kaydedilemedi." - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "Disket %i (%s): %ls" - IDS_2110 "Tüm imajlar (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Gelişmiş sektör imajları (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basit sektör imajları (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Yüzey imajları (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2113 "Emüle edilen makineyi yeniden başlatmak istediğinizden emin misiniz?" - IDS_2114 "86Box'tan çıkmak istediğinize emin misiniz?" - IDS_2115 "Ghostscript başlatılamadı" - IDS_2116 "MO %i (%ls): %ls" - IDS_2117 "MO imajları (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0" - IDS_2118 "86Box'a hoşgeldiniz!" - IDS_2119 "Dahili kontrolcü" - IDS_2120 "Çıkış" - IDS_2121 "Hiçbir ROM imajı bulunamadı" - IDS_2122 "Ayarları kaydetmek istediğinizden emin misiniz?" - IDS_2123 "Bu makineyi yeniden başlatacak." - IDS_2124 "Kaydet" - IDS_2125 "86Box Hakkında" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "Bir eski bilgisayar emülatörü\n\nYapanlar: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, ve diğerleri.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, ve diğerleri.\n\nGNU Genel Kamu Lisansı versiyon 2 veya sonrası altında yayınlanmıştır. Daha fazla bilgi için LICENSE'ı gözden geçirin." - IDS_2128 "Tamam" - IDS_2129 "Donanım mevcut değil" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "" LIB_NAME_PCAP " kurulu olduğundan ve " LIB_NAME_PCAP "-uyumlu bir internet ağında bulunduğunuzdan emin olun." - IDS_2131 "Geçersiz konfigürasyon" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " PostScript dosyalarının otomatik olarak PDF dosyalarına çevirilmesi için gereklidir.\n\nGenel PostScript yazıcısına gönderilen tüm dökümanlar PostScript (.ps) dosyaları olarak kaydedilecektir." - IDS_2135 "Tam ekran moduna geçiliyor" - IDS_2136 "Bu mesajı bir daha gösterme" - IDS_2137 "Çıkış yapma" - IDS_2138 "Yeniden başlat" - IDS_2139 "Yeniden başlatma" - IDS_2140 "MO imajları (*.IM?;*.MDI)\0*.IM?;*.MDI\0Tüm dosyalar (*.*)\0*.*\0" - IDS_2141 "CD-ROM imajları (*.ISO;*.CUE)\0*.ISO;*.CUE\0Tüm dosyalar (*.*)\0*.*\0" - IDS_2142 "%hs Cihaz Konfigürasyonu" - IDS_2143 "Monitör uyku modunda" - IDS_2144 "OpenGL Gölgelendiricileri (*.GLSL)\0*.GLSL\0Tüm dosyalar (*.*)\0*.*\0" - IDS_2145 "OpenGL ayarları" - IDS_2146 "Desteklenmeyen bir konfigürasyon yüklüyorsunuz" - IDS_2147 "Seçtiğiniz makineye uygun CPU (işlemci) türü filtrelemesi bu emülasyon için devre dışı bırakıldı.\n\nBu, normalde seçilen makine ile uyumlu olmayan bir CPU seçmenizi mümkün kılmaktadır. Ancak, bundan dolayı seçilen makinenin BIOS'u veya diğer yazılımlar ile uyumsuzluk sorunu yaşayabilirsiniz.\n\nBu filtrelemeyi devre dışı bırakmak emülatör tarafından resmi olarak desteklenmemektedir ve açtığınız bug (hata) raporları geçersiz olarak kapatılabilir." - IDS_2148 "Devam et" - IDS_2149 "Kaset: %s" - IDS_2150 "Kaset imajları (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Tüm dosyalar (*.*)\0*.*\0" - IDS_2151 "Kartuş %i: %ls" - IDS_2152 "Kartuş imajları (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Tüm dosyalar (*.*)\0*.*\0" - IDS_2153 "Oluşturucu başlatılırken hata oluştu" - IDS_2154 "OpenGL (3.0 Core) görüntüleyici başlatılamadı. Başka bir görüntüleyici kullanın." - IDS_2155 "Yürütmeye devam et" - IDS_2156 "Yürütmeyi duraklat" - IDS_2157 "Ctrl+Alt+Del" - IDS_2158 "Ctrl+Alt+Esc" - IDS_2159 "Makineyi yeniden başlat" - IDS_2160 "ACPI kapatma" - IDS_2161 "Ayarlar" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Hard disk (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLL veya ESDI CD-ROM sürücüleri hiçbir zaman var olmamıştır" - IDS_4100 "Diğer..." - IDS_4101 "Diğer (büyük)..." - IDS_4102 "Yeni Hard Disk Dosyası Oluştur" - IDS_4103 "Var Olan Hard Disk Dosyası Ekle" - IDS_4104 "HDI disk imajları 4 GB'tan daha büyük olamaz." - IDS_4105 "Disk imajları 127 GB'tan daha büyük olamaz." - IDS_4106 "Hard disk imajları (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Tüm dosyalar (*.*)\0*.*\0" - IDS_4107 "Dosya okunamıyor" - IDS_4108 "Dosyanın üzerine yazılamıyor" - IDS_4109 "512 dışında sektör boyutu olan HDI veya HDX imajları desteklenmemektedir." - IDS_4110 "USB şu anda desteklenmemektedir" - IDS_4111 "Disk imaj dosyası zaten var olmakta" - IDS_4112 "Lütfen geçerli bir dosya ismi belirleyin." - IDS_4113 "Disk imajı oluşturuldu" - IDS_4114 "Dosyanın var olduğuna ve okunabildiğine emin olun." - IDS_4115 "Dosyanın yazılabilir bir klasöre kaydedildiğinden emin olun." - IDS_4116 "Disk imajı çok büyük" - IDS_4117 "Yeni oluşturulan diski bölmeyi ve formatlamayı unutmayın." - IDS_4118 "Seçili dosyanın üzerine yazılacaktır. Bunu yapmak istediğinizden emin misiniz?" - IDS_4119 "Desteklenmeyen disk imajı" - IDS_4120 "Üzerine yaz" - IDS_4121 "Üzerine yazma" - IDS_4122 "Ham imaj (.img)" - IDS_4123 "HDI imajı (.hdi)" - IDS_4124 "HDX imajı (.hdx)" - IDS_4125 "Sabit-boyutlu VHD (.vhd)" - IDS_4126 "Dinamik-boyutlu VHD (.vhd)" - IDS_4127 "Differencing VHD (.vhd)" - IDS_4128 "Büyük bloklar (2 MB)" - IDS_4129 "Küçük bloklar (512 KB)" - IDS_4130 "VHD dosyaları (*.VHD)\0*.VHD\0Tüm dosyalar (*.*)\0*.*\0" - IDS_4131 "Ana VHD dosyasını seçin" - IDS_4132 "Bu, farkı alınan imaj oluşturulduktan sonra ana imaj dosyasının düzenlendiği anlamına geliyor olabilir.\n\nBu durum ayrıca imaj dosyaları kopyalandığında veya yerleri değiştirildiğinde veya imaj dosyalarını oluşturan programdaki bir hatadan dolayı olmuş olabilir.\n\nZaman damgalarını düzeltmek ister misiniz?" - IDS_4133 "Ana ve ek disk zaman damgaları uyuşmuyor" - IDS_4134 "VHD zaman damgası düzeltilemedi." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Devre dışı" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Devre dışı" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (cluster 1024)" - IDS_5898 "DMF (cluster 2048)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 MB (ISO 10090)" - IDS_5903 "3.5"" 230 MB (ISO 13963)" - IDS_5904 "3.5"" 540 MB (ISO 15498)" - IDS_5905 "3.5"" 640 MB (ISO 15498)" - IDS_5906 "3.5"" 1.3 GB (GigaMO)" - IDS_5907 "3.5"" 2.3 GB (GigaMO 2)" - IDS_5908 "5.25"" 600 MB" - IDS_5909 "5.25"" 650 MB" - IDS_5910 "5.25"" 1 GB" - IDS_5911 "5.25"" 1.3 GB" - - IDS_6144 "Mükemmel RPM" - IDS_6145 "mükemmel RPM değerinin 1% altı" - IDS_6146 "mükemmel RPM değerinin 1.5% altı" - IDS_6147 "mükemmel RPM değerinin 2% altı" - - IDS_7168 "(Sistem Varsayılanı)" -END -#define IDS_LANG_TRTR IDS_7168 - -// Turkish (TR) resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/uk-UA.rc b/src/win/languages/uk-UA.rc deleted file mode 100644 index 53f401e81..000000000 --- a/src/win/languages/uk-UA.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Ukrainian resources - -#ifdef _WIN32 -LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&Дія" - BEGIN - MENUITEM "&Клавіатура потребує захвату", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Правий CTRL - це лівий ALT", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "&Холодне перезавантаження...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "&Пауза", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "&Вихід...", IDM_ACTION_EXIT - END - POPUP "&Вигляд" - BEGIN - MENUITEM "&Приховати рядок стану", IDM_VID_HIDE_STATUS_BAR - MENUITEM "&Приховати панель інструментів", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Змінний розмір вікна", IDM_VID_RESIZE - MENUITEM "&Запам'ятати розмір і становище", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "&Рендеринг" - BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "&Вказати розміри...", IDM_VID_SPECIFY_DIM - MENUITEM "&Встановити відношення сторін 4:3", IDM_VID_FORCE43 - POPUP "&Масштаб вікна" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "Метод фільтрації" - BEGIN - MENUITEM "&Найближчий", IDM_VID_FILTER_NEAREST - MENUITEM "&Лінійний", IDM_VID_FILTER_LINEAR - END - MENUITEM "Масштабування Hi&DPI", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "&Повноекранний режим\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "&Розстягування у повноекранному режимі" - BEGIN - MENUITEM "&На весь екран", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Квадратні пікселі (зберегти відношення)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Цілісночисленне масштабування", IDM_VID_FS_INT - END - POPUP "Налаштування E&GA/(S)VGA" - BEGIN - MENUITEM "&Інвертувати кольори VGA", IDM_VID_INVERT - POPUP "&Тип екрана VGA" - BEGIN - MENUITEM "RGB &кольоровий", IDM_VID_GRAY_RGB - MENUITEM "&RGB монохромний", IDM_VID_GRAY_MONO - MENUITEM "&Бурштиновий відтінок", IDM_VID_GRAY_AMBER - MENUITEM "&Зелений відтінок", IDM_VID_GRAY_GREEN - MENUITEM "&Білий відтінок", IDM_VID_GRAY_WHITE - END - POPUP "Тип монохромного &конвертування" - BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Усереднений", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "Вильоти розгортки CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN - MENUITEM "Змінити контрастність &монохромного дисплея", IDM_VID_CGACON - END - MENUITEM "&Носії", IDM_MEDIA - POPUP "&Інструменти" - BEGIN - MENUITEM "&Налаштування машини...", IDM_CONFIG - MENUITEM "&Обновлення значків рядка стану", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "Зробити &знімок\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "&Параметри...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "Увімкнути інтеграцію &Discord", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "&Посилення звуку...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "Почати трасування\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Завершити трасування\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "&Допомога" - BEGIN - MENUITEM "&Документація...", IDM_DOCS - MENUITEM "&Про програму 86Box...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Новий образ...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Вибрати образ...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Вибрати образ (&Захист від запису)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Запис", IDM_CASSETTE_RECORD - MENUITEM "&Відтворення", IDM_CASSETTE_PLAY - MENUITEM "&Перемотування на початок", IDM_CASSETTE_REWIND - MENUITEM "&Перемотування у кінець", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "&Вилучити", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Образ...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "&Вилучити", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Новий образ...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Вибрати образ...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Вибрати образ (&Захист від запису)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Експорт в 86F...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "&Вилучити", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Відключити звук", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "&Пустий", IDM_CDROM_EMPTY - MENUITEM "&Знову завантажити попередній образ", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Образ...", IDM_CDROM_IMAGE - MENUITEM "&Тека...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Новий образ...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Вибрати образ...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Вибрати образ (&Захист від запису)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Вилучити", IDM_ZIP_EJECT - MENUITEM "&Знову завантажити попередній образ", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "&Новий образ...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "&Вибрати образ...", IDM_MO_IMAGE_EXISTING - MENUITEM "Вибрати образ (&Захист від запису)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "&Вилучити", IDM_MO_EJECT - MENUITEM "&Знову завантажити попередній образ", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "Цільова &частота кадрів" - BEGIN - MENUITEM "&Синхронізація з відео", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 кадрів в секунду", IDM_VID_GL_FPS_25 - MENUITEM "&30 кадрів в секунду", IDM_VID_GL_FPS_30 - MENUITEM "&50 кадрів в секунду", IDM_VID_GL_FPS_50 - MENUITEM "&60 кадрів в секунду", IDM_VID_GL_FPS_60 - MENUITEM "&75 кадрів в секунду", IDM_VID_GL_FPS_75 - END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "&Вибрати шейдер...", IDM_VID_GL_SHADER - MENUITEM "&Видалити шейдер", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "Параметри" -#define STR_SND_GAIN "Посилення звуку" -#define STR_NEW_FLOPPY "Новий образ" -#define STR_CONFIG "Налаштування" -#define STR_SPECIFY_DIM "Вказати розміри головного вікна" - -#define STR_OK "OK" -#define STR_CANCEL "Відміна" -#define STR_GLOBAL "Зберегти ці параметри як &глобальні за замовчуванням" -#define STR_DEFAULT "&За замовчуванням" -#define STR_LANGUAGE "Мова:" -#define STR_ICONSET "Набір іконок:" - -#define STR_GAIN "Посилення" - -#define STR_FILE_NAME "Ім'я файлу:" -#define STR_DISK_SIZE "Розмір диска:" -#define STR_RPM_MODE "RPM режим:" -#define STR_PROGRESS "Прогрес:" - -#define STR_WIDTH "Ширина:" -#define STR_HEIGHT "Висота:" -#define STR_LOCK_TO_SIZE "Зафіксувати розмір" - -#define STR_MACHINE_TYPE "Тип машини:" -#define STR_MACHINE "Системна плата:" -#define STR_CONFIGURE "Налаштування" -#define STR_CPU_TYPE "Тип ЦП:" -#define STR_CPU_SPEED "Швидкість:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Цикли очікування:" -#define STR_MB "МБ" -#define STR_MEMORY "Пам'ять:" -#define STR_TIME_SYNC "Синхронізація часу" -#define STR_DISABLED "Відключити" -#define STR_ENABLED_LOCAL "Увімкнути (місцеве)" -#define STR_ENABLED_UTC "Увімкнути (UTC)" -#define STR_DYNAREC "Динамічний рекомпілятор" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "Відеокарта:" -#define STR_VIDEO_2 "Відеокарта 2:" -#define STR_VOODOO "Прискорювач Voodoo" -#define STR_IBM8514 "Прискорювач IBM 8514/A" -#define STR_XGA "Прискорювач XGA" - -#define STR_MOUSE "Миша:" -#define STR_JOYSTICK "Джойстик:" -#define STR_JOY1 "Джойстик 1..." -#define STR_JOY2 "Джойстик 2..." -#define STR_JOY3 "Джойстик 3..." -#define STR_JOY4 "Джойстик 4..." - -#define STR_SOUND1 "Звукова карта 1:" -#define STR_SOUND2 "Звукова карта 2:" -#define STR_SOUND3 "Звукова карта 3:" -#define STR_SOUND4 "Звукова карта 4:" -#define STR_MIDI_OUT "MIDI Out при-ій:" -#define STR_MIDI_IN "MIDI In при-ій:" -#define STR_MPU401 "Окремий MPU-401" -#define STR_FLOAT "FLOAT32 звук" -#define STR_FM_DRIVER "Драйвер FM-синтезатора" -#define STR_FM_DRV_NUKED "Nuked (більш точний)" -#define STR_FM_DRV_YMFM "YMFM (швидший)" - -#define STR_NET_TYPE "Тип мережі:" -#define STR_PCAP "Пристрій PCap:" -#define STR_NET "Мережевий адаптер:" -#define STR_NET1 "Мережева карта 1:" -#define STR_NET2 "Мережева карта 2:" -#define STR_NET3 "Мережева карта 3:" -#define STR_NET4 "Мережева карта 4:" - -#define STR_COM1 "Пристрій COM1:" -#define STR_COM2 "Пристрій COM2:" -#define STR_COM3 "Пристрій COM3:" -#define STR_COM4 "Пристрій COM4:" -#define STR_LPT1 "Пристрій LPT1:" -#define STR_LPT2 "Пристрій LPT2:" -#define STR_LPT3 "Пристрій LPT3:" -#define STR_LPT4 "Пристрій LPT4:" -#define STR_SERIAL1 "Послідов. порт COM1" -#define STR_SERIAL2 "Послідов. порт COM2" -#define STR_SERIAL3 "Послідов. порт COM3" -#define STR_SERIAL4 "Послідов. порт COM4" -#define STR_PARALLEL1 "Паралельний порт LPT1" -#define STR_PARALLEL2 "Паралельний порт LPT2" -#define STR_PARALLEL3 "Паралельний порт LPT3" -#define STR_PARALLEL4 "Паралельний порт LPT4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "Контролер HD:" -#define STR_FDC "Контролер FD:" -#define STR_IDE_TER "Третинний IDE контролер" -#define STR_IDE_QUA "Четвертинний IDE контролер" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Контролер 1:" -#define STR_SCSI_2 "Контролер 2:" -#define STR_SCSI_3 "Контролер 3:" -#define STR_SCSI_4 "Контролер 4:" -#define STR_CASSETTE "Касета" - -#define STR_HDD "Жорсткі диски:" -#define STR_NEW "&Створити..." -#define STR_EXISTING "&Вибрати..." -#define STR_REMOVE "&Прибрати" -#define STR_BUS "Шина:" -#define STR_CHANNEL "Канал:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "&Вказати..." -#define STR_SECTORS "Сектора:" -#define STR_HEADS "Головки:" -#define STR_CYLS "Циліндри:" -#define STR_SIZE_MB "Розмір (МБ):" -#define STR_TYPE "Тип:" -#define STR_IMG_FORMAT "Тип образу:" -#define STR_BLOCK_SIZE "Розмір блоку:" - -#define STR_FLOPPY_DRIVES "Гнучкі диски:" -#define STR_TURBO "Турбо таймінги" -#define STR_CHECKBPB "Перевіряти BPB" -#define STR_CDROM_DRIVES "Дисководи CD-ROM:" -#define STR_CD_SPEED "Швидкість:" - -#define STR_MO_DRIVES "Магнітооптичні дисководи:" -#define STR_ZIP_DRIVES "ZIP дисководи:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA RTC:" -#define STR_ISAMEM "Карта розширення пам'яті (ISA)" -#define STR_ISAMEM_1 "Карта 1:" -#define STR_ISAMEM_2 "Карта 2:" -#define STR_ISAMEM_3 "Карта 3:" -#define STR_ISAMEM_4 "Карта 4:" -#define STR_BUGGER "Пристрій ISABugger" -#define STR_POSTCARD "Карта POST" - -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "Помилка" - IDS_2050 "Непереробна помилка" - IDS_2051 " - PAUSED" - IDS_2052 "Натисніть Ctrl+Alt+PgDn для повернення у віконний режим." - IDS_2053 "Швидкість" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "Образи ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box не зміг знайти жодного відповідного для використання файлу з ПЗУ.\n\nБудь ласка завантажте набір ПЗУ і витягніть його в каталог ""roms""." - IDS_2057 "(порожньо)" - IDS_2058 "Образи ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Усі файли (*.*)\0*.*\0" - IDS_2059 "Турбо" - IDS_2060 "Увімк" - IDS_2061 "Вимк" - IDS_2062 "Усі образи (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Прості посекторні образи (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Образ поверхні (*.86F)\0*.86F\0" - IDS_2063 "Системна плата ""%hs"" недоступна через відсутність файлу її ПЗУ в каталозі roms/machines. Переключення на доступну системну плату." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "Відеокарта ""%hs"" недоступна через відсутність файлу її ПЗУ в каталозі roms/video. Переключення на доступну відеокарту." - IDS_2065 "Комп'ютер" - IDS_2066 "Дисплей" - IDS_2067 "Пристрій введення" - IDS_2068 "Звук" - IDS_2069 "Мережа" - IDS_2070 "Порти (COM и LPT)" - IDS_2071 "Контролери дисків" - IDS_2072 "Жорсткі диски" - IDS_2073 "Гнучкі диски і CD-ROM" - IDS_2074 "Інші знімні при-ої" - IDS_2075 "Інша периферія" - IDS_2076 "Образи Surface (*.86F)\0*.86F\0" - IDS_2077 "Клацніть мишею для захвату курсора" - IDS_2078 "Натисніть F8+F12, щоб звільнити курсор" - IDS_2079 "Натисніть F8+F12 або середню кнопку миші, щоб звільнити курсор" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "Шина" - IDS_2082 "Файл" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "МБ" - IDS_2087 "Speed" - IDS_2088 "Перевіряти BPB" - IDS_2089 "КБ" - IDS_2090 "Не вдалося ініціалізувати рендер відео." - IDS_2091 "За замовчуванням" - IDS_2092 "%i WS" - IDS_2093 "Тип" - IDS_2094 "Не вдалося налаштувати PCap" - IDS_2095 "Пристрої PCap не знайдені" - IDS_2096 "Невірний пристрій PCap" - IDS_2097 "Стандартний 2-кнопковий джойстик" - IDS_2098 "Стандартний 4-кнопковий джойстик" - IDS_2099 "Стандартний 6-кнопковий джойстик" - IDS_2100 "Стандартний 8-кнопковий джойстик" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Система управління польотом Thrustmaster" - IDS_2104 "Ні" - IDS_2105 "Неможливо завантажити прискорювачі клавіатури." - IDS_2106 "Неможливо зарреєструвати необроблене (RAW) введення." - IDS_2107 "%u" - IDS_2108 "%u МБ (CHS: %i, %i, %i)" - IDS_2109 "Дисковод %i (%s): %ls" - IDS_2110 "Усі образи (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Розширені образи секторів (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Основні образи секторів (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Образи Flux (*.FDI)\0*.FDI\0Образи Surface (*.86F;*.MFM)\0*.86F;*.MFM\0Усі файли (*.*)\0*.*\0" - IDS_2113 "Ви впевнені, що хочете виконати холодне перезавантаження емульованої машини?" - IDS_2114 "Ви впевнені, що хочете вийти з 86Box?" - IDS_2115 "Неможливо ініціалізувати Ghostscript" - IDS_2116 "Магнітооптичний %i (%ls): %ls" - IDS_2117 "Образи магнітооптичних дисків (*.IM?;*.MDI)\0*.IM?;*.MDI\0Усі файлі (*.*)\0*.*\0" - IDS_2118 "Ласкаво просимо в 86Box!" - IDS_2119 "Вбудований контролер" - IDS_2120 "Вихід" - IDS_2121 "ПЗУ не знайдені" - IDS_2122 "Чи бажаєте ви зберегти налаштування?" - IDS_2123 "Це призведе до холодної перезагрузки емульованої машини." - IDS_2124 "Зберегти" - IDS_2125 "Про 86Box" - IDS_2126 "86Box v." EMU_VERSION - - IDS_2127 "Емулятор старих комп'ютерів\n\nАвтори: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nВипускаєтся під ліцензією GNU General Public License версії 2 або більше пізніше. Додадкову інформацію см. у файлі LICENSE." - IDS_2128 "OK" - IDS_2129 "Обладнання недоступне" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "Переконайтесь, що " LIB_NAME_PCAP " встановлений і ваше мережеве з'єднання, сумісне з " LIB_NAME_PCAP "." - IDS_2131 "Неприпустима конфігурація" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " потрібно для автоматичного перетворення файлів PostScript в PDF.\n\nсі документи, відправлені на загальний принтер PostScript, будуть збережені у вигляді файлів PostScript (.ps)." - IDS_2135 "Вхід у повноекранний режим" - IDS_2136 "Більше не показувати це повідомлення" - IDS_2137 "Не виходити" - IDS_2138 "Перезавантажити" - IDS_2139 "Не перезавантажувати" - IDS_2140 "Образи магнітооптичних дисків (*.IM?;*.MDI)\0*.IM?;*.MDI\0Усі файли (*.*)\0*.*\0" - IDS_2141 "Образи CD-ROM (*.ISO;*.CUE)\0*.ISO;*.CUE\0Усі файли (*.*)\0*.*\0" - IDS_2142 "Конфігурація пристрою %hs" - IDS_2143 "Монітор у сплячому режимі" - IDS_2144 "Шейдери OpenGL (*.GLSL)\0*.GLSL\0Усі файли (*.*)\0*.*\0" - IDS_2145 "Параметри OpenGL" - IDS_2146 "Ви завантажуєте непідтримувану конфігурацію" - IDS_2147 "Вибір типів ЦП для цієї системної плати на даній емульованій машині відключено.\n\nЦе дозволяє вибрати процесор, який в іншому випадку не сумісний з вибраною материнською платою. Однак, ви можете зіткнутися з несумісністю з BIOS материнської плати або іншим ПО.\n\nВключення цього параметра офіційно не підтримується, і всі подані звіти про помилки можуть бути закриті як недійсні." - IDS_2148 "Продовжити" - IDS_2149 "Касета: %s" - IDS_2150 "Образи касет (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Усі файли (*.*)\0*. *\0" - IDS_2151 "Картридж %i: %ls" - IDS_2152 "Образи картриджів (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Усі файли (*.*)\0*.*\0" - IDS_2153 "Помилка ініціалізації рендерера" - IDS_2154 "Неможливо ініціалізувати рендерер OpenGL (3.0). Будь ласка, використовуйте інший рендерер." - IDS_2155 "Відновити виконання" - IDS_2156 "Призупинити виконання" - IDS_2157 "Натиснути Ctrl+Alt+Del" - IDS_2158 "Натиснути Ctrl+Alt+Esc" - IDS_2159 "Холодне перезавантаження" - IDS_2160 "Сигнал завершення ACPI" - IDS_2161 "Налаштування машини" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Відеокарта #2 ""%hs"" недоступна через відсутність файлу її ПЗУ в каталозі roms/video. Відключення другої відеокарти." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "Жорсткий диск (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLL або ESDI дисководів CD-ROM ніколи не існувало" - IDS_4100 "Задати вручну..." - IDS_4101 "Задати вручну (large)..." - IDS_4102 "Створити новий жорсткий диск" - IDS_4103 "Вибрати існуючий жорсткий диск" - IDS_4104 "Розмір образів дисків HDI не може перевищувати 4 ГБ." - IDS_4105 "Розмір образів дисків не може перевищувати 127 ГБ." - IDS_4106 "Образи жорстких дисків (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Усі файли (*.*)\0*.*\0 " - IDS_4107 "Неможливо прочитати файл" - IDS_4108 "Неможливо записати файл" - IDS_4109 "Образи HDI або HDX з розміром сектора, відмінним від 512, не підтримуються." - IDS_4110 "USB поки не підтримується" - IDS_4111 "Файл образу диска вже існує" - IDS_4112 "Вкажіть правильне ім'я файлу." - IDS_4113 "Образ диску створено" - IDS_4114 "Переконайтеся, що файл є доступним для читання." - IDS_4115 "Переконайтеся, що файл зберігається в каталог, який є доступним для запису." - IDS_4116 "Занадто великий образ диска" - IDS_4117 "Не забудьте розмітити та відформатувати новостворений диск." - IDS_4118 "Вибраний файл буде перезаписано. Ви впевнені, що хочете використовувати його?" - IDS_4119 "Образ диска, що не підтримується" - IDS_4120 "Перезаписати" - IDS_4121 "Не перезаписувати" - IDS_4122 "RAW образ (.img)" - IDS_4123 "Образ HDI (.hdi)" - IDS_4124 "Образ HDX (.hdx)" - IDS_4125 "VHD фіксованого розміру (.vhd)" - IDS_4126 "VHD динамічного розміру (.vhd)" - IDS_4127 "Диференційований образ VHD (.vhd)" - IDS_4128 "Великі блоки (2 МБ)" - IDS_4129 "Маленькі блоки (512 КБ)" - IDS_4130 "Файли VHD (*.VHD)\0*.VHD\0Усі файли (*.*)\0*.*\0" - IDS_4131 "Виберіть батьківський VHD" - IDS_4132 "Це може означати, що батьківський образ був змінений після того, як було створено диференційований образ.\n\nЦе також може статися, якщо файли зображення були переміщені або скопійовані, або через помилку в програмі, що створила цей диск.\n \nВи хочете виправити тимчасові позначки?" - IDS_4133 "Тимчасові мітки батьківського та дочірнього дисків не співпадають" - IDS_4134 "Не вдалося виправити тимчасову позначку VHD." - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "CD-ROM %i (%s): %s" - - IDS_5376 "Відключено" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "Відключено" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 кБ" - IDS_5889 "180 кБ" - IDS_5890 "320 кБ" - IDS_5891 "360 кБ" - IDS_5892 "640 кБ" - IDS_5893 "720 кБ" - IDS_5894 "1.2 МБ" - IDS_5895 "1.25 МБ" - IDS_5896 "1.44 МБ" - IDS_5897 "DMF (кластер 1024)" - IDS_5898 "DMF (кластер 2048)" - IDS_5899 "2.88 МБ" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 МБ (ISO 10090)" - IDS_5903 "3.5"" 230 МБ (ISO 13963)" - IDS_5904 "3.5"" 540 МБ (ISO 15498)" - IDS_5905 "3.5"" 640 МБ (ISO 15498)" - IDS_5906 "3.5"" 1.3 ГБ (GigaMO)" - IDS_5907 "3.5"" 2.3 ГБ (GigaMO 2)" - IDS_5908 "5.25"" 600 МБ" - IDS_5909 "5.25"" 650 МБ" - IDS_5910 "5.25"" 1 ГБ" - IDS_5911 "5.25"" 1.3 ГБ" - - IDS_6144 "Точний RPM" - IDS_6145 "На 1% повільніше точного RPM" - IDS_6146 "На 1.5% повільніше точного RPM" - IDS_6147 "На 2% повільніше точного RPM" - - IDS_7168 "(Системний)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Ukrainian resources -//////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/zh-CN.rc b/src/win/languages/zh-CN.rc deleted file mode 100644 index 676574720..000000000 --- a/src/win/languages/zh-CN.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Simplified Chinese resources - -#ifdef _WIN32 -LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "操作(&A)" - BEGIN - MENUITEM "键盘需要捕捉(&K)", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "将右 CTRL 键映射为左 ALT 键(&R)", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "硬重置(&H)...", IDM_ACTION_HRESET - MENUITEM "Ctrl+Alt+Del(&C)\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+Esc(&E)", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "暂停(&P)", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "退出(&X)...", IDM_ACTION_EXIT - END - POPUP "查看(&V)" - BEGIN - MENUITEM "隐藏状态栏(&H)", IDM_VID_HIDE_STATUS_BAR - MENUITEM "隐藏工具栏(&T)", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "显示次要显示器(&S)", IDM_VID_MONITORS - MENUITEM "窗口大小可调(&R)", IDM_VID_RESIZE - MENUITEM "记住窗口大小和位置(&E)", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "渲染器(&N)" - BEGIN - MENUITEM "SDL (软件)(&S)", IDM_VID_SDL_SW - MENUITEM "SDL (硬件)(&H)", IDM_VID_SDL_HW - MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL - MENUITEM "OpenGL (3.0 Core)(&G)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "VNC(&V)", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "指定窗口大小...", IDM_VID_SPECIFY_DIM - MENUITEM "强制 4:3 显示比例(&O)", IDM_VID_FORCE43 - POPUP "窗口缩放系数(&W)" - BEGIN - MENUITEM "0.5x(&0)", IDM_VID_SCALE_1X - MENUITEM "1x(&1)", IDM_VID_SCALE_2X - MENUITEM "1.5x(&5)", IDM_VID_SCALE_3X - MENUITEM "2x(&2)", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "过滤方式" - BEGIN - MENUITEM "邻近(&N)", IDM_VID_FILTER_NEAREST - MENUITEM "线性(&L)", IDM_VID_FILTER_LINEAR - END - MENUITEM "HiDPI 缩放(&D)", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "全屏(&F)\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "全屏拉伸模式(&S)" - BEGIN - MENUITEM "全屏拉伸(&F)", IDM_VID_FS_FULL - MENUITEM "4:3(&4)", IDM_VID_FS_43 - MENUITEM "保持比例(&S)", IDM_VID_FS_KEEPRATIO - MENUITEM "整数比例(&I)", IDM_VID_FS_INT - END - POPUP "EGA/(S)VGA 设置(&G)" - BEGIN - MENUITEM "VGA 显示器反色显示(&I)", IDM_VID_INVERT - POPUP "VGA 屏幕类型(&T)" - BEGIN - MENUITEM "RGB 彩色(&C)", IDM_VID_GRAY_RGB - MENUITEM "RGB 灰度(&R)", IDM_VID_GRAY_MONO - MENUITEM "琥珀色单色显示器(&A)", IDM_VID_GRAY_AMBER - MENUITEM "绿色单色显示器(&G)", IDM_VID_GRAY_GREEN - MENUITEM "白色单色显示器(&W)", IDM_VID_GRAY_WHITE - END - POPUP "灰度转换类型(&C)" - BEGIN - MENUITEM "BT601 (NTSC/PAL)(&6)", IDM_VID_GRAYCT_601 - MENUITEM "BT709 (HDTV)(&7)", IDM_VID_GRAYCT_709 - MENUITEM "平均(&A)", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/EGA/(S)VGA 过扫描(&G)", IDM_VID_OVERSCAN - MENUITEM "更改单色显示对比度(&M)", IDM_VID_CGACON - END - MENUITEM "介质(&M)", IDM_MEDIA - POPUP "工具(&T)" - BEGIN - MENUITEM "设置(&S)...", IDM_CONFIG - MENUITEM "更新状态栏图标(&U)", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "截图(&C)\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "首选项(&P)...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "启用 Discord 集成(&D)", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "音量增益(&G)...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "开始追踪\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "结束追踪\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "帮助(&H)" - BEGIN - MENUITEM "文档(&D)...", IDM_DOCS - MENUITEM "关于 86Box(&A)...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新建映像(&N)...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "打开已存在的映像(&E)...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "打开已存在的映像并写保护(&W)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "录制(&R)", IDM_CASSETTE_RECORD - MENUITEM "播放(&P)", IDM_CASSETTE_PLAY - MENUITEM "倒带至起点(&R)", IDM_CASSETTE_REWIND - MENUITEM "快进至终点(&F)", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "弹出(&J)", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "映像(&I)...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "弹出(&J)", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新建映像(&N)...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "打开已存在的映像(&E)...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "打开已存在的映像并写保护(&W)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "导出为 86F 格式(&x)...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "弹出(&J)", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "静音(&M)", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "空置驱动器(&M)", IDM_CDROM_EMPTY - MENUITEM "载入上一个映像(&R)", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "映像(&I)...", IDM_CDROM_IMAGE - MENUITEM "文件夹(&F)...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新建映像(&N)...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "打开已存在的映像(&E)...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "打开已存在的映像并写保护(&W)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "弹出(&J)", IDM_ZIP_EJECT - MENUITEM "载入上一个映像(&R)", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新建映像(&N)...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "打开已存在的映像(&E)...", IDM_MO_IMAGE_EXISTING - MENUITEM "打开已存在的映像并写保护(&W)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "弹出(&J)", IDM_MO_EJECT - MENUITEM "载入上一个映像(&R)", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "目标帧率(&F)" - BEGIN - MENUITEM "与视频同步(&S)", IDM_VID_GL_FPS_BLITTER - MENUITEM "25 fps(&2)", IDM_VID_GL_FPS_25 - MENUITEM "30 fps(&3)", IDM_VID_GL_FPS_30 - MENUITEM "50 fps(&5)", IDM_VID_GL_FPS_50 - MENUITEM "60 fps(&6)", IDM_VID_GL_FPS_60 - MENUITEM "75 fps(&7)", IDM_VID_GL_FPS_75 - END - MENUITEM "垂直同步(&V)", IDM_VID_GL_VSYNC - MENUITEM "选择着色器(&S)...", IDM_VID_GL_SHADER - MENUITEM "移除着色器(&R)", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "首选项" -#define STR_SND_GAIN "音量增益" -#define STR_NEW_FLOPPY "新建映像" -#define STR_CONFIG "设置" -#define STR_SPECIFY_DIM "指定主窗口大小" - -#define STR_OK "确定" -#define STR_CANCEL "取消" -#define STR_GLOBAL "将以上设置存储为全局默认值(&G)" -#define STR_DEFAULT "默认(&D)" -#define STR_LANGUAGE "语言:" -#define STR_ICONSET "图标集:" - -#define STR_GAIN "增益" - -#define STR_FILE_NAME "文件名:" -#define STR_DISK_SIZE "磁盘大小:" -#define STR_RPM_MODE "转速 (RPM) 模式:" -#define STR_PROGRESS "进度:" - -#define STR_WIDTH "宽度:" -#define STR_HEIGHT "高度:" -#define STR_LOCK_TO_SIZE "锁定此大小" - -#define STR_MACHINE_TYPE "机器类型:" -#define STR_MACHINE "机型:" -#define STR_CONFIGURE "配置" -#define STR_CPU_TYPE "CPU 类型:" -#define STR_CPU_SPEED "速度:" -#define STR_FPU "浮点处理器 (FPU):" -#define STR_WAIT_STATES "等待状态 (WS):" -#define STR_MB "MB" -#define STR_MEMORY "内存:" -#define STR_TIME_SYNC "时间同步" -#define STR_DISABLED "禁用" -#define STR_ENABLED_LOCAL "启用 (本地时间)" -#define STR_ENABLED_UTC "启用 (协调世界时)" -#define STR_DYNAREC "动态重编译器" -#define STR_SOFTFLOAT "软浮点 FPU" - -#define STR_VIDEO "显卡:" -#define STR_VIDEO_2 "显卡 2:" -#define STR_VOODOO "Voodoo 显卡" -#define STR_IBM8514 "IBM 8514/A 显卡" -#define STR_XGA "XGA 显卡" - -#define STR_MOUSE "鼠标:" -#define STR_JOYSTICK "操纵杆:" -#define STR_JOY1 "操纵杆 1..." -#define STR_JOY2 "操纵杆 2..." -#define STR_JOY3 "操纵杆 3..." -#define STR_JOY4 "操纵杆 4..." - -#define STR_SOUND1 "声卡 1:" -#define STR_SOUND2 "声卡 2:" -#define STR_SOUND3 "声卡 3:" -#define STR_SOUND4 "声卡 4:" -#define STR_MIDI_OUT "MIDI 输出设备:" -#define STR_MIDI_IN "MIDI 输入设备:" -#define STR_MPU401 "独立 MPU-401" -#define STR_FLOAT "使用单精度浮点 (FLOAT32)" -#define STR_FM_DRIVER "调频合成器驱动器" -#define STR_FM_DRV_NUKED "Nuked (更准确)" -#define STR_FM_DRV_YMFM "YMFM (更快)" - -#define STR_NET_TYPE "网络类型:" -#define STR_PCAP "PCap 设备:" -#define STR_NET "网络适配器:" -#define STR_NET1 "网卡 1:" -#define STR_NET2 "网卡 2:" -#define STR_NET3 "网卡 3:" -#define STR_NET4 "网卡 4:" - -#define STR_COM1 "COM1 设备:" -#define STR_COM2 "COM2 设备:" -#define STR_COM3 "COM3 设备:" -#define STR_COM4 "COM4 设备:" -#define STR_LPT1 "LPT1 设备:" -#define STR_LPT2 "LPT2 设备:" -#define STR_LPT3 "LPT3 设备:" -#define STR_LPT4 "LPT4 设备:" -#define STR_SERIAL1 "串口 1" -#define STR_SERIAL2 "串口 2" -#define STR_SERIAL3 "串口 3" -#define STR_SERIAL4 "串口 4" -#define STR_PARALLEL1 "并口 1" -#define STR_PARALLEL2 "并口 2" -#define STR_PARALLEL3 "并口 3" -#define STR_PARALLEL4 "并口 4" -#define STR_SERIAL_PASS1 "串口直通 1" -#define STR_SERIAL_PASS2 "串口直通 2" -#define STR_SERIAL_PASS3 "串口直通 3" -#define STR_SERIAL_PASS4 "串口直通 4" - -#define STR_HDC "硬盘控制器:" -#define STR_FDC "软盘控制器:" -#define STR_IDE_TER "第三 IDE 控制器" -#define STR_IDE_QUA "第四 IDE 控制器" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "控制器 1:" -#define STR_SCSI_2 "控制器 2:" -#define STR_SCSI_3 "控制器 3:" -#define STR_SCSI_4 "控制器 4:" -#define STR_CASSETTE "磁带" - -#define STR_HDD "硬盘:" -#define STR_NEW "新建(&N)..." -#define STR_EXISTING "已有映像(&E)..." -#define STR_REMOVE "移除(&R)" -#define STR_BUS "总线:" -#define STR_CHANNEL "通道:" -#define STR_ID "ID:" -#define STR_SPEED "速度:" - -#define STR_SPECIFY "指定(&S)..." -#define STR_SECTORS "扇区(S):" -#define STR_HEADS "磁头(H):" -#define STR_CYLS "柱面(C):" -#define STR_SIZE_MB "大小 (MB):" -#define STR_TYPE "类型:" -#define STR_IMG_FORMAT "映像格式:" -#define STR_BLOCK_SIZE "块大小:" - -#define STR_FLOPPY_DRIVES "软盘驱动器:" -#define STR_TURBO "加速时序" -#define STR_CHECKBPB "检查 BPB" -#define STR_CDROM_DRIVES "光盘驱动器:" -#define STR_CD_SPEED "速度:" - -#define STR_MO_DRIVES "磁光盘驱动器:" -#define STR_ZIP_DRIVES "ZIP 驱动器:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA 实时时钟:" -#define STR_ISAMEM "ISA 内存扩充" -#define STR_ISAMEM_1 "扩展卡 1:" -#define STR_ISAMEM_2 "扩展卡 2:" -#define STR_ISAMEM_3 "扩展卡 3:" -#define STR_ISAMEM_4 "扩展卡 4:" -#define STR_BUGGER "ISABugger 设备" -#define STR_POSTCARD "自检 (POST) 卡" - -#define FONT_SIZE 9 -#define FONT_NAME "Microsoft YaHei" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "错误" - IDS_2050 "致命错误" - IDS_2051 " - 已暂停" - IDS_2052 "按下 Ctrl+Alt+PgDn 返回到窗口模式。" - IDS_2053 "速度" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIP 映像 (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box 找不到任何可用的 ROM 映像。\n\n请下载ROM 包并将其解压到 ""roms"" 文件夹中。" - IDS_2057 "(空)" - IDS_2058 "ZIP 映像 (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0所有文件 (*.*)\0*.*\0" - IDS_2059 "加速" - IDS_2060 "开" - IDS_2061 "关" - IDS_2062 "所有映像 (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0基本扇区映像 (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0表面映像 (*.86F)\0*.86F\0" - IDS_2063 "由于 roms/machines 文件夹中缺少合适的 ROM,机型 ""%hs"" 不可用。将切换到其他可用机型。" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "由于 roms/video 文件夹中缺少合适的 ROM,显卡 ""%hs"" 不可用。将切换到其他可用显卡。" - IDS_2065 "机型" - IDS_2066 "显示" - IDS_2067 "输入设备" - IDS_2068 "声音" - IDS_2069 "网络" - IDS_2070 "端口 (COM 和 LPT)" - IDS_2071 "存储控制器" - IDS_2072 "硬盘" - IDS_2073 "软盘/光盘驱动器" - IDS_2074 "其他可移动设备" - IDS_2075 "其他外围设备" - IDS_2076 "表面映像 (*.86F)\0*.86F\0" - IDS_2077 "单击窗口捕捉鼠标" - IDS_2078 "按下 F8+F12 释放鼠标" - IDS_2079 "按下 F8+F12 或鼠标中键释放鼠标" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "总线" - IDS_2082 "文件" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "速度" - IDS_2088 "检查 BPB" - IDS_2089 "KB" - IDS_2090 "无法初始化视频渲染器。" - IDS_2091 "默认" - IDS_2092 "%i 等待状态 (WS)" - IDS_2093 "类型" - IDS_2094 "设置 PCap 失败" - IDS_2095 "未找到 PCap 设备" - IDS_2096 "无效 PCap 设备" - IDS_2097 "标准 2 键操纵杆" - IDS_2098 "标准 4 键操纵杆" - IDS_2099 "标准 6 键操纵杆" - IDS_2100 "标准 8 键操纵杆" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "无" - IDS_2105 "无法加载键盘加速器。" - IDS_2106 "无法注册原始输入。" - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "软盘 %i (%s): %ls" - IDS_2110 "所有映像 (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0高级扇区映像 (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0基本扇区映像 (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux 映像 (*.FDI)\0*.FDI\0表面映像 (*.86F;*.MFM)\0*.86F;*.MFM\0所有文件 (*.*)\0*.*\0" - IDS_2113 "确定要硬重置模拟器吗?" - IDS_2114 "确定要退出 86Box 吗?" - IDS_2115 "无法初始化 Ghostscript" - IDS_2116 "磁光盘 %i (%ls): %ls" - IDS_2117 "磁光盘映像 (*.IM?;*.MDI)\0*.IM?;*.MDI\0所有文件 (*.*)\0*.*\0" - IDS_2118 "欢迎使用 86Box!" - IDS_2119 "内部控制器" - IDS_2120 "退出" - IDS_2121 "找不到 ROM" - IDS_2122 "要保存设置吗?" - IDS_2123 "此操作将硬重置模拟器。" - IDS_2124 "保存" - IDS_2125 "关于 86Box" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "一个旧式计算机模拟器\n\n作者: Miran Grča (OBattler)、RichardG867、Jasmine Iwanek、TC1995、coldbrewed、Teemu Korhonen (Manaatti)、Joakim L. Gilje、Adrien Moulin (elyosh)、Daniel Balsom (gloriouscow)、Cacodemon345、Fred N. van Kempen (waltje)、Tiseno100、reenigne 等人。\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\n本软件依据 GNU 通用公共许可证第二版或更新版本发布。详情见 LICENSE 文件。" - IDS_2128 "确定" - IDS_2129 "硬件不可用" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "请确认 " LIB_NAME_PCAP " 已安装且使用兼容 " LIB_NAME_PCAP " 的网络连接。" - IDS_2131 "无效配置" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " 是将 PostScript 文件转换为 PDF 所需要的库。\n\n使用通用 PostScript 打印机打印的文档将被保存为 PostScript (.ps) 文件。" - IDS_2135 "正在进入全屏模式" - IDS_2136 "不再显示此消息" - IDS_2137 "不退出" - IDS_2138 "重置" - IDS_2139 "不重置" - IDS_2140 "磁光盘映像 (*.IM?;*.MDI)\0*.IM?;*.MDI\0所有文件 (*.*)\0*.*\0" - IDS_2141 "光盘映像 (*.ISO;*.CUE)\0*.ISO;*.CUE\0所有文件 (*.*)\0*.*\0" - IDS_2142 "%hs 设备配置" - IDS_2143 "显示器处在睡眠状态" - IDS_2144 "OpenGL 着色器 (*.GLSL)\0*.GLSL\0所有文件 (*.*)\0*.*\0" - IDS_2145 "OpenGL 选项" - IDS_2146 "正在载入一个不受支持的配置" - IDS_2147 "此模拟计算机禁用了基于选定计算机的 CPU 类型过滤。\n\n能够选中与所选机器本不兼容的 CPU,但是可能会遇到与机器 BIOS 或其他软件不兼容的问题。\n\n启用此设置不受官方支持,并且提交的任何错误报告可能会视为无效而关闭。" - IDS_2148 "继续" - IDS_2149 "磁带: %s" - IDS_2150 "磁带映像 (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0所有文件 (*.*)\0*.*\0" - IDS_2151 "卡带 %i: %ls" - IDS_2152 "卡带映像 (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0所有文件 (*.*)\0*.*\0" - IDS_2153 "初始化渲染器时出错" - IDS_2154 "无法初始化 OpenGL (3.0 Core) 渲染器。请使用其他渲染器。" - IDS_2155 "恢复执行" - IDS_2156 "暂停执行" - IDS_2157 "按下 Ctrl+Alt+Del" - IDS_2158 "按下 Ctrl+Alt+Esc" - IDS_2159 "硬重置" - IDS_2160 "ACPI 关机" - IDS_2161 "设置" - IDS_2162 "类型" - IDS_2163 "无动态重编译" - IDS_2164 "旧式动态重编译" - IDS_2165 "新式动态重编译" - IDS_2166 "由于 roms/video 文件夹中缺少合适的 ROM,显卡 #2 ""%hs"" 不可用。将禁用第二张显卡。" - IDS_2167 "初始化网络驱动程序失败" - IDS_2168 "网络配置将切换为空驱动程序" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "硬盘 (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "不存在 MFM/RLL 或 ESDI CD-ROM 驱动器" - IDS_4100 "自定义..." - IDS_4101 "自定义 (大容量)..." - IDS_4102 "添加新硬盘" - IDS_4103 "添加已存在的硬盘" - IDS_4104 "HDI 磁盘映像不能超过 4 GB。" - IDS_4105 "磁盘映像不能超过 127 GB。" - IDS_4106 "硬盘映像 (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0所有文件 (*.*)\0*.*\0" - IDS_4107 "无法读取文件" - IDS_4108 "无法写入文件" - IDS_4109 "不支持非 512 字节扇区大小的 HDI 或 HDX 映像。" - IDS_4110 "尚未支持 USB" - IDS_4111 "磁盘映像文件已存在" - IDS_4112 "请指定有效的文件名。" - IDS_4113 "已创建磁盘映像" - IDS_4114 "请确定此文件已存在并可读取。" - IDS_4115 "请确定此文件保存在可写目录中。" - IDS_4116 "磁盘映像太大" - IDS_4117 "请记得为新创建的映像分区并格式化。" - IDS_4118 "选定的文件将被覆盖。确定继续使用此文件吗?" - IDS_4119 "不支持的磁盘映像" - IDS_4120 "覆盖" - IDS_4121 "不覆盖" - IDS_4122 "原始映像 (.img)" - IDS_4123 "HDI 映像 (.hdi)" - IDS_4124 "HDX 映像 (.hdx)" - IDS_4125 "固定大小 VHD (.vhd)" - IDS_4126 "动态大小 VHD (.vhd)" - IDS_4127 "差分 VHD (.vhd)" - IDS_4128 "大块 (2 MB)" - IDS_4129 "小块 (512 KB)" - IDS_4130 "VHD 文件 (*.VHD)\0*.VHD\0所有文件 (*.*)\0*.*\0" - IDS_4131 "选择父 VHD 文件" - IDS_4132 "父映像可能在创建差异映像后被修改。\n\n如果映像文件被移动或复制,或创建此磁盘的程序中存在错误,也可能发生这种情况。\n\n是否需要修复时间戳?" - IDS_4133 "父盘与子盘的时间戳不匹配" - IDS_4134 "无法修复 VHD 时间戳。" - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "光盘 %i (%s): %s" - - IDS_5376 "禁用" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "禁用" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (1024 簇)" - IDS_5898 "DMF (2048 簇)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5 英寸 128 MB (ISO 10090)" - IDS_5903 "3.5 英寸 230 MB (ISO 13963)" - IDS_5904 "3.5 英寸 540 MB (ISO 15498)" - IDS_5905 "3.5 英寸 640 MB (ISO 15498)" - IDS_5906 "3.5 英寸 1.3 GB (GigaMO)" - IDS_5907 "3.5 英寸 2.3 GB (GigaMO 2)" - IDS_5908 "5.25 英寸 600 MB" - IDS_5909 "5.25 英寸 650 MB" - IDS_5910 "5.25 英寸 1 GB" - IDS_5911 "5.25 英寸 1.3 GB" - - IDS_6144 "标准转速 (RPM)" - IDS_6145 "低于标准转速的 1%" - IDS_6146 "低于标准转速的 1.5%" - IDS_6147 "低于标准转速的 2%" - - IDS_7168 "(系统默认)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Simplified Chinese resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/zh-TW.rc b/src/win/languages/zh-TW.rc deleted file mode 100644 index 171d8e3f6..000000000 --- a/src/win/languages/zh-TW.rc +++ /dev/null @@ -1,636 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Traditional Chinese resources - -#ifdef _WIN32 -LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL -#pragma code_page(65001) -#endif //_WIN32 - -#define AUTHORS - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "動作(&A)" - BEGIN - MENUITEM "鍵盤需要捕捉(&K)", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "將右 CTRL 鍵映射為左 ALT 鍵(&R)", IDM_ACTION_RCTRL_IS_LALT - MENUITEM SEPARATOR - MENUITEM "硬重設(&H)...", IDM_ACTION_HRESET - MENUITEM "Ctrl+Alt+Del(&C)\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+Esc(&E)", IDM_ACTION_CTRL_ALT_ESC - MENUITEM SEPARATOR - MENUITEM "暫停(&P)", IDM_ACTION_PAUSE - MENUITEM SEPARATOR - MENUITEM "退出(&X)...", IDM_ACTION_EXIT - END - POPUP "檢視(&V)" - BEGIN - MENUITEM "隱藏狀態列(&H)", IDM_VID_HIDE_STATUS_BAR - MENUITEM "隱藏工具列(&T)", IDM_VID_HIDE_TOOLBAR - MENUITEM SEPARATOR - MENUITEM "Show non-primary monitors(&S)", IDM_VID_MONITORS - MENUITEM "視窗大小可調(&R)", IDM_VID_RESIZE - MENUITEM "記住視窗大小和位置(&E)", IDM_VID_REMEMBER - MENUITEM SEPARATOR - POPUP "渲染器(&N)" - BEGIN - MENUITEM "SDL (軟體)(&S)", IDM_VID_SDL_SW - MENUITEM "SDL (硬體)(&H)", IDM_VID_SDL_HW - MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL - MENUITEM "OpenGL (3.0 Core)(&G)", IDM_VID_OPENGL_CORE -#ifdef USE_VNC - MENUITEM "VNC(&V)", IDM_VID_VNC -#endif - END - MENUITEM SEPARATOR - MENUITEM "指定視窗大小...", IDM_VID_SPECIFY_DIM - MENUITEM "強制 4:3 顯示比例(&O)", IDM_VID_FORCE43 - POPUP "視窗縮放係數(&W)" - BEGIN - MENUITEM "0.5x(&0)", IDM_VID_SCALE_1X - MENUITEM "1x(&1)", IDM_VID_SCALE_2X - MENUITEM "1.5x(&5)", IDM_VID_SCALE_3X - MENUITEM "2x(&2)", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X - END - POPUP "過濾方式" - BEGIN - MENUITEM "鄰近(&N)", IDM_VID_FILTER_NEAREST - MENUITEM "線性(&L)", IDM_VID_FILTER_LINEAR - END - MENUITEM "HiDPI 縮放(&D)", IDM_VID_HIDPI - MENUITEM SEPARATOR - MENUITEM "全螢幕(&F)\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "全螢幕拉伸模式(&S)" - BEGIN - MENUITEM "全螢幕拉伸(&F)", IDM_VID_FS_FULL - MENUITEM "4:3(&4)", IDM_VID_FS_43 - MENUITEM "保持比例(&S)", IDM_VID_FS_KEEPRATIO - MENUITEM "整數比例(&I)", IDM_VID_FS_INT - END - POPUP "EGA/(S)VGA 設定(&G)" - BEGIN - MENUITEM "VGA 顯示器反色顯示(&I)", IDM_VID_INVERT - POPUP "VGA 螢幕類型(&T)" - BEGIN - MENUITEM "RGB 彩色(&C)", IDM_VID_GRAY_RGB - MENUITEM "RGB 灰度(&R)", IDM_VID_GRAY_MONO - MENUITEM "琥珀色單色顯示器(&A)", IDM_VID_GRAY_AMBER - MENUITEM "綠色單色顯示器(&G)", IDM_VID_GRAY_GREEN - MENUITEM "白色單色顯示器(&W)", IDM_VID_GRAY_WHITE - END - POPUP "灰度轉換類型(&C)" - BEGIN - MENUITEM "BT601 (NTSC/PAL)(&6)", IDM_VID_GRAYCT_601 - MENUITEM "BT709 (HDTV)(&7)", IDM_VID_GRAYCT_709 - MENUITEM "平均(&A)", IDM_VID_GRAYCT_AVE - END - END - MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/EGA/(S)VGA 過掃描(&G)", IDM_VID_OVERSCAN - MENUITEM "變更單色顯示對比度(&M)", IDM_VID_CGACON - END - MENUITEM "介質(&M)", IDM_MEDIA - POPUP "工具(&T)" - BEGIN - MENUITEM "設定(&S)...", IDM_CONFIG - MENUITEM "更新狀態列圖示(&U)", IDM_UPDATE_ICONS - MENUITEM SEPARATOR - MENUITEM "擷圖(&C)\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR - MENUITEM "偏好設定(&P)...", IDM_PREFERENCES -#ifdef DISCORD - MENUITEM "啟用 Discord 整合(&D)", IDM_DISCORD -#endif - MENUITEM SEPARATOR - MENUITEM "音量增益(&G)...", IDM_SND_GAIN -#ifdef MTR_ENABLED - MENUITEM SEPARATOR - MENUITEM "開始追踪\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "結束追踪\tCtrl+T", IDM_ACTION_END_TRACE -#endif - END - POPUP "說明(&H)" - BEGIN - MENUITEM "文件(&D)...", IDM_DOCS - MENUITEM "關於 86Box(&A)...", IDM_ABOUT - END -END - -StatusBarMenu MENU DISCARDABLE -BEGIN - MENUITEM SEPARATOR -END - -CassetteSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新增映像(&N)...", IDM_CASSETTE_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "開啟已存在的映像(&E)...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "開啟已存在的映像並寫保護(&W)...", IDM_CASSETTE_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "錄製(&R)", IDM_CASSETTE_RECORD - MENUITEM "播放(&P)", IDM_CASSETTE_PLAY - MENUITEM "倒帶至起點(&R)", IDM_CASSETTE_REWIND - MENUITEM "快進至終點(&F)", IDM_CASSETTE_FAST_FORWARD - MENUITEM SEPARATOR - MENUITEM "退出(&J)", IDM_CASSETTE_EJECT - END -END - -CartridgeSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "映像(&I)...", IDM_CARTRIDGE_IMAGE - MENUITEM SEPARATOR - MENUITEM "退出(&J)", IDM_CARTRIDGE_EJECT - END -END - -FloppySubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新增映像(&N)...", IDM_FLOPPY_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "開啟已存在的映像(&E)...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "開啟已存在的映像並寫保護(&W)...", IDM_FLOPPY_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "匯出為 86F 格式(&x)...", IDM_FLOPPY_EXPORT_TO_86F - MENUITEM SEPARATOR - MENUITEM "退出(&J)", IDM_FLOPPY_EJECT - END -END - -CdromSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "靜音(&M)", IDM_CDROM_MUTE - MENUITEM SEPARATOR - MENUITEM "空置光碟機(&M)", IDM_CDROM_EMPTY - MENUITEM "載入上一個映像(&R)", IDM_CDROM_RELOAD - MENUITEM SEPARATOR - MENUITEM "映像(&I)...", IDM_CDROM_IMAGE - MENUITEM "資料夾(&F)...", IDM_CDROM_DIR - END -END - -ZIPSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新增映像(&N)...", IDM_ZIP_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "開啟已存在的映像(&E)...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "開啟已存在的映像並寫保護(&W)...", IDM_ZIP_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "退出(&J)", IDM_ZIP_EJECT - MENUITEM "載入上一個映像(&R)", IDM_ZIP_RELOAD - END -END - -MOSubmenu MENU DISCARDABLE -BEGIN - POPUP "" - BEGIN - MENUITEM "新增映像(&N)...", IDM_MO_IMAGE_NEW - MENUITEM SEPARATOR - MENUITEM "開啟已存在的映像(&E)...", IDM_MO_IMAGE_EXISTING - MENUITEM "開啟已存在的映像並寫保護(&W)...", IDM_MO_IMAGE_EXISTING_WP - MENUITEM SEPARATOR - MENUITEM "退出(&J)", IDM_MO_EJECT - MENUITEM "載入上一個映像(&R)", IDM_MO_RELOAD - END -END - -VidGLSubMenu MENU DISCARDABLE -BEGIN - POPUP "目標幀率(&F)" - BEGIN - MENUITEM "與視訊同步(&S)", IDM_VID_GL_FPS_BLITTER - MENUITEM "25 fps(&2)", IDM_VID_GL_FPS_25 - MENUITEM "30 fps(&3)", IDM_VID_GL_FPS_30 - MENUITEM "50 fps(&5)", IDM_VID_GL_FPS_50 - MENUITEM "60 fps(&6)", IDM_VID_GL_FPS_60 - MENUITEM "75 fps(&7)", IDM_VID_GL_FPS_75 - END - MENUITEM "垂直同步(&V)", IDM_VID_GL_VSYNC - MENUITEM "選取著色器(&S)...", IDM_VID_GL_SHADER - MENUITEM "移除著色器(&R)", IDM_VID_GL_NOSHADER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -#define STR_PREFERENCES "偏好設定" -#define STR_SND_GAIN "音量增益" -#define STR_NEW_FLOPPY "新增映像" -#define STR_CONFIG "設定" -#define STR_SPECIFY_DIM "指定主視窗大小" - -#define STR_OK "確定" -#define STR_CANCEL "取消" -#define STR_GLOBAL "將以上設定存儲為全局預設值(&G)" -#define STR_DEFAULT "預設(&D)" -#define STR_LANGUAGE "語言:" -#define STR_ICONSET "圖示集:" - -#define STR_GAIN "增益" - -#define STR_FILE_NAME "檔案名:" -#define STR_DISK_SIZE "磁碟大小:" -#define STR_RPM_MODE "轉速 (RPM) 模式:" -#define STR_PROGRESS "進度:" - -#define STR_WIDTH "寬度:" -#define STR_HEIGHT "高度:" -#define STR_LOCK_TO_SIZE "鎖定此大小" - -#define STR_MACHINE_TYPE "機器類型:" -#define STR_MACHINE "機型:" -#define STR_CONFIGURE "設定" -#define STR_CPU_TYPE "CPU 類型:" -#define STR_CPU_SPEED "速度:" -#define STR_FPU "浮點處理器 (FPU):" -#define STR_WAIT_STATES "等待狀態 (WS):" -#define STR_MB "MB" -#define STR_MEMORY "記憶體:" -#define STR_TIME_SYNC "時間同步" -#define STR_DISABLED "停用" -#define STR_ENABLED_LOCAL "啟用 (本地時間)" -#define STR_ENABLED_UTC "啟用 (UTC)" -#define STR_DYNAREC "動態重編譯器" -#define STR_SOFTFLOAT "Softfloat FPU" - -#define STR_VIDEO "顯示卡:" -#define STR_VIDEO_2 "顯示卡 2:" -#define STR_VOODOO "Voodoo Graphics" -#define STR_IBM8514 "IBM 8514/A Graphics" -#define STR_XGA "XGA Graphics" - -#define STR_MOUSE "滑鼠:" -#define STR_JOYSTICK "搖桿:" -#define STR_JOY1 "搖桿 1..." -#define STR_JOY2 "搖桿 2..." -#define STR_JOY3 "搖桿 3..." -#define STR_JOY4 "搖桿 4..." - -#define STR_SOUND1 "音效卡 1:" -#define STR_SOUND2 "音效卡 2:" -#define STR_SOUND3 "音效卡 3:" -#define STR_SOUND4 "音效卡 4:" -#define STR_MIDI_OUT "MIDI 輸出裝置:" -#define STR_MIDI_IN "MIDI 輸入裝置:" -#define STR_MPU401 "獨立 MPU-401" -#define STR_FLOAT "使用單精度浮點 (FLOAT32)" -#define STR_FM_DRIVER "調頻合成器驅動器" -#define STR_FM_DRV_NUKED "Nuked (更準確)" -#define STR_FM_DRV_YMFM "YMFM (更快)" - -#define STR_NET_TYPE "網路類型:" -#define STR_PCAP "PCap 裝置:" -#define STR_NET "網路配接器:" -#define STR_NET1 "網路卡 1:" -#define STR_NET2 "網路卡 2:" -#define STR_NET3 "網路卡 3:" -#define STR_NET4 "網路卡 4:" - -#define STR_COM1 "COM1 裝置:" -#define STR_COM2 "COM2 裝置:" -#define STR_COM3 "COM3 裝置:" -#define STR_COM4 "COM4 裝置:" -#define STR_LPT1 "LPT1 裝置:" -#define STR_LPT2 "LPT2 裝置:" -#define STR_LPT3 "LPT3 裝置:" -#define STR_LPT4 "LPT4 裝置:" -#define STR_SERIAL1 "序列埠 1" -#define STR_SERIAL2 "序列埠 2" -#define STR_SERIAL3 "序列埠 3" -#define STR_SERIAL4 "序列埠 4" -#define STR_PARALLEL1 "並列埠 1" -#define STR_PARALLEL2 "並列埠 2" -#define STR_PARALLEL3 "並列埠 3" -#define STR_PARALLEL4 "並列埠 4" -#define STR_SERIAL_PASS1 "序列埠直通 1" -#define STR_SERIAL_PASS2 "序列埠直通 2" -#define STR_SERIAL_PASS3 "序列埠直通 3" -#define STR_SERIAL_PASS4 "序列埠直通 4" - -#define STR_HDC "硬碟控制器:" -#define STR_FDC "軟碟控制器:" -#define STR_IDE_TER "第三 IDE 控制器" -#define STR_IDE_QUA "第四 IDE 控制器" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "控制器 1:" -#define STR_SCSI_2 "控制器 2:" -#define STR_SCSI_3 "控制器 3:" -#define STR_SCSI_4 "控制器 4:" -#define STR_CASSETTE "磁帶" - -#define STR_HDD "硬碟:" -#define STR_NEW "新增(&N)..." -#define STR_EXISTING "已有映像(&E)..." -#define STR_REMOVE "移除(&R)" -#define STR_BUS "匯流排:" -#define STR_CHANNEL "通道:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" - -#define STR_SPECIFY "指定(&S)..." -#define STR_SECTORS "磁區(S):" -#define STR_HEADS "磁頭(H):" -#define STR_CYLS "磁柱(C):" -#define STR_SIZE_MB "大小 (MB):" -#define STR_TYPE "類型:" -#define STR_IMG_FORMAT "映像格式:" -#define STR_BLOCK_SIZE "區塊大小:" - -#define STR_FLOPPY_DRIVES "軟碟機:" -#define STR_TURBO "加速時序" -#define STR_CHECKBPB "檢查 BPB" -#define STR_CDROM_DRIVES "光碟機:" -#define STR_CD_SPEED "速度:" - -#define STR_MO_DRIVES "磁光碟機:" -#define STR_ZIP_DRIVES "ZIP 磁碟機:" -#define STR_250 "ZIP 250" - -#define STR_ISARTC "ISA 實時時鐘:" -#define STR_ISAMEM "ISA 記憶體擴充" -#define STR_ISAMEM_1 "擴充卡 1:" -#define STR_ISAMEM_2 "擴充卡 2:" -#define STR_ISAMEM_3 "擴充卡 3:" -#define STR_ISAMEM_4 "擴充卡 4:" -#define STR_BUGGER "ISABugger 裝置" -#define STR_POSTCARD "自檢 (POST) 卡" - -#define FONT_SIZE 9 -#define FONT_NAME "Microsoft JhengHei" - -#include "dialogs.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_2049 "錯誤" - IDS_2050 "致命錯誤" - IDS_2051 " - 已暫停" - IDS_2052 "按下 Ctrl+Alt+PgDn 返回到視窗模式。" - IDS_2053 "速度" - IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIP 映像 (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box 找不到任何可用的 ROM 映像。\n\n請下載 ROM 套件並將其解壓到 ""roms"" 資料夾。" - IDS_2057 "(空)" - IDS_2058 "ZIP 映像 (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0所有檔案 (*.*)\0*.*\0" - IDS_2059 "加速" - IDS_2060 "開" - IDS_2061 "關" - IDS_2062 "所有映像 (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0基本磁區映像 (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0表面映像 (*.86F)\0*.86F\0" - IDS_2063 "由於 roms/machines 資料夾中缺少合適的 ROM,機型 ""%hs"" 不可用。將切換到其他可用機型。" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2064 "由於 roms/video 資料夾中缺少合適的 ROM,顯示卡 ""%hs"" 不可用。將切換到其他可用顯示卡。" - IDS_2065 "機型" - IDS_2066 "顯示" - IDS_2067 "輸入裝置" - IDS_2068 "聲音" - IDS_2069 "網路" - IDS_2070 "連接埠 (COM 和 LPT)" - IDS_2071 "存儲控制器" - IDS_2072 "硬碟" - IDS_2073 "軟碟/光碟機" - IDS_2074 "其他可移除裝置" - IDS_2075 "其他周邊裝置" - IDS_2076 "表面映像 (*.86F)\0*.86F\0" - IDS_2077 "點擊視窗捕捉滑鼠" - IDS_2078 "按下 F8+F12 釋放滑鼠" - IDS_2079 "按下 F8+F12 或滑鼠中鍵釋放滑鼠" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2081 "匯流排" - IDS_2082 "檔案" - IDS_2083 "C" - IDS_2084 "H" - IDS_2085 "S" - IDS_2086 "MB" - IDS_2087 "Speed" - IDS_2088 "檢查 BPB" - IDS_2089 "KB" - IDS_2090 "無法初始化視訊渲染器。" - IDS_2091 "預設" - IDS_2092 "%i 等待狀態 (WS)" - IDS_2093 "類型" - IDS_2094 "設定 PCap 失敗" - IDS_2095 "未找到 PCap 裝置" - IDS_2096 "無效 PCap 裝置" - IDS_2097 "標準 2 鍵搖桿" - IDS_2098 "標準 4 鍵搖桿" - IDS_2099 "標準 6 鍵搖桿" - IDS_2100 "標準 8 鍵搖桿" - IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" - IDS_2104 "無" - IDS_2105 "無法載入鍵盤加速器。" - IDS_2106 "無法註冊原始輸入。" - IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" - IDS_2109 "軟碟 %i (%s): %ls" - IDS_2110 "所有映像 (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0進階磁區映像 (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0基本磁區映像 (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux 映像 (*.FDI)\0*.FDI\0表面映像 (*.86F;*.MFM)\0*.86F;*.MFM\0所有檔案 (*.*)\0*.*\0" - IDS_2113 "確定要硬重設模擬器嗎?" - IDS_2114 "確定要退出 86Box 嗎?" - IDS_2115 "無法初始化 Ghostscript" - IDS_2116 "磁光碟 %i (%ls): %ls" - IDS_2117 "磁光碟映像 (*.IM?;*.MDI)\0*.IM?;*.MDI\0所有檔案 (*.*)\0*.*\0" - IDS_2118 "歡迎使用 86Box!" - IDS_2119 "內部控制器" - IDS_2120 "退出" - IDS_2121 "找不到 ROM" - IDS_2122 "要儲存設定嗎?" - IDS_2123 "此操作將硬重設模擬器。" - IDS_2124 "儲存" - IDS_2125 "關於 86Box" - IDS_2126 "86Box v" EMU_VERSION - - IDS_2127 "一個舊式電腦模擬器\n\n作者: Miran Grča (OBattler)、RichardG867、Jasmine Iwanek、TC1995、coldbrewed、Teemu Korhonen (Manaatti)、Joakim L. Gilje、Adrien Moulin (elyosh)、Daniel Balsom (gloriouscow)、Cacodemon345、Fred N. van Kempen (waltje)、Tiseno100、reenigne 等人。\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\n本軟體依據 GNU 通用公共授權第二版或更新版本發布。詳情見 LICENSE 檔案。" - IDS_2128 "確定" - IDS_2129 "硬體不可用" -#ifdef _WIN32 -#define LIB_NAME_PCAP "WinPcap" -#else -#define LIB_NAME_PCAP "libpcap" -#endif - IDS_2130 "請確認 " LIB_NAME_PCAP " 已安裝且使用相容 " LIB_NAME_PCAP " 的網路連線。" - IDS_2131 "無效設定" -#ifdef _WIN32 -#define LIB_NAME_GS "gsdll32.dll" -#else -#define LIB_NAME_GS "libgs" -#endif - IDS_2133 LIB_NAME_GS " 是將 PostScript 檔案轉換為 PDF 所需要的庫。\n\n使用通用 PostScript 印表機列印的文件將被儲存為 PostScript (.ps) 檔案。" - IDS_2135 "正在進入全螢幕模式" - IDS_2136 "不要再顯示此消息" - IDS_2137 "不退出" - IDS_2138 "重設" - IDS_2139 "不重設" - IDS_2140 "磁光碟映像 (*.IM?;*.MDI)\0*.IM?;*.MDI\0所有檔案 (*.*)\0*.*\0" - IDS_2141 "光碟映像 (*.ISO;*.CUE)\0*.ISO;*.CUE\0所有檔案 (*.*)\0*.*\0" - IDS_2142 "%hs 裝置設定" - IDS_2143 "顯示器處在睡眠狀態" - IDS_2144 "OpenGL 著色器 (*.GLSL)\0*.GLSL\0所有檔案 (*.*)\0*.*\0" - IDS_2145 "OpenGL 選項" - IDS_2146 "正在載入一個不受支援的設定" - IDS_2147 "此模擬電腦停用了基於選定電腦的 CPU 類型過濾。\n\n能夠選中與所選機器本不相容的 CPU,但是可能會遇到與機器 BIOS 或其他軟體不相容的問題。\n\n啟用此設定不受官方支援,並且提交的任何錯誤報告可能會視為無效而關閉。" - IDS_2148 "繼續" - IDS_2149 "磁帶: %s" - IDS_2150 "磁帶映像 (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0所有檔案 (*.*)\0*.*\0" - IDS_2151 "卡帶 %i: %ls" - IDS_2152 "卡帶映像 (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0所有檔案 (*.*)\0*.*\0" - IDS_2153 "初始化渲染器時出錯" - IDS_2154 "無法初始化 OpenGL (3.0 Core) 渲染器。請使用其他渲染器。" - IDS_2155 "恢復執行" - IDS_2156 "暫停執行" - IDS_2157 "按下 Ctrl+Alt+Del" - IDS_2158 "按下 Ctrl+Alt+Esc" - IDS_2159 "硬重設" - IDS_2160 "ACPI 關機" - IDS_2161 "設定" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_4096 "硬碟 (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "不存在 MFM/RLL 或 ESDI CD-ROM 光碟機" - IDS_4100 "自訂..." - IDS_4101 "自訂 (大容量)..." - IDS_4102 "增加新硬碟" - IDS_4103 "增加已存在的硬碟" - IDS_4104 "HDI 磁碟映像不能超過 4 GB。" - IDS_4105 "磁碟映像不能超過 127 GB。" - IDS_4106 "硬碟映像 (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0所有檔案 (*.*)\0*.*\0" - IDS_4107 "無法讀取檔案" - IDS_4108 "無法寫入檔案" - IDS_4109 "不支援非 512 位元組磁區大小的 HDI 或 HDX 映像。" - IDS_4110 "尚未支援 USB" - IDS_4111 "磁碟映像檔案已存在" - IDS_4112 "請指定有效的檔案名。" - IDS_4113 "已創建磁碟映像" - IDS_4114 "請確定此檔案已存在並可讀取。" - IDS_4115 "請確定此檔案儲存在可寫目錄中。" - IDS_4116 "磁碟映像太大" - IDS_4117 "請記得為新創建的映像分區並格式化。" - IDS_4118 "選定的檔案將被覆蓋。確定繼續使用此檔案嗎?" - IDS_4119 "不支援的磁碟映像" - IDS_4120 "覆蓋" - IDS_4121 "不覆蓋" - IDS_4122 "原始映像 (.img)" - IDS_4123 "HDI 映像 (.hdi)" - IDS_4124 "HDX 映像 (.hdx)" - IDS_4125 "固定大小 VHD (.vhd)" - IDS_4126 "動態大小 VHD (.vhd)" - IDS_4127 "差分 VHD (.vhd)" - IDS_4128 "大區塊 (2 MB)" - IDS_4129 "小區塊 (512 KB)" - IDS_4130 "VHD 檔案 (*.VHD)\0*.VHD\0所有檔案 (*.*)\0*.*\0" - IDS_4131 "選取父 VHD 檔案" - IDS_4132 "父映像可能在創建差異映像後被修改。\n\n如果映像檔案被移動或複製,或創建此磁碟的程式中存在錯誤,也可能發生這種情況。\n\n是否需要修復時間戳?" - IDS_4133 "父碟與子碟的時間戳不匹配" - IDS_4134 "無法修復 VHD 時間戳。" - IDS_4135 "%01i:%02i" - - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" - - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" - - IDS_5120 "光碟 %i (%s): %s" - - IDS_5376 "停用" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" - - IDS_5632 "停用" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" - - IDS_5888 "160 kB" - IDS_5889 "180 kB" - IDS_5890 "320 kB" - IDS_5891 "360 kB" - IDS_5892 "640 kB" - IDS_5893 "720 kB" - IDS_5894 "1.2 MB" - IDS_5895 "1.25 MB" - IDS_5896 "1.44 MB" - IDS_5897 "DMF (1024 簇)" - IDS_5898 "DMF (2048 簇)" - IDS_5899 "2.88 MB" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5 英吋 128 MB (ISO 10090)" - IDS_5903 "3.5 英吋 230 MB (ISO 13963)" - IDS_5904 "3.5 英吋 540 MB (ISO 15498)" - IDS_5905 "3.5 英吋 640 MB (ISO 15498)" - IDS_5906 "3.5 英吋 1.3 GB (GigaMO)" - IDS_5907 "3.5 英吋 2.3 GB (GigaMO 2)" - IDS_5908 "5.25 英吋 600 MB" - IDS_5909 "5.25 英吋 650 MB" - IDS_5910 "5.25 英吋 1 GB" - IDS_5911 "5.25 英吋 1.3 GB" - - IDS_6144 "標準轉速 (RPM)" - IDS_6145 "低於標準轉速的 1%" - IDS_6146 "低於標準轉速的 1.5%" - IDS_6147 "低於標準轉速的 2%" - - IDS_7168 "(系統預設)" -END -#define IDS_LANG_ENUS IDS_7168 - -// Traditional Chinese resources -///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/pcap_if.rc b/src/win/pcap_if.rc deleted file mode 100644 index acc6d25c4..000000000 --- a/src/win/pcap_if.rc +++ /dev/null @@ -1,54 +0,0 @@ -#ifdef _WIN32 -#include -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - - -/* - * Icons by Devcore - * - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png - */ -#ifdef RELEASE_BUILD -100 ICON DISCARDABLE "win/icons/86Box-RB.ico" -#else -100 ICON DISCARDABLE "win/icons/86Box.ico" -#endif - - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,2,0 - PRODUCTVERSION 1,0,2,0 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments", "\0" - VALUE "CompanyName", "IRC #SoftHistory\0" - VALUE "FileDescription", "PCap_IF - test tool for WinPcap\0" - VALUE "FileVersion", "1.0.2\0" - VALUE "InternalName", "pcap_if\0" - VALUE "LegalCopyright", "Copyright 2017 Fred N. van Kempen\0" - VALUE "LegalTrademarks", "\0" - VALUE "OriginalFilename", "pcap_if.exe\0" - VALUE "PrivateBuild", "\0" - VALUE "ProductName", "WinPcap Test Tool\0" - VALUE "ProductVersion", "1.0.2\0" - VALUE "SpecialBuild", "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff --git a/src/win/win.c b/src/win/win.c deleted file mode 100644 index d77ab32fd..000000000 --- a/src/win/win.c +++ /dev/null @@ -1,1346 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Platform main support module for Windows. - * - * - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. - * Copyright 2021 Laci bá' - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#define NTDDI_VERSION 0x06010000 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/config.h> -#include <86box/device.h> -#include <86box/keyboard.h> -#include <86box/mouse.h> -#include <86box/timer.h> -#include <86box/nvr.h> -#include <86box/video.h> -#include <86box/mem.h> -#include <86box/rom.h> -#include <86box/path.h> -#define GLOBAL -#include <86box/plat.h> -#include <86box/plat_dynld.h> -#include <86box/thread.h> -#include <86box/ui.h> -#ifdef USE_VNC -# include <86box/vnc.h> -#endif -#include <86box/win_sdl.h> -#include <86box/win_opengl.h> -#include <86box/win.h> -#include <86box/version.h> -#include <86box/gdbstub.h> -#ifdef MTR_ENABLED -# include -#endif - -typedef struct rc_str_t { - WCHAR str[1024]; -} rc_str_t; - -/* Platform Public data, specific. */ -HINSTANCE hinstance; /* application instance */ -HANDLE ghMutex; -uint32_t lang_id; /* current and system language ID */ -uint32_t lang_sys; /* current and system language ID */ -DWORD dwSubLangID; -int acp_utf8; /* Windows supports UTF-8 codepage */ -volatile int cpu_thread_run = 1; - -/* Local data. */ -static HANDLE thMain; -static rc_str_t *lpRCstr2048 = NULL; -static rc_str_t *lpRCstr4096 = NULL; -static rc_str_t *lpRCstr4352 = NULL; -static rc_str_t *lpRCstr4608 = NULL; -static rc_str_t *lpRCstr5120 = NULL; -static rc_str_t *lpRCstr5376 = NULL; -static rc_str_t *lpRCstr5632 = NULL; -static rc_str_t *lpRCstr5888 = NULL; -static rc_str_t *lpRCstr6144 = NULL; -static rc_str_t *lpRCstr7168 = NULL; -static int vid_api_inited = 0; -static char *argbuf; -static int first_use = 1; -static LARGE_INTEGER StartingTime; -static LARGE_INTEGER Frequency; - -static const struct { - const char *name; - int local; - int (*init)(void *); - void (*close)(void); - void (*resize)(int x, int y); - int (*pause)(void); - void (*enable)(int enable); - void (*set_fs)(int fs); - void (*reload)(void); -} vid_apis[RENDERERS_NUM] = { - { "SDL_Software", 1, (int (*)(void *)) sdl_inits, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, sdl_reload }, - { "SDL_Hardware", 1, (int (*)(void *)) sdl_inith, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, sdl_reload }, - { "SDL_OpenGL", 1, (int (*)(void *)) sdl_initho, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, sdl_reload }, - { "OpenGL_Core", 1, (int (*)(void *)) opengl_init, opengl_close, opengl_resize, opengl_pause, NULL, opengl_set_fs, opengl_reload } -#ifdef USE_VNC - , - { "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause, NULL, NULL } -#endif -}; - -extern int title_update; - -#ifdef ENABLE_WIN_LOG -int win_do_log = ENABLE_WIN_LOG; - -static void -win_log(const char *fmt, ...) -{ - va_list ap; - - if (win_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define win_log(fmt, ...) -#endif - -void -free_string(rc_str_t **str) -{ - if (*str != NULL) { - free(*str); - *str = NULL; - } -} - -static void -LoadCommonStrings(void) -{ - int i; - - free_string(&lpRCstr7168); - free_string(&lpRCstr6144); - free_string(&lpRCstr5888); - free_string(&lpRCstr5632); - free_string(&lpRCstr5376); - free_string(&lpRCstr5120); - free_string(&lpRCstr4608); - free_string(&lpRCstr4352); - free_string(&lpRCstr4096); - free_string(&lpRCstr2048); - - lpRCstr2048 = calloc(STR_NUM_2048, sizeof(rc_str_t)); - lpRCstr4096 = calloc(STR_NUM_4096, sizeof(rc_str_t)); - lpRCstr4352 = calloc(STR_NUM_4352, sizeof(rc_str_t)); - lpRCstr4608 = calloc(STR_NUM_4608, sizeof(rc_str_t)); - lpRCstr5120 = calloc(STR_NUM_5120, sizeof(rc_str_t)); - lpRCstr5376 = calloc(STR_NUM_5376, sizeof(rc_str_t)); - lpRCstr5632 = calloc(STR_NUM_5632, sizeof(rc_str_t)); - lpRCstr5888 = calloc(STR_NUM_5888, sizeof(rc_str_t)); - lpRCstr6144 = calloc(STR_NUM_6144, sizeof(rc_str_t)); - lpRCstr7168 = calloc(STR_NUM_7168, sizeof(rc_str_t)); - - for (i = 0; i < STR_NUM_2048; i++) - LoadString(hinstance, 2048 + i, lpRCstr2048[i].str, 1024); - - for (i = 0; i < STR_NUM_4096; i++) - LoadString(hinstance, 4096 + i, lpRCstr4096[i].str, 1024); - - for (i = 0; i < STR_NUM_4352; i++) - LoadString(hinstance, 4352 + i, lpRCstr4352[i].str, 1024); - - for (i = 0; i < STR_NUM_4608; i++) - LoadString(hinstance, 4608 + i, lpRCstr4608[i].str, 1024); - - for (i = 0; i < STR_NUM_5120; i++) - LoadString(hinstance, 5120 + i, lpRCstr5120[i].str, 1024); - - for (i = 0; i < STR_NUM_5376; i++) { - if ((i == 0) || (i > 3)) - LoadString(hinstance, 5376 + i, lpRCstr5376[i].str, 1024); - } - - for (i = 0; i < STR_NUM_5632; i++) { - if ((i == 0) || (i > 3)) - LoadString(hinstance, 5632 + i, lpRCstr5632[i].str, 1024); - } - - for (i = 0; i < STR_NUM_5888; i++) - LoadString(hinstance, 5888 + i, lpRCstr5888[i].str, 1024); - - for (i = 0; i < STR_NUM_6144; i++) - LoadString(hinstance, 6144 + i, lpRCstr6144[i].str, 1024); - - for (i = 0; i < STR_NUM_7168; i++) - LoadString(hinstance, 7168 + i, lpRCstr7168[i].str, 1024); -} - -size_t -mbstoc16s(uint16_t dst[], const char src[], int len) -{ - if (src == NULL) - return 0; - if (len < 0) - return 0; - - size_t ret = MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, dst == NULL ? 0 : len); - - if (!ret) { - return -1; - } - - return ret; -} - -size_t -c16stombs(char dst[], const uint16_t src[], int len) -{ - if (src == NULL) - return 0; - if (len < 0) - return 0; - - size_t ret = WideCharToMultiByte(CP_UTF8, 0, src, -1, dst, dst == NULL ? 0 : len, NULL, NULL); - - if (!ret) { - return -1; - } - - return ret; -} - -int -has_language_changed(uint32_t id) -{ - return (lang_id != id); -} - -/* Set (or re-set) the language for the application. */ -void -set_language(uint32_t id) -{ - if (id == 0xFFFF) { - set_language(lang_sys); - lang_id = id; - return; - } - - if (lang_id != id) { - /* Set our new language ID. */ - lang_id = id; - SetThreadUILanguage(lang_id); - - /* Load the strings table for this ID. */ - LoadCommonStrings(); - - /* Reload main menu */ - menuMain = LoadMenu(hinstance, L"MainMenu"); - if (hwndMain != NULL) - SetMenu(hwndMain, menuMain); - - /* Re-init all the menus */ - ResetAllMenus(); - media_menu_init(); - } -} - -wchar_t * -plat_get_string(int i) -{ - LPTSTR str; - - if ((i >= 2048) && (i <= 3071)) - str = lpRCstr2048[i - 2048].str; - else if ((i >= 4096) && (i <= 4351)) - str = lpRCstr4096[i - 4096].str; - else if ((i >= 4352) && (i <= 4607)) - str = lpRCstr4352[i - 4352].str; - else if ((i >= 4608) && (i <= 5119)) - str = lpRCstr4608[i - 4608].str; - else if ((i >= 5120) && (i <= 5375)) - str = lpRCstr5120[i - 5120].str; - else if ((i >= 5376) && (i <= 5631)) - str = lpRCstr5376[i - 5376].str; - else if ((i >= 5632) && (i <= 5887)) - str = lpRCstr5632[i - 5632].str; - else if ((i >= 5888) && (i <= 6143)) - str = lpRCstr5888[i - 5888].str; - else if ((i >= 6144) && (i <= 7167)) - str = lpRCstr6144[i - 6144].str; - else - str = lpRCstr7168[i - 7168].str; - - return str; -} - -#ifdef MTR_ENABLED -void -init_trace(void) -{ - mtr_init("trace.json"); - mtr_start(); -} - -void -shutdown_trace(void) -{ - mtr_stop(); - mtr_shutdown(); -} -#endif - -/* Create a console if we don't already have one. */ -static void -CreateConsole(int init) -{ - HANDLE h; - FILE *fp; - fpos_t p; - int i; - - if (!init) { - if (force_debug) - FreeConsole(); - return; - } - - /* Are we logging to a file? */ - p = 0; - (void) fgetpos(stdout, &p); - if (p != -1) - return; - - /* Not logging to file, attach to console. */ - if (!AttachConsole(ATTACH_PARENT_PROCESS)) { - /* Parent has no console, create one. */ - if (!AllocConsole()) { - /* Cannot create console, just give up. */ - return; - } - } - fp = NULL; - if ((h = GetStdHandle(STD_OUTPUT_HANDLE)) != NULL) { - /* We got the handle, now open a file descriptor. */ - if ((i = _open_osfhandle((intptr_t) h, _O_TEXT)) != -1) { - /* We got a file descriptor, now allocate a new stream. */ - if ((fp = _fdopen(i, "w")) != NULL) { - /* Got the stream, re-initialize stdout without it. */ - (void) freopen("CONOUT$", "w", stdout); - setvbuf(stdout, NULL, _IONBF, 0); - fflush(stdout); - } - } - } - - if (fp != NULL) { - fclose(fp); - fp = NULL; - } -} - -static void -CloseConsole(void) -{ - CreateConsole(0); -} - -/* Process the commandline, and create standard argc/argv array. */ -static int -ProcessCommandLine(char ***argv) -{ - char **args; - int argc_max; - int i; - int q; - int argc; - - if (acp_utf8) { - i = strlen(GetCommandLineA()) + 1; - argbuf = (char *) malloc(i); - strcpy(argbuf, GetCommandLineA()); - } else { - i = c16stombs(NULL, GetCommandLineW(), 0) + 1; - argbuf = (char *) malloc(i); - c16stombs(argbuf, GetCommandLineW(), i); - } - - argc = 0; - argc_max = 64; - args = (char **) malloc(sizeof(char *) * argc_max); - if (args == NULL) { - free(argbuf); - return 0; - } - - /* parse commandline into argc/argv format */ - i = 0; - while (argbuf[i]) { - while (argbuf[i] == ' ') - i++; - - if (argbuf[i]) { - if ((argbuf[i] == '\'') || (argbuf[i] == '"')) { - q = argbuf[i++]; - if (!argbuf[i]) - break; - } else - q = 0; - - args[argc++] = &argbuf[i]; - - if (argc >= argc_max) { - argc_max += 64; - args = realloc(args, sizeof(char *) * argc_max); - if (args == NULL) { - free(argbuf); - return 0; - } - } - - while ((argbuf[i]) && (q ? (argbuf[i] != q) : (argbuf[i] != ' '))) - i++; - - if (argbuf[i]) { - argbuf[i] = 0; - i++; - } - } - } - - args[argc] = NULL; - *argv = args; - - return argc; -} - -/* For the Windows platform, this is the start of the application. */ -int WINAPI -WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nCmdShow) -{ - char **argv = NULL; - int argc; - int i; - - /* Initialize the COM library for the main thread. */ - CoInitializeEx(NULL, COINIT_MULTITHREADED); - - /* Check if Windows supports UTF-8 */ - if (GetACP() == CP_UTF8) - acp_utf8 = 1; - else - acp_utf8 = 0; - - /* Set this to the default value (windowed mode). */ - video_fullscreen = 0; - - /* We need this later. */ - hinstance = hInst; - - /* Set the application version ID string. */ - sprintf(emu_version, "%s v%s", EMU_NAME, EMU_VERSION_FULL); - - /* First, set our (default) language. */ - lang_sys = GetThreadUILanguage(); - set_language(DEFAULT_LANGUAGE); - - /* Process the command line for options. */ - argc = ProcessCommandLine(&argv); - - /* Pre-initialize the system, this loads the config file. */ - if (!pc_init(argc, argv)) { - /* Detach from console. */ - if (force_debug) - CreateConsole(0); - - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_HAS_SHUTDOWN, (WPARAM) 0, (LPARAM) hwndMain); - - free(argbuf); - free(argv); - return 1; - } - - extern int gfxcard[2]; - gfxcard[1] = 0; - - /* Create console window. */ - if (force_debug) { - CreateConsole(1); - atexit(CloseConsole); - } - - /* Handle our GUI. */ - i = ui_init(nCmdShow); - - /* Uninitialize COM before exit. */ - CoUninitialize(); - - free(argbuf); - free(argv); - return i; -} - -void -main_thread(void *param) -{ - uint32_t old_time; - uint32_t new_time; - int drawits; - int frames; - - framecountx = 0; - title_update = 1; - old_time = GetTickCount(); - drawits = frames = 0; - while (!is_quit && cpu_thread_run) { - /* See if it is time to run a frame of code. */ - new_time = GetTickCount(); -#ifdef USE_GDBSTUB - if (gdbstub_next_asap && (drawits <= 0)) - drawits = 10; - else -#endif - drawits += (new_time - old_time); - old_time = new_time; - if (drawits > 0 && !dopause) { - /* Yes, so do one frame now. */ - drawits -= 10; - if (drawits > 50) - drawits = 0; - - /* Run a block of code. */ - pc_run(); - - /* Every 200 frames we save the machine status. */ - if (++frames >= 200 && nvr_dosave) { - nvr_save(); - nvr_dosave = 0; - frames = 0; - } - } else /* Just so we dont overload the host OS. */ - Sleep(1); - - /* If needed, handle a screen resize. */ - if (atomic_load(&doresize_monitors[0]) && !video_fullscreen && !is_quit) { - if (vid_resize & 2) - plat_resize(fixed_size_x, fixed_size_y); - else - plat_resize(scrnsz_x, scrnsz_y); - atomic_store(&doresize_monitors[0], 0); - } - } - - is_quit = 1; -} - -/* - * We do this here since there is platform-specific stuff - * going on here, and we do it in a function separate from - * main() so we can call it from the UI module as well. - */ -void -do_start(void) -{ - LARGE_INTEGER qpc; - - /* We have not stopped yet. */ - is_quit = 0; - - /* Initialize the high-precision timer. */ - timeBeginPeriod(1); - QueryPerformanceFrequency(&qpc); - timer_freq = qpc.QuadPart; - win_log("Main timer precision: %llu\n", timer_freq); - - /* Start the emulator, really. */ - thMain = thread_create(main_thread, NULL); - SetThreadPriority(thMain, THREAD_PRIORITY_HIGHEST); -} - -/* Cleanly stop the emulator. */ -void -do_stop(void) -{ - /* Claim the video blitter. */ - startblit(); - - vid_apis[vid_api].close(); - - pc_close(thMain); - - thMain = NULL; - - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_HAS_SHUTDOWN, (WPARAM) 0, (LPARAM) hwndMain); -} - -void -plat_get_exe_name(char *s, int size) -{ - wchar_t *temp; - - if (acp_utf8) - GetModuleFileNameA(hinstance, s, size); - else { - temp = malloc(size * sizeof(wchar_t)); - GetModuleFileNameW(hinstance, temp, size); - c16stombs(s, temp, size); - free(temp); - } -} - -void -plat_tempfile(char *bufp, char *prefix, char *suffix) -{ - SYSTEMTIME SystemTime; - - if (prefix != NULL) - sprintf(bufp, "%s-", prefix); - else - strcpy(bufp, ""); - - GetLocalTime(&SystemTime); - sprintf(&bufp[strlen(bufp)], "%d%02d%02d-%02d%02d%02d-%03d%s", - SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay, - SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, - SystemTime.wMilliseconds, - suffix); -} - -int -plat_getcwd(char *bufp, int max) -{ - wchar_t *temp; - - if (acp_utf8) - (void) _getcwd(bufp, max); - else { - temp = malloc(max * sizeof(wchar_t)); - (void) _wgetcwd(temp, max); - c16stombs(bufp, temp, max); - free(temp); - } - - return 0; -} - -int -plat_chdir(char *path) -{ - wchar_t *temp; - int len; - int ret; - - if (acp_utf8) - return (_chdir(path)); - else { - len = mbstoc16s(NULL, path, 0) + 1; - temp = malloc(len * sizeof(wchar_t)); - mbstoc16s(temp, path, len); - - ret = _wchdir(temp); - - free(temp); - return ret; - } -} - -FILE * -plat_fopen(const char *path, const char *mode) -{ - wchar_t *pathw; - wchar_t *modew; - int len; - FILE *fp; - - if (acp_utf8) - return fopen(path, mode); - else { - len = mbstoc16s(NULL, path, 0) + 1; - pathw = malloc(sizeof(wchar_t) * len); - mbstoc16s(pathw, path, len); - - len = mbstoc16s(NULL, mode, 0) + 1; - modew = malloc(sizeof(wchar_t) * len); - mbstoc16s(modew, mode, len); - - fp = _wfopen(pathw, modew); - - free(pathw); - free(modew); - - return fp; - } -} - -/* Open a file, using Unicode pathname, with 64bit pointers. */ -FILE * -plat_fopen64(const char *path, const char *mode) -{ - return plat_fopen(path, mode); -} - -void -plat_remove(char *path) -{ - wchar_t *temp; - int len; - - if (acp_utf8) - remove(path); - else { - len = mbstoc16s(NULL, path, 0) + 1; - temp = malloc(len * sizeof(wchar_t)); - mbstoc16s(temp, path, len); - - _wremove(temp); - - free(temp); - } -} - -void -path_normalize(UNUSED(char *path)) -{ - /* No-op */ -} - -/* Make sure a path ends with a trailing (back)slash. */ -void -path_slash(char *path) -{ - if ((path[strlen(path) - 1] != '\\') && (path[strlen(path) - 1] != '/')) - strcat(path, "\\"); -} - -/* Return a trailing (back)slash if necessary. */ -const char * -path_get_slash(char *path) -{ - char *ret = ""; - - if ((path[strlen(path) - 1] != '\\') && (path[strlen(path) - 1] != '/')) - ret = "\\"; - - return ret; -} - -/* Check if the given path is absolute or not. */ -int -path_abs(char *path) -{ - if ((path[1] == ':') || (path[0] == '\\') || (path[0] == '/')) - return 1; - - return 0; -} - -/* Return the last element of a pathname. */ -char * -plat_get_basename(const char *path) -{ - int c = (int) strlen(path); - - while (c > 0) { - if (path[c] == '/' || path[c] == '\\') - return ((char *) &path[c + 1]); - c--; - } - - return ((char *) path); -} - -/* Return the 'directory' element of a pathname. */ -void -path_get_dirname(char *dest, const char *path) -{ - int c = (int) strlen(path); - const char *ptr; - - ptr = (char *) path; - - while (c > 0) { - if (path[c] == '/' || path[c] == '\\') { - ptr = (char *) &path[c]; - break; - } - c--; - } - - /* Copy to destination. */ - while (path < ptr) - *dest++ = *path++; - *dest = '\0'; -} - -char * -path_get_filename(char *s) -{ - int c = strlen(s) - 1; - - while (c > 0) { - if (s[c] == '/' || s[c] == '\\') - return (&s[c + 1]); - c--; - } - - return s; -} - -char * -path_get_extension(char *s) -{ - int c = strlen(s) - 1; - - if (c <= 0) - return s; - - while (c && s[c] != '.') - c--; - - if (!c) - return (&s[strlen(s)]); - - return (&s[c + 1]); -} - -void -path_append_filename(char *dest, const char *s1, const char *s2) -{ - strcpy(dest, s1); - path_slash(dest); - strcat(dest, s2); -} - -void -plat_put_backslash(char *s) -{ - int c = strlen(s) - 1; - - if (s[c] != '/' && s[c] != '\\') - s[c] = '/'; -} - -int -plat_dir_check(char *path) -{ - DWORD dwAttrib; - int len; - wchar_t *temp; - - if (acp_utf8) - dwAttrib = GetFileAttributesA(path); - else { - len = mbstoc16s(NULL, path, 0) + 1; - temp = malloc(len * sizeof(wchar_t)); - mbstoc16s(temp, path, len); - - dwAttrib = GetFileAttributesW(temp); - - free(temp); - } - - return ((dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) ? 1 : 0); -} - -int -plat_dir_create(char *path) -{ - int ret; - int len; - wchar_t *temp; - - if (acp_utf8) - return SHCreateDirectoryExA(NULL, path, NULL); - else { - len = mbstoc16s(NULL, path, 0) + 1; - temp = malloc(len * sizeof(wchar_t)); - mbstoc16s(temp, path, len); - - ret = SHCreateDirectoryExW(NULL, temp, NULL); - - free(temp); - - return ret; - } -} - -void * -plat_mmap(size_t size, uint8_t executable) -{ - return VirtualAlloc(NULL, size, MEM_COMMIT, executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE); -} - -void -plat_get_global_config_dir(char *strptr) -{ - wchar_t appdata_dir[1024] = { L'\0' }; - - if (_wgetenv(L"LOCALAPPDATA") && _wgetenv(L"LOCALAPPDATA")[0] != L'\0') { - size_t len = 0; - wcsncpy(appdata_dir, _wgetenv(L"LOCALAPPDATA"), 1024); - len = wcslen(appdata_dir); - if (appdata_dir[len - 1] != L'\\') { - appdata_dir[len] = L'\\'; - appdata_dir[len + 1] = L'\0'; - } - wcscat(appdata_dir, L"86box"); - CreateDirectoryW(appdata_dir, NULL); - wcscat(appdata_dir, L"\\"); - c16stombs(strptr, appdata_dir, 1024); - } -} - -void -plat_init_rom_paths(void) -{ - wchar_t appdata_dir[1024] = { L'\0' }; - - if (_wgetenv(L"LOCALAPPDATA") && _wgetenv(L"LOCALAPPDATA")[0] != L'\0') { - char appdata_dir_a[1024] = { '\0' }; - size_t len = 0; - wcsncpy(appdata_dir, _wgetenv(L"LOCALAPPDATA"), 1024); - len = wcslen(appdata_dir); - if (appdata_dir[len - 1] != L'\\') { - appdata_dir[len] = L'\\'; - appdata_dir[len + 1] = L'\0'; - } - wcscat(appdata_dir, L"86box"); - CreateDirectoryW(appdata_dir, NULL); - wcscat(appdata_dir, L"\\roms"); - CreateDirectoryW(appdata_dir, NULL); - wcscat(appdata_dir, L"\\"); - c16stombs(appdata_dir_a, appdata_dir, 1024); - rom_add_path(appdata_dir_a); - } -} - -void -plat_munmap(void *ptr, UNUSED(size_t size)) -{ - VirtualFree(ptr, 0, MEM_RELEASE); -} - -uint64_t -plat_timer_read(void) -{ - LARGE_INTEGER li; - - QueryPerformanceCounter(&li); - - return (li.QuadPart); -} - -static LARGE_INTEGER -plat_get_ticks_common(void) -{ - LARGE_INTEGER EndingTime; - LARGE_INTEGER ElapsedMicroseconds; - - if (first_use) { - QueryPerformanceFrequency(&Frequency); - QueryPerformanceCounter(&StartingTime); - first_use = 0; - } - - QueryPerformanceCounter(&EndingTime); - ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart; - - /* We now have the elapsed number of ticks, along with the - number of ticks-per-second. We use these values - to convert to the number of elapsed microseconds. - To guard against loss-of-precision, we convert - to microseconds *before* dividing by ticks-per-second. */ - ElapsedMicroseconds.QuadPart *= 1000000; - ElapsedMicroseconds.QuadPart /= Frequency.QuadPart; - - return ElapsedMicroseconds; -} - -uint32_t -plat_get_ticks(void) -{ - return (uint32_t) (plat_get_ticks_common().QuadPart / 1000); -} - -uint32_t -plat_get_micro_ticks(void) -{ - return (uint32_t) plat_get_ticks_common().QuadPart; -} - -void -plat_delay_ms(uint32_t count) -{ - Sleep(count); -} - -/* Return the VIDAPI number for the given name. */ -int -plat_vidapi(char *name) -{ - /* Default/System is SDL Hardware. */ - if (!strcasecmp(name, "default") || !strcasecmp(name, "system")) - return 1; - - /* If DirectDraw or plain SDL was specified, return SDL Software. */ - if (!strcasecmp(name, "ddraw") || !strcasecmp(name, "sdl")) - return 1; - - for (uint8_t i = 0; i < RENDERERS_NUM; i++) { - if (vid_apis[i].name && !strcasecmp(vid_apis[i].name, name)) - return i; - } - - /* Default value. */ - return 1; -} - -/* Return the VIDAPI name for the given number. */ -char * -plat_vidapi_name(int api) -{ - char *name = "default"; - - switch (api) { - case 0: - name = "sdl_software"; - break; - case 1: - break; - case 2: - name = "sdl_opengl"; - break; - case 3: - name = "opengl_core"; - break; -#ifdef USE_VNC - case 4: - name = "vnc"; - break; -#endif - default: - fatal("Unknown renderer: %i\n", api); - break; - } - - return name; -} - -int -plat_setvid(int api) -{ - int i; - - win_log("Initializing VIDAPI: api=%d\n", api); - startblit(); - - /* Close the (old) API. */ - vid_apis[vid_api].close(); - vid_api = api; - - if (vid_apis[vid_api].local) - ShowWindow(hwndRender, SW_SHOW); - else - ShowWindow(hwndRender, SW_HIDE); - - /* Initialize the (new) API. */ - i = vid_apis[vid_api].init((void *) hwndRender); - endblit(); - if (!i) - return 0; - - device_force_redraw(); - - vid_api_inited = 1; - - return 1; -} - -/* Tell the renderers about a new screen resolution. */ -void -plat_vidsize(int x, int y) -{ - if (!vid_api_inited || !vid_apis[vid_api].resize) - return; - - startblit(); - vid_apis[vid_api].resize(x, y); - endblit(); -} - -void -plat_vidapi_enable(int enable) -{ - int i = 1; - - if (!vid_api_inited || !vid_apis[vid_api].enable) - return; - - vid_apis[vid_api].enable(enable != 0); - - if (!i) - return; - - if (enable) - device_force_redraw(); -} - -int -get_vidpause(void) -{ - return (vid_apis[vid_api].pause()); -} - -void -plat_setfullscreen(int on) -{ - RECT rect; - int temp_x; - int temp_y; - int dpi = win_get_dpi(hwndMain); - - /* Are we changing from the same state to the same state? */ - if ((!!(on & 1)) == (!!video_fullscreen)) - return; - - if (on && video_fullscreen_first) { - video_fullscreen |= 2; - if (ui_msgbox_header(MBX_INFO | MBX_DONTASK, (wchar_t *) IDS_2135, (wchar_t *) IDS_2052) == 10) { - video_fullscreen_first = 0; - config_save(); - } - video_fullscreen &= 1; - } - - /* OK, claim the video. */ - if (!(on & 2)) - win_mouse_close(); - - /* Close the current mode, and open the new one. */ - video_fullscreen = (on & 1) | 2; - if (vid_apis[vid_api].set_fs) - vid_apis[vid_api].set_fs(on & 1); - if (!(on & 1)) { - plat_resize(scrnsz_x, scrnsz_y); - if (vid_resize) { - /* scale the screen base on DPI */ - if (!(vid_resize & 2) && window_remember) { - MoveWindow(hwndMain, window_x, window_y, window_w, window_h, TRUE); - GetClientRect(hwndMain, &rect); - - temp_x = rect.right - rect.left + 1; - temp_y = rect.bottom - rect.top + 1 - (hide_status_bar ? 0 : sbar_height) - (hide_tool_bar ? 0 : tbar_height); - } else { - if (dpi_scale) { - temp_x = MulDiv((vid_resize & 2) ? fixed_size_x : unscaled_size_x, dpi, 96); - temp_y = MulDiv((vid_resize & 2) ? fixed_size_y : unscaled_size_y, dpi, 96); - } else { - temp_x = (vid_resize & 2) ? fixed_size_x : unscaled_size_x; - temp_y = (vid_resize & 2) ? fixed_size_y : unscaled_size_y; - } - - /* Main Window. */ - if (vid_resize >= 2) - MoveWindow(hwndMain, window_x, window_y, window_w, window_h, TRUE); - - ResizeWindowByClientArea(hwndMain, temp_x, temp_y + (hide_status_bar ? 0 : sbar_height) + (hide_tool_bar ? 0 : tbar_height)); - } - - /* Toolbar. */ - MoveWindow(hwndRebar, 0, 0, temp_x, tbar_height, TRUE); - - /* Render window. */ - MoveWindow(hwndRender, 0, hide_tool_bar ? 0 : tbar_height, temp_x, temp_y, TRUE); - - /* Status bar. */ - GetClientRect(hwndMain, &rect); - MoveWindow(hwndSBAR, 0, rect.bottom - sbar_height, temp_x, sbar_height, TRUE); - - if (mouse_capture) - ClipCursor(&rect); - - scrnsz_x = (vid_resize & 2) ? fixed_size_x : unscaled_size_x; - scrnsz_y = (vid_resize & 2) ? fixed_size_y : unscaled_size_y; - } - } - video_fullscreen &= 1; - video_force_resize_set(1); - if (!(on & 1)) - atomic_store(&doresize_monitors[0], 1); - - win_mouse_init(); - - if (!(on & 2)) { - /* Release video and make it redraw the screen. */ - device_force_redraw(); - - /* Send a CTRL break code so CTRL does not get stuck. */ - keyboard_input(0, 0x01D); - } - - /* Finally, handle the host's mouse cursor. */ - /* win_log("%s full screen, %s cursor\n", on ? "enter" : "leave", on ? "hide" : "show"); */ - show_cursor(video_fullscreen ? 0 : -1); - - if (!(on & 2)) { - /* This is needed for OpenGL. */ - plat_vidapi_enable(0); - plat_vidapi_enable(1); - } -} - -void -plat_vid_reload_options(void) -{ - if (!vid_api_inited || !vid_apis[vid_api].reload) - return; - - vid_apis[vid_api].reload(); -} - -void -plat_vidapi_reload(void) -{ - vid_apis[vid_api].reload(); -} - -/* Sets up the program language before initialization. */ -uint32_t -plat_language_code(char *langcode) -{ - if (!strcmp(langcode, "system")) - return 0xFFFF; - - int len = mbstoc16s(NULL, langcode, 0) + 1; - wchar_t *temp = malloc(len * sizeof(wchar_t)); - mbstoc16s(temp, langcode, len); - - LCID lcid = LocaleNameToLCID(temp, 0); - - free(temp); - return lcid; -} - -/* Converts back the language code to LCID */ -void -plat_language_code_r(uint32_t lcid, char *outbuf, int len) -{ - if (lcid == 0xFFFF) { - strcpy(outbuf, "system"); - return; - } - - wchar_t buffer[LOCALE_NAME_MAX_LENGTH + 1]; - LCIDToLocaleName(lcid, buffer, LOCALE_NAME_MAX_LENGTH, 0); - - c16stombs(outbuf, buffer, len); -} - -void -plat_get_cpu_string(char *outbuf, uint8_t len) { - char cpu_string[] = "Unknown"; - strncpy(outbuf, cpu_string, len); -} - -void -plat_set_thread_name(void *thread, const char *name) -{ - /* SetThreadDescription was added in 14393. Revisit if we ever start requiring 10. */ - static void *kernel32_handle = NULL; - static HRESULT(WINAPI *pSetThreadDescription)(HANDLE hThread, PCWSTR lpThreadDescription) = NULL; - static dllimp_t kernel32_imports[] = { - // clang-format off - { "SetThreadDescription", &pSetThreadDescription }, - { NULL, NULL } - // clang-format on - }; - - if (!kernel32_handle) { - kernel32_handle = dynld_module("kernel32.dll", kernel32_imports); - if (!kernel32_handle) { - kernel32_handle = kernel32_imports; /* store dummy pointer to avoid trying again */ - pSetThreadDescription = NULL; - } - } - - if (pSetThreadDescription) { - size_t len = strlen(name) + 1; - wchar_t wname[len + 1]; - mbstowcs(wname, name, len); - pSetThreadDescription(thread ? (HANDLE) thread : GetCurrentThread(), wname); - } -} - -void -take_screenshot(void) -{ - startblit(); - monitors[0].mon_screenshots++; - endblit(); - device_force_redraw(); -} - -/* LPARAM interface to plat_get_string(). */ -LPARAM -win_get_string(int id) -{ - wchar_t *ret; - - ret = plat_get_string(id); - return ((LPARAM) ret); -} - -void /* plat_ */ -startblit(void) -{ - WaitForSingleObject(ghMutex, INFINITE); -} - -void /* plat_ */ -endblit(void) -{ - ReleaseMutex(ghMutex); -} - -double -plat_get_dpi(void) -{ - UINT dpi = win_get_dpi(hwndRender); - - return ((double) dpi) / 96.0; -} diff --git a/src/win/win_about.c b/src/win/win_about.c deleted file mode 100644 index 7ba55f73e..000000000 --- a/src/win/win_about.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Handle the About dialog. - * - * - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017-2018 Fred N. van Kempen. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP -#include -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/plat.h> -#include <86box/win.h> -#include <86box/version.h> - -void -AboutDialogCreate(HWND hwnd) -{ - int i; - TASKDIALOGCONFIG tdconfig = { 0 }; - TASKDIALOG_BUTTON tdbuttons[] = { - {IDOK, EMU_SITE_W }, - { IDCANCEL, MAKEINTRESOURCE(IDS_2128)} - }; - - wchar_t emu_version[256]; - i = swprintf(emu_version, sizeof_w(emu_version), L"%ls v%ls", EMU_NAME_W, EMU_VERSION_FULL_W); -#ifdef EMU_GIT_HASH - i += swprintf(&emu_version[i], sizeof_w(emu_version) - i, L" [%ls]", EMU_GIT_HASH_W); -#endif - -#if defined(__arm__) || defined(__TARGET_ARCH_ARM) -# define ARCH_STR L"arm" -#elif defined(__aarch64__) || defined(_M_ARM64) -# define ARCH_STR L"arm64" -#elif defined(__i386) || defined(__i386__) || defined(_M_IX86) -# define ARCH_STR L"i386" -#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) -# define ARCH_STR L"x86_64" -#else -# define ARCH_STR L"unknown" -#endif - swprintf(&emu_version[i], sizeof_w(emu_version) - i, L" [%ls, %ls]", ARCH_STR, plat_get_string(IDS_DYNAREC)); - - tdconfig.cbSize = sizeof(tdconfig); - tdconfig.hwndParent = hwnd; - tdconfig.hInstance = hinstance; - tdconfig.dwCommonButtons = 0; - tdconfig.pszWindowTitle = MAKEINTRESOURCE(IDS_2125); - tdconfig.pszMainIcon = (PCWSTR) 10; - tdconfig.pszMainInstruction = emu_version; - tdconfig.pszContent = MAKEINTRESOURCE(IDS_2127); - tdconfig.cButtons = ARRAYSIZE(tdbuttons); - tdconfig.pButtons = tdbuttons; - tdconfig.nDefaultButton = IDCANCEL; - TaskDialogIndirect(&tdconfig, &i, NULL, NULL); - - if (i == IDOK) - ShellExecute(hwnd, L"open", L"https://" EMU_SITE_W, NULL, NULL, SW_SHOW); -} diff --git a/src/win/win_cdrom.c b/src/win/win_cdrom.c deleted file mode 100644 index 58bd85c65..000000000 --- a/src/win/win_cdrom.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Handle the platform-side of CDROM/ZIP/MO drives. - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * Jasmine Iwanek, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017-2018 Fred N. van Kempen. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/config.h> -#include <86box/timer.h> -#include <86box/device.h> -#include <86box/cassette.h> -#include <86box/cartridge.h> -#include <86box/fdd.h> -#include <86box/hdd.h> -#include <86box/scsi_device.h> -#include <86box/cdrom.h> -#include <86box/mo.h> -#include <86box/zip.h> -#include <86box/scsi_disk.h> -#include <86box/plat.h> -#include <86box/ui.h> -#include <86box/win.h> - -void -cassette_mount(char *fn, uint8_t wp) -{ - pc_cas_set_fname(cassette, NULL); - memset(cassette_fname, 0, sizeof(cassette_fname)); - cassette_ui_writeprot = wp; - pc_cas_set_fname(cassette, fn); - if (fn != NULL) - memcpy(cassette_fname, fn, MIN(511, strlen(fn))); - ui_sb_update_icon_state(SB_CASSETTE, (fn == NULL) ? 1 : 0); - media_menu_update_cassette(); - ui_sb_update_tip(SB_CASSETTE); - config_save(); -} - -void -cassette_eject(void) -{ - pc_cas_set_fname(cassette, NULL); - memset(cassette_fname, 0x00, sizeof(cassette_fname)); - ui_sb_update_icon_state(SB_CASSETTE, 1); - media_menu_update_cassette(); - ui_sb_update_tip(SB_CASSETTE); - config_save(); -} - -void -cartridge_mount(uint8_t id, char *fn, UNUSED(uint8_t wp)) -{ - cart_close(id); - cart_load(id, fn); - ui_sb_update_icon_state(SB_CARTRIDGE | id, strlen(cart_fns[id]) ? 0 : 1); - media_menu_update_cartridge(id); - ui_sb_update_tip(SB_CARTRIDGE | id); - config_save(); -} - -void -cartridge_eject(uint8_t id) -{ - cart_close(id); - ui_sb_update_icon_state(SB_CARTRIDGE | id, 1); - media_menu_update_cartridge(id); - ui_sb_update_tip(SB_CARTRIDGE | id); - config_save(); -} - -void -floppy_mount(uint8_t id, char *fn, uint8_t wp) -{ - fdd_close(id); - ui_writeprot[id] = wp; - fdd_load(id, fn); - ui_sb_update_icon_state(SB_FLOPPY | id, strlen(floppyfns[id]) ? 0 : 1); - media_menu_update_floppy(id); - ui_sb_update_tip(SB_FLOPPY | id); - config_save(); -} - -void -floppy_eject(uint8_t id) -{ - fdd_close(id); - ui_sb_update_icon_state(SB_FLOPPY | id, 1); - media_menu_update_floppy(id); - ui_sb_update_tip(SB_FLOPPY | id); - config_save(); -} - -void -plat_cdrom_ui_update(uint8_t id, UNUSED(uint8_t reload)) -{ - const cdrom_t *drv = &cdrom[id]; - - if (drv->host_drive == 0) { - ui_sb_update_icon_state(SB_CDROM | id, 1); - } else { - ui_sb_update_icon_state(SB_CDROM | id, 0); - } - - media_menu_update_cdrom(id); - ui_sb_update_tip(SB_CDROM | id); -} - -void -cdrom_mount(uint8_t id, char *fn) -{ - cdrom[id].prev_host_drive = cdrom[id].host_drive; - strcpy(cdrom[id].prev_image_path, cdrom[id].image_path); - if (cdrom[id].ops && cdrom[id].ops->exit) - cdrom[id].ops->exit(&(cdrom[id])); - cdrom[id].ops = NULL; - memset(cdrom[id].image_path, 0, sizeof(cdrom[id].image_path)); - if ((fn != NULL) && (strlen(fn) >= 1) && (fn[strlen(fn) - 1] == '/')) - fn[strlen(fn) - 1] = '\\'; - cdrom_image_open(&(cdrom[id]), fn); - /* Signal media change to the emulated machine. */ - if (cdrom[id].insert) - cdrom[id].insert(cdrom[id].priv); - cdrom[id].host_drive = (strlen(cdrom[id].image_path) == 0) ? 0 : 200; - if (cdrom[id].host_drive == 200) { - ui_sb_update_icon_state(SB_CDROM | id, 0); - } else { - ui_sb_update_icon_state(SB_CDROM | id, 1); - } - media_menu_update_cdrom(id); - ui_sb_update_tip(SB_CDROM | id); - config_save(); -} - -void -mo_eject(uint8_t id) -{ - mo_t *dev = (mo_t *) mo_drives[id].priv; - - mo_disk_close(dev); - if (mo_drives[id].bus_type) { - /* Signal disk change to the emulated machine. */ - mo_insert(dev); - } - - ui_sb_update_icon_state(SB_MO | id, 1); - media_menu_update_mo(id); - ui_sb_update_tip(SB_MO | id); - config_save(); -} - -void -mo_mount(uint8_t id, char *fn, uint8_t wp) -{ - mo_t *dev = (mo_t *) mo_drives[id].priv; - - mo_disk_close(dev); - mo_drives[id].read_only = wp; - mo_load(dev, fn); - mo_insert(dev); - - ui_sb_update_icon_state(SB_MO | id, strlen(mo_drives[id].image_path) ? 0 : 1); - media_menu_update_mo(id); - ui_sb_update_tip(SB_MO | id); - - config_save(); -} - -void -mo_reload(uint8_t id) -{ - mo_t *dev = (mo_t *) mo_drives[id].priv; - - mo_disk_reload(dev); - if (strlen(mo_drives[id].image_path) == 0) { - ui_sb_update_icon_state(SB_MO | id, 1); - } else { - ui_sb_update_icon_state(SB_MO | id, 0); - } - - media_menu_update_mo(id); - ui_sb_update_tip(SB_MO | id); - - config_save(); -} - -void -zip_eject(uint8_t id) -{ - zip_t *dev = (zip_t *) zip_drives[id].priv; - - zip_disk_close(dev); - if (zip_drives[id].bus_type) { - /* Signal disk change to the emulated machine. */ - zip_insert(dev); - } - - ui_sb_update_icon_state(SB_ZIP | id, 1); - media_menu_update_zip(id); - ui_sb_update_tip(SB_ZIP | id); - config_save(); -} - -void -zip_mount(uint8_t id, char *fn, uint8_t wp) -{ - zip_t *dev = (zip_t *) zip_drives[id].priv; - - zip_disk_close(dev); - zip_drives[id].read_only = wp; - zip_load(dev, fn); - zip_insert(dev); - - ui_sb_update_icon_state(SB_ZIP | id, strlen(zip_drives[id].image_path) ? 0 : 1); - media_menu_update_zip(id); - ui_sb_update_tip(SB_ZIP | id); - - config_save(); -} - -void -zip_reload(uint8_t id) -{ - zip_t *dev = (zip_t *) zip_drives[id].priv; - - zip_disk_reload(dev); - if (strlen(zip_drives[id].image_path) == 0) { - ui_sb_update_icon_state(SB_ZIP | id, 1); - } else { - ui_sb_update_icon_state(SB_ZIP | id, 0); - } - - media_menu_update_zip(id); - ui_sb_update_tip(SB_ZIP | id); - - config_save(); -} diff --git a/src/win/win_devconf.c b/src/win/win_devconf.c deleted file mode 100644 index 92ab6b614..000000000 --- a/src/win/win_devconf.c +++ /dev/null @@ -1,832 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Windows device configuration dialog implementation. - * - * - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/ini.h> -#include <86box/config.h> -#include <86box/device.h> -#include <86box/plat.h> -#include <86box/mem.h> -#include <86box/rom.h> -#include <86box/midi_rtmidi.h> -#include <86box/ui.h> -#include <86box/win.h> -#include - -static device_context_t config_device; - -static uint8_t deviceconfig_changed = 0; -static int combo_to_struct[256]; - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - HWND h; - - int val_int; - int id; - int c; - int d; - int p; - int q; -#ifdef USE_RTMIDI - int num; -#endif - int changed; - int cid; - const device_config_t *config; - const device_config_selection_t *selection; - const device_config_bios_t *bios; - char s[512]; - char file_filter[512]; - const char *str; - const char *val_str; - wchar_t ws[512]; - wchar_t *wstr; - LPTSTR lptsTemp; - - config = config_device.dev->config; - - switch (message) { - case WM_INITDIALOG: - id = IDC_CONFIG_BASE; - config = config_device.dev->config; - - lptsTemp = (LPTSTR) malloc(512); - memset(combo_to_struct, 0, 256 * sizeof(int)); - - while (config->type != -1) { - selection = config->selection; - bios = config->bios; - h = GetDlgItem(hdlg, id); - - switch (config->type) { - case CONFIG_BINARY: - val_int = config_get_int((char *) config_device.name, - (char *) config->name, config->default_int); - - SendMessage(h, BM_SETCHECK, val_int, 0); - - id++; - break; - case CONFIG_SELECTION: - val_int = config_get_int((char *) config_device.name, - (char *) config->name, config->default_int); - - c = 0; - while (selection && selection->description && selection->description[0]) { - mbstowcs(lptsTemp, selection->description, - strlen(selection->description) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) lptsTemp); - if (val_int == selection->value) - SendMessage(h, CB_SETCURSEL, c, 0); - selection++; - c++; - } - - id += 2; - break; - case CONFIG_BIOS: - val_str = config_get_string((char *) config_device.name, - (char *) config->name, (char *) config->default_string); - - c = 0; - q = 0; - while (bios && (bios->files_no > 0)) { - mbstowcs(lptsTemp, bios->name, strlen(bios->name) + 1); - p = 0; - for (d = 0; d < bios->files_no; d++) - p += !!rom_present(bios->files[d]); - if (p == bios->files_no) { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) lptsTemp); - if (!strcmp(val_str, bios->internal_name)) - SendMessage(h, CB_SETCURSEL, c, 0); - combo_to_struct[c] = q; - c++; - } - q++; - bios++; - } - - id += 2; - break; -#ifdef USE_RTMIDI - case CONFIG_MIDI_OUT: - val_int = config_get_int((char *) config_device.name, - (char *) config->name, config->default_int); - - num = rtmidi_out_get_num_devs(); - for (c = 0; c < num; c++) { - rtmidi_out_get_dev_name(c, s); - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) lptsTemp); - if (val_int == c) - SendMessage(h, CB_SETCURSEL, c, 0); - } - - id += 2; - break; - case CONFIG_MIDI_IN: - val_int = config_get_int((char *) config_device.name, - (char *) config->name, config->default_int); - - num = rtmidi_in_get_num_devs(); - for (c = 0; c < num; c++) { - rtmidi_in_get_dev_name(c, s); - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) lptsTemp); - if (val_int == c) - SendMessage(h, CB_SETCURSEL, c, 0); - } - - id += 2; - break; -#endif - case CONFIG_SPINNER: - val_int = config_get_int((char *) config_device.name, - (char *) config->name, config->default_int); - - _swprintf(ws, L"%i", val_int); - SendMessage(h, WM_SETTEXT, 0, (LPARAM) ws); - - id += 2; - break; - case CONFIG_FNAME: - case CONFIG_STRING: - wstr = config_get_wstring((char *) config_device.name, - (char *) config->name, 0); - if (wstr) - SendMessage(h, WM_SETTEXT, 0, (LPARAM) wstr); - id += 3; - break; - case CONFIG_HEX16: - val_int = config_get_hex16((char *) config_device.name, - (char *) config->name, config->default_int); - - c = 0; - while (selection && selection->description && selection->description[0]) { - mbstowcs(lptsTemp, selection->description, - strlen(selection->description) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) lptsTemp); - if (val_int == selection->value) - SendMessage(h, CB_SETCURSEL, c, 0); - selection++; - c++; - } - - id += 2; - break; - case CONFIG_HEX20: - val_int = config_get_hex20((char *) config_device.name, - (char *) config->name, config->default_int); - - c = 0; - while (selection && selection->description && selection->description[0]) { - mbstowcs(lptsTemp, selection->description, - strlen(selection->description) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) lptsTemp); - if (val_int == selection->value) - SendMessage(h, CB_SETCURSEL, c, 0); - selection++; - c++; - } - - id += 2; - break; - } - config++; - } - free(lptsTemp); - return TRUE; - case WM_COMMAND: - cid = LOWORD(wParam); - if (cid == IDOK) { - id = IDC_CONFIG_BASE; - config = config_device.dev->config; - changed = 0; - char s[512]; - - while (config->type != -1) { - const device_config_selection_t *selection = config->selection; - h = GetDlgItem(hdlg, id); - - switch (config->type) { - case CONFIG_BINARY: - val_int = config_get_int((char *) config_device.name, - (char *) config->name, config->default_int); - - if (val_int != SendMessage(h, BM_GETCHECK, 0, 0)) - changed = 1; - - id++; - break; - case CONFIG_SELECTION: - val_int = config_get_int((char *) config_device.name, - (char *) config->name, config->default_int); - - c = SendMessage(h, CB_GETCURSEL, 0, 0); - - for (; c > 0; c--) - selection++; - - if (val_int != selection->value) - changed = 1; - - id += 2; - break; - case CONFIG_BIOS: - bios = config->bios; - - val_str = config_get_string((char *) config_device.name, - (char *) config->name, (char *) config->default_string); - - c = combo_to_struct[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - for (; c > 0; c--) - bios++; - - if (strcmp(val_str, bios->internal_name)) - changed = 1; - - id += 2; - break; - case CONFIG_MIDI_OUT: - val_int = config_get_int((char *) config_device.name, - (char *) config->name, config->default_int); - - c = SendMessage(h, CB_GETCURSEL, 0, 0); - - if (val_int != c) - changed = 1; - - id += 2; - break; - case CONFIG_MIDI_IN: - val_int = config_get_int((char *) config_device.name, - (char *) config->name, config->default_int); - - c = SendMessage(h, CB_GETCURSEL, 0, 0); - - if (val_int != c) - changed = 1; - - id += 2; - break; - case CONFIG_FNAME: - case CONFIG_STRING: - str = config_get_string((char *) config_device.name, - (char *) config->name, (char *) ""); - SendMessage(h, WM_GETTEXT, 511, (LPARAM) s); - if (strcmp(str, s)) - changed = 1; - - id += 3; - break; - case CONFIG_SPINNER: - val_int = config_get_int((char *) config_device.name, - (char *) config->name, config->default_int); - if (val_int > config->spinner.max) - val_int = config->spinner.max; - else if (val_int < config->spinner.min) - val_int = config->spinner.min; - - SendMessage(h, WM_GETTEXT, 79, (LPARAM) ws); - wcstombs(s, ws, 512); - sscanf(s, "%i", &c); - - if (val_int != c) - changed = 1; - - id += 2; - break; - case CONFIG_HEX16: - val_int = config_get_hex16((char *) config_device.name, - (char *) config->name, config->default_int); - - c = SendMessage(h, CB_GETCURSEL, 0, 0); - - for (; c > 0; c--) - selection++; - - if (val_int != selection->value) - changed = 1; - - id += 2; - break; - case CONFIG_HEX20: - val_int = config_get_hex20((char *) config_device.name, - (char *) config->name, config->default_int); - - c = SendMessage(h, CB_GETCURSEL, 0, 0); - - for (; c > 0; c--) - selection++; - - if (val_int != selection->value) - changed = 1; - - id += 2; - break; - } - config++; - } - - if (!changed) { - deviceconfig_changed = 0; - EndDialog(hdlg, 0); - return TRUE; - } - - deviceconfig_changed = 1; - - id = IDC_CONFIG_BASE; - config = config_device.dev->config; - - while (config->type != -1) { - selection = config->selection; - h = GetDlgItem(hdlg, id); - - switch (config->type) { - case CONFIG_BINARY: - config_set_int((char *) config_device.name, - (char *) config->name, SendMessage(h, BM_GETCHECK, 0, 0)); - - id++; - break; - case CONFIG_SELECTION: - c = SendMessage(h, CB_GETCURSEL, 0, 0); - for (; c > 0; c--) - selection++; - config_set_int((char *) config_device.name, (char *) config->name, selection->value); - - id += 2; - break; - case CONFIG_BIOS: - bios = config->bios; - c = combo_to_struct[SendMessage(h, CB_GETCURSEL, 0, 0)]; - for (; c > 0; c--) - bios++; - config_set_string((char *) config_device.name, (char *) config->name, (char *) bios->internal_name); - - id += 2; - break; - case CONFIG_MIDI_OUT: - c = SendMessage(h, CB_GETCURSEL, 0, 0); - config_set_int((char *) config_device.name, (char *) config->name, c); - - id += 2; - break; - case CONFIG_MIDI_IN: - c = SendMessage(h, CB_GETCURSEL, 0, 0); - config_set_int((char *) config_device.name, (char *) config->name, c); - - id += 2; - break; - case CONFIG_FNAME: - case CONFIG_STRING: - SendMessage(h, WM_GETTEXT, 511, (LPARAM) ws); - config_set_wstring((char *) config_device.name, (char *) config->name, ws); - - id += 3; - break; - case CONFIG_SPINNER: - SendMessage(h, WM_GETTEXT, 79, (LPARAM) ws); - wcstombs(s, ws, 512); - sscanf(s, "%i", &c); - if (c > config->spinner.max) - c = config->spinner.max; - else if (c < config->spinner.min) - c = config->spinner.min; - - config_set_int((char *) config_device.name, (char *) config->name, c); - - id += 2; - break; - case CONFIG_HEX16: - c = SendMessage(h, CB_GETCURSEL, 0, 0); - for (; c > 0; c--) - selection++; - config_set_hex16((char *) config_device.name, (char *) config->name, selection->value); - - id += 2; - break; - case CONFIG_HEX20: - c = SendMessage(h, CB_GETCURSEL, 0, 0); - for (; c > 0; c--) - selection++; - config_set_hex20((char *) config_device.name, (char *) config->name, selection->value); - - id += 2; - break; - } - config++; - } - - EndDialog(hdlg, 0); - return TRUE; - } else if (cid == IDCANCEL) { - deviceconfig_changed = 0; - EndDialog(hdlg, 0); - return TRUE; - } else { - id = IDC_CONFIG_BASE; - while (config->type != -1) { - switch (config->type) { - case CONFIG_BINARY: - id++; - break; - case CONFIG_SELECTION: - case CONFIG_HEX16: - case CONFIG_HEX20: - case CONFIG_BIOS: - case CONFIG_MIDI_OUT: - case CONFIG_MIDI_IN: - case CONFIG_SPINNER: - case CONFIG_STRING: - id += 2; - break; - case CONFIG_FNAME: - if (cid == id + 1) { - s[0] = 0; - h = GetDlgItem(hdlg, id); - SendMessage(h, WM_GETTEXT, 511, (LPARAM) s); - file_filter[0] = 0; - - strcat(file_filter, config->file_filter); - strcat(file_filter, "|All files (*.*)|*.*|"); - mbstowcs(ws, file_filter, strlen(file_filter) + 1); - d = strlen(file_filter); - - /* replace | with \0 */ - for (c = 0; c < d; ++c) { - if (ws[c] == L'|') - ws[c] = 0; - } - - if (!file_dlg(hdlg, ws, s, NULL, 0)) - SendMessage(h, WM_SETTEXT, 0, (LPARAM) wopenfilestring); - } - break; - } - config++; - } - } - break; - } - return FALSE; -} - -uint8_t -deviceconfig_inst_open(HWND hwnd, const device_t *device, int inst) -{ - const device_config_t *config = device->config; - uint16_t *data_block; - uint16_t *data; - DLGTEMPLATE *dlg; - DLGITEMTEMPLATE *item; - - data_block = malloc(16384); - dlg = (DLGTEMPLATE *) data_block; - int y = 10; - int id = IDC_CONFIG_BASE; - - deviceconfig_changed = 0; - - memset(data_block, 0, 16384); - - dlg->style = DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU; - dlg->x = 10; - dlg->y = 10; - dlg->cx = 220; - dlg->cy = 70; - - data = (uint16_t *) (dlg + 1); - - *data++ = 0; /*no menu*/ - *data++ = 0; /*predefined dialog box class*/ - - data += wsprintf(data, plat_get_string(IDS_2142), device->name) + 1; - - *data++ = 9; /*Point*/ - data += MultiByteToWideChar(CP_ACP, 0, "Segoe UI", -1, data, 120); - - if (((uintptr_t) data) & 2) - data++; - - while (config->type != -1) { - switch (config->type) { - case CONFIG_BINARY: - item = (DLGITEMTEMPLATE *) data; - item->x = 10; - item->y = y; - item->id = id++; - - item->cx = 100; - item->cy = 15; - - item->style = WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0080; /* button class */ - - data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); - *data++ = 0; /* no creation data */ - - y += 20; - break; - - case CONFIG_SELECTION: - case CONFIG_MIDI_OUT: - case CONFIG_MIDI_IN: - case CONFIG_HEX16: - case CONFIG_HEX20: - case CONFIG_BIOS: - /*Combo box*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 70; - item->y = y; - item->id = id++; - - item->cx = 140; - item->cy = 150; - - item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0085; /* combo box class */ - - data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - /*Static text*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 10; - item->y = y + 2; - item->id = id++; - - item->cx = 60; - item->cy = 20; - - item->style = WS_CHILD | WS_VISIBLE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0082; /* static class */ - - data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - y += 20; - break; - case CONFIG_SPINNER: - /*Spinner*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 70; - item->y = y; - item->id = id++; - - item->cx = 140; - item->cy = 14; - - item->style = WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_NUMBER; - item->dwExtendedStyle = WS_EX_CLIENTEDGE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0081; /* edit text class */ - - data += MultiByteToWideChar(CP_ACP, 0, "", -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - /* TODO: add up down class */ - /*Static text*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 10; - item->y = y + 2; - item->id = id++; - - item->cx = 60; - item->cy = 20; - - item->style = WS_CHILD | WS_VISIBLE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0082; /* static class */ - - data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - y += 20; - break; - case CONFIG_STRING: - /*Editable Text*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 70; - item->y = y; - item->id = id++; - - item->cx = 140; - item->cy = 14; - - item->style = WS_CHILD | WS_VISIBLE | ES_READONLY; - item->dwExtendedStyle = WS_EX_CLIENTEDGE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0081; /* edit text class */ - - data += MultiByteToWideChar(CP_ACP, 0, "", -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - /*Static text*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 10; - item->y = y + 2; - item->id = id++; - - item->cx = 60; - item->cy = 20; - - item->style = WS_CHILD | WS_VISIBLE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0082; /* static class */ - - data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - y += 20; - break; - case CONFIG_FNAME: - /*File*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 70; - item->y = y; - item->id = id++; - - item->cx = 100; - item->cy = 14; - - item->style = WS_CHILD | WS_VISIBLE | ES_READONLY; - item->dwExtendedStyle = WS_EX_CLIENTEDGE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0081; /* edit text class */ - - data += MultiByteToWideChar(CP_ACP, 0, "", -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - /* Button */ - item = (DLGITEMTEMPLATE *) data; - item->x = 175; - item->y = y; - item->id = id++; - - item->cx = 35; - item->cy = 14; - - item->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0080; /* button class */ - - data += MultiByteToWideChar(CP_ACP, 0, "Browse", -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - /*Static text*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 10; - item->y = y + 2; - item->id = id++; - - item->cx = 60; - item->cy = 20; - - item->style = WS_CHILD | WS_VISIBLE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0082; /* static class */ - - data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - y += 20; - break; - } - - if (((uintptr_t) data) & 2) - data++; - - config++; - } - - dlg->cdit = (id - IDC_CONFIG_BASE) + 2; - - item = (DLGITEMTEMPLATE *) data; - item->x = 100; - item->y = y + 5; - item->cx = 50; - item->cy = 14; - item->id = IDOK; /* OK button identifier */ - item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0080; /* button class */ - - data += MultiByteToWideChar(CP_ACP, 0, "OK", -1, data, 50); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - item = (DLGITEMTEMPLATE *) data; - item->x = 160; - item->y = y + 5; - item->cx = 50; - item->cy = 14; - item->id = IDCANCEL; /* OK button identifier */ - item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0080; /* button class */ - - data += MultiByteToWideChar(CP_ACP, 0, "Cancel", -1, data, 50); - *data++ = 0; /* no creation data */ - - dlg->cy = y + 25; - - device_set_context(&config_device, device, inst); - - DialogBoxIndirect(hinstance, dlg, hwnd, deviceconfig_dlgproc); - - free(data_block); - - return deviceconfig_changed; -} - -uint8_t -deviceconfig_open(HWND hwnd, const device_t *device) -{ - return deviceconfig_inst_open(hwnd, device, 0); -} diff --git a/src/win/win_dialog.c b/src/win/win_dialog.c deleted file mode 100644 index 15b00bf3f..000000000 --- a/src/win/win_dialog.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Several dialogs for the application. - * - * - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/plat.h> -#include <86box/ui.h> -#include <86box/win.h> - -#define STRING_OR_RESOURCE(s) ((!(s)) ? (NULL) : ((((uintptr_t) s) < ((uintptr_t) 65636)) ? (MAKEINTRESOURCE((uintptr_t) s)) : (s))) - -WCHAR wopenfilestring[512]; -char openfilestring[512]; -uint8_t filterindex = 0; - -int -ui_msgbox(int flags, void *message) -{ - return ui_msgbox_ex(flags, NULL, message, NULL, NULL, NULL); -} - -int -ui_msgbox_header(int flags, void *header, void *message) -{ - return ui_msgbox_ex(flags, header, message, NULL, NULL, NULL); -} - -int -ui_msgbox_ex(int flags, void *header, void *message, void *btn1, void *btn2, void *btn3) -{ - WCHAR temp[512]; - TASKDIALOGCONFIG tdconfig = { 0 }; - TASKDIALOG_BUTTON tdbuttons[3]; - TASKDIALOG_BUTTON tdb_yes = { IDYES, STRING_OR_RESOURCE(btn1) }; - TASKDIALOG_BUTTON tdb_no = { IDNO, STRING_OR_RESOURCE(btn2) }; - TASKDIALOG_BUTTON tdb_cancel = { IDCANCEL, STRING_OR_RESOURCE(btn3) }; - TASKDIALOG_BUTTON tdb_exit = { IDCLOSE, MAKEINTRESOURCE(IDS_2120) }; - int ret = 0; - int checked = 0; - - /* Configure the default OK button. */ - tdconfig.cButtons = 0; - if (btn1) - tdbuttons[tdconfig.cButtons++] = tdb_yes; - else - tdconfig.dwCommonButtons = TDCBF_OK_BUTTON; - - /* Configure the message type. */ - switch (flags & 0x1f) { - case MBX_INFO: /* just an informational message */ - tdconfig.pszMainIcon = TD_INFORMATION_ICON; - break; - - case MBX_ERROR: /* error message */ - if (flags & MBX_FATAL) { - tdconfig.pszMainIcon = TD_ERROR_ICON; - tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2050); /* "Fatal error" */ - - /* replace default "OK" button with "Exit" button */ - if (btn1) - tdconfig.cButtons = 0; - else - tdconfig.dwCommonButtons = 0; - tdbuttons[tdconfig.cButtons++] = tdb_exit; - } else { - tdconfig.pszMainIcon = TD_WARNING_ICON; - tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2049); /* "Error" */ - } - break; - - case MBX_QUESTION: /* question */ - case MBX_QUESTION_YN: - case MBX_QUESTION_OK: - if (!btn1) /* replace default "OK" button with "Yes" button */ - tdconfig.dwCommonButtons = (flags & MBX_QUESTION_OK) ? TDCBF_OK_BUTTON : TDCBF_YES_BUTTON; - - if (btn2) /* "No" button */ - tdbuttons[tdconfig.cButtons++] = tdb_no; - else - tdconfig.dwCommonButtons |= (flags & MBX_QUESTION_OK) ? TDCBF_CANCEL_BUTTON : TDCBF_NO_BUTTON; - - if (flags & MBX_QUESTION) { - if (btn3) /* "Cancel" button */ - tdbuttons[tdconfig.cButtons++] = tdb_cancel; - else - tdconfig.dwCommonButtons |= TDCBF_CANCEL_BUTTON; - } - - if (flags & MBX_WARNING) - tdconfig.pszMainIcon = TD_WARNING_ICON; - break; - } - - /* If the message is an ANSI string, convert it. */ - tdconfig.pszContent = (WCHAR *) STRING_OR_RESOURCE(message); - if (flags & MBX_ANSI) { - mbstoc16s(temp, (char *) message, strlen((char *) message) + 1); - tdconfig.pszContent = temp; - } - - /* Configure the rest of the TaskDialog. */ - tdconfig.cbSize = sizeof(tdconfig); - tdconfig.hwndParent = hwndMain; - if (flags & MBX_LINKS) - tdconfig.dwFlags = TDF_USE_COMMAND_LINKS; - tdconfig.pszWindowTitle = MAKEINTRESOURCE(IDS_STRINGS); - if (header) - tdconfig.pszMainInstruction = STRING_OR_RESOURCE(header); - tdconfig.pButtons = tdbuttons; - if (flags & MBX_DONTASK) - tdconfig.pszVerificationText = MAKEINTRESOURCE(IDS_2136); - - /* Run the TaskDialog. */ - TaskDialogIndirect(&tdconfig, &ret, NULL, &checked); - - /* Convert return values to generic ones. */ - if (ret == IDNO) - ret = 1; - else if (ret == IDCANCEL) - ret = -1; - else - ret = 0; - - /* 10 is added to the return value if "don't show again" is checked. */ - if (checked) - ret += 10; - - return ret; -} - -int -file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, WCHAR *title, int save) -{ - OPENFILENAME ofn; - BOOL r; -#if 0 - DWORD err; -#endif - int old_dopause; - - /* Initialize OPENFILENAME */ - ZeroMemory(&ofn, sizeof(ofn)); - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = hwnd; - ofn.lpstrFile = wopenfilestring; - - /* - * Set lpstrFile[0] to '\0' so that GetOpenFileName does - * not use the contents of szFile to initialize itself. - */ - memset(ofn.lpstrFile, 0x00, 512 * sizeof(WCHAR)); - if (fn) - memcpy(ofn.lpstrFile, fn, (wcslen(fn) << 1) + 2); - ofn.nMaxFile = sizeof_w(wopenfilestring); - ofn.lpstrFilter = f; - ofn.nFilterIndex = 1; - ofn.lpstrFileTitle = NULL; - ofn.nMaxFileTitle = 0; - ofn.lpstrInitialDir = NULL; - ofn.Flags = OFN_PATHMUSTEXIST; - if (!save) - ofn.Flags |= OFN_FILEMUSTEXIST; - if (title) - ofn.lpstrTitle = title; - - /* Display the Open dialog box. */ - old_dopause = dopause; - plat_pause(1); - if (save) - r = GetSaveFileName(&ofn); - else - r = GetOpenFileName(&ofn); - plat_pause(old_dopause); - - plat_chdir(usr_path); - - if (r) { - c16stombs(openfilestring, wopenfilestring, sizeof(openfilestring)); - filterindex = ofn.nFilterIndex; - - return 0; - } - - return 1; -} - -int -file_dlg(HWND hwnd, WCHAR *f, char *fn, char *title, int save) -{ - WCHAR ufn[512]; - WCHAR title_buf[512]; - - if (fn) - mbstoc16s(ufn, fn, strlen(fn) + 1); - if (title) - mbstoc16s(title_buf, title, sizeof title_buf); - - return (file_dlg_w(hwnd, f, fn ? ufn : NULL, title ? title_buf : NULL, save)); -} - -int -file_dlg_mb(HWND hwnd, char *f, char *fn, char *title, int save) -{ - WCHAR uf[512]; - WCHAR ufn[512]; - WCHAR title_buf[512]; - - mbstoc16s(uf, f, strlen(f) + 1); - mbstoc16s(ufn, fn, strlen(fn) + 1); - if (title) - mbstoc16s(title_buf, title, sizeof title_buf); - - return (file_dlg_w(hwnd, uf, ufn, title ? title_buf : NULL, save)); -} - -int -file_dlg_w_st(HWND hwnd, int id, WCHAR *fn, char *title, int save) -{ - WCHAR title_buf[512]; - if (title) - mbstoc16s(title_buf, title, sizeof title_buf); - return (file_dlg_w(hwnd, plat_get_string(id), fn, title ? title_buf : NULL, save)); -} - -int -file_dlg_st(HWND hwnd, int id, char *fn, char *title, int save) -{ - return (file_dlg(hwnd, plat_get_string(id), fn, title, save)); -} diff --git a/src/win/win_dynld.c b/src/win/win_dynld.c deleted file mode 100644 index 24690f2ba..000000000 --- a/src/win/win_dynld.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Try to load a support DLL. - * - * - * - * Authors: Fred N. van Kempen, - * - * Copyright 2017-2018 Fred N. van Kempen - * Copyright 2021-2023 Jasmine Iwanek. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/plat_dynld.h> - -#ifdef ENABLE_DYNLD_LOG -int dynld_do_log = ENABLE_DYNLD_LOG; - -static void -dynld_log(const char *fmt, ...) -{ - va_list ap; - - if (dynld_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define dynld_log(fmt, ...) -#endif - -void * -dynld_module(const char *name, dllimp_t *table) -{ - HMODULE h; - void *func; - - /* See if we can load the desired module. */ - if ((h = LoadLibrary(name)) == NULL) { - dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError()); - return (NULL); - } - - /* Now load the desired function pointers. */ - for (dllimp_t *imp = table; imp->name != NULL; imp++) { - func = GetProcAddress(h, imp->name); - if (func == NULL) { - dynld_log("DynLd(\"%s\"): function '%s' not found! (%08X)\n", - name, imp->name, GetLastError()); - FreeLibrary(h); - return (NULL); - } - - /* To overcome typing issues.. */ - *(char **) imp->func = (char *) func; - } - - /* All good. */ - dynld_log("loaded %s\n", name); - return ((void *) h); -} - -void -dynld_close(void *handle) -{ - if (handle != NULL) - FreeLibrary((HMODULE) handle); -} diff --git a/src/win/win_icon.c b/src/win/win_icon.c deleted file mode 100644 index f3426b8b5..000000000 --- a/src/win/win_icon.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implement the application's icon changing system. - * - * - * - * Authors: Laci bá' - * - * Copyright 2021 Laci bá'. - * Copyright 2021-2023 Jasmine Iwanek. - */ - -#include -#include -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/config.h> -#include <86box/path.h> -#include <86box/plat.h> -#include <86box/ui.h> -#include <86box/win.h> - -HICON hIcon[256]; /* icon data loaded from resources */ -char icon_set[256] = ""; /* name of the iconset to be used */ - -void -win_clear_icon_set(void) -{ - for (uint16_t i = 0; i < 256; i++) - if (hIcon[i] != 0) { - DestroyIcon(hIcon[i]); - hIcon[i] = 0; - } -} - -void -win_system_icon_set(void) -{ - int x = win_get_system_metrics(SM_CXSMICON, dpi); - int y = win_get_system_metrics(SM_CYSMICON, dpi); - - for (uint16_t i = 0; i < 256; i++) - hIcon[i] = LoadImage(hinstance, MAKEINTRESOURCE(i), IMAGE_ICON, x, y, LR_DEFAULTCOLOR); -} - -typedef struct -{ - int id; - char *filename; -} _ICON_DATA; - -const _ICON_DATA icon_files[] = { - {16, "floppy_525.ico" }, - { 17, "floppy_525_active.ico" }, - { 24, "floppy_35.ico" }, - { 25, "floppy_35_active.ico" }, - { 32, "cdrom.ico" }, - { 33, "cdrom_active.ico" }, - { 48, "zip.ico" }, - { 49, "zip_active.ico" }, - { 56, "mo.ico" }, - { 57, "mo_active.ico" }, - { 64, "cassette.ico" }, - { 65, "cassette_active.ico" }, - { 80, "hard_disk.ico" }, - { 81, "hard_disk_active.ico" }, - { 96, "network.ico" }, - { 97, "network_active.ico" }, - { 104, "cartridge.ico" }, - { 144, "floppy_525_empty.ico" }, - { 145, "floppy_525_empty_active.ico"}, - { 152, "floppy_35_empty.ico" }, - { 153, "floppy_35_empty_active.ico" }, - { 160, "cdrom_empty.ico" }, - { 161, "cdrom_empty_active.ico" }, - { 176, "zip_empty.ico" }, - { 177, "zip_empty_active.ico" }, - { 184, "mo_empty.ico" }, - { 185, "mo_empty_active.ico" }, - { 192, "cassette_empty.ico" }, - { 193, "cassette_empty_active.ico" }, - { 200, "run.ico" }, - { 201, "pause.ico" }, - { 202, "send_cad.ico" }, - { 203, "send_cae.ico" }, - { 204, "hard_reset.ico" }, - { 205, "acpi_shutdown.ico" }, - { 206, "settings.ico" }, - { 232, "cartridge_empty.ico" }, - { 240, "machine.ico" }, - { 241, "display.ico" }, - { 242, "input_devices.ico" }, - { 243, "sound.ico" }, - { 244, "ports.ico" }, - { 245, "other_peripherals.ico" }, - { 246, "floppy_and_cdrom_drives.ico"}, - { 247, "other_removable_devices.ico"}, - { 248, "floppy_disabled.ico" }, - { 249, "cdrom_disabled.ico" }, - { 250, "zip_disabled.ico" }, - { 251, "mo_disabled.ico" }, - { 252, "storage_controllers.ico" } -}; - -void -win_get_icons_path(char *path_root) -{ - char roms_root[1024] = { 0 }; - if (rom_path[0]) - strcpy(roms_root, rom_path); - else - path_append_filename(roms_root, exe_path, "roms"); - - path_append_filename(path_root, roms_root, "icons"); - path_slash(path_root); -} - -void -win_load_icon_set(void) -{ - win_clear_icon_set(); - win_system_icon_set(); - - if (strlen(icon_set) == 0) { - ToolBarLoadIcons(); - return; - } - - char path_root[2048] = { 0 }; - char temp[2048] = { 0 }; - wchar_t wtemp[2048] = { 0 }; - - win_get_icons_path(path_root); - strcat(path_root, icon_set); - path_slash(path_root); - - int count = sizeof(icon_files) / sizeof(_ICON_DATA); - int x = win_get_system_metrics(SM_CXSMICON, dpi); - int y = win_get_system_metrics(SM_CYSMICON, dpi); - for (int i = 0; i < count; i++) { - path_append_filename(temp, path_root, icon_files[i].filename); - mbstoc16s(wtemp, temp, strlen(temp) + 1); - - HICON ictemp; - ictemp = LoadImageW(NULL, (LPWSTR) wtemp, IMAGE_ICON, x, y, LR_LOADFROMFILE | LR_DEFAULTCOLOR); - if (ictemp) { - if (hIcon[icon_files[i].id]) - DestroyIcon(hIcon[icon_files[i].id]); - hIcon[icon_files[i].id] = ictemp; - } - } - - uint32_t curr_lang = lang_id; - lang_id = 0; - set_language(curr_lang); - - ToolBarLoadIcons(); -} diff --git a/src/win/win_joystick.cpp b/src/win/win_joystick.cpp deleted file mode 100644 index 9b264a700..000000000 --- a/src/win/win_joystick.cpp +++ /dev/null @@ -1,321 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Joystick interface to host device. - * - * - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define DIRECTINPUT_VERSION 0x0800 -#include -#define _USE_MATH_DEFINES -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/plat.h> -#include <86box/gameport.h> -#include <86box/win.h> - -#define DIDEVTYPE_JOYSTICK 4 - -plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; -joystick_t joystick_state[MAX_JOYSTICKS]; -int joysticks_present = 0; -int has_slider = 0; - -static LPDIRECTINPUT8 lpdi; -static LPDIRECTINPUTDEVICE8 lpdi_joystick[2] = { NULL, NULL }; -static GUID joystick_guids[MAX_JOYSTICKS]; - -#ifdef ENABLE_JOYSTICK_LOG -int joystick_do_log = ENABLE_JOYSTICK_LOG; - -static void -joystick_log(const char *fmt, ...) -{ - va_list ap; - - if (joystick_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define joystick_log(fmt, ...) -#endif - -static BOOL CALLBACK -joystick_enum_callback(LPCDIDEVICEINSTANCE lpddi, UNUSED(LPVOID data)) -{ - if (joysticks_present >= MAX_JOYSTICKS) - return DIENUM_STOP; - - joystick_log("joystick_enum_callback : found joystick %i : %s\n", joysticks_present, lpddi->tszProductName); - - joystick_guids[joysticks_present++] = lpddi->guidInstance; - - if (joysticks_present >= MAX_JOYSTICKS) - return DIENUM_STOP; - - return DIENUM_CONTINUE; -} - -BOOL CALLBACK -DIEnumDeviceObjectsCallback( - LPCDIDEVICEOBJECTINSTANCE lpddoi, - LPVOID pvRef) -{ - plat_joystick_t *state = (plat_joystick_t *) pvRef; - - if (lpddoi->guidType == GUID_XAxis || lpddoi->guidType == GUID_YAxis || lpddoi->guidType == GUID_ZAxis || lpddoi->guidType == GUID_RxAxis || lpddoi->guidType == GUID_RyAxis || lpddoi->guidType == GUID_RzAxis) { - if (state->nr_axes < MAX_JOY_AXES) { - memcpy(state->axis[state->nr_axes].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1); - joystick_log("Axis %i : %s %x %x\n", state->nr_axes, state->axis[state->nr_axes].name, lpddoi->dwOfs, lpddoi->dwType); - if (lpddoi->guidType == GUID_XAxis) - state->axis[state->nr_axes].id = 0; - else if (lpddoi->guidType == GUID_YAxis) - state->axis[state->nr_axes].id = 1; - else if (lpddoi->guidType == GUID_ZAxis) - state->axis[state->nr_axes].id = 2; - else if (lpddoi->guidType == GUID_RxAxis) - state->axis[state->nr_axes].id = 3; - else if (lpddoi->guidType == GUID_RyAxis) - state->axis[state->nr_axes].id = 4; - else if (lpddoi->guidType == GUID_RzAxis) - state->axis[state->nr_axes].id = 5; - else if (lpddoi->guidType == GUID_Slider) { - state->axis[state->nr_axes].id = 6 + has_slider; - has_slider++; - } - state->nr_axes++; - } - } else if (lpddoi->guidType == GUID_Button) { - if (state->nr_buttons < MAX_JOY_BUTTONS) { - memcpy(state->button[state->nr_buttons].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1); - joystick_log("Button %i : %s %x %x\n", state->nr_buttons, state->button[state->nr_buttons].name, lpddoi->dwOfs, lpddoi->dwType); - state->nr_buttons++; - } - } else if (lpddoi->guidType == GUID_POV) { - if (state->nr_povs < MAX_JOY_POVS) { - memcpy(state->pov[state->nr_povs].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1); - joystick_log("POV %i : %s %x %x\n", state->nr_povs, state->pov[state->nr_povs].name, lpddoi->dwOfs, lpddoi->dwType); - state->nr_povs++; - } - } - - return DIENUM_CONTINUE; -} - -void -joystick_init() -{ - int c; - - atexit(joystick_close); - - joysticks_present = 0; - - if (FAILED(DirectInput8Create(hinstance, DIRECTINPUT_VERSION, IID_IDirectInput8A, (void **) &lpdi, NULL))) - fatal("joystick_init : DirectInputCreate failed\n"); - - if (FAILED(lpdi->EnumDevices(DIDEVTYPE_JOYSTICK, joystick_enum_callback, NULL, DIEDFL_ATTACHEDONLY))) - fatal("joystick_init : EnumDevices failed\n"); - - joystick_log("joystick_init: joysticks_present=%i\n", joysticks_present); - - for (c = 0; c < joysticks_present; c++) { - LPDIRECTINPUTDEVICE8 lpdi_joystick_temp = NULL; - DIPROPRANGE joy_axis_range; - DIDEVICEINSTANCE device_instance; - DIDEVCAPS devcaps; - - if (FAILED(lpdi->CreateDevice(joystick_guids[c], &lpdi_joystick_temp, NULL))) - fatal("joystick_init : CreateDevice failed\n"); - if (FAILED(lpdi_joystick_temp->QueryInterface(IID_IDirectInputDevice8, (void **) &lpdi_joystick[c]))) - fatal("joystick_init : CreateDevice failed\n"); - lpdi_joystick_temp->Release(); - - memset(&device_instance, 0, sizeof(device_instance)); - device_instance.dwSize = sizeof(device_instance); - if (FAILED(lpdi_joystick[c]->GetDeviceInfo(&device_instance))) - fatal("joystick_init : GetDeviceInfo failed\n"); - joystick_log("Joystick %i :\n", c); - joystick_log(" tszInstanceName = %s\n", device_instance.tszInstanceName); - joystick_log(" tszProductName = %s\n", device_instance.tszProductName); - memcpy(plat_joystick_state[c].name, device_instance.tszInstanceName, strlen(device_instance.tszInstanceName) + 1); - - memset(&devcaps, 0, sizeof(devcaps)); - devcaps.dwSize = sizeof(devcaps); - if (FAILED(lpdi_joystick[c]->GetCapabilities(&devcaps))) - fatal("joystick_init : GetCapabilities failed\n"); - joystick_log(" Axes = %i\n", devcaps.dwAxes); - joystick_log(" Buttons = %i\n", devcaps.dwButtons); - joystick_log(" POVs = %i\n", devcaps.dwPOVs); - - has_slider = 0; - lpdi_joystick[c]->EnumObjects(DIEnumDeviceObjectsCallback, &plat_joystick_state[c], DIDFT_ALL); - - if (FAILED(lpdi_joystick[c]->SetCooperativeLevel(hwndMain, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) - fatal("joystick_init : SetCooperativeLevel failed\n"); - if (FAILED(lpdi_joystick[c]->SetDataFormat(&c_dfDIJoystick))) - fatal("joystick_init : SetDataFormat failed\n"); - - joy_axis_range.lMin = -32768; - joy_axis_range.lMax = 32767; - joy_axis_range.diph.dwSize = sizeof(DIPROPRANGE); - joy_axis_range.diph.dwHeaderSize = sizeof(DIPROPHEADER); - joy_axis_range.diph.dwHow = DIPH_BYOFFSET; - joy_axis_range.diph.dwObj = DIJOFS_X; - lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); - joy_axis_range.diph.dwObj = DIJOFS_Y; - lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); - joy_axis_range.diph.dwObj = DIJOFS_Z; - lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); - joy_axis_range.diph.dwObj = DIJOFS_RX; - lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); - joy_axis_range.diph.dwObj = DIJOFS_RY; - lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); - joy_axis_range.diph.dwObj = DIJOFS_RZ; - lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); - joy_axis_range.diph.dwObj = DIJOFS_SLIDER(0); - lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); - joy_axis_range.diph.dwObj = DIJOFS_SLIDER(1); - lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); - - if (FAILED(lpdi_joystick[c]->Acquire())) - fatal("joystick_init : Acquire failed\n"); - } -} - -void -joystick_close() -{ - if (lpdi_joystick[1]) { - lpdi_joystick[1]->Release(); - lpdi_joystick[1] = NULL; - } - if (lpdi_joystick[0]) { - lpdi_joystick[0]->Release(); - lpdi_joystick[0] = NULL; - } -} - -static int -joystick_get_axis(int joystick_nr, int mapping) -{ - if (mapping & POV_X) { - int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; - - if (LOWORD(pov) == 0xFFFF) - return 0; - else - return sin((2 * M_PI * (double) pov) / 36000.0) * 32767; - } else if (mapping & POV_Y) { - int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; - - if (LOWORD(pov) == 0xFFFF) - return 0; - else - return -cos((2 * M_PI * (double) pov) / 36000.0) * 32767; - } else - return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; -} - -void -joystick_process(void) -{ - int c; - int d; - - if (!joystick_type) - return; - - for (c = 0; c < joysticks_present; c++) { - DIJOYSTATE joystate; - int b; - - if (FAILED(lpdi_joystick[c]->Poll())) { - lpdi_joystick[c]->Acquire(); - lpdi_joystick[c]->Poll(); - } - if (FAILED(lpdi_joystick[c]->GetDeviceState(sizeof(DIJOYSTATE), (LPVOID) &joystate))) { - lpdi_joystick[c]->Acquire(); - lpdi_joystick[c]->Poll(); - lpdi_joystick[c]->GetDeviceState(sizeof(DIJOYSTATE), (LPVOID) &joystate); - } - - plat_joystick_state[c].a[0] = joystate.lX; - plat_joystick_state[c].a[1] = joystate.lY; - plat_joystick_state[c].a[2] = joystate.lZ; - plat_joystick_state[c].a[3] = joystate.lRx; - plat_joystick_state[c].a[4] = joystate.lRy; - plat_joystick_state[c].a[5] = joystate.lRz; - plat_joystick_state[c].a[6] = joystate.rglSlider[0]; - plat_joystick_state[c].a[7] = joystate.rglSlider[1]; - - for (b = 0; b < MAX_JOY_BUTTONS; b++) - plat_joystick_state[c].b[b] = joystate.rgbButtons[b] & 0x80; - - for (b = 0; b < MAX_JOY_POVS; b++) - plat_joystick_state[c].p[b] = joystate.rgdwPOV[b]; - // joystick_log("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", c, joystick_state[c].x, joystick_state[c].y, joystick_state[c].b[0], joystick_state[c].b[1], joysticks_present); - } - - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { - if (joystick_state[c].plat_joystick_nr) { - int joystick_nr = joystick_state[c].plat_joystick_nr - 1; - - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]); - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]]; - - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { - int x; - int y; - double angle; - double magnitude; - - x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]); - y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]); - - angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI); - magnitude = sqrt((double) x * (double) x + (double) y * (double) y); - - if (magnitude < 16384) - joystick_state[c].pov[d] = -1; - else - joystick_state[c].pov[d] = ((int) angle + 90 + 360) % 360; - } - } else { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = 0; - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = 0; - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - joystick_state[c].pov[d] = -1; - } - } -} - -void -win_joystick_handle(UNUSED(PRAWINPUT raw)) -{ - // Nothing to be done here, atleast currently -} diff --git a/src/win/win_joystick_rawinput.c b/src/win/win_joystick_rawinput.c deleted file mode 100644 index bb05c3f5c..000000000 --- a/src/win/win_joystick_rawinput.c +++ /dev/null @@ -1,551 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * RawInput joystick interface. - * - * - * - * Authors: Miran Grca, - * GH Cao, - * Jasmine Iwanek, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2020 GH Cao. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#include -#include -#include -#include -#include -#define _USE_MATH_DEFINES -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/plat.h> -#include <86box/gameport.h> -#include <86box/win.h> - -/* These are defined in hidusage.h in the Windows SDK, but not in mingw-w64. */ -#ifndef HID_USAGE_SIMULATION_AILERON -# define HID_USAGE_SIMULATION_AILERON ((USAGE) 0xb0) -#endif -#ifndef HID_USAGE_SIMULATION_ELEVATOR -# define HID_USAGE_SIMULATION_ELEVATOR ((USAGE) 0xb8) -#endif -#ifndef HID_USAGE_SIMULATION_ACCELLERATOR -# define HID_USAGE_SIMULATION_ACCELLERATOR ((USAGE) 0xc4) -#endif -#ifndef HID_USAGE_SIMULATION_BRAKE -# define HID_USAGE_SIMULATION_BRAKE ((USAGE) 0xc5) -#endif -#ifndef HID_USAGE_SIMULATION_CLUTCH -# define HID_USAGE_SIMULATION_CLUTCH ((USAGE) 0xc6) -#endif -#ifndef HID_USAGE_SIMULATION_SHIFTER -# define HID_USAGE_SIMULATION_SHIFTER ((USAGE) 0xc7) -#endif -#ifndef HID_USAGE_SIMULATION_STEERING -# define HID_USAGE_SIMULATION_STEERING ((USAGE) 0xc8) -#endif - -#ifdef ENABLE_JOYSTICK_LOG -int joystick_do_log = ENABLE_JOYSTICK_LOG; - -static void -joystick_log(const char *fmt, ...) -{ - va_list ap; - - if (joystick_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define joystick_log(fmt, ...) -#endif - -typedef struct { - HANDLE hdevice; - PHIDP_PREPARSED_DATA data; - - USAGE usage_button[256]; - - struct raw_axis_t { - USAGE usage; - USHORT link; - USHORT bitsize; - LONG max; - LONG min; - } axis[MAX_JOY_AXES]; - - struct raw_pov_t { - USAGE usage; - USHORT link; - LONG max; - LONG min; - } pov[MAX_JOY_POVS]; -} raw_joystick_t; - -plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; -joystick_t joystick_state[MAX_JOYSTICKS]; -int joysticks_present = 0; - -raw_joystick_t raw_joystick_state[MAX_PLAT_JOYSTICKS]; - -/* We only use the first 32 buttons reported, from Usage ID 1-128 */ -void -joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage) -{ - if (joy->nr_buttons >= MAX_JOY_BUTTONS) - return; - if (usage < 1 || usage > 128) - return; - - rawjoy->usage_button[usage] = joy->nr_buttons; - sprintf(joy->button[joy->nr_buttons].name, "Button %d", usage); - joy->nr_buttons++; -} - -void -joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop) -{ - if (joy->nr_axes >= MAX_JOY_AXES) - return; - - switch (prop->Range.UsageMin) { - case HID_USAGE_GENERIC_X: - sprintf(joy->axis[joy->nr_axes].name, "X"); - break; - case HID_USAGE_GENERIC_Y: - sprintf(joy->axis[joy->nr_axes].name, "Y"); - break; - case HID_USAGE_GENERIC_Z: - sprintf(joy->axis[joy->nr_axes].name, "Z"); - break; - case HID_USAGE_GENERIC_RX: - sprintf(joy->axis[joy->nr_axes].name, "RX"); - break; - case HID_USAGE_GENERIC_RY: - sprintf(joy->axis[joy->nr_axes].name, "RY"); - break; - case HID_USAGE_GENERIC_RZ: - sprintf(joy->axis[joy->nr_axes].name, "RZ"); - break; - case HID_USAGE_GENERIC_SLIDER: - sprintf(joy->axis[joy->nr_axes].name, "Slider"); - break; - case HID_USAGE_GENERIC_DIAL: - sprintf(joy->axis[joy->nr_axes].name, "Dial"); - break; - case HID_USAGE_GENERIC_WHEEL: - sprintf(joy->axis[joy->nr_axes].name, "Wheel"); - break; - case HID_USAGE_SIMULATION_AILERON: - sprintf(joy->axis[joy->nr_axes].name, "Aileron"); - break; - case HID_USAGE_SIMULATION_ELEVATOR: - sprintf(joy->axis[joy->nr_axes].name, "Elevator"); - break; - case HID_USAGE_SIMULATION_RUDDER: - sprintf(joy->axis[joy->nr_axes].name, "Rudder"); - break; - case HID_USAGE_SIMULATION_THROTTLE: - sprintf(joy->axis[joy->nr_axes].name, "Throttle"); - break; - case HID_USAGE_SIMULATION_ACCELLERATOR: - sprintf(joy->axis[joy->nr_axes].name, "Accelerator"); - break; - case HID_USAGE_SIMULATION_BRAKE: - sprintf(joy->axis[joy->nr_axes].name, "Brake"); - break; - case HID_USAGE_SIMULATION_CLUTCH: - sprintf(joy->axis[joy->nr_axes].name, "Clutch"); - break; - case HID_USAGE_SIMULATION_SHIFTER: - sprintf(joy->axis[joy->nr_axes].name, "Shifter"); - break; - case HID_USAGE_SIMULATION_STEERING: - sprintf(joy->axis[joy->nr_axes].name, "Steering"); - break; - default: - return; - } - - joy->axis[joy->nr_axes].id = joy->nr_axes; - rawjoy->axis[joy->nr_axes].usage = prop->Range.UsageMin; - rawjoy->axis[joy->nr_axes].link = prop->LinkCollection; - rawjoy->axis[joy->nr_axes].bitsize = prop->BitSize; - - /* Assume unsigned when min >= 0 */ - if (prop->LogicalMin < 0) { - rawjoy->axis[joy->nr_axes].max = prop->LogicalMax; - } else { - /* - * Some joysticks will send -1 in LogicalMax, like Xbox Controllers - * so we need to mask that to appropriate value (instead of 0xFFFFFFFF) - */ - rawjoy->axis[joy->nr_axes].max = prop->LogicalMax & ((1ULL << prop->BitSize) - 1); - } - rawjoy->axis[joy->nr_axes].min = prop->LogicalMin; - - joy->nr_axes++; -} - -void -joystick_add_pov(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop) -{ - if (joy->nr_povs >= MAX_JOY_POVS) - return; - - sprintf(joy->pov[joy->nr_povs].name, "POV %d", joy->nr_povs + 1); - rawjoy->pov[joy->nr_povs].usage = prop->Range.UsageMin; - rawjoy->pov[joy->nr_povs].link = prop->LinkCollection; - rawjoy->pov[joy->nr_povs].min = prop->LogicalMin; - rawjoy->pov[joy->nr_povs].max = prop->LogicalMax; - - joy->nr_povs++; -} - -void -joystick_get_capabilities(raw_joystick_t *rawjoy, plat_joystick_t *joy) -{ - UINT size = 0; - PHIDP_BUTTON_CAPS btn_caps = NULL; - PHIDP_VALUE_CAPS val_caps = NULL; - - /* Get preparsed data (HID data format) */ - GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_PREPARSEDDATA, NULL, &size); - rawjoy->data = malloc(size); - if (GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_PREPARSEDDATA, rawjoy->data, &size) <= 0) - fatal("joystick_get_capabilities: Failed to get preparsed data.\n"); - - HIDP_CAPS caps; - HidP_GetCaps(rawjoy->data, &caps); - - /* Buttons */ - if (caps.NumberInputButtonCaps > 0) { - btn_caps = calloc(caps.NumberInputButtonCaps, sizeof(HIDP_BUTTON_CAPS)); - if (HidP_GetButtonCaps(HidP_Input, btn_caps, &caps.NumberInputButtonCaps, rawjoy->data) != HIDP_STATUS_SUCCESS) { - joystick_log("joystick_get_capabilities: Failed to query input buttons.\n"); - goto end; - } - /* We only detect generic stuff */ - for (int c = 0; c < caps.NumberInputButtonCaps; c++) { - if (btn_caps[c].UsagePage != HID_USAGE_PAGE_BUTTON) - continue; - - int button_count = btn_caps[c].Range.UsageMax - btn_caps[c].Range.UsageMin + 1; - for (int b = 0; b < button_count; b++) { - joystick_add_button(rawjoy, joy, b + btn_caps[c].Range.UsageMin); - } - } - } - - /* Values (axes and povs) */ - if (caps.NumberInputValueCaps > 0) { - val_caps = calloc(caps.NumberInputValueCaps, sizeof(HIDP_VALUE_CAPS)); - if (HidP_GetValueCaps(HidP_Input, val_caps, &caps.NumberInputValueCaps, rawjoy->data) != HIDP_STATUS_SUCCESS) { - joystick_log("joystick_get_capabilities: Failed to query axes and povs.\n"); - goto end; - } - /* We only detect generic stuff */ - for (int c = 0; c < caps.NumberInputValueCaps; c++) { - if (val_caps[c].UsagePage != HID_USAGE_PAGE_GENERIC) - continue; - - if (val_caps[c].Range.UsageMin == HID_USAGE_GENERIC_HATSWITCH) - joystick_add_pov(rawjoy, joy, &val_caps[c]); - else - joystick_add_axis(rawjoy, joy, &val_caps[c]); - } - } - -end: - free(btn_caps); - free(val_caps); -} - -void -joystick_get_device_name(raw_joystick_t *rawjoy, plat_joystick_t *joy, PRID_DEVICE_INFO info) -{ - UINT size = 0; - WCHAR *device_name = NULL; - WCHAR device_desc_wide[200] = { 0 }; - - GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_DEVICENAME, device_name, &size); - device_name = calloc(size, sizeof(WCHAR)); - if (GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_DEVICENAME, device_name, &size) <= 0) - fatal("joystick_get_capabilities: Failed to get device name.\n"); - - HANDLE hDevObj = CreateFileW(device_name, GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - if (hDevObj) { - HidD_GetProductString(hDevObj, device_desc_wide, sizeof(WCHAR) * 200); - CloseHandle(hDevObj); - } - free(device_name); - - int result = WideCharToMultiByte(CP_ACP, 0, device_desc_wide, 200, joy->name, 260, NULL, NULL); - if (result == 0 || strlen(joy->name) == 0) - sprintf(joy->name, - "RawInput %s, VID:%04lX PID:%04lX", - info->hid.usUsage == HID_USAGE_GENERIC_JOYSTICK ? "Joystick" : "Gamepad", - info->hid.dwVendorId, - info->hid.dwProductId); -} - -void -joystick_init(void) -{ - UINT size = 0; - atexit(joystick_close); - - joysticks_present = 0; - memset(raw_joystick_state, 0, sizeof(raw_joystick_t) * MAX_PLAT_JOYSTICKS); - - /* Get a list of raw input devices from Windows */ - UINT raw_devices = 0; - GetRawInputDeviceList(NULL, &raw_devices, sizeof(RAWINPUTDEVICELIST)); - PRAWINPUTDEVICELIST deviceList = calloc(raw_devices, sizeof(RAWINPUTDEVICELIST)); - GetRawInputDeviceList(deviceList, &raw_devices, sizeof(RAWINPUTDEVICELIST)); - - for (int i = 0; i < raw_devices; i++) { - PRID_DEVICE_INFO info = NULL; - - if (joysticks_present >= MAX_PLAT_JOYSTICKS) - break; - if (deviceList[i].dwType != RIM_TYPEHID) - continue; - - /* Get device info: hardware IDs and usage IDs */ - GetRawInputDeviceInfoA(deviceList[i].hDevice, RIDI_DEVICEINFO, NULL, &size); - info = malloc(size); - info->cbSize = sizeof(RID_DEVICE_INFO); - if (GetRawInputDeviceInfoA(deviceList[i].hDevice, RIDI_DEVICEINFO, info, &size) <= 0) - goto end_loop; - - /* If this is not a joystick/gamepad, skip */ - if (info->hid.usUsagePage != HID_USAGE_PAGE_GENERIC) - goto end_loop; - if (info->hid.usUsage != HID_USAGE_GENERIC_JOYSTICK && info->hid.usUsage != HID_USAGE_GENERIC_GAMEPAD) - goto end_loop; - - plat_joystick_t *joy = &plat_joystick_state[joysticks_present]; - raw_joystick_t *rawjoy = &raw_joystick_state[joysticks_present]; - rawjoy->hdevice = deviceList[i].hDevice; - - joystick_get_capabilities(rawjoy, joy); - joystick_get_device_name(rawjoy, joy, info); - - joystick_log("joystick_init: %s - %d buttons, %d axes, %d POVs\n", - joy->name, joy->nr_buttons, joy->nr_axes, joy->nr_povs); - - joysticks_present++; - -end_loop: - free(info); - } - - joystick_log("joystick_init: joysticks_present=%i\n", joysticks_present); - - /* Initialize the RawInput (joystick and gamepad) module. */ - RAWINPUTDEVICE ridev[2]; - ridev[0].dwFlags = 0; - ridev[0].hwndTarget = NULL; - ridev[0].usUsagePage = HID_USAGE_PAGE_GENERIC; - ridev[0].usUsage = HID_USAGE_GENERIC_JOYSTICK; - - ridev[1].dwFlags = 0; - ridev[1].hwndTarget = NULL; - ridev[1].usUsagePage = HID_USAGE_PAGE_GENERIC; - ridev[1].usUsage = HID_USAGE_GENERIC_GAMEPAD; - - if (!RegisterRawInputDevices(ridev, 2, sizeof(RAWINPUTDEVICE))) - fatal("plat_joystick_init: RegisterRawInputDevices failed\n"); -} - -void -joystick_close(void) -{ - RAWINPUTDEVICE ridev[2]; - ridev[0].dwFlags = RIDEV_REMOVE; - ridev[0].hwndTarget = NULL; - ridev[0].usUsagePage = HID_USAGE_PAGE_GENERIC; - ridev[0].usUsage = HID_USAGE_GENERIC_JOYSTICK; - - ridev[1].dwFlags = RIDEV_REMOVE; - ridev[1].hwndTarget = NULL; - ridev[1].usUsagePage = HID_USAGE_PAGE_GENERIC; - ridev[1].usUsage = HID_USAGE_GENERIC_GAMEPAD; - - RegisterRawInputDevices(ridev, 2, sizeof(RAWINPUTDEVICE)); -} - -void -win_joystick_handle(PRAWINPUT raw) -{ - HRESULT r; - int j = -1; /* current joystick index, -1 when not found */ - - /* If the input is not from a known device, we ignore it */ - for (int i = 0; i < joysticks_present; i++) { - if (raw_joystick_state[i].hdevice == raw->header.hDevice) { - j = i; - break; - } - } - if (j == -1) - return; - - /* Read buttons */ - USAGE usage_list[128] = { 0 }; - ULONG usage_length = plat_joystick_state[j].nr_buttons; - memset(plat_joystick_state[j].b, 0, 32 * sizeof(int)); - - r = HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, usage_list, &usage_length, - raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid); - - if (r == HIDP_STATUS_SUCCESS) { - for (int i = 0; i < usage_length; i++) { - int button = raw_joystick_state[j].usage_button[usage_list[i]]; - plat_joystick_state[j].b[button] = 128; - } - } - - /* Read axes */ - for (int a = 0; a < plat_joystick_state[j].nr_axes; a++) { - const struct raw_axis_t *axis = &raw_joystick_state[j].axis[a]; - ULONG uvalue = 0; - LONG value = 0; - LONG center = (axis->max - axis->min + 1) / 2; - - r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, axis->link, axis->usage, &uvalue, - raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid); - - if (r == HIDP_STATUS_SUCCESS) { - if (axis->min < 0) { - /* extend signed uvalue to LONG */ - if (uvalue & (1 << (axis->bitsize - 1))) { - ULONG mask = (1 << axis->bitsize) - 1; - value = -1U ^ mask; - value |= uvalue; - } else { - value = uvalue; - } - } else { - /* Assume unsigned when min >= 0, convert to a signed value */ - value = (LONG) uvalue - center; - } - if (abs(value) == 1) - value = 0; - value = value * 32768 / center; - } - - plat_joystick_state[j].a[a] = value; -#if 0 - joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]); -#endif - } - - /* read povs */ - for (int p = 0; p < plat_joystick_state[j].nr_povs; p++) { - const struct raw_pov_t *pov = &raw_joystick_state[j].pov[p]; - ULONG uvalue = 0; - LONG value = -1; - - r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, pov->link, pov->usage, &uvalue, - raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid); - - if (r == HIDP_STATUS_SUCCESS && (uvalue >= pov->min && uvalue <= pov->max)) { - value = (uvalue - pov->min) * 36000; - value /= (pov->max - pov->min + 1); - value %= 36000; - } - - plat_joystick_state[j].p[p] = value; - -#if 0 - joystick_log("%s %-3d ", plat_joystick_state[j].pov[p].name, plat_joystick_state[j].p[p]); -#endif - } -#if 0 - joystick_log("\n"); -#endif -} - -static int -joystick_get_axis(int joystick_nr, int mapping) -{ - if (mapping & POV_X) { - int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; - if (LOWORD(pov) == 0xFFFF) - return 0; - else - return sin((2 * M_PI * (double) pov) / 36000.0) * 32767; - } else if (mapping & POV_Y) { - int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; - - if (LOWORD(pov) == 0xFFFF) - return 0; - else - return -cos((2 * M_PI * (double) pov) / 36000.0) * 32767; - } else - return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; -} - -void -joystick_process(void) -{ - int d; - - if (joystick_type == JS_TYPE_NONE) - return; - - for (int c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { - if (joystick_state[c].plat_joystick_nr) { - int joystick_nr = joystick_state[c].plat_joystick_nr - 1; - - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]); - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]]; - - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { - int x; - int y; - double angle; - double magnitude; - - x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]); - y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]); - - angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI); - magnitude = sqrt((double) x * (double) x + (double) y * (double) y); - - if (magnitude < 16384) - joystick_state[c].pov[d] = -1; - else - joystick_state[c].pov[d] = ((int) angle + 90 + 360) % 360; - } - } else { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = 0; - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = 0; - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - joystick_state[c].pov[d] = -1; - } - } -} diff --git a/src/win/win_joystick_xinput.c b/src/win/win_joystick_xinput.c deleted file mode 100644 index f313522a9..000000000 --- a/src/win/win_joystick_xinput.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Xinput joystick interface. - * - * - * - * Authors: Miran Grca, - * GH Cao, - * Jasmine Iwanek, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2019 GH Cao. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#include -#define _USE_MATH_DEFINES -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/plat.h> -#include <86box/gameport.h> -#include <86box/win.h> - -#define XINPUT_MAX_JOYSTICKS 4 -#define XINPUT_NAME "Xinput compatiable controller" -#define XINPUT_NAME_LX "Left Stick X" -#define XINPUT_NAME_LY "Left Stick Y" -#define XINPUT_NAME_RX "Right Stick X" -#define XINPUT_NAME_RY "Right Stick Y" -#define XINPUT_NAME_DPAD_X "D-pad X" -#define XINPUT_NAME_DPAD_Y "D-pad Y" -#define XINPUT_NAME_LB "LB" -#define XINPUT_NAME_RB "RB" -#define XINPUT_NAME_LT "LT" -#define XINPUT_NAME_RT "RT" -#define XINPUT_NAME_A "A" -#define XINPUT_NAME_B "B" -#define XINPUT_NAME_X "X" -#define XINPUT_NAME_Y "Y" -#define XINPUT_NAME_BACK "Back/View" -#define XINPUT_NAME_START "Start/Menu" -#define XINPUT_NAME_LS "Left Stick" -#define XINPUT_NAME_RS "Right Stick" - -#ifdef ENABLE_JOYSTICK_LOG -int joystick_do_log = ENABLE_JOYSTICK_LOG; - -static void -joystick_log(const char *fmt, ...) -{ - va_list ap; - - if (joystick_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define joystick_log(fmt, ...) -#endif - -plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; -joystick_t joystick_state[MAX_JOYSTICKS]; -int joysticks_present = 0; - -XINPUT_STATE controllers[XINPUT_MAX_JOYSTICKS]; - -void -joystick_init() -{ - atexit(joystick_close); - - joysticks_present = 0; - - memset(controllers, 0, sizeof(XINPUT_STATE) * XINPUT_MAX_JOYSTICKS); - - for (uint8_t c = 0; c < XINPUT_MAX_JOYSTICKS; c++) { - int value = XInputGetState(c, &controllers[c]); - if (value != ERROR_SUCCESS) - continue; - memcpy(plat_joystick_state[c].name, XINPUT_NAME, sizeof(XINPUT_NAME)); - - plat_joystick_state[c].nr_axes = 8; - - /* analog stick */ - memcpy(plat_joystick_state[c].axis[0].name, XINPUT_NAME_LX, sizeof(XINPUT_NAME_LX)); - plat_joystick_state[c].axis[0].id = 0; /* X axis */ - memcpy(plat_joystick_state[c].axis[1].name, XINPUT_NAME_LY, sizeof(XINPUT_NAME_LY)); - plat_joystick_state[c].axis[1].id = 1; /* Y axis */ - memcpy(plat_joystick_state[c].axis[2].name, XINPUT_NAME_RX, sizeof(XINPUT_NAME_RX)); - plat_joystick_state[c].axis[2].id = 3; /* RX axis */ - memcpy(plat_joystick_state[c].axis[3].name, XINPUT_NAME_RY, sizeof(XINPUT_NAME_RY)); - plat_joystick_state[c].axis[3].id = 4; /* RY axis */ - - /* d-pad, assigned to Z and RZ */ - memcpy(plat_joystick_state[c].axis[4].name, XINPUT_NAME_DPAD_X, sizeof(XINPUT_NAME_DPAD_X)); - plat_joystick_state[c].axis[4].id = 2; - memcpy(plat_joystick_state[c].axis[5].name, XINPUT_NAME_DPAD_Y, sizeof(XINPUT_NAME_DPAD_Y)); - plat_joystick_state[c].axis[5].id = 5; - - /* Analog trigger */ - memcpy(plat_joystick_state[c].axis[6].name, XINPUT_NAME_LT, sizeof(XINPUT_NAME_LT)); - plat_joystick_state[c].axis[6].id = 6; - memcpy(plat_joystick_state[c].axis[7].name, XINPUT_NAME_RT, sizeof(XINPUT_NAME_RT)); - plat_joystick_state[c].axis[7].id = 7; - - plat_joystick_state[c].nr_buttons = 12; - memcpy(plat_joystick_state[c].button[0].name, XINPUT_NAME_A, sizeof(XINPUT_NAME_A)); - memcpy(plat_joystick_state[c].button[1].name, XINPUT_NAME_B, sizeof(XINPUT_NAME_B)); - memcpy(plat_joystick_state[c].button[2].name, XINPUT_NAME_X, sizeof(XINPUT_NAME_X)); - memcpy(plat_joystick_state[c].button[3].name, XINPUT_NAME_Y, sizeof(XINPUT_NAME_Y)); - memcpy(plat_joystick_state[c].button[4].name, XINPUT_NAME_LB, sizeof(XINPUT_NAME_LB)); - memcpy(plat_joystick_state[c].button[5].name, XINPUT_NAME_RB, sizeof(XINPUT_NAME_RB)); - memcpy(plat_joystick_state[c].button[6].name, XINPUT_NAME_LT, sizeof(XINPUT_NAME_LT)); - memcpy(plat_joystick_state[c].button[7].name, XINPUT_NAME_RT, sizeof(XINPUT_NAME_RT)); - memcpy(plat_joystick_state[c].button[8].name, XINPUT_NAME_BACK, sizeof(XINPUT_NAME_BACK)); - memcpy(plat_joystick_state[c].button[9].name, XINPUT_NAME_START, sizeof(XINPUT_NAME_START)); - memcpy(plat_joystick_state[c].button[10].name, XINPUT_NAME_LS, sizeof(XINPUT_NAME_LS)); - memcpy(plat_joystick_state[c].button[11].name, XINPUT_NAME_RS, sizeof(XINPUT_NAME_RS)); - - plat_joystick_state[c].nr_povs = 0; - - joysticks_present++; - } - joystick_log("joystick_init: joysticks_present=%i\n", joysticks_present); -} - -void -joystick_close() -{ - // -} - -void -joystick_poll(void) -{ - for (int c = 0; c < joysticks_present; c++) { - int value = XInputGetState(c, &controllers[c]); - if (value != ERROR_SUCCESS) - continue; - - plat_joystick_state[c].a[0] = controllers[c].Gamepad.sThumbLX; - plat_joystick_state[c].a[1] = -controllers[c].Gamepad.sThumbLY; - plat_joystick_state[c].a[3] = controllers[c].Gamepad.sThumbRX; - plat_joystick_state[c].a[4] = -controllers[c].Gamepad.sThumbRY; - plat_joystick_state[c].a[6] = (double) controllers[c].Gamepad.bLeftTrigger / 255 * 32767; - plat_joystick_state[c].a[7] = (double) controllers[c].Gamepad.bRightTrigger / 255 * 32767; - - plat_joystick_state[c].b[0] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_A) ? 128 : 0; - plat_joystick_state[c].b[1] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_B) ? 128 : 0; - plat_joystick_state[c].b[2] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_X) ? 128 : 0; - plat_joystick_state[c].b[3] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_Y) ? 128 : 0; - plat_joystick_state[c].b[4] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) ? 128 : 0; - plat_joystick_state[c].b[5] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) ? 128 : 0; - plat_joystick_state[c].b[6] = (controllers[c].Gamepad.bLeftTrigger > 127) ? 128 : 0; - plat_joystick_state[c].b[7] = (controllers[c].Gamepad.bRightTrigger > 127) ? 128 : 0; - plat_joystick_state[c].b[8] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_BACK) ? 128 : 0; - plat_joystick_state[c].b[9] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_START) ? 128 : 0; - plat_joystick_state[c].b[10] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) ? 128 : 0; - plat_joystick_state[c].b[11] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) ? 128 : 0; - - int dpad_x = 0; - int dpad_y = 0; - if (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) - dpad_y -= 32767; - if (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) - dpad_y += 32767; - if (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) - dpad_x -= 32767; - if (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) - dpad_x += 32767; - - plat_joystick_state[c].a[2] = dpad_x; - plat_joystick_state[c].a[5] = dpad_y; - - for (int a = 0; a < 8; a++) { - if (plat_joystick_state[c].a[a] == -32768) - plat_joystick_state[c].a[a] = -32767; - if (plat_joystick_state[c].a[a] == 32768) - plat_joystick_state[c].a[a] = 32767; - } - } -} - -static int -joystick_get_axis(int joystick_nr, int mapping) -{ - if (mapping & POV_X) { - int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; - - if (LOWORD(pov) == 0xFFFF) - return 0; - else - return sin((2 * M_PI * (double) pov) / 36000.0) * 32767; - } else if (mapping & POV_Y) { - int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; - - if (LOWORD(pov) == 0xFFFF) - return 0; - else - return -cos((2 * M_PI * (double) pov) / 36000.0) * 32767; - } else - return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; -} - -void -joystick_process(void) -{ - int d; - - if (!joystick_type) - return; - - joystick_poll(); - - for (int c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { - if (joystick_state[c].plat_joystick_nr) { - int joystick_nr = joystick_state[c].plat_joystick_nr - 1; - - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]); - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]]; - - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { - int x; - int y; - double angle; - double magnitude; - - x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]); - y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]); - - angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI); - magnitude = sqrt((double) x * (double) x + (double) y * (double) y); - - if (magnitude < 16384) - joystick_state[c].pov[d] = -1; - else - joystick_state[c].pov[d] = ((int) angle + 90 + 360) % 360; - } - } else { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = 0; - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = 0; - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - joystick_state[c].pov[d] = -1; - } - } -} - -void -win_joystick_handle(UNUSED(PRAWINPUT raw)) -{ - // Nothing to be done here, atleast currently -} diff --git a/src/win/win_jsconf.c b/src/win/win_jsconf.c deleted file mode 100644 index 416e7858d..000000000 --- a/src/win/win_jsconf.c +++ /dev/null @@ -1,527 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/config.h> -#include <86box/device.h> -#include <86box/gameport.h> -#include <86box/plat.h> -#include <86box/win.h> - -static int joystick_nr; -static int joystick_config_type; -#define AXIS_STRINGS_MAX 3 -static char *axis_strings[AXIS_STRINGS_MAX] = { "X Axis", "Y Axis", "Z Axis" }; - -static uint8_t joystickconfig_changed = 0; - -static void -rebuild_axis_button_selections(HWND hdlg) -{ - int id = IDC_CONFIG_BASE + 2; - HWND h; - int joystick; - int c; - int d; - char s[269]; - - h = GetDlgItem(hdlg, IDC_CONFIG_BASE); - joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - - for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) { - int sel = c; - - h = GetDlgItem(hdlg, id); - SendMessage(h, CB_RESETCONTENT, 0, 0); - - if (joystick) { - for (d = 0; d < plat_joystick_state[joystick - 1].nr_axes; d++) { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) plat_joystick_state[joystick - 1].axis[d].name); - if (c < AXIS_STRINGS_MAX) { - if (!stricmp(axis_strings[c], plat_joystick_state[joystick - 1].axis[d].name)) - sel = d; - } - } - for (d = 0; d < plat_joystick_state[joystick - 1].nr_povs; d++) { - sprintf(s, "%s (X axis)", plat_joystick_state[joystick - 1].pov[d].name); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) s); - sprintf(s, "%s (Y axis)", plat_joystick_state[joystick - 1].pov[d].name); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) s); - } - SendMessage(h, CB_SETCURSEL, sel, 0); - EnableWindow(h, TRUE); - } else - EnableWindow(h, FALSE); - - id += 2; - } - - for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) { - h = GetDlgItem(hdlg, id); - SendMessage(h, CB_RESETCONTENT, 0, 0); - - if (joystick) { - for (d = 0; d < plat_joystick_state[joystick - 1].nr_buttons; d++) - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) plat_joystick_state[joystick - 1].button[d].name); - SendMessage(h, CB_SETCURSEL, c, 0); - EnableWindow(h, TRUE); - } else - EnableWindow(h, FALSE); - - id += 2; - } - - for (c = 0; c < joystick_get_pov_count(joystick_config_type) * 2; c++) { - int sel = c; - - h = GetDlgItem(hdlg, id); - SendMessage(h, CB_RESETCONTENT, 0, 0); - - if (joystick) { - for (d = 0; d < plat_joystick_state[joystick - 1].nr_povs; d++) { - sprintf(s, "%s (X axis)", plat_joystick_state[joystick - 1].pov[d].name); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) s); - sprintf(s, "%s (Y axis)", plat_joystick_state[joystick - 1].pov[d].name); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) s); - } - for (d = 0; d < plat_joystick_state[joystick - 1].nr_axes; d++) { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) plat_joystick_state[joystick - 1].axis[d].name); - } - SendMessage(h, CB_SETCURSEL, sel, 0); - EnableWindow(h, TRUE); - } else - EnableWindow(h, FALSE); - - id += 2; - } -} - -static int -get_axis(HWND hdlg, int id) -{ - HWND h = GetDlgItem(hdlg, id); - int axis_sel = SendMessage(h, CB_GETCURSEL, 0, 0); - int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_axes; - - if (axis_sel < nr_axes) - return axis_sel; - - axis_sel -= nr_axes; - if (axis_sel & 1) - return POV_Y | (axis_sel >> 1); - else - return POV_X | (axis_sel >> 1); -} - -static int -get_pov(HWND hdlg, int id) -{ - HWND h = GetDlgItem(hdlg, id); - int axis_sel = SendMessage(h, CB_GETCURSEL, 0, 0); - int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs * 2; - - if (axis_sel < nr_povs) { - if (axis_sel & 1) - return POV_Y | (axis_sel >> 1); - else - return POV_X | (axis_sel >> 1); - } - - return axis_sel - nr_povs; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - HWND h; - int c; - int id; - int joystick; - int nr_axes; - int nr_povs; - int mapping; - - switch (message) { - case WM_INITDIALOG: - { - h = GetDlgItem(hdlg, IDC_CONFIG_BASE); - id = IDC_CONFIG_BASE + 2; - joystick = joystick_state[joystick_nr].plat_joystick_nr; - - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) "None"); - - for (c = 0; c < joysticks_present; c++) - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) plat_joystick_state[c].name); - - SendMessage(h, CB_SETCURSEL, joystick, 0); - - rebuild_axis_button_selections(hdlg); - - if (joystick_state[joystick_nr].plat_joystick_nr) { - nr_axes = plat_joystick_state[joystick - 1].nr_axes; - nr_povs = plat_joystick_state[joystick - 1].nr_povs; - - for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) { - int mapping = joystick_state[joystick_nr].axis_mapping[c]; - - h = GetDlgItem(hdlg, id); - if (mapping & POV_X) - SendMessage(h, CB_SETCURSEL, nr_axes + (mapping & 3) * 2, 0); - else if (mapping & POV_Y) - SendMessage(h, CB_SETCURSEL, nr_axes + (mapping & 3) * 2 + 1, 0); - else - SendMessage(h, CB_SETCURSEL, mapping, 0); - id += 2; - } - for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) { - h = GetDlgItem(hdlg, id); - SendMessage(h, CB_SETCURSEL, joystick_state[joystick_nr].button_mapping[c], 0); - id += 2; - } - for (c = 0; c < joystick_get_pov_count(joystick_config_type); c++) { - h = GetDlgItem(hdlg, id); - mapping = joystick_state[joystick_nr].pov_mapping[c][0]; - if (mapping & POV_X) - SendMessage(h, CB_SETCURSEL, (mapping & 3) * 2, 0); - else if (mapping & POV_Y) - SendMessage(h, CB_SETCURSEL, (mapping & 3) * 2 + 1, 0); - else - SendMessage(h, CB_SETCURSEL, mapping + nr_povs * 2, 0); - id += 2; - h = GetDlgItem(hdlg, id); - mapping = joystick_state[joystick_nr].pov_mapping[c][1]; - if (mapping & POV_X) - SendMessage(h, CB_SETCURSEL, (mapping & 3) * 2, 0); - else if (mapping & POV_Y) - SendMessage(h, CB_SETCURSEL, (mapping & 3) * 2 + 1, 0); - else - SendMessage(h, CB_SETCURSEL, mapping + nr_povs * 2, 0); - id += 2; - } - } - } - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_CONFIG_BASE: - if (HIWORD(wParam) == CBN_SELCHANGE) - rebuild_axis_button_selections(hdlg); - break; - - case IDOK: - { - id = IDC_CONFIG_BASE + 2; - - h = GetDlgItem(hdlg, IDC_CONFIG_BASE); - joystick_state[joystick_nr].plat_joystick_nr = SendMessage(h, CB_GETCURSEL, 0, 0); - - if (joystick_state[joystick_nr].plat_joystick_nr) { - for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) { - joystick_state[joystick_nr].axis_mapping[c] = get_axis(hdlg, id); - id += 2; - } - for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) { - h = GetDlgItem(hdlg, id); - joystick_state[joystick_nr].button_mapping[c] = SendMessage(h, CB_GETCURSEL, 0, 0); - id += 2; - } - for (c = 0; c < joystick_get_pov_count(joystick_config_type); c++) { - h = GetDlgItem(hdlg, id); - joystick_state[joystick_nr].pov_mapping[c][0] = get_pov(hdlg, id); - id += 2; - h = GetDlgItem(hdlg, id); - joystick_state[joystick_nr].pov_mapping[c][1] = get_pov(hdlg, id); - id += 2; - } - } - } - joystickconfig_changed = 1; - EndDialog(hdlg, 0); - return TRUE; - case IDCANCEL: - joystickconfig_changed = 0; - EndDialog(hdlg, 0); - return TRUE; - } - break; - } - return FALSE; -} - -uint8_t -joystickconfig_open(HWND hwnd, int joy_nr, int type) -{ - uint16_t *data_block = malloc(16384); - uint16_t *data; - DLGTEMPLATE *dlg = (DLGTEMPLATE *) data_block; - DLGITEMTEMPLATE *item; - int y = 10; - int id = IDC_CONFIG_BASE; - int c; - char s[269]; - - joystickconfig_changed = 0; - - joystick_nr = joy_nr; - joystick_config_type = type; - - memset(data_block, 0, 4096); - - dlg->style = DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU; - dlg->x = 10; - dlg->y = 10; - dlg->cx = 220; - dlg->cy = 70; - - data = (uint16_t *) (dlg + 1); - - *data++ = 0; /*no menu*/ - *data++ = 0; /*predefined dialog box class*/ - data += MultiByteToWideChar(CP_ACP, 0, "Joystick Configuration", -1, data, 50); - - *data++ = 9; /*Point*/ - data += MultiByteToWideChar(CP_ACP, 0, "Segoe UI", -1, data, 50); - - if (((uintptr_t) data) & 2) - data++; - - /*Combo box*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 70; - item->y = y; - item->id = id++; - - item->cx = 140; - item->cy = 150; - - item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0085; /* combo box class */ - - data += MultiByteToWideChar(CP_ACP, 0, "Device", -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - /*Static text*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 10; - item->y = y + 2; - item->id = id++; - - item->cx = 60; - item->cy = 15; - - item->style = WS_CHILD | WS_VISIBLE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0082; /* static class */ - - data += MultiByteToWideChar(CP_ACP, 0, "Device", -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - y += 20; - - for (c = 0; c < joystick_get_axis_count(type); c++) { - /*Combo box*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 70; - item->y = y; - item->id = id++; - - item->cx = 140; - item->cy = 150; - - item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0085; /* combo box class */ - - data += MultiByteToWideChar(CP_ACP, 0, joystick_get_axis_name(type, c), -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - /*Static text*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 10; - item->y = y + 2; - item->id = id++; - - item->cx = 60; - item->cy = 15; - - item->style = WS_CHILD | WS_VISIBLE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0082; /* static class */ - - data += MultiByteToWideChar(CP_ACP, 0, joystick_get_axis_name(type, c), -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - y += 20; - } - - for (c = 0; c < joystick_get_button_count(type); c++) { - /*Combo box*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 70; - item->y = y; - item->id = id++; - - item->cx = 140; - item->cy = 150; - - item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0085; /* combo box class */ - - data += MultiByteToWideChar(CP_ACP, 0, joystick_get_button_name(type, c), -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - /*Static text*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 10; - item->y = y + 2; - item->id = id++; - - item->cx = 60; - item->cy = 15; - - item->style = WS_CHILD | WS_VISIBLE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0082; /* static class */ - - data += MultiByteToWideChar(CP_ACP, 0, joystick_get_button_name(type, c), -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - y += 20; - } - - for (c = 0; c < joystick_get_pov_count(type) * 2; c++) { - /*Combo box*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 70; - item->y = y; - item->id = id++; - - item->cx = 140; - item->cy = 150; - - item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0085; /* combo box class */ - - if (c & 1) - sprintf(s, "%s (Y axis)", joystick_get_pov_name(type, c / 2)); - else - sprintf(s, "%s (X axis)", joystick_get_pov_name(type, c / 2)); - data += MultiByteToWideChar(CP_ACP, 0, s, -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - /*Static text*/ - item = (DLGITEMTEMPLATE *) data; - item->x = 10; - item->y = y + 2; - item->id = id++; - - item->cx = 60; - item->cy = 15; - - item->style = WS_CHILD | WS_VISIBLE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0082; /* static class */ - - data += MultiByteToWideChar(CP_ACP, 0, s, -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - y += 20; - } - - dlg->cdit = (id - IDC_CONFIG_BASE) + 2; - - item = (DLGITEMTEMPLATE *) data; - item->x = 100; - item->y = y + 5; - item->cx = 50; - item->cy = 14; - item->id = IDOK; /* OK button identifier */ - item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0080; /* button class */ - - data += MultiByteToWideChar(CP_ACP, 0, "OK", -1, data, 50); - *data++ = 0; /* no creation data */ - - if (((uintptr_t) data) & 2) - data++; - - item = (DLGITEMTEMPLATE *) data; - item->x = 160; - item->y = y + 5; - item->cx = 50; - item->cy = 14; - item->id = IDCANCEL; /* Cancel button identifier */ - item->style = WS_CHILD | WS_VISIBLE; - - data = (uint16_t *) (item + 1); - *data++ = 0xFFFF; - *data++ = 0x0080; /* button class */ - - data += MultiByteToWideChar(CP_ACP, 0, "Cancel", -1, data, 50); - *data++ = 0; /* no creation data */ - - dlg->cy = y + 25; - - DialogBoxIndirect(hinstance, dlg, hwnd, joystickconfig_dlgproc); - - free(data_block); - - return joystickconfig_changed; -} diff --git a/src/win/win_keyboard.c b/src/win/win_keyboard.c deleted file mode 100644 index 54be91e6c..000000000 --- a/src/win/win_keyboard.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Windows raw keyboard input handler. - * - * - * - * Authors: Miran Grca, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#define _WIN32_WINNT 0x0501 -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/keyboard.h> -#include <86box/plat.h> -#include <86box/win.h> - -static uint16_t scancode_map[768]; - -/* This is so we can disambiguate scan codes that would otherwise conflict and get - passed on incorrectly. */ -static UINT16 -convert_scan_code(UINT16 scan_code) -{ - if ((scan_code & 0xff00) == 0xe000) - scan_code = (scan_code & 0xff) | 0x0100; - - if (scan_code == 0xE11D) - scan_code = 0x0100; - /* E0 00 is sent by some USB keyboards for their special keys, as it is an - invalid scan code (it has no untranslated set 2 equivalent), we mark it - appropriately so it does not get passed through. */ - else if ((scan_code > 0x01FF) || (scan_code == 0x0100)) - scan_code = 0xFFFF; - - return scan_code; -} - -void -keyboard_getkeymap(void) -{ - const WCHAR *keyName = L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; - const WCHAR *valueName = L"Scancode Map"; - unsigned char buf[32768]; - DWORD bufSize; - HKEY hKey; - int j; - const UINT32 *bufEx2; - int scMapCount; - const UINT16 *bufEx; - int scancode_unmapped; - int scancode_mapped; - - /* First, prepare the default scan code map list which is 1:1. - * Remappings will be inserted directly into it. - * 512 bytes so this takes less memory, bit 9 set means E0 - * prefix. - */ - for (j = 0; j < 512; j++) - scancode_map[j] = j; - - /* Get the scan code remappings from: - HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */ - bufSize = 32768; - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) { - if (RegQueryValueEx(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) { - bufEx2 = (UINT32 *) buf; - scMapCount = bufEx2[2]; - if ((bufSize != 0) && (scMapCount != 0)) { - bufEx = (UINT16 *) (buf + 12); - for (j = 0; j < scMapCount * 2; j += 2) { - /* Each scan code is 32-bit: 16 bits of remapped scan code, - and 16 bits of original scan code. */ - scancode_unmapped = bufEx[j + 1]; - scancode_mapped = bufEx[j]; - - scancode_unmapped = convert_scan_code(scancode_unmapped); - scancode_mapped = convert_scan_code(scancode_mapped); - - /* Ignore source scan codes with prefixes other than E1 - that are not E1 1D. */ - if (scancode_unmapped != 0xFFFF) - scancode_map[scancode_unmapped] = scancode_mapped; - } - } - } - RegCloseKey(hKey); - } -} - -void -keyboard_handle(PRAWINPUT raw) -{ - USHORT scancode; - static int recv_lalt = 0; - static int recv_ralt = 0; - static int recv_tab = 0; - - RAWKEYBOARD rawKB = raw->data.keyboard; - scancode = rawKB.MakeCode; - - if (kbd_req_capture && !mouse_capture && !video_fullscreen) - return; - - /* If it's not a scan code that starts with 0xE1 */ - if (!(rawKB.Flags & RI_KEY_E1)) { - if (rawKB.Flags & RI_KEY_E0) - scancode |= 0x100; - - /* Translate the scan code to 9-bit */ - scancode = convert_scan_code(scancode); - - /* Remap it according to the list from the Registry */ - if (scancode != scancode_map[scancode]) - pclog("Scan code remap: %03X -> %03X\n", scancode, scancode); - scancode = scancode_map[scancode]; - - /* If it's not 0xFFFF, send it to the emulated - keyboard. - We use scan code 0xFFFF to mean a mapping that - has a prefix other than E0 and that is not E1 1D, - which is, for our purposes, invalid. */ - if ((scancode == 0x00f) && !(rawKB.Flags & RI_KEY_BREAK) && (recv_lalt || recv_ralt) && (!kbd_req_capture || mouse_capture)) { - /* We received a TAB while ALT was pressed, while the mouse - is not captured, suppress the TAB and send an ALT key up. */ - if (recv_lalt) { - keyboard_input(0, 0x038); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x038); - keyboard_input(0, 0x038); - recv_lalt = 0; - } - if (recv_ralt) { - keyboard_input(0, 0x138); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x138); - keyboard_input(0, 0x138); - recv_ralt = 0; - } - } else if (((scancode == 0x038) || (scancode == 0x138)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_tab && (!kbd_req_capture || mouse_capture)) { - /* We received an ALT while TAB was pressed, while the mouse - is not captured, suppress the ALT and send a TAB key up. */ - keyboard_input(0, 0x00f); - recv_tab = 0; - } else { - switch (scancode) { - case 0x00f: - recv_tab = !(rawKB.Flags & RI_KEY_BREAK); - break; - case 0x038: - recv_lalt = !(rawKB.Flags & RI_KEY_BREAK); - break; - case 0x138: - recv_ralt = !(rawKB.Flags & RI_KEY_BREAK); - break; - } - - /* Translate right CTRL to left ALT if the user has so - chosen. */ - if ((scancode == 0x11d) && rctrl_is_lalt) - scancode = 0x038; - - /* Normal scan code pass through, pass it through as is if - it's not an invalid scan code. */ - if (scancode != 0xFFFF) - keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode); - } - } else { - if (rawKB.MakeCode == 0x1D) { - scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would - otherwise be E0 00 but that is invalid - anyway). - Also, take a potential mapping into - account. */ - } else - scancode = 0xFFFF; - if (scancode != 0xFFFF) - keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode); - } -} diff --git a/src/win/win_media_menu.c b/src/win/win_media_menu.c deleted file mode 100644 index 549a495b9..000000000 --- a/src/win/win_media_menu.c +++ /dev/null @@ -1,766 +0,0 @@ -#define UNICODE -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/cdrom.h> -#include <86box/config.h> -#include <86box/device.h> -#include <86box/timer.h> -#include <86box/cassette.h> -#include <86box/cartridge.h> -#include <86box/fdd.h> -#include <86box/fdd_86f.h> -#include <86box/hdc.h> -#include <86box/language.h> -#include <86box/machine.h> -#include <86box/scsi_device.h> -#include <86box/mo.h> -#include <86box/plat.h> -#include <86box/scsi.h> -#include <86box/sound.h> -#include <86box/ui.h> -#include <86box/zip.h> -#include <86box/win.h> - -#define MACHINE_HAS_IDE (machine_has_flags(machine, MACHINE_IDE_QUAD)) -#define MACHINE_HAS_SCSI (machine_has_flags(machine, MACHINE_SCSI)) - -#define CASSETTE_FIRST 0 -#define CARTRIDGE_FIRST CASSETTE_FIRST + 1 -#define FDD_FIRST CARTRIDGE_FIRST + 2 -#define CDROM_FIRST FDD_FIRST + FDD_NUM -#define ZIP_FIRST CDROM_FIRST + CDROM_NUM -#define MO_FIRST ZIP_FIRST + ZIP_NUM - -static HMENU media_menu; -static HMENU stbar_menu; -static HMENU menus[1 + 2 + FDD_NUM + CDROM_NUM + ZIP_NUM + MO_NUM]; - -static char index_map[255]; - -static void -media_menu_set_ids(HMENU hMenu, int id) -{ - int c = GetMenuItemCount(hMenu); - - MENUITEMINFO mii = { 0 }; - mii.fMask = MIIM_ID; - mii.cbSize = sizeof(mii); - - for (int i = 0; i < c; i++) { - GetMenuItemInfo(hMenu, i, TRUE, &mii); - mii.wID |= id; - SetMenuItemInfo(hMenu, i, TRUE, &mii); - } -} - -/* Loads the submenu from resource by name */ -static HMENU -media_menu_load_resource(wchar_t *lpName) -{ - HMENU loaded = LoadMenu(NULL, lpName); - - /* The actual submenu is in a dummy popup menu item */ - HMENU actual = GetSubMenu(loaded, 0); - - /* Now that we have our submenu, we can destroy the parent menu */ - RemoveMenu(loaded, (UINT_PTR) actual, MF_BYCOMMAND); - DestroyMenu(loaded); - - return actual; -} - -static void -media_menu_set_name_cassette(void) -{ - wchar_t name[512]; - wchar_t fn[512]; - MENUITEMINFO mii = { 0 }; - - if (strlen(cassette_fname) == 0) - _swprintf(name, plat_get_string(IDS_2149), plat_get_string(IDS_2057)); - else { - mbstoc16s(fn, cassette_fname, sizeof_w(fn)); - _swprintf(name, plat_get_string(IDS_2149), fn); - } - - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_STRING; - mii.dwTypeData = name; - - SetMenuItemInfo(media_menu, (UINT_PTR) menus[CASSETTE_FIRST], FALSE, &mii); -} - -static void -media_menu_set_name_cartridge(int drive) -{ - wchar_t name[512]; - wchar_t fn[512]; - MENUITEMINFO mii = { 0 }; - - if (strlen(cart_fns[drive]) == 0) { - _swprintf(name, plat_get_string(IDS_2151), - drive + 1, plat_get_string(IDS_2057)); - } else { - mbstoc16s(fn, cart_fns[drive], sizeof_w(fn)); - _swprintf(name, plat_get_string(IDS_2151), - drive + 1, fn); - } - - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_STRING; - mii.dwTypeData = name; - - SetMenuItemInfo(media_menu, (UINT_PTR) menus[CARTRIDGE_FIRST + drive], FALSE, &mii); -} - -static void -media_menu_set_name_floppy(int drive) -{ - wchar_t name[512]; - wchar_t temp[512]; - wchar_t fn[512]; - MENUITEMINFO mii = { 0 }; - - mbstoc16s(temp, fdd_getname(fdd_get_type(drive)), - strlen(fdd_getname(fdd_get_type(drive))) + 1); - if (strlen(floppyfns[drive]) == 0) { - _swprintf(name, plat_get_string(IDS_2109), - drive + 1, temp, plat_get_string(IDS_2057)); - } else { - mbstoc16s(fn, floppyfns[drive], sizeof_w(fn)); - _swprintf(name, plat_get_string(IDS_2109), - drive + 1, temp, fn); - } - - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_STRING; - mii.dwTypeData = name; - - SetMenuItemInfo(media_menu, (UINT_PTR) menus[FDD_FIRST + drive], FALSE, &mii); -} - -static void -media_menu_set_name_cdrom(int drive) -{ - wchar_t name[512]; - wchar_t *temp; - wchar_t fn[512]; - MENUITEMINFO mii = { 0 }; - - int bus = cdrom[drive].bus_type; - int id = IDS_5377 + (bus - 1); - - temp = plat_get_string(id); - - if (cdrom[drive].host_drive == 200) { - if (strlen(cdrom[drive].image_path) == 0) { - _swprintf(name, plat_get_string(IDS_5120), - drive + 1, temp, plat_get_string(IDS_2057)); - } else { - mbstoc16s(fn, cdrom[drive].image_path, sizeof_w(fn)); - _swprintf(name, plat_get_string(IDS_5120), - drive + 1, temp, fn); - } - } else - _swprintf(name, plat_get_string(IDS_5120), drive + 1, temp, plat_get_string(IDS_2057)); - - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_STRING; - mii.dwTypeData = name; - - SetMenuItemInfo(media_menu, (UINT_PTR) menus[CDROM_FIRST + drive], FALSE, &mii); -} - -static void -media_menu_set_name_zip(int drive) -{ - wchar_t name[512]; - wchar_t *temp; - wchar_t fn[512]; - MENUITEMINFO mii = { 0 }; - - int bus = zip_drives[drive].bus_type; - int id = IDS_5377 + (bus - 1); - - temp = plat_get_string(id); - - int type = zip_drives[drive].is_250 ? 250 : 100; - - if (strlen(zip_drives[drive].image_path) == 0) { - _swprintf(name, plat_get_string(IDS_2054), - type, drive + 1, temp, plat_get_string(IDS_2057)); - } else { - mbstoc16s(fn, zip_drives[drive].image_path, sizeof_w(fn)); - _swprintf(name, plat_get_string(IDS_2054), - type, drive + 1, temp, fn); - } - - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_STRING; - mii.dwTypeData = name; - - SetMenuItemInfo(media_menu, (UINT_PTR) menus[ZIP_FIRST + drive], FALSE, &mii); -} - -static void -media_menu_set_name_mo(int drive) -{ - wchar_t name[512]; - wchar_t *temp; - wchar_t fn[512]; - MENUITEMINFO mii = { 0 }; - - int bus = mo_drives[drive].bus_type; - int id = IDS_5377 + (bus - 1); - - temp = plat_get_string(id); - - if (strlen(mo_drives[drive].image_path) == 0) { - _swprintf(name, plat_get_string(IDS_2116), - drive + 1, temp, plat_get_string(IDS_2057)); - } else { - mbstoc16s(fn, mo_drives[drive].image_path, sizeof_w(fn)); - _swprintf(name, plat_get_string(IDS_2116), - drive + 1, temp, fn); - } - - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_STRING; - mii.dwTypeData = name; - - SetMenuItemInfo(media_menu, (UINT_PTR) menus[MO_FIRST + drive], FALSE, &mii); -} - -void -media_menu_update_cassette(void) -{ - int i = CASSETTE_FIRST; - - if (strlen(cassette_fname) == 0) { - EnableMenuItem(menus[i], IDM_CASSETTE_EJECT, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(menus[i], IDM_CASSETTE_RECORD, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(menus[i], IDM_CASSETTE_PLAY, MF_BYCOMMAND | MF_GRAYED); - CheckMenuItem(menus[i], IDM_CASSETTE_RECORD, MF_BYCOMMAND | MF_UNCHECKED); - CheckMenuItem(menus[i], IDM_CASSETTE_PLAY, MF_BYCOMMAND | MF_UNCHECKED); - EnableMenuItem(menus[i], IDM_CASSETTE_REWIND, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(menus[i], IDM_CASSETTE_FAST_FORWARD, MF_BYCOMMAND | MF_GRAYED); - } else { - EnableMenuItem(menus[i], IDM_CASSETTE_EJECT, MF_BYCOMMAND | MF_ENABLED); - EnableMenuItem(menus[i], IDM_CASSETTE_RECORD, MF_BYCOMMAND | MF_ENABLED); - EnableMenuItem(menus[i], IDM_CASSETTE_PLAY, MF_BYCOMMAND | MF_ENABLED); - if (strcmp(cassette_mode, "save") == 0) { - CheckMenuItem(menus[i], IDM_CASSETTE_RECORD, MF_BYCOMMAND | MF_CHECKED); - CheckMenuItem(menus[i], IDM_CASSETTE_PLAY, MF_BYCOMMAND | MF_UNCHECKED); - } else { - CheckMenuItem(menus[i], IDM_CASSETTE_RECORD, MF_BYCOMMAND | MF_UNCHECKED); - CheckMenuItem(menus[i], IDM_CASSETTE_PLAY, MF_BYCOMMAND | MF_CHECKED); - } - EnableMenuItem(menus[i], IDM_CASSETTE_REWIND, MF_BYCOMMAND | MF_ENABLED); - EnableMenuItem(menus[i], IDM_CASSETTE_FAST_FORWARD, MF_BYCOMMAND | MF_ENABLED); - } - - media_menu_set_name_cassette(); -} - -void -media_menu_update_cartridge(int id) -{ - int i = CARTRIDGE_FIRST + id; - - if (strlen(cart_fns[id]) == 0) - EnableMenuItem(menus[i], IDM_CARTRIDGE_EJECT | id, MF_BYCOMMAND | MF_GRAYED); - else - EnableMenuItem(menus[i], IDM_CARTRIDGE_EJECT | id, MF_BYCOMMAND | MF_ENABLED); - - media_menu_set_name_cartridge(id); -} - -void -media_menu_update_floppy(int id) -{ - int i = FDD_FIRST + id; - - if (strlen(floppyfns[id]) == 0) { - EnableMenuItem(menus[i], IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(menus[i], IDM_FLOPPY_EXPORT_TO_86F | id, MF_BYCOMMAND | MF_GRAYED); - } else { - EnableMenuItem(menus[i], IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | MF_ENABLED); - EnableMenuItem(menus[i], IDM_FLOPPY_EXPORT_TO_86F | id, MF_BYCOMMAND | MF_ENABLED); - } - - media_menu_set_name_floppy(id); -} - -void -media_menu_update_cdrom(int id) -{ - int i = CDROM_FIRST + id; - - if (!cdrom[id].sound_on) - CheckMenuItem(menus[i], IDM_CDROM_MUTE | id, MF_BYCOMMAND | MF_CHECKED); - else - CheckMenuItem(menus[i], IDM_CDROM_MUTE | id, MF_BYCOMMAND | MF_UNCHECKED); - - if (cdrom[id].host_drive == 200) { - CheckMenuItem(menus[i], IDM_CDROM_IMAGE | id, MF_BYCOMMAND | (cdrom[id].is_dir ? MF_UNCHECKED : MF_CHECKED)); - CheckMenuItem(menus[i], IDM_CDROM_DIR | id, MF_BYCOMMAND | (cdrom[id].is_dir ? MF_CHECKED : MF_UNCHECKED)); - CheckMenuItem(menus[i], IDM_CDROM_EMPTY | id, MF_BYCOMMAND | MF_UNCHECKED); - } else { - cdrom[id].host_drive = 0; - CheckMenuItem(menus[i], IDM_CDROM_IMAGE | id, MF_BYCOMMAND | MF_UNCHECKED); - CheckMenuItem(menus[i], IDM_CDROM_DIR | id, MF_BYCOMMAND | MF_UNCHECKED); - CheckMenuItem(menus[i], IDM_CDROM_EMPTY | id, MF_BYCOMMAND | MF_CHECKED); - } - - if (cdrom[id].prev_host_drive == 0) - EnableMenuItem(menus[i], IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); - else - EnableMenuItem(menus[i], IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_ENABLED); - - media_menu_set_name_cdrom(id); -} - -void -media_menu_update_zip(int id) -{ - int i = ZIP_FIRST + id; - - if (strlen(zip_drives[id].image_path) == 0) - EnableMenuItem(menus[i], IDM_ZIP_EJECT | id, MF_BYCOMMAND | MF_GRAYED); - else - EnableMenuItem(menus[i], IDM_ZIP_EJECT | id, MF_BYCOMMAND | MF_ENABLED); - - if (strlen(zip_drives[id].prev_image_path) == 0) - EnableMenuItem(menus[i], IDM_ZIP_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); - else - EnableMenuItem(menus[i], IDM_ZIP_RELOAD | id, MF_BYCOMMAND | MF_ENABLED); - - media_menu_set_name_zip(id); -} - -void -media_menu_update_mo(int id) -{ - int i = MO_FIRST + id; - - if (strlen(mo_drives[id].image_path) == 0) - EnableMenuItem(menus[i], IDM_MO_EJECT | id, MF_BYCOMMAND | MF_GRAYED); - else - EnableMenuItem(menus[i], IDM_MO_EJECT | id, MF_BYCOMMAND | MF_ENABLED); - - if (strlen(mo_drives[id].prev_image_path) == 0) - EnableMenuItem(menus[i], IDM_MO_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); - else - EnableMenuItem(menus[i], IDM_MO_RELOAD | id, MF_BYCOMMAND | MF_ENABLED); - - media_menu_set_name_mo(id); -} - -static void -media_menu_load_submenus(void) -{ - memset(index_map, -1, sizeof(index_map)); - - int curr = 0; - - menus[curr] = media_menu_load_resource(CASSETTE_SUBMENU_NAME); - media_menu_set_ids(menus[curr++], 0); - - for (int i = 0; i < 2; i++) { - menus[curr] = media_menu_load_resource(CARTRIDGE_SUBMENU_NAME); - media_menu_set_ids(menus[curr++], i); - } - - for (int i = 0; i < FDD_NUM; i++) { - menus[curr] = media_menu_load_resource(FLOPPY_SUBMENU_NAME); - media_menu_set_ids(menus[curr++], i); - } - - for (int i = 0; i < CDROM_NUM; i++) { - menus[curr] = media_menu_load_resource(CDROM_SUBMENU_NAME); - media_menu_set_ids(menus[curr++], i); - } - - for (int i = 0; i < ZIP_NUM; i++) { - menus[curr] = media_menu_load_resource(ZIP_SUBMENU_NAME); - media_menu_set_ids(menus[curr++], i); - } - - for (int i = 0; i < MO_NUM; i++) { - menus[curr] = media_menu_load_resource(MO_SUBMENU_NAME); - media_menu_set_ids(menus[curr++], i); - } -} - -static inline int -is_valid_cartridge(void) -{ - return (machine_has_cartridge(machine)); -} - -static inline int -is_valid_fdd(int i) -{ - return fdd_get_type(i) != 0; -} - -static inline int -is_valid_cdrom(int i) -{ - if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && !MACHINE_HAS_IDE && memcmp(hdc_get_internal_name(hdc_current), "xtide", 5) && memcmp(hdc_get_internal_name(hdc_current), "ide", 3)) - return 0; - if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !MACHINE_HAS_SCSI && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) - return 0; - return cdrom[i].bus_type != 0; -} - -static inline int -is_valid_zip(int i) -{ - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && !MACHINE_HAS_IDE && memcmp(hdc_get_internal_name(hdc_current), "xtide", 5) && memcmp(hdc_get_internal_name(hdc_current), "ide", 3)) - return 0; - if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !MACHINE_HAS_SCSI && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) - return 0; - return zip_drives[i].bus_type != 0; -} - -static inline int -is_valid_mo(int i) -{ - if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && !MACHINE_HAS_IDE && memcmp(hdc_get_internal_name(hdc_current), "xtide", 5) && memcmp(hdc_get_internal_name(hdc_current), "ide", 3)) - return 0; - if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !MACHINE_HAS_SCSI && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) - return 0; - return mo_drives[i].bus_type != 0; -} - -void -media_menu_reset(void) -{ - /* Remove existing entries. */ - int c = GetMenuItemCount(media_menu); - - for (int i = 0; i < c; i++) - RemoveMenu(media_menu, 0, MF_BYPOSITION); - - /* Add new ones. */ - int curr = 0; - - if (cassette_enable) { - AppendMenu(media_menu, MF_POPUP | MF_STRING, (UINT_PTR) menus[curr], L"Test"); - media_menu_update_cassette(); - } - curr++; - - for (int i = 0; i < 2; i++) { - if (is_valid_cartridge()) { - AppendMenu(media_menu, MF_POPUP | MF_STRING, (UINT_PTR) menus[curr], L"Test"); - media_menu_update_cartridge(i); - } - curr++; - } - - for (int i = 0; i < FDD_NUM; i++) { - if (is_valid_fdd(i)) { - AppendMenu(media_menu, MF_POPUP | MF_STRING, (UINT_PTR) menus[curr], L"Test"); - media_menu_update_floppy(i); - } - curr++; - } - - for (int i = 0; i < CDROM_NUM; i++) { - if (is_valid_cdrom(i)) { - AppendMenu(media_menu, MF_POPUP | MF_STRING, (UINT_PTR) menus[curr], L"Test"); - media_menu_update_cdrom(i); - } - curr++; - } - - for (int i = 0; i < ZIP_NUM; i++) { - if (is_valid_zip(i)) { - AppendMenu(media_menu, MF_POPUP | MF_STRING, (UINT_PTR) menus[curr], L"Test"); - media_menu_update_zip(i); - } - curr++; - } - - for (int i = 0; i < MO_NUM; i++) { - if (is_valid_mo(i)) { - AppendMenu(media_menu, MF_POPUP | MF_STRING, (UINT_PTR) menus[curr], L"Test"); - media_menu_update_mo(i); - } - curr++; - } -} - -/* Initializes the Media menu in the main menu bar. */ -static void -media_menu_main_init(void) -{ - HMENU hMenu; - LPWSTR lpMenuName; - - hMenu = GetMenu(hwndMain); - media_menu = CreatePopupMenu(); - - /* Get the menu name */ - int len = GetMenuString(hMenu, IDM_MEDIA, NULL, 0, MF_BYCOMMAND); - lpMenuName = malloc((len + 1) * sizeof(WCHAR)); - GetMenuString(hMenu, IDM_MEDIA, lpMenuName, len + 1, MF_BYCOMMAND); - - /* Replace the placeholder menu item */ - ModifyMenu(hMenu, IDM_MEDIA, MF_BYCOMMAND | MF_STRING | MF_POPUP, (UINT_PTR) media_menu, lpMenuName); - - /* Clean up */ - DrawMenuBar(hwndMain); - free(lpMenuName); -} - -void -media_menu_init(void) -{ - /* Initialize the main menu bar menu */ - media_menu_main_init(); - - /* Initialize the dummy status bar menu. */ - stbar_menu = CreateMenu(); - AppendMenu(stbar_menu, MF_POPUP, (UINT_PTR) media_menu, NULL); - - /* Load the submenus for each drive type. */ - media_menu_load_submenus(); - - /* Populate the Media and status bar menus. */ - media_menu_reset(); -} - -int -media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - int id = 0; - int ret = 0; - int wp = 0; - -#ifdef __clang__ - BROWSEINFO bi; -#endif - - id = LOWORD(wParam) & 0x00ff; - - switch (LOWORD(wParam) & 0xff00) { - case IDM_CASSETTE_IMAGE_NEW: - ret = file_dlg_st(hwnd, IDS_2150, "", NULL, 1); - if (!ret) { - if (strlen(openfilestring) == 0) - cassette_mount(NULL, wp); - else - cassette_mount(openfilestring, wp); - } - break; - - case IDM_CASSETTE_RECORD: - pc_cas_set_mode(cassette, 1); - CheckMenuItem(menus[CASSETTE_FIRST], IDM_CASSETTE_RECORD, MF_BYCOMMAND | MF_CHECKED); - CheckMenuItem(menus[CASSETTE_FIRST], IDM_CASSETTE_PLAY, MF_BYCOMMAND | MF_UNCHECKED); - break; - case IDM_CASSETTE_PLAY: - pc_cas_set_mode(cassette, 0); - CheckMenuItem(menus[CASSETTE_FIRST], IDM_CASSETTE_RECORD, MF_BYCOMMAND | MF_UNCHECKED); - CheckMenuItem(menus[CASSETTE_FIRST], IDM_CASSETTE_PLAY, MF_BYCOMMAND | MF_CHECKED); - break; - case IDM_CASSETTE_REWIND: - pc_cas_rewind(cassette); - break; - case IDM_CASSETTE_FAST_FORWARD: - pc_cas_append(cassette); - break; - - case IDM_CASSETTE_IMAGE_EXISTING_WP: - wp = 1; - /* FALLTHROUGH */ - case IDM_CASSETTE_IMAGE_EXISTING: - ret = file_dlg_st(hwnd, IDS_2150, cassette_fname, NULL, 0); - if (!ret) { - if (strlen(openfilestring) == 0) - cassette_mount(NULL, wp); - else - cassette_mount(openfilestring, wp); - } - break; - - case IDM_CASSETTE_EJECT: - cassette_eject(); - break; - - case IDM_CARTRIDGE_IMAGE: - ret = file_dlg_st(hwnd, IDS_2152, cart_fns[id], NULL, 0); - if (!ret) - cartridge_mount(id, openfilestring, wp); - break; - - case IDM_CARTRIDGE_EJECT: - cartridge_eject(id); - break; - - case IDM_FLOPPY_IMAGE_NEW: - NewFloppyDialogCreate(hwnd, id, 0); - break; - - case IDM_FLOPPY_IMAGE_EXISTING_WP: - wp = 1; - /* FALLTHROUGH */ - case IDM_FLOPPY_IMAGE_EXISTING: - ret = file_dlg_st(hwnd, IDS_2110, floppyfns[id], NULL, 0); - if (!ret) - floppy_mount(id, openfilestring, wp); - break; - - case IDM_FLOPPY_EJECT: - floppy_eject(id); - break; - - case IDM_FLOPPY_EXPORT_TO_86F: - ret = file_dlg_st(hwnd, IDS_2076, floppyfns[id], NULL, 1); - if (!ret) { - plat_pause(1); - ret = d86f_export(id, openfilestring); - if (!ret) - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_4108, (wchar_t *) IDS_4115); - plat_pause(0); - } - break; - - case IDM_CDROM_MUTE: - cdrom[id].sound_on ^= 1; - config_save(); - media_menu_update_cdrom(id); - sound_cd_thread_reset(); - break; - - case IDM_CDROM_EMPTY: - cdrom_eject(id); - break; - - case IDM_CDROM_RELOAD: - cdrom_reload(id); - break; - - case IDM_CDROM_IMAGE: - if (!file_dlg_st(hwnd, IDS_2141, cdrom[id].is_dir ? NULL : cdrom[id].image_path, NULL, 0)) { - cdrom_mount(id, openfilestring); - } - break; - - case IDM_CDROM_DIR: -#ifndef __clang__ - BROWSEINFO bi = { - .hwndOwner = hwnd, - .ulFlags = BIF_EDITBOX - }; -#else - bi.hwndOwner = hwnd; - bi.ulFlags = BIF_EDITBOX; -#endif - OleInitialize(NULL); - int old_dopause = dopause; - plat_pause(1); - LPITEMIDLIST pidl = SHBrowseForFolder(&bi); - plat_pause(old_dopause); - plat_chdir(usr_path); - if (pidl) { - wchar_t wbuf[MAX_PATH + 1]; - if (SHGetPathFromIDList(pidl, wbuf)) { - char buf[MAX_PATH + 1]; - c16stombs(buf, wbuf, sizeof(buf) - 1); - cdrom_mount(id, buf); - } - } - break; - - case IDM_ZIP_IMAGE_NEW: - NewFloppyDialogCreate(hwnd, id | 0x80, 0); /* NewZIPDialogCreate */ - break; - - case IDM_ZIP_IMAGE_EXISTING_WP: - wp = 1; - /* FALLTHROUGH */ - case IDM_ZIP_IMAGE_EXISTING: - ret = file_dlg_st(hwnd, IDS_2058, zip_drives[id].image_path, NULL, 0); - if (!ret) - zip_mount(id, openfilestring, wp); - break; - - case IDM_ZIP_EJECT: - zip_eject(id); - break; - - case IDM_ZIP_RELOAD: - zip_reload(id); - break; - - case IDM_MO_IMAGE_NEW: - NewFloppyDialogCreate(hwnd, id | 0x100, 0); /* NewZIPDialogCreate */ - break; - - case IDM_MO_IMAGE_EXISTING_WP: - wp = 1; - /* FALLTHROUGH */ - case IDM_MO_IMAGE_EXISTING: - ret = file_dlg_st(hwnd, IDS_2117, mo_drives[id].image_path, NULL, 0); - if (!ret) - mo_mount(id, openfilestring, wp); - break; - - case IDM_MO_EJECT: - mo_eject(id); - break; - - case IDM_MO_RELOAD: - mo_reload(id); - break; - - default: - return 0; - } - - return 1; -} - -HMENU -media_menu_get_cassette(void) -{ - return menus[CASSETTE_FIRST]; -} - -HMENU -media_menu_get_cartridge(int id) -{ - return menus[CARTRIDGE_FIRST + id]; -} - -HMENU -media_menu_get_floppy(int id) -{ - return menus[FDD_FIRST + id]; -} - -HMENU -media_menu_get_cdrom(int id) -{ - return menus[CDROM_FIRST + id]; -} - -HMENU -media_menu_get_zip(int id) -{ - return menus[ZIP_FIRST + id]; -} - -HMENU -media_menu_get_mo(int id) -{ - return menus[MO_FIRST + id]; -} diff --git a/src/win/win_mouse.c b/src/win/win_mouse.c deleted file mode 100644 index f2b185eaa..000000000 --- a/src/win/win_mouse.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * RawInput mouse interface. - * - * - * - * Authors: Miran Grca, - * GH Cao, - * Jasmine Iwanek, - * - * Copyright 2016-2017 Miran Grca. - * Copyright 2019 GH Cao. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/mouse.h> -#include <86box/pic.h> -#include <86box/plat.h> -#include <86box/win.h> - -int mouse_capture; - -void -win_mouse_init(void) -{ - atexit(win_mouse_close); - - mouse_capture = 0; - - /* Initialize the RawInput (mouse) module. */ - RAWINPUTDEVICE ridev; - ridev.dwFlags = 0; - ridev.hwndTarget = NULL; - ridev.usUsagePage = 0x01; - ridev.usUsage = 0x02; - if (!RegisterRawInputDevices(&ridev, 1, sizeof(ridev))) - fatal("plat_mouse_init: RegisterRawInputDevices failed\n"); -} - -void -win_mouse_handle(PRAWINPUT raw) -{ - RAWMOUSE state = raw->data.mouse; - static int x; - static int delta_x; - static int y; - static int delta_y; - static int b; - static int delta_z; - - b = mouse_get_buttons_ex(); - - /* read mouse buttons and wheel */ - if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) - b |= 1; - else if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP) - b &= ~1; - - if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN) - b |= 4; - else if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_UP) - b &= ~4; - - if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN) - b |= 2; - else if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP) - b &= ~2; - - if (state.usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) - b |= 8; - else if (state.usButtonFlags & RI_MOUSE_BUTTON_4_UP) - b &= ~8; - - if (state.usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) - b |= 16; - else if (state.usButtonFlags & RI_MOUSE_BUTTON_5_UP) - b &= ~16; - - mouse_set_buttons_ex(b); - - if (state.usButtonFlags & RI_MOUSE_WHEEL) { - delta_z = (SHORT) state.usButtonData / 120; - mouse_set_z(delta_z); - } else - delta_z = 0; - - if (state.usFlags & MOUSE_MOVE_ABSOLUTE) { - /* absolute mouse, i.e. RDP or VNC - * seems to work fine for RDP on Windows 10 - * Not sure about other environments. - */ - delta_x = (state.lLastX - x) / 25; - delta_y = (state.lLastY - y) / 25; - x = state.lLastX; - y = state.lLastY; - } else { - /* relative mouse, i.e. regular mouse */ - delta_x = state.lLastX; - delta_y = state.lLastY; - } - - mouse_scale(delta_x, delta_y); -} - -void -win_mouse_close(void) -{ - RAWINPUTDEVICE ridev; - ridev.dwFlags = RIDEV_REMOVE; - ridev.hwndTarget = NULL; - ridev.usUsagePage = 0x01; - ridev.usUsage = 0x02; - RegisterRawInputDevices(&ridev, 1, sizeof(ridev)); -} diff --git a/src/win/win_new_floppy.c b/src/win/win_new_floppy.c deleted file mode 100644 index d0a245a45..000000000 --- a/src/win/win_new_floppy.c +++ /dev/null @@ -1,842 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Handle the New Floppy Image dialog. - * - * - * - * Authors: Miran Grca, - * - * Copyright 2016-2019 Miran Grca. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP -#include -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/disksizes.h> -#include <86box/plat.h> -#include <86box/random.h> -#include <86box/ui.h> -#include <86box/scsi_device.h> -#include <86box/mo.h> -#include <86box/zip.h> -#include <86box/win.h> - -static unsigned char *empty; - -static int -create_86f(char *file_name, disk_size_t disk_size, uint8_t rpm_mode) -{ - FILE *fp; - - uint32_t magic = 0x46423638; - uint16_t version = 0x020C; - uint16_t dflags = 0; - uint16_t tflags = 0; - uint32_t index_hole_pos = 0; - uint32_t tarray[512]; - uint32_t array_size; - uint32_t track_base; - uint32_t track_size; - int i; - uint32_t shift = 0; - - dflags = 0; /* Has surface data? - Assume no for now. */ - dflags |= (disk_size.hole << 1); /* Hole */ - dflags |= ((disk_size.sides - 1) << 3); /* Sides. */ - dflags |= (0 << 4); /* Write protect? - Assume no for now. */ - dflags |= (rpm_mode << 5); /* RPM mode. */ - dflags |= (0 << 7); /* Has extra bit cells? - Assume no for now. */ - - tflags = disk_size.data_rate; /* Data rate. */ - tflags |= (disk_size.encoding << 3); /* Encoding. */ - tflags |= (disk_size.rpm << 5); /* RPM. */ - - switch (disk_size.hole) { - default: - case 0: - case 1: - switch (rpm_mode) { - case 1: - array_size = 25250; - break; - case 2: - array_size = 25374; - break; - case 3: - array_size = 25750; - break; - default: - array_size = 25000; - break; - } - break; - case 2: - switch (rpm_mode) { - case 1: - array_size = 50500; - break; - case 2: - array_size = 50750; - break; - case 3: - array_size = 51000; - break; - default: - array_size = 50000; - break; - } - break; - } - - empty = (unsigned char *) malloc(array_size); - - memset(tarray, 0, 2048); - memset(empty, 0, array_size); - - fp = plat_fopen(file_name, "wb"); - if (!fp) - return 0; - - fwrite(&magic, 4, 1, fp); - fwrite(&version, 2, 1, fp); - fwrite(&dflags, 2, 1, fp); - - track_size = array_size + 6; - - track_base = 8 + ((disk_size.sides == 2) ? 2048 : 1024); - - if (disk_size.tracks <= 43) - shift = 1; - - for (i = 0; i < (disk_size.tracks * disk_size.sides) << shift; i++) - tarray[i] = track_base + (i * track_size); - - fwrite(tarray, 1, (disk_size.sides == 2) ? 2048 : 1024, fp); - - for (i = 0; i < (disk_size.tracks * disk_size.sides) << shift; i++) { - fwrite(&tflags, 2, 1, fp); - fwrite(&index_hole_pos, 4, 1, fp); - fwrite(empty, 1, array_size, fp); - } - - free(empty); - - fclose(fp); - - return 1; -} - -static int is_zip; -static int is_mo; - -static int -create_sector_image(char *file_name, disk_size_t disk_size, uint8_t is_fdi) -{ - FILE *fp; - uint32_t total_size = 0; - uint32_t total_sectors = 0; - uint32_t sector_bytes = 0; - uint32_t root_dir_bytes = 0; - uint32_t fat_size = 0; - uint32_t fat1_offs = 0; - uint32_t fat2_offs = 0; - uint32_t zero_bytes = 0; - uint16_t base = 0x1000; - - fp = plat_fopen(file_name, "wb"); - if (!fp) - return 0; - - sector_bytes = (128 << disk_size.sector_len); - total_sectors = disk_size.sides * disk_size.tracks * disk_size.sectors; - if (total_sectors > ZIP_SECTORS) - total_sectors = ZIP_250_SECTORS; - total_size = total_sectors * sector_bytes; - root_dir_bytes = (disk_size.root_dir_entries << 5); - fat_size = (disk_size.spfat * sector_bytes); - fat1_offs = sector_bytes; - fat2_offs = fat1_offs + fat_size; - zero_bytes = fat2_offs + fat_size + root_dir_bytes; - - if (!is_zip && !is_mo && is_fdi) { - empty = (unsigned char *) malloc(base); - memset(empty, 0, base); - - *(uint32_t *) &(empty[0x08]) = (uint32_t) base; - *(uint32_t *) &(empty[0x0C]) = total_size; - *(uint16_t *) &(empty[0x10]) = (uint16_t) sector_bytes; - *(uint8_t *) &(empty[0x14]) = (uint8_t) disk_size.sectors; - *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sides; - *(uint8_t *) &(empty[0x1C]) = (uint8_t) disk_size.tracks; - - fwrite(empty, 1, base, fp); - free(empty); - } - - empty = (unsigned char *) malloc(total_size); - memset(empty, 0x00, zero_bytes); - - if (!is_zip && !is_mo) { - memset(empty + zero_bytes, 0xF6, total_size - zero_bytes); - - empty[0x00] = 0xEB; /* Jump to make MS-DOS happy. */ - empty[0x01] = 0x58; - empty[0x02] = 0x90; - - empty[0x03] = 0x38; /* '86BOX5.0' OEM ID. */ - empty[0x04] = 0x36; - empty[0x05] = 0x42; - empty[0x06] = 0x4F; - empty[0x07] = 0x58; - empty[0x08] = 0x35; - empty[0x09] = 0x2E; - empty[0x0A] = 0x30; - - *(uint16_t *) &(empty[0x0B]) = (uint16_t) sector_bytes; - *(uint8_t *) &(empty[0x0D]) = (uint8_t) disk_size.spc; - *(uint16_t *) &(empty[0x0E]) = (uint16_t) 1; - *(uint8_t *) &(empty[0x10]) = (uint8_t) disk_size.num_fats; - *(uint16_t *) &(empty[0x11]) = (uint16_t) disk_size.root_dir_entries; - *(uint16_t *) &(empty[0x13]) = (uint16_t) total_sectors; - *(uint8_t *) &(empty[0x15]) = (uint8_t) disk_size.media_desc; - *(uint16_t *) &(empty[0x16]) = (uint16_t) disk_size.spfat; - *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sectors; - *(uint8_t *) &(empty[0x1A]) = (uint8_t) disk_size.sides; - - empty[0x26] = 0x29; /* ')' followed by randomly-generated volume serial number. */ - empty[0x27] = random_generate(); - empty[0x28] = random_generate(); - empty[0x29] = random_generate(); - empty[0x2A] = random_generate(); - - memset(&(empty[0x2B]), 0x20, 11); - - empty[0x36] = 'F'; - empty[0x37] = 'A'; - empty[0x38] = 'T'; - empty[0x39] = '1'; - empty[0x3A] = '2'; - memset(&(empty[0x3B]), 0x20, 0x0003); - - empty[0x1FE] = 0x55; - empty[0x1FF] = 0xAA; - - empty[fat1_offs + 0x00] = empty[fat2_offs + 0x00] = empty[0x15]; - empty[fat1_offs + 0x01] = empty[fat2_offs + 0x01] = 0xFF; - empty[fat1_offs + 0x02] = empty[fat2_offs + 0x02] = 0xFF; - } - - fwrite(empty, 1, total_size, fp); - free(empty); - - fclose(fp); - - return 1; -} - -static int -create_zip_sector_image(char *file_name, disk_size_t disk_size, uint8_t is_zdi, HWND hwnd) -{ - HWND h; - FILE *fp; - uint32_t total_size = 0; - uint32_t total_sectors = 0; - uint32_t sector_bytes = 0; - uint32_t root_dir_bytes = 0; - uint32_t fat_size = 0; - uint32_t fat1_offs = 0; - uint32_t fat2_offs = 0; - uint32_t zero_bytes = 0; - uint16_t base = 0x1000; - uint32_t pbar_max = 0; - MSG msg; - - fp = plat_fopen(file_name, "wb"); - if (!fp) - return 0; - - sector_bytes = (128 << disk_size.sector_len); - total_sectors = disk_size.sides * disk_size.tracks * disk_size.sectors; - if (total_sectors > ZIP_SECTORS) - total_sectors = ZIP_250_SECTORS; - total_size = total_sectors * sector_bytes; - root_dir_bytes = (disk_size.root_dir_entries << 5); - fat_size = (disk_size.spfat * sector_bytes); - fat1_offs = sector_bytes; - fat2_offs = fat1_offs + fat_size; - zero_bytes = fat2_offs + fat_size + root_dir_bytes; - - pbar_max = total_size; - if (is_zdi) - pbar_max += base; - pbar_max >>= 11; - pbar_max--; - - h = GetDlgItem(hwnd, IDC_COMBO_RPM_MODE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - h = GetDlgItem(hwnd, IDT_FLP_RPM_MODE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - h = GetDlgItem(hwnd, IDC_PBAR_IMG_CREATE); - SendMessage(h, PBM_SETRANGE32, (WPARAM) 0, (LPARAM) pbar_max); - SendMessage(h, PBM_SETPOS, (WPARAM) 0, (LPARAM) 0); - EnableWindow(h, TRUE); - ShowWindow(h, SW_SHOW); - h = GetDlgItem(hwnd, IDT_FLP_PROGRESS); - EnableWindow(h, TRUE); - ShowWindow(h, SW_SHOW); - - h = GetDlgItem(hwnd, IDC_PBAR_IMG_CREATE); - pbar_max++; - - if (is_zdi) { - empty = (unsigned char *) malloc(base); - memset(empty, 0, base); - - *(uint32_t *) &(empty[0x08]) = (uint32_t) base; - *(uint32_t *) &(empty[0x0C]) = total_size; - *(uint16_t *) &(empty[0x10]) = (uint16_t) sector_bytes; - *(uint8_t *) &(empty[0x14]) = (uint8_t) disk_size.sectors; - *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sides; - *(uint8_t *) &(empty[0x1C]) = (uint8_t) disk_size.tracks; - - fwrite(empty, 1, 2048, fp); - SendMessage(h, PBM_SETPOS, (WPARAM) 1, (LPARAM) 0); - - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - fwrite(&empty[0x0800], 1, 2048, fp); - free(empty); - - SendMessage(h, PBM_SETPOS, (WPARAM) 2, (LPARAM) 0); - - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - pbar_max -= 2; - } - - empty = (unsigned char *) malloc(total_size); - memset(empty, 0x00, zero_bytes); - - if (total_sectors == ZIP_SECTORS) { - /* ZIP 100 */ - /* MBR */ - *(uint64_t *) &(empty[0x0000]) = 0x2054524150492EEBLL; - *(uint64_t *) &(empty[0x0008]) = 0x3930302065646F63LL; - *(uint64_t *) &(empty[0x0010]) = 0x67656D6F49202D20LL; - *(uint64_t *) &(empty[0x0018]) = 0x726F70726F432061LL; - *(uint64_t *) &(empty[0x0020]) = 0x202D206E6F697461LL; - *(uint64_t *) &(empty[0x0028]) = 0x30392F33322F3131LL; - - *(uint64_t *) &(empty[0x01AE]) = 0x0116010100E90644LL; - *(uint64_t *) &(empty[0x01B6]) = 0xED08BBE5014E0135LL; - *(uint64_t *) &(empty[0x01BE]) = 0xFFFFFE06FFFFFE80LL; - *(uint64_t *) &(empty[0x01C6]) = 0x0002FFE000000020LL; - - *(uint16_t *) &(empty[0x01FE]) = 0xAA55; - - /* 31 sectors filled with 0x48 */ - memset(&(empty[0x0200]), 0x48, 0x3E00); - - /* Boot sector */ - *(uint64_t *) &(empty[0x4000]) = 0x584F4236389058EBLL; - *(uint64_t *) &(empty[0x4008]) = 0x0008040200302E35LL; - *(uint64_t *) &(empty[0x4010]) = 0x00C0F80000020002LL; - *(uint64_t *) &(empty[0x4018]) = 0x0000002000FF003FLL; - *(uint32_t *) &(empty[0x4020]) = 0x0002FFE0; - *(uint16_t *) &(empty[0x4024]) = 0x0080; - - empty[0x4026] = 0x29; /* ')' followed by randomly-generated volume serial number. */ - empty[0x4027] = random_generate(); - empty[0x4028] = random_generate(); - empty[0x4029] = random_generate(); - empty[0x402A] = random_generate(); - - memset(&(empty[0x402B]), 0x00, 0x000B); - memset(&(empty[0x4036]), 0x20, 0x0008); - - empty[0x4036] = 'F'; - empty[0x4037] = 'A'; - empty[0x4038] = 'T'; - empty[0x4039] = '1'; - empty[0x403A] = '6'; - memset(&(empty[0x403B]), 0x20, 0x0003); - - empty[0x41FE] = 0x55; - empty[0x41FF] = 0xAA; - - empty[0x5000] = empty[0x1D000] = empty[0x4015]; - empty[0x5001] = empty[0x1D001] = 0xFF; - empty[0x5002] = empty[0x1D002] = 0xFF; - empty[0x5003] = empty[0x1D003] = 0xFF; - - /* Root directory = 0x35000 - Data = 0x39000 */ - } else { - /* ZIP 250 */ - /* MBR */ - *(uint64_t *) &(empty[0x0000]) = 0x2054524150492EEBLL; - *(uint64_t *) &(empty[0x0008]) = 0x3930302065646F63LL; - *(uint64_t *) &(empty[0x0010]) = 0x67656D6F49202D20LL; - *(uint64_t *) &(empty[0x0018]) = 0x726F70726F432061LL; - *(uint64_t *) &(empty[0x0020]) = 0x202D206E6F697461LL; - *(uint64_t *) &(empty[0x0028]) = 0x30392F33322F3131LL; - - *(uint64_t *) &(empty[0x01AE]) = 0x0116010100E900E9LL; - *(uint64_t *) &(empty[0x01B6]) = 0x2E32A7AC014E0135LL; - - *(uint64_t *) &(empty[0x01EE]) = 0xEE203F0600010180LL; - *(uint64_t *) &(empty[0x01F6]) = 0x000777E000000020LL; - *(uint16_t *) &(empty[0x01FE]) = 0xAA55; - - /* 31 sectors filled with 0x48 */ - memset(&(empty[0x0200]), 0x48, 0x3E00); - - /* The second sector begins with some strange data - in my reference image. */ - *(uint64_t *) &(empty[0x0200]) = 0x3831393230334409LL; - *(uint64_t *) &(empty[0x0208]) = 0x6A57766964483130LL; - *(uint64_t *) &(empty[0x0210]) = 0x3C3A34676063653FLL; - *(uint64_t *) &(empty[0x0218]) = 0x586A56A8502C4161LL; - *(uint64_t *) &(empty[0x0220]) = 0x6F2D702535673D6CLL; - *(uint64_t *) &(empty[0x0228]) = 0x255421B8602D3456LL; - *(uint64_t *) &(empty[0x0230]) = 0x577B22447B52603ELL; - *(uint64_t *) &(empty[0x0238]) = 0x46412CC871396170LL; - *(uint64_t *) &(empty[0x0240]) = 0x704F55237C5E2626LL; - *(uint64_t *) &(empty[0x0248]) = 0x6C7932C87D5C3C20LL; - *(uint64_t *) &(empty[0x0250]) = 0x2C50503E47543D6ELL; - *(uint64_t *) &(empty[0x0258]) = 0x46394E807721536ALL; - *(uint64_t *) &(empty[0x0260]) = 0x505823223F245325LL; - *(uint64_t *) &(empty[0x0268]) = 0x365C79B0393B5B6ELL; - - /* Boot sector */ - *(uint64_t *) &(empty[0x4000]) = 0x584F4236389058EBLL; - *(uint64_t *) &(empty[0x4008]) = 0x0001080200302E35LL; - *(uint64_t *) &(empty[0x4010]) = 0x00EFF80000020002LL; - *(uint64_t *) &(empty[0x4018]) = 0x0000002000400020LL; - *(uint32_t *) &(empty[0x4020]) = 0x000777E0; - *(uint16_t *) &(empty[0x4024]) = 0x0080; - - empty[0x4026] = 0x29; /* ')' followed by randomly-generated volume serial number. */ - empty[0x4027] = random_generate(); - empty[0x4028] = random_generate(); - empty[0x4029] = random_generate(); - empty[0x402A] = random_generate(); - - memset(&(empty[0x402B]), 0x00, 0x000B); - memset(&(empty[0x4036]), 0x20, 0x0008); - - empty[0x4036] = 'F'; - empty[0x4037] = 'A'; - empty[0x4038] = 'T'; - empty[0x4039] = '1'; - empty[0x403A] = '6'; - memset(&(empty[0x403B]), 0x20, 0x0003); - - empty[0x41FE] = 0x55; - empty[0x41FF] = 0xAA; - - empty[0x4200] = empty[0x22000] = empty[0x4015]; - empty[0x4201] = empty[0x22001] = 0xFF; - empty[0x4202] = empty[0x22002] = 0xFF; - empty[0x4203] = empty[0x22003] = 0xFF; - - /* Root directory = 0x3FE00 - Data = 0x38200 */ - } - - for (uint32_t i = 0; i < pbar_max; i++) { - fwrite(&empty[i << 11], 1, 2048, fp); - SendMessage(h, PBM_SETPOS, (WPARAM) i + 2, (LPARAM) 0); - - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - free(empty); - - fclose(fp); - - return 1; -} - -static int -create_mo_sector_image(char *file_name, int8_t disk_size, uint8_t is_mdi, HWND hwnd) -{ - HWND h; - FILE *fp; - const mo_type_t *dp = &mo_types[disk_size]; - uint8_t *empty; - uint8_t *empty2 = NULL; - uint32_t total_size = 0; - uint32_t total_size2; - uint32_t total_sectors = 0; - uint32_t sector_bytes = 0; - uint16_t base = 0x1000; - uint32_t pbar_max = 0; - uint32_t blocks_num; - uint32_t j; - MSG msg; - - fp = plat_fopen(file_name, "wb"); - if (!fp) - return 0; - - sector_bytes = dp->bytes_per_sector; - total_sectors = dp->sectors; - total_size = total_sectors * sector_bytes; - - total_size2 = (total_size >> 20) << 20; - total_size2 = total_size - total_size2; - - pbar_max = total_size; - pbar_max >>= 20; - blocks_num = pbar_max; - if (is_mdi) - pbar_max++; - if (total_size2 == 0) - pbar_max++; - - j = is_mdi ? 1 : 0; - - h = GetDlgItem(hwnd, IDC_COMBO_RPM_MODE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - h = GetDlgItem(hwnd, IDT_FLP_RPM_MODE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - h = GetDlgItem(hwnd, IDC_PBAR_IMG_CREATE); - SendMessage(h, PBM_SETRANGE32, (WPARAM) 0, (LPARAM) pbar_max - 1); - SendMessage(h, PBM_SETPOS, (WPARAM) 0, (LPARAM) 0); - EnableWindow(h, TRUE); - ShowWindow(h, SW_SHOW); - h = GetDlgItem(hwnd, IDT_FLP_PROGRESS); - EnableWindow(h, TRUE); - ShowWindow(h, SW_SHOW); - - h = GetDlgItem(hwnd, IDC_PBAR_IMG_CREATE); - - if (is_mdi) { - empty = (unsigned char *) malloc(base); - memset(empty, 0, base); - - *(uint32_t *) &(empty[0x08]) = (uint32_t) base; - *(uint32_t *) &(empty[0x0C]) = total_size; - *(uint16_t *) &(empty[0x10]) = (uint16_t) sector_bytes; - *(uint8_t *) &(empty[0x14]) = (uint8_t) 25; - *(uint8_t *) &(empty[0x18]) = (uint8_t) 64; - *(uint8_t *) &(empty[0x1C]) = (uint8_t) (dp->sectors / 64) / 25; - - fwrite(empty, 1, 2048, fp); - SendMessage(h, PBM_SETPOS, (WPARAM) 1, (LPARAM) 0); - - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - fwrite(&empty[0x0800], 1, 2048, fp); - free(empty); - - SendMessage(h, PBM_SETPOS, (WPARAM) 1, (LPARAM) 0); - - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - empty = (unsigned char *) malloc(1048576); - memset(empty, 0x00, 1048576); - - if (total_size2 > 0) { - empty2 = (unsigned char *) malloc(total_size2); - memset(empty, 0x00, total_size2); - } - - for (uint32_t i = 0; i < blocks_num; i++) { - fwrite(empty, 1, 1048576, fp); - - SendMessage(h, PBM_SETPOS, (WPARAM) i + j, (LPARAM) 0); - - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - if (total_size2 > 0) { - fwrite(empty2, 1, total_size2, fp); - - SendMessage(h, PBM_SETPOS, (WPARAM) pbar_max - 1, (LPARAM) 0); - - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - if (empty2 != NULL) - free(empty2); - free(empty); - - fclose(fp); - - return 1; -} - -static int fdd_id; -static int sb_part; - -static int file_type = 0; /* 0 = IMG, 1 = Japanese FDI, 2 = 86F */ -static char fd_file_name[1024]; - -/* Show a MessageBox dialog. This is nasty, I know. --FvK */ -static int -new_floppy_msgbox_header(HWND hwnd, int flags, void *header, void *message) -{ - HWND h; - int i; - - h = hwndMain; - hwndMain = hwnd; - - i = ui_msgbox_header(flags, header, message); - - hwndMain = h; - - return i; -} - -static int -new_floppy_msgbox_ex(HWND hwnd, int flags, void *header, void *message, void *btn1, void *btn2, void *btn3) -{ - HWND h; - int i; - - h = hwndMain; - hwndMain = hwnd; - - i = ui_msgbox_ex(flags, header, message, btn1, btn2, btn3); - - hwndMain = h; - - return i; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -NewFloppyDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - HWND h; - int i = 0; - int wcs_len; - int ext_offs; - const wchar_t *ext; - uint8_t disk_size; - uint8_t rpm_mode; - int ret; - FILE *fp; - int zip_types; - int mo_types; - int floppy_types; - wchar_t *twcs; - - switch (message) { - case WM_INITDIALOG: - plat_pause(1); - memset(fd_file_name, 0, 1024); - h = GetDlgItem(hdlg, IDC_COMBO_DISK_SIZE); - if (is_zip) { - zip_types = zip_drives[fdd_id].is_250 ? 2 : 1; - for (i = 0; i < zip_types; i++) - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_5900 + i)); - } else if (is_mo) { - mo_types = 10; - /* TODO: Proper string ID's. */ - for (i = 0; i < mo_types; i++) - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_5902 + i)); - } else { - floppy_types = 12; - for (i = 0; i < floppy_types; i++) - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_5888 + i)); - } - SendMessage(h, CB_SETCURSEL, 0, 0); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_COMBO_RPM_MODE); - for (i = 0; i < 4; i++) - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_6144 + i)); - SendMessage(h, CB_SETCURSEL, 0, 0); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - h = GetDlgItem(hdlg, IDT_FLP_RPM_MODE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - h = GetDlgItem(hdlg, IDOK); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_PBAR_IMG_CREATE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - h = GetDlgItem(hdlg, IDT_FLP_PROGRESS); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - h = GetDlgItem(hdlg, IDC_COMBO_DISK_SIZE); - disk_size = SendMessage(h, CB_GETCURSEL, 0, 0); - if (is_zip) - disk_size += 12; - if (!is_zip && !is_mo && (file_type == 2)) { - h = GetDlgItem(hdlg, IDC_COMBO_RPM_MODE); - rpm_mode = SendMessage(h, CB_GETCURSEL, 0, 0); - ret = create_86f(fd_file_name, disk_sizes[disk_size], rpm_mode); - } else { - if (is_zip) - ret = create_zip_sector_image(fd_file_name, disk_sizes[disk_size], file_type, hdlg); - if (is_mo) - ret = create_mo_sector_image(fd_file_name, disk_size, file_type, hdlg); - else - ret = create_sector_image(fd_file_name, disk_sizes[disk_size], file_type); - } - if (ret) { - if (is_zip) - zip_mount(fdd_id, fd_file_name, 0); - else if (is_mo) - mo_mount(fdd_id, fd_file_name, 0); - else - floppy_mount(fdd_id, fd_file_name, 0); - } else { - new_floppy_msgbox_header(hdlg, MBX_ERROR, (wchar_t *) IDS_4108, (wchar_t *) IDS_4115); - return TRUE; - } - fallthrough; - case IDCANCEL: - EndDialog(hdlg, 0); - plat_pause(0); - return TRUE; - - case IDC_CFILE: - if (!file_dlg_w(hdlg, plat_get_string(is_mo ? IDS_2140 : (is_zip ? IDS_2055 : IDS_2062)), L"", NULL, 1)) { - if (!wcschr(wopenfilestring, L'.')) { - if (wcslen(wopenfilestring) && (wcslen(wopenfilestring) <= 256)) { - twcs = &wopenfilestring[wcslen(wopenfilestring)]; - twcs[0] = L'.'; - if (!is_zip && !is_mo && (filterindex == 3)) { - twcs[1] = L'8'; - twcs[2] = L'6'; - twcs[3] = L'f'; - } else { - twcs[1] = L'i'; - twcs[2] = L'm'; - twcs[3] = L'g'; - } - } - } - h = GetDlgItem(hdlg, IDC_EDIT_FILE_NAME); - fp = _wfopen(wopenfilestring, L"rb"); - if (fp != NULL) { - fclose(fp); - if (new_floppy_msgbox_ex(hdlg, MBX_QUESTION, (wchar_t *) IDS_4111, (wchar_t *) IDS_4118, (wchar_t *) IDS_4120, (wchar_t *) IDS_4121, NULL) != 0) /* yes */ - return FALSE; - } - SendMessage(h, WM_SETTEXT, 0, (LPARAM) wopenfilestring); - memset(fd_file_name, 0, sizeof(fd_file_name)); - c16stombs(fd_file_name, wopenfilestring, sizeof(fd_file_name)); - h = GetDlgItem(hdlg, IDC_COMBO_DISK_SIZE); - if (!is_zip || zip_drives[fdd_id].is_250) - EnableWindow(h, TRUE); - wcs_len = wcslen(wopenfilestring); - ext_offs = wcs_len - 4; - ext = &(wopenfilestring[ext_offs]); - if (is_zip) { - if ((wcs_len >= 4) && !wcsicmp(ext, L".ZDI")) - file_type = 1; - else - file_type = 0; - } else if (is_mo) { - if ((wcs_len >= 4) && !wcsicmp(ext, L".MDI")) - file_type = 1; - else - file_type = 0; - } else { - if ((wcs_len >= 4) && !wcsicmp(ext, L".FDI")) - file_type = 1; - else if (((wcs_len >= 4) && !wcsicmp(ext, L".86F")) || (filterindex == 3)) - file_type = 2; - else - file_type = 0; - } - h = GetDlgItem(hdlg, IDT_FLP_RPM_MODE); - if (file_type == 2) { - EnableWindow(h, TRUE); - ShowWindow(h, SW_SHOW); - } else { - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - } - h = GetDlgItem(hdlg, IDC_COMBO_RPM_MODE); - if (file_type == 2) { - EnableWindow(h, TRUE); - ShowWindow(h, SW_SHOW); - } else { - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - } - h = GetDlgItem(hdlg, IDOK); - EnableWindow(h, TRUE); - return TRUE; - } else - return FALSE; - - default: - break; - } - break; - } - - return FALSE; -} - -void -NewFloppyDialogCreate(HWND hwnd, int id, int part) -{ - fdd_id = id & 0x7f; - sb_part = part; - is_zip = !!(id & 0x80); - is_mo = !!(id & 0x100); - if (is_zip && is_mo) { - fatal("Attempting to create a new image dialog that is for both ZIP and MO at the same time\n"); - return; - } - DialogBox(hinstance, (LPCTSTR) DLG_NEW_FLOPPY, hwnd, NewFloppyDialogProcedure); -} diff --git a/src/win/win_opengl.c b/src/win/win_opengl.c deleted file mode 100644 index 094b3d063..000000000 --- a/src/win/win_opengl.c +++ /dev/null @@ -1,1002 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Rendering module for OpenGL - * - * TODO: More shader features - * - scaling - * - multipass - * - previous frames - * (UI) options - * More error handling - * - * - * - * Authors: Teemu Korhonen - * - * Copyright 2021 Teemu Korhonen - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#define UNICODE -#include -#include -#include -#include -#include - -#include -#include -#include - -#if !defined(_MSC_VER) || defined(__clang__) -# include -#else -typedef LONG atomic_flag; -# define atomic_flag_clear(OBJ) InterlockedExchange(OBJ, 0) -# define atomic_flag_test_and_set(OBJ) InterlockedExchange(OBJ, 1) -#endif - -#include <86box/86box.h> -#include <86box/plat.h> -#include <86box/thread.h> -#include <86box/video.h> -#include <86box/win.h> -#include <86box/language.h> -#include <86box/win_opengl.h> -#include <86box/win_opengl_glslp.h> - -static const int INIT_WIDTH = 640; -static const int INIT_HEIGHT = 400; -static const int BUFFERPIXELS = 4194304; /* Same size as render_buffer, pow(2048 + 64, 2). */ -static const int BUFFERBYTES = 16777216; /* Pixel is 4 bytes. */ -static const int BUFFERCOUNT = 3; /* How many buffers to use for pixel transfer (2-3 is commonly recommended). */ -static const int ROW_LENGTH = 2048; /* Source buffer row lenght (including padding) */ - -/** - * @brief A dedicated OpenGL thread. - * OpenGL context's don't handle multiple threads well. - */ -static thread_t *thread = NULL; - -/** - * @brief A window usable with an OpenGL context - */ -static SDL_Window *window = NULL; - -/** - * @brief SDL window handle - */ -static HWND window_hwnd = NULL; - -/** - * @brief Parent window handle (hwndRender from win_ui) - */ -static HWND parent = NULL; - -/** - * @brief Events listened in OpenGL thread. - */ -static union { - struct - { - HANDLE closing; - HANDLE resize; - HANDLE reload; - HANDLE blit_waiting; - }; - HANDLE asArray[4]; -} sync_objects = { 0 }; - -/** - * @brief Blit event parameters. - */ -typedef struct -{ - int w, h; - void *buffer; /* Buffer for pixel transfer, allocated by gpu driver. */ - volatile atomic_flag in_use; /* Is buffer currently in use. */ - GLsync sync; /* Fence sync object used by opengl thread to track pixel transfer completion. */ -} blit_info_t; - -/** - * @brief Array of blit_infos, one for each buffer. - */ -static blit_info_t *blit_info = NULL; - -/** - * @brief Buffer index of next write operation. - */ -static int write_pos = 0; - -/** - * @brief Resize event parameters. - */ -static struct -{ - int width, height, fullscreen, scaling_mode; - mutex_t *mutex; -} resize_info = { 0 }; - -/** - * @brief Renderer options - */ -static struct -{ - int vsync; /* Vertical sync; 0 = off, 1 = on */ - int frametime; /* Frametime in microseconds, or -1 to sync with blitter */ - char shaderfile[512]; /* Shader file path. Match the length of openfilestring in win_dialog.c */ - int shaderfile_changed; /* Has shader file path changed. To prevent unnecessary shader recompilation. */ - int filter; /* 0 = Nearest, 1 = Linear */ - int filter_changed; /* Has filter changed. */ - mutex_t *mutex; -} options = { 0 }; - -/** - * @brief Identifiers to OpenGL objects and uniforms. - */ -typedef struct -{ - GLuint vertexArrayID; - GLuint vertexBufferID; - GLuint textureID; - GLuint unpackBufferID; - GLuint shader_progID; - - /* Uniforms */ - - GLint input_size; - GLint output_size; - GLint texture_size; - GLint frame_count; -} gl_identifiers; - -/** - * @brief Set or unset OpenGL context window as a child window. - * - * Modifies the window style and sets the parent window. - * WS_EX_NOACTIVATE keeps the window from stealing input focus. - */ -static void -set_parent_binding(int enable) -{ - long style = GetWindowLong(window_hwnd, GWL_STYLE); - long ex_style = GetWindowLong(window_hwnd, GWL_EXSTYLE); - - if (enable) { - style |= WS_CHILD; - ex_style |= WS_EX_NOACTIVATE; - } else { - style &= ~WS_CHILD; - ex_style &= ~WS_EX_NOACTIVATE; - } - - SetWindowLong(window_hwnd, GWL_STYLE, style); - SetWindowLong(window_hwnd, GWL_EXSTYLE, ex_style); - - SetParent(window_hwnd, enable ? parent : NULL); -} - -/** - * @brief Windows message handler for our window. - * @param message - * @param wParam - * @param lParam - * @param fullscreen - * @return Was message handled - */ -static int -handle_window_messages(UINT message, WPARAM wParam, LPARAM lParam, int fullscreen) -{ - switch (message) { - case WM_LBUTTONUP: - case WM_LBUTTONDOWN: - case WM_MBUTTONUP: - case WM_MBUTTONDOWN: - case WM_RBUTTONUP: - case WM_RBUTTONDOWN: - if (!fullscreen) { - /* Bring main window to front. */ - SetForegroundWindow(GetAncestor(parent, GA_ROOT)); - - /* Mouse events that enter and exit capture. */ - PostMessage(parent, message, wParam, lParam); - } - return 1; - case WM_KEYDOWN: - case WM_KEYUP: - case WM_SYSKEYDOWN: - case WM_SYSKEYUP: - if (fullscreen) { - PostMessage(parent, message, wParam, lParam); - } - return 1; - case WM_INPUT: - if (fullscreen) { - /* Raw input handler from win_ui.c : input_proc */ - - UINT size = 0; - PRAWINPUT raw = NULL; - - /* Here we read the raw input data */ - GetRawInputData((HRAWINPUT) lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); - raw = (PRAWINPUT) malloc(size); - if (GetRawInputData((HRAWINPUT) lParam, RID_INPUT, raw, &size, sizeof(RAWINPUTHEADER)) == size) { - switch (raw->header.dwType) { - case RIM_TYPEKEYBOARD: - keyboard_handle(raw); - break; - case RIM_TYPEMOUSE: - win_mouse_handle(raw); - break; - case RIM_TYPEHID: - win_joystick_handle(raw); - break; - } - } - free(raw); - } - return 1; - case WM_MOUSELEAVE: - if (fullscreen) { - /* Leave fullscreen if mouse leaves the renderer window. */ - PostMessage(GetAncestor(parent, GA_ROOT), WM_LEAVEFULLSCREEN, 0, 0); - } - return 0; - } - - return 0; -} - -/** - * @brief (Re-)apply shaders to OpenGL context. - * @param gl Identifiers from initialize - */ -static void -apply_shaders(gl_identifiers *gl) -{ - GLuint old_shader_ID = 0; - - if (gl->shader_progID != 0) - old_shader_ID = gl->shader_progID; - - if (strlen(options.shaderfile) > 0) - gl->shader_progID = load_custom_shaders(options.shaderfile); - else - gl->shader_progID = 0; - - if (gl->shader_progID == 0) - gl->shader_progID = load_default_shaders(); - - glUseProgram(gl->shader_progID); - - /* Delete old shader if one exists (changing shader) */ - if (old_shader_ID != 0) - glDeleteProgram(old_shader_ID); - - GLint vertex_coord = glGetAttribLocation(gl->shader_progID, "VertexCoord"); - if (vertex_coord != -1) { - glEnableVertexAttribArray(vertex_coord); - glVertexAttribPointer(vertex_coord, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), 0); - } - - GLint tex_coord = glGetAttribLocation(gl->shader_progID, "TexCoord"); - if (tex_coord != -1) { - glEnableVertexAttribArray(tex_coord); - glVertexAttribPointer(tex_coord, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void *) (2 * sizeof(GLfloat))); - } - - GLint color = glGetAttribLocation(gl->shader_progID, "Color"); - if (color != -1) { - glEnableVertexAttribArray(color); - glVertexAttribPointer(color, 4, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void *) (4 * sizeof(GLfloat))); - } - - GLint mvp_matrix = glGetUniformLocation(gl->shader_progID, "MVPMatrix"); - if (mvp_matrix != -1) { - static const GLfloat mvp[] = { - 1.f, 0.f, 0.f, 0.f, - 0.f, 1.f, 0.f, 0.f, - 0.f, 0.f, 1.f, 0.f, - 0.f, 0.f, 0.f, 1.f - }; - glUniformMatrix4fv(mvp_matrix, 1, GL_FALSE, mvp); - } - - GLint frame_direction = glGetUniformLocation(gl->shader_progID, "FrameDirection"); - if (frame_direction != -1) - glUniform1i(frame_direction, 1); /* always forward */ - - gl->input_size = glGetUniformLocation(gl->shader_progID, "InputSize"); - gl->output_size = glGetUniformLocation(gl->shader_progID, "OutputSize"); - gl->texture_size = glGetUniformLocation(gl->shader_progID, "TextureSize"); - gl->frame_count = glGetUniformLocation(gl->shader_progID, "FrameCount"); -} - -/** - * @brief Initialize OpenGL context - * @return Identifiers - */ -static int -initialize_glcontext(gl_identifiers *gl) -{ - /* Vertex, texture 2d coordinates and color (white) making a quad as triangle strip */ - static const GLfloat surface[] = { - -1.f, 1.f, 0.f, 0.f, 1.f, 1.f, 1.f, 1.f, - 1.f, 1.f, 1.f, 0.f, 1.f, 1.f, 1.f, 1.f, - -1.f, -1.f, 0.f, 1.f, 1.f, 1.f, 1.f, 1.f, - 1.f, -1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f - }; - - glGenVertexArrays(1, &gl->vertexArrayID); - - glBindVertexArray(gl->vertexArrayID); - - glGenBuffers(1, &gl->vertexBufferID); - glBindBuffer(GL_ARRAY_BUFFER, gl->vertexBufferID); - glBufferData(GL_ARRAY_BUFFER, sizeof(surface), surface, GL_STATIC_DRAW); - - glGenTextures(1, &gl->textureID); - glBindTexture(GL_TEXTURE_2D, gl->textureID); - - static const GLfloat border_color[] = { 0.f, 0.f, 0.f, 1.f }; - glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, options.filter ? GL_LINEAR : GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, options.filter ? GL_LINEAR : GL_NEAREST); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, INIT_WIDTH, INIT_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); - - glGenBuffers(1, &gl->unpackBufferID); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl->unpackBufferID); - - void *buf_ptr = NULL; - - if (GLAD_GL_ARB_buffer_storage) { - /* Create persistent buffer for pixel transfer. */ - glBufferStorage(GL_PIXEL_UNPACK_BUFFER, BUFFERBYTES * BUFFERCOUNT, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); - - buf_ptr = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, BUFFERBYTES * BUFFERCOUNT, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); - } else { - /* Fallback; create our own buffer. */ - buf_ptr = malloc(BUFFERBYTES * BUFFERCOUNT); - - glBufferData(GL_PIXEL_UNPACK_BUFFER, BUFFERBYTES * BUFFERCOUNT, NULL, GL_STREAM_DRAW); - } - - if (buf_ptr == NULL) - return 0; /* Most likely out of memory. */ - - /* Split the buffer area for each blit_info and set them available for use. */ - for (int i = 0; i < BUFFERCOUNT; i++) { - blit_info[i].buffer = (byte *) buf_ptr + BUFFERBYTES * i; - atomic_flag_clear(&blit_info[i].in_use); - } - - glClearColor(0.f, 0.f, 0.f, 1.f); - - apply_shaders(gl); - - return 1; -} - -/** - * @brief Clean up OpenGL context - * @param gl Identifiers from initialize - */ -static void -finalize_glcontext(gl_identifiers *gl) -{ - if (GLAD_GL_ARB_buffer_storage) - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); - else - free(blit_info[0].buffer); - - glDeleteProgram(gl->shader_progID); - glDeleteBuffers(1, &gl->unpackBufferID); - glDeleteTextures(1, &gl->textureID); - glDeleteBuffers(1, &gl->vertexBufferID); - glDeleteVertexArrays(1, &gl->vertexArrayID); -} - -/** - * @brief Renders a frame and swaps the buffer - * @param gl Identifiers from initialize - */ -static void -render_and_swap(gl_identifiers *gl) -{ - static int frame_counter = 0; - - glClear(GL_COLOR_BUFFER_BIT); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - SDL_GL_SwapWindow(window); - - if (gl->frame_count != -1) - glUniform1i(gl->frame_count, frame_counter = (frame_counter + 1) & 1023); -} - -/** - * @brief Handle failure in OpenGL thread. - * Keeps the thread sleeping until closing. - */ -static void -opengl_fail(void) -{ - if (window != NULL) { - SDL_DestroyWindow(window); - window = NULL; - } - - const wchar_t *message = plat_get_string(IDS_2153); - const wchar_t *header = plat_get_string(IDS_2154); - MessageBox(parent, header, message, MB_OK); - - WaitForSingleObject(sync_objects.closing, INFINITE); - - _endthread(); -} - -static void __stdcall opengl_debugmsg_callback(UNUSED(GLenum source), UNUSED(GLenum type), UNUSED(GLuint id), UNUSED(GLenum severity), UNUSED(GLsizei length), const GLchar *message, UNUSED(const void *userParam)) -{ - pclog("OpenGL: %s\n", message); -} - -/** - * @brief Main OpenGL thread proc. - * - * OpenGL context should be accessed only from this single thread. - * Events are used to synchronize communication. - */ -static void -opengl_main(UNUSED(void *param)) -{ - /* Initialize COM library for this thread before SDL does so. */ - CoInitializeEx(NULL, COINIT_MULTITHREADED); - - SDL_InitSubSystem(SDL_INIT_VIDEO); - - SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); /* Is this actually doing anything...? */ - - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - - if (GLAD_GL_ARB_debug_output && log_path[0] != '\0') - SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG | SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); - else - SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); - - window = SDL_CreateWindow("86Box OpenGL Renderer", 0, 0, resize_info.width, resize_info.height, SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS); - - if (window == NULL) { - pclog("OpenGL: failed to create OpenGL window.\n"); - opengl_fail(); - } - - /* Keep track of certain parameters, only changed in this thread to avoid race conditions */ - int fullscreen = resize_info.fullscreen; - int video_width = INIT_WIDTH; - int video_height = INIT_HEIGHT; - int output_width = resize_info.width; - int output_height = resize_info.height; - int frametime = options.frametime; - - SDL_SysWMinfo wmi = { 0 }; - SDL_VERSION(&wmi.version); - SDL_GetWindowWMInfo(window, &wmi); - - if (wmi.subsystem != SDL_SYSWM_WINDOWS) { - pclog("OpenGL: subsystem is not SDL_SYSWM_WINDOWS.\n"); - opengl_fail(); - } - - window_hwnd = wmi.info.win.window; - - if (!fullscreen) - set_parent_binding(1); - else - SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); - - SDL_GLContext context = SDL_GL_CreateContext(window); - - if (context == NULL) { - pclog("OpenGL: failed to create OpenGL context.\n"); - opengl_fail(); - } - - SDL_GL_SetSwapInterval(options.vsync); - - if (!gladLoadGLLoader(SDL_GL_GetProcAddress)) { - pclog("OpenGL: failed to set OpenGL loader.\n"); - SDL_GL_DeleteContext(context); - opengl_fail(); - } - - if (GLAD_GL_ARB_debug_output && log_path[0] != '\0') { - glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); - glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_PERFORMANCE_ARB, GL_DONT_CARE, 0, 0, GL_FALSE); - glDebugMessageCallbackARB(opengl_debugmsg_callback, NULL); - } - - pclog("OpenGL vendor: %s\n", glGetString(GL_VENDOR)); - pclog("OpenGL renderer: %s\n", glGetString(GL_RENDERER)); - pclog("OpenGL version: %s\n", glGetString(GL_VERSION)); - pclog("OpenGL shader language version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); - - /* Check that the driver actually reports version 3.0 or later */ - GLint major = -1; - glGetIntegerv(GL_MAJOR_VERSION, &major); - if (major < 3) { - pclog("OpenGL: Minimum OpenGL version 3.0 is required.\n"); - SDL_GL_DeleteContext(context); - opengl_fail(); - } - - /* Check if errors have been generated at this point */ - GLenum gl_error = glGetError(); - if (gl_error != GL_NO_ERROR) { - /* Log up to 10 errors */ - int i = 0; - do { - pclog("OpenGL: Error %u\n", gl_error); - i++; - } while ((gl_error = glGetError()) != GL_NO_ERROR && i < 10); - - SDL_GL_DeleteContext(context); - opengl_fail(); - } - - gl_identifiers gl = { 0 }; - - if (!initialize_glcontext(&gl)) { - pclog("OpenGL: failed to initialize.\n"); - finalize_glcontext(&gl); - SDL_GL_DeleteContext(context); - opengl_fail(); - } - - if (gl.frame_count != -1) - glUniform1i(gl.frame_count, 0); - if (gl.output_size != -1) - glUniform2f(gl.output_size, output_width, output_height); - - uint32_t last_swap = plat_get_micro_ticks() - frametime; - - int read_pos = 0; /* Buffer index of next read operation. */ - - /* Render loop */ - int closing = 0; - while (!closing) { - /* Rendering is done right after handling an event. */ - if (frametime < 0) - render_and_swap(&gl); - - DWORD wait_result = WAIT_TIMEOUT; - - do { - /* Rendering is timed by frame capping. */ - if (frametime >= 0) { - uint32_t ticks = plat_get_micro_ticks(); - - uint32_t elapsed = ticks - last_swap; - - if (elapsed + 1000 > frametime) { - /* Spin the remaining time (< 1ms) to next frame */ - while (elapsed < frametime) { - Sleep(0); /* Yield processor time */ - ticks = plat_get_micro_ticks(); - elapsed = ticks - last_swap; - } - - render_and_swap(&gl); - last_swap = ticks; - } - } - - if (GLAD_GL_ARB_sync) { - /* Check if commands that use buffers have been completed. */ - for (int i = 0; i < BUFFERCOUNT; i++) { - if (blit_info[i].sync != NULL && glClientWaitSync(blit_info[i].sync, GL_SYNC_FLUSH_COMMANDS_BIT, 0) != GL_TIMEOUT_EXPIRED) { - glDeleteSync(blit_info[i].sync); - blit_info[i].sync = NULL; - atomic_flag_clear(&blit_info[i].in_use); - } - } - } - - /* Handle window messages */ - MSG msg; - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - if (msg.hwnd != window_hwnd || !handle_window_messages(msg.message, msg.wParam, msg.lParam, fullscreen)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - /* Wait for synchronized events for 1ms before going back to window events */ - wait_result = WaitForMultipleObjects(sizeof(sync_objects) / sizeof(HANDLE), sync_objects.asArray, FALSE, 1); - - } while (wait_result == WAIT_TIMEOUT); - - const HANDLE sync_event = sync_objects.asArray[wait_result - WAIT_OBJECT_0]; - - if (sync_event == sync_objects.closing) { - closing = 1; - } else if (sync_event == sync_objects.blit_waiting) { - blit_info_t *info = &blit_info[read_pos]; - - if (video_width != info->w || video_height != info->h) { - video_width = info->w; - video_height = info->h; - - /* Resize the texture */ - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, video_width, video_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl.unpackBufferID); - - if (fullscreen) - SetEvent(sync_objects.resize); - } - - if (!GLAD_GL_ARB_buffer_storage) { - /* Fallback method, copy data to pixel buffer. */ - glBufferSubData(GL_PIXEL_UNPACK_BUFFER, BUFFERBYTES * read_pos, info->h * ROW_LENGTH * sizeof(uint32_t), info->buffer); - } - - /* Update texture from pixel buffer. */ - glPixelStorei(GL_UNPACK_SKIP_PIXELS, BUFFERPIXELS * read_pos); - glPixelStorei(GL_UNPACK_ROW_LENGTH, ROW_LENGTH); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, info->w, info->h, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); - - if (GLAD_GL_ARB_sync) { - /* Add fence to track when above gl commands are complete. */ - info->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - } else { - /* No sync objects; block until commands are complete. */ - glFinish(); - atomic_flag_clear(&info->in_use); - } - - read_pos = (read_pos + 1) % BUFFERCOUNT; - - /* Update uniforms */ - if (gl.input_size != -1) - glUniform2f(gl.input_size, video_width, video_height); - if (gl.texture_size != -1) - glUniform2f(gl.texture_size, video_width, video_height); - } else if (sync_event == sync_objects.resize) { - thread_wait_mutex(resize_info.mutex); - - if (fullscreen != resize_info.fullscreen) { - fullscreen = resize_info.fullscreen; - - set_parent_binding(!fullscreen); - - SDL_SetWindowFullscreen(window, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); - - if (fullscreen) { - SetForegroundWindow(window_hwnd); - SetFocus(window_hwnd); - - /* Clip cursor to prevent it moving to another monitor. */ - RECT rect; - GetWindowRect(window_hwnd, &rect); - ClipCursor(&rect); - } else - ClipCursor(NULL); - } - - if (fullscreen) { - int width; - int height; - int pad_x = 0; - int pad_y = 0; - int px_size = 1; - float ratio = 0; - const float ratio43 = 4.f / 3.f; - - SDL_GetWindowSize(window, &width, &height); - - if (video_width > 0 && video_height > 0) { - switch (resize_info.scaling_mode) { - case FULLSCR_SCALE_INT: - px_size = max(min(width / video_width, height / video_height), 1); - - pad_x = width - (video_width * px_size); - pad_y = height - (video_height * px_size); - break; - - case FULLSCR_SCALE_KEEPRATIO: - ratio = (float) video_width / (float) video_height; - case FULLSCR_SCALE_43: - if (ratio == 0) - ratio = ratio43; - if (ratio < ((float) width / (float) height)) - pad_x = width - (int) roundf((float) height * ratio); - else - pad_y = height - (int) roundf((float) width / ratio); - break; - - case FULLSCR_SCALE_FULL: - default: - break; - } - } - - output_width = width - pad_x; - output_height = height - pad_y; - - glViewport(pad_x / 2, pad_y / 2, output_width, output_height); - - if (gl.output_size != -1) - glUniform2f(gl.output_size, output_width, output_height); - } else { - SDL_SetWindowSize(window, resize_info.width, resize_info.height); - - /* SWP_NOZORDER is needed for child window and SDL doesn't enable it. */ - SetWindowPos(window_hwnd, parent, 0, 0, resize_info.width, resize_info.height, SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOACTIVATE); - - output_width = resize_info.width; - output_height = resize_info.height; - - glViewport(0, 0, resize_info.width, resize_info.height); - - if (gl.output_size != -1) - glUniform2f(gl.output_size, resize_info.width, resize_info.height); - } - - thread_release_mutex(resize_info.mutex); - } else if (sync_event == sync_objects.reload) { - thread_wait_mutex(options.mutex); - - frametime = options.frametime; - - SDL_GL_SetSwapInterval(options.vsync); - - if (options.shaderfile_changed) { - /* Change shader program. */ - apply_shaders(&gl); - - /* Uniforms need to be updated after proram change. */ - if (gl.input_size != -1) - glUniform2f(gl.input_size, video_width, video_height); - if (gl.output_size != -1) - glUniform2f(gl.output_size, output_width, output_height); - if (gl.texture_size != -1) - glUniform2f(gl.texture_size, video_width, video_height); - if (gl.frame_count != -1) - glUniform1i(gl.frame_count, 0); - - options.shaderfile_changed = 0; - } - - if (options.filter_changed) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, options.filter ? GL_LINEAR : GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, options.filter ? GL_LINEAR : GL_NEAREST); - - options.filter_changed = 0; - } - - thread_release_mutex(options.mutex); - } - - /* Keep cursor hidden in full screen and mouse capture */ - int show_cursor = !(fullscreen || !!mouse_capture); - if (SDL_ShowCursor(-1) != show_cursor) - SDL_ShowCursor(show_cursor); - } - - if (GLAD_GL_ARB_sync) { - for (int i = 0; i < BUFFERCOUNT; i++) { - if (blit_info[i].sync != NULL) - glDeleteSync(blit_info[i].sync); - } - } - - finalize_glcontext(&gl); - - SDL_GL_DeleteContext(context); - - set_parent_binding(0); - - SDL_DestroyWindow(window); - - window = NULL; - - CoUninitialize(); -} - -static void -opengl_blit(int x, int y, int w, int h, int monitor_index) -{ - if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (thread == NULL) || atomic_flag_test_and_set(&blit_info[write_pos].in_use) || monitor_index >= 1) { - video_blit_complete_monitor(monitor_index); - return; - } - - for (int row = 0; row < h; ++row) - video_copy(&(((uint8_t *) blit_info[write_pos].buffer)[row * ROW_LENGTH * sizeof(uint32_t)]), &(buffer32->line[y + row][x]), w * sizeof(uint32_t)); - - if (monitors[0].mon_screenshots) - video_screenshot(blit_info[write_pos].buffer, 0, 0, ROW_LENGTH); - - video_blit_complete(); - - blit_info[write_pos].w = w; - blit_info[write_pos].h = h; - - write_pos = (write_pos + 1) % BUFFERCOUNT; - - ReleaseSemaphore(sync_objects.blit_waiting, 1, NULL); -} - -static int -framerate_to_frametime(int framerate) -{ - if (framerate < 0) - return -1; - - return (int) ceilf(1.e6f / (float) framerate); -} - -int -opengl_init(HWND hwnd) -{ - if (thread != NULL) - return 0; - - for (int i = 0; i < sizeof(sync_objects) / sizeof(HANDLE); i++) - sync_objects.asArray[i] = CreateEvent(NULL, FALSE, FALSE, NULL); - - sync_objects.closing = CreateEvent(NULL, FALSE, FALSE, NULL); - sync_objects.resize = CreateEvent(NULL, FALSE, FALSE, NULL); - sync_objects.reload = CreateEvent(NULL, FALSE, FALSE, NULL); - sync_objects.blit_waiting = CreateSemaphore(NULL, 0, BUFFERCOUNT * 2, NULL); - - parent = hwnd; - - RECT parent_size; - - GetWindowRect(parent, &parent_size); - - resize_info.width = parent_size.right - parent_size.left; - resize_info.height = parent_size.bottom - parent_size.top; - resize_info.fullscreen = video_fullscreen & 1; - resize_info.scaling_mode = video_fullscreen_scale; - resize_info.mutex = thread_create_mutex(); - - options.vsync = video_vsync; - options.frametime = framerate_to_frametime(video_framerate); - strcpy_s(options.shaderfile, sizeof(options.shaderfile), video_shader); - options.shaderfile_changed = 0; - options.filter = video_filter_method; - options.filter_changed = 0; - options.mutex = thread_create_mutex(); - - blit_info = (blit_info_t *) malloc(BUFFERCOUNT * sizeof(blit_info_t)); - memset(blit_info, 0, BUFFERCOUNT * sizeof(blit_info_t)); - - /* Buffers are not yet allocated, set them as in use. */ - for (int i = 0; i < BUFFERCOUNT; i++) - atomic_flag_test_and_set(&blit_info[i].in_use); - - write_pos = 0; - - thread = thread_create(opengl_main, NULL); - - atexit(opengl_close); - - video_setblit(opengl_blit); - - return 1; -} - -int -opengl_pause(void) -{ - return 0; -} - -void -opengl_close(void) -{ - if (thread == NULL) - return; - - SetEvent(sync_objects.closing); - - thread_wait(thread); - - thread_close_mutex(resize_info.mutex); - thread_close_mutex(options.mutex); - - thread = NULL; - - free(blit_info); - - for (int i = 0; i < sizeof(sync_objects) / sizeof(HANDLE); i++) { - CloseHandle(sync_objects.asArray[i]); - sync_objects.asArray[i] = NULL; - } - - parent = NULL; -} - -void -opengl_set_fs(int fs) -{ - if (thread == NULL) - return; - - thread_wait_mutex(resize_info.mutex); - - resize_info.fullscreen = fs; - resize_info.scaling_mode = video_fullscreen_scale; - - thread_release_mutex(resize_info.mutex); - - SetEvent(sync_objects.resize); -} - -void -opengl_resize(int w, int h) -{ - if (thread == NULL) - return; - - thread_wait_mutex(resize_info.mutex); - - resize_info.width = w; - resize_info.height = h; - resize_info.scaling_mode = video_fullscreen_scale; - - thread_release_mutex(resize_info.mutex); - - SetEvent(sync_objects.resize); -} - -void -opengl_reload(void) -{ - if (thread == NULL) - return; - - thread_wait_mutex(options.mutex); - - options.vsync = video_vsync; - options.frametime = framerate_to_frametime(video_framerate); - - if (strcmp(video_shader, options.shaderfile) != 0) { - strcpy_s(options.shaderfile, sizeof(options.shaderfile), video_shader); - options.shaderfile_changed = 1; - } - - if (video_filter_method != options.filter) { - options.filter = video_filter_method; - options.filter_changed = 1; - } - - thread_release_mutex(options.mutex); - - SetEvent(sync_objects.reload); -} diff --git a/src/win/win_opengl_glslp.c b/src/win/win_opengl_glslp.c deleted file mode 100644 index 9689f3ab2..000000000 --- a/src/win/win_opengl_glslp.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * File parser for .glslp and .glsl shader files - * in the format of libretro. - * - * TODO: Read .glslp files for multipass shaders and settings. - * - * - * - * Authors: Teemu Korhonen - * - * Copyright 2021 Teemu Korhonen - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include - -#include -#include -#include -#include - -#include <86box/86box.h> -#include <86box/plat.h> -#include <86box/win_opengl_glslp.h> - -/** - * @brief Default vertex shader. - */ -static const GLchar *vertex_shader = "#version 130\n\ -in vec2 VertexCoord;\n\ -in vec2 TexCoord;\n\ -out vec2 tex;\n\ -void main(){\n\ - gl_Position = vec4(VertexCoord, 0.0, 1.0);\n\ - tex = TexCoord;\n\ -}\n"; - -/** - * @brief Default fragment shader. - */ -static const GLchar *fragment_shader = "#version 130\n\ -in vec2 tex;\n\ -uniform sampler2D texsampler;\n\ -out vec4 color;\n\ -void main() {\n\ - color = texture(texsampler, tex);\n\ -}\n"; - -/** - * @brief OpenGL shader program build targets - */ -typedef enum { - OPENGL_BUILD_TARGET_VERTEX, - OPENGL_BUILD_TARGET_FRAGMENT, - OPENGL_BUILD_TARGET_LINK -} opengl_build_target_t; - -/** - * @brief Reads a whole file into a null terminated string. - * @param Path Path to the file relative to executable path. - * @return Pointer to the string or NULL on error. Remember to free() after use. - */ -static char * -read_file_to_string(const char *path) -{ - FILE *fp = plat_fopen(path, "rb"); - - if (fp != NULL) { - /* get file size */ - fseek(fp, 0, SEEK_END); - - size_t file_size = (size_t) ftell(fp); - - fseek(fp, 0, SEEK_SET); - - /* read to buffer and close */ - char *content = (char *) malloc(sizeof(char) * (file_size + 1)); - - if (!content) - return NULL; - - size_t length = fread(content, sizeof(char), file_size, fp); - - fclose(fp); - - content[length] = 0; - - return content; - } - return NULL; -} - -static int -check_status(GLuint id, opengl_build_target_t build_target, const char *shader_path) -{ - GLint status = GL_FALSE; - - if (build_target != OPENGL_BUILD_TARGET_LINK) - glGetShaderiv(id, GL_COMPILE_STATUS, &status); - else - glGetProgramiv(id, GL_LINK_STATUS, &status); - - if (status == GL_FALSE) { - int info_log_length; - - if (build_target != OPENGL_BUILD_TARGET_LINK) - glGetShaderiv(id, GL_INFO_LOG_LENGTH, &info_log_length); - else - glGetProgramiv(id, GL_INFO_LOG_LENGTH, &info_log_length); - - GLchar *info_log_text = (GLchar *) malloc(sizeof(GLchar) * info_log_length); - - if (build_target != OPENGL_BUILD_TARGET_LINK) - glGetShaderInfoLog(id, info_log_length, NULL, info_log_text); - else - glGetProgramInfoLog(id, info_log_length, NULL, info_log_text); - - const char *reason = NULL; - - switch (build_target) { - case OPENGL_BUILD_TARGET_VERTEX: - reason = "compiling vertex shader"; - break; - case OPENGL_BUILD_TARGET_FRAGMENT: - reason = "compiling fragment shader"; - break; - case OPENGL_BUILD_TARGET_LINK: - reason = "linking shader program"; - break; - } - - /* Shader compilation log can be lengthy, mark begin and end */ - const char *line = "--------------------"; - - pclog("OpenGL: Error when %s in %s:\n%sBEGIN%s\n%s\n%s END %s\n", reason, shader_path, line, line, info_log_text, line, line); - - free(info_log_text); - - return 0; - } - - return 1; -} - -/** - * @brief Compile custom shaders into a program. - * @return Shader program identifier. - */ -GLuint -load_custom_shaders(const char *path) -{ - char *shader = read_file_to_string(path); - - if (shader != NULL) { - int success = 1; - - const char *vertex_sources[3] = { "#version 130\n", "#define VERTEX\n", shader }; - const char *fragment_sources[3] = { "#version 130\n", "#define FRAGMENT\n", shader }; - - /* Check if the shader program defines version directive */ - char *version_start = strstr(shader, "#version"); - - /* If the shader program contains a version directive, - it must be captured and placed as the first statement. */ - if (version_start != NULL) { - /* Version directive found, search the line end */ - const char *version_end = strchr(version_start, '\n'); - - if (version_end != NULL) { - char version[30] = ""; - - size_t version_len = MIN(version_end - version_start + 1, 29); - - strncat(version, version_start, version_len); - - /* replace the default version directive */ - vertex_sources[0] = version; - fragment_sources[0] = version; - } - - /* Comment out the original version directive - as only one is allowed. */ - memset(version_start, '/', 2); - } - - GLuint vertex_id = glCreateShader(GL_VERTEX_SHADER); - GLuint fragment_id = glCreateShader(GL_FRAGMENT_SHADER); - - glShaderSource(vertex_id, 3, vertex_sources, NULL); - glCompileShader(vertex_id); - success *= check_status(vertex_id, OPENGL_BUILD_TARGET_VERTEX, path); - - glShaderSource(fragment_id, 3, fragment_sources, NULL); - glCompileShader(fragment_id); - success *= check_status(fragment_id, OPENGL_BUILD_TARGET_FRAGMENT, path); - - free(shader); - - GLuint prog_id = 0; - - if (success) { - prog_id = glCreateProgram(); - - glAttachShader(prog_id, vertex_id); - glAttachShader(prog_id, fragment_id); - glLinkProgram(prog_id); - check_status(prog_id, OPENGL_BUILD_TARGET_LINK, path); - - glDetachShader(prog_id, vertex_id); - glDetachShader(prog_id, fragment_id); - } - - glDeleteShader(vertex_id); - glDeleteShader(fragment_id); - - return prog_id; - } - return 0; -} - -/** - * @brief Compile default shaders into a program. - * @return Shader program identifier. - */ -GLuint -load_default_shaders(void) -{ - GLuint vertex_id = glCreateShader(GL_VERTEX_SHADER); - GLuint fragment_id = glCreateShader(GL_FRAGMENT_SHADER); - - glShaderSource(vertex_id, 1, &vertex_shader, NULL); - glCompileShader(vertex_id); - - glShaderSource(fragment_id, 1, &fragment_shader, NULL); - glCompileShader(fragment_id); - - GLuint prog_id = glCreateProgram(); - - glAttachShader(prog_id, vertex_id); - glAttachShader(prog_id, fragment_id); - - glLinkProgram(prog_id); - - glDetachShader(prog_id, vertex_id); - glDetachShader(prog_id, fragment_id); - - glDeleteShader(vertex_id); - glDeleteShader(fragment_id); - - return prog_id; -} diff --git a/src/win/win_preferences.c b/src/win/win_preferences.c deleted file mode 100644 index ee93321a8..000000000 --- a/src/win/win_preferences.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Handle the dialog for changing the program's language and other global settings. - * - * - * - * Authors: Laci bá' - * - * Copyright 2021 Laci bá' - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP -#include -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/config.h> -#include <86box/plat.h> -#include <86box/sound.h> -#include <86box/win.h> -#include <86box/ui.h> -#include <86box/resource.h> - -/* Language */ -static LCID temp_language; - -static char temp_icon_set[256] = { 0 }; - -int enum_helper; -int c; - -HWND hwndPreferences; - -BOOL CALLBACK -EnumResLangProc(UNUSED(HMODULE hModule), UNUSED(LPCTSTR lpszType), UNUSED(LPCTSTR lpszName), WORD wIDLanguage, LONG_PTR lParam) -{ - wchar_t temp[LOCALE_NAME_MAX_LENGTH + 1]; - LCIDToLocaleName(wIDLanguage, temp, LOCALE_NAME_MAX_LENGTH, 0); - wchar_t dispname[MAX_PATH + 1]; - GetLocaleInfoEx(temp, LOCALE_SENGLISHDISPLAYNAME, dispname, MAX_PATH); - SendMessage((HWND) lParam, CB_ADDSTRING, 0, (LPARAM) dispname); - SendMessage((HWND) lParam, CB_SETITEMDATA, c, (LPARAM) wIDLanguage); - - if (wIDLanguage == lang_id) - enum_helper = c; - c++; - - return 1; -} - -/* Load available languages */ -static void -preferences_fill_languages(HWND hdlg) -{ - temp_language = GetThreadUILanguage(); - HWND lang_combo = GetDlgItem(hdlg, IDC_COMBO_LANG); - - SendMessage(lang_combo, CB_RESETCONTENT, 0, 0); - SendMessage(lang_combo, CB_ADDSTRING, 0, win_get_string(IDS_7168)); - SendMessage(lang_combo, CB_SETITEMDATA, 0, 0xFFFF); - - enum_helper = 0; - c = 1; - // if no one is selected, then it was 0xFFFF or unsupported language, in either case go with index enum_helper=0 - // also start enum index from c=1 - EnumResourceLanguages(hinstance, RT_MENU, L"MainMenu", &EnumResLangProc, (LPARAM) lang_combo); - - SendMessage(lang_combo, CB_SETCURSEL, enum_helper, 0); -} - -/* Load available iconsets */ -static void -preferences_fill_iconsets(HWND hdlg) -{ - HWND icon_combo = GetDlgItem(hdlg, IDC_COMBO_ICON); - - /* Add the default one */ - wchar_t buffer[512] = L"("; - wcscat(buffer, plat_get_string(IDS_DEFAULT)); - wcscat(buffer, L")"); - - SendMessage(icon_combo, CB_RESETCONTENT, 0, 0); - SendMessage(icon_combo, CB_ADDSTRING, 0, (LPARAM) buffer); - SendMessage(icon_combo, CB_SETITEMDATA, 0, (LPARAM) strdup("")); - - int combo_index = -1; - - /* Find for extra ones */ - HANDLE hFind; - WIN32_FIND_DATA data; - - char icon_path_root[512]; - win_get_icons_path(icon_path_root); - - wchar_t search[512]; - mbstoc16s(search, icon_path_root, strlen(icon_path_root) + 1); - wcscat(search, L"*.*"); - - hFind = FindFirstFile((LPCWSTR) search, &data); - - if (hFind != INVALID_HANDLE_VALUE) { - do { - if (wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L"..") && (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - wchar_t temp[512] = { 0 }; - wchar_t dispname[512] = { 0 }; - mbstoc16s(temp, icon_path_root, strlen(icon_path_root) + 1); - wcscat(temp, data.cFileName); - wcscat(temp, L"\\iconinfo.txt"); - - wcscpy(dispname, data.cFileName); - FILE *fp = _wfopen(temp, L"r"); - if (fp) { - char line[512] = { 0 }; - if (fgets(line, 511, fp)) { - mbstoc16s(dispname, line, strlen(line) + 1); - } - - fclose(fp); - } - - char filename[512]; - c16stombs(filename, data.cFileName, 511); - - int index = SendMessage(icon_combo, CB_ADDSTRING, 0, (LPARAM) dispname); - SendMessage(icon_combo, CB_SETITEMDATA, index, (LPARAM) (strdup(filename))); - - if (!strcmp(filename, icon_set)) - combo_index = index; - } - } while (FindNextFile(hFind, &data)); - FindClose(hFind); - } - - if (combo_index == -1) { - combo_index = 0; - strcpy(temp_icon_set, ""); - } - - SendMessage(icon_combo, CB_SETCURSEL, combo_index, 0); -} - -/* This returns 1 if any variable has changed, 0 if not. */ -static int -preferences_settings_changed(void) -{ - int i = 0; - - /* Language */ - i = i || has_language_changed(temp_language); - i = i || strcmp(temp_icon_set, icon_set); - - return i; -} - -/* IndexOf by ItemData */ -static int -preferences_indexof(HWND combo, LPARAM itemdata) -{ - for (int i = 0; i < SendMessage(combo, CB_GETCOUNT, 0, 0); i++) - if (SendMessage(combo, CB_GETITEMDATA, i, 0) == itemdata) - return i; - - return -1; -} - -/* This saves the settings back to the global variables. */ -static void -preferences_settings_save(void) -{ - /* Language */ - set_language(temp_language); - - /* Iconset */ - strcpy(icon_set, temp_icon_set); - win_load_icon_set(); - - /* Update title bar */ - update_mouse_msg(); - - /* Update status bar */ - config_changed = 1; - ui_sb_set_ready(-1); - ui_sb_update_panes(); - ui_sb_update_text(); - - /* Save the language changes */ - config_save(); -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -PreferencesDlgProcedure(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - switch (message) { - case WM_INITDIALOG: - hwndPreferences = hdlg; - /* Language */ - temp_language = lang_id; - strcpy(temp_icon_set, icon_set); - preferences_fill_languages(hdlg); - preferences_fill_iconsets(hdlg); - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - if (preferences_settings_changed()) - preferences_settings_save(); - EndDialog(hdlg, 0); - return TRUE; - - case IDCANCEL: - EndDialog(hdlg, 0); - return TRUE; - - case IDC_COMBO_LANG: - if (HIWORD(wParam) == CBN_SELCHANGE) { - HWND combo = GetDlgItem(hdlg, IDC_COMBO_LANG); - int index = SendMessage(combo, CB_GETCURSEL, 0, 0); - temp_language = SendMessage(combo, CB_GETITEMDATA, index, 0); - } - break; - - case IDC_COMBO_ICON: - if (HIWORD(wParam) == CBN_SELCHANGE) { - HWND combo = GetDlgItem(hdlg, IDC_COMBO_ICON); - int index = SendMessage(combo, CB_GETCURSEL, 0, 0); - strcpy(temp_icon_set, (char *) SendMessage(combo, CB_GETITEMDATA, index, 0)); - } - break; - - case IDC_BUTTON_DEFAULT: - { - HWND combo = GetDlgItem(hdlg, IDC_COMBO_LANG); - int index = preferences_indexof(combo, DEFAULT_LANGUAGE); - SendMessage(combo, CB_SETCURSEL, index, 0); - temp_language = DEFAULT_LANGUAGE; - break; - } - - case IDC_BUTTON_DEFICON: - { - SendMessage(GetDlgItem(hdlg, IDC_COMBO_ICON), CB_SETCURSEL, 0, 0); - strcpy(temp_icon_set, ""); - break; - } - default: - break; - } - break; - - case WM_DESTROY: - { - LRESULT temp; - HWND combo = GetDlgItem(hdlg, IDC_COMBO_ICON); - for (int i = 0; i < SendMessage(combo, CB_GETCOUNT, 0, 0); i++) { - temp = SendMessage(combo, CB_GETITEMDATA, i, 0); - if (temp) { - free((void *) temp); - SendMessage(combo, CB_SETITEMDATA, i, 0); - } - } - } - break; - } - - return FALSE; -} - -void -PreferencesDlgCreate(HWND hwnd) -{ - DialogBox(hinstance, (LPCTSTR) DLG_PREFERENCES, hwnd, PreferencesDlgProcedure); -} diff --git a/src/win/win_sdl.c b/src/win/win_sdl.c deleted file mode 100644 index ea9c8455d..000000000 --- a/src/win/win_sdl.c +++ /dev/null @@ -1,626 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Rendering module for libSDL2 - * - * NOTE: Given all the problems reported with FULLSCREEN use of SDL, - * we will not use that, but, instead, use a new window which - * covers the entire desktop. - * - * - * - * Authors: Fred N. van Kempen, - * Michael Drüing, - * - * Copyright 2018-2020 Fred N. van Kempen. - * Copyright 2018-2020 Michael Drüing. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#define UNICODE -#define WIN32_LEAN_AND_MEAN -#include -#include -#include - -#include -#include -#include -#include -/* This #undef is needed because a SDL include header redefines HAVE_STDARG_H. */ -#undef HAVE_STDARG_H -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/plat.h> -#include <86box/plat_dynld.h> -#include <86box/video.h> -#include <86box/ui.h> -#include <86box/win.h> -#include <86box/win_sdl.h> -#include <86box/version.h> - -#define RENDERER_FULL_SCREEN 1 -#define RENDERER_HARDWARE 2 -#define RENDERER_OPENGL 4 - -static SDL_Window *sdl_win = NULL; -static SDL_Renderer *sdl_render = NULL; -static SDL_Texture *sdl_tex = NULL; -static HWND sdl_parent_hwnd = NULL; -static int sdl_w; -static int sdl_h; -static int sdl_fs; -static int sdl_flags = -1; -static int cur_w; -static int cur_h; -static int cur_wx = 0; -static int cur_wy = 0; -static int cur_ww = 0; -static int cur_wh = 0; -static volatile int sdl_enabled = 0; -static SDL_mutex *sdl_mutex = NULL; - -typedef struct -{ - const void *magic; - Uint32 id; - char *title; - SDL_Surface *icon; - int x, y; - int w, h; - int min_w, min_h; - int max_w, max_h; - Uint32 flags; - Uint32 last_fullscreen_flags; - - /* Stored position and size for windowed mode */ - SDL_Rect windowed; - - SDL_DisplayMode fullscreen_mode; - - float brightness; - Uint16 *gamma; - Uint16 *saved_gamma; /* (just offset into gamma) */ - - SDL_Surface *surface; - SDL_bool surface_valid; - - SDL_bool is_hiding; - SDL_bool is_destroying; - - void *shaper; - - SDL_HitTest hit_test; - void *hit_test_data; - - void *data; - - void *driverdata; - - SDL_Window *prev; - SDL_Window *next; -} SDL_Window_Ex; - -#ifdef ENABLE_SDL_LOG -int sdl_do_log = ENABLE_SDL_LOG; - -static void -sdl_log(const char *fmt, ...) -{ - va_list ap; - - if (sdl_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define sdl_log(fmt, ...) -#endif - -static void -sdl_integer_scale(double *d, double *g) -{ - double ratio; - - if (*d > *g) { - ratio = floor(*d / *g); - *d = *g * ratio; - } else { - ratio = ceil(*d / *g); - *d = *g / ratio; - } -} - -static void -sdl_stretch(int *w, int *h, int *x, int *y) -{ - double hw; - double gw; - double hh; - double gh; - double dx; - double dy; - double dw; - double dh; - double gsr; - double hsr; - - hw = (double) sdl_w; - hh = (double) sdl_h; - gw = (double) *w; - gh = (double) *h; - hsr = hw / hh; - - switch (video_fullscreen_scale) { - default: - case FULLSCR_SCALE_FULL: - *w = sdl_w; - *h = sdl_h; - *x = 0; - *y = 0; - break; - case FULLSCR_SCALE_43: - case FULLSCR_SCALE_KEEPRATIO: - if (video_fullscreen_scale == FULLSCR_SCALE_43) - gsr = 4.0 / 3.0; - else - gsr = gw / gh; - if (gsr <= hsr) { - dw = hh * gsr; - dh = hh; - } else { - dw = hw; - dh = hw / gsr; - } - dx = (hw - dw) / 2.0; - dy = (hh - dh) / 2.0; - *w = (int) dw; - *h = (int) dh; - *x = (int) dx; - *y = (int) dy; - break; - case FULLSCR_SCALE_INT: - gsr = gw / gh; - if (gsr <= hsr) { - dw = hh * gsr; - dh = hh; - } else { - dw = hw; - dh = hw / gsr; - } - sdl_integer_scale(&dw, &gw); - sdl_integer_scale(&dh, &gh); - dx = (hw - dw) / 2.0; - dy = (hh - dh) / 2.0; - *w = (int) dw; - *h = (int) dh; - *x = (int) dx; - *y = (int) dy; - break; - } -} - -static void -sdl_blit(int x, int y, int w, int h, int monitor_index) -{ - SDL_Rect r_src; - int ret; - - if (!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL) || monitor_index >= 1) { - video_blit_complete_monitor(monitor_index); - return; - } - - SDL_LockMutex(sdl_mutex); - - r_src.x = x; - r_src.y = y; - r_src.w = w; - r_src.h = h; - SDL_UpdateTexture(sdl_tex, &r_src, &(buffer32->line[y][x]), 2048 * sizeof(uint32_t)); - - if (monitors[0].mon_screenshots) - video_screenshot(buffer32->dat, x, y, 2048); - - video_blit_complete(); - - SDL_RenderClear(sdl_render); - - r_src.x = x; - r_src.y = y; - r_src.w = w; - r_src.h = h; - - ret = SDL_RenderCopy(sdl_render, sdl_tex, &r_src, 0); - if (ret) - sdl_log("SDL: unable to copy texture to renderer (%s)\n", SDL_GetError()); - - SDL_RenderPresent(sdl_render); - SDL_UnlockMutex(sdl_mutex); -} - -static void -sdl_blit_ex(int x, int y, int w, int h, UNUSED(int monitor_index)) -{ - SDL_Rect r_src; - void *pixeldata; - int pitch; - int ret; - - if (!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL)) { - video_blit_complete(); - return; - } - - SDL_LockMutex(sdl_mutex); - - SDL_LockTexture(sdl_tex, 0, &pixeldata, &pitch); - - for (int row = 0; row < h; ++row) - video_copy(&(((uint8_t *) pixeldata)[row * 2048 * sizeof(uint32_t)]), &(buffer32->line[y + row][x]), w * sizeof(uint32_t)); - - if (monitors[0].mon_screenshots) - video_screenshot((uint32_t *) pixeldata, 0, 0, 2048); - - SDL_UnlockTexture(sdl_tex); - - video_blit_complete(); - - SDL_RenderClear(sdl_render); - - r_src.x = 0; - r_src.y = 0; - r_src.w = w; - r_src.h = h; - - ret = SDL_RenderCopy(sdl_render, sdl_tex, &r_src, 0); - if (ret) - sdl_log("SDL: unable to copy texture to renderer (%s)\n", SDL_GetError()); - - SDL_RenderPresent(sdl_render); - SDL_UnlockMutex(sdl_mutex); -} - -static void -sdl_destroy_window(void) -{ - if (sdl_win != NULL) { - SDL_DestroyWindow(sdl_win); - sdl_win = NULL; - } -} - -static void -sdl_destroy_texture(void) -{ - if (sdl_tex != NULL) { - SDL_DestroyTexture(sdl_tex); - sdl_tex = NULL; - } - - /* SDL_DestroyRenderer also automatically destroys all associated textures. */ - if (sdl_render != NULL) { - SDL_DestroyRenderer(sdl_render); - sdl_render = NULL; - } -} - -void -sdl_close(void) -{ - if (sdl_mutex != NULL) - SDL_LockMutex(sdl_mutex); - - /* Unregister our renderer! */ - video_setblit(NULL); - - if (sdl_enabled) - sdl_enabled = 0; - - if (sdl_mutex != NULL) { - SDL_DestroyMutex(sdl_mutex); - sdl_mutex = NULL; - } - - sdl_destroy_texture(); - sdl_destroy_window(); - ImmAssociateContext(hwndMain, NULL); - SetFocus(hwndMain); - - if (sdl_parent_hwnd != NULL) { - DestroyWindow(sdl_parent_hwnd); - sdl_parent_hwnd = NULL; - } - - /* Quit. */ - SDL_Quit(); - sdl_flags = -1; -} - -static int old_capture = 0; - -static void -sdl_select_best_hw_driver(void) -{ - SDL_RendererInfo renderInfo; - - for (int i = 0; i < SDL_GetNumRenderDrivers(); ++i) { - SDL_GetRenderDriverInfo(i, &renderInfo); - if (renderInfo.flags & SDL_RENDERER_ACCELERATED) { - SDL_SetHint(SDL_HINT_RENDER_DRIVER, renderInfo.name); - return; - } - } -} - -static void -sdl_init_texture(void) -{ - if (sdl_flags & RENDERER_HARDWARE) { - sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_ACCELERATED); - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0"); - } else - sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_SOFTWARE); - - sdl_tex = SDL_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STREAMING, 2048, 2048); -} - -static void -sdl_reinit_texture(void) -{ - if (sdl_flags == -1) - return; - - sdl_destroy_texture(); - sdl_init_texture(); -} - -void -sdl_set_fs(int fs) -{ - int w = 0; - int h = 0; - int x = 0; - int y = 0; - RECT rect; - - SDL_LockMutex(sdl_mutex); - sdl_enabled = 0; - - if (fs) { - ShowWindow(sdl_parent_hwnd, TRUE); - SetParent(hwndRender, sdl_parent_hwnd); - ShowWindow(hwndRender, TRUE); - MoveWindow(sdl_parent_hwnd, 0, 0, sdl_w, sdl_h, TRUE); - - /* Show the window, make it topmost, and give it focus. */ - w = unscaled_size_x; - h = efscrnsz_y; - sdl_stretch(&w, &h, &x, &y); - MoveWindow(hwndRender, x, y, w, h, TRUE); - ImmAssociateContext(sdl_parent_hwnd, NULL); - SetFocus(sdl_parent_hwnd); - - /* Redirect RawInput to this new window. */ - old_capture = mouse_capture; - GetWindowRect(hwndRender, &rect); - ClipCursor(&rect); - mouse_capture = 1; - } else { - SetParent(hwndRender, hwndMain); - ShowWindow(sdl_parent_hwnd, FALSE); - ShowWindow(hwndRender, TRUE); - ImmAssociateContext(hwndMain, NULL); - SetFocus(hwndMain); - mouse_capture = old_capture; - - if (mouse_capture) { - GetWindowRect(hwndRender, &rect); - ClipCursor(&rect); - } else - ClipCursor(&oldclip); - } - - sdl_fs = fs; - - if (fs) - sdl_flags |= RENDERER_FULL_SCREEN; - else - sdl_flags &= ~RENDERER_FULL_SCREEN; - -#if 0 - sdl_reinit_texture(); -#endif - sdl_enabled = 1; - SDL_UnlockMutex(sdl_mutex); -} - -static int -sdl_init_common(int flags) -{ - wchar_t temp[128]; - SDL_version ver; - - sdl_log("SDL: init (flags=%d)\n", flags); - - /* Get and log the version of the DLL we are using. */ - SDL_GetVersion(&ver); - sdl_log("SDL: version %d.%d.%d\n", ver.major, ver.minor, ver.patch); - - /* Initialize the SDL system. */ - if (SDL_Init(SDL_INIT_VIDEO) < 0) { - sdl_log("SDL: initialization failed (%s)\n", SDL_GetError()); - return 0; - } - - if (flags & RENDERER_HARDWARE) { - if (flags & RENDERER_OPENGL) - SDL_SetHint(SDL_HINT_RENDER_DRIVER, "OpenGL"); - else - sdl_select_best_hw_driver(); - } - - /* Get the size of the (current) desktop. */ - sdl_w = GetSystemMetrics(SM_CXSCREEN); - sdl_h = GetSystemMetrics(SM_CYSCREEN); - - /* Create the desktop-covering window. */ - _swprintf(temp, L"%s v%s", EMU_NAME_W, EMU_VERSION_FULL_W); - sdl_parent_hwnd = CreateWindow(SDL_CLASS_NAME, temp, WS_POPUP, 0, 0, sdl_w, sdl_h, - HWND_DESKTOP, NULL, hinstance, NULL); - ShowWindow(sdl_parent_hwnd, FALSE); - - sdl_flags = flags; - - if (sdl_win == NULL) { - sdl_log("SDL: unable to CreateWindowFrom (%s)\n", SDL_GetError()); - } - - sdl_win = SDL_CreateWindowFrom((void *) hwndRender); - sdl_init_texture(); - sdl_set_fs(video_fullscreen & 1); - - /* Make sure we get a clean exit. */ - atexit(sdl_close); - - /* Register our renderer! */ - video_setblit((video_grayscale || invert_display) ? sdl_blit_ex : sdl_blit); - - sdl_enabled = 1; - sdl_mutex = SDL_CreateMutex(); - - return 1; -} - -int -sdl_inits(UNUSED(HWND h)) -{ - return sdl_init_common(0); -} - -int -sdl_inith(UNUSED(HWND h)) -{ - return sdl_init_common(RENDERER_HARDWARE); -} - -int -sdl_initho(UNUSED(HWND h)) -{ - return sdl_init_common(RENDERER_HARDWARE | RENDERER_OPENGL); -} - -int -sdl_pause(void) -{ - return 0; -} - -void -sdl_resize(int x, int y) -{ - int ww = 0; - int wh = 0; - int wx = 0; - int wy = 0; - - if (video_fullscreen & 2) - return; - - if ((x == cur_w) && (y == cur_h)) - return; - - SDL_LockMutex(sdl_mutex); - - ww = x; - wh = y; - - if (sdl_fs) { - sdl_stretch(&ww, &wh, &wx, &wy); - MoveWindow(hwndRender, wx, wy, ww, wh, TRUE); - } - - cur_w = x; - cur_h = y; - - cur_wx = wx; - cur_wy = wy; - cur_ww = ww; - cur_wh = wh; - - SDL_SetWindowSize(sdl_win, cur_ww, cur_wh); - SDL_SetWindowPosition(sdl_win, cur_wx, cur_wy); - - sdl_reinit_texture(); - - SDL_UnlockMutex(sdl_mutex); -} - -void -sdl_enable(int enable) -{ - if (sdl_flags == -1) - return; - - SDL_LockMutex(sdl_mutex); - sdl_enabled = !!enable; - - if (enable == 1) { - SDL_SetWindowSize(sdl_win, cur_ww, cur_wh); - sdl_reinit_texture(); - } - - SDL_UnlockMutex(sdl_mutex); -} - -void -sdl_reload(void) -{ - if (sdl_flags & RENDERER_HARDWARE) { - SDL_LockMutex(sdl_mutex); - - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0"); - sdl_reinit_texture(); - - SDL_UnlockMutex(sdl_mutex); - } - - video_setblit((video_grayscale || invert_display) ? sdl_blit_ex : sdl_blit); -} diff --git a/src/win/win_settings.c b/src/win/win_settings.c deleted file mode 100644 index 139c387a8..000000000 --- a/src/win/win_settings.c +++ /dev/null @@ -1,5708 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Windows 86Box Settings dialog handler. - * - * - * - * Authors: Miran Grca, - * David Hrdlička, - * Jasmine Iwanek, - * - * Copyright 2016-2019 Miran Grca. - * Copyright 2018-2019 David Hrdlička. - * Copyright 2021 Laci bá' - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#include -#undef BITMAP -#ifdef ENABLE_SETTINGS_LOG -# include -#endif -#include -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/config.h> -#include "cpu.h" -#include <86box/mem.h> -#include <86box/rom.h> -#include <86box/device.h> -#include <86box/timer.h> -#include <86box/cassette.h> -#include <86box/nvr.h> -#include <86box/machine.h> -#include <86box/gameport.h> -#include <86box/isamem.h> -#include <86box/isartc.h> -#include <86box/lpt.h> -#include <86box/mouse.h> -#include <86box/serial.h> -#include <86box/scsi.h> -#include <86box/scsi_device.h> -#include <86box/cdrom.h> -#include <86box/hdd.h> -#include <86box/hdc.h> -#include <86box/hdc_ide.h> -#include <86box/zip.h> -#include <86box/mo.h> -#include <86box/fdd.h> -#include <86box/fdc.h> -#include <86box/fdc_ext.h> -#include <86box/thread.h> -#include <86box/network.h> -#include <86box/sound.h> -#include <86box/midi.h> -#include <86box/snd_mpu401.h> -#include <86box/snd_opl.h> -#include <86box/video.h> -#include <86box/vid_xga_device.h> -#include <86box/plat.h> -#include <86box/ui.h> -#include <86box/win.h> -#include <86box/serial_passthrough.h> -#include "../disk/minivhd/minivhd.h" - -/* Icon, Bus, File, C, H, S, Size, Speed */ -#define C_COLUMNS_HARD_DISKS 7 - -#define C_COLUMNS_FLOPPY_DRIVES 3 -#define C_COLUMNS_CDROM_DRIVES 3 -#define C_COLUMNS_MO_DRIVES 2 -#define C_COLUMNS_ZIP_DRIVES 2 - -static int first_cat = 0; - -/* Machine category */ -static int temp_machine_type; -static int temp_machine; -static int temp_cpu; -static int temp_wait_states; -static int temp_fpu; -static int temp_sync; -static cpu_family_t *temp_cpu_f; -static uint32_t temp_mem_size; -#ifdef USE_DYNAREC -static int temp_dynarec; -#endif -static int temp_fpu_softfloat; - -/* Video category */ -static int temp_gfxcard[2]; -static int temp_ibm8514; -static int temp_voodoo; -static int temp_xga; - -/* Input devices category */ -static int temp_mouse; -static int temp_joystick; - -/* Sound category */ -static int temp_sound_card[SOUND_CARD_MAX]; -static int temp_midi_output_device; -static int temp_midi_input_device; -static int temp_mpu401; -static int temp_float; -static int temp_fm_driver; - -/* Network category */ -static int temp_net_type[NET_CARD_MAX]; -static uint16_t temp_net_card[NET_CARD_MAX]; -static char temp_pcap_dev[NET_CARD_MAX][128]; - -/* Ports category */ -static int temp_lpt_devices[PARALLEL_MAX]; -static uint8_t temp_serial[SERIAL_MAX]; -static uint8_t temp_lpt[PARALLEL_MAX]; -static int temp_serial_passthrough_enabled[SERIAL_MAX]; - -/* Other peripherals category */ -static int temp_fdc_card; -static int temp_hdc; -static int temp_ide_ter; -static int temp_ide_qua; -static int temp_cassette; -static int temp_scsi_card[SCSI_BUS_MAX]; -static int temp_bugger; -static int temp_postcard; -static int temp_isartc; -static int temp_isamem[ISAMEM_MAX]; - -static uint8_t temp_deviceconfig; - -/* Hard disks category */ -static hard_disk_t temp_hdd[HDD_NUM]; - -/* Floppy drives category */ -static int temp_fdd_types[FDD_NUM]; -static int temp_fdd_turbo[FDD_NUM]; -static int temp_fdd_check_bpb[FDD_NUM]; - -/* Other removable devices category */ -static cdrom_t temp_cdrom[CDROM_NUM]; -static zip_drive_t temp_zip_drives[ZIP_NUM]; -static mo_drive_t temp_mo_drives[MO_NUM]; - -static HWND hwndParentDialog; -static HWND hwndChildDialog; - -static uint32_t displayed_category = 0; - -extern int is486; -static int listtomachinetype[256]; -static int listtomachine[256]; -static int listtocpufamily[256]; -static int listtocpu[256]; -static int settings_list_to_device[2][256]; -static int settings_list_to_fdc[20]; -static int settings_list_to_midi[20]; -static int settings_list_to_midi_in[20]; -static int settings_list_to_hdc[20]; - -static int max_spt = 63; -static int max_hpc = 255; -static int max_tracks = 266305; -static uint64_t mfm_tracking; -static uint64_t esdi_tracking; -static uint64_t xta_tracking; -static uint64_t ide_tracking; -static uint64_t scsi_tracking[8]; -static uint64_t size; -static int hd_listview_items; -static int hdc_id_to_listview_index[HDD_NUM]; -static int no_update = 0; -static int existing = 0; -static int chs_enabled = 0; -static int lv1_current_sel; -static int lv2_current_sel; -static int hard_disk_added = 0; -static int next_free_id = 0; -static int selection = 127; -static int spt; -static int hpc; -static int tracks; -static int ignore_change = 0; - -static hard_disk_t new_hdd; -static hard_disk_t *hdd_ptr; - -static wchar_t hd_file_name[512]; -static WCHAR device_name[512]; - -static int -settings_get_check(HWND hdlg, int id) -{ - return SendMessage(GetDlgItem(hdlg, id), BM_GETCHECK, 0, 0); -} - -static int -settings_get_cur_sel(HWND hdlg, int id) -{ - return SendMessage(GetDlgItem(hdlg, id), CB_GETCURSEL, 0, 0); -} - -static void -settings_set_check(HWND hdlg, int id, int val) -{ - SendMessage(GetDlgItem(hdlg, id), BM_SETCHECK, val, 0); -} - -static void -settings_set_cur_sel(HWND hdlg, int id, int val) -{ - SendMessage(GetDlgItem(hdlg, id), CB_SETCURSEL, val, 0); -} - -static void -settings_reset_content(HWND hdlg, int id) -{ - SendMessage(GetDlgItem(hdlg, id), CB_RESETCONTENT, 0, 0); -} - -static void -settings_add_string(HWND hdlg, int id, LPARAM string) -{ - SendMessage(GetDlgItem(hdlg, id), CB_ADDSTRING, 0, string); -} - -static void -settings_enable_window(HWND hdlg, int id, int condition) -{ - EnableWindow(GetDlgItem(hdlg, id), condition ? TRUE : FALSE); -} - -static void -settings_show_window(HWND hdlg, int id, int condition) -{ - HWND h; - - h = GetDlgItem(hdlg, id); - EnableWindow(h, condition ? TRUE : FALSE); - ShowWindow(h, condition ? SW_SHOW : SW_HIDE); -} - -static void -settings_listview_enable_styles(HWND hdlg, int id) -{ - HWND h; - - h = GetDlgItem(hdlg, id); - SetWindowTheme(h, L"Explorer", NULL); - ListView_SetExtendedListViewStyle(h, LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER); -} - -static void -settings_listview_select(HWND hdlg, int id, int selection) -{ - HWND h; - - h = GetDlgItem(hdlg, id); - ListView_SetItemState(h, selection, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); -} - -static void -settings_process_messages(void) -{ - MSG msg; - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } -} - -static BOOL -image_list_init(HWND hdlg, int id, const uint8_t *icon_ids) -{ - HICON hiconItem; - HIMAGELIST hSmall; - HWND hwndList = GetDlgItem(hdlg, id); - - int i = 0; - - hSmall = ListView_GetImageList(hwndList, LVSIL_SMALL); - if (hSmall != 0) - ImageList_Destroy(hSmall); - - hSmall = ImageList_Create(win_get_system_metrics(SM_CXSMICON, dpi), - win_get_system_metrics(SM_CYSMICON, dpi), - ILC_MASK | ILC_COLOR32, 1, 1); - - while (1) { - if (icon_ids[i] == 0) - break; - - hiconItem = hIcon[icon_ids[i]]; - ImageList_AddIcon(hSmall, hiconItem); - - i++; - } - - ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); - - return TRUE; -} - -/* Show a MessageBox dialog. This is nasty, I know. --FvK */ -static int -settings_msgbox_header(int flags, void *header, void *message) -{ - HWND h; - int i; - - h = hwndMain; - hwndMain = hwndParentDialog; - - i = ui_msgbox_header(flags, header, message); - - hwndMain = h; - - return i; -} - -static int -settings_msgbox_ex(int flags, void *header, void *message, void *btn1, void *btn2, void *btn3) -{ - HWND h; - int i; - - h = hwndMain; - hwndMain = hwndParentDialog; - - i = ui_msgbox_ex(flags, header, message, btn1, btn2, btn3); - - hwndMain = h; - - return i; -} - -/* This does the initial read of global variables into the temporary ones. */ -static void -win_settings_init(void) -{ - int i = 0; - - /* Machine category */ - temp_machine_type = machine_get_type(machine); - temp_machine = machine; - temp_cpu_f = cpu_f; - temp_wait_states = cpu_waitstates; - temp_cpu = cpu; - temp_mem_size = mem_size; -#ifdef USE_DYNAREC - temp_dynarec = cpu_use_dynarec; -#endif - temp_fpu_softfloat = fpu_softfloat; - temp_fpu = fpu_type; - temp_sync = time_sync; - - /* Video category */ - temp_gfxcard[0] = gfxcard[0]; - temp_gfxcard[1] = gfxcard[1]; - temp_voodoo = voodoo_enabled; - temp_ibm8514 = ibm8514_standalone_enabled; - temp_xga = xga_standalone_enabled; - - /* Input devices category */ - temp_mouse = mouse_type; - temp_joystick = joystick_type; - - /* Sound category */ - for (i = 0; i < SOUND_CARD_MAX; i++) - temp_sound_card[i] = sound_card_current[i]; - temp_midi_output_device = midi_output_device_current; - temp_midi_input_device = midi_input_device_current; - temp_mpu401 = mpu401_standalone_enable; - temp_float = sound_is_float; - temp_fm_driver = fm_driver; - - /* Network category */ - for (i = 0; i < NET_CARD_MAX; i++) { - temp_net_type[i] = net_cards_conf[i].net_type; - memset(temp_pcap_dev[i], 0, sizeof(temp_pcap_dev[i])); -#ifdef ENABLE_SETTINGS_LOG - assert(sizeof(temp_pcap_dev[i]) == sizeof(net_cards_conf[i].host_dev_name)); -#endif - memcpy(temp_pcap_dev[i], net_cards_conf[i].host_dev_name, sizeof(net_cards_conf[i].host_dev_name)); - temp_net_card[i] = net_cards_conf[i].device_num; - } - - /* Ports category */ - for (i = 0; i < PARALLEL_MAX; i++) { - temp_lpt_devices[i] = lpt_ports[i].device; - temp_lpt[i] = lpt_ports[i].enabled; - } - for (i = 0; i < SERIAL_MAX; i++) { - temp_serial[i] = com_ports[i].enabled; - temp_serial_passthrough_enabled[i] = serial_passthrough_enabled[i]; - } - - /* Storage devices category */ - for (i = 0; i < SCSI_BUS_MAX; i++) - temp_scsi_card[i] = scsi_card_current[i]; - temp_fdc_card = fdc_type; - temp_hdc = hdc_current; - temp_ide_ter = ide_ter_enabled; - temp_ide_qua = ide_qua_enabled; - temp_cassette = cassette_enable; - - mfm_tracking = xta_tracking = esdi_tracking = ide_tracking = 0; - for (i = 0; i < SCSI_LUN_MAX; i++) - scsi_tracking[i] = 0; - - /* Hard disks category */ - memcpy(temp_hdd, hdd, HDD_NUM * sizeof(hard_disk_t)); - for (i = 0; i < HDD_NUM; i++) { - if (hdd[i].bus == HDD_BUS_MFM) - mfm_tracking |= (1 << (hdd[i].mfm_channel << 3)); - else if (hdd[i].bus == HDD_BUS_XTA) - xta_tracking |= (1 << (hdd[i].xta_channel << 3)); - else if (hdd[i].bus == HDD_BUS_ESDI) - esdi_tracking |= (1 << (hdd[i].esdi_channel << 3)); - else if ((hdd[i].bus == HDD_BUS_IDE) || (hdd[i].bus == HDD_BUS_ATAPI)) - ide_tracking |= (1 << (hdd[i].ide_channel << 3)); - else if (hdd[i].bus == HDD_BUS_SCSI) - scsi_tracking[hdd[i].scsi_id >> 3] |= (1 << ((hdd[i].scsi_id & 0x07) << 3)); - } - - /* Floppy drives category */ - for (i = 0; i < FDD_NUM; i++) { - temp_fdd_types[i] = fdd_get_type(i); - temp_fdd_turbo[i] = fdd_get_turbo(i); - temp_fdd_check_bpb[i] = fdd_get_check_bpb(i); - } - - /* Other removable devices category */ - memcpy(temp_cdrom, cdrom, CDROM_NUM * sizeof(cdrom_t)); - for (i = 0; i < CDROM_NUM; i++) { - if (cdrom[i].bus_type == CDROM_BUS_ATAPI) - ide_tracking |= (2 << (cdrom[i].ide_channel << 3)); - else if (cdrom[i].bus_type == CDROM_BUS_SCSI) - scsi_tracking[cdrom[i].scsi_device_id >> 3] |= (1 << ((cdrom[i].scsi_device_id & 0x07) << 3)); - } - memcpy(temp_zip_drives, zip_drives, ZIP_NUM * sizeof(zip_drive_t)); - for (i = 0; i < ZIP_NUM; i++) { - if (zip_drives[i].bus_type == ZIP_BUS_ATAPI) - ide_tracking |= (4 << (zip_drives[i].ide_channel << 3)); - else if (zip_drives[i].bus_type == ZIP_BUS_SCSI) - scsi_tracking[zip_drives[i].scsi_device_id >> 3] |= (1 << ((zip_drives[i].scsi_device_id & 0x07) << 3)); - } - memcpy(temp_mo_drives, mo_drives, MO_NUM * sizeof(mo_drive_t)); - for (i = 0; i < MO_NUM; i++) { - if (mo_drives[i].bus_type == MO_BUS_ATAPI) - ide_tracking |= (1 << (mo_drives[i].ide_channel << 3)); - else if (mo_drives[i].bus_type == MO_BUS_SCSI) - scsi_tracking[mo_drives[i].scsi_device_id >> 3] |= (1 << ((mo_drives[i].scsi_device_id & 0x07) << 3)); - } - - /* Other peripherals category */ - temp_bugger = bugger_enabled; - temp_postcard = postcard_enabled; - temp_isartc = isartc_type; - - /* ISA memory boards. */ - for (i = 0; i < ISAMEM_MAX; i++) - temp_isamem[i] = isamem_type[i]; - - temp_deviceconfig = 0; -} - -/* This returns 1 if any variable has changed, 0 if not. */ -static int -win_settings_changed(void) -{ - int i = 0; - - /* Machine category */ - i = i || (machine != temp_machine); - i = i || (cpu_f != temp_cpu_f); - i = i || (cpu_waitstates != temp_wait_states); - i = i || (cpu != temp_cpu); - i = i || (mem_size != temp_mem_size); -#ifdef USE_DYNAREC - i = i || (temp_dynarec != cpu_use_dynarec); -#endif - i = i || (temp_fpu_softfloat != fpu_softfloat); - i = i || (temp_fpu != fpu_type); - i = i || (temp_sync != time_sync); - - /* Video category */ - i = i || (gfxcard[0] != temp_gfxcard[0]); - i = i || (gfxcard[1] != temp_gfxcard[1]); - i = i || (voodoo_enabled != temp_voodoo); - i = i || (ibm8514_standalone_enabled != temp_ibm8514); - i = i || (xga_standalone_enabled != temp_xga); - - /* Input devices category */ - i = i || (mouse_type != temp_mouse); - i = i || (joystick_type != temp_joystick); - - /* Sound category */ - for (uint8_t j = 0; j < SOUND_CARD_MAX; j++) - i = i || (sound_card_current[j] != temp_sound_card[j]); - i = i || (midi_output_device_current != temp_midi_output_device); - i = i || (midi_input_device_current != temp_midi_input_device); - i = i || (mpu401_standalone_enable != temp_mpu401); - i = i || (sound_is_float != temp_float); - i = i || (fm_driver != temp_fm_driver); - - /* Network category */ - for (uint8_t j = 0; j < NET_CARD_MAX; j++) { - i = i || (net_cards_conf[j].net_type != temp_net_type[j]); - i = i || strcmp(temp_pcap_dev[j], net_cards_conf[j].host_dev_name); - i = i || (net_cards_conf[j].device_num != temp_net_card[j]); - } - - /* Ports category */ - for (uint8_t j = 0; j < PARALLEL_MAX; j++) { - i = i || (temp_lpt_devices[j] != lpt_ports[j].device); - i = i || (temp_lpt[j] != lpt_ports[j].enabled); - } - for (uint8_t j = 0; j < SERIAL_MAX; j++) { - i = i || (temp_serial[j] != com_ports[j].enabled); - i = i || (temp_serial_passthrough_enabled[i] != serial_passthrough_enabled[i]); - } - - /* Storage devices category */ - for (uint8_t j = 0; j < SCSI_BUS_MAX; j++) - i = i || (temp_scsi_card[j] != scsi_card_current[j]); - i = i || (fdc_type != temp_fdc_card); - i = i || (hdc_current != temp_hdc); - i = i || (temp_ide_ter != ide_ter_enabled); - i = i || (temp_ide_qua != ide_qua_enabled); - i = i || (temp_cassette != cassette_enable); - - /* Hard disks category */ - i = i || memcmp(hdd, temp_hdd, HDD_NUM * sizeof(hard_disk_t)); - - /* Floppy drives category */ - for (uint8_t j = 0; j < FDD_NUM; j++) { - i = i || (temp_fdd_types[j] != fdd_get_type(j)); - i = i || (temp_fdd_turbo[j] != fdd_get_turbo(j)); - i = i || (temp_fdd_check_bpb[j] != fdd_get_check_bpb(j)); - } - - /* Other removable devices category */ - i = i || memcmp(cdrom, temp_cdrom, CDROM_NUM * sizeof(cdrom_t)); - i = i || memcmp(zip_drives, temp_zip_drives, ZIP_NUM * sizeof(zip_drive_t)); - i = i || memcmp(mo_drives, temp_mo_drives, MO_NUM * sizeof(mo_drive_t)); - - /* Other peripherals category */ - i = i || (temp_bugger != bugger_enabled); - i = i || (temp_postcard != postcard_enabled); - i = i || (temp_isartc != isartc_type); - - /* ISA memory boards. */ - for (uint8_t j = 0; j < ISAMEM_MAX; j++) - i = i || (temp_isamem[j] != isamem_type[j]); - - i = i || !!temp_deviceconfig; - - return i; -} - -/* This saves the settings back to the global variables. */ -static void -win_settings_save(void) -{ - pc_reset_hard_close(); - - /* Machine category */ - machine = temp_machine; - cpu_f = temp_cpu_f; - cpu_waitstates = temp_wait_states; - cpu = temp_cpu; - mem_size = temp_mem_size; -#ifdef USE_DYNAREC - cpu_use_dynarec = temp_dynarec; -#endif - fpu_softfloat = temp_fpu_softfloat; - fpu_type = temp_fpu; - time_sync = temp_sync; - - /* Video category */ - gfxcard[0] = temp_gfxcard[0]; - gfxcard[1] = temp_gfxcard[1]; - voodoo_enabled = temp_voodoo; - ibm8514_standalone_enabled = temp_ibm8514; - xga_standalone_enabled = temp_xga; - - /* Input devices category */ - mouse_type = temp_mouse; - joystick_type = temp_joystick; - - /* Sound category */ - for (uint8_t i = 0; i < SOUND_CARD_MAX; i++) - sound_card_current[i] = temp_sound_card[i]; - midi_output_device_current = temp_midi_output_device; - midi_input_device_current = temp_midi_input_device; - mpu401_standalone_enable = temp_mpu401; - sound_is_float = temp_float; - fm_driver = temp_fm_driver; - - /* Network category */ - for (uint8_t i = 0; i < NET_CARD_MAX; i++) { - net_cards_conf[i].net_type = temp_net_type[i]; - memset(net_cards_conf[i].host_dev_name, '\0', sizeof(net_cards_conf[i].host_dev_name)); - strcpy(net_cards_conf[i].host_dev_name, temp_pcap_dev[i]); - net_cards_conf[i].device_num = temp_net_card[i]; - } - - /* Ports category */ - for (uint8_t i = 0; i < PARALLEL_MAX; i++) { - lpt_ports[i].device = temp_lpt_devices[i]; - lpt_ports[i].enabled = temp_lpt[i]; - } - for (uint8_t i = 0; i < SERIAL_MAX; i++) { - com_ports[i].enabled = temp_serial[i]; - serial_passthrough_enabled[i] = temp_serial_passthrough_enabled[i]; - } - - /* Storage devices category */ - for (uint8_t i = 0; i < SCSI_BUS_MAX; i++) - scsi_card_current[i] = temp_scsi_card[i]; - hdc_current = temp_hdc; - fdc_type = temp_fdc_card; - ide_ter_enabled = temp_ide_ter; - ide_qua_enabled = temp_ide_qua; - cassette_enable = temp_cassette; - - /* Hard disks category */ - memcpy(hdd, temp_hdd, HDD_NUM * sizeof(hard_disk_t)); - for (uint8_t i = 0; i < HDD_NUM; i++) - hdd[i].priv = NULL; - - /* Floppy drives category */ - for (uint8_t i = 0; i < FDD_NUM; i++) { - fdd_set_type(i, temp_fdd_types[i]); - fdd_set_turbo(i, temp_fdd_turbo[i]); - fdd_set_check_bpb(i, temp_fdd_check_bpb[i]); - } - - /* Removable devices category */ - memcpy(cdrom, temp_cdrom, CDROM_NUM * sizeof(cdrom_t)); - for (uint8_t i = 0; i < CDROM_NUM; i++) { - cdrom[i].is_dir = 0; - cdrom[i].priv = NULL; - cdrom[i].ops = NULL; - cdrom[i].image = NULL; - cdrom[i].insert = NULL; - cdrom[i].close = NULL; - cdrom[i].get_volume = NULL; - cdrom[i].get_channel = NULL; - } - memcpy(zip_drives, temp_zip_drives, ZIP_NUM * sizeof(zip_drive_t)); - for (uint8_t i = 0; i < ZIP_NUM; i++) { - zip_drives[i].fp = NULL; - zip_drives[i].priv = NULL; - } - memcpy(mo_drives, temp_mo_drives, MO_NUM * sizeof(mo_drive_t)); - for (uint8_t i = 0; i < MO_NUM; i++) { - mo_drives[i].fp = NULL; - mo_drives[i].priv = NULL; - } - - /* Other peripherals category */ - bugger_enabled = temp_bugger; - postcard_enabled = temp_postcard; - isartc_type = temp_isartc; - - /* ISA memory boards. */ - for (uint8_t i = 0; i < ISAMEM_MAX; i++) - isamem_type[i] = temp_isamem[i]; - - /* Mark configuration as changed. */ - config_changed = 2; - - pc_reset_hard_init(); -} - -static void -win_settings_machine_recalc_softfloat(HWND hdlg) -{ - if (temp_fpu == FPU_NONE) { - settings_set_check(hdlg, IDC_CHECK_SOFTFLOAT, FALSE); - settings_enable_window(hdlg, IDC_CHECK_SOFTFLOAT, FALSE); - } else { - settings_set_check(hdlg, IDC_CHECK_SOFTFLOAT, (machine_has_flags(temp_machine, MACHINE_SOFTFLOAT_ONLY) ? TRUE : temp_fpu_softfloat)); - settings_enable_window(hdlg, IDC_CHECK_SOFTFLOAT, (machine_has_flags(temp_machine, MACHINE_SOFTFLOAT_ONLY) ? FALSE : TRUE)); - } -} - -static void -win_settings_machine_recalc_fpu(HWND hdlg) -{ - int c; - int type; - LPTSTR lptsTemp; - const char *stransi; - - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - - settings_reset_content(hdlg, IDC_COMBO_FPU); - c = 0; - while (1) { - stransi = fpu_get_name_from_index(temp_cpu_f, temp_cpu, c); - type = fpu_get_type_from_index(temp_cpu_f, temp_cpu, c); - if (!stransi) - break; - - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - settings_add_string(hdlg, IDC_COMBO_FPU, (LPARAM) (LPCSTR) lptsTemp); - if (!c || (type == temp_fpu)) - settings_set_cur_sel(hdlg, IDC_COMBO_FPU, c); - - c++; - } - - settings_enable_window(hdlg, IDC_COMBO_FPU, c > 1); - - temp_fpu = fpu_get_type_from_index(temp_cpu_f, temp_cpu, settings_get_cur_sel(hdlg, IDC_COMBO_FPU)); - - win_settings_machine_recalc_softfloat(hdlg); -} - -static void -win_settings_machine_recalc_cpu(HWND hdlg) -{ - int cpu_type; -#ifdef USE_DYNAREC - int cpu_flags; -#endif - - cpu_type = temp_cpu_f->cpus[temp_cpu].cpu_type; - settings_enable_window(hdlg, IDC_COMBO_WS, (cpu_type >= CPU_286) && (cpu_type <= CPU_386DX)); - -#ifdef USE_DYNAREC - cpu_flags = temp_cpu_f->cpus[temp_cpu].cpu_flags; - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) && (cpu_flags & CPU_REQUIRES_DYNAREC)) - fatal("Attempting to select a CPU that requires the recompiler and does not support it at the same time\n"); - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || ((cpu_flags & CPU_REQUIRES_DYNAREC) && !cpu_override)) { - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC)) - temp_dynarec = 0; - if (cpu_flags & CPU_REQUIRES_DYNAREC) - temp_dynarec = 1; - settings_set_check(hdlg, IDC_CHECK_DYNAREC, temp_dynarec); - settings_enable_window(hdlg, IDC_CHECK_DYNAREC, FALSE); - } else { - settings_set_check(hdlg, IDC_CHECK_DYNAREC, temp_dynarec); - settings_enable_window(hdlg, IDC_CHECK_DYNAREC, TRUE); - } -#endif - - win_settings_machine_recalc_fpu(hdlg); -} - -static void -win_settings_machine_recalc_cpu_m(HWND hdlg) -{ - int c; - int i; - int first_eligible = -1; - int current_eligible = 0; - int last_eligible = 0; - LPTSTR lptsTemp; - const char *stransi; - - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - - settings_reset_content(hdlg, IDC_COMBO_CPU_SPEED); - c = i = 0; - while (temp_cpu_f->cpus[c].cpu_type != 0) { - if (cpu_is_eligible(temp_cpu_f, c, temp_machine)) { - stransi = (char *) temp_cpu_f->cpus[c].name; - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - settings_add_string(hdlg, IDC_COMBO_CPU_SPEED, (LPARAM) (LPCSTR) lptsTemp); - - if (first_eligible == -1) - first_eligible = i; - if (temp_cpu == c) - current_eligible = i; - last_eligible = i; - - listtocpu[i++] = c; - } - c++; - } - if (i == 0) - fatal("No eligible CPUs for the selected family\n"); - settings_enable_window(hdlg, IDC_COMBO_CPU_SPEED, i != 1); - if (current_eligible < first_eligible) - current_eligible = first_eligible; - else if (current_eligible > last_eligible) - current_eligible = last_eligible; - temp_cpu = listtocpu[current_eligible]; - settings_set_cur_sel(hdlg, IDC_COMBO_CPU_SPEED, current_eligible); - - win_settings_machine_recalc_cpu(hdlg); - - free(lptsTemp); -} - -static void -win_settings_machine_recalc_machine(HWND hdlg) -{ - HWND h; - int c; - int i; - int current_eligible; - LPTSTR lptsTemp; - char *stransi; - UDACCEL accel; - const device_t *d; - - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - - d = (device_t *) machine_get_device(temp_machine); - settings_enable_window(hdlg, IDC_CONFIGURE_MACHINE, d && d->config); - - settings_reset_content(hdlg, IDC_COMBO_CPU_TYPE); - c = i = 0; - current_eligible = -1; - while (cpu_families[c].package != 0) { - if (cpu_family_is_eligible(&cpu_families[c], temp_machine)) { - stransi = malloc(strlen((char *) cpu_families[c].manufacturer) + strlen((char *) cpu_families[c].name) + 2); - sprintf(stransi, "%s %s", (char *) cpu_families[c].manufacturer, (char *) cpu_families[c].name); - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - free(stransi); - settings_add_string(hdlg, IDC_COMBO_CPU_TYPE, (LPARAM) (LPCSTR) lptsTemp); - if (&cpu_families[c] == temp_cpu_f) - current_eligible = i; - listtocpufamily[i++] = c; - } - c++; - } - if (i == 0) - fatal("No eligible CPU families for the selected machine\n"); - settings_enable_window(hdlg, IDC_COMBO_CPU_TYPE, TRUE); - if (current_eligible == -1) { - temp_cpu_f = (cpu_family_t *) &cpu_families[listtocpufamily[0]]; - settings_set_cur_sel(hdlg, IDC_COMBO_CPU_TYPE, 0); - } else { - settings_set_cur_sel(hdlg, IDC_COMBO_CPU_TYPE, current_eligible); - } - settings_enable_window(hdlg, IDC_COMBO_CPU_TYPE, i != 1); - - win_settings_machine_recalc_cpu_m(hdlg); - - if (machine_get_ram_granularity(temp_machine) & 1023) { - /* KB granularity */ - h = GetDlgItem(hdlg, IDC_MEMSPIN); - SendMessage(h, UDM_SETRANGE, 0, (machine_get_min_ram(temp_machine) << 16) | machine_get_max_ram(temp_machine)); - - accel.nSec = 0; - accel.nInc = machine_get_ram_granularity(temp_machine); - SendMessage(h, UDM_SETACCEL, 1, (LPARAM) &accel); - - SendMessage(h, UDM_SETPOS, 0, temp_mem_size); - - h = GetDlgItem(hdlg, IDC_TEXT_MB); - SendMessage(h, WM_SETTEXT, 0, win_get_string(IDS_KB)); - } else { - /* MB granularity */ - h = GetDlgItem(hdlg, IDC_MEMSPIN); - SendMessage(h, UDM_SETRANGE, 0, (machine_get_min_ram(temp_machine) << 6) | (machine_get_max_ram(temp_machine) >> 10)); - - accel.nSec = 0; - accel.nInc = machine_get_ram_granularity(temp_machine) >> 10; - - SendMessage(h, UDM_SETACCEL, 1, (LPARAM) &accel); - - SendMessage(h, UDM_SETPOS, 0, temp_mem_size >> 10); - - h = GetDlgItem(hdlg, IDC_TEXT_MB); - SendMessage(h, WM_SETTEXT, 0, win_get_string(IDS_MB)); - } - - settings_enable_window(hdlg, IDC_MEMSPIN, machine_get_min_ram(temp_machine) != machine_get_max_ram(temp_machine)); - settings_enable_window(hdlg, IDC_MEMTEXT, machine_get_min_ram(temp_machine) != machine_get_max_ram(temp_machine)); - - free(lptsTemp); -} - -static char * -machine_type_get_internal_name(int id) -{ - if (id < MACHINE_TYPE_MAX) - return ""; - else - return NULL; -} - -int -machine_type_available(int id) -{ - int c = 0; - - if ((id > 0) && (id < MACHINE_TYPE_MAX)) { - while (machine_get_internal_name_ex(c) != NULL) { - if (machine_available(c) && (machine_get_type(c) == id)) - return 1; - c++; - } - } - - return 0; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - HWND h; - HWND h2; - int c; - int d; - int old_machine_type; - LPTSTR lptsTemp; - char *stransi; - - switch (message) { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_MACHINE_TYPE); - memset(listtomachinetype, 0x00, sizeof(listtomachinetype)); - while (machine_type_get_internal_name(c) != NULL) { - if (machine_type_available(c)) { - stransi = (char *) machine_types[c].name; - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - settings_add_string(hdlg, IDC_COMBO_MACHINE_TYPE, (LPARAM) lptsTemp); - listtomachinetype[d] = c; - if (c == temp_machine_type) - settings_set_cur_sel(hdlg, IDC_COMBO_MACHINE_TYPE, d); - d++; - } - c++; - } - - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_MACHINE); - memset(listtomachine, 0x00, sizeof(listtomachine)); - while (machine_get_internal_name_ex(c) != NULL) { - if (machine_available(c) && (machine_get_type(c) == temp_machine_type)) { - stransi = (char *) machine_getname_ex(c); - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - settings_add_string(hdlg, IDC_COMBO_MACHINE, (LPARAM) lptsTemp); - listtomachine[d] = c; - if (c == temp_machine) - settings_set_cur_sel(hdlg, IDC_COMBO_MACHINE, d); - d++; - } - c++; - } - - settings_add_string(hdlg, IDC_COMBO_WS, win_get_string(IDS_DEFAULT)); - for (c = 0; c < 8; c++) { /* TODO */ - wsprintf(lptsTemp, plat_get_string(IDS_WS), c); - settings_add_string(hdlg, IDC_COMBO_WS, (LPARAM) lptsTemp); - } - - settings_set_cur_sel(hdlg, IDC_COMBO_WS, temp_wait_states); - -#ifdef USE_DYNAREC - settings_set_check(hdlg, IDC_CHECK_DYNAREC, 0); -#endif - - settings_set_check(hdlg, IDC_CHECK_SOFTFLOAT, 0); - - h = GetDlgItem(hdlg, IDC_MEMSPIN); - h2 = GetDlgItem(hdlg, IDC_MEMTEXT); - SendMessage(h, UDM_SETBUDDY, (WPARAM) h2, 0); - - if (temp_sync & TIME_SYNC_ENABLED) { - if (temp_sync & TIME_SYNC_UTC) - settings_set_check(hdlg, IDC_RADIO_TS_UTC, BST_CHECKED); - else - settings_set_check(hdlg, IDC_RADIO_TS_LOCAL, BST_CHECKED); - } else - settings_set_check(hdlg, IDC_RADIO_TS_DISABLED, BST_CHECKED); - - win_settings_machine_recalc_machine(hdlg); - - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_COMBO_MACHINE_TYPE: - if (HIWORD(wParam) == CBN_SELCHANGE) { - old_machine_type = temp_machine_type; - temp_machine_type = listtomachinetype[settings_get_cur_sel(hdlg, IDC_COMBO_MACHINE_TYPE)]; - - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - - settings_reset_content(hdlg, IDC_COMBO_MACHINE); - c = d = 0; - memset(listtomachine, 0x00, sizeof(listtomachine)); - while (machine_get_internal_name_ex(c) != NULL) { - if (machine_available(c) && (machine_get_type(c) == temp_machine_type)) { - stransi = (char *) machine_getname_ex(c); - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - settings_add_string(hdlg, IDC_COMBO_MACHINE, (LPARAM) lptsTemp); - listtomachine[d] = c; - if (c == temp_machine) - settings_set_cur_sel(hdlg, IDC_COMBO_MACHINE, d); - d++; - } - c++; - } - if (old_machine_type != temp_machine_type) { - settings_set_cur_sel(hdlg, IDC_COMBO_MACHINE, 0); - temp_machine = listtomachine[0]; - - win_settings_machine_recalc_machine(hdlg); - } - - free(lptsTemp); - } - break; - case IDC_COMBO_MACHINE: - if (HIWORD(wParam) == CBN_SELCHANGE) { - temp_machine = listtomachine[settings_get_cur_sel(hdlg, IDC_COMBO_MACHINE)]; - win_settings_machine_recalc_machine(hdlg); - } - break; - case IDC_COMBO_CPU_TYPE: - if (HIWORD(wParam) == CBN_SELCHANGE) { - temp_cpu_f = (cpu_family_t *) &cpu_families[listtocpufamily[settings_get_cur_sel(hdlg, IDC_COMBO_CPU_TYPE)]]; - temp_cpu = 0; - win_settings_machine_recalc_cpu_m(hdlg); - } - break; - case IDC_COMBO_CPU_SPEED: - if (HIWORD(wParam) == CBN_SELCHANGE) { - temp_cpu = listtocpu[settings_get_cur_sel(hdlg, IDC_COMBO_CPU_SPEED)]; - win_settings_machine_recalc_cpu(hdlg); - } - break; - case IDC_COMBO_FPU: - if (HIWORD(wParam) == CBN_SELCHANGE) { - temp_fpu = fpu_get_type_from_index(temp_cpu_f, temp_cpu, - settings_get_cur_sel(hdlg, IDC_COMBO_FPU)); - } - win_settings_machine_recalc_softfloat(hdlg); - break; - case IDC_CONFIGURE_MACHINE: - temp_machine = listtomachine[settings_get_cur_sel(hdlg, IDC_COMBO_MACHINE)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) machine_get_device(temp_machine)); - break; - } - - return FALSE; - - case WM_SAVESETTINGS: - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - stransi = (char *) malloc(512); - -#ifdef USE_DYNAREC - temp_dynarec = settings_get_check(hdlg, IDC_CHECK_DYNAREC); -#endif - - temp_fpu_softfloat = settings_get_check(hdlg, IDC_CHECK_SOFTFLOAT); - - if (settings_get_check(hdlg, IDC_RADIO_TS_DISABLED)) - temp_sync = TIME_SYNC_DISABLED; - - if (settings_get_check(hdlg, IDC_RADIO_TS_LOCAL)) - temp_sync = TIME_SYNC_ENABLED; - - if (settings_get_check(hdlg, IDC_RADIO_TS_UTC)) - temp_sync = TIME_SYNC_ENABLED | TIME_SYNC_UTC; - - temp_wait_states = settings_get_cur_sel(hdlg, IDC_COMBO_WS); - - h = GetDlgItem(hdlg, IDC_MEMTEXT); - SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, 512); - sscanf(stransi, "%u", &temp_mem_size); - if (!(machine_get_ram_granularity(temp_machine) & 1023)) - temp_mem_size = temp_mem_size << 10; - temp_mem_size &= ~(machine_get_ram_granularity(temp_machine) - 1); - if (temp_mem_size < machine_get_min_ram(temp_machine)) - temp_mem_size = machine_get_min_ram(temp_machine); - else if (temp_mem_size > machine_get_max_ram(temp_machine)) - temp_mem_size = machine_get_max_ram(temp_machine); - free(stransi); - free(lptsTemp); - - default: - return FALSE; - } - - return FALSE; -} - -static void -generate_device_name(const device_t *device, const char *internal_name, int bus) -{ - char temp[512]; - const WCHAR *wtemp; - - memset(device_name, 0x00, 512 * sizeof(WCHAR)); - memset(temp, 0x00, 512); - - if (!strcmp(internal_name, "none")) { - /* Translate "None". */ - wtemp = (WCHAR *) win_get_string(IDS_2104); - memcpy(device_name, wtemp, (wcslen(wtemp) + 1) * sizeof(WCHAR)); - return; - } else if (!strcmp(internal_name, "internal")) - memcpy(temp, "Internal", 9); - else - device_get_name(device, bus, temp); - - mbstowcs(device_name, temp, strlen(temp) + 1); -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - int c = 0; - int d = 0; - int e; - - switch (message) { - case WM_INITDIALOG: - // Primary Video Card - settings_reset_content(hdlg, IDC_COMBO_VIDEO); - - while (1) { - /* Skip "internal" if machine doesn't have it. */ - if ((c == 1) && !machine_has_flags(temp_machine, MACHINE_VIDEO)) { - c++; - continue; - } - - generate_device_name(video_card_getdevice(c), video_get_internal_name(c), 1); - - if (!device_name[0]) - break; - - if (video_card_available(c) && device_is_valid(video_card_getdevice(c), temp_machine)) { - if (c == 0) // "None" - settings_add_string(hdlg, IDC_COMBO_VIDEO, win_get_string(IDS_2104)); - else if (c == 1) // "Internal" - settings_add_string(hdlg, IDC_COMBO_VIDEO, win_get_string(IDS_2119)); - else - settings_add_string(hdlg, IDC_COMBO_VIDEO, (LPARAM) device_name); - settings_list_to_device[0][d] = c; - if ((c == 0) || (c == temp_gfxcard[0])) - settings_set_cur_sel(hdlg, IDC_COMBO_VIDEO, d); - d++; - } - - c++; - - settings_process_messages(); - } - - settings_enable_window(hdlg, IDC_COMBO_VIDEO, !machine_has_flags(temp_machine, MACHINE_VIDEO_ONLY)); - e = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)]; - settings_enable_window(hdlg, IDC_CONFIGURE_VID, video_card_has_config(e)); - - // Secondary Video Card - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_VIDEO_2); - - while (1) { - /* Skip "internal" if machine doesn't have it. */ - if ((c == 1) && !machine_has_flags(temp_machine, MACHINE_VIDEO)) { - c++; - continue; - } - - generate_device_name(video_card_getdevice(c), video_get_internal_name(c), 1); - - if (!device_name[0]) - break; - - if ((c > 1) && (video_card_get_flags(c) == video_card_get_flags(temp_gfxcard[0]))) { - c++; - continue; - } - - if (video_card_available(c) && device_is_valid(video_card_getdevice(c), temp_machine)) { - if (c == 0) // "None" - settings_add_string(hdlg, IDC_COMBO_VIDEO_2, win_get_string(IDS_2104)); - else if (c == 1) // "Internal" - settings_add_string(hdlg, IDC_COMBO_VIDEO_2, win_get_string(IDS_2119)); - else - settings_add_string(hdlg, IDC_COMBO_VIDEO_2, (LPARAM) device_name); - settings_list_to_device[1][d] = c; - if ((c == 0) || (c == temp_gfxcard[1])) - settings_set_cur_sel(hdlg, IDC_COMBO_VIDEO_2, d); - d++; - } - - c++; - - settings_process_messages(); - } - - settings_enable_window(hdlg, IDC_COMBO_VIDEO_2, !machine_has_flags(temp_machine, MACHINE_VIDEO_ONLY)); - e = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO_2)]; - settings_enable_window(hdlg, IDC_CONFIGURE_VID_2, video_card_has_config(e)); - - settings_enable_window(hdlg, IDC_CHECK_VOODOO, machine_has_bus(temp_machine, MACHINE_BUS_PCI)); - settings_set_check(hdlg, IDC_CHECK_VOODOO, temp_voodoo); - settings_enable_window(hdlg, IDC_BUTTON_VOODOO, machine_has_bus(temp_machine, MACHINE_BUS_PCI) && temp_voodoo); - - settings_enable_window(hdlg, IDC_CHECK_IBM8514, machine_has_bus(temp_machine, MACHINE_BUS_ISA16) || machine_has_bus(temp_machine, MACHINE_BUS_MCA)); - settings_set_check(hdlg, IDC_CHECK_IBM8514, temp_ibm8514); - - settings_enable_window(hdlg, IDC_CHECK_XGA, machine_has_bus(temp_machine, MACHINE_BUS_ISA16) || machine_has_bus(temp_machine, MACHINE_BUS_MCA)); - settings_set_check(hdlg, IDC_CHECK_XGA, temp_xga); - settings_enable_window(hdlg, IDC_BUTTON_XGA, (machine_has_bus(temp_machine, MACHINE_BUS_ISA16) || machine_has_bus(temp_machine, MACHINE_BUS_MCA)) && temp_xga); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_COMBO_VIDEO: - temp_gfxcard[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)]; - settings_enable_window(hdlg, IDC_CONFIGURE_VID, video_card_has_config(temp_gfxcard[0])); - - // Secondary Video Card - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_VIDEO_2); - - while (1) { - /* Skip "internal" if machine doesn't have it. */ - if ((c == 1) && !machine_has_flags(temp_machine, MACHINE_VIDEO)) { - c++; - continue; - } - - generate_device_name(video_card_getdevice(c), video_get_internal_name(c), 1); - - if (!device_name[0]) - break; - - if ((c > 1) && (video_card_get_flags(c) == video_card_get_flags(temp_gfxcard[0]))) { - c++; - continue; - } - - if (video_card_available(c) && device_is_valid(video_card_getdevice(c), temp_machine)) { - if (c == 0) // "None" - settings_add_string(hdlg, IDC_COMBO_VIDEO_2, win_get_string(IDS_2104)); - else if (c == 1) // "Internal" - settings_add_string(hdlg, IDC_COMBO_VIDEO_2, win_get_string(IDS_2119)); - else - settings_add_string(hdlg, IDC_COMBO_VIDEO_2, (LPARAM) device_name); - settings_list_to_device[1][d] = c; - if ((c == 0) || (c == temp_gfxcard[1])) - settings_set_cur_sel(hdlg, IDC_COMBO_VIDEO_2, d); - d++; - } - - c++; - - settings_process_messages(); - } - - settings_enable_window(hdlg, IDC_COMBO_VIDEO_2, !machine_has_flags(temp_machine, MACHINE_VIDEO_ONLY)); - e = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO_2)]; - settings_enable_window(hdlg, IDC_CONFIGURE_VID_2, video_card_has_config(e)); - break; - - case IDC_COMBO_VIDEO_2: - temp_gfxcard[1] = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO_2)]; - settings_enable_window(hdlg, IDC_CONFIGURE_VID_2, video_card_has_config(temp_gfxcard[1])); - break; - - case IDC_CHECK_VOODOO: - temp_voodoo = settings_get_check(hdlg, IDC_CHECK_VOODOO); - settings_enable_window(hdlg, IDC_BUTTON_VOODOO, temp_voodoo); - break; - - case IDC_CHECK_IBM8514: - temp_ibm8514 = settings_get_check(hdlg, IDC_CHECK_IBM8514); - break; - - case IDC_CHECK_XGA: - temp_xga = settings_get_check(hdlg, IDC_CHECK_XGA); - settings_enable_window(hdlg, IDC_BUTTON_XGA, temp_xga); - break; - - case IDC_BUTTON_VOODOO: - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) &voodoo_device); - break; - - case IDC_BUTTON_XGA: - if (machine_has_bus(temp_machine, MACHINE_BUS_MCA) > 0) - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) &xga_device); - else - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) &xga_isa_device); - break; - - case IDC_CONFIGURE_VID: - temp_gfxcard[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) video_card_getdevice(temp_gfxcard[0])); - break; - - case IDC_CONFIGURE_VID_2: - temp_gfxcard[1] = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO_2)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) video_card_getdevice(temp_gfxcard[1])); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - temp_gfxcard[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)]; - temp_gfxcard[1] = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO_2)]; - temp_voodoo = settings_get_check(hdlg, IDC_CHECK_VOODOO); - temp_ibm8514 = settings_get_check(hdlg, IDC_CHECK_IBM8514); - temp_xga = settings_get_check(hdlg, IDC_CHECK_XGA); - - default: - return FALSE; - } - return FALSE; -} - -static int -mouse_valid(int num, int m) -{ - const device_t *dev; - - if ((num == MOUSE_TYPE_INTERNAL) && !machine_has_flags(m, MACHINE_MOUSE)) - return 0; - - dev = mouse_get_device(num); - return (device_is_valid(dev, m)); -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_input_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - wchar_t str[128]; - const char *joy_name; - int c; - int d; - - switch (message) { - case WM_INITDIALOG: - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_MOUSE); - for (c = 0; c < mouse_get_ndev(); c++) { - if (mouse_valid(c, temp_machine)) { - generate_device_name(mouse_get_device(c), mouse_get_internal_name(c), 0); - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_MOUSE, win_get_string(IDS_2104)); - else if (c == 1) - settings_add_string(hdlg, IDC_COMBO_MOUSE, win_get_string(IDS_2119)); - else - settings_add_string(hdlg, IDC_COMBO_MOUSE, (LPARAM) device_name); - settings_list_to_device[0][d] = c; - if ((c == 0) || (c == temp_mouse)) - settings_set_cur_sel(hdlg, IDC_COMBO_MOUSE, d); - d++; - } - } - - settings_enable_window(hdlg, IDC_CONFIGURE_MOUSE, mouse_has_config(temp_mouse)); - - c = 0; - joy_name = joystick_get_name(c); - while (joy_name) { - mbstowcs(str, joy_name, strlen(joy_name) + 1); - settings_add_string(hdlg, IDC_COMBO_JOYSTICK, (LPARAM) str); - - c++; - joy_name = joystick_get_name(c); - } - settings_enable_window(hdlg, IDC_COMBO_JOYSTICK, TRUE); - settings_set_cur_sel(hdlg, IDC_COMBO_JOYSTICK, temp_joystick); - - for (c = 0; c < 4; c++) - settings_enable_window(hdlg, IDC_JOY1 + c, joystick_get_max_joysticks(temp_joystick) > c); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_COMBO_MOUSE: - temp_mouse = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_MOUSE)]; - settings_enable_window(hdlg, IDC_CONFIGURE_MOUSE, mouse_has_config(temp_mouse)); - break; - - case IDC_CONFIGURE_MOUSE: - temp_mouse = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_MOUSE)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) mouse_get_device(temp_mouse)); - break; - - case IDC_COMBO_JOYSTICK: - temp_joystick = settings_get_cur_sel(hdlg, IDC_COMBO_JOYSTICK); - - for (c = 0; c < MAX_JOYSTICKS; c++) - settings_enable_window(hdlg, IDC_JOY1 + c, joystick_get_max_joysticks(temp_joystick) > c); - break; - - case IDC_JOY1: - case IDC_JOY2: - case IDC_JOY3: - case IDC_JOY4: - temp_joystick = settings_get_cur_sel(hdlg, IDC_COMBO_JOYSTICK); - temp_deviceconfig |= joystickconfig_open(hdlg, LOWORD(wParam) - IDC_JOY1, temp_joystick); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - temp_mouse = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_MOUSE)]; - temp_joystick = settings_get_cur_sel(hdlg, IDC_COMBO_JOYSTICK); - - default: - return FALSE; - } - return FALSE; -} - -static int -mpu401_present(void) -{ - return temp_mpu401 ? 1 : 0; -} - -int -mpu401_standalone_allow(void) -{ - const char *mdout; - const char *mdin; - - if (!machine_has_bus(temp_machine, MACHINE_BUS_ISA) && !machine_has_bus(temp_machine, MACHINE_BUS_MCA)) - return 0; - - mdout = midi_out_device_get_internal_name(temp_midi_output_device); - mdin = midi_in_device_get_internal_name(temp_midi_input_device); - - if (mdout != NULL) { - if (!strcmp(mdout, "none") && !strcmp(mdin, "none")) - return 0; - } - - return 1; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - uint16_t c; - uint16_t d; - LPTSTR lptsTemp; - const device_t *sound_dev[SOUND_CARD_MAX]; - - switch (message) { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_SOUND1); - while (1) { - /* Skip "internal" if machine doesn't have it. */ - if ((c == 1) && !machine_has_flags(temp_machine, MACHINE_SOUND)) { - c++; - continue; - } - - generate_device_name(sound_card_getdevice(c), sound_card_get_internal_name(c), 1); - - if (!device_name[0]) - break; - - if (sound_card_available(c)) { - sound_dev[0] = sound_card_getdevice(c); - - if (device_is_valid(sound_dev[0], temp_machine)) { - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_SOUND1, win_get_string(IDS_2104)); - else if (c == 1) - settings_add_string(hdlg, IDC_COMBO_SOUND1, win_get_string(IDS_2119)); - else - settings_add_string(hdlg, IDC_COMBO_SOUND1, (LPARAM) device_name); - settings_list_to_device[0][d] = c; - if ((c == 0) || (c == temp_sound_card[0])) - settings_set_cur_sel(hdlg, IDC_COMBO_SOUND1, d); - d++; - } - } - - c++; - } - - settings_enable_window(hdlg, IDC_COMBO_SOUND1, d); - settings_enable_window(hdlg, IDC_CONFIGURE_SND1, sound_card_has_config(temp_sound_card[0])); - - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_SOUND2); - while (1) { - /* Skip "internal" */ - if (c == 1) { - c++; - continue; - } - - generate_device_name(sound_card_getdevice(c), sound_card_get_internal_name(c), 1); - - if (!device_name[0]) - break; - - if (sound_card_available(c)) { - sound_dev[1] = sound_card_getdevice(c); - - if (device_is_valid(sound_dev[1], temp_machine)) { - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_SOUND2, win_get_string(IDS_2104)); - else if (c == 1) - settings_add_string(hdlg, IDC_COMBO_SOUND2, win_get_string(IDS_2119)); - else - settings_add_string(hdlg, IDC_COMBO_SOUND2, (LPARAM) device_name); - settings_list_to_device[0][d] = c; - if ((c == 0) || (c == temp_sound_card[1])) - settings_set_cur_sel(hdlg, IDC_COMBO_SOUND2, d); - d++; - } - } - - c++; - } - - settings_enable_window(hdlg, IDC_COMBO_SOUND2, d); - settings_enable_window(hdlg, IDC_CONFIGURE_SND2, sound_card_has_config(temp_sound_card[1])); - - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_SOUND3); - while (1) { - /* Skip "internal" */ - if (c == 1) { - c++; - continue; - } - - generate_device_name(sound_card_getdevice(c), sound_card_get_internal_name(c), 1); - - if (!device_name[0]) - break; - - if (sound_card_available(c)) { - sound_dev[2] = sound_card_getdevice(c); - - if (device_is_valid(sound_dev[2], temp_machine)) { - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_SOUND3, win_get_string(IDS_2104)); - else if (c == 1) - settings_add_string(hdlg, IDC_COMBO_SOUND3, win_get_string(IDS_2119)); - else - settings_add_string(hdlg, IDC_COMBO_SOUND3, (LPARAM) device_name); - settings_list_to_device[0][d] = c; - if ((c == 0) || (c == temp_sound_card[2])) - settings_set_cur_sel(hdlg, IDC_COMBO_SOUND3, d); - d++; - } - } - - c++; - } - - settings_enable_window(hdlg, IDC_COMBO_SOUND3, d); - settings_enable_window(hdlg, IDC_CONFIGURE_SND3, sound_card_has_config(temp_sound_card[2])); - - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_SOUND4); - while (1) { - /* Skip "internal" */ - if (c == 1) { - c++; - continue; - } - - generate_device_name(sound_card_getdevice(c), sound_card_get_internal_name(c), 1); - - if (!device_name[0]) - break; - - if (sound_card_available(c)) { - sound_dev[3] = sound_card_getdevice(c); - - if (device_is_valid(sound_dev[3], temp_machine)) { - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_SOUND4, win_get_string(IDS_2104)); - else if (c == 1) - settings_add_string(hdlg, IDC_COMBO_SOUND4, win_get_string(IDS_2119)); - else - settings_add_string(hdlg, IDC_COMBO_SOUND4, (LPARAM) device_name); - settings_list_to_device[0][d] = c; - if ((c == 0) || (c == temp_sound_card[3])) - settings_set_cur_sel(hdlg, IDC_COMBO_SOUND4, d); - d++; - } - } - - c++; - } - - settings_enable_window(hdlg, IDC_COMBO_SOUND4, d); - settings_enable_window(hdlg, IDC_CONFIGURE_SND4, sound_card_has_config(temp_sound_card[3])); - - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_MIDI_OUT); - while (1) { - generate_device_name(midi_out_device_getdevice(c), midi_out_device_get_internal_name(c), 0); - - if (!device_name[0]) - break; - - if (midi_out_device_available(c)) { - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_MIDI_OUT, win_get_string(IDS_2104)); - else - settings_add_string(hdlg, IDC_COMBO_MIDI_OUT, (LPARAM) device_name); - settings_list_to_midi[d] = c; - if ((c == 0) || (c == temp_midi_output_device)) - settings_set_cur_sel(hdlg, IDC_COMBO_MIDI_OUT, d); - d++; - } - - c++; - } - - settings_enable_window(hdlg, IDC_CONFIGURE_MIDI_OUT, midi_out_device_has_config(temp_midi_output_device)); - - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_MIDI_IN); - while (1) { - generate_device_name(midi_in_device_getdevice(c), midi_in_device_get_internal_name(c), 0); - - if (!device_name[0]) - break; - - if (midi_in_device_available(c)) { - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_MIDI_IN, win_get_string(IDS_2104)); - else - settings_add_string(hdlg, IDC_COMBO_MIDI_IN, (LPARAM) device_name); - settings_list_to_midi_in[d] = c; - if ((c == 0) || (c == temp_midi_input_device)) - settings_set_cur_sel(hdlg, IDC_COMBO_MIDI_IN, d); - d++; - } - - c++; - } - - settings_enable_window(hdlg, IDC_CONFIGURE_MIDI_IN, midi_in_device_has_config(temp_midi_input_device)); - settings_set_check(hdlg, IDC_CHECK_MPU401, temp_mpu401); - settings_enable_window(hdlg, IDC_CHECK_MPU401, mpu401_standalone_allow()); - settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_standalone_allow() && temp_mpu401); - settings_set_check(hdlg, IDC_CHECK_FLOAT, temp_float); - - if (temp_fm_driver == FM_DRV_YMFM) - settings_set_check(hdlg, IDC_RADIO_FM_DRV_YMFM, BST_CHECKED); - else - settings_set_check(hdlg, IDC_RADIO_FM_DRV_NUKED, BST_CHECKED); - - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_COMBO_SOUND1: - temp_sound_card[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND1)]; - settings_enable_window(hdlg, IDC_CONFIGURE_SND1, sound_card_has_config(temp_sound_card[0])); - settings_set_check(hdlg, IDC_CHECK_MPU401, temp_mpu401); - settings_enable_window(hdlg, IDC_CHECK_MPU401, mpu401_standalone_allow()); - settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_standalone_allow() && temp_mpu401); - break; - - case IDC_CONFIGURE_SND1: - temp_sound_card[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND1)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) sound_card_getdevice(temp_sound_card[0])); - break; - - case IDC_COMBO_SOUND2: - temp_sound_card[1] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND2)]; - settings_enable_window(hdlg, IDC_CONFIGURE_SND2, sound_card_has_config(temp_sound_card[1])); - settings_set_check(hdlg, IDC_CHECK_MPU401, temp_mpu401); - settings_enable_window(hdlg, IDC_CHECK_MPU401, mpu401_standalone_allow()); - settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_standalone_allow() && temp_mpu401); - break; - - case IDC_CONFIGURE_SND2: - temp_sound_card[1] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND2)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) sound_card_getdevice(temp_sound_card[1])); - break; - - case IDC_COMBO_SOUND3: - temp_sound_card[2] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND3)]; - settings_enable_window(hdlg, IDC_CONFIGURE_SND3, sound_card_has_config(temp_sound_card[2])); - settings_set_check(hdlg, IDC_CHECK_MPU401, temp_mpu401); - settings_enable_window(hdlg, IDC_CHECK_MPU401, mpu401_standalone_allow()); - settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_standalone_allow() && temp_mpu401); - break; - - case IDC_CONFIGURE_SND3: - temp_sound_card[2] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND3)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) sound_card_getdevice(temp_sound_card[2])); - break; - - case IDC_COMBO_SOUND4: - temp_sound_card[3] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND4)]; - settings_enable_window(hdlg, IDC_CONFIGURE_SND4, sound_card_has_config(temp_sound_card[3])); - settings_set_check(hdlg, IDC_CHECK_MPU401, temp_mpu401); - settings_enable_window(hdlg, IDC_CHECK_MPU401, mpu401_standalone_allow()); - settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_standalone_allow() && temp_mpu401); - break; - - case IDC_CONFIGURE_SND4: - temp_sound_card[3] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND4)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) sound_card_getdevice(temp_sound_card[3])); - break; - - case IDC_COMBO_MIDI_OUT: - temp_midi_output_device = settings_list_to_midi[settings_get_cur_sel(hdlg, IDC_COMBO_MIDI_OUT)]; - settings_enable_window(hdlg, IDC_CONFIGURE_MIDI_OUT, midi_out_device_has_config(temp_midi_output_device)); - settings_set_check(hdlg, IDC_CHECK_MPU401, temp_mpu401); - settings_enable_window(hdlg, IDC_CHECK_MPU401, mpu401_standalone_allow()); - settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_standalone_allow() && temp_mpu401); - break; - - case IDC_CONFIGURE_MIDI_OUT: - temp_midi_output_device = settings_list_to_midi[settings_get_cur_sel(hdlg, IDC_COMBO_MIDI_OUT)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) midi_out_device_getdevice(temp_midi_output_device)); - break; - - case IDC_COMBO_MIDI_IN: - temp_midi_input_device = settings_list_to_midi_in[settings_get_cur_sel(hdlg, IDC_COMBO_MIDI_IN)]; - settings_enable_window(hdlg, IDC_CONFIGURE_MIDI_IN, midi_in_device_has_config(temp_midi_input_device)); - settings_set_check(hdlg, IDC_CHECK_MPU401, temp_mpu401); - settings_enable_window(hdlg, IDC_CHECK_MPU401, mpu401_standalone_allow()); - settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_standalone_allow() && temp_mpu401); - break; - - case IDC_CONFIGURE_MIDI_IN: - temp_midi_input_device = settings_list_to_midi_in[settings_get_cur_sel(hdlg, IDC_COMBO_MIDI_IN)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) midi_in_device_getdevice(temp_midi_input_device)); - break; - - case IDC_CHECK_MPU401: - temp_mpu401 = settings_get_check(hdlg, IDC_CHECK_MPU401); - - settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_present()); - break; - - case IDC_CONFIGURE_MPU401: - temp_deviceconfig |= deviceconfig_open(hdlg, machine_has_bus(temp_machine, MACHINE_BUS_MCA) ? (void *) &mpu401_mca_device : (void *) &mpu401_device); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - temp_sound_card[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND1)]; - temp_sound_card[1] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND2)]; - temp_sound_card[2] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND3)]; - temp_sound_card[3] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND4)]; - temp_midi_output_device = settings_list_to_midi[settings_get_cur_sel(hdlg, IDC_COMBO_MIDI_OUT)]; - temp_midi_input_device = settings_list_to_midi_in[settings_get_cur_sel(hdlg, IDC_COMBO_MIDI_IN)]; - temp_mpu401 = settings_get_check(hdlg, IDC_CHECK_MPU401); - temp_float = settings_get_check(hdlg, IDC_CHECK_FLOAT); - if (settings_get_check(hdlg, IDC_RADIO_FM_DRV_NUKED)) - temp_fm_driver = FM_DRV_NUKED; - if (settings_get_check(hdlg, IDC_RADIO_FM_DRV_YMFM)) - temp_fm_driver = FM_DRV_YMFM; - default: - return FALSE; - } - return FALSE; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_ports_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - int c; - int i; - const char *s; - LPTSTR lptsTemp; - - switch (message) { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - - for (i = 0; i < PARALLEL_MAX; i++) { - c = 0; - while (1) { - s = (char *) lpt_device_get_name(c); - - if (!s) - break; - - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_LPT1 + i, win_get_string(IDS_2104)); - else { - mbstowcs(lptsTemp, s, strlen(s) + 1); - settings_add_string(hdlg, IDC_COMBO_LPT1 + i, (LPARAM) lptsTemp); - } - - c++; - } - settings_set_cur_sel(hdlg, IDC_COMBO_LPT1 + i, temp_lpt_devices[i]); - - settings_set_check(hdlg, IDC_CHECK_PARALLEL1 + i, temp_lpt[i]); - settings_enable_window(hdlg, IDC_COMBO_LPT1 + i, temp_lpt[i]); - } - - for (i = 0; i < SERIAL_MAX; i++) { - settings_set_check(hdlg, IDC_CHECK_SERIAL1 + i, temp_serial[i]); - settings_set_check(hdlg, IDC_CHECK_SERIAL_PASS1 + i, temp_serial_passthrough_enabled[i]); - } - - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_CHECK_PARALLEL1: - case IDC_CHECK_PARALLEL2: - case IDC_CHECK_PARALLEL3: - case IDC_CHECK_PARALLEL4: - i = LOWORD(wParam) - IDC_CHECK_PARALLEL1; - settings_enable_window(hdlg, IDC_COMBO_LPT1 + i, - settings_get_check(hdlg, IDC_CHECK_PARALLEL1 + i) == BST_CHECKED); - break; - } - break; - - case WM_SAVESETTINGS: - for (i = 0; i < PARALLEL_MAX; i++) { - temp_lpt_devices[i] = settings_get_cur_sel(hdlg, IDC_COMBO_LPT1 + i); - temp_lpt[i] = settings_get_check(hdlg, IDC_CHECK_PARALLEL1 + i); - } - - for (i = 0; i < SERIAL_MAX; i++) { - temp_serial[i] = settings_get_check(hdlg, IDC_CHECK_SERIAL1 + i); - temp_serial_passthrough_enabled[i] = settings_get_check(hdlg, IDC_CHECK_SERIAL_PASS1 + i); - } - - default: - return FALSE; - } - return FALSE; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_storage_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - int c; - int d; - int e; - int is_at; - LPTSTR lptsTemp; - char *stransi; - const device_t *scsi_dev; - const device_t *fdc_dev; - const device_t *hdc_dev; - - switch (message) { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - stransi = (char *) malloc(512); - - /*HD controller config*/ - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_HDC); - while (1) { - /* Skip "internal" if machine doesn't have it. */ - if ((c == 1) && !machine_has_flags(temp_machine, MACHINE_HDC)) { - c++; - continue; - } - - generate_device_name(hdc_get_device(c), hdc_get_internal_name(c), 1); - - if (!device_name[0]) - break; - - if (hdc_available(c)) { - hdc_dev = hdc_get_device(c); - - if (device_is_valid(hdc_dev, temp_machine)) { - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_HDC, win_get_string(IDS_2104)); - else if (c == 1) - settings_add_string(hdlg, IDC_COMBO_HDC, win_get_string(IDS_2119)); - else - settings_add_string(hdlg, IDC_COMBO_HDC, (LPARAM) device_name); - settings_list_to_hdc[d] = c; - if ((c == 0) || (c == temp_hdc)) - settings_set_cur_sel(hdlg, IDC_COMBO_HDC, d); - d++; - } - } - - c++; - } - - settings_enable_window(hdlg, IDC_COMBO_HDC, d); - settings_enable_window(hdlg, IDC_CONFIGURE_HDC, hdc_has_config(temp_hdc)); - - /*FD controller config*/ - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_FDC); - while (1) { - generate_device_name(fdc_card_getdevice(c), fdc_card_get_internal_name(c), 1); - - if (!device_name[0]) - break; - - if (fdc_card_available(c)) { - fdc_dev = fdc_card_getdevice(c); - - if (device_is_valid(fdc_dev, temp_machine)) { - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_FDC, win_get_string(IDS_2119)); - else - settings_add_string(hdlg, IDC_COMBO_FDC, (LPARAM) device_name); - settings_list_to_fdc[d] = c; - if ((c == 0) || (c == temp_fdc_card)) - settings_set_cur_sel(hdlg, IDC_COMBO_FDC, d); - d++; - } - } - - c++; - } - - settings_enable_window(hdlg, IDC_COMBO_FDC, d); - settings_enable_window(hdlg, IDC_CONFIGURE_FDC, fdc_card_has_config(temp_fdc_card)); - - /*SCSI config*/ - c = d = 0; - for (e = 0; e < SCSI_BUS_MAX; e++) - settings_reset_content(hdlg, IDC_COMBO_SCSI_1 + e); - while (1) { - generate_device_name(scsi_card_getdevice(c), scsi_card_get_internal_name(c), 1); - - if (!device_name[0]) - break; - - if (scsi_card_available(c)) { - scsi_dev = scsi_card_getdevice(c); - - if (device_is_valid(scsi_dev, temp_machine)) { - for (e = 0; e < SCSI_BUS_MAX; e++) { - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_SCSI_1 + e, win_get_string(IDS_2104)); - else - settings_add_string(hdlg, IDC_COMBO_SCSI_1 + e, (LPARAM) device_name); - - if ((c == 0) || (c == temp_scsi_card[e])) - settings_set_cur_sel(hdlg, IDC_COMBO_SCSI_1 + e, d); - } - - settings_list_to_device[0][d] = c; - d++; - } - } - - c++; - } - - for (c = 0; c < SCSI_BUS_MAX; c++) { - settings_enable_window(hdlg, IDC_COMBO_SCSI_1 + c, d); - settings_enable_window(hdlg, IDC_CONFIGURE_SCSI_1 + c, scsi_card_has_config(temp_scsi_card[c])); - } - is_at = IS_AT(temp_machine); - settings_enable_window(hdlg, IDC_CHECK_IDE_TER, is_at); - settings_enable_window(hdlg, IDC_BUTTON_IDE_TER, is_at && temp_ide_ter); - settings_enable_window(hdlg, IDC_CHECK_IDE_QUA, is_at); - settings_enable_window(hdlg, IDC_BUTTON_IDE_QUA, is_at && temp_ide_qua); - settings_enable_window(hdlg, IDC_CHECK_CASSETTE, machine_has_bus(temp_machine, MACHINE_BUS_CASSETTE)); - settings_set_check(hdlg, IDC_CHECK_IDE_TER, temp_ide_ter); - settings_set_check(hdlg, IDC_CHECK_IDE_QUA, temp_ide_qua); - settings_set_check(hdlg, IDC_CHECK_CASSETTE, (temp_cassette && machine_has_bus(temp_machine, MACHINE_BUS_CASSETTE))); - - free(stransi); - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_CONFIGURE_FDC: - temp_fdc_card = settings_list_to_fdc[settings_get_cur_sel(hdlg, IDC_COMBO_FDC)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) fdc_card_getdevice(temp_fdc_card)); - break; - - case IDC_COMBO_FDC: - temp_fdc_card = settings_list_to_fdc[settings_get_cur_sel(hdlg, IDC_COMBO_FDC)]; - settings_enable_window(hdlg, IDC_CONFIGURE_FDC, fdc_card_has_config(temp_fdc_card)); - break; - - case IDC_CONFIGURE_HDC: - temp_hdc = settings_list_to_hdc[settings_get_cur_sel(hdlg, IDC_COMBO_HDC)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) hdc_get_device(temp_hdc)); - break; - - case IDC_COMBO_HDC: - temp_hdc = settings_list_to_hdc[settings_get_cur_sel(hdlg, IDC_COMBO_HDC)]; - settings_enable_window(hdlg, IDC_CONFIGURE_HDC, hdc_has_config(temp_hdc)); - break; - - case IDC_CONFIGURE_SCSI_1 ... IDC_CONFIGURE_SCSI_4: - c = LOWORD(wParam) - IDC_CONFIGURE_SCSI_1; - temp_scsi_card[c] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SCSI_1 + c)]; - temp_deviceconfig |= deviceconfig_inst_open(hdlg, (void *) scsi_card_getdevice(temp_scsi_card[c]), c + 1); - break; - - case IDC_COMBO_SCSI_1 ... IDC_COMBO_SCSI_4: - c = LOWORD(wParam) - IDC_COMBO_SCSI_1; - temp_scsi_card[c] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SCSI_1 + c)]; - settings_enable_window(hdlg, IDC_CONFIGURE_SCSI_1 + c, scsi_card_has_config(temp_scsi_card[c])); - break; - - case IDC_CHECK_IDE_TER: - temp_ide_ter = settings_get_check(hdlg, IDC_CHECK_IDE_TER); - settings_enable_window(hdlg, IDC_BUTTON_IDE_TER, temp_ide_ter); - break; - - case IDC_BUTTON_IDE_TER: - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) &ide_ter_device); - break; - - case IDC_CHECK_IDE_QUA: - temp_ide_qua = settings_get_check(hdlg, IDC_CHECK_IDE_QUA); - settings_enable_window(hdlg, IDC_BUTTON_IDE_QUA, temp_ide_qua); - break; - - case IDC_BUTTON_IDE_QUA: - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) &ide_qua_device); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - temp_hdc = settings_list_to_hdc[settings_get_cur_sel(hdlg, IDC_COMBO_HDC)]; - temp_fdc_card = settings_list_to_fdc[settings_get_cur_sel(hdlg, IDC_COMBO_FDC)]; - for (c = 0; c < SCSI_BUS_MAX; c++) - temp_scsi_card[c] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SCSI_1 + c)]; - temp_ide_ter = settings_get_check(hdlg, IDC_CHECK_IDE_TER); - temp_ide_qua = settings_get_check(hdlg, IDC_CHECK_IDE_QUA); - temp_cassette = settings_get_check(hdlg, IDC_CHECK_CASSETTE); - - default: - return FALSE; - } - return FALSE; -} - -static void -network_recalc_combos(HWND hdlg) -{ - ignore_change = 1; - - for (uint8_t i = 0; i < NET_CARD_MAX; i++) { - settings_enable_window(hdlg, IDC_COMBO_PCAP1 + i, temp_net_type[i] == NET_TYPE_PCAP); - settings_enable_window(hdlg, IDC_COMBO_NET1 + i, - (temp_net_type[i] == NET_TYPE_SLIRP) || ((temp_net_type[i] == NET_TYPE_PCAP) && (network_dev_to_id(temp_pcap_dev[i]) > 0))); - settings_enable_window(hdlg, IDC_CONFIGURE_NET1 + i, network_card_has_config(temp_net_card[i]) && ((temp_net_type[i] == NET_TYPE_SLIRP) || ((temp_net_type[i] == NET_TYPE_PCAP) && (network_dev_to_id(temp_pcap_dev[i]) > 0)))); - } - - ignore_change = 0; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_network_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - int c; - int d; - LPTSTR lptsTemp; - - switch (message) { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - - for (uint8_t i = 0; i < NET_CARD_MAX; i++) { - settings_add_string(hdlg, IDC_COMBO_NET1_TYPE + i, (LPARAM) L"Null Driver"); - settings_add_string(hdlg, IDC_COMBO_NET1_TYPE + i, (LPARAM) L"SLiRP"); - settings_add_string(hdlg, IDC_COMBO_NET1_TYPE + i, (LPARAM) L"PCap"); - settings_set_cur_sel(hdlg, IDC_COMBO_NET1_TYPE + i, temp_net_type[i]); - settings_enable_window(hdlg, IDC_COMBO_PCAP1 + i, temp_net_type[i] == NET_TYPE_PCAP); - - for (c = 0; c < network_ndev; c++) { - mbstowcs(lptsTemp, network_devs[c].description, strlen(network_devs[c].description) + 1); - settings_add_string(hdlg, IDC_COMBO_PCAP1 + i, (LPARAM) lptsTemp); - } - settings_set_cur_sel(hdlg, IDC_COMBO_PCAP1 + i, network_dev_to_id(temp_pcap_dev[i])); - - /* NIC config */ - c = d = 0; - settings_reset_content(hdlg, IDC_COMBO_NET1 + i); - while (1) { - generate_device_name(network_card_getdevice(c), network_card_get_internal_name(c), 1); - - if (device_name[0] == L'\0') - break; - - if (network_card_available(c) && device_is_valid(network_card_getdevice(c), temp_machine)) { - if (c == 0) - settings_add_string(hdlg, IDC_COMBO_NET1 + i, win_get_string(IDS_2104)); - else - settings_add_string(hdlg, IDC_COMBO_NET1 + i, (LPARAM) device_name); - settings_list_to_device[0][d] = c; - if ((c == 0) || (c == temp_net_card[i])) - settings_set_cur_sel(hdlg, IDC_COMBO_NET1 + i, d); - d++; - } - - c++; - } - - settings_enable_window(hdlg, IDC_COMBO_NET1 + i, d); - network_recalc_combos(hdlg); - } - free(lptsTemp); - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_COMBO_NET1_TYPE: - if (ignore_change) - return FALSE; - - temp_net_type[0] = settings_get_cur_sel(hdlg, IDC_COMBO_NET1_TYPE); - network_recalc_combos(hdlg); - break; - case IDC_COMBO_NET2_TYPE: - if (ignore_change) - return FALSE; - - temp_net_type[1] = settings_get_cur_sel(hdlg, IDC_COMBO_NET2_TYPE); - network_recalc_combos(hdlg); - break; - case IDC_COMBO_NET3_TYPE: - if (ignore_change) - return FALSE; - - temp_net_type[2] = settings_get_cur_sel(hdlg, IDC_COMBO_NET3_TYPE); - network_recalc_combos(hdlg); - break; - case IDC_COMBO_NET4_TYPE: - if (ignore_change) - return FALSE; - - temp_net_type[3] = settings_get_cur_sel(hdlg, IDC_COMBO_NET4_TYPE); - network_recalc_combos(hdlg); - break; - - case IDC_COMBO_PCAP1: - if (ignore_change) - return FALSE; - - memset(temp_pcap_dev[0], '\0', sizeof(temp_pcap_dev[0])); - strcpy(temp_pcap_dev[0], network_devs[settings_get_cur_sel(hdlg, IDC_COMBO_PCAP1)].device); - network_recalc_combos(hdlg); - break; - case IDC_COMBO_PCAP2: - if (ignore_change) - return FALSE; - - memset(temp_pcap_dev[1], '\0', sizeof(temp_pcap_dev[1])); - strcpy(temp_pcap_dev[1], network_devs[settings_get_cur_sel(hdlg, IDC_COMBO_PCAP2)].device); - network_recalc_combos(hdlg); - break; - case IDC_COMBO_PCAP3: - if (ignore_change) - return FALSE; - - memset(temp_pcap_dev[2], '\0', sizeof(temp_pcap_dev[2])); - strcpy(temp_pcap_dev[2], network_devs[settings_get_cur_sel(hdlg, IDC_COMBO_PCAP3)].device); - network_recalc_combos(hdlg); - break; - case IDC_COMBO_PCAP4: - if (ignore_change) - return FALSE; - - memset(temp_pcap_dev[3], '\0', sizeof(temp_pcap_dev[3])); - strcpy(temp_pcap_dev[3], network_devs[settings_get_cur_sel(hdlg, IDC_COMBO_PCAP4)].device); - network_recalc_combos(hdlg); - break; - - case IDC_COMBO_NET1: - if (ignore_change) - return FALSE; - - temp_net_card[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET1)]; - network_recalc_combos(hdlg); - break; - case IDC_COMBO_NET2: - if (ignore_change) - return FALSE; - - temp_net_card[1] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET2)]; - network_recalc_combos(hdlg); - break; - case IDC_COMBO_NET3: - if (ignore_change) - return FALSE; - - temp_net_card[2] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET3)]; - network_recalc_combos(hdlg); - break; - case IDC_COMBO_NET4: - if (ignore_change) - return FALSE; - - temp_net_card[3] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET4)]; - network_recalc_combos(hdlg); - break; - - case IDC_CONFIGURE_NET1: - if (ignore_change) - return FALSE; - - temp_net_card[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET1)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) network_card_getdevice(temp_net_card[0])); - break; - case IDC_CONFIGURE_NET2: - if (ignore_change) - return FALSE; - - temp_net_card[1] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET2)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) network_card_getdevice(temp_net_card[1])); - break; - case IDC_CONFIGURE_NET3: - if (ignore_change) - return FALSE; - - temp_net_card[2] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET3)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) network_card_getdevice(temp_net_card[2])); - break; - case IDC_CONFIGURE_NET4: - if (ignore_change) - return FALSE; - - temp_net_card[3] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET4)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) network_card_getdevice(temp_net_card[3])); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - for (uint8_t i = 0; i < NET_CARD_MAX; i++) { - temp_net_type[i] = settings_get_cur_sel(hdlg, IDC_COMBO_NET1_TYPE + i); - memset(temp_pcap_dev[i], '\0', sizeof(temp_pcap_dev[i])); - strcpy(temp_pcap_dev[i], network_devs[settings_get_cur_sel(hdlg, IDC_COMBO_PCAP1 + i)].device); - temp_net_card[i] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET1 + i)]; - } - default: - return FALSE; - } - - return FALSE; -} - -static void -normalize_hd_list(void) -{ - hard_disk_t ihdd[HDD_NUM]; - int j = 0; - - memset(ihdd, 0x00, HDD_NUM * sizeof(hard_disk_t)); - - for (uint8_t i = 0; i < HDD_NUM; i++) { - if (temp_hdd[i].bus != HDD_BUS_DISABLED) { - memcpy(&(ihdd[j]), &(temp_hdd[i]), sizeof(hard_disk_t)); - j++; - } - } - - memcpy(temp_hdd, ihdd, HDD_NUM * sizeof(hard_disk_t)); -} - -static int -get_selected_hard_disk(HWND hdlg) -{ - int hard_disk = -1; - int j = 0; - HWND h; - - if (hd_listview_items == 0) - return 0; - - for (int i = 0; i < hd_listview_items; i++) { - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - j = ListView_GetItemState(h, i, LVIS_SELECTED); - if (j) - hard_disk = i; - } - - return hard_disk; -} - -static void -add_locations(HWND hdlg) -{ - LPTSTR lptsTemp; - int i = 0; - - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - - for (i = 0; i < 6; i++) - settings_add_string(hdlg, IDC_COMBO_HD_BUS, win_get_string(IDS_4352 + i)); - - for (i = 0; i < 2; i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1); - settings_add_string(hdlg, IDC_COMBO_HD_CHANNEL, (LPARAM) lptsTemp); - } - - for (i = 0; i < (SCSI_BUS_MAX * SCSI_ID_MAX); i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4135), i >> 4, i & 15); - settings_add_string(hdlg, IDC_COMBO_HD_ID, (LPARAM) lptsTemp); - } - - for (i = 0; i < (IDE_BUS_MAX * IDE_CHAN_MAX); i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1); - settings_add_string(hdlg, IDC_COMBO_HD_CHANNEL_IDE, (LPARAM) lptsTemp); - } - - free(lptsTemp); -} - -static uint8_t -next_free_binary_channel(uint64_t *tracking) -{ - for (int64_t i = 0; i < 2; i++) { - if (!(*tracking & (0xffLL << (i << 3LL)))) - return i; - } - - return 2; -} - -static uint8_t -next_free_ide_channel(void) -{ - for (int64_t i = 0; i < (IDE_BUS_MAX * IDE_CHAN_MAX); i++) { - if (!(ide_tracking & (0xffLL << (i << 3LL)))) - return i; - } - - return 7; -} - -static void -next_free_scsi_id(uint8_t *id) -{ - for (int64_t i = 0; i < (SCSI_BUS_MAX * SCSI_ID_MAX); i++) { - if (!(scsi_tracking[i >> 3] & (0xffLL << ((i & 0x07) << 3LL)))) { - *id = i; - return; - } - } - - *id = 6; -} - -static void -recalc_location_controls(HWND hdlg, int is_add_dlg, int assign_id) -{ - int bus = 0; - - for (uint16_t i = IDT_CHANNEL; i <= IDT_ID; i++) - settings_show_window(hdlg, i, FALSE); - settings_show_window(hdlg, IDC_COMBO_HD_CHANNEL, FALSE); - settings_show_window(hdlg, IDC_COMBO_HD_ID, FALSE); - settings_show_window(hdlg, IDC_COMBO_HD_CHANNEL_IDE, FALSE); - - if ((hd_listview_items > 0) || is_add_dlg) { - bus = settings_get_cur_sel(hdlg, IDC_COMBO_HD_BUS) + 1; - - switch (bus) { - case HDD_BUS_MFM: /* MFM */ - settings_show_window(hdlg, IDT_CHANNEL, TRUE); - settings_show_window(hdlg, IDC_COMBO_HD_CHANNEL, TRUE); - - if (assign_id) - temp_hdd[lv1_current_sel].mfm_channel = next_free_binary_channel(&mfm_tracking); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL, is_add_dlg ? new_hdd.mfm_channel : temp_hdd[lv1_current_sel].mfm_channel); - break; - case HDD_BUS_XTA: /* XTA */ - settings_show_window(hdlg, IDT_CHANNEL, TRUE); - settings_show_window(hdlg, IDC_COMBO_HD_CHANNEL, TRUE); - - if (assign_id) - temp_hdd[lv1_current_sel].xta_channel = next_free_binary_channel(&xta_tracking); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL, is_add_dlg ? new_hdd.xta_channel : temp_hdd[lv1_current_sel].xta_channel); - break; - case HDD_BUS_ESDI: /* ESDI */ - settings_show_window(hdlg, IDT_CHANNEL, TRUE); - settings_show_window(hdlg, IDC_COMBO_HD_CHANNEL, TRUE); - - if (assign_id) - temp_hdd[lv1_current_sel].esdi_channel = next_free_binary_channel(&esdi_tracking); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL, is_add_dlg ? new_hdd.esdi_channel : temp_hdd[lv1_current_sel].esdi_channel); - break; - case HDD_BUS_IDE: /* IDE */ - case HDD_BUS_ATAPI: /* ATAPI */ - settings_show_window(hdlg, IDT_CHANNEL, TRUE); - settings_show_window(hdlg, IDC_COMBO_HD_CHANNEL_IDE, TRUE); - - if (assign_id) - temp_hdd[lv1_current_sel].ide_channel = next_free_ide_channel(); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL_IDE, is_add_dlg ? new_hdd.ide_channel : temp_hdd[lv1_current_sel].ide_channel); - break; - case HDD_BUS_SCSI: /* SCSI */ - settings_show_window(hdlg, IDT_ID, TRUE); - settings_show_window(hdlg, IDT_LUN, TRUE); - settings_show_window(hdlg, IDC_COMBO_HD_ID, TRUE); - - if (assign_id) - next_free_scsi_id((is_add_dlg ? &(new_hdd.scsi_id) : &(temp_hdd[lv1_current_sel].scsi_id))); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_ID, is_add_dlg ? new_hdd.scsi_id : temp_hdd[lv1_current_sel].scsi_id); - } - } - - settings_show_window(hdlg, IDT_BUS, (hd_listview_items != 0) || is_add_dlg); - settings_show_window(hdlg, IDC_COMBO_HD_BUS, (hd_listview_items != 0) || is_add_dlg); -} - -static int -bus_full(uint64_t *tracking, int count) -{ - int full = 0; - - switch (count) { - default: - case 2: - full = (*tracking & 0xFF00LL); - full = full && (*tracking & 0x00FFLL); - break; - case 8: - full = (*tracking & 0xFF00000000000000LL); - full = full && (*tracking & 0x00FF000000000000LL); - full = full && (*tracking & 0x0000FF0000000000LL); - full = full && (*tracking & 0x000000FF00000000LL); - full = full && (*tracking & 0x00000000FF000000LL); - full = full && (*tracking & 0x0000000000FF0000LL); - full = full && (*tracking & 0x000000000000FF00LL); - full = full && (*tracking & 0x00000000000000FFLL); - break; - } - - return full; -} - -static void -recalc_next_free_id(HWND hdlg) -{ - int i; - int enable_add = 0; - int c_mfm = 0; - int c_esdi = 0; - int c_xta = 0; - int c_ide = 0; - int c_atapi = 0; - int c_scsi = 0; - - next_free_id = -1; - - for (i = 0; i < HDD_NUM; i++) { - if (temp_hdd[i].bus == HDD_BUS_MFM) - c_mfm++; - else if (temp_hdd[i].bus == HDD_BUS_ESDI) - c_esdi++; - else if (temp_hdd[i].bus == HDD_BUS_XTA) - c_xta++; - else if (temp_hdd[i].bus == HDD_BUS_IDE) - c_ide++; - else if (temp_hdd[i].bus == HDD_BUS_ATAPI) - c_atapi++; - else if (temp_hdd[i].bus == HDD_BUS_SCSI) - c_scsi++; - } - - for (i = 0; i < HDD_NUM; i++) { - if (temp_hdd[i].bus == HDD_BUS_DISABLED) { - next_free_id = i; - break; - } - } - - enable_add = enable_add || (next_free_id >= 0); - enable_add = enable_add && ((c_mfm < MFM_NUM) || (c_esdi < ESDI_NUM) || (c_xta < XTA_NUM) || (c_ide < IDE_NUM) || (c_ide < ATAPI_NUM) || (c_scsi < SCSI_NUM)); - enable_add = enable_add && (!bus_full(&mfm_tracking, 2) || !bus_full(&esdi_tracking, 2) || !bus_full(&xta_tracking, 2) || !bus_full(&ide_tracking, IDE_CHAN_MAX * IDE_BUS_MAX) || - !bus_full(&(scsi_tracking[0]), 8) || !bus_full(&(scsi_tracking[1]), 8) || !bus_full(&(scsi_tracking[2]), 8) || !bus_full(&(scsi_tracking[3]), 8) || - !bus_full(&(scsi_tracking[4]), 8) || !bus_full(&(scsi_tracking[5]), 8) || !bus_full(&(scsi_tracking[6]), 8) || !bus_full(&(scsi_tracking[7]), 8)); - - settings_enable_window(hdlg, IDC_BUTTON_HDD_ADD_NEW, enable_add); - settings_enable_window(hdlg, IDC_BUTTON_HDD_ADD, enable_add); - settings_enable_window(hdlg, IDC_BUTTON_HDD_REMOVE, - (c_mfm != 0) || (c_esdi != 0) || (c_xta != 0) || (c_ide != 0) || (c_atapi != 0) || (c_scsi != 0)); -} - -static void -win_settings_hard_disks_update_item(HWND hdlg, int i, int column) -{ - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - LVITEM lvI; - WCHAR szText[256]; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - lvI.iSubItem = column; - lvI.iItem = i; - - if (column == 0) { /* Bus */ - switch (temp_hdd[i].bus) { - case HDD_BUS_MFM: - wsprintf(szText, plat_get_string(IDS_4608), temp_hdd[i].mfm_channel >> 1, temp_hdd[i].mfm_channel & 1); - break; - case HDD_BUS_XTA: - wsprintf(szText, plat_get_string(IDS_4609), temp_hdd[i].xta_channel >> 1, temp_hdd[i].xta_channel & 1); - break; - case HDD_BUS_ESDI: - wsprintf(szText, plat_get_string(IDS_4610), temp_hdd[i].esdi_channel >> 1, temp_hdd[i].esdi_channel & 1); - break; - case HDD_BUS_IDE: - wsprintf(szText, plat_get_string(IDS_4611), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1); - break; - case HDD_BUS_ATAPI: - wsprintf(szText, plat_get_string(IDS_4612), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1); - break; - case HDD_BUS_SCSI: - wsprintf(szText, plat_get_string(IDS_4613), temp_hdd[i].scsi_id >> 4, temp_hdd[i].scsi_id & 15); - break; - } - lvI.pszText = szText; - lvI.iImage = 0; - } else if (column == 1) { /* File */ - if (!strnicmp(temp_hdd[i].fn, usr_path, strlen(usr_path))) - mbstoc16s(szText, temp_hdd[i].fn + strlen(usr_path), sizeof_w(szText)); - else - mbstoc16s(szText, temp_hdd[i].fn, sizeof_w(szText)); - lvI.pszText = szText; - lvI.iImage = 0; - } else if (column == 2) { /* Cylinders */ - wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].tracks); - lvI.pszText = szText; - lvI.iImage = 0; - } else if (column == 3) { /* Heads */ - wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].hpc); - lvI.pszText = szText; - lvI.iImage = 0; - } else if (column == 4) { /* Sectors */ - wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].spt); - lvI.pszText = szText; - lvI.iImage = 0; - } else if (column == 5) { /* Size (MB) */ - wsprintf(szText, plat_get_string(IDS_4098), (temp_hdd[i].tracks * temp_hdd[i].hpc * temp_hdd[i].spt) >> 11); - lvI.pszText = szText; - lvI.iImage = 0; - } else if (column == 6) { /* Speed (RPM) */ - mbstoc16s(szText, hdd_preset_getname(temp_hdd[i].speed_preset), sizeof_w(szText)); - lvI.pszText = szText; - lvI.iImage = 0; - } - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; -} - -static BOOL -win_settings_hard_disks_recalc_list(HWND hdlg) -{ - LVITEM lvI; - int j = 0; - WCHAR szText[256]; - WCHAR usr_path_w[1024]; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - - mbstoc16s(usr_path_w, usr_path, sizeof_w(usr_path_w)); - - hd_listview_items = 0; - lv1_current_sel = -1; - - ListView_DeleteAllItems(hwndList); - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (uint8_t i = 0; i < HDD_NUM; i++) { - if (temp_hdd[i].bus > 0) { - hdc_id_to_listview_index[i] = j; - lvI.iSubItem = 0; - - /* Bus */ - switch (temp_hdd[i].bus) { - case HDD_BUS_MFM: - wsprintf(szText, plat_get_string(IDS_4608), temp_hdd[i].mfm_channel >> 1, temp_hdd[i].mfm_channel & 1); - break; - case HDD_BUS_XTA: - wsprintf(szText, plat_get_string(IDS_4609), temp_hdd[i].xta_channel >> 1, temp_hdd[i].xta_channel & 1); - break; - case HDD_BUS_ESDI: - wsprintf(szText, plat_get_string(IDS_4610), temp_hdd[i].esdi_channel >> 1, temp_hdd[i].esdi_channel & 1); - break; - case HDD_BUS_IDE: - wsprintf(szText, plat_get_string(IDS_4611), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1); - break; - case HDD_BUS_ATAPI: - wsprintf(szText, plat_get_string(IDS_4612), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1); - break; - case HDD_BUS_SCSI: - wsprintf(szText, plat_get_string(IDS_4613), temp_hdd[i].scsi_id >> 4, temp_hdd[i].scsi_id & 15); - break; - } - lvI.pszText = szText; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - - /* File */ - lvI.iSubItem = 1; - if (!strnicmp(temp_hdd[i].fn, usr_path, strlen(usr_path))) - mbstoc16s(szText, temp_hdd[i].fn + strlen(usr_path), sizeof_w(szText)); - else - mbstoc16s(szText, temp_hdd[i].fn, sizeof_w(szText)); - lvI.pszText = szText; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - - /* Cylinders */ - lvI.iSubItem = 2; - wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].tracks); - lvI.pszText = szText; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - - /* Heads */ - lvI.iSubItem = 3; - wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].hpc); - lvI.pszText = szText; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - - /* Sectors */ - lvI.iSubItem = 4; - wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].spt); - lvI.pszText = szText; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - - /* Size (MB) */ - lvI.iSubItem = 5; - wsprintf(szText, plat_get_string(IDS_4098), (temp_hdd[i].tracks * temp_hdd[i].hpc * temp_hdd[i].spt) >> 11); - lvI.pszText = szText; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - - /* Speed (RPM) */ - lvI.iSubItem = 6; - mbstoc16s(szText, hdd_preset_getname(temp_hdd[i].speed_preset), sizeof_w(szText)); - lvI.pszText = szText; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - - j++; - } else - hdc_id_to_listview_index[i] = -1; - } - - hd_listview_items = j; - - return TRUE; -} - -#define C_COLUMNS_HARD_DISKS_BUS 104 -#define C_COLUMNS_HARD_DISKS_FILE 254 -#define C_COLUMNS_HARD_DISKS_CYLS 50 -#define C_COLUMNS_HARD_DISKS_HEADS 26 -#define C_COLUMNS_HARD_DISKS_SECT 32 -#define C_COLUMNS_HARD_DISKS_SIZE 50 -#define C_COLUMNS_HARD_DISKS_SPEED 100 - -static void -win_settings_hard_disks_resize_columns(HWND hdlg) -{ - /* Bus, File, Cylinders, Heads, Sectors, Size */ - int width[C_COLUMNS_HARD_DISKS] = { - C_COLUMNS_HARD_DISKS_BUS, - C_COLUMNS_HARD_DISKS_FILE, - C_COLUMNS_HARD_DISKS_CYLS, - C_COLUMNS_HARD_DISKS_HEADS, - C_COLUMNS_HARD_DISKS_SECT, - C_COLUMNS_HARD_DISKS_SIZE, - C_COLUMNS_HARD_DISKS_SPEED - }; - int total = 0; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - RECT r; - - GetWindowRect(hwndList, &r); - for (int iCol = 0; iCol < (C_COLUMNS_HARD_DISKS - 1); iCol++) { - width[iCol] = MulDiv(width[iCol], dpi, 96); - total += width[iCol]; - ListView_SetColumnWidth(hwndList, iCol, MulDiv(width[iCol], dpi, 96)); - } - width[C_COLUMNS_HARD_DISKS - 1] = (r.right - r.left) - 4 - total; - ListView_SetColumnWidth(hwndList, C_COLUMNS_HARD_DISKS - 1, width[C_COLUMNS_HARD_DISKS - 1]); -} - -static BOOL -win_settings_hard_disks_init_columns(HWND hdlg) -{ - LVCOLUMN lvc; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - for (int iCol = 0; iCol < C_COLUMNS_HARD_DISKS; iCol++) { - lvc.iSubItem = iCol; - lvc.pszText = plat_get_string(IDS_BUS + iCol); - - switch (iCol) { - case 0: /* Bus */ - lvc.cx = C_COLUMNS_HARD_DISKS_BUS; - lvc.fmt = LVCFMT_LEFT; - break; - case 1: /* File */ - lvc.cx = C_COLUMNS_HARD_DISKS_FILE; - lvc.fmt = LVCFMT_LEFT; - break; - case 2: /* Cylinders */ - lvc.cx = C_COLUMNS_HARD_DISKS_CYLS; - lvc.fmt = LVCFMT_RIGHT; - break; - case 3: /* Heads */ - lvc.cx = C_COLUMNS_HARD_DISKS_HEADS; - lvc.fmt = LVCFMT_RIGHT; - break; - case 4: /* Sectors */ - lvc.cx = C_COLUMNS_HARD_DISKS_SECT; - lvc.fmt = LVCFMT_RIGHT; - break; - case 5: /* Size (MB) */ - lvc.cx = C_COLUMNS_HARD_DISKS_SIZE; - lvc.fmt = LVCFMT_RIGHT; - break; - case 6: /* Speed (RPM) */ - lvc.cx = C_COLUMNS_HARD_DISKS_SPEED; - lvc.fmt = LVCFMT_RIGHT; - break; - } - - if (ListView_InsertColumn(hwndList, iCol, &lvc) == -1) - return FALSE; - } - - win_settings_hard_disks_resize_columns(hdlg); - return TRUE; -} - -static void -get_edit_box_contents(HWND hdlg, int id, uint32_t *val) -{ - HWND h; - WCHAR szText[256]; - char stransi[256]; - - h = GetDlgItem(hdlg, id); - SendMessage(h, WM_GETTEXT, 255, (LPARAM) szText); - wcstombs(stransi, szText, 256); - sscanf(stransi, "%u", val); -} - -static void -set_edit_box_contents(HWND hdlg, int id, uint32_t val) -{ - HWND h; - WCHAR szText[256]; - - h = GetDlgItem(hdlg, id); - wsprintf(szText, plat_get_string(IDS_2107), val); - SendMessage(h, WM_SETTEXT, wcslen(szText), (LPARAM) szText); -} - -static void -set_edit_box_text_contents(HWND hdlg, int id, WCHAR *text) -{ - HWND h = GetDlgItem(hdlg, id); - SendMessage(h, WM_SETTEXT, wcslen(text), (LPARAM) text); -} - -static void -get_edit_box_text_contents(HWND hdlg, int id, WCHAR *text_buffer, int buffer_size) -{ - HWND h = GetDlgItem(hdlg, id); - SendMessage(h, WM_GETTEXT, (WPARAM) buffer_size, (LPARAM) text_buffer); -} - -static int -hdconf_initialize_hdt_combo(HWND hdlg) -{ - uint64_t temp_size = 0; - uint32_t size_mb = 0; - WCHAR szText[256]; - - selection = 127; - - for (uint8_t i = 0; i < 127; i++) { - temp_size = ((uint64_t) hdd_table[i][0]) * hdd_table[i][1] * hdd_table[i][2]; - size_mb = (uint32_t) (temp_size >> 11LL); - wsprintf(szText, plat_get_string(IDS_2108), size_mb, hdd_table[i][0], hdd_table[i][1], hdd_table[i][2]); - settings_add_string(hdlg, IDC_COMBO_HD_TYPE, (LPARAM) szText); - if ((tracks == (int) hdd_table[i][0]) && (hpc == (int) hdd_table[i][1]) && (spt == (int) hdd_table[i][2])) - selection = i; - } - settings_add_string(hdlg, IDC_COMBO_HD_TYPE, win_get_string(IDS_4100)); - settings_add_string(hdlg, IDC_COMBO_HD_TYPE, win_get_string(IDS_4101)); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_TYPE, selection); - return selection; -} - -static void -recalc_selection(HWND hdlg) -{ - selection = 127; - for (uint8_t i = 0; i < 127; i++) { - if ((tracks == (int) hdd_table[i][0]) && (hpc == (int) hdd_table[i][1]) && (spt == (int) hdd_table[i][2])) - selection = i; - } - if ((selection == 127) && (hpc == 16) && (spt == 63)) - selection = 128; - settings_set_cur_sel(hdlg, IDC_COMBO_HD_TYPE, selection); -} - -HWND vhd_progress_hdlg; - -static void -vhd_progress_callback(uint32_t current_sector, UNUSED(uint32_t total_sectors)) -{ - MSG msg; - HWND h = GetDlgItem(vhd_progress_hdlg, IDC_PBAR_IMG_CREATE); - SendMessage(h, PBM_SETPOS, current_sector, (LPARAM) 0); - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } -} - -/* If the disk geometry requested in the 86Box GUI is not compatible with the internal VHD geometry, - * we adjust it to the next-largest size that is compatible. On average, this will be a difference - * of about 21 MB, and should only be necessary for VHDs larger than 31.5 GB, so should never be more - * than a tenth of a percent change in size. - */ -static void -adjust_86box_geometry_for_vhd(MVHDGeom *_86box_geometry, MVHDGeom *vhd_geometry) -{ - if (_86box_geometry->cyl <= 65535) { - vhd_geometry->cyl = _86box_geometry->cyl; - vhd_geometry->heads = _86box_geometry->heads; - vhd_geometry->spt = _86box_geometry->spt; - return; - } - - int desired_sectors = _86box_geometry->cyl * _86box_geometry->heads * _86box_geometry->spt; - if (desired_sectors > 267321600) - desired_sectors = 267321600; - - int remainder = desired_sectors % 85680; /* 8560 is the LCM of 1008 (63*16) and 4080 (255*16) */ - if (remainder > 0) - desired_sectors += (85680 - remainder); - - _86box_geometry->cyl = desired_sectors / (16 * 63); - _86box_geometry->heads = 16; - _86box_geometry->spt = 63; - - vhd_geometry->cyl = desired_sectors / (16 * 255); - vhd_geometry->heads = 16; - vhd_geometry->spt = 255; -} - -static void -adjust_vhd_geometry_for_86box(MVHDGeom *vhd_geometry) -{ - if (vhd_geometry->spt <= 63) - return; - - int desired_sectors = vhd_geometry->cyl * vhd_geometry->heads * vhd_geometry->spt; - if (desired_sectors > 267321600) - desired_sectors = 267321600; - - int remainder = desired_sectors % 85680; /* 8560 is the LCM of 1008 (63*16) and 4080 (255*16) */ - if (remainder > 0) - desired_sectors -= remainder; - - vhd_geometry->cyl = desired_sectors / (16 * 63); - vhd_geometry->heads = 16; - vhd_geometry->spt = 63; -} - -static MVHDGeom -create_drive_vhd_fixed(char *filename, int cyl, int heads, int spt) -{ - MVHDGeom _86box_geometry = { .cyl = cyl, .heads = heads, .spt = spt }; - MVHDGeom vhd_geometry; - adjust_86box_geometry_for_vhd(&_86box_geometry, &vhd_geometry); - - HWND h = GetDlgItem(vhd_progress_hdlg, IDC_PBAR_IMG_CREATE); - settings_show_window(vhd_progress_hdlg, IDT_FILE_NAME, FALSE); - settings_show_window(vhd_progress_hdlg, IDC_EDIT_HD_FILE_NAME, FALSE); - settings_show_window(vhd_progress_hdlg, IDC_CFILE, FALSE); - settings_show_window(vhd_progress_hdlg, IDC_PBAR_IMG_CREATE, TRUE); - settings_enable_window(vhd_progress_hdlg, IDT_PROGRESS, TRUE); - SendMessage(h, PBM_SETRANGE32, (WPARAM) 0, (LPARAM) vhd_geometry.cyl * vhd_geometry.heads * vhd_geometry.spt); - SendMessage(h, PBM_SETPOS, (WPARAM) 0, (LPARAM) 0); - - int vhd_error = 0; - MVHDMeta *vhd = mvhd_create_fixed(filename, vhd_geometry, &vhd_error, vhd_progress_callback); - if (vhd == NULL) { - _86box_geometry.cyl = 0; - _86box_geometry.heads = 0; - _86box_geometry.spt = 0; - } else { - mvhd_close(vhd); - } - - return _86box_geometry; -} - -static MVHDGeom -create_drive_vhd_dynamic(char *filename, int cyl, int heads, int spt, int blocksize) -{ - MVHDGeom _86box_geometry = { .cyl = cyl, .heads = heads, .spt = spt }; - MVHDGeom vhd_geometry; - adjust_86box_geometry_for_vhd(&_86box_geometry, &vhd_geometry); - int vhd_error = 0; - MVHDCreationOptions options; - options.block_size_in_sectors = blocksize; - options.path = filename; - options.size_in_bytes = 0; - options.geometry = vhd_geometry; - options.type = MVHD_TYPE_DYNAMIC; - - MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error); - if (vhd == NULL) { - _86box_geometry.cyl = 0; - _86box_geometry.heads = 0; - _86box_geometry.spt = 0; - } else { - mvhd_close(vhd); - } - - return _86box_geometry; -} - -static MVHDGeom -create_drive_vhd_diff(char *filename, char *parent_filename, int blocksize) -{ - int vhd_error = 0; - MVHDCreationOptions options; - options.block_size_in_sectors = blocksize; - options.path = filename; - options.parent_path = parent_filename; - options.type = MVHD_TYPE_DIFF; - - MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error); - MVHDGeom vhd_geometry; - if (vhd == NULL) { - vhd_geometry.cyl = 0; - vhd_geometry.heads = 0; - vhd_geometry.spt = 0; - } else { - vhd_geometry = mvhd_get_geometry(vhd); - - if (vhd_geometry.spt > 63) { - vhd_geometry.cyl = mvhd_calc_size_sectors(&vhd_geometry) / (16 * 63); - vhd_geometry.heads = 16; - vhd_geometry.spt = 63; - } - - mvhd_close(vhd); - } - - return vhd_geometry; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - HWND h; - FILE *fp; - uint32_t temp; - uint32_t i = 0; - uint32_t sector_size = 512; - uint32_t zero = 0; - uint32_t base = 0x1000; - uint64_t signature = 0xD778A82044445459LL; - uint64_t r = 0; - char *big_buf; - char hd_file_name_multibyte[1200]; - int b = 0; - int vhd_error = 0; - uint8_t channel = 0; - uint8_t id = 0; - wchar_t *twcs; - int img_format; - int block_size; - WCHAR text_buf[256]; - RECT rect; - POINT point; - int dlg_height_adjust; - - switch (message) { - case WM_INITDIALOG: - memset(hd_file_name, 0, sizeof(hd_file_name)); - - hdd_ptr = &(temp_hdd[next_free_id]); - - SetWindowText(hdlg, plat_get_string((existing & 1) ? IDS_4103 : IDS_4102)); - - no_update = 1; - spt = (existing & 1) ? 0 : 17; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - hpc = (existing & 1) ? 0 : 15; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - tracks = (existing & 1) ? 0 : 1023; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - size = (tracks * hpc * spt) << 9; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20LL)); - hdconf_initialize_hdt_combo(hdlg); - - settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4122)); - settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4123)); - settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4124)); - settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4125)); - settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4126)); - settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4127)); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_IMG_FORMAT, 0); - - settings_add_string(hdlg, IDC_COMBO_HD_BLOCK_SIZE, win_get_string(IDS_4128)); - settings_add_string(hdlg, IDC_COMBO_HD_BLOCK_SIZE, win_get_string(IDS_4129)); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_BLOCK_SIZE, 0); - - settings_show_window(hdlg, IDC_COMBO_HD_BLOCK_SIZE, FALSE); - settings_show_window(hdlg, IDT_BLOCK_SIZE, FALSE); - - if (existing & 1) { - settings_enable_window(hdlg, IDC_EDIT_HD_SPT, FALSE); - settings_enable_window(hdlg, IDC_EDIT_HD_HPC, FALSE); - settings_enable_window(hdlg, IDC_EDIT_HD_CYL, FALSE); - settings_enable_window(hdlg, IDC_EDIT_HD_SIZE, FALSE); - settings_enable_window(hdlg, IDC_COMBO_HD_TYPE, FALSE); - settings_show_window(hdlg, IDC_COMBO_HD_IMG_FORMAT, FALSE); - settings_show_window(hdlg, IDT_IMG_FORMAT, FALSE); - - /* adjust window size */ - GetWindowRect(hdlg, &rect); - OffsetRect(&rect, -rect.left, -rect.top); - dlg_height_adjust = rect.bottom / 5; - SetWindowPos(hdlg, NULL, 0, 0, rect.right, rect.bottom - dlg_height_adjust, SWP_NOMOVE | SWP_NOREPOSITION | SWP_NOZORDER); - h = GetDlgItem(hdlg, IDOK); - GetWindowRect(h, &rect); - point.x = rect.left; - point.y = rect.top; - ScreenToClient(hdlg, &point); - SetWindowPos(h, NULL, point.x, point.y - dlg_height_adjust, 0, 0, SWP_NOSIZE | SWP_NOREPOSITION | SWP_NOZORDER); - h = GetDlgItem(hdlg, IDCANCEL); - GetWindowRect(h, &rect); - point.x = rect.left; - point.y = rect.top; - ScreenToClient(hdlg, &point); - SetWindowPos(h, NULL, point.x, point.y - dlg_height_adjust, 0, 0, SWP_NOSIZE | SWP_NOREPOSITION | SWP_NOZORDER); - - chs_enabled = 0; - } else - chs_enabled = 1; - - add_locations(hdlg); - hdd_ptr->bus = HDD_BUS_IDE; - max_spt = 255; - max_hpc = 255; - settings_set_cur_sel(hdlg, IDC_COMBO_HD_BUS, hdd_ptr->bus - 1); - max_tracks = 266305; - recalc_location_controls(hdlg, 1, 0); - - channel = next_free_ide_channel(); - next_free_scsi_id(&id); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL, 0); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_ID, id); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL_IDE, channel); - - new_hdd.mfm_channel = next_free_binary_channel(&mfm_tracking); - new_hdd.esdi_channel = next_free_binary_channel(&esdi_tracking); - new_hdd.xta_channel = next_free_binary_channel(&xta_tracking); - new_hdd.ide_channel = channel; - new_hdd.scsi_id = id; - - settings_enable_window(hdlg, IDC_EDIT_HD_FILE_NAME, FALSE); - settings_show_window(hdlg, IDT_PROGRESS, FALSE); - settings_show_window(hdlg, IDC_PBAR_IMG_CREATE, FALSE); - - no_update = 0; - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - hdd_ptr->bus = settings_get_cur_sel(hdlg, IDC_COMBO_HD_BUS) + 1; - - /* Make sure no file name is allowed with removable SCSI hard disks. */ - if (wcslen(hd_file_name) == 0) { - hdd_ptr->bus = HDD_BUS_DISABLED; - settings_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2131, (wchar_t *) IDS_4112); - return TRUE; - } - - get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &(hdd_ptr->spt)); - get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &(hdd_ptr->hpc)); - get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &(hdd_ptr->tracks)); - spt = hdd_ptr->spt; - hpc = hdd_ptr->hpc; - tracks = hdd_ptr->tracks; - - switch (hdd_ptr->bus) { - case HDD_BUS_MFM: - hdd_ptr->mfm_channel = settings_get_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL); - break; - case HDD_BUS_ESDI: - hdd_ptr->esdi_channel = settings_get_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL); - break; - case HDD_BUS_XTA: - hdd_ptr->xta_channel = settings_get_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL); - break; - case HDD_BUS_IDE: - case HDD_BUS_ATAPI: - hdd_ptr->ide_channel = settings_get_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - break; - case HDD_BUS_SCSI: - hdd_ptr->scsi_id = settings_get_cur_sel(hdlg, IDC_COMBO_HD_ID); - break; - } - - memset(hdd_ptr->fn, 0, sizeof(hdd_ptr->fn)); - c16stombs(hdd_ptr->fn, hd_file_name, sizeof(hdd_ptr->fn)); - strcpy(hd_file_name_multibyte, hdd_ptr->fn); - - sector_size = 512; - - if (!(existing & 1) && (wcslen(hd_file_name) > 0)) { - if (size > 0x1FFFFFFE00LL) { - settings_msgbox_header(MBX_ERROR, (wchar_t *) IDS_4116, (wchar_t *) IDS_4105); - return TRUE; - } - - img_format = settings_get_cur_sel(hdlg, IDC_COMBO_HD_IMG_FORMAT); - if (img_format < IMG_FMT_VHD_FIXED) { - fp = _wfopen(hd_file_name, L"wb"); - } else { - fp = (FILE *) 0; - } - - if (img_format == IMG_FMT_HDI) { /* HDI file */ - if (size >= 0x100000000LL) { - fclose(fp); - settings_msgbox_header(MBX_ERROR, (wchar_t *) IDS_4116, (wchar_t *) IDS_4104); - return TRUE; - } - - fwrite(&zero, 1, 4, fp); /* 00000000: Zero/unknown */ - fwrite(&zero, 1, 4, fp); /* 00000004: Zero/unknown */ - fwrite(&base, 1, 4, fp); /* 00000008: Offset at which data starts */ - fwrite(&size, 1, 4, fp); /* 0000000C: Full size of the data (32-bit) */ - fwrite(§or_size, 1, 4, fp); /* 00000010: Sector size in bytes */ - fwrite(&spt, 1, 4, fp); /* 00000014: Sectors per cylinder */ - fwrite(&hpc, 1, 4, fp); /* 00000018: Heads per cylinder */ - fwrite(&tracks, 1, 4, fp); /* 0000001C: Cylinders */ - - for (i = 0; i < 0x3f8; i++) - fwrite(&zero, 1, 4, fp); - } else if (img_format == IMG_FMT_HDX) { /* HDX file */ - fwrite(&signature, 1, 8, fp); /* 00000000: Signature */ - fwrite(&size, 1, 8, fp); /* 00000008: Full size of the data (64-bit) */ - fwrite(§or_size, 1, 4, fp); /* 00000010: Sector size in bytes */ - fwrite(&spt, 1, 4, fp); /* 00000014: Sectors per cylinder */ - fwrite(&hpc, 1, 4, fp); /* 00000018: Heads per cylinder */ - fwrite(&tracks, 1, 4, fp); /* 0000001C: Cylinders */ - fwrite(&zero, 1, 4, fp); /* 00000020: [Translation] Sectors per cylinder */ - fwrite(&zero, 1, 4, fp); /* 00000004: [Translation] Heads per cylinder */ - } else if (img_format >= IMG_FMT_VHD_FIXED) { /* VHD file */ - MVHDGeom _86box_geometry; - block_size = settings_get_cur_sel(hdlg, IDC_COMBO_HD_BLOCK_SIZE) == 0 ? MVHD_BLOCK_LARGE : MVHD_BLOCK_SMALL; - switch (img_format) { - case IMG_FMT_VHD_FIXED: - vhd_progress_hdlg = hdlg; - _86box_geometry = create_drive_vhd_fixed(hd_file_name_multibyte, tracks, hpc, spt); - break; - case IMG_FMT_VHD_DYNAMIC: - _86box_geometry = create_drive_vhd_dynamic(hd_file_name_multibyte, tracks, hpc, spt, block_size); - break; - case IMG_FMT_VHD_DIFF: - if (file_dlg_w(hdlg, plat_get_string(IDS_4130), L"", plat_get_string(IDS_4131), 0)) { - return TRUE; - } - _86box_geometry = create_drive_vhd_diff(hd_file_name_multibyte, openfilestring, block_size); - break; - } - - if (img_format != IMG_FMT_VHD_DIFF) - settings_msgbox_header(MBX_INFO, (wchar_t *) IDS_4113, (wchar_t *) IDS_4117); - - hdd_ptr->tracks = _86box_geometry.cyl; - hdd_ptr->hpc = _86box_geometry.heads; - hdd_ptr->spt = _86box_geometry.spt; - - hard_disk_added = 1; - EndDialog(hdlg, 0); - return TRUE; - } - - big_buf = (char *) malloc(1048576); - memset(big_buf, 0, 1048576); - - r = size >> 20; - size &= 0xfffff; - - if (size || r) { - settings_show_window(hdlg, IDT_FILE_NAME, FALSE); - settings_show_window(hdlg, IDC_EDIT_HD_FILE_NAME, FALSE); - settings_show_window(hdlg, IDC_CFILE, FALSE); - settings_show_window(hdlg, IDC_PBAR_IMG_CREATE, TRUE); - settings_enable_window(hdlg, IDT_PROGRESS, TRUE); - - h = GetDlgItem(hdlg, IDC_PBAR_IMG_CREATE); - SendMessage(h, PBM_SETRANGE32, (WPARAM) 0, (LPARAM) r); - SendMessage(h, PBM_SETPOS, (WPARAM) 0, (LPARAM) 0); - } - - h = GetDlgItem(hdlg, IDC_PBAR_IMG_CREATE); - - if (size) { - if (fp) { - fwrite(big_buf, 1, size, fp); - } - SendMessage(h, PBM_SETPOS, (WPARAM) 1, (LPARAM) 0); - } - - if (r) { - for (i = 0; i < r; i++) { - if (fp) { - fwrite(big_buf, 1, 1048576, fp); - } - SendMessage(h, PBM_SETPOS, (i + 1), (LPARAM) 0); - - settings_process_messages(); - } - } - - free(big_buf); - - if (fp) { - fclose(fp); - } - settings_msgbox_header(MBX_INFO, (wchar_t *) IDS_4113, (wchar_t *) IDS_4117); - } - - hard_disk_added = 1; - EndDialog(hdlg, 0); - return TRUE; - - case IDCANCEL: - hard_disk_added = 0; - hdd_ptr->bus = HDD_BUS_DISABLED; - EndDialog(hdlg, 0); - return TRUE; - - case IDC_CFILE: - if (!file_dlg_w(hdlg, plat_get_string(IDS_4106), L"", NULL, !(existing & 1))) { - if (!wcschr(wopenfilestring, L'.')) { - if (wcslen(wopenfilestring) && (wcslen(wopenfilestring) <= 256)) { - twcs = &wopenfilestring[wcslen(wopenfilestring)]; - twcs[0] = L'.'; - twcs[1] = L'i'; - twcs[2] = L'm'; - twcs[3] = L'g'; - } - } - - if (!(existing & 1)) { - fp = _wfopen(wopenfilestring, L"rb"); - if (fp != NULL) { - fclose(fp); - if (settings_msgbox_ex(MBX_QUESTION_YN, (wchar_t *) IDS_4111, (wchar_t *) IDS_4118, (wchar_t *) IDS_4120, (wchar_t *) IDS_4121, NULL) != 0) /* yes */ - return FALSE; - } - } - - fp = _wfopen(wopenfilestring, (existing & 1) ? L"rb" : L"wb"); - if (fp == NULL) { -hdd_add_file_open_error: - fclose(fp); - settings_msgbox_header(MBX_ERROR, (existing & 1) ? (wchar_t *) IDS_4114 : (wchar_t *) IDS_4115, (existing & 1) ? (wchar_t *) IDS_4107 : (wchar_t *) IDS_4108); - return TRUE; - } - if (existing & 1) { - if (image_is_hdi(openfilestring) || image_is_hdx(openfilestring, 1)) { - fseeko64(fp, 0x10, SEEK_SET); - fread(§or_size, 1, 4, fp); - if (sector_size != 512) { - settings_msgbox_header(MBX_ERROR, (wchar_t *) IDS_4119, (wchar_t *) IDS_4109); - fclose(fp); - return TRUE; - } - spt = hpc = tracks = 0; - fread(&spt, 1, 4, fp); - fread(&hpc, 1, 4, fp); - fread(&tracks, 1, 4, fp); - } else if (image_is_vhd(openfilestring, 1)) { - fclose(fp); - MVHDMeta *vhd = mvhd_open(openfilestring, 0, &vhd_error); - if (vhd == NULL) { - settings_msgbox_header(MBX_ERROR, (existing & 1) ? (wchar_t *) IDS_4114 : (wchar_t *) IDS_4115, (existing & 1) ? (wchar_t *) IDS_4107 : (wchar_t *) IDS_4108); - return TRUE; - } else if (vhd_error == MVHD_ERR_TIMESTAMP) { - if (settings_msgbox_ex(MBX_QUESTION_YN | MBX_WARNING, plat_get_string(IDS_4133), plat_get_string(IDS_4132), NULL, NULL, NULL) != 0) { - int ts_res = mvhd_diff_update_par_timestamp(vhd, &vhd_error); - if (ts_res != 0) { - settings_msgbox_header(MBX_ERROR, plat_get_string(IDS_2049), plat_get_string(IDS_4134)); - mvhd_close(vhd); - return TRUE; - } - } else { - mvhd_close(vhd); - return TRUE; - } - } - - MVHDGeom vhd_geom = mvhd_get_geometry(vhd); - adjust_vhd_geometry_for_86box(&vhd_geom); - tracks = vhd_geom.cyl; - hpc = vhd_geom.heads; - spt = vhd_geom.spt; - size = (uint64_t) tracks * hpc * spt * 512; - mvhd_close(vhd); - } else { - fseeko64(fp, 0, SEEK_END); - size = ftello64(fp); - if (((size % 17) == 0) && (size <= 142606336)) { - spt = 17; - if (size <= 26738688) - hpc = 4; - else if (((size % 3072) == 0) && (size <= 53477376)) - hpc = 6; - else { - for (i = 5; i < 16; i++) { - if (((size % (i << 9)) == 0) && (size <= ((i * 17) << 19))) - break; - if (i == 5) - i++; - } - hpc = i; - } - } else { - spt = 63; - hpc = 16; - } - - tracks = ((size >> 9) / hpc) / spt; - } - - if ((spt > max_spt) || (hpc > max_hpc) || (tracks > max_tracks)) - goto hdd_add_file_open_error; - no_update = 1; - - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); - recalc_selection(hdlg); - - settings_enable_window(hdlg, IDC_EDIT_HD_SPT, TRUE); - settings_enable_window(hdlg, IDC_EDIT_HD_HPC, TRUE); - settings_enable_window(hdlg, IDC_EDIT_HD_CYL, TRUE); - settings_enable_window(hdlg, IDC_EDIT_HD_SIZE, TRUE); - settings_enable_window(hdlg, IDC_COMBO_HD_TYPE, TRUE); - - chs_enabled = 1; - - no_update = 0; - } - - fclose(fp); - } - - h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); - SendMessage(h, WM_SETTEXT, 0, (LPARAM) wopenfilestring); - memset(hd_file_name, 0, sizeof(hd_file_name)); - wcscpy(hd_file_name, wopenfilestring); - - return TRUE; - - case IDC_EDIT_HD_CYL: - if (no_update) - return FALSE; - - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &temp); - if (tracks != (int64_t) temp) { - tracks = temp; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (tracks > max_tracks) { - tracks = max_tracks; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, (uint32_t) tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - no_update = 0; - break; - - case IDC_EDIT_HD_HPC: - if (no_update) - return FALSE; - - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &temp); - if (hpc != (int64_t) temp) { - hpc = temp; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (hpc > max_hpc) { - hpc = max_hpc; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, (uint32_t) hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - no_update = 0; - break; - - case IDC_EDIT_HD_SPT: - if (no_update) - return FALSE; - - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &temp); - if (spt != (int64_t) temp) { - spt = temp; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (spt > max_spt) { - spt = max_spt; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - no_update = 0; - break; - - case IDC_EDIT_HD_SIZE: - if (no_update) - return FALSE; - - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, &temp); - if (temp != (uint32_t) (size >> 20)) { - size = ((uint64_t) temp) << 20LL; - /* This is needed to ensure VHD standard compliance. */ - hdd_image_calc_chs((uint32_t *) &tracks, (uint32_t *) &hpc, (uint32_t *) &spt, temp); - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, (uint32_t) tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, (uint32_t) hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, (uint32_t) spt); - recalc_selection(hdlg); - } - - if (tracks > max_tracks) { - tracks = max_tracks; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, (uint32_t) tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (hpc > max_hpc) { - hpc = max_hpc; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, (uint32_t) hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (spt > max_spt) { - spt = max_spt; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, (uint32_t) spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - no_update = 0; - break; - - case IDC_COMBO_HD_TYPE: - if (no_update) - return FALSE; - - no_update = 1; - temp = settings_get_cur_sel(hdlg, IDC_COMBO_HD_TYPE); - if ((temp != selection) && (temp != 127) && (temp != 128)) { - selection = temp; - tracks = hdd_table[selection][0]; - hpc = hdd_table[selection][1]; - spt = hdd_table[selection][2]; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, (uint32_t) tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, (uint32_t) hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, (uint32_t) spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - } else if ((temp != selection) && (temp == 127)) - selection = temp; - else if ((temp != selection) && (temp == 128)) { - selection = temp; - hpc = 16; - spt = 63; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, (uint32_t) hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, (uint32_t) spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - } - - if (spt > max_spt) { - spt = max_spt; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, (uint32_t) spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (hpc > max_hpc) { - hpc = max_hpc; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, (uint32_t) hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (tracks > max_tracks) { - tracks = max_tracks; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, (uint32_t) tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - no_update = 0; - break; - - case IDC_COMBO_HD_BUS: - if (no_update) - return FALSE; - - no_update = 1; - recalc_location_controls(hdlg, 1, 0); - b = settings_get_cur_sel(hdlg, IDC_COMBO_HD_BUS) + 1; - if (b != hdd_ptr->bus) { - hdd_ptr->bus = b; - - switch (hdd_ptr->bus) { - default: - case HDD_BUS_DISABLED: - max_spt = max_hpc = max_tracks = 0; - break; - case HDD_BUS_MFM: - max_spt = 26; /* 17 for MFM, 26 for RLL. */ - max_hpc = 15; - max_tracks = 2047; - break; - case HDD_BUS_XTA: - max_spt = 63; - max_hpc = 16; - max_tracks = 1023; - break; - case HDD_BUS_ESDI: - max_spt = 99; /* ESDI drives usually had 32 to 43 sectors per track. */ - max_hpc = 16; - max_tracks = 266305; - break; - case HDD_BUS_IDE: - max_spt = 255; - max_hpc = 255; - max_tracks = 266305; - break; - case HDD_BUS_ATAPI: - case HDD_BUS_SCSI: - max_spt = 255; - max_hpc = 255; - max_tracks = 266305; - break; - } - - if (!chs_enabled) { - settings_enable_window(hdlg, IDC_EDIT_HD_SPT, FALSE); - settings_enable_window(hdlg, IDC_EDIT_HD_HPC, FALSE); - settings_enable_window(hdlg, IDC_EDIT_HD_CYL, FALSE); - settings_enable_window(hdlg, IDC_EDIT_HD_SIZE, FALSE); - settings_enable_window(hdlg, IDC_COMBO_HD_TYPE, FALSE); - } - - if (spt > max_spt) { - spt = max_spt; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, (uint32_t) spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (hpc > max_hpc) { - hpc = max_hpc; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, (uint32_t) hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (tracks > max_tracks) { - tracks = max_tracks; - size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, (uint32_t) tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - } - - no_update = 0; - break; - case IDC_COMBO_HD_IMG_FORMAT: - img_format = settings_get_cur_sel(hdlg, IDC_COMBO_HD_IMG_FORMAT); - - no_update = 1; - if (img_format == IMG_FMT_VHD_DIFF) { /* They switched to a diff VHD; disable the geometry fields. */ - settings_enable_window(hdlg, IDC_EDIT_HD_SPT, FALSE); - set_edit_box_text_contents(hdlg, IDC_EDIT_HD_SPT, L"(N/A)"); - settings_enable_window(hdlg, IDC_EDIT_HD_HPC, FALSE); - set_edit_box_text_contents(hdlg, IDC_EDIT_HD_HPC, L"(N/A)"); - settings_enable_window(hdlg, IDC_EDIT_HD_CYL, FALSE); - set_edit_box_text_contents(hdlg, IDC_EDIT_HD_CYL, L"(N/A)"); - settings_enable_window(hdlg, IDC_EDIT_HD_SIZE, FALSE); - set_edit_box_text_contents(hdlg, IDC_EDIT_HD_SIZE, L"(N/A)"); - settings_enable_window(hdlg, IDC_COMBO_HD_TYPE, FALSE); - settings_reset_content(hdlg, IDC_COMBO_HD_TYPE); - settings_add_string(hdlg, IDC_COMBO_HD_TYPE, (LPARAM) L"(use parent)"); - settings_set_cur_sel(hdlg, IDC_COMBO_HD_TYPE, 0); - } else { - get_edit_box_text_contents(hdlg, IDC_EDIT_HD_SPT, text_buf, 256); - if (!wcscmp(text_buf, L"(N/A)")) { - settings_enable_window(hdlg, IDC_EDIT_HD_SPT, TRUE); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, 17); - spt = 17; - settings_enable_window(hdlg, IDC_EDIT_HD_HPC, TRUE); - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, 15); - hpc = 15; - settings_enable_window(hdlg, IDC_EDIT_HD_CYL, TRUE); - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, 1023); - tracks = 1023; - settings_enable_window(hdlg, IDC_EDIT_HD_SIZE, TRUE); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) ((uint64_t) 17 * 15 * 1023 * 512 >> 20)); - size = (uint64_t) 17 * 15 * 1023 * 512; - - settings_reset_content(hdlg, IDC_COMBO_HD_TYPE); - hdconf_initialize_hdt_combo(hdlg); - settings_enable_window(hdlg, IDC_COMBO_HD_TYPE, TRUE); - } - } - no_update = 0; - - if (img_format == IMG_FMT_VHD_DYNAMIC || img_format == IMG_FMT_VHD_DIFF) { /* For dynamic and diff VHDs, show the block size dropdown. */ - settings_show_window(hdlg, IDC_COMBO_HD_BLOCK_SIZE, TRUE); - settings_show_window(hdlg, IDT_BLOCK_SIZE, TRUE); - } else { /* Hide it otherwise. */ - settings_show_window(hdlg, IDC_COMBO_HD_BLOCK_SIZE, FALSE); - settings_show_window(hdlg, IDT_BLOCK_SIZE, FALSE); - } - break; - } - - return FALSE; - } - - return FALSE; -} - -int -hard_disk_was_added(void) -{ - return hard_disk_added; -} - -void -hard_disk_add_open(HWND hwnd, int is_existing) -{ - existing = is_existing; - hard_disk_added = 0; - DialogBox(hinstance, (LPCWSTR) DLG_CFG_HARD_DISKS_ADD, hwnd, win_settings_hard_disks_add_proc); -} - -static void -hard_disk_track(uint8_t id) -{ - switch (temp_hdd[id].bus) { - case HDD_BUS_MFM: - mfm_tracking |= (1 << (temp_hdd[id].mfm_channel << 3)); - break; - case HDD_BUS_ESDI: - esdi_tracking |= (1 << (temp_hdd[id].esdi_channel << 3)); - break; - case HDD_BUS_XTA: - xta_tracking |= (1 << (temp_hdd[id].xta_channel << 3)); - break; - case HDD_BUS_IDE: - case HDD_BUS_ATAPI: - ide_tracking |= (1 << (temp_hdd[id].ide_channel << 3)); - break; - case HDD_BUS_SCSI: - scsi_tracking[temp_hdd[id].scsi_id >> 3] |= (1 << ((temp_hdd[id].scsi_id & 0x07) << 3)); - break; - } -} - -static void -hard_disk_untrack(uint8_t id) -{ - switch (temp_hdd[id].bus) { - case HDD_BUS_MFM: - mfm_tracking &= ~(1 << (temp_hdd[id].mfm_channel << 3)); - break; - case HDD_BUS_ESDI: - esdi_tracking &= ~(1 << (temp_hdd[id].esdi_channel << 3)); - break; - case HDD_BUS_XTA: - xta_tracking &= ~(1 << (temp_hdd[id].xta_channel << 3)); - break; - case HDD_BUS_IDE: - case HDD_BUS_ATAPI: - ide_tracking &= ~(1 << (temp_hdd[id].ide_channel << 3)); - break; - case HDD_BUS_SCSI: - scsi_tracking[temp_hdd[id].scsi_id >> 3] &= ~(1 << ((temp_hdd[id].scsi_id & 0x07) << 3)); - break; - } -} - -static void -hard_disk_track_all(void) -{ - for (uint8_t i = 0; i < HDD_NUM; i++) - hard_disk_track(i); -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - int old_sel = 0; - int b = 0; - int assign = 0; - const uint8_t hd_icons[2] = { 80, 0 }; - - switch (message) { - case WM_INITDIALOG: - ignore_change = 1; - - normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. - This will cause an emulator reset prompt on the first opening of this category with a messy hard disk list - (which can only happen by manually editing the configuration file). */ - win_settings_hard_disks_init_columns(hdlg); - image_list_init(hdlg, IDC_LIST_HARD_DISKS, (const uint8_t *) hd_icons); - win_settings_hard_disks_recalc_list(hdlg); - recalc_next_free_id(hdlg); - add_locations(hdlg); - if (hd_listview_items > 0) { - settings_listview_select(hdlg, IDC_LIST_HARD_DISKS, 0); - lv1_current_sel = 0; - settings_set_cur_sel(hdlg, IDC_COMBO_HD_BUS, temp_hdd[0].bus - 1); - } else - lv1_current_sel = -1; - recalc_location_controls(hdlg, 0, 0); - - settings_listview_enable_styles(hdlg, IDC_LIST_HARD_DISKS); - - ignore_change = 0; - return TRUE; - - case WM_NOTIFY: - if ((hd_listview_items == 0) || ignore_change) - return FALSE; - - if ((((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR) lParam)->idFrom == IDC_LIST_HARD_DISKS)) { - old_sel = lv1_current_sel; - lv1_current_sel = get_selected_hard_disk(hdlg); - if (lv1_current_sel == old_sel) - return FALSE; - ignore_change = 1; - settings_set_cur_sel(hdlg, IDC_COMBO_HD_BUS, temp_hdd[lv1_current_sel].bus - 1); - recalc_location_controls(hdlg, 0, 0); - ignore_change = 0; - } - break; - - case WM_COMMAND: - if (ignore_change && (LOWORD(wParam) != IDC_BUTTON_HDD_ADD) && (LOWORD(wParam) != IDC_BUTTON_HDD_ADD_NEW) && (LOWORD(wParam) != IDC_BUTTON_HDD_REMOVE)) - return FALSE; - switch (LOWORD(wParam)) { - case IDC_COMBO_HD_BUS: - ignore_change = 1; - b = settings_get_cur_sel(hdlg, IDC_COMBO_HD_BUS) + 1; - if (b != temp_hdd[lv1_current_sel].bus) { - hard_disk_untrack(lv1_current_sel); - assign = (temp_hdd[lv1_current_sel].bus == b) ? 0 : 1; - temp_hdd[lv1_current_sel].bus = b; - recalc_location_controls(hdlg, 0, assign); - hard_disk_track(lv1_current_sel); - win_settings_hard_disks_update_item(hdlg, lv1_current_sel, 0); - } - ignore_change = 0; - return FALSE; - - case IDC_COMBO_HD_CHANNEL: - ignore_change = 1; - hard_disk_untrack(lv1_current_sel); - temp_hdd[lv1_current_sel].channel = settings_get_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL); - hard_disk_track(lv1_current_sel); - win_settings_hard_disks_update_item(hdlg, lv1_current_sel, 0); - ignore_change = 0; - return FALSE; - - case IDC_COMBO_HD_CHANNEL_IDE: - ignore_change = 1; - hard_disk_untrack(lv1_current_sel); - temp_hdd[lv1_current_sel].ide_channel = settings_get_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - hard_disk_track(lv1_current_sel); - win_settings_hard_disks_update_item(hdlg, lv1_current_sel, 0); - ignore_change = 0; - return FALSE; - - case IDC_COMBO_HD_ID: - ignore_change = 1; - hard_disk_untrack(lv1_current_sel); - temp_hdd[lv1_current_sel].scsi_id = settings_get_cur_sel(hdlg, IDC_COMBO_HD_ID); - hard_disk_track(lv1_current_sel); - win_settings_hard_disks_update_item(hdlg, lv1_current_sel, 0); - ignore_change = 0; - return FALSE; - - case IDC_BUTTON_HDD_ADD: - case IDC_BUTTON_HDD_ADD_NEW: - hard_disk_add_open(hdlg, (LOWORD(wParam) == IDC_BUTTON_HDD_ADD)); - if (hard_disk_added) { - ignore_change = 1; - win_settings_hard_disks_recalc_list(hdlg); - recalc_next_free_id(hdlg); - hard_disk_track_all(); - ignore_change = 0; - } - return FALSE; - - case IDC_BUTTON_HDD_REMOVE: - temp_hdd[lv1_current_sel].fn[0] = '\0'; - hard_disk_untrack(lv1_current_sel); - temp_hdd[lv1_current_sel].bus = HDD_BUS_DISABLED; /* Only set the bus to zero, the list normalize code below will take care of turning this entire entry to a complete zero. */ - normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. */ - ignore_change = 1; - win_settings_hard_disks_recalc_list(hdlg); - recalc_next_free_id(hdlg); - if (hd_listview_items > 0) { - settings_listview_select(hdlg, IDC_LIST_HARD_DISKS, 0); - lv1_current_sel = 0; - settings_set_cur_sel(hdlg, IDC_COMBO_HD_BUS, temp_hdd[0].bus - 1); - } else - lv1_current_sel = -1; - recalc_location_controls(hdlg, 0, 0); - ignore_change = 0; - return FALSE; - } - - case WM_DPICHANGED_AFTERPARENT: - win_settings_hard_disks_resize_columns(hdlg); - image_list_init(hdlg, IDC_LIST_HARD_DISKS, (const uint8_t *) hd_icons); - break; - default: - return FALSE; - } - - return FALSE; -} - -static int -combo_id_to_string_id(int combo_id) -{ - return IDS_5376 + combo_id; -} - -static int -combo_id_to_format_string_id(int combo_id) -{ - return IDS_5632 + combo_id; -} - -static BOOL -win_settings_floppy_drives_recalc_list(HWND hdlg) -{ - LVITEM lvI; - char s[256]; - const char *t; - WCHAR szText[256]; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.state = 0; - - for (uint8_t i = 0; i < FDD_NUM; i++) { - lvI.iSubItem = 0; - if (temp_fdd_types[i] > 0) { - t = fdd_getname(temp_fdd_types[i]); - strncpy(s, t, sizeof(s) - 1); - mbstowcs(szText, s, strlen(s) + 1); - lvI.pszText = szText; - } else - lvI.pszText = plat_get_string(IDS_5376); - lvI.iItem = i; - lvI.iImage = temp_fdd_types[i]; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - - lvI.iSubItem = 1; - lvI.pszText = plat_get_string(temp_fdd_turbo[i] ? IDS_2060 : IDS_2061); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - - lvI.iSubItem = 2; - lvI.pszText = plat_get_string(temp_fdd_check_bpb[i] ? IDS_2060 : IDS_2061); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - } - - return TRUE; -} - -static BOOL -win_settings_cdrom_drives_recalc_list(HWND hdlg) -{ - LVITEM lvI; - int fsid = 0; - WCHAR szText[256]; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (uint8_t i = 0; i < CDROM_NUM; i++) { - fsid = combo_id_to_format_string_id(temp_cdrom[i].bus_type); - - lvI.iSubItem = 0; - switch (temp_cdrom[i].bus_type) { - default: - case CDROM_BUS_DISABLED: - lvI.pszText = plat_get_string(fsid); - lvI.iImage = 0; - break; - case CDROM_BUS_ATAPI: - wsprintf(szText, plat_get_string(fsid), temp_cdrom[i].ide_channel >> 1, temp_cdrom[i].ide_channel & 1); - lvI.pszText = szText; - lvI.iImage = 1; - break; - case CDROM_BUS_SCSI: - wsprintf(szText, plat_get_string(fsid), temp_cdrom[i].scsi_device_id >> 4, temp_cdrom[i].scsi_device_id & 15); - lvI.pszText = szText; - lvI.iImage = 1; - break; - } - - lvI.iItem = i; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - - lvI.iSubItem = 1; - if (temp_cdrom[i].bus_type == CDROM_BUS_DISABLED) - lvI.pszText = plat_get_string(IDS_2104); - else { - wsprintf(szText, L"%ix", temp_cdrom[i].speed); - lvI.pszText = szText; - } - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - -#if 0 - lvI.iSubItem = 2; - lvI.pszText = plat_get_string(temp_cdrom[i].early ? IDS_2060 : IDS_2061); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; -#endif - } - - return TRUE; -} - -static BOOL -win_settings_mo_drives_recalc_list(HWND hdlg) -{ - LVITEM lvI; - int fsid = 0; - WCHAR szText[256]; - char szType[30]; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_MO_DRIVES); - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (uint8_t i = 0; i < MO_NUM; i++) { - fsid = combo_id_to_format_string_id(temp_mo_drives[i].bus_type); - - lvI.iSubItem = 0; - switch (temp_mo_drives[i].bus_type) { - default: - case MO_BUS_DISABLED: - lvI.pszText = plat_get_string(fsid); - lvI.iImage = 0; - break; - case MO_BUS_ATAPI: - wsprintf(szText, plat_get_string(fsid), temp_mo_drives[i].ide_channel >> 1, temp_mo_drives[i].ide_channel & 1); - lvI.pszText = szText; - lvI.iImage = 1; - break; - case MO_BUS_SCSI: - wsprintf(szText, plat_get_string(fsid), temp_mo_drives[i].scsi_device_id >> 4, temp_mo_drives[i].scsi_device_id & 15); - lvI.pszText = szText; - lvI.iImage = 1; - break; - } - - lvI.iItem = i; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - - lvI.iSubItem = 1; - if (temp_mo_drives[i].bus_type == MO_BUS_DISABLED) - lvI.pszText = plat_get_string(IDS_2104); - else { - memset(szType, 0, 30); - memcpy(szType, mo_drive_types[temp_mo_drives[i].type].vendor, 8); - szType[strlen(szType)] = ' '; - memcpy(szType + strlen(szType), mo_drive_types[temp_mo_drives[i].type].model, 16); - szType[strlen(szType)] = ' '; - memcpy(szType + strlen(szType), mo_drive_types[temp_mo_drives[i].type].revision, 4); - - mbstowcs(szText, szType, strlen(szType) + 1); - lvI.pszText = szText; - } - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - } - - return TRUE; -} - -static BOOL -win_settings_zip_drives_recalc_list(HWND hdlg) -{ - LVITEM lvI; - int fsid = 0; - WCHAR szText[256]; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (uint8_t i = 0; i < ZIP_NUM; i++) { - fsid = combo_id_to_format_string_id(temp_zip_drives[i].bus_type); - - lvI.iSubItem = 0; - switch (temp_zip_drives[i].bus_type) { - default: - case ZIP_BUS_DISABLED: - lvI.pszText = plat_get_string(fsid); - lvI.iImage = 0; - break; - case ZIP_BUS_ATAPI: - wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].ide_channel >> 1, temp_zip_drives[i].ide_channel & 1); - lvI.pszText = szText; - lvI.iImage = 1; - break; - case ZIP_BUS_SCSI: - wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].scsi_device_id >> 4, temp_zip_drives[i].scsi_device_id & 15); - lvI.pszText = szText; - lvI.iImage = 1; - break; - } - - lvI.iItem = i; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - - lvI.iSubItem = 1; - lvI.pszText = plat_get_string(temp_zip_drives[i].is_250 ? IDS_5901 : IDS_5900); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - } - - return TRUE; -} - -#define C_COLUMNS_FLOPPY_DRIVES_TYPE 292 -#define C_COLUMNS_FLOPPY_DRIVES_TURBO 58 -#define C_COLUMNS_FLOPPY_DRIVES_BPB 89 - -static void -win_settings_floppy_drives_resize_columns(HWND hdlg) -{ - int width[C_COLUMNS_FLOPPY_DRIVES] = { - C_COLUMNS_FLOPPY_DRIVES_TYPE, - C_COLUMNS_FLOPPY_DRIVES_TURBO, - C_COLUMNS_FLOPPY_DRIVES_BPB - }; - int total = 0; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); - RECT r; - - GetWindowRect(hwndList, &r); - for (uint8_t iCol = 0; iCol < C_COLUMNS_FLOPPY_DRIVES; iCol++) { - width[iCol] = MulDiv(width[iCol], dpi, 96); - total += width[iCol]; - ListView_SetColumnWidth(hwndList, iCol, MulDiv(width[iCol], dpi, 96)); - } - width[C_COLUMNS_FLOPPY_DRIVES - 1] = (r.right - r.left) - 4 - total; - ListView_SetColumnWidth(hwndList, 2, width[C_COLUMNS_FLOPPY_DRIVES - 1]); -} - -static BOOL -win_settings_floppy_drives_init_columns(HWND hdlg) -{ - LVCOLUMN lvc; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - /* Type */ - lvc.iSubItem = 0; - lvc.pszText = plat_get_string(IDS_TYPE); - - lvc.cx = C_COLUMNS_FLOPPY_DRIVES_TYPE; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) - return FALSE; - - /* Turbo */ - lvc.iSubItem = 1; - lvc.pszText = plat_get_string(IDS_2059); - - lvc.cx = C_COLUMNS_FLOPPY_DRIVES_TURBO; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) - return FALSE; - - /* Check BPB */ - lvc.iSubItem = 2; - lvc.pszText = plat_get_string(IDS_BPB); - - lvc.cx = C_COLUMNS_FLOPPY_DRIVES_BPB; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 2, &lvc) == -1) - return FALSE; - - win_settings_floppy_drives_resize_columns(hdlg); - return TRUE; -} - -#define C_COLUMNS_CDROM_DRIVES_BUS 292 -#define C_COLUMNS_CDROM_DRIVES_SPEED 58 -#define C_COLUMNS_CDROM_DRIVES_EARLIER 89 - -static void -win_settings_cdrom_drives_resize_columns(HWND hdlg) -{ - int width[C_COLUMNS_CDROM_DRIVES] = { - C_COLUMNS_CDROM_DRIVES_BUS, - C_COLUMNS_CDROM_DRIVES_SPEED, - C_COLUMNS_CDROM_DRIVES_EARLIER - }; - int total = 0; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - RECT r; - - GetWindowRect(hwndList, &r); - for (uint8_t iCol = 0; iCol < C_COLUMNS_CDROM_DRIVES; iCol++) { - width[iCol] = MulDiv(width[iCol], dpi, 96); - total += width[iCol]; - ListView_SetColumnWidth(hwndList, iCol, MulDiv(width[iCol], dpi, 96)); - } - width[C_COLUMNS_CDROM_DRIVES - 1] = (r.right - r.left) - 4 - total; - ListView_SetColumnWidth(hwndList, 2, width[C_COLUMNS_CDROM_DRIVES - 1]); -} - -static BOOL -win_settings_cdrom_drives_init_columns(HWND hdlg) -{ - LVCOLUMN lvc; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - /* Bus */ - lvc.iSubItem = 0; - lvc.pszText = plat_get_string(IDS_BUS); - - lvc.cx = C_COLUMNS_CDROM_DRIVES_BUS; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) - return FALSE; - - /* Speed */ - lvc.iSubItem = 1; - lvc.pszText = plat_get_string(IDS_2053); - - lvc.cx = C_COLUMNS_CDROM_DRIVES_SPEED; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) - return FALSE; - - /* Type */ - lvc.iSubItem = 2; - lvc.pszText = plat_get_string(IDS_2162); - - lvc.cx = C_COLUMNS_CDROM_DRIVES_EARLIER; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 2, &lvc) == -1) - return FALSE; - - win_settings_cdrom_drives_resize_columns(hdlg); - return TRUE; -} - -#define C_COLUMNS_MO_DRIVES_BUS 292 -#define C_COLUMNS_MO_DRIVES_TYPE 147 - -static void -win_settings_mo_drives_resize_columns(HWND hdlg) -{ - int width[C_COLUMNS_MO_DRIVES] = { - C_COLUMNS_MO_DRIVES_BUS, - C_COLUMNS_MO_DRIVES_TYPE - }; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_MO_DRIVES); - RECT r; - - GetWindowRect(hwndList, &r); - width[0] = MulDiv(width[0], dpi, 96); - ListView_SetColumnWidth(hwndList, 0, MulDiv(width[0], dpi, 96)); - width[C_COLUMNS_MO_DRIVES - 1] = (r.right - r.left) - 4 - width[0]; - ListView_SetColumnWidth(hwndList, 1, width[C_COLUMNS_MO_DRIVES - 1]); -} - -static BOOL -win_settings_mo_drives_init_columns(HWND hdlg) -{ - LVCOLUMN lvc; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_MO_DRIVES); - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - /* Bus */ - lvc.iSubItem = 0; - lvc.pszText = plat_get_string(IDS_BUS); - - lvc.cx = C_COLUMNS_MO_DRIVES_BUS; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) - return FALSE; - - /* Type */ - lvc.iSubItem = 1; - lvc.pszText = plat_get_string(IDS_TYPE); - - lvc.cx = C_COLUMNS_MO_DRIVES_TYPE; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) - return FALSE; - - win_settings_mo_drives_resize_columns(hdlg); - return TRUE; -} - -#define C_COLUMNS_ZIP_DRIVES_BUS 292 -#define C_COLUMNS_ZIP_DRIVES_TYPE 147 - -static void -win_settings_zip_drives_resize_columns(HWND hdlg) -{ - int width[C_COLUMNS_ZIP_DRIVES] = { - C_COLUMNS_ZIP_DRIVES_BUS, - C_COLUMNS_ZIP_DRIVES_TYPE - }; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); - RECT r; - - GetWindowRect(hwndList, &r); - width[0] = MulDiv(width[0], dpi, 96); - ListView_SetColumnWidth(hwndList, 0, MulDiv(width[0], dpi, 96)); - width[C_COLUMNS_ZIP_DRIVES - 1] = (r.right - r.left) - 4 - width[0]; - ListView_SetColumnWidth(hwndList, 1, width[C_COLUMNS_ZIP_DRIVES - 1]); -} - -static BOOL -win_settings_zip_drives_init_columns(HWND hdlg) -{ - LVCOLUMN lvc; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - /* Bus */ - lvc.iSubItem = 0; - lvc.pszText = plat_get_string(IDS_BUS); - - lvc.cx = C_COLUMNS_ZIP_DRIVES_BUS; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) - return FALSE; - - /* Type */ - lvc.iSubItem = 1; - lvc.pszText = plat_get_string(IDS_TYPE); - - lvc.cx = C_COLUMNS_ZIP_DRIVES_TYPE; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) - return FALSE; - - win_settings_zip_drives_resize_columns(hdlg); - return TRUE; -} - -static int -get_selected_drive(HWND hdlg, int id, int max) -{ - int drive = -1; - int j = 0; - HWND h; - - for (int i = 0; i < max; i++) { - h = GetDlgItem(hdlg, id); - j = ListView_GetItemState(h, i, LVIS_SELECTED); - if (j) - drive = i; - } - - return drive; -} - -static void -win_settings_floppy_drives_update_item(HWND hdlg, int i) -{ - LVITEM lvI; - char s[256]; - const char *t; - WCHAR szText[256]; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - lvI.iSubItem = 0; - lvI.iItem = i; - - if (temp_fdd_types[i] > 0) { - t = fdd_getname(temp_fdd_types[i]); - strncpy(s, t, sizeof(s) - 1); - mbstowcs(szText, s, strlen(s) + 1); - lvI.pszText = szText; - } else - lvI.pszText = plat_get_string(IDS_5376); - lvI.iImage = temp_fdd_types[i]; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; - - lvI.iSubItem = 1; - lvI.pszText = plat_get_string(temp_fdd_turbo[i] ? IDS_2060 : IDS_2061); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; - - lvI.iSubItem = 2; - lvI.pszText = plat_get_string(temp_fdd_check_bpb[i] ? IDS_2060 : IDS_2061); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; -} - -static void -win_settings_cdrom_drives_update_item(HWND hdlg, int i) -{ - LVITEM lvI; - WCHAR szText[256]; - int fsid; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - lvI.iSubItem = 0; - lvI.iItem = i; - - fsid = combo_id_to_format_string_id(temp_cdrom[i].bus_type); - - switch (temp_cdrom[i].bus_type) { - default: - case CDROM_BUS_DISABLED: - lvI.pszText = plat_get_string(fsid); - lvI.iImage = 0; - break; - case CDROM_BUS_ATAPI: - wsprintf(szText, plat_get_string(fsid), temp_cdrom[i].ide_channel >> 1, temp_cdrom[i].ide_channel & 1); - lvI.pszText = szText; - lvI.iImage = 1; - break; - case CDROM_BUS_SCSI: - wsprintf(szText, plat_get_string(fsid), temp_cdrom[i].scsi_device_id >> 4, temp_cdrom[i].scsi_device_id & 15); - lvI.pszText = szText; - lvI.iImage = 1; - break; - } - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; - - lvI.iSubItem = 1; - if (temp_cdrom[i].bus_type == CDROM_BUS_DISABLED) - lvI.pszText = plat_get_string(IDS_2104); - else { - wsprintf(szText, L"%ix", temp_cdrom[i].speed); - lvI.pszText = szText; - } - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; - -#if 0 - lvI.iSubItem = 2; - lvI.pszText = plat_get_string(temp_cdrom[i].early ? IDS_2060 : IDS_2061); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; -#endif -} - -static void -win_settings_mo_drives_update_item(HWND hdlg, int i) -{ - LVITEM lvI; - WCHAR szText[256]; - char szType[30]; - int fsid; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_MO_DRIVES); - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - /* Bus */ - lvI.iSubItem = 0; - lvI.iItem = i; - - fsid = combo_id_to_format_string_id(temp_mo_drives[i].bus_type); - - switch (temp_mo_drives[i].bus_type) { - default: - case MO_BUS_DISABLED: - lvI.pszText = plat_get_string(fsid); - lvI.iImage = 0; - break; - case MO_BUS_ATAPI: - wsprintf(szText, plat_get_string(fsid), temp_mo_drives[i].ide_channel >> 1, temp_mo_drives[i].ide_channel & 1); - lvI.pszText = szText; - lvI.iImage = 1; - break; - case MO_BUS_SCSI: - wsprintf(szText, plat_get_string(fsid), temp_mo_drives[i].scsi_device_id >> 4, temp_mo_drives[i].scsi_device_id & 15); - lvI.pszText = szText; - lvI.iImage = 1; - break; - } - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; - - /* Type */ - lvI.iSubItem = 1; - if (temp_mo_drives[i].bus_type == MO_BUS_DISABLED) - lvI.pszText = plat_get_string(IDS_2104); - else { - memset(szType, 0, 30); - memcpy(szType, mo_drive_types[temp_mo_drives[i].type].vendor, 8); - szType[strlen(szType)] = ' '; - memcpy(szType + strlen(szType), mo_drive_types[temp_mo_drives[i].type].model, 16); - szType[strlen(szType)] = ' '; - memcpy(szType + strlen(szType), mo_drive_types[temp_mo_drives[i].type].revision, 4); - mbstowcs(szText, szType, strlen(szType) + 1); - lvI.pszText = szText; - } - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; -} - -static void -win_settings_zip_drives_update_item(HWND hdlg, int i) -{ - LVITEM lvI; - WCHAR szText[256]; - int fsid; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - lvI.iSubItem = 0; - lvI.iItem = i; - - fsid = combo_id_to_format_string_id(temp_zip_drives[i].bus_type); - - switch (temp_zip_drives[i].bus_type) { - default: - case ZIP_BUS_DISABLED: - lvI.pszText = plat_get_string(fsid); - lvI.iImage = 0; - break; - case ZIP_BUS_ATAPI: - wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].ide_channel >> 1, temp_zip_drives[i].ide_channel & 1); - lvI.pszText = szText; - lvI.iImage = 1; - break; - case ZIP_BUS_SCSI: - wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].scsi_device_id >> 4, temp_zip_drives[i].scsi_device_id & 15); - lvI.pszText = szText; - lvI.iImage = 1; - break; - } - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; - - lvI.iSubItem = 1; - lvI.pszText = plat_get_string(temp_zip_drives[i].is_250 ? IDS_5901 : IDS_5900); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; -} - -static void -cdrom_add_locations(HWND hdlg) -{ - LPTSTR lptsTemp; - int i = 0; - - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - - for (i = CDROM_BUS_DISABLED; i <= CDROM_BUS_SCSI; i++) { - if ((i == CDROM_BUS_DISABLED) || (i >= CDROM_BUS_ATAPI)) - settings_add_string(hdlg, IDC_COMBO_CD_BUS, win_get_string(combo_id_to_string_id(i))); - } - - for (i = 1; i <= 72; i++) { - wsprintf(lptsTemp, L"%ix", i); - settings_add_string(hdlg, IDC_COMBO_CD_SPEED, (LPARAM) lptsTemp); - } - - for (i = 0; i < (SCSI_BUS_MAX * SCSI_ID_MAX); i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4135), i >> 4, i & 15); - settings_add_string(hdlg, IDC_COMBO_CD_ID, (LPARAM) lptsTemp); - } - - for (i = 0; i < (IDE_BUS_MAX * IDE_CHAN_MAX); i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1); - settings_add_string(hdlg, IDC_COMBO_CD_CHANNEL_IDE, (LPARAM) lptsTemp); - } - - free(lptsTemp); -} - -static void -cdrom_recalc_location_controls(HWND hdlg, int assign_id) -{ - int bus = temp_cdrom[lv2_current_sel].bus_type; - - for (uint16_t i = IDT_CD_ID; i <= IDT_CD_CHANNEL; i++) - settings_show_window(hdlg, i, FALSE); - settings_show_window(hdlg, IDC_COMBO_CD_ID, FALSE); - settings_show_window(hdlg, IDC_COMBO_CD_CHANNEL_IDE, FALSE); - settings_show_window(hdlg, IDC_COMBO_CD_SPEED, bus != CDROM_BUS_DISABLED); - settings_show_window(hdlg, IDT_CD_SPEED, bus != CDROM_BUS_DISABLED); -#if 0 - settings_show_window(hdlg, IDC_COMBO_CD_TYPE, bus != CDROM_BUS_DISABLED); -#endif - if (bus != CDROM_BUS_DISABLED) { - settings_set_cur_sel(hdlg, IDC_COMBO_CD_SPEED, temp_cdrom[lv2_current_sel].speed - 1); -#if 0 - settings_set_check(hdlg, IDC_COMBO_CD_TYPE, temp_cdrom[lv2_current_sel].early); -#endif - } - - switch (bus) { - case CDROM_BUS_ATAPI: /* ATAPI */ - settings_show_window(hdlg, IDT_CD_CHANNEL, TRUE); - settings_show_window(hdlg, IDC_COMBO_CD_CHANNEL_IDE, TRUE); - - if (assign_id) - temp_cdrom[lv2_current_sel].ide_channel = next_free_ide_channel(); - - settings_set_cur_sel(hdlg, IDC_COMBO_CD_CHANNEL_IDE, temp_cdrom[lv2_current_sel].ide_channel); - break; - case CDROM_BUS_SCSI: /* SCSI */ - settings_show_window(hdlg, IDT_CD_ID, TRUE); - settings_show_window(hdlg, IDC_COMBO_CD_ID, TRUE); - - if (assign_id) - next_free_scsi_id(&temp_cdrom[lv2_current_sel].scsi_device_id); - - settings_set_cur_sel(hdlg, IDC_COMBO_CD_ID, temp_cdrom[lv2_current_sel].scsi_device_id); - break; - } -} - -static void -mo_add_locations(HWND hdlg) -{ - LPTSTR lptsTemp; - char *temp; - int i = 0; - - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - temp = (char *) malloc(30 * sizeof(char)); - - for (i = MO_BUS_DISABLED; i <= MO_BUS_SCSI; i++) { - if ((i == MO_BUS_DISABLED) || (i >= MO_BUS_ATAPI)) - settings_add_string(hdlg, IDC_COMBO_MO_BUS, win_get_string(combo_id_to_string_id(i))); - } - - for (i = 0; i < (SCSI_BUS_MAX * SCSI_ID_MAX); i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4135), i >> 4, i & 15); - settings_add_string(hdlg, IDC_COMBO_MO_ID, (LPARAM) lptsTemp); - } - - for (i = 0; i < (IDE_BUS_MAX * IDE_CHAN_MAX); i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1); - settings_add_string(hdlg, IDC_COMBO_MO_CHANNEL_IDE, (LPARAM) lptsTemp); - } - - for (int i = 0; i < KNOWN_MO_DRIVE_TYPES; i++) { - memset(temp, 0, 30); - memcpy(temp, mo_drive_types[i].vendor, 8); - temp[strlen(temp)] = ' '; - memcpy(temp + strlen(temp), mo_drive_types[i].model, 16); - temp[strlen(temp)] = ' '; - memcpy(temp + strlen(temp), mo_drive_types[i].revision, 4); - - mbstowcs(lptsTemp, temp, strlen(temp) + 1); - settings_add_string(hdlg, IDC_COMBO_MO_TYPE, (LPARAM) lptsTemp); - } - - free(temp); - free(lptsTemp); -} - -static void -mo_recalc_location_controls(HWND hdlg, int assign_id) -{ - int bus = temp_mo_drives[lv1_current_sel].bus_type; - - for (int i = IDT_MO_ID; i <= IDT_MO_CHANNEL; i++) - settings_show_window(hdlg, i, FALSE); - settings_show_window(hdlg, IDC_COMBO_MO_ID, FALSE); - settings_show_window(hdlg, IDC_COMBO_MO_CHANNEL_IDE, FALSE); - settings_show_window(hdlg, IDC_COMBO_MO_TYPE, bus != MO_BUS_DISABLED); - settings_show_window(hdlg, IDT_MO_TYPE, bus != MO_BUS_DISABLED); - - if (bus != MO_BUS_DISABLED) - settings_set_cur_sel(hdlg, IDC_COMBO_MO_TYPE, temp_mo_drives[lv1_current_sel].type); - - switch (bus) { - case MO_BUS_ATAPI: /* ATAPI */ - settings_show_window(hdlg, IDT_MO_CHANNEL, TRUE); - settings_show_window(hdlg, IDC_COMBO_MO_CHANNEL_IDE, TRUE); - - if (assign_id) - temp_mo_drives[lv1_current_sel].ide_channel = next_free_ide_channel(); - - settings_set_cur_sel(hdlg, IDC_COMBO_MO_CHANNEL_IDE, temp_mo_drives[lv1_current_sel].ide_channel); - break; - case MO_BUS_SCSI: /* SCSI */ - settings_show_window(hdlg, IDT_MO_ID, TRUE); - settings_show_window(hdlg, IDC_COMBO_MO_ID, TRUE); - - if (assign_id) - next_free_scsi_id(&temp_mo_drives[lv1_current_sel].scsi_device_id); - - settings_set_cur_sel(hdlg, IDC_COMBO_MO_ID, temp_mo_drives[lv1_current_sel].scsi_device_id); - break; - } -} - -static void -zip_add_locations(HWND hdlg) -{ - LPTSTR lptsTemp; - int i = 0; - - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - - for (i = ZIP_BUS_DISABLED; i <= ZIP_BUS_SCSI; i++) { - if ((i == ZIP_BUS_DISABLED) || (i >= ZIP_BUS_ATAPI)) - settings_add_string(hdlg, IDC_COMBO_ZIP_BUS, win_get_string(combo_id_to_string_id(i))); - } - - for (i = 0; i < (SCSI_BUS_MAX * SCSI_LUN_MAX); i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4135), i >> 4, i & 15); - settings_add_string(hdlg, IDC_COMBO_ZIP_ID, (LPARAM) lptsTemp); - } - - for (i = 0; i < (IDE_BUS_MAX * IDE_CHAN_MAX); i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1); - settings_add_string(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE, (LPARAM) lptsTemp); - } - - free(lptsTemp); -} - -static void -zip_recalc_location_controls(HWND hdlg, int assign_id) -{ - int bus = temp_zip_drives[lv2_current_sel].bus_type; - - for (int i = IDT_ZIP_ID; i <= IDT_ZIP_LUN; i++) - settings_show_window(hdlg, i, FALSE); - settings_show_window(hdlg, IDC_COMBO_ZIP_ID, FALSE); - settings_show_window(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE, FALSE); - settings_show_window(hdlg, IDC_CHECK250, bus != ZIP_BUS_DISABLED); - - if (bus != ZIP_BUS_DISABLED) - settings_set_check(hdlg, IDC_CHECK250, temp_zip_drives[lv2_current_sel].is_250); - - switch (bus) { - case ZIP_BUS_ATAPI: /* ATAPI */ - settings_show_window(hdlg, IDT_ZIP_LUN, TRUE); - settings_show_window(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE, TRUE); - - if (assign_id) - temp_zip_drives[lv2_current_sel].ide_channel = next_free_ide_channel(); - - settings_set_cur_sel(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE, temp_zip_drives[lv2_current_sel].ide_channel); - break; - case ZIP_BUS_SCSI: /* SCSI */ - settings_show_window(hdlg, IDT_ZIP_ID, TRUE); - settings_show_window(hdlg, IDC_COMBO_ZIP_ID, TRUE); - - if (assign_id) - next_free_scsi_id(&temp_zip_drives[lv2_current_sel].scsi_device_id); - - settings_set_cur_sel(hdlg, IDC_COMBO_ZIP_ID, temp_zip_drives[lv2_current_sel].scsi_device_id); - break; - } -} - -static void -cdrom_track(uint8_t id) -{ - if (temp_cdrom[id].bus_type == CDROM_BUS_ATAPI) - ide_tracking |= (2 << (temp_cdrom[id].ide_channel << 3)); - else if (temp_cdrom[id].bus_type == CDROM_BUS_SCSI) - scsi_tracking[temp_cdrom[id].scsi_device_id >> 3] |= (1 << (temp_cdrom[id].scsi_device_id & 0x07)); -} - -static void -cdrom_untrack(uint8_t id) -{ - if (temp_cdrom[id].bus_type == CDROM_BUS_ATAPI) - ide_tracking &= ~(2 << (temp_cdrom[id].ide_channel << 3)); - else if (temp_cdrom[id].bus_type == CDROM_BUS_SCSI) - scsi_tracking[temp_cdrom[id].scsi_device_id >> 3] &= ~(1 << (temp_cdrom[id].scsi_device_id & 0x07)); -} - -static void -zip_track(uint8_t id) -{ - if (temp_zip_drives[id].bus_type == ZIP_BUS_ATAPI) - ide_tracking |= (1 << temp_zip_drives[id].ide_channel); - else if (temp_zip_drives[id].bus_type == ZIP_BUS_SCSI) - scsi_tracking[temp_zip_drives[id].scsi_device_id >> 3] |= (1 << (temp_zip_drives[id].scsi_device_id & 0x07)); -} - -static void -zip_untrack(uint8_t id) -{ - if (temp_zip_drives[id].bus_type == ZIP_BUS_ATAPI) - ide_tracking &= ~(1 << temp_zip_drives[id].ide_channel); - else if (temp_zip_drives[id].bus_type == ZIP_BUS_SCSI) - scsi_tracking[temp_zip_drives[id].scsi_device_id >> 3] &= ~(1 << (temp_zip_drives[id].scsi_device_id & 0x07)); -} - -static void -mo_track(uint8_t id) -{ - if (temp_mo_drives[id].bus_type == MO_BUS_ATAPI) - ide_tracking |= (1 << (temp_mo_drives[id].ide_channel << 3)); - else if (temp_mo_drives[id].bus_type == MO_BUS_SCSI) - scsi_tracking[temp_mo_drives[id].scsi_device_id >> 3] |= (1 << (temp_mo_drives[id].scsi_device_id & 0x07)); -} - -static void -mo_untrack(uint8_t id) -{ - if (temp_mo_drives[id].bus_type == MO_BUS_ATAPI) - ide_tracking &= ~(1 << (temp_mo_drives[id].ide_channel << 3)); - else if (temp_mo_drives[id].bus_type == MO_BUS_SCSI) - scsi_tracking[temp_mo_drives[id].scsi_device_id >> 3] &= ~(1 << (temp_mo_drives[id].scsi_device_id & 0x07)); -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_floppy_and_cdrom_drives_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - int old_sel = 0; - int b = 0; - int assign = 0; - uint32_t b2 = 0; - WCHAR szText[256]; - const uint8_t fd_icons[15] = { 248, 16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24, 0 }; - const uint8_t cd_icons[3] = { 249, 32, 0 }; - - switch (message) { - case WM_INITDIALOG: - ignore_change = 1; - - lv1_current_sel = 0; - win_settings_floppy_drives_init_columns(hdlg); - image_list_init(hdlg, IDC_LIST_FLOPPY_DRIVES, (const uint8_t *) fd_icons); - win_settings_floppy_drives_recalc_list(hdlg); - settings_listview_select(hdlg, IDC_LIST_FLOPPY_DRIVES, 0); - for (uint8_t i = 0; i < 14; i++) { - if (i == 0) - settings_add_string(hdlg, IDC_COMBO_FD_TYPE, win_get_string(IDS_5376)); - else { - mbstowcs(szText, fdd_getname(i), strlen(fdd_getname(i)) + 1); - settings_add_string(hdlg, IDC_COMBO_FD_TYPE, (LPARAM) szText); - } - } - settings_set_cur_sel(hdlg, IDC_COMBO_FD_TYPE, temp_fdd_types[lv1_current_sel]); - - settings_set_check(hdlg, IDC_CHECKTURBO, temp_fdd_turbo[lv1_current_sel]); - settings_set_check(hdlg, IDC_CHECKBPB, temp_fdd_check_bpb[lv1_current_sel]); - - settings_listview_enable_styles(hdlg, IDC_LIST_FLOPPY_DRIVES); - - lv2_current_sel = 0; - win_settings_cdrom_drives_init_columns(hdlg); - image_list_init(hdlg, IDC_LIST_CDROM_DRIVES, (const uint8_t *) cd_icons); - win_settings_cdrom_drives_recalc_list(hdlg); - settings_listview_select(hdlg, IDC_LIST_CDROM_DRIVES, 0); - cdrom_add_locations(hdlg); - - switch (temp_cdrom[lv2_current_sel].bus_type) { - default: - case CDROM_BUS_DISABLED: - b = 0; - break; - case CDROM_BUS_ATAPI: - b = 1; - break; - case CDROM_BUS_SCSI: - b = 2; - break; - } - settings_set_cur_sel(hdlg, IDC_COMBO_CD_BUS, b); - cdrom_recalc_location_controls(hdlg, 0); - - settings_listview_enable_styles(hdlg, IDC_LIST_CDROM_DRIVES); - - ignore_change = 0; - return TRUE; - - case WM_NOTIFY: - if (ignore_change) - return FALSE; - - if ((((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR) lParam)->idFrom == IDC_LIST_FLOPPY_DRIVES)) { - old_sel = lv1_current_sel; - lv1_current_sel = get_selected_drive(hdlg, IDC_LIST_FLOPPY_DRIVES, FDD_NUM); - if (lv1_current_sel == old_sel) - return FALSE; - ignore_change = 1; - settings_set_cur_sel(hdlg, IDC_COMBO_FD_TYPE, temp_fdd_types[lv1_current_sel]); - settings_set_check(hdlg, IDC_CHECKTURBO, temp_fdd_turbo[lv1_current_sel]); - settings_set_check(hdlg, IDC_CHECKBPB, temp_fdd_check_bpb[lv1_current_sel]); - ignore_change = 0; - } else if ((((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR) lParam)->idFrom == IDC_LIST_CDROM_DRIVES)) { - old_sel = lv2_current_sel; - lv2_current_sel = get_selected_drive(hdlg, IDC_LIST_CDROM_DRIVES, CDROM_NUM); - if (lv2_current_sel == old_sel) - return FALSE; - ignore_change = 1; - - switch (temp_cdrom[lv2_current_sel].bus_type) { - default: - case CDROM_BUS_DISABLED: - b = 0; - break; - case CDROM_BUS_ATAPI: - b = 1; - break; - case CDROM_BUS_SCSI: - b = 2; - break; - } - settings_set_cur_sel(hdlg, IDC_COMBO_CD_BUS, b); - - cdrom_recalc_location_controls(hdlg, 0); - ignore_change = 0; - } - break; - - case WM_COMMAND: - if (ignore_change) - return FALSE; - - ignore_change = 1; - switch (LOWORD(wParam)) { - case IDC_COMBO_FD_TYPE: - temp_fdd_types[lv1_current_sel] = settings_get_cur_sel(hdlg, IDC_COMBO_FD_TYPE); - win_settings_floppy_drives_update_item(hdlg, lv1_current_sel); - break; - - case IDC_CHECKTURBO: - temp_fdd_turbo[lv1_current_sel] = settings_get_check(hdlg, IDC_CHECKTURBO); - win_settings_floppy_drives_update_item(hdlg, lv1_current_sel); - break; - - case IDC_CHECKBPB: - temp_fdd_check_bpb[lv1_current_sel] = settings_get_check(hdlg, IDC_CHECKBPB); - win_settings_floppy_drives_update_item(hdlg, lv1_current_sel); - break; - - case IDC_COMBO_CD_BUS: - b = settings_get_cur_sel(hdlg, IDC_COMBO_CD_BUS); - switch (b) { - case 0: - b2 = CDROM_BUS_DISABLED; - break; - case 1: - b2 = CDROM_BUS_ATAPI; - break; - case 2: - b2 = CDROM_BUS_SCSI; - break; - } - if (b2 == temp_cdrom[lv2_current_sel].bus_type) - break; - cdrom_untrack(lv2_current_sel); - assign = (temp_cdrom[lv2_current_sel].bus_type == b2) ? 0 : 1; - if (temp_cdrom[lv2_current_sel].bus_type == CDROM_BUS_DISABLED) - temp_cdrom[lv2_current_sel].speed = 8; - temp_cdrom[lv2_current_sel].bus_type = b2; - cdrom_recalc_location_controls(hdlg, assign); - cdrom_track(lv2_current_sel); - win_settings_cdrom_drives_update_item(hdlg, lv2_current_sel); - break; - - case IDC_COMBO_CD_ID: - cdrom_untrack(lv2_current_sel); - temp_cdrom[lv2_current_sel].scsi_device_id = settings_get_cur_sel(hdlg, IDC_COMBO_CD_ID); - cdrom_track(lv2_current_sel); - win_settings_cdrom_drives_update_item(hdlg, lv2_current_sel); - break; - - case IDC_COMBO_CD_CHANNEL_IDE: - cdrom_untrack(lv2_current_sel); - temp_cdrom[lv2_current_sel].ide_channel = settings_get_cur_sel(hdlg, IDC_COMBO_CD_CHANNEL_IDE); - cdrom_track(lv2_current_sel); - win_settings_cdrom_drives_update_item(hdlg, lv2_current_sel); - break; - - case IDC_COMBO_CD_SPEED: - temp_cdrom[lv2_current_sel].speed = settings_get_cur_sel(hdlg, IDC_COMBO_CD_SPEED) + 1; - win_settings_cdrom_drives_update_item(hdlg, lv2_current_sel); - break; - -#if 0 - case IDC_COMBO_CD_TYPE:: - temp_cdrom[lv2_current_sel].early = settings_get_check(hdlg, IDC_COMBO_CD_TYPE:); - win_settings_cdrom_drives_update_item(hdlg, lv2_current_sel); - break; -#endif - } - ignore_change = 0; - - case WM_DPICHANGED_AFTERPARENT: - win_settings_floppy_drives_resize_columns(hdlg); - image_list_init(hdlg, IDC_LIST_FLOPPY_DRIVES, (const uint8_t *) fd_icons); - win_settings_cdrom_drives_resize_columns(hdlg); - image_list_init(hdlg, IDC_LIST_CDROM_DRIVES, (const uint8_t *) cd_icons); - break; - default: - return FALSE; - } - - return FALSE; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_other_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - int old_sel = 0; - int b = 0; - int assign = 0; - uint32_t b2 = 0; - const uint8_t mo_icons[3] = { 251, 56, 0 }; - const uint8_t zip_icons[3] = { 250, 48, 0 }; - - switch (message) { - case WM_INITDIALOG: - ignore_change = 1; - - lv1_current_sel = 0; - win_settings_mo_drives_init_columns(hdlg); - image_list_init(hdlg, IDC_LIST_MO_DRIVES, (const uint8_t *) mo_icons); - win_settings_mo_drives_recalc_list(hdlg); - settings_listview_select(hdlg, IDC_LIST_MO_DRIVES, 0); - mo_add_locations(hdlg); - - switch (temp_mo_drives[lv1_current_sel].bus_type) { - default: - case MO_BUS_DISABLED: - b = 0; - break; - case MO_BUS_ATAPI: - b = 1; - break; - case MO_BUS_SCSI: - b = 2; - break; - } - settings_set_cur_sel(hdlg, IDC_COMBO_MO_BUS, b); - mo_recalc_location_controls(hdlg, 0); - - settings_listview_enable_styles(hdlg, IDC_LIST_MO_DRIVES); - - lv2_current_sel = 0; - win_settings_zip_drives_init_columns(hdlg); - image_list_init(hdlg, IDC_LIST_ZIP_DRIVES, (const uint8_t *) zip_icons); - win_settings_zip_drives_recalc_list(hdlg); - settings_listview_select(hdlg, IDC_LIST_ZIP_DRIVES, 0); - zip_add_locations(hdlg); - - switch (temp_zip_drives[lv2_current_sel].bus_type) { - default: - case ZIP_BUS_DISABLED: - b = 0; - break; - case ZIP_BUS_ATAPI: - b = 1; - break; - case ZIP_BUS_SCSI: - b = 2; - break; - } - settings_set_cur_sel(hdlg, IDC_COMBO_ZIP_BUS, b); - zip_recalc_location_controls(hdlg, 0); - - settings_listview_enable_styles(hdlg, IDC_LIST_ZIP_DRIVES); - - ignore_change = 0; - return TRUE; - - case WM_NOTIFY: - if (ignore_change) - return FALSE; - - if ((((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR) lParam)->idFrom == IDC_LIST_MO_DRIVES)) { - old_sel = lv1_current_sel; - lv1_current_sel = get_selected_drive(hdlg, IDC_LIST_MO_DRIVES, MO_NUM); - if (lv1_current_sel == old_sel) - return FALSE; - ignore_change = 1; - - switch (temp_mo_drives[lv1_current_sel].bus_type) { - default: - case MO_BUS_DISABLED: - b = 0; - break; - case MO_BUS_ATAPI: - b = 1; - break; - case MO_BUS_SCSI: - b = 2; - break; - } - settings_set_cur_sel(hdlg, IDC_COMBO_MO_BUS, b); - - mo_recalc_location_controls(hdlg, 0); - ignore_change = 0; - } else if ((((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR) lParam)->idFrom == IDC_LIST_ZIP_DRIVES)) { - old_sel = lv2_current_sel; - lv2_current_sel = get_selected_drive(hdlg, IDC_LIST_ZIP_DRIVES, ZIP_NUM); - if (lv2_current_sel == old_sel) - return FALSE; - ignore_change = 1; - - switch (temp_zip_drives[lv2_current_sel].bus_type) { - default: - case ZIP_BUS_DISABLED: - b = 0; - break; - case ZIP_BUS_ATAPI: - b = 1; - break; - case ZIP_BUS_SCSI: - b = 2; - break; - } - settings_set_cur_sel(hdlg, IDC_COMBO_ZIP_BUS, b); - - zip_recalc_location_controls(hdlg, 0); - ignore_change = 0; - } - break; - - case WM_COMMAND: - if (ignore_change) - return FALSE; - - ignore_change = 1; - switch (LOWORD(wParam)) { - case IDC_COMBO_MO_BUS: - b = settings_get_cur_sel(hdlg, IDC_COMBO_MO_BUS); - switch (b) { - case 0: - b2 = MO_BUS_DISABLED; - break; - case 1: - b2 = MO_BUS_ATAPI; - break; - case 2: - b2 = MO_BUS_SCSI; - break; - } - if (b2 == temp_mo_drives[lv1_current_sel].bus_type) - break; - mo_untrack(lv1_current_sel); - assign = (temp_mo_drives[lv1_current_sel].bus_type == b2) ? 0 : 1; - if (temp_mo_drives[lv1_current_sel].bus_type == MO_BUS_DISABLED) - temp_mo_drives[lv1_current_sel].type = 0; - temp_mo_drives[lv1_current_sel].bus_type = b2; - mo_recalc_location_controls(hdlg, assign); - mo_track(lv1_current_sel); - win_settings_mo_drives_update_item(hdlg, lv1_current_sel); - break; - - case IDC_COMBO_MO_ID: - mo_untrack(lv1_current_sel); - temp_mo_drives[lv1_current_sel].scsi_device_id = settings_get_cur_sel(hdlg, IDC_COMBO_MO_ID); - mo_track(lv1_current_sel); - win_settings_mo_drives_update_item(hdlg, lv1_current_sel); - break; - - case IDC_COMBO_MO_CHANNEL_IDE: - mo_untrack(lv1_current_sel); - temp_mo_drives[lv1_current_sel].ide_channel = settings_get_cur_sel(hdlg, IDC_COMBO_MO_CHANNEL_IDE); - mo_track(lv1_current_sel); - win_settings_mo_drives_update_item(hdlg, lv1_current_sel); - break; - - case IDC_COMBO_MO_TYPE: - temp_mo_drives[lv1_current_sel].type = settings_get_cur_sel(hdlg, IDC_COMBO_MO_TYPE); - win_settings_mo_drives_update_item(hdlg, lv1_current_sel); - break; - - case IDC_COMBO_ZIP_BUS: - b = settings_get_cur_sel(hdlg, IDC_COMBO_ZIP_BUS); - switch (b) { - case 0: - b2 = ZIP_BUS_DISABLED; - break; - case 1: - b2 = ZIP_BUS_ATAPI; - break; - case 2: - b2 = ZIP_BUS_SCSI; - break; - } - if (b2 == temp_zip_drives[lv2_current_sel].bus_type) - break; - zip_untrack(lv2_current_sel); - assign = (temp_zip_drives[lv2_current_sel].bus_type == b2) ? 0 : 1; - temp_zip_drives[lv2_current_sel].bus_type = b2; - zip_recalc_location_controls(hdlg, assign); - zip_track(lv2_current_sel); - win_settings_zip_drives_update_item(hdlg, lv2_current_sel); - break; - - case IDC_COMBO_ZIP_ID: - zip_untrack(lv2_current_sel); - temp_zip_drives[lv2_current_sel].scsi_device_id = settings_get_cur_sel(hdlg, IDC_COMBO_ZIP_ID); - zip_track(lv2_current_sel); - win_settings_zip_drives_update_item(hdlg, lv2_current_sel); - break; - - case IDC_COMBO_ZIP_CHANNEL_IDE: - zip_untrack(lv2_current_sel); - temp_zip_drives[lv2_current_sel].ide_channel = settings_get_cur_sel(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE); - zip_track(lv2_current_sel); - win_settings_zip_drives_update_item(hdlg, lv2_current_sel); - break; - - case IDC_CHECK250: - temp_zip_drives[lv2_current_sel].is_250 = settings_get_check(hdlg, IDC_CHECK250); - win_settings_zip_drives_update_item(hdlg, lv2_current_sel); - break; - } - ignore_change = 0; - - case WM_DPICHANGED_AFTERPARENT: - win_settings_mo_drives_resize_columns(hdlg); - image_list_init(hdlg, IDC_LIST_MO_DRIVES, (const uint8_t *) mo_icons); - win_settings_zip_drives_resize_columns(hdlg); - image_list_init(hdlg, IDC_LIST_ZIP_DRIVES, (const uint8_t *) zip_icons); - break; - default: - return FALSE; - } - - return FALSE; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - int c; - int d; - int e; - LPTSTR lptsTemp; - char *stransi; - const device_t *dev; - - switch (message) { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - stransi = (char *) malloc(512); - - /* Populate the ISA RTC card dropdown. */ - e = 0; - settings_reset_content(hdlg, IDC_COMBO_ISARTC); - for (d = 0;; d++) { - generate_device_name(isartc_get_device(d), isartc_get_internal_name(d), 0); - - if (!device_name[0]) - break; - dev = isartc_get_device(d); - if (device_is_valid(dev, temp_machine)) { - if (d == 0) { - settings_add_string(hdlg, IDC_COMBO_ISARTC, win_get_string(IDS_2104)); - settings_set_cur_sel(hdlg, IDC_COMBO_ISARTC, 0); - } else - settings_add_string(hdlg, IDC_COMBO_ISARTC, (LPARAM) device_name); - settings_list_to_device[1][e] = d; - if (d == temp_isartc) - settings_set_cur_sel(hdlg, IDC_COMBO_ISARTC, e); - e++; - } - } - settings_enable_window(hdlg, IDC_COMBO_ISARTC, machine_has_bus(temp_machine, MACHINE_BUS_ISA)); - settings_enable_window(hdlg, IDC_CONFIGURE_ISARTC, ((temp_isartc != 0) && machine_has_bus(temp_machine, MACHINE_BUS_ISA))); - - /* Populate the ISA memory card dropdowns. */ - for (c = 0; c < ISAMEM_MAX; c++) { - e = 0; - settings_reset_content(hdlg, IDC_COMBO_ISAMEM_1 + c); - for (d = 0;; d++) { - generate_device_name(isamem_get_device(d), (char *) isamem_get_internal_name(d), 0); - - if (!device_name[0]) - break; - - dev = isamem_get_device(d); - if (device_is_valid(dev, temp_machine)) { - if (d == 0) { - settings_add_string(hdlg, IDC_COMBO_ISAMEM_1 + c, win_get_string(IDS_2104)); - settings_set_cur_sel(hdlg, IDC_COMBO_ISAMEM_1 + c, 0); - } else - settings_add_string(hdlg, IDC_COMBO_ISAMEM_1 + c, (LPARAM) device_name); - settings_list_to_device[0][e] = d; - if (d == temp_isamem[c]) - settings_set_cur_sel(hdlg, IDC_COMBO_ISAMEM_1 + c, e); - e++; - } - } - settings_enable_window(hdlg, IDC_COMBO_ISAMEM_1 + c, machine_has_bus(temp_machine, MACHINE_BUS_ISA)); - settings_enable_window(hdlg, IDC_CONFIGURE_ISAMEM_1 + c, ((temp_isamem[c] != 0) && machine_has_bus(temp_machine, MACHINE_BUS_ISA))); - } - - settings_enable_window(hdlg, IDC_CHECK_BUGGER, machine_has_bus(temp_machine, MACHINE_BUS_ISA)); - settings_set_check(hdlg, IDC_CHECK_BUGGER, (temp_bugger && machine_has_bus(temp_machine, MACHINE_BUS_ISA))); - settings_set_check(hdlg, IDC_CHECK_POSTCARD, temp_postcard); - - free(stransi); - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_CONFIGURE_ISARTC: - temp_isartc = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_ISARTC)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *) isartc_get_device(temp_isartc)); - break; - - case IDC_COMBO_ISARTC: - temp_isartc = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_ISARTC)]; - settings_enable_window(hdlg, IDC_CONFIGURE_ISARTC, temp_isartc != 0); - break; - - case IDC_COMBO_ISAMEM_1: - case IDC_COMBO_ISAMEM_2: - case IDC_COMBO_ISAMEM_3: - case IDC_COMBO_ISAMEM_4: - c = LOWORD(wParam) - IDC_COMBO_ISAMEM_1; - temp_isamem[c] = settings_list_to_device[0][settings_get_cur_sel(hdlg, LOWORD(wParam))]; - settings_enable_window(hdlg, IDC_CONFIGURE_ISAMEM_1 + c, temp_isamem[c] != 0); - break; - - case IDC_CONFIGURE_ISAMEM_1: - case IDC_CONFIGURE_ISAMEM_2: - case IDC_CONFIGURE_ISAMEM_3: - case IDC_CONFIGURE_ISAMEM_4: - c = LOWORD(wParam) - IDC_CONFIGURE_ISAMEM_1; - temp_deviceconfig |= deviceconfig_inst_open(hdlg, (void *) isamem_get_device(temp_isamem[c]), c + 1); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - temp_isartc = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_ISARTC)]; - for (c = 0; c < ISAMEM_MAX; c++) { - temp_isamem[c] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_ISAMEM_1 + c)]; - } - temp_bugger = settings_get_check(hdlg, IDC_CHECK_BUGGER); - temp_postcard = settings_get_check(hdlg, IDC_CHECK_POSTCARD); - - default: - return FALSE; - } - return FALSE; -} - -void -win_settings_show_child(HWND hwndParent, DWORD child_id) -{ - if (child_id == displayed_category) - return; - else - displayed_category = child_id; - - SendMessage(hwndChildDialog, WM_SAVESETTINGS, 0, 0); - - DestroyWindow(hwndChildDialog); - - switch (child_id) { - case SETTINGS_PAGE_MACHINE: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_MACHINE, hwndParent, win_settings_machine_proc); - break; - case SETTINGS_PAGE_VIDEO: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_VIDEO, hwndParent, win_settings_video_proc); - break; - case SETTINGS_PAGE_INPUT: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_INPUT, hwndParent, win_settings_input_proc); - break; - case SETTINGS_PAGE_SOUND: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_SOUND, hwndParent, win_settings_sound_proc); - break; - case SETTINGS_PAGE_NETWORK: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_NETWORK, hwndParent, win_settings_network_proc); - break; - case SETTINGS_PAGE_PORTS: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_PORTS, hwndParent, win_settings_ports_proc); - break; - case SETTINGS_PAGE_STORAGE: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_STORAGE, hwndParent, win_settings_storage_proc); - break; - case SETTINGS_PAGE_HARD_DISKS: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_HARD_DISKS, hwndParent, win_settings_hard_disks_proc); - break; - case SETTINGS_PAGE_FLOPPY_AND_CDROM_DRIVES: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_FLOPPY_AND_CDROM_DRIVES, hwndParent, win_settings_floppy_and_cdrom_drives_proc); - break; - case SETTINGS_PAGE_OTHER_REMOVABLE_DEVICES: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_OTHER_REMOVABLE_DEVICES, hwndParent, win_settings_other_removable_devices_proc); - break; - case SETTINGS_PAGE_PERIPHERALS: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_PERIPHERALS, hwndParent, win_settings_peripherals_proc); - break; - default: - fatal("Invalid child dialog ID\n"); - return; - } - - ShowWindow(hwndChildDialog, SW_SHOWNORMAL); -} - -static BOOL -win_settings_main_insert_categories(HWND hwndList) -{ - LVITEM lvI; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (uint8_t i = 0; i < 11; i++) { - lvI.pszText = plat_get_string(IDS_2065 + i); - lvI.iItem = i; - lvI.iImage = i; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - } - - return TRUE; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_confirm(HWND hdlg) -{ - int i; - - SendMessage(hwndChildDialog, WM_SAVESETTINGS, 0, 0); - - if (win_settings_changed()) { - if (confirm_save && !settings_only) - i = settings_msgbox_ex(MBX_QUESTION_OK | MBX_WARNING | MBX_DONTASK, (wchar_t *) IDS_2122, (wchar_t *) IDS_2123, (wchar_t *) IDS_2124, NULL, NULL); - else - i = 0; - - if (i == 10) { - confirm_save = 0; - i = 0; - } - - if (i == 0) - win_settings_save(); - else - return FALSE; - } - - DestroyWindow(hwndChildDialog); - EndDialog(hdlg, 0); - win_notify_dlg_closed(); - return TRUE; -} - -static void -win_settings_categories_resize_columns(HWND hdlg) -{ - HWND hwndList = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); - RECT r; - - GetWindowRect(hwndList, &r); - ListView_SetColumnWidth(hwndList, 0, (r.right - r.left) + 1 - 5); -} - -static BOOL -win_settings_categories_init_columns(HWND hdlg) -{ - LVCOLUMN lvc; - int iCol = 0; - HWND hwndList = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - lvc.iSubItem = 0; - lvc.pszText = plat_get_string(2048); - - lvc.cx = 171; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, iCol, &lvc) == -1) - return FALSE; - - win_settings_categories_resize_columns(hdlg); - return TRUE; -} - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_main_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h = NULL; - int category; - int j = 0; - const uint8_t cat_icons[12] = { 240, 241, 242, 243, 96, 244, 252, 80, 246, 247, 245, 0 }; - - hwndParentDialog = hdlg; - - switch (message) { - case WM_INITDIALOG: - dpi = win_get_dpi(hdlg); - win_settings_init(); - displayed_category = -1; - h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); - win_settings_categories_init_columns(hdlg); - image_list_init(hdlg, IDC_SETTINGSCATLIST, (const uint8_t *) cat_icons); - win_settings_main_insert_categories(h); - settings_listview_select(hdlg, IDC_SETTINGSCATLIST, first_cat); - settings_listview_enable_styles(hdlg, IDC_SETTINGSCATLIST); - return TRUE; - case WM_NOTIFY: - if ((((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR) lParam)->idFrom == IDC_SETTINGSCATLIST)) { - category = -1; - for (uint8_t i = 0; i < 11; i++) { - h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); - j = ListView_GetItemState(h, i, LVIS_SELECTED); - if (j) - category = i; - } - if (category != -1) - win_settings_show_child(hdlg, category); - } - break; - case WM_CLOSE: - DestroyWindow(hwndChildDialog); - EndDialog(hdlg, 0); - win_notify_dlg_closed(); - return TRUE; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - return win_settings_confirm(hdlg); - case IDCANCEL: - DestroyWindow(hwndChildDialog); - EndDialog(hdlg, 0); - win_notify_dlg_closed(); - return TRUE; - } - break; - - case WM_DPICHANGED: - dpi = HIWORD(wParam); - win_settings_categories_resize_columns(hdlg); - image_list_init(hdlg, IDC_SETTINGSCATLIST, (const uint8_t *) cat_icons); - break; - default: - return FALSE; - } - - return FALSE; -} - -void -win_settings_open_ex(HWND hwnd, int category) -{ - win_notify_dlg_open(); - - first_cat = category; - DialogBox(hinstance, (LPCWSTR) DLG_CONFIG, hwnd, win_settings_main_proc); -} - -void -win_settings_open(HWND hwnd) -{ - win_settings_open_ex(hwnd, SETTINGS_PAGE_MACHINE); -} diff --git a/src/win/win_snd_gain.c b/src/win/win_snd_gain.c deleted file mode 100644 index 5297661bf..000000000 --- a/src/win/win_snd_gain.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Handle the sound gain dialog. - * - * - * - * Authors: Miran Grca, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP -#include -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/config.h> -#include <86box/plat.h> -#include <86box/sound.h> -#include <86box/win.h> - -static uint8_t old_gain; - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -SoundGainDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) -{ - HWND h; - - switch (message) { - case WM_INITDIALOG: - old_gain = sound_gain; - h = GetDlgItem(hdlg, IDC_SLIDER_GAIN); - SendMessage(h, TBM_SETRANGE, (WPARAM) 1, MAKELONG(0, 9)); - SendMessage(h, TBM_SETPOS, (WPARAM) 1, 9 - (sound_gain >> 1)); - SendMessage(h, TBM_SETTICFREQ, (WPARAM) 1, 0); - SendMessage(h, TBM_SETLINESIZE, (WPARAM) 0, 1); - SendMessage(h, TBM_SETPAGESIZE, (WPARAM) 0, 2); - break; - - case WM_VSCROLL: - h = GetDlgItem(hdlg, IDC_SLIDER_GAIN); - sound_gain = (9 - SendMessage(h, TBM_GETPOS, (WPARAM) 0, 0)) << 1; - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - h = GetDlgItem(hdlg, IDC_SLIDER_GAIN); - sound_gain = (9 - SendMessage(h, TBM_GETPOS, (WPARAM) 0, 0)) << 1; - config_save(); - EndDialog(hdlg, 0); - return TRUE; - - case IDCANCEL: - sound_gain = old_gain; - config_save(); - EndDialog(hdlg, 0); - return TRUE; - - default: - break; - } - break; - } - - return FALSE; -} - -void -SoundGainDialogCreate(HWND hwnd) -{ - DialogBox(hinstance, (LPCTSTR) DLG_SND_GAIN, hwnd, SoundGainDialogProcedure); -} diff --git a/src/win/win_specify_dim.c b/src/win/win_specify_dim.c deleted file mode 100644 index 5bedb846d..000000000 --- a/src/win/win_specify_dim.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Handle the dialog for specifying the dimensions of the main window. - * - * - * - * Authors: Miran Grca, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP -#include -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/config.h> -#include <86box/plat.h> -#include <86box/video.h> -#include <86box/sound.h> -#include <86box/win.h> - -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -SpecifyDimensionsDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - HWND h2; - HMENU hmenu; - UDACCEL accel; - UDACCEL accel2; - RECT r; - uint32_t temp_x = 0; - uint32_t temp_y = 0; - int dpi = 96; - int lock; - LPTSTR lptsTemp; - char *stransi; - - switch (message) { - case WM_INITDIALOG: - GetWindowRect(hwndRender, &r); - - h = GetDlgItem(hdlg, IDC_WIDTHSPIN); - h2 = GetDlgItem(hdlg, IDC_EDIT_WIDTH); - SendMessage(h, UDM_SETBUDDY, (WPARAM) h2, 0); - SendMessage(h, UDM_SETRANGE, 0, (120 << 16) | 2048); - accel.nSec = 0; - accel.nInc = 8; - SendMessage(h, UDM_SETACCEL, 1, (LPARAM) &accel); - SendMessage(h, UDM_SETPOS, 0, r.right - r.left); - - h = GetDlgItem(hdlg, IDC_HEIGHTSPIN); - h2 = GetDlgItem(hdlg, IDC_EDIT_HEIGHT); - SendMessage(h, UDM_SETBUDDY, (WPARAM) h2, 0); - SendMessage(h, UDM_SETRANGE, 0, (120 << 16) | 2048); - accel2.nSec = 0; - accel2.nInc = 8; - SendMessage(h, UDM_SETACCEL, 1, (LPARAM) &accel2); - SendMessage(h, UDM_SETPOS, 0, r.bottom - r.top); - - h = GetDlgItem(hdlg, IDC_CHECK_LOCK_SIZE); - SendMessage(h, BM_SETCHECK, !!(vid_resize & 2), 0); - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); - stransi = (char *) malloc(512); - - h = GetDlgItem(hdlg, IDC_EDIT_WIDTH); - SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, 512); - sscanf(stransi, "%u", &temp_x); - fixed_size_x = temp_x; - - h = GetDlgItem(hdlg, IDC_EDIT_HEIGHT); - SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, 512); - sscanf(stransi, "%u", &temp_y); - fixed_size_y = temp_y; - - h = GetDlgItem(hdlg, IDC_CHECK_LOCK_SIZE); - lock = SendMessage(h, BM_GETCHECK, 0, 0); - - if (lock) { - vid_resize = 2; - window_remember = 0; - } else { - vid_resize = 1; - window_remember = 1; - } - hmenu = GetMenu(hwndMain); - CheckMenuItem(hmenu, IDM_VID_REMEMBER, (window_remember == 1) ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize == 1) ? MF_CHECKED : MF_UNCHECKED); - EnableMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize & 2) ? MF_GRAYED : MF_ENABLED); - - if (vid_resize == 1) - SetWindowLongPtr(hwndMain, GWL_STYLE, (WS_OVERLAPPEDWINDOW) | WS_VISIBLE); - else - SetWindowLongPtr(hwndMain, GWL_STYLE, (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX & ~WS_MAXIMIZEBOX) | WS_VISIBLE); - - /* scale the screen base on DPI */ - if (dpi_scale) { - dpi = win_get_dpi(hwndMain); - temp_x = MulDiv(temp_x, dpi, 96); - temp_y = MulDiv(temp_y, dpi, 96); - } - - ResizeWindowByClientArea(hwndMain, temp_x, temp_y + sbar_height + tbar_height); - - if (vid_resize) { - CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_VID_SCALE_2X, MF_CHECKED); - scale = 1; - } - EnableMenuItem(hmenu, IDM_VID_SCALE_1X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_2X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_3X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_4X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_5X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_6X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_7X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_8X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_9X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_10X, vid_resize ? MF_GRAYED : MF_ENABLED); - - scrnsz_x = fixed_size_x; - scrnsz_y = fixed_size_y; - atomic_store(&doresize_monitors[0], 1); - - GetWindowRect(hwndMain, &r); - - if (mouse_capture) - ClipCursor(&r); - - if (window_remember || (vid_resize & 2)) { - window_x = r.left; - window_y = r.top; - if (!(vid_resize & 2)) { - window_w = r.right - r.left; - window_h = r.bottom - r.top; - } - } - - config_save(); - - free(stransi); - free(lptsTemp); - - EndDialog(hdlg, 0); - return TRUE; - - case IDCANCEL: - EndDialog(hdlg, 0); - return TRUE; - - default: - break; - } - break; - } - - return FALSE; -} - -void -SpecifyDimensionsDialogCreate(HWND hwnd) -{ - DialogBox(hinstance, (LPCTSTR) DLG_SPECIFY_DIM, hwnd, SpecifyDimensionsDialogProcedure); -} diff --git a/src/win/win_stbar.c b/src/win/win_stbar.c deleted file mode 100644 index 2cf8d84f4..000000000 --- a/src/win/win_stbar.c +++ /dev/null @@ -1,1058 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implement the application's Status Bar. - * - * - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#include -#include -#undef BITMAP -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/config.h> -#include "cpu.h" -#include <86box/device.h> -#include <86box/machine.h> -#include <86box/timer.h> -#include <86box/cassette.h> -#include <86box/cartridge.h> -#include <86box/hdd.h> -#include <86box/hdc.h> -#include <86box/fdd.h> -#include <86box/fdd_86f.h> -#include <86box/scsi.h> -#include <86box/scsi_device.h> -#include <86box/cdrom.h> -#include <86box/zip.h> -#include <86box/mo.h> -#include <86box/cdrom_image.h> -#include <86box/scsi_disk.h> -#include <86box/thread.h> -#include <86box/network.h> -#include <86box/video.h> -#include <86box/sound.h> -#include <86box/plat.h> -#include <86box/ui.h> -#include <86box/win.h> - -HWND hwndSBAR; -int update_icons = 1; -int reset_occurred = 1; - -static LONG_PTR OriginalProcedure; -static WCHAR **sbTips; -static int *iStatusWidths; -static int *sb_part_meanings; -static uint8_t *sb_part_icons; -static int sb_parts = 0; -static int sb_ready = 0; -static uint8_t sb_map[256]; -static int icon_width = 24; -static wchar_t sb_text[512] = L"\0"; -static wchar_t sb_bugtext[512] = L"\0"; - -/* Also used by win_settings.c */ -intptr_t -fdd_type_to_icon(int type) -{ - int ret = 248; - - switch (type) { - case 0: - break; - - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - ret = 16; - break; - - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - ret = 24; - break; - - default: - break; - } - - return ret; -} - -/* FIXME: should be hdd_count() in hdd.c */ -static int -hdd_count(int bus) -{ - int c = 0; - - for (uint8_t i = 0; i < HDD_NUM; i++) { - if (hdd[i].bus == bus) - c++; - } - - return c; -} - -void -ui_sb_timer_callback(int pane) -{ - if (!(reset_occurred & 1)) { - sb_part_icons[pane] &= ~1; - - if (sb_part_icons && sb_part_icons[pane]) { - SendMessage(hwndSBAR, SB_SETICON, pane, - (LPARAM) hIcon[sb_part_icons[pane]]); - } - } else - reset_occurred &= ~1; - - reset_occurred &= ~2; -} - -/* API */ -/* API: update one of the icons after activity. */ -void -ui_sb_update_icon(int tag, int active) -{ - uint8_t found = 0xff; - - if (!update_icons || !sb_ready) - return; - - if ((tag & 0xf0) >= SB_TEXT) - return; - - found = sb_map[tag]; - if ((found != 0xff) && ((sb_part_icons[found] ^ active) & 1) && active) { - sb_part_icons[found] |= 1; - - PostMessage(hwndSBAR, SB_SETICON, found, - (LPARAM) hIcon[sb_part_icons[found]]); - - reset_occurred = 2; - SetTimer(hwndMain, 0x8000 | found, 75, NULL); - } -} - -/* API: This is for the drive state indicator. */ -void -ui_sb_update_icon_state(int tag, int state) -{ - uint8_t found = 0xff; - - if (!sb_ready || ((tag & 0xf0) >= SB_HDD)) - return; - - found = sb_map[tag]; - if (found != 0xff) { - sb_part_icons[found] &= ~128; - sb_part_icons[found] |= (state ? 128 : 0); - - SendMessage(hwndSBAR, SB_SETICON, found, - (LPARAM) hIcon[sb_part_icons[found]]); - } -} - -static void -StatusBarCreateCassetteTip(int part) -{ - WCHAR tempTip[512]; - WCHAR fn[512]; - - if (strlen(cassette_fname) == 0) - _swprintf(tempTip, plat_get_string(IDS_2149), plat_get_string(IDS_2057)); - else { - mbstoc16s(fn, cassette_fname, sizeof_w(fn)); - _swprintf(tempTip, plat_get_string(IDS_2149), fn); - } - - if (sbTips[part] != NULL) { - free(sbTips[part]); - sbTips[part] = NULL; - } - sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - -static void -StatusBarCreateCartridgeTip(int part) -{ - WCHAR tempTip[512]; - WCHAR fn[512]; - int drive = sb_part_meanings[part] & 0xf; - - if (strlen(cart_fns[drive]) == 0) { - _swprintf(tempTip, plat_get_string(IDS_2151), - drive + 1, plat_get_string(IDS_2057)); - } else { - mbstoc16s(fn, cart_fns[drive], sizeof_w(fn)); - _swprintf(tempTip, plat_get_string(IDS_2151), - drive + 1, fn); - } - - if (sbTips[part] != NULL) { - free(sbTips[part]); - sbTips[part] = NULL; - } - sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - -static void -StatusBarCreateFloppyTip(int part) -{ - WCHAR wtext[512]; - WCHAR tempTip[512]; - WCHAR fn[512]; - - int drive = sb_part_meanings[part] & 0xf; - - mbstoc16s(wtext, fdd_getname(fdd_get_type(drive)), - strlen(fdd_getname(fdd_get_type(drive))) + 1); - if (strlen(floppyfns[drive]) == 0) { - _swprintf(tempTip, plat_get_string(IDS_2109), - drive + 1, wtext, plat_get_string(IDS_2057)); - } else { - mbstoc16s(fn, floppyfns[drive], sizeof_w(fn)); - _swprintf(tempTip, plat_get_string(IDS_2109), - drive + 1, wtext, fn); - } - - if (sbTips[part] != NULL) { - free(sbTips[part]); - sbTips[part] = NULL; - } - sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - -static void -StatusBarCreateCdromTip(int part) -{ - WCHAR tempTip[512]; - WCHAR *szText; - WCHAR fn[512]; - int id; - int drive = sb_part_meanings[part] & 0xf; - int bus = cdrom[drive].bus_type; - - id = IDS_5377 + (bus - 1); - szText = plat_get_string(id); - - if (cdrom[drive].host_drive == 200) { - if (strlen(cdrom[drive].image_path) == 0) { - _swprintf(tempTip, plat_get_string(IDS_5120), - drive + 1, szText, plat_get_string(IDS_2057)); - } else { - mbstoc16s(fn, cdrom[drive].image_path, sizeof_w(fn)); - _swprintf(tempTip, plat_get_string(IDS_5120), - drive + 1, szText, fn); - } - } else - _swprintf(tempTip, plat_get_string(IDS_5120), drive + 1, szText, plat_get_string(IDS_2057)); - - if (sbTips[part] != NULL) { - free(sbTips[part]); - sbTips[part] = NULL; - } - sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 4); - wcscpy(sbTips[part], tempTip); -} - -static void -StatusBarCreateZIPTip(int part) -{ - WCHAR tempTip[512]; - WCHAR *szText; - WCHAR fn[512]; - int id; - int drive = sb_part_meanings[part] & 0xf; - int bus = zip_drives[drive].bus_type; - - id = IDS_5377 + (bus - 1); - szText = plat_get_string(id); - - int type = zip_drives[drive].is_250 ? 250 : 100; - - if (strlen(zip_drives[drive].image_path) == 0) { - _swprintf(tempTip, plat_get_string(IDS_2054), - type, drive + 1, szText, plat_get_string(IDS_2057)); - } else { - mbstoc16s(fn, zip_drives[drive].image_path, sizeof_w(fn)); - _swprintf(tempTip, plat_get_string(IDS_2054), - type, drive + 1, szText, fn); - } - - if (sbTips[part] != NULL) { - free(sbTips[part]); - sbTips[part] = NULL; - } - sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - -static void -StatusBarCreateMOTip(int part) -{ - WCHAR tempTip[512]; - WCHAR *szText; - WCHAR fn[512]; - int id; - int drive = sb_part_meanings[part] & 0xf; - int bus = mo_drives[drive].bus_type; - - id = IDS_5377 + (bus - 1); - szText = plat_get_string(id); - - if (strlen(mo_drives[drive].image_path) == 0) { - _swprintf(tempTip, plat_get_string(IDS_2116), - drive + 1, szText, plat_get_string(IDS_2057)); - } else { - mbstoc16s(fn, mo_drives[drive].image_path, sizeof_w(fn)); - _swprintf(tempTip, plat_get_string(IDS_2116), - drive + 1, szText, fn); - } - - if (sbTips[part] != NULL) { - free(sbTips[part]); - sbTips[part] = NULL; - } - sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - -static void -StatusBarCreateDiskTip(int part) -{ - WCHAR tempTip[512]; - WCHAR *szText; - int id; - int bus = sb_part_meanings[part] & 0xf; - - id = IDS_4352 + (bus - 1); - szText = plat_get_string(id); - - _swprintf(tempTip, plat_get_string(IDS_4096), szText); - if (sbTips[part] != NULL) - free(sbTips[part]); - sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - -static void -StatusBarCreateNetworkTip(int part) -{ - WCHAR tempTip[512]; - - _swprintf(tempTip, plat_get_string(IDS_2069)); - - if (sbTips[part] != NULL) - free(sbTips[part]); - sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - -static void -StatusBarCreateSoundTip(int part) -{ - WCHAR tempTip[512]; - - _swprintf(tempTip, plat_get_string(IDS_2068)); - - if (sbTips[part] != NULL) - free(sbTips[part]); - sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - -/* API */ -void -ui_sb_update_tip(int meaning) -{ - uint8_t part = 0xff; - - if (!sb_ready || (sb_parts == 0) || (sb_part_meanings == NULL)) - return; - - part = sb_map[meaning]; - - if (part != 0xff) { - switch (meaning & 0xf0) { - case SB_CASSETTE: - StatusBarCreateCassetteTip(part); - break; - - case SB_CARTRIDGE: - StatusBarCreateCartridgeTip(part); - break; - - case SB_FLOPPY: - StatusBarCreateFloppyTip(part); - break; - - case SB_CDROM: - StatusBarCreateCdromTip(part); - break; - - case SB_ZIP: - StatusBarCreateZIPTip(part); - break; - - case SB_MO: - StatusBarCreateMOTip(part); - break; - - case SB_HDD: - StatusBarCreateDiskTip(part); - break; - - case SB_NETWORK: - StatusBarCreateNetworkTip(part); - break; - - case SB_SOUND: - StatusBarCreateSoundTip(part); - break; - - default: - break; - } - - SendMessage(hwndSBAR, SB_SETTIPTEXT, part, (LPARAM) sbTips[part]); - } -} - -static void -StatusBarDestroyTips(void) -{ - if (sb_parts == 0) - return; - - if (!sbTips) - return; - - for (int i = 0; i < sb_parts; i++) { - if (sbTips[i]) { - free(sbTips[i]); - sbTips[i] = NULL; - } - } - - free(sbTips); - sbTips = NULL; -} - -/* API: mark the status bar as not ready. */ -/* Values: -1 - not ready, but don't clear POST text - 0 - not ready - 1 - ready */ -void -ui_sb_set_ready(int ready) -{ - if (ready == 0) { - ui_sb_bugui(NULL); - ui_sb_set_text(NULL); - } - - if (ready == -1) - ready = 0; - - sb_ready = ready; -} - -/* API: update the status bar panes. */ -void -ui_sb_update_panes(void) -{ - int i; - int id; - int cart_int; - int mfm_int; - int xta_int; - int esdi_int; - int ide_int; - int scsi_int; - int edge = 0; - int c_mfm; - int c_esdi; - int c_xta; - int c_ide; - int c_scsi; - int do_net; - const char *hdc_name; - - if (!config_changed) - return; - - if (sb_ready) { - sb_ready = 0; - } - - cart_int = machine_has_cartridge(machine) ? 1 : 0; - mfm_int = machine_has_flags(machine, MACHINE_MFM) ? 1 : 0; - xta_int = machine_has_flags(machine, MACHINE_XTA) ? 1 : 0; - esdi_int = machine_has_flags(machine, MACHINE_ESDI) ? 1 : 0; - ide_int = machine_has_flags(machine, MACHINE_IDE_QUAD) ? 1 : 0; - scsi_int = machine_has_flags(machine, MACHINE_SCSI) ? 1 : 0; - - c_mfm = hdd_count(HDD_BUS_MFM); - c_esdi = hdd_count(HDD_BUS_ESDI); - c_xta = hdd_count(HDD_BUS_XTA); - c_ide = hdd_count(HDD_BUS_IDE); - c_scsi = hdd_count(HDD_BUS_SCSI); - do_net = network_available(); - - media_menu_reset(); - - if (sb_parts > 0) { - for (i = 0; i < sb_parts; i++) - SendMessage(hwndSBAR, SB_SETICON, i, (LPARAM) NULL); - SendMessage(hwndSBAR, SB_SETPARTS, (WPARAM) 0, (LPARAM) NULL); - - if (iStatusWidths) { - free(iStatusWidths); - iStatusWidths = NULL; - } - if (sb_part_meanings) { - free(sb_part_meanings); - sb_part_meanings = NULL; - } - if (sb_part_icons) { - free(sb_part_icons); - sb_part_icons = NULL; - } - StatusBarDestroyTips(); - } - - memset(sb_map, 0xff, sizeof(sb_map)); - - sb_parts = 0; - if (cassette_enable) - sb_parts++; - if (cart_int) - sb_parts += 2; - for (i = 0; i < FDD_NUM; i++) { - if (fdd_get_type(i) != 0) - sb_parts++; - } - hdc_name = hdc_get_internal_name(hdc_current); - for (i = 0; i < CDROM_NUM; i++) { - /* Could be Internal or External IDE.. */ - if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && !ide_int && memcmp(hdc_name, "xtide", 5) && memcmp(hdc_name, "ide", 3)) - continue; - - if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !scsi_int && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) - continue; - if (cdrom[i].bus_type != 0) - sb_parts++; - } - for (i = 0; i < ZIP_NUM; i++) { - /* Could be Internal or External IDE.. */ - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && !ide_int && memcmp(hdc_name, "xtide", 5) && memcmp(hdc_name, "ide", 3)) - continue; - - if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !scsi_int && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) - continue; - if (zip_drives[i].bus_type != 0) - sb_parts++; - } - for (i = 0; i < MO_NUM; i++) { - /* Could be Internal or External IDE.. */ - if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && !ide_int && memcmp(hdc_name, "xtide", 5) && memcmp(hdc_name, "ide", 3)) - continue; - - if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !scsi_int && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) - continue; - if (mo_drives[i].bus_type != 0) - sb_parts++; - } - if (c_mfm && (mfm_int || !memcmp(hdc_name, "st506", 5))) { - /* MFM drives, and MFM or Internal controller. */ - sb_parts++; - } - if (c_esdi && (esdi_int || !memcmp(hdc_name, "esdi", 4))) { - /* ESDI drives, and ESDI or Internal controller. */ - sb_parts++; - } - if (c_xta && (xta_int || !memcmp(hdc_name, "xta", 3))) - sb_parts++; - if (c_ide && (ide_int || !memcmp(hdc_name, "xtide", 5) || !memcmp(hdc_name, "ide", 3))) - sb_parts++; - if (c_scsi && (scsi_int || (scsi_card_current[0] != 0) || (scsi_card_current[1] != 0) || (scsi_card_current[2] != 0) || (scsi_card_current[3] != 0))) - sb_parts++; - if (do_net) - sb_parts++; - sb_parts += 2; - - iStatusWidths = (int *) malloc(sb_parts * sizeof(int)); - memset(iStatusWidths, 0, sb_parts * sizeof(int)); - sb_part_meanings = (int *) malloc(sb_parts * sizeof(int)); - memset(sb_part_meanings, 0, sb_parts * sizeof(int)); - sb_part_icons = (uint8_t *) malloc(sb_parts * sizeof(uint8_t)); - memset(sb_part_icons, 0, sb_parts * sizeof(uint8_t)); - sbTips = (WCHAR **) malloc(sb_parts * sizeof(WCHAR *)); - memset(sbTips, 0, sb_parts * sizeof(WCHAR *)); - - sb_parts = 0; - if (cassette_enable) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_CASSETTE; - sb_map[SB_CASSETTE] = sb_parts; - sb_parts++; - } - for (i = 0; i < 2; i++) { - if (cart_int) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_CARTRIDGE | i; - sb_map[SB_CARTRIDGE | i] = sb_parts; - sb_parts++; - } - } - for (i = 0; i < FDD_NUM; i++) { - if (fdd_get_type(i) != 0) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_FLOPPY | i; - sb_map[SB_FLOPPY | i] = sb_parts; - sb_parts++; - } - } - for (i = 0; i < CDROM_NUM; i++) { - /* Could be Internal or External IDE.. */ - if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && !ide_int && memcmp(hdc_name, "xtide", 5) && memcmp(hdc_name, "ide", 3)) - continue; - if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !scsi_int && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) - continue; - if (cdrom[i].bus_type != 0) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_CDROM | i; - sb_map[SB_CDROM | i] = sb_parts; - sb_parts++; - } - } - for (i = 0; i < ZIP_NUM; i++) { - /* Could be Internal or External IDE.. */ - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && !ide_int && memcmp(hdc_name, "xtide", 5) && memcmp(hdc_name, "ide", 3)) - continue; - if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !scsi_int && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) - continue; - if (zip_drives[i].bus_type != 0) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_ZIP | i; - sb_map[SB_ZIP | i] = sb_parts; - sb_parts++; - } - } - for (i = 0; i < MO_NUM; i++) { - /* Could be Internal or External IDE.. */ - if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && !ide_int && memcmp(hdc_name, "xtide", 5) && memcmp(hdc_name, "ide", 3)) - continue; - if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !scsi_int && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) - continue; - if (mo_drives[i].bus_type != 0) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_MO | i; - sb_map[SB_MO | i] = sb_parts; - sb_parts++; - } - } - if (c_mfm && (mfm_int || !memcmp(hdc_name, "st506", 5))) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_MFM; - sb_map[SB_HDD | HDD_BUS_MFM] = sb_parts; - sb_parts++; - } - if (c_esdi && (esdi_int || !memcmp(hdc_name, "esdi", 4))) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_ESDI; - sb_map[SB_HDD | HDD_BUS_ESDI] = sb_parts; - sb_parts++; - } - if (c_xta && (xta_int || !memcmp(hdc_name, "xta", 3))) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_XTA; - sb_map[SB_HDD | HDD_BUS_XTA] = sb_parts; - sb_parts++; - } - if (c_ide && (ide_int || !memcmp(hdc_name, "xtide", 5) || !memcmp(hdc_name, "ide", 3))) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_IDE; - sb_map[SB_HDD | HDD_BUS_IDE] = sb_parts; - sb_parts++; - } - if (c_scsi && (scsi_int || (scsi_card_current[0] != 0) || (scsi_card_current[1] != 0) || (scsi_card_current[2] != 0) || (scsi_card_current[3] != 0))) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_SCSI; - sb_map[SB_HDD | HDD_BUS_SCSI] = sb_parts; - sb_parts++; - } - if (do_net) { - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_NETWORK; - sb_map[SB_NETWORK] = sb_parts; - sb_parts++; - } - - edge += icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = SB_SOUND; - sb_map[SB_SOUND] = sb_parts; - sb_parts++; - - if (sb_parts) - iStatusWidths[sb_parts] = -1; - sb_part_meanings[sb_parts] = SB_TEXT; - sb_map[SB_TEXT] = sb_parts; - sb_parts++; - - SendMessage(hwndSBAR, SB_SETPARTS, (WPARAM) sb_parts, (LPARAM) iStatusWidths); - - for (i = 0; i < sb_parts; i++) { - switch (sb_part_meanings[i] & 0xf0) { - case SB_CASSETTE: /* Cassette */ - sb_part_icons[i] = (strlen(cassette_fname) == 0) ? 128 : 0; - sb_part_icons[i] |= 64; - StatusBarCreateCassetteTip(i); - break; - - case SB_CARTRIDGE: /* Cartridge */ - sb_part_icons[i] = (strlen(cart_fns[sb_part_meanings[i] & 0xf]) == 0) ? 128 : 0; - sb_part_icons[i] |= 104; - StatusBarCreateCartridgeTip(i); - break; - - case SB_FLOPPY: /* Floppy */ - sb_part_icons[i] = (strlen(floppyfns[sb_part_meanings[i] & 0xf]) == 0) ? 128 : 0; - sb_part_icons[i] |= fdd_type_to_icon(fdd_get_type(sb_part_meanings[i] & 0xf)); - StatusBarCreateFloppyTip(i); - break; - - case SB_CDROM: /* CD-ROM */ - id = sb_part_meanings[i] & 0xf; - if (cdrom[id].host_drive == 200) - sb_part_icons[i] = (strlen(cdrom[id].image_path) == 0) ? 128 : 0; - else - sb_part_icons[i] = 128; - sb_part_icons[i] |= 32; - StatusBarCreateCdromTip(i); - break; - - case SB_ZIP: /* Iomega ZIP */ - sb_part_icons[i] = (strlen(zip_drives[sb_part_meanings[i] & 0xf].image_path) == 0) ? 128 : 0; - sb_part_icons[i] |= 48; - StatusBarCreateZIPTip(i); - break; - - case SB_MO: /* Magneto-Optical disk */ - sb_part_icons[i] = (strlen(mo_drives[sb_part_meanings[i] & 0xf].image_path) == 0) ? 128 : 0; - sb_part_icons[i] |= 56; - StatusBarCreateMOTip(i); - break; - - case SB_HDD: /* Hard disk */ - sb_part_icons[i] = 80; - StatusBarCreateDiskTip(i); - break; - - case SB_NETWORK: /* Network */ - sb_part_icons[i] = 96; - StatusBarCreateNetworkTip(i); - break; - - case SB_SOUND: /* Sound */ - sb_part_icons[i] = 243; - StatusBarCreateSoundTip(i); - break; - - case SB_TEXT: /* Status text */ - SendMessage(hwndSBAR, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) L""); - sb_part_icons[i] = 255; - break; - } - - if (sb_part_icons[i] != 255) { - SendMessage(hwndSBAR, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) L""); - SendMessage(hwndSBAR, SB_SETICON, i, (LPARAM) hIcon[sb_part_icons[i]]); - SendMessage(hwndSBAR, SB_SETTIPTEXT, i, (LPARAM) sbTips[i]); - } else - SendMessage(hwndSBAR, SB_SETICON, i, (LPARAM) NULL); - } - - sb_ready = 1; - if (reset_occurred & 2) - reset_occurred |= 1; -} - -static VOID APIENTRY -StatusBarPopupMenu(HWND hwnd, POINT pt, int id) -{ - HMENU menu; - - if (id >= (sb_parts - 1)) - return; - - pt.x = id * icon_width; /* Justify to the left. */ - pt.y = 0; /* Justify to the top. */ - ClientToScreen(hwnd, &pt); - - switch (sb_part_meanings[id] & 0xF0) { - case SB_CASSETTE: - menu = media_menu_get_cassette(); - break; - case SB_CARTRIDGE: - menu = media_menu_get_cartridge(sb_part_meanings[id] & 0x0F); - break; - case SB_FLOPPY: - menu = media_menu_get_floppy(sb_part_meanings[id] & 0x0F); - break; - case SB_CDROM: - menu = media_menu_get_cdrom(sb_part_meanings[id] & 0x0F); - break; - case SB_ZIP: - menu = media_menu_get_zip(sb_part_meanings[id] & 0x0F); - break; - case SB_MO: - menu = media_menu_get_mo(sb_part_meanings[id] & 0x0F); - break; - default: - return; - } - - TrackPopupMenu(menu, - TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_LEFTBUTTON, - pt.x, pt.y, 0, hwndSBAR, NULL); -} - -/* API: Load status bar icons */ -void -StatusBarLoadIcon(UNUSED(HINSTANCE hInst)) -{ - win_load_icon_set(); -} - -/* Handle messages for the Status Bar window. */ -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - RECT rc; - POINT pt; - int item_id = 0; - int i; - HINSTANCE hInst; - - switch (message) { - case WM_COMMAND: - media_menu_proc(hwnd, message, wParam, lParam); - return 0; - - case WM_LBUTTONDOWN: - case WM_RBUTTONDOWN: - GetClientRect(hwnd, &rc); - pt.x = GET_X_LPARAM(lParam); - pt.y = GET_Y_LPARAM(lParam); - if (PtInRect(&rc, pt)) - StatusBarPopupMenu(hwnd, pt, (pt.x / icon_width)); - break; - - case WM_LBUTTONDBLCLK: - GetClientRect(hwnd, &rc); - pt.x = GET_X_LPARAM(lParam); - pt.y = GET_Y_LPARAM(lParam); - item_id = (pt.x / icon_width); - if (PtInRect(&rc, pt) && (item_id < sb_parts)) { - if (sb_part_meanings[item_id] == SB_SOUND) - SoundGainDialogCreate(hwndMain); - } - break; - - case WM_DPICHANGED_AFTERPARENT: - /* DPI changed, reload icons */ - hInst = (HINSTANCE) GetWindowLongPtr(hwnd, GWLP_HINSTANCE); - dpi = win_get_dpi(hwnd); - icon_width = MulDiv(SB_ICON_WIDTH, dpi, 96); - StatusBarLoadIcon(hInst); - - for (i = 0; i < sb_parts; i++) { - if (sb_part_icons[i] != 255) { - SendMessage(hwndSBAR, SB_SETICON, i, (LPARAM) hIcon[sb_part_icons[i]]); - } - - iStatusWidths[i] = (i + 1) * icon_width; - } - iStatusWidths[i - 1] = -1; - SendMessage(hwndSBAR, SB_SETPARTS, (WPARAM) sb_parts, (LPARAM) iStatusWidths); - break; - - default: - return (CallWindowProc((WNDPROC) OriginalProcedure, - hwnd, message, wParam, lParam)); - } - - return 0; -} - -/* API: Create and set up the Status Bar window. */ -void -StatusBarCreate(HWND hwndParent, uintptr_t idStatus, HINSTANCE hInst) -{ - RECT rectDialog; - int dw; - int dh; - - /* Get current DPI and calculate icon sizes */ - dpi = win_get_dpi(hwndParent); - icon_width = MulDiv(SB_ICON_WIDTH, dpi, 96); - - /* Load our icons into the cache for faster access. */ - StatusBarLoadIcon(hInst); - - GetWindowRect(hwndParent, &rectDialog); - dw = rectDialog.right - rectDialog.left; - dh = rectDialog.bottom - rectDialog.top; - - /* Load the Common Controls DLL if needed. */ - InitCommonControls(); - - /* Create the window, and make sure it's using the STATUS class. */ - hwndSBAR = CreateWindowEx(0, - STATUSCLASSNAME, - (LPCTSTR) NULL, - SBARS_SIZEGRIP | WS_CHILD | WS_VISIBLE | SBT_TOOLTIPS, - 0, dh - 17, dw, 17, - hwndParent, - (HMENU) idStatus, hInst, NULL); - - /* Replace the original procedure with ours. */ - OriginalProcedure = GetWindowLongPtr(hwndSBAR, GWLP_WNDPROC); - SetWindowLongPtr(hwndSBAR, GWLP_WNDPROC, (LONG_PTR) &StatusBarProcedure); - - SendMessage(hwndSBAR, SB_SETMINHEIGHT, (WPARAM) 17, (LPARAM) 0); - - /* Align the window with the parent (main) window. */ - GetWindowRect(hwndSBAR, &rectDialog); - SetWindowPos(hwndSBAR, - HWND_TOPMOST, - rectDialog.left, rectDialog.top, - rectDialog.right - rectDialog.left, - rectDialog.bottom - rectDialog.top, - SWP_SHOWWINDOW); - - /* Initialize the status bar. This is clumsy. */ - sb_parts = 1; - iStatusWidths = (int *) malloc(sb_parts * sizeof(int)); - memset(iStatusWidths, 0, sb_parts * sizeof(int)); - sb_part_meanings = (int *) malloc(sb_parts * sizeof(int)); - memset(sb_part_meanings, 0, sb_parts * sizeof(int)); - sb_part_icons = (uint8_t *) malloc(sb_parts * sizeof(uint8_t)); - memset(sb_part_icons, 0, sb_parts * sizeof(uint8_t)); - sbTips = (WCHAR **) malloc(sb_parts * sizeof(WCHAR *)); - memset(sbTips, 0, sb_parts * sizeof(WCHAR *)); - sb_parts = 0; - iStatusWidths[sb_parts] = -1; - sb_part_meanings[sb_parts] = SB_TEXT; - sb_part_icons[sb_parts] = 255; - sb_parts++; - SendMessage(hwndSBAR, SB_SETPARTS, (WPARAM) sb_parts, (LPARAM) iStatusWidths); - SendMessage(hwndSBAR, SB_SETTEXT, 0 | SBT_NOBORDERS, - (LPARAM) plat_get_string(IDS_2118)); - - sb_ready = 1; -} - -void -ui_sb_update_text(void) -{ - uint8_t part = 0xff; - - if (!sb_ready || (sb_parts == 0) || (sb_part_meanings == NULL)) - return; - - part = sb_map[SB_TEXT]; - - if (part != 0xff) - SendMessage(hwndSBAR, SB_SETTEXT, part | SBT_NOBORDERS, (LPARAM) ((sb_text[0] != L'\0') ? sb_text : sb_bugtext)); -} - -/* API */ -void -ui_sb_set_text_w(wchar_t *wstr) -{ - if (wstr) - wcscpy(sb_text, wstr); - else - memset(sb_text, 0x00, sizeof(sb_text)); - ui_sb_update_text(); -} - -/* API */ -void -ui_sb_set_text(char *str) -{ - if (str) - mbstowcs(sb_text, str, strlen(str) + 1); - else - memset(sb_text, 0x00, sizeof(sb_text)); - ui_sb_update_text(); -} - -/* API */ -void -ui_sb_bugui(char *str) -{ - if (str) - mbstowcs(sb_bugtext, str, strlen(str) + 1); - else - memset(sb_bugtext, 0x00, sizeof(sb_bugtext)); - ui_sb_update_text(); -} - -/* API */ -void -ui_sb_mt32lcd(UNUSED(char *str)) -{ - // -} diff --git a/src/win/win_thread.c b/src/win/win_thread.c deleted file mode 100644 index e874c4941..000000000 --- a/src/win/win_thread.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implement threads and mutexes for the Win32 platform. - * - * - * - * Authors: Sarah Walker, - * Fred N. van Kempen, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2017-2018 Fred N. van Kempen. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#include -#undef BITMAP -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/plat.h> -#include <86box/thread.h> - -typedef struct { - HANDLE handle; -} win_event_t; - -thread_t * -thread_create_named(void (*func)(void *param), void *param, const char *name) -{ - uintptr_t bt = _beginthread(func, 0, param); - plat_set_thread_name((void *) bt, name); - return ((thread_t *) bt); -} - -int -thread_test_mutex(thread_t *arg) -{ - if (arg == NULL) - return 0; - - return (WaitForSingleObject(arg, 0) == WAIT_OBJECT_0) ? 1 : 0; -} - -int -thread_wait(thread_t *arg) -{ - if (arg == NULL) - return 0; - - if (WaitForSingleObject(arg, INFINITE)) - return 1; - - return 0; -} - -event_t * -thread_create_event(void) -{ - win_event_t *ev = malloc(sizeof(win_event_t)); - - ev->handle = CreateEvent(NULL, FALSE, FALSE, NULL); - - return ((event_t *) ev); -} - -void -thread_set_event(event_t *arg) -{ - win_event_t *ev = (win_event_t *) arg; - - if (arg == NULL) - return; - - SetEvent(ev->handle); -} - -void -thread_reset_event(event_t *arg) -{ - win_event_t *ev = (win_event_t *) arg; - - if (arg == NULL) - return; - - ResetEvent(ev->handle); -} - -int -thread_wait_event(event_t *arg, int timeout) -{ - win_event_t *ev = (win_event_t *) arg; - - if (arg == NULL) - return 0; - - if (ev->handle == NULL) - return 0; - - if (timeout == -1) - timeout = INFINITE; - - if (WaitForSingleObject(ev->handle, timeout)) - return 1; - - return 0; -} - -void -thread_destroy_event(event_t *arg) -{ - win_event_t *ev = (win_event_t *) arg; - - if (arg == NULL) - return; - - CloseHandle(ev->handle); - - free(ev); -} - -mutex_t * -thread_create_mutex(void) -{ - mutex_t *mutex = malloc(sizeof(CRITICAL_SECTION)); - - InitializeCriticalSection(mutex); - - return mutex; -} - -int -thread_wait_mutex(mutex_t *mutex) -{ - if (mutex == NULL) - return 0; - - LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION) mutex; - - EnterCriticalSection(critsec); - - return 1; -} - -int -thread_release_mutex(mutex_t *mutex) -{ - if (mutex == NULL) - return 0; - - LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION) mutex; - - LeaveCriticalSection(critsec); - - return 1; -} - -void -thread_close_mutex(mutex_t *mutex) -{ - if (mutex == NULL) - return; - - LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION) mutex; - - DeleteCriticalSection(critsec); - - free(critsec); -} diff --git a/src/win/win_toolbar.c b/src/win/win_toolbar.c deleted file mode 100644 index 5c8621eea..000000000 --- a/src/win/win_toolbar.c +++ /dev/null @@ -1,208 +0,0 @@ -#define UNICODE -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/plat.h> -#include <86box/resource.h> -#include <86box/ui.h> -#include <86box/video.h> -#include <86box/win.h> - -HWND hwndRebar = NULL; -static HWND hwndToolbar = NULL; -static HIMAGELIST hImageList = NULL; -static wchar_t wTitle[512] = { 0 }; -static WNDPROC pOriginalProcedure = NULL; - -enum image_index { - RUN, - PAUSE, - CTRL_ALT_DEL, - CTRL_ALT_ESC, - HARD_RESET, - ACPI_SHUTDOWN, - SETTINGS -}; - -void -ToolBarLoadIcons(void) -{ - if (!hwndToolbar) - return; - - if (hImageList) - ImageList_Destroy(hImageList); - - hImageList = ImageList_Create(win_get_system_metrics(SM_CXSMICON, dpi), - win_get_system_metrics(SM_CYSMICON, dpi), - ILC_MASK | ILC_COLOR32, 1, 1); - - // The icons must be loaded in the same order as the `image_index` - // enumeration above. - - ImageList_AddIcon(hImageList, hIcon[200]); // Run - ImageList_AddIcon(hImageList, hIcon[201]); // Pause - ImageList_AddIcon(hImageList, hIcon[202]); // Ctrl+Alt+Delete - ImageList_AddIcon(hImageList, hIcon[203]); // Ctrl+Alt+Esc - ImageList_AddIcon(hImageList, hIcon[204]); // Hard reset - ImageList_AddIcon(hImageList, hIcon[205]); // ACPI shutdown - ImageList_AddIcon(hImageList, hIcon[206]); // Settings - - SendMessage(hwndToolbar, TB_SETIMAGELIST, 0, (LPARAM) hImageList); -} - -int -ToolBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) { - case WM_NOTIFY: - switch (((LPNMHDR) lParam)->code) { - case TTN_GETDISPINFO: - { - LPTOOLTIPTEXT lpttt = (LPTOOLTIPTEXT) lParam; - - // Set the instance of the module that contains the resource. - lpttt->hinst = hinstance; - - uintptr_t idButton = lpttt->hdr.idFrom; - - switch (idButton) { - case IDM_ACTION_PAUSE: - if (dopause) - lpttt->lpszText = MAKEINTRESOURCE(IDS_2155); - else - lpttt->lpszText = MAKEINTRESOURCE(IDS_2156); - break; - - case IDM_ACTION_RESET_CAD: - lpttt->lpszText = MAKEINTRESOURCE(IDS_2157); - break; - - case IDM_ACTION_CTRL_ALT_ESC: - lpttt->lpszText = MAKEINTRESOURCE(IDS_2158); - break; - - case IDM_ACTION_HRESET: - lpttt->lpszText = MAKEINTRESOURCE(IDS_2159); - break; - - case IDM_CONFIG: - lpttt->lpszText = MAKEINTRESOURCE(IDS_2161); - break; - } - - return TRUE; - } - } - } - - return (CallWindowProc(pOriginalProcedure, hwnd, message, wParam, lParam)); -} - -void -ToolBarUpdatePause(int pause) -{ - TBBUTTONINFO tbbi; - - tbbi.cbSize = sizeof(tbbi); - tbbi.dwMask = TBIF_IMAGE; - tbbi.iImage = pause ? RUN : PAUSE; - - SendMessage(hwndToolbar, TB_SETBUTTONINFO, IDM_ACTION_PAUSE, (LPARAM) &tbbi); -} - -static TBBUTTON buttons[] = { - {PAUSE, IDM_ACTION_PAUSE, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, 0}, - { HARD_RESET, IDM_ACTION_HRESET, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, 0}, - { ACPI_SHUTDOWN, 0, TBSTATE_HIDDEN, BTNS_BUTTON, { 0 }, 0, 0}, - { 0, 0, TBSTATE_INDETERMINATE, BTNS_SEP, { 0 }, 0, 0}, - { CTRL_ALT_DEL, IDM_ACTION_RESET_CAD, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, 0}, - { CTRL_ALT_ESC, IDM_ACTION_CTRL_ALT_ESC, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, 0}, - { 0, 0, TBSTATE_INDETERMINATE, BTNS_SEP, { 0 }, 0, 0}, - { SETTINGS, IDM_CONFIG, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, 0} -}; - -void -ToolBarCreate(HWND hwndParent, HINSTANCE hInst) -{ - REBARINFO rbi = { 0 }; - REBARBANDINFO rbbi = { 0 }; - int btnSize; - - // Create the toolbar. - hwndToolbar = CreateWindowEx(WS_EX_PALETTEWINDOW, TOOLBARCLASSNAME, NULL, - WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT | CCS_TOP | BTNS_AUTOSIZE | CCS_NOPARENTALIGN | CCS_NORESIZE | CCS_NODIVIDER, - 0, 0, 0, 0, - hwndParent, NULL, hInst, NULL); - - ToolBarLoadIcons(); - - // Add buttons. - SendMessage(hwndToolbar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0); - SendMessage(hwndToolbar, TB_ADDBUTTONS, sizeof(buttons) / sizeof(TBBUTTON), (LPARAM) &buttons); - - // Autosize the toolbar and determine its size. - btnSize = LOWORD(SendMessage(hwndToolbar, TB_GETBUTTONSIZE, 0, 0)); - - // Replace the original procedure with ours. - pOriginalProcedure = (WNDPROC) GetWindowLongPtr(hwndToolbar, GWLP_WNDPROC); - SetWindowLongPtr(hwndToolbar, GWLP_WNDPROC, (LONG_PTR) &ToolBarProcedure); - - // Make sure the Pause button is in the correct state. - ToolBarUpdatePause(dopause); - - // Create the containing Rebar. - hwndRebar = CreateWindowEx(0, REBARCLASSNAME, NULL, - WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | RBS_VARHEIGHT | CCS_NODIVIDER | CCS_NOPARENTALIGN, - 0, 0, scrnsz_x, 0, - hwndParent, NULL, hInst, NULL); - - // Create and send the REBARINFO structure. - rbi.cbSize = sizeof(rbi); - SendMessage(hwndRebar, RB_SETBARINFO, 0, (LPARAM) &rbi); - - // Add the toolbar to the rebar. - rbbi.cbSize = sizeof(rbbi); - rbbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_STYLE; - rbbi.hwndChild = hwndToolbar; - rbbi.cxMinChild = 0; - rbbi.cyMinChild = btnSize; - rbbi.fStyle = RBBS_NOGRIPPER; - SendMessage(hwndRebar, RB_INSERTBAND, -1, (LPARAM) &rbbi); - - // Add a label for machine information. - rbbi.fMask = RBBIM_TEXT | RBBIM_STYLE; - rbbi.lpText = TEXT("Test"); - rbbi.fStyle = RBBS_NOGRIPPER; - SendMessage(hwndRebar, RB_INSERTBAND, -1, (LPARAM) &rbbi); - - SendMessage(hwndRebar, RB_MAXIMIZEBAND, 0, 0); - ShowWindow(hwndRebar, TRUE); - - return; -} - -wchar_t * -ui_window_title(wchar_t *s) -{ - REBARBANDINFO rbbi = { 0 }; - if (!video_fullscreen) { - if (s != NULL) { - wcsncpy(wTitle, s, sizeof_w(wTitle) - 1); - } else - s = wTitle; - - rbbi.cbSize = sizeof(rbbi); - rbbi.fMask = RBBIM_TEXT; - rbbi.lpText = s; - SendMessage(hwndRebar, RB_SETBANDINFO, 1, (LPARAM) &rbbi); - } else { - if (s == NULL) - s = wTitle; - } - - return s; -} diff --git a/src/win/win_ui.c b/src/win/win_ui.c deleted file mode 100644 index ec4a785ab..000000000 --- a/src/win/win_ui.c +++ /dev/null @@ -1,1662 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * user Interface module for WinAPI on Windows. - * - * - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * Jasmine Iwanek, - * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. - * Copyright 2019-2020 GH Cao. - * Copyright 2021-2023 Jasmine Iwanek. - */ -#include -#define UNICODE -#include -#include -#include -#include -#include -#include -#include -#include -#include <86box/plat.h> -#include <86box/86box.h> -#include <86box/config.h> -#include "../cpu/cpu.h" -#include <86box/device.h> -#include <86box/keyboard.h> -#include <86box/mouse.h> -#include <86box/timer.h> -#include <86box/nvr.h> -#include <86box/video.h> -#include <86box/vid_ega.h> // for update_overscan -#include <86box/plat_dynld.h> -#include <86box/ui.h> -#include <86box/win.h> -#include <86box/version.h> -#ifdef DISCORD -# include <86box/discord.h> -#endif - -#ifdef MTR_ENABLED -# include -#endif - -#define TIMER_1SEC 1 /* ID of the one-second timer */ - -/* Platform Public data, specific. */ -HWND hwndMain = NULL; /* application main window */ -HWND hwndRender = NULL; /* machine render window */ -HWND hwndRender2 = NULL; /* machine second screen render window */ -HMENU menuMain; /* application main menu */ -RECT oldclip; /* mouse rect */ -int sbar_height = 23; /* statusbar height */ -int tbar_height = 23; /* toolbar height */ -int minimized = 0; -int infocus = 1; -int button_down = 0; -int rctrl_is_lalt = 0; -int user_resize = 0; -int fixed_size_x = 0; -int fixed_size_y = 0; -int kbd_req_capture = 0; -int hide_status_bar = 0; -int hide_tool_bar = 0; -int dpi = 96; - -extern char openfilestring[512]; -extern WCHAR wopenfilestring[512]; - -/* Local data. */ -static int manager_wm = 0; -static int save_window_pos = 0; -static int pause_state = 0; -static int padded_frame = 0; -static int vis = -1; - -/* Per Monitor DPI Aware v2 APIs, Windows 10 v1703+ */ -void *user32_handle = NULL; -static UINT(WINAPI *pGetDpiForWindow)(HWND); -static UINT(WINAPI *pGetSystemMetricsForDpi)(int i, UINT dpi); -static DPI_AWARENESS_CONTEXT(WINAPI *pGetWindowDpiAwarenessContext)(HWND); -static BOOL(WINAPI *pAreDpiAwarenessContextsEqual)(DPI_AWARENESS_CONTEXT A, DPI_AWARENESS_CONTEXT B); -static dllimp_t user32_imports[] = { - {"GetDpiForWindow", &pGetDpiForWindow }, - { "GetSystemMetricsForDpi", &pGetSystemMetricsForDpi }, - { "GetWindowDpiAwarenessContext", &pGetWindowDpiAwarenessContext}, - { "AreDpiAwarenessContextsEqual", &pAreDpiAwarenessContextsEqual}, - { NULL, NULL } -}; - -/* Taskbar application ID API, Windows 7+ */ -void *shell32_handle = NULL; -static HRESULT(WINAPI *pSetCurrentProcessExplicitAppUserModelID)(PCWSTR AppID); -static dllimp_t shell32_imports[] = { - {"SetCurrentProcessExplicitAppUserModelID", &pSetCurrentProcessExplicitAppUserModelID}, - { NULL, NULL } -}; - -int -win_get_dpi(HWND hwnd) -{ - if (user32_handle != NULL) { - return pGetDpiForWindow(hwnd); - } else { - HDC dc = GetDC(hwnd); - UINT dpi = GetDeviceCaps(dc, LOGPIXELSX); - ReleaseDC(hwnd, dc); - return dpi; - } -} - -int -win_get_system_metrics(int index, int dpi) -{ - if (user32_handle != NULL) { - /* Only call GetSystemMetricsForDpi when we are using PMv2 */ - DPI_AWARENESS_CONTEXT c = pGetWindowDpiAwarenessContext(hwndMain); - if (pAreDpiAwarenessContextsEqual(c, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)) - return pGetSystemMetricsForDpi(index, dpi); - } - - return GetSystemMetrics(index); -} - -void -ResizeWindowByClientArea(HWND hwnd, int width, int height) -{ - if ((vid_resize == 1) || padded_frame) { - int padding = win_get_system_metrics(SM_CXPADDEDBORDER, dpi); - width += (win_get_system_metrics(SM_CXFRAME, dpi) + padding) * 2; - height += (win_get_system_metrics(SM_CYFRAME, dpi) + padding) * 2; - } else { - width += win_get_system_metrics(SM_CXFIXEDFRAME, dpi) * 2; - height += win_get_system_metrics(SM_CYFIXEDFRAME, dpi) * 2; - } - - height += win_get_system_metrics(SM_CYCAPTION, dpi); - height += win_get_system_metrics(SM_CYBORDER, dpi) + win_get_system_metrics(SM_CYMENUSIZE, dpi); - - SetWindowPos(hwnd, NULL, 0, 0, width, height, SWP_NOMOVE); -} - -/* Set host cursor visible or not. */ -void -show_cursor(int val) -{ - if (val == vis) - return; - - if (val == 0) { - while (1) - if (ShowCursor(FALSE) < 0) - break; - } else - ShowCursor(TRUE); - - vis = val; -} - -static void -video_toggle_option(HMENU h, int *val, int id) -{ - startblit(); - *val ^= 1; - CheckMenuItem(h, id, *val ? MF_CHECKED : MF_UNCHECKED); - endblit(); - config_save(); - device_force_redraw(); -} - -/* Recursively finds and deletes target submenu */ -static int -delete_submenu(HMENU parent, HMENU target) -{ - for (int i = 0; i < GetMenuItemCount(parent); i++) { - MENUITEMINFO mii; - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_SUBMENU; - - if (GetMenuItemInfo(parent, i, TRUE, &mii) != 0) { - if (mii.hSubMenu == target) { - DeleteMenu(parent, i, MF_BYPOSITION); - return 1; - } else if (mii.hSubMenu != NULL) { - if (delete_submenu(mii.hSubMenu, target)) - return 1; - } - } - } - - return 0; -} - -static int menu_vidapi = -1; -static HMENU cur_menu = NULL; - -static void -show_render_options_menu(void) -{ - if (vid_api == menu_vidapi) - return; - - if (cur_menu != NULL) { - if (delete_submenu(menuMain, cur_menu)) - cur_menu = NULL; - } - - if (cur_menu == NULL) { - switch (IDM_VID_SDL_SW + vid_api) { - case IDM_VID_OPENGL_CORE: - cur_menu = LoadMenu(hinstance, VID_GL_SUBMENU); - InsertMenu(GetSubMenu(menuMain, 1), 6, MF_BYPOSITION | MF_STRING | MF_POPUP, (UINT_PTR) cur_menu, plat_get_string(IDS_2145)); - CheckMenuItem(menuMain, IDM_VID_GL_FPS_BLITTER, video_framerate == -1 ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GL_FPS_25, video_framerate == 25 ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GL_FPS_30, video_framerate == 30 ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GL_FPS_50, video_framerate == 50 ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GL_FPS_60, video_framerate == 60 ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GL_FPS_75, video_framerate == 75 ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GL_VSYNC, video_vsync ? MF_CHECKED : MF_UNCHECKED); - EnableMenuItem(menuMain, IDM_VID_GL_NOSHADER, strlen(video_shader) > 0 ? MF_ENABLED : MF_DISABLED); - break; - } - } - - menu_vidapi = vid_api; -} - -static void -video_set_filter_menu(HMENU menu) -{ - CheckMenuItem(menu, IDM_VID_FILTER_NEAREST, vid_api == 0 || video_filter_method == 0 ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menu, IDM_VID_FILTER_LINEAR, vid_api != 0 && video_filter_method == 1 ? MF_CHECKED : MF_UNCHECKED); - EnableMenuItem(menu, IDM_VID_FILTER_NEAREST, vid_api == 0 ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(menu, IDM_VID_FILTER_LINEAR, vid_api == 0 ? MF_GRAYED : MF_ENABLED); -} - -void -ResetAllMenus(void) -{ - CheckMenuItem(menuMain, IDM_ACTION_RCTRL_IS_LALT, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_ACTION_KBD_REQ_CAPTURE, MF_UNCHECKED); - - CheckMenuItem(menuMain, IDM_UPDATE_ICONS, MF_UNCHECKED); - - CheckMenuItem(menuMain, IDM_VID_HIDE_STATUS_BAR, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_HIDE_TOOLBAR, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_FORCE43, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_OVERSCAN, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_INVERT, MF_UNCHECKED); - - CheckMenuItem(menuMain, IDM_VID_MONITORS, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_RESIZE, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SDL_SW, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SDL_HW, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SDL_OPENGL, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_OPENGL_CORE, MF_UNCHECKED); - - menu_vidapi = -1; - cur_menu = NULL; - show_render_options_menu(); -#ifdef USE_VNC - CheckMenuItem(menuMain, IDM_VID_VNC, MF_UNCHECKED); -#endif - CheckMenuItem(menuMain, IDM_VID_FS_FULL, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_FS_43, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_FS_KEEPRATIO, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_FS_INT, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SPECIFY_DIM, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_REMEMBER, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_1X, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_2X, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_3X, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_4X, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_5X, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_6X, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_7X, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_8X, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_9X, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_10X, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_HIDPI, MF_UNCHECKED); - - CheckMenuItem(menuMain, IDM_VID_CGACON, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GRAYCT_601, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GRAYCT_709, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GRAYCT_AVE, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GRAY_RGB, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GRAY_MONO, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GRAY_AMBER, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GRAY_GREEN, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GRAY_WHITE, MF_UNCHECKED); - - CheckMenuItem(menuMain, IDM_ACTION_RCTRL_IS_LALT, rctrl_is_lalt ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_ACTION_KBD_REQ_CAPTURE, kbd_req_capture ? MF_CHECKED : MF_UNCHECKED); - - CheckMenuItem(menuMain, IDM_UPDATE_ICONS, update_icons ? MF_CHECKED : MF_UNCHECKED); - - CheckMenuItem(menuMain, IDM_VID_HIDE_STATUS_BAR, hide_status_bar ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_HIDE_TOOLBAR, hide_tool_bar ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_FORCE43, force_43 ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_OVERSCAN, enable_overscan ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_INVERT, invert_display ? MF_CHECKED : MF_UNCHECKED); - - if (show_second_monitors == 1) - CheckMenuItem(menuMain, IDM_VID_MONITORS, MF_CHECKED); - - if (vid_resize == 1) - CheckMenuItem(menuMain, IDM_VID_RESIZE, MF_CHECKED); - CheckMenuItem(menuMain, IDM_VID_SDL_SW + vid_api, MF_CHECKED); - CheckMenuItem(menuMain, IDM_VID_FS_FULL + video_fullscreen_scale, MF_CHECKED); - CheckMenuItem(menuMain, IDM_VID_REMEMBER, window_remember ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_1X + scale, MF_CHECKED); - CheckMenuItem(menuMain, IDM_VID_HIDPI, dpi_scale ? MF_CHECKED : MF_UNCHECKED); - - CheckMenuItem(menuMain, IDM_VID_CGACON, vid_cga_contrast ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_GRAYCT_601 + video_graytype, MF_CHECKED); - CheckMenuItem(menuMain, IDM_VID_GRAY_RGB + video_grayscale, MF_CHECKED); - - video_set_filter_menu(menuMain); - -#ifdef DISCORD - if (discord_loaded) - CheckMenuItem(menuMain, IDM_DISCORD, enable_discord ? MF_CHECKED : MF_UNCHECKED); - else - EnableMenuItem(menuMain, IDM_DISCORD, MF_DISABLED); -#endif - -#ifdef MTR_ENABLED - EnableMenuItem(menuMain, IDM_ACTION_END_TRACE, MF_DISABLED); -#endif - - if (vid_resize) { - if (vid_resize >= 2) { - CheckMenuItem(menuMain, IDM_VID_RESIZE, MF_UNCHECKED); - EnableMenuItem(menuMain, IDM_VID_RESIZE, MF_GRAYED); - } - - CheckMenuItem(menuMain, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); - CheckMenuItem(menuMain, IDM_VID_SCALE_2X, MF_CHECKED); - EnableMenuItem(menuMain, IDM_VID_SCALE_1X, MF_GRAYED); - EnableMenuItem(menuMain, IDM_VID_SCALE_2X, MF_GRAYED); - EnableMenuItem(menuMain, IDM_VID_SCALE_3X, MF_GRAYED); - EnableMenuItem(menuMain, IDM_VID_SCALE_4X, MF_GRAYED); - EnableMenuItem(menuMain, IDM_VID_SCALE_5X, MF_GRAYED); - EnableMenuItem(menuMain, IDM_VID_SCALE_6X, MF_GRAYED); - EnableMenuItem(menuMain, IDM_VID_SCALE_7X, MF_GRAYED); - EnableMenuItem(menuMain, IDM_VID_SCALE_8X, MF_GRAYED); - EnableMenuItem(menuMain, IDM_VID_SCALE_9X, MF_GRAYED); - EnableMenuItem(menuMain, IDM_VID_SCALE_10X, MF_GRAYED); - } -} - -void -win_notify_dlg_open(void) -{ - manager_wm = 1; - pause_state = dopause; - plat_pause(1); - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDDLGSTATUS, (WPARAM) 1, (LPARAM) hwndMain); -} - -void -win_notify_dlg_closed(void) -{ - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDDLGSTATUS, (WPARAM) 0, (LPARAM) hwndMain); - plat_pause(pause_state); - manager_wm = 0; -} - -void -plat_power_off(void) -{ - confirm_exit_cmdl = 0; - nvr_save(); - config_save(); - - /* Deduct a sufficiently large number of cycles that no instructions will - run before the main thread is terminated */ - cycles -= 99999999; - - KillTimer(hwndMain, TIMER_1SEC); - PostQuitMessage(0); - - /* Cleanly terminate all of the emulator's components so as - to avoid things like threads getting stuck. */ -#if 0 - do_stop(); -#endif - cpu_thread_run = 0; - -#if 0 - exit(-1); -#endif -} - -#ifdef MTR_ENABLED -static void -handle_trace(HMENU hmenu, int trace) -{ - EnableMenuItem(hmenu, IDM_ACTION_BEGIN_TRACE, trace ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_ACTION_END_TRACE, trace ? MF_ENABLED : MF_GRAYED); - if (trace) { - init_trace(); - } else { - shutdown_trace(); - } -} -#endif - -/* Catch WM_INPUT messages for 'current focus' window. */ -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -input_proc(UNUSED(HWND hwnd), UINT message, UNUSED(WPARAM wParam), LPARAM lParam) -{ - switch (message) { - case WM_INPUT: - if (infocus) { - UINT size = 0; - PRAWINPUT raw = NULL; - - /* Here we read the raw input data */ - GetRawInputData((HRAWINPUT) lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); - raw = (PRAWINPUT) malloc(size); - if (GetRawInputData((HRAWINPUT) lParam, RID_INPUT, raw, &size, sizeof(RAWINPUTHEADER)) == size) { - switch (raw->header.dwType) { - case RIM_TYPEKEYBOARD: - keyboard_handle(raw); - break; - case RIM_TYPEMOUSE: - win_mouse_handle(raw); - break; - case RIM_TYPEHID: - win_joystick_handle(raw); - break; - } - } - free(raw); - } - break; - case WM_SETFOCUS: - infocus = 1; - break; - - case WM_KILLFOCUS: - infocus = 0; - plat_mouse_capture(0); - break; - - case WM_LBUTTONDOWN: - button_down |= 1; - break; - - case WM_LBUTTONUP: - if ((button_down & 1) && !video_fullscreen) - plat_mouse_capture(1); - button_down &= ~1; - break; - - case WM_MBUTTONUP: - if (mouse_get_buttons() < 3) - plat_mouse_capture(0); - break; - - default: - return 1; -#if 0 - return(CallWindowProc((WNDPROC)input_orig_proc, - hwnd, message, wParam, lParam)); -#endif - } - - return 0; -} - -static LRESULT CALLBACK -MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - HMENU hmenu; - - int i; - RECT rect; - RECT *rect_p; - - WINDOWPOS *pos; - - int temp_x; - int temp_y; - - if (input_proc(hwnd, message, wParam, lParam) == 0) - return 0; - - switch (message) { - case WM_CREATE: - SetTimer(hwnd, TIMER_1SEC, 1000, NULL); - break; - - case WM_COMMAND: - hmenu = GetMenu(hwnd); - switch (LOWORD(wParam)) { - case IDM_ACTION_SCREENSHOT: - take_screenshot(); - break; - -#ifdef MTR_ENABLED - case IDM_ACTION_BEGIN_TRACE: - case IDM_ACTION_END_TRACE: - case IDM_ACTION_TRACE: - tracing_on = !tracing_on; - handle_trace(hmenu, tracing_on); - break; -#endif - - case IDM_ACTION_HRESET: - win_notify_dlg_open(); - if (confirm_reset) - i = ui_msgbox_ex(MBX_QUESTION_YN | MBX_DONTASK, (wchar_t *) IDS_2113, NULL, (wchar_t *) IDS_2138, (wchar_t *) IDS_2139, NULL); - else - i = 0; - if ((i % 10) == 0) { - pc_reset_hard(); - if (i == 10) { - confirm_reset = 0; - nvr_save(); - config_save(); - } - } - win_notify_dlg_closed(); - break; - - case IDM_ACTION_RESET_CAD: - pc_send_cad(); - break; - - case IDM_ACTION_EXIT: - win_notify_dlg_open(); - if (confirm_exit && confirm_exit_cmdl) - i = ui_msgbox_ex(MBX_QUESTION_YN | MBX_DONTASK, (wchar_t *) IDS_2114, NULL, (wchar_t *) IDS_2120, (wchar_t *) IDS_2137, NULL); - else - i = 0; - if ((i % 10) == 0) { - if (i == 10) { - confirm_exit = 0; - nvr_save(); - config_save(); - } - KillTimer(hwnd, TIMER_1SEC); - PostQuitMessage(0); - } - win_notify_dlg_closed(); - break; - - case IDM_ACTION_CTRL_ALT_ESC: - pc_send_cae(); - break; - - case IDM_ACTION_RCTRL_IS_LALT: - rctrl_is_lalt ^= 1; - CheckMenuItem(hmenu, IDM_ACTION_RCTRL_IS_LALT, rctrl_is_lalt ? MF_CHECKED : MF_UNCHECKED); - config_save(); - break; - - case IDM_ACTION_KBD_REQ_CAPTURE: - kbd_req_capture ^= 1; - CheckMenuItem(hmenu, IDM_ACTION_KBD_REQ_CAPTURE, kbd_req_capture ? MF_CHECKED : MF_UNCHECKED); - config_save(); - break; - - case IDM_ACTION_PAUSE: - plat_pause(dopause ^ 1); - CheckMenuItem(menuMain, IDM_ACTION_PAUSE, dopause ? MF_CHECKED : MF_UNCHECKED); - break; - - case IDM_CONFIG: - win_settings_open(hwnd); - break; - - case IDM_SND_GAIN: - SoundGainDialogCreate(hwnd); - break; - - case IDM_ABOUT: - AboutDialogCreate(hwnd); - break; - - case IDM_DOCS: - ShellExecute(hwnd, L"open", EMU_DOCS_URL_W, NULL, NULL, SW_SHOW); - break; - - case IDM_UPDATE_ICONS: - update_icons ^= 1; - CheckMenuItem(hmenu, IDM_UPDATE_ICONS, update_icons ? MF_CHECKED : MF_UNCHECKED); - config_save(); - break; - - case IDM_VID_HIDE_STATUS_BAR: - hide_status_bar ^= 1; - CheckMenuItem(hmenu, IDM_VID_HIDE_STATUS_BAR, hide_status_bar ? MF_CHECKED : MF_UNCHECKED); - ShowWindow(hwndSBAR, hide_status_bar ? SW_HIDE : SW_SHOW); - GetWindowRect(hwnd, &rect); - if (hide_status_bar) - MoveWindow(hwnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top - sbar_height, TRUE); - else - MoveWindow(hwnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top + sbar_height, TRUE); - config_save(); - break; - - case IDM_VID_HIDE_TOOLBAR: - hide_tool_bar ^= 1; - CheckMenuItem(hmenu, IDM_VID_HIDE_TOOLBAR, hide_tool_bar ? MF_CHECKED : MF_UNCHECKED); - ShowWindow(hwndRebar, hide_tool_bar ? SW_HIDE : SW_SHOW); - GetWindowRect(hwnd, &rect); - if (hide_tool_bar) { - MoveWindow(hwnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top - tbar_height, TRUE); - SetWindowPos(hwndRender, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); - } else { - MoveWindow(hwnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top + tbar_height, TRUE); - SetWindowPos(hwndRender, NULL, 0, tbar_height, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); - } - config_save(); - break; - - case IDM_VID_MONITORS: - show_second_monitors ^= 1; - CheckMenuItem(hmenu, IDM_VID_MONITORS, (show_second_monitors & 1) ? MF_CHECKED : MF_UNCHECKED); - break; - - case IDM_VID_RESIZE: - vid_resize ^= 1; - CheckMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize & 1) ? MF_CHECKED : MF_UNCHECKED); - - if (vid_resize == 1) - SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW) | WS_VISIBLE); - else - SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX & ~WS_MAXIMIZEBOX) | WS_VISIBLE); - - /* scale the screen base on DPI */ - if (dpi_scale) { - temp_x = MulDiv(unscaled_size_x, dpi, 96); - temp_y = MulDiv(unscaled_size_y, dpi, 96); - } else { - temp_x = unscaled_size_x; - temp_y = unscaled_size_y; - } - - ResizeWindowByClientArea(hwnd, temp_x, temp_y + (hide_status_bar ? 0 : sbar_height) + (hide_tool_bar ? 0 : tbar_height)); - - if (mouse_capture) { - ClipCursor(&rect); - } - - if (vid_resize) { - CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_VID_SCALE_2X, MF_CHECKED); - scale = 1; - } - EnableMenuItem(hmenu, IDM_VID_SCALE_1X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_2X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_3X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_4X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_5X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_6X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_7X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_8X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_9X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_10X, vid_resize ? MF_GRAYED : MF_ENABLED); - - scrnsz_x = unscaled_size_x; - scrnsz_y = unscaled_size_y; - atomic_store(&doresize_monitors[0], 1); - config_save(); - break; - - case IDM_VID_REMEMBER: - window_remember = !window_remember; - CheckMenuItem(hmenu, IDM_VID_REMEMBER, window_remember ? MF_CHECKED : MF_UNCHECKED); - GetWindowRect(hwnd, &rect); - if (window_remember || (vid_resize & 2)) { - window_x = rect.left; - window_y = rect.top; - if (!(vid_resize & 2)) { - window_w = rect.right - rect.left; - window_h = rect.bottom - rect.top; - } - } - config_save(); - break; - - case IDM_VID_SDL_SW: - case IDM_VID_SDL_HW: - case IDM_VID_SDL_OPENGL: - case IDM_VID_OPENGL_CORE: -#ifdef USE_VNC - case IDM_VID_VNC: -#endif - CheckMenuItem(hmenu, IDM_VID_SDL_SW + vid_api, MF_UNCHECKED); - plat_setvid(LOWORD(wParam) - IDM_VID_SDL_SW); - CheckMenuItem(hmenu, IDM_VID_SDL_SW + vid_api, MF_CHECKED); - video_set_filter_menu(hmenu); - config_save(); - show_render_options_menu(); - break; - - case IDM_VID_GL_FPS_BLITTER: - case IDM_VID_GL_FPS_25: - case IDM_VID_GL_FPS_30: - case IDM_VID_GL_FPS_50: - case IDM_VID_GL_FPS_60: - case IDM_VID_GL_FPS_75: - { - static const int fps[] = { -1, 25, 30, 50, 60, 75 }; - int idx = 0; - for (; fps[idx] != video_framerate; idx++) - ; - CheckMenuItem(hmenu, IDM_VID_GL_FPS_BLITTER + idx, MF_UNCHECKED); - video_framerate = fps[LOWORD(wParam) - IDM_VID_GL_FPS_BLITTER]; - CheckMenuItem(hmenu, LOWORD(wParam), MF_CHECKED); - plat_vid_reload_options(); - config_save(); - break; - } - case IDM_VID_GL_VSYNC: - video_vsync = !video_vsync; - CheckMenuItem(hmenu, IDM_VID_GL_VSYNC, video_vsync ? MF_CHECKED : MF_UNCHECKED); - plat_vid_reload_options(); - config_save(); - break; - case IDM_VID_GL_SHADER: - win_notify_dlg_open(); - if (file_dlg_st(hwnd, IDS_2144, video_shader, NULL, 0) == 0) { - strcpy_s(video_shader, sizeof(video_shader), openfilestring); - EnableMenuItem(menuMain, IDM_VID_GL_NOSHADER, strlen(video_shader) > 0 ? MF_ENABLED : MF_DISABLED); - } - win_notify_dlg_closed(); - plat_vid_reload_options(); - break; - case IDM_VID_GL_NOSHADER: - video_shader[0] = '\0'; - EnableMenuItem(menuMain, IDM_VID_GL_NOSHADER, MF_DISABLED); - plat_vid_reload_options(); - break; - - case IDM_VID_FULLSCREEN: - plat_setfullscreen(1); - config_save(); - break; - - case IDM_VID_FS_FULL: - case IDM_VID_FS_43: - case IDM_VID_FS_KEEPRATIO: - case IDM_VID_FS_INT: - CheckMenuItem(hmenu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_UNCHECKED); - video_fullscreen_scale = LOWORD(wParam) - IDM_VID_FS_FULL; - CheckMenuItem(hmenu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_CHECKED); - device_force_redraw(); - config_save(); - break; - - case IDM_VID_SCALE_1X: - case IDM_VID_SCALE_2X: - case IDM_VID_SCALE_3X: - case IDM_VID_SCALE_4X: - case IDM_VID_SCALE_5X: - case IDM_VID_SCALE_6X: - case IDM_VID_SCALE_7X: - case IDM_VID_SCALE_8X: - case IDM_VID_SCALE_9X: - case IDM_VID_SCALE_10X: - CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); - scale = LOWORD(wParam) - IDM_VID_SCALE_1X; - CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_CHECKED); - reset_screen_size(); - device_force_redraw(); - video_force_resize_set(1); - atomic_store(&doresize_monitors[0], 1); - config_save(); - break; - - case IDM_VID_FILTER_NEAREST: - case IDM_VID_FILTER_LINEAR: - video_filter_method = LOWORD(wParam) - IDM_VID_FILTER_NEAREST; - video_set_filter_menu(hmenu); - plat_vid_reload_options(); - config_save(); - break; - - case IDM_VID_HIDPI: - dpi_scale = !dpi_scale; - CheckMenuItem(hmenu, IDM_VID_HIDPI, dpi_scale ? MF_CHECKED : MF_UNCHECKED); - atomic_store(&doresize_monitors[0], 1); - config_save(); - break; - - case IDM_PREFERENCES: - PreferencesDlgCreate(hwnd); - break; - - case IDM_VID_SPECIFY_DIM: - SpecifyDimensionsDialogCreate(hwnd); - break; - - case IDM_VID_FORCE43: - video_toggle_option(hmenu, &force_43, IDM_VID_FORCE43); - video_force_resize_set(1); - break; - - case IDM_VID_INVERT: - video_toggle_option(hmenu, &invert_display, IDM_VID_INVERT); - video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy; - plat_vidapi_reload(); - break; - - case IDM_VID_OVERSCAN: - update_overscan = 1; - video_toggle_option(hmenu, &enable_overscan, IDM_VID_OVERSCAN); - video_force_resize_set(1); - break; - - case IDM_VID_CGACON: - vid_cga_contrast ^= 1; - CheckMenuItem(hmenu, IDM_VID_CGACON, vid_cga_contrast ? MF_CHECKED : MF_UNCHECKED); - cgapal_rebuild(); - config_save(); - break; - - case IDM_VID_GRAYCT_601: - case IDM_VID_GRAYCT_709: - case IDM_VID_GRAYCT_AVE: - CheckMenuItem(hmenu, IDM_VID_GRAYCT_601 + video_graytype, MF_UNCHECKED); - video_graytype = LOWORD(wParam) - IDM_VID_GRAYCT_601; - CheckMenuItem(hmenu, IDM_VID_GRAYCT_601 + video_graytype, MF_CHECKED); - device_force_redraw(); - config_save(); - break; - - case IDM_VID_GRAY_RGB: - case IDM_VID_GRAY_MONO: - case IDM_VID_GRAY_AMBER: - case IDM_VID_GRAY_GREEN: - case IDM_VID_GRAY_WHITE: - CheckMenuItem(hmenu, IDM_VID_GRAY_RGB + video_grayscale, MF_UNCHECKED); - video_grayscale = LOWORD(wParam) - IDM_VID_GRAY_RGB; - video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy; - plat_vidapi_reload(); - CheckMenuItem(hmenu, IDM_VID_GRAY_RGB + video_grayscale, MF_CHECKED); - device_force_redraw(); - config_save(); - break; - -#ifdef DISCORD - case IDM_DISCORD: - if (!discord_loaded) - break; - enable_discord ^= 1; - CheckMenuItem(hmenu, IDM_DISCORD, enable_discord ? MF_CHECKED : MF_UNCHECKED); - if (enable_discord) { - discord_init(); - discord_update_activity(dopause); - } else - discord_close(); - break; -#endif - - default: - media_menu_proc(hwnd, message, wParam, lParam); - break; - } - return 0; - - case WM_ENTERMENULOOP: - break; - - case WM_DPICHANGED: - dpi = HIWORD(wParam); - GetWindowRect(hwndSBAR, &rect); - sbar_height = rect.bottom - rect.top; - GetWindowRect(hwndRebar, &rect); - tbar_height = rect.bottom - rect.top; - rect_p = (RECT *) lParam; - if (vid_resize == 1) - MoveWindow(hwnd, rect_p->left, rect_p->top, rect_p->right - rect_p->left, rect_p->bottom - rect_p->top, TRUE); - else if (vid_resize >= 2) { - temp_x = fixed_size_x; - temp_y = fixed_size_y; - if (dpi_scale) { - temp_x = MulDiv(temp_x, dpi, 96); - temp_y = MulDiv(temp_y, dpi, 96); - } - - /* Main Window. */ - ResizeWindowByClientArea(hwndMain, temp_x, temp_y + (hide_status_bar ? 0 : sbar_height) + (hide_tool_bar ? 0 : tbar_height)); - } else if (!user_resize) - atomic_store(&doresize_monitors[0], 1); - break; - - case WM_WINDOWPOSCHANGED: - if (video_fullscreen & 1) - PostMessage(hwndMain, WM_LEAVEFULLSCREEN, 0, 0); - - pos = (WINDOWPOS *) lParam; - GetClientRect(hwndMain, &rect); - - if (IsIconic(hwndMain)) { - plat_vidapi_enable(0); - minimized = 1; - return 0; - } else if (minimized) { - minimized = 0; - video_force_resize_set(1); - } - - if (!(pos->flags & SWP_NOSIZE) && (window_remember || (vid_resize & 2))) { - window_x = pos->x; - window_y = pos->y; - if (!(vid_resize & 2)) { - window_w = pos->cx; - window_h = pos->cy; - } - save_window_pos = 1; - config_save(); - } - - if (!(pos->flags & SWP_NOSIZE) || !user_resize) { - plat_vidapi_enable(0); - - if (!hide_status_bar) - MoveWindow(hwndSBAR, 0, rect.bottom - sbar_height, sbar_height, rect.right, TRUE); - - if (!hide_tool_bar) - MoveWindow(hwndRebar, 0, 0, rect.right, tbar_height, TRUE); - - MoveWindow(hwndRender, 0, hide_tool_bar ? 0 : tbar_height, rect.right, rect.bottom - (hide_status_bar ? 0 : sbar_height) - (hide_tool_bar ? 0 : tbar_height), TRUE); - - GetClientRect(hwndRender, &rect); - if (dpi_scale) { - temp_x = MulDiv(rect.right, 96, dpi); - temp_y = MulDiv(rect.bottom, 96, dpi); - - if (temp_x != scrnsz_x || temp_y != scrnsz_y) { - scrnsz_x = temp_x; - scrnsz_y = temp_y; - atomic_store(&doresize_monitors[0], 1); - } - } else { - if (rect.right != scrnsz_x || rect.bottom != scrnsz_y) { - scrnsz_x = rect.right; - scrnsz_y = rect.bottom; - atomic_store(&doresize_monitors[0], 1); - } - } - - plat_vidsize(rect.right, rect.bottom); - - if (mouse_capture) { - GetWindowRect(hwndRender, &rect); - ClipCursor(&rect); - } - - plat_vidapi_enable(2); - } - - return 0; - - case WM_TIMER: - if (wParam == TIMER_1SEC) - pc_onesec(); - else if ((wParam >= 0x8000) && (wParam <= 0x80ff)) - ui_sb_timer_callback(wParam & 0xff); - break; - - case WM_LEAVEFULLSCREEN: - plat_setfullscreen(0); - config_save(); - break; - - case WM_KEYDOWN: - case WM_KEYUP: - case WM_SYSKEYDOWN: - case WM_SYSKEYUP: - return 0; - - case WM_CLOSE: - win_notify_dlg_open(); - if (confirm_exit && confirm_exit_cmdl) - i = ui_msgbox_ex(MBX_QUESTION_YN | MBX_DONTASK, (wchar_t *) IDS_2114, NULL, (wchar_t *) IDS_2120, (wchar_t *) IDS_2137, NULL); - else - i = 0; - if ((i % 10) == 0) { - if (i == 10) { - confirm_exit = 0; - nvr_save(); - config_save(); - } - KillTimer(hwnd, TIMER_1SEC); - PostQuitMessage(0); - } - win_notify_dlg_closed(); - break; - - case WM_DESTROY: - win_clear_icon_set(); - KillTimer(hwnd, TIMER_1SEC); - PostQuitMessage(0); - break; - - case WM_SHOWSETTINGS: - if (manager_wm) - break; - manager_wm = 1; - win_settings_open(hwnd); - manager_wm = 0; - break; - - case WM_PAUSE: - if (manager_wm) - break; - manager_wm = 1; - plat_pause(dopause ^ 1); - CheckMenuItem(menuMain, IDM_ACTION_PAUSE, dopause ? MF_CHECKED : MF_UNCHECKED); - manager_wm = 0; - break; - - case WM_HARDRESET: - if (manager_wm) - break; - win_notify_dlg_open(); - if (confirm_reset) - i = ui_msgbox_ex(MBX_QUESTION_YN | MBX_DONTASK, (wchar_t *) IDS_2113, NULL, (wchar_t *) IDS_2138, (wchar_t *) IDS_2139, NULL); - else - i = 0; - if ((i % 10) == 0) { - pc_reset_hard(); - if (i == 10) { - confirm_reset = 0; - nvr_save(); - config_save(); - } - } - win_notify_dlg_closed(); - break; - - case WM_SHUTDOWN: - if (manager_wm) - break; - if (LOWORD(wParam) == 1) { - confirm_exit = 0; - nvr_save(); - config_save(); - KillTimer(hwnd, TIMER_1SEC); - PostQuitMessage(0); - } else { - win_notify_dlg_open(); - if (confirm_exit && confirm_exit_cmdl) - i = ui_msgbox_ex(MBX_QUESTION_YN | MBX_DONTASK, (wchar_t *) IDS_2114, NULL, (wchar_t *) IDS_2120, (wchar_t *) IDS_2137, NULL); - else - i = 0; - if ((i % 10) == 0) { - if (i == 10) { - confirm_exit = 0; - nvr_save(); - config_save(); - } - KillTimer(hwnd, TIMER_1SEC); - PostQuitMessage(0); - } - win_notify_dlg_closed(); - } - break; - - case WM_CTRLALTDEL: - if (manager_wm) - break; - manager_wm = 1; - pc_send_cad(); - manager_wm = 0; - break; - - case WM_SYSCOMMAND: - /* - * Disable ALT key *ALWAYS*, - * I don't think there's any use for - * reaching the menu that way. - */ - if (wParam == SC_KEYMENU && HIWORD(lParam) <= 0) { - return 0; /*disable ALT key for menu*/ - } - - default: - return (DefWindowProc(hwnd, message, wParam, lParam)); - - case WM_SETFOCUS: - infocus = 1; - break; - - case WM_KILLFOCUS: - infocus = 0; - plat_mouse_capture(0); - break; - - case WM_ACTIVATE: - if ((wParam != WA_INACTIVE) && !(video_fullscreen & 2)) { - video_force_resize_set(1); - plat_vidapi_enable(0); - plat_vidapi_enable(1); - } - break; - - case WM_ACTIVATEAPP: - /* Leave full screen on switching application except - for OpenGL Core and VNC renderers. */ - if (video_fullscreen & 1 && wParam == FALSE && vid_api < 3) - PostMessage(hwndMain, WM_LEAVEFULLSCREEN, 0, 0); - break; - - case WM_ENTERSIZEMOVE: - user_resize = 1; - break; - - case WM_EXITSIZEMOVE: - user_resize = 0; - - /* If window is not resizable, then tell the main thread to - resize it, as sometimes, moves can mess up the window size. */ - if (!vid_resize) - atomic_store(&doresize_monitors[0], 1); - break; - } - - return 0; -} - -static LRESULT CALLBACK -SubWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) { - case WM_LBUTTONDOWN: - button_down |= 2; - break; - - case WM_LBUTTONUP: - if ((button_down & 2) && !video_fullscreen) - plat_mouse_capture(1); - button_down &= ~2; - break; - - case WM_MBUTTONUP: - if (mouse_get_buttons() < 3) - plat_mouse_capture(0); - break; - - default: - return (DefWindowProc(hwnd, message, wParam, lParam)); - } - - return 0; -} - -static LRESULT CALLBACK -SDLMainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - if (input_proc(hwnd, message, wParam, lParam) == 0) - return 0; - - return (DefWindowProc(hwnd, message, wParam, lParam)); -} - -static LRESULT CALLBACK -SDLSubWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - return (DefWindowProc(hwnd, message, wParam, lParam)); -} - -static HRESULT CALLBACK -TaskDialogProcedure(HWND hwnd, UINT message, UNUSED(WPARAM wParam), LPARAM lParam, UNUSED(LONG_PTR lpRefData)) -{ - switch (message) { - case TDN_HYPERLINK_CLICKED: - /* open linked URL */ - ShellExecute(hwnd, L"open", (LPCWSTR) lParam, NULL, NULL, SW_SHOW); - break; - } - - return S_OK; -} - -int -ui_init(int nCmdShow) -{ - WCHAR title[200]; - WNDCLASSEX wincl; /* buffer for main window's class */ - RAWINPUTDEVICE ridev; /* RawInput device */ - MSG messages = { 0 }; /* received-messages buffer */ - HWND hwnd = NULL; /* handle for our window */ - HACCEL haccel; /* handle to accelerator table */ - RECT rect; - int bRet; - TASKDIALOGCONFIG tdconfig = { 0 }; - TASKDIALOG_BUTTON tdbuttons[] = { - {IDCANCEL, MAKEINTRESOURCE(IDS_2120)} - }; - uint32_t helper_lang; - static int fs_on_signal = 0; - static int fs_off_signal = 0; - - /* Load DPI related Windows 10 APIs */ - user32_handle = dynld_module("user32.dll", user32_imports); - - /* Set the application ID for the taskbar. */ - shell32_handle = dynld_module("shell32.dll", shell32_imports); - if (shell32_handle) - pSetCurrentProcessExplicitAppUserModelID(L"86Box.86Box"); - - /* Set up TaskDialog configuration. */ - tdconfig.cbSize = sizeof(tdconfig); - tdconfig.dwFlags = TDF_ENABLE_HYPERLINKS; - tdconfig.dwCommonButtons = 0; - tdconfig.pszWindowTitle = MAKEINTRESOURCE(IDS_STRINGS); - tdconfig.pszMainIcon = TD_ERROR_ICON; - tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2050); - tdconfig.cButtons = ARRAYSIZE(tdbuttons); - tdconfig.pButtons = tdbuttons; - tdconfig.pfCallback = TaskDialogProcedure; - - /* Load the desired iconset */ - win_load_icon_set(); - - /* Start settings-only mode if requested. */ - if (settings_only) { - if (!pc_init_modules()) { - /* Dang, no ROMs found at all! */ - tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2121); - tdconfig.pszContent = MAKEINTRESOURCE(IDS_2056); - TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); - return 6; - } - - /* Load the desired language */ - helper_lang = lang_id; - lang_id = 0; - set_language(helper_lang); - - win_settings_open(NULL); - return 0; - } - -#ifdef DISCORD - if (!discord_load()) { - enable_discord = 0; - } else if (enable_discord) { - /* Initialize the Discord API */ - discord_init(); - - /* Update Discord status */ - discord_update_activity(dopause); - } -#endif - - /* Create our main window's class and register it. */ - wincl.hInstance = hinstance; - wincl.lpszClassName = CLASS_NAME; - wincl.lpfnWndProc = MainWindowProcedure; - wincl.style = CS_DBLCLKS; /* Catch double-clicks */ - wincl.cbSize = sizeof(WNDCLASSEX); - wincl.hIcon = NULL; - wincl.hIconSm = NULL; - wincl.hCursor = NULL; - wincl.lpszMenuName = NULL; - wincl.cbClsExtra = 0; - wincl.cbWndExtra = 0; - wincl.hbrBackground = CreateSolidBrush(RGB(0, 0, 0)); - - /* Load proper icons */ - wchar_t path[MAX_PATH + 1] = { 0 }; - GetModuleFileNameW(hinstance, path, MAX_PATH); - ExtractIconExW(path, 0, &wincl.hIcon, &wincl.hIconSm, 1); - - if (!RegisterClassEx(&wincl)) - return 2; - wincl.lpszClassName = SUB_CLASS_NAME; - wincl.lpfnWndProc = SubWindowProcedure; - if (!RegisterClassEx(&wincl)) - return 2; - wincl.lpszClassName = SDL_CLASS_NAME; - wincl.lpfnWndProc = SDLMainWindowProcedure; - if (!RegisterClassEx(&wincl)) - return 2; - wincl.lpszClassName = SDL_SUB_CLASS_NAME; - wincl.lpfnWndProc = SDLSubWindowProcedure; - if (!RegisterClassEx(&wincl)) - return 2; - - /* Now create our main window. */ - swprintf_s(title, sizeof_w(title), L"%hs - %s %s", vm_name, EMU_NAME_W, EMU_VERSION_FULL_W); - hwnd = CreateWindowEx( - 0, /* no extended possibilites */ - CLASS_NAME, /* class name */ - title, /* Title Text */ - (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX) | DS_3DLOOK, - CW_USEDEFAULT, /* Windows decides the position */ - CW_USEDEFAULT, /* where window ends up on the screen */ - scrnsz_x + (GetSystemMetrics(SM_CXFIXEDFRAME) * 2), /* width */ - scrnsz_y + (GetSystemMetrics(SM_CYFIXEDFRAME) * 2) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 1, /* and height in pixels */ - HWND_DESKTOP, /* window is a child to desktop */ - NULL, /* no menu (yet) */ - hinstance, /* Program Instance handler */ - NULL); /* no Window Creation data */ - hwndMain = tdconfig.hwndParent = hwnd; - - ui_window_title(title); - - /* Get the current DPI */ - dpi = win_get_dpi(hwndMain); - - /* Check if we have a padded window frame */ - padded_frame = (GetSystemMetrics(SM_CXPADDEDBORDER) != 0); - - /* Create the status bar window. */ - StatusBarCreate(hwndMain, IDC_STATUS, hinstance); - - /* Get the actual height of the status bar */ - GetWindowRect(hwndSBAR, &rect); - sbar_height = rect.bottom - rect.top; - if (hide_status_bar) - ShowWindow(hwndSBAR, SW_HIDE); - - /* Create the toolbar window. */ - ToolBarCreate(hwndMain, hinstance); - - /* Get the actual height of the toolbar */ - tbar_height = SendMessage(hwndRebar, RB_GETROWHEIGHT, 0, 0); - if (hide_tool_bar) - ShowWindow(hwndRebar, SW_HIDE); - - /* Set up main window for resizing if configured. */ - if (vid_resize == 1) - SetWindowLongPtr(hwnd, GWL_STYLE, - (WS_OVERLAPPEDWINDOW)); - else - SetWindowLongPtr(hwnd, GWL_STYLE, - (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX)); - - /* Create the Machine Rendering window. */ - hwndRender = CreateWindow(/*L"STATIC"*/ SUB_CLASS_NAME, NULL, WS_CHILD | SS_BITMAP, - 0, 0, 1, 1, hwnd, NULL, hinstance, NULL); - - /* Initiate a resize in order to properly arrange all controls. - Move to the last-saved position if needed. */ - if ((vid_resize < 2) && window_remember) - MoveWindow(hwnd, window_x, window_y, window_w, window_h, TRUE); - else { - if (vid_resize >= 2) { - MoveWindow(hwnd, window_x, window_y, window_w, window_h, TRUE); - scrnsz_x = fixed_size_x; - scrnsz_y = fixed_size_y; - } - ResizeWindowByClientArea(hwnd, scrnsz_x, scrnsz_y + (hide_status_bar ? 0 : sbar_height) + (hide_tool_bar ? 0 : tbar_height)); - } - - /* Load the desired language */ - helper_lang = lang_id; - lang_id = 0; - set_language(helper_lang); - - /* Make the window visible on the screen. */ - ShowWindow(hwnd, nCmdShow); - - /* Warn the user about unsupported configs. */ - if (cpu_override && ui_msgbox_ex(MBX_WARNING | MBX_QUESTION_OK, (void *) IDS_2146, (void *) IDS_2147, (void *) IDS_2148, (void *) IDS_2120, NULL)) { - DestroyWindow(hwnd); - return 0; - } - - GetClipCursor(&oldclip); - - /* Initialize the RawInput (keyboard) module. */ - memset(&ridev, 0x00, sizeof(ridev)); - ridev.usUsagePage = 0x01; - ridev.usUsage = 0x06; - ridev.dwFlags = RIDEV_NOHOTKEYS; - ridev.hwndTarget = NULL; /* current focus window */ - if (!RegisterRawInputDevices(&ridev, 1, sizeof(ridev))) { - tdconfig.pszContent = MAKEINTRESOURCE(IDS_2106); - TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); - return 4; - } - keyboard_getkeymap(); - - /* Load the accelerator table */ - haccel = LoadAccelerators(hinstance, ACCEL_NAME); - if (haccel == NULL) { - tdconfig.pszContent = MAKEINTRESOURCE(IDS_2105); - TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); - return 3; - } - - /* Initialize the mouse module. */ - if (!start_in_fullscreen) - win_mouse_init(); - - /* - * Before we can create the Render window, we first have - * to prepare some other things that it depends on. - */ - ghMutex = CreateMutex(NULL, FALSE, NULL); - - /* All done, fire up the actual emulated machine. */ - if (!pc_init_modules()) { - /* Dang, no ROMs found at all! */ - tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2121); - tdconfig.pszContent = MAKEINTRESOURCE(IDS_2056); - TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); - return 6; - } - - /* Initialize the configured Video API. */ - if (!plat_setvid(vid_api)) { - tdconfig.pszContent = MAKEINTRESOURCE(IDS_2090); - TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); - return 5; - } - - /* Set up the current window size. */ - if (vid_resize & 2) - plat_resize(fixed_size_x, fixed_size_y); - else - plat_resize(scrnsz_x, scrnsz_y); - - /* Initialize the rendering window, or fullscreen. */ - if (start_in_fullscreen) - plat_setfullscreen(3); - - /* Fire up the machine. */ - pc_reset_hard_init(); - - /* Set the PAUSE mode depending on the renderer. */ - plat_pause(0); - - /* If so requested via the command line, inform the - * application that started us of our HWND, using the - * the hWnd and unique ID the application has given - * us. */ - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDHWND, (WPARAM) unique_id, (LPARAM) hwndMain); - - /* - * Everything has been configured, and all seems to work, - * so now it is time to start the main thread to do some - * real work, and we will hang in here, dealing with the - * UI until we're done. - */ - do_start(); - - /* Run the message loop. It will run until GetMessage() returns 0 */ - while (!is_quit) { - bRet = GetMessage(&messages, NULL, 0, 0); - if ((bRet == 0) || is_quit) - break; - - if (bRet == -1) { - fatal("bRet is -1\n"); - } - - /* On WM_QUIT, tell the CPU thread to stop running. That will then tell us - to stop running as well. */ - if (messages.message == WM_QUIT) - cpu_thread_run = 0; - - if (!TranslateAccelerator(hwnd, haccel, &messages)) { - /* Don't process other keypresses. */ - if (messages.message == WM_SYSKEYDOWN || messages.message == WM_SYSKEYUP || messages.message == WM_KEYDOWN || messages.message == WM_KEYUP) - continue; - - TranslateMessage(&messages); - DispatchMessage(&messages); - } - - if (mouse_capture && keyboard_ismsexit()) { - /* Release the in-app mouse. */ - plat_mouse_capture(0); - } - - if (!fs_off_signal && video_fullscreen && keyboard_isfsexit()) { - /* Signal "exit fullscreen mode". */ - fs_off_signal = 1; - } else if (fs_off_signal && video_fullscreen && keyboard_isfsexit_up()) { - plat_setfullscreen(0); - fs_off_signal = 0; - } - - if (!fs_on_signal && !video_fullscreen && keyboard_isfsenter()) { - /* Signal "enter fullscreen mode". */ - fs_on_signal = 1; - } else if (fs_on_signal && !video_fullscreen && keyboard_isfsenter_up()) { - plat_setfullscreen(1); - fs_on_signal = 0; - } - -#ifdef DISCORD - /* Run Discord API callbacks */ - if (enable_discord) - discord_run_callbacks(); -#endif - } - - timeEndPeriod(1); - - if (mouse_capture) - plat_mouse_capture(0); - - /* Close down the emulator. */ - do_stop(); - - UnregisterClass(SDL_SUB_CLASS_NAME, hinstance); - UnregisterClass(SDL_CLASS_NAME, hinstance); - UnregisterClass(SUB_CLASS_NAME, hinstance); - UnregisterClass(CLASS_NAME, hinstance); - - win_mouse_close(); - -#ifdef DISCORD - /* Shut down the Discord integration */ - discord_close(); -#endif - - if (user32_handle != NULL) - dynld_close(user32_handle); - - return (messages.wParam); -} - -/* We should have the language ID as a parameter. */ -void -plat_pause(int p) -{ - static wchar_t oldtitle[512]; - wchar_t title[512]; - - /* If un-pausing, as the renderer if that's OK. */ - if (p == 0) - p = get_vidpause(); - - /* If already so, done. */ - if (dopause == p) { - /* Send the WM to a manager if needed. */ - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSTATUS, (WPARAM) !!dopause, (LPARAM) hwndMain); - - return; - } - - if (p) { - if (mouse_capture) - plat_mouse_capture(0); - - wcsncpy(oldtitle, ui_window_title(NULL), sizeof_w(oldtitle) - 1); - wcscpy(title, oldtitle); - wcscat(title, plat_get_string(IDS_2051)); - ui_window_title(title); - } else - ui_window_title(oldtitle); - - /* If un-pausing, synchronize the internal clock with the host's time. */ - if ((p == 0) && (time_sync & TIME_SYNC_ENABLED)) - nvr_time_sync(); - - dopause = p; - - /* Update the actual menu. */ - CheckMenuItem(menuMain, IDM_ACTION_PAUSE, - dopause ? MF_CHECKED : MF_UNCHECKED); - -#ifdef DISCORD - /* Update Discord status */ - if (enable_discord) - discord_update_activity(dopause); -#endif - - /* Update the toolbar */ - ToolBarUpdatePause(p); - - /* Send the WM to a manager if needed. */ - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSTATUS, (WPARAM) !!dopause, (LPARAM) hwndMain); -} - -/* Tell the UI about a new screen resolution. */ -void -plat_resize(int x, int y) -{ - /* First, see if we should resize the UI window. */ - if (!vid_resize) { - /* scale the screen base on DPI */ - if (dpi_scale) { - x = MulDiv(x, dpi, 96); - y = MulDiv(y, dpi, 96); - } - ResizeWindowByClientArea(hwndMain, x, y + (hide_status_bar ? 0 : sbar_height) + (hide_tool_bar ? 0 : tbar_height)); - } -} - -void -plat_resize_request(int w, int h, int monitor_index) -{ - atomic_store((&doresize_monitors[monitor_index]), 1); -} - -void -plat_mouse_capture(int on) -{ - RECT rect; - - if (!kbd_req_capture && (mouse_type == MOUSE_TYPE_NONE) && !machine_has_mouse()) - return; - - if (on && !mouse_capture) { - /* Enable the in-app mouse. */ - GetClipCursor(&oldclip); - GetWindowRect(hwndRender, &rect); - ClipCursor(&rect); - show_cursor(0); - mouse_capture = 1; - } else if (!on && mouse_capture) { - /* Disable the in-app mouse. */ - ClipCursor(&oldclip); - show_cursor(-1); - - mouse_capture = 0; - } -} - -void -ui_init_monitor(UNUSED(int monitor_index)) -{ - // Nothing done here yet -} - -void -ui_deinit_monitor(UNUSED(int monitor_index)) -{ - // Nothing done here yet -} - -void -ui_hard_reset_completed(void) -{ - // Nothing done here yet -} From 5d57026af423f54c01e116187b69e3147fb29ffe Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 16 Mar 2024 04:07:27 +0500 Subject: [PATCH 684/936] Fix Ghostscript DLL filename in an error message on 64-bit Windows --- src/qt/qt_platform.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 46d50672e..385a8c56f 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -581,7 +581,11 @@ c16stombs(char dst[], const uint16_t src[], int len) #endif #ifdef _WIN32 -# define LIB_NAME_GS "gsdll32.dll" +# if defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) +# define LIB_NAME_GS "gsdll64.dll" +# else +# define LIB_NAME_GS "gsdll32.dll" +#endif # define MOUSE_CAPTURE_KEYSEQ "F8+F12" #else # define LIB_NAME_GS "libgs" From a46fb2e76b2f53ec29092c6fa52667b28cb61372 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 17 Mar 2024 02:37:46 +0500 Subject: [PATCH 685/936] Fix up the arch check for the GS DLL filename --- src/qt/qt_platform.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 385a8c56f..824f71023 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -581,11 +581,11 @@ c16stombs(char dst[], const uint16_t src[], int len) #endif #ifdef _WIN32 -# if defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) +# if defined(__amd64__) || defined(_M_X64) || defined(__aarch64__) || defined(_M_ARM64) # define LIB_NAME_GS "gsdll64.dll" # else # define LIB_NAME_GS "gsdll32.dll" -#endif +# endif # define MOUSE_CAPTURE_KEYSEQ "F8+F12" #else # define LIB_NAME_GS "libgs" From d212aad3179264a61ded8c91c83fdac78457e31a Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 17 Mar 2024 02:38:57 +0500 Subject: [PATCH 686/936] Add missing period to error messages to fix their translations --- src/qt/qt_harddiskdialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_harddiskdialog.cpp b/src/qt/qt_harddiskdialog.cpp index 5dab101b8..187bf4ba2 100644 --- a/src/qt/qt_harddiskdialog.cpp +++ b/src/qt/qt_harddiskdialog.cpp @@ -567,7 +567,7 @@ HarddiskDialog::onExistingFileSelected(const QString &fileName, bool precheck) } else if (image_is_vhd(fileNameUtf8.data(), 1)) { MVHDMeta *vhd = mvhd_open(fileNameUtf8.data(), 0, &vhd_error); if (vhd == nullptr) { - QMessageBox::critical(this, tr("Unable to read file"), tr("Make sure the file exists and is readable")); + QMessageBox::critical(this, tr("Unable to read file"), tr("Make sure the file exists and is readable.")); return; } else if (vhd_error == MVHD_ERR_TIMESTAMP) { QMessageBox::StandardButton btn = QMessageBox::warning(this, tr("Parent and child disk timestamps do not match"), tr("This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?"), QMessageBox::Yes | QMessageBox::No); @@ -618,7 +618,7 @@ HarddiskDialog::onExistingFileSelected(const QString &fileName, bool precheck) } if ((sectors > max_sectors) || (heads > max_heads) || (cylinders > max_cylinders)) { - QMessageBox::critical(this, tr("Unable to read file"), tr("Make sure the file exists and is readable")); + QMessageBox::critical(this, tr("Unable to read file"), tr("Make sure the file exists and is readable.")); return; } From 5b96375baf9da73b83765a21489ce01285b2b3c3 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 17 Mar 2024 02:39:17 +0500 Subject: [PATCH 687/936] Sort the language dropdown alphabetically --- src/qt/qt_progsettings.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt/qt_progsettings.cpp b/src/qt/qt_progsettings.cpp index 4dda901d7..164f69418 100644 --- a/src/qt/qt_progsettings.cpp +++ b/src/qt/qt_progsettings.cpp @@ -110,6 +110,7 @@ ProgSettings::ProgSettings(QWidget *parent) ui->comboBoxLanguage->setCurrentIndex(ui->comboBoxLanguage->findData(i.key())); } } + ui->comboBoxLanguage->model()->sort(Qt::AscendingOrder); mouseSensitivity = mouse_sensitivity; ui->horizontalSlider->setValue(mouseSensitivity * 100.); From 84cdb5ea3507fa7d6f906a348c440caa3e4bab20 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 16 Mar 2024 19:46:49 +0500 Subject: [PATCH 688/936] CMake: hardcode the Qt UI option to ON on Windows --- CMakeLists.txt | 7 ++++++- src/CMakeLists.txt | 2 -- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae39fbccf..1dfed3fb9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -136,9 +136,14 @@ option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" option(MINITRACE "Enable Chrome tracing using the modified minitrace library" OFF) option(GDBSTUB "Enable GDB stub server for debugging" OFF) option(DEV_BRANCH "Development branch" OFF) -option(QT "Qt GUI" ON) option(DISCORD "Discord Rich Presence support" ON) +if(WIN32) + set(QT ON) +else() + option(QT "Qt GUI" ON) +endif() + # Development branch features # # Option Description Def. Condition Otherwise diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ec32d7548..7030e9f63 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -226,8 +226,6 @@ endif() if (QT) add_subdirectory(qt) -elseif(WIN32) - add_subdirectory(win) else() add_compile_definitions(USE_SDL_UI) add_subdirectory(unix) From b3819f69629a585fe48b25cbec88ee157c8a6e90 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 16 Mar 2024 19:47:59 +0500 Subject: [PATCH 689/936] Remove or trim leftover header files --- bumpversion.sh | 12 - src/include/86box/resource.h | 524 --------------------------- src/include/86box/win.h | 202 ----------- src/include/86box/win_opengl.h | 29 -- src/include/86box/win_opengl_glslp.h | 24 -- src/include/86box/win_sdl.h | 63 ---- src/include_make/86box/version.h | 49 --- 7 files changed, 903 deletions(-) delete mode 100644 src/include/86box/resource.h delete mode 100644 src/include/86box/win_opengl.h delete mode 100644 src/include/86box/win_opengl_glslp.h delete mode 100644 src/include/86box/win_sdl.h delete mode 100644 src/include_make/86box/version.h diff --git a/bumpversion.sh b/bumpversion.sh index 4681e72be..6e2536cbe 100644 --- a/bumpversion.sh +++ b/bumpversion.sh @@ -26,12 +26,6 @@ then fi shift -# Extract version components. -newversion_maj=$(echo "$newversion" | cut -d. -f1) -newversion_min=$(echo "$newversion" | cut -d. -f2) -newversion_patch=$(echo "$newversion" | cut -d. -f3) -[ -z "$newversion_patch" ] && newversion_patch=0 - if [ -z "${romversion}" ]; then # Get the latest ROM release from the GitHub API. romversion=$(curl --silent "https://api.github.com/repos/86Box/roms/releases/latest" | @@ -62,12 +56,6 @@ patch_file() { } 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/include_make/*/version.h EMU_VERSION 's/(#\s*define\s+EMU_VERSION\s+")[^"]+/\1'"$newversion"'/' -patch_file src/include_make/*/version.h EMU_VERSION_MAJ 's/(#\s*define\s+EMU_VERSION_MAJ\s+)[0-9]+/\1'"$newversion_maj"'/' -patch_file src/include_make/*/version.h EMU_VERSION_MIN 's/(#\s*define\s+EMU_VERSION_MIN\s+)[0-9]+/\1'"$newversion_min"'/' -patch_file src/include_make/*/version.h EMU_VERSION_PATCH 's/(#\s*define\s+EMU_VERSION_PATCH\s+)[0-9]+/\1'"$newversion_patch"'/' -patch_file src/include_make/*/version.h COPYRIGHT_YEAR 's/(#\s*define\s+COPYRIGHT_YEAR\s+)[0-9]+/\1'"$(date +%Y)"'/' -patch_file src/include_make/*/version.h EMU_DOCS_URL 's/(#\s*define\s+EMU_DOCS_URL\s+"https:\/\/[^\/]+\/en\/v)[^\/]+/\1'"$newversion_maj.$newversion_min"'/' 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'/' diff --git a/src/include/86box/resource.h b/src/include/86box/resource.h deleted file mode 100644 index 2e6628c77..000000000 --- a/src/include/86box/resource.h +++ /dev/null @@ -1,524 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Windows resource defines. - * - * - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * David Hrdlička, - * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2018-2019 David Hrdlička. - * Copyright 2021-2022 Jasmine Iwanek. - */ - -#ifndef WIN_RESOURCE_H -#define WIN_RESOURCE_H - -/* Dialog IDs. */ -#define DLG_ABOUT 101 /* top-level dialog */ -#define DLG_STATUS 102 /* top-level dialog */ -#define DLG_SND_GAIN 103 /* top-level dialog */ -#define DLG_NEW_FLOPPY 104 /* top-level dialog */ -#define DLG_SPECIFY_DIM 105 /* top-level dialog */ -#define DLG_PREFERENCES 106 /* top-level dialog */ -#define DLG_CONFIG 110 /* top-level dialog */ -#define DLG_CFG_MACHINE 111 /* sub-dialog of config */ -#define DLG_CFG_VIDEO 112 /* sub-dialog of config */ -#define DLG_CFG_INPUT 113 /* sub-dialog of config */ -#define DLG_CFG_SOUND 114 /* sub-dialog of config */ -#define DLG_CFG_NETWORK 115 /* sub-dialog of config */ -#define DLG_CFG_PORTS 116 /* sub-dialog of config */ -#define DLG_CFG_STORAGE 117 /* sub-dialog of config */ -#define DLG_CFG_HARD_DISKS 118 /* sub-dialog of config */ -#define DLG_CFG_HARD_DISKS_ADD 119 /* sub-dialog of config */ -#define DLG_CFG_FLOPPY_AND_CDROM_DRIVES 120 /* sub-dialog of config */ -#define DLG_CFG_OTHER_REMOVABLE_DEVICES 121 /* sub-dialog of config */ -#define DLG_CFG_PERIPHERALS 122 /* sub-dialog of config */ - -/* Static text label IDs. */ - -/* DLG_SND_GAIN */ -#define IDT_GAIN 1700 /* Gain */ - -/* DLG_NEW_FLOPPY */ -#define IDT_FLP_FILE_NAME 1701 /* File name: */ -#define IDT_FLP_DISK_SIZE 1702 /* Disk size: */ -#define IDT_FLP_RPM_MODE 1703 /* RPM mode: */ -#define IDT_FLP_PROGRESS 1704 /* Progress: */ - -/* DLG_SPECIFY_DIM */ -#define IDT_WIDTH 1705 /* ??? */ -#define IDT_HEIGHT 1706 /* ??? */ - -/* DLG_CFG_MACHINE */ -#define IDT_MACHINE_TYPE 1707 /* Machine type: */ -#define IDT_MACHINE 1708 /* Machine: */ -#define IDT_CPU_TYPE 1709 /* CPU type: */ -#define IDT_CPU_SPEED 1710 /* CPU speed: */ -#define IDT_FPU 1711 /* FPU: */ -#define IDT_WAIT_STATES 1712 /* Wait states: */ -#define IDT_MB 1713 /* MB == IDC_TEXT_MB */ -#define IDT_MEMORY 1714 /* Memory: */ - -/* DLG_CFG_VIDEO */ -#define IDT_VIDEO 1715 /* Video: */ -#define IDT_VIDEO_2 1716 /* Video 2: */ - -/* DLG_CFG_INPUT */ -#define IDT_MOUSE 1717 /* Mouse: */ -#define IDT_JOYSTICK 1718 /* Joystick: */ - -/* DLG_CFG_SOUND */ -#define IDT_SOUND1 1719 /* Sound card #1: */ -#define IDT_SOUND2 1720 /* Sound card #2: */ -#define IDT_SOUND3 1721 /* Sound card #3: */ -#define IDT_SOUND4 1722 /* Sound card #4: */ -#define IDT_MIDI_OUT 1723 /* MIDI Out Device: */ -#define IDT_MIDI_IN 1724 /* MIDI In Device: */ - -/* DLG_CFG_NETWORK */ -#define IDT_NET_TYPE 1725 /* Network type: */ -#define IDT_PCAP 1726 /* PCap device: */ -#define IDT_NET 1727 /* Network adapter: */ -#define IDT_NET1 1728 /* Network adapter 1: */ -#define IDT_NET2 1729 /* Network adapter 2: */ -#define IDT_NET3 1730 /* Network adapter 3: */ -#define IDT_NET4 1731 /* Network adapter 4: */ - -/* DLG_CFG_PORTS */ -#define IDT_COM1 1732 /* COM1 Device: */ -#define IDT_COM2 1733 /* COM1 Device: */ -#define IDT_COM3 1734 /* COM1 Device: */ -#define IDT_COM4 1735 /* COM1 Device: */ - -#define IDT_LPT1 1736 /* LPT1 Device: */ -#define IDT_LPT2 1737 /* LPT2 Device: */ -#define IDT_LPT3 1738 /* LPT3 Device: */ -#define IDT_LPT4 1739 /* LPT4 Device: */ - -/* DLG_CFG_STORAGE */ -#define IDT_HDC 1740 /* HD Controller: */ -#define IDT_FDC 1741 /* Ext FD Controller: */ -#define IDT_SCSI_1 1742 /* SCSI Board #1: */ -#define IDT_SCSI_2 1743 /* SCSI Board #2: */ -#define IDT_SCSI_3 1744 /* SCSI Board #3: */ -#define IDT_SCSI_4 1745 /* SCSI Board #4: */ - -/* DLG_CFG_HARD_DISKS */ -#define IDT_HDD 1746 /* Hard disks: */ -#define IDT_BUS 1747 /* Bus: */ -#define IDT_CHANNEL 1748 /* Channel: */ -#define IDT_ID 1749 /* ID: */ -#define IDT_LUN 1750 /* LUN: */ -#define IDT_SPEED 1751 /* Speed: */ - -/* DLG_CFG_HARD_DISKS_ADD */ -#define IDT_SECTORS 1752 /* Sectors: */ -#define IDT_HEADS 1753 /* Heads: */ -#define IDT_CYLS 1754 /* Cylinders: */ -#define IDT_SIZE_MB 1755 /* Size (MB): */ -#define IDT_TYPE 1756 /* Type: */ -#define IDT_FILE_NAME 1757 /* File name: */ -#define IDT_IMG_FORMAT 1758 /* Image Format: */ -#define IDT_BLOCK_SIZE 1759 /* Block Size: */ -#define IDT_PROGRESS 1760 /* Progress: */ - -/* DLG_CFG_FLOPPY_AND_CDROM_DRIVES */ -#define IDT_FLOPPY_DRIVES 1761 /* Floppy drives: */ -#define IDT_FDD_TYPE 1762 /* Type: */ -#define IDT_CD_DRIVES 1763 /* CD-ROM drives: */ -#define IDT_CD_BUS 1764 /* Bus: */ -#define IDT_CD_ID 1765 /* ID: */ -#define IDT_CD_LUN 1766 /* LUN: */ -#define IDT_CD_CHANNEL 1767 /* Channel: */ -#define IDT_CD_SPEED 1768 /* Speed: */ -#define IDT_CD_TYPE 1769 /* Type: */ - -/* DLG_CFG_OTHER_REMOVABLE_DEVICES */ -#define IDT_MO_DRIVES 1770 /* MO drives: */ -#define IDT_MO_BUS 1771 /* Bus: */ -#define IDT_MO_ID 1772 /* ID: */ -#define IDT_MO_CHANNEL 1773 /* Channel */ -#define IDT_MO_TYPE 1774 /* Type: */ - -#define IDT_ZIP_DRIVES 1775 /* ZIP drives: */ -#define IDT_ZIP_BUS 1776 /* Bus: */ -#define IDT_ZIP_ID 1777 /* ID: */ -#define IDT_ZIP_LUN 1778 /* LUN: */ -#define IDT_ZIP_CHANNEL 1779 /* Channel: */ - -/* DLG_CFG_PERIPHERALS */ -#define IDT_ISARTC 1780 /* ISA RTC: */ -#define IDT_ISAMEM_1 1781 /* ISAMEM Board #1: */ -#define IDT_ISAMEM_2 1782 /* ISAMEM Board #2: */ -#define IDT_ISAMEM_3 1783 /* ISAMEM Board #3: */ -#define IDT_ISAMEM_4 1784 /* ISAMEM Board #4: */ - -/* - * To try to keep these organized, we now group the - * constants per dialog, as this allows easy adding - * and deleting items. - */ -#define IDC_SETTINGSCATLIST 1001 /* generic config */ -#define IDC_CFILE 1002 /* Select File dialog */ -#define IDC_TIME_SYNC 1005 -#define IDC_RADIO_TS_DISABLED 1006 -#define IDC_RADIO_TS_LOCAL 1007 -#define IDC_RADIO_TS_UTC 1008 - -#define IDC_COMBO_MACHINE_TYPE 1010 -#define IDC_COMBO_MACHINE 1011 /* machine/cpu config */ -#define IDC_CONFIGURE_MACHINE 1012 -#define IDC_COMBO_CPU_TYPE 1013 -#define IDC_COMBO_CPU_SPEED 1014 -#define IDC_COMBO_FPU 1015 -#define IDC_COMBO_WS 1016 -#ifdef USE_DYNAREC -# define IDC_CHECK_DYNAREC 1017 -#endif -#define IDC_CHECK_SOFTFLOAT 1018 -#define IDC_MEMTEXT 1019 -#define IDC_MEMSPIN 1020 -#define IDC_TEXT_MB IDT_MB - -#define IDC_VIDEO 1021 /* video config */ -#define IDC_COMBO_VIDEO 1022 -#define IDC_VIDEO_2 1023 -#define IDC_COMBO_VIDEO_2 1024 -#define IDC_CHECK_VOODOO 1025 -#define IDC_BUTTON_VOODOO 1026 -#define IDC_CHECK_IBM8514 1027 -#define IDC_CHECK_XGA 1028 -#define IDC_BUTTON_XGA 1029 - -#define IDC_INPUT 1030 /* input config */ -#define IDC_COMBO_MOUSE 1031 -#define IDC_COMBO_JOYSTICK 1032 -#define IDC_COMBO_JOY 1033 -#define IDC_CONFIGURE_MOUSE 1034 - -#define IDC_SOUND 1040 /* sound config */ -#define IDC_COMBO_SOUND1 1041 -#define IDC_COMBO_SOUND2 1042 -#define IDC_COMBO_SOUND3 1043 -#define IDC_COMBO_SOUND4 1044 -#define IDC_COMBO_MIDI_OUT 1045 -#define IDC_CHECK_MPU401 1046 -#define IDC_CONFIGURE_MPU401 1047 -#define IDC_CHECK_FLOAT 1048 -#define IDC_CONFIGURE_GUS 1049 -#define IDC_COMBO_MIDI_IN 1050 -#define IDC_CONFIGURE_CMS 1051 -#define IDC_CONFIGURE_SSI 1052 -#define IDC_FM_DRIVER 1053 -#define IDC_RADIO_FM_DRV_NUKED 1054 -#define IDC_RADIO_FM_DRV_YMFM 1055 - -#define IDC_COMBO_NET1_TYPE 1060 /* network config */ -#define IDC_COMBO_NET2_TYPE 1061 -#define IDC_COMBO_NET3_TYPE 1062 -#define IDC_COMBO_NET4_TYPE 1063 -#define IDC_COMBO_PCAP1 1064 -#define IDC_COMBO_PCAP2 1065 -#define IDC_COMBO_PCAP3 1066 -#define IDC_COMBO_PCAP4 1067 -#define IDC_COMBO_NET1 1068 -#define IDC_COMBO_NET2 1069 -#define IDC_COMBO_NET3 1070 -#define IDC_COMBO_NET4 1071 - -#define IDC_COMBO_LPT1 1080 /* ports config */ -#define IDC_COMBO_LPT2 1081 -#define IDC_COMBO_LPT3 1082 -#define IDC_COMBO_LPT4 1083 -#define IDC_CHECK_SERIAL1 1084 -#define IDC_CHECK_SERIAL2 1085 -#define IDC_CHECK_SERIAL3 1086 -#define IDC_CHECK_SERIAL4 1087 -#define IDC_CHECK_PARALLEL1 1088 -#define IDC_CHECK_PARALLEL2 1089 -#define IDC_CHECK_PARALLEL3 1090 -#define IDC_CHECK_PARALLEL4 1091 -#define IDC_CHECK_SERIAL_PASS1 1092 -#define IDC_CHECK_SERIAL_PASS2 1093 -#define IDC_CHECK_SERIAL_PASS3 1094 -#define IDC_CHECK_SERIAL_PASS4 1095 - -#define IDC_OTHER_PERIPH 1110 /* storage controllers config */ -#define IDC_COMBO_HDC 1111 -#define IDC_CONFIGURE_HDC 1112 -#define IDC_CHECK_IDE_TER 1113 -#define IDC_BUTTON_IDE_TER 1114 -#define IDC_CHECK_IDE_QUA 1115 -#define IDC_BUTTON_IDE_QUA 1116 -#define IDC_GROUP_SCSI 1117 -#define IDC_COMBO_SCSI_1 1118 -#define IDC_COMBO_SCSI_2 1119 -#define IDC_COMBO_SCSI_3 1120 -#define IDC_COMBO_SCSI_4 1121 -#define IDC_CONFIGURE_SCSI_1 1122 -#define IDC_CONFIGURE_SCSI_2 1123 -#define IDC_CONFIGURE_SCSI_3 1124 -#define IDC_CONFIGURE_SCSI_4 1125 -#define IDC_CHECK_CASSETTE 1126 - -#define IDC_HARD_DISKS 1130 /* hard disks config */ -#define IDC_LIST_HARD_DISKS 1131 -#define IDC_BUTTON_HDD_ADD_NEW 1132 -#define IDC_BUTTON_HDD_ADD 1133 -#define IDC_BUTTON_HDD_REMOVE 1134 -#define IDC_COMBO_HD_BUS 1135 -#define IDC_COMBO_HD_CHANNEL 1136 -#define IDC_COMBO_HD_ID 1137 -#define IDC_COMBO_HD_SPEED 1138 -#define IDC_COMBO_HD_CHANNEL_IDE 1139 - -#define IDC_EDIT_HD_FILE_NAME 1140 /* add hard disk dialog */ -#define IDC_EDIT_HD_SPT 1141 -#define IDC_EDIT_HD_HPC 1142 -#define IDC_EDIT_HD_CYL 1143 -#define IDC_EDIT_HD_SIZE 1144 -#define IDC_COMBO_HD_TYPE 1145 -#define IDC_PBAR_IMG_CREATE 1146 -#define IDC_COMBO_HD_IMG_FORMAT 1147 -#define IDC_COMBO_HD_BLOCK_SIZE 1148 - -#define IDC_REMOV_DEVICES 1150 /* floppy and cd-rom drives config */ -#define IDC_LIST_FLOPPY_DRIVES 1151 -#define IDC_COMBO_FD_TYPE 1152 -#define IDC_CHECKTURBO 1153 -#define IDC_CHECKBPB 1154 -#define IDC_LIST_CDROM_DRIVES 1155 -#define IDC_COMBO_CD_BUS 1156 -#define IDC_COMBO_CD_ID 1157 -#define IDC_COMBO_CD_LUN 1158 -#define IDC_COMBO_CD_CHANNEL_IDE 1159 -#define IDC_COMBO_CD_TYPE 1160 - -#define IDC_LIST_ZIP_DRIVES 1170 /* other removable devices config */ -#define IDC_COMBO_ZIP_BUS 1171 -#define IDC_COMBO_ZIP_ID 1172 -#define IDC_COMBO_ZIP_LUN 1173 -#define IDC_COMBO_ZIP_CHANNEL_IDE 1174 -#define IDC_CHECK250 1175 -#define IDC_COMBO_CD_SPEED 1176 -#define IDC_LIST_MO_DRIVES 1177 -#define IDC_COMBO_MO_BUS 1178 -#define IDC_COMBO_MO_ID 1179 -#define IDC_COMBO_MO_LUN 1170 -#define IDC_COMBO_MO_CHANNEL_IDE 1181 -#define IDC_COMBO_MO_TYPE 1182 - -#define IDC_CHECK_BUGGER 1190 /* other periph config */ -#define IDC_CHECK_POSTCARD 1191 -#define IDC_COMBO_ISARTC 1192 -#define IDC_CONFIGURE_ISARTC 1193 -#define IDC_COMBO_FDC 1194 -#define IDC_CONFIGURE_FDC 1195 -#define IDC_GROUP_ISAMEM 1196 -#define IDC_COMBO_ISAMEM_1 1197 -#define IDC_COMBO_ISAMEM_2 1198 -#define IDC_COMBO_ISAMEM_3 1199 -#define IDC_COMBO_ISAMEM_4 1200 -#define IDC_CONFIGURE_ISAMEM_1 1201 -#define IDC_CONFIGURE_ISAMEM_2 1202 -#define IDC_CONFIGURE_ISAMEM_3 1203 -#define IDC_CONFIGURE_ISAMEM_4 1204 - -#define IDC_SLIDER_GAIN 1210 /* sound gain dialog */ - -#define IDC_EDIT_FILE_NAME 1220 /* new floppy image dialog */ -#define IDC_COMBO_DISK_SIZE 1221 -#define IDC_COMBO_RPM_MODE 1222 - -#define IDC_COMBO_LANG 1009 /* change language dialog */ -#define IDC_COMBO_ICON 1010 -#define IDC_CHECKBOX_GLOBAL 1300 -#define IDC_BUTTON_DEFAULT 1302 -#define IDC_BUTTON_DEFICON 1304 - -/* For the DeviceConfig code, re-do later. */ -#define IDC_CONFIG_BASE 1300 -#define IDC_CONFIGURE_VID 1300 -#define IDC_CONFIGURE_VID_2 1301 -#define IDC_CONFIGURE_SND1 1302 -#define IDC_CONFIGURE_SND2 1303 -#define IDC_CONFIGURE_SND3 1304 -#define IDC_CONFIGURE_SND4 1305 -#define IDC_CONFIGURE_VOODOO 1306 -#define IDC_CONFIGURE_NET1_TYPE 1310 -#define IDC_CONFIGURE_NET2_TYPE 1311 -#define IDC_CONFIGURE_NET3_TYPE 1312 -#define IDC_CONFIGURE_NET4_TYPE 1313 -#define IDC_CONFIGURE_PCAP1 1314 -#define IDC_CONFIGURE_PCAP2 1315 -#define IDC_CONFIGURE_PCAP3 1316 -#define IDC_CONFIGURE_PCAP4 1317 -#define IDC_CONFIGURE_NET1 1318 -#define IDC_CONFIGURE_NET2 1319 -#define IDC_CONFIGURE_NET3 1320 -#define IDC_CONFIGURE_NET4 1321 -#define IDC_CONFIGURE_MIDI_OUT 1322 -#define IDC_CONFIGURE_MIDI_IN 1323 -#define IDC_CONFIGURE_SERIAL_PASS1 1324 -#define IDC_CONFIGURE_SERIAL_PASS2 1325 -#define IDC_CONFIGURE_SERIAL_PASS3 1326 -#define IDC_CONFIGURE_SERIAL_PASS4 1327 -#define IDC_JOY1 1330 -#define IDC_JOY2 1331 -#define IDC_JOY3 1332 -#define IDC_JOY4 1333 -#define IDC_HDTYPE 1380 -#define IDC_RENDER 1381 -#define IDC_STATUS 1382 - -#define IDC_EDIT_WIDTH 1400 /* specify main window dimensions dialog */ -#define IDC_WIDTHSPIN 1401 -#define IDC_EDIT_HEIGHT 1402 -#define IDC_HEIGHTSPIN 1403 -#define IDC_CHECK_LOCK_SIZE 1404 - -#define IDM_ABOUT 40001 -#define IDC_ABOUT_ICON 65535 -#define IDM_ACTION_KBD_REQ_CAPTURE 40010 -#define IDM_ACTION_RCTRL_IS_LALT 40011 -#define IDM_ACTION_SCREENSHOT 40012 -#define IDM_ACTION_HRESET 40013 -#define IDM_ACTION_RESET_CAD 40014 -#define IDM_ACTION_EXIT 40015 -#define IDM_ACTION_CTRL_ALT_ESC 40016 -#define IDM_ACTION_PAUSE 40017 -#ifdef MTR_ENABLED -# define IDM_ACTION_BEGIN_TRACE 40018 -# define IDM_ACTION_END_TRACE 40019 -# define IDM_ACTION_TRACE 40020 -#endif -#define IDM_CONFIG 40021 -#define IDM_VID_HIDE_STATUS_BAR 40022 -#define IDM_VID_HIDE_TOOLBAR 40023 -#define IDM_UPDATE_ICONS 40030 -#define IDM_SND_GAIN 40031 -#define IDM_VID_MONITORS 40040 -#define IDM_VID_RESIZE 40041 -#define IDM_VID_REMEMBER 40042 -#define IDM_VID_SDL_SW 40050 -#define IDM_VID_SDL_HW 40051 -#define IDM_VID_SDL_OPENGL 40052 -#define IDM_VID_OPENGL_CORE 40053 -#ifdef USE_VNC -# define IDM_VID_VNC 40054 -#endif -#define IDM_VID_SCALE_1X 40055 -#define IDM_VID_SCALE_2X 40056 -#define IDM_VID_SCALE_3X 40057 -#define IDM_VID_SCALE_4X 40058 -#define IDM_VID_SCALE_5X 40059 -#define IDM_VID_SCALE_6X 40060 -#define IDM_VID_SCALE_7X 40061 -#define IDM_VID_SCALE_8X 40062 -#define IDM_VID_SCALE_9X 40063 -#define IDM_VID_SCALE_10X 40064 - -#define IDM_VID_HIDPI 40065 -#define IDM_VID_FULLSCREEN 40066 -#define IDM_VID_FS_FULL 40067 -#define IDM_VID_FS_43 40068 -#define IDM_VID_FS_KEEPRATIO 40069 -#define IDM_VID_FS_INT 40070 -#define IDM_VID_SPECIFY_DIM 40071 -#define IDM_VID_FORCE43 40072 -#define IDM_VID_OVERSCAN 40073 -#define IDM_VID_INVERT 40074 -#define IDM_VID_CGACON 40075 -#define IDM_VID_GRAYCT_601 40076 -#define IDM_VID_GRAYCT_709 40077 -#define IDM_VID_GRAYCT_AVE 40078 -#define IDM_VID_GRAY_RGB 40080 -#define IDM_VID_GRAY_MONO 40081 -#define IDM_VID_GRAY_AMBER 40082 -#define IDM_VID_GRAY_GREEN 40083 -#define IDM_VID_GRAY_WHITE 40084 -#define IDM_VID_FILTER_NEAREST 40085 -#define IDM_VID_FILTER_LINEAR 40086 - -#define IDM_MEDIA 40087 -#define IDM_DOCS 40088 - -#define IDM_DISCORD 40090 - -#define IDM_PREFERENCES 40091 - -#define IDM_VID_GL_FPS_BLITTER 40100 -#define IDM_VID_GL_FPS_25 40101 -#define IDM_VID_GL_FPS_30 40102 -#define IDM_VID_GL_FPS_50 40103 -#define IDM_VID_GL_FPS_60 40104 -#define IDM_VID_GL_FPS_75 40105 -#define IDM_VID_GL_VSYNC 40106 -#define IDM_VID_GL_SHADER 40107 -#define IDM_VID_GL_NOSHADER 40108 - -/* - * We need 7 bits for CDROM (2 bits ID and 5 bits for host drive), - * and 5 bits for Removable Disks (5 bits for ID), so we use an - * 8bit (256 entries) space for these devices. - */ -#define IDM_CASSETTE_IMAGE_NEW 0x1200 -#define IDM_CASSETTE_IMAGE_EXISTING 0x1300 -#define IDM_CASSETTE_IMAGE_EXISTING_WP 0x1400 -#define IDM_CASSETTE_RECORD 0x1500 -#define IDM_CASSETTE_PLAY 0x1600 -#define IDM_CASSETTE_REWIND 0x1700 -#define IDM_CASSETTE_FAST_FORWARD 0x1800 -#define IDM_CASSETTE_EJECT 0x1900 - -#define IDM_CARTRIDGE_IMAGE 0x2200 -#define IDM_CARTRIDGE_EJECT 0x2300 - -#define IDM_FLOPPY_IMAGE_NEW 0x3200 -#define IDM_FLOPPY_IMAGE_EXISTING 0x3300 -#define IDM_FLOPPY_IMAGE_EXISTING_WP 0x3400 -#define IDM_FLOPPY_EXPORT_TO_86F 0x3500 -#define IDM_FLOPPY_EJECT 0x3600 - -#define IDM_CDROM_MUTE 0x4200 -#define IDM_CDROM_EMPTY 0x4300 -#define IDM_CDROM_RELOAD 0x4400 -#define IDM_CDROM_IMAGE 0x4500 -#define IDM_CDROM_DIR 0x4600 -#define IDM_CDROM_HOST_DRIVE 0x4700 - -#define IDM_ZIP_IMAGE_NEW 0x5200 -#define IDM_ZIP_IMAGE_EXISTING 0x5300 -#define IDM_ZIP_IMAGE_EXISTING_WP 0x5400 -#define IDM_ZIP_EJECT 0x5500 -#define IDM_ZIP_RELOAD 0x5600 - -#define IDM_MO_IMAGE_NEW 0x6200 -#define IDM_MO_IMAGE_EXISTING 0x6300 -#define IDM_MO_IMAGE_EXISTING_WP 0x6400 -#define IDM_MO_EJECT 0x6500 -#define IDM_MO_RELOAD 0x6600 - -/* Next default values for new objects */ -#ifdef APSTUDIO_INVOKED -# ifndef APSTUDIO_READONLY_SYMBOLS -# define _APS_NO_MFC 1 -# define _APS_NEXT_RESOURCE_VALUE 1400 -# define _APS_NEXT_COMMAND_VALUE 55000 -# define _APS_NEXT_CONTROL_VALUE 1800 -# define _APS_NEXT_SYMED_VALUE 200 -# endif -#endif - -#endif /*WIN_RESOURCE_H*/ diff --git a/src/include/86box/win.h b/src/include/86box/win.h index 35f6688ad..5cead7cb0 100644 --- a/src/include/86box/win.h +++ b/src/include/86box/win.h @@ -26,50 +26,7 @@ #ifndef UNICODE # define UNICODE #endif -#define BITMAP WINDOWS_BITMAP -#if 0 -# ifdef _WIN32_WINNT -# undef _WIN32_WINNT -# define _WIN32_WINNT 0x0501 -# endif -#endif -#include "resource.h" #include -#undef BITMAP - -/* DPI Awareness Context, copied from MinGW-w64 windef.h */ -#ifndef _DPI_AWARENESS_CONTEXTS_ -DECLARE_HANDLE(DPI_AWARENESS_CONTEXT); -# define DPI_AWARENESS_CONTEXT_UNAWARE ((DPI_AWARENESS_CONTEXT) -1) -# define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE ((DPI_AWARENESS_CONTEXT) -2) -# define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ((DPI_AWARENESS_CONTEXT) -3) -# define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT) -4) -# define DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED ((DPI_AWARENESS_CONTEXT) -5) -#endif - -#ifndef WM_DPICHANGED_AFTERPARENT -# define WM_DPICHANGED_AFTERPARENT 0x02E3 -#endif - -/* Class names and such. */ -#define CLASS_NAME L"86BoxMainWnd" -#define MENU_NAME L"MainMenu" -#define ACCEL_NAME L"MainAccel" -#define SUB_CLASS_NAME L"86BoxSubWnd" -#define SB_CLASS_NAME L"86BoxStatusBar" -#define SB_MENU_NAME L"StatusBarMenu" -#define FS_CLASS_NAME L"86BoxFullScreen" -#define SDL_CLASS_NAME L"86BoxSDLWnd" -#define SDL_SUB_CLASS_NAME L"86BoxSDLSubWnd" - -#define CASSETTE_SUBMENU_NAME L"CassetteSubmenu" -#define CARTRIDGE_SUBMENU_NAME L"CartridgeSubmenu" -#define FLOPPY_SUBMENU_NAME L"FloppySubmenu" -#define CDROM_SUBMENU_NAME L"CdromSubmenu" -#define ZIP_SUBMENU_NAME L"ZIPSubmenu" -#define MO_SUBMENU_NAME L"MOSubmenu" - -#define VID_GL_SUBMENU L"VidGLSubMenu" /* Application-specific window messages. @@ -92,163 +49,4 @@ DECLARE_HANDLE(DPI_AWARENESS_CONTEXT); /* The emulator has shut down. */ #define WM_HAS_SHUTDOWN 0x8897 -#ifdef USE_VNC -# define RENDERERS_NUM 5 -#else -# define RENDERERS_NUM 4 -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -extern HINSTANCE hinstance; -extern HWND hwndMain; -extern HWND hwndRender; -extern HWND hwndRender2; -extern HANDLE ghMutex; -extern HICON hIcon[256]; -extern int dpi; -extern RECT oldclip; -extern int sbar_height; -extern int tbar_height; -extern int user_resize; -extern int acp_utf8; - -#if 0 -extern int status_is_open; -#endif - -extern char openfilestring[512]; -extern WCHAR wopenfilestring[512]; - -extern uint8_t filterindex; - -extern void ResizeWindowByClientArea(HWND hwnd, int width, int height); - -/* Emulator start/stop support functions. */ -extern void do_start(void); -extern void do_stop(void); - -/* Internal platform support functions. */ -extern int has_language_changed(uint32_t id); -extern void set_language(uint32_t id); -extern int get_vidpause(void); -extern void show_cursor(int); - -extern void keyboard_getkeymap(void); -extern void keyboard_handle(PRAWINPUT raw); - -extern void win_mouse_init(void); -extern void win_mouse_close(void); -extern void win_mouse_handle(PRAWINPUT raw); - -extern void win_joystick_handle(PRAWINPUT raw); - -extern void win_notify_dlg_open(void); -extern void win_notify_dlg_closed(void); -extern int win_get_dpi(HWND hwnd); -extern int win_get_system_metrics(int i, int dpi); - -extern LPARAM win_get_string(int id); - -extern void win_clear_icon_set(void); -extern void win_system_icon_set(void); -extern void win_load_icon_set(void); -extern void win_get_icons_path(char *path_root); - -extern intptr_t fdd_type_to_icon(int type); - -#ifdef EMU_DEVICE_H -extern uint8_t deviceconfig_open(HWND hwnd, const device_t *device); -extern uint8_t deviceconfig_inst_open(HWND hwnd, const device_t *device, int inst); -#endif -extern uint8_t joystickconfig_open(HWND hwnd, int joy_nr, int type); - -extern int getfile(HWND hwnd, char *f, char *fn); -extern int getsfile(HWND hwnd, char *f, char *fn); - -extern void hard_disk_add_open(HWND hwnd, int is_existing); -extern int hard_disk_was_added(void); - -/* Platform UI support functions. */ -extern int ui_init(int nCmdShow); - -/* Functions in win_about.c: */ -extern void AboutDialogCreate(HWND hwnd); - -/* Functions in win_snd_gain.c: */ -extern void SoundGainDialogCreate(HWND hwnd); - -/* Functions in win_new_floppy.c: */ -extern void NewFloppyDialogCreate(HWND hwnd, int id, int part); - -/* Functions in win_specify_dim.c: */ -extern void SpecifyDimensionsDialogCreate(HWND hwnd); - -/* Functions in win_preferences.c: */ -extern void PreferencesDlgCreate(HWND hwnd); - -/* Functions in win_settings.c: */ -#define SETTINGS_PAGE_MACHINE 0 -#define SETTINGS_PAGE_VIDEO 1 -#define SETTINGS_PAGE_INPUT 2 -#define SETTINGS_PAGE_SOUND 3 -#define SETTINGS_PAGE_NETWORK 4 -#define SETTINGS_PAGE_PORTS 5 -#define SETTINGS_PAGE_STORAGE 6 -#define SETTINGS_PAGE_HARD_DISKS 7 -#define SETTINGS_PAGE_FLOPPY_AND_CDROM_DRIVES 8 -#define SETTINGS_PAGE_OTHER_REMOVABLE_DEVICES 9 -#define SETTINGS_PAGE_PERIPHERALS 10 - -extern void win_settings_open(HWND hwnd); -extern void win_settings_open_ex(HWND hwnd, int category); - -/* Functions in win_stbar.c: */ -extern HWND hwndSBAR; -extern void StatusBarCreate(HWND hwndParent, uintptr_t idStatus, HINSTANCE hInst); -extern int MediaMenuHandler(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); - -/* Functions in win_toolbar.c */ -extern HWND hwndRebar; -extern void ToolBarCreate(HWND hwndParent, HINSTANCE hInst); -extern void ToolBarLoadIcons(void); -extern void ToolBarUpdatePause(int paused); - -/* Functions in win_dialog.c: */ -/* Pass NULL in the title param to use the default title. */ -extern int file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, WCHAR *title, int save); -extern int file_dlg(HWND hwnd, WCHAR *f, char *fn, char *title, int save); -extern int file_dlg_mb(HWND hwnd, char *f, char *fn, char *title, int save); -extern int file_dlg_w_st(HWND hwnd, int i, WCHAR *fn, char *title, int save); -extern int file_dlg_st(HWND hwnd, int i, char *fn, char *title, int save); - -extern wchar_t *BrowseFolder(wchar_t *saved_path, wchar_t *title); - -/* Functions in win_media_menu.c */ -extern void media_menu_init(void); -extern void media_menu_reset(void); -extern int media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); -extern HMENU media_menu_get_cassette(void); -extern HMENU media_menu_get_cartridge(int id); -extern HMENU media_menu_get_floppy(int id); -extern HMENU media_menu_get_cdrom(int id); -extern HMENU media_menu_get_zip(int id); -extern HMENU media_menu_get_mo(int id); -extern void media_menu_update_cassette(void); -extern void media_menu_update_cartridge(int id); -extern void media_menu_update_floppy(int id); -extern void media_menu_update_cdrom(int id); -extern void media_menu_update_zip(int id); -extern void media_menu_update_mo(int id); - -/* Functions in win_ui.c */ -extern HMENU menuMain; -extern void ResetAllMenus(void); - -#ifdef __cplusplus -} -#endif - #endif /*PLAT_WIN_H*/ diff --git a/src/include/86box/win_opengl.h b/src/include/86box/win_opengl.h deleted file mode 100644 index d354131ef..000000000 --- a/src/include/86box/win_opengl.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Header file for OpenGL rendering module - * - * Authors: Teemu Korhonen - * - * Copyright 2021 Teemu Korhonen - */ - -#ifndef WIN_OPENGL_H -#define WIN_OPENGL_H - -#define UNICODE -#include - -extern int opengl_init(HWND hwnd); -extern int opengl_pause(void); -extern void opengl_close(void); -extern void opengl_set_fs(int fs); -extern void opengl_resize(int w, int h); -extern void opengl_reload(void); - -#endif /*!WIN_OPENGL_H*/ diff --git a/src/include/86box/win_opengl_glslp.h b/src/include/86box/win_opengl_glslp.h deleted file mode 100644 index 6586cd526..000000000 --- a/src/include/86box/win_opengl_glslp.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Header file for shader file parser. - * - * Authors: Teemu Korhonen - * - * Copyright 2021 Teemu Korhonen - */ - -#ifndef WIN_OPENGL_GLSLP_H -#define WIN_OPENGL_GLSLP_H - -#include - -GLuint load_custom_shaders(const char *path); -GLuint load_default_shaders(void); - -#endif /*!WIN_OPENGL_GLSLP_H*/ diff --git a/src/include/86box/win_sdl.h b/src/include/86box/win_sdl.h deleted file mode 100644 index 69340e8b6..000000000 --- a/src/include/86box/win_sdl.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Definitions for the libSDL2 rendering module. - * - * - * - * Authors: Fred N. van Kempen, - * Michael Drüing, - * - * Copyright 2018-2019 Fred N. van Kempen. - * Copyright 2018-2019 Michael Drüing. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WIN_SDL_H -#define WIN_SDL_H - -extern void sdl_close(void); -extern int sdl_inits(HWND h); -extern int sdl_inith(HWND h); -extern int sdl_initho(HWND h); -extern int sdl_pause(void); -extern void sdl_resize(int x, int y); -extern void sdl_enable(int enable); -extern void sdl_set_fs(int fs); -extern void sdl_reload(void); - -#endif /*WIN_SDL_H*/ diff --git a/src/include_make/86box/version.h b/src/include_make/86box/version.h deleted file mode 100644 index 4bb6c71d7..000000000 --- a/src/include_make/86box/version.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Definitions for project version, branding, and external links. - * - * - * - * Authors: Miran Grca, - * - * Copyright 2020 Miran Grca. - */ - -#define _LSTR(s) L ## s -#define LSTR(s) _LSTR(s) - -/* Version info. */ -#define EMU_NAME "86Box" -#define EMU_NAME_W LSTR(EMU_NAME) - -#define EMU_VERSION "4.1.1" -#define EMU_VERSION_W LSTR(EMU_VERSION) -#define EMU_VERSION_EX "3.50" /* frozen due to IDE re-detection behavior on Windows */ -#define EMU_VERSION_MAJ 4 -#define EMU_VERSION_MIN 1 -#define EMU_VERSION_PATCH 1 - -#define EMU_BUILD_NUM 0 - -#define EMU_VERSION_FULL EMU_VERSION -#define EMU_VERSION_FULL_W EMU_VERSION_W - -#define COPYRIGHT_YEAR "2024" - -/* Web URL info. */ -#define EMU_SITE "86box.net" -#define EMU_SITE_W LSTR(EMU_SITE) -#define EMU_ROMS_URL "https://github.com/86Box/roms/releases/latest" -#define EMU_ROMS_URL_W LSTR(EMU_ROMS_URL) -#ifdef RELEASE_BUILD -# define EMU_DOCS_URL "https://86box.readthedocs.io/en/v4.1/" -#else -# define EMU_DOCS_URL "https://86box.readthedocs.io" -#endif -#define EMU_DOCS_URL_W LSTR(EMU_DOCS_URL) From 27e78da4ec9f849b60615c85792d9a5f87ad1737 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 18 Mar 2024 17:10:36 +0100 Subject: [PATCH 690/936] WIP: PAS16. See above, currently very WIP. --- src/include/86box/pit.h | 28 ++- src/include/86box/pit_fast.h | 3 +- src/include/86box/sound.h | 2 - src/pit.c | 117 +++++---- src/pit_fast.c | 67 ++--- src/sound/CMakeLists.txt | 7 +- src/sound/snd_pas16.c | 475 ++++++++++++++++++----------------- src/sound/sound.c | 2 - 8 files changed, 381 insertions(+), 320 deletions(-) diff --git a/src/include/86box/pit.h b/src/include/86box/pit.h index d288b7e6c..078694633 100644 --- a/src/include/86box/pit.h +++ b/src/include/86box/pit.h @@ -42,6 +42,7 @@ typedef struct ctr_t { int state; int null_count; int do_read_status; + int enable; union { int32_t count; @@ -57,7 +58,7 @@ typedef struct ctr_t { uint32_t l; void (*load_func)(uint8_t new_m, int new_count); - void (*out_func)(int new_out, int old_out); + void (*out_func)(int new_out, int old_out, void *priv); } ctr_t; typedef struct PIT { @@ -68,8 +69,12 @@ typedef struct PIT { ctr_t counters[3]; uint8_t ctrl; + void *dev_priv; + void (*dev_timer)(void *priv); } pit_t; +extern pit_t *ext_pit; + enum { PIT_8253 = 0, PIT_8254 = 1, @@ -87,7 +92,7 @@ typedef struct pit_intf_t { /* Sets if a counter's CLOCK input is from the timer or not - used by PCjr. */ void (*set_using_timer)(void *data, int counter_id, int using_timer); /* Sets a counter's OUT output handler. */ - void (*set_out_func)(void *data, int counter_id, void (*func)(int new_out, int old_out)); + void (*set_out_func)(void *data, int counter_id, void (*func)(int new_out, int old_out, void *priv)); /* Sets a counter's load count handler. */ void (*set_load_func)(void *data, int counter_id, void (*func)(uint8_t new_m, int new_count)); void (*ctr_clock)(void *data, int counter_id); @@ -113,20 +118,24 @@ extern uint64_t RTCCONST; extern int refresh_at_enable; /* Sets a counter's CLOCK input. */ -extern void pit_ctr_set_clock(ctr_t *ctr, int clock); +extern void pit_ctr_set_clock(ctr_t *ctr, int clock, void *priv); -extern pit_t *pit_common_init(int type, void (*out0)(int new_out, int old_out), void (*out1)(int new_out, int old_out)); +extern void pit_ctr_set_out_func(void *data, int counter_id, void (*func)(int new_out, int old_out, void *priv)); + +extern void pit_ctr_set_using_timer(void *data, int counter_id, int using_timer); + +extern pit_t *pit_common_init(int type, void (*out0)(int new_out, int old_out, void *priv), void (*out1)(int new_out, int old_out, void *priv)); extern pit_t *pit_ps2_init(int type); extern void pit_reset(pit_t *dev); -extern void pit_irq0_timer_ps2(int new_out, int old_out); +extern void pit_irq0_timer_ps2(int new_out, int old_out, void *priv); -extern void pit_refresh_timer_xt(int new_out, int old_out); -extern void pit_refresh_timer_at(int new_out, int old_out); +extern void pit_refresh_timer_xt(int new_out, int old_out, void *priv); +extern void pit_refresh_timer_at(int new_out, int old_out, void *priv); -extern void pit_speaker_timer(int new_out, int old_out); +extern void pit_speaker_timer(int new_out, int old_out, void *priv); -extern void pit_nmi_timer_ps2(int new_out, int old_out); +extern void pit_nmi_timer_ps2(int new_out, int old_out, void *priv); extern void pit_set_clock(uint32_t clock); extern void pit_handler(int set, uint16_t base, int size, void *priv); @@ -135,6 +144,7 @@ extern uint8_t pit_read_reg(void *priv, uint8_t reg); #ifdef EMU_DEVICE_H extern const device_t i8253_device; +extern const device_t i8253_ext_io_device; extern const device_t i8254_device; extern const device_t i8254_sec_device; extern const device_t i8254_ext_io_device; diff --git a/src/include/86box/pit_fast.h b/src/include/86box/pit_fast.h index 2485a360c..845105185 100644 --- a/src/include/86box/pit_fast.h +++ b/src/include/86box/pit_fast.h @@ -59,7 +59,8 @@ typedef struct ctrf_t { pc_timer_t timer; void (*load_func)(uint8_t new_m, int new_count); - void (*out_func)(int new_out, int old_out); + void (*out_func)(int new_out, int old_out, void *priv); + void *priv; } ctrf_t; typedef struct pitf_t { diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index b8f9be5b2..0359c0ff8 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -123,10 +123,8 @@ extern const device_t cms_device; /* Gravis UltraSound and UltraSound Max */ extern const device_t gus_device; -# if defined(DEV_BRANCH) && defined(USE_PAS16) /* Pro Audio Spectrum 16 */ extern const device_t pas16_device; -# endif /* IBM PS/1 Audio Card */ extern const device_t ps1snd_device; diff --git a/src/pit.c b/src/pit.c index 6045fd842..4f64d40c1 100644 --- a/src/pit.c +++ b/src/pit.c @@ -94,13 +94,15 @@ pit_log(const char *fmt, ...) #endif static void -ctr_set_out(ctr_t *ctr, int out) +ctr_set_out(ctr_t *ctr, int out, void *priv) { + pit_t *pit = (pit_t *)priv; + if (ctr == NULL) return; if (ctr->out_func != NULL) - ctr->out_func(out, ctr->out); + ctr->out_func(out, ctr->out, pit); ctr->out = out; } @@ -146,8 +148,9 @@ ctr_load_count(ctr_t *ctr) } static void -ctr_tick(ctr_t *ctr) +ctr_tick(ctr_t *ctr, void *priv) { + pit_t *pit = (pit_t *)priv; uint8_t state = ctr->state; if ((state & 0x03) == 0x01) { @@ -155,7 +158,7 @@ ctr_tick(ctr_t *ctr) ctr_load_count(ctr); ctr->state++; if (((ctr->m & 0x07) == 0x01) && (ctr->state == 2)) - ctr_set_out(ctr, 0); + ctr_set_out(ctr, 0, pit); } else switch (ctr->m & 0x07) { case 0: /* Interrupt on terminal count */ @@ -165,7 +168,7 @@ ctr_tick(ctr_t *ctr) ctr_decrease_count(ctr); if (ctr->count < 1) { ctr->state = 3; - ctr_set_out(ctr, 1); + ctr_set_out(ctr, 1, pit); } } break; @@ -185,7 +188,7 @@ ctr_tick(ctr_t *ctr) ctr_decrease_count(ctr); if (ctr->count < 1) { ctr->state = 3; - ctr_set_out(ctr, 1); + ctr_set_out(ctr, 1, pit); } } break; @@ -205,7 +208,7 @@ ctr_tick(ctr_t *ctr) case 3: ctr_load_count(ctr); ctr->state = 2; - ctr_set_out(ctr, 1); + ctr_set_out(ctr, 1, pit); break; case 2: if (ctr->gate == 0) @@ -214,7 +217,7 @@ ctr_tick(ctr_t *ctr) ctr_decrease_count(ctr); if (ctr->count < 2) { ctr->state = 3; - ctr_set_out(ctr, 0); + ctr_set_out(ctr, 0, pit); } } break; @@ -240,7 +243,7 @@ ctr_tick(ctr_t *ctr) if (ctr->count < 0) { ctr_load_count(ctr); ctr->state = 3; - ctr_set_out(ctr, 0); + ctr_set_out(ctr, 0, pit); } else if (ctr->newcount) ctr->newcount = 0; } @@ -259,7 +262,7 @@ ctr_tick(ctr_t *ctr) if (ctr->count < 0) { ctr_load_count(ctr); ctr->state = 2; - ctr_set_out(ctr, 1); + ctr_set_out(ctr, 1, pit); } else if (ctr->newcount) ctr->newcount = 0; } @@ -284,13 +287,13 @@ ctr_tick(ctr_t *ctr) ctr_decrease_count(ctr); if (ctr->count < 1) { ctr->state = 3; - ctr_set_out(ctr, 0); + ctr_set_out(ctr, 0, pit); } } break; case 3: ctr->state = 0; - ctr_set_out(ctr, 1); + ctr_set_out(ctr, 1, pit); break; default: @@ -316,7 +319,7 @@ ctr_clock(void *data, int counter_id) if (ctr->using_timer) return; - ctr_tick(ctr); + ctr_tick(ctr, pit); } static void @@ -351,7 +354,7 @@ ctr_load(ctr_t *ctr) if (ctr->load_func != NULL) ctr->load_func(ctr->m, ctr->l ? ctr->l : 0x10000); - pit_log("Counter loaded, state = %i, gate = %i\n", ctr->state, ctr->gate); + pclog("Counter loaded, state = %i, gate = %i, latch = %i\n", ctr->state, ctr->gate, ctr->latch); } static __inline void @@ -390,7 +393,7 @@ ctr_latch_count(ctr_t *ctr) break; } - pit_log("latched counter = %04X\n", ctr->rl & 0xffff); + pclog("rm = %x, latched counter = %04X\n", ctr->rm & 0x03, ctr->rl & 0xffff); } uint16_t @@ -415,7 +418,7 @@ pit_ctr_set_load_func(void *data, int counter_id, void (*func)(uint8_t new_m, in } void -pit_ctr_set_out_func(void *data, int counter_id, void (*func)(int new_out, int old_out)) +pit_ctr_set_out_func(void *data, int counter_id, void (*func)(int new_out, int old_out, void *priv)) { if (data == NULL) return; @@ -448,14 +451,14 @@ pit_ctr_set_gate(void *data, int counter_id, int gate) /* Here we handle the rising edges. */ if (mode & 1) { if (mode != 1) - ctr_set_out(ctr, 1); + ctr_set_out(ctr, 1, pit); ctr->state = 1; } else if (mode == 2) ctr->state = 3; } else if (old && !gate) { /* Here we handle the lowering edges. */ if (mode & 2) - ctr_set_out(ctr, 1); + ctr_set_out(ctr, 1, pit); } break; @@ -465,8 +468,9 @@ pit_ctr_set_gate(void *data, int counter_id, int gate) } static __inline void -pit_ctr_set_clock_common(ctr_t *ctr, int clock) +pit_ctr_set_clock_common(ctr_t *ctr, int clock, void *priv) { + pit_t *pit = (pit_t *)priv; int old = ctr->clock; ctr->clock = clock; @@ -484,18 +488,18 @@ pit_ctr_set_clock_common(ctr_t *ctr, int clock) ctr->s1_det++; /* Falling edge. */ if (ctr->s1_det >= 2) { ctr->s1_det = 0; - ctr_tick(ctr); + ctr_tick(ctr, pit); } } } else if (old && !ctr->clock) - ctr_tick(ctr); + ctr_tick(ctr, pit); } } void -pit_ctr_set_clock(ctr_t *ctr, int clock) +pit_ctr_set_clock(ctr_t *ctr, int clock, void *priv) { - pit_ctr_set_clock_common(ctr, clock); + pit_ctr_set_clock_common(ctr, clock, priv); } void @@ -516,7 +520,10 @@ pit_timer_over(void *priv) dev->clock ^= 1; for (uint8_t i = 0; i < 3; i++) - pit_ctr_set_clock_common(&dev->counters[i], dev->clock); + pit_ctr_set_clock_common(&dev->counters[i], dev->clock, dev); + + if (dev->dev_timer != NULL) + dev->dev_timer(dev); timer_advance_u64(&dev->callback_timer, PITCONST >> 1ULL); } @@ -528,7 +535,8 @@ pit_write(uint16_t addr, uint8_t val, void *priv) int t = (addr & 3); ctr_t *ctr; - pit_log("[%04X:%08X] pit_write(%04X, %02X, %08X)\n", CS, cpu_state.pc, addr, val, priv); + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + pclog("[%04X:%08X] pit_write(%04X, %02X, %08X)\n", CS, cpu_state.pc, addr, val, priv); switch (addr & 3) { case 3: /* control */ @@ -544,7 +552,8 @@ pit_write(uint16_t addr, uint8_t val, void *priv) ctr_latch_count(&dev->counters[1]); if (val & 8) ctr_latch_count(&dev->counters[2]); - pit_log("PIT %i: Initiated readback command\n", t); + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + pclog("PIT %i: Initiated readback command\n", t); } if (!(val & 0x10)) { if (val & 2) @@ -561,7 +570,8 @@ pit_write(uint16_t addr, uint8_t val, void *priv) if (!(dev->ctrl & 0x30)) { ctr_latch_count(ctr); - pit_log("PIT %i: Initiated latched read, %i bytes latched\n", + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + pclog("PIT %i: Initiated latched read, %i bytes latched\n", t, ctr->latched); } else { ctr->ctrl = val; @@ -571,14 +581,16 @@ pit_write(uint16_t addr, uint8_t val, void *priv) ctr->m &= 3; ctr->null_count = 1; ctr->bcd = (ctr->ctrl & 0x01); - ctr_set_out(ctr, !!ctr->m); + ctr_set_out(ctr, !!ctr->m, dev); ctr->state = 0; if (ctr->latched) { - pit_log("PIT %i: Reload while counter is latched\n", t); + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + pclog("PIT %i: Reload while counter is latched\n", t); ctr->rl--; } - pit_log("PIT %i: M = %i, RM/WM = %i, State = %i, Out = %i\n", t, ctr->m, ctr->rm, ctr->state, ctr->out); + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + pclog("PIT %i: M = %i, RM/WM = %i, State = %i, Out = %i\n", t, ctr->m, ctr->rm, ctr->state, ctr->out); } } break; @@ -595,30 +607,31 @@ pit_write(uint16_t addr, uint8_t val, void *priv) case 1: ctr->l = val; if (ctr->m == 0) - ctr_set_out(ctr, 0); + ctr_set_out(ctr, 0, dev); ctr_load(ctr); break; case 2: ctr->l = (val << 8); if (ctr->m == 0) - ctr_set_out(ctr, 0); + ctr_set_out(ctr, 0, dev); ctr_load(ctr); break; case 3: case 0x83: if (ctr->wm & 0x80) { ctr->l = (ctr->l & 0x00ff) | (val << 8); - pit_log("PIT %i: Written high byte %02X, latch now %04X\n", t, val, ctr->l); + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + pclog("PIT %i: Written high byte %02X, latch now %04X\n", t, val, ctr->l); ctr_load(ctr); } else { ctr->l = (ctr->l & 0xff00) | val; - pit_log("PIT %i: Written low byte %02X, latch now %04X\n", t, val, ctr->l); + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + pclog("PIT %i: Written low byte %02X, latch now %04X\n", t, val, ctr->l); if (ctr->m == 0) { ctr->state = 0; - ctr_set_out(ctr, 0); + ctr_set_out(ctr, 0, dev); } } - if (ctr->wm & 0x80) ctr->wm &= ~0x80; else @@ -749,13 +762,14 @@ pit_read(uint16_t addr, void *priv) break; } - pit_log("[%04X:%08X] pit_read(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret); + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + pclog("[%04X:%08X] pit_read(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret); return ret; } void -pit_irq0_timer_ps2(int new_out, int old_out) +pit_irq0_timer_ps2(int new_out, int old_out, UNUSED(void *priv)) { if (new_out && !old_out) { picint(1); @@ -770,21 +784,21 @@ pit_irq0_timer_ps2(int new_out, int old_out) } void -pit_refresh_timer_xt(int new_out, int old_out) +pit_refresh_timer_xt(int new_out, int old_out, UNUSED(void *priv)) { if (new_out && !old_out) dma_channel_read(0); } void -pit_refresh_timer_at(int new_out, int old_out) +pit_refresh_timer_at(int new_out, int old_out, UNUSED(void *priv)) { if (refresh_at_enable && new_out && !old_out) ppi.pb ^= 0x10; } void -pit_speaker_timer(int new_out, UNUSED(int old_out)) +pit_speaker_timer(int new_out, UNUSED(int old_out), UNUSED(void *priv)) { int l; @@ -804,7 +818,7 @@ pit_speaker_timer(int new_out, UNUSED(int old_out)) } void -pit_nmi_timer_ps2(int new_out, UNUSED(int old_out)) +pit_nmi_timer_ps2(int new_out, UNUSED(int old_out), UNUSED(void *priv)) { nmi = new_out; @@ -882,6 +896,9 @@ pit_init(const device_t *info) pit_read, NULL, NULL, pit_write, NULL, NULL, dev); } + dev->dev_priv = NULL; + dev->dev_timer = NULL; + return dev; } @@ -899,6 +916,20 @@ const device_t i8253_device = { .config = NULL }; +const device_t i8253_ext_io_device = { + .name = "Intel 8253 Programmable Interval Timer (External I/O)", + .internal_name = "i8253_ext_io", + .flags = DEVICE_ISA, + .local = PIT_8253 | PIT_EXT_IO, + .init = pit_init, + .close = pit_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t i8254_device = { .name = "Intel 8254 Programmable Interval Timer", .internal_name = "i8254", @@ -956,7 +987,7 @@ const device_t i8254_ps2_device = { }; pit_t * -pit_common_init(int type, void (*out0)(int new_out, int old_out), void (*out1)(int new_out, int old_out)) +pit_common_init(int type, void (*out0)(int new_out, int old_out, void *priv), void (*out1)(int new_out, int old_out, void *priv)) { void *pit; diff --git a/src/pit_fast.c b/src/pit_fast.c index f9d055375..9c5d622ec 100644 --- a/src/pit_fast.c +++ b/src/pit_fast.c @@ -66,13 +66,15 @@ pit_log(const char *fmt, ...) #endif static void -pitf_ctr_set_out(ctrf_t *ctr, int out) +pitf_ctr_set_out(ctrf_t *ctr, int out, void *priv) { + pitf_t *pit = (pitf_t *)priv; + if (ctr == NULL) return; if (ctr->out_func != NULL) - ctr->out_func(out, ctr->out); + ctr->out_func(out, ctr->out, pit); ctr->out = out; } @@ -98,7 +100,7 @@ pitf_ctr_get_count(void *data, int counter_id) } static void -pitf_ctr_set_out_func(void *data, int counter_id, void (*func)(int new_out, int old_out)) +pitf_ctr_set_out_func(void *data, int counter_id, void (*func)(int new_out, int old_out, void *priv)) { if (data == NULL) return; @@ -154,8 +156,9 @@ pitf_dump_and_disable_timer(ctrf_t *ctr) } static void -pitf_ctr_load(ctrf_t *ctr) +pitf_ctr_load(ctrf_t *ctr, void *priv) { + pitf_t *pit = (pitf_t *)priv; int l = ctr->l ? ctr->l : 0x10000; ctr->newcount = 0; @@ -166,7 +169,7 @@ pitf_ctr_load(ctrf_t *ctr) ctr->count = l; if (ctr->using_timer) timer_set_delay_u64(&ctr->timer, (uint64_t) (l * PITCONST)); - pitf_ctr_set_out(ctr, 0); + pitf_ctr_set_out(ctr, 0, pit); ctr->thit = 0; ctr->enabled = ctr->gate; break; @@ -178,7 +181,7 @@ pitf_ctr_load(ctrf_t *ctr) ctr->count = l - 1; if (ctr->using_timer) timer_set_delay_u64(&ctr->timer, (uint64_t) ((l - 1) * PITCONST)); - pitf_ctr_set_out(ctr, 1); + pitf_ctr_set_out(ctr, 1, pit); ctr->thit = 0; } ctr->enabled = ctr->gate; @@ -188,7 +191,7 @@ pitf_ctr_load(ctrf_t *ctr) ctr->count = l; if (ctr->using_timer) timer_set_delay_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * PITCONST)); - pitf_ctr_set_out(ctr, 1); + pitf_ctr_set_out(ctr, 1, pit); ctr->thit = 0; } ctr->enabled = ctr->gate; @@ -200,7 +203,7 @@ pitf_ctr_load(ctrf_t *ctr) ctr->count = l; if (ctr->using_timer) timer_set_delay_u64(&ctr->timer, (uint64_t) (l * PITCONST)); - pitf_ctr_set_out(ctr, 0); + pitf_ctr_set_out(ctr, 0, pit); ctr->thit = 0; } ctr->enabled = ctr->gate; @@ -223,8 +226,9 @@ pitf_ctr_load(ctrf_t *ctr) } static void -pitf_set_gate_no_timer(ctrf_t *ctr, int gate) +pitf_set_gate_no_timer(ctrf_t *ctr, int gate, void *priv) { + pitf_t *pit = (pitf_t *)priv; int l = ctr->l ? ctr->l : 0x10000; if (ctr->disabled) { @@ -245,7 +249,7 @@ pitf_set_gate_no_timer(ctrf_t *ctr, int gate) ctr->count = l; if (ctr->using_timer) timer_set_delay_u64(&ctr->timer, (uint64_t) (l * PITCONST)); - pitf_ctr_set_out(ctr, 0); + pitf_ctr_set_out(ctr, 0, pit); ctr->thit = 0; ctr->enabled = 1; } @@ -255,7 +259,7 @@ pitf_set_gate_no_timer(ctrf_t *ctr, int gate) ctr->count = l - 1; if (ctr->using_timer) timer_set_delay_u64(&ctr->timer, (uint64_t) (l * PITCONST)); - pitf_ctr_set_out(ctr, 1); + pitf_ctr_set_out(ctr, 1, pit); ctr->thit = 0; } ctr->enabled = gate; @@ -265,7 +269,7 @@ pitf_set_gate_no_timer(ctrf_t *ctr, int gate) ctr->count = l; if (ctr->using_timer) timer_set_delay_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * PITCONST)); - pitf_ctr_set_out(ctr, 1); + pitf_ctr_set_out(ctr, 1, pit); ctr->thit = 0; } ctr->enabled = gate; @@ -291,12 +295,13 @@ pitf_ctr_set_gate(void *data, int counter_id, int gate) return; } - pitf_set_gate_no_timer(ctr, gate); + pitf_set_gate_no_timer(ctr, gate, pit); } static void -pitf_over(ctrf_t *ctr) +pitf_over(ctrf_t *ctr, void *priv) { + pitf_t *pit = (pitf_t *)priv; int l = ctr->l ? ctr->l : 0x10000; if (ctr->disabled) { ctr->count += 0xffff; @@ -309,7 +314,7 @@ pitf_over(ctrf_t *ctr) case 0: /*Interrupt on terminal count*/ case 1: /*Hardware retriggerable one-shot*/ if (!ctr->thit) - pitf_ctr_set_out(ctr, 1); + pitf_ctr_set_out(ctr, 1, pit); ctr->thit = 1; ctr->count += 0xffff; if (ctr->using_timer) @@ -319,17 +324,17 @@ pitf_over(ctrf_t *ctr) ctr->count += l; if (ctr->using_timer) timer_advance_u64(&ctr->timer, (uint64_t) (l * PITCONST)); - pitf_ctr_set_out(ctr, 0); - pitf_ctr_set_out(ctr, 1); + pitf_ctr_set_out(ctr, 0, pit); + pitf_ctr_set_out(ctr, 1, pit); break; case 3: /*Square wave mode*/ if (ctr->out) { - pitf_ctr_set_out(ctr, 0); + pitf_ctr_set_out(ctr, 0, pit); ctr->count += (l >> 1); if (ctr->using_timer) timer_advance_u64(&ctr->timer, (uint64_t) ((l >> 1) * PITCONST)); } else { - pitf_ctr_set_out(ctr, 1); + pitf_ctr_set_out(ctr, 1, pit); ctr->count += ((l + 1) >> 1); if (ctr->using_timer) timer_advance_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * PITCONST)); @@ -341,8 +346,8 @@ pitf_over(ctrf_t *ctr) break; case 4: /*Software triggered strove*/ if (!ctr->thit) { - pitf_ctr_set_out(ctr, 0); - pitf_ctr_set_out(ctr, 1); + pitf_ctr_set_out(ctr, 0, pit); + pitf_ctr_set_out(ctr, 1, pit); } if (ctr->newcount) { ctr->newcount = 0; @@ -358,8 +363,8 @@ pitf_over(ctrf_t *ctr) break; case 5: /*Hardware triggered strove*/ if (!ctr->thit) { - pitf_ctr_set_out(ctr, 0); - pitf_ctr_set_out(ctr, 1); + pitf_ctr_set_out(ctr, 0, pit); + pitf_ctr_set_out(ctr, 1, pit); } ctr->thit = 1; ctr->count += 0xffff; @@ -453,9 +458,9 @@ pitf_write(uint16_t addr, uint8_t val, void *priv) ctr->rereadlatch = 1; ctr->initial = 1; if (!ctr->m) - pitf_ctr_set_out(ctr, 0); + pitf_ctr_set_out(ctr, 0, dev); else - pitf_ctr_set_out(ctr, 1); + pitf_ctr_set_out(ctr, 1, dev); ctr->disabled = 1; pit_log("PIT %i: M = %i, RM/WM = %i, State = %i, Out = %i\n", t, ctr->m, ctr->rm, ctr->state, ctr->out); @@ -472,16 +477,16 @@ pitf_write(uint16_t addr, uint8_t val, void *priv) switch (ctr->wm) { case 1: ctr->l = val; - pitf_ctr_load(ctr); + pitf_ctr_load(ctr, dev); break; case 2: ctr->l = (val << 8); - pitf_ctr_load(ctr); + pitf_ctr_load(ctr, dev); break; case 0: ctr->l &= 0xFF; ctr->l |= (val << 8); - pitf_ctr_load(ctr); + pitf_ctr_load(ctr, dev); ctr->wm = 3; break; case 3: @@ -610,7 +615,8 @@ static void pitf_timer_over(void *priv) { ctrf_t *ctr = (ctrf_t *) priv; - pitf_over(ctr); + pit_t *pit = (pit_t *)ctr->priv; + pitf_over(ctr, pit); } static void @@ -627,7 +633,7 @@ pitf_ctr_clock(void *data, int counter_id) ctr->count -= (ctr->m == 3) ? 2 : 1; if (!ctr->count) - pitf_over(ctr); + pitf_over(ctr, pit); } static void @@ -679,6 +685,7 @@ pitf_init(const device_t *info) if (!(dev->flags & PIT_PS2) && !(dev->flags & PIT_CUSTOM_CLOCK)) { for (int i = 0; i < 3; i++) { ctrf_t *ctr = &dev->counters[i]; + ctr->priv = dev; timer_add(&ctr->timer, pitf_timer_over, (void *) ctr, 0); } } diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index 72f05ff6d..c1bbc811f 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -17,7 +17,7 @@ add_library(snd OBJECT sound.c snd_opl.c snd_opl_nuked.c snd_opl_ymfm.cpp snd_re midi.c snd_speaker.c snd_pssj.c snd_lpt_dac.c snd_ac97_codec.c snd_ac97_via.c snd_lpt_dss.c snd_ps1.c snd_adlib.c snd_adlibgold.c snd_ad1848.c snd_audiopci.c snd_azt2316a.c snd_cms.c snd_cmi8x38.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c - snd_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c + snd_emu8k.c snd_mpu401.c snd_pas16.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c snd_optimc.c) if(OPENAL) @@ -116,11 +116,6 @@ endif() add_subdirectory(ymfm) target_link_libraries(86Box ymfm) -if(PAS16) - target_compile_definitions(snd PRIVATE USE_PAS16) - target_sources(snd PRIVATE snd_pas16.c) -endif() - if(GUSMAX) target_compile_definitions(snd PRIVATE USE_GUSMAX) endif() diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 3ce9b5c4c..32879cd1e 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -12,6 +12,7 @@ #include <86box/dma.h> #include <86box/filters.h> #include <86box/io.h> +#include <86box/midi.h> #include <86box/pic.h> #include <86box/timer.h> #include <86box/pit.h> @@ -132,34 +133,25 @@ typedef struct pas16_t { uint8_t sys_conf_2; uint8_t sys_conf_3; uint8_t sys_conf_4; - - struct { - uint32_t l[3]; - int64_t c[3]; - pc_timer_t timer[3]; - uint8_t m[3]; - uint8_t ctrl; - uint8_t ctrls[2]; - int wp; - int rm[3]; - int wm[3]; - uint16_t rl[3]; - int thit[3]; - int delay[3]; - int rereadlatch[3]; - int64_t enable[3]; - } pit; + uint8_t waitstates; + uint8_t midi_ctrl; + uint8_t midi_stat; + uint8_t midi_data; + uint8_t midi_fifo[16]; fm_drv_t opl; sb_dsp_t dsp; + mpu_t *mpu; int16_t pcm_buffer[2][SOUNDBUFLEN]; int pos; + + int midi_uart_out; + + pit_t *pit; } pas16_t; -static uint8_t pas16_pit_in(uint16_t port, void *priv); -static void pas16_pit_out(uint16_t port, uint8_t val, void *priv); static void pas16_update(pas16_t *pas16); static int pas16_dmas[8] = { 4, 1, 2, 3, 0, 5, 6, 7 }; @@ -169,7 +161,8 @@ static int pas16_sb_dmas[8] = { 0, 1, 2, 3 }; enum { PAS16_INT_SAMP = 0x04, - PAS16_INT_PCM = 0x08 + PAS16_INT_PCM = 0x08, + PAS16_INT_MIDI = 0x10, }; enum { @@ -204,6 +197,96 @@ pas16_log(const char *fmt, ...) # define pas16_log(fmt, ...) #endif +static void +pas16_update_midi_irqs(pas16_t *pas16) +{ + int irq = 0; + + pas16->irq_stat &= ~PAS16_INT_MIDI; + + if ((pas16->uart_status & 0x18) || (dev->uart_status & 0x04)) { + pas16->irq_stat |= PAS16_INT_MIDI; + irq = 1; + } + + if (irq) + picint(1 << pas16->irq); + else + picintc(1 << pas16->irq); +} + +static void +pas16_update_tx_irq(pas16_t *pas16) +{ + pas16->uart_status &= ~0x18; + + if ((pas16->irq_ena & PAS16_INT_MIDI) && (pas16->uart_ctrl & 0x18)) + pas16->uart_status |= 0x18; + + pas16_update_midi_irqs(pas16); +} + +static void +pas16_update_rx_irq(pas16_t *pas16) +{ + pas16->uart_status &= ~0x04; + + if ((pas16->irq_ena & PAS16_INT_MIDI) && (pas16->uart_ctrl & 0x04)) + pas16->uart_status |= 0x04; + + pas16_update_midi_irqs(pas16); +} + +static void +pas16_scan_fifo(pas16_t *pas16) +{ + if (pas16->read_fifo_pos != pas16->write_fifo_pos) { + pas16->uart_data = pas16->uart_fifo[pas16->read_fifo_pos]; + pas16->read_fifo_pos = (pas16->read_fifo_pos + 1) & 0x0f; + + es1371_set_rx_irq(pas16, 1); + } else + es1371_set_rx_irq(pas16, 0); +} + +static void +es1371_write_fifo(es1371_t *dev, uint8_t val) +{ + if (dev->write_fifo_pos < 16) { + dev->uart_fifo[dev->write_fifo_pos] = val | UART_FIFO_BYTE_VALID; + dev->write_fifo_pos = (dev->write_fifo_pos + 1) & 0x0f; + } +} + +static void +es1371_reset_fifo(es1371_t *dev) +{ + for (uint8_t i = 0; i < 16; i++) + dev->uart_fifo[i] = 0x00000000; + + dev->read_fifo_pos = dev->write_fifo_pos = 0; + + es1371_set_rx_irq(dev, 0); +} + +static void +pas16_reset(void *priv) +{ + pas16_t *pas16 = (pas16_t *) priv; + + pas16->uart_status = 0xff; + pas16->uart_ctrl = 0x00; + + for (uint8_t i = 0; i < 16; i++) + pas16->uart_fifo[i] = 0x00; + + pas16_set_tx_irq(pas16, 0); + + pas16_reset_fifo(pas16); + + pas16_update_midi_irqs(pas16); +} + static uint8_t pas16_in(uint16_t port, void *priv) { @@ -230,18 +313,24 @@ pas16_in(uint16_t port, void *priv) break; case 0xb8b: - temp = (pas16->irq_ena & ~0xe0) | 0x20; + temp = pas16->irq_ena & ~0xe0; + temp |= 0x01; break; case 0xf8a: temp = pas16->pcm_ctrl; break; - case 0x1388: - case 0x1389: - case 0x138a: - case 0x138b: - temp = pas16_pit_in(port, pas16); + case 0x1789: + temp = 0; + break; + case 0x178a: + temp = pas16->uart_data; + pas16_set_rx_irq(pas16, 0); + break; + + case 0x1b88: + temp = pas16->uart_status; break; case 0x2789: /*Board revision*/ @@ -249,7 +338,7 @@ pas16_in(uint16_t port, void *priv) break; case 0x7f89: - temp = pas16->enhancedscsi & ~1; + temp = pas16->enhancedscsi & ~0x01; break; case 0x8388: @@ -265,6 +354,10 @@ pas16_in(uint16_t port, void *priv) temp = pas16->sys_conf_4; break; + case 0xbf88: + temp = pas16->waitstates; + break; + case 0xef8b: temp = 0x0c; break; @@ -275,10 +368,10 @@ pas16_in(uint16_t port, void *priv) case 0xf389: temp = pas16->io_conf_2; break; - case 0xf38b: + case 0xf38a: temp = pas16->io_conf_3; break; - case 0xf38c: + case 0xf38b: temp = pas16->io_conf_4; break; @@ -294,7 +387,7 @@ pas16_in(uint16_t port, void *priv) break; case 0xff88: /*Board model*/ - temp = 4; /*PAS16*/ + temp = 0x04; /*PAS16*/ break; case 0xff8b: /*Master mode read*/ temp = 0x20 | 0x10 | 0x01; /*AT bus, XT/AT timing*/ @@ -303,7 +396,7 @@ pas16_in(uint16_t port, void *priv) default: break; } - pas16_log("pas16_in : port %04X return %02X %04X:%04X\n", port, temp, CS, cpu_state.pc); + pclog("pas16_in : port %04X return %02X %04X:%04X\n", port, temp, CS, cpu_state.pc); return temp; } @@ -311,7 +404,8 @@ static void pas16_out(uint16_t port, uint8_t val, void *priv) { pas16_t *pas16 = (pas16_t *) priv; - pas16_log("pas16_out : port %04X val %02X %04X:%04X\n", port, val, CS, cpu_state.pc); + pit_t *pit = (pit_t *) pas16->pit; + pclog("pas16_out : port %04X val %02X %04X:%04X\n", port, val, CS, cpu_state.pc); switch ((port - pas16->base) + 0x388) { case 0x388: case 0x389: @@ -348,14 +442,35 @@ pas16_out(uint16_t port, uint8_t val, void *priv) case 0xf8a: if ((val & PAS16_PCM_ENA) && !(pas16->pcm_ctrl & PAS16_PCM_ENA)) /*Guess*/ pas16->stereo_lr = 0; + pas16->pcm_ctrl = val; break; - case 0x1388: - case 0x1389: - case 0x138a: - case 0x138b: - pas16_pit_out(port, val, pas16); + case 0x1789: + case 0x178b: + pas16->uart_ctrl = val; + + if ((val & 0x60) == 0x60) { + /* Reset TX */ + pas16_set_tx_irq(pas16, 1); + + /* Software reset */ + pas16_reset_fifo(pas16); + } else { + pas16_set_tx_irq(pas16, 1); + + pas16_update_tx_irq(pas16); + pas16_update_rx_irq(pas16); + } + break; + + case 0x178a: + midi_raw_out_byte(val); + pas16_set_tx_irq(pas16, 1); + break; + + case 0x1b88: + pas16->uart_status = val; break; case 0x7f89: @@ -363,6 +478,10 @@ pas16_out(uint16_t port, uint8_t val, void *priv) break; case 0x8388: + if ((val & 0x80) && !(pas16->sys_conf_1 & 0x80)) { + pclog("Reset.\n"); + pas16_reset(pas16); + } pas16->sys_conf_1 = val; break; case 0x8389: @@ -375,18 +494,22 @@ pas16_out(uint16_t port, uint8_t val, void *priv) pas16->sys_conf_4 = val; break; + case 0xbf88: + pas16->waitstates = val; + break; + case 0xf388: pas16->io_conf_1 = val; break; case 0xf389: pas16->io_conf_2 = val; pas16->dma = pas16_dmas[val & 0x7]; - pas16_log("pas16_out : set PAS DMA %i\n", pas16->dma); + pclog("pas16_out : set PAS DMA %i\n", pas16->dma); break; case 0xf38a: pas16->io_conf_3 = val; pas16->irq = pas16_irqs[val & 0xf]; - pas16_log("pas16_out : set PAS IRQ %i\n", pas16->irq); + pclog("pas16_out : set PAS IRQ %i\n", pas16->irq); break; case 0xf38b: pas16->io_conf_4 = val; @@ -398,11 +521,17 @@ pas16_out(uint16_t port, uint8_t val, void *priv) sb_dsp_setaddr(&pas16->dsp, ((pas16->compat_base & 0xf) << 4) | 0x200); else sb_dsp_setaddr(&pas16->dsp, 0); + if (pas16->compat & 0x01) + mpu401_change_addr(pas16->mpu, ((pas16->compat_base & 0xf0) | 0x300)); + else + mpu401_change_addr(pas16->mpu, 0); break; case 0xf789: pas16->compat_base = val; if (pas16->compat & 0x02) sb_dsp_setaddr(&pas16->dsp, ((pas16->compat_base & 0xf) << 4) | 0x200); + if (pas16->compat & 0x01) + mpu401_change_addr(pas16->mpu, ((pas16->compat_base & 0xf0) | 0x300)); break; case 0xfb8a: @@ -413,7 +542,7 @@ pas16_out(uint16_t port, uint8_t val, void *priv) break; default: - pas16_log("pas16_out : unknown %04X\n", port); + pclog("pas16_out : unknown %04X\n", port); } #if 0 if (cpu_state.pc == 0x80048CF3) { @@ -424,167 +553,17 @@ pas16_out(uint16_t port, uint8_t val, void *priv) #endif } + static void -pas16_pit_out(uint16_t port, uint8_t val, void *priv) +pas16_scan_fifo(pas16_t *pas16) { - pas16_t *pas16 = (pas16_t *) priv; - int t; - switch (port & 3) { - case 3: /*CTRL*/ - if ((val & 0xC0) == 0xC0) { - if (!(val & 0x20)) { - if (val & 2) - pas16->pit.rl[0] = timer_get_remaining_u64(&pas16->pit.timer[0]) / PITCONST; - if (val & 4) - pas16->pit.rl[1] = pas16->pit.c[1]; - if (val & 8) - pas16->pit.rl[2] = pas16->pit.c[2]; - } - return; - } - t = val >> 6; - pas16->pit.ctrls[t] = pas16->pit.ctrl = val; - if (t == 3) { - printf("Bad PIT reg select\n"); - return; - } - if (!(pas16->pit.ctrl & 0x30)) { - if (!t) - pas16->pit.rl[t] = timer_get_remaining_u64(&pas16->pit.timer[t]) / PITCONST; - else { - pas16->pit.rl[t] = pas16->pit.c[t]; - if (pas16->pit.c[t] < 0) - pas16->pit.rl[t] = 0; - } - pas16->pit.ctrl |= 0x30; - pas16->pit.rereadlatch[t] = 0; - pas16->pit.rm[t] = 3; - } else { - pas16->pit.rm[t] = pas16->pit.wm[t] = (pas16->pit.ctrl >> 4) & 3; - pas16->pit.m[t] = (val >> 1) & 7; - if (pas16->pit.m[t] > 5) - pas16->pit.m[t] &= 3; - if (!pas16->pit.rm[t]) { - pas16->pit.rm[t] = 3; - if (!t) - pas16->pit.rl[t] = timer_get_remaining_u64(&pas16->pit.timer[t]) / PITCONST; - else - pas16->pit.rl[t] = pas16->pit.c[t]; - } - pas16->pit.rereadlatch[t] = 1; - } - pas16->pit.wp = 0; - pas16->pit.thit[t] = 0; - break; - case 0: - case 1: - case 2: /*Timers*/ - t = port & 3; - switch (pas16->pit.wm[t]) { - case 1: - pas16->pit.l[t] = val; - pas16->pit.thit[t] = 0; - pas16->pit.c[t] = pas16->pit.l[t]; - if (!t) - timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); - pas16->pit.enable[t] = 1; - break; - case 2: - pas16->pit.l[t] = val << 8; - pas16->pit.thit[t] = 0; - pas16->pit.c[t] = pas16->pit.l[t]; - if (!t) - timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); - pas16->pit.enable[t] = 1; - break; - case 0: - pas16->pit.l[t] &= 0xFF; - pas16->pit.l[t] |= (val << 8); - pas16->pit.c[t] = pas16->pit.l[t]; - if (!t) - timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); - pas16->pit.thit[t] = 0; - pas16->pit.wm[t] = 3; - pas16->pit.enable[t] = 1; - break; - case 3: - pas16->pit.l[t] &= 0xFF00; - pas16->pit.l[t] |= val; - pas16->pit.wm[t] = 0; - break; + if (pas16->read_fifo_pos != pas16->write_fifo_pos) { + pas16->uart_data = pas16->uart_fifo[pas16->read_fifo_pos]; + pas16->read_fifo_pos = (pas16->read_fifo_pos + 1) & 7; - default: - break; - } - if (!pas16->pit.l[t]) { - pas16->pit.l[t] |= 0x10000; - pas16->pit.c[t] = pas16->pit.l[t]; - if (!t) - timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); - } - break; - - default: - break; - } -} - -static uint8_t -pas16_pit_in(uint16_t port, void *priv) -{ - pas16_t *pas16 = (pas16_t *) priv; - uint8_t temp = 0xff; - int t = port & 3; - switch (port & 3) { - case 0: - case 1: - case 2: /*Timers*/ - if (pas16->pit.rereadlatch[t]) { - pas16->pit.rereadlatch[t] = 0; - if (!t) { - pas16->pit.rl[t] = timer_get_remaining_u64(&pas16->pit.timer[t]) / PITCONST; - if ((timer_get_remaining_u64(&pas16->pit.timer[t]) / PITCONST) > 65536) - pas16->pit.rl[t] = 0xFFFF; - } else { - pas16->pit.rl[t] = pas16->pit.c[t]; - if (pas16->pit.c[t] > 65536) - pas16->pit.rl[t] = 0xFFFF; - } - } - switch (pas16->pit.rm[t]) { - case 0: - temp = pas16->pit.rl[t] >> 8; - pas16->pit.rm[t] = 3; - pas16->pit.rereadlatch[t] = 1; - break; - case 1: - temp = (pas16->pit.rl[t]) & 0xFF; - pas16->pit.rereadlatch[t] = 1; - break; - case 2: - temp = (pas16->pit.rl[t]) >> 8; - pas16->pit.rereadlatch[t] = 1; - break; - case 3: - temp = (pas16->pit.rl[t]) & 0xFF; - if (pas16->pit.m[t] & 0x80) - pas16->pit.m[t] &= 7; - else - pas16->pit.rm[t] = 0; - break; - - default: - break; - } - break; - case 3: /*Control*/ - temp = pas16->pit.ctrl; - break; - - default: - break; - } - return temp; + pas16_set_rx_irq(pas16, 1); + } else + pas16_set_rx_irq(pas16, 0); } static uint8_t @@ -593,30 +572,34 @@ pas16_readdma(pas16_t *pas16) return dma_channel_read(pas16->dma); } + static void pas16_pcm_poll(void *priv) { - pas16_t *pas16 = (pas16_t *) priv; + pit_t *pit = (pit_t *)priv; + pas16_t *pas16 = (pas16_t *) pit->dev_priv; + uint16_t temp = 0x0000; + pas16_update(pas16); - if (pas16->pit.m[0] & 2) { - if (pas16->pit.l[0]) - timer_advance_u64(&pas16->pit.timer[0], pas16->pit.l[0] * PITCONST); - else - timer_advance_u64(&pas16->pit.timer[0], 0x10000 * PITCONST); - } else { - pas16->pit.enable[0] = 0; + if (pit->counters[0].m & 2) { + if (pit->counters[0].l) + timer_advance_u64(&pit->callback_timer, pit->counters[0].l * (PITCONST << 1ULL)); + else { + timer_advance_u64(&pit->callback_timer, 0x10000 * (PITCONST << 1ULL)); + } } pas16->irq_stat |= PAS16_INT_SAMP; if (pas16->irq_ena & PAS16_INT_SAMP) picint(1 << pas16->irq); + else + picintc(1 << pas16->irq); /*Update sample rate counter*/ - if (pas16->pit.enable[1]) { + pas16_log("Enable (t1) = %d.\n", pit->counters[1].enable); + if (pit->counters[1].enable) { if (pas16->pcm_ctrl & PAS16_PCM_ENA) { - uint16_t temp; - if (pas16->sys_conf_2 & PAS16_SC2_16BIT) { temp = pas16_readdma(pas16) << 8; temp |= pas16_readdma(pas16); @@ -637,29 +620,42 @@ pas16_pcm_poll(void *priv) } } if (pas16->sys_conf_2 & PAS16_SC2_16BIT) - pas16->pit.c[1] -= 2; + pit->counters[1].rl -= 2; else - pas16->pit.c[1]--; - if (pas16->pit.c[1] == 0) { - if (pas16->pit.m[1] & 2) { - if (pas16->pit.l[1]) - pas16->pit.c[1] += pas16->pit.l[1]; + pit->counters[1].rl--; + + pas16_log("RL=%d, mode=%x.\n", pit->counters[1].rl, pit->counters[1].m & 0x03); + if (pit->counters[1].rl == 0xffff) { + if (pit->counters[1].m & 2) { + if (pit->counters[1].l & 0xffff) + pit->counters[1].rl = pit->counters[1].l & 0xffff; else - pas16->pit.c[1] += 0x10000; + pit->counters[1].rl = 0; } else { - pas16->pit.c[1] = -1; - pas16->pit.enable[1] = 0; + pit->counters[1].enable = 0; + pit->counters[1].rl = 0; } + pas16_log("New counter=%d, mode=%x.\n", pit->counters[1].rl, pit->counters[1].m & 0x03); pas16->irq_stat |= PAS16_INT_PCM; if (pas16->irq_ena & PAS16_INT_PCM) { - pas16_log("pas16_pcm_poll : cause IRQ %i %02X\n", pas16->irq, 1 << pas16->irq); + pclog("pas16_pcm_poll : cause IRQ %i %02X, enable timer 1 = %x\n", pas16->irq, 1 << pas16->irq, pit->counters[1].enable); picint(1 << pas16->irq); - } + } else + picintc(1 << pas16->irq); } } } +static void +pas16_pit_timer0(int new_out, int old_out, void *priv) +{ + pit_t *pit = (pit_t *)priv; + pclog("NewOut=%d, OldOut=%d.\n", new_out, old_out); + pit->counters[1].enable = new_out; + pit_ctr_set_clock(&pit->counters[0], new_out, pit); +} + static void pas16_out_base(UNUSED(uint16_t port), uint8_t val, void *priv) { @@ -669,8 +665,9 @@ pas16_out_base(UNUSED(uint16_t port), uint8_t val, void *priv) io_removehandler((pas16->base - 0x388) + 0x0788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); io_removehandler((pas16->base - 0x388) + 0x0b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); io_removehandler((pas16->base - 0x388) + 0x0f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x1388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + pit_handler(0, (pas16->base - 0x388) + 0x1388, 0x0004, pas16->pit); io_removehandler((pas16->base - 0x388) + 0x1788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler((pas16->base - 0x388) + 0x1b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); io_removehandler((pas16->base - 0x388) + 0x2788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); io_removehandler((pas16->base - 0x388) + 0x7f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); io_removehandler((pas16->base - 0x388) + 0x8388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); @@ -685,14 +682,15 @@ pas16_out_base(UNUSED(uint16_t port), uint8_t val, void *priv) io_removehandler((pas16->base - 0x388) + 0xff88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); pas16->base = val << 2; - pas16_log("pas16_write_base : PAS16 base now at %04X\n", pas16->base); + pclog("pas16_write_base : PAS16 base now at %04X\n", pas16->base); io_sethandler((pas16->base - 0x388) + 0x0388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); io_sethandler((pas16->base - 0x388) + 0x0788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); io_sethandler((pas16->base - 0x388) + 0x0b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); io_sethandler((pas16->base - 0x388) + 0x0f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x1388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + pit_handler(1, (pas16->base - 0x388) + 0x1388, 0x0004, pas16->pit); io_sethandler((pas16->base - 0x388) + 0x1788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler((pas16->base - 0x388) + 0x1b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); io_sethandler((pas16->base - 0x388) + 0x2788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); io_sethandler((pas16->base - 0x388) + 0x7f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); io_sethandler((pas16->base - 0x388) + 0x8388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); @@ -759,10 +757,22 @@ pas16_init(UNUSED(const device_t *info)) fm_driver_get(FM_YMF262, &pas16->opl); sb_dsp_init(&pas16->dsp, SB2, SB_SUBTYPE_DEFAULT, pas16); + pas16->mpu = (mpu_t *) malloc(sizeof(mpu_t)); + memset(pas16->mpu, 0, sizeof(mpu_t)); + mpu401_init(pas16->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); + sb_dsp_set_mpu(&pas16->dsp, pas16->mpu); + + pas16->pit = device_add(&i8254_ext_io_device); + + pas16->midi_uart_out = 1; io_sethandler(0x9a01, 0x0001, NULL, NULL, NULL, pas16_out_base, NULL, NULL, pas16); - - timer_add(&pas16->pit.timer[0], pas16_pcm_poll, pas16, 0); + pit_ctr_set_out_func(pas16->pit, 0, pas16_pit_timer0); + pit_ctr_set_using_timer(pas16->pit, 0, 1); + pit_ctr_set_using_timer(pas16->pit, 1, 0); + pit_ctr_set_using_timer(pas16->pit, 2, 0); + pas16->pit->dev_priv = pas16; + pas16->pit->dev_timer = pas16_pcm_poll; sound_add_handler(pas16_get_buffer, pas16); music_add_handler(pas16_get_music_buffer, pas16); @@ -778,10 +788,21 @@ pas16_close(void *priv) free(pas16); } +static const device_config_t pas16_config[] = { + { + .name = "receive_input401", + .description = "Receive input (MPU-401)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + const device_t pas16_device = { .name = "Pro Audio Spectrum 16", .internal_name = "pas16", - .flags = DEVICE_ISA, + .flags = DEVICE_ISA | DEVICE_AT, .local = 0, .init = pas16_init, .close = pas16_close, @@ -789,5 +810,5 @@ const device_t pas16_device = { { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, - .config = NULL + .config = pas16_config }; diff --git a/src/sound/sound.c b/src/sound/sound.c index 81f70d921..50eb984d6 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -149,9 +149,7 @@ static const SOUND_CARD sound_cards[] = { { &sb_vibra16s_device }, { &sb_vibra16xv_device }, { &ssi2001_device }, -#if defined(DEV_BRANCH) && defined(USE_PAS16) { &pas16_device }, -#endif { &pssj_isa_device }, { &tndy_device }, { &wss_device }, From 23ba920bbf105718b0b30ad5d7971e4f83b39339 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 16 Mar 2024 19:53:11 +0500 Subject: [PATCH 691/936] Clean up the plat and ui API Remove functions no longer defined or used on any plat/UI Remove the old non-multi-monitor-aware plat_resize() and rename plat_resize_monitor() to plat_resize() --- src/include/86box/plat.h | 19 +------------------ src/include/86box/ui.h | 6 ------ src/qt/qt_platform.cpp | 17 +++++------------ src/qt/qt_ui.cpp | 12 +++--------- src/unix/unix.c | 16 ++-------------- src/unix/unix_sdl.c | 6 +++--- 6 files changed, 14 insertions(+), 62 deletions(-) diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index 84f0318c2..32f50c638 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -113,7 +113,6 @@ extern int hide_status_bar; extern int hide_tool_bar; /* System-related functions. */ -extern char *fix_exe_path(char *str); extern FILE *plat_fopen(const char *path, const char *mode); extern FILE *plat_fopen64(const char *path, const char *mode); extern void plat_remove(char *path); @@ -129,29 +128,19 @@ extern void *plat_mmap(size_t size, uint8_t executable); extern void plat_munmap(void *ptr, size_t size); extern uint64_t plat_timer_read(void); extern uint32_t plat_get_ticks(void); -extern uint32_t plat_get_micro_ticks(void); extern void plat_delay_ms(uint32_t count); extern void plat_pause(int p); extern void plat_mouse_capture(int on); extern int plat_vidapi(char *name); extern char *plat_vidapi_name(int api); -extern int plat_setvid(int api); -extern void plat_vidsize(int x, int y); -extern void plat_setfullscreen(int on); -extern void plat_resize_monitor(int x, int y, int monitor_index); +extern void plat_resize(int x, int y, int monitor_index); extern void plat_resize_request(int x, int y, int monitor_index); -extern void plat_resize(int x, int y); -extern void plat_vidapi_enable(int enabled); -extern void plat_vidapi_reload(void); -extern void plat_vid_reload_options(void); extern uint32_t plat_language_code(char *langcode); extern void plat_language_code_r(uint32_t lcid, char *outbuf, int len); extern void plat_get_cpu_string(char *outbuf, uint8_t len); -extern double plat_get_dpi(void); extern void plat_set_thread_name(void *thread, const char *name); /* Resource management. */ -extern void set_language(uint32_t id); extern wchar_t *plat_get_string(int id); /* Emulator start/stop support functions. */ @@ -183,17 +172,11 @@ extern void ioctl_close(uint8_t id); /* Other stuff. */ extern void startblit(void); extern void endblit(void); -extern void take_screenshot(void); /* Conversion between UTF-8 and UTF-16. */ extern size_t mbstoc16s(uint16_t dst[], const char src[], int len); extern size_t c16stombs(char dst[], const uint16_t src[], int len); -#ifdef MTR_ENABLED -extern void init_trace(void); -extern void shutdown_trace(void); -#endif - #ifdef __cplusplus } #endif diff --git a/src/include/86box/ui.h b/src/include/86box/ui.h index 9698f896c..c12eb73a0 100644 --- a/src/include/86box/ui.h +++ b/src/include/86box/ui.h @@ -42,9 +42,6 @@ extern "C" { extern int ui_msgbox(int flags, void *message); extern int ui_msgbox_header(int flags, void *header, void *message); -extern int ui_msgbox_ex(int flags, void *header, void *message, void *btn1, void *btn2, void *btn3); - -extern void ui_check_menu_item(int id, int checked); /* Status Bar functions. */ #define SB_ICON_WIDTH 24 @@ -60,16 +57,13 @@ extern void ui_check_menu_item(int id, int checked); #define SB_TEXT 0x90 extern wchar_t *ui_window_title(wchar_t *s); -extern void ui_status_update(void); extern void ui_hard_reset_completed(void); extern void ui_init_monitor(int monitor_index); extern void ui_deinit_monitor(int monitor_index); -extern int ui_sb_find_part(int tag); extern void ui_sb_set_ready(int ready); extern void ui_sb_update_panes(void); extern void ui_sb_update_text(void); extern void ui_sb_update_tip(int meaning); -extern void ui_sb_timer_callback(int pane); extern void ui_sb_update_icon(int tag, int active); extern void ui_sb_update_icon_state(int tag, int state); extern void ui_sb_set_text_w(wchar_t *wstr); diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 824f71023..da97680fa 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -149,6 +149,11 @@ strnicmp(const char *s1, const char *s2, size_t n) #endif } +void +do_start(void) +{ +} + void do_stop(void) { @@ -425,12 +430,6 @@ plat_power_off(void) QTimer::singleShot(0, (const QWidget *) main_window, &QMainWindow::close); } -void -set_language(uint32_t id) -{ - lang_id = id; -} - extern "C++" { QMap> ProgSettings::lcid_langcode = { { 0x0403, { "ca-ES", "Catalan (Spain)" } }, @@ -741,12 +740,6 @@ plat_get_cpu_string(char *outbuf, uint8_t len) { } -double -plat_get_dpi(void) -{ - return util::screenOfWidget(main_window)->devicePixelRatio(); -} - void plat_set_thread_name(void *thread, const char *name) { diff --git a/src/qt/qt_ui.cpp b/src/qt/qt_ui.cpp index 47e6b48a2..b544bbde1 100644 --- a/src/qt/qt_ui.cpp +++ b/src/qt/qt_ui.cpp @@ -95,14 +95,14 @@ plat_resize_request(int w, int h, int monitor_index) if (video_fullscreen || is_quit) return; if (vid_resize & 2) { - plat_resize_monitor(fixed_size_x, fixed_size_y, monitor_index); + plat_resize(fixed_size_x, fixed_size_y, monitor_index); } else { - plat_resize_monitor(w, h, monitor_index); + plat_resize(w, h, monitor_index); } } void -plat_resize_monitor(int w, int h, int monitor_index) +plat_resize(int w, int h, int monitor_index) { if (monitor_index >= 1) main_window->resizeContentsMonitor(w, h, monitor_index); @@ -110,12 +110,6 @@ plat_resize_monitor(int w, int h, int monitor_index) main_window->resizeContents(w, h); } -void -plat_setfullscreen(int on) -{ - main_window->setFullscreen(on > 0 ? true : false); -} - void plat_mouse_capture(int on) { diff --git a/src/unix/unix.c b/src/unix/unix.c index 2a9324307..848ed0f22 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -448,12 +448,6 @@ plat_get_ticks(void) return (uint32_t) (plat_get_ticks_common() / 1000); } -uint32_t -plat_get_micro_ticks(void) -{ - return (uint32_t) plat_get_ticks_common(); -} - void plat_remove(char *path) { @@ -578,9 +572,9 @@ main_thread(void *param) /* If needed, handle a screen resize. */ if (atomic_load(&doresize_monitors[0]) && !video_fullscreen && !is_quit) { if (vid_resize & 2) - plat_resize(fixed_size_x, fixed_size_y); + plat_resize(fixed_size_x, fixed_size_y, 0); else - plat_resize(scrnsz_x, scrnsz_y); + plat_resize(scrnsz_x, scrnsz_y, 0); atomic_store(&doresize_monitors[0], 1); } } @@ -1358,12 +1352,6 @@ plat_vidapi_name(int i) return "default"; } -void -set_language(uint32_t id) -{ - lang_id = id; -} - /* Sets up the program language before initialization. */ uint32_t plat_language_code(char *langcode) diff --git a/src/unix/unix_sdl.c b/src/unix/unix_sdl.c index 3ba8c1ae0..c7cc898be 100644 --- a/src/unix/unix_sdl.c +++ b/src/unix/unix_sdl.c @@ -424,9 +424,9 @@ sdl_init_common(int flags) sdl_set_fs(video_fullscreen); if (!(video_fullscreen & 1)) { if (vid_resize & 2) - plat_resize(fixed_size_x, fixed_size_y); + plat_resize(fixed_size_x, fixed_size_y, 0); else - plat_resize(scrnsz_x, scrnsz_y); + plat_resize(scrnsz_x, scrnsz_y, 0); } if ((vid_resize < 2) && window_remember) { SDL_SetWindowSize(sdl_win, window_w, window_h); @@ -479,7 +479,7 @@ plat_mouse_capture(int on) } void -plat_resize(int w, int h) +plat_resize(int w, int h, UNUSED(int monitor_index)) { SDL_LockMutex(sdl_mutex); resize_w = w; From c5c4dcb2685bf32dcc194938fedaa61c4cb36b1a Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 16 Mar 2024 19:54:03 +0500 Subject: [PATCH 692/936] Remove the unfinished and unused Qt SDL renderer --- src/qt/qt_sdl.c | 708 ------------------------------------------------ src/qt/qt_sdl.h | 72 ----- 2 files changed, 780 deletions(-) delete mode 100644 src/qt/qt_sdl.c delete mode 100644 src/qt/qt_sdl.h diff --git a/src/qt/qt_sdl.c b/src/qt/qt_sdl.c deleted file mode 100644 index 15af4d7b6..000000000 --- a/src/qt/qt_sdl.c +++ /dev/null @@ -1,708 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Rendering module for libSDL2 - * - * NOTE: Given all the problems reported with FULLSCREEN use of SDL, - * we will not use that, but, instead, use a new window which - * covers the entire desktop. - * - * - * - * Authors: Fred N. van Kempen, - * Michael Drüing, - * - * Copyright 2018-2020 Fred N. van Kempen. - * Copyright 2018-2020 Michael Drüing. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include - -#include -#include -#include -#include -/* This #undef is needed because a SDL include header redefines HAVE_STDARG_H. */ -#undef HAVE_STDARG_H -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/mouse.h> -#include <86box/keyboard.h> -#include <86box/device.h> -#include <86box/plat.h> -#include <86box/plat_dynld.h> -#include <86box/video.h> -#include <86box/ui.h> -#include <86box/version.h> - -#include "qt_sdl.h" - -#define RENDERER_FULL_SCREEN 1 -#define RENDERER_HARDWARE 2 -#define RENDERER_OPENGL 4 - -static SDL_Window *sdl_win = NULL; -static SDL_Renderer *sdl_render = NULL; -static SDL_Texture *sdl_tex = NULL; -static int sdl_w; -static int sdl_h; -static int sdl_fs; -static int sdl_flags = -1; -static int cur_w; -static int cur_h; -static int cur_ww = 0; -static int cur_wh = 0; -static volatile int sdl_enabled = 0; -static SDL_mutex *sdl_mutex = NULL; - -static const uint16_t sdl_to_xt[0x200] = { - [SDL_SCANCODE_ESCAPE] = 0x01, - [SDL_SCANCODE_1] = 0x02, - [SDL_SCANCODE_2] = 0x03, - [SDL_SCANCODE_3] = 0x04, - [SDL_SCANCODE_4] = 0x05, - [SDL_SCANCODE_5] = 0x06, - [SDL_SCANCODE_6] = 0x07, - [SDL_SCANCODE_7] = 0x08, - [SDL_SCANCODE_8] = 0x09, - [SDL_SCANCODE_9] = 0x0A, - [SDL_SCANCODE_0] = 0x0B, - [SDL_SCANCODE_MINUS] = 0x0C, - [SDL_SCANCODE_EQUALS] = 0x0D, - [SDL_SCANCODE_BACKSPACE] = 0x0E, - [SDL_SCANCODE_TAB] = 0x0F, - [SDL_SCANCODE_Q] = 0x10, - [SDL_SCANCODE_W] = 0x11, - [SDL_SCANCODE_E] = 0x12, - [SDL_SCANCODE_R] = 0x13, - [SDL_SCANCODE_T] = 0x14, - [SDL_SCANCODE_Y] = 0x15, - [SDL_SCANCODE_U] = 0x16, - [SDL_SCANCODE_I] = 0x17, - [SDL_SCANCODE_O] = 0x18, - [SDL_SCANCODE_P] = 0x19, - [SDL_SCANCODE_LEFTBRACKET] = 0x1A, - [SDL_SCANCODE_RIGHTBRACKET] = 0x1B, - [SDL_SCANCODE_RETURN] = 0x1C, - [SDL_SCANCODE_LCTRL] = 0x1D, - [SDL_SCANCODE_A] = 0x1E, - [SDL_SCANCODE_S] = 0x1F, - [SDL_SCANCODE_D] = 0x20, - [SDL_SCANCODE_F] = 0x21, - [SDL_SCANCODE_G] = 0x22, - [SDL_SCANCODE_H] = 0x23, - [SDL_SCANCODE_J] = 0x24, - [SDL_SCANCODE_K] = 0x25, - [SDL_SCANCODE_L] = 0x26, - [SDL_SCANCODE_SEMICOLON] = 0x27, - [SDL_SCANCODE_APOSTROPHE] = 0x28, - [SDL_SCANCODE_GRAVE] = 0x29, - [SDL_SCANCODE_LSHIFT] = 0x2A, - [SDL_SCANCODE_BACKSLASH] = 0x2B, - [SDL_SCANCODE_Z] = 0x2C, - [SDL_SCANCODE_X] = 0x2D, - [SDL_SCANCODE_C] = 0x2E, - [SDL_SCANCODE_V] = 0x2F, - [SDL_SCANCODE_B] = 0x30, - [SDL_SCANCODE_N] = 0x31, - [SDL_SCANCODE_M] = 0x32, - [SDL_SCANCODE_COMMA] = 0x33, - [SDL_SCANCODE_PERIOD] = 0x34, - [SDL_SCANCODE_SLASH] = 0x35, - [SDL_SCANCODE_RSHIFT] = 0x36, - [SDL_SCANCODE_KP_MULTIPLY] = 0x37, - [SDL_SCANCODE_LALT] = 0x38, - [SDL_SCANCODE_SPACE] = 0x39, - [SDL_SCANCODE_CAPSLOCK] = 0x3A, - [SDL_SCANCODE_F1] = 0x3B, - [SDL_SCANCODE_F2] = 0x3C, - [SDL_SCANCODE_F3] = 0x3D, - [SDL_SCANCODE_F4] = 0x3E, - [SDL_SCANCODE_F5] = 0x3F, - [SDL_SCANCODE_F6] = 0x40, - [SDL_SCANCODE_F7] = 0x41, - [SDL_SCANCODE_F8] = 0x42, - [SDL_SCANCODE_F9] = 0x43, - [SDL_SCANCODE_F10] = 0x44, - [SDL_SCANCODE_NUMLOCKCLEAR] = 0x45, - [SDL_SCANCODE_SCROLLLOCK] = 0x46, - [SDL_SCANCODE_HOME] = 0x147, - [SDL_SCANCODE_UP] = 0x148, - [SDL_SCANCODE_PAGEUP] = 0x149, - [SDL_SCANCODE_KP_MINUS] = 0x4A, - [SDL_SCANCODE_LEFT] = 0x14B, - [SDL_SCANCODE_KP_5] = 0x4C, - [SDL_SCANCODE_RIGHT] = 0x14D, - [SDL_SCANCODE_KP_PLUS] = 0x4E, - [SDL_SCANCODE_END] = 0x14F, - [SDL_SCANCODE_DOWN] = 0x150, - [SDL_SCANCODE_PAGEDOWN] = 0x151, - [SDL_SCANCODE_INSERT] = 0x152, - [SDL_SCANCODE_DELETE] = 0x153, - [SDL_SCANCODE_F11] = 0x57, - [SDL_SCANCODE_F12] = 0x58, - - [SDL_SCANCODE_KP_ENTER] = 0x11c, - [SDL_SCANCODE_RCTRL] = 0x11d, - [SDL_SCANCODE_KP_DIVIDE] = 0x135, - [SDL_SCANCODE_RALT] = 0x138, - [SDL_SCANCODE_KP_9] = 0x49, - [SDL_SCANCODE_KP_8] = 0x48, - [SDL_SCANCODE_KP_7] = 0x47, - [SDL_SCANCODE_KP_6] = 0x4D, - [SDL_SCANCODE_KP_4] = 0x4B, - [SDL_SCANCODE_KP_3] = 0x51, - [SDL_SCANCODE_KP_2] = 0x50, - [SDL_SCANCODE_KP_1] = 0x4F, - [SDL_SCANCODE_KP_0] = 0x52, - [SDL_SCANCODE_KP_PERIOD] = 0x53, - - [SDL_SCANCODE_LGUI] = 0x15B, - [SDL_SCANCODE_RGUI] = 0x15C, - [SDL_SCANCODE_APPLICATION] = 0x15D, - [SDL_SCANCODE_PRINTSCREEN] = 0x137, - [SDL_SCANCODE_NONUSBACKSLASH] = 0x56, -}; - -// #define ENABLE_SDL_LOG 3 -#ifdef ENABLE_SDL_LOG -int sdl_do_log = ENABLE_SDL_LOG; - -static void -sdl_log(const char *fmt, ...) -{ - va_list ap; - - if (sdl_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define sdl_log(fmt, ...) -#endif - -static void -sdl_integer_scale(double *d, double *g) -{ - double ratio; - - if (*d > *g) { - ratio = floor(*d / *g); - *d = *g * ratio; - } else { - ratio = ceil(*d / *g); - *d = *g / ratio; - } -} - -static void -sdl_stretch(int *w, int *h, int *x, int *y) -{ - double hw; - double gw; - double hh; - double gh; - double dx; - double dy; - double dw; - double dh; - double gsr; - double hsr; - - hw = (double) sdl_w; - hh = (double) sdl_h; - gw = (double) *w; - gh = (double) *h; - hsr = hw / hh; - - switch (video_fullscreen_scale) { - case FULLSCR_SCALE_FULL: - default: - *w = sdl_w; - *h = sdl_h; - *x = 0; - *y = 0; - break; - case FULLSCR_SCALE_43: - case FULLSCR_SCALE_KEEPRATIO: - if (video_fullscreen_scale == FULLSCR_SCALE_43) - gsr = 4.0 / 3.0; - else - gsr = gw / gh; - if (gsr <= hsr) { - dw = hh * gsr; - dh = hh; - } else { - dw = hw; - dh = hw / gsr; - } - dx = (hw - dw) / 2.0; - dy = (hh - dh) / 2.0; - *w = (int) dw; - *h = (int) dh; - *x = (int) dx; - *y = (int) dy; - break; - case FULLSCR_SCALE_INT: - gsr = gw / gh; - if (gsr <= hsr) { - dw = hh * gsr; - dh = hh; - } else { - dw = hw; - dh = hw / gsr; - } - sdl_integer_scale(&dw, &gw); - sdl_integer_scale(&dh, &gh); - dx = (hw - dw) / 2.0; - dy = (hh - dh) / 2.0; - *w = (int) dw; - *h = (int) dh; - *x = (int) dx; - *y = (int) dy; - break; - } -} - -static void -sdl_blit(int x, int y, int w, int h) -{ - SDL_Rect r_src; - void *pixeldata; - int ret; - int pitch; - - if (!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL)) { - video_blit_complete(); - return; - } - - SDL_LockMutex(sdl_mutex); - SDL_LockTexture(sdl_tex, 0, &pixeldata, &pitch); - - video_copy(pixeldata, &(buffer32->line[y][x]), h * (2048) * sizeof(uint32_t)); - - if (monitors[m_monitor_index].mon_screenshots) - video_screenshot((uint32_t *) pixeldata, 0, 0, (2048)); - - SDL_UnlockTexture(sdl_tex); - - video_blit_complete(); - - SDL_RenderClear(sdl_render); - - r_src.x = 0; - r_src.y = 0; - r_src.w = w; - r_src.h = h; - - ret = SDL_RenderCopy(sdl_render, sdl_tex, &r_src, 0); - if (ret) - sdl_log("SDL: unable to copy texture to renderer (%s)\n", sdl_GetError()); - - SDL_RenderPresent(sdl_render); - - SDL_UnlockMutex(sdl_mutex); -} - -static void -sdl_destroy_window(void) -{ - if (sdl_win != NULL) { - SDL_DestroyWindow(sdl_win); - sdl_win = NULL; - } -} - -static void -sdl_destroy_texture(void) -{ - if (sdl_tex != NULL) { - SDL_DestroyTexture(sdl_tex); - sdl_tex = NULL; - } - - /* SDL_DestroyRenderer also automatically destroys all associated textures. */ - if (sdl_render != NULL) { - SDL_DestroyRenderer(sdl_render); - sdl_render = NULL; - } -} - -void -sdl_close(void) -{ - if (sdl_mutex != NULL) - SDL_LockMutex(sdl_mutex); - - /* Unregister our renderer! */ - video_setblit(NULL); - - if (sdl_enabled) - sdl_enabled = 0; - - if (sdl_mutex != NULL) { - SDL_DestroyMutex(sdl_mutex); - sdl_mutex = NULL; - } - - sdl_destroy_texture(); - sdl_destroy_window(); - - /* Quit. */ - SDL_Quit(); - sdl_flags = -1; -} - -static void -sdl_select_best_hw_driver(void) -{ - SDL_RendererInfo renderInfo; - - for (int i = 0; i < SDL_GetNumRenderDrivers(); ++i) { - SDL_GetRenderDriverInfo(i, &renderInfo); - if (renderInfo.flags & SDL_RENDERER_ACCELERATED) { - SDL_SetHint(SDL_HINT_RENDER_DRIVER, renderInfo.name); - return; - } - } -} - -static void -sdl_init_texture(void) -{ - if (sdl_flags & RENDERER_HARDWARE) { - sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_ACCELERATED); - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0"); - } else { - sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_SOFTWARE); - } - - sdl_tex = SDL_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STREAMING, 2048, 2048); - - if (sdl_render == NULL) { - sdl_log("SDL: unable to SDL_CreateRenderer (%s)\n", SDL_GetError()); - } - if (sdl_tex == NULL) { - sdl_log("SDL: unable to SDL_CreateTexture (%s)\n", SDL_GetError()); - } -} - -static void -sdl_reinit_texture(void) -{ - if (sdl_flags == -1) - return; - - sdl_destroy_texture(); - sdl_init_texture(); -} - -void -sdl_set_fs(int fs) -{ - SDL_SetWindowFullscreen(sdl_win, fs ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); - SDL_SetRelativeMouseMode((SDL_bool) mouse_capture); - - sdl_fs = fs; - - if (fs) { - sdl_flags |= RENDERER_FULL_SCREEN; - } else { - sdl_flags &= ~RENDERER_FULL_SCREEN; - } - - sdl_reinit_texture(); -} - -static int -sdl_init_common(void *win, int flags) -{ - wchar_t temp[128]; - SDL_version ver; - - sdl_log("SDL: init (fs=%d)\n", 0); - - /* Get and log the version of the DLL we are using. */ - SDL_GetVersion(&ver); - sdl_log("SDL: version %d.%d.%d\n", ver.major, ver.minor, ver.patch); - - /* Initialize the SDL system. */ - if (SDL_Init(SDL_INIT_VIDEO) < 0) { - sdl_log("SDL: initialization failed (%s)\n", SDL_GetError()); - return (0); - } - - if (flags & RENDERER_HARDWARE) { - if (flags & RENDERER_OPENGL) - SDL_SetHint(SDL_HINT_RENDER_DRIVER, "OpenGL"); - else - sdl_select_best_hw_driver(); - } - - /* Get the size of the (current) desktop. */ - SDL_DisplayMode dm; - if (SDL_GetDesktopDisplayMode(0, &dm) != 0) { - sdl_log("SDL: SDL_GetDesktopDisplayMode failed (%s)\n", SDL_GetError()); - return (0); - } - sdl_w = dm.w; - sdl_h = dm.h; - sdl_flags = flags; - - sdl_win = SDL_CreateWindow("86Box renderer", 640, 480, 100, 100, sdl_flags); - if (sdl_win == NULL) { - sdl_log("SDL: unable to CreateWindowFrom (%s)\n", SDL_GetError()); - } - sdl_init_texture(); - sdl_set_fs(video_fullscreen & 1); - - /* Make sure we get a clean exit. */ - atexit(sdl_close); - - /* Register our renderer! */ - video_setblit(sdl_blit); - - sdl_enabled = 1; - sdl_mutex = SDL_CreateMutex(); - - return (1); -} - -int -sdl_inits(void *win) -{ - return sdl_init_common(win, 0); -} - -int -sdl_inith(void *win) -{ - return sdl_init_common(win, RENDERER_HARDWARE); -} - -int -sdl_initho(void *win) -{ - return sdl_init_common(win, RENDERER_HARDWARE | RENDERER_OPENGL); -} - -int -sdl_pause(void) -{ - return 0; -} - -void -sdl_resize(int w, int h) -{ - int ww = 0; - int wh = 0; - - if (video_fullscreen & 2) - return; - - if ((w == cur_w) && (h == cur_h)) - return; - - SDL_LockMutex(sdl_mutex); - - ww = w; - wh = h; - - if (sdl_fs) { - // sdl_stretch(&ww, &wh, &wx, &wy); - // MoveWindow(hwndRender, wx, wy, ww, wh, TRUE); - } - - cur_w = w; - cur_h = h; - - cur_ww = ww; - cur_wh = wh; - - SDL_SetWindowSize(sdl_win, cur_ww, cur_wh); - sdl_reinit_texture(); - - SDL_UnlockMutex(sdl_mutex); -} - -void -sdl_enable(int enable) -{ - if (sdl_flags == -1) - return; - - SDL_LockMutex(sdl_mutex); - sdl_enabled = !!enable; - - if (enable == 1) { - SDL_SetWindowSize(sdl_win, cur_ww, cur_wh); - sdl_reinit_texture(); - } - - SDL_UnlockMutex(sdl_mutex); -} - -void -sdl_reload(void) -{ - if (sdl_flags & RENDERER_HARDWARE) { - SDL_LockMutex(sdl_mutex); - - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0"); - sdl_reinit_texture(); - - SDL_UnlockMutex(sdl_mutex); - } -} - -static int mouse_inside = 0; -enum sdl_main_status -sdl_main() -{ - int ret = SdlMainOk; - SDL_Rect r_src; - SDL_Event event; - - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_QUIT: - ret = SdlMainQuit; - break; - case SDL_MOUSEWHEEL: - { - if (mouse_capture || video_fullscreen) { - if (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) { - event.wheel.x *= -1; - event.wheel.y *= -1; - } - mouse_set_z(event.wheel.y); - } - break; - } - case SDL_MOUSEMOTION: - { - if (mouse_capture || video_fullscreen) - mouse_scale(event.motion.xrel, event.motion.yrel); - break; - } - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - { - if (!dopause && (event.button.button == SDL_BUTTON_LEFT) - && !(mouse_capture || video_fullscreen) - && event.button.state == SDL_RELEASED - && mouse_inside) { - plat_mouse_capture(1); - break; - } - if (mouse_get_buttons() < 3 && event.button.button == SDL_BUTTON_MIDDLE && !video_fullscreen) { - plat_mouse_capture(0); - break; - } - if (mouse_capture || video_fullscreen) { - int buttonmask = 0; - - switch (event.button.button) { - case SDL_BUTTON_LEFT: - buttonmask = 1; - break; - case SDL_BUTTON_RIGHT: - buttonmask = 2; - break; - case SDL_BUTTON_MIDDLE: - buttonmask = 4; - break; - } - if (event.button.state == SDL_PRESSED) - mouse_set_buttons_ex(mouse_get_buttons_ex() | buttonmask); - else - mouse_set_buttons_ex(mouse_get_buttons_ex() & ~buttonmask); - } - break; - } - case SDL_RENDER_DEVICE_RESET: - case SDL_RENDER_TARGETS_RESET: - { - sdl_reinit_texture(); - break; - } - case SDL_KEYDOWN: - case SDL_KEYUP: - { - uint16_t xtkey = 0; - switch (event.key.keysym.scancode) { - default: - xtkey = sdl_to_xt[event.key.keysym.scancode]; - break; - } - keyboard_input(event.key.state == SDL_PRESSED, xtkey); - } - break; - case SDL_WINDOWEVENT: - { - switch (event.window.event) { - case SDL_WINDOWEVENT_ENTER: - mouse_inside = 1; - break; - case SDL_WINDOWEVENT_LEAVE: - mouse_inside = 0; - break; - } - } - } - } - - if (mouse_capture && keyboard_ismsexit()) { - plat_mouse_capture(0); - } - if (video_fullscreen && keyboard_isfsexit()) { - plat_setfullscreen(0); - } - - return ret; -} - -void -sdl_mouse_capture(int on) -{ - SDL_SetRelativeMouseMode((SDL_bool) on); -} diff --git a/src/qt/qt_sdl.h b/src/qt/qt_sdl.h deleted file mode 100644 index f9709c857..000000000 --- a/src/qt/qt_sdl.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Definitions for the libSDL2 rendering module. - * - * - * - * Authors: Fred N. van Kempen, - * Michael Drüing, - * - * Copyright 2018-2019 Fred N. van Kempen. - * Copyright 2018-2019 Michael Drüing. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef WIN_SDL_H -#define WIN_SDL_H - -extern void *sdl_win_handle; -extern void sdl_close(void); -extern int sdl_inits(); -extern int sdl_inith(); -extern int sdl_initho(); -extern int sdl_pause(void); -extern void sdl_resize(int w, int h); -extern void sdl_enable(int enable); -extern void sdl_set_fs(int fs); -extern void sdl_reload(void); - -enum sdl_main_status { - SdlMainOk, - SdlMainQuit, -}; - -extern enum sdl_main_status sdl_main(); - -extern void sdl_mouse_capture(int on); - -#endif /*WIN_SDL_H*/ From 9e5ead428cc4eead39c89bd0765fa30de9a331be Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 19 Mar 2024 17:31:46 -0300 Subject: [PATCH 693/936] De-underscore the Aptiva 510 --- src/include/86box/machine.h | 2 +- src/machine/m_at_386dx_486.c | 4 ++-- src/machine/machine_table.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 18abf9ea9..ee18a89b1 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -521,7 +521,7 @@ extern int machine_at_403tg_d_init(const machine_t *); extern int machine_at_403tg_d_mr_init(const machine_t *); extern int machine_at_pb450_init(const machine_t *); extern int machine_at_pb450_init(const machine_t *); -extern int machine_at_aptiva_510_init(const machine_t *); +extern int machine_at_aptiva510_init(const machine_t *); extern int machine_at_pc330_6573_init(const machine_t *); extern int machine_at_mvi486_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 4cfa7447e..0c687bf20 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -722,11 +722,11 @@ machine_at_pc330_6573_common_init(const machine_t *model) } int -machine_at_aptiva_510_init(const machine_t *model) +machine_at_aptiva510_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/aptiva_510/$IMAGES.USF", + ret = bios_load_linear("roms/machines/aptiva510/$IMAGES.USF", 0x000e0000, 131072, 0); if (bios_only || !ret) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 04cc59043..6683f41f0 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -7187,10 +7187,10 @@ const machine_t machines[] = { /* Has IBM PS/2 Type 1 KBC firmware. */ { .name = "[OPTi 802G] IBM Aptiva 510/710/Vision", - .internal_name = "aptiva_510", + .internal_name = "aptiva510", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_OPTI_895_802G, - .init = machine_at_aptiva_510_init, + .init = machine_at_aptiva510_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, From e587cda80d6948adb171df0c2c67d8ddda2c823e Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 16 Mar 2024 20:21:47 +0500 Subject: [PATCH 694/936] Translations: Remove a few unused strings --- src/qt/languages/ca-ES.po | 6 ------ src/qt/languages/cs-CZ.po | 6 ------ src/qt/languages/de-DE.po | 6 ------ src/qt/languages/en-GB.po | 6 ------ src/qt/languages/en-US.po | 6 ------ src/qt/languages/es-ES.po | 6 ------ src/qt/languages/fi-FI.po | 6 ------ src/qt/languages/fr-FR.po | 6 ------ src/qt/languages/hr-HR.po | 6 ------ src/qt/languages/hu-HU.po | 6 ------ src/qt/languages/it-IT.po | 6 ------ src/qt/languages/ja-JP.po | 6 ------ src/qt/languages/ko-KR.po | 6 ------ src/qt/languages/pl-PL.po | 6 ------ src/qt/languages/pt-BR.po | 6 ------ src/qt/languages/pt-PT.po | 6 ------ src/qt/languages/ru-RU.po | 6 ------ src/qt/languages/sk-SK.po | 6 ------ src/qt/languages/sl-SI.po | 6 ------ src/qt/languages/tr-TR.po | 6 ------ src/qt/languages/uk-UA.po | 6 ------ src/qt/languages/zh-CN.po | 6 ------ src/qt/languages/zh-TW.po | 6 ------ src/qt/qt_platform.cpp | 1 - src/unix/unix.c | 2 -- 25 files changed, 141 deletions(-) diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po index cba27b839..4554bec10 100644 --- a/src/qt/languages/ca-ES.po +++ b/src/qt/languages/ca-ES.po @@ -760,9 +760,6 @@ msgstr "%i estado(s) de Espera" msgid "Type" msgstr "Tipus" -msgid "Failed to set up PCap" -msgstr "No s'ha pogut configurar PCap" - msgid "No PCap devices found" msgstr "No s'han trobat dispositius PCap" @@ -1000,9 +997,6 @@ msgstr "No has estat possible escriure el fitxer" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "Les imatges HDI o HDX amb una mida de sector diferent de 512 no s'admeten." -msgid "USB is not yet supported" -msgstr "L'USB encara no s'admete" - msgid "Disk image file already exists" msgstr "El fitxer d'imatge de disc ja existeix" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index 31388ca54..aa8ad5664 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -760,9 +760,6 @@ msgstr "%i čekací stav(y)" msgid "Type" msgstr "Typ" -msgid "Failed to set up PCap" -msgstr "Nastala chyba při inicializaci knihovny PCap" - msgid "No PCap devices found" msgstr "Nebyla nalezena žádná PCap zařízení" @@ -1000,9 +997,6 @@ msgstr "Nebylo možné zapisovat do souboru" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "Obraz disku ve formátu HDI nebo HDX s velikostí sektoru jinou než 512 bajtů nejsou podporovány." -msgid "USB is not yet supported" -msgstr "USB zatím není podporováno." - msgid "Disk image file already exists" msgstr "Soubor obrazu disku již existuje" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index 86289507c..8a9360b96 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -760,9 +760,6 @@ msgstr "%i Wartezustände" msgid "Type" msgstr "Typ" -msgid "Failed to set up PCap" -msgstr "PCap konnte nicht eingerichtet werden" - msgid "No PCap devices found" msgstr "Keine PCap-Geräte gefunden" @@ -1000,9 +997,6 @@ msgstr "Die Datei konnte nicht beschrieben werden" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "HDI- oder HDX-Images mit einer Sektorgröße größer als 512 kB werden nicht unterstützt." -msgid "USB is not yet supported" -msgstr "USB wird noch nicht unterstützt" - msgid "Disk image file already exists" msgstr "Die Festplattenimagedatei existiert bereits" diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index cff4be3ef..e3d007cc4 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -760,9 +760,6 @@ msgstr "%i Wait state(s)" msgid "Type" msgstr "Type" -msgid "Failed to set up PCap" -msgstr "Failed to set up PCap" - msgid "No PCap devices found" msgstr "No PCap devices found" @@ -1000,9 +997,6 @@ msgstr "Unable to write file" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "HDI or HDX images with a sector size other than 512 are not supported." -msgid "USB is not yet supported" -msgstr "USB is not yet supported" - msgid "Disk image file already exists" msgstr "Disk image file already exists" diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index f3bca870f..8b2c20ffe 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -760,9 +760,6 @@ msgstr "%i Wait state(s)" msgid "Type" msgstr "Type" -msgid "Failed to set up PCap" -msgstr "Failed to set up PCap" - msgid "No PCap devices found" msgstr "No PCap devices found" @@ -1000,9 +997,6 @@ msgstr "Unable to write file" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "HDI or HDX images with a sector size other than 512 are not supported." -msgid "USB is not yet supported" -msgstr "USB is not yet supported" - msgid "Disk image file already exists" msgstr "Disk image file already exists" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index e41a94947..b88c38b07 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -760,9 +760,6 @@ msgstr "%i estado(s) de Espera" msgid "Type" msgstr "Tipo" -msgid "Failed to set up PCap" -msgstr "Incapaz de configurar PCap" - msgid "No PCap devices found" msgstr "No se encontraron dispositivos PCap" @@ -1000,9 +997,6 @@ msgstr "No se pudo escribir el archivo" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "No se soportan las imágenes HDI o HDX con un tamaño de sector diferente a 512." -msgid "USB is not yet supported" -msgstr "No se soporta aún el USB" - msgid "Disk image file already exists" msgstr "La imagen de disco ya existe" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index ddf6a0683..04a745816 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -760,9 +760,6 @@ msgstr "%i odotustilaa" msgid "Type" msgstr "Tyyppi" -msgid "Failed to set up PCap" -msgstr "PCap-asennus epäonnistui" - msgid "No PCap devices found" msgstr "PCap-laitteita ei löytynyt" @@ -1000,9 +997,6 @@ msgstr "Tiedostoon ei voi kirjoittaa" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "HDI- ja HDX-levykuvien ainoa tuettu sektorikoko on 512" -msgid "USB is not yet supported" -msgstr "USB-tukea ei vielä ole" - msgid "Disk image file already exists" msgstr "Levykuva on jo olemassa" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index c443a881d..3abe3e53f 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -760,9 +760,6 @@ msgstr "%i état(s) d'attente" msgid "Type" msgstr "Type" -msgid "Failed to set up PCap" -msgstr "Impossible d'initialiser PCap" - msgid "No PCap devices found" msgstr "Aucun dispositif PCap trouvé" @@ -1000,9 +997,6 @@ msgstr "Impossible d'écrire le fichier" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "Les images HDI ou HDX avec une taille de secteur différente de 512 non sont pas prises en charge." -msgid "USB is not yet supported" -msgstr "USB n'est pas encore pris en charge." - msgid "Disk image file already exists" msgstr "Le fichier de l'image disque existe déjà." diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index 28db9e32d..a830644a0 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -760,9 +760,6 @@ msgstr "%i stanje čekanja" msgid "Type" msgstr "Tip" -msgid "Failed to set up PCap" -msgstr "Postavljanje PCap-a nije uspjelo" - msgid "No PCap devices found" msgstr "Nema PCap uređaja" @@ -1000,9 +997,6 @@ msgstr "Nije moguće napisati datoteku" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "HDI ili HDX slike s veličinom sektora koja nije 512 kB nisu podržane." -msgid "USB is not yet supported" -msgstr "USB nije još podržano" - msgid "Disk image file already exists" msgstr "Slika diska već postoji" diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index 07770c077..a22f6808e 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -760,9 +760,6 @@ msgstr "%i várakozási ciklus(ok)" msgid "Type" msgstr "Típus" -msgid "Failed to set up PCap" -msgstr "Nem sikerült a PCap beállítása" - msgid "No PCap devices found" msgstr "Nem találhatóak PCap eszközök" @@ -1000,9 +997,6 @@ msgstr "A fájl nem írható" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "Az 512-től eltérő szektorméretű HDI vagy HDX képek nem támogatottak." -msgid "USB is not yet supported" -msgstr "Az USB még nem támogatott" - msgid "Disk image file already exists" msgstr "A lemezképfájl már létezik" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index 39ecd7e89..7ff74c116 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -760,9 +760,6 @@ msgstr "%i stati d'attesa" msgid "Type" msgstr "Tipo" -msgid "Failed to set up PCap" -msgstr "Impossibile impostare PCap" - msgid "No PCap devices found" msgstr "Nessun dispositivo PCap trovato" @@ -1000,9 +997,6 @@ msgstr "Impossibile scrivere al file" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "Le immagini HDI o HDX con settori di dimensioni diverse da 512 non sono supportati." -msgid "USB is not yet supported" -msgstr "USB non è ancora supportato" - msgid "Disk image file already exists" msgstr "Immagine disco già esiste" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index 5eb5d23c1..b5aaa82e7 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -760,9 +760,6 @@ msgstr "%iつのウェイト ステート" msgid "Type" msgstr "タイプ" -msgid "Failed to set up PCap" -msgstr "PCapのセットアップに失敗しました" - msgid "No PCap devices found" msgstr "PCapデバイスがありません" @@ -1000,9 +997,6 @@ msgstr "ファイルの書き込みができません" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "512以外のセクタサイズを持つHDIまたはHDXイメージはサポートされていません。" -msgid "USB is not yet supported" -msgstr "USBはまだ非対応です" - msgid "Disk image file already exists" msgstr "ディスクイメージファイルが既に存在します" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index 2eaf53b2e..59855f460 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -760,9 +760,6 @@ msgstr "%i 대기 상태" msgid "Type" msgstr "형식" -msgid "Failed to set up PCap" -msgstr "PCap 설정에 실패했습니다" - msgid "No PCap devices found" msgstr "PCap 장치가 없습니다" @@ -1000,9 +997,6 @@ msgstr "파일을 저장할 수 없습니다" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "512 바이트 이외의 섹터 크기를 가진 HDI 또는 HDX 형식의 이미지를 생성할 수 없습니다" -msgid "USB is not yet supported" -msgstr "USB는 아직 지원하지 않습니다" - msgid "Disk image file already exists" msgstr "디스크 이미지 파일이 이미 존재합니다" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index 583774ab4..b3e71ffa0 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -760,9 +760,6 @@ msgstr "%i Stany oczekiwania" msgid "Type" msgstr "Rodzaj" -msgid "Failed to set up PCap" -msgstr "Nie udało się ustawić PCap" - msgid "No PCap devices found" msgstr "Nie znaleziono urządzeń PCap" @@ -1000,9 +997,6 @@ msgstr "Nie można zapisać pliku" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "Obrazy HDI lub HDX z rozmiarem sektora innym niż 512 nie są wspierane." -msgid "USB is not yet supported" -msgstr "USB nie jest jeszcze wspierane" - msgid "Disk image file already exists" msgstr "Plik obrazu dysku już istnieje" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 8ee668a1d..b46012101 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -760,9 +760,6 @@ msgstr "%i estado(s) de espera" msgid "Type" msgstr "Tipo" -msgid "Failed to set up PCap" -msgstr "Não foi possível configurar o PCap" - msgid "No PCap devices found" msgstr "Nenhum dispositivo PCap encontrado" @@ -1000,9 +997,6 @@ msgstr "Não foi possível escrever o arquivo" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "Imagens HDI ou HDX com um tamanho de setor que não seja 512 não são suportadas." -msgid "USB is not yet supported" -msgstr "O USB ainda não é suportado" - msgid "Disk image file already exists" msgstr "Esta imagem existe" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index 6ae146eaf..fc892f6dc 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -760,9 +760,6 @@ msgstr "%i estado(s) de espera" msgid "Type" msgstr "Tipo" -msgid "Failed to set up PCap" -msgstr "Falha na configuração de PCap" - msgid "No PCap devices found" msgstr "Não foi encontrado um dispositivo PCap" @@ -1000,9 +997,6 @@ msgstr "Não foi possível escrever o ficheiro" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "Imagens HDI ou HDX com um tamanho de sector diferente de 512 não são suportadas." -msgid "USB is not yet supported" -msgstr "O barramento USB ainda não tem suporte" - msgid "Disk image file already exists" msgstr "A imagem de disco já existe" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index cbeeafdd5..7ed5d0b5f 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -850,9 +850,6 @@ msgstr "%i WS" msgid "Type" msgstr "Тип" -msgid "Failed to set up PCap" -msgstr "Не удалось настроить PCap" - msgid "No PCap devices found" msgstr "Устройства PCap не найдены" @@ -1090,9 +1087,6 @@ msgstr "Невозможно записать файл" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "Образы HDI или HDX с размером сектора, отличным от 512, не поддерживаются." -msgid "USB is not yet supported" -msgstr "USB пока не поддерживается" - msgid "Disk image file already exists" msgstr "Файл образа диска уже существует" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index cdcfcbfe8..8842a5215 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -760,9 +760,6 @@ msgstr "%i čakací stav(y)" msgid "Type" msgstr "Typ" -msgid "Failed to set up PCap" -msgstr "Nastala chyba pri inicializácii knižnice PCap" - msgid "No PCap devices found" msgstr "Neboli nájdené žiadne PCap zariadenia" @@ -1000,9 +997,6 @@ msgstr "Nebolo možné zapisovať do súboru" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "Obraz disku vo formáte HDI alebo HDX s veľkosťou sektora inou ako 512 bajtov nie sú podporované." -msgid "USB is not yet supported" -msgstr "USB zatiaľ nie je podporované." - msgid "Disk image file already exists" msgstr "Súbor obrazu disku už existuje" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index d56318aed..ae173ad30 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -760,9 +760,6 @@ msgstr "%i stanj čakanja" msgid "Type" msgstr "Vrsta" -msgid "Failed to set up PCap" -msgstr "Nastavitev PCap ni uspela" - msgid "No PCap devices found" msgstr "Nobena naprava PCap ni bila najdena" @@ -1000,9 +997,6 @@ msgstr "Ne morem pisati v datoteko" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "Slike HDI ali HDX, ki nimajo sektorjev velikosti 512 bajtov, niso podprte." -msgid "USB is not yet supported" -msgstr "USB še ni podprt" - msgid "Disk image file already exists" msgstr "Datoteka s sliko diska že obstaja" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index 1af206659..5c413fb58 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -760,9 +760,6 @@ msgstr "%i Bekleme durumları" msgid "Type" msgstr "Tür" -msgid "Failed to set up PCap" -msgstr "PCap ayarlanamadı" - msgid "No PCap devices found" msgstr "Herhangi bir PCap cihazı bulunamadı" @@ -1000,9 +997,6 @@ msgstr "Dosyanın üzerine yazılamıyor" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "512 dışında sektör boyutu olan HDI veya HDX imajları desteklenmemektedir." -msgid "USB is not yet supported" -msgstr "USB şu anda desteklenmemektedir" - msgid "Disk image file already exists" msgstr "Disk imaj dosyası zaten var olmakta" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index 860116fe8..da48b74c7 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -760,9 +760,6 @@ msgstr "%i WS" msgid "Type" msgstr "Тип" -msgid "Failed to set up PCap" -msgstr "Не вдалося налаштувати PCap" - msgid "No PCap devices found" msgstr "Пристрої PCap не знайдені" @@ -1000,9 +997,6 @@ msgstr "Неможливо записати файл" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "Образи HDI або HDX з розміром сектора, відмінним від 512, не підтримуються." -msgid "USB is not yet supported" -msgstr "USB поки не підтримується" - msgid "Disk image file already exists" msgstr "Файл образу диска вже існує" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index eade3f77e..8a09cf87d 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -760,9 +760,6 @@ msgstr "%i 等待状态 (WS)" msgid "Type" msgstr "类型" -msgid "Failed to set up PCap" -msgstr "设置 PCap 失败" - msgid "No PCap devices found" msgstr "未找到 PCap 设备" @@ -1000,9 +997,6 @@ msgstr "无法写入文件" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "不支持非 512 字节扇区大小的 HDI 或 HDX 映像。" -msgid "USB is not yet supported" -msgstr "尚未支持 USB" - msgid "Disk image file already exists" msgstr "磁盘映像文件已存在" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 0e61363f4..f05e16cd6 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -760,9 +760,6 @@ msgstr "%i 等待狀態 (WS)" msgid "Type" msgstr "類型" -msgid "Failed to set up PCap" -msgstr "設定 PCap 失敗" - msgid "No PCap devices found" msgstr "未找到 PCap 裝置" @@ -1000,9 +997,6 @@ msgstr "無法寫入檔案" msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "不支援非 512 位元組磁區大小的 HDI 或 HDX 映像。" -msgid "USB is not yet supported" -msgstr "尚未支援 USB" - msgid "Disk image file already exists" msgstr "磁碟映像檔案已存在" diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index da97680fa..04a255ac8 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -602,7 +602,6 @@ ProgSettings::reloadStrings() translatedstrings[IDS_2079] = QCoreApplication::translate("", "Press F8+F12 or middle button to release mouse").replace("F8+F12", MOUSE_CAPTURE_KEYSEQ).replace("CTRL-END", QLocale::system().name() == "de_DE" ? "Strg+Ende" : "CTRL-END").toStdWString(); translatedstrings[IDS_2131] = QCoreApplication::translate("", "Invalid configuration").toStdWString(); translatedstrings[IDS_4099] = QCoreApplication::translate("", "MFM/RLL or ESDI CD-ROM drives never existed").toStdWString(); - translatedstrings[IDS_2094] = QCoreApplication::translate("", "Failed to set up PCap").toStdWString(); translatedstrings[IDS_2095] = QCoreApplication::translate("", "No PCap devices found").toStdWString(); translatedstrings[IDS_2096] = QCoreApplication::translate("", "Invalid PCap device").toStdWString(); translatedstrings[IDS_2130] = QCoreApplication::translate("", "Make sure libpcap is installed and that you are on a libpcap-compatible network connection.").toStdWString(); diff --git a/src/unix/unix.c b/src/unix/unix.c index 848ed0f22..9cce3c898 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -256,8 +256,6 @@ plat_get_string(int i) return L"Invalid configuration"; case IDS_4099: return L"MFM/RLL or ESDI CD-ROM drives never existed"; - case IDS_2094: - return L"Failed to set up PCap"; case IDS_2095: return L"No PCap devices found"; case IDS_2096: From 8e06b5449fcf7d2fe6db9104be418df2099562ca Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Tue, 19 Mar 2024 14:27:19 +0500 Subject: [PATCH 695/936] Overhaul plat_get_string() Now takes constants with human-readable names instead of Win32 string table IDs, language.h is no longer needed ui_msgbox*() no longer accepts string IDs as arguments directly, plat_get_string() must be explicitly called to retrieve the string --- src/86box.c | 20 +-- src/config.c | 8 +- src/disk/hdd.c | 2 +- src/include/86box/language.h | 283 ----------------------------------- src/include/86box/plat.h | 20 ++- src/network/net_plip.c | 1 - src/network/network.c | 2 +- src/printer/prt_ps.c | 3 +- src/qt/qt_harddiskdialog.cpp | 8 +- src/qt/qt_main.cpp | 6 +- src/qt/qt_platform.cpp | 38 +++-- src/qt/qt_ui.cpp | 5 - src/unix/unix.c | 32 ++-- src/video/vid_svga.c | 2 +- 14 files changed, 78 insertions(+), 352 deletions(-) delete mode 100644 src/include/86box/language.h diff --git a/src/86box.c b/src/86box.c index 79ddc7692..88229a820 100644 --- a/src/86box.c +++ b/src/86box.c @@ -954,12 +954,12 @@ pc_init_modules(void) /* Load the ROMs for the selected machine. */ if (!machine_available(machine)) { - swprintf(temp, sizeof_w(temp), plat_get_string(IDS_2063), machine_getname()); + swprintf(temp, sizeof_w(temp), plat_get_string(STRING_HW_NOT_AVAILABLE_MACHINE), machine_getname()); c = 0; machine = -1; while (machine_get_internal_name_ex(c) != NULL) { if (machine_available(c)) { - ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2129, temp); + ui_msgbox_header(MBX_INFO, plat_get_string(STRING_HW_NOT_AVAILABLE_TITLE), temp); machine = c; config_save(); break; @@ -976,12 +976,12 @@ pc_init_modules(void) if (!video_card_available(gfxcard[0])) { memset(tempc, 0, sizeof(tempc)); device_get_name(video_card_getdevice(gfxcard[0]), 0, tempc); - swprintf(temp, sizeof_w(temp), plat_get_string(IDS_2064), tempc); + swprintf(temp, sizeof_w(temp), plat_get_string(STRING_HW_NOT_AVAILABLE_VIDEO), tempc); c = 0; while (video_get_internal_name(c) != NULL) { gfxcard[0] = -1; if (video_card_available(c)) { - ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2129, temp); + ui_msgbox_header(MBX_INFO, plat_get_string(STRING_HW_NOT_AVAILABLE_TITLE), temp); gfxcard[0] = c; config_save(); break; @@ -997,8 +997,8 @@ pc_init_modules(void) if (!video_card_available(gfxcard[1])) { char tempc[512] = { 0 }; device_get_name(video_card_getdevice(gfxcard[1]), 0, tempc); - swprintf(temp, sizeof_w(temp), plat_get_string(IDS_2163), tempc); - ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2129, temp); + swprintf(temp, sizeof_w(temp), plat_get_string(STRING_HW_NOT_AVAILABLE_VIDEO2), tempc); + ui_msgbox_header(MBX_INFO, plat_get_string(STRING_HW_NOT_AVAILABLE_TITLE), temp); gfxcard[1] = 0; } @@ -1289,17 +1289,17 @@ update_mouse_msg(void) mbstowcs(wcpu, cpu_s->name, strlen(cpu_s->name) + 1); #ifdef _WIN32 swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%%i%%%% - %ls", - plat_get_string(IDS_2077)); + plat_get_string(STRING_MOUSE_CAPTURE)); swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%%i%%%% - %ls", - (mouse_get_buttons() > 2) ? plat_get_string(IDS_2078) : plat_get_string(IDS_2079)); + (mouse_get_buttons() > 2) ? plat_get_string(STRING_MOUSE_RELEASE) : plat_get_string(STRING_MOUSE_RELEASE_MMB)); wcsncpy(mouse_msg[2], L"%i%%", sizeof_w(mouse_msg[2])); #else swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls - %ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu, - plat_get_string(IDS_2077)); + plat_get_string(STRING_MOUSE_CAPTURE)); swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls - %ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu, - (mouse_get_buttons() > 2) ? plat_get_string(IDS_2078) : plat_get_string(IDS_2079)); + (mouse_get_buttons() > 2) ? plat_get_string(STRING_MOUSE_RELEASE) : plat_get_string(STRING_MOUSE_RELEASE_MMB)); swprintf(mouse_msg[2], sizeof_w(mouse_msg[2]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu); #endif diff --git a/src/config.c b/src/config.c index 84c570f62..da02a93b0 100644 --- a/src/config.c +++ b/src/config.c @@ -663,9 +663,9 @@ load_network(void) if (nc->net_type == NET_TYPE_PCAP) { if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) { if (network_ndev == 1) - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2095, (wchar_t *) IDS_2130); + ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_PCAP_ERROR_NO_DEVICES), plat_get_string(STRING_PCAP_ERROR_DESC)); else if (network_dev_to_id(p) == -1) - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2096, (wchar_t *) IDS_2130); + ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_PCAP_ERROR_INVALID_DEVICE), plat_get_string(STRING_PCAP_ERROR_DESC)); strcpy(nc->host_dev_name, "none"); } else strncpy(nc->host_dev_name, p, sizeof(nc->host_dev_name) - 1); @@ -710,9 +710,9 @@ load_network(void) if (nc->net_type == NET_TYPE_PCAP) { if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) { if (network_ndev == 1) - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2095, (wchar_t *) IDS_2130); + ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_PCAP_ERROR_NO_DEVICES), plat_get_string(STRING_PCAP_ERROR_DESC)); else if (network_dev_to_id(p) == -1) - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2096, (wchar_t *) IDS_2130); + ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_PCAP_ERROR_INVALID_DEVICE), plat_get_string(STRING_PCAP_ERROR_DESC)); strcpy(nc->host_dev_name, "none"); } else strncpy(nc->host_dev_name, p, sizeof(nc->host_dev_name) - 1); diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 3bb15c241..23dd51b92 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -53,7 +53,7 @@ hdd_string_to_bus(char *str, int cdrom) if (!strcmp(str, "mfm") || !strcmp(str, "rll")) { if (cdrom) { no_cdrom: - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2131, (wchar_t *) IDS_4099); + ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_INVALID_CONFIG), plat_get_string(STRING_NO_ST506_ESDI_CDROM)); return 0; } diff --git a/src/include/86box/language.h b/src/include/86box/language.h deleted file mode 100644 index 3c96e711f..000000000 --- a/src/include/86box/language.h +++ /dev/null @@ -1,283 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Definitions for the language management module. - * - * - * - * Authors: Fred N. van Kempen, - * - * Copyright 2017-2018 Fred N. van Kempen. - * Copyright 2022 Jasmine Iwanek. - */ - -#ifndef LANG_UAGE_H -#define LANG_UAGE_H - -/* String IDs. */ -#define IDS_STRINGS 2048 // "86Box" -#define IDS_2049 2049 // "Error" -#define IDS_2050 2050 // "Fatal error" -#define IDS_2051 2051 // " - PAUSED" -#define IDS_2052 2052 // "Press Ctrl+Alt+PgDn..." -#define IDS_2053 2053 // "Speed" -#define IDS_2054 2054 // "ZIP %i (%03i): %ls" -#define IDS_2055 2055 // "ZIP images (*.IM?)\0*.IM..." -#define IDS_2056 2056 // "No usable ROM images found!" -#define IDS_2057 2057 // "(empty)" -#define IDS_2058 2058 // "ZIP images (*.IM?)\0*.IM..." -#define IDS_2059 2059 // "(Turbo)" -#define IDS_2060 2060 // "On" -#define IDS_2061 2061 // "Off" -#define IDS_2062 2062 // "All floppy images (*.DSK..." -#define IDS_2063 2063 // "Machine ""%hs"" is not..." -#define IDS_2064 2064 // "Video card ""%hs"" is not..." -#define IDS_2065 2065 // "Machine" -#define IDS_2066 2066 // "Display" -#define IDS_2067 2067 // "Input devices" -#define IDS_2068 2068 // "Sound" -#define IDS_2069 2069 // "Network" -#define IDS_2070 2070 // "Ports (COM & LPT)" -#define IDS_2071 2071 // "Storage controllers" -#define IDS_2072 2072 // "Hard disks" -#define IDS_2073 2073 // "Floppy and CD-ROM drives" -#define IDS_2074 2074 // "Other removable devices" -#define IDS_2075 2075 // "Other peripherals" -#define IDS_2076 2076 // "Surface-based images (*.8.." -#define IDS_2077 2077 // "Click to capture mouse" -#define IDS_2078 2078 // "Press F12-F8 to release mouse" -#define IDS_2079 2079 // "Press F12-F8 or middle button.." -#define IDS_2081 2081 // "Bus" -#define IDS_BUS IDS_2081 // "Bus" -#define IDS_2082 2082 // "File" -#define IDS_2083 2083 // "C" -#define IDS_2084 2084 // "H" -#define IDS_2085 2085 // "S" -#define IDS_2086 2086 // "MB" -#define IDS_MB IDS_2086 // "MB" -#define IDS_2087 2087 // "Speed" - -#define IDS_2088 2088 // "Check BPB" -#define IDS_BPB IDS_2088 // "Check BPB" - -#define IDS_2089 2089 // "KB" -#define IDS_KB IDS_2089 // "KB" - -#define IDS_2090 2090 // "Could not initialize the video..." - -#define IDS_2091 2091 // "Default" -#define IDS_DEFAULT IDS_2091 // "Default" - -#define IDS_2092 2092 // "%i Wait state(s)" -#define IDS_WS IDS_2092 // "%i Wait state(s)" - -#define IDS_2093 2093 // "Type" -#define IDS_TYPE IDS_2093 // "Type" - -/* TODO */ -#define IDS_2094 2094 // "PCap failed to set up.." -#define IDS_2095 2095 // "No PCap devices found" -#define IDS_2096 2096 // "Invalid PCap device" -#define IDS_2097 2097 // "Standard 2-button joystick(s)" -#define IDS_2098 2098 // "Standard 4-button joystick" -#define IDS_2099 2099 // "Standard 6-button joystick" -#define IDS_2100 2100 // "Standard 8-button joystick" -#define IDS_2101 2101 // "CH Flightstick Pro" -#define IDS_2102 2102 // "Microsoft SideWinder Pad" -#define IDS_2103 2103 // "Thrustmaster Flight Cont.." -#define IDS_2104 2104 // "None" -#define IDS_2105 2105 // "Unable to load keyboard..." -#define IDS_2106 2106 // "Unable to register raw input." -#define IDS_2107 2107 // "%u" -#define IDS_2108 2108 // "%u MB (CHS: %i, %i, %i)" -#define IDS_2109 2109 // "Floppy %i (%s): %ls" -#define IDS_2110 2110 // "All floppy images (*.0??;*.." -#define IDS_2113 2113 // "Are you sure you want to..." -#define IDS_2114 2114 // "Are you sure you want to..." -#define IDS_2115 2115 // "Unable to initialize Ghostscript..." -#define IDS_2116 2116 // "MO %i (%03i): %ls" -#define IDS_2117 2117 // "MO images (*.IM?)\0*.IM..." -#define IDS_2118 2118 // "Welcome to 86Box!" -#define IDS_2119 2119 // "Internal controller" -#define IDS_2120 2120 // "Exit" -#define IDS_2121 2121 // "No ROMs found" -#define IDS_2122 2122 // "Do you want to save the settings?" -#define IDS_2123 2123 // "This will hard reset the emulated..." -#define IDS_2124 2124 // "Save" -#define IDS_2125 2125 // "About 86Box" -#define IDS_2126 2126 // "86Box v" EMU_VERSION -#define IDS_2127 2127 // "An emulator of old computers..." -#define IDS_2128 2128 // "OK" -#define IDS_2129 2129 // "Hardware not available" -#define IDS_2130 2130 // "Make sure " LIB_NAME_PCAP "..." -#define IDS_2131 2131 // "Invalid configuration" -#define IDS_2133 2133 // LIB_NAME_GS " is required for... -#define IDS_2135 2135 // "Entering fullscreen mode" -#define IDS_2136 2136 // "Don't show this message again" -#define IDS_2137 2137 // "Don't exit" -#define IDS_2138 2138 // "Reset" -#define IDS_2139 2139 // "Don't reset" -#define IDS_2140 2140 // "MO images (*.IM?)\0*.IM?..." -#define IDS_2141 2141 // "CD-ROM images (*.ISO;*.CU.." -#define IDS_2142 2142 // "%hs Device Configuration" -#define IDS_2143 2143 // "Monitor in sleep mode" -#define IDS_2144 2144 // "OpenGL Shaders (*.GLSL)..." -#define IDS_2145 2145 // "OpenGL options" -#define IDS_2146 2146 // "You are loading an unsupported..." -#define IDS_2147 2147 // "CPU type filtering based on..." -#define IDS_2148 2148 // "Continue" -#define IDS_2149 2149 // "Cassette: %s" -#define IDS_2150 2150 // "Cassette images (*.PCM;*.RAW;*..." -#define IDS_2151 2151 // "Cartridge %i: %ls" -#define IDS_2152 2152 // "Cartridge images (*.JRC)\0*.JRC\0..." -#define IDS_2153 2153 // "Error initializing renderer" -#define IDS_2154 2154 // "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -#define IDS_2155 2155 // "Resume execution" -#define IDS_2156 2156 // "Pause execution" -#define IDS_2157 2157 // "Press Ctrl+Alt+Del" -#define IDS_2158 2158 // "Press Ctrl+Alt+Esc" -#define IDS_2159 2159 // "Hard reset" -#define IDS_2160 2160 // "ACPI shutdown" -#define IDS_2161 2161 // "Settings" -#define IDS_2162 2162 // "Early drive" -#define IDS_2163 2163 // "no dynarec" -#define IDS_2164 2164 // "old dynarec" -#define IDS_2165 2165 // "new dynarec" -#ifdef USE_DYNAREC -# ifdef USE_NEW_DYNAREC -# define IDS_DYNAREC IDS_2165 -# else -# define IDS_DYNAREC IDS_2164 -# endif -#else -# define IDS_DYNAREC IDS_2163 -#endif -#define IDS_2166 2166 // "Video card #2 ""%hs"" is not..." -#define IDS_2167 2167 // "Network driver initialization failed" -#define IDS_2168 2168 // "The network configuration will be switched to the null driver" - -#define IDS_4096 4096 // "Hard disk (%s)" -#define IDS_4097 4097 // "%01i:%01i" -#define IDS_4098 4098 // "%i" -#define IDS_4099 4099 // "MFM/RLL or ESDI CD-ROM driv.." -#define IDS_4100 4100 // "Custom..." -#define IDS_4101 4101 // "Custom (large)..." -#define IDS_4102 4102 // "Add New Hard Disk" -#define IDS_4103 4103 // "Add Existing Hard Disk" -#define IDS_4104 4104 // "HDI disk images cannot be..." -#define IDS_4105 4105 // "Disk images cannot be larger..." -#define IDS_4106 4106 // "Hard disk images (*.HDI;*.HD.." -#define IDS_4107 4107 // "Unable to open the file for read" -#define IDS_4108 4108 // "Unable to open the file for write" -#define IDS_4109 4109 // "HDI or HDX image with a sect.." -#define IDS_4110 4110 // "USB is not yet supported" -#define IDS_4111 4111 // "Disk image file already exists" -#define IDS_4112 4112 // "Please specify a valid file name." -#define IDS_4113 4113 // "Remember to partition and fo.." -#define IDS_4114 4114 // "Make sure the file exists and..." -#define IDS_4115 4115 // "Make sure the file is being..." -#define IDS_4116 4116 // "Disk image too large" -#define IDS_4117 4117 // "Remember to partition and format..." -#define IDS_4118 4118 // "The selected file will be..." -#define IDS_4119 4119 // "Unsupported disk image" -#define IDS_4120 4120 // "Overwrite" -#define IDS_4121 4121 // "Don't overwrite" -#define IDS_4122 4122 // "Raw image (.img)" -#define IDS_4123 4123 // "HDI image (.hdi)" -#define IDS_4124 4124 // "HDX image (.hdx)" -#define IDS_4125 4125 // "Fixed-size VHD (.vhd)" -#define IDS_4126 4126 // "Dynamic-size VHD (.vhd)" -#define IDS_4127 4127 // "Differencing VHD (.vhd)" -#define IDS_4128 4128 // "Large blocks (2 MB)" -#define IDS_4129 4129 // "Small blocks (512 KB)" -#define IDS_4130 4130 // "VHD files (*.VHD)\0*.VHD\0All..." -#define IDS_4131 4131 // "Select the parent VHD" -#define IDS_4132 4132 // "This could mean that the parent..." -#define IDS_4133 4133 // "Parent and child disk timestamps..." -#define IDS_4134 4134 // "Could not fix VHD timestamp." -#define IDS_4135 4135 // "%01i:%02i" - -#define IDS_4352 4352 // "MFM/RLL" -#define IDS_4353 4353 // "XT IDE" -#define IDS_4354 4354 // "ESDI" -#define IDS_4355 4355 // "IDE" -#define IDS_4356 4356 // "ATAPI" -#define IDS_4357 4357 // "SCSI" - -#define IDS_4608 4608 // "MFM/RLL (%01i:%01i)" -#define IDS_4609 4609 // "XT IDE (%01i:%01i)" -#define IDS_4610 4610 // "ESDI (%01i:%01i)" -#define IDS_4611 4611 // "IDE (%01i:%01i)" -#define IDS_4612 4612 // "ATAPI (%01i:%01i)" -#define IDS_4613 4613 // "SCSI (%02i:%02i)" - -#define IDS_5120 5120 // "CD-ROM %i (%s): %s" - -#define IDS_5376 5376 // "Disabled" -#define IDS_5377 5377 // -#define IDS_5378 5378 // -#define IDS_5379 5379 // -#define IDS_5380 5380 // -#define IDS_5381 5381 // "ATAPI" -#define IDS_5382 5382 // "SCSI" - -#define IDS_5632 5632 // "Disabled" -#define IDS_5633 5633 // -#define IDS_5634 5634 // -#define IDS_5635 5635 // -#define IDS_5636 5636 // -#define IDS_5637 5637 // "ATAPI (%01i:%01i)" -#define IDS_5638 5638 // "SCSI (%02i:%02i)" - -#define IDS_5888 5888 // "160 kB" -#define IDS_5889 5889 // "180 kB" -#define IDS_5890 5890 // "320 kB" -#define IDS_5891 5891 // "360 kB" -#define IDS_5892 5892 // "640 kB" -#define IDS_5893 5893 // "720 kB" -#define IDS_5894 5894 // "1.2 MB" -#define IDS_5895 5895 // "1.25 MB" -#define IDS_5896 5896 // "1.44 MB" -#define IDS_5897 5897 // "DMF (cluster 1024)" -#define IDS_5898 5898 // "DMF (cluster 2048)" -#define IDS_5899 5899 // "2.88 MB" -#define IDS_5900 5900 // "ZIP 100" -#define IDS_5901 5901 // "ZIP 250" -#define IDS_5902 5902 // "3.5\" 128 MB (ISO 10090)" -#define IDS_5903 5903 // "3.5\" 230 MB (ISO 13963)" -#define IDS_5904 5904 // "3.5\" 540 MB (ISO 15498)" -#define IDS_5905 5905 // "3.5\" 640 MB (ISO 15498)" -#define IDS_5906 5906 // "3.5\" 1.3 GB (GigaMO)" -#define IDS_5907 5907 // "3.5\" 2.3 GB (GigaMO 2)" -#define IDS_5908 5908 // "5.25\" 600 MB" -#define IDS_5909 5909 // "5.25\" 650 MB" -#define IDS_5910 5910 // "5.25\" 1 GB" -#define IDS_5911 5911 // "5.25\" 1.3 GB" - -#define IDS_6144 6144 // "Perfect RPM" -#define IDS_6145 6145 // "1%% below perfect RPM" -#define IDS_6146 6146 // "1.5%% below perfect RPM" -#define IDS_6147 6147 // "2%% below perfect RPM" - -#define IDS_7168 7168 // "(System Default)" - -#define IDS_LANG_ENUS IDS_7168 - -#define STR_NUM_2048 121 -// UNUSED: #define STR_NUM_3072 11 -#define STR_NUM_4096 40 -#define STR_NUM_4352 6 -#define STR_NUM_4608 6 -#define STR_NUM_5120 1 -#define STR_NUM_5376 7 -#define STR_NUM_5632 7 -#define STR_NUM_5888 24 -#define STR_NUM_6144 4 -#define STR_NUM_7168 1 - -#endif /*LANG_UAGE_H*/ diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index 32f50c638..5b36bab7e 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -30,7 +30,25 @@ #endif /* String ID numbers. */ -#include <86box/language.h> +enum { + STRING_MOUSE_CAPTURE, /* "Click to capture mouse" */ + STRING_MOUSE_RELEASE, /* "Press F8+F12/Ctrl+End to release mouse" */ + STRING_MOUSE_RELEASE_MMB, /* "Press F8+F12/Ctrl+End or middle button to release mouse" */ + STRING_INVALID_CONFIG, /* "Invalid configuration" */ + STRING_NO_ST506_ESDI_CDROM, /* "MFM/RLL or ESDI CD-ROM drives never existed" */ + STRING_NET_ERROR, /* "Failed to initialize network driver" */ + STRING_NET_ERROR_DESC, /* "The network configuration will be switched..." */ + STRING_PCAP_ERROR_NO_DEVICES, /* "No PCap devices found" */ + STRING_PCAP_ERROR_INVALID_DEVICE, /* "Invalid PCap device" */ + STRING_PCAP_ERROR_DESC, /* "Make sure libpcap is installed..." */ + STRING_GHOSTSCRIPT_ERROR_TITLE, /* "Unable to initialize Ghostscript" */ + STRING_GHOSTSCRIPT_ERROR_DESC, /* "gsdll32.dll/gsdll64.dll/libgs is required..." */ + STRING_HW_NOT_AVAILABLE_TITLE, /* "Hardware not available" */ + STRING_HW_NOT_AVAILABLE_MACHINE, /* "Machine \"%hs\" is not available..." */ + STRING_HW_NOT_AVAILABLE_VIDEO, /* "Video card \"%hs\" is not available..." */ + STRING_HW_NOT_AVAILABLE_VIDEO2, /* "Video card #2 \"%hs\" is not available..." */ + STRING_MONITOR_SLEEP /* "Monitor in sleep mode" */ +}; /* The Win32 API uses _wcsicmp. */ #ifdef _WIN32 diff --git a/src/network/net_plip.c b/src/network/net_plip.c index 41e5502a6..8b0bf460c 100644 --- a/src/network/net_plip.c +++ b/src/network/net_plip.c @@ -26,7 +26,6 @@ #include #define HAVE_STDARG_H #include <86box/86box.h> -#include <86box/language.h> #include <86box/lpt.h> #include <86box/timer.h> #include <86box/pit.h> diff --git a/src/network/network.c b/src/network/network.c index fe3bf8489..d0ebe8ef3 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -504,7 +504,7 @@ network_attach(void *card_drv, uint8_t *mac, NETRXCB rx, NETSETLINKSTATE set_lin if(net_cards_conf[net_card_current].net_type != NET_TYPE_NONE) { // We're here because of a failure - swprintf(tempmsg, sizeof_w(tempmsg), L"%ls:

%s

%ls", plat_get_string(IDS_2167), net_drv_error, plat_get_string(IDS_2168)); + swprintf(tempmsg, sizeof_w(tempmsg), L"%ls:

%s

%ls", plat_get_string(STRING_NET_ERROR), net_drv_error, plat_get_string(STRING_NET_ERROR_DESC)); ui_msgbox(MBX_ERROR, tempmsg); net_cards_conf[net_card_current].net_type = NET_TYPE_NONE; } diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index c0e3958b2..e6362019f 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -23,7 +23,6 @@ #include #include #include <86box/86box.h> -#include <86box/language.h> #include <86box/lpt.h> #include <86box/timer.h> #include <86box/pit.h> @@ -352,7 +351,7 @@ ps_init(void *lpt) } #endif if (ghostscript_handle == NULL) { - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2115, (wchar_t *) IDS_2133); + ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_GHOSTSCRIPT_ERROR_TITLE), plat_get_string(STRING_GHOSTSCRIPT_ERROR_DESC)); } else { if (gsapi_revision(&rev, sizeof(rev)) == 0) { pclog("Loaded %s, rev %ld (%ld)\n", rev.product, rev.revision, rev.revisiondate); diff --git a/src/qt/qt_harddiskdialog.cpp b/src/qt/qt_harddiskdialog.cpp index 187bf4ba2..5efd895dc 100644 --- a/src/qt/qt_harddiskdialog.cpp +++ b/src/qt/qt_harddiskdialog.cpp @@ -516,8 +516,8 @@ HarddiskDialog::onExistingFileSelected(const QString &fileName, bool precheck) fp = _wfopen(wopenfilestring, L"rb"); if (fp != NULL) { fclose(fp); - if (settings_msgbox_ex(MBX_QUESTION_YN, (wchar_t *) IDS_4111, (wchar_t *) IDS_4118, (wchar_t *) IDS_4120, (wchar_t *) IDS_4121, NULL) != 0) / * yes * / - return FALSE; + if (settings_msgbox_ex(MBX_QUESTION_YN, L"Disk image file already exists", L"The selected file will be overwritten. Are you sure you want to use it?", L"Overwrite", L"Don't overwrite", NULL) != 0) / * yes * / + return false; } } @@ -525,8 +525,8 @@ HarddiskDialog::onExistingFileSelected(const QString &fileName, bool precheck) if (fp == NULL) { hdd_add_file_open_error: fclose(fp); - settings_msgbox_header(MBX_ERROR, (existing & 1) ? (wchar_t *) IDS_4114 : (wchar_t *) IDS_4115, (existing & 1) ? (wchar_t *) IDS_4107 : (wchar_t *) IDS_4108); - return TRUE; + settings_msgbox_header(MBX_ERROR, (existing & 1) ? L"Make sure the file exists and is readable." : L"Make sure the file is being saved to a writable directory.", (existing & 1) ? L"Unable to read file" : L"Unable to write file"); + return true; } #endif diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index f87f8b6a9..493563c66 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -214,7 +214,11 @@ main(int argc, char *argv[]) #endif if (!pc_init_modules()) { - ui_msgbox_header(MBX_FATAL, (void *) IDS_2121, (void *) IDS_2056); + QMessageBox fatalbox(QMessageBox::Icon::Critical, QObject::tr("No ROMs found"), + QObject::tr("86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory."), + QMessageBox::Ok); + fatalbox.setTextFormat(Qt::TextFormat::RichText); + fatalbox.exec(); return 6; } diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 04a255ac8..079906753 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -597,31 +597,29 @@ void ProgSettings::reloadStrings() { translatedstrings.clear(); - translatedstrings[IDS_2077] = QCoreApplication::translate("", "Click to capture mouse").toStdWString(); - translatedstrings[IDS_2078] = QCoreApplication::translate("", "Press F8+F12 to release mouse").replace("F8+F12", MOUSE_CAPTURE_KEYSEQ).replace("CTRL-END", QLocale::system().name() == "de_DE" ? "Strg+Ende" : "CTRL-END").toStdWString(); - translatedstrings[IDS_2079] = QCoreApplication::translate("", "Press F8+F12 or middle button to release mouse").replace("F8+F12", MOUSE_CAPTURE_KEYSEQ).replace("CTRL-END", QLocale::system().name() == "de_DE" ? "Strg+Ende" : "CTRL-END").toStdWString(); - translatedstrings[IDS_2131] = QCoreApplication::translate("", "Invalid configuration").toStdWString(); - translatedstrings[IDS_4099] = QCoreApplication::translate("", "MFM/RLL or ESDI CD-ROM drives never existed").toStdWString(); - translatedstrings[IDS_2095] = QCoreApplication::translate("", "No PCap devices found").toStdWString(); - translatedstrings[IDS_2096] = QCoreApplication::translate("", "Invalid PCap device").toStdWString(); - translatedstrings[IDS_2130] = QCoreApplication::translate("", "Make sure libpcap is installed and that you are on a libpcap-compatible network connection.").toStdWString(); - translatedstrings[IDS_2115] = QCoreApplication::translate("", "Unable to initialize Ghostscript").toStdWString(); - translatedstrings[IDS_2063] = QCoreApplication::translate("", "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine.").toStdWString(); - translatedstrings[IDS_2064] = QCoreApplication::translate("", "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card.").toStdWString(); - translatedstrings[IDS_2163] = QCoreApplication::translate("", "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card.").toStdWString(); - translatedstrings[IDS_2129] = QCoreApplication::translate("", "Hardware not available").toStdWString(); - translatedstrings[IDS_2143] = QCoreApplication::translate("", "Monitor in sleep mode").toStdWString(); - translatedstrings[IDS_2121] = QCoreApplication::translate("", "No ROMs found").toStdWString(); - translatedstrings[IDS_2056] = QCoreApplication::translate("", "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory.").toStdWString(); - translatedstrings[IDS_2167] = QCoreApplication::translate("", "Failed to initialize network driver").toStdWString(); - translatedstrings[IDS_2168] = QCoreApplication::translate("", "The network configuration will be switched to the null driver").toStdWString(); + translatedstrings[STRING_MOUSE_CAPTURE] = QCoreApplication::translate("", "Click to capture mouse").toStdWString(); + translatedstrings[STRING_MOUSE_RELEASE] = QCoreApplication::translate("", "Press F8+F12 to release mouse").replace("F8+F12", MOUSE_CAPTURE_KEYSEQ).replace("CTRL-END", QLocale::system().name() == "de_DE" ? "Strg+Ende" : "CTRL-END").toStdWString(); + translatedstrings[STRING_MOUSE_RELEASE_MMB] = QCoreApplication::translate("", "Press F8+F12 or middle button to release mouse").replace("F8+F12", MOUSE_CAPTURE_KEYSEQ).replace("CTRL-END", QLocale::system().name() == "de_DE" ? "Strg+Ende" : "CTRL-END").toStdWString(); + translatedstrings[STRING_INVALID_CONFIG] = QCoreApplication::translate("", "Invalid configuration").toStdWString(); + translatedstrings[STRING_NO_ST506_ESDI_CDROM] = QCoreApplication::translate("", "MFM/RLL or ESDI CD-ROM drives never existed").toStdWString(); + translatedstrings[STRING_PCAP_ERROR_NO_DEVICES] = QCoreApplication::translate("", "No PCap devices found").toStdWString(); + translatedstrings[STRING_PCAP_ERROR_INVALID_DEVICE] = QCoreApplication::translate("", "Invalid PCap device").toStdWString(); + translatedstrings[STRING_PCAP_ERROR_DESC] = QCoreApplication::translate("", "Make sure libpcap is installed and that you are on a libpcap-compatible network connection.").toStdWString(); + translatedstrings[STRING_GHOSTSCRIPT_ERROR_TITLE] = QCoreApplication::translate("", "Unable to initialize Ghostscript").toStdWString(); + translatedstrings[STRING_HW_NOT_AVAILABLE_MACHINE] = QCoreApplication::translate("", "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine.").toStdWString(); + translatedstrings[STRING_HW_NOT_AVAILABLE_VIDEO] = QCoreApplication::translate("", "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card.").toStdWString(); + translatedstrings[STRING_HW_NOT_AVAILABLE_VIDEO2] = QCoreApplication::translate("", "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card.").toStdWString(); + translatedstrings[STRING_HW_NOT_AVAILABLE_TITLE] = QCoreApplication::translate("", "Hardware not available").toStdWString(); + translatedstrings[STRING_MONITOR_SLEEP] = QCoreApplication::translate("", "Monitor in sleep mode").toStdWString(); + translatedstrings[STRING_NET_ERROR] = QCoreApplication::translate("", "Failed to initialize network driver").toStdWString(); + translatedstrings[STRING_NET_ERROR_DESC] = QCoreApplication::translate("", "The network configuration will be switched to the null driver").toStdWString(); - auto gsstr = QCoreApplication::translate("", " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files."); + auto gsstr = QCoreApplication::translate("", " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files."); if (gsstr.contains("libgs")) { gsstr.replace("libgs", LIB_NAME_GS); } else gsstr.prepend(LIB_NAME_GS); - translatedstrings[IDS_2133] = gsstr.toStdWString(); + translatedstrings[STRING_GHOSTSCRIPT_ERROR_DESC] = gsstr.toStdWString(); } wchar_t * diff --git a/src/qt/qt_ui.cpp b/src/qt/qt_ui.cpp index b544bbde1..5412a0e4a 100644 --- a/src/qt/qt_ui.cpp +++ b/src/qt/qt_ui.cpp @@ -122,11 +122,6 @@ plat_mouse_capture(int on) int ui_msgbox_header(int flags, void *header, void *message) { - if (header <= (void *) 7168) - header = plat_get_string((uintptr_t) header); - if (message <= (void *) 7168) - message = plat_get_string((uintptr_t) message); - auto hdr = (flags & MBX_ANSI) ? QString((char *) header) : QString::fromWCharArray(reinterpret_cast(header)); auto msg = (flags & MBX_ANSI) ? QString((char *) message) : QString::fromWCharArray(reinterpret_cast(message)); diff --git a/src/unix/unix.c b/src/unix/unix.c index 9cce3c898..3eddc2bbb 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -246,33 +246,33 @@ wchar_t * plat_get_string(int i) { switch (i) { - case IDS_2077: + case STRING_MOUSE_CAPTURE: return L"Click to capture mouse"; - case IDS_2078: + case STRING_MOUSE_RELEASE: return L"Press CTRL-END to release mouse"; - case IDS_2079: + case STRING_MOUSE_RELEASE_MMB: return L"Press CTRL-END or middle button to release mouse"; - case IDS_2131: + case STRING_INVALID_CONFIG: return L"Invalid configuration"; - case IDS_4099: + case STRING_NO_ST506_ESDI_CDROM: return L"MFM/RLL or ESDI CD-ROM drives never existed"; - case IDS_2095: + case STRING_PCAP_ERROR_NO_DEVICES: return L"No PCap devices found"; - case IDS_2096: + case STRING_PCAP_ERROR_INVALID_DEVICE: return L"Invalid PCap device"; - case IDS_2133: + case STRING_GHOSTSCRIPT_ERROR_DESC: return L"libgs is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files."; - case IDS_2130: + case STRING_PCAP_ERROR_DESC: return L"Make sure libpcap is installed and that you are on a libpcap-compatible network connection."; - case IDS_2115: + case STRING_GHOSTSCRIPT_ERROR_TITLE: return L"Unable to initialize Ghostscript"; - case IDS_2063: + case STRING_HW_NOT_AVAILABLE_MACHINE: return L"Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine."; - case IDS_2064: + case STRING_HW_NOT_AVAILABLE_VIDEO: return L"Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card."; - case IDS_2129: + case STRING_HW_NOT_AVAILABLE_TITLE: return L"Hardware not available"; - case IDS_2143: + case STRING_MONITOR_SLEEP: return L"Monitor in sleep mode"; } return L""; @@ -638,10 +638,6 @@ ui_msgbox_header(int flags, void *header, void *message) if (!header) header = (void *) ((flags & MBX_ANSI) ? "86Box" : L"86Box"); - if (header <= (void *) 7168) - header = (void *) plat_get_string((uintptr_t) header); - if (message <= (void *) 7168) - message = (void *) plat_get_string((uintptr_t) message); msgbtn.buttonid = 1; msgbtn.text = "OK"; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index b20364689..6e32bdc40 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -957,7 +957,7 @@ svga_recalctimings(svga_t *svga) video_blit_memtoscreen_monitor(x_start, y_start, svga->monitor->mon_xsize + x_add, svga->monitor->mon_ysize + y_add, svga->monitor_index); video_wait_for_buffer_monitor(svga->monitor_index); svga->dpms_ui = 1; - ui_sb_set_text_w(plat_get_string(IDS_2143)); + ui_sb_set_text_w(plat_get_string(STRING_MONITOR_SLEEP)); } } else if (svga->dpms_ui) { svga->dpms_ui = 0; From ae7d4454cbbd115ad8977cd3ac6e1db908c5d567 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 20 Mar 2024 16:48:09 +0500 Subject: [PATCH 696/936] Move Windows font overrides away from translations Determine which font to use with a dedicated function instead --- src/qt/languages/ca-ES.po | 6 ------ src/qt/languages/cs-CZ.po | 6 ------ src/qt/languages/de-DE.po | 6 ------ src/qt/languages/en-GB.po | 6 ------ src/qt/languages/en-US.po | 6 ------ src/qt/languages/es-ES.po | 6 ------ src/qt/languages/fi-FI.po | 6 ------ src/qt/languages/fr-FR.po | 6 ------ src/qt/languages/hr-HR.po | 6 ------ src/qt/languages/hu-HU.po | 6 ------ src/qt/languages/it-IT.po | 6 ------ src/qt/languages/ja-JP.po | 6 ------ src/qt/languages/ko-KR.po | 6 ------ src/qt/languages/pl-PL.po | 6 ------ src/qt/languages/pt-BR.po | 6 ------ src/qt/languages/pt-PT.po | 6 ------ src/qt/languages/ru-RU.po | 6 ------ src/qt/languages/sk-SK.po | 6 ------ src/qt/languages/sl-SI.po | 6 ------ src/qt/languages/tr-TR.po | 6 ------ src/qt/languages/uk-UA.po | 6 ------ src/qt/languages/zh-CN.po | 6 ------ src/qt/languages/zh-TW.po | 6 ------ src/qt/qt_main.cpp | 4 +--- src/qt/qt_mainwindow.cpp | 4 +--- src/qt/qt_progsettings.cpp | 19 +++++++++++++++++++ src/qt/qt_progsettings.hpp | 3 +++ 27 files changed, 24 insertions(+), 144 deletions(-) diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po index 4554bec10..0074e4a01 100644 --- a/src/qt/languages/ca-ES.po +++ b/src/qt/languages/ca-ES.po @@ -625,12 +625,6 @@ msgstr "Dispositiu ISABugger" msgid "POST card" msgstr "Targeta POST" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index aa8ad5664..f02f63e14 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -625,12 +625,6 @@ msgstr "Zařízení ISABugger" msgid "POST card" msgstr "Karta pro kódy POST" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index 8a9360b96..62308e9d8 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -625,12 +625,6 @@ msgstr "ISABugger-Gerät" msgid "POST card" msgstr "POST-Code-Karte" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index e3d007cc4..8fb00f833 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -625,12 +625,6 @@ msgstr "ISABugger device" msgid "POST card" msgstr "POST card" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index 8b2c20ffe..147521bb3 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -625,12 +625,6 @@ msgstr "ISABugger device" msgid "POST card" msgstr "POST card" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index b88c38b07..066a31310 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -625,12 +625,6 @@ msgstr "Dispositivo ISABugger" msgid "POST card" msgstr "Tarjeta POST" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index 04a745816..a81857596 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -625,12 +625,6 @@ msgstr "ISABugger-laite" msgid "POST card" msgstr "POST-kortti" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index 3abe3e53f..4e9b94d33 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -625,12 +625,6 @@ msgstr "Dispositif ISABugger" msgid "POST card" msgstr "Carte POST" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index a830644a0..0255a8280 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -625,12 +625,6 @@ msgstr "Uređaj ISABugger" msgid "POST card" msgstr "Kartica POST" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index a22f6808e..e5225dbbb 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -625,12 +625,6 @@ msgstr "ISABugger eszköz" msgid "POST card" msgstr "POST kártya" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index 7ff74c116..43ece2315 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -625,12 +625,6 @@ msgstr "Dispositivo ISABugger" msgid "POST card" msgstr "Scheda POST" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index b5aaa82e7..971bbd29f 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -625,12 +625,6 @@ msgstr "ISABuggerデバイス" msgid "POST card" msgstr "POSTカード" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Meiryo UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index 59855f460..ea6e196fe 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -625,12 +625,6 @@ msgstr "ISABugger 장치" msgid "POST card" msgstr "POST 카드" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Malgun Gothic" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index b3e71ffa0..c6a70d905 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -625,12 +625,6 @@ msgstr "Urządzenie ISABugger" msgid "POST card" msgstr "Karta POST" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index b46012101..45d8a8530 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -625,12 +625,6 @@ msgstr "Dispositivo ISABugger" msgid "POST card" msgstr "Placa de diagnóstico" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index fc892f6dc..156f63926 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -625,12 +625,6 @@ msgstr "Dispositivo ISABugger" msgid "POST card" msgstr "Placa POST" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index 7ed5d0b5f..41cad4eda 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -712,12 +712,6 @@ msgstr "Карта POST" msgid "86Box Unit Tester" msgstr "Модульный Тестер 86Box" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index 8842a5215..a6d13b95b 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -625,12 +625,6 @@ msgstr "Zariadenie ISABugger" msgid "POST card" msgstr "Karta pre kódy POST" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index ae173ad30..93941ffe8 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -625,12 +625,6 @@ msgstr "Naprava ISABugger" msgid "POST card" msgstr "Kartica POST" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index 5c413fb58..c65f6077c 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -625,12 +625,6 @@ msgstr "ISABugger cihazı" msgid "POST card" msgstr "POST kartı" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index da48b74c7..f7a819a92 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -625,12 +625,6 @@ msgstr "Пристрій ISABugger" msgid "POST card" msgstr "Карта POST" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Segoe UI" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index 8a09cf87d..5c3fbb54f 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -625,12 +625,6 @@ msgstr "ISABugger 设备" msgid "POST card" msgstr "自检 (POST) 卡" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Microsoft YaHei" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index f05e16cd6..927eb2d85 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -625,12 +625,6 @@ msgstr "ISABugger 裝置" msgid "POST card" msgstr "自檢 (POST) 卡" -msgid "FONT_SIZE" -msgstr "9" - -msgid "FONT_NAME" -msgstr "Microsoft JhengHei" - msgid "86Box" msgstr "86Box" diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 493563c66..a621d1441 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -191,9 +191,7 @@ main(int argc, char *argv[]) fprintf(stderr, "Qt: version %s, platform \"%s\"\n", qVersion(), QApplication::platformName().toUtf8().data()); ProgSettings::loadTranslators(&app); #ifdef Q_OS_WINDOWS - auto font_name = QObject::tr("FONT_NAME"); - auto font_size = QObject::tr("FONT_SIZE"); - QApplication::setFont(QFont(font_name, font_size.toInt())); + QApplication::setFont(QFont(ProgSettings::getFontName(lang_id), 9)); SetCurrentProcessExplicitAppUserModelID(L"86Box.86Box"); #endif diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index f0d2cf431..f4c01b4a2 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -1919,9 +1919,7 @@ MainWindow::changeEvent(QEvent *event) { #ifdef Q_OS_WINDOWS if (event->type() == QEvent::LanguageChange) { - auto font_name = tr("FONT_NAME"); - auto font_size = tr("FONT_SIZE"); - QApplication::setFont(QFont(font_name, font_size.toInt())); + QApplication::setFont(QFont(ProgSettings::getFontName(lang_id), 9)); } #endif QWidget::changeEvent(event); diff --git a/src/qt/qt_progsettings.cpp b/src/qt/qt_progsettings.cpp index cf15e6c04..2d047a787 100644 --- a/src/qt/qt_progsettings.cpp +++ b/src/qt/qt_progsettings.cpp @@ -153,6 +153,25 @@ ProgSettings::on_pushButton_released() ui->comboBox->setCurrentIndex(0); } +#ifdef Q_OS_WINDOWS +/* Return the standard font name on Windows, which is overridden per-language + to prevent CJK fonts with embedded bitmaps being chosen as a fallback. */ +QString +ProgSettings::getFontName(uint32_t lcid) +{ + if (lcid == 0x0804) /* zh-CN */ + return "Microsoft YaHei"; + else if (lcid == 0x0404) /* zh-TW */ + return "Microsoft JhengHei"; + else if (lcid == 0x0411) /* ja-JP */ + return "Meiryo UI"; + else if (lcid == 0x0412) /* ko-KR */ + return "Malgun Gothic"; + else + return "Segoe UI"; +} +#endif + void ProgSettings::loadTranslators(QObject *parent) { diff --git a/src/qt/qt_progsettings.hpp b/src/qt/qt_progsettings.hpp index 7565869b0..d41f267df 100644 --- a/src/qt/qt_progsettings.hpp +++ b/src/qt/qt_progsettings.hpp @@ -16,6 +16,9 @@ public: ~ProgSettings(); static QString getIconSetPath(); static QIcon loadIcon(QString file); +#ifdef Q_OS_WINDOWS + static QString getFontName(uint32_t lcid); +#endif static void loadTranslators(QObject *parent = nullptr); static void reloadStrings(); class CustomTranslator : public QTranslator { From 3cc0a9176cab43efebcc614df0aee2adfbaa07a3 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 20 Mar 2024 16:49:15 +0500 Subject: [PATCH 697/936] Remove unused and unmaintained pcap_if utility --- src/network/pcap_if.c | 296 ------------------------------------------ 1 file changed, 296 deletions(-) delete mode 100644 src/network/pcap_if.c diff --git a/src/network/pcap_if.c b/src/network/pcap_if.c deleted file mode 100644 index 1d3e39221..000000000 --- a/src/network/pcap_if.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * VARCem Virtual ARchaeological Computer EMulator. - * An emulator of (mostly) x86-based PC systems and devices, - * using the ISA,EISA,VLB,MCA and PCI system buses, roughly - * spanning the era between 1981 and 1995. - * - * Simple program to show usage of (Win)Pcap. - * - * Based on the "libpcap" examples. - * - * - * - * Authors: Fred N. van Kempen, - * - * Copyright 2017-2018 Fred N. van Kempen. - * - * Redistribution and use in source and binary forms, with - * or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the entire - * above notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names - * of its contributors may be used to endorse or promote - * products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/plat.h> -#include <86box/plat_dynld.h> - -static void *pcap_handle; /* handle to WinPcap DLL */ - -/* Pointers to the real functions. */ -static int (*f_pcap_findalldevs)(pcap_if_t **, char *); -static void (*f_pcap_freealldevs)(pcap_if_t *); -static pcap_t *(*f_pcap_open_live)(const char *, int, int, int, char *); -static int (*f_pcap_next_ex)(pcap_t *, struct pcap_pkthdr **, const unsigned char **); -static void (*f_pcap_close)(pcap_t *); -static dllimp_t pcap_imports[] = { - // clang-format off - { "pcap_findalldevs", &f_pcap_findalldevs }, - { "pcap_freealldevs", &f_pcap_freealldevs }, - { "pcap_open_live", &f_pcap_open_live }, - { "pcap_next_ex", &f_pcap_next_ex }, - { "pcap_close", &f_pcap_close }, - { NULL, NULL }, - // clang-format on -}; - -typedef struct { - char device[128]; - char description[128]; -} capdev_t; - -/* Retrieve an easy-to-use list of devices. */ -static int -get_devlist(capdev_t *list) -{ - char errbuf[PCAP_ERRBUF_SIZE]; - pcap_if_t *devlist; - int i = 0; - - /* Retrieve the device list from the local machine */ - if (f_pcap_findalldevs(&devlist, errbuf) == -1) { - fprintf(stderr, "Error in pcap_findalldevs_ex: %s\n", errbuf); - return (-1); - } - - for (pcap_if_t *dev = devlist; dev != NULL; dev = dev->next) { - strcpy(list->device, dev->name); - if (dev->description) - strcpy(list->description, dev->description); - else - memset(list->description, '\0', sizeof(list->description)); - list++; - i++; - } - - /* Release the memory. */ - f_pcap_freealldevs(devlist); - - return i; -} - -/* Simple HEXDUMP routine for raw data. */ -static void -hex_dump(unsigned char *bufp, int len) -{ - char asci[20]; - unsigned char c; - long addr; - - addr = 0; - while (len-- > 0) { - c = bufp[addr]; - if ((addr % 16) == 0) - printf("%04lx %02x", addr, c); - else - printf(" %02x", c); - asci[addr & 15] = (uint8_t) isprint(c) ? c : '.'; - if ((++addr % 16) == 0) { - asci[16] = '\0'; - printf(" | %s |\n", asci); - } - } - - if (addr % 16) { - while (addr % 16) { - printf(" "); - asci[addr & 15] = ' '; - addr++; - } - asci[16] = '\0'; - printf(" | %s |\n", asci); - } -} - -/* Print a standard Ethernet MAC address. */ -static void -eth_praddr(unsigned char *ptr) -{ - printf("%02x:%02x:%02x:%02x:%02x:%02x", - ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]); -} - -/* Print a standard Ethernet header. */ -static int -eth_prhdr(unsigned char *ptr) -{ - unsigned short type; - - printf("Ethernet "); - eth_praddr(ptr + 6); - printf(" > "); - eth_praddr(ptr); - type = (ptr[12] << 8) | ptr[13]; - printf(" type %04x\n", type); - - return 14; -} - -/* Capture packets from the network, and print them. */ -static int -start_cap(char *dev) -{ - char temp[PCAP_ERRBUF_SIZE]; - struct pcap_pkthdr *hdr; - const unsigned char *pkt; - const struct tm *ltime; - time_t now; - pcap_t *pcap; - int rc; - - /* Open the device for reading from it. */ - pcap = f_pcap_open_live(dev, - 1518, /* MTU */ - 1, /* promisc mode */ - 10, /* timeout */ - temp); - if (pcap == NULL) { - fprintf(stderr, "Pcap: open_live(%s): %s\n", dev, temp); - return 2; - } - - printf("Listening on '%s'..\n", dev); - for (;;) { - rc = f_pcap_next_ex(pcap, &hdr, &pkt); - if (rc < 0) - break; - - /* Did we time out? */ - if (rc == 0) - continue; - - /* Convert the timestamp to readable format. */ - now = hdr->ts.tv_sec; - ltime = localtime(&now); - strftime(temp, sizeof(temp), "%H:%M:%S", ltime); - - /* Process and print the packet. */ - printf("\n<< %s,%.6ld len=%u\n", - temp, hdr->ts.tv_usec, hdr->len); - rc = eth_prhdr((unsigned char *) pkt); - hex_dump((unsigned char *) pkt + rc, hdr->len - rc); - } - - /* All done, close up. */ - f_pcap_close(pcap); - - return 0; -} - -/* Show a list of available network interfaces. */ -static void -show_devs(capdev_t *list, int num) -{ - if (num > 0) { - printf("Available network interfaces:\n\n"); - - for (int i = 0; i < num; i++) { - printf(" %d - %s\n", i + 1, list->device); - if (list->description[0] != '\0') - printf(" (%s)\n", list->description); - else - printf(" (No description available)\n"); - list++; - printf("\n"); - } - } else { - printf("No interfaces found!\nMake sure WinPcap is installed.\n"); - } -} - -int -main(int argc, char **argv) -{ - capdev_t interfaces[32]; - int numdev; - int i; - - /* Try loading the DLL. */ -#ifdef _WIN32 - pcap_handle = dynld_module("wpcap.dll", pcap_imports); -#elif defined __APPLE__ - pcap_handle = dynld_module("libpcap.dylib", pcap_imports); -#else - pcap_handle = dynld_module("libpcap.so", pcap_imports); -#endif - if (pcap_handle == NULL) { -#ifdef _WIN32 - fprintf(stderr, "Unable to load WinPcap DLL !\n"); -#else - fprintf(stderr, "Unable to load libpcap.so !\n"); -#endif - return 1; - } - - /* Get the list. */ - numdev = get_devlist(interfaces); - - if (argc == 1) { - /* No arguments, just show the list. */ - show_devs(interfaces, numdev); - - dynld_close(pcap_handle); - - return numdev; - } - - /* Assume argument to be the interface number to listen on. */ - i = atoi(argv[1]); - if (i < 0 || i > numdev) { - fprintf(stderr, "Invalid interface number %d !\n", i); - - dynld_close(pcap_handle); - - return 1; - } - - /* Looks good, go and listen.. */ - i = start_cap(interfaces[i - 1].device); - - dynld_close(pcap_handle); - - return i; -} From 82e6a7a1293d91267110f0ecda22a3ead00c8ecd Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 20 Mar 2024 17:17:12 +0500 Subject: [PATCH 698/936] Don't recognize no longer used HDD bus types --- src/disk/hdd.c | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 23dd51b92..7acfc82be 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -50,7 +50,7 @@ hdd_string_to_bus(char *str, int cdrom) if (!strcmp(str, "none")) return HDD_BUS_DISABLED; - if (!strcmp(str, "mfm") || !strcmp(str, "rll")) { + if (!strcmp(str, "mfm")) { if (cdrom) { no_cdrom: ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_INVALID_CONFIG), plat_get_string(STRING_NO_ST506_ESDI_CDROM)); @@ -60,41 +60,22 @@ no_cdrom: return HDD_BUS_MFM; } - /* FIXME: delete 'rll' in a year or so.. --FvK */ - if (!strcmp(str, "esdi") || !strcmp(str, "rll")) { + if (!strcmp(str, "esdi")) { if (cdrom) goto no_cdrom; return HDD_BUS_ESDI; } - if (!strcmp(str, "ide_pio_only")) - return HDD_BUS_IDE; - if (!strcmp(str, "ide")) return HDD_BUS_IDE; - if (!strcmp(str, "atapi_pio_only")) - return HDD_BUS_ATAPI; - if (!strcmp(str, "atapi")) return HDD_BUS_ATAPI; - if (!strcmp(str, "eide")) - return HDD_BUS_IDE; - if (!strcmp(str, "xta")) return HDD_BUS_XTA; - if (!strcmp(str, "atide")) - return HDD_BUS_IDE; - - if (!strcmp(str, "ide_pio_and_dma")) - return HDD_BUS_IDE; - - if (!strcmp(str, "atapi_pio_and_dma")) - return HDD_BUS_ATAPI; - if (!strcmp(str, "scsi")) return HDD_BUS_SCSI; From f02fd4568c461aad97f29623f2780b9d572a0146 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 20 Mar 2024 18:52:51 +0500 Subject: [PATCH 699/936] Simplify dynamic string handling and localization Use Qt `.arg()` instead of substring replacement; Fully remove remnants of SDL renderers from translations; Restore platform-dependent pcap library name in the pcap error message, but use Npcap on Windows instead --- src/qt/languages/ca-ES.po | 47 ++++++++++++---------------------- src/qt/languages/cs-CZ.po | 47 ++++++++++++---------------------- src/qt/languages/de-DE.po | 50 ++++++++++++++----------------------- src/qt/languages/en-GB.po | 47 ++++++++++++---------------------- src/qt/languages/en-US.po | 47 ++++++++++++---------------------- src/qt/languages/es-ES.po | 47 ++++++++++++---------------------- src/qt/languages/fi-FI.po | 47 ++++++++++++---------------------- src/qt/languages/fr-FR.po | 47 ++++++++++++---------------------- src/qt/languages/hr-HR.po | 47 ++++++++++++---------------------- src/qt/languages/hu-HU.po | 47 ++++++++++++---------------------- src/qt/languages/it-IT.po | 47 ++++++++++++---------------------- src/qt/languages/ja-JP.po | 47 ++++++++++++---------------------- src/qt/languages/ko-KR.po | 47 ++++++++++++---------------------- src/qt/languages/pl-PL.po | 47 ++++++++++++---------------------- src/qt/languages/pt-BR.po | 47 ++++++++++++---------------------- src/qt/languages/pt-PT.po | 47 ++++++++++++---------------------- src/qt/languages/ru-RU.po | 47 ++++++++++++---------------------- src/qt/languages/sk-SK.po | 47 ++++++++++++---------------------- src/qt/languages/sl-SI.po | 47 ++++++++++++---------------------- src/qt/languages/tr-TR.po | 47 ++++++++++++---------------------- src/qt/languages/uk-UA.po | 47 ++++++++++++---------------------- src/qt/languages/zh-CN.po | 47 ++++++++++++---------------------- src/qt/languages/zh-TW.po | 47 ++++++++++++---------------------- src/qt/qt_machinestatus.cpp | 12 ++++----- src/qt/qt_platform.cpp | 22 +++++++--------- src/qt/qt_progsettings.hpp | 6 ----- 26 files changed, 386 insertions(+), 738 deletions(-) diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po index 0074e4a01..ff69d11a7 100644 --- a/src/qt/languages/ca-ES.po +++ b/src/qt/languages/ca-ES.po @@ -40,14 +40,11 @@ msgstr "&Recordar mida i posició" msgid "Re&nderer" msgstr "Re&nderitzador" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ msgstr "Altres perifèrics" msgid "Click to capture mouse" msgstr "Feu clic per capturar el ratolí" -msgid "Press F8+F12 to release mouse" -msgstr "Premeu F8+F12 per alliberar el ratolí" +msgid "Press %1 to release mouse" +msgstr "Premeu %1 per alliberar el ratolí" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Premeu F8+F12 o el botó central per alliberar el ratolí" +msgid "Press %1 or middle button to release mouse" +msgstr "Premeu %1 o el botó central per alliberar el ratolí" msgid "Bus" msgstr "Bus" @@ -853,26 +850,14 @@ msgstr "Un emulador d'ordinadors antics\n\nAutors: Miran Grča (OBattler), Richa msgid "Hardware not available" msgstr "Maquinari no disponible" -msgid "WinPcap" -msgstr "WinPcap" - -msgid "libpcap" -msgstr "libpcap" - -msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "Assegureu-vos que el libpcap està instal·lat i que està en una connexió de xarxa compatible amb libpcap." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Assegureu-vos que el %1 està instal·lat i que està en una connexió de xarxa compatible amb %1." msgid "Invalid configuration" msgstr "Configuració invàlida" -msgid "gsdll32.dll" -msgstr "gsdll32.dll" - -msgid "libgs" -msgstr "libgs" - -msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr " és necessària per a la conversió automàtica de fitxers PostScript a PDF.\n\nQualsevol document enviat a la impressora genèrica postScript es desarà com a fitxer PostScript (.ps)." +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "%1 és necessària per a la conversió automàtica de fitxers PostScript a PDF.\n\nQualsevol document enviat a la impressora genèrica postScript es desarà com a fitxer PostScript (.ps)." msgid "Entering fullscreen mode" msgstr "Entrant en mode pantalla completa" @@ -892,8 +877,8 @@ msgstr "No resetejar" msgid "CD-ROM images" msgstr "Imatges de CD-ROM" -msgid "%hs Device Configuration" -msgstr "%hs Configuració de Dispositiu" +msgid "%1 Device Configuration" +msgstr "%1 Configuració de Dispositiu" msgid "Monitor in sleep mode" msgstr "Monitor en mode estalvi" @@ -949,8 +934,8 @@ msgstr "Reinicialització completa" msgid "ACPI shutdown" msgstr "Apagada ACPI" -msgid "Hard disk (%s)" -msgstr "Disc dur (%s)" +msgid "Hard disk (%1)" +msgstr "Disc dur (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index f02f63e14..f89521fdf 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -40,14 +40,11 @@ msgstr "&Pamatovat velikost a pozici" msgid "Re&nderer" msgstr "&Renderer" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ msgstr "Jiné příslušenství" msgid "Click to capture mouse" msgstr "Klikněte pro zabraní myši" -msgid "Press F8+F12 to release mouse" -msgstr "Stiskněte F8+F12 pro uvolnění myši" +msgid "Press %1 to release mouse" +msgstr "Stiskněte %1 pro uvolnění myši" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Stiskněte F8+F12 nebo prostřední tlačítko pro uvolnění myši" +msgid "Press %1 or middle button to release mouse" +msgstr "Stiskněte %1 nebo prostřední tlačítko pro uvolnění myši" msgid "Bus" msgstr "Sběrnice" @@ -853,26 +850,14 @@ msgstr "Emulátor starých počítačů\n\nAutoři: Miran Grča (OBattler), Rich msgid "Hardware not available" msgstr "Hardware není dostupný" -msgid "WinPcap" -msgstr "WinPcap" - -msgid "libpcap" -msgstr "libpcap" - -msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "Ujistěte se, že je nainstalován libpcap a používáte síťové připojení s ním kompatibilní." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Ujistěte se, že je nainstalován %1 a používáte síťové připojení s ním kompatibilní." msgid "Invalid configuration" msgstr "Neplatná konfigurace" -msgid "gsdll32.dll" -msgstr "gsdll32.dll" - -msgid "libgs" -msgstr "libgs" - -msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr " je potřeba pro automatický převod PostScript dokumentů do PDF.\n\nJakékoliv dokumenty vytisknuté přes obecnou PostScriptovou tiskárnu budou uloženy jako PostScript (.ps) soubory." +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "%1 je potřeba pro automatický převod PostScript dokumentů do PDF.\n\nJakékoliv dokumenty vytisknuté přes obecnou PostScriptovou tiskárnu budou uloženy jako PostScript (.ps) soubory." msgid "Entering fullscreen mode" msgstr "Vstup do režimu celé obrazovky" @@ -892,8 +877,8 @@ msgstr "Neresetovat" msgid "CD-ROM images" msgstr "Obraz CD-ROM disku" -msgid "%hs Device Configuration" -msgstr "Konfigurace zařízení %hs" +msgid "%1 Device Configuration" +msgstr "Konfigurace zařízení %1" msgid "Monitor in sleep mode" msgstr "Monitor je v režimu spánku" @@ -949,8 +934,8 @@ msgstr "Resetovat" msgid "ACPI shutdown" msgstr "Vypnout skrze rozhraní ACPI" -msgid "Hard disk (%s)" -msgstr "Pevný disk (%s)" +msgid "Hard disk (%1)" +msgstr "Pevný disk (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index 62308e9d8..6c898c25c 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -40,14 +40,11 @@ msgstr "&Größe && Position merken" msgid "Re&nderer" msgstr "Re&nderer" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0-Kern)" @@ -718,11 +715,14 @@ msgstr "Andere Peripheriegeräte" msgid "Click to capture mouse" msgstr "Zum Einfangen des Mauszeigers bitte klicken" -msgid "Press F8+F12 to release mouse" -msgstr "Bitte F8+F12 zur Mausfreigabe drücken" +msgid "Press %1 to release mouse" +msgstr "Bitte %1 zur Mausfreigabe drücken" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Bitte F8+F12 oder die mittlere Maustaste zur Mausfreigabe drücken" +msgid "Press %1 or middle button to release mouse" +msgstr "Bitte %1 oder die mittlere Maustaste zur Mausfreigabe drücken" + +msgid "Ctrl+End" +msgstr "Strg+Ende" msgid "Bus" msgstr "Bus" @@ -853,26 +853,14 @@ msgstr "Ein Emulator für alte Computer\n\nAutoren: Miran Grča (OBattler), Rich msgid "Hardware not available" msgstr "Hardware nicht verfügbar" -msgid "WinPcap" -msgstr "WinPcap" - -msgid "libpcap" -msgstr "libpcap" - -msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "Bitte stellen Sie sicher, dass libpcap installiert ist und sie eine libpcap-kompatible Netzwerkverbindung nutzen." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Bitte stellen Sie sicher, dass %1 installiert ist und sie eine %1-kompatible Netzwerkverbindung nutzen." msgid "Invalid configuration" msgstr "Ungültige Konfiguration" -msgid "gsdll32.dll" -msgstr "gsdll32.dll" - -msgid "libgs" -msgstr "libgs" - -msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr " wird zur automatischen Konversion von PostScript-Dateien in das PDF-Format benötigt.\n\nSämtliche an den generischen PostScript-Drucker gesendete Dateien werden als PostScript (.ps)-Dateien gesichert." +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "%1 wird zur automatischen Konversion von PostScript-Dateien in das PDF-Format benötigt.\n\nSämtliche an den generischen PostScript-Drucker gesendete Dateien werden als PostScript (.ps)-Dateien gesichert." msgid "Entering fullscreen mode" msgstr "Vollbildmodus wird aktiviert" @@ -892,8 +880,8 @@ msgstr "Nicht zurücksetzen" msgid "CD-ROM images" msgstr "CD-ROM-Images" -msgid "%hs Device Configuration" -msgstr "%hs-Gerätekonfiguration" +msgid "%1 Device Configuration" +msgstr "%1-Gerätekonfiguration" msgid "Monitor in sleep mode" msgstr "Monitor im Standbymodus" @@ -949,8 +937,8 @@ msgstr "Hard-Reset" msgid "ACPI shutdown" msgstr "ACPI-basiertes Herunterfahren" -msgid "Hard disk (%s)" -msgstr "Festplatte (%s)" +msgid "Hard disk (%1)" +msgstr "Festplatte (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index 8fb00f833..a1ee53f0a 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -40,14 +40,11 @@ msgstr "R&emember size && position" msgid "Re&nderer" msgstr "Re&nderer" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ msgstr "Other peripherals" msgid "Click to capture mouse" msgstr "Click to capture mouse" -msgid "Press F8+F12 to release mouse" -msgstr "Press F8+F12 to release mouse" +msgid "Press %1 to release mouse" +msgstr "Press %1 to release mouse" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Press F8+F12 or middle button to release mouse" +msgid "Press %1 or middle button to release mouse" +msgstr "Press %1 or middle button to release mouse" msgid "Bus" msgstr "Bus" @@ -853,26 +850,14 @@ msgstr "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), Richard msgid "Hardware not available" msgstr "Hardware not available" -msgid "WinPcap" -msgstr "WinPcap" - -msgid "libpcap" -msgstr "libpcap" - -msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Make sure %1 is installed and that you are on a %1-compatible network connection." msgid "Invalid configuration" msgstr "Invalid configuration" -msgid "gsdll32.dll" -msgstr "gsdll32.dll" - -msgid "libgs" -msgstr "libgs" - -msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." msgid "Entering fullscreen mode" msgstr "Entering fullscreen mode" @@ -892,8 +877,8 @@ msgstr "Don't reset" msgid "CD-ROM images" msgstr "CD-ROM images" -msgid "%hs Device Configuration" -msgstr "%hs Device Configuration" +msgid "%1 Device Configuration" +msgstr "%1 Device Configuration" msgid "Monitor in sleep mode" msgstr "Monitor in sleep mode" @@ -949,8 +934,8 @@ msgstr "Hard reset" msgid "ACPI shutdown" msgstr "ACPI shutdown" -msgid "Hard disk (%s)" -msgstr "Hard disk (%s)" +msgid "Hard disk (%1)" +msgstr "Hard disk (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index 147521bb3..854ce4bac 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -40,14 +40,11 @@ msgstr "R&emember size && position" msgid "Re&nderer" msgstr "Re&nderer" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ msgstr "Other peripherals" msgid "Click to capture mouse" msgstr "Click to capture mouse" -msgid "Press F8+F12 to release mouse" -msgstr "Press F8+F12 to release mouse" +msgid "Press %1 to release mouse" +msgstr "Press %1 to release mouse" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Press F8+F12 or middle button to release mouse" +msgid "Press %1 or middle button to release mouse" +msgstr "Press %1 or middle button to release mouse" msgid "Bus" msgstr "Bus" @@ -853,26 +850,14 @@ msgstr "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), Richard msgid "Hardware not available" msgstr "Hardware not available" -msgid "WinPcap" -msgstr "WinPcap" - -msgid "libpcap" -msgstr "libpcap" - -msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Make sure %1 is installed and that you are on a %1-compatible network connection." msgid "Invalid configuration" msgstr "Invalid configuration" -msgid "gsdll32.dll" -msgstr "gsdll32.dll" - -msgid "libgs" -msgstr "libgs" - -msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." msgid "Entering fullscreen mode" msgstr "Entering fullscreen mode" @@ -892,8 +877,8 @@ msgstr "Don't reset" msgid "CD-ROM images" msgstr "CD-ROM images" -msgid "%hs Device Configuration" -msgstr "%hs Device Configuration" +msgid "%1 Device Configuration" +msgstr "%1 Device Configuration" msgid "Monitor in sleep mode" msgstr "Monitor in sleep mode" @@ -949,8 +934,8 @@ msgstr "Hard reset" msgid "ACPI shutdown" msgstr "ACPI shutdown" -msgid "Hard disk (%s)" -msgstr "Hard disk (%s)" +msgid "Hard disk (%1)" +msgstr "Hard disk (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index 066a31310..f68c6926e 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -40,14 +40,11 @@ msgstr "&Recordar tamaño y posición" msgid "Re&nderer" msgstr "Re&nderizador" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ msgstr "Otros periféricos" msgid "Click to capture mouse" msgstr "Haga click para capturar el ratón" -msgid "Press F8+F12 to release mouse" -msgstr "Pulse F8+F12 para liberar el ratón" +msgid "Press %1 to release mouse" +msgstr "Pulse %1 para liberar el ratón" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Pulse F8+F12 o el botón central para liberar el ratón" +msgid "Press %1 or middle button to release mouse" +msgstr "Pulse %1 o el botón central para liberar el ratón" msgid "Bus" msgstr "Bus" @@ -853,26 +850,14 @@ msgstr "Un emulador de ordenadores antigüos\n\nAutores: Miran Grča (OBattler), msgid "Hardware not available" msgstr "Equipo no disponible" -msgid "WinPcap" -msgstr "WinPcap" - -msgid "libpcap" -msgstr "libpcap" - -msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "Asegúrate de que libpcap está instalado y de que estás en una conexión de red compatible con libpcap." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Asegúrate de que %1 está instalado y de que estás en una conexión de red compatible con %1." msgid "Invalid configuration" msgstr "Configuración inválida" -msgid "gsdll32.dll" -msgstr "gsdll32.dll" - -msgid "libgs" -msgstr "libgs" - -msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr " es necesaria para la conversión automática de archivos PostScript a PDF.\n\nCualquier documento enviado a la impresora genérica postScript se guardará como archivo PostScript (.ps)." +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "%1 es necesaria para la conversión automática de archivos PostScript a PDF.\n\nCualquier documento enviado a la impresora genérica postScript se guardará como archivo PostScript (.ps)." msgid "Entering fullscreen mode" msgstr "Entrando en modo pantalla completa" @@ -892,8 +877,8 @@ msgstr "No reinicializar" msgid "CD-ROM images" msgstr "Imágenes de CD-ROM" -msgid "%hs Device Configuration" -msgstr "%hs Configuración de Dispositivo" +msgid "%1 Device Configuration" +msgstr "%1 Configuración de Dispositivo" msgid "Monitor in sleep mode" msgstr "Monitor en modo ahorro" @@ -949,8 +934,8 @@ msgstr "Hard reset" msgid "ACPI shutdown" msgstr "Parada ACPI" -msgid "Hard disk (%s)" -msgstr "Disco duro (%s)" +msgid "Hard disk (%1)" +msgstr "Disco duro (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index a81857596..c34639550 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -40,14 +40,11 @@ msgstr "&Muista koko ja sijainti" msgid "Re&nderer" msgstr "&Renderöijä" -msgid "&SDL (Software)" -msgstr "&SDL (ohjelmistopohjainen)" +msgid "&Qt (Software)" +msgstr "&Qt (ohjelmistopohjainen)" -msgid "SDL (&Hardware)" -msgstr "SDL (&laitteistokiihdytetty)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ msgstr "Muut oheislaitteet" msgid "Click to capture mouse" msgstr "Kaappaa hiiri klikkaamalla" -msgid "Press F8+F12 to release mouse" -msgstr "Paina F8+F12 vapauttaaksesi hiiren" +msgid "Press %1 to release mouse" +msgstr "Paina %1 vapauttaaksesi hiiren" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Paina F8+F12 tai keskipainiketta vapauttaaksesi hiiren" +msgid "Press %1 or middle button to release mouse" +msgstr "Paina %1 tai keskipainiketta vapauttaaksesi hiiren" msgid "Bus" msgstr "Väylä" @@ -853,26 +850,14 @@ msgstr "Vanhojen tietokoneiden emulaattori\n\nTekijät: Miran Grča (OBattler), msgid "Hardware not available" msgstr "Laitteisto ei ole saatavilla" -msgid "WinPcap" -msgstr "WinPcap" - -msgid "libpcap" -msgstr "libpcap" - -msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "Varmista, että libpcap on asennettu ja että verkkoyhteytesi on libpcap-yhteensopiva." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Varmista, että %1 on asennettu ja että verkkoyhteytesi on %1-yhteensopiva." msgid "Invalid configuration" msgstr "Virheelliset määritykset" -msgid "gsdll32.dll" -msgstr "gsdll32.dll" - -msgid "libgs" -msgstr "libgs" - -msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr " vaaditaan PostScript-tiedostojen automaattiseen muuntamiseen PDF-tiedostoiksi.\n\nKaikki geneeriselle PostScript-tulostimelle lähetetyt asiakirjat tallennetaan PostScript (.ps) -tiedostoina." +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "%1 vaaditaan PostScript-tiedostojen automaattiseen muuntamiseen PDF-tiedostoiksi.\n\nKaikki geneeriselle PostScript-tulostimelle lähetetyt asiakirjat tallennetaan PostScript (.ps) -tiedostoina." msgid "Entering fullscreen mode" msgstr "Siirrytään koko näytön tilaan" @@ -892,8 +877,8 @@ msgstr "Älä käynnistä uudelleen" msgid "CD-ROM images" msgstr "CD-ROM-levykuvat" -msgid "%hs Device Configuration" -msgstr "%hs - Laitteen määritykset" +msgid "%1 Device Configuration" +msgstr "%1 - Laitteen määritykset" msgid "Monitor in sleep mode" msgstr "Näyttö lepotilassa" @@ -949,8 +934,8 @@ msgstr "Kylmä uudelleenkäynnistys" msgid "ACPI shutdown" msgstr "ACPI-sammutus" -msgid "Hard disk (%s)" -msgstr "Kiintolevy (%s)" +msgid "Hard disk (%1)" +msgstr "Kiintolevy (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index 4e9b94d33..3fe8faa2e 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -40,14 +40,11 @@ msgstr "S&auvegarder taille && position" msgid "Re&nderer" msgstr "Moteur de &rendu vidéo" -msgid "&SDL (Software)" -msgstr "&SDL (Logiciel)" +msgid "&Qt (Software)" +msgstr "&Qt (Logiciel)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Materiel)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ msgstr "Autres périfériques" msgid "Click to capture mouse" msgstr "Cliquer pour capturer la souris" -msgid "Press F8+F12 to release mouse" -msgstr "Appuyer sur F8+F12 pour libérer la souris" +msgid "Press %1 to release mouse" +msgstr "Appuyer sur %1 pour libérer la souris" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Appuyer sur F8+F12 ou le bouton central pour libérer la souris" +msgid "Press %1 or middle button to release mouse" +msgstr "Appuyer sur %1 ou le bouton central pour libérer la souris" msgid "Bus" msgstr "Bus" @@ -853,26 +850,14 @@ msgstr "Un émulateur de vieux ordinateurs\n\nAuteurs: Miran Grča (OBattler), R msgid "Hardware not available" msgstr "Matériel non disponible" -msgid "WinPcap" -msgstr "WinPcap" - -msgid "libpcap" -msgstr "libpcap" - -msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "Assurez-vous que libpcap est installé et que vou utilisez une connexion réseau compatible avec libpcap." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Assurez-vous que %1 est installé et que vou utilisez une connexion réseau compatible avec %1." msgid "Invalid configuration" msgstr "Configuration non valide" -msgid "gsdll32.dll" -msgstr "gsdll32.dll" - -msgid "libgs" -msgstr "libgs" - -msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr " est nécessair pour la conversion automatique des fichiers PostScript dans PDF.\n\nTous les documents envoyés à l'imprimante générique PostScript seront sauvés comme des fichiers PostScript (.ps)." +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "%1 est nécessair pour la conversion automatique des fichiers PostScript dans PDF.\n\nTous les documents envoyés à l'imprimante générique PostScript seront sauvés comme des fichiers PostScript (.ps)." msgid "Entering fullscreen mode" msgstr "Entrer en mode plein écran" @@ -892,8 +877,8 @@ msgstr "Ne pas réinitialiser" msgid "CD-ROM images" msgstr "Images CD-ROM" -msgid "%hs Device Configuration" -msgstr "Configuration du dispositif %hs" +msgid "%1 Device Configuration" +msgstr "Configuration du dispositif %1" msgid "Monitor in sleep mode" msgstr "Moniteur en mode veille" @@ -949,8 +934,8 @@ msgstr "Hard reset" msgid "ACPI shutdown" msgstr "Arrêt ACPI" -msgid "Hard disk (%s)" -msgstr "Disque dur (%s)" +msgid "Hard disk (%1)" +msgstr "Disque dur (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index 0255a8280..db8a157cd 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -40,14 +40,11 @@ msgstr "&Zapamtite veličinu i položaj" msgid "Re&nderer" msgstr "&Renderer" -msgid "&SDL (Software)" -msgstr "&SDL (Softver)" +msgid "&Qt (Software)" +msgstr "&Qt (Softver)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardver)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 jezgra)" @@ -718,11 +715,11 @@ msgstr "Ostali periferni uređaji" msgid "Click to capture mouse" msgstr "Kliknite da uhvatite miš" -msgid "Press F8+F12 to release mouse" -msgstr "Pritisnite F8+F12 za otpustanje miša" +msgid "Press %1 to release mouse" +msgstr "Pritisnite %1 za otpustanje miša" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Pritisnite F8+F12 ili srednji gumb miša za otpuštanje miša" +msgid "Press %1 or middle button to release mouse" +msgstr "Pritisnite %1 ili srednji gumb miša za otpuštanje miša" msgid "Bus" msgstr "Bus" @@ -853,26 +850,14 @@ msgstr "Emulator starih računala\n\nAutori: Miran Grča (OBattler), RichardG867 msgid "Hardware not available" msgstr "Hardver nije dostupan" -msgid "WinPcap" -msgstr "WinPcap" - -msgid "libpcap" -msgstr "libpcap" - -msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "Provjerite je li libpcap instaliran i jeste li na mreži, kompadibilnoj s libpcap." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Provjerite je li %1 instaliran i jeste li na mreži, kompadibilnoj s %1." msgid "Invalid configuration" msgstr "Nevažeća konfiguracija" -msgid "gsdll32.dll" -msgstr "gsdll32.dll" - -msgid "libgs" -msgstr "libgs" - -msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr " je potrebno za automatsku konverziju PostScript datoteke u PDF datoteke.\n\nSvi dokumenti poslani na generički PostScript pisač bit će spremljeni kao PostScript (.ps) datoteke." +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "%1 je potrebno za automatsku konverziju PostScript datoteke u PDF datoteke.\n\nSvi dokumenti poslani na generički PostScript pisač bit će spremljeni kao PostScript (.ps) datoteke." msgid "Entering fullscreen mode" msgstr "Ulazim u cijelozaslonski način" @@ -892,8 +877,8 @@ msgstr "Ne resetiraj" msgid "CD-ROM images" msgstr "CD-ROM slike" -msgid "%hs Device Configuration" -msgstr "Konfiguracija uređaja %hs " +msgid "%1 Device Configuration" +msgstr "Konfiguracija uređaja %1" msgid "Monitor in sleep mode" msgstr "Ekran u stanju mirovanja" @@ -949,8 +934,8 @@ msgstr "Ponovno pokretanje" msgid "ACPI shutdown" msgstr "ACPI bazirano gašenje" -msgid "Hard disk (%s)" -msgstr "Tvrdi disk (%s)" +msgid "Hard disk (%1)" +msgstr "Tvrdi disk (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index e5225dbbb..679502f00 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -40,14 +40,11 @@ msgstr "Méret és pozíció &megjegyzése" msgid "Re&nderer" msgstr "&Megjelenítő" -msgid "&SDL (Software)" -msgstr "&SDL (Szoftveres)" +msgid "&Qt (Software)" +msgstr "&Qt (Szoftveres)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardveres)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ msgstr "Egyéb perifériák" msgid "Click to capture mouse" msgstr "Kattintson az egér elfogásához" -msgid "Press F8+F12 to release mouse" -msgstr "Nyomja meg az F8+F12-t az egér elengédéséhez" +msgid "Press %1 to release mouse" +msgstr "Nyomja meg az %1-t az egér elengédéséhez" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Nyomja meg az F8+F12-t vagy a középső gombot az egér elengédéséhez" +msgid "Press %1 or middle button to release mouse" +msgstr "Nyomja meg az %1-t vagy a középső gombot az egér elengédéséhez" msgid "Bus" msgstr "Busz" @@ -853,26 +850,14 @@ msgstr "Régi számítógépek emulátora\n\nFejlesztők: Miran Grča (OBattler) msgid "Hardware not available" msgstr "Hardver nem elérhető" -msgid "WinPcap" -msgstr "WinPcap" - -msgid "libpcap" -msgstr "libpcap" - -msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "Győződjön meg hogy a(z) libpcap telepítve van és jelenleg a libpcap-kompatibilis kapcsolatot használja." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Győződjön meg hogy a(z) %1 telepítve van és jelenleg a %1-kompatibilis kapcsolatot használja." msgid "Invalid configuration" msgstr "Érvénytelen konfiguráció" -msgid "gsdll32.dll" -msgstr "gsdll32.dll" - -msgid "libgs" -msgstr "libgs" - -msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr " szükséges a PostScript fájlok PDF formátumba való automatikus konvertálásához.\n\nAz általános PostScript nyomtatóra küldött dokumentumok PostScript (.ps) fájlként kerülnek mentésre." +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "%1 szükséges a PostScript fájlok PDF formátumba való automatikus konvertálásához.\n\nAz általános PostScript nyomtatóra küldött dokumentumok PostScript (.ps) fájlként kerülnek mentésre." msgid "Entering fullscreen mode" msgstr "Teljes képernyős módra váltás" @@ -892,8 +877,8 @@ msgstr "Ne indítsa újra" msgid "CD-ROM images" msgstr "CD-ROM-képek" -msgid "%hs Device Configuration" -msgstr "%hs eszközkonfiguráció" +msgid "%1 Device Configuration" +msgstr "%1 eszközkonfiguráció" msgid "Monitor in sleep mode" msgstr "Képernyő alvó módban" @@ -949,8 +934,8 @@ msgstr "Hardveres újraindítás" msgid "ACPI shutdown" msgstr "ACPI leállítás" -msgid "Hard disk (%s)" -msgstr "Merevlemez (%s)" +msgid "Hard disk (%1)" +msgstr "Merevlemez (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index 43ece2315..dfb11fb59 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -40,14 +40,11 @@ msgstr "R&icorda dimensioni e posizione" msgid "Re&nderer" msgstr "Re&nderer" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ msgstr "Altre periferiche" msgid "Click to capture mouse" msgstr "Fare clic per catturare mouse" -msgid "Press F8+F12 to release mouse" -msgstr "Premi F8+F12 per rilasciare il mouse" +msgid "Press %1 to release mouse" +msgstr "Premi %1 per rilasciare il mouse" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Premi F8+F12 o pulsante centrale per rilasciare il mouse" +msgid "Press %1 or middle button to release mouse" +msgstr "Premi %1 o pulsante centrale per rilasciare il mouse" msgid "Bus" msgstr "Bus" @@ -853,26 +850,14 @@ msgstr "Un emulatore di computer vecchi\n\nAutori: Miran Grča (OBattler), Richa msgid "Hardware not available" msgstr "Hardware non disponibile" -msgid "WinPcap" -msgstr "WinPcap" - -msgid "libpcap" -msgstr "libpcap" - -msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "Controllare se libpcap è installato e che tu sia connesso ad una connessione libpcap compatibile." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Controllare se %1 è installato e che tu sia connesso ad una connessione %1 compatibile." msgid "Invalid configuration" msgstr "Configurazione invalida" -msgid "gsdll32.dll" -msgstr "gsdll32.dll" - -msgid "libgs" -msgstr "libgs" - -msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr " è richiesto per la conversione automatica di file PostScript a file PDF.\n\nQualsiasi documento mandato alla stampante generica PostScript sarà salvato come file PostScript. (.ps)" +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "%1 è richiesto per la conversione automatica di file PostScript a file PDF.\n\nQualsiasi documento mandato alla stampante generica PostScript sarà salvato come file PostScript. (.ps)" msgid "Entering fullscreen mode" msgstr "Entrando nella modalità schermo intero" @@ -892,8 +877,8 @@ msgstr "Non riavviare" msgid "CD-ROM images" msgstr "Immagini CD-ROM" -msgid "%hs Device Configuration" -msgstr "Configurazione del dispositivo %hs" +msgid "%1 Device Configuration" +msgstr "Configurazione del dispositivo %1" msgid "Monitor in sleep mode" msgstr "Monitor in modalità riposo" @@ -949,8 +934,8 @@ msgstr "Riavvia" msgid "ACPI shutdown" msgstr "Arresto ACPI" -msgid "Hard disk (%s)" -msgstr "Hard disk (%s)" +msgid "Hard disk (%1)" +msgstr "Hard disk (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index 971bbd29f..c2b0a3d71 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -40,14 +40,11 @@ msgstr "ウィンドウのサイズと位置を保存(&E)" msgid "Re&nderer" msgstr "レンダラー(&N)" -msgid "&SDL (Software)" -msgstr "SDL (ソフトウェア)(&S)" +msgid "&Qt (Software)" +msgstr "Qt (ソフトウェア)(&Q)" -msgid "SDL (&Hardware)" -msgstr "SDL (ハードウェア)(&H)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (OpenGL)(&O)" +msgid "Qt (&OpenGL)" +msgstr "Qt (OpenGL)(&O)" msgid "Open&GL (3.0 Core)" msgstr "OpenGL (3.0 Core)(&G)" @@ -718,11 +715,11 @@ msgstr "他の周辺デバイス" msgid "Click to capture mouse" msgstr "左クリックでマウスをキャプチャします" -msgid "Press F8+F12 to release mouse" -msgstr "F8+F12キーでマウスを解放します" +msgid "Press %1 to release mouse" +msgstr "%1キーでマウスを解放します" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "F8+F12キーまたは中クリックでマウスを解放します" +msgid "Press %1 or middle button to release mouse" +msgstr "%1キーまたは中クリックでマウスを解放します" msgid "Bus" msgstr "バス" @@ -853,26 +850,14 @@ msgstr "古いパソコンのエミュレーター\n\n著者: Miran Grča (OBatt msgid "Hardware not available" msgstr "ハードウェアが利用できません" -msgid "WinPcap" -msgstr "WinPcap" - -msgid "libpcap" -msgstr "libpcap" - -msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "がインストールされてるか、libpcapに対応したネットワークに接続されてるか確認してください。" +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "がインストールされてるか、%1に対応したネットワークに接続されてるか確認してください。" msgid "Invalid configuration" msgstr "不正な設定です" -msgid "gsdll32.dll" -msgstr "gsdll32.dll" - -msgid "libgs" -msgstr "libgs" - -msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr "PostScriptファイルをPDFに自動変換するにはlibgsが必要です。\n\n汎用PostScriptプリンターに送信された文書は、PostScript (.ps) ファイルとして保存されます。" +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "PostScriptファイルをPDFに自動変換するには%1が必要です。\n\n汎用PostScriptプリンターに送信された文書は、PostScript (.ps) ファイルとして保存されます。" msgid "Entering fullscreen mode" msgstr "全画面モードを入力" @@ -892,8 +877,8 @@ msgstr "リセットしない" msgid "CD-ROM images" msgstr "CD-ROMイメージ" -msgid "%hs Device Configuration" -msgstr "%hs のデバイス設定" +msgid "%1 Device Configuration" +msgstr "%1 のデバイス設定" msgid "Monitor in sleep mode" msgstr "モニターのスリープモード" @@ -949,8 +934,8 @@ msgstr "ハードリセット" msgid "ACPI shutdown" msgstr "ACPIシャットダウン" -msgid "Hard disk (%s)" -msgstr "ハードディスク (%s)" +msgid "Hard disk (%1)" +msgstr "ハードディスク (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index ea6e196fe..99e74e880 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -40,14 +40,11 @@ msgstr "창 크기와 위치를 기억하기(&E)" msgid "Re&nderer" msgstr "렌더러(&N)" -msgid "&SDL (Software)" -msgstr "SDL (소프트웨어)(&S)" +msgid "&Qt (Software)" +msgstr "Qt (소프트웨어)(&Q)" -msgid "SDL (&Hardware)" -msgstr "SDL (하드웨어)(&H)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (OpenGL)(&O)" +msgid "Qt (&OpenGL)" +msgstr "Qt (OpenGL)(&O)" msgid "Open&GL (3.0 Core)" msgstr "OpenGL (3.0 Core)(&G)" @@ -718,11 +715,11 @@ msgstr "기타 주변기기" msgid "Click to capture mouse" msgstr "이 창을 클릭하면 마우스를 사용합니다" -msgid "Press F8+F12 to release mouse" -msgstr "F12+F8키를 누르면 마우스를 해제합니다" +msgid "Press %1 to release mouse" +msgstr "%1키를 누르면 마우스를 해제합니다" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "F12+F8키 또는 가운데 버튼을 클릭하면 마우스를 해제합니다" +msgid "Press %1 or middle button to release mouse" +msgstr "%1키 또는 가운데 버튼을 클릭하면 마우스를 해제합니다" msgid "Bus" msgstr "버스" @@ -853,26 +850,14 @@ msgstr "고전 컴퓨터 에뮬레이터\n\n저자: Miran Grča (OBattler), Rich msgid "Hardware not available" msgstr "하드웨어를 이용할 수 없습니다" -msgid "WinPcap" -msgstr "WinPcap" - -msgid "libpcap" -msgstr "libpcap" - -msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "이 설치되었는지 libpcap에 대응하는 네트워크에 접속되어 있는지 확인해 주세요." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "이 설치되었는지 %1에 대응하는 네트워크에 접속되어 있는지 확인해 주세요." msgid "Invalid configuration" msgstr "올바르지 않은 설정입니다" -msgid "gsdll32.dll" -msgstr "gsdll32.dll" - -msgid "libgs" -msgstr "libgs" - -msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr "은(는) PostScript 파일을 PDF로 자동변환하는 데에 필요합니다.\n\n표준 PostScript 프린터로 보내신 임의의 문서는 PostScript (.ps) 파일로 저장됩니다." +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "%1은(는) PostScript 파일을 PDF로 자동변환하는 데에 필요합니다.\n\n표준 PostScript 프린터로 보내신 임의의 문서는 PostScript (.ps) 파일로 저장됩니다." msgid "Entering fullscreen mode" msgstr "전체 화면으로 전환" @@ -892,8 +877,8 @@ msgstr "재시작 안함" msgid "CD-ROM images" msgstr "CD-ROM 이미지" -msgid "%hs Device Configuration" -msgstr "%hs 장치 설정" +msgid "%1 Device Configuration" +msgstr "%1 장치 설정" msgid "Monitor in sleep mode" msgstr "모니터 절전 모드" @@ -949,8 +934,8 @@ msgstr "재시작" msgid "ACPI shutdown" msgstr "ACPI 종료" -msgid "Hard disk (%s)" -msgstr "하드 디스크 (%s)" +msgid "Hard disk (%1)" +msgstr "하드 디스크 (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index c6a70d905..b67946434 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -40,14 +40,11 @@ msgstr "P&amiętaj rozmiar &i pozycję" msgid "Re&nderer" msgstr "Re&nderer" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ msgstr "Inne urządzenia peryferyjne" msgid "Click to capture mouse" msgstr "Kliknij w celu przechwycenia myszy" -msgid "Press F8+F12 to release mouse" -msgstr "Naciśnij klawisze F8+F12 w celu uwolnienia myszy" +msgid "Press %1 to release mouse" +msgstr "Naciśnij klawisze %1 w celu uwolnienia myszy" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Naciśnij klawisze F8+F12 lub środkowy przycisk w celu uwolnienia myszy" +msgid "Press %1 or middle button to release mouse" +msgstr "Naciśnij klawisze %1 lub środkowy przycisk w celu uwolnienia myszy" msgid "Bus" msgstr "Magistrala" @@ -853,26 +850,14 @@ msgstr "Emulator starych komputerów\n\nAutorzy: Miran Grča (OBattler), Richard msgid "Hardware not available" msgstr "Sprzęt niedostępny" -msgid "WinPcap" -msgstr "WinPcap" - -msgid "libpcap" -msgstr "libpcap" - -msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "Sprawdź, czy libpcap jest zainstalowany i czy posiadasz połączenie sieciowe kompatybilne z libpcap." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Sprawdź, czy %1 jest zainstalowany i czy posiadasz połączenie sieciowe kompatybilne z %1." msgid "Invalid configuration" msgstr "Nieprawidłowa konfiguracja" -msgid "gsdll32.dll" -msgstr "gsdll32.dll" - -msgid "libgs" -msgstr "libgs" - -msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr " jest wymagany do automatycznej konwersji plików PostScript do PDF.\n\nDokumenty wysłane do ogólnej drukarki PostScript zostaną zapisane jako pliki PostScript (.ps)." +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "%1 jest wymagany do automatycznej konwersji plików PostScript do PDF.\n\nDokumenty wysłane do ogólnej drukarki PostScript zostaną zapisane jako pliki PostScript (.ps)." msgid "Entering fullscreen mode" msgstr "Przechodzenie do trybu pełnoekranowego" @@ -892,8 +877,8 @@ msgstr "Nie przywracaj" msgid "CD-ROM images" msgstr "Obrazy CD-ROM" -msgid "%hs Device Configuration" -msgstr "Konfiguracja urządzenia %hs" +msgid "%1 Device Configuration" +msgstr "Konfiguracja urządzenia %1" msgid "Monitor in sleep mode" msgstr "Monitor w trybie czuwania" @@ -949,8 +934,8 @@ msgstr "Twardy reset" msgid "ACPI shutdown" msgstr "Wyłączenie ACPI" -msgid "Hard disk (%s)" -msgstr "Dysk twardy (%s)" +msgid "Hard disk (%1)" +msgstr "Dysk twardy (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 45d8a8530..689841312 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -40,14 +40,11 @@ msgstr "&Lembrar tamanho e posição" msgid "Re&nderer" msgstr "&Renderizador" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (Núcleo 3.0)" @@ -718,11 +715,11 @@ msgstr "Outros periféricos" msgid "Click to capture mouse" msgstr "Clique para capturar o mouse" -msgid "Press F8+F12 to release mouse" -msgstr "Aperte F8+F12 para liberar o mouse" +msgid "Press %1 to release mouse" +msgstr "Aperte %1 para liberar o mouse" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Aperte F8+F12 ou botão do meio para liberar o mouse" +msgid "Press %1 or middle button to release mouse" +msgstr "Aperte %1 ou botão do meio para liberar o mouse" msgid "Bus" msgstr "Barramento" @@ -853,26 +850,14 @@ msgstr "Um emulador de computadores antigos\n\nAutores: Miran Grča (OBattler), msgid "Hardware not available" msgstr "Hardware não disponível" -msgid "WinPcap" -msgstr "WinPcap" - -msgid "libpcap" -msgstr "libpcap" - -msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "Certifique-se de que libpcap esteja instalado e que você tenha uma conexão de rede compatível com libpcap." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Certifique-se de que %1 esteja instalado e que você tenha uma conexão de rede compatível com %1." msgid "Invalid configuration" msgstr "Configuração inválida" -msgid "gsdll32.dll" -msgstr "gsdll32.dll" - -msgid "libgs" -msgstr "libgs" - -msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr " é necessário para a conversão automática de arquivos PostScript para PDF.\n\nQualquer documento enviado para a impressora genérica PostScript será salvo como arquivos PostScript (.ps)." +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "%1 é necessário para a conversão automática de arquivos PostScript para PDF.\n\nQualquer documento enviado para a impressora genérica PostScript será salvo como arquivos PostScript (.ps)." msgid "Entering fullscreen mode" msgstr "Entrando no modo de tela cheia" @@ -892,8 +877,8 @@ msgstr "Não reiniciar" msgid "CD-ROM images" msgstr "Imagens de CD-ROM" -msgid "%hs Device Configuration" -msgstr "Configuração do dispositivo %hs" +msgid "%1 Device Configuration" +msgstr "Configuração do dispositivo %1" msgid "Monitor in sleep mode" msgstr "Monitor em modo de suspensão" @@ -949,8 +934,8 @@ msgstr "Reinicialização completa" msgid "ACPI shutdown" msgstr "Desligamento por ACPI" -msgid "Hard disk (%s)" -msgstr "Disco rígido (%s)" +msgid "Hard disk (%1)" +msgstr "Disco rígido (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index 156f63926..adfc05391 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -40,14 +40,11 @@ msgstr "&Lembrar tamanho e posição" msgid "Re&nderer" msgstr "&Renderizador" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (Núcleo 3.0)" @@ -718,11 +715,11 @@ msgstr "Outros dispositivos" msgid "Click to capture mouse" msgstr "Clique para capturar o rato" -msgid "Press F8+F12 to release mouse" -msgstr "Pressione F8+F12 para soltar o rato" +msgid "Press %1 to release mouse" +msgstr "Pressione %1 para soltar o rato" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Pressione F8+F12 ou tecla média para soltar o rato" +msgid "Press %1 or middle button to release mouse" +msgstr "Pressione %1 ou tecla média para soltar o rato" msgid "Bus" msgstr "Barramento" @@ -853,26 +850,14 @@ msgstr "Um emulador de computadores antigos\n\nAutores: Miran Grča (OBattler), msgid "Hardware not available" msgstr "Hardware não disponível" -msgid "WinPcap" -msgstr "WinPcap" - -msgid "libpcap" -msgstr "libpcap" - -msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "Certifique-se de que a biblioteca libpcap está instalada e de que está a utilizar uma ligação de rede compatível com a biblioteca libpcap." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Certifique-se de que a biblioteca %1 está instalada e de que está a utilizar uma ligação de rede compatível com a biblioteca %1." msgid "Invalid configuration" msgstr "Configuração inválida" -msgid "gsdll32.dll" -msgstr "gsdll32.dll" - -msgid "libgs" -msgstr "libgs" - -msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr " é requerido para a conversão automática de ficheiros PostScript para ficheiros PDF.\n\nQualquer documento enviado para a impressora PostScript genérica será gravado como um ficheiro PostScript (.ps)." +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "%1 é requerido para a conversão automática de ficheiros PostScript para ficheiros PDF.\n\nQualquer documento enviado para a impressora PostScript genérica será gravado como um ficheiro PostScript (.ps)." msgid "Entering fullscreen mode" msgstr "A entrar no modo de ecrã cheio" @@ -892,8 +877,8 @@ msgstr "Não reiniciar" msgid "CD-ROM images" msgstr "Imagens CD-ROM" -msgid "%hs Device Configuration" -msgstr "Configuração de dispositivo %hs" +msgid "%1 Device Configuration" +msgstr "Configuração de dispositivo %1" msgid "Monitor in sleep mode" msgstr "Ecrã em modo de sono" @@ -949,8 +934,8 @@ msgstr "Reinicialização completa" msgid "ACPI shutdown" msgstr "Encerramento ACPI" -msgid "Hard disk (%s)" -msgstr "Disco rígido (%s)" +msgid "Hard disk (%1)" +msgstr "Disco rígido (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index 41cad4eda..96da04710 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -43,14 +43,11 @@ msgstr "&Запомнить размер и положение" msgid "Re&nderer" msgstr "&Рендеринг" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0)" @@ -808,11 +805,11 @@ msgstr "Другая периферия" msgid "Click to capture mouse" msgstr "Щёлкните мышью для захвата курсора" -msgid "Press F8+F12 to release mouse" -msgstr "Нажмите F8+F12 чтобы освободить курсор" +msgid "Press %1 to release mouse" +msgstr "Нажмите %1, чтобы освободить курсор" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Нажмите F8+F12 или среднюю кнопку мыши чтобы освободить курсор" +msgid "Press %1 or middle button to release mouse" +msgstr "Нажмите %1 или среднюю кнопку мыши, чтобы освободить курсор" msgid "Bus" msgstr "Шина" @@ -943,26 +940,14 @@ msgstr "Эмулятор старых компьютеров\n\nАвторы: Mi msgid "Hardware not available" msgstr "Оборудование недоступно" -msgid "WinPcap" -msgstr "WinPcap" - -msgid "libpcap" -msgstr "libpcap" - -msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "Убедитесь, что libpcap установлен и ваше сетевое соединение, совместимо с libpcap." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Убедитесь, что %1 установлен и ваше сетевое соединение совместимо с %1." msgid "Invalid configuration" msgstr "Недопустимая конфигурация" -msgid "gsdll32.dll" -msgstr "gsdll32.dll" - -msgid "libgs" -msgstr "libgs" - -msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr " требуется для автоматического преобразования файлов PostScript в PDF.\n\nВсе документы, отправленные на общий принтер PostScript, будут сохранены в виде файлов PostScript (.ps)." +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "Для автоматического преобразования файлов PostScript в PDF требуется %1.\n\nВсе документы, отправленные на общий принтер PostScript, будут сохранены в виде файлов PostScript (.ps)." msgid "Entering fullscreen mode" msgstr "Вход в полноэкранный режим" @@ -982,8 +967,8 @@ msgstr "Не перезагружать" msgid "CD-ROM images" msgstr "Образы CD-ROM" -msgid "%hs Device Configuration" -msgstr "Конфигурация устройства %hs" +msgid "%1 Device Configuration" +msgstr "Конфигурация устройства %1" msgid "Monitor in sleep mode" msgstr "Монитор в спящем режиме" @@ -1039,8 +1024,8 @@ msgstr "Холодная перезагрузка" msgid "ACPI shutdown" msgstr "Сигнал завершения ACPI" -msgid "Hard disk (%s)" -msgstr "Жёсткий диск (%s)" +msgid "Hard disk (%1)" +msgstr "Жёсткий диск (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index a6d13b95b..c22445a19 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -40,14 +40,11 @@ msgstr "&Pamätať si veľkosť a polohu" msgid "Re&nderer" msgstr "&Renderer" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ msgstr "Iné príslušenstvo" msgid "Click to capture mouse" msgstr "Kliknite pre zabráni myši" -msgid "Press F8+F12 to release mouse" -msgstr "Stlačte F8+F12 pre uvoľnenie myši" +msgid "Press %1 to release mouse" +msgstr "Stlačte %1 pre uvoľnenie myši" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Stlačte F8+F12 alebo prostredné tlačidlo na uvoľnenie myši" +msgid "Press %1 or middle button to release mouse" +msgstr "Stlačte %1 alebo prostredné tlačidlo na uvoľnenie myši" msgid "Bus" msgstr "Zbernica" @@ -853,26 +850,14 @@ msgstr "Emulátor starých počítačov\n\nAutori: Miran Grča (OBattler), Richa msgid "Hardware not available" msgstr "Hardvér nie je dostupný" -msgid "WinPcap" -msgstr "WinPcap" - -msgid "libpcap" -msgstr "libpcap" - -msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "Uistite sa, že je nainštalovaný libpcap a používate sieťové pripojenie s ním kompatibilné." +msgid "Make sure %1 is installed and that you are on a libpcap-compatible network connection." +msgstr "Uistite sa, že je nainštalovaný %1 a používate sieťové pripojenie s ním kompatibilné." msgid "Invalid configuration" msgstr "Neplatná konfigurácia" -msgid "gsdll32.dll" -msgstr "gsdll32.dll" - -msgid "libgs" -msgstr "libgs" - -msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr " je potrebná pre automatický prevod PostScript dokumentov do PDF.\n\nAkékoľvek dokumenty vytlačené cez všeobecnú PostScriptovú tlačiareň budú uložené ako PostScript (.ps) súbory." +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "%1 je potrebná pre automatický prevod PostScript dokumentov do PDF.\n\nAkékoľvek dokumenty vytlačené cez všeobecnú PostScriptovú tlačiareň budú uložené ako PostScript (.ps) súbory." msgid "Entering fullscreen mode" msgstr "Vstup do režimu celej obrazovky" @@ -892,8 +877,8 @@ msgstr "Neresetovať" msgid "CD-ROM images" msgstr "Obraz CD-ROM disku" -msgid "%hs Device Configuration" -msgstr "Konfigurácia zariadenia %hs" +msgid "%1 Device Configuration" +msgstr "Konfigurácia zariadenia %1" msgid "Monitor in sleep mode" msgstr "Monitor je v režime spánku" @@ -949,8 +934,8 @@ msgstr "Resetovať" msgid "ACPI shutdown" msgstr "Vypnúť cez rozhranie ACPI" -msgid "Hard disk (%s)" -msgstr "Pevný disk (%s)" +msgid "Hard disk (%1)" +msgstr "Pevný disk (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index 93941ffe8..c32c6c754 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -40,14 +40,11 @@ msgstr "&Zapomni si velikost in položaj" msgid "Re&nderer" msgstr "&Upodabljanje" -msgid "&SDL (Software)" -msgstr "&SDL (programsko)" +msgid "&Qt (Software)" +msgstr "&Qt (programsko)" -msgid "SDL (&Hardware)" -msgstr "SDL (s&trojno)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (Jedro 3.0)" @@ -718,11 +715,11 @@ msgstr "Druga periferija" msgid "Click to capture mouse" msgstr "Kliknite za zajem miške" -msgid "Press F8+F12 to release mouse" -msgstr "Pritisnite F8+F12 za izpust miške" +msgid "Press %1 to release mouse" +msgstr "Pritisnite %1 za izpust miške" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Pritisnite F8+F12 ali srednji gumb za izpust miške" +msgid "Press %1 or middle button to release mouse" +msgstr "Pritisnite %1 ali srednji gumb za izpust miške" msgid "Bus" msgstr "Vodilo" @@ -853,26 +850,14 @@ msgstr "Emulator starih računalnikov\n\nAvtorji: Miran Grča (OBattler), Richar msgid "Hardware not available" msgstr "Strojna oprema ni na voljo" -msgid "WinPcap" -msgstr "WinPcap" - -msgid "libpcap" -msgstr "libpcap" - -msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "Prepičajte se, da je nameščen libpcap in da ste na omrežni povezavi, združljivi z " +msgid "Make sure %1 is installed and that you are on a libpcap-compatible network connection." +msgstr "Prepičajte se, da je nameščen %1 in da ste na omrežni povezavi, združljivi z libpcap." msgid "Invalid configuration" msgstr "Neveljavna konfiguracija" -msgid "gsdll32.dll" -msgstr "gsdll32.dll" - -msgid "libgs" -msgstr "libgs" - -msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr " je potreben za samodejno pretvorbo PostScript datotek v PDF.\n\nVsi dokumenti, poslani generičnemu PostScript tiskalniku bodo shranjeni kot PostScript (.ps) datoteke." +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "%1 je potreben za samodejno pretvorbo PostScript datotek v PDF.\n\nVsi dokumenti, poslani generičnemu PostScript tiskalniku bodo shranjeni kot PostScript (.ps) datoteke." msgid "Entering fullscreen mode" msgstr "Preklapljam v celozaslonski način" @@ -892,8 +877,8 @@ msgstr "Ne resetiraj" msgid "CD-ROM images" msgstr "Slike CD-ROM" -msgid "%hs Device Configuration" -msgstr "Konfiguracija naprave %hs" +msgid "%1 Device Configuration" +msgstr "Konfiguracija naprave %1" msgid "Monitor in sleep mode" msgstr "Zaslon v načinu spanja" @@ -949,8 +934,8 @@ msgstr "Ponovni zagon" msgid "ACPI shutdown" msgstr "Zaustavitev ACPI" -msgid "Hard disk (%s)" -msgstr "Trdi disk (%s)" +msgid "Hard disk (%1)" +msgstr "Trdi disk (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index c65f6077c..a1ce42b38 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -40,14 +40,11 @@ msgstr "&Pencere boyut ve pozisyonunu hatırla" msgid "Re&nderer" msgstr "&İşleyici" -msgid "&SDL (Software)" -msgstr "&SDL (Yazılım)" +msgid "&Qt (Software)" +msgstr "&Qt (Yazılım)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Donanım)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0 Core)" @@ -718,11 +715,11 @@ msgstr "Diğer cihazlar" msgid "Click to capture mouse" msgstr "Farenin yakalanması için tıklayın" -msgid "Press F8+F12 to release mouse" -msgstr "Farenin bırakılması için F8+F12 tuşlarına basın" +msgid "Press %1 to release mouse" +msgstr "Farenin bırakılması için %1 tuşlarına basın" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Farenin bırakılması için F8+F12 veya farenin orta tuşuna basın" +msgid "Press %1 or middle button to release mouse" +msgstr "Farenin bırakılması için %1 veya farenin orta tuşuna basın" msgid "Bus" msgstr "Veri yolu" @@ -853,26 +850,14 @@ msgstr "Bir eski bilgisayar emülatörü\n\nYapanlar: Miran Grča (OBattler), Ri msgid "Hardware not available" msgstr "Donanım mevcut değil" -msgid "WinPcap" -msgstr "WinPcap" - -msgid "libpcap" -msgstr "libpcap" - -msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "libpcap kurulu olduğundan ve libpcap-uyumlu bir internet ağında bulunduğunuzdan emin olun." +msgid "Make sure %1 is installed and that you are on a libpcap-compatible network connection." +msgstr "%1 kurulu olduğundan ve libpcap-uyumlu bir internet ağında bulunduğunuzdan emin olun." msgid "Invalid configuration" msgstr "Geçersiz konfigürasyon" -msgid "gsdll32.dll" -msgstr "gsdll32.dll" - -msgid "libgs" -msgstr "libgs" - -msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr " PostScript dosyalarının otomatik olarak PDF dosyalarına çevirilmesi için gereklidir.\n\nGenel PostScript yazıcısına gönderilen tüm dökümanlar PostScript (.ps) dosyaları olarak kaydedilecektir." +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "%1 PostScript dosyalarının otomatik olarak PDF dosyalarına çevirilmesi için gereklidir.\n\nGenel PostScript yazıcısına gönderilen tüm dökümanlar PostScript (.ps) dosyaları olarak kaydedilecektir." msgid "Entering fullscreen mode" msgstr "Tam ekran moduna geçiliyor" @@ -892,8 +877,8 @@ msgstr "Yeniden başlatma" msgid "CD-ROM images" msgstr "CD-ROM imajları" -msgid "%hs Device Configuration" -msgstr "%hs Cihaz Konfigürasyonu" +msgid "%1 Device Configuration" +msgstr "%1 Cihaz Konfigürasyonu" msgid "Monitor in sleep mode" msgstr "Monitör uyku modunda" @@ -949,8 +934,8 @@ msgstr "Makineyi yeniden başlat" msgid "ACPI shutdown" msgstr "ACPI kapatma" -msgid "Hard disk (%s)" -msgstr "Hard disk (%s)" +msgid "Hard disk (%1)" +msgstr "Hard disk (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index f7a819a92..0dc666c0d 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -40,14 +40,11 @@ msgstr "&Запам'ятати розмір і становище" msgid "Re&nderer" msgstr "&Рендеринг" -msgid "&SDL (Software)" -msgstr "&SDL (Software)" +msgid "&Qt (Software)" +msgstr "&Qt (Software)" -msgid "SDL (&Hardware)" -msgstr "SDL (&Hardware)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (&OpenGL)" +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" msgstr "Open&GL (3.0)" @@ -718,11 +715,11 @@ msgstr "Інша периферія" msgid "Click to capture mouse" msgstr "Клацніть мишею для захвату курсора" -msgid "Press F8+F12 to release mouse" -msgstr "Натисніть F8+F12, щоб звільнити курсор" +msgid "Press %1 to release mouse" +msgstr "Натисніть %1, щоб звільнити курсор" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "Натисніть F8+F12 або середню кнопку миші, щоб звільнити курсор" +msgid "Press %1 or middle button to release mouse" +msgstr "Натисніть %1 або середню кнопку миші, щоб звільнити курсор" msgid "Bus" msgstr "Шина" @@ -853,26 +850,14 @@ msgstr "Емулятор старих комп'ютерів\n\nАвтори: Mir msgid "Hardware not available" msgstr "Обладнання недоступне" -msgid "WinPcap" -msgstr "WinPcap" - -msgid "libpcap" -msgstr "libpcap" - -msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "Переконайтесь, що libpcap встановлений і ваше мережеве з'єднання, сумісне з libpcap." +msgid "Make sure %1 is installed and that you are on a libpcap-compatible network connection." +msgstr "Переконайтесь, що %1 встановлений і ваше мережеве з'єднання, сумісне з libpcap." msgid "Invalid configuration" msgstr "Неприпустима конфігурація" -msgid "gsdll32.dll" -msgstr "gsdll32.dll" - -msgid "libgs" -msgstr "libgs" - -msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr " потрібно для автоматичного перетворення файлів PostScript в PDF.\n\nВсі документи, відправлені на загальний принтер PostScript, будуть збережені у вигляді файлів PostScript (.ps)." +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "%1 потрібно для автоматичного перетворення файлів PostScript в PDF.\n\nВсі документи, відправлені на загальний принтер PostScript, будуть збережені у вигляді файлів PostScript (.ps)." msgid "Entering fullscreen mode" msgstr "Вхід у повноекранний режим" @@ -892,8 +877,8 @@ msgstr "Не перезавантажувати" msgid "CD-ROM images" msgstr "Образи CD-ROM" -msgid "%hs Device Configuration" -msgstr "Конфігурація пристрою %hs" +msgid "%1 Device Configuration" +msgstr "Конфігурація пристрою %1" msgid "Monitor in sleep mode" msgstr "Монітор у сплячому режимі" @@ -949,8 +934,8 @@ msgstr "Холодне перезавантаження" msgid "ACPI shutdown" msgstr "Сигнал завершення ACPI" -msgid "Hard disk (%s)" -msgstr "Жорсткий диск (%s)" +msgid "Hard disk (%1)" +msgstr "Жорсткий диск (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index 5c3fbb54f..dea46160e 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -40,14 +40,11 @@ msgstr "记住窗口大小和位置(&E)" msgid "Re&nderer" msgstr "渲染器(&N)" -msgid "&SDL (Software)" -msgstr "SDL (软件)(&S)" +msgid "&Qt (Software)" +msgstr "Qt (软件)(&Q)" -msgid "SDL (&Hardware)" -msgstr "SDL (硬件)(&H)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (OpenGL)(&O)" +msgid "Qt (&OpenGL)" +msgstr "Qt (OpenGL)(&O)" msgid "Open&GL (3.0 Core)" msgstr "OpenGL (3.0 Core)(&G)" @@ -718,11 +715,11 @@ msgstr "其他外围设备" msgid "Click to capture mouse" msgstr "单击窗口捕捉鼠标" -msgid "Press F8+F12 to release mouse" -msgstr "按下 F8+F12 释放鼠标" +msgid "Press %1 to release mouse" +msgstr "按下 %1 释放鼠标" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "按下 F8+F12 或鼠标中键释放鼠标" +msgid "Press %1 or middle button to release mouse" +msgstr "按下 %1 或鼠标中键释放鼠标" msgid "Bus" msgstr "总线" @@ -853,26 +850,14 @@ msgstr "一个旧式计算机模拟器\n\n作者: Miran Grča (OBattler)、Richa msgid "Hardware not available" msgstr "硬件不可用" -msgid "WinPcap" -msgstr "WinPcap" - -msgid "libpcap" -msgstr "libpcap" - -msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "请确认 libpcap 已安装且使用兼容 libpcap 的网络连接。" +msgid "Make sure %1 is installed and that you are on a libpcap-compatible network connection." +msgstr "请确认 %1 已安装且使用兼容 libpcap 的网络连接。" msgid "Invalid configuration" msgstr "无效配置" -msgid "gsdll32.dll" -msgstr "gsdll32.dll" - -msgid "libgs" -msgstr "libgs" - -msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr " 是将 PostScript 文件转换为 PDF 所需要的库。\n\n使用通用 PostScript 打印机打印的文档将被保存为 PostScript (.ps) 文件。" +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "%1 是将 PostScript 文件转换为 PDF 所需要的库。\n\n使用通用 PostScript 打印机打印的文档将被保存为 PostScript (.ps) 文件。" msgid "Entering fullscreen mode" msgstr "正在进入全屏模式" @@ -892,8 +877,8 @@ msgstr "不重置" msgid "CD-ROM images" msgstr "光盘映像" -msgid "%hs Device Configuration" -msgstr "%hs 设备配置" +msgid "%1 Device Configuration" +msgstr "%1 设备配置" msgid "Monitor in sleep mode" msgstr "显示器处在睡眠状态" @@ -949,8 +934,8 @@ msgstr "硬重置" msgid "ACPI shutdown" msgstr "ACPI 关机" -msgid "Hard disk (%s)" -msgstr "硬盘 (%s)" +msgid "Hard disk (%1)" +msgstr "硬盘 (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 927eb2d85..9392ce717 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -40,14 +40,11 @@ msgstr "記住視窗大小和位置(&E)" msgid "Re&nderer" msgstr "渲染器(&N)" -msgid "&SDL (Software)" -msgstr "SDL (軟體)(&S)" +msgid "&Qt (Software)" +msgstr "Qt (軟體)(&Q)" -msgid "SDL (&Hardware)" -msgstr "SDL (硬體)(&H)" - -msgid "SDL (&OpenGL)" -msgstr "SDL (OpenGL)(&O)" +msgid "Qt (&OpenGL)" +msgstr "Qt (OpenGL)(&O)" msgid "Open&GL (3.0 Core)" msgstr "OpenGL (3.0 Core)(&G)" @@ -718,11 +715,11 @@ msgstr "其他周邊裝置" msgid "Click to capture mouse" msgstr "點擊視窗捕捉滑鼠" -msgid "Press F8+F12 to release mouse" -msgstr "按下 F8+F12 釋放滑鼠" +msgid "Press %1 to release mouse" +msgstr "按下 %1 釋放滑鼠" -msgid "Press F8+F12 or middle button to release mouse" -msgstr "按下 F8+F12 或滑鼠中鍵釋放滑鼠" +msgid "Press %1 or middle button to release mouse" +msgstr "按下 %1 或滑鼠中鍵釋放滑鼠" msgid "Bus" msgstr "匯流排" @@ -853,26 +850,14 @@ msgstr "一個舊式電腦模擬器\n\n作者: Miran Grča (OBattler)、RichardG msgid "Hardware not available" msgstr "硬體不可用" -msgid "WinPcap" -msgstr "WinPcap" - -msgid "libpcap" -msgstr "libpcap" - -msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "請確認 libpcap 已安裝且使用相容 libpcap 的網路連線。" +msgid "Make sure %1 is installed and that you are on a libpcap-compatible network connection." +msgstr "請確認 %1 已安裝且使用相容 libpcap 的網路連線。" msgid "Invalid configuration" msgstr "無效設定" -msgid "gsdll32.dll" -msgstr "gsdll32.dll" - -msgid "libgs" -msgstr "libgs" - -msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr " 是將 PostScript 檔案轉換為 PDF 所需要的庫。\n\n使用通用 PostScript 印表機列印的文件將被儲存為 PostScript (.ps) 檔案。" +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "%1 是將 PostScript 檔案轉換為 PDF 所需要的庫。\n\n使用通用 PostScript 印表機列印的文件將被儲存為 PostScript (.ps) 檔案。" msgid "Entering fullscreen mode" msgstr "正在進入全螢幕模式" @@ -892,8 +877,8 @@ msgstr "不重設" msgid "CD-ROM images" msgstr "光碟映像" -msgid "%hs Device Configuration" -msgstr "%hs 裝置設定" +msgid "%1 Device Configuration" +msgstr "%1 裝置設定" msgid "Monitor in sleep mode" msgstr "顯示器處在睡眠狀態" @@ -949,8 +934,8 @@ msgstr "硬重設" msgid "ACPI shutdown" msgstr "ACPI 關機" -msgid "Hard disk (%s)" -msgstr "硬碟 (%s)" +msgid "Hard disk (%1)" +msgstr "硬碟 (%1)" msgid "%01i:%01i" msgstr "%01i:%01i" diff --git a/src/qt/qt_machinestatus.cpp b/src/qt/qt_machinestatus.cpp index 59ea960f8..dee487657 100644 --- a/src/qt/qt_machinestatus.cpp +++ b/src/qt/qt_machinestatus.cpp @@ -596,21 +596,21 @@ MachineStatus::refresh(QStatusBar *sbar) d->hdds[HDD_BUS_MFM].label = std::make_unique(); d->hdds[HDD_BUS_MFM].setActive(false); d->hdds[HDD_BUS_MFM].refresh(); - d->hdds[HDD_BUS_MFM].label->setToolTip(tr("Hard disk (%s)").replace("%s", "MFM/RLL")); + d->hdds[HDD_BUS_MFM].label->setToolTip(tr("Hard disk (%1)").arg("MFM/RLL")); sbar->addWidget(d->hdds[HDD_BUS_MFM].label.get()); } if ((has_esdi || (hdc_name.left(4) == QStringLiteral("esdi"))) && (c_esdi > 0)) { d->hdds[HDD_BUS_ESDI].label = std::make_unique(); d->hdds[HDD_BUS_ESDI].setActive(false); d->hdds[HDD_BUS_ESDI].refresh(); - d->hdds[HDD_BUS_ESDI].label->setToolTip(tr("Hard disk (%s)").replace("%s", "ESDI")); + d->hdds[HDD_BUS_ESDI].label->setToolTip(tr("Hard disk (%1)").arg("ESDI")); sbar->addWidget(d->hdds[HDD_BUS_ESDI].label.get()); } if ((has_xta || (hdc_name.left(3) == QStringLiteral("xta"))) && (c_xta > 0)) { d->hdds[HDD_BUS_XTA].label = std::make_unique(); d->hdds[HDD_BUS_XTA].setActive(false); d->hdds[HDD_BUS_XTA].refresh(); - d->hdds[HDD_BUS_XTA].label->setToolTip(tr("Hard disk (%s)").replace("%s", "XTA")); + d->hdds[HDD_BUS_XTA].label->setToolTip(tr("Hard disk (%1)").arg("XTA")); sbar->addWidget(d->hdds[HDD_BUS_XTA].label.get()); } if (hasIDE() || (hdc_name.left(5) == QStringLiteral("xtide")) || @@ -620,14 +620,14 @@ MachineStatus::refresh(QStatusBar *sbar) d->hdds[HDD_BUS_IDE].label = std::make_unique(); d->hdds[HDD_BUS_IDE].setActive(false); d->hdds[HDD_BUS_IDE].refresh(); - d->hdds[HDD_BUS_IDE].label->setToolTip(tr("Hard disk (%s)").replace("%s", "IDE")); + d->hdds[HDD_BUS_IDE].label->setToolTip(tr("Hard disk (%1)").arg("IDE")); sbar->addWidget(d->hdds[HDD_BUS_IDE].label.get()); } if (c_atapi > 0) { d->hdds[HDD_BUS_ATAPI].label = std::make_unique(); d->hdds[HDD_BUS_ATAPI].setActive(false); d->hdds[HDD_BUS_ATAPI].refresh(); - d->hdds[HDD_BUS_ATAPI].label->setToolTip(tr("Hard disk (%s)").replace("%s", "ATAPI")); + d->hdds[HDD_BUS_ATAPI].label->setToolTip(tr("Hard disk (%1)").arg("ATAPI")); sbar->addWidget(d->hdds[HDD_BUS_ATAPI].label.get()); } } @@ -638,7 +638,7 @@ MachineStatus::refresh(QStatusBar *sbar) d->hdds[HDD_BUS_SCSI].label = std::make_unique(); d->hdds[HDD_BUS_SCSI].setActive(false); d->hdds[HDD_BUS_SCSI].refresh(); - d->hdds[HDD_BUS_SCSI].label->setToolTip(tr("Hard disk (%s)").replace("%s", "SCSI")); + d->hdds[HDD_BUS_SCSI].label->setToolTip(tr("Hard disk (%1)").arg("SCSI")); sbar->addWidget(d->hdds[HDD_BUS_SCSI].label.get()); } diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 079906753..c7cc76ffe 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -581,14 +581,16 @@ c16stombs(char dst[], const uint16_t src[], int len) #ifdef _WIN32 # if defined(__amd64__) || defined(_M_X64) || defined(__aarch64__) || defined(_M_ARM64) -# define LIB_NAME_GS "gsdll64.dll" +# define LIB_NAME_GS "gsdll64.dll" # else -# define LIB_NAME_GS "gsdll32.dll" +# define LIB_NAME_GS "gsdll32.dll" # endif +# define LIB_NAME_PCAP "Npcap" # define MOUSE_CAPTURE_KEYSEQ "F8+F12" #else # define LIB_NAME_GS "libgs" -# define MOUSE_CAPTURE_KEYSEQ "CTRL-END" +# define LIB_NAME_PCAP "libpcap" +# define MOUSE_CAPTURE_KEYSEQ "Ctrl+End" #endif QMap ProgSettings::translatedstrings; @@ -598,14 +600,15 @@ ProgSettings::reloadStrings() { translatedstrings.clear(); translatedstrings[STRING_MOUSE_CAPTURE] = QCoreApplication::translate("", "Click to capture mouse").toStdWString(); - translatedstrings[STRING_MOUSE_RELEASE] = QCoreApplication::translate("", "Press F8+F12 to release mouse").replace("F8+F12", MOUSE_CAPTURE_KEYSEQ).replace("CTRL-END", QLocale::system().name() == "de_DE" ? "Strg+Ende" : "CTRL-END").toStdWString(); - translatedstrings[STRING_MOUSE_RELEASE_MMB] = QCoreApplication::translate("", "Press F8+F12 or middle button to release mouse").replace("F8+F12", MOUSE_CAPTURE_KEYSEQ).replace("CTRL-END", QLocale::system().name() == "de_DE" ? "Strg+Ende" : "CTRL-END").toStdWString(); + translatedstrings[STRING_MOUSE_RELEASE] = QCoreApplication::translate("", "Press %1 to release mouse").arg(QCoreApplication::translate("", MOUSE_CAPTURE_KEYSEQ)).toStdWString(); + translatedstrings[STRING_MOUSE_RELEASE_MMB] = QCoreApplication::translate("", "Press %1 or middle button to release mouse").arg(QCoreApplication::translate("", MOUSE_CAPTURE_KEYSEQ)).toStdWString(); translatedstrings[STRING_INVALID_CONFIG] = QCoreApplication::translate("", "Invalid configuration").toStdWString(); translatedstrings[STRING_NO_ST506_ESDI_CDROM] = QCoreApplication::translate("", "MFM/RLL or ESDI CD-ROM drives never existed").toStdWString(); translatedstrings[STRING_PCAP_ERROR_NO_DEVICES] = QCoreApplication::translate("", "No PCap devices found").toStdWString(); translatedstrings[STRING_PCAP_ERROR_INVALID_DEVICE] = QCoreApplication::translate("", "Invalid PCap device").toStdWString(); - translatedstrings[STRING_PCAP_ERROR_DESC] = QCoreApplication::translate("", "Make sure libpcap is installed and that you are on a libpcap-compatible network connection.").toStdWString(); + translatedstrings[STRING_PCAP_ERROR_DESC] = QCoreApplication::translate("", "Make sure %1 is installed and that you are on a %1-compatible network connection.").arg(LIB_NAME_PCAP).toStdWString(); translatedstrings[STRING_GHOSTSCRIPT_ERROR_TITLE] = QCoreApplication::translate("", "Unable to initialize Ghostscript").toStdWString(); + translatedstrings[STRING_GHOSTSCRIPT_ERROR_DESC] = QCoreApplication::translate("", "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files.").arg(LIB_NAME_GS).toStdWString(); translatedstrings[STRING_HW_NOT_AVAILABLE_MACHINE] = QCoreApplication::translate("", "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine.").toStdWString(); translatedstrings[STRING_HW_NOT_AVAILABLE_VIDEO] = QCoreApplication::translate("", "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card.").toStdWString(); translatedstrings[STRING_HW_NOT_AVAILABLE_VIDEO2] = QCoreApplication::translate("", "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card.").toStdWString(); @@ -613,13 +616,6 @@ ProgSettings::reloadStrings() translatedstrings[STRING_MONITOR_SLEEP] = QCoreApplication::translate("", "Monitor in sleep mode").toStdWString(); translatedstrings[STRING_NET_ERROR] = QCoreApplication::translate("", "Failed to initialize network driver").toStdWString(); translatedstrings[STRING_NET_ERROR_DESC] = QCoreApplication::translate("", "The network configuration will be switched to the null driver").toStdWString(); - - auto gsstr = QCoreApplication::translate("", " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files."); - if (gsstr.contains("libgs")) { - gsstr.replace("libgs", LIB_NAME_GS); - } else - gsstr.prepend(LIB_NAME_GS); - translatedstrings[STRING_GHOSTSCRIPT_ERROR_DESC] = gsstr.toStdWString(); } wchar_t * diff --git a/src/qt/qt_progsettings.hpp b/src/qt/qt_progsettings.hpp index d41f267df..642b2002d 100644 --- a/src/qt/qt_progsettings.hpp +++ b/src/qt/qt_progsettings.hpp @@ -40,12 +40,6 @@ public: sourceText = "Begin trace\tCtrl+T"; if (strcmp(sourceText, "End trace") == 0) sourceText = "End trace\tCtrl+T"; - if (strcmp(sourceText, "&Qt (Software)") == 0) { - QString finalstr = QTranslator::translate("", "&SDL (Software)", disambiguation, n); - finalstr.replace("SDL", "Qt"); - finalstr.replace("(&S)", "(&Q)"); - return finalstr; - } QString finalstr = QTranslator::translate("", sourceText, disambiguation, n); #ifdef Q_OS_MACOS if (finalstr.contains('\t')) From 8a27a77aa1443f42c733f99c71e795bf3c5f7a65 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 20 Mar 2024 18:53:29 +0500 Subject: [PATCH 700/936] Translations: Purge more unused strings --- src/qt/languages/ca-ES.po | 39 --------------------------------------- src/qt/languages/cs-CZ.po | 39 --------------------------------------- src/qt/languages/de-DE.po | 39 --------------------------------------- src/qt/languages/en-GB.po | 39 --------------------------------------- src/qt/languages/en-US.po | 39 --------------------------------------- src/qt/languages/es-ES.po | 39 --------------------------------------- src/qt/languages/fi-FI.po | 39 --------------------------------------- src/qt/languages/fr-FR.po | 39 --------------------------------------- src/qt/languages/hr-HR.po | 39 --------------------------------------- src/qt/languages/hu-HU.po | 39 --------------------------------------- src/qt/languages/it-IT.po | 39 --------------------------------------- src/qt/languages/ja-JP.po | 39 --------------------------------------- src/qt/languages/ko-KR.po | 39 --------------------------------------- src/qt/languages/pl-PL.po | 39 --------------------------------------- src/qt/languages/pt-BR.po | 39 --------------------------------------- src/qt/languages/pt-PT.po | 39 --------------------------------------- src/qt/languages/ru-RU.po | 39 --------------------------------------- src/qt/languages/sk-SK.po | 39 --------------------------------------- src/qt/languages/sl-SI.po | 39 --------------------------------------- src/qt/languages/tr-TR.po | 39 --------------------------------------- src/qt/languages/uk-UA.po | 39 --------------------------------------- src/qt/languages/zh-CN.po | 39 --------------------------------------- src/qt/languages/zh-TW.po | 39 --------------------------------------- 23 files changed, 897 deletions(-) diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po index ff69d11a7..3cde2ff11 100644 --- a/src/qt/languages/ca-ES.po +++ b/src/qt/languages/ca-ES.po @@ -586,9 +586,6 @@ msgstr "Comprovar BPB" msgid "CD-ROM drives:" msgstr "Unitats de CD-ROM:" -msgid "Earlier drive" -msgstr "Unitat anterior" - msgid "MO drives:" msgstr "Unitats MO:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "Cap" -msgid "Unable to load keyboard accelerators." -msgstr "No has estat possible carregar els acceleradors del teclat." - -msgid "Unable to register raw input." -msgstr "No has estat possible registrar l'entrada en brut." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "Apagada ACPI" msgid "Hard disk (%1)" msgstr "Disc dur (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "Les unitats de CD-ROM MFM/RLL o ESDI no van existir mai" @@ -1048,9 +1030,6 @@ msgstr "Les marques de temps del pare i el fill no coincideixen" msgid "Could not fix VHD timestamp." msgstr "No has estat possible corregir la marca de temps del VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ msgstr "IDE" msgid "ATAPI" msgstr "ATAPI" -msgid "MFM/RLL (%01i:%01i)" -msgstr "MFM/RLL (%01i:%01i)" - -msgid "XTA (%01i:%01i)" -msgstr "XTA (%01i:%01i)" - -msgid "ESDI (%01i:%01i)" -msgstr "ESDI (%01i:%01i)" - -msgid "IDE (%01i:%01i)" -msgstr "IDE (%01i:%01i)" - -msgid "ATAPI (%01i:%01i)" -msgstr "ATAPI (%01i:%01i)" - -msgid "SCSI (%01i:%02i)" -msgstr "SCSI (%01i:%02i)" - msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index f89521fdf..717a4f488 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -586,9 +586,6 @@ msgstr "Kontrola BPB" msgid "CD-ROM drives:" msgstr "Mechaniky CD-ROM:" -msgid "Earlier drive" -msgstr "Časná mechanika" - msgid "MO drives:" msgstr "Magnetooptické mechaniky:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "Žadné" -msgid "Unable to load keyboard accelerators." -msgstr "Nebylo možné nahrát klávesnicové zkratky." - -msgid "Unable to register raw input." -msgstr "Nebylo možné zaregistrovat raw input." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "Vypnout skrze rozhraní ACPI" msgid "Hard disk (%1)" msgstr "Pevný disk (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "CD-ROM mechaniky pro rozhraní MFM/RLL nebo ESDI nikdy neexistovaly" @@ -1048,9 +1030,6 @@ msgstr "Časová razítka nadřazeného a podřazeného disku nesouhlasí" msgid "Could not fix VHD timestamp." msgstr "Nebylo možné opravit časové razítko VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ msgstr "IDE" msgid "ATAPI" msgstr "ATAPI" -msgid "MFM/RLL (%01i:%01i)" -msgstr "MFM/RLL (%01i:%01i)" - -msgid "XTA (%01i:%01i)" -msgstr "XTA (%01i:%01i)" - -msgid "ESDI (%01i:%01i)" -msgstr "ESDI (%01i:%01i)" - -msgid "IDE (%01i:%01i)" -msgstr "IDE (%01i:%01i)" - -msgid "ATAPI (%01i:%01i)" -msgstr "ATAPI (%01i:%01i)" - -msgid "SCSI (%01i:%02i)" -msgstr "SCSI (%01i:%02i)" - msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index 6c898c25c..c5e5e78aa 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -586,9 +586,6 @@ msgstr "BPB überprüfen" msgid "CD-ROM drives:" msgstr "CD-ROM-Laufwerke:" -msgid "Earlier drive" -msgstr "Früheres Laufwerk" - msgid "MO drives:" msgstr "MO-Laufwerke:" @@ -784,15 +781,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "Ohne" -msgid "Unable to load keyboard accelerators." -msgstr "Tastaturbeschleuniger konnten nicht geladen werden." - -msgid "Unable to register raw input." -msgstr "Roheingaben konnten nicht registriert werden." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -940,12 +928,6 @@ msgstr "ACPI-basiertes Herunterfahren" msgid "Hard disk (%1)" msgstr "Festplatte (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLL- oder ESDI CD-ROM-Laufwerke hat es niemals gegeben" @@ -1051,9 +1033,6 @@ msgstr "Die Zeitstempel der Eltern- und der Kindesplatte stimmen nicht überein" msgid "Could not fix VHD timestamp." msgstr "Der Zeitstempel der VHD konnte nicht korrigiert werden." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1069,24 +1048,6 @@ msgstr "IDE" msgid "ATAPI" msgstr "ATAPI" -msgid "MFM/RLL (%01i:%01i)" -msgstr "MFM/RLL (%01i:%01i)" - -msgid "XTA (%01i:%01i)" -msgstr "XTA (%01i:%01i)" - -msgid "ESDI (%01i:%01i)" -msgstr "ESDI (%01i:%01i)" - -msgid "IDE (%01i:%01i)" -msgstr "IDE (%01i:%01i)" - -msgid "ATAPI (%01i:%01i)" -msgstr "ATAPI (%01i:%01i)" - -msgid "SCSI (%01i:%02i)" -msgstr "SCSI (%01i:%02i)" - msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index a1ee53f0a..8e22289b8 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -586,9 +586,6 @@ msgstr "Check BPB" msgid "CD-ROM drives:" msgstr "CD-ROM drives:" -msgid "Earlier drive" -msgstr "Earlier drive" - msgid "MO drives:" msgstr "MO drives:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "None" -msgid "Unable to load keyboard accelerators." -msgstr "Unable to load keyboard accelerators." - -msgid "Unable to register raw input." -msgstr "Unable to register raw input." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "ACPI shutdown" msgid "Hard disk (%1)" msgstr "Hard disk (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLL or ESDI CD-ROM drives never existed" @@ -1048,9 +1030,6 @@ msgstr "Parent and child disk timestamps do not match" msgid "Could not fix VHD timestamp." msgstr "Could not fix VHD timestamp." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ msgstr "IDE" msgid "ATAPI" msgstr "ATAPI" -msgid "MFM/RLL (%01i:%01i)" -msgstr "MFM/RLL (%01i:%01i)" - -msgid "XTA (%01i:%01i)" -msgstr "XTA (%01i:%01i)" - -msgid "ESDI (%01i:%01i)" -msgstr "ESDI (%01i:%01i)" - -msgid "IDE (%01i:%01i)" -msgstr "IDE (%01i:%01i)" - -msgid "ATAPI (%01i:%01i)" -msgstr "ATAPI (%01i:%01i)" - -msgid "SCSI (%01i:%02i)" -msgstr "SCSI (%01i:%02i)" - msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index 854ce4bac..8298ba0e3 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -586,9 +586,6 @@ msgstr "Check BPB" msgid "CD-ROM drives:" msgstr "CD-ROM drives:" -msgid "Earlier drive" -msgstr "Earlier drive" - msgid "MO drives:" msgstr "MO drives:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "None" -msgid "Unable to load keyboard accelerators." -msgstr "Unable to load keyboard accelerators." - -msgid "Unable to register raw input." -msgstr "Unable to register raw input." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "ACPI shutdown" msgid "Hard disk (%1)" msgstr "Hard disk (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLL or ESDI CD-ROM drives never existed" @@ -1048,9 +1030,6 @@ msgstr "Parent and child disk timestamps do not match" msgid "Could not fix VHD timestamp." msgstr "Could not fix VHD timestamp." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ msgstr "IDE" msgid "ATAPI" msgstr "ATAPI" -msgid "MFM/RLL (%01i:%01i)" -msgstr "MFM/RLL (%01i:%01i)" - -msgid "XTA (%01i:%01i)" -msgstr "XTA (%01i:%01i)" - -msgid "ESDI (%01i:%01i)" -msgstr "ESDI (%01i:%01i)" - -msgid "IDE (%01i:%01i)" -msgstr "IDE (%01i:%01i)" - -msgid "ATAPI (%01i:%01i)" -msgstr "ATAPI (%01i:%01i)" - -msgid "SCSI (%01i:%02i)" -msgstr "SCSI (%01i:%02i)" - msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index f68c6926e..4e2c84d26 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -586,9 +586,6 @@ msgstr "Chequear BPB" msgid "CD-ROM drives:" msgstr "Unidades de CD-ROM:" -msgid "Earlier drive" -msgstr "Unidad anterior" - msgid "MO drives:" msgstr "Unidades MO:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "Ninguno" -msgid "Unable to load keyboard accelerators." -msgstr "No fué posible cargar aceleradores de teclado." - -msgid "Unable to register raw input." -msgstr "No fué posible registrar entrada directa." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "Parada ACPI" msgid "Hard disk (%1)" msgstr "Disco duro (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "Nunca existieron unidades de CD-ROM MFM/RLL o ESDI" @@ -1048,9 +1030,6 @@ msgstr "Las marcas de tiempo del padre e hijo no coinciden" msgid "Could not fix VHD timestamp." msgstr "No fué posible corregir la marca de tiempo del VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ msgstr "IDE" msgid "ATAPI" msgstr "ATAPI" -msgid "MFM/RLL (%01i:%01i)" -msgstr "MFM/RLL (%01i:%01i)" - -msgid "XTA (%01i:%01i)" -msgstr "XTA (%01i:%01i)" - -msgid "ESDI (%01i:%01i)" -msgstr "ESDI (%01i:%01i)" - -msgid "IDE (%01i:%01i)" -msgstr "IDE (%01i:%01i)" - -msgid "ATAPI (%01i:%01i)" -msgstr "ATAPI (%01i:%01i)" - -msgid "SCSI (%01i:%02i)" -msgstr "SCSI (%01i:%02i)" - msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index c34639550..8935f66b4 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -586,9 +586,6 @@ msgstr "Tarkista BPB" msgid "CD-ROM drives:" msgstr "CD-ROM-asemat:" -msgid "Earlier drive" -msgstr "Aiemmat asemat" - msgid "MO drives:" msgstr "Magneettisoptiset asemat (MO):" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "Ei mikään" -msgid "Unable to load keyboard accelerators." -msgstr "Näppäinkiihdyttimien lataus epäonnistui" - -msgid "Unable to register raw input." -msgstr "Raakasyötteen rekisteröinti epäonnistui" - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u Mt (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "ACPI-sammutus" msgid "Hard disk (%1)" msgstr "Kiintolevy (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLL- tai ESDI-CD-ROM-asemia ei ole koskaan ollut olemassa" @@ -1048,9 +1030,6 @@ msgstr "Ylä- ja alatason levyjen aikaleimat eivät täsmää" msgid "Could not fix VHD timestamp." msgstr "VHD aikaleimaa ei pystytty korjaamaan." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ msgstr "IDE" msgid "ATAPI" msgstr "ATAPI" -msgid "MFM/RLL (%01i:%01i)" -msgstr "MFM/RLL (%01i:%01i)" - -msgid "XTA (%01i:%01i)" -msgstr "XTA (%01i:%01i)" - -msgid "ESDI (%01i:%01i)" -msgstr "ESDI (%01i:%01i)" - -msgid "IDE (%01i:%01i)" -msgstr "IDE (%01i:%01i)" - -msgid "ATAPI (%01i:%01i)" -msgstr "ATAPI (%01i:%01i)" - -msgid "SCSI (%01i:%02i)" -msgstr "SCSI (%01i:%02i)" - msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index 3fe8faa2e..c1a0ba18c 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -586,9 +586,6 @@ msgstr "Vérifier BPB" msgid "CD-ROM drives:" msgstr "Lecterus CD-ROM:" -msgid "Earlier drive" -msgstr "Lecteur plus tôt" - msgid "MO drives:" msgstr "Lecteurs magnéto-optiques:" @@ -781,15 +778,6 @@ msgstr "Système de contrôle de vol Thrustmaster" msgid "None" msgstr "Aucun" -msgid "Unable to load keyboard accelerators." -msgstr "Impossible de charger les accélérateurs de clavier." - -msgid "Unable to register raw input." -msgstr "Impossible de charger l'entrée raw." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u Mo (CTS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "Arrêt ACPI" msgid "Hard disk (%1)" msgstr "Disque dur (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "Les lecteurs de CD-ROM MFM/RLL ou ESDI n'ont jamais existé" @@ -1048,9 +1030,6 @@ msgstr "Les horodatages des disques parent et enfant ne correspondent pas" msgid "Could not fix VHD timestamp." msgstr "Impossible de réparer l'horodatage du VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ msgstr "IDE" msgid "ATAPI" msgstr "ATAPI" -msgid "MFM/RLL (%01i:%01i)" -msgstr "MFM/RLL (%01i:%01i)" - -msgid "XTA (%01i:%01i)" -msgstr "XTA (%01i:%01i)" - -msgid "ESDI (%01i:%01i)" -msgstr "ESDI (%01i:%01i)" - -msgid "IDE (%01i:%01i)" -msgstr "IDE (%01i:%01i)" - -msgid "ATAPI (%01i:%01i)" -msgstr "ATAPI (%01i:%01i)" - -msgid "SCSI (%01i:%02i)" -msgstr "SCSI (%01i:%02i)" - msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index db8a157cd..bd87c6b61 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -586,9 +586,6 @@ msgstr "Provjeraj BPB" msgid "CD-ROM drives:" msgstr "CD-ROM pogoni:" -msgid "Earlier drive" -msgstr "Raniji pogon" - msgid "MO drives:" msgstr "MO pogoni:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "Bez" -msgid "Unable to load keyboard accelerators." -msgstr "Nije moguće učitati ubrzivače tipkovnice." - -msgid "Unable to register raw input." -msgstr "Nije moguće registrirati neobrađeni unos." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "ACPI bazirano gašenje" msgid "Hard disk (%1)" msgstr "Tvrdi disk (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLL ili ESDI CD-ROM pogoni nisu nikada postojali" @@ -1048,9 +1030,6 @@ msgstr "Vremenske ozanke matične i poređenog diska ne odgovaraju." msgid "Could not fix VHD timestamp." msgstr "Ne mogu popraviti vremensku oznaku slike VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ msgstr "IDE" msgid "ATAPI" msgstr "ATAPI" -msgid "MFM/RLL (%01i:%01i)" -msgstr "MFM/RLL (%01i:%01i)" - -msgid "XTA (%01i:%01i)" -msgstr "XTA (%01i:%01i)" - -msgid "ESDI (%01i:%01i)" -msgstr "ESDI (%01i:%01i)" - -msgid "IDE (%01i:%01i)" -msgstr "IDE (%01i:%01i)" - -msgid "ATAPI (%01i:%01i)" -msgstr "ATAPI (%01i:%01i)" - -msgid "SCSI (%01i:%02i)" -msgstr "SCSI (%01i:%02i)" - msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index 679502f00..7df519ea2 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -586,9 +586,6 @@ msgstr "BPB ellenőrzés" msgid "CD-ROM drives:" msgstr "CD-ROM meghajtók:" -msgid "Earlier drive" -msgstr "Korábbi meghajtó" - msgid "MO drives:" msgstr "MO-meghajtók:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "Nincs" -msgid "Unable to load keyboard accelerators." -msgstr "Nem lehet betölteni a billentyűzetgyorsítókat." - -msgid "Unable to register raw input." -msgstr "A közvetlen nyers bevitel regisztrálása nem sikerült." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "ACPI leállítás" msgid "Hard disk (%1)" msgstr "Merevlemez (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLL vagy ESDI CD-ROM meghajtók soha nem léteztek" @@ -1048,9 +1030,6 @@ msgstr "A szülő- és a gyermeklemez időbélyegei nem egyeznek" msgid "Could not fix VHD timestamp." msgstr "Nem sikerült kijavítani a VHD időbélyegét." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ msgstr "IDE" msgid "ATAPI" msgstr "ATAPI" -msgid "MFM/RLL (%01i:%01i)" -msgstr "MFM/RLL (%01i:%01i)" - -msgid "XTA (%01i:%01i)" -msgstr "XTA (%01i:%01i)" - -msgid "ESDI (%01i:%01i)" -msgstr "ESDI (%01i:%01i)" - -msgid "IDE (%01i:%01i)" -msgstr "IDE (%01i:%01i)" - -msgid "ATAPI (%01i:%01i)" -msgstr "ATAPI (%01i:%01i)" - -msgid "SCSI (%01i:%02i)" -msgstr "SCSI (%01i:%02i)" - msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index dfb11fb59..97c19bbbf 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -586,9 +586,6 @@ msgstr "Verifica BPB" msgid "CD-ROM drives:" msgstr "Unità CD-ROM:" -msgid "Earlier drive" -msgstr "Unità anteriore" - msgid "MO drives:" msgstr "Unità magneto-ottiche:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "Nessuno" -msgid "Unable to load keyboard accelerators." -msgstr "Impossibile caricare gli acceleratori da tastiera." - -msgid "Unable to register raw input." -msgstr "Impossibile registrare input raw." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "Arresto ACPI" msgid "Hard disk (%1)" msgstr "Hard disk (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "Le unità CD-ROM MFM/RLL o ESDI non sono mai esistite." @@ -1048,9 +1030,6 @@ msgstr "Le marcature di tempo padre e figlio non corrispondono" msgid "Could not fix VHD timestamp." msgstr "Impossibile aggiustare marcature di tempo VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ msgstr "IDE" msgid "ATAPI" msgstr "ATAPI" -msgid "MFM/RLL (%01i:%01i)" -msgstr "MFM/RLL (%01i:%01i)" - -msgid "XTA (%01i:%01i)" -msgstr "XTA (%01i:%01i)" - -msgid "ESDI (%01i:%01i)" -msgstr "ESDI (%01i:%01i)" - -msgid "IDE (%01i:%01i)" -msgstr "IDE (%01i:%01i)" - -msgid "ATAPI (%01i:%01i)" -msgstr "ATAPI (%01i:%01i)" - -msgid "SCSI (%01i:%02i)" -msgstr "SCSI (%01i:%02i)" - msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index c2b0a3d71..7ae841f9d 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -586,9 +586,6 @@ msgstr "BPBチェック" msgid "CD-ROM drives:" msgstr "CD-ROMドライブ:" -msgid "Earlier drive" -msgstr "先のドライブ" - msgid "MO drives:" msgstr "光磁気ドライブ:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster飛行制御システム" msgid "None" msgstr "なし" -msgid "Unable to load keyboard accelerators." -msgstr "キーボードアクセラレータを読み込めません。" - -msgid "Unable to register raw input." -msgstr "生入力が登録できません。" - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS値: %i、%i、%i)" @@ -937,12 +925,6 @@ msgstr "ACPIシャットダウン" msgid "Hard disk (%1)" msgstr "ハードディスク (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLLやESDI CD-ROMドライブが存在しません" @@ -1048,9 +1030,6 @@ msgstr "親ディスクと子ディスクのタイムス タンプが一致し msgid "Could not fix VHD timestamp." msgstr "VHD のタイムスタンプを修正できません。" -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ msgstr "IDE" msgid "ATAPI" msgstr "ATAPI" -msgid "MFM/RLL (%01i:%01i)" -msgstr "MFM/RLL (%01i:%01i)" - -msgid "XTA (%01i:%01i)" -msgstr "XTA (%01i:%01i)" - -msgid "ESDI (%01i:%01i)" -msgstr "ESDI (%01i:%01i)" - -msgid "IDE (%01i:%01i)" -msgstr "IDE (%01i:%01i)" - -msgid "ATAPI (%01i:%01i)" -msgstr "ATAPI (%01i:%01i)" - -msgid "SCSI (%01i:%02i)" -msgstr "SCSI (%01i:%02i)" - msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index 99e74e880..29a6ce8dc 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -586,9 +586,6 @@ msgstr "BPB 확인" msgid "CD-ROM drives:" msgstr "CD-ROM 드라이브:" -msgid "Earlier drive" -msgstr "이전 드라이브" - msgid "MO drives:" msgstr "광자기 드라이브:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "없음" -msgid "Unable to load keyboard accelerators." -msgstr "키보드 가속기를 불러올 수 없습니다." - -msgid "Unable to register raw input." -msgstr "Raw 입력을 등록할 수 없습니다." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "ACPI 종료" msgid "Hard disk (%1)" msgstr "하드 디스크 (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLL 또는 ESDI CD-ROM 드라이브가 존재하지 않습니다" @@ -1048,9 +1030,6 @@ msgstr "부모 디스크와 자식 디스크의 타임스탬프가 일치하지 msgid "Could not fix VHD timestamp." msgstr "VHD 타임스탬프를 고칠 수 없습니다" -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ msgstr "IDE" msgid "ATAPI" msgstr "ATAPI" -msgid "MFM/RLL (%01i:%01i)" -msgstr "MFM/RLL (%01i:%01i)" - -msgid "XTA (%01i:%01i)" -msgstr "XTA (%01i:%01i)" - -msgid "ESDI (%01i:%01i)" -msgstr "ESDI (%01i:%01i)" - -msgid "IDE (%01i:%01i)" -msgstr "IDE (%01i:%01i)" - -msgid "ATAPI (%01i:%01i)" -msgstr "ATAPI (%01i:%01i)" - -msgid "SCSI (%01i:%02i)" -msgstr "SCSI (%01i:%02i)" - msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index b67946434..b19bde052 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -586,9 +586,6 @@ msgstr "Sprawdzaj BPB" msgid "CD-ROM drives:" msgstr "Napędy CD-ROM:" -msgid "Earlier drive" -msgstr "Wcześniejszy napęd" - msgid "MO drives:" msgstr "Napędy MO:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "Żaden" -msgid "Unable to load keyboard accelerators." -msgstr "Nie można załadować akceleratorów klawiaturowych." - -msgid "Unable to register raw input." -msgstr "Nie można zarejestrować surowych danych wejściowych." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "Wyłączenie ACPI" msgid "Hard disk (%1)" msgstr "Dysk twardy (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "Napędy CD-ROM MFM/RLL lub ESDI nigdy nie istniały" @@ -1048,9 +1030,6 @@ msgstr "Sygnatury czasowe dysku nadrzędnego i podrzędnego nie zgadzają się" msgid "Could not fix VHD timestamp." msgstr "Nie można naprawić sygnatury czasowej VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ msgstr "IDE" msgid "ATAPI" msgstr "ATAPI" -msgid "MFM/RLL (%01i:%01i)" -msgstr "MFM/RLL (%01i:%01i)" - -msgid "XTA (%01i:%01i)" -msgstr "XTA (%01i:%01i)" - -msgid "ESDI (%01i:%01i)" -msgstr "ESDI (%01i:%01i)" - -msgid "IDE (%01i:%01i)" -msgstr "IDE (%01i:%01i)" - -msgid "ATAPI (%01i:%01i)" -msgstr "ATAPI (%01i:%01i)" - -msgid "SCSI (%01i:%02i)" -msgstr "SCSI (%01i:%02i)" - msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 689841312..137fd89bf 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -586,9 +586,6 @@ msgstr "Verificar BPB" msgid "CD-ROM drives:" msgstr "Unidades de CD-ROM:" -msgid "Earlier drive" -msgstr "Unidade anterior" - msgid "MO drives:" msgstr "Unidades magneto-ópticas:" @@ -781,15 +778,6 @@ msgstr "Sistema de Controle de Voo Thrustmaster" msgid "None" msgstr "Nada" -msgid "Unable to load keyboard accelerators." -msgstr "Não foi possível carregar os aceleradores do teclado." - -msgid "Unable to register raw input." -msgstr "Não foi possível registrar a entrada bruta." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "Desligamento por ACPI" msgid "Hard disk (%1)" msgstr "Disco rígido (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "As unidades de CD-ROM MFM/RLL ou ESDI nunca existiram" @@ -1048,9 +1030,6 @@ msgstr "A data/hora dos arquivos de pais e filhos não correspondem" msgid "Could not fix VHD timestamp." msgstr "Não foi possível consertar o carimbo de data/hora da VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ msgstr "IDE" msgid "ATAPI" msgstr "ATAPI" -msgid "MFM/RLL (%01i:%01i)" -msgstr "MFM/RLL (%01i:%01i)" - -msgid "XTA (%01i:%01i)" -msgstr "XTA (%01i:%01i)" - -msgid "ESDI (%01i:%01i)" -msgstr "ESDI (%01i:%01i)" - -msgid "IDE (%01i:%01i)" -msgstr "IDE (%01i:%01i)" - -msgid "ATAPI (%01i:%01i)" -msgstr "ATAPI (%01i:%01i)" - -msgid "SCSI (%01i:%02i)" -msgstr "SCSI (%01i:%02i)" - msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index adfc05391..9e98b135f 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -586,9 +586,6 @@ msgstr "Verificar BPB" msgid "CD-ROM drives:" msgstr "Unidades CD-ROM:" -msgid "Earlier drive" -msgstr "Unidade anterior" - msgid "MO drives:" msgstr "Unidades magneto-ópticas:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "Nenhum" -msgid "Unable to load keyboard accelerators." -msgstr "Não foi possível inicializar os aceleradores de teclado." - -msgid "Unable to register raw input." -msgstr "Não foi possível registar a entrada bruta." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CCS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "Encerramento ACPI" msgid "Hard disk (%1)" msgstr "Disco rígido (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "Unidades CD-ROM com barramento MFM/RLL ou ESDI nunca existiram!" @@ -1048,9 +1030,6 @@ msgstr "Os carimbos de data/hora dos discos pai e filho não correspondem!" msgid "Could not fix VHD timestamp." msgstr "Não foi possível corrigir o carimbo de data/hora do VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ msgstr "IDE" msgid "ATAPI" msgstr "ATAPI" -msgid "MFM/RLL (%01i:%01i)" -msgstr "MFM/RLL (%01i:%01i)" - -msgid "XTA (%01i:%01i)" -msgstr "XTA (%01i:%01i)" - -msgid "ESDI (%01i:%01i)" -msgstr "ESDI (%01i:%01i)" - -msgid "IDE (%01i:%01i)" -msgstr "IDE (%01i:%01i)" - -msgid "ATAPI (%01i:%01i)" -msgstr "ATAPI (%01i:%01i)" - -msgid "SCSI (%01i:%02i)" -msgstr "SCSI (%01i:%02i)" - msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index 96da04710..e913514f9 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -670,9 +670,6 @@ msgstr "Проверять BPB" msgid "CD-ROM drives:" msgstr "Дисководы CD-ROM:" -msgid "Earlier drive" -msgstr "Предыдущий дисковод" - msgid "MO drives:" msgstr "Магнитооптические дисководы:" @@ -871,15 +868,6 @@ msgstr "Система управления полётом Thrustmaster" msgid "None" msgstr "Нет" -msgid "Unable to load keyboard accelerators." -msgstr "Невозможно загрузить ускорители клавиатуры." - -msgid "Unable to register raw input." -msgstr "Невозможно зарегистрировать необработанный (RAW) ввод." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u МБ (CHS: %i, %i, %i)" @@ -1027,12 +1015,6 @@ msgstr "Сигнал завершения ACPI" msgid "Hard disk (%1)" msgstr "Жёсткий диск (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLL или ESDI дисководов CD-ROM никогда не существовало" @@ -1138,9 +1120,6 @@ msgstr "Временные метки родительского и дочерн msgid "Could not fix VHD timestamp." msgstr "Не удалось исправить временную метку VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1156,24 +1135,6 @@ msgstr "IDE" msgid "ATAPI" msgstr "ATAPI" -msgid "MFM/RLL (%01i:%01i)" -msgstr "MFM/RLL (%01i:%01i)" - -msgid "XTA (%01i:%01i)" -msgstr "XTA (%01i:%01i)" - -msgid "ESDI (%01i:%01i)" -msgstr "ESDI (%01i:%01i)" - -msgid "IDE (%01i:%01i)" -msgstr "IDE (%01i:%01i)" - -msgid "ATAPI (%01i:%01i)" -msgstr "ATAPI (%01i:%01i)" - -msgid "SCSI (%01i:%02i)" -msgstr "SCSI (%01i:%02i)" - msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index c22445a19..95ebba063 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -586,9 +586,6 @@ msgstr "Kontrola BPB" msgid "CD-ROM drives:" msgstr "Mechaniky CD-ROM:" -msgid "Earlier drive" -msgstr "Skorá mechanika" - msgid "MO drives:" msgstr "Magnetooptické mechaniky:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "Žiadne" -msgid "Unable to load keyboard accelerators." -msgstr "Nebolo možné nahrať klávesnicové skratky." - -msgid "Unable to register raw input." -msgstr "Nebolo možné zaregistrovať raw input." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "Vypnúť cez rozhranie ACPI" msgid "Hard disk (%1)" msgstr "Pevný disk (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "CD-ROM mechaniky pre rozhranie MFM/RLL alebo ESDI nikdy neexistovali" @@ -1048,9 +1030,6 @@ msgstr "Časové pečiatky nadradeného a podradeného disku nesúhlasia" msgid "Could not fix VHD timestamp." msgstr "Nebolo možné opraviť časovú pečiatku VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ msgstr "IDE" msgid "ATAPI" msgstr "ATAPI" -msgid "MFM/RLL (%01i:%01i)" -msgstr "MFM/RLL (%01i:%01i)" - -msgid "XTA (%01i:%01i)" -msgstr "XTA (%01i:%01i)" - -msgid "ESDI (%01i:%01i)" -msgstr "ESDI (%01i:%01i)" - -msgid "IDE (%01i:%01i)" -msgstr "IDE (%01i:%01i)" - -msgid "ATAPI (%01i:%01i)" -msgstr "ATAPI (%01i:%01i)" - -msgid "SCSI (%01i:%02i)" -msgstr "SCSI (%01i:%02i)" - msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index c32c6c754..b0a7e1a04 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -586,9 +586,6 @@ msgstr "Preverjaj BPB" msgid "CD-ROM drives:" msgstr "Pogoni CD-ROM:" -msgid "Earlier drive" -msgstr "Zgodnejši pogon" - msgid "MO drives:" msgstr "Magnetno-optični pogoni:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "Brez" -msgid "Unable to load keyboard accelerators." -msgstr "Ne morem naložiti pospeševalnikov tipkovnice." - -msgid "Unable to register raw input." -msgstr "Ne morem registrirati neobdelanega vnosa." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "Zaustavitev ACPI" msgid "Hard disk (%1)" msgstr "Trdi disk (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLL ali ESDI pogoni CD-ROM niso nikoli obstajali" @@ -1048,9 +1030,6 @@ msgstr "Časovna žiga starševske slike diska in slike diska otroka se ne ujema msgid "Could not fix VHD timestamp." msgstr "Ne morem popraviti časovnega žiga slike VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ msgstr "IDE" msgid "ATAPI" msgstr "ATAPI" -msgid "MFM/RLL (%01i:%01i)" -msgstr "MFM/RLL (%01i:%01i)" - -msgid "XTA (%01i:%01i)" -msgstr "XTA (%01i:%01i)" - -msgid "ESDI (%01i:%01i)" -msgstr "ESDI (%01i:%01i)" - -msgid "IDE (%01i:%01i)" -msgstr "IDE (%01i:%01i)" - -msgid "ATAPI (%01i:%01i)" -msgstr "ATAPI (%01i:%01i)" - -msgid "SCSI (%01i:%02i)" -msgstr "SCSI (%01i:%02i)" - msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index a1ce42b38..bfe745301 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -586,9 +586,6 @@ msgstr "BPB'yi denetle" msgid "CD-ROM drives:" msgstr "CD-ROM sürücüleri:" -msgid "Earlier drive" -msgstr "Daha erken sürüş" - msgid "MO drives:" msgstr "MO sürücüleri:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Kontrol Sistemi" msgid "None" msgstr "Hiçbiri" -msgid "Unable to load keyboard accelerators." -msgstr "Klavye ivdirgeçleri yüklenemedi." - -msgid "Unable to register raw input." -msgstr "Ham girdi kaydedilemedi." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "ACPI kapatma" msgid "Hard disk (%1)" msgstr "Hard disk (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLL veya ESDI CD-ROM sürücüleri hiçbir zaman var olmamıştır" @@ -1048,9 +1030,6 @@ msgstr "Ana ve ek disk zaman damgaları uyuşmuyor" msgid "Could not fix VHD timestamp." msgstr "VHD zaman damgası düzeltilemedi." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ msgstr "IDE" msgid "ATAPI" msgstr "ATAPI" -msgid "MFM/RLL (%01i:%01i)" -msgstr "MFM/RLL (%01i:%01i)" - -msgid "XTA (%01i:%01i)" -msgstr "XTA (%01i:%01i)" - -msgid "ESDI (%01i:%01i)" -msgstr "ESDI (%01i:%01i)" - -msgid "IDE (%01i:%01i)" -msgstr "IDE (%01i:%01i)" - -msgid "ATAPI (%01i:%01i)" -msgstr "ATAPI (%01i:%01i)" - -msgid "SCSI (%01i:%02i)" -msgstr "SCSI (%01i:%02i)" - msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index 0dc666c0d..c4731a375 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -586,9 +586,6 @@ msgstr "Перевіряти BPB" msgid "CD-ROM drives:" msgstr "Дисководи CD-ROM:" -msgid "Earlier drive" -msgstr "Більш ранній дисковод" - msgid "MO drives:" msgstr "Магнітооптичні дисководи:" @@ -781,15 +778,6 @@ msgstr "Система управління польотом Thrustmaster" msgid "None" msgstr "Ні" -msgid "Unable to load keyboard accelerators." -msgstr "Неможливо завантажити прискорювачі клавіатури." - -msgid "Unable to register raw input." -msgstr "Неможливо зарреєструвати необроблене (RAW) введення." - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u МБ (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "Сигнал завершення ACPI" msgid "Hard disk (%1)" msgstr "Жорсткий диск (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "MFM/RLL або ESDI дисководів CD-ROM ніколи не існувало" @@ -1048,9 +1030,6 @@ msgstr "Тимчасові мітки батьківського та дочір msgid "Could not fix VHD timestamp." msgstr "Не вдалося виправити тимчасову позначку VHD." -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ msgstr "IDE" msgid "ATAPI" msgstr "ATAPI" -msgid "MFM/RLL (%01i:%01i)" -msgstr "MFM/RLL (%01i:%01i)" - -msgid "XTA (%01i:%01i)" -msgstr "XTA (%01i:%01i)" - -msgid "ESDI (%01i:%01i)" -msgstr "ESDI (%01i:%01i)" - -msgid "IDE (%01i:%01i)" -msgstr "IDE (%01i:%01i)" - -msgid "ATAPI (%01i:%01i)" -msgstr "ATAPI (%01i:%01i)" - -msgid "SCSI (%01i:%02i)" -msgstr "SCSI (%01i:%02i)" - msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index dea46160e..87d291739 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -586,9 +586,6 @@ msgstr "检查 BPB" msgid "CD-ROM drives:" msgstr "光盘驱动器:" -msgid "Earlier drive" -msgstr "早先的驱动器" - msgid "MO drives:" msgstr "磁光盘驱动器:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "无" -msgid "Unable to load keyboard accelerators." -msgstr "无法加载键盘加速器。" - -msgid "Unable to register raw input." -msgstr "无法注册原始输入。" - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "ACPI 关机" msgid "Hard disk (%1)" msgstr "硬盘 (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "不存在 MFM/RLL 或 ESDI CD-ROM 驱动器" @@ -1048,9 +1030,6 @@ msgstr "父盘与子盘的时间戳不匹配" msgid "Could not fix VHD timestamp." msgstr "无法修复 VHD 时间戳。" -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ msgstr "IDE" msgid "ATAPI" msgstr "ATAPI" -msgid "MFM/RLL (%01i:%01i)" -msgstr "MFM/RLL (%01i:%01i)" - -msgid "XTA (%01i:%01i)" -msgstr "XTA (%01i:%01i)" - -msgid "ESDI (%01i:%01i)" -msgstr "ESDI (%01i:%01i)" - -msgid "IDE (%01i:%01i)" -msgstr "IDE (%01i:%01i)" - -msgid "ATAPI (%01i:%01i)" -msgstr "ATAPI (%01i:%01i)" - -msgid "SCSI (%01i:%02i)" -msgstr "SCSI (%01i:%02i)" - msgid "CD-ROM %i (%s): %s" msgstr "光盘 %i (%s): %s" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 9392ce717..2fe3405a3 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -586,9 +586,6 @@ msgstr "檢查 BPB" msgid "CD-ROM drives:" msgstr "光碟機:" -msgid "Earlier drive" -msgstr "早先的光碟機" - msgid "MO drives:" msgstr "磁光碟機:" @@ -781,15 +778,6 @@ msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "無" -msgid "Unable to load keyboard accelerators." -msgstr "無法載入鍵盤加速器。" - -msgid "Unable to register raw input." -msgstr "無法註冊原始輸入。" - -msgid "%u" -msgstr "%u" - msgid "%u MB (CHS: %i, %i, %i)" msgstr "%u MB (CHS: %i, %i, %i)" @@ -937,12 +925,6 @@ msgstr "ACPI 關機" msgid "Hard disk (%1)" msgstr "硬碟 (%1)" -msgid "%01i:%01i" -msgstr "%01i:%01i" - -msgid "%01i" -msgstr "%01i" - msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "不存在 MFM/RLL 或 ESDI CD-ROM 光碟機" @@ -1048,9 +1030,6 @@ msgstr "父碟與子碟的時間戳不匹配" msgid "Could not fix VHD timestamp." msgstr "無法修復 VHD 時間戳。" -msgid "%01i:%02i" -msgstr "%01i:%02i" - msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1066,24 +1045,6 @@ msgstr "IDE" msgid "ATAPI" msgstr "ATAPI" -msgid "MFM/RLL (%01i:%01i)" -msgstr "MFM/RLL (%01i:%01i)" - -msgid "XTA (%01i:%01i)" -msgstr "XTA (%01i:%01i)" - -msgid "ESDI (%01i:%01i)" -msgstr "ESDI (%01i:%01i)" - -msgid "IDE (%01i:%01i)" -msgstr "IDE (%01i:%01i)" - -msgid "ATAPI (%01i:%01i)" -msgstr "ATAPI (%01i:%01i)" - -msgid "SCSI (%01i:%02i)" -msgstr "SCSI (%01i:%02i)" - msgid "CD-ROM %i (%s): %s" msgstr "光碟 %i (%s): %s" From 3e61092d02a52d69b537c879ab9fe6bc5cc78ab0 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 20 Mar 2024 20:21:52 +0500 Subject: [PATCH 701/936] Translations: Add headers to indicate target lang --- src/qt/languages/ca-ES.po | 8 ++++++++ src/qt/languages/cs-CZ.po | 8 ++++++++ src/qt/languages/de-DE.po | 8 ++++++++ src/qt/languages/en-GB.po | 8 ++++++++ src/qt/languages/en-US.po | 8 ++++++++ src/qt/languages/es-ES.po | 8 ++++++++ src/qt/languages/fi-FI.po | 8 ++++++++ src/qt/languages/fr-FR.po | 8 ++++++++ src/qt/languages/hr-HR.po | 8 ++++++++ src/qt/languages/hu-HU.po | 8 ++++++++ src/qt/languages/it-IT.po | 8 ++++++++ src/qt/languages/ja-JP.po | 8 ++++++++ src/qt/languages/ko-KR.po | 8 ++++++++ src/qt/languages/pl-PL.po | 8 ++++++++ src/qt/languages/pt-BR.po | 8 ++++++++ src/qt/languages/pt-PT.po | 8 ++++++++ src/qt/languages/ru-RU.po | 8 ++++++++ src/qt/languages/sk-SK.po | 8 ++++++++ src/qt/languages/sl-SI.po | 8 ++++++++ src/qt/languages/tr-TR.po | 8 ++++++++ src/qt/languages/uk-UA.po | 8 ++++++++ src/qt/languages/zh-CN.po | 8 ++++++++ src/qt/languages/zh-TW.po | 8 ++++++++ 23 files changed, 184 insertions(+) diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po index 3cde2ff11..94b35a235 100644 --- a/src/qt/languages/ca-ES.po +++ b/src/qt/languages/ca-ES.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: ca_ES\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Acció" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index 717a4f488..84debf20b 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: cs_CZ\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Akce" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index c5e5e78aa..70b856aa2 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: de_DE\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Aktionen" diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index 8e22289b8..a20a1ec36 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: en_GB\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Action" diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index 8298ba0e3..39400ebcc 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: en_US\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Action" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index 4e2c84d26..21fedd7df 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: es_ES\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Acción" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index 8935f66b4..829e9870f 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: fi_FI\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Toiminto" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index c1a0ba18c..f7687132f 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: fr_FR\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Action" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index bd87c6b61..eb69971b8 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: hr_HR\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Radnje" diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index 7df519ea2..ac088e148 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: hu_HU\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Művelet" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index 97c19bbbf..0ce1efabb 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: it_IT\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Azione" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index 7ae841f9d..c20848be6 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: ja_JP\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "操作(&A)" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index 29a6ce8dc..afecf78f6 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: ko_KR\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "동작(&A)" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index b19bde052..993e6633a 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: pl_PL\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Akcje" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 137fd89bf..642031e9a 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: pt_BR\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Ação" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index 9e98b135f..3aa004e83 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: pt_PT\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Ação" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index e913514f9..a4103c3e8 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: ru_RU\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Действие" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index 95ebba063..8aeb0f082 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: sk_SK\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Podujatia" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index b0a7e1a04..2a4b68e46 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: sl_SI\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Dejanja" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index bfe745301..ada5ff87f 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: tr_TR\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Komutlar" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index c4731a375..8dca70a85 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: uk_UA\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "&Дія" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index 87d291739..7dd7be6d2 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: zh_CN\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "操作(&A)" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 2fe3405a3..8ea4d2290 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -1,3 +1,11 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: zh_TW\n" +"X-Source-Language: en_US\n" + msgid "&Action" msgstr "動作(&A)" From 18495cb09d96d6420e751ae7ab18f08fd1cd8632 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 20 Mar 2024 20:36:09 +0500 Subject: [PATCH 702/936] Clean up redundant English "translations" --- src/qt/languages/en-GB.po | 1156 +----------------------------------- src/qt/languages/en-US.po | 1167 ------------------------------------- 2 files changed, 5 insertions(+), 2318 deletions(-) diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index a20a1ec36..fa6d1e2c3 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -6,1169 +6,23 @@ msgstr "" "X-Language: en_GB\n" "X-Source-Language: en_US\n" -msgid "&Action" -msgstr "&Action" - -msgid "&Keyboard requires capture" -msgstr "&Keyboard requires capture" - -msgid "&Right CTRL is left ALT" -msgstr "&Right CTRL is left ALT" - -msgid "&Hard Reset..." -msgstr "&Hard Reset..." - -msgid "&Ctrl+Alt+Del\tCtrl+F12" -msgstr "&Ctrl+Alt+Del\tCtrl+F12" - -msgid "Ctrl+Alt+&Esc" -msgstr "Ctrl+Alt+&Esc" - -msgid "&Pause" -msgstr "&Pause" - -msgid "E&xit..." -msgstr "E&xit..." - -msgid "&View" -msgstr "&View" - -msgid "&Hide status bar" -msgstr "&Hide status bar" - -msgid "Hide &toolbar" -msgstr "Hide &toolbar" - -msgid "&Resizeable window" -msgstr "&Resizeable window" - -msgid "R&emember size && position" -msgstr "R&emember size && position" - -msgid "Re&nderer" -msgstr "Re&nderer" - -msgid "&Qt (Software)" -msgstr "&Qt (Software)" - -msgid "Qt (&OpenGL)" -msgstr "Qt (&OpenGL)" - -msgid "Open&GL (3.0 Core)" -msgstr "Open&GL (3.0 Core)" - -msgid "&VNC" -msgstr "&VNC" - -msgid "Specify dimensions..." -msgstr "Specify dimensions..." - -msgid "F&orce 4:3 display ratio" -msgstr "F&orce 4:3 display ratio" - -msgid "&Window scale factor" -msgstr "&Window scale factor" - -msgid "&0.5x" -msgstr "&0.5x" - -msgid "&1x" -msgstr "&1x" - -msgid "1.&5x" -msgstr "1.&5x" - -msgid "&2x" -msgstr "&2x" - -msgid "&3x" -msgstr "&3x" - -msgid "&4x" -msgstr "&4x" - -msgid "&5x" -msgstr "&5x" - -msgid "&6x" -msgstr "&6x" - -msgid "&7x" -msgstr "&7x" - -msgid "&8x" -msgstr "&8x" - -msgid "Filter method" -msgstr "Filter method" - -msgid "&Nearest" -msgstr "&Nearest" - -msgid "&Linear" -msgstr "&Linear" - -msgid "Hi&DPI scaling" -msgstr "Hi&DPI scaling" - -msgid "&Fullscreen\tCtrl+Alt+PgUp" -msgstr "&Fullscreen\tCtrl+Alt+PgUp" - -msgid "Fullscreen &stretch mode" -msgstr "Fullscreen &stretch mode" - -msgid "&Full screen stretch" -msgstr "&Full screen stretch" - -msgid "&4:3" -msgstr "&4:3" - -msgid "&Square pixels (Keep ratio)" -msgstr "&Square pixels (Keep ratio)" - -msgid "&Integer scale" -msgstr "&Integer scale" - -msgid "4:&3 Integer scale" -msgstr "4:&3 Integer scale" - -msgid "E&GA/(S)VGA settings" -msgstr "E&GA/(S)VGA settings" - -msgid "&Inverted VGA monitor" -msgstr "&Inverted VGA monitor" - -msgid "VGA screen &type" -msgstr "VGA screen &type" - msgid "RGB &Color" msgstr "RGB &Colour" msgid "&RGB Grayscale" msgstr "&RGB Greyscale" -msgid "&Amber monitor" -msgstr "&Amber monitor" - -msgid "&Green monitor" -msgstr "&Green monitor" - -msgid "&White monitor" -msgstr "&White monitor" - -msgid "Grayscale &conversion type" -msgstr "Grayscale &conversion type" - -msgid "BT&601 (NTSC/PAL)" -msgstr "BT&601 (NTSC/PAL)" - -msgid "BT&709 (HDTV)" -msgstr "BT&709 (HDTV)" - -msgid "&Average" -msgstr "&Average" - -msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" -msgstr "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" - -msgid "Change contrast for &monochrome display" -msgstr "Change contrast for &monochrome display" - -msgid "&Media" -msgstr "&Media" - -msgid "&Tools" -msgstr "&Tools" - -msgid "&Settings..." -msgstr "&Settings..." - -msgid "&Update status bar icons" -msgstr "&Update status bar icons" - -msgid "Take s&creenshot\tCtrl+F11" -msgstr "Take s&creenshot\tCtrl+F11" - -msgid "&Preferences..." -msgstr "&Preferences..." - -msgid "Enable &Discord integration" -msgstr "Enable &Discord integration" - -msgid "Sound &gain..." -msgstr "Sound &gain..." - -msgid "Begin trace\tCtrl+T" -msgstr "Begin trace\tCtrl+T" - -msgid "End trace\tCtrl+T" -msgstr "End trace\tCtrl+T" - -msgid "&Help" -msgstr "&Help" - -msgid "&Documentation..." -msgstr "&Documentation..." - -msgid "&About 86Box..." -msgstr "&About 86Box..." - -msgid "&New image..." -msgstr "&New image..." - -msgid "&Existing image..." -msgstr "&Existing image..." - -msgid "Existing image (&Write-protected)..." -msgstr "Existing image (&Write-protected)..." - -msgid "&Record" -msgstr "&Record" - -msgid "&Play" -msgstr "&Play" - -msgid "&Rewind to the beginning" -msgstr "&Rewind to the beginning" - -msgid "&Fast forward to the end" -msgstr "&Fast forward to the end" - -msgid "E&ject" -msgstr "E&ject" - -msgid "&Image..." -msgstr "&Image..." - -msgid "E&xport to 86F..." -msgstr "E&xport to 86F..." - -msgid "&Mute" -msgstr "&Mute" - -msgid "E&mpty" -msgstr "E&mpty" - -msgid "&Reload previous image" -msgstr "&Reload previous image" - -msgid "&Folder..." -msgstr "&Folder..." - -msgid "Target &framerate" -msgstr "Target &framerate" - -msgid "&Sync with video" -msgstr "&Sync with video" - -msgid "&25 fps" -msgstr "&25 fps" - -msgid "&30 fps" -msgstr "&30 fps" - -msgid "&50 fps" -msgstr "&50 fps" - -msgid "&60 fps" -msgstr "&60 fps" - -msgid "&75 fps" -msgstr "&75 fps" - -msgid "&VSync" -msgstr "&VSync" - -msgid "&Select shader..." -msgstr "&Select shader..." - -msgid "&Remove shader" -msgstr "&Remove shader" - -msgid "Preferences" -msgstr "Preferences" - -msgid "Sound Gain" -msgstr "Sound Gain" - -msgid "New Image" -msgstr "New Image" - -msgid "Settings" -msgstr "Settings" - -msgid "Specify Main Window Dimensions" -msgstr "Specify Main Window Dimensions" - -msgid "OK" -msgstr "OK" - -msgid "Cancel" -msgstr "Cancel" - -msgid "Save these settings as &global defaults" -msgstr "Save these settings as &global defaults" - -msgid "&Default" -msgstr "&Default" - -msgid "Language:" -msgstr "Language:" - -msgid "Icon set:" -msgstr "Icon set:" - -msgid "Gain" -msgstr "Gain" - -msgid "File name:" -msgstr "File name:" - -msgid "Disk size:" -msgstr "Disk size:" - -msgid "RPM mode:" -msgstr "RPM mode:" - -msgid "Progress:" -msgstr "Progress:" - -msgid "Width:" -msgstr "Width:" - -msgid "Height:" -msgstr "Height:" - -msgid "Lock to this size" -msgstr "Lock to this size" - -msgid "Machine type:" -msgstr "Machine type:" - -msgid "Machine:" -msgstr "Machine:" - -msgid "Configure" -msgstr "Configure" - -msgid "CPU type:" -msgstr "CPU type:" - -msgid "Speed:" -msgstr "Speed:" - -msgid "Frequency:" -msgstr "Frequency:" - -msgid "FPU:" -msgstr "FPU:" - -msgid "Wait states:" -msgstr "Wait states:" - -msgid "MB" -msgstr "MB" - -msgid "Memory:" -msgstr "Memory:" - msgid "Time synchronization" -msgstr "Time synchronization" - -msgid "Disabled" -msgstr "Disabled" - -msgid "Enabled (local time)" -msgstr "Enabled (local time)" - -msgid "Enabled (UTC)" -msgstr "Enabled (UTC)" - -msgid "Dynamic Recompiler" -msgstr "Dynamic Recompiler" - -msgid "Video:" -msgstr "Video:" - -msgid "Voodoo Graphics" -msgstr "Voodoo Graphics" - -msgid "IBM 8514/A Graphics" -msgstr "IBM 8514/A Graphics" - -msgid "XGA Graphics" -msgstr "XGA Graphics" - -msgid "Mouse:" -msgstr "Mouse:" - -msgid "Joystick:" -msgstr "Joystick:" - -msgid "Joystick 1..." -msgstr "Joystick 1..." - -msgid "Joystick 2..." -msgstr "Joystick 2..." - -msgid "Joystick 3..." -msgstr "Joystick 3..." - -msgid "Joystick 4..." -msgstr "Joystick 4..." - -msgid "Sound card #1:" -msgstr "Sound card #1:" - -msgid "Sound card #2:" -msgstr "Sound card #2:" - -msgid "Sound card #3:" -msgstr "Sound card #3:" - -msgid "Sound card #4:" -msgstr "Sound card #4:" - -msgid "MIDI Out Device:" -msgstr "MIDI Out Device:" - -msgid "MIDI In Device:" -msgstr "MIDI In Device:" - -msgid "Standalone MPU-401" -msgstr "Standalone MPU-401" - -msgid "Use FLOAT32 sound" -msgstr "Use FLOAT32 sound" - -msgid "FM synth driver" -msgstr "FM synth driver" - -msgid "Nuked (more accurate)" -msgstr "Nuked (more accurate)" - -msgid "YMFM (faster)" -msgstr "YMFM (faster)" - -msgid "Network type:" -msgstr "Network type:" - -msgid "PCap device:" -msgstr "PCap device:" - -msgid "Network adapter:" -msgstr "Network adapter:" - -msgid "COM1 Device:" -msgstr "COM1 Device:" - -msgid "COM2 Device:" -msgstr "COM2 Device:" - -msgid "COM3 Device:" -msgstr "COM3 Device:" - -msgid "COM4 Device:" -msgstr "COM4 Device:" - -msgid "LPT1 Device:" -msgstr "LPT1 Device:" - -msgid "LPT2 Device:" -msgstr "LPT2 Device:" - -msgid "LPT3 Device:" -msgstr "LPT3 Device:" - -msgid "LPT4 Device:" -msgstr "LPT4 Device:" - -msgid "Serial port 1" -msgstr "Serial port 1" - -msgid "Serial port 2" -msgstr "Serial port 2" - -msgid "Serial port 3" -msgstr "Serial port 3" - -msgid "Serial port 4" -msgstr "Serial port 4" - -msgid "Parallel port 1" -msgstr "Parallel port 1" - -msgid "Parallel port 2" -msgstr "Parallel port 2" - -msgid "Parallel port 3" -msgstr "Parallel port 3" - -msgid "Parallel port 4" -msgstr "Parallel port 4" - -msgid "HD Controller:" -msgstr "HD Controller:" - -msgid "FD Controller:" -msgstr "FD Controller:" - -msgid "Tertiary IDE Controller" -msgstr "Tertiary IDE Controller" - -msgid "Quaternary IDE Controller" -msgstr "Quaternary IDE Controller" - -msgid "SCSI" -msgstr "SCSI" - -msgid "Controller 1:" -msgstr "Controller 1:" - -msgid "Controller 2:" -msgstr "Controller 2:" - -msgid "Controller 3:" -msgstr "Controller 3:" - -msgid "Controller 4:" -msgstr "Controller 4:" - -msgid "Cassette" -msgstr "Cassette" - -msgid "Hard disks:" -msgstr "Hard disks:" - -msgid "&New..." -msgstr "&New..." - -msgid "&Existing..." -msgstr "&Existing..." - -msgid "&Remove" -msgstr "&Remove" - -msgid "Bus:" -msgstr "Bus:" - -msgid "Channel:" -msgstr "Channel:" - -msgid "ID:" -msgstr "ID:" - -msgid "&Specify..." -msgstr "&Specify..." - -msgid "Sectors:" -msgstr "Sectors:" - -msgid "Heads:" -msgstr "Heads:" - -msgid "Cylinders:" -msgstr "Cylinders:" - -msgid "Size (MB):" -msgstr "Size (MB):" - -msgid "Type:" -msgstr "Type:" - -msgid "Image Format:" -msgstr "Image Format:" - -msgid "Block Size:" -msgstr "Block Size:" - -msgid "Floppy drives:" -msgstr "Floppy drives:" - -msgid "Turbo timings" -msgstr "Turbo timings" - -msgid "Check BPB" -msgstr "Check BPB" - -msgid "CD-ROM drives:" -msgstr "CD-ROM drives:" - -msgid "MO drives:" -msgstr "MO drives:" - -msgid "ZIP drives:" -msgstr "ZIP drives:" - -msgid "ZIP 250" -msgstr "ZIP 250" - -msgid "ISA RTC:" -msgstr "ISA RTC:" - -msgid "ISA Memory Expansion" -msgstr "ISA Memory Expansion" - -msgid "Card 1:" -msgstr "Card 1:" - -msgid "Card 2:" -msgstr "Card 2:" - -msgid "Card 3:" -msgstr "Card 3:" - -msgid "Card 4:" -msgstr "Card 4:" - -msgid "ISABugger device" -msgstr "ISABugger device" - -msgid "POST card" -msgstr "POST card" - -msgid "86Box" -msgstr "86Box" - -msgid "Error" -msgstr "Error" - -msgid "Fatal error" -msgstr "Fatal error" - -msgid " - PAUSED" -msgstr " - PAUSED" - -msgid "Press Ctrl+Alt+PgDn to return to windowed mode." -msgstr "Press Ctrl+Alt+PgDn to return to windowed mode." - -msgid "Speed" -msgstr "Speed" - -msgid "ZIP %03i %i (%s): %ls" -msgstr "ZIP %03i %i (%s): %ls" - -msgid "ZIP images" -msgstr "ZIP images" - -msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." -msgstr "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." - -msgid "(empty)" -msgstr "(empty)" - -msgid "All files" -msgstr "All files" - -msgid "Turbo" -msgstr "Turbo" - -msgid "On" -msgstr "On" - -msgid "Off" -msgstr "Off" - -msgid "All images" -msgstr "All images" - -msgid "Basic sector images" -msgstr "Basic sector images" - -msgid "Surface images" -msgstr "Surface images" - -msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." -msgstr "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." - -msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." -msgstr "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." - -msgid "Machine" -msgstr "Machine" - -msgid "Display" -msgstr "Display" - -msgid "Input devices" -msgstr "Input devices" - -msgid "Sound" -msgstr "Sound" - -msgid "Network" -msgstr "Network" - -msgid "Ports (COM & LPT)" -msgstr "Ports (COM & LPT)" - -msgid "Storage controllers" -msgstr "Storage controllers" - -msgid "Hard disks" -msgstr "Hard disks" - -msgid "Floppy & CD-ROM drives" -msgstr "Floppy & CD-ROM drives" - -msgid "Other removable devices" -msgstr "Other removable devices" - -msgid "Other peripherals" -msgstr "Other peripherals" - -msgid "Click to capture mouse" -msgstr "Click to capture mouse" - -msgid "Press %1 to release mouse" -msgstr "Press %1 to release mouse" - -msgid "Press %1 or middle button to release mouse" -msgstr "Press %1 or middle button to release mouse" - -msgid "Bus" -msgstr "Bus" - -msgid "File" -msgstr "File" - -msgid "C" -msgstr "C" - -msgid "H" -msgstr "H" - -msgid "S" -msgstr "S" - -msgid "KB" -msgstr "KB" +msgstr "Time synchronisation" msgid "Could not initialize the video renderer." -msgstr "Could not initialize the video renderer." - -msgid "Default" -msgstr "Default" - -msgid "%i Wait state(s)" -msgstr "%i Wait state(s)" - -msgid "Type" -msgstr "Type" - -msgid "No PCap devices found" -msgstr "No PCap devices found" - -msgid "Invalid PCap device" -msgstr "Invalid PCap device" - -msgid "Standard 2-button joystick(s)" -msgstr "Standard 2-button joystick(s)" - -msgid "Standard 4-button joystick" -msgstr "Standard 4-button joystick" - -msgid "Standard 6-button joystick" -msgstr "Standard 6-button joystick" - -msgid "Standard 8-button joystick" -msgstr "Standard 8-button joystick" - -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" - -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" - -msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control System" - -msgid "None" -msgstr "None" - -msgid "%u MB (CHS: %i, %i, %i)" -msgstr "%u MB (CHS: %i, %i, %i)" - -msgid "Floppy %i (%s): %ls" -msgstr "Floppy %i (%s): %ls" - -msgid "Advanced sector images" -msgstr "Advanced sector images" - -msgid "Flux images" -msgstr "Flux images" - -msgid "Are you sure you want to hard reset the emulated machine?" -msgstr "Are you sure you want to hard reset the emulated machine?" - -msgid "Are you sure you want to exit 86Box?" -msgstr "Are you sure you want to exit 86Box?" - -msgid "Unable to initialize Ghostscript" -msgstr "Unable to initialize Ghostscript" - -msgid "MO %i (%ls): %ls" -msgstr "MO %i (%ls): %ls" - -msgid "MO images" -msgstr "MO images" - -msgid "Welcome to 86Box!" -msgstr "Welcome to 86Box!" - -msgid "Internal controller" -msgstr "Internal controller" - -msgid "Exit" -msgstr "Exit" - -msgid "No ROMs found" -msgstr "No ROMs found" - -msgid "Do you want to save the settings?" -msgstr "Do you want to save the settings?" - -msgid "This will hard reset the emulated machine." -msgstr "This will hard reset the emulated machine." - -msgid "Save" -msgstr "Save" - -msgid "About 86Box" -msgstr "About 86Box" - -msgid "86Box v" -msgstr "86Box v" - -msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." - -msgid "Hardware not available" -msgstr "Hardware not available" - -msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." -msgstr "Make sure %1 is installed and that you are on a %1-compatible network connection." - -msgid "Invalid configuration" -msgstr "Invalid configuration" - -msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." - -msgid "Entering fullscreen mode" -msgstr "Entering fullscreen mode" - -msgid "Don't show this message again" -msgstr "Don't show this message again" - -msgid "Don't exit" -msgstr "Don't exit" - -msgid "Reset" -msgstr "Reset" - -msgid "Don't reset" -msgstr "Don't reset" - -msgid "CD-ROM images" -msgstr "CD-ROM images" - -msgid "%1 Device Configuration" -msgstr "%1 Device Configuration" - -msgid "Monitor in sleep mode" -msgstr "Monitor in sleep mode" - -msgid "OpenGL Shaders" -msgstr "OpenGL Shaders" - -msgid "OpenGL options" -msgstr "OpenGL options" - -msgid "You are loading an unsupported configuration" -msgstr "You are loading an unsupported configuration" - -msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." -msgstr "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." - -msgid "Continue" -msgstr "Continue" - -msgid "Cassette: %s" -msgstr "Cassette: %s" - -msgid "Cassette images" -msgstr "Cassette images" - -msgid "Cartridge %i: %ls" -msgstr "Cartridge %i: %ls" - -msgid "Cartridge images" -msgstr "Cartridge images" +msgstr "Could not initialise the video renderer." msgid "Error initializing renderer" -msgstr "Error initializing renderer" +msgstr "Error initialising renderer" msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." - -msgid "Resume execution" -msgstr "Resume execution" - -msgid "Pause execution" -msgstr "Pause execution" - -msgid "Press Ctrl+Alt+Del" -msgstr "Press Ctrl+Alt+Del" - -msgid "Press Ctrl+Alt+Esc" -msgstr "Press Ctrl+Alt+Esc" - -msgid "Hard reset" -msgstr "Hard reset" - -msgid "ACPI shutdown" -msgstr "ACPI shutdown" - -msgid "Hard disk (%1)" -msgstr "Hard disk (%1)" - -msgid "MFM/RLL or ESDI CD-ROM drives never existed" -msgstr "MFM/RLL or ESDI CD-ROM drives never existed" - -msgid "Custom..." -msgstr "Custom..." - -msgid "Custom (large)..." -msgstr "Custom (large)..." - -msgid "Add New Hard Disk" -msgstr "Add New Hard Disk" - -msgid "Add Existing Hard Disk" -msgstr "Add Existing Hard Disk" - -msgid "HDI disk images cannot be larger than 4 GB." -msgstr "HDI disk images cannot be larger than 4 GB." - -msgid "Disk images cannot be larger than 127 GB." -msgstr "Disk images cannot be larger than 127 GB." - -msgid "Hard disk images" -msgstr "Hard disk images" - -msgid "Unable to read file" -msgstr "Unable to read file" - -msgid "Unable to write file" -msgstr "Unable to write file" - -msgid "HDI or HDX images with a sector size other than 512 are not supported." -msgstr "HDI or HDX images with a sector size other than 512 are not supported." - -msgid "Disk image file already exists" -msgstr "Disk image file already exists" - -msgid "Please specify a valid file name." -msgstr "Please specify a valid file name." - -msgid "Disk image created" -msgstr "Disk image created" - -msgid "Make sure the file exists and is readable." -msgstr "Make sure the file exists and is readable." - -msgid "Make sure the file is being saved to a writable directory." -msgstr "Make sure the file is being saved to a writable directory." - -msgid "Disk image too large" -msgstr "Disk image too large" - -msgid "Remember to partition and format the newly-created drive." -msgstr "Remember to partition and format the newly-created drive." - -msgid "The selected file will be overwritten. Are you sure you want to use it?" -msgstr "The selected file will be overwritten. Are you sure you want to use it?" - -msgid "Unsupported disk image" -msgstr "Unsupported disk image" - -msgid "Overwrite" -msgstr "Overwrite" - -msgid "Don't overwrite" -msgstr "Don't overwrite" - -msgid "Raw image (.img)" -msgstr "Raw image (.img)" - -msgid "HDI image (.hdi)" -msgstr "HDI image (.hdi)" - -msgid "HDX image (.hdx)" -msgstr "HDX image (.hdx)" - -msgid "Fixed-size VHD (.vhd)" -msgstr "Fixed-size VHD (.vhd)" - -msgid "Dynamic-size VHD (.vhd)" -msgstr "Dynamic-size VHD (.vhd)" - -msgid "Differencing VHD (.vhd)" -msgstr "Differencing VHD (.vhd)" - -msgid "Large blocks (2 MB)" -msgstr "Large blocks (2 MB)" - -msgid "Small blocks (512 KB)" -msgstr "Small blocks (512 KB)" - -msgid "VHD files" -msgstr "VHD files" - -msgid "Select the parent VHD" -msgstr "Select the parent VHD" - -msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" -msgstr "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" - -msgid "Parent and child disk timestamps do not match" -msgstr "Parent and child disk timestamps do not match" - -msgid "Could not fix VHD timestamp." -msgstr "Could not fix VHD timestamp." - -msgid "MFM/RLL" -msgstr "MFM/RLL" - -msgid "XTA" -msgstr "XTA" - -msgid "ESDI" -msgstr "ESDI" - -msgid "IDE" -msgstr "IDE" - -msgid "ATAPI" -msgstr "ATAPI" - -msgid "CD-ROM %i (%s): %s" -msgstr "CD-ROM %i (%s): %s" - -msgid "160 kB" -msgstr "160 kB" - -msgid "180 kB" -msgstr "180 kB" - -msgid "320 kB" -msgstr "320 kB" - -msgid "360 kB" -msgstr "360 kB" - -msgid "640 kB" -msgstr "640 kB" - -msgid "720 kB" -msgstr "720 kB" - -msgid "1.2 MB" -msgstr "1.2 MB" - -msgid "1.25 MB" -msgstr "1.25 MB" - -msgid "1.44 MB" -msgstr "1.44 MB" - -msgid "DMF (cluster 1024)" -msgstr "DMF (cluster 1024)" - -msgid "DMF (cluster 2048)" -msgstr "DMF (cluster 2048)" - -msgid "2.88 MB" -msgstr "2.88 MB" - -msgid "ZIP 100" -msgstr "ZIP 100" - -msgid "3.5\" 128 MB (ISO 10090)" -msgstr "3.5\" 128 MB (ISO 10090)" - -msgid "3.5\" 230 MB (ISO 13963)" -msgstr "3.5\" 230 MB (ISO 13963)" - -msgid "3.5\" 540 MB (ISO 15498)" -msgstr "3.5\" 540 MB (ISO 15498)" - -msgid "3.5\" 640 MB (ISO 15498)" -msgstr "3.5\" 640 MB (ISO 15498)" - -msgid "3.5\" 1.3 GB (GigaMO)" -msgstr "3.5\" 1.3 GB (GigaMO)" - -msgid "3.5\" 2.3 GB (GigaMO 2)" -msgstr "3.5\" 2.3 GB (GigaMO 2)" - -msgid "5.25\" 600 MB" -msgstr "5.25\" 600 MB" - -msgid "5.25\" 650 MB" -msgstr "5.25\" 650 MB" - -msgid "5.25\" 1 GB" -msgstr "5.25\" 1 GB" - -msgid "5.25\" 1.3 GB" -msgstr "5.25\" 1.3 GB" - -msgid "Perfect RPM" -msgstr "Perfect RPM" - -msgid "1% below perfect RPM" -msgstr "1% below perfect RPM" - -msgid "1.5% below perfect RPM" -msgstr "1.5% below perfect RPM" - -msgid "2% below perfect RPM" -msgstr "2% below perfect RPM" - -msgid "(System Default)" -msgstr "(System Default)" - -msgid "Failed to initialize network driver" -msgstr "Failed to initialize network driver" - -msgid "The network configuration will be switched to the null driver" -msgstr "The network configuration will be switched to the null driver" - -msgid "Mouse sensitivity:" -msgstr "Mouse sensitivity:" - -msgid "Select media images from program working directory" -msgstr "Select media images from program working directory" - -msgid "PIT mode:" -msgstr "PIT mode:" - -msgid "Auto" -msgstr "Auto" - -msgid "Slow" -msgstr "Slow" - -msgid "Fast" -msgstr "Fast" - -msgid "&Auto-pause on focus loss" -msgstr "&Auto-pause on focus loss" - -msgid "WinBox is no longer supported" -msgstr "WinBox is no longer supported" +msgstr "OpenGL (3.0 Core) renderer could not be initialised. Use another renderer." msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." -msgstr "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behaviour will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index 39400ebcc..e78536c66 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -5,1170 +5,3 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Language: en_US\n" "X-Source-Language: en_US\n" - -msgid "&Action" -msgstr "&Action" - -msgid "&Keyboard requires capture" -msgstr "&Keyboard requires capture" - -msgid "&Right CTRL is left ALT" -msgstr "&Right CTRL is left ALT" - -msgid "&Hard Reset..." -msgstr "&Hard Reset..." - -msgid "&Ctrl+Alt+Del\tCtrl+F12" -msgstr "&Ctrl+Alt+Del\tCtrl+F12" - -msgid "Ctrl+Alt+&Esc" -msgstr "Ctrl+Alt+&Esc" - -msgid "&Pause" -msgstr "&Pause" - -msgid "E&xit..." -msgstr "E&xit..." - -msgid "&View" -msgstr "&View" - -msgid "&Hide status bar" -msgstr "&Hide status bar" - -msgid "Hide &toolbar" -msgstr "Hide &toolbar" - -msgid "&Resizeable window" -msgstr "&Resizeable window" - -msgid "R&emember size && position" -msgstr "R&emember size && position" - -msgid "Re&nderer" -msgstr "Re&nderer" - -msgid "&Qt (Software)" -msgstr "&Qt (Software)" - -msgid "Qt (&OpenGL)" -msgstr "Qt (&OpenGL)" - -msgid "Open&GL (3.0 Core)" -msgstr "Open&GL (3.0 Core)" - -msgid "&VNC" -msgstr "&VNC" - -msgid "Specify dimensions..." -msgstr "Specify dimensions..." - -msgid "F&orce 4:3 display ratio" -msgstr "F&orce 4:3 display ratio" - -msgid "&Window scale factor" -msgstr "&Window scale factor" - -msgid "&0.5x" -msgstr "&0.5x" - -msgid "&1x" -msgstr "&1x" - -msgid "1.&5x" -msgstr "1.&5x" - -msgid "&2x" -msgstr "&2x" - -msgid "&3x" -msgstr "&3x" - -msgid "&4x" -msgstr "&4x" - -msgid "&5x" -msgstr "&5x" - -msgid "&6x" -msgstr "&6x" - -msgid "&7x" -msgstr "&7x" - -msgid "&8x" -msgstr "&8x" - -msgid "Filter method" -msgstr "Filter method" - -msgid "&Nearest" -msgstr "&Nearest" - -msgid "&Linear" -msgstr "&Linear" - -msgid "Hi&DPI scaling" -msgstr "Hi&DPI scaling" - -msgid "&Fullscreen\tCtrl+Alt+PgUp" -msgstr "&Fullscreen\tCtrl+Alt+PgUp" - -msgid "Fullscreen &stretch mode" -msgstr "Fullscreen &stretch mode" - -msgid "&Full screen stretch" -msgstr "&Full screen stretch" - -msgid "&4:3" -msgstr "&4:3" - -msgid "&Square pixels (Keep ratio)" -msgstr "&Square pixels (Keep ratio)" - -msgid "&Integer scale" -msgstr "&Integer scale" - -msgid "4:&3 Integer scale" -msgstr "4:&3 Integer scale" - -msgid "E&GA/(S)VGA settings" -msgstr "E&GA/(S)VGA settings" - -msgid "&Inverted VGA monitor" -msgstr "&Inverted VGA monitor" - -msgid "VGA screen &type" -msgstr "VGA screen &type" - -msgid "RGB &Color" -msgstr "RGB &Color" - -msgid "&RGB Grayscale" -msgstr "&RGB Grayscale" - -msgid "&Amber monitor" -msgstr "&Amber monitor" - -msgid "&Green monitor" -msgstr "&Green monitor" - -msgid "&White monitor" -msgstr "&White monitor" - -msgid "Grayscale &conversion type" -msgstr "Grayscale &conversion type" - -msgid "BT&601 (NTSC/PAL)" -msgstr "BT&601 (NTSC/PAL)" - -msgid "BT&709 (HDTV)" -msgstr "BT&709 (HDTV)" - -msgid "&Average" -msgstr "&Average" - -msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" -msgstr "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" - -msgid "Change contrast for &monochrome display" -msgstr "Change contrast for &monochrome display" - -msgid "&Media" -msgstr "&Media" - -msgid "&Tools" -msgstr "&Tools" - -msgid "&Settings..." -msgstr "&Settings..." - -msgid "&Update status bar icons" -msgstr "&Update status bar icons" - -msgid "Take s&creenshot\tCtrl+F11" -msgstr "Take s&creenshot\tCtrl+F11" - -msgid "&Preferences..." -msgstr "&Preferences..." - -msgid "Enable &Discord integration" -msgstr "Enable &Discord integration" - -msgid "Sound &gain..." -msgstr "Sound &gain..." - -msgid "Begin trace\tCtrl+T" -msgstr "Begin trace\tCtrl+T" - -msgid "End trace\tCtrl+T" -msgstr "End trace\tCtrl+T" - -msgid "&Help" -msgstr "&Help" - -msgid "&Documentation..." -msgstr "&Documentation..." - -msgid "&About 86Box..." -msgstr "&About 86Box..." - -msgid "&New image..." -msgstr "&New image..." - -msgid "&Existing image..." -msgstr "&Existing image..." - -msgid "Existing image (&Write-protected)..." -msgstr "Existing image (&Write-protected)..." - -msgid "&Record" -msgstr "&Record" - -msgid "&Play" -msgstr "&Play" - -msgid "&Rewind to the beginning" -msgstr "&Rewind to the beginning" - -msgid "&Fast forward to the end" -msgstr "&Fast forward to the end" - -msgid "E&ject" -msgstr "E&ject" - -msgid "&Image..." -msgstr "&Image..." - -msgid "E&xport to 86F..." -msgstr "E&xport to 86F..." - -msgid "&Mute" -msgstr "&Mute" - -msgid "E&mpty" -msgstr "E&mpty" - -msgid "&Reload previous image" -msgstr "&Reload previous image" - -msgid "&Folder..." -msgstr "&Folder..." - -msgid "Target &framerate" -msgstr "Target &framerate" - -msgid "&Sync with video" -msgstr "&Sync with video" - -msgid "&25 fps" -msgstr "&25 fps" - -msgid "&30 fps" -msgstr "&30 fps" - -msgid "&50 fps" -msgstr "&50 fps" - -msgid "&60 fps" -msgstr "&60 fps" - -msgid "&75 fps" -msgstr "&75 fps" - -msgid "&VSync" -msgstr "&VSync" - -msgid "&Select shader..." -msgstr "&Select shader..." - -msgid "&Remove shader" -msgstr "&Remove shader" - -msgid "Preferences" -msgstr "Preferences" - -msgid "Sound Gain" -msgstr "Sound Gain" - -msgid "New Image" -msgstr "New Image" - -msgid "Settings" -msgstr "Settings" - -msgid "Specify Main Window Dimensions" -msgstr "Specify Main Window Dimensions" - -msgid "OK" -msgstr "OK" - -msgid "Cancel" -msgstr "Cancel" - -msgid "Save these settings as &global defaults" -msgstr "Save these settings as &global defaults" - -msgid "&Default" -msgstr "&Default" - -msgid "Language:" -msgstr "Language:" - -msgid "Icon set:" -msgstr "Icon set:" - -msgid "Gain" -msgstr "Gain" - -msgid "File name:" -msgstr "File name:" - -msgid "Disk size:" -msgstr "Disk size:" - -msgid "RPM mode:" -msgstr "RPM mode:" - -msgid "Progress:" -msgstr "Progress:" - -msgid "Width:" -msgstr "Width:" - -msgid "Height:" -msgstr "Height:" - -msgid "Lock to this size" -msgstr "Lock to this size" - -msgid "Machine type:" -msgstr "Machine type:" - -msgid "Machine:" -msgstr "Machine:" - -msgid "Configure" -msgstr "Configure" - -msgid "CPU type:" -msgstr "CPU type:" - -msgid "Speed:" -msgstr "Speed:" - -msgid "Frequency:" -msgstr "Frequency:" - -msgid "FPU:" -msgstr "FPU:" - -msgid "Wait states:" -msgstr "Wait states:" - -msgid "MB" -msgstr "MB" - -msgid "Memory:" -msgstr "Memory:" - -msgid "Time synchronization" -msgstr "Time synchronization" - -msgid "Disabled" -msgstr "Disabled" - -msgid "Enabled (local time)" -msgstr "Enabled (local time)" - -msgid "Enabled (UTC)" -msgstr "Enabled (UTC)" - -msgid "Dynamic Recompiler" -msgstr "Dynamic Recompiler" - -msgid "Video:" -msgstr "Video:" - -msgid "Voodoo Graphics" -msgstr "Voodoo Graphics" - -msgid "IBM 8514/A Graphics" -msgstr "IBM 8514/A Graphics" - -msgid "XGA Graphics" -msgstr "XGA Graphics" - -msgid "Mouse:" -msgstr "Mouse:" - -msgid "Joystick:" -msgstr "Joystick:" - -msgid "Joystick 1..." -msgstr "Joystick 1..." - -msgid "Joystick 2..." -msgstr "Joystick 2..." - -msgid "Joystick 3..." -msgstr "Joystick 3..." - -msgid "Joystick 4..." -msgstr "Joystick 4..." - -msgid "Sound card #1:" -msgstr "Sound card #1:" - -msgid "Sound card #2:" -msgstr "Sound card #2:" - -msgid "Sound card #3:" -msgstr "Sound card #3:" - -msgid "Sound card #4:" -msgstr "Sound card #4:" - -msgid "MIDI Out Device:" -msgstr "MIDI Out Device:" - -msgid "MIDI In Device:" -msgstr "MIDI In Device:" - -msgid "Standalone MPU-401" -msgstr "Standalone MPU-401" - -msgid "Use FLOAT32 sound" -msgstr "Use FLOAT32 sound" - -msgid "FM synth driver" -msgstr "FM synth driver" - -msgid "Nuked (more accurate)" -msgstr "Nuked (more accurate)" - -msgid "YMFM (faster)" -msgstr "YMFM (faster)" - -msgid "Network type:" -msgstr "Network type:" - -msgid "PCap device:" -msgstr "PCap device:" - -msgid "Network adapter:" -msgstr "Network adapter:" - -msgid "COM1 Device:" -msgstr "COM1 Device:" - -msgid "COM2 Device:" -msgstr "COM2 Device:" - -msgid "COM3 Device:" -msgstr "COM3 Device:" - -msgid "COM4 Device:" -msgstr "COM4 Device:" - -msgid "LPT1 Device:" -msgstr "LPT1 Device:" - -msgid "LPT2 Device:" -msgstr "LPT2 Device:" - -msgid "LPT3 Device:" -msgstr "LPT3 Device:" - -msgid "LPT4 Device:" -msgstr "LPT4 Device:" - -msgid "Serial port 1" -msgstr "Serial port 1" - -msgid "Serial port 2" -msgstr "Serial port 2" - -msgid "Serial port 3" -msgstr "Serial port 3" - -msgid "Serial port 4" -msgstr "Serial port 4" - -msgid "Parallel port 1" -msgstr "Parallel port 1" - -msgid "Parallel port 2" -msgstr "Parallel port 2" - -msgid "Parallel port 3" -msgstr "Parallel port 3" - -msgid "Parallel port 4" -msgstr "Parallel port 4" - -msgid "HD Controller:" -msgstr "HD Controller:" - -msgid "FD Controller:" -msgstr "FD Controller:" - -msgid "Tertiary IDE Controller" -msgstr "Tertiary IDE Controller" - -msgid "Quaternary IDE Controller" -msgstr "Quaternary IDE Controller" - -msgid "SCSI" -msgstr "SCSI" - -msgid "Controller 1:" -msgstr "Controller 1:" - -msgid "Controller 2:" -msgstr "Controller 2:" - -msgid "Controller 3:" -msgstr "Controller 3:" - -msgid "Controller 4:" -msgstr "Controller 4:" - -msgid "Cassette" -msgstr "Cassette" - -msgid "Hard disks:" -msgstr "Hard disks:" - -msgid "&New..." -msgstr "&New..." - -msgid "&Existing..." -msgstr "&Existing..." - -msgid "&Remove" -msgstr "&Remove" - -msgid "Bus:" -msgstr "Bus:" - -msgid "Channel:" -msgstr "Channel:" - -msgid "ID:" -msgstr "ID:" - -msgid "&Specify..." -msgstr "&Specify..." - -msgid "Sectors:" -msgstr "Sectors:" - -msgid "Heads:" -msgstr "Heads:" - -msgid "Cylinders:" -msgstr "Cylinders:" - -msgid "Size (MB):" -msgstr "Size (MB):" - -msgid "Type:" -msgstr "Type:" - -msgid "Image Format:" -msgstr "Image Format:" - -msgid "Block Size:" -msgstr "Block Size:" - -msgid "Floppy drives:" -msgstr "Floppy drives:" - -msgid "Turbo timings" -msgstr "Turbo timings" - -msgid "Check BPB" -msgstr "Check BPB" - -msgid "CD-ROM drives:" -msgstr "CD-ROM drives:" - -msgid "MO drives:" -msgstr "MO drives:" - -msgid "ZIP drives:" -msgstr "ZIP drives:" - -msgid "ZIP 250" -msgstr "ZIP 250" - -msgid "ISA RTC:" -msgstr "ISA RTC:" - -msgid "ISA Memory Expansion" -msgstr "ISA Memory Expansion" - -msgid "Card 1:" -msgstr "Card 1:" - -msgid "Card 2:" -msgstr "Card 2:" - -msgid "Card 3:" -msgstr "Card 3:" - -msgid "Card 4:" -msgstr "Card 4:" - -msgid "ISABugger device" -msgstr "ISABugger device" - -msgid "POST card" -msgstr "POST card" - -msgid "86Box" -msgstr "86Box" - -msgid "Error" -msgstr "Error" - -msgid "Fatal error" -msgstr "Fatal error" - -msgid " - PAUSED" -msgstr " - PAUSED" - -msgid "Press Ctrl+Alt+PgDn to return to windowed mode." -msgstr "Press Ctrl+Alt+PgDn to return to windowed mode." - -msgid "Speed" -msgstr "Speed" - -msgid "ZIP %03i %i (%s): %ls" -msgstr "ZIP %03i %i (%s): %ls" - -msgid "ZIP images" -msgstr "ZIP images" - -msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." -msgstr "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." - -msgid "(empty)" -msgstr "(empty)" - -msgid "All files" -msgstr "All files" - -msgid "Turbo" -msgstr "Turbo" - -msgid "On" -msgstr "On" - -msgid "Off" -msgstr "Off" - -msgid "All images" -msgstr "All images" - -msgid "Basic sector images" -msgstr "Basic sector images" - -msgid "Surface images" -msgstr "Surface images" - -msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." -msgstr "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." - -msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." -msgstr "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." - -msgid "Machine" -msgstr "Machine" - -msgid "Display" -msgstr "Display" - -msgid "Input devices" -msgstr "Input devices" - -msgid "Sound" -msgstr "Sound" - -msgid "Network" -msgstr "Network" - -msgid "Ports (COM & LPT)" -msgstr "Ports (COM & LPT)" - -msgid "Storage controllers" -msgstr "Storage controllers" - -msgid "Hard disks" -msgstr "Hard disks" - -msgid "Floppy & CD-ROM drives" -msgstr "Floppy & CD-ROM drives" - -msgid "Other removable devices" -msgstr "Other removable devices" - -msgid "Other peripherals" -msgstr "Other peripherals" - -msgid "Click to capture mouse" -msgstr "Click to capture mouse" - -msgid "Press %1 to release mouse" -msgstr "Press %1 to release mouse" - -msgid "Press %1 or middle button to release mouse" -msgstr "Press %1 or middle button to release mouse" - -msgid "Bus" -msgstr "Bus" - -msgid "File" -msgstr "File" - -msgid "C" -msgstr "C" - -msgid "H" -msgstr "H" - -msgid "S" -msgstr "S" - -msgid "KB" -msgstr "KB" - -msgid "Could not initialize the video renderer." -msgstr "Could not initialize the video renderer." - -msgid "Default" -msgstr "Default" - -msgid "%i Wait state(s)" -msgstr "%i Wait state(s)" - -msgid "Type" -msgstr "Type" - -msgid "No PCap devices found" -msgstr "No PCap devices found" - -msgid "Invalid PCap device" -msgstr "Invalid PCap device" - -msgid "Standard 2-button joystick(s)" -msgstr "Standard 2-button joystick(s)" - -msgid "Standard 4-button joystick" -msgstr "Standard 4-button joystick" - -msgid "Standard 6-button joystick" -msgstr "Standard 6-button joystick" - -msgid "Standard 8-button joystick" -msgstr "Standard 8-button joystick" - -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" - -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" - -msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control System" - -msgid "None" -msgstr "None" - -msgid "%u MB (CHS: %i, %i, %i)" -msgstr "%u MB (CHS: %i, %i, %i)" - -msgid "Floppy %i (%s): %ls" -msgstr "Floppy %i (%s): %ls" - -msgid "Advanced sector images" -msgstr "Advanced sector images" - -msgid "Flux images" -msgstr "Flux images" - -msgid "Are you sure you want to hard reset the emulated machine?" -msgstr "Are you sure you want to hard reset the emulated machine?" - -msgid "Are you sure you want to exit 86Box?" -msgstr "Are you sure you want to exit 86Box?" - -msgid "Unable to initialize Ghostscript" -msgstr "Unable to initialize Ghostscript" - -msgid "MO %i (%ls): %ls" -msgstr "MO %i (%ls): %ls" - -msgid "MO images" -msgstr "MO images" - -msgid "Welcome to 86Box!" -msgstr "Welcome to 86Box!" - -msgid "Internal controller" -msgstr "Internal controller" - -msgid "Exit" -msgstr "Exit" - -msgid "No ROMs found" -msgstr "No ROMs found" - -msgid "Do you want to save the settings?" -msgstr "Do you want to save the settings?" - -msgid "This will hard reset the emulated machine." -msgstr "This will hard reset the emulated machine." - -msgid "Save" -msgstr "Save" - -msgid "About 86Box" -msgstr "About 86Box" - -msgid "86Box v" -msgstr "86Box v" - -msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." - -msgid "Hardware not available" -msgstr "Hardware not available" - -msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." -msgstr "Make sure %1 is installed and that you are on a %1-compatible network connection." - -msgid "Invalid configuration" -msgstr "Invalid configuration" - -msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." - -msgid "Entering fullscreen mode" -msgstr "Entering fullscreen mode" - -msgid "Don't show this message again" -msgstr "Don't show this message again" - -msgid "Don't exit" -msgstr "Don't exit" - -msgid "Reset" -msgstr "Reset" - -msgid "Don't reset" -msgstr "Don't reset" - -msgid "CD-ROM images" -msgstr "CD-ROM images" - -msgid "%1 Device Configuration" -msgstr "%1 Device Configuration" - -msgid "Monitor in sleep mode" -msgstr "Monitor in sleep mode" - -msgid "OpenGL Shaders" -msgstr "OpenGL Shaders" - -msgid "OpenGL options" -msgstr "OpenGL options" - -msgid "You are loading an unsupported configuration" -msgstr "You are loading an unsupported configuration" - -msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." -msgstr "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." - -msgid "Continue" -msgstr "Continue" - -msgid "Cassette: %s" -msgstr "Cassette: %s" - -msgid "Cassette images" -msgstr "Cassette images" - -msgid "Cartridge %i: %ls" -msgstr "Cartridge %i: %ls" - -msgid "Cartridge images" -msgstr "Cartridge images" - -msgid "Error initializing renderer" -msgstr "Error initializing renderer" - -msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." - -msgid "Resume execution" -msgstr "Resume execution" - -msgid "Pause execution" -msgstr "Pause execution" - -msgid "Press Ctrl+Alt+Del" -msgstr "Press Ctrl+Alt+Del" - -msgid "Press Ctrl+Alt+Esc" -msgstr "Press Ctrl+Alt+Esc" - -msgid "Hard reset" -msgstr "Hard reset" - -msgid "ACPI shutdown" -msgstr "ACPI shutdown" - -msgid "Hard disk (%1)" -msgstr "Hard disk (%1)" - -msgid "MFM/RLL or ESDI CD-ROM drives never existed" -msgstr "MFM/RLL or ESDI CD-ROM drives never existed" - -msgid "Custom..." -msgstr "Custom..." - -msgid "Custom (large)..." -msgstr "Custom (large)..." - -msgid "Add New Hard Disk" -msgstr "Add New Hard Disk" - -msgid "Add Existing Hard Disk" -msgstr "Add Existing Hard Disk" - -msgid "HDI disk images cannot be larger than 4 GB." -msgstr "HDI disk images cannot be larger than 4 GB." - -msgid "Disk images cannot be larger than 127 GB." -msgstr "Disk images cannot be larger than 127 GB." - -msgid "Hard disk images" -msgstr "Hard disk images" - -msgid "Unable to read file" -msgstr "Unable to read file" - -msgid "Unable to write file" -msgstr "Unable to write file" - -msgid "HDI or HDX images with a sector size other than 512 are not supported." -msgstr "HDI or HDX images with a sector size other than 512 are not supported." - -msgid "Disk image file already exists" -msgstr "Disk image file already exists" - -msgid "Please specify a valid file name." -msgstr "Please specify a valid file name." - -msgid "Disk image created" -msgstr "Disk image created" - -msgid "Make sure the file exists and is readable." -msgstr "Make sure the file exists and is readable." - -msgid "Make sure the file is being saved to a writable directory." -msgstr "Make sure the file is being saved to a writable directory." - -msgid "Disk image too large" -msgstr "Disk image too large" - -msgid "Remember to partition and format the newly-created drive." -msgstr "Remember to partition and format the newly-created drive." - -msgid "The selected file will be overwritten. Are you sure you want to use it?" -msgstr "The selected file will be overwritten. Are you sure you want to use it?" - -msgid "Unsupported disk image" -msgstr "Unsupported disk image" - -msgid "Overwrite" -msgstr "Overwrite" - -msgid "Don't overwrite" -msgstr "Don't overwrite" - -msgid "Raw image (.img)" -msgstr "Raw image (.img)" - -msgid "HDI image (.hdi)" -msgstr "HDI image (.hdi)" - -msgid "HDX image (.hdx)" -msgstr "HDX image (.hdx)" - -msgid "Fixed-size VHD (.vhd)" -msgstr "Fixed-size VHD (.vhd)" - -msgid "Dynamic-size VHD (.vhd)" -msgstr "Dynamic-size VHD (.vhd)" - -msgid "Differencing VHD (.vhd)" -msgstr "Differencing VHD (.vhd)" - -msgid "Large blocks (2 MB)" -msgstr "Large blocks (2 MB)" - -msgid "Small blocks (512 KB)" -msgstr "Small blocks (512 KB)" - -msgid "VHD files" -msgstr "VHD files" - -msgid "Select the parent VHD" -msgstr "Select the parent VHD" - -msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" -msgstr "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" - -msgid "Parent and child disk timestamps do not match" -msgstr "Parent and child disk timestamps do not match" - -msgid "Could not fix VHD timestamp." -msgstr "Could not fix VHD timestamp." - -msgid "MFM/RLL" -msgstr "MFM/RLL" - -msgid "XTA" -msgstr "XTA" - -msgid "ESDI" -msgstr "ESDI" - -msgid "IDE" -msgstr "IDE" - -msgid "ATAPI" -msgstr "ATAPI" - -msgid "CD-ROM %i (%s): %s" -msgstr "CD-ROM %i (%s): %s" - -msgid "160 kB" -msgstr "160 kB" - -msgid "180 kB" -msgstr "180 kB" - -msgid "320 kB" -msgstr "320 kB" - -msgid "360 kB" -msgstr "360 kB" - -msgid "640 kB" -msgstr "640 kB" - -msgid "720 kB" -msgstr "720 kB" - -msgid "1.2 MB" -msgstr "1.2 MB" - -msgid "1.25 MB" -msgstr "1.25 MB" - -msgid "1.44 MB" -msgstr "1.44 MB" - -msgid "DMF (cluster 1024)" -msgstr "DMF (cluster 1024)" - -msgid "DMF (cluster 2048)" -msgstr "DMF (cluster 2048)" - -msgid "2.88 MB" -msgstr "2.88 MB" - -msgid "ZIP 100" -msgstr "ZIP 100" - -msgid "3.5\" 128 MB (ISO 10090)" -msgstr "3.5\" 128 MB (ISO 10090)" - -msgid "3.5\" 230 MB (ISO 13963)" -msgstr "3.5\" 230 MB (ISO 13963)" - -msgid "3.5\" 540 MB (ISO 15498)" -msgstr "3.5\" 540 MB (ISO 15498)" - -msgid "3.5\" 640 MB (ISO 15498)" -msgstr "3.5\" 640 MB (ISO 15498)" - -msgid "3.5\" 1.3 GB (GigaMO)" -msgstr "3.5\" 1.3 GB (GigaMO)" - -msgid "3.5\" 2.3 GB (GigaMO 2)" -msgstr "3.5\" 2.3 GB (GigaMO 2)" - -msgid "5.25\" 600 MB" -msgstr "5.25\" 600 MB" - -msgid "5.25\" 650 MB" -msgstr "5.25\" 650 MB" - -msgid "5.25\" 1 GB" -msgstr "5.25\" 1 GB" - -msgid "5.25\" 1.3 GB" -msgstr "5.25\" 1.3 GB" - -msgid "Perfect RPM" -msgstr "Perfect RPM" - -msgid "1% below perfect RPM" -msgstr "1% below perfect RPM" - -msgid "1.5% below perfect RPM" -msgstr "1.5% below perfect RPM" - -msgid "2% below perfect RPM" -msgstr "2% below perfect RPM" - -msgid "(System Default)" -msgstr "(System Default)" - -msgid "Failed to initialize network driver" -msgstr "Failed to initialize network driver" - -msgid "The network configuration will be switched to the null driver" -msgstr "The network configuration will be switched to the null driver" - -msgid "Mouse sensitivity:" -msgstr "Mouse sensitivity:" - -msgid "Select media images from program working directory" -msgstr "Select media images from program working directory" - -msgid "PIT mode:" -msgstr "PIT mode:" - -msgid "Auto" -msgstr "Auto" - -msgid "Slow" -msgstr "Slow" - -msgid "Fast" -msgstr "Fast" - -msgid "&Auto-pause on focus loss" -msgstr "&Auto-pause on focus loss" - -msgid "WinBox is no longer supported" -msgstr "WinBox is no longer supported" - -msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." -msgstr "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." From 9354c6a6eff5e6f323f9c91a45a78dc8a80fe45f Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 20 Mar 2024 20:41:31 +0500 Subject: [PATCH 703/936] Qt: Fix CD-ROM menu not updating after ejecting a CD from the guest --- src/qt/CMakeLists.txt | 1 - src/qt/qt_cdrom.c | 54 ----------------------------------------- src/qt/qt_mediamenu.cpp | 23 ++++++++++++++++++ src/qt/qt_mediamenu.hpp | 1 + 4 files changed, 24 insertions(+), 55 deletions(-) delete mode 100644 src/qt/qt_cdrom.c diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index e189ec569..422989a44 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -61,7 +61,6 @@ add_library(plat STATIC add_library(ui STATIC qt_ui.cpp - qt_cdrom.c qt_mainwindow.cpp qt_mainwindow.hpp diff --git a/src/qt/qt_cdrom.c b/src/qt/qt_cdrom.c deleted file mode 100644 index 1facae486..000000000 --- a/src/qt/qt_cdrom.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Handle the platform-side of CDROM/ZIP/MO drives. - * - * - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017-2018 Fred N. van Kempen. - */ - -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/config.h> -#include <86box/timer.h> -#include <86box/device.h> -#include <86box/cassette.h> -#include <86box/cartridge.h> -#include <86box/fdd.h> -#include <86box/hdd.h> -#include <86box/scsi_device.h> -#include <86box/cdrom.h> -#include <86box/mo.h> -#include <86box/zip.h> -#include <86box/scsi_disk.h> -#include <86box/plat.h> -#include <86box/ui.h> - -void -plat_cdrom_ui_update(uint8_t id, uint8_t reload) -{ - cdrom_t *drv = &cdrom[id]; - - if (drv->host_drive == 0) { - ui_sb_update_icon_state(SB_CDROM | id, 1); - } else { - ui_sb_update_icon_state(SB_CDROM | id, 0); - } - - // media_menu_update_cdrom(id); - ui_sb_update_tip(SB_CDROM | id); -} diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index 541e31190..2365fb728 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -521,6 +521,23 @@ MediaMenu::cdromReload(int index, int slot) ui_sb_update_tip(SB_CDROM | index); } +void +MediaMenu::cdromUpdateUi(int i) +{ + cdrom_t *drv = &cdrom[i]; + + if (drv->host_drive == 0) { + mhm.addImageToHistory(i, ui::MediaType::Optical, drv->prev_image_path, QString()); + ui_sb_update_icon_state(SB_CDROM | i, 1); + } else { + mhm.addImageToHistory(i, ui::MediaType::Optical, drv->prev_image_path, drv->image_path); + ui_sb_update_icon_state(SB_CDROM | i, 0); + } + + cdromUpdateMenu(i); + ui_sb_update_tip(SB_CDROM | i); +} + void MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) { @@ -892,6 +909,12 @@ MediaMenu::getMediaOpenDirectory() // callbacks from 86box C code extern "C" { +void +plat_cdrom_ui_update(uint8_t id, uint8_t reload) +{ + MediaMenu::ptr->cdromUpdateUi(id); +} + void zip_eject(uint8_t id) { diff --git a/src/qt/qt_mediamenu.hpp b/src/qt/qt_mediamenu.hpp index 57fd8dfc2..03d046847 100644 --- a/src/qt/qt_mediamenu.hpp +++ b/src/qt/qt_mediamenu.hpp @@ -45,6 +45,7 @@ public: void cdromMount(int i, const QString &filename); void cdromEject(int i); void cdromReload(int index, int slot); + void cdromUpdateUi(int i); void updateImageHistory(int index, int slot, ui::MediaType type); void clearImageHistory(); void cdromUpdateMenu(int i); From 4052ae2e32dad231fdcd6e806c155d5c222df901 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 20 Mar 2024 21:25:14 +0500 Subject: [PATCH 704/936] Use a signal instead --- src/qt/qt_mediamenu.cpp | 3 ++- src/qt/qt_mediamenu.hpp | 9 +++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index 2365fb728..7f7d120b8 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -61,6 +61,7 @@ MediaMenu::MediaMenu(QWidget *parent) : QObject(parent) { parentWidget = parent; + connect(this, &MediaMenu::onCdromUpdateUi, this, &MediaMenu::cdromUpdateUi, Qt::QueuedConnection); } void @@ -912,7 +913,7 @@ extern "C" { void plat_cdrom_ui_update(uint8_t id, uint8_t reload) { - MediaMenu::ptr->cdromUpdateUi(id); + emit MediaMenu::ptr->onCdromUpdateUi(id); } void diff --git a/src/qt/qt_mediamenu.hpp b/src/qt/qt_mediamenu.hpp index 03d046847..7835077b3 100644 --- a/src/qt/qt_mediamenu.hpp +++ b/src/qt/qt_mediamenu.hpp @@ -10,7 +10,7 @@ extern "C" { } class QMenu; -class MediaMenu : QObject { +class MediaMenu : public QObject { Q_OBJECT public: MediaMenu(QWidget *parent); @@ -45,7 +45,6 @@ public: void cdromMount(int i, const QString &filename); void cdromEject(int i); void cdromReload(int index, int slot); - void cdromUpdateUi(int i); void updateImageHistory(int index, int slot, ui::MediaType type); void clearImageHistory(); void cdromUpdateMenu(int i); @@ -68,6 +67,12 @@ public: void nicDisconnect(int i); void nicUpdateMenu(int i); +public slots: + void cdromUpdateUi(int i); + +signals: + void onCdromUpdateUi(int i); + private: QWidget *parentWidget = nullptr; From df231b0d873d6fd9fab83d0e7b869f65e46e409b Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 20 Mar 2024 22:26:10 +0500 Subject: [PATCH 705/936] Implement the rest of _eject/_mount functions Implement the rest of media eject/mount functions declared in plat.h, intended for future use --- src/qt/qt_mediamenu.cpp | 53 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index 7f7d120b8..af6d40e79 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -909,6 +909,47 @@ MediaMenu::getMediaOpenDirectory() // callbacks from 86box C code extern "C" { +void +cassette_mount(char *fn, uint8_t wp) +{ + MediaMenu::ptr->cassetteMount(QString(fn), wp); +} + +void +cassette_eject(void) +{ + MediaMenu::ptr->cassetteEject(); +} + +void +cartridge_mount(uint8_t id, char *fn, uint8_t wp) +{ + MediaMenu::ptr->cartridgeMount(id, QString(fn)); +} + +void +cartridge_eject(uint8_t id) +{ + MediaMenu::ptr->cartridgeEject(id); +} + +void +floppy_mount(uint8_t id, char *fn, uint8_t wp) +{ + MediaMenu::ptr->floppyMount(id, QString(fn), wp); +} + +void +floppy_eject(uint8_t id) +{ + MediaMenu::ptr->floppyEject(id); +} + +void +cdrom_mount(uint8_t id, char *fn) +{ + MediaMenu::ptr->cdromMount(id, QString(fn)); +} void plat_cdrom_ui_update(uint8_t id, uint8_t reload) @@ -922,6 +963,12 @@ zip_eject(uint8_t id) MediaMenu::ptr->zipEject(id); } +void +zip_mount(uint8_t id, char *fn, uint8_t wp) +{ + MediaMenu::ptr->zipMount(id, QString(fn), wp); +} + void zip_reload(uint8_t id) { @@ -934,6 +981,12 @@ mo_eject(uint8_t id) MediaMenu::ptr->moEject(id); } +void +mo_mount(uint8_t id, char *fn, uint8_t wp) +{ + MediaMenu::ptr->moMount(id, QString(fn), wp); +} + void mo_reload(uint8_t id) { From 53fbe7343e7795507891345d2bf531b11067ccb3 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 20 Mar 2024 22:30:11 +0500 Subject: [PATCH 706/936] Check for pcap DLL in Npcap's installation directory on Windows --- src/network/net_pcap.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index e1747580b..16caaec7e 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -365,7 +365,13 @@ net_pcap_prepare(netdev_t *list) /* Try loading the DLL. */ #ifdef _WIN32 + /* Add the Npcap directory to the DLL search path. */ + char npcap_dir[512]; + GetSystemDirectoryA(npcap_dir, 480); + strcat(npcap_dir, "\\Npcap"); + SetDllDirectoryA(npcap_dir); libpcap_handle = dynld_module("wpcap.dll", pcap_imports); + SetDllDirectoryA(NULL); /* reset the DLL search path */ #elif defined __APPLE__ libpcap_handle = dynld_module("libpcap.dylib", pcap_imports); #else From 0660f08a40732c34ef299cc8f48d25a348417553 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 20 Mar 2024 22:21:31 +0100 Subject: [PATCH 707/936] PB450 fixes. --- src/machine/m_at_386dx_486.c | 25 +++++++++++++------------ src/machine/machine_table.c | 2 +- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 4cfa7447e..9e527e8c3 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -671,25 +671,26 @@ machine_at_pb450_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); + device_add(&ide_vlb_2ch_device); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x11, PCI_CARD_NORMAL, 5, 4, 3, 2); - pci_register_slot(0x12, PCI_CARD_NORMAL, 9, 8, 7, 6); - - device_add(&opti895_device); - device_add(&opti822_device); - device_add(&keyboard_ps2_intel_ami_pci_device); - device_add(&fdc37c661_ide_device); - device_add(&ide_opti611_vlb_sec_device); - device_add(&ide_vlb_2ch_device); - device_add(&intel_flash_bxt_device); - device_add(&phoenix_486_jumper_pci_device); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 5, 6, 7, 8); if (gfxcard[0] == VID_INTERNAL) device_add(&gd5428_vlb_onboard_device); + device_add(&opti602_device); + device_add(&opti895_device); + device_add(&opti822_device); + device_add(&keyboard_ps2_ami_device); + device_add(&fdc37c661_ide_device); + device_add(&ide_opti611_vlb_sec_device); + device_add(&intel_flash_bxt_device); + device_add(&phoenix_486_jumper_pci_device); + return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 04cc59043..9a7161c7f 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -6438,7 +6438,7 @@ const machine_t machines[] = { .max = 65536, .step = 1024 }, - .nvrmask = 127, + .nvrmask = 255, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, From 3e27bdb86ac9404870abfd577d357119aaa02c98 Mon Sep 17 00:00:00 2001 From: maximus105 <58270614+maximus105@users.noreply.github.com> Date: Wed, 20 Mar 2024 23:35:03 +0200 Subject: [PATCH 708/936] Fix broken translation for ZIP drives --- src/qt/qt_settingsotherremovable.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_settingsotherremovable.cpp b/src/qt/qt_settingsotherremovable.cpp index f8b29dac5..36918ad99 100644 --- a/src/qt/qt_settingsotherremovable.cpp +++ b/src/qt/qt_settingsotherremovable.cpp @@ -140,8 +140,8 @@ SettingsOtherRemovable::SettingsOtherRemovable(QWidget *parent) model = new QStandardItemModel(0, 2, this); ui->tableViewZIP->setModel(model); - model->setHeaderData(0, Qt::Horizontal, "Bus"); - model->setHeaderData(1, Qt::Horizontal, "Type"); + model->setHeaderData(0, Qt::Horizontal, tr("Bus")); + model->setHeaderData(1, Qt::Horizontal, tr("Type")); model->insertRows(0, ZIP_NUM); for (int i = 0; i < ZIP_NUM; i++) { auto idx = model->index(i, 0); From 53503cb843e83cc2e5edaa0f24c43ab1065ecadd Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 21 Mar 2024 00:47:17 +0100 Subject: [PATCH 709/936] ALi M1217: No on-chip IDE controller. --- src/chipset/ali6117.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/chipset/ali6117.c b/src/chipset/ali6117.c index c7ada4bc6..cc2e465a2 100644 --- a/src/chipset/ali6117.c +++ b/src/chipset/ali6117.c @@ -471,7 +471,8 @@ ali6117_init(const device_t *info) dev->local = info->local; - device_add(&ide_isa_device); + if (!(dev->local & 0x08)) + device_add(&ide_isa_device); ali6117_setup(dev); From 2fd511cc585568a5eb02daf16ee980db93e67dec Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 29 Feb 2024 21:31:16 +0600 Subject: [PATCH 710/936] Add ESFMu for ESFM emulation --- src/cpu/cpu.h | 7 + src/sound/CMakeLists.txt | 2 +- src/sound/esfmu/esfm.c | 2316 ++++++++++++++++++++++++++++++ src/sound/esfmu/esfm.h | 289 ++++ src/sound/esfmu/esfm_registers.c | 999 +++++++++++++ src/sound/snd_opl_esfm.c | 223 +++ 6 files changed, 3835 insertions(+), 1 deletion(-) create mode 100644 src/sound/esfmu/esfm.c create mode 100644 src/sound/esfmu/esfm.h create mode 100644 src/sound/esfmu/esfm_registers.c create mode 100644 src/sound/snd_opl_esfm.c diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 16a9eba10..f2e1242df 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -21,7 +21,14 @@ #ifndef EMU_CPU_H #define EMU_CPU_H +#ifndef NO_SOFTFLOAT_INCLUDE #include "softfloat/softfloat.h" +#else +typedef struct floatx80 { // leave alignment to compiler + uint64_t exp; + uint16_t fraction; +} floatx80; +#endif enum { FPU_NONE, diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index 72f05ff6d..9b2cc1416 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -18,7 +18,7 @@ add_library(snd OBJECT sound.c snd_opl.c snd_opl_nuked.c snd_opl_ymfm.cpp snd_re snd_lpt_dss.c snd_ps1.c snd_adlib.c snd_adlibgold.c snd_ad1848.c snd_audiopci.c snd_azt2316a.c snd_cms.c snd_cmi8x38.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c snd_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c - snd_optimc.c) + snd_optimc.c esfmu/esfm.c esfmu/esfm_registers.c snd_opl_esfm.c) if(OPENAL) if(VCPKG_TOOLCHAIN) diff --git a/src/sound/esfmu/esfm.c b/src/sound/esfmu/esfm.c new file mode 100644 index 000000000..7409603fe --- /dev/null +++ b/src/sound/esfmu/esfm.c @@ -0,0 +1,2316 @@ +/* + * ESFMu: emulator for the ESS "ESFM" enhanced OPL3 clone + * Copyright (C) 2023 Kagamiin~ + * + * This file includes code and data from the Nuked OPL3 project, copyright (C) + * 2013-2023 Nuke.YKT. Its usage, modification and redistribution is allowed + * under the terms of the GNU Lesser General Public License version 2.1 or + * later. + * + * ESFMu is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 2.1 + * of the License, or (at your option) any later version. + * + * ESFMu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ESFMu. If not, see . + */ + +/* + * ESFMu wouldn't have been possible without the hard work and dedication of + * the retro computer hardware research and preservation community. + * + * I'd like to thank: + * - Nuke.YKT + * Developer of Nuked OPL3, which was the basis for ESFMu's code and + * also a great learning resource on Yamaha FM synthesis for myself. + * Nuke.YKT also gives shoutouts on behalf of Nuked OPL3 to: + * - MAME Development Team(Jarek Burczynski, Tatsuyuki Satoh): + * Feedback and Rhythm part calculation information. + * - forums.submarine.org.uk(carbon14, opl3): + * Tremolo and phase generator calculation information. + * - OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): + * OPL2 ROMs. + * - siliconpr0n.org(John McMaster, digshadow): + * YMF262 and VRC VII decaps and die shots. + * - rainwarrior + * For performing the initial research on ESFM drivers and documenting + * ESS's patent on native mode operator organization. + * - jwt27 + * For kickstarting the ESFM research project and compiling rainwarrior's + * findings and more in an accessible document ("ESFM Demystified"). + * - pachuco/CatButts + * For documenting ESS's patent on ESFM's feedback implementation, which + * was vital in getting ESFMu's sound output to be accurate. + * - akumanatt + * For helping out with code optimization. + * - And everybody who helped out with real hardware testing + */ + +#include "esfm.h" +#include +#include +#include +#include +#include + +/* + * Log-scale quarter sine table extracted from OPL3 ROM; taken straight from + * Nuked OPL3 source code. + * TODO: Extract sine table from ESFM die scans... does ESFM even use a sine + * table? Patent documents give a hint to a possible method of generating sine + * waves using some sort of boolean logic wizardry (lol) + * Optimization: All 8 waveforms are calculated and unfolded from the actual + * data in OPL3's ROM. Negative entries are marked by 0x8000. + */ +static const uint16_t logsinrom[1024*8] = { + // wave 0 + 0x0859, 0x06c3, 0x0607, 0x058b, 0x052e, 0x04e4, 0x04a6, 0x0471, + 0x0443, 0x041a, 0x03f5, 0x03d3, 0x03b5, 0x0398, 0x037e, 0x0365, + 0x034e, 0x0339, 0x0324, 0x0311, 0x02ff, 0x02ed, 0x02dc, 0x02cd, + 0x02bd, 0x02af, 0x02a0, 0x0293, 0x0286, 0x0279, 0x026d, 0x0261, + 0x0256, 0x024b, 0x0240, 0x0236, 0x022c, 0x0222, 0x0218, 0x020f, + 0x0206, 0x01fd, 0x01f5, 0x01ec, 0x01e4, 0x01dc, 0x01d4, 0x01cd, + 0x01c5, 0x01be, 0x01b7, 0x01b0, 0x01a9, 0x01a2, 0x019b, 0x0195, + 0x018f, 0x0188, 0x0182, 0x017c, 0x0177, 0x0171, 0x016b, 0x0166, + 0x0160, 0x015b, 0x0155, 0x0150, 0x014b, 0x0146, 0x0141, 0x013c, + 0x0137, 0x0133, 0x012e, 0x0129, 0x0125, 0x0121, 0x011c, 0x0118, + 0x0114, 0x010f, 0x010b, 0x0107, 0x0103, 0x00ff, 0x00fb, 0x00f8, + 0x00f4, 0x00f0, 0x00ec, 0x00e9, 0x00e5, 0x00e2, 0x00de, 0x00db, + 0x00d7, 0x00d4, 0x00d1, 0x00cd, 0x00ca, 0x00c7, 0x00c4, 0x00c1, + 0x00be, 0x00bb, 0x00b8, 0x00b5, 0x00b2, 0x00af, 0x00ac, 0x00a9, + 0x00a7, 0x00a4, 0x00a1, 0x009f, 0x009c, 0x0099, 0x0097, 0x0094, + 0x0092, 0x008f, 0x008d, 0x008a, 0x0088, 0x0086, 0x0083, 0x0081, + 0x007f, 0x007d, 0x007a, 0x0078, 0x0076, 0x0074, 0x0072, 0x0070, + 0x006e, 0x006c, 0x006a, 0x0068, 0x0066, 0x0064, 0x0062, 0x0060, + 0x005e, 0x005c, 0x005b, 0x0059, 0x0057, 0x0055, 0x0053, 0x0052, + 0x0050, 0x004e, 0x004d, 0x004b, 0x004a, 0x0048, 0x0046, 0x0045, + 0x0043, 0x0042, 0x0040, 0x003f, 0x003e, 0x003c, 0x003b, 0x0039, + 0x0038, 0x0037, 0x0035, 0x0034, 0x0033, 0x0031, 0x0030, 0x002f, + 0x002e, 0x002d, 0x002b, 0x002a, 0x0029, 0x0028, 0x0027, 0x0026, + 0x0025, 0x0024, 0x0023, 0x0022, 0x0021, 0x0020, 0x001f, 0x001e, + 0x001d, 0x001c, 0x001b, 0x001a, 0x0019, 0x0018, 0x0017, 0x0017, + 0x0016, 0x0015, 0x0014, 0x0014, 0x0013, 0x0012, 0x0011, 0x0011, + 0x0010, 0x000f, 0x000f, 0x000e, 0x000d, 0x000d, 0x000c, 0x000c, + 0x000b, 0x000a, 0x000a, 0x0009, 0x0009, 0x0008, 0x0008, 0x0007, + 0x0007, 0x0007, 0x0006, 0x0006, 0x0005, 0x0005, 0x0005, 0x0004, + 0x0004, 0x0004, 0x0003, 0x0003, 0x0003, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0003, 0x0003, 0x0003, 0x0004, 0x0004, + 0x0004, 0x0005, 0x0005, 0x0005, 0x0006, 0x0006, 0x0007, 0x0007, + 0x0007, 0x0008, 0x0008, 0x0009, 0x0009, 0x000a, 0x000a, 0x000b, + 0x000c, 0x000c, 0x000d, 0x000d, 0x000e, 0x000f, 0x000f, 0x0010, + 0x0011, 0x0011, 0x0012, 0x0013, 0x0014, 0x0014, 0x0015, 0x0016, + 0x0017, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, + 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, + 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002d, 0x002e, + 0x002f, 0x0030, 0x0031, 0x0033, 0x0034, 0x0035, 0x0037, 0x0038, + 0x0039, 0x003b, 0x003c, 0x003e, 0x003f, 0x0040, 0x0042, 0x0043, + 0x0045, 0x0046, 0x0048, 0x004a, 0x004b, 0x004d, 0x004e, 0x0050, + 0x0052, 0x0053, 0x0055, 0x0057, 0x0059, 0x005b, 0x005c, 0x005e, + 0x0060, 0x0062, 0x0064, 0x0066, 0x0068, 0x006a, 0x006c, 0x006e, + 0x0070, 0x0072, 0x0074, 0x0076, 0x0078, 0x007a, 0x007d, 0x007f, + 0x0081, 0x0083, 0x0086, 0x0088, 0x008a, 0x008d, 0x008f, 0x0092, + 0x0094, 0x0097, 0x0099, 0x009c, 0x009f, 0x00a1, 0x00a4, 0x00a7, + 0x00a9, 0x00ac, 0x00af, 0x00b2, 0x00b5, 0x00b8, 0x00bb, 0x00be, + 0x00c1, 0x00c4, 0x00c7, 0x00ca, 0x00cd, 0x00d1, 0x00d4, 0x00d7, + 0x00db, 0x00de, 0x00e2, 0x00e5, 0x00e9, 0x00ec, 0x00f0, 0x00f4, + 0x00f8, 0x00fb, 0x00ff, 0x0103, 0x0107, 0x010b, 0x010f, 0x0114, + 0x0118, 0x011c, 0x0121, 0x0125, 0x0129, 0x012e, 0x0133, 0x0137, + 0x013c, 0x0141, 0x0146, 0x014b, 0x0150, 0x0155, 0x015b, 0x0160, + 0x0166, 0x016b, 0x0171, 0x0177, 0x017c, 0x0182, 0x0188, 0x018f, + 0x0195, 0x019b, 0x01a2, 0x01a9, 0x01b0, 0x01b7, 0x01be, 0x01c5, + 0x01cd, 0x01d4, 0x01dc, 0x01e4, 0x01ec, 0x01f5, 0x01fd, 0x0206, + 0x020f, 0x0218, 0x0222, 0x022c, 0x0236, 0x0240, 0x024b, 0x0256, + 0x0261, 0x026d, 0x0279, 0x0286, 0x0293, 0x02a0, 0x02af, 0x02bd, + 0x02cd, 0x02dc, 0x02ed, 0x02ff, 0x0311, 0x0324, 0x0339, 0x034e, + 0x0365, 0x037e, 0x0398, 0x03b5, 0x03d3, 0x03f5, 0x041a, 0x0443, + 0x0471, 0x04a6, 0x04e4, 0x052e, 0x058b, 0x0607, 0x06c3, 0x0859, + 0x8859, 0x86c3, 0x8607, 0x858b, 0x852e, 0x84e4, 0x84a6, 0x8471, + 0x8443, 0x841a, 0x83f5, 0x83d3, 0x83b5, 0x8398, 0x837e, 0x8365, + 0x834e, 0x8339, 0x8324, 0x8311, 0x82ff, 0x82ed, 0x82dc, 0x82cd, + 0x82bd, 0x82af, 0x82a0, 0x8293, 0x8286, 0x8279, 0x826d, 0x8261, + 0x8256, 0x824b, 0x8240, 0x8236, 0x822c, 0x8222, 0x8218, 0x820f, + 0x8206, 0x81fd, 0x81f5, 0x81ec, 0x81e4, 0x81dc, 0x81d4, 0x81cd, + 0x81c5, 0x81be, 0x81b7, 0x81b0, 0x81a9, 0x81a2, 0x819b, 0x8195, + 0x818f, 0x8188, 0x8182, 0x817c, 0x8177, 0x8171, 0x816b, 0x8166, + 0x8160, 0x815b, 0x8155, 0x8150, 0x814b, 0x8146, 0x8141, 0x813c, + 0x8137, 0x8133, 0x812e, 0x8129, 0x8125, 0x8121, 0x811c, 0x8118, + 0x8114, 0x810f, 0x810b, 0x8107, 0x8103, 0x80ff, 0x80fb, 0x80f8, + 0x80f4, 0x80f0, 0x80ec, 0x80e9, 0x80e5, 0x80e2, 0x80de, 0x80db, + 0x80d7, 0x80d4, 0x80d1, 0x80cd, 0x80ca, 0x80c7, 0x80c4, 0x80c1, + 0x80be, 0x80bb, 0x80b8, 0x80b5, 0x80b2, 0x80af, 0x80ac, 0x80a9, + 0x80a7, 0x80a4, 0x80a1, 0x809f, 0x809c, 0x8099, 0x8097, 0x8094, + 0x8092, 0x808f, 0x808d, 0x808a, 0x8088, 0x8086, 0x8083, 0x8081, + 0x807f, 0x807d, 0x807a, 0x8078, 0x8076, 0x8074, 0x8072, 0x8070, + 0x806e, 0x806c, 0x806a, 0x8068, 0x8066, 0x8064, 0x8062, 0x8060, + 0x805e, 0x805c, 0x805b, 0x8059, 0x8057, 0x8055, 0x8053, 0x8052, + 0x8050, 0x804e, 0x804d, 0x804b, 0x804a, 0x8048, 0x8046, 0x8045, + 0x8043, 0x8042, 0x8040, 0x803f, 0x803e, 0x803c, 0x803b, 0x8039, + 0x8038, 0x8037, 0x8035, 0x8034, 0x8033, 0x8031, 0x8030, 0x802f, + 0x802e, 0x802d, 0x802b, 0x802a, 0x8029, 0x8028, 0x8027, 0x8026, + 0x8025, 0x8024, 0x8023, 0x8022, 0x8021, 0x8020, 0x801f, 0x801e, + 0x801d, 0x801c, 0x801b, 0x801a, 0x8019, 0x8018, 0x8017, 0x8017, + 0x8016, 0x8015, 0x8014, 0x8014, 0x8013, 0x8012, 0x8011, 0x8011, + 0x8010, 0x800f, 0x800f, 0x800e, 0x800d, 0x800d, 0x800c, 0x800c, + 0x800b, 0x800a, 0x800a, 0x8009, 0x8009, 0x8008, 0x8008, 0x8007, + 0x8007, 0x8007, 0x8006, 0x8006, 0x8005, 0x8005, 0x8005, 0x8004, + 0x8004, 0x8004, 0x8003, 0x8003, 0x8003, 0x8002, 0x8002, 0x8002, + 0x8002, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8002, + 0x8002, 0x8002, 0x8002, 0x8003, 0x8003, 0x8003, 0x8004, 0x8004, + 0x8004, 0x8005, 0x8005, 0x8005, 0x8006, 0x8006, 0x8007, 0x8007, + 0x8007, 0x8008, 0x8008, 0x8009, 0x8009, 0x800a, 0x800a, 0x800b, + 0x800c, 0x800c, 0x800d, 0x800d, 0x800e, 0x800f, 0x800f, 0x8010, + 0x8011, 0x8011, 0x8012, 0x8013, 0x8014, 0x8014, 0x8015, 0x8016, + 0x8017, 0x8017, 0x8018, 0x8019, 0x801a, 0x801b, 0x801c, 0x801d, + 0x801e, 0x801f, 0x8020, 0x8021, 0x8022, 0x8023, 0x8024, 0x8025, + 0x8026, 0x8027, 0x8028, 0x8029, 0x802a, 0x802b, 0x802d, 0x802e, + 0x802f, 0x8030, 0x8031, 0x8033, 0x8034, 0x8035, 0x8037, 0x8038, + 0x8039, 0x803b, 0x803c, 0x803e, 0x803f, 0x8040, 0x8042, 0x8043, + 0x8045, 0x8046, 0x8048, 0x804a, 0x804b, 0x804d, 0x804e, 0x8050, + 0x8052, 0x8053, 0x8055, 0x8057, 0x8059, 0x805b, 0x805c, 0x805e, + 0x8060, 0x8062, 0x8064, 0x8066, 0x8068, 0x806a, 0x806c, 0x806e, + 0x8070, 0x8072, 0x8074, 0x8076, 0x8078, 0x807a, 0x807d, 0x807f, + 0x8081, 0x8083, 0x8086, 0x8088, 0x808a, 0x808d, 0x808f, 0x8092, + 0x8094, 0x8097, 0x8099, 0x809c, 0x809f, 0x80a1, 0x80a4, 0x80a7, + 0x80a9, 0x80ac, 0x80af, 0x80b2, 0x80b5, 0x80b8, 0x80bb, 0x80be, + 0x80c1, 0x80c4, 0x80c7, 0x80ca, 0x80cd, 0x80d1, 0x80d4, 0x80d7, + 0x80db, 0x80de, 0x80e2, 0x80e5, 0x80e9, 0x80ec, 0x80f0, 0x80f4, + 0x80f8, 0x80fb, 0x80ff, 0x8103, 0x8107, 0x810b, 0x810f, 0x8114, + 0x8118, 0x811c, 0x8121, 0x8125, 0x8129, 0x812e, 0x8133, 0x8137, + 0x813c, 0x8141, 0x8146, 0x814b, 0x8150, 0x8155, 0x815b, 0x8160, + 0x8166, 0x816b, 0x8171, 0x8177, 0x817c, 0x8182, 0x8188, 0x818f, + 0x8195, 0x819b, 0x81a2, 0x81a9, 0x81b0, 0x81b7, 0x81be, 0x81c5, + 0x81cd, 0x81d4, 0x81dc, 0x81e4, 0x81ec, 0x81f5, 0x81fd, 0x8206, + 0x820f, 0x8218, 0x8222, 0x822c, 0x8236, 0x8240, 0x824b, 0x8256, + 0x8261, 0x826d, 0x8279, 0x8286, 0x8293, 0x82a0, 0x82af, 0x82bd, + 0x82cd, 0x82dc, 0x82ed, 0x82ff, 0x8311, 0x8324, 0x8339, 0x834e, + 0x8365, 0x837e, 0x8398, 0x83b5, 0x83d3, 0x83f5, 0x841a, 0x8443, + 0x8471, 0x84a6, 0x84e4, 0x852e, 0x858b, 0x8607, 0x86c3, 0x8859, + // wave 1 + 0x0859, 0x06c3, 0x0607, 0x058b, 0x052e, 0x04e4, 0x04a6, 0x0471, + 0x0443, 0x041a, 0x03f5, 0x03d3, 0x03b5, 0x0398, 0x037e, 0x0365, + 0x034e, 0x0339, 0x0324, 0x0311, 0x02ff, 0x02ed, 0x02dc, 0x02cd, + 0x02bd, 0x02af, 0x02a0, 0x0293, 0x0286, 0x0279, 0x026d, 0x0261, + 0x0256, 0x024b, 0x0240, 0x0236, 0x022c, 0x0222, 0x0218, 0x020f, + 0x0206, 0x01fd, 0x01f5, 0x01ec, 0x01e4, 0x01dc, 0x01d4, 0x01cd, + 0x01c5, 0x01be, 0x01b7, 0x01b0, 0x01a9, 0x01a2, 0x019b, 0x0195, + 0x018f, 0x0188, 0x0182, 0x017c, 0x0177, 0x0171, 0x016b, 0x0166, + 0x0160, 0x015b, 0x0155, 0x0150, 0x014b, 0x0146, 0x0141, 0x013c, + 0x0137, 0x0133, 0x012e, 0x0129, 0x0125, 0x0121, 0x011c, 0x0118, + 0x0114, 0x010f, 0x010b, 0x0107, 0x0103, 0x00ff, 0x00fb, 0x00f8, + 0x00f4, 0x00f0, 0x00ec, 0x00e9, 0x00e5, 0x00e2, 0x00de, 0x00db, + 0x00d7, 0x00d4, 0x00d1, 0x00cd, 0x00ca, 0x00c7, 0x00c4, 0x00c1, + 0x00be, 0x00bb, 0x00b8, 0x00b5, 0x00b2, 0x00af, 0x00ac, 0x00a9, + 0x00a7, 0x00a4, 0x00a1, 0x009f, 0x009c, 0x0099, 0x0097, 0x0094, + 0x0092, 0x008f, 0x008d, 0x008a, 0x0088, 0x0086, 0x0083, 0x0081, + 0x007f, 0x007d, 0x007a, 0x0078, 0x0076, 0x0074, 0x0072, 0x0070, + 0x006e, 0x006c, 0x006a, 0x0068, 0x0066, 0x0064, 0x0062, 0x0060, + 0x005e, 0x005c, 0x005b, 0x0059, 0x0057, 0x0055, 0x0053, 0x0052, + 0x0050, 0x004e, 0x004d, 0x004b, 0x004a, 0x0048, 0x0046, 0x0045, + 0x0043, 0x0042, 0x0040, 0x003f, 0x003e, 0x003c, 0x003b, 0x0039, + 0x0038, 0x0037, 0x0035, 0x0034, 0x0033, 0x0031, 0x0030, 0x002f, + 0x002e, 0x002d, 0x002b, 0x002a, 0x0029, 0x0028, 0x0027, 0x0026, + 0x0025, 0x0024, 0x0023, 0x0022, 0x0021, 0x0020, 0x001f, 0x001e, + 0x001d, 0x001c, 0x001b, 0x001a, 0x0019, 0x0018, 0x0017, 0x0017, + 0x0016, 0x0015, 0x0014, 0x0014, 0x0013, 0x0012, 0x0011, 0x0011, + 0x0010, 0x000f, 0x000f, 0x000e, 0x000d, 0x000d, 0x000c, 0x000c, + 0x000b, 0x000a, 0x000a, 0x0009, 0x0009, 0x0008, 0x0008, 0x0007, + 0x0007, 0x0007, 0x0006, 0x0006, 0x0005, 0x0005, 0x0005, 0x0004, + 0x0004, 0x0004, 0x0003, 0x0003, 0x0003, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0003, 0x0003, 0x0003, 0x0004, 0x0004, + 0x0004, 0x0005, 0x0005, 0x0005, 0x0006, 0x0006, 0x0007, 0x0007, + 0x0007, 0x0008, 0x0008, 0x0009, 0x0009, 0x000a, 0x000a, 0x000b, + 0x000c, 0x000c, 0x000d, 0x000d, 0x000e, 0x000f, 0x000f, 0x0010, + 0x0011, 0x0011, 0x0012, 0x0013, 0x0014, 0x0014, 0x0015, 0x0016, + 0x0017, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, + 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, + 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002d, 0x002e, + 0x002f, 0x0030, 0x0031, 0x0033, 0x0034, 0x0035, 0x0037, 0x0038, + 0x0039, 0x003b, 0x003c, 0x003e, 0x003f, 0x0040, 0x0042, 0x0043, + 0x0045, 0x0046, 0x0048, 0x004a, 0x004b, 0x004d, 0x004e, 0x0050, + 0x0052, 0x0053, 0x0055, 0x0057, 0x0059, 0x005b, 0x005c, 0x005e, + 0x0060, 0x0062, 0x0064, 0x0066, 0x0068, 0x006a, 0x006c, 0x006e, + 0x0070, 0x0072, 0x0074, 0x0076, 0x0078, 0x007a, 0x007d, 0x007f, + 0x0081, 0x0083, 0x0086, 0x0088, 0x008a, 0x008d, 0x008f, 0x0092, + 0x0094, 0x0097, 0x0099, 0x009c, 0x009f, 0x00a1, 0x00a4, 0x00a7, + 0x00a9, 0x00ac, 0x00af, 0x00b2, 0x00b5, 0x00b8, 0x00bb, 0x00be, + 0x00c1, 0x00c4, 0x00c7, 0x00ca, 0x00cd, 0x00d1, 0x00d4, 0x00d7, + 0x00db, 0x00de, 0x00e2, 0x00e5, 0x00e9, 0x00ec, 0x00f0, 0x00f4, + 0x00f8, 0x00fb, 0x00ff, 0x0103, 0x0107, 0x010b, 0x010f, 0x0114, + 0x0118, 0x011c, 0x0121, 0x0125, 0x0129, 0x012e, 0x0133, 0x0137, + 0x013c, 0x0141, 0x0146, 0x014b, 0x0150, 0x0155, 0x015b, 0x0160, + 0x0166, 0x016b, 0x0171, 0x0177, 0x017c, 0x0182, 0x0188, 0x018f, + 0x0195, 0x019b, 0x01a2, 0x01a9, 0x01b0, 0x01b7, 0x01be, 0x01c5, + 0x01cd, 0x01d4, 0x01dc, 0x01e4, 0x01ec, 0x01f5, 0x01fd, 0x0206, + 0x020f, 0x0218, 0x0222, 0x022c, 0x0236, 0x0240, 0x024b, 0x0256, + 0x0261, 0x026d, 0x0279, 0x0286, 0x0293, 0x02a0, 0x02af, 0x02bd, + 0x02cd, 0x02dc, 0x02ed, 0x02ff, 0x0311, 0x0324, 0x0339, 0x034e, + 0x0365, 0x037e, 0x0398, 0x03b5, 0x03d3, 0x03f5, 0x041a, 0x0443, + 0x0471, 0x04a6, 0x04e4, 0x052e, 0x058b, 0x0607, 0x06c3, 0x0859, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + // wave 2 + 0x0859, 0x06c3, 0x0607, 0x058b, 0x052e, 0x04e4, 0x04a6, 0x0471, + 0x0443, 0x041a, 0x03f5, 0x03d3, 0x03b5, 0x0398, 0x037e, 0x0365, + 0x034e, 0x0339, 0x0324, 0x0311, 0x02ff, 0x02ed, 0x02dc, 0x02cd, + 0x02bd, 0x02af, 0x02a0, 0x0293, 0x0286, 0x0279, 0x026d, 0x0261, + 0x0256, 0x024b, 0x0240, 0x0236, 0x022c, 0x0222, 0x0218, 0x020f, + 0x0206, 0x01fd, 0x01f5, 0x01ec, 0x01e4, 0x01dc, 0x01d4, 0x01cd, + 0x01c5, 0x01be, 0x01b7, 0x01b0, 0x01a9, 0x01a2, 0x019b, 0x0195, + 0x018f, 0x0188, 0x0182, 0x017c, 0x0177, 0x0171, 0x016b, 0x0166, + 0x0160, 0x015b, 0x0155, 0x0150, 0x014b, 0x0146, 0x0141, 0x013c, + 0x0137, 0x0133, 0x012e, 0x0129, 0x0125, 0x0121, 0x011c, 0x0118, + 0x0114, 0x010f, 0x010b, 0x0107, 0x0103, 0x00ff, 0x00fb, 0x00f8, + 0x00f4, 0x00f0, 0x00ec, 0x00e9, 0x00e5, 0x00e2, 0x00de, 0x00db, + 0x00d7, 0x00d4, 0x00d1, 0x00cd, 0x00ca, 0x00c7, 0x00c4, 0x00c1, + 0x00be, 0x00bb, 0x00b8, 0x00b5, 0x00b2, 0x00af, 0x00ac, 0x00a9, + 0x00a7, 0x00a4, 0x00a1, 0x009f, 0x009c, 0x0099, 0x0097, 0x0094, + 0x0092, 0x008f, 0x008d, 0x008a, 0x0088, 0x0086, 0x0083, 0x0081, + 0x007f, 0x007d, 0x007a, 0x0078, 0x0076, 0x0074, 0x0072, 0x0070, + 0x006e, 0x006c, 0x006a, 0x0068, 0x0066, 0x0064, 0x0062, 0x0060, + 0x005e, 0x005c, 0x005b, 0x0059, 0x0057, 0x0055, 0x0053, 0x0052, + 0x0050, 0x004e, 0x004d, 0x004b, 0x004a, 0x0048, 0x0046, 0x0045, + 0x0043, 0x0042, 0x0040, 0x003f, 0x003e, 0x003c, 0x003b, 0x0039, + 0x0038, 0x0037, 0x0035, 0x0034, 0x0033, 0x0031, 0x0030, 0x002f, + 0x002e, 0x002d, 0x002b, 0x002a, 0x0029, 0x0028, 0x0027, 0x0026, + 0x0025, 0x0024, 0x0023, 0x0022, 0x0021, 0x0020, 0x001f, 0x001e, + 0x001d, 0x001c, 0x001b, 0x001a, 0x0019, 0x0018, 0x0017, 0x0017, + 0x0016, 0x0015, 0x0014, 0x0014, 0x0013, 0x0012, 0x0011, 0x0011, + 0x0010, 0x000f, 0x000f, 0x000e, 0x000d, 0x000d, 0x000c, 0x000c, + 0x000b, 0x000a, 0x000a, 0x0009, 0x0009, 0x0008, 0x0008, 0x0007, + 0x0007, 0x0007, 0x0006, 0x0006, 0x0005, 0x0005, 0x0005, 0x0004, + 0x0004, 0x0004, 0x0003, 0x0003, 0x0003, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0003, 0x0003, 0x0003, 0x0004, 0x0004, + 0x0004, 0x0005, 0x0005, 0x0005, 0x0006, 0x0006, 0x0007, 0x0007, + 0x0007, 0x0008, 0x0008, 0x0009, 0x0009, 0x000a, 0x000a, 0x000b, + 0x000c, 0x000c, 0x000d, 0x000d, 0x000e, 0x000f, 0x000f, 0x0010, + 0x0011, 0x0011, 0x0012, 0x0013, 0x0014, 0x0014, 0x0015, 0x0016, + 0x0017, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, + 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, + 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002d, 0x002e, + 0x002f, 0x0030, 0x0031, 0x0033, 0x0034, 0x0035, 0x0037, 0x0038, + 0x0039, 0x003b, 0x003c, 0x003e, 0x003f, 0x0040, 0x0042, 0x0043, + 0x0045, 0x0046, 0x0048, 0x004a, 0x004b, 0x004d, 0x004e, 0x0050, + 0x0052, 0x0053, 0x0055, 0x0057, 0x0059, 0x005b, 0x005c, 0x005e, + 0x0060, 0x0062, 0x0064, 0x0066, 0x0068, 0x006a, 0x006c, 0x006e, + 0x0070, 0x0072, 0x0074, 0x0076, 0x0078, 0x007a, 0x007d, 0x007f, + 0x0081, 0x0083, 0x0086, 0x0088, 0x008a, 0x008d, 0x008f, 0x0092, + 0x0094, 0x0097, 0x0099, 0x009c, 0x009f, 0x00a1, 0x00a4, 0x00a7, + 0x00a9, 0x00ac, 0x00af, 0x00b2, 0x00b5, 0x00b8, 0x00bb, 0x00be, + 0x00c1, 0x00c4, 0x00c7, 0x00ca, 0x00cd, 0x00d1, 0x00d4, 0x00d7, + 0x00db, 0x00de, 0x00e2, 0x00e5, 0x00e9, 0x00ec, 0x00f0, 0x00f4, + 0x00f8, 0x00fb, 0x00ff, 0x0103, 0x0107, 0x010b, 0x010f, 0x0114, + 0x0118, 0x011c, 0x0121, 0x0125, 0x0129, 0x012e, 0x0133, 0x0137, + 0x013c, 0x0141, 0x0146, 0x014b, 0x0150, 0x0155, 0x015b, 0x0160, + 0x0166, 0x016b, 0x0171, 0x0177, 0x017c, 0x0182, 0x0188, 0x018f, + 0x0195, 0x019b, 0x01a2, 0x01a9, 0x01b0, 0x01b7, 0x01be, 0x01c5, + 0x01cd, 0x01d4, 0x01dc, 0x01e4, 0x01ec, 0x01f5, 0x01fd, 0x0206, + 0x020f, 0x0218, 0x0222, 0x022c, 0x0236, 0x0240, 0x024b, 0x0256, + 0x0261, 0x026d, 0x0279, 0x0286, 0x0293, 0x02a0, 0x02af, 0x02bd, + 0x02cd, 0x02dc, 0x02ed, 0x02ff, 0x0311, 0x0324, 0x0339, 0x034e, + 0x0365, 0x037e, 0x0398, 0x03b5, 0x03d3, 0x03f5, 0x041a, 0x0443, + 0x0471, 0x04a6, 0x04e4, 0x052e, 0x058b, 0x0607, 0x06c3, 0x0859, + 0x0859, 0x06c3, 0x0607, 0x058b, 0x052e, 0x04e4, 0x04a6, 0x0471, + 0x0443, 0x041a, 0x03f5, 0x03d3, 0x03b5, 0x0398, 0x037e, 0x0365, + 0x034e, 0x0339, 0x0324, 0x0311, 0x02ff, 0x02ed, 0x02dc, 0x02cd, + 0x02bd, 0x02af, 0x02a0, 0x0293, 0x0286, 0x0279, 0x026d, 0x0261, + 0x0256, 0x024b, 0x0240, 0x0236, 0x022c, 0x0222, 0x0218, 0x020f, + 0x0206, 0x01fd, 0x01f5, 0x01ec, 0x01e4, 0x01dc, 0x01d4, 0x01cd, + 0x01c5, 0x01be, 0x01b7, 0x01b0, 0x01a9, 0x01a2, 0x019b, 0x0195, + 0x018f, 0x0188, 0x0182, 0x017c, 0x0177, 0x0171, 0x016b, 0x0166, + 0x0160, 0x015b, 0x0155, 0x0150, 0x014b, 0x0146, 0x0141, 0x013c, + 0x0137, 0x0133, 0x012e, 0x0129, 0x0125, 0x0121, 0x011c, 0x0118, + 0x0114, 0x010f, 0x010b, 0x0107, 0x0103, 0x00ff, 0x00fb, 0x00f8, + 0x00f4, 0x00f0, 0x00ec, 0x00e9, 0x00e5, 0x00e2, 0x00de, 0x00db, + 0x00d7, 0x00d4, 0x00d1, 0x00cd, 0x00ca, 0x00c7, 0x00c4, 0x00c1, + 0x00be, 0x00bb, 0x00b8, 0x00b5, 0x00b2, 0x00af, 0x00ac, 0x00a9, + 0x00a7, 0x00a4, 0x00a1, 0x009f, 0x009c, 0x0099, 0x0097, 0x0094, + 0x0092, 0x008f, 0x008d, 0x008a, 0x0088, 0x0086, 0x0083, 0x0081, + 0x007f, 0x007d, 0x007a, 0x0078, 0x0076, 0x0074, 0x0072, 0x0070, + 0x006e, 0x006c, 0x006a, 0x0068, 0x0066, 0x0064, 0x0062, 0x0060, + 0x005e, 0x005c, 0x005b, 0x0059, 0x0057, 0x0055, 0x0053, 0x0052, + 0x0050, 0x004e, 0x004d, 0x004b, 0x004a, 0x0048, 0x0046, 0x0045, + 0x0043, 0x0042, 0x0040, 0x003f, 0x003e, 0x003c, 0x003b, 0x0039, + 0x0038, 0x0037, 0x0035, 0x0034, 0x0033, 0x0031, 0x0030, 0x002f, + 0x002e, 0x002d, 0x002b, 0x002a, 0x0029, 0x0028, 0x0027, 0x0026, + 0x0025, 0x0024, 0x0023, 0x0022, 0x0021, 0x0020, 0x001f, 0x001e, + 0x001d, 0x001c, 0x001b, 0x001a, 0x0019, 0x0018, 0x0017, 0x0017, + 0x0016, 0x0015, 0x0014, 0x0014, 0x0013, 0x0012, 0x0011, 0x0011, + 0x0010, 0x000f, 0x000f, 0x000e, 0x000d, 0x000d, 0x000c, 0x000c, + 0x000b, 0x000a, 0x000a, 0x0009, 0x0009, 0x0008, 0x0008, 0x0007, + 0x0007, 0x0007, 0x0006, 0x0006, 0x0005, 0x0005, 0x0005, 0x0004, + 0x0004, 0x0004, 0x0003, 0x0003, 0x0003, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0003, 0x0003, 0x0003, 0x0004, 0x0004, + 0x0004, 0x0005, 0x0005, 0x0005, 0x0006, 0x0006, 0x0007, 0x0007, + 0x0007, 0x0008, 0x0008, 0x0009, 0x0009, 0x000a, 0x000a, 0x000b, + 0x000c, 0x000c, 0x000d, 0x000d, 0x000e, 0x000f, 0x000f, 0x0010, + 0x0011, 0x0011, 0x0012, 0x0013, 0x0014, 0x0014, 0x0015, 0x0016, + 0x0017, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, + 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, + 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002d, 0x002e, + 0x002f, 0x0030, 0x0031, 0x0033, 0x0034, 0x0035, 0x0037, 0x0038, + 0x0039, 0x003b, 0x003c, 0x003e, 0x003f, 0x0040, 0x0042, 0x0043, + 0x0045, 0x0046, 0x0048, 0x004a, 0x004b, 0x004d, 0x004e, 0x0050, + 0x0052, 0x0053, 0x0055, 0x0057, 0x0059, 0x005b, 0x005c, 0x005e, + 0x0060, 0x0062, 0x0064, 0x0066, 0x0068, 0x006a, 0x006c, 0x006e, + 0x0070, 0x0072, 0x0074, 0x0076, 0x0078, 0x007a, 0x007d, 0x007f, + 0x0081, 0x0083, 0x0086, 0x0088, 0x008a, 0x008d, 0x008f, 0x0092, + 0x0094, 0x0097, 0x0099, 0x009c, 0x009f, 0x00a1, 0x00a4, 0x00a7, + 0x00a9, 0x00ac, 0x00af, 0x00b2, 0x00b5, 0x00b8, 0x00bb, 0x00be, + 0x00c1, 0x00c4, 0x00c7, 0x00ca, 0x00cd, 0x00d1, 0x00d4, 0x00d7, + 0x00db, 0x00de, 0x00e2, 0x00e5, 0x00e9, 0x00ec, 0x00f0, 0x00f4, + 0x00f8, 0x00fb, 0x00ff, 0x0103, 0x0107, 0x010b, 0x010f, 0x0114, + 0x0118, 0x011c, 0x0121, 0x0125, 0x0129, 0x012e, 0x0133, 0x0137, + 0x013c, 0x0141, 0x0146, 0x014b, 0x0150, 0x0155, 0x015b, 0x0160, + 0x0166, 0x016b, 0x0171, 0x0177, 0x017c, 0x0182, 0x0188, 0x018f, + 0x0195, 0x019b, 0x01a2, 0x01a9, 0x01b0, 0x01b7, 0x01be, 0x01c5, + 0x01cd, 0x01d4, 0x01dc, 0x01e4, 0x01ec, 0x01f5, 0x01fd, 0x0206, + 0x020f, 0x0218, 0x0222, 0x022c, 0x0236, 0x0240, 0x024b, 0x0256, + 0x0261, 0x026d, 0x0279, 0x0286, 0x0293, 0x02a0, 0x02af, 0x02bd, + 0x02cd, 0x02dc, 0x02ed, 0x02ff, 0x0311, 0x0324, 0x0339, 0x034e, + 0x0365, 0x037e, 0x0398, 0x03b5, 0x03d3, 0x03f5, 0x041a, 0x0443, + 0x0471, 0x04a6, 0x04e4, 0x052e, 0x058b, 0x0607, 0x06c3, 0x0859, + // wave 3 + 0x0859, 0x06c3, 0x0607, 0x058b, 0x052e, 0x04e4, 0x04a6, 0x0471, + 0x0443, 0x041a, 0x03f5, 0x03d3, 0x03b5, 0x0398, 0x037e, 0x0365, + 0x034e, 0x0339, 0x0324, 0x0311, 0x02ff, 0x02ed, 0x02dc, 0x02cd, + 0x02bd, 0x02af, 0x02a0, 0x0293, 0x0286, 0x0279, 0x026d, 0x0261, + 0x0256, 0x024b, 0x0240, 0x0236, 0x022c, 0x0222, 0x0218, 0x020f, + 0x0206, 0x01fd, 0x01f5, 0x01ec, 0x01e4, 0x01dc, 0x01d4, 0x01cd, + 0x01c5, 0x01be, 0x01b7, 0x01b0, 0x01a9, 0x01a2, 0x019b, 0x0195, + 0x018f, 0x0188, 0x0182, 0x017c, 0x0177, 0x0171, 0x016b, 0x0166, + 0x0160, 0x015b, 0x0155, 0x0150, 0x014b, 0x0146, 0x0141, 0x013c, + 0x0137, 0x0133, 0x012e, 0x0129, 0x0125, 0x0121, 0x011c, 0x0118, + 0x0114, 0x010f, 0x010b, 0x0107, 0x0103, 0x00ff, 0x00fb, 0x00f8, + 0x00f4, 0x00f0, 0x00ec, 0x00e9, 0x00e5, 0x00e2, 0x00de, 0x00db, + 0x00d7, 0x00d4, 0x00d1, 0x00cd, 0x00ca, 0x00c7, 0x00c4, 0x00c1, + 0x00be, 0x00bb, 0x00b8, 0x00b5, 0x00b2, 0x00af, 0x00ac, 0x00a9, + 0x00a7, 0x00a4, 0x00a1, 0x009f, 0x009c, 0x0099, 0x0097, 0x0094, + 0x0092, 0x008f, 0x008d, 0x008a, 0x0088, 0x0086, 0x0083, 0x0081, + 0x007f, 0x007d, 0x007a, 0x0078, 0x0076, 0x0074, 0x0072, 0x0070, + 0x006e, 0x006c, 0x006a, 0x0068, 0x0066, 0x0064, 0x0062, 0x0060, + 0x005e, 0x005c, 0x005b, 0x0059, 0x0057, 0x0055, 0x0053, 0x0052, + 0x0050, 0x004e, 0x004d, 0x004b, 0x004a, 0x0048, 0x0046, 0x0045, + 0x0043, 0x0042, 0x0040, 0x003f, 0x003e, 0x003c, 0x003b, 0x0039, + 0x0038, 0x0037, 0x0035, 0x0034, 0x0033, 0x0031, 0x0030, 0x002f, + 0x002e, 0x002d, 0x002b, 0x002a, 0x0029, 0x0028, 0x0027, 0x0026, + 0x0025, 0x0024, 0x0023, 0x0022, 0x0021, 0x0020, 0x001f, 0x001e, + 0x001d, 0x001c, 0x001b, 0x001a, 0x0019, 0x0018, 0x0017, 0x0017, + 0x0016, 0x0015, 0x0014, 0x0014, 0x0013, 0x0012, 0x0011, 0x0011, + 0x0010, 0x000f, 0x000f, 0x000e, 0x000d, 0x000d, 0x000c, 0x000c, + 0x000b, 0x000a, 0x000a, 0x0009, 0x0009, 0x0008, 0x0008, 0x0007, + 0x0007, 0x0007, 0x0006, 0x0006, 0x0005, 0x0005, 0x0005, 0x0004, + 0x0004, 0x0004, 0x0003, 0x0003, 0x0003, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x0859, 0x06c3, 0x0607, 0x058b, 0x052e, 0x04e4, 0x04a6, 0x0471, + 0x0443, 0x041a, 0x03f5, 0x03d3, 0x03b5, 0x0398, 0x037e, 0x0365, + 0x034e, 0x0339, 0x0324, 0x0311, 0x02ff, 0x02ed, 0x02dc, 0x02cd, + 0x02bd, 0x02af, 0x02a0, 0x0293, 0x0286, 0x0279, 0x026d, 0x0261, + 0x0256, 0x024b, 0x0240, 0x0236, 0x022c, 0x0222, 0x0218, 0x020f, + 0x0206, 0x01fd, 0x01f5, 0x01ec, 0x01e4, 0x01dc, 0x01d4, 0x01cd, + 0x01c5, 0x01be, 0x01b7, 0x01b0, 0x01a9, 0x01a2, 0x019b, 0x0195, + 0x018f, 0x0188, 0x0182, 0x017c, 0x0177, 0x0171, 0x016b, 0x0166, + 0x0160, 0x015b, 0x0155, 0x0150, 0x014b, 0x0146, 0x0141, 0x013c, + 0x0137, 0x0133, 0x012e, 0x0129, 0x0125, 0x0121, 0x011c, 0x0118, + 0x0114, 0x010f, 0x010b, 0x0107, 0x0103, 0x00ff, 0x00fb, 0x00f8, + 0x00f4, 0x00f0, 0x00ec, 0x00e9, 0x00e5, 0x00e2, 0x00de, 0x00db, + 0x00d7, 0x00d4, 0x00d1, 0x00cd, 0x00ca, 0x00c7, 0x00c4, 0x00c1, + 0x00be, 0x00bb, 0x00b8, 0x00b5, 0x00b2, 0x00af, 0x00ac, 0x00a9, + 0x00a7, 0x00a4, 0x00a1, 0x009f, 0x009c, 0x0099, 0x0097, 0x0094, + 0x0092, 0x008f, 0x008d, 0x008a, 0x0088, 0x0086, 0x0083, 0x0081, + 0x007f, 0x007d, 0x007a, 0x0078, 0x0076, 0x0074, 0x0072, 0x0070, + 0x006e, 0x006c, 0x006a, 0x0068, 0x0066, 0x0064, 0x0062, 0x0060, + 0x005e, 0x005c, 0x005b, 0x0059, 0x0057, 0x0055, 0x0053, 0x0052, + 0x0050, 0x004e, 0x004d, 0x004b, 0x004a, 0x0048, 0x0046, 0x0045, + 0x0043, 0x0042, 0x0040, 0x003f, 0x003e, 0x003c, 0x003b, 0x0039, + 0x0038, 0x0037, 0x0035, 0x0034, 0x0033, 0x0031, 0x0030, 0x002f, + 0x002e, 0x002d, 0x002b, 0x002a, 0x0029, 0x0028, 0x0027, 0x0026, + 0x0025, 0x0024, 0x0023, 0x0022, 0x0021, 0x0020, 0x001f, 0x001e, + 0x001d, 0x001c, 0x001b, 0x001a, 0x0019, 0x0018, 0x0017, 0x0017, + 0x0016, 0x0015, 0x0014, 0x0014, 0x0013, 0x0012, 0x0011, 0x0011, + 0x0010, 0x000f, 0x000f, 0x000e, 0x000d, 0x000d, 0x000c, 0x000c, + 0x000b, 0x000a, 0x000a, 0x0009, 0x0009, 0x0008, 0x0008, 0x0007, + 0x0007, 0x0007, 0x0006, 0x0006, 0x0005, 0x0005, 0x0005, 0x0004, + 0x0004, 0x0004, 0x0003, 0x0003, 0x0003, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + // wave 4 + 0x0859, 0x0607, 0x052e, 0x04a6, 0x0443, 0x03f5, 0x03b5, 0x037e, + 0x034e, 0x0324, 0x02ff, 0x02dc, 0x02bd, 0x02a0, 0x0286, 0x026d, + 0x0256, 0x0240, 0x022c, 0x0218, 0x0206, 0x01f5, 0x01e4, 0x01d4, + 0x01c5, 0x01b7, 0x01a9, 0x019b, 0x018f, 0x0182, 0x0177, 0x016b, + 0x0160, 0x0155, 0x014b, 0x0141, 0x0137, 0x012e, 0x0125, 0x011c, + 0x0114, 0x010b, 0x0103, 0x00fb, 0x00f4, 0x00ec, 0x00e5, 0x00de, + 0x00d7, 0x00d1, 0x00ca, 0x00c4, 0x00be, 0x00b8, 0x00b2, 0x00ac, + 0x00a7, 0x00a1, 0x009c, 0x0097, 0x0092, 0x008d, 0x0088, 0x0083, + 0x007f, 0x007a, 0x0076, 0x0072, 0x006e, 0x006a, 0x0066, 0x0062, + 0x005e, 0x005b, 0x0057, 0x0053, 0x0050, 0x004d, 0x004a, 0x0046, + 0x0043, 0x0040, 0x003e, 0x003b, 0x0038, 0x0035, 0x0033, 0x0030, + 0x002e, 0x002b, 0x0029, 0x0027, 0x0025, 0x0023, 0x0021, 0x001f, + 0x001d, 0x001b, 0x0019, 0x0017, 0x0016, 0x0014, 0x0013, 0x0011, + 0x0010, 0x000f, 0x000d, 0x000c, 0x000b, 0x000a, 0x0009, 0x0008, + 0x0007, 0x0006, 0x0005, 0x0005, 0x0004, 0x0003, 0x0003, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0002, + 0x0002, 0x0003, 0x0003, 0x0004, 0x0005, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000f, 0x0010, + 0x0011, 0x0013, 0x0014, 0x0016, 0x0017, 0x0019, 0x001b, 0x001d, + 0x001f, 0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002b, 0x002e, + 0x0030, 0x0033, 0x0035, 0x0038, 0x003b, 0x003e, 0x0040, 0x0043, + 0x0046, 0x004a, 0x004d, 0x0050, 0x0053, 0x0057, 0x005b, 0x005e, + 0x0062, 0x0066, 0x006a, 0x006e, 0x0072, 0x0076, 0x007a, 0x007f, + 0x0083, 0x0088, 0x008d, 0x0092, 0x0097, 0x009c, 0x00a1, 0x00a7, + 0x00ac, 0x00b2, 0x00b8, 0x00be, 0x00c4, 0x00ca, 0x00d1, 0x00d7, + 0x00de, 0x00e5, 0x00ec, 0x00f4, 0x00fb, 0x0103, 0x010b, 0x0114, + 0x011c, 0x0125, 0x012e, 0x0137, 0x0141, 0x014b, 0x0155, 0x0160, + 0x016b, 0x0177, 0x0182, 0x018f, 0x019b, 0x01a9, 0x01b7, 0x01c5, + 0x01d4, 0x01e4, 0x01f5, 0x0206, 0x0218, 0x022c, 0x0240, 0x0256, + 0x026d, 0x0286, 0x02a0, 0x02bd, 0x02dc, 0x02ff, 0x0324, 0x034e, + 0x037e, 0x03b5, 0x03f5, 0x0443, 0x04a6, 0x052e, 0x0607, 0x0859, + 0x8859, 0x8607, 0x852e, 0x84a6, 0x8443, 0x83f5, 0x83b5, 0x837e, + 0x834e, 0x8324, 0x82ff, 0x82dc, 0x82bd, 0x82a0, 0x8286, 0x826d, + 0x8256, 0x8240, 0x822c, 0x8218, 0x8206, 0x81f5, 0x81e4, 0x81d4, + 0x81c5, 0x81b7, 0x81a9, 0x819b, 0x818f, 0x8182, 0x8177, 0x816b, + 0x8160, 0x8155, 0x814b, 0x8141, 0x8137, 0x812e, 0x8125, 0x811c, + 0x8114, 0x810b, 0x8103, 0x80fb, 0x80f4, 0x80ec, 0x80e5, 0x80de, + 0x80d7, 0x80d1, 0x80ca, 0x80c4, 0x80be, 0x80b8, 0x80b2, 0x80ac, + 0x80a7, 0x80a1, 0x809c, 0x8097, 0x8092, 0x808d, 0x8088, 0x8083, + 0x807f, 0x807a, 0x8076, 0x8072, 0x806e, 0x806a, 0x8066, 0x8062, + 0x805e, 0x805b, 0x8057, 0x8053, 0x8050, 0x804d, 0x804a, 0x8046, + 0x8043, 0x8040, 0x803e, 0x803b, 0x8038, 0x8035, 0x8033, 0x8030, + 0x802e, 0x802b, 0x8029, 0x8027, 0x8025, 0x8023, 0x8021, 0x801f, + 0x801d, 0x801b, 0x8019, 0x8017, 0x8016, 0x8014, 0x8013, 0x8011, + 0x8010, 0x800f, 0x800d, 0x800c, 0x800b, 0x800a, 0x8009, 0x8008, + 0x8007, 0x8006, 0x8005, 0x8005, 0x8004, 0x8003, 0x8003, 0x8002, + 0x8002, 0x8001, 0x8001, 0x8001, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8001, 0x8001, 0x8001, 0x8002, + 0x8002, 0x8003, 0x8003, 0x8004, 0x8005, 0x8005, 0x8006, 0x8007, + 0x8008, 0x8009, 0x800a, 0x800b, 0x800c, 0x800d, 0x800f, 0x8010, + 0x8011, 0x8013, 0x8014, 0x8016, 0x8017, 0x8019, 0x801b, 0x801d, + 0x801f, 0x8021, 0x8023, 0x8025, 0x8027, 0x8029, 0x802b, 0x802e, + 0x8030, 0x8033, 0x8035, 0x8038, 0x803b, 0x803e, 0x8040, 0x8043, + 0x8046, 0x804a, 0x804d, 0x8050, 0x8053, 0x8057, 0x805b, 0x805e, + 0x8062, 0x8066, 0x806a, 0x806e, 0x8072, 0x8076, 0x807a, 0x807f, + 0x8083, 0x8088, 0x808d, 0x8092, 0x8097, 0x809c, 0x80a1, 0x80a7, + 0x80ac, 0x80b2, 0x80b8, 0x80be, 0x80c4, 0x80ca, 0x80d1, 0x80d7, + 0x80de, 0x80e5, 0x80ec, 0x80f4, 0x80fb, 0x8103, 0x810b, 0x8114, + 0x811c, 0x8125, 0x812e, 0x8137, 0x8141, 0x814b, 0x8155, 0x8160, + 0x816b, 0x8177, 0x8182, 0x818f, 0x819b, 0x81a9, 0x81b7, 0x81c5, + 0x81d4, 0x81e4, 0x81f5, 0x8206, 0x8218, 0x822c, 0x8240, 0x8256, + 0x826d, 0x8286, 0x82a0, 0x82bd, 0x82dc, 0x82ff, 0x8324, 0x834e, + 0x837e, 0x83b5, 0x83f5, 0x8443, 0x84a6, 0x852e, 0x8607, 0x8859, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + // wave 5 + 0x0859, 0x0607, 0x052e, 0x04a6, 0x0443, 0x03f5, 0x03b5, 0x037e, + 0x034e, 0x0324, 0x02ff, 0x02dc, 0x02bd, 0x02a0, 0x0286, 0x026d, + 0x0256, 0x0240, 0x022c, 0x0218, 0x0206, 0x01f5, 0x01e4, 0x01d4, + 0x01c5, 0x01b7, 0x01a9, 0x019b, 0x018f, 0x0182, 0x0177, 0x016b, + 0x0160, 0x0155, 0x014b, 0x0141, 0x0137, 0x012e, 0x0125, 0x011c, + 0x0114, 0x010b, 0x0103, 0x00fb, 0x00f4, 0x00ec, 0x00e5, 0x00de, + 0x00d7, 0x00d1, 0x00ca, 0x00c4, 0x00be, 0x00b8, 0x00b2, 0x00ac, + 0x00a7, 0x00a1, 0x009c, 0x0097, 0x0092, 0x008d, 0x0088, 0x0083, + 0x007f, 0x007a, 0x0076, 0x0072, 0x006e, 0x006a, 0x0066, 0x0062, + 0x005e, 0x005b, 0x0057, 0x0053, 0x0050, 0x004d, 0x004a, 0x0046, + 0x0043, 0x0040, 0x003e, 0x003b, 0x0038, 0x0035, 0x0033, 0x0030, + 0x002e, 0x002b, 0x0029, 0x0027, 0x0025, 0x0023, 0x0021, 0x001f, + 0x001d, 0x001b, 0x0019, 0x0017, 0x0016, 0x0014, 0x0013, 0x0011, + 0x0010, 0x000f, 0x000d, 0x000c, 0x000b, 0x000a, 0x0009, 0x0008, + 0x0007, 0x0006, 0x0005, 0x0005, 0x0004, 0x0003, 0x0003, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0002, + 0x0002, 0x0003, 0x0003, 0x0004, 0x0005, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000f, 0x0010, + 0x0011, 0x0013, 0x0014, 0x0016, 0x0017, 0x0019, 0x001b, 0x001d, + 0x001f, 0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002b, 0x002e, + 0x0030, 0x0033, 0x0035, 0x0038, 0x003b, 0x003e, 0x0040, 0x0043, + 0x0046, 0x004a, 0x004d, 0x0050, 0x0053, 0x0057, 0x005b, 0x005e, + 0x0062, 0x0066, 0x006a, 0x006e, 0x0072, 0x0076, 0x007a, 0x007f, + 0x0083, 0x0088, 0x008d, 0x0092, 0x0097, 0x009c, 0x00a1, 0x00a7, + 0x00ac, 0x00b2, 0x00b8, 0x00be, 0x00c4, 0x00ca, 0x00d1, 0x00d7, + 0x00de, 0x00e5, 0x00ec, 0x00f4, 0x00fb, 0x0103, 0x010b, 0x0114, + 0x011c, 0x0125, 0x012e, 0x0137, 0x0141, 0x014b, 0x0155, 0x0160, + 0x016b, 0x0177, 0x0182, 0x018f, 0x019b, 0x01a9, 0x01b7, 0x01c5, + 0x01d4, 0x01e4, 0x01f5, 0x0206, 0x0218, 0x022c, 0x0240, 0x0256, + 0x026d, 0x0286, 0x02a0, 0x02bd, 0x02dc, 0x02ff, 0x0324, 0x034e, + 0x037e, 0x03b5, 0x03f5, 0x0443, 0x04a6, 0x052e, 0x0607, 0x0859, + 0x0859, 0x0607, 0x052e, 0x04a6, 0x0443, 0x03f5, 0x03b5, 0x037e, + 0x034e, 0x0324, 0x02ff, 0x02dc, 0x02bd, 0x02a0, 0x0286, 0x026d, + 0x0256, 0x0240, 0x022c, 0x0218, 0x0206, 0x01f5, 0x01e4, 0x01d4, + 0x01c5, 0x01b7, 0x01a9, 0x019b, 0x018f, 0x0182, 0x0177, 0x016b, + 0x0160, 0x0155, 0x014b, 0x0141, 0x0137, 0x012e, 0x0125, 0x011c, + 0x0114, 0x010b, 0x0103, 0x00fb, 0x00f4, 0x00ec, 0x00e5, 0x00de, + 0x00d7, 0x00d1, 0x00ca, 0x00c4, 0x00be, 0x00b8, 0x00b2, 0x00ac, + 0x00a7, 0x00a1, 0x009c, 0x0097, 0x0092, 0x008d, 0x0088, 0x0083, + 0x007f, 0x007a, 0x0076, 0x0072, 0x006e, 0x006a, 0x0066, 0x0062, + 0x005e, 0x005b, 0x0057, 0x0053, 0x0050, 0x004d, 0x004a, 0x0046, + 0x0043, 0x0040, 0x003e, 0x003b, 0x0038, 0x0035, 0x0033, 0x0030, + 0x002e, 0x002b, 0x0029, 0x0027, 0x0025, 0x0023, 0x0021, 0x001f, + 0x001d, 0x001b, 0x0019, 0x0017, 0x0016, 0x0014, 0x0013, 0x0011, + 0x0010, 0x000f, 0x000d, 0x000c, 0x000b, 0x000a, 0x0009, 0x0008, + 0x0007, 0x0006, 0x0005, 0x0005, 0x0004, 0x0003, 0x0003, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0002, + 0x0002, 0x0003, 0x0003, 0x0004, 0x0005, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000f, 0x0010, + 0x0011, 0x0013, 0x0014, 0x0016, 0x0017, 0x0019, 0x001b, 0x001d, + 0x001f, 0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002b, 0x002e, + 0x0030, 0x0033, 0x0035, 0x0038, 0x003b, 0x003e, 0x0040, 0x0043, + 0x0046, 0x004a, 0x004d, 0x0050, 0x0053, 0x0057, 0x005b, 0x005e, + 0x0062, 0x0066, 0x006a, 0x006e, 0x0072, 0x0076, 0x007a, 0x007f, + 0x0083, 0x0088, 0x008d, 0x0092, 0x0097, 0x009c, 0x00a1, 0x00a7, + 0x00ac, 0x00b2, 0x00b8, 0x00be, 0x00c4, 0x00ca, 0x00d1, 0x00d7, + 0x00de, 0x00e5, 0x00ec, 0x00f4, 0x00fb, 0x0103, 0x010b, 0x0114, + 0x011c, 0x0125, 0x012e, 0x0137, 0x0141, 0x014b, 0x0155, 0x0160, + 0x016b, 0x0177, 0x0182, 0x018f, 0x019b, 0x01a9, 0x01b7, 0x01c5, + 0x01d4, 0x01e4, 0x01f5, 0x0206, 0x0218, 0x022c, 0x0240, 0x0256, + 0x026d, 0x0286, 0x02a0, 0x02bd, 0x02dc, 0x02ff, 0x0324, 0x034e, + 0x037e, 0x03b5, 0x03f5, 0x0443, 0x04a6, 0x052e, 0x0607, 0x0859, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + // wave 6 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + // wave 7 + 0x0000, 0x0008, 0x0010, 0x0018, 0x0020, 0x0028, 0x0030, 0x0038, + 0x0040, 0x0048, 0x0050, 0x0058, 0x0060, 0x0068, 0x0070, 0x0078, + 0x0080, 0x0088, 0x0090, 0x0098, 0x00a0, 0x00a8, 0x00b0, 0x00b8, + 0x00c0, 0x00c8, 0x00d0, 0x00d8, 0x00e0, 0x00e8, 0x00f0, 0x00f8, + 0x0100, 0x0108, 0x0110, 0x0118, 0x0120, 0x0128, 0x0130, 0x0138, + 0x0140, 0x0148, 0x0150, 0x0158, 0x0160, 0x0168, 0x0170, 0x0178, + 0x0180, 0x0188, 0x0190, 0x0198, 0x01a0, 0x01a8, 0x01b0, 0x01b8, + 0x01c0, 0x01c8, 0x01d0, 0x01d8, 0x01e0, 0x01e8, 0x01f0, 0x01f8, + 0x0200, 0x0208, 0x0210, 0x0218, 0x0220, 0x0228, 0x0230, 0x0238, + 0x0240, 0x0248, 0x0250, 0x0258, 0x0260, 0x0268, 0x0270, 0x0278, + 0x0280, 0x0288, 0x0290, 0x0298, 0x02a0, 0x02a8, 0x02b0, 0x02b8, + 0x02c0, 0x02c8, 0x02d0, 0x02d8, 0x02e0, 0x02e8, 0x02f0, 0x02f8, + 0x0300, 0x0308, 0x0310, 0x0318, 0x0320, 0x0328, 0x0330, 0x0338, + 0x0340, 0x0348, 0x0350, 0x0358, 0x0360, 0x0368, 0x0370, 0x0378, + 0x0380, 0x0388, 0x0390, 0x0398, 0x03a0, 0x03a8, 0x03b0, 0x03b8, + 0x03c0, 0x03c8, 0x03d0, 0x03d8, 0x03e0, 0x03e8, 0x03f0, 0x03f8, + 0x0400, 0x0408, 0x0410, 0x0418, 0x0420, 0x0428, 0x0430, 0x0438, + 0x0440, 0x0448, 0x0450, 0x0458, 0x0460, 0x0468, 0x0470, 0x0478, + 0x0480, 0x0488, 0x0490, 0x0498, 0x04a0, 0x04a8, 0x04b0, 0x04b8, + 0x04c0, 0x04c8, 0x04d0, 0x04d8, 0x04e0, 0x04e8, 0x04f0, 0x04f8, + 0x0500, 0x0508, 0x0510, 0x0518, 0x0520, 0x0528, 0x0530, 0x0538, + 0x0540, 0x0548, 0x0550, 0x0558, 0x0560, 0x0568, 0x0570, 0x0578, + 0x0580, 0x0588, 0x0590, 0x0598, 0x05a0, 0x05a8, 0x05b0, 0x05b8, + 0x05c0, 0x05c8, 0x05d0, 0x05d8, 0x05e0, 0x05e8, 0x05f0, 0x05f8, + 0x0600, 0x0608, 0x0610, 0x0618, 0x0620, 0x0628, 0x0630, 0x0638, + 0x0640, 0x0648, 0x0650, 0x0658, 0x0660, 0x0668, 0x0670, 0x0678, + 0x0680, 0x0688, 0x0690, 0x0698, 0x06a0, 0x06a8, 0x06b0, 0x06b8, + 0x06c0, 0x06c8, 0x06d0, 0x06d8, 0x06e0, 0x06e8, 0x06f0, 0x06f8, + 0x0700, 0x0708, 0x0710, 0x0718, 0x0720, 0x0728, 0x0730, 0x0738, + 0x0740, 0x0748, 0x0750, 0x0758, 0x0760, 0x0768, 0x0770, 0x0778, + 0x0780, 0x0788, 0x0790, 0x0798, 0x07a0, 0x07a8, 0x07b0, 0x07b8, + 0x07c0, 0x07c8, 0x07d0, 0x07d8, 0x07e0, 0x07e8, 0x07f0, 0x07f8, + 0x0800, 0x0808, 0x0810, 0x0818, 0x0820, 0x0828, 0x0830, 0x0838, + 0x0840, 0x0848, 0x0850, 0x0858, 0x0860, 0x0868, 0x0870, 0x0878, + 0x0880, 0x0888, 0x0890, 0x0898, 0x08a0, 0x08a8, 0x08b0, 0x08b8, + 0x08c0, 0x08c8, 0x08d0, 0x08d8, 0x08e0, 0x08e8, 0x08f0, 0x08f8, + 0x0900, 0x0908, 0x0910, 0x0918, 0x0920, 0x0928, 0x0930, 0x0938, + 0x0940, 0x0948, 0x0950, 0x0958, 0x0960, 0x0968, 0x0970, 0x0978, + 0x0980, 0x0988, 0x0990, 0x0998, 0x09a0, 0x09a8, 0x09b0, 0x09b8, + 0x09c0, 0x09c8, 0x09d0, 0x09d8, 0x09e0, 0x09e8, 0x09f0, 0x09f8, + 0x0a00, 0x0a08, 0x0a10, 0x0a18, 0x0a20, 0x0a28, 0x0a30, 0x0a38, + 0x0a40, 0x0a48, 0x0a50, 0x0a58, 0x0a60, 0x0a68, 0x0a70, 0x0a78, + 0x0a80, 0x0a88, 0x0a90, 0x0a98, 0x0aa0, 0x0aa8, 0x0ab0, 0x0ab8, + 0x0ac0, 0x0ac8, 0x0ad0, 0x0ad8, 0x0ae0, 0x0ae8, 0x0af0, 0x0af8, + 0x0b00, 0x0b08, 0x0b10, 0x0b18, 0x0b20, 0x0b28, 0x0b30, 0x0b38, + 0x0b40, 0x0b48, 0x0b50, 0x0b58, 0x0b60, 0x0b68, 0x0b70, 0x0b78, + 0x0b80, 0x0b88, 0x0b90, 0x0b98, 0x0ba0, 0x0ba8, 0x0bb0, 0x0bb8, + 0x0bc0, 0x0bc8, 0x0bd0, 0x0bd8, 0x0be0, 0x0be8, 0x0bf0, 0x0bf8, + 0x0c00, 0x0c08, 0x0c10, 0x0c18, 0x0c20, 0x0c28, 0x0c30, 0x0c38, + 0x0c40, 0x0c48, 0x0c50, 0x0c58, 0x0c60, 0x0c68, 0x0c70, 0x0c78, + 0x0c80, 0x0c88, 0x0c90, 0x0c98, 0x0ca0, 0x0ca8, 0x0cb0, 0x0cb8, + 0x0cc0, 0x0cc8, 0x0cd0, 0x0cd8, 0x0ce0, 0x0ce8, 0x0cf0, 0x0cf8, + 0x0d00, 0x0d08, 0x0d10, 0x0d18, 0x0d20, 0x0d28, 0x0d30, 0x0d38, + 0x0d40, 0x0d48, 0x0d50, 0x0d58, 0x0d60, 0x0d68, 0x0d70, 0x0d78, + 0x0d80, 0x0d88, 0x0d90, 0x0d98, 0x0da0, 0x0da8, 0x0db0, 0x0db8, + 0x0dc0, 0x0dc8, 0x0dd0, 0x0dd8, 0x0de0, 0x0de8, 0x0df0, 0x0df8, + 0x0e00, 0x0e08, 0x0e10, 0x0e18, 0x0e20, 0x0e28, 0x0e30, 0x0e38, + 0x0e40, 0x0e48, 0x0e50, 0x0e58, 0x0e60, 0x0e68, 0x0e70, 0x0e78, + 0x0e80, 0x0e88, 0x0e90, 0x0e98, 0x0ea0, 0x0ea8, 0x0eb0, 0x0eb8, + 0x0ec0, 0x0ec8, 0x0ed0, 0x0ed8, 0x0ee0, 0x0ee8, 0x0ef0, 0x0ef8, + 0x0f00, 0x0f08, 0x0f10, 0x0f18, 0x0f20, 0x0f28, 0x0f30, 0x0f38, + 0x0f40, 0x0f48, 0x0f50, 0x0f58, 0x0f60, 0x0f68, 0x0f70, 0x0f78, + 0x0f80, 0x0f88, 0x0f90, 0x0f98, 0x0fa0, 0x0fa8, 0x0fb0, 0x0fb8, + 0x0fc0, 0x0fc8, 0x0fd0, 0x0fd8, 0x0fe0, 0x0fe8, 0x0ff0, 0x0ff8, + 0x8ff8, 0x8ff0, 0x8fe8, 0x8fe0, 0x8fd8, 0x8fd0, 0x8fc8, 0x8fc0, + 0x8fb8, 0x8fb0, 0x8fa8, 0x8fa0, 0x8f98, 0x8f90, 0x8f88, 0x8f80, + 0x8f78, 0x8f70, 0x8f68, 0x8f60, 0x8f58, 0x8f50, 0x8f48, 0x8f40, + 0x8f38, 0x8f30, 0x8f28, 0x8f20, 0x8f18, 0x8f10, 0x8f08, 0x8f00, + 0x8ef8, 0x8ef0, 0x8ee8, 0x8ee0, 0x8ed8, 0x8ed0, 0x8ec8, 0x8ec0, + 0x8eb8, 0x8eb0, 0x8ea8, 0x8ea0, 0x8e98, 0x8e90, 0x8e88, 0x8e80, + 0x8e78, 0x8e70, 0x8e68, 0x8e60, 0x8e58, 0x8e50, 0x8e48, 0x8e40, + 0x8e38, 0x8e30, 0x8e28, 0x8e20, 0x8e18, 0x8e10, 0x8e08, 0x8e00, + 0x8df8, 0x8df0, 0x8de8, 0x8de0, 0x8dd8, 0x8dd0, 0x8dc8, 0x8dc0, + 0x8db8, 0x8db0, 0x8da8, 0x8da0, 0x8d98, 0x8d90, 0x8d88, 0x8d80, + 0x8d78, 0x8d70, 0x8d68, 0x8d60, 0x8d58, 0x8d50, 0x8d48, 0x8d40, + 0x8d38, 0x8d30, 0x8d28, 0x8d20, 0x8d18, 0x8d10, 0x8d08, 0x8d00, + 0x8cf8, 0x8cf0, 0x8ce8, 0x8ce0, 0x8cd8, 0x8cd0, 0x8cc8, 0x8cc0, + 0x8cb8, 0x8cb0, 0x8ca8, 0x8ca0, 0x8c98, 0x8c90, 0x8c88, 0x8c80, + 0x8c78, 0x8c70, 0x8c68, 0x8c60, 0x8c58, 0x8c50, 0x8c48, 0x8c40, + 0x8c38, 0x8c30, 0x8c28, 0x8c20, 0x8c18, 0x8c10, 0x8c08, 0x8c00, + 0x8bf8, 0x8bf0, 0x8be8, 0x8be0, 0x8bd8, 0x8bd0, 0x8bc8, 0x8bc0, + 0x8bb8, 0x8bb0, 0x8ba8, 0x8ba0, 0x8b98, 0x8b90, 0x8b88, 0x8b80, + 0x8b78, 0x8b70, 0x8b68, 0x8b60, 0x8b58, 0x8b50, 0x8b48, 0x8b40, + 0x8b38, 0x8b30, 0x8b28, 0x8b20, 0x8b18, 0x8b10, 0x8b08, 0x8b00, + 0x8af8, 0x8af0, 0x8ae8, 0x8ae0, 0x8ad8, 0x8ad0, 0x8ac8, 0x8ac0, + 0x8ab8, 0x8ab0, 0x8aa8, 0x8aa0, 0x8a98, 0x8a90, 0x8a88, 0x8a80, + 0x8a78, 0x8a70, 0x8a68, 0x8a60, 0x8a58, 0x8a50, 0x8a48, 0x8a40, + 0x8a38, 0x8a30, 0x8a28, 0x8a20, 0x8a18, 0x8a10, 0x8a08, 0x8a00, + 0x89f8, 0x89f0, 0x89e8, 0x89e0, 0x89d8, 0x89d0, 0x89c8, 0x89c0, + 0x89b8, 0x89b0, 0x89a8, 0x89a0, 0x8998, 0x8990, 0x8988, 0x8980, + 0x8978, 0x8970, 0x8968, 0x8960, 0x8958, 0x8950, 0x8948, 0x8940, + 0x8938, 0x8930, 0x8928, 0x8920, 0x8918, 0x8910, 0x8908, 0x8900, + 0x88f8, 0x88f0, 0x88e8, 0x88e0, 0x88d8, 0x88d0, 0x88c8, 0x88c0, + 0x88b8, 0x88b0, 0x88a8, 0x88a0, 0x8898, 0x8890, 0x8888, 0x8880, + 0x8878, 0x8870, 0x8868, 0x8860, 0x8858, 0x8850, 0x8848, 0x8840, + 0x8838, 0x8830, 0x8828, 0x8820, 0x8818, 0x8810, 0x8808, 0x8800, + 0x87f8, 0x87f0, 0x87e8, 0x87e0, 0x87d8, 0x87d0, 0x87c8, 0x87c0, + 0x87b8, 0x87b0, 0x87a8, 0x87a0, 0x8798, 0x8790, 0x8788, 0x8780, + 0x8778, 0x8770, 0x8768, 0x8760, 0x8758, 0x8750, 0x8748, 0x8740, + 0x8738, 0x8730, 0x8728, 0x8720, 0x8718, 0x8710, 0x8708, 0x8700, + 0x86f8, 0x86f0, 0x86e8, 0x86e0, 0x86d8, 0x86d0, 0x86c8, 0x86c0, + 0x86b8, 0x86b0, 0x86a8, 0x86a0, 0x8698, 0x8690, 0x8688, 0x8680, + 0x8678, 0x8670, 0x8668, 0x8660, 0x8658, 0x8650, 0x8648, 0x8640, + 0x8638, 0x8630, 0x8628, 0x8620, 0x8618, 0x8610, 0x8608, 0x8600, + 0x85f8, 0x85f0, 0x85e8, 0x85e0, 0x85d8, 0x85d0, 0x85c8, 0x85c0, + 0x85b8, 0x85b0, 0x85a8, 0x85a0, 0x8598, 0x8590, 0x8588, 0x8580, + 0x8578, 0x8570, 0x8568, 0x8560, 0x8558, 0x8550, 0x8548, 0x8540, + 0x8538, 0x8530, 0x8528, 0x8520, 0x8518, 0x8510, 0x8508, 0x8500, + 0x84f8, 0x84f0, 0x84e8, 0x84e0, 0x84d8, 0x84d0, 0x84c8, 0x84c0, + 0x84b8, 0x84b0, 0x84a8, 0x84a0, 0x8498, 0x8490, 0x8488, 0x8480, + 0x8478, 0x8470, 0x8468, 0x8460, 0x8458, 0x8450, 0x8448, 0x8440, + 0x8438, 0x8430, 0x8428, 0x8420, 0x8418, 0x8410, 0x8408, 0x8400, + 0x83f8, 0x83f0, 0x83e8, 0x83e0, 0x83d8, 0x83d0, 0x83c8, 0x83c0, + 0x83b8, 0x83b0, 0x83a8, 0x83a0, 0x8398, 0x8390, 0x8388, 0x8380, + 0x8378, 0x8370, 0x8368, 0x8360, 0x8358, 0x8350, 0x8348, 0x8340, + 0x8338, 0x8330, 0x8328, 0x8320, 0x8318, 0x8310, 0x8308, 0x8300, + 0x82f8, 0x82f0, 0x82e8, 0x82e0, 0x82d8, 0x82d0, 0x82c8, 0x82c0, + 0x82b8, 0x82b0, 0x82a8, 0x82a0, 0x8298, 0x8290, 0x8288, 0x8280, + 0x8278, 0x8270, 0x8268, 0x8260, 0x8258, 0x8250, 0x8248, 0x8240, + 0x8238, 0x8230, 0x8228, 0x8220, 0x8218, 0x8210, 0x8208, 0x8200, + 0x81f8, 0x81f0, 0x81e8, 0x81e0, 0x81d8, 0x81d0, 0x81c8, 0x81c0, + 0x81b8, 0x81b0, 0x81a8, 0x81a0, 0x8198, 0x8190, 0x8188, 0x8180, + 0x8178, 0x8170, 0x8168, 0x8160, 0x8158, 0x8150, 0x8148, 0x8140, + 0x8138, 0x8130, 0x8128, 0x8120, 0x8118, 0x8110, 0x8108, 0x8100, + 0x80f8, 0x80f0, 0x80e8, 0x80e0, 0x80d8, 0x80d0, 0x80c8, 0x80c0, + 0x80b8, 0x80b0, 0x80a8, 0x80a0, 0x8098, 0x8090, 0x8088, 0x8080, + 0x8078, 0x8070, 0x8068, 0x8060, 0x8058, 0x8050, 0x8048, 0x8040, + 0x8038, 0x8030, 0x8028, 0x8020, 0x8018, 0x8010, 0x8008, 0x8000, +}; + +/* + * Inverse exponent table extracted from OPL3 ROM; taken straight from + * Nuked OPL3 source code. + * TODO: Verify if ESFM uses an exponent table or if it possibly uses another + * method to skirt around Yamaha's patents? + * Optimization: All entries are shifted left by one from the actual data in + * OPL3's ROM. + */ +static const uint16_t exprom[256] = { + 0xff4, 0xfea, 0xfde, 0xfd4, 0xfc8, 0xfbe, 0xfb4, 0xfa8, + 0xf9e, 0xf92, 0xf88, 0xf7e, 0xf72, 0xf68, 0xf5c, 0xf52, + 0xf48, 0xf3e, 0xf32, 0xf28, 0xf1e, 0xf14, 0xf08, 0xefe, + 0xef4, 0xeea, 0xee0, 0xed4, 0xeca, 0xec0, 0xeb6, 0xeac, + 0xea2, 0xe98, 0xe8e, 0xe84, 0xe7a, 0xe70, 0xe66, 0xe5c, + 0xe52, 0xe48, 0xe3e, 0xe34, 0xe2a, 0xe20, 0xe16, 0xe0c, + 0xe04, 0xdfa, 0xdf0, 0xde6, 0xddc, 0xdd2, 0xdca, 0xdc0, + 0xdb6, 0xdac, 0xda4, 0xd9a, 0xd90, 0xd88, 0xd7e, 0xd74, + 0xd6a, 0xd62, 0xd58, 0xd50, 0xd46, 0xd3c, 0xd34, 0xd2a, + 0xd22, 0xd18, 0xd10, 0xd06, 0xcfe, 0xcf4, 0xcec, 0xce2, + 0xcda, 0xcd0, 0xcc8, 0xcbe, 0xcb6, 0xcae, 0xca4, 0xc9c, + 0xc92, 0xc8a, 0xc82, 0xc78, 0xc70, 0xc68, 0xc60, 0xc56, + 0xc4e, 0xc46, 0xc3c, 0xc34, 0xc2c, 0xc24, 0xc1c, 0xc12, + 0xc0a, 0xc02, 0xbfa, 0xbf2, 0xbea, 0xbe0, 0xbd8, 0xbd0, + 0xbc8, 0xbc0, 0xbb8, 0xbb0, 0xba8, 0xba0, 0xb98, 0xb90, + 0xb88, 0xb80, 0xb78, 0xb70, 0xb68, 0xb60, 0xb58, 0xb50, + 0xb48, 0xb40, 0xb38, 0xb32, 0xb2a, 0xb22, 0xb1a, 0xb12, + 0xb0a, 0xb02, 0xafc, 0xaf4, 0xaec, 0xae4, 0xade, 0xad6, + 0xace, 0xac6, 0xac0, 0xab8, 0xab0, 0xaa8, 0xaa2, 0xa9a, + 0xa92, 0xa8c, 0xa84, 0xa7c, 0xa76, 0xa6e, 0xa68, 0xa60, + 0xa58, 0xa52, 0xa4a, 0xa44, 0xa3c, 0xa36, 0xa2e, 0xa28, + 0xa20, 0xa18, 0xa12, 0xa0c, 0xa04, 0x9fe, 0x9f6, 0x9f0, + 0x9e8, 0x9e2, 0x9da, 0x9d4, 0x9ce, 0x9c6, 0x9c0, 0x9b8, + 0x9b2, 0x9ac, 0x9a4, 0x99e, 0x998, 0x990, 0x98a, 0x984, + 0x97c, 0x976, 0x970, 0x96a, 0x962, 0x95c, 0x956, 0x950, + 0x948, 0x942, 0x93c, 0x936, 0x930, 0x928, 0x922, 0x91c, + 0x916, 0x910, 0x90a, 0x904, 0x8fc, 0x8f6, 0x8f0, 0x8ea, + 0x8e4, 0x8de, 0x8d8, 0x8d2, 0x8cc, 0x8c6, 0x8c0, 0x8ba, + 0x8b4, 0x8ae, 0x8a8, 0x8a2, 0x89c, 0x896, 0x890, 0x88a, + 0x884, 0x87e, 0x878, 0x872, 0x86c, 0x866, 0x860, 0x85a, + 0x854, 0x850, 0x84a, 0x844, 0x83e, 0x838, 0x832, 0x82c, + 0x828, 0x822, 0x81c, 0x816, 0x810, 0x80c, 0x806, 0x800 +}; + +/* + * Frequency multiplier table multiplied by 2; taken straight from Nuked OPL3 + * source code. + */ +static const uint8_t mt[16] = { + 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 20, 24, 24, 30, 30 +}; + +/* + * This is used during the envelope generation to apply KSL to the envelope by + * determining how much to shift right the keyscale attenuation value before + * adding it to the envelope level. + */ +static const uint8_t kslshift[4] = { + 8, 1, 2, 0 +}; + +/* + * This encodes which emulation mode channels are the secondary channel in a + * 4-op channel pair (where the entry is non-negative), and which is the + * corresponding primary channel for that secondary channel. + */ +static const int emu_4op_secondary_to_primary[18] = +{ + -1, -1, -1, 0, 1, 2, -1, -1, -1, + -1, -1, -1, 9, 10, 11, -1, -1, -1 +}; + +/* + * Envelope generator dither table, taken straight from Nuked OPL3 source code. + */ +static const uint8_t eg_incstep[4][4] = { + { 0, 0, 0, 0 }, + { 1, 0, 0, 0 }, + { 1, 0, 1, 0 }, + { 1, 1, 1, 0 } +}; + +/* ------------------------------------------------------------------------- */ +static inline int13 +ESFM_envelope_wavegen(uint3 waveform, int16 phase, uint10 envelope) +{ + int13 out; + uint16 lookup = logsinrom[((uint16)waveform << 10) | (phase & 0x3ff)]; + uint16 level = (lookup & 0x1fff) + (envelope << 3); + if (level > 0x1fff) + { + level = 0x1fff; + } + out = exprom[level & 0xff] >> (level >> 8); + if (lookup & 0x8000) + { + out = -out; + } + return out; +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_envelope_calc(esfm_slot *slot) +{ + uint8 nonzero; + uint8 rate; + uint5 rate_hi; + uint2 rate_lo; + uint4 reg_rate = 0; + uint4 ks; + uint8 eg_shift, shift; + bool eg_off; + uint9 eg_rout; + int16 eg_inc; + bool reset = 0; + bool key_on; + bool key_on_signal; + + key_on = *slot->in.key_on; + if (!slot->chip->native_mode) + { + int pair_primary_idx = emu_4op_secondary_to_primary[slot->channel->channel_idx]; + if (pair_primary_idx >= 0) + { + esfm_channel *pair_primary = &slot->channel->chip->channels[pair_primary_idx]; + if (pair_primary->emu_mode_4op_enable) + { + key_on = *pair_primary->slots[0].in.key_on; + } + } + else if ((slot->channel->channel_idx == 7 || slot->channel->channel_idx == 8) + && slot->slot_idx == 1) + { + key_on = slot->channel->key_on_2; + } + } + + slot->in.eg_output = slot->in.eg_position + (slot->t_level << 2) + + (slot->in.eg_ksl_offset >> kslshift[slot->ksl]); + if (slot->tremolo_en) + { + uint8 tremolo; + if (slot->chip->native_mode) + { + tremolo = slot->channel->chip->tremolo >> ((!slot->tremolo_deep << 1) + 2); + } + else + { + tremolo = slot->channel->chip->tremolo >> ((!slot->chip->emu_tremolo_deep << 1) + 2); + } + slot->in.eg_output += tremolo; + } + + if (slot->in.eg_delay_run && slot->in.eg_delay_counter < 32768) + { + slot->in.eg_delay_counter++; + } + + // triggers on key-on edge + if (key_on && !slot->in.key_on_gate) + { + slot->in.eg_delay_run = 1; + slot->in.eg_delay_counter = 0; + slot->in.eg_delay_transitioned_01 = 0; + slot->in.eg_delay_transitioned_01_gate = 0; + slot->in.eg_delay_transitioned_10 = 0; + slot->in.eg_delay_transitioned_10_gate = 0; + slot->in.eg_delay_counter_compare = 0; + if (slot->env_delay > 0) + { + slot->in.eg_delay_counter_compare = 256 << slot->env_delay; + } + } + else if (!key_on) + { + slot->in.eg_delay_run = 0; + } + + // TODO: is this really how the chip behaves? Can it only transition the envelope delay once? Am I implementing this in a sane way? I feel like this is a roundabout hack. + if ((slot->in.eg_delay_transitioned_10 && !slot->in.eg_delay_transitioned_10_gate) || + (slot->in.eg_delay_transitioned_01 && !slot->in.eg_delay_transitioned_01_gate) + ) + { + slot->in.eg_delay_counter_compare = 0; + if (slot->env_delay > 0) + { + slot->in.eg_delay_counter_compare = 256 << slot->env_delay; + } + if (slot->in.eg_delay_transitioned_10) + { + slot->in.eg_delay_transitioned_10_gate = 1; + } + if (slot->in.eg_delay_transitioned_01) + { + slot->in.eg_delay_transitioned_01_gate = 1; + } + } + + if (key_on && ((slot->in.eg_delay_counter >= slot->in.eg_delay_counter_compare) || !slot->chip->native_mode)) + { + key_on_signal = 1; + } else { + key_on_signal = 0; + } + + if (key_on && slot->in.eg_state == EG_RELEASE) + { + + if ((slot->in.eg_delay_counter >= slot->in.eg_delay_counter_compare) || !slot->chip->native_mode) + { + reset = 1; + reg_rate = slot->attack_rate; + } + else + { + reg_rate = slot->release_rate; + } + } + else + { + switch (slot->in.eg_state) + { + case EG_ATTACK: + reg_rate = slot->attack_rate; + break; + case EG_DECAY: + reg_rate = slot->decay_rate; + break; + case EG_SUSTAIN: + if (!slot->env_sustaining) + { + reg_rate = slot->release_rate; + } + break; + case EG_RELEASE: + reg_rate = slot->release_rate; + break; + } + } + slot->in.key_on_gate = key_on; + slot->in.phase_reset = reset; + ks = slot->in.keyscale >> ((!slot->ksr) << 1); + nonzero = (reg_rate != 0); + rate = ks + (reg_rate << 2); + rate_hi = rate >> 2; + rate_lo = rate & 0x03; + if (rate_hi & 0x10) + { + rate_hi = 0x0f; + } + eg_shift = rate_hi + slot->chip->eg_clocks; + shift = 0; + if (nonzero) + { + if (rate_hi < 12) + { + if (slot->chip->eg_tick) + { + switch (eg_shift) + { + case 12: + shift = 1; + break; + case 13: + shift = (rate_lo >> 1) & 0x01; + break; + case 14: + shift = rate_lo & 0x01; + break; + default: + break; + } + } + } + else + { + shift = (rate_hi & 0x03) + + eg_incstep[rate_lo][slot->chip->global_timer & 0x03]; + if (shift & 0x04) + { + shift = 0x03; + } + if (!shift) + { + shift = slot->chip->eg_tick; + } + } + } + eg_rout = slot->in.eg_position; + eg_inc = 0; + eg_off = 0; + /* Instant attack */ + if (reset && rate_hi == 0x0f) + { + eg_rout = 0x00; + } + /* Envelope off */ + if ((slot->in.eg_position & 0x1f8) == 0x1f8) + { + eg_off = 1; + } + if (slot->in.eg_state != EG_ATTACK && !reset && eg_off) + { + eg_rout = 0x1ff; + } + switch (slot->in.eg_state) + { + case EG_ATTACK: + if (slot->in.eg_position == 0) + { + slot->in.eg_state = EG_DECAY; + } + else if (key_on_signal && shift > 0 && rate_hi != 0x0f) + { + eg_inc = ~slot->in.eg_position >> (4 - shift); + } + break; + case EG_DECAY: + if ((slot->in.eg_position >> 4) == slot->sustain_lvl) + { + slot->in.eg_state = EG_SUSTAIN; + } + else if (!eg_off && !reset && shift > 0) + { + eg_inc = 1 << (shift - 1); + } + break; + case EG_SUSTAIN: + case EG_RELEASE: + if (!eg_off && !reset && shift > 0) + { + eg_inc = 1 << (shift - 1); + } + break; + } + slot->in.eg_position = (eg_rout + eg_inc) & 0x1ff; + /* Key off */ + if (reset) + { + slot->in.eg_state = EG_ATTACK; + } + if (!key_on_signal) + { + slot->in.eg_state = EG_RELEASE; + } +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_phase_generate(esfm_slot *slot) +{ + esfm_chip *chip; + uint10 f_num; + uint32 basefreq; + bool rm_xor, n_bit; + uint23 noise; + uint10 phase; + + chip = slot->chip; + f_num = slot->f_num; + if (slot->vibrato_en) + { + int8_t range; + uint8_t vibpos; + + range = (f_num >> 7) & 7; + vibpos = chip->vibrato_pos; + + if (!(vibpos & 3)) + { + range = 0; + } + else if (vibpos & 1) + { + range >>= 1; + } + range >>= !slot->vibrato_deep; + + if (vibpos & 4) + { + range = -range; + } + f_num += range; + } + basefreq = (f_num << slot->block) >> 1; + phase = (uint10)(slot->in.phase_acc >> 9); + if (slot->in.phase_reset) + { + slot->in.phase_acc = 0; + } + slot->in.phase_acc += (basefreq * mt[slot->mult]) >> 1; + slot->in.phase_acc &= (1 << 19) - 1; + slot->in.phase_out = phase; + /* Noise mode (rhythm) sounds */ + noise = chip->lfsr; + if (slot->slot_idx == 3 && slot->rhy_noise) + { + esfm_slot *prev_slot = &slot->channel->slots[2]; + + chip->rm_hh_bit2 = (phase >> 2) & 1; + chip->rm_hh_bit3 = (phase >> 3) & 1; + chip->rm_hh_bit7 = (phase >> 7) & 1; + chip->rm_hh_bit8 = (phase >> 8) & 1; + + chip->rm_tc_bit3 = (prev_slot->in.phase_out >> 3) & 1; + chip->rm_tc_bit5 = (prev_slot->in.phase_out >> 5) & 1; + + rm_xor = (chip->rm_hh_bit2 ^ chip->rm_hh_bit7) + | (chip->rm_hh_bit3 ^ chip->rm_tc_bit5) + | (chip->rm_tc_bit3 ^ chip->rm_tc_bit5); + + switch(slot->rhy_noise) + { + case 1: + // SD + slot->in.phase_out = (chip->rm_hh_bit8 << 9) + | ((chip->rm_hh_bit8 ^ (noise & 1)) << 8); + break; + case 2: + // HH + slot->in.phase_out = rm_xor << 9; + if (rm_xor ^ (noise & 1)) + { + slot->in.phase_out |= 0xd0; + } + else + { + slot->in.phase_out |= 0x34; + } + break; + case 3: + // TC + slot->in.phase_out = (rm_xor << 9) | 0x80; + break; + } + } + + n_bit = ((noise >> 14) ^ noise) & 0x01; + chip->lfsr = (noise >> 1) | (n_bit << 22); +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_phase_generate_emu(esfm_slot *slot) +{ + esfm_chip *chip; + uint3 block; + uint10 f_num; + uint32 basefreq; + bool rm_xor, n_bit; + uint23 noise; + uint10 phase; + int pair_primary_idx; + + chip = slot->chip; + block = slot->channel->slots[0].block; + f_num = slot->channel->slots[0].f_num; + + pair_primary_idx = emu_4op_secondary_to_primary[slot->channel->channel_idx]; + if (pair_primary_idx >= 0) + { + esfm_channel *pair_primary = &slot->channel->chip->channels[pair_primary_idx]; + if (pair_primary->emu_mode_4op_enable) + { + block = pair_primary->slots[0].block; + f_num = pair_primary->slots[0].f_num; + } + } + + if (slot->vibrato_en) + { + int8_t range; + uint8_t vibpos; + + range = (f_num >> 7) & 7; + vibpos = chip->vibrato_pos; + + if (!(vibpos & 3)) + { + range = 0; + } + else if (vibpos & 1) + { + range >>= 1; + } + range >>= !chip->emu_vibrato_deep; + + if (vibpos & 4) + { + range = -range; + } + f_num += range; + } + basefreq = (f_num << block) >> 1; + phase = (uint10)(slot->in.phase_acc >> 9); + if (slot->in.phase_reset) + { + slot->in.phase_acc = 0; + } + slot->in.phase_acc += (basefreq * mt[slot->mult]) >> 1; + slot->in.phase_acc &= (1 << 19) - 1; + slot->in.phase_out = phase; + + /* Noise mode (rhythm) sounds */ + noise = chip->lfsr; + // HH + if (slot->channel->channel_idx == 7 && slot->slot_idx == 0) + { + chip->rm_hh_bit2 = (phase >> 2) & 1; + chip->rm_hh_bit3 = (phase >> 3) & 1; + chip->rm_hh_bit7 = (phase >> 7) & 1; + chip->rm_hh_bit8 = (phase >> 8) & 1; + } + // TC + if (slot->channel->channel_idx == 8 && slot->slot_idx == 1) + { + chip->rm_tc_bit3 = (phase >> 3) & 1; + chip->rm_tc_bit5 = (phase >> 5) & 1; + } + if (chip->emu_rhy_mode_flags & 0x20) + { + rm_xor = (chip->rm_hh_bit2 ^ chip->rm_hh_bit7) + | (chip->rm_hh_bit3 ^ chip->rm_tc_bit5) + | (chip->rm_tc_bit3 ^ chip->rm_tc_bit5); + if (slot->channel->channel_idx == 7) + { + if (slot->slot_idx == 0) { + // HH + slot->in.phase_out = rm_xor << 9; + if (rm_xor ^ (noise & 1)) + { + slot->in.phase_out |= 0xd0; + } + else + { + slot->in.phase_out |= 0x34; + } + } + else if (slot->slot_idx == 1) + { + // SD + slot->in.phase_out = (chip->rm_hh_bit8 << 9) + | ((chip->rm_hh_bit8 ^ (noise & 1)) << 8); + } + } + else if (slot->channel->channel_idx == 8 && slot->slot_idx == 1) + { + // TC + slot->in.phase_out = (rm_xor << 9) | 0x80; + } + } + + n_bit = ((noise >> 14) ^ noise) & 0x01; + chip->lfsr = (noise >> 1) | (n_bit << 22); +} + +/** + * TODO: Figure out what's ACTUALLY going on inside the real chip! + * This is not accurate at all, but it's the closest I was able to get with + * empirical testing (and it's closer than nothing). + */ +/* ------------------------------------------------------------------------- */ +static int16 +ESFM_slot3_noise3_mod_input_calc(esfm_slot *slot) +{ + esfm_channel *channel = slot->channel; + int16 phase; + int13 output_buf = *channel->slots[1].in.mod_input; + int i; + + // Go through previous slots' partial results and recalculate outputs + // (we skip slot 0 because its calculation happens at the end, not at the beginning) + for (i = 1; i < 3; i++) + { + // double the pitch + phase = channel->slots[i].in.phase_acc >> 8; + if (channel->slots[i].mod_in_level) + { + phase += output_buf >> (7 - channel->slots[i].mod_in_level); + } + output_buf = ESFM_envelope_wavegen(channel->slots[2].waveform, phase, channel->slots[i].in.eg_output); + } + + return output_buf >> (8 - slot->mod_in_level); +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_slot_generate(esfm_slot *slot) +{ + int16 phase = slot->in.phase_out; + if (slot->mod_in_level) + { + if (slot->slot_idx == 3 && slot->rhy_noise == 3) + { + phase += ESFM_slot3_noise3_mod_input_calc(slot); + } + else + { + phase += *slot->in.mod_input >> (7 - slot->mod_in_level); + } + } + slot->in.output = ESFM_envelope_wavegen(slot->waveform, phase, slot->in.eg_output); + if (slot->output_level) + { + int13 output_value = slot->in.output >> (7 - slot->output_level); + slot->channel->output[0] += output_value & slot->out_enable[0]; + slot->channel->output[1] += output_value & slot->out_enable[1]; + } +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_slot_generate_emu(esfm_slot *slot) +{ + const esfm_chip *chip = slot->chip; + uint3 waveform = slot->waveform & (chip->emu_newmode != 0 ? 0x07 : 0x03); + bool rhythm_slot_double_volume = (slot->chip->emu_rhy_mode_flags & 0x20) != 0 + && slot->channel->channel_idx >= 6 && slot->channel->channel_idx < 9; + int16 phase = slot->in.phase_out; + int14 output_value; + + phase += *slot->in.mod_input & slot->in.emu_mod_enable; + slot->in.output = ESFM_envelope_wavegen(waveform, phase, slot->in.eg_output); + output_value = (slot->in.output & slot->in.emu_output_enable) << rhythm_slot_double_volume; + if (chip->emu_newmode) + { + slot->channel->output[0] += output_value & slot->channel->slots[0].out_enable[0]; + slot->channel->output[1] += output_value & slot->channel->slots[0].out_enable[1]; + } + else + { + slot->channel->output[0] += output_value; + slot->channel->output[1] += output_value; + } +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_process_feedback(esfm_chip *chip) +{ + int channel_idx; + + for (channel_idx = 0; channel_idx < 18; channel_idx++) + { + esfm_slot *slot = &chip->channels[channel_idx].slots[0]; + uint32 basefreq, phase_offset; + uint3 block; + uint10 f_num; + int32_t wave_out, wave_last; + int32_t phase_feedback; + uint32_t iter_counter; + uint3 waveform; + uint3 mod_in_shift; + uint32_t phase, phase_acc; + uint10 eg_output; + + if (slot->mod_in_level && (chip->native_mode || (slot->in.mod_input == &slot->in.feedback_buf))) + { + if (chip->native_mode) + { + waveform = slot->waveform; + } + else + { + waveform = slot->waveform & (0x03 | (0x02 << (chip->emu_newmode != 0))); + } + f_num = slot->f_num; + block = slot->block; + basefreq = (f_num << block) >> 1; + phase_offset = (basefreq * mt[slot->mult]) >> 1; + mod_in_shift = 7 - slot->mod_in_level; + phase_acc = (uint32_t)(slot->in.phase_acc - phase_offset * 28); + eg_output = slot->in.eg_output; + + // ASM optimizaions! +#if defined(__GNUC__) && defined(__x86_64__) + asm ( + "movzbq %[wave], %%r8 \n\t" + "shll $11, %%r8d \n\t" + "leaq %[sinrom], %%rax \n\t" + "addq %%rax, %%r8 \n\t" + "leaq %[exprom], %%r9 \n\t" + "movzwl %[eg_out], %%r10d \n\t" + "shll $3, %%r10d \n\t" + "xorl %%r11d, %%r11d \n\t" + "movl %%r11d, %[out] \n\t" + "movl $29, %%edx \n" + "1: \n\t" + // phase_feedback = (wave_out + wave_last) >> 2; + "movl %[out], %[p_fb] \n\t" + "addl %%r11d, %[p_fb] \n\t" + "sarl $2, %[p_fb] \n\t" + // wave_last = wave_out + "movl %[out], %%r11d \n\t" + // phase = phase_feedback >> mod_in_shift; + "movl %[p_fb], %%eax \n\t" + "movb %[mod_in], %%cl \n\t" + "sarl %%cl, %%eax \n\t" + // phase += phase_acc >> 9; + "movl %[p_acc], %%ebx \n\t" + "sarl $9, %%ebx \n\t" + "addl %%ebx, %%eax \n\t" + // lookup = logsinrom[(waveform << 10) | (phase & 0x3ff)]; + "andq $0x3ff, %%rax \n\t" + "movzwl (%%r8, %%rax, 2), %%ebx \n\t" + "movl %%ebx, %%eax \n\t" + // level = (lookup & 0x1fff) + (envelope << 3); + "movl $0x1fff, %%ecx \n\t" + "andl %%ecx, %%eax \n\t" + "addl %%r10d, %%eax \n\t" + // if (level > 0x1fff) level = 0x1fff; + "cmpl %%ecx, %%eax \n\t" + "cmoval %%ecx, %%eax \n\t" + // wave_out = exprom[level & 0xff] >> (level >> 8); + "movb %%ah, %%cl \n\t" + "movzbl %%al, %%eax \n\t" + "movzwl (%%r9, %%rax, 2), %[out] \n\t" + "shrl %%cl, %[out] \n\t" + // if (lookup & 0x8000) wave_out = -wave_out; + // in other words, lookup is negative + "movl %[out], %%ecx \n\t" + "negl %%ecx \n\t" + "testw %%bx, %%bx \n\t" + "cmovsl %%ecx, %[out] \n\t" + // phase_acc += phase_offset + "addl %[p_off], %[p_acc] \n\t" + // loop + "decl %%edx \n\t" + "jne 1b \n\t" + : [p_fb] "=&r" (phase_feedback), + [p_acc] "+r" (phase_acc), + [out] "=&r" (wave_out) + : [p_off] "r" (phase_offset), + [mod_in] "r" (mod_in_shift), + [wave] "g" (waveform), + [eg_out] "g" (eg_output), + [sinrom] "m" (logsinrom), + [exprom] "m" (exprom) + : "cc", "ax", "bx", "cx", "dx", "r8", "r9", "r10", "r11" + ); +#elif defined(__GNUC__) && defined(__i386__) + asm ( + "movzbl %b[wave], %%eax \n\t" + "shll $11, %%eax \n\t" + "leal %[sinrom], %%edi \n\t" + "addl %%eax, %%edi \n\t" + "shlw $3, %[eg_out] \n\t" + "xorl %[out], %[out] \n\t" + "movl %[out], %[last] \n\t" + "movl $29, %[i] \n" + "1: \n\t" + // phase_feedback = (wave_out + wave_last) >> 2; + "movl %[out], %%eax \n\t" + "addl %[last], %%eax \n\t" + "sarl $2, %%eax \n\t" + "movl %%eax, %[p_fb] \n\t" + // wave_last = wave_out + "movl %[out], %[last] \n\t" + // phase = phase_feedback >> mod_in_shift; + "movb %[mod_in], %%cl \n\t" + "sarl %%cl, %%eax \n\t" + // phase += phase_acc >> 9; + "movl %[p_acc], %%ebx \n\t" + "shrl $9, %%ebx \n\t" + "addl %%ebx, %%eax \n\t" + // lookup = logsinrom[(waveform << 10) | (phase & 0x3ff)]; + "andl $0x3ff, %%eax \n\t" + "movzwl (%%edi, %%eax, 2), %%ebx \n\t" + "movl %%ebx, %%eax \n\t" + // level = (lookup & 0x1fff) + (envelope << 3); + "movl $0x1fff, %%ecx \n\t" + "andl %%ecx, %%eax \n\t" + "addw %[eg_out], %%ax \n\t" + // if (level > 0x1fff) level = 0x1fff; + "cmpl %%ecx, %%eax \n\t" + "cmoval %%ecx, %%eax \n\t" + // wave_out = exprom[level & 0xff] >> (level >> 8); + "movb %%ah, %%cl \n\t" + "movzbl %%al, %%eax \n\t" + "leal %[exprom], %[out] \n\t" + "movzwl (%[out], %%eax, 2), %[out] \n\t" + "shrl %%cl, %[out] \n\t" + // if (lookup & 0x8000) wave_out = -wave_out; + // in other words, lookup is negative + "movl %[out], %%ecx \n\t" + "negl %%ecx \n\t" + "testw %%bx, %%bx \n\t" + "cmovsl %%ecx, %[out] \n\t" + // phase_acc += phase_offset + "addl %[p_off], %[p_acc] \n\t" + // loop + "decl %[i] \n\t" + "jne 1b \n\t" + : [p_fb] "=&m" (phase_feedback), + [p_acc] "+r" (phase_acc), + [out] "=&r" (wave_out), + [last] "=&m" (wave_last), + [eg_out] "+m" (eg_output) + : [p_off] "m" (phase_offset), + [mod_in] "m" (mod_in_shift), + [wave] "m" (waveform), + [sinrom] "m" (logsinrom), + [exprom] "m" (exprom), + [i] "m" (iter_counter) + : "cc", "ax", "bx", "cx", "di" + ); +#elif defined(__GNUC__) && defined(__arm__) + asm ( + "movs r3, #0 \n\t" + "movs %[out], #0 \n\t" + "ldr r8, =0x1fff \n\t" + "movs r2, #29 \n" + "1: \n\t" + // phase_feedback = (wave_out + wave_last) >> 2; + "adds %[p_fb], %[out], r3 \n\t" + "asrs %[p_fb], %[p_fb], #2 \n\t" + // wave_last = wave_out + "mov r3, %[out] \n\t" + // phase = phase_feedback >> mod_in_shift; + "asr r0, %[p_fb], %[mod_in] \n\t" + // phase += phase_acc >> 9; + "add r0, r0, %[p_acc], asr #9 \n\t" + // lookup = logsinrom[(waveform << 10) | (phase & 0x3ff)]; + "lsls r0, r0, #22 \n\t" + "lsrs r0, r0, #21 \n\t" + "ldrsh r1, [%[sinrom], r0] \n\t" + // level = (lookup & 0x1fff) + (envelope << 3); + "and r0, r8, r1 \n\t" + "add r0, r0, %[eg_out], lsl #3 \n\t" + // if (level > 0x1fff) level = 0x1fff; + "cmp r0, r8 \n\t" + "it hi \n\t" + "movhi r0, r8 \n\t" + // wave_out = exprom[level & 0xff] >> (level >> 8); + "lsrs %[out], r0, #8 \n\t" + "ands r0, r0, #255 \n\t" + "lsls r0, r0, #1 \n\t" + "ldrh r0, [%[exprom], r0] \n\t" + "lsr %[out], r0, %[out] \n\t" + // if (lookup & 0x8000) wave_out = -wave_out; + // in other words, lookup is negative + "tst r1, r1 \n\t" + "it mi \n\t" + "negmi %[out], %[out] \n\t" + // phase_acc += phase_offset + "adds %[p_acc], %[p_acc], %[p_off]\n\t" + // loop + "subs r2, r2, #1 \n\t" + "bne 1b \n\t" + : [p_fb] "=&r" (phase_feedback), + [p_acc] "+r" (phase_acc), + [out] "=&r" (wave_out) + : [p_off] "r" (phase_offset), + [mod_in] "r" (mod_in_shift), + [eg_out] "r" (eg_output), + [sinrom] "r" (logsinrom + waveform * 1024), + [exprom] "r" (exprom) + : "cc", "r0", "r1", "r2", "r3", "r8" + ); +#else + wave_out = 0; + wave_last = 0; + for (iter_counter = 0; iter_counter < 29; iter_counter++) + { + phase_feedback = (wave_out + wave_last) >> 2; + wave_last = wave_out; + phase = phase_feedback >> mod_in_shift; + phase += phase_acc >> 9; + wave_out = ESFM_envelope_wavegen(waveform, phase, eg_output); + phase_acc += phase_offset; + } +#endif + + // TODO: Figure out - is this how the ESFM chip does it, like the + // patent literally says? (it's really hacky...) + // slot->in.output = wave_out; + + // This would be the more canonical way to do it, reusing the rest of + // the synthesis pipeline to finish the calculation: + if (chip->native_mode) + { + slot->in.feedback_buf = phase_feedback; + } + else + { + slot->in.feedback_buf = phase_feedback >> (7 - slot->mod_in_level); + } + } + } +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_process_channel(esfm_channel *channel) +{ + int slot_idx; + channel->output[0] = channel->output[1] = 0; + for (slot_idx = 0; slot_idx < 4; slot_idx++) + { + esfm_slot *slot = &channel->slots[slot_idx]; + ESFM_envelope_calc(slot); + ESFM_phase_generate(slot); + if(slot_idx > 0) + { + ESFM_slot_generate(slot); + } + } + // ESFM feedback calculation takes a large number of clock cycles, so + // defer slot 0 generation to the end + // TODO: verify this behavior on real hardware +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_process_channel_emu(esfm_channel *channel) +{ + int slot_idx; + channel->output[0] = channel->output[1] = 0; + for (slot_idx = 0; slot_idx < 2; slot_idx++) + { + esfm_slot *slot = &channel->slots[slot_idx]; + ESFM_envelope_calc(slot); + ESFM_phase_generate_emu(slot); + if(slot_idx > 0) + { + ESFM_slot_generate_emu(slot); + } + } + // ESFM feedback calculation takes a large number of clock cycles, so + // defer slot 0 generation to the end + // TODO: verify this behavior on real hardware +} + +/* ------------------------------------------------------------------------- */ +static int16_t +ESFM_clip_sample(int32 sample) +{ + // TODO: Supposedly, the real ESFM chip actually overflows rather than + // clipping. Verify that. + if (sample > 32767) + { + sample = 32767; + } + else if (sample < -32768) + { + sample = -32768; + } + return (int16_t)sample; +} + +#define TIMER1_CONST (0.2517482517482517) +#define TIMER2_CONST (0.06293706293706293) +/* ------------------------------------------------------------------------- */ +static void +ESFM_update_timers(esfm_chip *chip) +{ + int i; + // Tremolo + if ((chip->global_timer & 0x3f) == 0x3f) + { + chip->tremolo_pos = (chip->tremolo_pos + 1) % 210; + if (chip->tremolo_pos < 105) + { + chip->tremolo = chip->tremolo_pos; + } + else + { + chip->tremolo = (210 - chip->tremolo_pos); + } + } + + // Vibrato + if ((chip->global_timer & 0x3ff) == 0x3ff) + { + chip->vibrato_pos = (chip->vibrato_pos + 1) & 0x07; + } + + chip->global_timer = (chip->global_timer + 1) & 0x3ff; + + // Envelope generator dither clocks + chip->eg_clocks = 0; + if (chip->eg_timer) + { + uint8 shift = 0; + while (shift < 36 && ((chip->eg_timer >> shift) & 1) == 0) + { + shift++; + } + + if (shift <= 12) + { + chip->eg_clocks = shift + 1; + } + } + + if (chip->eg_tick || chip->eg_timer_overflow) + { + if (chip->eg_timer == (1llu << 36) - 1) + { + chip->eg_timer = 0; + chip->eg_timer_overflow = 1; + } + else + { + chip->eg_timer++; + chip->eg_timer_overflow = 0; + } + } + + for (i = 0; i < 2; i++) + { + if (chip->timer_enable[i]) + { + chip->timer_accumulator[i] += i == 0 ? TIMER1_CONST : TIMER2_CONST; + if (chip->timer_accumulator[i] > 1.0) + { + chip->timer_accumulator[i] -= 1.0; + chip->timer_counter[i]++; + if (chip->timer_counter[i] == 0) + { + if (chip->timer_mask[i] == 0) + { + chip->timer_overflow[i] = true; + } + chip->timer_counter[i] = chip->timer_reload[i]; + } + } + } + } + + chip->eg_tick ^= 1; +} + +#define KEY_ON_REGS_START (18 * 4 * 8) +/* ------------------------------------------------------------------------- */ +int +ESFM_reg_write_chan_idx(esfm_chip *chip, uint16_t reg) +{ + int which_reg = -1; + if (chip->native_mode) + { + bool is_key_on_reg = reg >= KEY_ON_REGS_START && reg < (KEY_ON_REGS_START + 20); + if (is_key_on_reg) + { + which_reg = reg - KEY_ON_REGS_START; + } + } + else + { + uint8_t reg_low = reg & 0xff; + bool high = reg & 0x100; + bool is_key_on_reg = reg_low >= 0xb0 && reg_low < 0xb9; + if (is_key_on_reg) + { + which_reg = (reg_low & 0x0f) + high * 9; + } + } + + return which_reg; +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_update_write_buffer(esfm_chip *chip) +{ + esfm_write_buf *write_buf; + bool note_off_written[20]; + bool bassdrum_written = false; + int i; + for (i = 0; i < 20; i++) + { + note_off_written[i] = false; + } + while((write_buf = &chip->write_buf[chip->write_buf_start]), + write_buf->valid && write_buf->timestamp <= chip->write_buf_timestamp) + { + int is_which_note_on_reg = + ESFM_reg_write_chan_idx(chip, write_buf->address); + if (is_which_note_on_reg >= 0) + { + if ((chip->native_mode && (write_buf->data & 0x01) == 0) + || (!chip->native_mode && (write_buf->data & 0x20) == 0) + ) + { + // this is a note off command; note down that we got note off for this channel + note_off_written[is_which_note_on_reg] = true; + } + else + { + // this is a note on command; have we gotten a note off for this channel in this cycle? + if (note_off_written[is_which_note_on_reg]) + { + // we have a conflict; let the note off be processed first and defer the + // rest of the buffer to the next cycle + break; + } + } + } + if ((chip->native_mode && write_buf->address == 0x4bd) + || (!chip->native_mode && (write_buf->address & 0xff) == 0xbd) + ) + { + // bassdrum register write (rhythm mode note-on/off control) + // have we already written to the bassdrum register in this cycle + if (bassdrum_written) { + // we have a conflict + break; + } + bassdrum_written = true; + } + + write_buf->valid = 0; + ESFM_write_reg(chip, write_buf->address, write_buf->data); + chip->write_buf_start = (chip->write_buf_start + 1) % ESFM_WRITEBUF_SIZE; + } + + chip->write_buf_timestamp++; +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_generate(esfm_chip *chip, int16_t *buf) +{ + int channel_idx; + + chip->output_accm[0] = chip->output_accm[1] = 0; + for (channel_idx = 0; channel_idx < 18; channel_idx++) + { + esfm_channel *channel = &chip->channels[channel_idx]; + if (chip->native_mode) + { + ESFM_process_channel(channel); + } + else + { + ESFM_process_channel_emu(channel); + } + } + ESFM_process_feedback(chip); + for (channel_idx = 0; channel_idx < 18; channel_idx++) + { + esfm_channel *channel = &chip->channels[channel_idx]; + if (chip->native_mode) + { + ESFM_slot_generate(&channel->slots[0]); + } + else + { + ESFM_slot_generate_emu(&channel->slots[0]); + } + chip->output_accm[0] += channel->output[0]; + chip->output_accm[1] += channel->output[1]; + } + + buf[0] = ESFM_clip_sample(chip->output_accm[0]); + buf[1] = ESFM_clip_sample(chip->output_accm[1]); + + ESFM_update_timers(chip); + ESFM_update_write_buffer(chip); +} + +/* ------------------------------------------------------------------------- */ +int16_t +ESFM_get_channel_output_native(esfm_chip *chip, int channel_idx) +{ + int16_t result; + int32_t temp_mix = 0; + int i; + + if (channel_idx < 0 || channel_idx >= 18) + { + return 0; + } + + for (i = 0; i < 4; i++) + { + esfm_slot *slot = &chip->channels[channel_idx].slots[i]; + + if (slot->output_level) + { + int13 output_value = slot->in.output >> (7 - slot->output_level); + temp_mix += output_value & slot->out_enable[0]; + temp_mix += output_value & slot->out_enable[1]; + } + } + + if (temp_mix > 32767) + { + temp_mix = 32767; + } + else if (temp_mix < -32768) + { + temp_mix = -32768; + } + result = temp_mix; + return result; +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_generate_stream(esfm_chip *chip, int16_t *sndptr, uint32_t num_samples) +{ + uint32_t i; + + for (i = 0; i < num_samples; i++) + { + ESFM_generate(chip, sndptr); + sndptr += 2; + } +} diff --git a/src/sound/esfmu/esfm.h b/src/sound/esfmu/esfm.h new file mode 100644 index 000000000..41ac6983f --- /dev/null +++ b/src/sound/esfmu/esfm.h @@ -0,0 +1,289 @@ +/* + * ESFMu: emulator for the ESS "ESFM" enhanced OPL3 clone + * Copyright (C) 2023 Kagamiin~ + * + * ESFMu is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 2.1 + * of the License, or (at your option) any later version. + * + * ESFMu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ESFMu. If not, see . + */ + +/* + * ESFMu wouldn't have been possible without the hard work and dedication of + * the retro computer hardware research and preservation community. + * + * I'd like to thank: + * - Nuke.YKT + * Developer of Nuked OPL3, which was the basis for ESFMu's code and + * also a great learning resource on Yamaha FM synthesis for myself. + * Nuke.YKT also gives shoutouts on behalf of Nuked OPL3 to: + * - MAME Development Team(Jarek Burczynski, Tatsuyuki Satoh): + * Feedback and Rhythm part calculation information. + * - forums.submarine.org.uk(carbon14, opl3): + * Tremolo and phase generator calculation information. + * - OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): + * OPL2 ROMs. + * - siliconpr0n.org(John McMaster, digshadow): + * YMF262 and VRC VII decaps and die shots. + * - rainwarrior + * For performing the initial research on ESFM drivers and documenting + * ESS's patent on native mode operator organization. + * - jwt27 + * For kickstarting the ESFM research project and compiling rainwarrior's + * findings and more in an accessible document ("ESFM Demystified"). + * - pachuco/CatButts + * For documenting ESS's patent on ESFM's feedback implementation, which + * was vital in getting ESFMu's sound output to be accurate. + * - akumanatt + * For helping out with code optimization. + * - And everybody who helped out with real hardware testing + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _esfm_slot esfm_slot; +typedef struct _esfm_slot_internal esfm_slot_internal; +typedef struct _esfm_channel esfm_channel; +typedef struct _esfm_chip esfm_chip; + + +void ESFM_init (esfm_chip *chip); +void ESFM_write_reg (esfm_chip *chip, uint16_t address, uint8_t data); +void ESFM_write_reg_buffered (esfm_chip *chip, uint16_t address, uint8_t data); +void ESFM_write_reg_buffered_fast (esfm_chip *chip, uint16_t address, uint8_t data); +void ESFM_write_port (esfm_chip *chip, uint8_t offset, uint8_t data); +uint8_t ESFM_readback_reg (esfm_chip *chip, uint16_t address); +uint8_t ESFM_read_port (esfm_chip *chip, uint8_t offset); +void ESFM_generate(esfm_chip *chip, int16_t *buf); +void ESFM_generate_stream(esfm_chip *chip, int16_t *sndptr, uint32_t num_samples); +int16_t ESFM_get_channel_output_native(esfm_chip *chip, int channel_idx); + + +// These are fake types just for syntax sugar. +// Beware of their underlying types when reading/writing to them. +typedef uint8_t flag; +typedef uint8_t uint2; +typedef uint8_t uint3; +typedef uint8_t uint4; +typedef uint8_t uint5; +typedef uint8_t uint6; +typedef uint8_t uint8; +typedef uint16_t uint9; +typedef uint16_t uint10; +typedef uint16_t uint11; +typedef uint16_t uint12; +typedef uint16_t uint16; +typedef uint32_t uint19; +typedef uint32_t uint23; +typedef uint32_t uint32; +typedef uint64_t uint36; + +typedef int16_t int13; +typedef int16_t int14; +typedef int16_t int16; +typedef int32_t int32; + +enum eg_states +{ + EG_ATTACK, + EG_DECAY, + EG_SUSTAIN, + EG_RELEASE +}; + + +typedef struct _esfm_write_buf +{ + uint64_t timestamp; + uint16_t address; + uint8_t data; + flag valid; + +} esfm_write_buf; + +typedef struct _emu_slot_channel_mapping +{ + int channel_idx; + int slot_idx; + +} emu_slot_channel_mapping; + +typedef struct _esfm_slot_internal +{ + uint9 eg_position; + uint9 eg_ksl_offset; + uint10 eg_output; + + uint4 keyscale; + + int13 output; + int13 emu_output_enable; + int13 emu_mod_enable; + int13 feedback_buf; + int13 *mod_input; + + uint19 phase_acc; + uint10 phase_out; + flag phase_reset; + flag *key_on; + flag key_on_gate; + + uint2 eg_state; + flag eg_delay_run; + flag eg_delay_transitioned_10; + flag eg_delay_transitioned_10_gate; + flag eg_delay_transitioned_01; + flag eg_delay_transitioned_01_gate; + uint16 eg_delay_counter; + uint16 eg_delay_counter_compare; + +} esfm_slot_internal; + +struct _esfm_slot +{ + // Metadata + esfm_channel *channel; + esfm_chip *chip; + uint2 slot_idx; + + // Register data + int13 out_enable[2]; + uint10 f_num; + uint3 block; + uint3 output_level; + // a.k.a. feedback level in emu mode + uint3 mod_in_level; + + uint6 t_level; + uint4 mult; + uint3 waveform; + // Only for 4th slot + uint2 rhy_noise; + + uint4 attack_rate; + uint4 decay_rate; + uint4 sustain_lvl; + uint4 release_rate; + + flag tremolo_en; + flag tremolo_deep; + flag vibrato_en; + flag vibrato_deep; + flag emu_connection_typ; + flag env_sustaining; + flag ksr; + uint2 ksl; + uint3 env_delay; + // overlaps with env_delay bit 0 + // TODO: check if emu mode only uses this, or if it actually overwrites the channel field used by native mode + flag emu_key_on; + + // Internal state + esfm_slot_internal in; +}; + +struct _esfm_channel +{ + esfm_chip *chip; + esfm_slot slots[4]; + uint5 channel_idx; + int16 output[2]; + flag key_on; + flag emu_mode_4op_enable; + // Only for 17th and 18th channels + flag key_on_2; + flag emu_mode_4op_enable_2; +}; + +#define ESFM_WRITEBUF_SIZE 1024 +#define ESFM_WRITEBUF_DELAY 2 + +struct _esfm_chip +{ + esfm_channel channels[18]; + int32 output_accm[2]; + uint16 addr_latch; + + flag emu_wavesel_enable; + flag emu_newmode; + flag native_mode; + + flag keyscale_mode; + + // Global state + uint36 eg_timer; + uint10 global_timer; + uint8 eg_clocks; + flag eg_tick; + flag eg_timer_overflow; + uint8 tremolo; + uint8 tremolo_pos; + uint8 vibrato_pos; + uint23 lfsr; + + flag rm_hh_bit2; + flag rm_hh_bit3; + flag rm_hh_bit7; + flag rm_hh_bit8; + flag rm_tc_bit3; + flag rm_tc_bit5; + + // 0xbd register in emulation mode, exposed in 0x4bd in native mode + // ("bass drum" register) + uint8 emu_rhy_mode_flags; + + flag emu_vibrato_deep; + flag emu_tremolo_deep; + + double timer_accumulator[2]; + uint8 timer_reload[2]; + uint8 timer_counter[2]; + flag timer_enable[2]; + flag timer_mask[2]; + flag timer_overflow[2]; + flag irq_bit; + + // -- Test bits (NOT IMPLEMENTED) -- + // Halts the envelope generators from advancing. Written on bit 0, read back from bit 5. + flag test_bit_w0_r5_eg_halt; + /* + * Activates some sort of waveform test mode that amplifies the output volume greatly + * and continuously shifts the waveform table downwards, possibly also outputting the + * waveform's derivative? (it's so weird!) + */ + flag test_bit_1_distort; + // Seems to do nothing. + flag test_bit_2; + // Seems to do nothing. + flag test_bit_3; + // Appears to attenuate the output by about 3 dB. + flag test_bit_4_attenuate; + // Written on bit 5, read back from bit 0. Seems to do nothing. + flag test_bit_w5_r0; + // Resets all phase generators and holds them in the reset state while this bit is set. + flag test_bit_6_phase_stop_reset; + // Seems to do nothing. + flag test_bit_7; + + esfm_write_buf write_buf[ESFM_WRITEBUF_SIZE]; + size_t write_buf_start; + size_t write_buf_end; + uint64_t write_buf_timestamp; +}; + +#ifdef __cplusplus +} +#endif diff --git a/src/sound/esfmu/esfm_registers.c b/src/sound/esfmu/esfm_registers.c new file mode 100644 index 000000000..34ce8b19e --- /dev/null +++ b/src/sound/esfmu/esfm_registers.c @@ -0,0 +1,999 @@ +/* + * ESFMu: emulator for the ESS "ESFM" enhanced OPL3 clone + * Copyright (C) 2023 Kagamiin~ + * + * This file includes code and data from the Nuked OPL3 project, copyright (C) + * 2013-2023 Nuke.YKT. Its usage, modification and redistribution is allowed + * under the terms of the GNU Lesser General Public License version 2.1 or + * later. + * + * ESFMu is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 2.1 + * of the License, or (at your option) any later version. + * + * ESFMu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ESFMu. If not, see . + */ + +/* + * ESFMu wouldn't have been possible without the hard work and dedication of + * the retro computer hardware research and preservation community. + * + * I'd like to thank: + * - Nuke.YKT + * Developer of Nuked OPL3, which was the basis for ESFMu's code and + * also a great learning resource on Yamaha FM synthesis for myself. + * Nuke.YKT also gives shoutouts on behalf of Nuked OPL3 to: + * - MAME Development Team(Jarek Burczynski, Tatsuyuki Satoh): + * Feedback and Rhythm part calculation information. + * - forums.submarine.org.uk(carbon14, opl3): + * Tremolo and phase generator calculation information. + * - OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): + * OPL2 ROMs. + * - siliconpr0n.org(John McMaster, digshadow): + * YMF262 and VRC VII decaps and die shots. + * - rainwarrior + * For performing the initial research on ESFM drivers and documenting + * ESS's patent on native mode operator organization. + * - jwt27 + * For kickstarting the ESFM research project and compiling rainwarrior's + * findings and more in an accessible document ("ESFM Demystified"). + * - pachuco/CatButts + * For documenting ESS's patent on ESFM's feedback implementation, which + * was vital in getting ESFMu's sound output to be accurate. + * - And everybody who helped out with real hardware testing + */ + +#include "esfm.h" +#include +#include +#include +#include + + +/* + * Table of KSL values extracted from OPL3 ROM; taken straight from Nuked OPL3 + * source code. + * TODO: Check if ESFM uses the same KSL values. + */ + +static const int16 kslrom[16] = { + 0, 32, 40, 45, 48, 51, 53, 55, 56, 58, 59, 60, 61, 62, 63, 64 +}; + +/* + * This maps the low 5 bits of emulation mode address to an emulation mode + * slot; taken straight from Nuked OPL3. Used for decoding certain emulation + * mode address ranges. + */ +static const int8_t ad_slot[0x20] = { + 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, 9, 10, 11, -1, -1, + 12, 13, 14, 15, 16, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +/* + * This maps an emulation mode slot index to a tuple representing the + * corresponding native mode channel and slot. + */ +static const emu_slot_channel_mapping emu_slot_map[36] = +{ + { 0, 0}, { 1, 0}, { 2, 0}, { 0, 1}, { 1, 1}, { 2, 1}, + { 3, 0}, { 4, 0}, { 5, 0}, { 3, 1}, { 4, 1}, { 5, 1}, + { 6, 0}, { 7, 0}, { 8, 0}, { 6, 1}, { 7, 1}, { 8, 1}, + { 9, 0}, {10, 0}, {11, 0}, { 9, 1}, {10, 1}, {11, 1}, + {12, 0}, {13, 0}, {14, 0}, {12, 1}, {13, 1}, {14, 1}, + {15, 0}, {16, 0}, {17, 0}, {15, 1}, {16, 1}, {17, 1} +}; + +/* + * This encodes which emulation mode channels are the secondary channel in a + * 4-op channel pair (where the entry is non-negative), and which is the + * corresponding primary channel for that secondary channel. + */ +static const int emu_4op_secondary_to_primary[18] = +{ + -1, -1, -1, 0, 1, 2, -1, -1, -1, + -1, -1, -1, 9, 10, 11, -1, -1, -1 +}; + +/* + * This encodes the operator outputs to be enabled or disabled for + * each 4-op algorithm in emulation mode. + * Indices: FM+FM, FM+AM, AM+FM, AM+AM (lower channel MSB, upper channel LSB) + * Values: enable OP1, OP2, OP3, OP4 + */ +static const bool emu_4op_alg_output_enable[4][4] = +{ + {0, 0, 0, 1}, + {0, 1, 0, 1}, + {1, 0, 0, 1}, + {1, 0, 1, 1} +}; + +/* + * This encodes the operator interconnections to be enabled or disabled for + * each 4-op algorithm in emulation mode. + * Indices: FM+FM, FM+AM, AM+FM, AM+AM (lower channel MSB, upper channel LSB) + * Values: enable OP1FB, OP1->2, OP2->3, OP3->4 + */ +static const bool emu_4op_alg_mod_enable[4][4] = +{ + {1, 1, 1, 1}, + {1, 1, 0, 1}, + {1, 0, 1, 1}, + {1, 0, 1, 0} +}; + + +/* ------------------------------------------------------------------------- */ +static void +ESFM_emu_rearrange_connections(esfm_channel *channel) +{ + int secondary_to_primary; + + secondary_to_primary = emu_4op_secondary_to_primary[channel->channel_idx]; + if (secondary_to_primary >= 0) + { + esfm_channel *pair_primary = &channel->chip->channels[secondary_to_primary]; + if (pair_primary->emu_mode_4op_enable) + { + // always work from primary channel in pair when dealing with 4-op + channel = pair_primary; + } + } + + if (channel->emu_mode_4op_enable && (channel->channel_idx % 9) < 3 && channel->chip->emu_newmode) + { + esfm_channel *secondary = &channel->chip->channels[channel->channel_idx + 3]; + uint2 algorithm = ((channel->slots[0].emu_connection_typ != 0) << 1) + | (secondary->slots[0].emu_connection_typ != 0); + int i; + + secondary->slots[0].in.mod_input = &channel->slots[1].in.output; + + for (i = 0; i < 2; i++) + { + channel->slots[i].in.emu_mod_enable = + emu_4op_alg_mod_enable[algorithm][i] ? ~((int13) 0) : 0; + channel->slots[i].in.emu_output_enable = + emu_4op_alg_output_enable[algorithm][i] ? ~((int13) 0) : 0; + + secondary->slots[i].in.emu_mod_enable = + emu_4op_alg_mod_enable[algorithm][i + 2] ? ~((int13) 0) : 0; + secondary->slots[i].in.emu_output_enable = + emu_4op_alg_output_enable[algorithm][i + 2] ? ~((int13) 0) : 0; + } + } + else if ((channel->chip->emu_rhy_mode_flags & 0x20) != 0 + && (channel->channel_idx == 7 || channel->channel_idx == 8)) + { + channel->slots[0].in.emu_mod_enable = 0; + channel->slots[1].in.emu_mod_enable = 0; + channel->slots[0].in.emu_output_enable = ~((int13) 0); + channel->slots[1].in.emu_output_enable = ~((int13) 0); + } + else + { + channel->slots[0].in.mod_input = &channel->slots[0].in.feedback_buf; + + channel->slots[0].in.emu_mod_enable = ~((int13) 0); + channel->slots[0].in.emu_output_enable = + (channel->slots[0].emu_connection_typ != 0) ? ~((int13) 0) : 0; + channel->slots[1].in.emu_output_enable = ~((int13) 0); + channel->slots[1].in.emu_mod_enable = + (channel->slots[0].emu_connection_typ != 0) ? 0 : ~((int13) 0); + } +} + + +/* ------------------------------------------------------------------------- */ +static void +ESFM_emu_to_native_switch(esfm_chip *chip) +{ + size_t channel_idx, slot_idx; + for (channel_idx = 0; channel_idx < 18; channel_idx++) + { + for (slot_idx = 0; slot_idx < 4; slot_idx++) + { + esfm_channel *channel = &chip->channels[channel_idx]; + esfm_slot *slot = &channel->slots[slot_idx]; + + if (slot_idx == 0) + { + slot->in.mod_input = &slot->in.feedback_buf; + } + else + { + esfm_slot *prev_slot = &channel->slots[slot_idx - 1]; + slot->in.mod_input = &prev_slot->in.output; + } + } + } +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_native_to_emu_switch(esfm_chip *chip) +{ + size_t channel_idx; + for (channel_idx = 0; channel_idx < 18; channel_idx++) + { + ESFM_emu_rearrange_connections(&chip->channels[channel_idx]); + } +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_slot_update_keyscale(esfm_slot *slot) +{ + if (slot->slot_idx > 0 && !slot->chip->native_mode) + { + return; + } + + int16 ksl = (kslrom[slot->f_num >> 6] << 2) - ((0x08 - slot->block) << 5); + if (ksl < 0) + { + ksl = 0; + } + slot->in.eg_ksl_offset = ksl; + slot->in.keyscale = (slot->block << 1) + | ((slot->f_num >> (8 + !slot->chip->keyscale_mode)) & 0x01); +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_emu_channel_update_keyscale(esfm_channel *channel) +{ + int secondary_to_primary; + + secondary_to_primary = emu_4op_secondary_to_primary[channel->channel_idx]; + if (secondary_to_primary >= 0) + { + esfm_channel *pair_primary = &channel->chip->channels[secondary_to_primary]; + if (pair_primary->emu_mode_4op_enable) + { + // always work from primary channel in pair when dealing with 4-op + channel = pair_primary; + } + } + + ESFM_slot_update_keyscale(&channel->slots[0]); + channel->slots[1].in.eg_ksl_offset = channel->slots[0].in.eg_ksl_offset; + channel->slots[1].in.keyscale = channel->slots[0].in.keyscale; + + if (channel->emu_mode_4op_enable && (channel->channel_idx % 9) < 3 && channel->chip->emu_newmode) + { + int i; + esfm_channel *secondary = &channel->chip->channels[channel->channel_idx + 3]; + secondary->slots[0].f_num = channel->slots[0].f_num; + secondary->slots[0].block = channel->slots[0].block; + + for (i = 0; i < 2; i++) + { + secondary->slots[i].in.eg_ksl_offset = channel->slots[0].in.eg_ksl_offset; + secondary->slots[i].in.keyscale = channel->slots[0].in.keyscale; + } + } +} + +/* ------------------------------------------------------------------------- */ +static inline uint8_t +ESFM_slot_readback (esfm_slot *slot, uint8_t register_idx) +{ + uint8_t data = 0; + switch (register_idx & 0x07) + { + case 0x00: + data |= (slot->tremolo_en != 0) << 7; + data |= (slot->vibrato_en != 0) << 6; + data |= (slot->env_sustaining != 0) << 5; + data |= (slot->vibrato_en != 0) << 4; + data |= slot->mult & 0x0f; + break; + case 0x01: + data |= slot->ksl << 6; + data |= slot->t_level & 0x3f; + break; + case 0x02: + data |= slot->attack_rate << 4; + data |= slot->decay_rate & 0x0f; + break; + case 0x03: + data |= slot->sustain_lvl << 4; + data |= slot->release_rate & 0x0f; + break; + case 0x04: + data = slot->f_num & 0xff; + break; + case 0x05: + data |= slot->env_delay << 5; + data |= (slot->block & 0x07) << 2; + data |= (slot->f_num >> 8) & 0x03; + break; + case 0x06: + data |= (slot->tremolo_deep != 0) << 7; + data |= (slot->vibrato_deep != 0) << 6; + data |= (slot->out_enable[1] != 0) << 5; + data |= (slot->out_enable[0] != 0) << 4; + data |= (slot->mod_in_level & 0x07) << 1; + data |= slot->emu_connection_typ & 0x01; + break; + case 0x07: + data |= slot->output_level << 5; + data |= (slot->rhy_noise & 0x03) << 3; + data |= slot->waveform & 0x07; + break; + } + return data; +} + +/* ------------------------------------------------------------------------- */ +static inline void +ESFM_slot_write (esfm_slot *slot, uint8_t register_idx, uint8_t data) +{ + switch (register_idx & 0x07) + { + case 0x00: + slot->tremolo_en = (data & 0x80) != 0; + slot->vibrato_en = (data & 0x40) != 0; + slot->env_sustaining = (data & 0x20) != 0; + slot->ksr = (data & 0x10) != 0; + slot->mult = data & 0x0f; + break; + case 0x01: + slot->ksl = data >> 6; + slot->t_level = data & 0x3f; + ESFM_slot_update_keyscale(slot); + break; + case 0x02: + slot->attack_rate = data >> 4; + slot->decay_rate = data & 0x0f; + break; + case 0x03: + slot->sustain_lvl = data >> 4; + slot->release_rate = data & 0x0f; + break; + case 0x04: + slot->f_num = (slot->f_num & 0x300) | data; + ESFM_slot_update_keyscale(slot); + break; + case 0x05: + if (slot->env_delay < (data >> 5)) + { + slot->in.eg_delay_transitioned_01 = 1; + } + else if (slot->env_delay > (data >> 5)) + { + slot->in.eg_delay_transitioned_10 = 1; + } + slot->env_delay = data >> 5; + slot->emu_key_on = (data >> 5) & 0x01; + slot->block = (data >> 2) & 0x07; + slot->f_num = (slot->f_num & 0xff) | ((data & 0x03) << 8); + ESFM_slot_update_keyscale(slot); + break; + case 0x06: + slot->tremolo_deep = (data & 0x80) != 0; + slot->vibrato_deep = (data & 0x40) != 0; + slot->out_enable[1] = (data & 0x20) ? ~((int13) 0) : 0; + slot->out_enable[0] = (data & 0x10) ? ~((int13) 0) : 0; + slot->mod_in_level = (data >> 1) & 0x07; + slot->emu_connection_typ = data & 0x01; + break; + case 0x07: + slot->output_level = data >> 5; + slot->rhy_noise = (data >> 3) & 0x03; + slot->waveform = data & 0x07; + break; + } +} + +#define KEY_ON_REGS_START (18 * 4 * 8) +#define TIMER1_REG (0x402) +#define TIMER2_REG (0x403) +#define TIMER_SETUP_REG (0x404) +#define CONFIG_REG (0x408) +#define BASSDRUM_REG (0x4bd) +#define TEST_REG (0x501) +#define FOUROP_CONN_REG (0x504) +#define NATIVE_MODE_REG (0x505) + +/* ------------------------------------------------------------------------- */ +static void +ESFM_write_reg_native (esfm_chip *chip, uint16_t address, uint8_t data) +{ + int i; + address = address & 0x7ff; + + if (address < KEY_ON_REGS_START) + { + // Slot register write + size_t channel_idx = address >> 5; + size_t slot_idx = (address >> 3) & 0x03; + size_t register_idx = address & 0x07; + esfm_slot *slot = &chip->channels[channel_idx].slots[slot_idx]; + + ESFM_slot_write(slot, register_idx, data); + } + else if (address < KEY_ON_REGS_START + 16) + { + // Key-on registers + size_t channel_idx = (address - KEY_ON_REGS_START); + esfm_channel *channel = &chip->channels[channel_idx]; + channel->key_on = data & 0x01; + channel->emu_mode_4op_enable = (data & 0x02) != 0; + } + else if (address < KEY_ON_REGS_START + 20) + { + // Key-on channels 17 and 18 (each half) + size_t channel_idx = 16 + ((address & 0x02) >> 1); + bool second_half = address & 0x01; + esfm_channel *channel = &chip->channels[channel_idx]; + if (second_half) + { + channel->key_on_2 = data & 0x01; + channel->emu_mode_4op_enable_2 = (data & 0x02) != 0; + } + else + { + channel->key_on = data & 0x01; + channel->emu_mode_4op_enable = (data & 0x02) != 0; + } + } + else + { + switch (address & 0x5ff) + { + case TIMER1_REG: + chip->timer_reload[0] = data; + break; + case TIMER2_REG: + chip->timer_reload[1] = data; + break; + case TIMER_SETUP_REG: + if (data & 0x80) + { + chip->timer_overflow[0] = 0; + chip->timer_overflow[1] = 0; + chip->irq_bit = 0; + } + chip->timer_enable[0] = (data & 0x01) != 0; + chip->timer_enable[1] = (data & 0x02) != 0; + chip->timer_mask[0] = (data & 0x20) != 0; + chip->timer_mask[1] = (data & 0x40) != 0; + break; + case CONFIG_REG: + chip->keyscale_mode = (data & 0x40) != 0; + break; + case BASSDRUM_REG: + chip->emu_rhy_mode_flags = data & 0x3f; + chip->emu_vibrato_deep = (data & 0x40) != 0; + chip->emu_tremolo_deep = (data & 0x80) != 0; + break; + case FOUROP_CONN_REG: + for (i = 0; i < 3; i++) + { + chip->channels[i].emu_mode_4op_enable = (data >> i) & 0x01; + chip->channels[i + 9].emu_mode_4op_enable = (data >> (i + 3)) & 0x01; + } + break; + case TEST_REG: + chip->test_bit_w0_r5_eg_halt = (data & 0x01) | ((data & 0x20) != 0); + chip->test_bit_1_distort = (data & 0x02) != 0; + chip->test_bit_2 = (data & 0x04) != 0; + chip->test_bit_3 = (data & 0x08) != 0; + chip->test_bit_4_attenuate = (data & 0x10) != 0; + chip->test_bit_w5_r0 = (data & 0x20) != 0; + chip->test_bit_6_phase_stop_reset = (data & 0x40) != 0; + chip->test_bit_7 = (data & 0x80) != 0; + break; + } + } +} + +/* ------------------------------------------------------------------------- */ +static uint8_t +ESFM_readback_reg_native (esfm_chip *chip, uint16_t address) +{ + int i; + uint8_t data = 0; + address = address & 0x7ff; + + if (address < KEY_ON_REGS_START) + { + // Slot register read + size_t channel_idx = address >> 5; + size_t slot_idx = (address >> 3) & 0x03; + size_t register_idx = address & 0x07; + esfm_slot *slot = &chip->channels[channel_idx].slots[slot_idx]; + + data = ESFM_slot_readback(slot, register_idx); + } + else if (address < KEY_ON_REGS_START + 16) + { + // Key-on registers + size_t channel_idx = (address - KEY_ON_REGS_START); + esfm_channel *channel = &chip->channels[channel_idx]; + + data |= channel->key_on != 0; + data |= (channel->emu_mode_4op_enable != 0) << 1; + } + else if (address < KEY_ON_REGS_START + 20) + { + // Key-on channels 17 and 18 (each half) + size_t channel_idx = 16 + ((address & 0x02) >> 1); + bool second_half = address & 0x01; + esfm_channel *channel = &chip->channels[channel_idx]; + if (second_half) + { + data |= channel->key_on_2 != 0; + data |= (channel->emu_mode_4op_enable_2 != 0) << 1; + } + else + { + data |= channel->key_on != 0; + data |= (channel->emu_mode_4op_enable != 0) << 1; + } + } + else + { + switch (address & 0x5ff) + { + case TIMER1_REG: + data = chip->timer_reload[0]; + break; + case TIMER2_REG: + data = chip->timer_reload[1]; + break; + case TIMER_SETUP_REG: + data |= chip->timer_enable[0] != 0; + data |= (chip->timer_enable[1] != 0) << 1; + data |= (chip->timer_mask[0] != 0) << 5; + data |= (chip->timer_mask[1] != 0) << 6; + break; + case CONFIG_REG: + data |= (chip->keyscale_mode != 0) << 6; + break; + case BASSDRUM_REG: + data |= chip->emu_rhy_mode_flags; + data |= chip->emu_vibrato_deep << 6; + data |= chip->emu_tremolo_deep << 7; + break; + case TEST_REG: + data |= chip->test_bit_w5_r0 != 0; + data |= (chip->test_bit_1_distort != 0) << 1; + data |= (chip->test_bit_2 != 0) << 2; + data |= (chip->test_bit_3 != 0) << 3; + data |= (chip->test_bit_4_attenuate != 0) << 4; + data |= (chip->test_bit_w0_r5_eg_halt != 0) << 5; + data |= (chip->test_bit_6_phase_stop_reset != 0) << 6; + data |= (chip->test_bit_7 != 0) << 7; + break; + case FOUROP_CONN_REG: + for (i = 0; i < 3; i++) + { + data |= (chip->channels[i].emu_mode_4op_enable != 0) << i; + data |= (chip->channels[i + 9].emu_mode_4op_enable != 0) << (i + 3); + } + break; + case NATIVE_MODE_REG: + data |= (chip->emu_newmode != 0); + data |= (chip->native_mode != 0) << 7; + break; + } + } + return data; +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_write_reg_emu (esfm_chip *chip, uint16_t address, uint8_t data) +{ + bool high = (address & 0x100) != 0; + uint8_t reg = address & 0xff; + int emu_slot_idx = ad_slot[address & 0x1f]; + int natv_chan_idx = -1; + int natv_slot_idx = -1; + int emu_chan_idx = (reg & 0x0f) > 8 ? -1 : ((reg & 0x0f) + high * 9); + + if (emu_slot_idx >= 0) + { + if (high) + { + emu_slot_idx += 18; + } + + natv_chan_idx = emu_slot_map[emu_slot_idx].channel_idx; + natv_slot_idx = emu_slot_map[emu_slot_idx].slot_idx; + } + + if (reg == 0xbd) + { + chip->emu_rhy_mode_flags = data & 0x3f; + chip->emu_vibrato_deep = (data & 0x40) != 0; + chip->emu_tremolo_deep = (data & 0x80) != 0; + if (chip->emu_rhy_mode_flags & 0x20) + { + // TODO: check if writes to 0xbd actually affect the readable key-on flags at + // 0x246, 0x247, 0x248; and if there's any visible effect from the SD and TC flags + chip->channels[6].key_on = (data & 0x10) != 0; + chip->channels[7].key_on = (data & 0x01) != 0; + chip->channels[8].key_on = (data & 0x04) != 0; + chip->channels[7].key_on_2 = (data & 0x08) != 0; + chip->channels[8].key_on_2 = (data & 0x02) != 0; + } + ESFM_emu_rearrange_connections(&chip->channels[7]); + ESFM_emu_rearrange_connections(&chip->channels[8]); + return; + } + + switch(reg & 0xf0) + { + case 0x00: + if (high) + { + int i; + switch(reg & 0x0f) + { + case 0x01: + chip->emu_wavesel_enable = (data & 0x20) != 0; + break; + case 0x02: + chip->timer_reload[0] = data; + break; + case 0x03: + chip->timer_reload[1] = data; + break; + case 0x04: + for (i = 0; i < 3; i++) + { + chip->channels[i].emu_mode_4op_enable = (data >> i) & 0x01; + chip->channels[i + 9].emu_mode_4op_enable = (data >> (i + 3)) & 0x01; + } + for (i = 0; i < 6; i++) + { + ESFM_emu_rearrange_connections(&chip->channels[i]); + ESFM_emu_rearrange_connections(&chip->channels[i + 9]); + } + break; + case 0x05: + chip->emu_newmode = data & 0x01; + if ((data & 0x80) != 0) + { + chip->native_mode = 1; + ESFM_emu_to_native_switch(chip); + } + break; + case 0x08: + chip->keyscale_mode = (data & 0x40) != 0; + break; + } + } + else + { + switch(reg & 0x0f) + { + case 0x01: + chip->emu_wavesel_enable = (data & 0x20) != 0; + break; + case 0x02: + chip->timer_reload[0] = data; + break; + case 0x03: + chip->timer_reload[1] = data; + break; + case 0x04: + chip->timer_enable[0] = data & 0x01; + chip->timer_enable[1] = (data & 0x02) != 0; + chip->timer_mask[0] = (data & 0x20) != 0; + chip->timer_mask[1] = (data & 0x40) != 0; + if (data & 0x80) + { + chip->irq_bit = 0; + } + break; + case 0x08: + chip->keyscale_mode = (data & 0x40) != 0; + break; + } + } + break; + case 0x20: case 0x30: + if (emu_slot_idx >= 0) + { + ESFM_slot_write(&chip->channels[natv_chan_idx].slots[natv_slot_idx], 0x0, data); + } + break; + case 0x40: case 0x50: + if (emu_slot_idx >= 0) + { + ESFM_slot_write(&chip->channels[natv_chan_idx].slots[natv_slot_idx], 0x1, data); + ESFM_emu_channel_update_keyscale(&chip->channels[natv_chan_idx]); + } + break; + case 0x60: case 0x70: + if (emu_slot_idx >= 0) + { + ESFM_slot_write(&chip->channels[natv_chan_idx].slots[natv_slot_idx], 0x2, data); + } + break; + case 0x80: case 0x90: + if (emu_slot_idx >= 0) + { + ESFM_slot_write(&chip->channels[natv_chan_idx].slots[natv_slot_idx], 0x3, data); + } + break; + case 0xa0: + if (emu_chan_idx >= 0) + { + ESFM_slot_write(&chip->channels[emu_chan_idx].slots[0], 0x4, data); + ESFM_emu_channel_update_keyscale(&chip->channels[emu_chan_idx]); + } + break; + case 0xb0: + if (emu_chan_idx >= 0) + { + esfm_channel *channel = &chip->channels[emu_chan_idx]; + // TODO: check if emulation mode actually writes to the native mode key on registers + // it might only use slot 0's emu key on field... + channel->key_on = (data & 0x20) != 0; + if (channel->channel_idx == 7 || channel->channel_idx == 8) + { + channel->key_on_2 = (data & 0x20) != 0; + } + ESFM_slot_write(&channel->slots[0], 0x5, data); + ESFM_emu_channel_update_keyscale(&chip->channels[emu_chan_idx]); + } + break; + case 0xc0: + if (emu_chan_idx >= 0) + { + ESFM_slot_write(&chip->channels[emu_chan_idx].slots[0], 0x6, data); + ESFM_emu_rearrange_connections(&chip->channels[emu_chan_idx]); + } + break; + case 0xe0: case 0xf0: + if (emu_slot_idx >= 0) + { + ESFM_slot_write(&chip->channels[natv_chan_idx].slots[natv_slot_idx], 0x7, data); + } + break; + } +} + + +/* ------------------------------------------------------------------------- */ +void +ESFM_write_reg (esfm_chip *chip, uint16_t address, uint8_t data) +{ + if (chip->native_mode) + { + ESFM_write_reg_native(chip, address, data); + return; + } + else + { + ESFM_write_reg_emu(chip, address, data); + return; + } +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_write_reg_buffered (esfm_chip *chip, uint16_t address, uint8_t data) +{ + uint64_t timestamp; + esfm_write_buf *new_entry, *last_entry; + + new_entry = &chip->write_buf[chip->write_buf_end]; + last_entry = &chip->write_buf[(chip->write_buf_end - 1) % ESFM_WRITEBUF_SIZE]; + + if (new_entry->valid) { + ESFM_write_reg(chip, new_entry->address, new_entry->data); + chip->write_buf_start = (chip->write_buf_end + 1) % ESFM_WRITEBUF_SIZE; + } + + new_entry->valid = 1; + new_entry->address = address; + new_entry->data = data; + timestamp = last_entry->timestamp + ESFM_WRITEBUF_DELAY; + if (timestamp < chip->write_buf_timestamp) + { + timestamp = chip->write_buf_timestamp; + } + + new_entry->timestamp = timestamp; + chip->write_buf_end = (chip->write_buf_end + 1) % ESFM_WRITEBUF_SIZE; +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_write_reg_buffered_fast (esfm_chip *chip, uint16_t address, uint8_t data) +{ + esfm_write_buf *new_entry; + + new_entry = &chip->write_buf[chip->write_buf_end]; + + if (new_entry->valid) { + ESFM_write_reg(chip, new_entry->address, new_entry->data); + chip->write_buf_start = (chip->write_buf_end + 1) % ESFM_WRITEBUF_SIZE; + } + + new_entry->valid = 1; + new_entry->address = address; + new_entry->data = data; + new_entry->timestamp = chip->write_buf_timestamp; + chip->write_buf_end = (chip->write_buf_end + 1) % ESFM_WRITEBUF_SIZE; +} + +/* ------------------------------------------------------------------------- */ +uint8_t +ESFM_readback_reg (esfm_chip *chip, uint16_t address) +{ + if (chip->native_mode) + { + return ESFM_readback_reg_native(chip, address); + } + else + { + return 0; + } +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_write_port (esfm_chip *chip, uint8_t offset, uint8_t data) +{ + if (chip->native_mode) + { + switch(offset) + { + case 0: + chip->native_mode = 0; + ESFM_native_to_emu_switch(chip); + // TODO: verify if the address write goes through + chip->addr_latch = data; + break; + case 1: + ESFM_write_reg_native(chip, chip->addr_latch, data); + break; + case 2: + chip->addr_latch = (chip->addr_latch & 0xff00) | data; + break; + case 3: + chip->addr_latch = chip->addr_latch & 0xff; + chip->addr_latch |= (uint16)data << 8; + break; + } + } + else + { + switch(offset) + { + case 0: + chip->addr_latch = data; + break; + case 1: case 3: + ESFM_write_reg_emu(chip, chip->addr_latch, data); + break; + case 2: + chip->addr_latch = (uint16)data | 0x100; + break; + } + } +} + +/* ------------------------------------------------------------------------- */ +uint8_t +ESFM_read_port (esfm_chip *chip, uint8_t offset) +{ + uint8_t data = 0; + + switch(offset) + { + case 0: + data |= (chip->irq_bit != 0) << 7; + data |= (chip->timer_overflow[0] != 0) << 6; + data |= (chip->timer_overflow[1] != 0) << 5; + break; + case 1: + if (chip->native_mode) + { + data = ESFM_readback_reg_native(chip, chip->addr_latch); + } + else + { + data = 0; + } + break; + case 2: case 3: + // This matches OPL3 behavior. + data = 0xff; + break; + } + + return data; +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_set_mode (esfm_chip *chip, bool native_mode) +{ + native_mode = native_mode != 0; + + if (native_mode != (chip->native_mode != 0)) + { + chip->native_mode = native_mode; + if (native_mode) + { + ESFM_emu_to_native_switch(chip); + } + else + { + ESFM_native_to_emu_switch(chip); + } + } +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_init (esfm_chip *chip) +{ + esfm_slot *slot; + esfm_channel *channel; + size_t channel_idx, slot_idx; + + memset(chip, 0, sizeof(esfm_chip)); + for (channel_idx = 0; channel_idx < 18; channel_idx++) + { + for (slot_idx = 0; slot_idx < 4; slot_idx++) + { + channel = &chip->channels[channel_idx]; + slot = &channel->slots[slot_idx]; + + channel->chip = chip; + channel->channel_idx = channel_idx; + slot->channel = channel; + slot->chip = chip; + slot->slot_idx = slot_idx; + slot->in.eg_position = slot->in.eg_output = 0x1ff; + slot->in.eg_state = EG_RELEASE; + slot->in.emu_mod_enable = ~((int13) 0); + if (slot_idx == 0) + { + slot->in.mod_input = &slot->in.feedback_buf; + } + else + { + esfm_slot *prev_slot = &channel->slots[slot_idx - 1]; + slot->in.mod_input = &prev_slot->in.output; + } + + if (slot_idx == 1) + { + slot->in.emu_output_enable = ~((int13) 0); + } + + if (channel_idx > 15 && slot_idx & 0x02) + { + slot->in.key_on = &channel->key_on_2; + } + else + { + slot->in.key_on = &channel->key_on; + } + + slot->out_enable[0] = slot->out_enable[1] = ~((int13) 0); + } + } + + chip->lfsr = 1; +} + diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c new file mode 100644 index 000000000..f7372730c --- /dev/null +++ b/src/sound/snd_opl_esfm.c @@ -0,0 +1,223 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * ESFMu ESFM emulator. + * + * + * Authors: Fred N. van Kempen, + * Miran Grca, + * Alexey Khokholov (Nuke.YKT) + * Cacodemon345 + * + * Copyright 2017-2020 Fred N. van Kempen. + * Copyright 2016-2020 Miran Grca. + * Copyright 2013-2018 Alexey Khokholov (Nuke.YKT) + * Copyright 2024 Cacodemon345 + */ + +#include +#include +#include +#include +#include + +#include "esfmu/esfm.h" + +#define HAVE_STDARG_H +#define NO_SOFTFLOAT_INCLUDE +#include <86box/86box.h> +#include <86box/sound.h> +#include <86box/device.h> +#include <86box/timer.h> +#include <86box/snd_opl.h> + +#define RSM_FRAC 10 + +enum { + FLAG_CYCLES = 0x02, + FLAG_OPL3 = 0x01 +}; + +typedef struct { + esfm_chip opl; + int8_t flags; + int8_t pad; + + uint16_t port; + uint8_t status; + uint8_t timer_ctrl; + uint16_t timer_count[2]; + uint16_t timer_cur_count[2]; + + // OPL3L + int32_t rateratio; + int32_t samplecnt; + int32_t oldsamples[2]; + int32_t samples[2]; + + int pos; + int32_t buffer[SOUNDBUFLEN * 2]; +} esfm_drv_t; + +void +esfm_drv_generate_resampled(esfm_drv_t *dev, int32_t *bufp) +{ + while (dev->samplecnt >= dev->rateratio) { + int16_t samples[2] = { 0, 0 }; + dev->oldsamples[0] = dev->samples[0]; + dev->oldsamples[1] = dev->samples[1]; + ESFM_generate(&dev->opl, samples); + dev->samples[0] = samples[0]; + dev->samples[1] = samples[1]; + dev->samplecnt -= dev->rateratio; + } + + bufp[0] = (int32_t) ((dev->oldsamples[0] * (dev->rateratio - dev->samplecnt) + + dev->samples[0] * dev->samplecnt) + / dev->rateratio); + bufp[1] = (int32_t) ((dev->oldsamples[1] * (dev->rateratio - dev->samplecnt) + + dev->samples[1] * dev->samplecnt) + / dev->rateratio); + + dev->samplecnt += 1 << RSM_FRAC; +} + +void +esfm_drv_generate_stream(esfm_drv_t *dev, int32_t *sndptr, uint32_t num) +{ + for (uint32_t i = 0; i < num; i++) { + esfm_drv_generate_resampled(dev, sndptr); + sndptr += 2; + } +} + +static void +esfm_drv_set_do_cycles(void *priv, int8_t do_cycles) +{ + esfm_drv_t *dev = (esfm_drv_t *) priv; + + if (do_cycles) + dev->flags |= FLAG_CYCLES; + else + dev->flags &= ~FLAG_CYCLES; +} + +static void * +esfm_drv_init(const device_t *info) +{ + esfm_drv_t *dev = (esfm_drv_t *) calloc(1, sizeof(esfm_drv_t)); + dev->flags = FLAG_CYCLES | FLAG_OPL3; + + /* Initialize the ESFMu object. */ + ESFM_init(&dev->opl); + dev->rateratio = (SOUND_FREQ << RSM_FRAC) / 49716; + + return dev; +} + +static void +esfm_drv_close(void *priv) +{ + esfm_drv_t *dev = (esfm_drv_t *) priv; + free(dev); +} + +static int32_t * +esfm_drv_update(void *priv) +{ + esfm_drv_t *dev = (esfm_drv_t *) priv; + + if (dev->pos >= sound_pos_global) + return dev->buffer; + + esfm_drv_generate_stream(dev, + &dev->buffer[dev->pos * 2], + sound_pos_global - dev->pos); + + for (; dev->pos < sound_pos_global; dev->pos++) { + dev->buffer[dev->pos * 2] /= 2; + dev->buffer[(dev->pos * 2) + 1] /= 2; + } + + return dev->buffer; +} + + +static void +esfm_drv_reset_buffer(void *priv) +{ + esfm_drv_t *dev = (esfm_drv_t *) priv; + + dev->pos = 0; +} + +static uint8_t +esfm_drv_read(uint16_t port, void *priv) +{ + esfm_drv_t *dev = (esfm_drv_t *) priv; + + if (dev->flags & FLAG_CYCLES) + cycles -= ((int) (isa_timing * 8)); + + esfm_drv_update(dev); + + uint8_t ret = 0xff; + + ret = ESFM_read_port(&dev->opl, port & 3); + + return ret; +} + +static void +esfm_drv_write(uint16_t port, uint8_t val, void *priv) +{ + esfm_drv_t *dev = (esfm_drv_t *) priv; + + if (dev->flags & FLAG_CYCLES) + cycles -= ((int) (isa_timing * 8)); + + esfm_drv_update(dev); + + if (dev->opl.native_mode) { + if ((port & 3) == 1) { + ESFM_write_reg_buffered_fast(&dev->opl, dev->opl.addr_latch, val); + } else { + ESFM_write_port(&dev->opl, port & 3, val); + } + } else { + if ((port & 3) == 1 || (port & 3) == 3) { + ESFM_write_reg_buffered_fast(&dev->opl, dev->opl.addr_latch, val); + } else { + ESFM_write_port(&dev->opl, port & 3, val); + } + } +} + +const device_t esfm_esfmu_device = { + .name = "ESS Technology ESFM (ESFMu)", + .internal_name = "ymf262_nuked", + .flags = 0, + .local = FM_YMF262, + .init = esfm_drv_init, + .close = esfm_drv_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const fm_drv_t nuked_opl_drv = { + &esfm_drv_read, + &esfm_drv_write, + &esfm_drv_update, + &esfm_drv_reset_buffer, + &esfm_drv_set_do_cycles, + NULL, + NULL, +}; From eec49e4a76400273edb402e1c5f63041836b2e4b Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 29 Feb 2024 22:21:25 +0600 Subject: [PATCH 711/936] Fix multiple symbol definition error --- src/sound/snd_opl_esfm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index f7372730c..ec549700a 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -212,7 +212,7 @@ const device_t esfm_esfmu_device = { .config = NULL }; -const fm_drv_t nuked_opl_drv = { +const fm_drv_t esfmu_opl_drv = { &esfm_drv_read, &esfm_drv_write, &esfm_drv_update, From 12c64ab43d7d5164deabc7c09f763be669808fa4 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 29 Feb 2024 22:57:51 +0600 Subject: [PATCH 712/936] Fix incorrect internal name --- src/sound/snd_opl_esfm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index ec549700a..47796a911 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -200,9 +200,9 @@ esfm_drv_write(uint16_t port, uint8_t val, void *priv) const device_t esfm_esfmu_device = { .name = "ESS Technology ESFM (ESFMu)", - .internal_name = "ymf262_nuked", + .internal_name = "esfm_esfmu", .flags = 0, - .local = FM_YMF262, + .local = 0, .init = esfm_drv_init, .close = esfm_drv_close, .reset = NULL, From 2341b28c7f4cb222dededb44a69873e9ce57f315 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 1 Mar 2024 01:58:48 +0600 Subject: [PATCH 713/936] Add FM_ESFM type --- src/include/86box/snd_opl.h | 6 +++++- src/sound/snd_opl.c | 5 +++++ src/sound/snd_opl_esfm.c | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/include/86box/snd_opl.h b/src/include/86box/snd_opl.h index 0d89589c4..441e2a119 100644 --- a/src/include/86box/snd_opl.h +++ b/src/include/86box/snd_opl.h @@ -22,7 +22,8 @@ enum fm_type { FM_YMF262 = 1, /* OPL3 */ FM_YMF289B = 2, /* OPL3-L */ FM_YMF278B = 3, /* OPL 4 */ - FM_MAX = 4 + FM_ESFM = 4, /* ESFM */ + FM_MAX = 5 }; enum fm_driver { @@ -45,6 +46,7 @@ extern uint8_t fm_driver_get(int chip_id, fm_drv_t *drv); extern const fm_drv_t nuked_opl_drv; extern const fm_drv_t ymfm_drv; +extern const fm_drv_t esfmu_opl_drv; #ifdef EMU_DEVICE_H extern const device_t ym3812_nuked_device; @@ -54,6 +56,8 @@ extern const device_t ym3812_ymfm_device; extern const device_t ymf262_ymfm_device; extern const device_t ymf289b_ymfm_device; extern const device_t ymf278b_ymfm_device; + +extern const device_t esfm_esfmu_device; #endif #endif /*SOUND_OPL_H*/ diff --git a/src/sound/snd_opl.c b/src/sound/snd_opl.c index 21cc66f04..d98b3ccc2 100644 --- a/src/sound/snd_opl.c +++ b/src/sound/snd_opl.c @@ -68,6 +68,11 @@ fm_driver_get(int chip_id, fm_drv_t *drv) *drv = ymfm_drv; drv->priv = device_add_inst(&ymf278b_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); break; + + case FM_ESFM: + *drv = esfmu_opl_drv; + drv->priv = device_add_inst(&esfm_esfmu_device, fm_dev_inst[fm_driver][chip_id]++); + break; default: return 0; diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index 47796a911..d8e350418 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -202,7 +202,7 @@ const device_t esfm_esfmu_device = { .name = "ESS Technology ESFM (ESFMu)", .internal_name = "esfm_esfmu", .flags = 0, - .local = 0, + .local = FM_ESFM, .init = esfm_drv_init, .close = esfm_drv_close, .reset = NULL, From e1badc3e0f70b0d28d39888e820f543ebb65ae69 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 1 Mar 2024 13:10:06 +0600 Subject: [PATCH 714/936] ESFM update --- src/sound/esfmu/esfm.c | 3 ++- src/sound/esfmu/esfm_registers.c | 15 +++++++++++---- src/sound/snd_opl_esfm.c | 32 ++++++-------------------------- 3 files changed, 19 insertions(+), 31 deletions(-) diff --git a/src/sound/esfmu/esfm.c b/src/sound/esfmu/esfm.c index 7409603fe..08beadb5a 100644 --- a/src/sound/esfmu/esfm.c +++ b/src/sound/esfmu/esfm.c @@ -2117,7 +2117,7 @@ ESFM_update_timers(esfm_chip *chip) { if (chip->timer_enable[i]) { - chip->timer_accumulator[i] += i == 0 ? TIMER1_CONST : TIMER2_CONST; + chip->timer_accumulator[i] += (i == 0) ? TIMER1_CONST : TIMER2_CONST; if (chip->timer_accumulator[i] > 1.0) { chip->timer_accumulator[i] -= 1.0; @@ -2126,6 +2126,7 @@ ESFM_update_timers(esfm_chip *chip) { if (chip->timer_mask[i] == 0) { + chip->irq_bit = true; chip->timer_overflow[i] = true; } chip->timer_counter[i] = chip->timer_reload[i]; diff --git a/src/sound/esfmu/esfm_registers.c b/src/sound/esfmu/esfm_registers.c index 34ce8b19e..653d91e9a 100644 --- a/src/sound/esfmu/esfm_registers.c +++ b/src/sound/esfmu/esfm_registers.c @@ -647,9 +647,11 @@ ESFM_write_reg_emu (esfm_chip *chip, uint16_t address, uint8_t data) break; case 0x02: chip->timer_reload[0] = data; + chip->timer_counter[0] = data; break; case 0x03: chip->timer_reload[1] = data; + chip->timer_counter[1] = data; break; case 0x04: for (i = 0; i < 3; i++) @@ -685,19 +687,24 @@ ESFM_write_reg_emu (esfm_chip *chip, uint16_t address, uint8_t data) break; case 0x02: chip->timer_reload[0] = data; + chip->timer_counter[0] = data; break; case 0x03: chip->timer_reload[1] = data; + chip->timer_counter[1] = data; break; case 0x04: - chip->timer_enable[0] = data & 0x01; - chip->timer_enable[1] = (data & 0x02) != 0; - chip->timer_mask[0] = (data & 0x20) != 0; - chip->timer_mask[1] = (data & 0x40) != 0; if (data & 0x80) { chip->irq_bit = 0; + chip->timer_overflow[0] = 0; + chip->timer_overflow[1] = 0; + break; } + chip->timer_enable[0] = data & 0x01; + chip->timer_enable[1] = (data & 0x02) != 0; + chip->timer_mask[1] = (data & 0x20) != 0; + chip->timer_mask[0] = (data & 0x40) != 0; break; case 0x08: chip->keyscale_mode = (data & 0x40) != 0; diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index d8e350418..16f728ab3 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -54,44 +54,25 @@ typedef struct { uint16_t timer_count[2]; uint16_t timer_cur_count[2]; - // OPL3L - int32_t rateratio; - int32_t samplecnt; - int32_t oldsamples[2]; - int32_t samples[2]; - int pos; int32_t buffer[SOUNDBUFLEN * 2]; } esfm_drv_t; void -esfm_drv_generate_resampled(esfm_drv_t *dev, int32_t *bufp) +esfm_generate_raw(esfm_drv_t *dev, int32_t *bufp) { - while (dev->samplecnt >= dev->rateratio) { - int16_t samples[2] = { 0, 0 }; - dev->oldsamples[0] = dev->samples[0]; - dev->oldsamples[1] = dev->samples[1]; - ESFM_generate(&dev->opl, samples); - dev->samples[0] = samples[0]; - dev->samples[1] = samples[1]; - dev->samplecnt -= dev->rateratio; - } + int16_t samples[2] = { 0, 0 }; + ESFM_generate(&dev->opl, samples); - bufp[0] = (int32_t) ((dev->oldsamples[0] * (dev->rateratio - dev->samplecnt) - + dev->samples[0] * dev->samplecnt) - / dev->rateratio); - bufp[1] = (int32_t) ((dev->oldsamples[1] * (dev->rateratio - dev->samplecnt) - + dev->samples[1] * dev->samplecnt) - / dev->rateratio); - - dev->samplecnt += 1 << RSM_FRAC; + bufp[0] = (int32_t) samples[0]; + bufp[1] = (int32_t) samples[1]; } void esfm_drv_generate_stream(esfm_drv_t *dev, int32_t *sndptr, uint32_t num) { for (uint32_t i = 0; i < num; i++) { - esfm_drv_generate_resampled(dev, sndptr); + esfm_generate_raw(dev, sndptr); sndptr += 2; } } @@ -115,7 +96,6 @@ esfm_drv_init(const device_t *info) /* Initialize the ESFMu object. */ ESFM_init(&dev->opl); - dev->rateratio = (SOUND_FREQ << RSM_FRAC) / 49716; return dev; } From 5d97fb886fb6ac8ea78b71e765a60eb193ebd93e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 1 Mar 2024 16:10:31 +0600 Subject: [PATCH 715/936] Fix bad audio on ESFM emulation --- src/sound/snd_opl_esfm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index 16f728ab3..3720c8ada 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -112,14 +112,14 @@ esfm_drv_update(void *priv) { esfm_drv_t *dev = (esfm_drv_t *) priv; - if (dev->pos >= sound_pos_global) + if (dev->pos >= music_pos_global) return dev->buffer; esfm_drv_generate_stream(dev, &dev->buffer[dev->pos * 2], - sound_pos_global - dev->pos); + music_pos_global - dev->pos); - for (; dev->pos < sound_pos_global; dev->pos++) { + for (; dev->pos < music_pos_global; dev->pos++) { dev->buffer[dev->pos * 2] /= 2; dev->buffer[(dev->pos * 2) + 1] /= 2; } From d806ce250ea51bb4ccd44411cd7ddcd4465edac8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 1 Mar 2024 22:14:41 +0600 Subject: [PATCH 716/936] ESFMu update --- src/sound/esfmu/esfm_registers.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/sound/esfmu/esfm_registers.c b/src/sound/esfmu/esfm_registers.c index 653d91e9a..e2f432ed1 100644 --- a/src/sound/esfmu/esfm_registers.c +++ b/src/sound/esfmu/esfm_registers.c @@ -453,21 +453,24 @@ ESFM_write_reg_native (esfm_chip *chip, uint16_t address, uint8_t data) { case TIMER1_REG: chip->timer_reload[0] = data; + chip->timer_counter[0] = data; break; case TIMER2_REG: chip->timer_reload[1] = data; + chip->timer_counter[1] = data; break; case TIMER_SETUP_REG: if (data & 0x80) { + chip->irq_bit = 0; chip->timer_overflow[0] = 0; chip->timer_overflow[1] = 0; - chip->irq_bit = 0; + break; } chip->timer_enable[0] = (data & 0x01) != 0; chip->timer_enable[1] = (data & 0x02) != 0; - chip->timer_mask[0] = (data & 0x20) != 0; - chip->timer_mask[1] = (data & 0x40) != 0; + chip->timer_mask[1] = (data & 0x20) != 0; + chip->timer_mask[0] = (data & 0x40) != 0; break; case CONFIG_REG: chip->keyscale_mode = (data & 0x40) != 0; @@ -547,16 +550,16 @@ ESFM_readback_reg_native (esfm_chip *chip, uint16_t address) switch (address & 0x5ff) { case TIMER1_REG: - data = chip->timer_reload[0]; + data = chip->timer_counter[0]; break; case TIMER2_REG: - data = chip->timer_reload[1]; + data = chip->timer_counter[1]; break; case TIMER_SETUP_REG: data |= chip->timer_enable[0] != 0; data |= (chip->timer_enable[1] != 0) << 1; - data |= (chip->timer_mask[0] != 0) << 5; - data |= (chip->timer_mask[1] != 0) << 6; + data |= (chip->timer_mask[1] != 0) << 5; + data |= (chip->timer_mask[0] != 0) << 6; break; case CONFIG_REG: data |= (chip->keyscale_mode != 0) << 6; From 8308f410694b3b46670efbd5c3fb41622d712447 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 2 Mar 2024 02:51:07 +0600 Subject: [PATCH 717/936] A bit of ESS --- src/include/86box/snd_sb_dsp.h | 5 +++++ src/sound/snd_sb_dsp.c | 27 ++++++++++++++++++--------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index 3e0e40e80..568b02f47 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -5,6 +5,11 @@ #define SB_SUBTYPE_DEFAULT 0 /*Handle as a Creative card*/ #define SB_SUBTYPE_CLONE_AZT2316A_0X11 1 /*Aztech Sound Galaxy Pro 16 AB, DSP 3.1 - SBPRO2 clone*/ #define SB_SUBTYPE_CLONE_AZT1605_0X0C 2 /*Aztech Sound Galaxy Nova 16 Extra / Packard Bell Forte 16, DSP 2.1 - SBPRO2 clone*/ +#define SB_SUBTYPE_ESS_ES688 3 /* ESS Technology ES688 */ +#define SB_SUBTYPE_ESS_ES1688 4 /* ESS Technology ES1688 */ + +/* ESS-related */ +#define IS_ESS(dsp) ((dsp)->sb_subtype >= SB_SUBTYPE_ESS_ES688) /* aztech-related */ #define IS_AZTECH(dsp) ((dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11 || (dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) /* check for future AZT cards here */ diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index cf4498b4b..d94faa29e 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -906,17 +906,21 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sb_8_pause = 1; break; case 0xD1: /* Speaker on */ - if (dsp->sb_type < SB15) - dsp->sb_8_pause = 1; - else if (dsp->sb_type < SB16) - dsp->muted = 0; + if (!IS_ESS(dsp)) { + if (dsp->sb_type < SB15) + dsp->sb_8_pause = 1; + else if (dsp->sb_type < SB16) + dsp->muted = 0; + } dsp->sb_speaker = 1; break; case 0xD3: /* Speaker off */ - if (dsp->sb_type < SB15) - dsp->sb_8_pause = 1; - else if (dsp->sb_type < SB16) - dsp->muted = 1; + if (!IS_ESS(dsp)) { + if (dsp->sb_type < SB15) + dsp->sb_8_pause = 1; + else if (dsp->sb_type < SB16) + dsp->muted = 1; + } dsp->sb_speaker = 0; break; case 0xD4: /* Continue 8-bit DMA */ @@ -944,6 +948,11 @@ sb_exec_command(sb_dsp_t *dsp) sb_add_data(dsp, ~dsp->sb_data[0]); break; case 0xE1: /* Get DSP version */ + if (IS_ESS(dsp)) { + sb_add_data(dsp, 0x3); + sb_add_data(dsp, 0x1); + break; + } if (IS_AZTECH(dsp)) { if (dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11) { sb_add_data(dsp, 0x3); @@ -1036,7 +1045,7 @@ sb_write(uint16_t a, uint8_t v, void *priv) sb_dsp_t *dsp = (sb_dsp_t *) priv; /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ - if (dsp->sb_type < SB16) + if (dsp->sb_type < SB16 && (!IS_ESS(dsp) || (IS_ESS(dsp) && ((a & 0xF) != 0xE)))) a &= 0xfffe; switch (a & 0xF) { From d5dad279c4e9a7bb12286ef35a38e98e4fe546fa Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 2 Mar 2024 16:50:29 +0600 Subject: [PATCH 718/936] ESSreg macro --- src/include/86box/snd_sb_dsp.h | 2 ++ src/sound/snd_sb_dsp.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index 568b02f47..bf9ceab53 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -140,6 +140,8 @@ typedef struct sb_dsp_t { uint8_t azt_eeprom[AZTECH_EEPROM_SIZE]; /* the eeprom in the Aztech cards is attached to the DSP */ + uint8_t ess_regs[256]; /* ESS registers. */ + mpu_t *mpu; } sb_dsp_t; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index d94faa29e..79415ac5b 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -135,6 +135,8 @@ sb_dsp_log(const char *fmt, ...) # define sb_dsp_log(fmt, ...) #endif +#define ESSreg(reg) (dsp)->ess_regs[reg - 0xA0] + static __inline double sinc(double x) { From 97b239aed50c3b5c149e4195548cc1d75e3677e0 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 2 Mar 2024 17:12:26 +0600 Subject: [PATCH 719/936] More small pieces of ESS emulation --- src/include/86box/snd_sb_dsp.h | 1 + src/sound/snd_sb_dsp.c | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index bf9ceab53..6f94a9801 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -141,6 +141,7 @@ typedef struct sb_dsp_t { uint8_t azt_eeprom[AZTECH_EEPROM_SIZE]; /* the eeprom in the Aztech cards is attached to the DSP */ uint8_t ess_regs[256]; /* ESS registers. */ + uint8_t ess_playback_mode; mpu_t *mpu; } sb_dsp_t; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 79415ac5b..1e2d469a2 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -1332,6 +1332,15 @@ sb_dsp_dma_attach(sb_dsp_t *dsp, dsp->dma_priv = priv; } +void +sb_ess_finish_dma(sb_dsp_t *dsp) +{ + if (!dsp->ess_playback_mode) + return; + ESSreg(0xB8) &= ~0x01; + dma_set_drq(dsp->sb_8_dmanum, 0); +} + void pollsb(void *priv) { @@ -1530,6 +1539,7 @@ pollsb(void *priv) else { dsp->sb_8_enable = 0; timer_disable(&dsp->output_timer); + sb_ess_finish_dma(dsp); } sb_irq(dsp, 1); } @@ -1582,6 +1592,7 @@ pollsb(void *priv) else { dsp->sb_16_enable = 0; timer_disable(&dsp->output_timer); + sb_ess_finish_dma(dsp); } sb_irq(dsp, 0); } From 3f72c788bdd837cb8c940f1559f76929e6e3ffbd Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 2 Mar 2024 17:29:05 +0600 Subject: [PATCH 720/936] ESS bits for IRQ raise --- src/sound/snd_sb_dsp.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 1e2d469a2..c028f98c1 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -224,6 +224,12 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) break; } + /* TODO: Investigate real hardware for this (the ES1887 datasheet documents this bit somewhat oddly.) */ + if (dsp->ess_playback_mode && bit <= 1 && set && !masked) { + if (!(ESSreg(0xB1) & 0x40)) // if ESS playback, and IRQ disabled, do not fire + return; + } + if (set && !masked) dsp->irq_update(dsp->irq_priv, 1); else if (!set) @@ -377,6 +383,9 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) if (!timer_is_enabled(&dsp->output_timer)) timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); } + + /* This will be set later for ESS playback/record modes. */ + dsp->ess_playback_mode = 0; } void @@ -409,6 +418,32 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) memset(dsp->record_buffer, 0, sizeof(dsp->record_buffer)); } +void +sb_start_dma_ess(sb_dsp_t* dsp, int dma8, int autoinit, uint8_t format, int len) +{ + if (IS_ESS(dsp)) { + dma_set_drq(dsp->sb_8_dmanum, 0); + dma_set_drq(dsp->sb_16_8_dmanum, 0); + } + sb_start_dma(dsp, dma8, autoinit, format, len); + dsp->ess_playback_mode = 1; + dma_set_drq(dsp->sb_8_dmanum, 1); + dma_set_drq(dsp->sb_16_8_dmanum, 1); +} + +void +sb_start_dma_ess_i(sb_dsp_t* dsp, int dma8, int autoinit, uint8_t format, int len) +{ + if (IS_ESS(dsp)) { + dma_set_drq(dsp->sb_8_dmanum, 0); + dma_set_drq(dsp->sb_16_8_dmanum, 0); + } + sb_start_dma_i(dsp, dma8, autoinit, format, len); + dsp->ess_playback_mode = 1; + dma_set_drq(dsp->sb_8_dmanum, 1); + dma_set_drq(dsp->sb_16_8_dmanum, 1); +} + int sb_8_read_dma(void *priv) { From 4369284f6549258ee465566416b3c93ee4b59d0e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 2 Mar 2024 17:36:55 +0600 Subject: [PATCH 721/936] ESS register 0xA2 update function --- src/sound/snd_sb_dsp.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index c028f98c1..12b04a008 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -585,6 +585,18 @@ sb_dsp_setdma16_translate(sb_dsp_t *dsp, int translate) dsp->sb_16_dma_translate = translate; } +/* TODO: Investigate ESS cards' filtering on real hardware as well. + (DOSBox-X did it purely off some laptop's ESS chip, which isn't a good look.) */ +static void sb_ess_update_filter_freq(sb_dsp_t *dsp) { + if (dsp->sb_freq >= 22050) + ESSreg(0xA1) = 256 - (795500UL / dsp->sb_freq); + else + ESSreg(0xA1) = 128 - (397700UL / dsp->sb_freq); + + unsigned int freq = ((dsp->sb_freq * 4) / (5 * 2)); /* 80% of 1/2 the sample rate */ + ESSreg(0xA2) = 256 - (7160000 / (freq * 82)); +} + void sb_exec_command(sb_dsp_t *dsp) { @@ -796,6 +808,9 @@ sb_exec_command(sb_dsp_t *dsp) if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16)) recalc_sb16_filter(0, temp); dsp->sb_freq = temp; + if (IS_ESS(dsp)) { + sb_ess_update_filter_freq(dsp); + } break; case 0x41: /* Set output sampling rate */ case 0x42: /* Set input sampling rate */ From 3f7fbc7467266e5456281b7808222cd6c9622a79 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 2 Mar 2024 17:41:51 +0600 Subject: [PATCH 722/936] Extended mode toggle --- src/include/86box/snd_sb_dsp.h | 1 + src/sound/snd_sb_dsp.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index 6f94a9801..f04734ebb 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -142,6 +142,7 @@ typedef struct sb_dsp_t { uint8_t ess_regs[256]; /* ESS registers. */ uint8_t ess_playback_mode; + uint8_t ess_extended_mode; mpu_t *mpu; } sb_dsp_t; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 12b04a008..08a69ec82 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -610,6 +610,13 @@ sb_exec_command(sb_dsp_t *dsp) if (dsp->sb_type >= SB16) dsp->sb_8051_ram[0x20] = dsp->sb_command; + if (IS_ESS(dsp)) { + if (dsp->sb_command == 0xC6 || dsp->sb_command == 0xC7){ + dsp->ess_extended_mode = !!(dsp->sb_command == 0xC6); + return; + } + } + switch (dsp->sb_command) { case 0x01: /* ???? */ if (dsp->sb_type >= SB16) From eda528d98c0f2371b555dc6c61abd67b6e34daff Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 2 Mar 2024 17:48:21 +0600 Subject: [PATCH 723/936] ESS register read function --- src/sound/snd_sb_dsp.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 08a69ec82..05b6abe43 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -587,7 +587,8 @@ sb_dsp_setdma16_translate(sb_dsp_t *dsp, int translate) /* TODO: Investigate ESS cards' filtering on real hardware as well. (DOSBox-X did it purely off some laptop's ESS chip, which isn't a good look.) */ -static void sb_ess_update_filter_freq(sb_dsp_t *dsp) { +static void sb_ess_update_filter_freq(sb_dsp_t *dsp) +{ if (dsp->sb_freq >= 22050) ESSreg(0xA1) = 256 - (795500UL / dsp->sb_freq); else @@ -597,6 +598,27 @@ static void sb_ess_update_filter_freq(sb_dsp_t *dsp) { ESSreg(0xA2) = 256 - (7160000 / (freq * 82)); } +static unsigned int sb_ess_get_dma_len(sb_dsp_t *dsp) +{ + unsigned int r; + + r = (unsigned int)ESSreg(0xA5) << 8U; + r |= (unsigned int)ESSreg(0xA4); + + /* the 16-bit counter is a "two's complement" of the DMA count because it counts UP to 0 and triggers IRQ on overflow */ + return 0x10000U-r; +} + +static uint8_t sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) +{ + switch (reg) { + default: + return ESSreg(reg); + } + + return 0xFF; +} + void sb_exec_command(sb_dsp_t *dsp) { From e7e582cd740541dfe61f290967e77e5e1d618f51 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 3 Mar 2024 16:02:56 +0600 Subject: [PATCH 724/936] Finish DSP part of ESS --- src/include/86box/snd_sb_dsp.h | 1 + src/sound/CMakeLists.txt | 2 +- src/sound/snd_ess.c | 258 +++++++++++++++++++++++++++++++++ src/sound/snd_sb_dsp.c | 219 ++++++++++++++++++++++++---- 4 files changed, 454 insertions(+), 26 deletions(-) create mode 100644 src/sound/snd_ess.c diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index f04734ebb..2b39a0303 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -143,6 +143,7 @@ typedef struct sb_dsp_t { uint8_t ess_regs[256]; /* ESS registers. */ uint8_t ess_playback_mode; uint8_t ess_extended_mode; + uint8_t ess_reload_len; mpu_t *mpu; } sb_dsp_t; diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index 9b2cc1416..9206f6be9 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -18,7 +18,7 @@ add_library(snd OBJECT sound.c snd_opl.c snd_opl_nuked.c snd_opl_ymfm.cpp snd_re snd_lpt_dss.c snd_ps1.c snd_adlib.c snd_adlibgold.c snd_ad1848.c snd_audiopci.c snd_azt2316a.c snd_cms.c snd_cmi8x38.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c snd_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c - snd_optimc.c esfmu/esfm.c esfmu/esfm_registers.c snd_opl_esfm.c) + snd_optimc.c esfmu/esfm.c esfmu/esfm_registers.c snd_opl_esfm.c snd_ess.c) if(OPENAL) if(VCPKG_TOOLCHAIN) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c new file mode 100644 index 000000000..d762117cd --- /dev/null +++ b/src/sound/snd_ess.c @@ -0,0 +1,258 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Sound Blaster emulation. + * + * + * + * Authors: Sarah Walker, + * Miran Grca, + * TheCollector1995, + * + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H + +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/filters.h> +#include <86box/gameport.h> +#include <86box/hdc.h> +#include <86box/isapnp.h> +#include <86box/hdc_ide.h> +#include <86box/io.h> +#include <86box/mca.h> +#include <86box/mem.h> +#include <86box/midi.h> +#include <86box/pic.h> +#include <86box/rom.h> +#include <86box/sound.h> +#include <86box/timer.h> +#include <86box/snd_sb.h> +#include <86box/plat_unused.h> + +static const double sb_att_4dbstep_3bits[] = { + 164.0, 2067.0, 3276.0, 5193.0, 8230.0, 13045.0, 20675.0, 32767.0 +}; + +static const double sb_att_7dbstep_2bits[] = { + 164.0, 6537.0, 14637.0, 32767.0 +}; + +/* SB PRO */ +typedef struct ess_mixer_t { + double master_l; + double master_r; + double voice_l; + double voice_r; + double fm_l; + double fm_r; + double cd_l; + double cd_r; + double line_l; + double line_r; + double mic; + /*see sb_ct1745_mixer for values for input selector*/ + int32_t input_selector; + + int input_filter; + int in_filter_freq; + int output_filter; + + int stereo; + int stereo_isleft; + + uint8_t index; + uint8_t regs[256]; +} ess_mixer_t; + +typedef struct ess_t { + uint8_t mixer_enabled; + fm_drv_t opl; + sb_dsp_t dsp; + union { + ess_mixer_t mixer_sbpro; + }; + mpu_t *mpu; + emu8k_t emu8k; + void *gameport; + + int pnp; + + uint8_t pos_regs[8]; + uint8_t pnp_rom[512]; + + uint16_t opl_pnp_addr; + uint16_t gameport_addr; + + void *opl_mixer; + void (*opl_mix)(void*, double*, double*); +} ess_t; + +static inline uint8_t expand16to32(const uint8_t t) { + /* 4-bit -> 5-bit expansion. + * + * 0 -> 0 + * 1 -> 2 + * 2 -> 4 + * 3 -> 6 + * .... + * 7 -> 14 + * 8 -> 17 + * 9 -> 19 + * 10 -> 21 + * 11 -> 23 + * .... + * 15 -> 31 */ + return (t << 1) | (t >> 3); +} + +void +ess_mixer_write(uint16_t addr, uint8_t val, void *priv) +{ + ess_t *ess = (ess_t *) priv; + ess_mixer_t *mixer = &ess->mixer_sbpro; + + if (!(addr & 1)) { + mixer->index = val; + mixer->regs[0x01] = val; + } else { + if (mixer->index == 0) { + /* Reset */ + mixer->regs[0x0a] = mixer->regs[0x0c] = 0x00; + mixer->regs[0x0e] = 0x00; + /* Changed default from -11dB to 0dB */ + mixer->regs[0x04] = mixer->regs[0x22] = 0xee; + mixer->regs[0x26] = mixer->regs[0x28] = 0xee; + mixer->regs[0x2e] = 0x00; + sb_dsp_set_stereo(&ess->dsp, mixer->regs[0x0e] & 2); + } else { + mixer->regs[mixer->index] = val; + + switch (mixer->index) { + /* Compatibility: chain registers 0x02 and 0x22 as well as 0x06 and 0x26 */ + case 0x02: + case 0x06: + case 0x08: + mixer->regs[mixer->index + 0x20] = ((val & 0xe) << 4) | (val & 0xe); + break; + + case 0x22: + case 0x26: + case 0x28: + mixer->regs[mixer->index - 0x20] = (val & 0xe); + break; + + /* More compatibility: + SoundBlaster Pro selects register 020h for 030h, 022h for 032h, + 026h for 036h, and 028h for 038h. */ + case 0x30: + case 0x32: + case 0x36: + case 0x38: + mixer->regs[mixer->index - 0x10] = (val & 0xee); + break; + + case 0x00: + case 0x04: + case 0x0a: + case 0x0c: + case 0x0e: + case 0x2e: + break; + + default: + //sb_log("ess: Unknown register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + break; + } + } + + mixer->voice_l = sb_att_4dbstep_3bits[(mixer->regs[0x04] >> 5) & 0x7] / 32768.0; + mixer->voice_r = sb_att_4dbstep_3bits[(mixer->regs[0x04] >> 1) & 0x7] / 32768.0; + mixer->master_l = sb_att_4dbstep_3bits[(mixer->regs[0x22] >> 5) & 0x7] / 32768.0; + mixer->master_r = sb_att_4dbstep_3bits[(mixer->regs[0x22] >> 1) & 0x7] / 32768.0; + mixer->fm_l = sb_att_4dbstep_3bits[(mixer->regs[0x26] >> 5) & 0x7] / 32768.0; + mixer->fm_r = sb_att_4dbstep_3bits[(mixer->regs[0x26] >> 1) & 0x7] / 32768.0; + mixer->cd_l = sb_att_4dbstep_3bits[(mixer->regs[0x28] >> 5) & 0x7] / 32768.0; + mixer->cd_r = sb_att_4dbstep_3bits[(mixer->regs[0x28] >> 1) & 0x7] / 32768.0; + mixer->line_l = sb_att_4dbstep_3bits[(mixer->regs[0x2e] >> 5) & 0x7] / 32768.0; + mixer->line_r = sb_att_4dbstep_3bits[(mixer->regs[0x2e] >> 1) & 0x7] / 32768.0; + + mixer->mic = sb_att_7dbstep_2bits[(mixer->regs[0x0a] >> 1) & 0x3] / 32768.0; + + mixer->output_filter = !(mixer->regs[0xe] & 0x20); + mixer->input_filter = !(mixer->regs[0xc] & 0x20); + mixer->in_filter_freq = ((mixer->regs[0xc] & 0x8) == 0) ? 3200 : 8800; + mixer->stereo = mixer->regs[0xe] & 2; + if (mixer->index == 0xe) + sb_dsp_set_stereo(&ess->dsp, val & 2); + + switch (mixer->regs[0xc] & 6) { + case 2: + mixer->input_selector = INPUT_CD_L | INPUT_CD_R; + break; + case 6: + mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; + break; + default: + mixer->input_selector = INPUT_MIC; + break; + } + + /* TODO: pcspeaker volume? Or is it not worth? */ + } +} + +uint8_t +ess_mixer_read(uint16_t addr, void *priv) +{ + const ess_t *ess = (ess_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_sbpro; + + if (!(addr & 1)) + return mixer->index; + + switch (mixer->index) { + case 0x00: + case 0x04: + case 0x0a: + case 0x0c: + case 0x0e: + case 0x22: + case 0x26: + case 0x28: + case 0x2e: + case 0x02: + case 0x06: + case 0x30: + case 0x32: + case 0x36: + case 0x38: + return mixer->regs[mixer->index]; + + default: + //sb_log("ess: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + break; + } + + return 0xff; +} + +void +ess_mixer_reset(ess_t *ess) +{ + ess_mixer_write(4, 0, ess); + ess_mixer_write(5, 0, ess); +} \ No newline at end of file diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 05b6abe43..29b065477 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -6,6 +6,7 @@ #define _USE_MATH_DEFINES #include +#include #include #include #include @@ -418,30 +419,65 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) memset(dsp->record_buffer, 0, sizeof(dsp->record_buffer)); } -void -sb_start_dma_ess(sb_dsp_t* dsp, int dma8, int autoinit, uint8_t format, int len) + +static unsigned int sb_ess_get_dma_len(sb_dsp_t *dsp) { + unsigned int r; + + r = (unsigned int)ESSreg(0xA5) << 8U; + r |= (unsigned int)ESSreg(0xA4); + + /* the 16-bit counter is a "two's complement" of the DMA count because it counts UP to 0 and triggers IRQ on overflow */ + return 0x10000U-r; +} + +void +sb_start_dma_ess(sb_dsp_t* dsp) +{ + uint8_t real_format = 0; + uint32_t len = !(ESSreg(0xB7) & 4) ? dsp->sb_8_length : dsp->sb_16_length; + + if (!dsp->ess_reload_len) { + len = sb_ess_get_dma_len(dsp); + } + if (IS_ESS(dsp)) { dma_set_drq(dsp->sb_8_dmanum, 0); dma_set_drq(dsp->sb_16_8_dmanum, 0); } - sb_start_dma(dsp, dma8, autoinit, format, len); + real_format |= !!(ESSreg(0xB7) & 0x20) ? 0x10 : 0; + real_format |= !!(ESSreg(0xB7) & 0x8) ? 0x20 : 0; + if (!!(ESSreg(0xB8) & 8)) + sb_start_dma_i(dsp, !(ESSreg(0xB7) & 4), (ESSreg(0xB8) >> 2) & 1, real_format, sb_ess_get_dma_len(dsp)); + else + sb_start_dma(dsp, !(ESSreg(0xB7) & 4), (ESSreg(0xB8) >> 2) & 1, real_format, sb_ess_get_dma_len(dsp)); dsp->ess_playback_mode = 1; dma_set_drq(dsp->sb_8_dmanum, 1); dma_set_drq(dsp->sb_16_8_dmanum, 1); } void -sb_start_dma_ess_i(sb_dsp_t* dsp, int dma8, int autoinit, uint8_t format, int len) +sb_stop_dma_ess(sb_dsp_t* dsp) { - if (IS_ESS(dsp)) { - dma_set_drq(dsp->sb_8_dmanum, 0); - dma_set_drq(dsp->sb_16_8_dmanum, 0); + dsp->sb_8_enable = dsp->sb_16_enable = 0; + dma_set_drq(dsp->sb_16_8_dmanum, 0); + dma_set_drq(dsp->sb_8_dmanum, 0); +} + +static void sb_ess_update_dma_status(sb_dsp_t* dsp) +{ + bool dma_en = (ESSreg(0xB8) & 1)?true:false; + + // if the DRQ is disabled, do not start + if (!(ESSreg(0xB2) & 0x40)) + dma_en = false; + + if (dma_en) { + if (!dsp->sb_8_enable && !dsp->sb_16_enable) sb_start_dma_ess(dsp); + } + else { + if (dsp->sb_8_enable || dsp->sb_16_enable) sb_stop_dma_ess(dsp); } - sb_start_dma_i(dsp, dma8, autoinit, format, len); - dsp->ess_playback_mode = 1; - dma_set_drq(dsp->sb_8_dmanum, 1); - dma_set_drq(dsp->sb_16_8_dmanum, 1); } int @@ -598,17 +634,6 @@ static void sb_ess_update_filter_freq(sb_dsp_t *dsp) ESSreg(0xA2) = 256 - (7160000 / (freq * 82)); } -static unsigned int sb_ess_get_dma_len(sb_dsp_t *dsp) -{ - unsigned int r; - - r = (unsigned int)ESSreg(0xA5) << 8U; - r |= (unsigned int)ESSreg(0xA4); - - /* the 16-bit counter is a "two's complement" of the DMA count because it counts UP to 0 and triggers IRQ on overflow */ - return 0x10000U-r; -} - static uint8_t sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) { switch (reg) { @@ -619,6 +644,120 @@ static uint8_t sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) return 0xFF; } +static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) +{ + uint8_t chg = 0x00; + sb_dsp_log("ESS register write reg=%02xh val=%02xh\n",reg,data); + + switch (reg) { + case 0xA1: /* Extended Mode Sample Rate Generator */ + { + ESSreg(reg) = data; + if (data & 0x80) + dsp->sb_freq = 795500UL / (256ul - data); + else + dsp->sb_freq = 397700UL / (128ul - data); + + if (dsp->sb_16_enable || dsp->sb_8_enable) { + sb_stop_dma_ess(dsp); + sb_start_dma_ess(dsp); + } + break; + } + case 0xA2: /* Filter divider (effectively, a hardware lowpass filter under S/W control) */ + ESSreg(reg) = data; + break; + + case 0xA4: /* DMA Transfer Count Reload (low) */ + case 0xA5: /* DMA Transfer Count Reload (high) */ + ESSreg(reg) = data; + if (dsp->sb_16_length == 0 || dsp->sb_8_length == 0) + dsp->ess_reload_len = 1; + break; + + case 0xA8: /* Analog Control */ + /* bits 7:5 0 Reserved. Always write 0 + * bit 4 1 Reserved. Always write 1 + * bit 3 Record monitor 1=Enable record monitor + * enable + * bit 2 0 Reserved. Always write 0 + * bits 1:0 Stereo/mono select 00=Reserved + * 01=Stereo + * 10=Mono + * 11=Reserved */ + chg = ESSreg(reg) ^ data; + ESSreg(reg) = data; + if (chg & 0x3) { + if (dsp->sb_16_enable || dsp->sb_8_enable) { + sb_stop_dma_ess(dsp); + sb_start_dma_ess(dsp); + } + } + break; + + case 0xB1: /* Legacy Audio Interrupt Control */ + case 0xB2: /* DRQ Control */ + chg = ESSreg(reg) ^ data; + ESSreg(reg) = (ESSreg(reg) & 0x0F) + (data & 0xF0); // lower 4 bits not writeable + if (chg & 0x40) sb_ess_update_dma_status(dsp); + break; + case 0xB5: /* DAC Direct Access Holding (low) */ + case 0xB6: /* DAC Direct Access Holding (high) */ + ESSreg(reg) = data; + break; + + case 0xB7: /* Audio 1 Control 1 */ + /* bit 7 Enable FIFO to/from codec + * bit 6 Opposite from bit 3 Must be set opposite to bit 3 + * bit 5 FIFO signed mode 1=Data is signed twos-complement 0=Data is unsigned + * bit 4 Reserved Always write 1 + * bit 3 FIFO stereo mode 1=Data is stereo + * bit 2 FIFO 16-bit mode 1=Data is 16-bit + * bit 1 Reserved Always write 0 + * bit 0 Generate load signal */ + chg = ESSreg(reg) ^ data; + ESSreg(reg) = data; + if (chg & 0x0C) { + if (dsp->sb_16_enable || dsp->sb_8_enable) { + sb_stop_dma_ess(dsp); + sb_start_dma_ess(dsp); + } + } + break; + + case 0xB8: /* Audio 1 Control 2 */ + /* bits 7:4 reserved + * bit 3 CODEC mode 1=first DMA converter in ADC mode + * 0=first DMA converter in DAC mode + * bit 2 DMA mode 1=auto-initialize mode + * 0=normal DMA mode + * bit 1 DMA read enable 1=first DMA is read (for ADC) + * 0=first DMA is write (for DAC) + * bit 0 DMA xfer enable 1=DMA is allowed to proceed */ + data &= 0xF; + chg = ESSreg(reg) ^ data; + ESSreg(reg) = data; + + if (chg & 1) + dsp->ess_reload_len = 1; + + if (chg & 0xB) { + if (chg & 0xA) sb_stop_dma_ess(dsp); /* changing capture/playback direction? stop DMA to reinit */ + sb_ess_update_dma_status(dsp); + } + break; + + case 0xB9: /* Audio 1 Transfer Type */ + case 0xBA: /* Left Channel ADC Offset Adjust */ + case 0xBB: /* Right Channel ADC Offset Adjust */ + ESSreg(reg) = data; + break; + + default: + break; + } +} + void sb_exec_command(sb_dsp_t *dsp) { @@ -632,11 +771,17 @@ sb_exec_command(sb_dsp_t *dsp) if (dsp->sb_type >= SB16) dsp->sb_8051_ram[0x20] = dsp->sb_command; - if (IS_ESS(dsp)) { - if (dsp->sb_command == 0xC6 || dsp->sb_command == 0xC7){ + if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { + if (dsp->sb_command == 0xC6 || dsp->sb_command == 0xC7) { dsp->ess_extended_mode = !!(dsp->sb_command == 0xC6); return; } + if (dsp->sb_command == 0xC0) { + sb_add_data(dsp, sb_ess_read_reg(dsp, dsp->sb_data[0])); + } else if (dsp->sb_command < 0xC0 && dsp->ess_extended_mode) { + sb_ess_write_reg(dsp, dsp->sb_command, dsp->sb_data[0]); + } + return; } switch (dsp->sb_command) { @@ -1062,12 +1207,29 @@ sb_exec_command(sb_dsp_t *dsp) while (sb16_copyright[c]) sb_add_data(dsp, sb16_copyright[c++]); sb_add_data(dsp, 0); + } else if (IS_ESS(dsp)) { + sb_add_data(dsp, 0); } break; case 0xE4: /* Write test register */ dsp->sb_test = dsp->sb_data[0]; break; - case 0xE7: /* ???? */ + case 0xE7: /* ???? */ /* ESS detect/read config on ESS cards */ + if (IS_ESS(dsp)) { + switch (dsp->sb_subtype) { + default: + break; + case SB_SUBTYPE_ESS_ES688: + sb_add_data(dsp, 0x68); + sb_add_data(dsp, 0x80 | 0x04); + break; + case SB_SUBTYPE_ESS_ES1688: + // Determined via Windows driver debugging. + sb_add_data(dsp, 0x68); + sb_add_data(dsp, 0x80 | 0x09); + break; + } + } break; case 0xE8: /* Read test register */ sb_add_data(dsp, dsp->sb_test); @@ -1170,6 +1332,13 @@ sb_write(uint16_t a, uint8_t v, void *priv) else if (dsp->sb_command == 0x08 && dsp->sb_data_stat == 1 && dsp->sb_data[0] == 0x07) sb_commands[dsp->sb_command] = 2; } + if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { + if (dsp->sb_command <= 0xC0) { + sb_commands[dsp->sb_command] = 1; + } else { + sb_commands[dsp->sb_command] = 0; + } + } } if (dsp->sb_data_stat == sb_commands[dsp->sb_command] || sb_commands[dsp->sb_command] == -1) { sb_exec_command(dsp); From 7f9f072b3e51324a299b07bd2140f1cebebcb261 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 3 Mar 2024 16:19:01 +0600 Subject: [PATCH 725/936] Add ESS ES1688 (COMPLETELY UNTESTED!!!) --- src/include/86box/sound.h | 4 + src/sound/snd_ess.c | 261 +++++++++++++++++++++++++++++++++++++- src/sound/sound.c | 1 + 3 files changed, 265 insertions(+), 1 deletion(-) diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index b8f9be5b2..c6fdada89 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -184,6 +184,10 @@ extern const device_t cmi8338_onboard_device; extern const device_t cmi8738_device; extern const device_t cmi8738_onboard_device; extern const device_t cmi8738_6ch_onboard_device; + +/* ESS Technology */ +extern const device_t ess_1688_device; + #endif #endif /*EMU_SOUND_H*/ diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index d762117cd..5b6852b68 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -255,4 +255,263 @@ ess_mixer_reset(ess_t *ess) { ess_mixer_write(4, 0, ess); ess_mixer_write(5, 0, ess); -} \ No newline at end of file +} + +void +ess_get_buffer_sbpro(int32_t *buffer, int len, void *priv) +{ + sb_t *sb = (sb_t *) priv; + const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; + double out_l = 0.0; + double out_r = 0.0; + + sb_dsp_update(&sb->dsp); + + for (int c = 0; c < len * 2; c += 2) { + out_l = 0.0; + out_r = 0.0; + + /* TODO: Implement the stereo switch on the mixer instead of on the dsp? */ + if (mixer->output_filter) { + out_l += (sb_iir(0, 0, (double) sb->dsp.buffer[c]) * mixer->voice_l) / 3.9; + out_r += (sb_iir(0, 1, (double) sb->dsp.buffer[c + 1]) * mixer->voice_r) / 3.9; + } else { + out_l += (sb->dsp.buffer[c] * mixer->voice_l) / 3.0; + out_r += (sb->dsp.buffer[c + 1] * mixer->voice_r) / 3.0; + } + + /* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */ + out_l *= mixer->master_l; + out_r *= mixer->master_r; + + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; + } + + sb->dsp.pos = 0; +} + +void +ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) +{ + ess_t *ess = (ess_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_sbpro; + double out_l = 0.0; + double out_r = 0.0; + const int32_t *opl_buf = NULL; + const int32_t *opl2_buf = NULL; + + opl_buf = ess->opl.update(ess->opl.priv); + + sb_dsp_update(&ess->dsp); + + for (int c = 0; c < len * 2; c += 2) { + out_l = 0.0; + out_r = 0.0; + + { + out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; + out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; + if (ess->opl_mix && ess->opl_mixer) + ess->opl_mix(ess->opl_mixer, &out_l, &out_r); + } + + /* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */ + out_l *= mixer->master_l; + out_r *= mixer->master_r; + + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; + } + + ess->opl.reset_buffer(ess->opl.priv); +} + +void +ess_filter_cd_audio(int channel, double *buffer, void *priv) +{ + const ess_t *ess = (ess_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_sbpro; + double c; + double cd = channel ? mixer->cd_r : mixer->cd_l; + double master = channel ? mixer->master_r : mixer->master_l; + + if (mixer->output_filter) + c = (sb_iir(2, channel, *buffer) * cd) / 3.9; + else + c = (*buffer * cd) / 3.0; + *buffer = c * master; +} + +static void * +ess_1688_init(UNUSED(const device_t *info)) +{ + /* SB Pro 2 port mappings, 220h or 240h. + 2x0 to 2x3 -> FM chip (18 voices) + 2x4 to 2x5 -> Mixer interface + 2x6, 2xA, 2xC, 2xE -> DSP chip + 2x8, 2x9, 388 and 389 FM chip (9 voices) + 2x0+10 to 2x0+13 CDROM interface. */ + ess_t *ess = malloc(sizeof(ess_t)); + uint16_t addr = device_get_config_hex16("base"); + memset(ess, 0, sizeof(ess_t)); + + fm_driver_get(FM_ESFM, &ess->opl); + + sb_dsp_set_real_opl(&ess->dsp, 1); + sb_dsp_init(&ess->dsp, SBPRO2, SB_SUBTYPE_ESS_ES1688, ess); + sb_dsp_setaddr(&ess->dsp, addr); + sb_dsp_setirq(&ess->dsp, device_get_config_int("irq")); + sb_dsp_setdma8(&ess->dsp, device_get_config_int("dma")); + ess_mixer_reset(ess); + /* DSP I/O handler is activated in sb_dsp_setaddr */ + { + io_sethandler(addr, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_sethandler(addr + 8, 0x0002, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_sethandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + } + + ess->mixer_enabled = 1; + io_sethandler(addr + 4, 0x0002, + ess_mixer_read, NULL, NULL, + ess_mixer_write, NULL, NULL, + ess); + sound_add_handler(ess_get_buffer_sbpro, ess); + music_add_handler(ess_get_music_buffer_sbpro, ess); + sound_set_cd_audio_filter(ess_filter_cd_audio, ess); + + if (device_get_config_int("receive_input")) + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &ess->dsp); + + return ess; +} + +void +ess_close(void *priv) +{ + ess_t *ess = (ess_t *) priv; + sb_dsp_close(&ess->dsp); + + free(ess); +} + +void +ess_speed_changed(void *priv) +{ + ess_t *ess = (ess_t *) priv; + + sb_dsp_speed_changed(&ess->dsp); +} + +static const device_config_t ess_config[] = { + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x220, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "0x220", + .value = 0x220 + }, + { + .description = "0x240", + .value = 0x240 + }, + { .description = "" } + } + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 7, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "IRQ 2", + .value = 2 + }, + { + .description = "IRQ 5", + .value = 5 + }, + { + .description = "IRQ 7", + .value = 7 + }, + { + .description = "IRQ 10", + .value = 10 + }, + { .description = "" } + } + }, + { + .name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 1, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "DMA 0", + .value = 0 + }, + { + .description = "DMA 1", + .value = 1 + }, + { + .description = "DMA 3", + .value = 3 + }, + { .description = "" } + } + }, + { + .name = "opl", + .description = "Enable OPL", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, + { + .name = "receive_input", + .description = "Receive input (SB MIDI)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +const device_t ess_1688_device = { + .name = "ESS Technology ESS1688", + .internal_name = "ess_1688", + .flags = DEVICE_ISA, + .local = 0, + .init = ess_1688_init, + .close = ess_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = ess_speed_changed, + .force_redraw = NULL, + .config = ess_config +}; \ No newline at end of file diff --git a/src/sound/sound.c b/src/sound/sound.c index 81f70d921..2f6b91aca 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -165,6 +165,7 @@ static const SOUND_CARD sound_cards[] = { { &es1371_device }, { &ad1881_device }, { &cs4297a_device }, + { &ess_1688_device }, { NULL } // clang-format on }; From 6ab45767e5fad8b8d1638c677a3be07cf8e55d50 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 3 Mar 2024 16:26:49 +0600 Subject: [PATCH 726/936] Some cleanup and crash fixes --- src/sound/snd_ess.c | 1 - src/sound/snd_opl_esfm.c | 11 ++++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 5b6852b68..f0f1b5ec7 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -299,7 +299,6 @@ ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) double out_l = 0.0; double out_r = 0.0; const int32_t *opl_buf = NULL; - const int32_t *opl2_buf = NULL; opl_buf = ess->opl.update(ess->opl.priv); diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index 3720c8ada..cbd9a93a3 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -54,18 +54,19 @@ typedef struct { uint16_t timer_count[2]; uint16_t timer_cur_count[2]; + int16_t samples[2]; + int pos; - int32_t buffer[SOUNDBUFLEN * 2]; + int32_t buffer[MUSICBUFLEN * 2]; } esfm_drv_t; void esfm_generate_raw(esfm_drv_t *dev, int32_t *bufp) { - int16_t samples[2] = { 0, 0 }; - ESFM_generate(&dev->opl, samples); + ESFM_generate(&dev->opl, &dev->samples[0]); - bufp[0] = (int32_t) samples[0]; - bufp[1] = (int32_t) samples[1]; + bufp[0] = dev->samples[0]; + bufp[1] = dev->samples[1]; } void From d46e00e5a05307e25ed24dfb7540a6ec8f393432 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 4 Mar 2024 00:16:04 +0600 Subject: [PATCH 727/936] Autolen updating --- src/sound/snd_sb_dsp.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 29b065477..ed74fea68 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -644,6 +644,10 @@ static uint8_t sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) return 0xFF; } +static void sb_ess_update_autolen(sb_dsp_t *dsp) { + dsp->sb_8_autolen = dsp->sb_16_autolen = sb_ess_get_dma_len(dsp); +} + static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) { uint8_t chg = 0x00; @@ -671,7 +675,8 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) case 0xA4: /* DMA Transfer Count Reload (low) */ case 0xA5: /* DMA Transfer Count Reload (high) */ ESSreg(reg) = data; - if (dsp->sb_16_length == 0 || dsp->sb_8_length == 0) + sb_ess_update_autolen(dsp); + if (dsp->sb_16_length < 0 || dsp->sb_8_length < 0) dsp->ess_reload_len = 1; break; @@ -741,6 +746,9 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) if (chg & 1) dsp->ess_reload_len = 1; + if (chg & 4) + sb_ess_update_autolen(dsp); + if (chg & 0xB) { if (chg & 0xA) sb_stop_dma_ess(dsp); /* changing capture/playback direction? stop DMA to reinit */ sb_ess_update_dma_status(dsp); From 650b7e633beecd54d278707719b74b055426739e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 4 Mar 2024 00:20:27 +0600 Subject: [PATCH 728/936] Minor fixing --- src/sound/snd_sb_dsp.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index ed74fea68..7977cc030 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -722,6 +722,10 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) * bit 0 Generate load signal */ chg = ESSreg(reg) ^ data; ESSreg(reg) = data; + + if (chg & 4) + sb_ess_update_autolen(dsp); + if (chg & 0x0C) { if (dsp->sb_16_enable || dsp->sb_8_enable) { sb_stop_dma_ess(dsp); @@ -746,9 +750,6 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) if (chg & 1) dsp->ess_reload_len = 1; - if (chg & 4) - sb_ess_update_autolen(dsp); - if (chg & 0xB) { if (chg & 0xA) sb_stop_dma_ess(dsp); /* changing capture/playback direction? stop DMA to reinit */ sb_ess_update_dma_status(dsp); From 68f6779b2f53216308841fbead06f23f07383a66 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 4 Mar 2024 01:35:34 +0600 Subject: [PATCH 729/936] Handle length reloading correctly --- src/sound/snd_sb_dsp.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 7977cc030..58131515d 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -437,8 +437,9 @@ sb_start_dma_ess(sb_dsp_t* dsp) uint8_t real_format = 0; uint32_t len = !(ESSreg(0xB7) & 4) ? dsp->sb_8_length : dsp->sb_16_length; - if (!dsp->ess_reload_len) { + if (dsp->ess_reload_len) { len = sb_ess_get_dma_len(dsp); + dsp->ess_reload_len = 0; } if (IS_ESS(dsp)) { @@ -676,7 +677,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) case 0xA5: /* DMA Transfer Count Reload (high) */ ESSreg(reg) = data; sb_ess_update_autolen(dsp); - if (dsp->sb_16_length < 0 || dsp->sb_8_length < 0) + if ((dsp->sb_16_length < 0 && !dsp->sb_16_enable) && (dsp->sb_8_length < 0 && !dsp->sb_8_enable)) dsp->ess_reload_len = 1; break; @@ -1912,6 +1913,7 @@ sb_poll_i(void *priv) else { dsp->sb_8_enable = 0; timer_disable(&dsp->input_timer); + sb_ess_finish_dma(dsp); } sb_irq(dsp, 1); } @@ -1960,6 +1962,7 @@ sb_poll_i(void *priv) else { dsp->sb_16_enable = 0; timer_disable(&dsp->input_timer); + sb_ess_finish_dma(dsp); } sb_irq(dsp, 0); } From dfa0ec6be80dab9dc800724dd988d9c9584eeae9 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 4 Mar 2024 02:00:07 +0600 Subject: [PATCH 730/936] Implement ESS identification mixer register --- src/sound/snd_ess.c | 21 +++++++++++++++++++-- src/sound/snd_sb_dsp.c | 3 +++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index f0f1b5ec7..9347a755e 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -76,6 +76,9 @@ typedef struct ess_mixer_t { uint8_t index; uint8_t regs[256]; + + uint8_t ess_id_str[4]; + uint8_t ess_id_str_pos : 2; } ess_mixer_t; typedef struct ess_t { @@ -128,6 +131,8 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) if (!(addr & 1)) { mixer->index = val; mixer->regs[0x01] = val; + if (val == 0x40) + mixer->ess_id_str_pos = 0; } else { if (mixer->index == 0) { /* Reset */ @@ -218,8 +223,8 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) uint8_t ess_mixer_read(uint16_t addr, void *priv) { - const ess_t *ess = (ess_t *) priv; - const ess_mixer_t *mixer = &ess->mixer_sbpro; + ess_t *ess = (ess_t *) priv; + ess_mixer_t *mixer = &ess->mixer_sbpro; if (!(addr & 1)) return mixer->index; @@ -242,6 +247,11 @@ ess_mixer_read(uint16_t addr, void *priv) case 0x38: return mixer->regs[mixer->index]; + case 0x40: + { + return mixer->ess_id_str[mixer->ess_id_str_pos++]; + } + default: //sb_log("ess: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; @@ -391,6 +401,13 @@ ess_1688_init(UNUSED(const device_t *info)) if (device_get_config_int("receive_input")) midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &ess->dsp); + { + ess->mixer_sbpro.ess_id_str[0] = 0x16; + ess->mixer_sbpro.ess_id_str[1] = 0x88; + ess->mixer_sbpro.ess_id_str[2] = (addr >> 8) & 0xff; + ess->mixer_sbpro.ess_id_str[3] = addr & 0xff; + } + return ess; } diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 58131515d..45f8440a2 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -900,6 +900,9 @@ sb_exec_command(sb_dsp_t *dsp) case 0x10: /* 8-bit direct mode */ sb_dsp_update(dsp); dsp->sbdat = dsp->sbdatl = dsp->sbdatr = (dsp->sb_data[0] ^ 0x80) << 8; + // FIXME: What does the ESS AudioDrive do to its filter/sample rate divider registers when emulating this Sound Blaster command? + ESSreg(0xA1) = 128 - (397700 / 22050); + ESSreg(0xA2) = 256 - (7160000 / (82 * ((4 * 22050) / 10))); break; case 0x14: /* 8-bit single cycle DMA output */ sb_start_dma(dsp, 1, 0, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); From a2b13cadbff2d8ca9c295cd9431371527b5e3b75 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 4 Mar 2024 13:18:50 +0600 Subject: [PATCH 731/936] ESS: implement mixer regs and fix ESS-specific DMA --- src/sound/snd_ess.c | 105 ++++++++++++++++++++++++++++++++++++----- src/sound/snd_sb_dsp.c | 17 +++++-- 2 files changed, 106 insertions(+), 16 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 9347a755e..b58618c3a 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #define HAVE_STDARG_H @@ -122,6 +123,11 @@ static inline uint8_t expand16to32(const uint8_t t) { return (t << 1) | (t >> 3); } +static double ess_mixer_get_vol_4bit(uint8_t vol) +{ + return (48.0 + (20.0 * log((vol & 0xF) / 15.0))) / 48.0; +} + void ess_mixer_write(uint16_t addr, uint8_t val, void *priv) { @@ -142,6 +148,14 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->regs[0x04] = mixer->regs[0x22] = 0xee; mixer->regs[0x26] = mixer->regs[0x28] = 0xee; mixer->regs[0x2e] = 0x00; + + /* Initialize ESS regs. */ + mixer->regs[0x14] = mixer->regs[0x32] = 0x88; + mixer->regs[0x36] = 0x88; + mixer->regs[0x38] = 0x00; + mixer->regs[0x3a] = 0x00; + mixer->regs[0x3e] = 0x00; + sb_dsp_set_stereo(&ess->dsp, mixer->regs[0x0e] & 2); } else { mixer->regs[mixer->index] = val; @@ -153,20 +167,29 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) case 0x08: mixer->regs[mixer->index + 0x20] = ((val & 0xe) << 4) | (val & 0xe); break; + + case 0x14: + mixer->regs[0x4] = val & 0xee; + break; case 0x22: case 0x26: case 0x28: + case 0x2E: mixer->regs[mixer->index - 0x20] = (val & 0xe); + mixer->regs[mixer->index + 0x10] = val; break; /* More compatibility: SoundBlaster Pro selects register 020h for 030h, 022h for 032h, 026h for 036h, and 028h for 038h. */ case 0x30: + mixer->regs[mixer->index - 0x10] = (val & 0xee); + break; case 0x32: case 0x36: case 0x38: + case 0x3e: mixer->regs[mixer->index - 0x10] = (val & 0xee); break; @@ -175,25 +198,75 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) case 0x0a: case 0x0c: case 0x0e: - case 0x2e: break; + case 0x40: { + uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] & 0x38) << 1); + gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); + io_removehandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + if (mixer->regs[0x40] & 1) { + io_sethandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + } + + switch ((mixer->regs[0x40] >> 5) & 7) { + case 0: + mpu401_change_addr(ess->mpu, 0x00); + mpu401_setirq(ess->mpu, -1); + break; + case 1: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, -1); + break; + case 2: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, ess->dsp.sb_irqnum); + break; + case 3: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 0xE); + break; + case 4: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 0xA); + break; + case 5: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 0xB); + break; + case 6: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 0xC); + break; + case 7: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 0xD); + break; + } + break; + } + default: //sb_log("ess: Unknown register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } } - mixer->voice_l = sb_att_4dbstep_3bits[(mixer->regs[0x04] >> 5) & 0x7] / 32768.0; - mixer->voice_r = sb_att_4dbstep_3bits[(mixer->regs[0x04] >> 1) & 0x7] / 32768.0; - mixer->master_l = sb_att_4dbstep_3bits[(mixer->regs[0x22] >> 5) & 0x7] / 32768.0; - mixer->master_r = sb_att_4dbstep_3bits[(mixer->regs[0x22] >> 1) & 0x7] / 32768.0; - mixer->fm_l = sb_att_4dbstep_3bits[(mixer->regs[0x26] >> 5) & 0x7] / 32768.0; - mixer->fm_r = sb_att_4dbstep_3bits[(mixer->regs[0x26] >> 1) & 0x7] / 32768.0; - mixer->cd_l = sb_att_4dbstep_3bits[(mixer->regs[0x28] >> 5) & 0x7] / 32768.0; - mixer->cd_r = sb_att_4dbstep_3bits[(mixer->regs[0x28] >> 1) & 0x7] / 32768.0; - mixer->line_l = sb_att_4dbstep_3bits[(mixer->regs[0x2e] >> 5) & 0x7] / 32768.0; - mixer->line_r = sb_att_4dbstep_3bits[(mixer->regs[0x2e] >> 1) & 0x7] / 32768.0; + mixer->voice_l = ess_mixer_get_vol_4bit(mixer->regs[0x14]); + mixer->voice_r = ess_mixer_get_vol_4bit(mixer->regs[0x14] >> 4); + mixer->master_l = ess_mixer_get_vol_4bit(mixer->regs[0x32]); + mixer->master_r = ess_mixer_get_vol_4bit(mixer->regs[0x32] >> 4); + mixer->fm_l = ess_mixer_get_vol_4bit(mixer->regs[0x36]); + mixer->fm_r = ess_mixer_get_vol_4bit(mixer->regs[0x36] >> 4); + mixer->cd_l = ess_mixer_get_vol_4bit(mixer->regs[0x38]); + mixer->cd_r = ess_mixer_get_vol_4bit(mixer->regs[0x38] >> 4); + mixer->line_l = ess_mixer_get_vol_4bit(mixer->regs[0x3e]); + mixer->line_r = ess_mixer_get_vol_4bit(mixer->regs[0x3e] >> 4); mixer->mic = sb_att_7dbstep_2bits[(mixer->regs[0x0a] >> 1) & 0x3] / 32768.0; @@ -372,6 +445,8 @@ ess_1688_init(UNUSED(const device_t *info)) sb_dsp_setaddr(&ess->dsp, addr); sb_dsp_setirq(&ess->dsp, device_get_config_int("irq")); sb_dsp_setdma8(&ess->dsp, device_get_config_int("dma")); + sb_dsp_setdma16_8(&ess->dsp, device_get_config_int("dma")); + sb_dsp_setdma16_supported(&ess->dsp, 0); ess_mixer_reset(ess); /* DSP I/O handler is activated in sb_dsp_setaddr */ { @@ -408,6 +483,14 @@ ess_1688_init(UNUSED(const device_t *info)) ess->mixer_sbpro.ess_id_str[3] = addr & 0xff; } + ess->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); + mpu401_init(ess->mpu, 0, 0, M_UART, 1); + sb_dsp_set_mpu(&ess->dsp, ess->mpu); + + ess->gameport = gameport_add(&gameport_pnp_device); + ess->gameport_addr = 0x000; + gameport_remap(ess->gameport, ess->gameport_addr); + return ess; } diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 45f8440a2..fa3133768 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -437,7 +437,7 @@ sb_start_dma_ess(sb_dsp_t* dsp) uint8_t real_format = 0; uint32_t len = !(ESSreg(0xB7) & 4) ? dsp->sb_8_length : dsp->sb_16_length; - if (dsp->ess_reload_len) { + if (dsp->ess_reload_len || len <= 0) { len = sb_ess_get_dma_len(dsp); dsp->ess_reload_len = 0; } @@ -449,9 +449,9 @@ sb_start_dma_ess(sb_dsp_t* dsp) real_format |= !!(ESSreg(0xB7) & 0x20) ? 0x10 : 0; real_format |= !!(ESSreg(0xB7) & 0x8) ? 0x20 : 0; if (!!(ESSreg(0xB8) & 8)) - sb_start_dma_i(dsp, !(ESSreg(0xB7) & 4), (ESSreg(0xB8) >> 2) & 1, real_format, sb_ess_get_dma_len(dsp)); + sb_start_dma_i(dsp, !(ESSreg(0xB7) & 4), (ESSreg(0xB8) >> 2) & 1, real_format, len); else - sb_start_dma(dsp, !(ESSreg(0xB7) & 4), (ESSreg(0xB8) >> 2) & 1, real_format, sb_ess_get_dma_len(dsp)); + sb_start_dma(dsp, !(ESSreg(0xB7) & 4), (ESSreg(0xB8) >> 2) & 1, real_format, len); dsp->ess_playback_mode = 1; dma_set_drq(dsp->sb_8_dmanum, 1); dma_set_drq(dsp->sb_16_8_dmanum, 1); @@ -748,8 +748,15 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) chg = ESSreg(reg) ^ data; ESSreg(reg) = data; - if (chg & 1) - dsp->ess_reload_len = 1; + if (chg & 1) { + if (dsp->sb_16_enable || dsp->sb_8_enable) { + if (dsp->sb_16_enable) + dsp->sb_16_length = sb_ess_get_dma_len(dsp); + if (dsp->sb_8_enable) + dsp->sb_8_length = sb_ess_get_dma_len(dsp); + } else + dsp->ess_reload_len = 1; + } if (chg & 0xB) { if (chg & 0xA) sb_stop_dma_ess(dsp); /* changing capture/playback direction? stop DMA to reinit */ From 181d42610fa7299d6b55e2a3570e67c7ed18a94f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 4 Mar 2024 13:20:20 +0600 Subject: [PATCH 732/936] Correct name of ESS device --- src/sound/snd_ess.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index b58618c3a..d3e02bf2f 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -602,8 +602,8 @@ static const device_config_t ess_config[] = { }; const device_t ess_1688_device = { - .name = "ESS Technology ESS1688", - .internal_name = "ess_1688", + .name = "ESS Technology ES1688", + .internal_name = "ess_es1688", .flags = DEVICE_ISA, .local = 0, .init = ess_1688_init, From 2446c4ebd4671c16b289163d26d09ea76190ac63 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 4 Mar 2024 14:56:07 +0600 Subject: [PATCH 733/936] Fix some stale functions --- src/sound/snd_ess.c | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index d3e02bf2f..504122a0b 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -78,27 +78,19 @@ typedef struct ess_mixer_t { uint8_t index; uint8_t regs[256]; - uint8_t ess_id_str[4]; - uint8_t ess_id_str_pos : 2; + uint8_t ess_id_str[256]; + uint8_t ess_id_str_pos; } ess_mixer_t; typedef struct ess_t { uint8_t mixer_enabled; fm_drv_t opl; sb_dsp_t dsp; - union { - ess_mixer_t mixer_sbpro; - }; + ess_mixer_t mixer_sbpro; + mpu_t *mpu; - emu8k_t emu8k; void *gameport; - int pnp; - - uint8_t pos_regs[8]; - uint8_t pnp_rom[512]; - - uint16_t opl_pnp_addr; uint16_t gameport_addr; void *opl_mixer; @@ -322,7 +314,11 @@ ess_mixer_read(uint16_t addr, void *priv) case 0x40: { - return mixer->ess_id_str[mixer->ess_id_str_pos++]; + uint8_t val = mixer->ess_id_str[mixer->ess_id_str_pos]; + mixer->ess_id_str_pos++; + if (mixer->ess_id_str_pos >= 4) + mixer->ess_id_str_pos = 0; + return val; } default: @@ -343,12 +339,12 @@ ess_mixer_reset(ess_t *ess) void ess_get_buffer_sbpro(int32_t *buffer, int len, void *priv) { - sb_t *sb = (sb_t *) priv; - const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; + ess_t *ess = (ess_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_sbpro; double out_l = 0.0; double out_r = 0.0; - sb_dsp_update(&sb->dsp); + sb_dsp_update(&ess->dsp); for (int c = 0; c < len * 2; c += 2) { out_l = 0.0; @@ -356,11 +352,11 @@ ess_get_buffer_sbpro(int32_t *buffer, int len, void *priv) /* TODO: Implement the stereo switch on the mixer instead of on the dsp? */ if (mixer->output_filter) { - out_l += (sb_iir(0, 0, (double) sb->dsp.buffer[c]) * mixer->voice_l) / 3.9; - out_r += (sb_iir(0, 1, (double) sb->dsp.buffer[c + 1]) * mixer->voice_r) / 3.9; + out_l += (sb_iir(0, 0, (double) ess->dsp.buffer[c]) * mixer->voice_l) / 3.9; + out_r += (sb_iir(0, 1, (double) ess->dsp.buffer[c + 1]) * mixer->voice_r) / 3.9; } else { - out_l += (sb->dsp.buffer[c] * mixer->voice_l) / 3.0; - out_r += (sb->dsp.buffer[c + 1] * mixer->voice_r) / 3.0; + out_l += (ess->dsp.buffer[c] * mixer->voice_l) / 3.0; + out_r += (ess->dsp.buffer[c + 1] * mixer->voice_r) / 3.0; } /* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */ @@ -371,7 +367,7 @@ ess_get_buffer_sbpro(int32_t *buffer, int len, void *priv) buffer[c + 1] += (int32_t) out_r; } - sb->dsp.pos = 0; + ess->dsp.pos = 0; } void @@ -434,9 +430,8 @@ ess_1688_init(UNUSED(const device_t *info)) 2x6, 2xA, 2xC, 2xE -> DSP chip 2x8, 2x9, 388 and 389 FM chip (9 voices) 2x0+10 to 2x0+13 CDROM interface. */ - ess_t *ess = malloc(sizeof(ess_t)); + ess_t *ess = calloc(sizeof(ess_t), 1); uint16_t addr = device_get_config_hex16("base"); - memset(ess, 0, sizeof(ess_t)); fm_driver_get(FM_ESFM, &ess->opl); From 6ae6ca11714b746b2967fa1b8a18f2587c02f9d8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 4 Mar 2024 15:04:17 +0600 Subject: [PATCH 734/936] Fix OPL address decoding getting disabled for some reason --- src/sound/snd_ess.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 504122a0b..0d507dc5f 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -195,6 +195,8 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) case 0x40: { uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] & 0x38) << 1); gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); + /* This doesn't work yet. */ + /* io_removehandler(0x0388, 0x0004, ess->opl.read, NULL, NULL, ess->opl.write, NULL, NULL, @@ -204,7 +206,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) ess->opl.read, NULL, NULL, ess->opl.write, NULL, NULL, ess->opl.priv); - } + }*/ switch ((mixer->regs[0x40] >> 5) & 7) { case 0: From 2bdd5ca9bcfa4361650367003173855e14b44eb8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 4 Mar 2024 15:58:02 +0600 Subject: [PATCH 735/936] Correct IRQ selection and detection fixes --- src/sound/snd_ess.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 0d507dc5f..7f48c95c0 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -79,7 +79,7 @@ typedef struct ess_mixer_t { uint8_t regs[256]; uint8_t ess_id_str[256]; - uint8_t ess_id_str_pos; + uint8_t ess_id_str_pos : 2; } ess_mixer_t; typedef struct ess_t { @@ -192,6 +192,10 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) case 0x0e: break; + case 0x64: + mixer->regs[mixer->index] &= ~0x8; + break; + case 0x40: { uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] & 0x38) << 1); gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); @@ -223,23 +227,23 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) break; case 3: mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 0xE); + mpu401_setirq(ess->mpu, 11); break; case 4: mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 0xA); + mpu401_setirq(ess->mpu, 9); break; case 5: mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 0xB); + mpu401_setirq(ess->mpu, 5); break; case 6: mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 0xC); + mpu401_setirq(ess->mpu, 7); break; case 7: mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 0xD); + mpu401_setirq(ess->mpu, 10); break; } break; @@ -302,6 +306,7 @@ ess_mixer_read(uint16_t addr, void *priv) case 0x0a: case 0x0c: case 0x0e: + case 0x14: case 0x22: case 0x26: case 0x28: @@ -312,8 +317,12 @@ ess_mixer_read(uint16_t addr, void *priv) case 0x32: case 0x36: case 0x38: + case 0x3e: return mixer->regs[mixer->index]; + case 0x64: + return mixer->regs[mixer->index] & 7; + case 0x40: { uint8_t val = mixer->ess_id_str[mixer->ess_id_str_pos]; @@ -324,11 +333,11 @@ ess_mixer_read(uint16_t addr, void *priv) } default: - //sb_log("ess: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + pclog("ess: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } - return 0xff; + return 0x00; } void From 552f595bc549b17a754fe57bb73ba8ae8434dfc3 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 4 Mar 2024 16:00:41 +0600 Subject: [PATCH 736/936] Fix AudioDrive detection on Windows 3.1 Sound is not working, and neither is MPU-401 --- src/sound/snd_ess.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 7f48c95c0..400983aba 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -320,9 +320,6 @@ ess_mixer_read(uint16_t addr, void *priv) case 0x3e: return mixer->regs[mixer->index]; - case 0x64: - return mixer->regs[mixer->index] & 7; - case 0x40: { uint8_t val = mixer->ess_id_str[mixer->ess_id_str_pos]; From 2e9e20c0787a37301493c3c7896ebd73cb08097a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 5 Mar 2024 14:06:20 +0600 Subject: [PATCH 737/936] Deal with edge cases where drivers use non-ESS playback route --- src/sound/snd_sb_dsp.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index fa3133768..90d66c144 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -353,11 +353,27 @@ sb_add_data(sb_dsp_t *dsp, uint8_t v) dsp->sb_read_wp &= 0xff; } +static unsigned int sb_ess_get_dma_len(sb_dsp_t *dsp) +{ + unsigned int r; + + r = (unsigned int)ESSreg(0xA5) << 8U; + r |= (unsigned int)ESSreg(0xA4); + + /* the 16-bit counter is a "two's complement" of the DMA count because it counts UP to 0 and triggers IRQ on overflow */ + return 0x10000U-r; +} + void sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) { dsp->sb_pausetime = -1; + if (dsp->ess_reload_len) { + len = sb_ess_get_dma_len(dsp); + dsp->ess_reload_len = 0; + } + if (dma8) { dsp->sb_8_length = dsp->sb_8_origlength = len; dsp->sb_8_format = format; @@ -392,6 +408,11 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) void sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) { + if (dsp->ess_reload_len) { + len = sb_ess_get_dma_len(dsp); + dsp->ess_reload_len = 0; + } + if (dma8) { dsp->sb_8_length = dsp->sb_8_origlength = len; dsp->sb_8_format = format; @@ -419,18 +440,6 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) memset(dsp->record_buffer, 0, sizeof(dsp->record_buffer)); } - -static unsigned int sb_ess_get_dma_len(sb_dsp_t *dsp) -{ - unsigned int r; - - r = (unsigned int)ESSreg(0xA5) << 8U; - r |= (unsigned int)ESSreg(0xA4); - - /* the 16-bit counter is a "two's complement" of the DMA count because it counts UP to 0 and triggers IRQ on overflow */ - return 0x10000U-r; -} - void sb_start_dma_ess(sb_dsp_t* dsp) { From 0362f563f6ffbac876a002c7e552885cbf358d34 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 5 Mar 2024 16:14:50 +0600 Subject: [PATCH 738/936] Some fixes --- src/sound/snd_ess.c | 4 ++-- src/sound/snd_sb_dsp.c | 43 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 400983aba..57ba092c3 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -250,7 +250,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) } default: - //sb_log("ess: Unknown register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + pclog("ess: Unknown register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } } @@ -334,7 +334,7 @@ ess_mixer_read(uint16_t addr, void *priv) break; } - return 0x00; + return 0x0a; } void diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 90d66c144..7cc189d30 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -585,15 +585,53 @@ sb_16_write_dma(void *priv, uint16_t val) void sb_dsp_setirq(sb_dsp_t *dsp, int irq) { + uint8_t t = 0x00; sb_dsp_log("IRQ now: %i\n", irq); dsp->sb_irqnum = irq; + + /* legacy audio interrupt control */ + t = 0x80;/*game compatible IRQ*/ + switch (dsp->sb_irqnum) { + case 5: t |= 0x5; break; + case 7: t |= 0xA; break; + case 10: t |= 0xF; break; + } + ESSreg(0xB1) = t; + + /* DRQ control */ + t = 0x80;/*game compatible DRQ */ + switch (dsp->sb_8_dmanum) { + case 0: t |= 0x5; break; + case 1: t |= 0xA; break; + case 3: t |= 0xF; break; + } + ESSreg(0xB2) = t; } void sb_dsp_setdma8(sb_dsp_t *dsp, int dma) { + uint8_t t = 0x00; sb_dsp_log("8-bit DMA now: %i\n", dma); dsp->sb_8_dmanum = dma; + + /* legacy audio interrupt control */ + t = 0x80;/*game compatible IRQ*/ + switch (dsp->sb_irqnum) { + case 5: t |= 0x5; break; + case 7: t |= 0xA; break; + case 10: t |= 0xF; break; + } + ESSreg(0xB1) = t; + + /* DRQ control */ + t = 0x80;/*game compatible DRQ */ + switch (dsp->sb_8_dmanum) { + case 0: t |= 0x5; break; + case 1: t |= 0xA; break; + case 3: t |= 0xF; break; + } + ESSreg(0xB2) = t; } void @@ -661,7 +699,7 @@ static void sb_ess_update_autolen(sb_dsp_t *dsp) { static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) { uint8_t chg = 0x00; - sb_dsp_log("ESS register write reg=%02xh val=%02xh\n",reg,data); + pclog("ESS register write reg=%02xh val=%02xh\n",reg,data); switch (reg) { case 0xA1: /* Extended Mode Sample Rate Generator */ @@ -798,6 +836,7 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sb_8051_ram[0x20] = dsp->sb_command; if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { + pclog("dsp->sb_command = 0x%X\n", dsp->sb_command); if (dsp->sb_command == 0xC6 || dsp->sb_command == 0xC7) { dsp->ess_extended_mode = !!(dsp->sb_command == 0xC6); return; @@ -1365,7 +1404,7 @@ sb_write(uint16_t a, uint8_t v, void *priv) if (dsp->sb_command <= 0xC0) { sb_commands[dsp->sb_command] = 1; } else { - sb_commands[dsp->sb_command] = 0; + sb_commands[dsp->sb_command] = -1; } } } From f4c2a9c3ac6daffba83d395ae3b64bc672cd31e3 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 5 Mar 2024 21:43:57 +0600 Subject: [PATCH 739/936] Logging aids --- src/sound/snd_ess.c | 6 +++++- src/sound/snd_sb_dsp.c | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 57ba092c3..a97d5e244 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -151,6 +151,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) sb_dsp_set_stereo(&ess->dsp, mixer->regs[0x0e] & 2); } else { mixer->regs[mixer->index] = val; + pclog("ess: Register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); switch (mixer->index) { /* Compatibility: chain registers 0x02 and 0x22 as well as 0x06 and 0x26 */ @@ -197,6 +198,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) break; case 0x40: { + break; uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] & 0x38) << 1); gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); /* This doesn't work yet. */ @@ -318,6 +320,7 @@ ess_mixer_read(uint16_t addr, void *priv) case 0x36: case 0x38: case 0x3e: + pclog("ess: Register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); return mixer->regs[mixer->index]; case 0x40: @@ -326,6 +329,7 @@ ess_mixer_read(uint16_t addr, void *priv) mixer->ess_id_str_pos++; if (mixer->ess_id_str_pos >= 4) mixer->ess_id_str_pos = 0; + pclog("ess: ID READ: %02X (pos %d)\n", val, mixer->ess_id_str_pos); return val; } @@ -491,7 +495,7 @@ ess_1688_init(UNUSED(const device_t *info)) sb_dsp_set_mpu(&ess->dsp, ess->mpu); ess->gameport = gameport_add(&gameport_pnp_device); - ess->gameport_addr = 0x000; + ess->gameport_addr = 0x200; gameport_remap(ess->gameport, ess->gameport_addr); return ess; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 7cc189d30..a6069226d 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -834,9 +834,9 @@ sb_exec_command(sb_dsp_t *dsp) See https://github.com/joncampbell123/dosbox-x/issues/1044 */ if (dsp->sb_type >= SB16) dsp->sb_8051_ram[0x20] = dsp->sb_command; + pclog("dsp->sb_command = 0x%X\n", dsp->sb_command); if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { - pclog("dsp->sb_command = 0x%X\n", dsp->sb_command); if (dsp->sb_command == 0xC6 || dsp->sb_command == 0xC7) { dsp->ess_extended_mode = !!(dsp->sb_command == 0xC6); return; From b8ff131996de0538bc6b5c6cb86c050d7ac803bd Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 5 Mar 2024 23:41:38 +0600 Subject: [PATCH 740/936] More changes --- src/sound/snd_sb_dsp.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index a6069226d..44d9d0950 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -710,10 +710,6 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) else dsp->sb_freq = 397700UL / (128ul - data); - if (dsp->sb_16_enable || dsp->sb_8_enable) { - sb_stop_dma_ess(dsp); - sb_start_dma_ess(dsp); - } break; } case 0xA2: /* Filter divider (effectively, a hardware lowpass filter under S/W control) */ @@ -742,8 +738,15 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) ESSreg(reg) = data; if (chg & 0x3) { if (dsp->sb_16_enable || dsp->sb_8_enable) { - sb_stop_dma_ess(dsp); - sb_start_dma_ess(dsp); + uint8_t real_format = 0x00; + real_format |= !!(ESSreg(0xB7) & 0x20) ? 0x10 : 0; + real_format |= !!(ESSreg(0xB7) & 0x8) ? 0x20 : 0; + + if (dsp->sb_16_enable) + dsp->sb_16_format = real_format; + + if (dsp->sb_8_enable) + dsp->sb_8_format = real_format; } } break; From c76ada30b7105f09700b9fe0f6e72248d1c5bc8d Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Tue, 5 Mar 2024 21:22:15 -0300 Subject: [PATCH 741/936] Some cleanup, implementing IRQ and DMA channel register update --- src/sound/snd_ess.c | 62 +++++++++++++++---------- src/sound/snd_sb_dsp.c | 102 +++++++++++++++++++++++++++-------------- 2 files changed, 105 insertions(+), 59 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index a97d5e244..0193c69c9 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -6,16 +6,20 @@ * * This file is part of the 86Box distribution. * - * Sound Blaster emulation. + * ESS AudioDrive emulation. * * * * Authors: Sarah Walker, * Miran Grca, * TheCollector1995, + * Cacodemon345, + * Kagamiin~, * * Copyright 2008-2020 Sarah Walker. * Copyright 2016-2020 Miran Grca. + * Copyright 2024 Cacodemon345 + * Copyright 2024 Kagamiin~ */ #include #include @@ -79,7 +83,7 @@ typedef struct ess_mixer_t { uint8_t regs[256]; uint8_t ess_id_str[256]; - uint8_t ess_id_str_pos : 2; + uint8_t ess_id_str_pos; } ess_mixer_t; typedef struct ess_t { @@ -130,7 +134,10 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->index = val; mixer->regs[0x01] = val; if (val == 0x40) + { + pclog("ess: Mixer addr 0x40 selected, ID string offset reset\n"); mixer->ess_id_str_pos = 0; + } } else { if (mixer->index == 0) { /* Reset */ @@ -151,7 +158,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) sb_dsp_set_stereo(&ess->dsp, mixer->regs[0x0e] & 2); } else { mixer->regs[mixer->index] = val; - pclog("ess: Register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + pclog("ess: Mixer Register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); switch (mixer->index) { /* Compatibility: chain registers 0x02 and 0x22 as well as 0x06 and 0x26 */ @@ -198,23 +205,27 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) break; case 0x40: { - break; - uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] & 0x38) << 1); - gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); - /* This doesn't work yet. */ - /* - io_removehandler(0x0388, 0x0004, - ess->opl.read, NULL, NULL, - ess->opl.write, NULL, NULL, - ess->opl.priv); - if (mixer->regs[0x40] & 1) { - io_sethandler(0x0388, 0x0004, - ess->opl.read, NULL, NULL, - ess->opl.write, NULL, NULL, - ess->opl.priv); - }*/ + /* TODO: Implement "Read-Sequence-Key" method of software address selection + * (needed for ESSCFG.EXE to work properly) */ - switch ((mixer->regs[0x40] >> 5) & 7) { + uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] << 1) & 0x30); + gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); + + /* This doesn't work yet. */ +#if 1 + io_removehandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + if ((mixer->regs[0x40] & 0x1) != 0) + { + io_sethandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + } +#endif + switch ((mixer->regs[0x40] >> 5) & 0x7) { case 0: mpu401_change_addr(ess->mpu, 0x00); mpu401_setirq(ess->mpu, -1); @@ -252,7 +263,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) } default: - pclog("ess: Unknown register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + pclog("ess: Unknown mixer register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } } @@ -320,21 +331,22 @@ ess_mixer_read(uint16_t addr, void *priv) case 0x36: case 0x38: case 0x3e: - pclog("ess: Register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + pclog("ess: Mixer Register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); return mixer->regs[mixer->index]; case 0x40: { uint8_t val = mixer->ess_id_str[mixer->ess_id_str_pos]; + uint8_t pos_log = mixer->ess_id_str_pos; /* TODO remove */ mixer->ess_id_str_pos++; if (mixer->ess_id_str_pos >= 4) mixer->ess_id_str_pos = 0; - pclog("ess: ID READ: %02X (pos %d)\n", val, mixer->ess_id_str_pos); + pclog("ess: ID READ: %02X (pos %d)\n", val, pos_log); return val; } default: - pclog("ess: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + pclog("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } @@ -491,7 +503,7 @@ ess_1688_init(UNUSED(const device_t *info)) } ess->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); - mpu401_init(ess->mpu, 0, 0, M_UART, 1); + mpu401_init(ess->mpu, 0, -1, M_UART, 1); sb_dsp_set_mpu(&ess->dsp, ess->mpu); ess->gameport = gameport_add(&gameport_pnp_device); @@ -620,4 +632,4 @@ const device_t ess_1688_device = { .speed_changed = ess_speed_changed, .force_redraw = NULL, .config = ess_config -}; \ No newline at end of file +}; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 44d9d0950..d14b41d9e 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -582,6 +582,37 @@ sb_16_write_dma(void *priv, uint16_t val) return ret; } +void +sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy) +{ + uint8_t t = 0x00; + /* IRQ control */ + if (legacy) + { + t |= 0x80; + } + switch (dsp->sb_irqnum) { + case 5: t |= 0x5; break; + case 7: t |= 0xA; break; + case 10: t |= 0xF; break; + } + pclog("ESSreg 0xB1 was %02X, irqnum is %d, t is %02X; new 0xB1 is %02X\n", ESSreg(0xB1), dsp->sb_irqnum, t, (ESSreg(0xB1) & 0xF0) | t); + ESSreg(0xB1) = (ESSreg(0xB1) & 0xF0) | t; + + /* DRQ control */ + t = 0x00; + if (legacy) + { + t |= 0x80; + } + switch (dsp->sb_8_dmanum) { + case 0: t |= 0x5; break; + case 1: t |= 0xA; break; + case 3: t |= 0xF; break; + } + ESSreg(0xB2) = (ESSreg(0xB2) & 0xF0) | t; +} + void sb_dsp_setirq(sb_dsp_t *dsp, int irq) { @@ -589,23 +620,7 @@ sb_dsp_setirq(sb_dsp_t *dsp, int irq) sb_dsp_log("IRQ now: %i\n", irq); dsp->sb_irqnum = irq; - /* legacy audio interrupt control */ - t = 0x80;/*game compatible IRQ*/ - switch (dsp->sb_irqnum) { - case 5: t |= 0x5; break; - case 7: t |= 0xA; break; - case 10: t |= 0xF; break; - } - ESSreg(0xB1) = t; - - /* DRQ control */ - t = 0x80;/*game compatible DRQ */ - switch (dsp->sb_8_dmanum) { - case 0: t |= 0x5; break; - case 1: t |= 0xA; break; - case 3: t |= 0xF; break; - } - ESSreg(0xB2) = t; + sb_ess_update_irq_drq_readback_regs(dsp, true); } void @@ -615,23 +630,7 @@ sb_dsp_setdma8(sb_dsp_t *dsp, int dma) sb_dsp_log("8-bit DMA now: %i\n", dma); dsp->sb_8_dmanum = dma; - /* legacy audio interrupt control */ - t = 0x80;/*game compatible IRQ*/ - switch (dsp->sb_irqnum) { - case 5: t |= 0x5; break; - case 7: t |= 0xA; break; - case 10: t |= 0xF; break; - } - ESSreg(0xB1) = t; - - /* DRQ control */ - t = 0x80;/*game compatible DRQ */ - switch (dsp->sb_8_dmanum) { - case 0: t |= 0x5; break; - case 1: t |= 0xA; break; - case 3: t |= 0xF; break; - } - ESSreg(0xB2) = t; + sb_ess_update_irq_drq_readback_regs(dsp, true); } void @@ -686,6 +685,7 @@ static uint8_t sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) { switch (reg) { default: + pclog("ESS register read reg=%02xh val=%02xh\n",reg, ESSreg(reg)); return ESSreg(reg); } @@ -752,9 +752,43 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) break; case 0xB1: /* Legacy Audio Interrupt Control */ + ESSreg(reg) = (ESSreg(reg) & 0x0F) + (data & 0xF0); // lower 4 bits not writeable + switch (data & 0x0C) + { + case 0x00: + dsp->sb_irqnum = 2; + break; + case 0x04: + dsp->sb_irqnum = 5; + break; + case 0x08: + dsp->sb_irqnum = 7; + break; + case 0x0C: + dsp->sb_irqnum = 10; + break; + } + sb_ess_update_irq_drq_readback_regs(dsp, false); + break; case 0xB2: /* DRQ Control */ chg = ESSreg(reg) ^ data; ESSreg(reg) = (ESSreg(reg) & 0x0F) + (data & 0xF0); // lower 4 bits not writeable + switch (data & 0x0C) + { + case 0x00: + dsp->sb_8_dmanum = -1; + break; + case 0x04: + dsp->sb_8_dmanum = 0; + break; + case 0x08: + dsp->sb_8_dmanum = 1; + break; + case 0x0C: + dsp->sb_8_dmanum = 3; + break; + } + sb_ess_update_irq_drq_readback_regs(dsp, false); if (chg & 0x40) sb_ess_update_dma_status(dsp); break; case 0xB5: /* DAC Direct Access Holding (low) */ From d3aa111ba3b4e93667fdcf1181459621539225c5 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 8 Mar 2024 12:13:09 -0300 Subject: [PATCH 742/936] Fix bug in command length override; fix some other stuff; logging galore --- src/sound/snd_ess.c | 8 +++++ src/sound/snd_sb_dsp.c | 74 +++++++++++++++++++++++++++++++++++------- 2 files changed, 71 insertions(+), 11 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 0193c69c9..3de6615a3 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -335,7 +335,10 @@ ess_mixer_read(uint16_t addr, void *priv) return mixer->regs[mixer->index]; case 0x40: + + if (0) { + // not on ES1688 uint8_t val = mixer->ess_id_str[mixer->ess_id_str_pos]; uint8_t pos_log = mixer->ess_id_str_pos; /* TODO remove */ mixer->ess_id_str_pos++; @@ -344,6 +347,11 @@ ess_mixer_read(uint16_t addr, void *priv) pclog("ess: ID READ: %02X (pos %d)\n", val, pos_log); return val; } + else + { + pclog("ess: Mixer Register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + return mixer->regs[mixer->index]; + } default: pclog("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index d14b41d9e..fdcaf4587 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -228,7 +228,10 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) /* TODO: Investigate real hardware for this (the ES1887 datasheet documents this bit somewhat oddly.) */ if (dsp->ess_playback_mode && bit <= 1 && set && !masked) { if (!(ESSreg(0xB1) & 0x40)) // if ESS playback, and IRQ disabled, do not fire + { + pclog("ess: IRQ was masked"); return; + } } if (set && !masked) @@ -240,6 +243,7 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) void sb_irq(sb_dsp_t *dsp, int irq8) { + pclog("sb: IRQ raised\n"); sb_update_status(dsp, !irq8, 1); } @@ -330,6 +334,9 @@ sb_doreset(sb_dsp_t *dsp) dsp->sb_asp_regs[5] = 0x01; dsp->sb_asp_regs[9] = 0xf8; + + /* Initialize ESS registers */ + ESSreg(0xA5) = 0xf8; } void @@ -596,7 +603,6 @@ sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy) case 7: t |= 0xA; break; case 10: t |= 0xF; break; } - pclog("ESSreg 0xB1 was %02X, irqnum is %d, t is %02X; new 0xB1 is %02X\n", ESSreg(0xB1), dsp->sb_irqnum, t, (ESSreg(0xB1) & 0xF0) | t); ESSreg(0xB1) = (ESSreg(0xB1) & 0xF0) | t; /* DRQ control */ @@ -704,11 +710,16 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) switch (reg) { case 0xA1: /* Extended Mode Sample Rate Generator */ { + double temp; ESSreg(reg) = data; if (data & 0x80) dsp->sb_freq = 795500UL / (256ul - data); else dsp->sb_freq = 397700UL / (128ul - data); + temp = 1000000.0 / dsp->sb_freq; + dsp->sblatchi = dsp->sblatcho = TIMER_USEC * temp; + dsp->sb_timei = dsp->sb_timeo; + pclog("ess: Sample rate - %ihz (%f)\n", dsp->sb_freq, dsp->sblatcho); break; } @@ -720,6 +731,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) case 0xA5: /* DMA Transfer Count Reload (high) */ ESSreg(reg) = data; sb_ess_update_autolen(dsp); + pclog("ess: DMA Transfer Count Reload length set to %d samples\n", sb_ess_get_dma_len(dsp)); if ((dsp->sb_16_length < 0 && !dsp->sb_16_enable) && (dsp->sb_8_length < 0 && !dsp->sb_8_enable)) dsp->ess_reload_len = 1; break; @@ -855,6 +867,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) break; default: + pclog("UNKNOWN ESS register write reg=%02xh val=%02xh\n",reg,data); break; } } @@ -870,8 +883,21 @@ sb_exec_command(sb_dsp_t *dsp) /* Update 8051 ram with the current DSP command. See https://github.com/joncampbell123/dosbox-x/issues/1044 */ if (dsp->sb_type >= SB16) + { dsp->sb_8051_ram[0x20] = dsp->sb_command; - pclog("dsp->sb_command = 0x%X\n", dsp->sb_command); + } + + { + int i; + char data_s[256]; + data_s[0] = '\0'; + + for (i = 0; i < sb_commands[dsp->sb_command]; i++) + { + snprintf(data_s, 256, " 0x%02X", dsp->sb_data[i]); + } + pclog("dsp->sb_command = 0x%02X%s, length %d\n", dsp->sb_command, data_s, sb_commands[dsp->sb_command]); + } if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { if (dsp->sb_command == 0xC6 || dsp->sb_command == 0xC7) { @@ -1083,7 +1109,8 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sblatcho = dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_data[0]); temp = 256 - dsp->sb_data[0]; temp = 1000000 / temp; - sb_dsp_log("Sample rate - %ihz (%i)\n", temp, dsp->sblatcho); + sb_dsp_log("Sample rate - %ihz (%f)\n", temp, dsp->sblatcho); + pclog("Sample rate - %ihz (%f)\n", temp, dsp->sblatcho); if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16)) recalc_sb16_filter(0, temp); dsp->sb_freq = temp; @@ -1095,7 +1122,8 @@ sb_exec_command(sb_dsp_t *dsp) case 0x42: /* Set input sampling rate */ if (dsp->sb_type >= SB16) { dsp->sblatcho = (uint64_t) (TIMER_USEC * (1000000.0f / (float) (dsp->sb_data[1] + (dsp->sb_data[0] << 8)))); - sb_dsp_log("Sample rate - %ihz (%i)\n", dsp->sb_data[1] + (dsp->sb_data[0] << 8), dsp->sblatcho); + sb_dsp_log("Sample rate - %ihz (%f)\n", dsp->sb_data[1] + (dsp->sb_data[0] << 8), dsp->sblatcho); + pclog("Sample rate - %ihz (%f)\n", dsp->sb_data[1] + (dsp->sb_data[0] << 8), dsp->sblatcho); temp = dsp->sb_freq; dsp->sb_freq = dsp->sb_data[1] + (dsp->sb_data[0] << 8); dsp->sb_timeo = 256LL + dsp->sb_freq; @@ -1396,6 +1424,8 @@ sb_write(uint16_t a, uint8_t v, void *priv) if (dsp->sb_type < SB16 && (!IS_ESS(dsp) || (IS_ESS(dsp) && ((a & 0xF) != 0xE)))) a &= 0xfffe; + //pclog("sb: port write %03x %02x\n", a, v); + switch (a & 0xF) { case 6: /* Reset */ if (!dsp->uart_midi) { @@ -1428,8 +1458,6 @@ sb_write(uint16_t a, uint8_t v, void *priv) if (v == 0x01) sb_add_data(dsp, 0); dsp->sb_data_stat++; - } else { - dsp->sb_data[dsp->sb_data_stat++] = v; if (IS_AZTECH(dsp)) { /* variable length commands */ if (dsp->sb_command == 0x08 && dsp->sb_data_stat == 1 && dsp->sb_data[0] == 0x08) @@ -1444,6 +1472,8 @@ sb_write(uint16_t a, uint8_t v, void *priv) sb_commands[dsp->sb_command] = -1; } } + } else { + dsp->sb_data[dsp->sb_data_stat++] = v; } if (dsp->sb_data_stat == sb_commands[dsp->sb_command] || sb_commands[dsp->sb_command] == -1) { sb_exec_command(dsp); @@ -1469,7 +1499,13 @@ sb_read(uint16_t a, void *priv) /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ if (dsp->sb_type < SB16) - a &= 0xfffe; + { + /* Exception: ESS AudioDrive does not alias port base+0xf */ + if (!IS_ESS(dsp) || !((a & 0xF) == 0xF)) + { + a &= 0xfffe; + } + } switch (a & 0xf) { case 0xA: /* Read data */ @@ -1509,6 +1545,10 @@ sb_read(uint16_t a, void *priv) break; case 0xE: /* Read data ready */ dsp->irq_update(dsp->irq_priv, 0); + if (dsp->sb_irq8 || dsp->sb_irq16) + { + pclog("sb: IRQ acknowledged\n"); + } dsp->sb_irq8 = dsp->sb_irq16 = 0; /* Only bit 7 is defined but aztech diagnostics fail if the others are set. Keep the original behavior to not interfere with what's already working. */ if (IS_AZTECH(dsp)) { @@ -1520,16 +1560,25 @@ sb_read(uint16_t a, void *priv) } break; case 0xF: /* 16-bit ack */ - dsp->sb_irq16 = 0; - if (!dsp->sb_irq8) - dsp->irq_update(dsp->irq_priv, 0); - sb_dsp_log("SB 16-bit ACK read 0xFF\n"); + if (!IS_ESS(dsp)) + { + if (dsp->sb_irq16) + { + pclog("sb: 16-bit IRQ acknowledged"); + } + dsp->sb_irq16 = 0; + if (!dsp->sb_irq8) + dsp->irq_update(dsp->irq_priv, 0); + sb_dsp_log("SB 16-bit ACK read 0xFF\n"); + } ret = 0xff; break; default: break; } + + //pclog("sb: port read %03x %02x\n", a, ret); return ret; } @@ -1634,6 +1683,7 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) dsp->sb_8051_ram[0x37] = 0x38; memset(dsp->sb_asp_ram, 0xff, sizeof(dsp->sb_asp_ram)); + } void @@ -1692,6 +1742,7 @@ sb_ess_finish_dma(sb_dsp_t *dsp) return; ESSreg(0xB8) &= ~0x01; dma_set_drq(dsp->sb_8_dmanum, 0); + pclog("ess: DMA finished"); } void @@ -1886,6 +1937,7 @@ pollsb(void *priv) break; } + if (dsp->sb_8_length < 0) { if (dsp->sb_8_autoinit) dsp->sb_8_length = dsp->sb_8_origlength = dsp->sb_8_autolen; From 6d3f2c478b97299c41d0735367b2e33069410b5f Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sat, 9 Mar 2024 19:14:36 -0300 Subject: [PATCH 743/936] Fix port 388h being disabled erroneously; set filter freq on sample rate change --- src/sound/snd_ess.c | 30 +++++++++++++++--------------- src/sound/snd_sb_dsp.c | 5 +++++ 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 3de6615a3..f771ee6db 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -135,7 +135,6 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->regs[0x01] = val; if (val == 0x40) { - pclog("ess: Mixer addr 0x40 selected, ID string offset reset\n"); mixer->ess_id_str_pos = 0; } } else { @@ -211,20 +210,21 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] << 1) & 0x30); gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); - /* This doesn't work yet. */ -#if 1 - io_removehandler(0x0388, 0x0004, - ess->opl.read, NULL, NULL, - ess->opl.write, NULL, NULL, - ess->opl.priv); - if ((mixer->regs[0x40] & 0x1) != 0) + if (0) { - io_sethandler(0x0388, 0x0004, - ess->opl.read, NULL, NULL, - ess->opl.write, NULL, NULL, - ess->opl.priv); + /* Not on ES1688. */ + io_removehandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + if ((mixer->regs[0x40] & 0x1) != 0) + { + io_sethandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + } } -#endif switch ((mixer->regs[0x40] >> 5) & 0x7) { case 0: mpu401_change_addr(ess->mpu, 0x00); @@ -338,7 +338,7 @@ ess_mixer_read(uint16_t addr, void *priv) if (0) { - // not on ES1688 + /* not on ES1688 */ uint8_t val = mixer->ess_id_str[mixer->ess_id_str_pos]; uint8_t pos_log = mixer->ess_id_str_pos; /* TODO remove */ mixer->ess_id_str_pos++; @@ -475,6 +475,7 @@ ess_1688_init(UNUSED(const device_t *info)) sb_dsp_setdma16_8(&ess->dsp, device_get_config_int("dma")); sb_dsp_setdma16_supported(&ess->dsp, 0); ess_mixer_reset(ess); + /* DSP I/O handler is activated in sb_dsp_setaddr */ { io_sethandler(addr, 0x0004, @@ -502,7 +503,6 @@ ess_1688_init(UNUSED(const device_t *info)) if (device_get_config_int("receive_input")) midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &ess->dsp); - { ess->mixer_sbpro.ess_id_str[0] = 0x16; ess->mixer_sbpro.ess_id_str[1] = 0x88; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index fdcaf4587..3d150b9f9 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -716,6 +716,11 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) dsp->sb_freq = 795500UL / (256ul - data); else dsp->sb_freq = 397700UL / (128ul - data); + // TODO: check if this command updates the filter or not + sb_ess_update_filter_freq(dsp); + ESSreg(reg) = data; /* HACK: sb_ess_update_filter_freq updates 0xA1. + * I'm not sure if that could cause an off by one + * error, so this is just to be safe. */ temp = 1000000.0 / dsp->sb_freq; dsp->sblatchi = dsp->sblatcho = TIMER_USEC * temp; dsp->sb_timei = dsp->sb_timeo; From b59db332f0152b3271351fd2c4518137e902b457 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sat, 9 Mar 2024 23:55:36 -0300 Subject: [PATCH 744/936] Implement registers 0xC2/0xC3; sound now works in Win3.1 --- src/sound/snd_sb_dsp.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 3d150b9f9..0b55953da 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -868,6 +868,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) case 0xB9: /* Audio 1 Transfer Type */ case 0xBA: /* Left Channel ADC Offset Adjust */ case 0xBB: /* Right Channel ADC Offset Adjust */ + case 0xC3: /* Internal state register */ ESSreg(reg) = data; break; @@ -909,9 +910,18 @@ sb_exec_command(sb_dsp_t *dsp) dsp->ess_extended_mode = !!(dsp->sb_command == 0xC6); return; } - if (dsp->sb_command == 0xC0) { + else if (dsp->sb_command == 0xC2) + { + sb_ess_write_reg(dsp, 0xC3, dsp->sb_data[0]); + } + else if (dsp->sb_command == 0xC3) + { + sb_add_data(dsp, sb_ess_read_reg(dsp, 0xC3)); + } + else if (dsp->sb_command == 0xC0) { sb_add_data(dsp, sb_ess_read_reg(dsp, dsp->sb_data[0])); - } else if (dsp->sb_command < 0xC0 && dsp->ess_extended_mode) { + } + else if (dsp->sb_command < 0xC0 && dsp->ess_extended_mode) { sb_ess_write_reg(dsp, dsp->sb_command, dsp->sb_data[0]); } return; @@ -1471,7 +1481,7 @@ sb_write(uint16_t a, uint8_t v, void *priv) sb_commands[dsp->sb_command] = 2; } if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { - if (dsp->sb_command <= 0xC0) { + if (dsp->sb_command <= 0xC0 || dsp->sb_command == 0xC2) { sb_commands[dsp->sb_command] = 1; } else { sb_commands[dsp->sb_command] = -1; From 34be04ab800321ce797cf1634ee5318e52f63c10 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 10 Mar 2024 15:32:57 -0300 Subject: [PATCH 745/936] Implementing command 0xF2 IRQ masking behavior --- src/include/86box/snd_sb_dsp.h | 2 ++ src/sound/snd_sb_dsp.c | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index 2b39a0303..4c0aab113 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -130,6 +130,8 @@ typedef struct sb_dsp_t { pc_timer_t wb_timer; int wb_full; + pc_timer_t irq_timer; + int busy_count; int record_pos_read; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 0b55953da..30931f3d6 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -209,6 +209,15 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) { int masked = 0; + if (dsp->sb_irq8 || dsp->sb_irq16) + return; + + if (!(ESSreg(0xB1) & 0x10)) // if ESS playback, and IRQ disabled, do not fire + { + pclog("ess: IRQ was masked"); + return; + } + switch (bit) { default: case 0: @@ -599,6 +608,7 @@ sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy) t |= 0x80; } switch (dsp->sb_irqnum) { + case 9: t |= 0x0; break; case 5: t |= 0x5; break; case 7: t |= 0xA; break; case 10: t |= 0xF; break; @@ -627,6 +637,8 @@ sb_dsp_setirq(sb_dsp_t *dsp, int irq) dsp->sb_irqnum = irq; sb_ess_update_irq_drq_readback_regs(dsp, true); + + ESSreg(0xB1) = (ESSreg(0xB1) & 0xEF) | 0x10; } void @@ -1384,7 +1396,15 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0xF2: /* Trigger 8-bit IRQ */ sb_dsp_log("Trigger IRQ\n"); - sb_irq(dsp, 1); + if (IS_ESS(dsp)) { + if (timer_is_enabled(&dsp->irq_timer)) + pclog("F2 already written\n"); + else { + timer_set_delay_u64(&dsp->irq_timer, (100ULL * TIMER_USEC)); + pclog("F2 written\n"); + } + } else + sb_irq(dsp, 1); break; case 0xF3: /* Trigger 16-bit IRQ */ sb_dsp_log("Trigger IRQ\n"); @@ -1483,6 +1503,8 @@ sb_write(uint16_t a, uint8_t v, void *priv) if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { if (dsp->sb_command <= 0xC0 || dsp->sb_command == 0xC2) { sb_commands[dsp->sb_command] = 1; + } else if (dsp->sb_command == 0xC6 || dsp->sb_command == 0xC7) { + sb_commands[dsp->sb_command] = 0; } else { sb_commands[dsp->sb_command] = -1; } @@ -1652,6 +1674,14 @@ sb_dsp_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) return 0; } +void +sb_dsp_irq_poll(void *priv) +{ + sb_dsp_t *dsp = (sb_dsp_t *) priv; + + sb_irq(dsp, 1); +} + void sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) { @@ -1680,6 +1710,7 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) timer_add(&dsp->output_timer, pollsb, dsp, 0); timer_add(&dsp->input_timer, sb_poll_i, dsp, 0); timer_add(&dsp->wb_timer, NULL, dsp, 0); + timer_add(&dsp->irq_timer, sb_dsp_irq_poll, dsp, 0); /* Initialise SB16 filter to same cutoff as 8-bit SBs (3.2 kHz). This will be recalculated when a set frequency command is sent. */ From 7c998872935b4582df029b3e503a1dc0fa6b63b6 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Mon, 11 Mar 2024 18:49:10 -0300 Subject: [PATCH 746/936] Implementing ESS DMA counter; handling disable of auto-init while DMA is turned on --- src/include/86box/snd_sb_dsp.h | 1 + src/sound/snd_sb_dsp.c | 178 +++++++++++++++++++++++++++------ 2 files changed, 148 insertions(+), 31 deletions(-) diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index 4c0aab113..4833dea33 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -146,6 +146,7 @@ typedef struct sb_dsp_t { uint8_t ess_playback_mode; uint8_t ess_extended_mode; uint8_t ess_reload_len; + uint32_t ess_dma_counter; mpu_t *mpu; } sb_dsp_t; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 30931f3d6..ebda12652 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -212,9 +212,11 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) if (dsp->sb_irq8 || dsp->sb_irq16) return; - if (!(ESSreg(0xB1) & 0x10)) // if ESS playback, and IRQ disabled, do not fire + /* NOTE: not on ES1688 or ES1868 */ + if (IS_ESS(dsp) && dsp->sb_subtype != SB_SUBTYPE_ESS_ES1688 + && !(ESSreg(0xB1) & 0x10)) // if ESS playback, and IRQ disabled, do not fire { - pclog("ess: IRQ was masked"); + pclog("ess: IRQ was masked\n"); return; } @@ -238,7 +240,7 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) if (dsp->ess_playback_mode && bit <= 1 && set && !masked) { if (!(ESSreg(0xB1) & 0x40)) // if ESS playback, and IRQ disabled, do not fire { - pclog("ess: IRQ was masked"); + pclog("ess: IRQ was masked\n"); return; } } @@ -369,15 +371,19 @@ sb_add_data(sb_dsp_t *dsp, uint8_t v) dsp->sb_read_wp &= 0xff; } +static unsigned int sb_ess_get_dma_counter(sb_dsp_t *dsp) +{ + unsigned int c; + + c = (unsigned int)ESSreg(0xA5) << 8U; + c |= (unsigned int)ESSreg(0xA4); + + return c; +} + static unsigned int sb_ess_get_dma_len(sb_dsp_t *dsp) { - unsigned int r; - - r = (unsigned int)ESSreg(0xA5) << 8U; - r |= (unsigned int)ESSreg(0xA4); - - /* the 16-bit counter is a "two's complement" of the DMA count because it counts UP to 0 and triggers IRQ on overflow */ - return 0x10000U-r; + return 0x10000U - sb_ess_get_dma_counter(dsp); } void @@ -385,11 +391,6 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) { dsp->sb_pausetime = -1; - if (dsp->ess_reload_len) { - len = sb_ess_get_dma_len(dsp); - dsp->ess_reload_len = 0; - } - if (dma8) { dsp->sb_8_length = dsp->sb_8_origlength = len; dsp->sb_8_format = format; @@ -424,11 +425,6 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) void sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) { - if (dsp->ess_reload_len) { - len = sb_ess_get_dma_len(dsp); - dsp->ess_reload_len = 0; - } - if (dma8) { dsp->sb_8_length = dsp->sb_8_origlength = len; dsp->sb_8_format = format; @@ -460,12 +456,8 @@ void sb_start_dma_ess(sb_dsp_t* dsp) { uint8_t real_format = 0; - uint32_t len = !(ESSreg(0xB7) & 4) ? dsp->sb_8_length : dsp->sb_16_length; - - if (dsp->ess_reload_len || len <= 0) { - len = sb_ess_get_dma_len(dsp); - dsp->ess_reload_len = 0; - } + dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); + uint32_t len = sb_ess_get_dma_len(dsp); if (IS_ESS(dsp)) { dma_set_drq(dsp->sb_8_dmanum, 0); @@ -748,7 +740,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) case 0xA5: /* DMA Transfer Count Reload (high) */ ESSreg(reg) = data; sb_ess_update_autolen(dsp); - pclog("ess: DMA Transfer Count Reload length set to %d samples\n", sb_ess_get_dma_len(dsp)); + pclog("ess: DMA Transfer Count Reload length set to %d samples (0x%x)\n", sb_ess_get_dma_len(dsp), sb_ess_get_dma_counter(dsp)); if ((dsp->sb_16_length < 0 && !dsp->sb_16_enable) && (dsp->sb_8_length < 0 && !dsp->sb_8_enable)) dsp->ess_reload_len = 1; break; @@ -871,6 +863,18 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) dsp->ess_reload_len = 1; } + if (chg & 0x4) + { + if (dsp->sb_16_enable) + { + dsp->sb_16_autoinit = (ESSreg(0xB8) & 0x4) != 0; + } + if (dsp->sb_8_enable) + { + dsp->sb_8_autoinit = (ESSreg(0xB8) & 0x4) != 0; + } + } + if (chg & 0xB) { if (chg & 0xA) sb_stop_dma_ess(dsp); /* changing capture/playback direction? stop DMA to reinit */ sb_ess_update_dma_status(dsp); @@ -1060,8 +1064,12 @@ sb_exec_command(sb_dsp_t *dsp) sb_start_dma(dsp, 1, 0, ADPCM_2, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; + dsp->ess_dma_counter++; if (dsp->sb_command == 0x17) + { dsp->sb_8_length--; + dsp->ess_dma_counter++; + } break; case 0x1C: /* 8-bit autoinit DMA output */ if (dsp->sb_type >= SB15) @@ -1072,6 +1080,7 @@ sb_exec_command(sb_dsp_t *dsp) sb_start_dma(dsp, 1, 1, ADPCM_2, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; + dsp->ess_dma_counter++; } break; case 0x20: /* 8-bit direct input */ @@ -1177,8 +1186,12 @@ sb_exec_command(sb_dsp_t *dsp) sb_start_dma(dsp, 1, 0, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; + dsp->ess_dma_counter++; if (dsp->sb_command == 0x75) + { dsp->sb_8_length--; + dsp->ess_dma_counter++; + } break; case 0x77: /* 2.6-bit ADPCM output with reference */ dsp->sbref = dsp->dma_readb(dsp->dma_priv); @@ -1188,14 +1201,19 @@ sb_exec_command(sb_dsp_t *dsp) sb_start_dma(dsp, 1, 0, ADPCM_26, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; + dsp->ess_dma_counter++; if (dsp->sb_command == 0x77) + { dsp->sb_8_length--; + dsp->ess_dma_counter++; + } break; case 0x7D: /* 4-bit ADPCM autoinit output */ if (dsp->sb_type >= SB15) { sb_start_dma(dsp, 1, 1, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; + dsp->ess_dma_counter++; } break; case 0x7F: /* 2.6-bit ADPCM autoinit output */ @@ -1203,6 +1221,7 @@ sb_exec_command(sb_dsp_t *dsp) sb_start_dma(dsp, 1, 1, ADPCM_26, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; + dsp->ess_dma_counter++; } break; case 0x80: /* Pause DAC */ @@ -1822,6 +1841,7 @@ pollsb(void *priv) } else dsp->sbdatl = dsp->sbdatr = dsp->sbdat; dsp->sb_8_length--; + dsp->ess_dma_counter++; break; case 0x10: /* Mono signed */ data[0] = dsp->dma_readb(dsp->dma_priv); @@ -1839,6 +1859,7 @@ pollsb(void *priv) } else dsp->sbdatl = dsp->sbdatr = dsp->sbdat; dsp->sb_8_length--; + dsp->ess_dma_counter++; break; case 0x20: /* Stereo unsigned */ data[0] = dsp->dma_readb(dsp->dma_priv); @@ -1848,6 +1869,7 @@ pollsb(void *priv) dsp->sbdatl = (data[0] ^ 0x80) << 8; dsp->sbdatr = (data[1] ^ 0x80) << 8; dsp->sb_8_length -= 2; + dsp->ess_dma_counter += 2; break; case 0x30: /* Stereo signed */ data[0] = dsp->dma_readb(dsp->dma_priv); @@ -1857,6 +1879,7 @@ pollsb(void *priv) dsp->sbdatl = data[0] << 8; dsp->sbdatr = data[1] << 8; dsp->sb_8_length -= 2; + dsp->ess_dma_counter += 2; break; case ADPCM_4: @@ -1886,6 +1909,7 @@ pollsb(void *priv) dsp->sbdacpos = 0; dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; + dsp->ess_dma_counter++; } if (dsp->stereo) { @@ -1929,6 +1953,7 @@ pollsb(void *priv) dsp->sbdacpos = 0; dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; + dsp->ess_dma_counter++; } if (dsp->stereo) { @@ -1965,6 +1990,8 @@ pollsb(void *priv) if (dsp->sbdacpos >= 4) { dsp->sbdacpos = 0; dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; } if (dsp->stereo) { @@ -1984,7 +2011,7 @@ pollsb(void *priv) } - if (dsp->sb_8_length < 0) { + if (dsp->sb_8_length < 0 && !dsp->ess_playback_mode) { if (dsp->sb_8_autoinit) dsp->sb_8_length = dsp->sb_8_origlength = dsp->sb_8_autolen; else { @@ -1994,6 +2021,26 @@ pollsb(void *priv) } sb_irq(dsp, 1); } + if (dsp->ess_dma_counter > 0xffff) + { + if (dsp->ess_playback_mode) + { + if (!dsp->sb_8_autoinit) + { + dsp->sb_8_enable = 0; + timer_disable(&dsp->output_timer); + sb_ess_finish_dma(dsp); + } + if (ESSreg(0xB1) & 0x40) + { + sb_irq(dsp, 1); + pclog("IRQ fired via ESS DMA counter, next IRQ in %d samples\n", sb_ess_get_dma_len(dsp)); + } + } + uint32_t temp = dsp->ess_dma_counter & 0xffff; + dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); + dsp->ess_dma_counter += temp; + } } if (dsp->sb_16_enable && !dsp->sb_16_pause && (dsp->sb_pausetime < 0LL) && dsp->sb_16_output) { sb_dsp_update(dsp); @@ -2005,6 +2052,7 @@ pollsb(void *priv) break; dsp->sbdatl = dsp->sbdatr = data[0] ^ 0x8000; dsp->sb_16_length--; + dsp->ess_dma_counter += 2; break; case 0x10: /* Mono signed */ data[0] = dsp->dma_readw(dsp->dma_priv); @@ -2012,6 +2060,7 @@ pollsb(void *priv) break; dsp->sbdatl = dsp->sbdatr = data[0]; dsp->sb_16_length--; + dsp->ess_dma_counter += 2; break; case 0x20: /* Stereo unsigned */ data[0] = dsp->dma_readw(dsp->dma_priv); @@ -2021,6 +2070,7 @@ pollsb(void *priv) dsp->sbdatl = data[0] ^ 0x8000; dsp->sbdatr = data[1] ^ 0x8000; dsp->sb_16_length -= 2; + dsp->ess_dma_counter += 4; break; case 0x30: /* Stereo signed */ data[0] = dsp->dma_readw(dsp->dma_priv); @@ -2030,13 +2080,14 @@ pollsb(void *priv) dsp->sbdatl = data[0]; dsp->sbdatr = data[1]; dsp->sb_16_length -= 2; + dsp->ess_dma_counter += 4; break; default: break; } - if (dsp->sb_16_length < 0) { + if (dsp->sb_16_length < 0 && !dsp->ess_playback_mode) { sb_dsp_log("16DMA over %i\n", dsp->sb_16_autoinit); if (dsp->sb_16_autoinit) dsp->sb_16_length = dsp->sb_16_origlength = dsp->sb_16_autolen; @@ -2047,6 +2098,25 @@ pollsb(void *priv) } sb_irq(dsp, 0); } + if (dsp->ess_dma_counter > 0xffff) + { + if (dsp->ess_playback_mode) + { + if (!dsp->sb_16_autoinit) + { + dsp->sb_16_enable = 0; + timer_disable(&dsp->output_timer); + sb_ess_finish_dma(dsp); + } + if (ESSreg(0xB1) & 0x40) + { + sb_irq(dsp, 0); + } + } + uint32_t temp = dsp->ess_dma_counter & 0xffff; + dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); + dsp->ess_dma_counter += temp; + } } if (dsp->sb_pausetime > -1) { dsp->sb_pausetime--; @@ -2072,12 +2142,14 @@ sb_poll_i(void *priv) case 0x00: /* Mono unsigned As the manual says, only the left channel is recorded */ dsp->dma_writeb(dsp->dma_priv, (dsp->record_buffer[dsp->record_pos_read] >> 8) ^ 0x80); dsp->sb_8_length--; + dsp->ess_dma_counter++; dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; break; case 0x10: /* Mono signed As the manual says, only the left channel is recorded */ dsp->dma_writeb(dsp->dma_priv, (dsp->record_buffer[dsp->record_pos_read] >> 8)); dsp->sb_8_length--; + dsp->ess_dma_counter++; dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; break; @@ -2085,6 +2157,7 @@ sb_poll_i(void *priv) dsp->dma_writeb(dsp->dma_priv, (dsp->record_buffer[dsp->record_pos_read] >> 8) ^ 0x80); dsp->dma_writeb(dsp->dma_priv, (dsp->record_buffer[dsp->record_pos_read + 1] >> 8) ^ 0x80); dsp->sb_8_length -= 2; + dsp->ess_dma_counter += 2; dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; break; @@ -2092,6 +2165,7 @@ sb_poll_i(void *priv) dsp->dma_writeb(dsp->dma_priv, (dsp->record_buffer[dsp->record_pos_read] >> 8)); dsp->dma_writeb(dsp->dma_priv, (dsp->record_buffer[dsp->record_pos_read + 1] >> 8)); dsp->sb_8_length -= 2; + dsp->ess_dma_counter += 2; dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; break; @@ -2100,7 +2174,7 @@ sb_poll_i(void *priv) break; } - if (dsp->sb_8_length < 0) { + if (dsp->sb_8_length < 0 && !dsp->ess_playback_mode) { if (dsp->sb_8_autoinit) dsp->sb_8_length = dsp->sb_8_origlength = dsp->sb_8_autolen; else { @@ -2110,6 +2184,25 @@ sb_poll_i(void *priv) } sb_irq(dsp, 1); } + if (dsp->ess_dma_counter > 0xffff) + { + if (dsp->ess_playback_mode) + { + if (!dsp->sb_8_autoinit) + { + dsp->sb_8_enable = 0; + timer_disable(&dsp->input_timer); + sb_ess_finish_dma(dsp); + } + if (ESSreg(0xB1) & 0x40) + { + sb_irq(dsp, 1); + } + } + uint32_t temp = dsp->ess_dma_counter & 0xffff; + dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); + dsp->ess_dma_counter += temp; + } processed = 1; } if (dsp->sb_16_enable && !dsp->sb_16_pause && (dsp->sb_pausetime < 0LL) && !dsp->sb_16_output) { @@ -2118,6 +2211,7 @@ sb_poll_i(void *priv) if (dsp->dma_writew(dsp->dma_priv, dsp->record_buffer[dsp->record_pos_read] ^ 0x8000)) return; dsp->sb_16_length--; + dsp->ess_dma_counter += 2; dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; break; @@ -2125,6 +2219,7 @@ sb_poll_i(void *priv) if (dsp->dma_writew(dsp->dma_priv, dsp->record_buffer[dsp->record_pos_read])) return; dsp->sb_16_length--; + dsp->ess_dma_counter += 2; dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; break; @@ -2133,6 +2228,7 @@ sb_poll_i(void *priv) return; dsp->dma_writew(dsp->dma_priv, dsp->record_buffer[dsp->record_pos_read + 1] ^ 0x8000); dsp->sb_16_length -= 2; + dsp->ess_dma_counter += 4; dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; break; @@ -2141,6 +2237,7 @@ sb_poll_i(void *priv) return; dsp->dma_writew(dsp->dma_priv, dsp->record_buffer[dsp->record_pos_read + 1]); dsp->sb_16_length -= 2; + dsp->ess_dma_counter += 4; dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; break; @@ -2149,7 +2246,7 @@ sb_poll_i(void *priv) break; } - if (dsp->sb_16_length < 0) { + if (dsp->sb_16_length < 0 && !dsp->ess_playback_mode) { if (dsp->sb_16_autoinit) dsp->sb_16_length = dsp->sb_16_origlength = dsp->sb_16_autolen; else { @@ -2159,6 +2256,25 @@ sb_poll_i(void *priv) } sb_irq(dsp, 0); } + if (dsp->ess_dma_counter > 0xffff) + { + if (dsp->ess_playback_mode) + { + if (!dsp->sb_16_autoinit) + { + dsp->sb_16_enable = 0; + timer_disable(&dsp->input_timer); + sb_ess_finish_dma(dsp); + } + if (ESSreg(0xB1) & 0x40) + { + sb_irq(dsp, 0); + } + } + uint32_t temp = dsp->ess_dma_counter & 0xffff; + dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); + dsp->ess_dma_counter += temp; + } processed = 1; } /* Assume this is direct mode */ From 7ad48f8d2996b5ced373b19dbd4f80a0d9827647 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 12 Mar 2024 10:10:00 -0300 Subject: [PATCH 747/936] Switching filter implementation to use SB16 filters; fixing CD audio volume --- src/sound/snd_ess.c | 11 ++---- src/sound/snd_sb_dsp.c | 88 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 75 insertions(+), 24 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index f771ee6db..9996ad006 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -150,7 +150,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) /* Initialize ESS regs. */ mixer->regs[0x14] = mixer->regs[0x32] = 0x88; mixer->regs[0x36] = 0x88; - mixer->regs[0x38] = 0x00; + mixer->regs[0x38] = 0x88; mixer->regs[0x3a] = 0x00; mixer->regs[0x3e] = 0x00; @@ -384,8 +384,8 @@ ess_get_buffer_sbpro(int32_t *buffer, int len, void *priv) /* TODO: Implement the stereo switch on the mixer instead of on the dsp? */ if (mixer->output_filter) { - out_l += (sb_iir(0, 0, (double) ess->dsp.buffer[c]) * mixer->voice_l) / 3.9; - out_r += (sb_iir(0, 1, (double) ess->dsp.buffer[c + 1]) * mixer->voice_r) / 3.9; + out_l += (low_fir_sb16(0, 0, (double) ess->dsp.buffer[c]) * mixer->voice_l) / 3.0; + out_r += (low_fir_sb16(0, 1, (double) ess->dsp.buffer[c + 1]) * mixer->voice_r) / 3.0; } else { out_l += (ess->dsp.buffer[c] * mixer->voice_l) / 3.0; out_r += (ess->dsp.buffer[c + 1] * mixer->voice_r) / 3.0; @@ -446,10 +446,7 @@ ess_filter_cd_audio(int channel, double *buffer, void *priv) double cd = channel ? mixer->cd_r : mixer->cd_l; double master = channel ? mixer->master_r : mixer->master_l; - if (mixer->output_filter) - c = (sb_iir(2, channel, *buffer) * cd) / 3.9; - else - c = (*buffer * cd) / 3.0; + c = (*buffer * cd) / 3.0; *buffer = c * master; } diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index ebda12652..f179ce284 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -175,6 +175,37 @@ recalc_sb16_filter(int c, int playback_freq) low_fir_sb16_coef[c][n] /= gain; } +static void +recalc_opl_filter(int c, int playback_freq) +{ + /* Cutoff frequency = playback / 2 */ + int n; + double w; + double h; + double fC = ((double) playback_freq) / (double) (FREQ_49716 * 2); + double gain; + + for (n = 0; n < SB16_NCoef; n++) { + /* Blackman window */ + w = 0.42 - (0.5 * cos((2.0 * n * M_PI) / (double) (SB16_NCoef - 1))) + (0.08 * cos((4.0 * n * M_PI) / (double) (SB16_NCoef - 1))); + /* Sinc filter */ + h = sinc(2.0 * fC * ((double) n - ((double) (SB16_NCoef - 1) / 2.0))); + + /* Create windowed-sinc filter */ + low_fir_sb16_coef[c][n] = w * h; + } + + low_fir_sb16_coef[c][(SB16_NCoef - 1) / 2] = 1.0; + + gain = 0.0; + for (n = 0; n < SB16_NCoef; n++) + gain += low_fir_sb16_coef[c][n]; + + /* Normalise filter, to produce unity gain */ + for (n = 0; n < SB16_NCoef; n++) + low_fir_sb16_coef[c][n] /= gain; +} + static void sb_irq_update_pic(void *priv, int set) { @@ -678,17 +709,29 @@ sb_dsp_setdma16_translate(sb_dsp_t *dsp, int translate) dsp->sb_16_dma_translate = translate; } +static void sb_ess_update_reg_a2(sb_dsp_t *dsp, uint8_t val) +{ + double freq = (7160000.0 / (256.0 - ((double) val))) * 41.0; + int temp = (int) freq; + ESSreg(0xA2) = val; + + if (dsp->sb_freq != temp) + recalc_sb16_filter(0, temp); + dsp->sb_freq = temp; +} + /* TODO: Investigate ESS cards' filtering on real hardware as well. (DOSBox-X did it purely off some laptop's ESS chip, which isn't a good look.) */ static void sb_ess_update_filter_freq(sb_dsp_t *dsp) { + double temp = (7160000.0 / (((((double) dsp->sb_freq) / 2.0) * 0.80) * 82.0)) - 256.0; + if (dsp->sb_freq >= 22050) ESSreg(0xA1) = 256 - (795500UL / dsp->sb_freq); else ESSreg(0xA1) = 128 - (397700UL / dsp->sb_freq); - unsigned int freq = ((dsp->sb_freq * 4) / (5 * 2)); /* 80% of 1/2 the sample rate */ - ESSreg(0xA2) = 256 - (7160000 / (freq * 82)); + sb_ess_update_reg_a2(dsp, (uint8_t) temp); } static uint8_t sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) @@ -720,20 +763,14 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) dsp->sb_freq = 795500UL / (256ul - data); else dsp->sb_freq = 397700UL / (128ul - data); - // TODO: check if this command updates the filter or not - sb_ess_update_filter_freq(dsp); - ESSreg(reg) = data; /* HACK: sb_ess_update_filter_freq updates 0xA1. - * I'm not sure if that could cause an off by one - * error, so this is just to be safe. */ temp = 1000000.0 / dsp->sb_freq; dsp->sblatchi = dsp->sblatcho = TIMER_USEC * temp; dsp->sb_timei = dsp->sb_timeo; pclog("ess: Sample rate - %ihz (%f)\n", dsp->sb_freq, dsp->sblatcho); - break; } case 0xA2: /* Filter divider (effectively, a hardware lowpass filter under S/W control) */ - ESSreg(reg) = data; + sb_ess_update_reg_a2(dsp, data); break; case 0xA4: /* DMA Transfer Count Reload (low) */ @@ -1147,6 +1184,7 @@ sb_exec_command(sb_dsp_t *dsp) temp = 1000000 / temp; sb_dsp_log("Sample rate - %ihz (%f)\n", temp, dsp->sblatcho); pclog("Sample rate - %ihz (%f)\n", temp, dsp->sblatcho); + // if ((dsp->sb_freq != temp) && (IS_ESS(dsp) || (dsp->sb_type >= SB16))) if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16)) recalc_sb16_filter(0, temp); dsp->sb_freq = temp; @@ -1165,7 +1203,7 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sb_timeo = 256LL + dsp->sb_freq; dsp->sblatchi = dsp->sblatcho; dsp->sb_timei = dsp->sb_timeo; - if (dsp->sb_freq != temp && dsp->sb_type >= SB16) + if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16)) recalc_sb16_filter(0, dsp->sb_freq); dsp->sb_8051_ram[0x13] = dsp->sb_freq & 0xff; dsp->sb_8051_ram[0x14] = (dsp->sb_freq >> 8) & 0xff; @@ -1731,14 +1769,30 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) timer_add(&dsp->wb_timer, NULL, dsp, 0); timer_add(&dsp->irq_timer, sb_dsp_irq_poll, dsp, 0); - /* Initialise SB16 filter to same cutoff as 8-bit SBs (3.2 kHz). This will be recalculated when - a set frequency command is sent. */ - recalc_sb16_filter(0, 3200 * 2); - if (dsp->sb_has_real_opl) - recalc_sb16_filter(1, FREQ_49716); + if (IS_ESS(dsp)) + /* Initialize ESS filter to 8 kHz. This will be recalculated when a set frequency command is + sent. */ + recalc_sb16_filter(0, 8000 * 2); else - recalc_sb16_filter(1, FREQ_48000); - recalc_sb16_filter(2, FREQ_44100); + /* Initialise SB16 filter to same cutoff as 8-bit SBs (3.2 kHz). This will be recalculated when + a set frequency command is sent. */ + recalc_sb16_filter(0, 3200 * 2); + if (IS_ESS(dsp) || (dsp->sb_type >= SBPRO2)) { + /* OPL3 or dual OPL2 is stereo. */ + if (dsp->sb_has_real_opl) + recalc_opl_filter(1, FREQ_49716 * 2); + else + recalc_sb16_filter(1, FREQ_48000 * 2); + } else { + /* OPL2 is mono. */ + if (dsp->sb_has_real_opl) + recalc_opl_filter(1, FREQ_49716); + else + recalc_sb16_filter(1, FREQ_48000); + } + /* CD Audio is stereo. */ + recalc_sb16_filter(2, FREQ_44100 * 2); + /* PC speaker is mono. */ recalc_sb16_filter(3, 18939); /* Initialize SB16 8051 RAM and ASP internal RAM */ From 0ed203cbd50dc697a453ffebdf8722db8420308f Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Tue, 12 Mar 2024 18:12:57 -0300 Subject: [PATCH 748/936] Mixer functions; recording (incomplete/commented out); set default IRQ to 5 --- src/include/86box/snd_sb.h | 16 +-- src/sound/snd_ess.c | 211 +++++++++++++++++++++++++++++++------ 2 files changed, 188 insertions(+), 39 deletions(-) diff --git a/src/include/86box/snd_sb.h b/src/include/86box/snd_sb.h index 621cb4ade..f236c284a 100644 --- a/src/include/86box/snd_sb.h +++ b/src/include/86box/snd_sb.h @@ -105,13 +105,15 @@ typedef struct sb_ct1745_mixer_t { int input_selector_left; int input_selector_right; -#define INPUT_MIC 1 -#define INPUT_CD_R 2 -#define INPUT_CD_L 4 -#define INPUT_LINE_R 8 -#define INPUT_LINE_L 16 -#define INPUT_MIDI_R 32 -#define INPUT_MIDI_L 64 +#define INPUT_MIC 1 +#define INPUT_CD_R 2 +#define INPUT_CD_L 4 +#define INPUT_LINE_R 8 +#define INPUT_LINE_L 16 +#define INPUT_MIDI_R 32 +#define INPUT_MIDI_L 64 +#define INPUT_MIXER_L 128 +#define INPUT_MIXER_R 256 int mic_agc; diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 9996ad006..0f57bca7d 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -21,6 +21,7 @@ * Copyright 2024 Cacodemon345 * Copyright 2024 Kagamiin~ */ + #include #include #include @@ -48,6 +49,8 @@ #include <86box/snd_sb.h> #include <86box/plat_unused.h> + + static const double sb_att_4dbstep_3bits[] = { 164.0, 2067.0, 3276.0, 5193.0, 8230.0, 13045.0, 20675.0, 32767.0 }; @@ -56,6 +59,11 @@ static const double sb_att_7dbstep_2bits[] = { 164.0, 6537.0, 14637.0, 32767.0 }; +static const double sb_att_1p4dbstep_4bits[] = { + 164.0, 3431.0, 4031.0, 4736.0, 5565.0, 6537.0, 7681.0, 9025.0, + 10603.0, 12458.0, 14637.0, 17196.0, 20204.0, 23738.0, 27889.0, 32767.0 +}; + /* SB PRO */ typedef struct ess_mixer_t { double master_l; @@ -68,7 +76,10 @@ typedef struct ess_mixer_t { double cd_r; double line_l; double line_r; - double mic; + double mic_l; + double mic_r; + double auxb_l; + double auxb_r; /*see sb_ct1745_mixer for values for input selector*/ int32_t input_selector; @@ -84,6 +95,12 @@ typedef struct ess_mixer_t { uint8_t ess_id_str[256]; uint8_t ess_id_str_pos; + +#if 0 + int record_pos_write_cd; + double record_pos_write_cd_sigma; + int record_pos_write_music; +#endif } ess_mixer_t; typedef struct ess_t { @@ -166,11 +183,57 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) case 0x08: mixer->regs[mixer->index + 0x20] = ((val & 0xe) << 4) | (val & 0xe); break; - + + case 0x0A: + { + uint8_t mic_vol_2bit = (mixer->regs[0x0a] >> 1) & 0x3; + mixer->mic_l = mixer->mic_r = sb_att_7dbstep_2bits[mic_vol_2bit] / 32768.0; + mixer->regs[0x1A] = mic_vol_2bit | (mic_vol_2bit << 2); + break; + } + + case 0x0C: + switch (mixer->regs[0x0C] & 6) { + case 2: + mixer->input_selector = INPUT_CD_L | INPUT_CD_R; + break; + case 6: + mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; + break; + default: + mixer->input_selector = INPUT_MIC; + break; + } + break; + case 0x14: mixer->regs[0x4] = val & 0xee; break; + case 0x1A: + mixer->mic_l = sb_att_1p4dbstep_4bits[(mixer->regs[0x1A] >> 4) & 0xF]; + mixer->mic_r = sb_att_1p4dbstep_4bits[mixer->regs[0x1A] & 0xF]; + break; + + case 0x1C: + if ((mixer->regs[0x1C] & 0x07) == 0x07) + { + mixer->input_selector = INPUT_MIXER_L | INPUT_MIXER_R; + } + else if ((mixer->regs[0x1C] & 0x07) == 0x06) + { + mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; + } + else if ((mixer->regs[0x1C] & 0x06) == 0x02) + { + mixer->input_selector = INPUT_CD_L | INPUT_CD_R; + } + else if ((mixer->regs[0x1C] & 0x02) == 0) + { + mixer->input_selector = INPUT_MIC; + } + break; + case 0x22: case 0x26: case 0x28: @@ -192,10 +255,13 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->regs[mixer->index - 0x10] = (val & 0xee); break; + case 0x3a: + break; + case 0x00: case 0x04: - case 0x0a: - case 0x0c: + break; + case 0x0e: break; @@ -268,18 +334,18 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) } } - mixer->voice_l = ess_mixer_get_vol_4bit(mixer->regs[0x14]); - mixer->voice_r = ess_mixer_get_vol_4bit(mixer->regs[0x14] >> 4); - mixer->master_l = ess_mixer_get_vol_4bit(mixer->regs[0x32]); - mixer->master_r = ess_mixer_get_vol_4bit(mixer->regs[0x32] >> 4); - mixer->fm_l = ess_mixer_get_vol_4bit(mixer->regs[0x36]); - mixer->fm_r = ess_mixer_get_vol_4bit(mixer->regs[0x36] >> 4); - mixer->cd_l = ess_mixer_get_vol_4bit(mixer->regs[0x38]); - mixer->cd_r = ess_mixer_get_vol_4bit(mixer->regs[0x38] >> 4); - mixer->line_l = ess_mixer_get_vol_4bit(mixer->regs[0x3e]); - mixer->line_r = ess_mixer_get_vol_4bit(mixer->regs[0x3e] >> 4); - - mixer->mic = sb_att_7dbstep_2bits[(mixer->regs[0x0a] >> 1) & 0x3] / 32768.0; + mixer->voice_l = ess_mixer_get_vol_4bit(mixer->regs[0x14] >> 4); + mixer->voice_r = ess_mixer_get_vol_4bit(mixer->regs[0x14]); + mixer->master_l = ess_mixer_get_vol_4bit(mixer->regs[0x32] >> 4); + mixer->master_r = ess_mixer_get_vol_4bit(mixer->regs[0x32]); + mixer->fm_l = ess_mixer_get_vol_4bit(mixer->regs[0x36] >> 4); + mixer->fm_r = ess_mixer_get_vol_4bit(mixer->regs[0x36]); + mixer->cd_l = ess_mixer_get_vol_4bit(mixer->regs[0x38] >> 4); + mixer->cd_r = ess_mixer_get_vol_4bit(mixer->regs[0x38]); + mixer->line_l = ess_mixer_get_vol_4bit(mixer->regs[0x3e] >> 4); + mixer->line_r = ess_mixer_get_vol_4bit(mixer->regs[0x3e]); + mixer->auxb_l = ess_mixer_get_vol_4bit(mixer->regs[0x3a] >> 4); + mixer->auxb_r = ess_mixer_get_vol_4bit(mixer->regs[0x3a]); mixer->output_filter = !(mixer->regs[0xe] & 0x20); mixer->input_filter = !(mixer->regs[0xc] & 0x20); @@ -288,18 +354,6 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) if (mixer->index == 0xe) sb_dsp_set_stereo(&ess->dsp, val & 2); - switch (mixer->regs[0xc] & 6) { - case 2: - mixer->input_selector = INPUT_CD_L | INPUT_CD_R; - break; - case 6: - mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; - break; - default: - mixer->input_selector = INPUT_MIC; - break; - } - /* TODO: pcspeaker volume? Or is it not worth? */ } } @@ -406,7 +460,13 @@ void ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) { ess_t *ess = (ess_t *) priv; - const ess_mixer_t *mixer = &ess->mixer_sbpro; + const ess_mixer_t *mixer = &ess->mixer_sbpro; +#if 0 + int rec_pos = ess->mixer_sbpro.record_pos_write_music; + int c_record; + int32_t in_l; + int32_t in_r; +#endif double out_l = 0.0; double out_r = 0.0; const int32_t *opl_buf = NULL; @@ -430,24 +490,106 @@ ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) out_l *= mixer->master_l; out_r *= mixer->master_r; +#if 0 + // Pull input after applying mixer's master volume scaling + in_l = (mixer->input_selector & INPUT_MIXER_L) ? ((int32_t) out_l) : 0; + in_r = (mixer->input_selector & INPUT_MIXER_R) ? ((int32_t) out_l) : 0; + + if (ess->dsp.sb_enable_i) { + // NOTE: this is nearest-neighbor sampling. This is gonna generate aliasing like HECK. Is this what the real card does? + c_record = rec_pos + ((c * ess->dsp.sb_freq) / MUSIC_FREQ); + + ess->dsp.record_buffer[c_record & 0xfffe] += in_l; + ess->dsp.record_buffer[(c_record & 0xfffe) + 1] += in_r; + + if (ess->dsp.record_buffer[c_record & 0xfffe] < -32768) + { + ess->dsp.record_buffer[c_record & 0xfffe] = -32768; + } + else if (ess->dsp.record_buffer[c_record & 0xfffe] > 32767) + { + ess->dsp.record_buffer[c_record & 0xfffe] = 32767; + } + + if (ess->dsp.record_buffer[(c_record & 0xfffe) + 1] < -32768) + { + ess->dsp.record_buffer[(c_record & 0xfffe) + 1] = -32768; + } + else if (ess->dsp.record_buffer[(c_record & 0xfffe) + 1] > 32767) + { + ess->dsp.record_buffer[(c_record & 0xfffe) + 1] = 32767; + } + } + buffer[c] += (int32_t) out_l; buffer[c + 1] += (int32_t) out_r; +#endif } +#if 0 + ess->mixer_sbpro.record_pos_write_music += ((len * 2 * ess->dsp.sb_freq) / MUSIC_FREQ); + ess->mixer_sbpro.record_pos_write_music &= 0xfffe; + + if (ess->mixer_sbpro.record_pos_write_music < ess->mixer_sbpro.record_pos_write_cd) + { + ess->dsp.record_pos_write = ess->mixer_sbpro.record_pos_write_music; + } +#endif + ess->opl.reset_buffer(ess->opl.priv); } void ess_filter_cd_audio(int channel, double *buffer, void *priv) { - const ess_t *ess = (ess_t *) priv; - const ess_mixer_t *mixer = &ess->mixer_sbpro; + const ess_t *ess = (ess_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_sbpro; double c; +#if 0 + double rec_pos = ess->mixer_sbpro.record_pos_write_cd; + double rec_pos_sigma = ess->mixer_sbpro.record_pos_write_cd_sigma; + int c_record; + int selector = channel ? INPUT_MIXER_R : INPUT_MIXER_L; + int rec_buf_pos; + int32_t in; +#endif double cd = channel ? mixer->cd_r : mixer->cd_l; double master = channel ? mixer->master_r : mixer->master_l; c = (*buffer * cd) / 3.0; *buffer = c * master; +#if 0 + in = (mixer->input_selector & selector) ? (int32_t)(c * master) : 0; + + if (ess->dsp.sb_enable_i) + { + // NOTE: this is nearest-neighbor sampling. This is gonna generate aliasing like HECK. Is this what the real card does? + c_record = (int)(rec_pos + rec_pos_sigma); + rec_buf_pos = channel ? ((c_record & 0xfffe) + 1) : (c_record & 0xfffe); + + ess->dsp.record_buffer[rec_buf_pos] += in; + + if (ess->dsp.record_buffer[rec_buf_pos] < -32768) + { + ess->dsp.record_buffer[rec_buf_pos] = -32768; + } + else if (ess->dsp.record_buffer[rec_buf_pos] > 32767) + { + ess->dsp.record_buffer[rec_buf_pos] = 32767; + } + } + + ess->mixer_sbpro.record_pos_write_cd += ((2 * (double)ess->dsp.sb_freq) / MUSIC_FREQ) + rec_pos_sigma; + ess->mixer_sbpro.record_pos_write_cd &= ~1; + ess->mixer_sbpro.record_pos_write_cd_sigma = (double)rec_pos + ((2 * (double)ess->dsp.sb_freq) / MUSIC_FREQ) + rec_pos_sigma - ess->mixer_sbpro.record_pos_write_cd; + + ess->mixer_sbpro.record_pos_write_cd &= 0xfffe; + + if (ess->mixer_sbpro.record_pos_write_cd < ess->mixer_sbpro.record_pos_write_music) + { + ess->dsp.record_pos_write = ess->mixer_sbpro.record_pos_write_cd; + } +#endif } static void * @@ -507,6 +649,11 @@ ess_1688_init(UNUSED(const device_t *info)) ess->mixer_sbpro.ess_id_str[3] = addr & 0xff; } +#if 0 + ess->mixer_sbpro.record_pos_write_cd = ess->dsp.record_pos_write; + ess->mixer_sbpro.record_pos_write_music = ess->dsp.record_pos_write; +#endif + ess->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); mpu401_init(ess->mpu, 0, -1, M_UART, 1); sb_dsp_set_mpu(&ess->dsp, ess->mpu); @@ -561,7 +708,7 @@ static const device_config_t ess_config[] = { .description = "IRQ", .type = CONFIG_SELECTION, .default_string = "", - .default_int = 7, + .default_int = 5, .file_filter = "", .spinner = { 0 }, .selection = { From f4c75226efee7fc23267322f5a9ffd80fd139660 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Wed, 13 Mar 2024 00:05:45 -0300 Subject: [PATCH 749/936] Implementing ESPCM decompression (incomplete) --- src/include/86box/snd_sb_dsp.h | 9 +- src/sound/snd_sb_dsp.c | 200 +++++++++++++++++++++++++++++++++ 2 files changed, 208 insertions(+), 1 deletion(-) diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index 4833dea33..6e5266b43 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -9,7 +9,7 @@ #define SB_SUBTYPE_ESS_ES1688 4 /* ESS Technology ES1688 */ /* ESS-related */ -#define IS_ESS(dsp) ((dsp)->sb_subtype >= SB_SUBTYPE_ESS_ES688) +#define IS_ESS(dsp) ((dsp)->sb_subtype == SB_SUBTYPE_ESS_ES688 || (dsp)->sb_subtype == SB_SUBTYPE_ESS_ES1688) /* check for future ESS cards here */ /* aztech-related */ #define IS_AZTECH(dsp) ((dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11 || (dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) /* check for future AZT cards here */ @@ -148,6 +148,13 @@ typedef struct sb_dsp_t { uint8_t ess_reload_len; uint32_t ess_dma_counter; + // ESPCM + uint8_t espcm_sample_idx; + uint8_t espcm_range; + uint8_t espcm_byte_buffer[4]; + uint8_t espcm_code_buffer[10]; /* used for ESPCM_3 */ + uint8_t espcm_last_nibble; /* used for ESPCM_3 */ + mpu_t *mpu; } sb_dsp_t; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index f179ce284..54c8bcc5e 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -32,6 +32,9 @@ #define ADPCM_4 1 #define ADPCM_26 2 #define ADPCM_2 3 +#define ESPCM_4 4 +#define ESPCM_3 5 +#define ESPCM_1 6 // not ESPCM_2, unlike what the manuals say /*The recording safety margin is intended for uneven "len" calls to the get_buffer mixer calls on sound_sb*/ #define SB_DSP_REC_SAFEFTY_MARGIN 4096 @@ -116,6 +119,25 @@ uint8_t adjustMap2[24] = { 252, 0, 252, 0 }; +uint8_t espcm_range_map[256] = { + -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, + -10, -8, -7, -5, -4, -3, -2, -1, 0, 2, 3, 4, 5, 6, 8, 9, + -12, -11, -9, -8, -6, -5, -3, -2, 0, 2, 3, 5, 6, 8, 10, 11, + -14, -12, -11, -9, -7, -5, -4, -2, 0, 2, 4, 5, 7, 9, 11, 13, + -16, -14, -12, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12, 14, + -21, -18, -16, -13, -11, -8, -6, -3, 0, 2, 5, 7, 10, 12, 15, 18, + -27, -24, -21, -17, -14, -11, -8, -4, 0, 3, 7, 10, 13, 17, 20, 24, + -35, -28, -24, -20, -16, -12, -8, -4, 0, 4, 8, 12, 16, 20, 24, 28, + -40, -35, -30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, + -48, -42, -36, -30, -24, -18, -12, -6, 0, 6, 12, 18, 24, 30, 36, 43, + -56, -49, -42, -35, -28, -21, -14, -7, 0, 7, 14, 21, 28, 35, 42, 49, + -72, -63, -54, -45, -36, -27, -18, -9, 0, 9, 18, 27, 36, 45, 54, 63, + -85, -74, -64, -53, -43, -32, -22, -11, 0, 11, 22, 33, 43, 54, 64, 75, + -102, -98, -85, -71, -58, -45, -31, -14, 0, 13, 26, 39, 52, 65, 78, 90, + -127,-112, -96, -80, -64, -48, -32, -16, 0, 16, 32, 48, 64, 80, 96, 112, + -128,-127,-109, -91, -73, -54, -36, -18, 0, 18, 36, 54, 73, 91, 109, 127 +}; + double low_fir_sb16_coef[4][SB16_NCoef]; #ifdef ENABLE_SB_DSP_LOG @@ -1216,6 +1238,78 @@ sb_exec_command(sb_dsp_t *dsp) case 0x48: /* Set DSP block transfer size */ dsp->sb_8_autolen = dsp->sb_data[0] + (dsp->sb_data[1] << 8); break; + case 0x65: /* 4-bit ESPCM output with reference */ + if (!IS_ESS(dsp)) + { + break; + } + dsp->sbref = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + fallthrough; + case 0x64: /* 4-bit ESPCM output */ + if (IS_ESS(dsp)) + { + sb_start_dma(dsp, 1, 0, ESPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + } + break; + case 0x67: /* 3-bit ESPCM output with reference */ + if (!IS_ESS(dsp)) + { + break; + } + dsp->sbref = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + fallthrough; + case 0x66: /* 3-bit ESPCM output */ + if (IS_ESS(dsp)) + { + sb_start_dma(dsp, 1, 0, ESPCM_3, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + } + break; + case 0x6B: /* 1-bit ESPCM output with reference */ + if (!IS_ESS(dsp)) + { + break; + } + dsp->sbref = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + fallthrough; + case 0x6A: /* 1-bit ESPCM output */ + if (IS_ESS(dsp)) + { + sb_start_dma(dsp, 1, 0, ESPCM_1, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + } + break; + case 0x6F: /* 4-bit ESPCM input with reference */ + if (!IS_ESS(dsp)) + { + break; + } + dsp->sbref = (dsp->record_buffer[dsp->record_pos_read] >> 8) ^ 0x80; + dsp->record_pos_read += 2; + dsp->record_pos_read &= 0xFFFF; + fallthrough; + case 0x6E: /* 4-bit ESPCM input */ + if (IS_ESS(dsp)) + { + sb_start_dma_i(dsp, 1, 0, ESPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + dsp->sbdat2 = (dsp->record_buffer[dsp->record_pos_read] >> 8) ^ 0x80; + dsp->record_pos_read += 2; + dsp->record_pos_read &= 0xFFFF; + } + break; case 0x75: /* 4-bit ADPCM output with reference */ dsp->sbref = dsp->dma_readb(dsp->dma_priv); dsp->sbstep = 0; @@ -2060,6 +2154,112 @@ pollsb(void *priv) dsp->sbdatl = dsp->sbdatr = dsp->sbdat; break; + case ESPCM_4: + if (dsp->espcm_sample_idx >= 19) + { + dsp->espcm_sample_idx = 0; + } + if (dsp->espcm_sample_idx == 0) + { + dsp->espcm_byte_buffer[0] = dsp->dma_readb(dsp->dma_priv); + dsp->espcm_sample_idx++; + dsp->sb_8_length--; + dsp->ess_dma_counter++; + + dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; + tempi = dsp->espcm_byte_buffer[0] >> 4; + } + else if (dsp->espcm_sample_idx & 1) + { + dsp->espcm_byte_buffer[0] = dsp->dma_readb(dsp->dma_priv); + dsp->espcm_sample_idx++; + dsp->sb_8_length--; + dsp->ess_dma_counter++; + + tempi = dsp->espcm_byte_buffer[0] & 0x0F; + } + else + { + dsp->espcm_sample_idx++; + tempi = dsp->espcm_byte_buffer[0] >> 4; + } + + tempi |= (dsp->espcm_range << 4); + data[0] = espcm_range_map[tempi]; + dsp->sbdat = data[0] << 8; + if (dsp->stereo) + { + sb_dsp_log("pollsb: ESPCM 4, dsp->stereo, %s channel, %04X\n", + dsp->sbleftright ? "left" : "right", dsp->sbdat); + if (dsp->sbleftright) + dsp->sbdatl = dsp->sbdat; + else + dsp->sbdatr = dsp->sbdat; + dsp->sbleftright = !dsp->sbleftright; + } + else + { + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + } + break; + + case ESPCM_3: + // TODO + break; + + case ESPCM_1: + if (dsp->espcm_sample_idx >= 19) + { + dsp->espcm_sample_idx = 0; + } + if (dsp->espcm_sample_idx == 0) + { + dsp->espcm_byte_buffer[0] = dsp->dma_readb(dsp->dma_priv); + dsp->espcm_sample_idx++; + dsp->sb_8_length--; + dsp->ess_dma_counter++; + + dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; + dsp->espcm_byte_buffer[0] >>= 5; + tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xF : 0x0; + dsp->espcm_byte_buffer[0] >>= 1; + } + else if (dsp->espcm_sample_idx == 3 | dsp->espcm_sample_idx == 11) + { + dsp->espcm_byte_buffer[0] = dsp->dma_readb(dsp->dma_priv); + dsp->espcm_sample_idx++; + dsp->sb_8_length--; + dsp->ess_dma_counter++; + + tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xF : 0x0; + dsp->espcm_byte_buffer[0] >>= 1; + } + else + { + dsp->espcm_sample_idx++; + tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xF : 0x0; + dsp->espcm_byte_buffer[0] >>= 1; + } + + tempi |= (dsp->espcm_range << 4); + data[0] = espcm_range_map[tempi]; + dsp->sbdat = data[0] << 8; + if (dsp->stereo) + { + sb_dsp_log("pollsb: ESPCM 1, dsp->stereo, %s channel, %04X\n", + dsp->sbleftright ? "left" : "right", dsp->sbdat); + if (dsp->sbleftright) + dsp->sbdatl = dsp->sbdat; + else + dsp->sbdatr = dsp->sbdat; + dsp->sbleftright = !dsp->sbleftright; + } + else + { + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + } + break; + default: break; } From e2200f8d750d89543d5975d08e9895c0152f0c30 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Wed, 13 Mar 2024 10:51:11 -0300 Subject: [PATCH 750/936] Add tables for ESPCM_3 mode --- src/include/86box/snd_sb_dsp.h | 2 +- src/sound/snd_sb_dsp.c | 101 ++++++++++++++++++++++++++++++++- 2 files changed, 100 insertions(+), 3 deletions(-) diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index 6e5266b43..7b516a987 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -153,7 +153,7 @@ typedef struct sb_dsp_t { uint8_t espcm_range; uint8_t espcm_byte_buffer[4]; uint8_t espcm_code_buffer[10]; /* used for ESPCM_3 */ - uint8_t espcm_last_nibble; /* used for ESPCM_3 */ + uint8_t espcm_last_value; /* used for ESPCM_3 */ mpu_t *mpu; } sb_dsp_t; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 54c8bcc5e..530d16015 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -119,7 +119,12 @@ uint8_t adjustMap2[24] = { 252, 0, 252, 0 }; -uint8_t espcm_range_map[256] = { +/* Upper half only used for ESPCM_3 mode. */ +/* TODO: Extract actual table (or exact ranges + range interpolation algo, whatever it is) from chip, someday, somehow. + * This current table is part software reverse engineering, part guesswork/extrapolation. + * It's close enough to what's in the chip to produce acceptable results, but not exact. + **/ +uint8_t espcm_range_map[512] = { -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, -10, -8, -7, -5, -4, -3, -2, -1, 0, 2, 3, 4, 5, 6, 8, 9, -12, -11, -9, -8, -6, -5, -3, -2, 0, 2, 3, 5, 6, 8, 10, 11, @@ -135,7 +140,99 @@ uint8_t espcm_range_map[256] = { -85, -74, -64, -53, -43, -32, -22, -11, 0, 11, 22, 33, 43, 54, 64, 75, -102, -98, -85, -71, -58, -45, -31, -14, 0, 13, 26, 39, 52, 65, 78, 90, -127,-112, -96, -80, -64, -48, -32, -16, 0, 16, 32, 48, 64, 80, 96, 112, - -128,-127,-109, -91, -73, -54, -36, -18, 0, 18, 36, 54, 73, 91, 109, 127 + -128,-127,-109, -91, -73, -54, -36, -18, 0, 18, 36, 54, 73, 91, 109, 127, + -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, + -10, -9, -8, -6, -5, -4, -3, -2, -1, 1, 2, 3, 4, 6, 7, 8, + -13, -11, -9, -7, -6, -5, -3, -2, -1, 2, 3, 5, 6, 7, 9, 10, + -15, -13, -12, -10, -8, -6, -5, -3, -1, 2, 3, 5, 6, 8, 10, 12, + -18, -15, -13, -11, -9, -7, -5, -3, -1, 2, 3, 5, 7, 9, 11, 13, + -24, -20, -17, -15, -12, -10, -7, -5, -2, 2, 3, 6, 8, 11, 13, 16, + -29, -26, -23, -19, -16, -13, -10, -6, -2, 2, 5, 8, 11, 15, 18, 22, + -34, -30, -26, -22, -18, -14, -10, -6, -2, 2, 6, 10, 14, 18, 22, 26, + -43, -38, -33, -28, -23, -18, -13, -8, -3, 2, 7, 12, 17, 22, 27, 32, + -51, -45, -39, -33, -27, -21, -15, -9, -3, 3, 9, 15, 21, 27, 33, 39, + -60, -53, -46, -39, -32, -25, -18, -11, -4, 3, 10, 17, 24, 31, 38, 45, + -77, -68, -59, -50, -41, -32, -23, -14, -5, 4, 13, 22, 31, 40, 49, 58, + -90, -80, -69, -59, -48, -38, -27, -17, -6, 5, 16, 27, 38, 48, 59, 69, + -112,-104, -91, -78, -65, -52, -38, -23, -7, 6, 19, 32, 45, 58, 71, 84, + -128,-120,-104, -88, -72, -56, -40, -24, -8, 8, 24, 40, 56, 72, 88, 104, + -128,-128,-118,-100, -82, -64, -45, -27, -9, 9, 27, 45, 63, 82, 100, 118 +}; + +/* address = table_index(9:8) | dsp->espcm_last_value(7:3) | codeword(2:0) + * the value is a base index into espcm_range_map with bits at (8, 3:0), + * to be OR'ed with dsp->espcm_range at (7:4) + */ +uint16_t espcm3_dpcm_tables[1024] = +{ + /* Table 0 */ + 256, 257, 258, 259, 260, 263, 266, 269, 0, 257, 258, 259, 260, 263, 266, 269, + 0, 1, 258, 259, 260, 263, 266, 269, 1, 2, 259, 260, 261, 263, 266, 269, + 1, 3, 260, 261, 262, 264, 266, 269, 1, 3, 4, 261, 262, 264, 266, 269, + 2, 4, 5, 262, 263, 264, 266, 269, 2, 4, 6, 263, 264, 265, 267, 269, + 2, 4, 6, 7, 264, 265, 267, 269, 2, 5, 7, 8, 265, 266, 267, 269, + 2, 5, 7, 8, 9, 266, 268, 270, 2, 5, 7, 9, 10, 267, 268, 270, + 2, 5, 8, 10, 11, 268, 269, 270, 2, 5, 8, 11, 12, 269, 270, 271, + 2, 5, 8, 11, 12, 13, 270, 271, 2, 5, 8, 11, 12, 13, 14, 271, + 0, 257, 258, 259, 260, 263, 266, 269, 0, 1, 258, 259, 260, 263, 266, 269, + 0, 1, 2, 259, 260, 263, 266, 269, 1, 2, 3, 260, 261, 263, 266, 269, + 1, 3, 4, 261, 262, 264, 266, 269, 1, 3, 5, 262, 263, 264, 266, 269, + 2, 4, 5, 6, 263, 264, 266, 269, 2, 4, 6, 7, 264, 265, 267, 269, + 2, 4, 6, 7, 8, 265, 267, 269, 2, 5, 7, 8, 9, 266, 267, 269, + 2, 5, 7, 9, 10, 267, 268, 270, 2, 5, 7, 9, 10, 11, 268, 270, + 2, 5, 8, 10, 11, 12, 269, 270, 2, 5, 8, 11, 12, 13, 270, 271, + 2, 5, 8, 11, 12, 13, 14, 271, 2, 5, 8, 11, 12, 13, 14, 15, + /* Table 1 */ + 257, 260, 262, 263, 264, 265, 267, 270, 257, 260, 262, 263, 264, 265, 267, 270, + 1, 260, 262, 263, 264, 265, 267, 270, 1, 260, 262, 263, 264, 265, 267, 270, + 1, 260, 262, 263, 264, 265, 267, 270, 1, 4, 262, 263, 264, 265, 267, 270, + 1, 4, 262, 263, 264, 265, 267, 270, 1, 4, 6, 263, 264, 265, 267, 270, + 1, 4, 6, 7, 264, 265, 267, 270, 1, 4, 6, 7, 8, 265, 267, 270, + 1, 4, 6, 7, 8, 9, 267, 270, 1, 4, 6, 7, 8, 9, 267, 270, + 1, 4, 6, 7, 8, 9, 11, 270, 1, 4, 6, 7, 8, 9, 11, 270, + 1, 4, 6, 7, 8, 9, 11, 270, 1, 4, 6, 7, 8, 9, 11, 14, + 257, 260, 262, 263, 264, 265, 267, 270, 1, 260, 262, 263, 264, 265, 267, 270, + 1, 260, 262, 263, 264, 265, 267, 270, 1, 260, 262, 263, 264, 265, 267, 270, + 1, 4, 262, 263, 264, 265, 267, 270, 1, 4, 262, 263, 264, 265, 267, 270, + 1, 4, 6, 263, 264, 265, 267, 270, 1, 4, 6, 7, 264, 265, 267, 270, + 1, 4, 6, 7, 8, 265, 267, 270, 1, 4, 6, 7, 8, 9, 267, 270, + 1, 4, 6, 7, 8, 9, 267, 270, 1, 4, 6, 7, 8, 9, 11, 270, + 1, 4, 6, 7, 8, 9, 11, 270, 1, 4, 6, 7, 8, 9, 11, 270, + 1, 4, 6, 7, 8, 9, 11, 14, 1, 4, 6, 7, 8, 9, 11, 14, + /* Table 2 */ + 256, 257, 258, 259, 260, 262, 265, 268, 0, 257, 258, 259, 260, 262, 265, 268, + 0, 1, 258, 259, 260, 262, 265, 269, 1, 2, 259, 260, 261, 263, 265, 269, + 1, 3, 260, 261, 262, 263, 265, 269, 1, 3, 4, 261, 262, 263, 265, 269, + 1, 3, 5, 262, 263, 264, 266, 269, 1, 4, 5, 6, 263, 264, 266, 269, + 1, 4, 6, 7, 264, 265, 266, 269, 1, 4, 6, 7, 8, 265, 266, 269, + 2, 4, 6, 7, 8, 9, 267, 269, 2, 4, 6, 7, 8, 9, 267, 269, + 2, 5, 7, 8, 9, 10, 11, 270, 2, 5, 7, 8, 9, 10, 11, 270, + 2, 5, 8, 9, 10, 11, 12, 270, 2, 6, 8, 10, 11, 12, 13, 14, + 257, 258, 259, 260, 261, 263, 265, 269, 1, 259, 260, 261, 262, 263, 266, 269, + 1, 260, 261, 262, 263, 264, 266, 269, 1, 260, 261, 262, 263, 264, 266, 269, + 2, 4, 262, 263, 264, 265, 267, 269, 2, 4, 262, 263, 264, 265, 267, 269, + 2, 5, 6, 263, 264, 265, 267, 270, 2, 5, 6, 7, 264, 265, 267, 270, + 2, 5, 7, 8, 265, 266, 267, 270, 2, 5, 7, 8, 9, 266, 268, 270, + 2, 6, 8, 9, 10, 267, 268, 270, 2, 6, 8, 9, 10, 11, 268, 270, + 2, 6, 8, 10, 11, 12, 269, 270, 2, 6, 9, 11, 12, 13, 270, 271, + 3, 6, 9, 11, 12, 13, 14, 271, 3, 6, 9, 11, 12, 13, 14, 15, + /* Table 3 */ + 256, 258, 260, 261, 262, 263, 264, 265, 0, 258, 260, 261, 262, 263, 264, 265, + 1, 259, 260, 261, 262, 263, 264, 266, 1, 259, 260, 261, 262, 263, 264, 266, + 1, 3, 260, 261, 262, 263, 264, 266, 1, 3, 4, 261, 262, 263, 264, 267, + 1, 3, 4, 5, 262, 263, 264, 267, 1, 3, 4, 5, 6, 263, 264, 267, + 1, 3, 5, 6, 7, 264, 265, 268, 1, 3, 5, 6, 7, 8, 265, 268, + 1, 4, 6, 7, 8, 9, 266, 269, 1, 4, 6, 7, 8, 9, 10, 269, + 1, 4, 6, 7, 8, 9, 10, 269, 1, 4, 6, 7, 8, 9, 11, 270, + 1, 4, 6, 7, 8, 9, 11, 270, 1, 4, 6, 7, 8, 9, 11, 14, + 257, 260, 262, 263, 264, 265, 267, 270, 1, 260, 262, 263, 264, 265, 267, 270, + 1, 260, 262, 263, 264, 265, 267, 270, 2, 261, 262, 263, 264, 265, 267, 270, + 2, 261, 262, 263, 264, 265, 267, 270, 2, 5, 262, 263, 264, 265, 267, 270, + 3, 6, 263, 264, 265, 266, 268, 270, 3, 6, 7, 264, 265, 266, 268, 270, + 4, 7, 8, 265, 266, 267, 268, 270, 4, 7, 8, 9, 266, 267, 268, 270, + 4, 7, 8, 9, 10, 267, 268, 270, 5, 7, 8, 9, 10, 11, 268, 270, + 5, 7, 8, 9, 10, 11, 12, 270, 5, 7, 8, 9, 10, 11, 12, 270, + 6, 7, 8, 9, 10, 11, 13, 271, 6, 7, 8, 9, 10, 11, 13, 15 }; double low_fir_sb16_coef[4][SB16_NCoef]; From 9d54a78918cdae2d40b085be82bffd492105254a Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Wed, 13 Mar 2024 11:39:56 -0300 Subject: [PATCH 751/936] Implement ESPCM_3 decoding --- src/include/86box/snd_sb_dsp.h | 1 + src/sound/snd_sb_dsp.c | 91 +++++++++++++++++++++++++++++++++- 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index 7b516a987..a9bd93ddc 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -153,6 +153,7 @@ typedef struct sb_dsp_t { uint8_t espcm_range; uint8_t espcm_byte_buffer[4]; uint8_t espcm_code_buffer[10]; /* used for ESPCM_3 */ + uint8_t espcm_table_index; /* used for ESPCM_3 */ uint8_t espcm_last_value; /* used for ESPCM_3 */ mpu_t *mpu; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 530d16015..018e2d380 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -2301,7 +2301,96 @@ pollsb(void *priv) break; case ESPCM_3: - // TODO + if (dsp->espcm_sample_idx >= 19) + { + dsp->espcm_sample_idx = 0; + } + if (dsp->espcm_sample_idx == 0) + { + dsp->espcm_byte_buffer[0] = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + + dsp->espcm_sample_idx++; + + dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; + tempi = dsp->espcm_byte_buffer[0] >> 4; + dsp->espcm_last_value = tempi; + } + else if (dsp->espcm_sample_idx == 1) + { + for (tempi = 0; tempi < 4; tempi++) + { + dsp->espcm_byte_buffer[tempi] = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + } + + dsp->espcm_table_index = dsp->espcm_byte_buffer[0] & 0x03; + dsp->espcm_code_buffer[0] = (dsp->espcm_byte_buffer[0] >> 2) & 0x07; + dsp->espcm_code_buffer[1] = (dsp->espcm_byte_buffer[0] >> 5) & 0x07; + dsp->espcm_code_buffer[2] = (dsp->espcm_byte_buffer[1]) & 0x07; + dsp->espcm_code_buffer[3] = (dsp->espcm_byte_buffer[1] >> 3) & 0x07; + dsp->espcm_code_buffer[4] = ((dsp->espcm_byte_buffer[1] >> 6) & 0x03) | ((dsp->espcm_byte_buffer[2] & 0x01) << 2); + dsp->espcm_code_buffer[5] = (dsp->espcm_byte_buffer[2] >> 1) & 0x07; + dsp->espcm_code_buffer[6] = (dsp->espcm_byte_buffer[2] >> 4) & 0x07; + dsp->espcm_code_buffer[7] = ((dsp->espcm_byte_buffer[2] >> 7) & 0x01) | ((dsp->espcm_byte_buffer[3] & 0x03) << 1); + dsp->espcm_code_buffer[8] = (dsp->espcm_byte_buffer[3] >> 2) & 0x07; + dsp->espcm_code_buffer[9] = (dsp->espcm_byte_buffer[3] >> 5) & 0x07; + + tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[0]; + tempi = espcm3_dpcm_tables[tempi]; + dsp->espcm_last_value = tempi; + dsp->espcm_sample_idx++; + } + else if (dsp->espcm_sample_idx == 11) + { + for (tempi = 1; tempi < 4; tempi++) + { + dsp->espcm_byte_buffer[tempi] = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + } + + dsp->espcm_code_buffer[0] = (dsp->espcm_byte_buffer[1]) & 0x07; + dsp->espcm_code_buffer[1] = (dsp->espcm_byte_buffer[1] >> 3) & 0x07; + dsp->espcm_code_buffer[2] = ((dsp->espcm_byte_buffer[1] >> 6) & 0x03) | ((dsp->espcm_byte_buffer[2] & 0x01) << 2); + dsp->espcm_code_buffer[3] = (dsp->espcm_byte_buffer[2] >> 1) & 0x07; + dsp->espcm_code_buffer[4] = (dsp->espcm_byte_buffer[2] >> 4) & 0x07; + dsp->espcm_code_buffer[5] = ((dsp->espcm_byte_buffer[2] >> 7) & 0x01) | ((dsp->espcm_byte_buffer[3] & 0x03) << 1); + dsp->espcm_code_buffer[6] = (dsp->espcm_byte_buffer[3] >> 2) & 0x07; + dsp->espcm_code_buffer[7] = (dsp->espcm_byte_buffer[3] >> 5) & 0x07; + + tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[0]; + tempi = espcm3_dpcm_tables[tempi]; + dsp->espcm_last_value = tempi; + dsp->espcm_sample_idx++; + } + else + { + tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[(dsp->espcm_sample_idx - 1) % 10]; + tempi = espcm3_dpcm_tables[tempi]; + dsp->espcm_last_value = tempi; + dsp->espcm_sample_idx++; + } + + tempi |= (dsp->espcm_range << 4); + data[0] = espcm_range_map[tempi]; + dsp->sbdat = data[0] << 8; + if (dsp->stereo) + { + sb_dsp_log("pollsb: ESPCM 3, dsp->stereo, %s channel, %04X\n", + dsp->sbleftright ? "left" : "right", dsp->sbdat); + if (dsp->sbleftright) + dsp->sbdatl = dsp->sbdat; + else + dsp->sbdatr = dsp->sbdat; + dsp->sbleftright = !dsp->sbleftright; + } + else + { + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + } break; case ESPCM_1: From 416edcf1a5b93d70209ba7e6ee1a0fcdd58b5320 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Wed, 13 Mar 2024 11:41:50 -0300 Subject: [PATCH 752/936] Fix: clear espcm_sample_idx upon starting ESPCM DMA --- src/sound/snd_sb_dsp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 018e2d380..7972864a1 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -1348,6 +1348,7 @@ sb_exec_command(sb_dsp_t *dsp) if (IS_ESS(dsp)) { sb_start_dma(dsp, 1, 0, ESPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + dsp->espcm_sample_idx = 0; dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; dsp->ess_dma_counter++; @@ -1366,6 +1367,7 @@ sb_exec_command(sb_dsp_t *dsp) if (IS_ESS(dsp)) { sb_start_dma(dsp, 1, 0, ESPCM_3, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + dsp->espcm_sample_idx = 0; dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; dsp->ess_dma_counter++; @@ -1384,6 +1386,7 @@ sb_exec_command(sb_dsp_t *dsp) if (IS_ESS(dsp)) { sb_start_dma(dsp, 1, 0, ESPCM_1, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + dsp->espcm_sample_idx = 0; dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; dsp->ess_dma_counter++; @@ -1402,6 +1405,7 @@ sb_exec_command(sb_dsp_t *dsp) if (IS_ESS(dsp)) { sb_start_dma_i(dsp, 1, 0, ESPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + dsp->espcm_sample_idx = 0; dsp->sbdat2 = (dsp->record_buffer[dsp->record_pos_read] >> 8) ^ 0x80; dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; From 6fc43a80828c44aba861832dc3fbe22a390ec243 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Wed, 13 Mar 2024 19:28:12 -0300 Subject: [PATCH 753/936] Implement ESPCM_4 recording --- src/include/86box/snd_sb_dsp.h | 7 +-- src/sound/snd_sb_dsp.c | 87 +++++++++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 4 deletions(-) diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index a9bd93ddc..7a1873b9c 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -152,9 +152,10 @@ typedef struct sb_dsp_t { uint8_t espcm_sample_idx; uint8_t espcm_range; uint8_t espcm_byte_buffer[4]; - uint8_t espcm_code_buffer[10]; /* used for ESPCM_3 */ - uint8_t espcm_table_index; /* used for ESPCM_3 */ - uint8_t espcm_last_value; /* used for ESPCM_3 */ + uint8_t espcm_code_buffer[19]; /* used for ESPCM_3 and for ESPCM_4 recording */ + int8_t espcm_sample_buffer[19]; /* used for ESPCM_4 recording */ + uint8_t espcm_table_index; /* used for ESPCM_3 */ + uint8_t espcm_last_value; /* used for ESPCM_3 */ mpu_t *mpu; } sb_dsp_t; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 7972864a1..0c1b789d1 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -124,7 +124,7 @@ uint8_t adjustMap2[24] = { * This current table is part software reverse engineering, part guesswork/extrapolation. * It's close enough to what's in the chip to produce acceptable results, but not exact. **/ -uint8_t espcm_range_map[512] = { +int8_t espcm_range_map[512] = { -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, -10, -8, -7, -5, -4, -3, -2, -1, 0, 2, 3, 4, 5, 6, 8, 9, -12, -11, -9, -8, -6, -5, -3, -2, 0, 2, 3, 5, 6, 8, 10, 11, @@ -2331,6 +2331,7 @@ pollsb(void *priv) } dsp->espcm_table_index = dsp->espcm_byte_buffer[0] & 0x03; + dsp->espcm_code_buffer[0] = (dsp->espcm_byte_buffer[0] >> 2) & 0x07; dsp->espcm_code_buffer[1] = (dsp->espcm_byte_buffer[0] >> 5) & 0x07; dsp->espcm_code_buffer[2] = (dsp->espcm_byte_buffer[1]) & 0x07; @@ -2613,6 +2614,90 @@ sb_poll_i(void *priv) dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; break; + case ESPCM_4: + // I assume the real hardware double-buffers the blocks or something like that. + // We're not gonna do that here. + dsp->espcm_sample_buffer[dsp->espcm_sample_idx] = dsp->record_buffer[dsp->record_pos_read] >> 8; + dsp->espcm_sample_idx++; + dsp->record_pos_read += 2; + dsp->record_pos_read &= 0xFFFF; + if (dsp->espcm_sample_idx >= 19) + { + int i, bit, table_addr, sigma, last_sigma; + int8_t min_sample = 127, max_sample = -128, s; + uint8_t b; + + for (i = 0; i < 19; i++) + { + s = dsp->espcm_sample_buffer[i]; + if (s < min_sample) + { + min_sample = s; + } + if (s > max_sample) + { + max_sample = s; + } + } + if (min_sample < 0) + { + min_sample = -min_sample; + } + if (max_sample < 0) + { + max_sample = -max_sample; + } + if (min_sample > max_sample) + { + max_sample = min_sample; + } + + for (table_addr = 15; table_addr < 256; table_addr += 16) + { + if (max_sample <= espcm_range_map[table_addr]) + { + break; + } + } + dsp->espcm_range = table_addr >> 4; + + for (i = 0; i < 19; i++) + { + table_addr = dsp->espcm_range << 4; + last_sigma = 9999; + s = dsp->espcm_sample_buffer[i]; + for (; (table_addr >> 4) == dsp->espcm_range; table_addr++) + { + sigma = espcm_range_map[table_addr] - s; + if (sigma < 0) + { + sigma = -sigma; + } + if (sigma > last_sigma) + { + break; + } + last_sigma = sigma; + } + table_addr--; + dsp->espcm_code_buffer[i] = table_addr & 0x0F; + } + + b = dsp->espcm_range | (dsp->espcm_code_buffer[0] << 4); + dsp->dma_writeb(dsp->dma_priv, b); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + + for (i = 1; i < 10; i++) + { + b = dsp->espcm_code_buffer[i * 2 - 1] | (dsp->espcm_code_buffer[i * 2] << 4); + dsp->dma_writeb(dsp->dma_priv, b); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + } + + dsp->espcm_sample_idx = 0; + } default: break; From 011b06441dac21fa9a598f4af13ec716ea559878 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Wed, 13 Mar 2024 22:00:46 -0300 Subject: [PATCH 754/936] Removing extraneous DSP update from ess_get_music_buffer_sbpro --- src/sound/snd_ess.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 0f57bca7d..55c6f9d60 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -473,8 +473,6 @@ ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) opl_buf = ess->opl.update(ess->opl.priv); - sb_dsp_update(&ess->dsp); - for (int c = 0; c < len * 2; c += 2) { out_l = 0.0; out_r = 0.0; From 40607b291dcfc909081d7128dd7374dc630bf953 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Tue, 19 Mar 2024 13:01:54 -0300 Subject: [PATCH 755/936] Fixing ESPCM 1/2 --- src/include/86box/fifo.h | 5 + src/include/86box/snd_sb_dsp.h | 29 ++-- src/sound/snd_sb_dsp.c | 274 +++++++++++++++++++++------------ 3 files changed, 201 insertions(+), 107 deletions(-) diff --git a/src/include/86box/fifo.h b/src/include/86box/fifo.h index e76189d8a..f87f932e0 100644 --- a/src/include/86box/fifo.h +++ b/src/include/86box/fifo.h @@ -1,3 +1,6 @@ +#ifndef FIFO_H +#define FIFO_H + /* * 86Box A hypervisor and IBM PC system emulator that specializes in * running old operating systems and software designed for IBM @@ -71,3 +74,5 @@ extern void fifo_reset(void *priv); extern void fifo_reset_evt(void *priv); extern void fifo_close(void *priv); extern void *fifo_init(int len); + +#endif /*FIFO_H*/ diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index 7a1873b9c..f5905ccc2 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -1,6 +1,8 @@ #ifndef SOUND_SND_SB_DSP_H #define SOUND_SND_SB_DSP_H +#include <86box/fifo.h> + /*Sound Blaster Clones, for quirks*/ #define SB_SUBTYPE_DEFAULT 0 /*Handle as a Creative card*/ #define SB_SUBTYPE_CLONE_AZT2316A_0X11 1 /*Aztech Sound Galaxy Pro 16 AB, DSP 3.1 - SBPRO2 clone*/ @@ -142,20 +144,25 @@ typedef struct sb_dsp_t { uint8_t azt_eeprom[AZTECH_EEPROM_SIZE]; /* the eeprom in the Aztech cards is attached to the DSP */ - uint8_t ess_regs[256]; /* ESS registers. */ - uint8_t ess_playback_mode; - uint8_t ess_extended_mode; - uint8_t ess_reload_len; + uint8_t ess_regs[256]; /* ESS registers. */ + uint8_t ess_playback_mode; + uint8_t ess_extended_mode; + uint8_t ess_reload_len; uint32_t ess_dma_counter; + int ess_irq_generic; + int ess_irq_dmactr; // ESPCM - uint8_t espcm_sample_idx; - uint8_t espcm_range; - uint8_t espcm_byte_buffer[4]; - uint8_t espcm_code_buffer[19]; /* used for ESPCM_3 and for ESPCM_4 recording */ - int8_t espcm_sample_buffer[19]; /* used for ESPCM_4 recording */ - uint8_t espcm_table_index; /* used for ESPCM_3 */ - uint8_t espcm_last_value; /* used for ESPCM_3 */ + fifo64_t *espcm_fifo; + int espcm_fifo_reset; + int espcm_mode; + uint8_t espcm_sample_idx; + uint8_t espcm_range; + uint8_t espcm_byte_buffer[4]; + uint8_t espcm_code_buffer[19]; /* used for ESPCM_3 and for ESPCM_4 recording */ + int8_t espcm_sample_buffer[19]; /* used for ESPCM_4 recording */ + uint8_t espcm_table_index; /* used for ESPCM_3 */ + uint8_t espcm_last_value; /* used for ESPCM_3 */ mpu_t *mpu; } sb_dsp_t; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 0c1b789d1..34ddb1a50 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -34,7 +34,8 @@ #define ADPCM_2 3 #define ESPCM_4 4 #define ESPCM_3 5 -#define ESPCM_1 6 // not ESPCM_2, unlike what the manuals say +#define ESPCM_1 7 +#define ESPCM_4E 8 // for encoding mode switching /*The recording safety margin is intended for uneven "len" calls to the get_buffer mixer calls on sound_sb*/ #define SB_DSP_REC_SAFEFTY_MARGIN 4096 @@ -386,12 +387,16 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) break; } - /* TODO: Investigate real hardware for this (the ES1887 datasheet documents this bit somewhat oddly.) */ - if (dsp->ess_playback_mode && bit <= 1 && set && !masked) { - if (!(ESSreg(0xB1) & 0x40)) // if ESS playback, and IRQ disabled, do not fire - { - pclog("ess: IRQ was masked\n"); - return; + /* NOTE: not on ES1688, apparently; investigate on ES1868 */ + if (IS_ESS(dsp) && dsp->sb_subtype != SB_SUBTYPE_ESS_ES1688) + { + /* TODO: Investigate real hardware for this (the ES1887 datasheet documents this bit somewhat oddly.) */ + if (dsp->ess_playback_mode && bit <= 1 && set && !masked) { + if (!(ESSreg(0xB1) & 0x40)) // if ESS playback, and IRQ disabled, do not fire + { + pclog("ess: IRQ was masked\n"); + return; + } } } @@ -945,6 +950,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) dsp->sb_irqnum = 10; break; } + pclog("ess: IRQ set to %d\n", dsp->sb_irqnum); sb_ess_update_irq_drq_readback_regs(dsp, false); break; case 0xB2: /* DRQ Control */ @@ -965,6 +971,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) dsp->sb_8_dmanum = 3; break; } + pclog("ess: DMA set to %d\n", dsp->sb_8_dmanum); sb_ess_update_irq_drq_readback_regs(dsp, false); if (chg & 0x40) sb_ess_update_dma_status(dsp); break; @@ -1041,6 +1048,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) case 0xBA: /* Left Channel ADC Offset Adjust */ case 0xBB: /* Right Channel ADC Offset Adjust */ case 0xC3: /* Internal state register */ + case 0xCF: /* GPO0/1 power management register */ ESSreg(reg) = data; break; @@ -1066,13 +1074,15 @@ sb_exec_command(sb_dsp_t *dsp) } { - int i; - char data_s[256]; + int i, l, s = 0; + char data_s[256], *dsptr = data_s; data_s[0] = '\0'; for (i = 0; i < sb_commands[dsp->sb_command]; i++) { - snprintf(data_s, 256, " 0x%02X", dsp->sb_data[i]); + l = snprintf(dsptr, 256 - s, " 0x%02X", dsp->sb_data[i]); + s += l; + dsptr += l; } pclog("dsp->sb_command = 0x%02X%s, length %d\n", dsp->sb_command, data_s, sb_commands[dsp->sb_command]); } @@ -1090,6 +1100,14 @@ sb_exec_command(sb_dsp_t *dsp) { sb_add_data(dsp, sb_ess_read_reg(dsp, 0xC3)); } + else if (dsp->sb_command == 0xCE) + { + sb_add_data(dsp, sb_ess_read_reg(dsp, 0xCF)); + } + else if (dsp->sb_command == 0xCF) + { + sb_ess_write_reg(dsp, 0xCF, dsp->sb_data[0]); + } else if (dsp->sb_command == 0xC0) { sb_add_data(dsp, sb_ess_read_reg(dsp, dsp->sb_data[0])); } @@ -1336,79 +1354,60 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sb_8_autolen = dsp->sb_data[0] + (dsp->sb_data[1] << 8); break; case 0x65: /* 4-bit ESPCM output with reference */ - if (!IS_ESS(dsp)) - { - break; - } - dsp->sbref = dsp->dma_readb(dsp->dma_priv); - dsp->sb_8_length--; - dsp->ess_dma_counter++; - fallthrough; case 0x64: /* 4-bit ESPCM output */ if (IS_ESS(dsp)) { + if (dsp->espcm_mode != ESPCM_4) + { + fifo_reset(dsp->espcm_fifo); + dsp->espcm_sample_idx = 0; + } + dsp->espcm_mode = ESPCM_4; sb_start_dma(dsp, 1, 0, ESPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - dsp->espcm_sample_idx = 0; - dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); - dsp->sb_8_length--; - dsp->ess_dma_counter++; } break; case 0x67: /* 3-bit ESPCM output with reference */ - if (!IS_ESS(dsp)) - { - break; - } - dsp->sbref = dsp->dma_readb(dsp->dma_priv); - dsp->sb_8_length--; - dsp->ess_dma_counter++; - fallthrough; case 0x66: /* 3-bit ESPCM output */ if (IS_ESS(dsp)) { + pclog("ess: Starting espcm3 transfer\n"); + if (dsp->espcm_mode != ESPCM_3) + { + pclog("ess: ESPCM FIFO reset\n"); + fifo_reset(dsp->espcm_fifo); + dsp->espcm_sample_idx = 0; + } + dsp->espcm_mode = ESPCM_3; sb_start_dma(dsp, 1, 0, ESPCM_3, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - dsp->espcm_sample_idx = 0; - dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); - dsp->sb_8_length--; - dsp->ess_dma_counter++; } break; - case 0x6B: /* 1-bit ESPCM output with reference */ - if (!IS_ESS(dsp)) - { - break; - } - dsp->sbref = dsp->dma_readb(dsp->dma_priv); - dsp->sb_8_length--; - dsp->ess_dma_counter++; - fallthrough; - case 0x6A: /* 1-bit ESPCM output */ + case 0x6D: /* 1-bit ESPCM output with reference */ + case 0x6C: /* 1-bit ESPCM output */ if (IS_ESS(dsp)) { + pclog("ess: Starting espcm1 transfer\n"); + if (dsp->espcm_mode != ESPCM_1) + { + pclog("ess: ESPCM FIFO reset\n"); + fifo_reset(dsp->espcm_fifo); + dsp->espcm_sample_idx = 0; + } + dsp->espcm_mode = ESPCM_1; sb_start_dma(dsp, 1, 0, ESPCM_1, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - dsp->espcm_sample_idx = 0; - dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); - dsp->sb_8_length--; - dsp->ess_dma_counter++; } break; case 0x6F: /* 4-bit ESPCM input with reference */ - if (!IS_ESS(dsp)) - { - break; - } - dsp->sbref = (dsp->record_buffer[dsp->record_pos_read] >> 8) ^ 0x80; - dsp->record_pos_read += 2; - dsp->record_pos_read &= 0xFFFF; - fallthrough; case 0x6E: /* 4-bit ESPCM input */ if (IS_ESS(dsp)) { - sb_start_dma_i(dsp, 1, 0, ESPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + if (dsp->espcm_mode != ESPCM_4E) + { + fifo_reset(dsp->espcm_fifo); + dsp->espcm_sample_idx = 0; + } + dsp->espcm_mode = ESPCM_4E; + sb_start_dma_i(dsp, 1, 0, ESPCM_4E, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->espcm_sample_idx = 0; - dsp->sbdat2 = (dsp->record_buffer[dsp->record_pos_read] >> 8) ^ 0x80; - dsp->record_pos_read += 2; - dsp->record_pos_read &= 0xFFFF; } break; case 0x75: /* 4-bit ADPCM output with reference */ @@ -1655,12 +1654,15 @@ sb_exec_command(sb_dsp_t *dsp) timer_set_delay_u64(&dsp->irq_timer, (100ULL * TIMER_USEC)); pclog("F2 written\n"); } - } else + } else { sb_irq(dsp, 1); + dsp->ess_irq_generic = true; + } break; case 0xF3: /* Trigger 16-bit IRQ */ sb_dsp_log("Trigger IRQ\n"); sb_irq(dsp, 0); + dsp->ess_irq_generic = true; break; case 0xF8: if (dsp->sb_type < SB16) @@ -1722,6 +1724,12 @@ sb_write(uint16_t a, uint8_t v, void *priv) } dsp->sbreset = v; } + + if (!(v & 2) && (dsp->espcm_fifo_reset & 2)) + { + fifo_reset(dsp->espcm_fifo); + } + dsp->espcm_fifo_reset = v; dsp->uart_midi = 0; dsp->uart_irq = 0; dsp->onebyte_midi = 0; @@ -1752,10 +1760,23 @@ sb_write(uint16_t a, uint8_t v, void *priv) else if (dsp->sb_command == 0x08 && dsp->sb_data_stat == 1 && dsp->sb_data[0] == 0x07) sb_commands[dsp->sb_command] = 2; } - if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { - if (dsp->sb_command <= 0xC0 || dsp->sb_command == 0xC2) { + if (IS_ESS(dsp) && dsp->sb_command >= 0x64 && dsp->sb_command <= 0x6F) + { + if (dsp->sb_subtype == SB_SUBTYPE_ESS_ES1688) + { + sb_commands[dsp->sb_command] = 2; + } + else + { + sb_commands[dsp->sb_command] = 2; + } + } + else if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { + if (dsp->sb_command <= 0xC0 || dsp->sb_command == 0xC2 + || dsp->sb_command == 0xCF) { sb_commands[dsp->sb_command] = 1; - } else if (dsp->sb_command == 0xC6 || dsp->sb_command == 0xC7) { + } else if (dsp->sb_command == 0xC3 || dsp->sb_command == 0xC6 + || dsp->sb_command == 0xC7 || dsp->sb_command == 0xCE) { sb_commands[dsp->sb_command] = 0; } else { sb_commands[dsp->sb_command] = -1; @@ -1787,6 +1808,10 @@ sb_read(uint16_t a, void *priv) uint8_t ret = 0x00; /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ + if ((a & 0xF) == 0x9 || (a & 0xF) == 0xB) + { + pclog("ess: Read-Sequence-Key? port 0x%X", a); + } if (dsp->sb_type < SB16) { /* Exception: ESS AudioDrive does not alias port base+0xf */ @@ -1814,6 +1839,23 @@ sb_read(uint16_t a, void *priv) dsp->busy_count = (dsp->busy_count + 1) & 3; else dsp->busy_count = 0; + if (IS_ESS(dsp)) + { + if (dsp->wb_full || (dsp->busy_count & 2)) { + dsp->wb_full = timer_is_enabled(&dsp->wb_timer); + } + uint8_t busy_flag = dsp->wb_full ? 0x80 : 0x00; + uint8_t data_rdy = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x40; + uint8_t fifo_full = 0; // Unimplemented + uint8_t fifo_empty = 0; + uint8_t fifo_half = 0; + uint8_t irq_generic = dsp->ess_irq_generic ? 0x04 : 0x00; + uint8_t irq_fifohe = 0; // Unimplemented + uint8_t irq_dmactr = dsp->ess_irq_dmactr ? 0x01 : 0x00; + + return busy_flag | data_rdy | fifo_full | fifo_empty + | fifo_half | irq_generic | irq_fifohe | irq_dmactr; + } if (dsp->wb_full || (dsp->busy_count & 2)) { dsp->wb_full = timer_is_enabled(&dsp->wb_timer); if (IS_AZTECH(dsp)) { @@ -1839,6 +1881,7 @@ sb_read(uint16_t a, void *priv) pclog("sb: IRQ acknowledged\n"); } dsp->sb_irq8 = dsp->sb_irq16 = 0; + dsp->ess_irq_generic = dsp->ess_irq_dmactr = false; /* Only bit 7 is defined but aztech diagnostics fail if the others are set. Keep the original behavior to not interfere with what's already working. */ if (IS_AZTECH(dsp)) { sb_dsp_log("SB Read Data Aztech read %02X, Read RP = %d, Read WP = %d\n", (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80, dsp->sb_read_rp, dsp->sb_read_wp); @@ -1891,6 +1934,7 @@ sb_dsp_input_msg(void *priv, uint8_t *msg, uint32_t len) for (uint32_t i = 0; i < len; i++) sb_add_data(dsp, msg[i]); sb_irq(dsp, 1); + dsp->ess_irq_generic = true; } else if (dsp->midi_in_poll) { for (uint32_t i = 0; i < len; i++) sb_add_data(dsp, msg[i]); @@ -1932,6 +1976,7 @@ sb_dsp_irq_poll(void *priv) sb_dsp_t *dsp = (sb_dsp_t *) priv; sb_irq(dsp, 1); + dsp->ess_irq_generic = true; } void @@ -1998,6 +2043,8 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) memset(dsp->sb_asp_ram, 0xff, sizeof(dsp->sb_asp_ram)); + dsp->espcm_fifo = fifo64_init(); + fifo_set_trigger_len(dsp->espcm_fifo, 1); } void @@ -2059,6 +2106,25 @@ sb_ess_finish_dma(sb_dsp_t *dsp) pclog("ess: DMA finished"); } +void +sb_espcm_fifoctl_run(sb_dsp_t *dsp) +{ + if (fifo_get_empty(dsp->espcm_fifo)) + { + while (!fifo_get_full(dsp->espcm_fifo)) + { + int32_t val; + val = dsp->dma_readb(dsp->dma_priv); + dsp->ess_dma_counter++; + fifo_write(val & 0xff, dsp->espcm_fifo); + if (val & DMA_OVER) + { + break; + } + } + } +} + void pollsb(void *priv) { @@ -2262,29 +2328,32 @@ pollsb(void *priv) } if (dsp->espcm_sample_idx == 0) { - dsp->espcm_byte_buffer[0] = dsp->dma_readb(dsp->dma_priv); - dsp->espcm_sample_idx++; - dsp->sb_8_length--; - dsp->ess_dma_counter++; + sb_espcm_fifoctl_run(dsp); + dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; tempi = dsp->espcm_byte_buffer[0] >> 4; } else if (dsp->espcm_sample_idx & 1) { - dsp->espcm_byte_buffer[0] = dsp->dma_readb(dsp->dma_priv); - dsp->espcm_sample_idx++; + sb_espcm_fifoctl_run(dsp); + dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; - dsp->ess_dma_counter++; tempi = dsp->espcm_byte_buffer[0] & 0x0F; } else { - dsp->espcm_sample_idx++; tempi = dsp->espcm_byte_buffer[0] >> 4; } + if (dsp->espcm_sample_idx == 18) + { + dsp->sb_8_length--; + } + + dsp->espcm_sample_idx++; + tempi |= (dsp->espcm_range << 4); data[0] = espcm_range_map[tempi]; dsp->sbdat = data[0] << 8; @@ -2311,11 +2380,8 @@ pollsb(void *priv) } if (dsp->espcm_sample_idx == 0) { - dsp->espcm_byte_buffer[0] = dsp->dma_readb(dsp->dma_priv); - dsp->sb_8_length--; - dsp->ess_dma_counter++; - - dsp->espcm_sample_idx++; + sb_espcm_fifoctl_run(dsp); + dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; tempi = dsp->espcm_byte_buffer[0] >> 4; @@ -2325,9 +2391,9 @@ pollsb(void *priv) { for (tempi = 0; tempi < 4; tempi++) { - dsp->espcm_byte_buffer[tempi] = dsp->dma_readb(dsp->dma_priv); + sb_espcm_fifoctl_run(dsp); + dsp->espcm_byte_buffer[tempi] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; - dsp->ess_dma_counter++; } dsp->espcm_table_index = dsp->espcm_byte_buffer[0] & 0x03; @@ -2346,15 +2412,14 @@ pollsb(void *priv) tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[0]; tempi = espcm3_dpcm_tables[tempi]; dsp->espcm_last_value = tempi; - dsp->espcm_sample_idx++; } else if (dsp->espcm_sample_idx == 11) { for (tempi = 1; tempi < 4; tempi++) { - dsp->espcm_byte_buffer[tempi] = dsp->dma_readb(dsp->dma_priv); + sb_espcm_fifoctl_run(dsp); + dsp->espcm_byte_buffer[tempi] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; - dsp->ess_dma_counter++; } dsp->espcm_code_buffer[0] = (dsp->espcm_byte_buffer[1]) & 0x07; @@ -2369,16 +2434,21 @@ pollsb(void *priv) tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[0]; tempi = espcm3_dpcm_tables[tempi]; dsp->espcm_last_value = tempi; - dsp->espcm_sample_idx++; } else { tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[(dsp->espcm_sample_idx - 1) % 10]; tempi = espcm3_dpcm_tables[tempi]; dsp->espcm_last_value = tempi; - dsp->espcm_sample_idx++; } + if (dsp->espcm_sample_idx == 18) + { + dsp->sb_8_length--; + } + + dsp->espcm_sample_idx++; + tempi |= (dsp->espcm_range << 4); data[0] = espcm_range_map[tempi]; dsp->sbdat = data[0] << 8; @@ -2405,33 +2475,36 @@ pollsb(void *priv) } if (dsp->espcm_sample_idx == 0) { - dsp->espcm_byte_buffer[0] = dsp->dma_readb(dsp->dma_priv); - dsp->espcm_sample_idx++; - dsp->sb_8_length--; - dsp->ess_dma_counter++; + sb_espcm_fifoctl_run(dsp); + dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; dsp->espcm_byte_buffer[0] >>= 5; - tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xF : 0x0; + tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xC : 0x4; dsp->espcm_byte_buffer[0] >>= 1; } else if (dsp->espcm_sample_idx == 3 | dsp->espcm_sample_idx == 11) { - dsp->espcm_byte_buffer[0] = dsp->dma_readb(dsp->dma_priv); - dsp->espcm_sample_idx++; + sb_espcm_fifoctl_run(dsp); + dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; - dsp->ess_dma_counter++; - tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xF : 0x0; + tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xC : 0x4; dsp->espcm_byte_buffer[0] >>= 1; } else { - dsp->espcm_sample_idx++; - tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xF : 0x0; + tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xC : 0x4; dsp->espcm_byte_buffer[0] >>= 1; } + if (dsp->espcm_sample_idx == 18) + { + dsp->sb_8_length--; + } + + dsp->espcm_sample_idx++; + tempi |= (dsp->espcm_range << 4); data[0] = espcm_range_map[tempi]; dsp->sbdat = data[0] << 8; @@ -2465,6 +2538,7 @@ pollsb(void *priv) sb_ess_finish_dma(dsp); } sb_irq(dsp, 1); + dsp->ess_irq_generic = true; } if (dsp->ess_dma_counter > 0xffff) { @@ -2479,6 +2553,7 @@ pollsb(void *priv) if (ESSreg(0xB1) & 0x40) { sb_irq(dsp, 1); + dsp->ess_irq_dmactr = true; pclog("IRQ fired via ESS DMA counter, next IRQ in %d samples\n", sb_ess_get_dma_len(dsp)); } } @@ -2542,6 +2617,7 @@ pollsb(void *priv) sb_ess_finish_dma(dsp); } sb_irq(dsp, 0); + dsp->ess_irq_generic = true; } if (dsp->ess_dma_counter > 0xffff) { @@ -2556,6 +2632,7 @@ pollsb(void *priv) if (ESSreg(0xB1) & 0x40) { sb_irq(dsp, 0); + dsp->ess_irq_dmactr = true; } } uint32_t temp = dsp->ess_dma_counter & 0xffff; @@ -2567,6 +2644,7 @@ pollsb(void *priv) dsp->sb_pausetime--; if (dsp->sb_pausetime < 0) { sb_irq(dsp, 1); + dsp->ess_irq_generic = true; if (!dsp->sb_8_enable) timer_disable(&dsp->output_timer); sb_dsp_log("SB pause over\n"); @@ -2614,7 +2692,7 @@ sb_poll_i(void *priv) dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; break; - case ESPCM_4: + case ESPCM_4E: // I assume the real hardware double-buffers the blocks or something like that. // We're not gonna do that here. dsp->espcm_sample_buffer[dsp->espcm_sample_idx] = dsp->record_buffer[dsp->record_pos_read] >> 8; @@ -2712,6 +2790,7 @@ sb_poll_i(void *priv) sb_ess_finish_dma(dsp); } sb_irq(dsp, 1); + dsp->ess_irq_generic = true; } if (dsp->ess_dma_counter > 0xffff) { @@ -2726,6 +2805,7 @@ sb_poll_i(void *priv) if (ESSreg(0xB1) & 0x40) { sb_irq(dsp, 1); + dsp->ess_irq_dmactr = true; } } uint32_t temp = dsp->ess_dma_counter & 0xffff; @@ -2784,6 +2864,7 @@ sb_poll_i(void *priv) sb_ess_finish_dma(dsp); } sb_irq(dsp, 0); + dsp->ess_irq_generic = true; } if (dsp->ess_dma_counter > 0xffff) { @@ -2798,6 +2879,7 @@ sb_poll_i(void *priv) if (ESSreg(0xB1) & 0x40) { sb_irq(dsp, 0); + dsp->ess_irq_dmactr = true; } } uint32_t temp = dsp->ess_dma_counter & 0xffff; From 56859a9173f4007c2316c87727c2d34ca93065ac Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Tue, 19 Mar 2024 18:48:51 -0300 Subject: [PATCH 756/936] Fixing ESPCM 2/2 --- src/sound/snd_sb_dsp.c | 399 ++++++++++++++++++++++++----------------- 1 file changed, 230 insertions(+), 169 deletions(-) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 34ddb1a50..f94724e68 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -1357,8 +1357,10 @@ sb_exec_command(sb_dsp_t *dsp) case 0x64: /* 4-bit ESPCM output */ if (IS_ESS(dsp)) { - if (dsp->espcm_mode != ESPCM_4) + if (dsp->espcm_mode != ESPCM_4 + || (dsp->sb_8_enable && dsp->sb_8_pause)) { + pclog("ess: ESPCM FIFO reset\n"); fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1370,8 +1372,8 @@ sb_exec_command(sb_dsp_t *dsp) case 0x66: /* 3-bit ESPCM output */ if (IS_ESS(dsp)) { - pclog("ess: Starting espcm3 transfer\n"); - if (dsp->espcm_mode != ESPCM_3) + if (dsp->espcm_mode != ESPCM_3 + || (dsp->sb_8_enable && dsp->sb_8_pause)) { pclog("ess: ESPCM FIFO reset\n"); fifo_reset(dsp->espcm_fifo); @@ -1385,8 +1387,8 @@ sb_exec_command(sb_dsp_t *dsp) case 0x6C: /* 1-bit ESPCM output */ if (IS_ESS(dsp)) { - pclog("ess: Starting espcm1 transfer\n"); - if (dsp->espcm_mode != ESPCM_1) + if (dsp->espcm_mode != ESPCM_1 + || (dsp->sb_8_enable && dsp->sb_8_pause)) { pclog("ess: ESPCM FIFO reset\n"); fifo_reset(dsp->espcm_fifo); @@ -1400,8 +1402,10 @@ sb_exec_command(sb_dsp_t *dsp) case 0x6E: /* 4-bit ESPCM input */ if (IS_ESS(dsp)) { - if (dsp->espcm_mode != ESPCM_4E) + if (dsp->espcm_mode != ESPCM_4E + || (dsp->sb_8_enable && dsp->sb_8_pause)) { + pclog("ess: ESPCM FIFO reset\n"); fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -2109,7 +2113,7 @@ sb_ess_finish_dma(sb_dsp_t *dsp) void sb_espcm_fifoctl_run(sb_dsp_t *dsp) { - if (fifo_get_empty(dsp->espcm_fifo)) + if (fifo_get_empty(dsp->espcm_fifo) && !dsp->sb_8_pause) { while (!fifo_get_full(dsp->espcm_fifo)) { @@ -2134,191 +2138,212 @@ pollsb(void *priv) int data[2]; timer_advance_u64(&dsp->output_timer, dsp->sblatcho); - if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && dsp->sb_8_output) { + if (dsp->sb_8_enable && dsp->sb_pausetime < 0 && dsp->sb_8_output) { sb_dsp_update(dsp); switch (dsp->sb_8_format) { case 0x00: /* Mono unsigned */ - data[0] = dsp->dma_readb(dsp->dma_priv); - /* Needed to prevent clicking in Worms, which programs the DSP to - auto-init DMA but programs the DMA controller to single cycle */ - if (data[0] == DMA_NODATA) - break; - dsp->sbdat = (data[0] ^ 0x80) << 8; - if (dsp->stereo) { - sb_dsp_log("pollsb: Mono unsigned, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); - if (dsp->sbleftright) - dsp->sbdatl = dsp->sbdat; - else - dsp->sbdatr = dsp->sbdat; - dsp->sbleftright = !dsp->sbleftright; - } else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; - dsp->sb_8_length--; - dsp->ess_dma_counter++; + if (!dsp->sb_8_pause) + { + data[0] = dsp->dma_readb(dsp->dma_priv); + /* Needed to prevent clicking in Worms, which programs the DSP to + auto-init DMA but programs the DMA controller to single cycle */ + if (data[0] == DMA_NODATA) + break; + dsp->sbdat = (data[0] ^ 0x80) << 8; + if (dsp->stereo) { + sb_dsp_log("pollsb: Mono unsigned, dsp->stereo, %s channel, %04X\n", + dsp->sbleftright ? "left" : "right", dsp->sbdat); + if (dsp->sbleftright) + dsp->sbdatl = dsp->sbdat; + else + dsp->sbdatr = dsp->sbdat; + dsp->sbleftright = !dsp->sbleftright; + } else + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + dsp->sb_8_length--; + dsp->ess_dma_counter++; + } break; case 0x10: /* Mono signed */ - data[0] = dsp->dma_readb(dsp->dma_priv); - if (data[0] == DMA_NODATA) - break; - dsp->sbdat = data[0] << 8; - if (dsp->stereo) { - sb_dsp_log("pollsb: Mono signed, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", data[0], dsp->sbdat); - if (dsp->sbleftright) - dsp->sbdatl = dsp->sbdat; - else - dsp->sbdatr = dsp->sbdat; - dsp->sbleftright = !dsp->sbleftright; - } else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; - dsp->sb_8_length--; - dsp->ess_dma_counter++; + if (!dsp->sb_8_pause) + { + data[0] = dsp->dma_readb(dsp->dma_priv); + if (data[0] == DMA_NODATA) + break; + dsp->sbdat = data[0] << 8; + if (dsp->stereo) { + sb_dsp_log("pollsb: Mono signed, dsp->stereo, %s channel, %04X\n", + dsp->sbleftright ? "left" : "right", data[0], dsp->sbdat); + if (dsp->sbleftright) + dsp->sbdatl = dsp->sbdat; + else + dsp->sbdatr = dsp->sbdat; + dsp->sbleftright = !dsp->sbleftright; + } else + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + dsp->sb_8_length--; + dsp->ess_dma_counter++; + } break; case 0x20: /* Stereo unsigned */ - data[0] = dsp->dma_readb(dsp->dma_priv); - data[1] = dsp->dma_readb(dsp->dma_priv); - if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) - break; - dsp->sbdatl = (data[0] ^ 0x80) << 8; - dsp->sbdatr = (data[1] ^ 0x80) << 8; - dsp->sb_8_length -= 2; - dsp->ess_dma_counter += 2; + if (!dsp->sb_8_pause) + { + data[0] = dsp->dma_readb(dsp->dma_priv); + data[1] = dsp->dma_readb(dsp->dma_priv); + if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) + break; + dsp->sbdatl = (data[0] ^ 0x80) << 8; + dsp->sbdatr = (data[1] ^ 0x80) << 8; + dsp->sb_8_length -= 2; + dsp->ess_dma_counter += 2; + } break; case 0x30: /* Stereo signed */ - data[0] = dsp->dma_readb(dsp->dma_priv); - data[1] = dsp->dma_readb(dsp->dma_priv); - if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) - break; - dsp->sbdatl = data[0] << 8; - dsp->sbdatr = data[1] << 8; - dsp->sb_8_length -= 2; - dsp->ess_dma_counter += 2; + if (!dsp->sb_8_pause) + { + data[0] = dsp->dma_readb(dsp->dma_priv); + data[1] = dsp->dma_readb(dsp->dma_priv); + if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) + break; + dsp->sbdatl = data[0] << 8; + dsp->sbdatr = data[1] << 8; + dsp->sb_8_length -= 2; + dsp->ess_dma_counter += 2; + } break; case ADPCM_4: - if (dsp->sbdacpos) - tempi = (dsp->sbdat2 & 0xF) + dsp->sbstep; - else - tempi = (dsp->sbdat2 >> 4) + dsp->sbstep; - if (tempi < 0) - tempi = 0; - if (tempi > 63) - tempi = 63; - - ref = dsp->sbref + scaleMap4[tempi]; - if (ref > 0xff) - dsp->sbref = 0xff; - else if (ref < 0x00) - dsp->sbref = 0x00; - else - dsp->sbref = ref; - - dsp->sbstep = (dsp->sbstep + adjustMap4[tempi]) & 0xff; - dsp->sbdat = (dsp->sbref ^ 0x80) << 8; - - dsp->sbdacpos++; - - if (dsp->sbdacpos >= 2) { - dsp->sbdacpos = 0; - dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); - dsp->sb_8_length--; - dsp->ess_dma_counter++; - } - - if (dsp->stereo) { - sb_dsp_log("pollsb: ADPCM 4, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); - if (dsp->sbleftright) - dsp->sbdatl = dsp->sbdat; + if (!dsp->sb_8_pause) + { + if (dsp->sbdacpos) + tempi = (dsp->sbdat2 & 0xF) + dsp->sbstep; else - dsp->sbdatr = dsp->sbdat; - dsp->sbleftright = !dsp->sbleftright; - } else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + tempi = (dsp->sbdat2 >> 4) + dsp->sbstep; + if (tempi < 0) + tempi = 0; + if (tempi > 63) + tempi = 63; + + ref = dsp->sbref + scaleMap4[tempi]; + if (ref > 0xff) + dsp->sbref = 0xff; + else if (ref < 0x00) + dsp->sbref = 0x00; + else + dsp->sbref = ref; + + dsp->sbstep = (dsp->sbstep + adjustMap4[tempi]) & 0xff; + dsp->sbdat = (dsp->sbref ^ 0x80) << 8; + + dsp->sbdacpos++; + + if (dsp->sbdacpos >= 2) { + dsp->sbdacpos = 0; + dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + } + + if (dsp->stereo) { + sb_dsp_log("pollsb: ADPCM 4, dsp->stereo, %s channel, %04X\n", + dsp->sbleftright ? "left" : "right", dsp->sbdat); + if (dsp->sbleftright) + dsp->sbdatl = dsp->sbdat; + else + dsp->sbdatr = dsp->sbdat; + dsp->sbleftright = !dsp->sbleftright; + } else + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + } break; case ADPCM_26: - if (!dsp->sbdacpos) - tempi = (dsp->sbdat2 >> 5) + dsp->sbstep; - else if (dsp->sbdacpos == 1) - tempi = ((dsp->sbdat2 >> 2) & 7) + dsp->sbstep; - else - tempi = ((dsp->sbdat2 << 1) & 7) + dsp->sbstep; - - if (tempi < 0) - tempi = 0; - if (tempi > 39) - tempi = 39; - - ref = dsp->sbref + scaleMap26[tempi]; - if (ref > 0xff) - dsp->sbref = 0xff; - else if (ref < 0x00) - dsp->sbref = 0x00; - else - dsp->sbref = ref; - dsp->sbstep = (dsp->sbstep + adjustMap26[tempi]) & 0xff; - - dsp->sbdat = (dsp->sbref ^ 0x80) << 8; - - dsp->sbdacpos++; - if (dsp->sbdacpos >= 3) { - dsp->sbdacpos = 0; - dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); - dsp->sb_8_length--; - dsp->ess_dma_counter++; - } - - if (dsp->stereo) { - sb_dsp_log("pollsb: ADPCM 26, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); - if (dsp->sbleftright) - dsp->sbdatl = dsp->sbdat; + if (!dsp->sb_8_pause) + { + if (!dsp->sbdacpos) + tempi = (dsp->sbdat2 >> 5) + dsp->sbstep; + else if (dsp->sbdacpos == 1) + tempi = ((dsp->sbdat2 >> 2) & 7) + dsp->sbstep; else - dsp->sbdatr = dsp->sbdat; - dsp->sbleftright = !dsp->sbleftright; - } else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + tempi = ((dsp->sbdat2 << 1) & 7) + dsp->sbstep; + + if (tempi < 0) + tempi = 0; + if (tempi > 39) + tempi = 39; + + ref = dsp->sbref + scaleMap26[tempi]; + if (ref > 0xff) + dsp->sbref = 0xff; + else if (ref < 0x00) + dsp->sbref = 0x00; + else + dsp->sbref = ref; + dsp->sbstep = (dsp->sbstep + adjustMap26[tempi]) & 0xff; + + dsp->sbdat = (dsp->sbref ^ 0x80) << 8; + + dsp->sbdacpos++; + if (dsp->sbdacpos >= 3) { + dsp->sbdacpos = 0; + dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + } + + if (dsp->stereo) { + sb_dsp_log("pollsb: ADPCM 26, dsp->stereo, %s channel, %04X\n", + dsp->sbleftright ? "left" : "right", dsp->sbdat); + if (dsp->sbleftright) + dsp->sbdatl = dsp->sbdat; + else + dsp->sbdatr = dsp->sbdat; + dsp->sbleftright = !dsp->sbleftright; + } else + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + } break; case ADPCM_2: - tempi = ((dsp->sbdat2 >> ((3 - dsp->sbdacpos) * 2)) & 3) + dsp->sbstep; - if (tempi < 0) - tempi = 0; - if (tempi > 23) - tempi = 23; + if (!dsp->sb_8_pause) + { + tempi = ((dsp->sbdat2 >> ((3 - dsp->sbdacpos) * 2)) & 3) + dsp->sbstep; + if (tempi < 0) + tempi = 0; + if (tempi > 23) + tempi = 23; - ref = dsp->sbref + scaleMap2[tempi]; - if (ref > 0xff) - dsp->sbref = 0xff; - else if (ref < 0x00) - dsp->sbref = 0x00; - else - dsp->sbref = ref; - dsp->sbstep = (dsp->sbstep + adjustMap2[tempi]) & 0xff; - - dsp->sbdat = (dsp->sbref ^ 0x80) << 8; - - dsp->sbdacpos++; - if (dsp->sbdacpos >= 4) { - dsp->sbdacpos = 0; - dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); - dsp->sb_8_length--; - dsp->ess_dma_counter++; - } - - if (dsp->stereo) { - sb_dsp_log("pollsb: ADPCM 2, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); - if (dsp->sbleftright) - dsp->sbdatl = dsp->sbdat; + ref = dsp->sbref + scaleMap2[tempi]; + if (ref > 0xff) + dsp->sbref = 0xff; + else if (ref < 0x00) + dsp->sbref = 0x00; else - dsp->sbdatr = dsp->sbdat; - dsp->sbleftright = !dsp->sbleftright; - } else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + dsp->sbref = ref; + dsp->sbstep = (dsp->sbstep + adjustMap2[tempi]) & 0xff; + + dsp->sbdat = (dsp->sbref ^ 0x80) << 8; + + dsp->sbdacpos++; + if (dsp->sbdacpos >= 4) { + dsp->sbdacpos = 0; + dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); + dsp->sb_8_length--; + dsp->ess_dma_counter++; + } + + if (dsp->stereo) { + sb_dsp_log("pollsb: ADPCM 2, dsp->stereo, %s channel, %04X\n", + dsp->sbleftright ? "left" : "right", dsp->sbdat); + if (dsp->sbleftright) + dsp->sbdatl = dsp->sbdat; + else + dsp->sbdatr = dsp->sbdat; + dsp->sbleftright = !dsp->sbleftright; + } else + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + } break; case ESPCM_4: @@ -2329,6 +2354,10 @@ pollsb(void *priv) if (dsp->espcm_sample_idx == 0) { sb_espcm_fifoctl_run(dsp); + if (fifo_get_empty(dsp->espcm_fifo)) + { + break; + } dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; @@ -2337,6 +2366,10 @@ pollsb(void *priv) else if (dsp->espcm_sample_idx & 1) { sb_espcm_fifoctl_run(dsp); + if (fifo_get_empty(dsp->espcm_fifo)) + { + break; + } dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; @@ -2381,6 +2414,10 @@ pollsb(void *priv) if (dsp->espcm_sample_idx == 0) { sb_espcm_fifoctl_run(dsp); + if (fifo_get_empty(dsp->espcm_fifo)) + { + break; + } dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; @@ -2392,9 +2429,17 @@ pollsb(void *priv) for (tempi = 0; tempi < 4; tempi++) { sb_espcm_fifoctl_run(dsp); + if (fifo_get_empty(dsp->espcm_fifo)) + { + break; + } dsp->espcm_byte_buffer[tempi] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; } + if (tempi < 4) + { + break; + } dsp->espcm_table_index = dsp->espcm_byte_buffer[0] & 0x03; @@ -2418,9 +2463,17 @@ pollsb(void *priv) for (tempi = 1; tempi < 4; tempi++) { sb_espcm_fifoctl_run(dsp); + if (fifo_get_empty(dsp->espcm_fifo)) + { + break; + } dsp->espcm_byte_buffer[tempi] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; } + if (tempi < 4) + { + break; + } dsp->espcm_code_buffer[0] = (dsp->espcm_byte_buffer[1]) & 0x07; dsp->espcm_code_buffer[1] = (dsp->espcm_byte_buffer[1] >> 3) & 0x07; @@ -2476,6 +2529,10 @@ pollsb(void *priv) if (dsp->espcm_sample_idx == 0) { sb_espcm_fifoctl_run(dsp); + if (fifo_get_empty(dsp->espcm_fifo)) + { + break; + } dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; @@ -2486,6 +2543,10 @@ pollsb(void *priv) else if (dsp->espcm_sample_idx == 3 | dsp->espcm_sample_idx == 11) { sb_espcm_fifoctl_run(dsp); + if (fifo_get_empty(dsp->espcm_fifo)) + { + break; + } dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; From a776a54b55b6ad5fc25a1ff89c40f6e8c811f0a1 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Thu, 21 Mar 2024 15:11:08 -0400 Subject: [PATCH 757/936] network: Modify the PCAP filter to allow multicast packets --- src/network/net_pcap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index 16caaec7e..852191c55 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -500,7 +500,7 @@ net_pcap_init(const netcard_t *card, const uint8_t *mac_addr, void *priv, char * pcap_log("PCAP: installing filter for MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); sprintf(filter_exp, - "( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", + "( ((ether broadcast) or (ether multicast) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5], mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); if (f_pcap_compile(pcap->pcap, &fp, filter_exp, 0, 0xffffffff) != -1) { From 778cd2bc4686b40d75af3e46cb7f6f2c8e2b7ce2 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 21 Mar 2024 22:00:48 +0100 Subject: [PATCH 758/936] Refactor PAS16 code (Audio/MIDI/PIT) This should make it work once and for all after many years of being broken/not working. --- src/include/86box/pit.h | 3 +- src/pit.c | 40 ++-- src/sound/snd_pas16.c | 478 ++++++++++++++++++++-------------------- 3 files changed, 261 insertions(+), 260 deletions(-) diff --git a/src/include/86box/pit.h b/src/include/86box/pit.h index 078694633..d9bce667d 100644 --- a/src/include/86box/pit.h +++ b/src/include/86box/pit.h @@ -56,6 +56,8 @@ typedef struct ctr_t { }; uint32_t l; + uint32_t lback; + uint32_t lback2; void (*load_func)(uint8_t new_m, int new_count); void (*out_func)(int new_out, int old_out, void *priv); @@ -70,7 +72,6 @@ typedef struct PIT { uint8_t ctrl; void *dev_priv; - void (*dev_timer)(void *priv); } pit_t; extern pit_t *ext_pit; diff --git a/src/pit.c b/src/pit.c index 4f64d40c1..20baf3f66 100644 --- a/src/pit.c +++ b/src/pit.c @@ -103,6 +103,7 @@ ctr_set_out(ctr_t *ctr, int out, void *priv) if (ctr->out_func != NULL) ctr->out_func(out, ctr->out, pit); + ctr->out = out; } @@ -354,7 +355,7 @@ ctr_load(ctr_t *ctr) if (ctr->load_func != NULL) ctr->load_func(ctr->m, ctr->l ? ctr->l : 0x10000); - pclog("Counter loaded, state = %i, gate = %i, latch = %i\n", ctr->state, ctr->gate, ctr->latch); + pit_log("Counter loaded, state = %i, gate = %i, latch = %i\n", ctr->state, ctr->gate, ctr->latch); } static __inline void @@ -393,7 +394,7 @@ ctr_latch_count(ctr_t *ctr) break; } - pclog("rm = %x, latched counter = %04X\n", ctr->rm & 0x03, ctr->rl & 0xffff); + pit_log("rm = %x, latched counter = %04X\n", ctr->rm & 0x03, ctr->rl & 0xffff); } uint16_t @@ -522,9 +523,6 @@ pit_timer_over(void *priv) for (uint8_t i = 0; i < 3; i++) pit_ctr_set_clock_common(&dev->counters[i], dev->clock, dev); - if (dev->dev_timer != NULL) - dev->dev_timer(dev); - timer_advance_u64(&dev->callback_timer, PITCONST >> 1ULL); } @@ -536,7 +534,7 @@ pit_write(uint16_t addr, uint8_t val, void *priv) ctr_t *ctr; if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) - pclog("[%04X:%08X] pit_write(%04X, %02X, %08X)\n", CS, cpu_state.pc, addr, val, priv); + pit_log("[%04X:%08X] pit_write(%04X, %02X, %08X)\n", CS, cpu_state.pc, addr, val, priv); switch (addr & 3) { case 3: /* control */ @@ -553,7 +551,7 @@ pit_write(uint16_t addr, uint8_t val, void *priv) if (val & 8) ctr_latch_count(&dev->counters[2]); if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) - pclog("PIT %i: Initiated readback command\n", t); + pit_log("PIT %i: Initiated readback command\n", t); } if (!(val & 0x10)) { if (val & 2) @@ -571,7 +569,7 @@ pit_write(uint16_t addr, uint8_t val, void *priv) if (!(dev->ctrl & 0x30)) { ctr_latch_count(ctr); if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) - pclog("PIT %i: Initiated latched read, %i bytes latched\n", + pit_log("PIT %i: Initiated latched read, %i bytes latched\n", t, ctr->latched); } else { ctr->ctrl = val; @@ -585,12 +583,12 @@ pit_write(uint16_t addr, uint8_t val, void *priv) ctr->state = 0; if (ctr->latched) { if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) - pclog("PIT %i: Reload while counter is latched\n", t); + pit_log("PIT %i: Reload while counter is latched\n", t); ctr->rl--; } if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) - pclog("PIT %i: M = %i, RM/WM = %i, State = %i, Out = %i\n", t, ctr->m, ctr->rm, ctr->state, ctr->out); + pit_log("PIT %i: M = %i, RM/WM = %i, State = %i, Out = %i\n", t, ctr->m, ctr->rm, ctr->state, ctr->out); } } break; @@ -606,12 +604,20 @@ pit_write(uint16_t addr, uint8_t val, void *priv) break; case 1: ctr->l = val; + ctr->lback = ctr->l; + ctr->lback2 = ctr->l; + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + pit_log("PIT %i (1): Written byte %02X, latch now %04X\n", t, val, ctr->l); if (ctr->m == 0) ctr_set_out(ctr, 0, dev); ctr_load(ctr); break; case 2: ctr->l = (val << 8); + ctr->lback = ctr->l; + ctr->lback2 = ctr->l; + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + pit_log("PIT %i (2): Written byte %02X, latch now %04X\n", t, val, ctr->l); if (ctr->m == 0) ctr_set_out(ctr, 0, dev); ctr_load(ctr); @@ -620,13 +626,17 @@ pit_write(uint16_t addr, uint8_t val, void *priv) case 0x83: if (ctr->wm & 0x80) { ctr->l = (ctr->l & 0x00ff) | (val << 8); + ctr->lback = ctr->l; + ctr->lback2 = ctr->l; if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) - pclog("PIT %i: Written high byte %02X, latch now %04X\n", t, val, ctr->l); + pit_log("PIT %i (0x83): Written high byte %02X, latch now %04X\n", t, val, ctr->l); ctr_load(ctr); } else { ctr->l = (ctr->l & 0xff00) | val; + ctr->lback = ctr->l; + ctr->lback2 = ctr->l; if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) - pclog("PIT %i: Written low byte %02X, latch now %04X\n", t, val, ctr->l); + pit_log("PIT %i (3): Written low byte %02X, latch now %04X\n", t, val, ctr->l); if (ctr->m == 0) { ctr->state = 0; ctr_set_out(ctr, 0, dev); @@ -763,7 +773,7 @@ pit_read(uint16_t addr, void *priv) } if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) - pclog("[%04X:%08X] pit_read(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret); + pit_log("[%04X:%08X] pit_read(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret); return ret; } @@ -890,15 +900,13 @@ pit_init(const device_t *info) } dev->flags = info->local; + dev->dev_priv = NULL; if (!(dev->flags & PIT_EXT_IO)) { io_sethandler((dev->flags & PIT_SECONDARY) ? 0x0048 : 0x0040, 0x0004, pit_read, NULL, NULL, pit_write, NULL, NULL, dev); } - dev->dev_priv = NULL; - dev->dev_timer = NULL; - return dev; } diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 32879cd1e..d8187cf0f 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -137,25 +137,29 @@ typedef struct pas16_t { uint8_t midi_ctrl; uint8_t midi_stat; uint8_t midi_data; - uint8_t midi_fifo[16]; + uint8_t fifo_stat; + int midi_r; + int midi_w; + int midi_uart_out; + int midi_uart_in; + uint8_t midi_queue[256]; + int sysex; fm_drv_t opl; sb_dsp_t dsp; mpu_t *mpu; + pc_timer_t timer; int16_t pcm_buffer[2][SOUNDBUFLEN]; int pos; - int midi_uart_out; - pit_t *pit; } pas16_t; static void pas16_update(pas16_t *pas16); static int pas16_dmas[8] = { 4, 1, 2, 3, 0, 5, 6, 7 }; -static int pas16_irqs[16] = { 0, 2, 3, 4, 5, 6, 7, 10, 11, 12, 14, 15, 0, 0, 0, 0 }; static int pas16_sb_irqs[8] = { 0, 2, 3, 5, 7, 10, 11, 12 }; static int pas16_sb_dmas[8] = { 0, 1, 2, 3 }; @@ -167,7 +171,8 @@ enum { enum { PAS16_PCM_MONO = 0x20, - PAS16_PCM_ENA = 0x40 + PAS16_PCM_ENA = 0x40, + PAS16_PCM_DMA_ENA = 0x80 }; enum { @@ -197,124 +202,51 @@ pas16_log(const char *fmt, ...) # define pas16_log(fmt, ...) #endif +static uint8_t +pas16_in(uint16_t port, void *priv); static void -pas16_update_midi_irqs(pas16_t *pas16) +pas16_out(uint16_t port, uint8_t val, void *priv); + +static void +pas16_update_irq(pas16_t *pas16) { - int irq = 0; - - pas16->irq_stat &= ~PAS16_INT_MIDI; - - if ((pas16->uart_status & 0x18) || (dev->uart_status & 0x04)) { + if (pas16->midi_uart_out && (pas16->midi_stat & 0x18)) { pas16->irq_stat |= PAS16_INT_MIDI; - irq = 1; + if (pas16->irq_ena & PAS16_INT_MIDI) + picint(1 << pas16->irq); } - - if (irq) - picint(1 << pas16->irq); - else - picintc(1 << pas16->irq); -} - -static void -pas16_update_tx_irq(pas16_t *pas16) -{ - pas16->uart_status &= ~0x18; - - if ((pas16->irq_ena & PAS16_INT_MIDI) && (pas16->uart_ctrl & 0x18)) - pas16->uart_status |= 0x18; - - pas16_update_midi_irqs(pas16); -} - -static void -pas16_update_rx_irq(pas16_t *pas16) -{ - pas16->uart_status &= ~0x04; - - if ((pas16->irq_ena & PAS16_INT_MIDI) && (pas16->uart_ctrl & 0x04)) - pas16->uart_status |= 0x04; - - pas16_update_midi_irqs(pas16); -} - -static void -pas16_scan_fifo(pas16_t *pas16) -{ - if (pas16->read_fifo_pos != pas16->write_fifo_pos) { - pas16->uart_data = pas16->uart_fifo[pas16->read_fifo_pos]; - pas16->read_fifo_pos = (pas16->read_fifo_pos + 1) & 0x0f; - - es1371_set_rx_irq(pas16, 1); - } else - es1371_set_rx_irq(pas16, 0); -} - -static void -es1371_write_fifo(es1371_t *dev, uint8_t val) -{ - if (dev->write_fifo_pos < 16) { - dev->uart_fifo[dev->write_fifo_pos] = val | UART_FIFO_BYTE_VALID; - dev->write_fifo_pos = (dev->write_fifo_pos + 1) & 0x0f; + if (pas16->midi_uart_in && (pas16->midi_stat & 0x04)) { + pas16->irq_stat |= PAS16_INT_MIDI; + if (pas16->irq_ena & PAS16_INT_MIDI) + picint(1 << pas16->irq); } } -static void -es1371_reset_fifo(es1371_t *dev) -{ - for (uint8_t i = 0; i < 16; i++) - dev->uart_fifo[i] = 0x00000000; - - dev->read_fifo_pos = dev->write_fifo_pos = 0; - - es1371_set_rx_irq(dev, 0); -} - -static void -pas16_reset(void *priv) -{ - pas16_t *pas16 = (pas16_t *) priv; - - pas16->uart_status = 0xff; - pas16->uart_ctrl = 0x00; - - for (uint8_t i = 0; i < 16; i++) - pas16->uart_fifo[i] = 0x00; - - pas16_set_tx_irq(pas16, 0); - - pas16_reset_fifo(pas16); - - pas16_update_midi_irqs(pas16); -} - static uint8_t pas16_in(uint16_t port, void *priv) { pas16_t *pas16 = (pas16_t *) priv; uint8_t temp = 0xff; - switch ((port - pas16->base) + 0x388) { + switch (port) { case 0x388: case 0x389: case 0x38a: case 0x38b: - temp = pas16->opl.read((port - pas16->base) + 0x388, pas16->opl.priv); + temp = pas16->opl.read(port, pas16->opl.priv); break; case 0xb88: temp = pas16->audio_mixer; break; - case 0xb89: temp = pas16->irq_stat; break; - case 0xb8a: temp = pas16->audiofilt; break; - case 0xb8b: - temp = pas16->irq_ena & ~0xe0; - temp |= 0x01; + temp = pas16->irq_ena | 0x20; + pas16_log("IRQ Mask read=%02x.\n", temp); break; case 0xf8a: @@ -322,19 +254,36 @@ pas16_in(uint16_t port, void *priv) break; case 0x1789: - temp = 0; + case 0x178b: + temp = pas16->midi_ctrl; break; case 0x178a: - temp = pas16->uart_data; - pas16_set_rx_irq(pas16, 0); + case 0x1b8a: + temp = 0; + if (pas16->midi_uart_in) { + if ((pas16->midi_data == 0xaa) && (pas16->midi_ctrl & 0x04)) + temp = pas16->midi_data; + else { + temp = pas16->midi_queue[pas16->midi_r]; + if (pas16->midi_r != pas16->midi_w) { + pas16->midi_r++; + pas16->midi_r &= 0xff; + } + } + pas16->midi_stat &= ~0x04; + pas16_update_irq(pas16); + } break; case 0x1b88: - temp = pas16->uart_status; + temp = pas16->midi_stat; + break; + case 0x1b89: + temp = pas16->fifo_stat; break; case 0x2789: /*Board revision*/ - temp = 0; + temp = 0x00; break; case 0x7f89: @@ -347,19 +296,18 @@ pas16_in(uint16_t port, void *priv) case 0x8389: temp = pas16->sys_conf_2; break; - case 0x838b: + case 0x838a: temp = pas16->sys_conf_3; break; - case 0x838c: + case 0x838b: temp = pas16->sys_conf_4; break; case 0xbf88: temp = pas16->waitstates; break; - case 0xef8b: - temp = 0x0c; + temp = 0x00; break; case 0xf388: @@ -367,9 +315,11 @@ pas16_in(uint16_t port, void *priv) break; case 0xf389: temp = pas16->io_conf_2; + pas16_log("pas16_in : set PAS DMA %i\n", pas16->dma); break; case 0xf38a: temp = pas16->io_conf_3; + pas16_log("pas16_in : set PAS IRQ %i\n", pas16->irq); break; case 0xf38b: temp = pas16->io_conf_4; @@ -396,7 +346,7 @@ pas16_in(uint16_t port, void *priv) default: break; } - pclog("pas16_in : port %04X return %02X %04X:%04X\n", port, temp, CS, cpu_state.pc); + pas16_log("pas16_in : port %04X return %02X %04X:%04X\n", port, temp, CS, cpu_state.pc); return temp; } @@ -405,30 +355,27 @@ pas16_out(uint16_t port, uint8_t val, void *priv) { pas16_t *pas16 = (pas16_t *) priv; pit_t *pit = (pit_t *) pas16->pit; - pclog("pas16_out : port %04X val %02X %04X:%04X\n", port, val, CS, cpu_state.pc); - switch ((port - pas16->base) + 0x388) { + pas16_log("pas16_out : port %04X val %02X %04X:%04X\n", port, val, CS, cpu_state.pc); + switch (port) { case 0x388: case 0x389: case 0x38a: case 0x38b: - pas16->opl.write((port - pas16->base) + 0x388, val, pas16->opl.priv); + pas16->opl.write(port, val, pas16->opl.priv); break; case 0xb88: pas16->audio_mixer = val; break; - case 0xb89: pas16->irq_stat &= ~val; break; - case 0xb8a: pas16_update(pas16); pas16->audiofilt = val; break; - case 0xb8b: - pas16->irq_ena = val; + pas16->irq_ena = val & 0x1f; break; case 0xf88: @@ -448,29 +395,33 @@ pas16_out(uint16_t port, uint8_t val, void *priv) case 0x1789: case 0x178b: - pas16->uart_ctrl = val; - + pas16->midi_ctrl = val; if ((val & 0x60) == 0x60) { - /* Reset TX */ - pas16_set_tx_irq(pas16, 1); + pas16->midi_uart_out = 0; + pas16->midi_uart_in = 0; + } else if (val & 0x18) { + pas16->midi_uart_out = 1; + } else if (val & 0x04) + pas16->midi_uart_in = 1; + else + pas16->midi_uart_out = 1; - /* Software reset */ - pas16_reset_fifo(pas16); - } else { - pas16_set_tx_irq(pas16, 1); - - pas16_update_tx_irq(pas16); - pas16_update_rx_irq(pas16); - } + pas16_update_irq(pas16); break; - case 0x178a: - midi_raw_out_byte(val); - pas16_set_tx_irq(pas16, 1); + case 0x1b8a: + pas16->midi_data = val; + pas16_log("UART OUT=%d.\n", pas16->midi_uart_out); + if (pas16->midi_uart_out) + midi_raw_out_byte(val); break; case 0x1b88: - pas16->uart_status = val; + pas16->midi_stat = val; + pas16_update_irq(pas16); + break; + case 0x1b89: + pas16->fifo_stat = val; break; case 0x7f89: @@ -478,9 +429,10 @@ pas16_out(uint16_t port, uint8_t val, void *priv) break; case 0x8388: - if ((val & 0x80) && !(pas16->sys_conf_1 & 0x80)) { - pclog("Reset.\n"); - pas16_reset(pas16); + if ((val & 0xc0) && !(pas16->sys_conf_1 & 0xc0)) { + pas16_log("Reset.\n"); + picintc(1 << pas16->irq); + val = 0x00; } pas16->sys_conf_1 = val; break; @@ -504,12 +456,19 @@ pas16_out(uint16_t port, uint8_t val, void *priv) case 0xf389: pas16->io_conf_2 = val; pas16->dma = pas16_dmas[val & 0x7]; - pclog("pas16_out : set PAS DMA %i\n", pas16->dma); + pas16_log("pas16_out : set PAS DMA %i\n", pas16->dma); break; case 0xf38a: pas16->io_conf_3 = val; - pas16->irq = pas16_irqs[val & 0xf]; - pclog("pas16_out : set PAS IRQ %i\n", pas16->irq); + pas16->irq = val & 0x0f; + if (pas16->irq <= 6) { + pas16->irq++; + } else if ((pas16->irq > 6) && (pas16->irq < 0x0b)) + pas16->irq += 3; + else + pas16->irq += 4; + + pas16_log("pas16_out : set PAS IRQ %i, val=%02x\n", pas16->irq, val & 0x0f); break; case 0xf38b: pas16->io_conf_4 = val; @@ -538,32 +497,12 @@ pas16_out(uint16_t port, uint8_t val, void *priv) pas16->sb_irqdma = val; sb_dsp_setirq(&pas16->dsp, pas16_sb_irqs[(val >> 3) & 7]); sb_dsp_setdma8(&pas16->dsp, pas16_sb_dmas[(val >> 6) & 3]); - pas16_log("pas16_out : set SB IRQ %i DMA %i\n", pas16_sb_irqs[(val >> 3) & 7], pas16_sb_dmas[(val >> 6) & 3]); + pas16_log("pas16_out : set SB IRQ %i DMA %i.\n", pas16_sb_irqs[(val >> 3) & 7], pas16_sb_dmas[(val >> 6) & 3]); break; default: - pclog("pas16_out : unknown %04X\n", port); + pas16_log("pas16_out : unknown %04X\n", port); } -#if 0 - if (cpu_state.pc == 0x80048CF3) { - if (output) - fatal("here\n"); - output = 3; - } -#endif -} - - -static void -pas16_scan_fifo(pas16_t *pas16) -{ - if (pas16->read_fifo_pos != pas16->write_fifo_pos) { - pas16->uart_data = pas16->uart_fifo[pas16->read_fifo_pos]; - pas16->read_fifo_pos = (pas16->read_fifo_pos + 1) & 7; - - pas16_set_rx_irq(pas16, 1); - } else - pas16_set_rx_irq(pas16, 0); } static uint8_t @@ -572,39 +511,49 @@ pas16_readdma(pas16_t *pas16) return dma_channel_read(pas16->dma); } - static void pas16_pcm_poll(void *priv) { - pit_t *pit = (pit_t *)priv; - pas16_t *pas16 = (pas16_t *) pit->dev_priv; + pas16_t *pas16 = (pas16_t *) priv; + pit_t *pit = (pit_t *) pas16->pit; + int data; uint16_t temp = 0x0000; - pas16_update(pas16); - if (pit->counters[0].m & 2) { - if (pit->counters[0].l) - timer_advance_u64(&pit->callback_timer, pit->counters[0].l * (PITCONST << 1ULL)); - else { - timer_advance_u64(&pit->callback_timer, 0x10000 * (PITCONST << 1ULL)); + if (pit->counters[0].m & 0x02) { + if (pit->counters[0].l & 0xff) { + if (pas16->dma >= 5) + timer_advance_u64(&pas16->timer, (pit->counters[0].l & 0xff) * (PITCONST << 1ULL)); + else + timer_advance_u64(&pas16->timer, (pit->counters[0].l & 0xff) * PITCONST); + } else { + if (pas16->dma >= 5) + timer_advance_u64(&pas16->timer, 0x100 * (PITCONST << 1ULL)); + else + timer_advance_u64(&pas16->timer, 0x100 * PITCONST); } } + pas16_update_irq(pas16); + pas16->irq_stat |= PAS16_INT_SAMP; - if (pas16->irq_ena & PAS16_INT_SAMP) + if (pas16->irq_ena & PAS16_INT_SAMP) { + pas16_log("INT SAMP.\n"); picint(1 << pas16->irq); - else - picintc(1 << pas16->irq); + } /*Update sample rate counter*/ - pas16_log("Enable (t1) = %d.\n", pit->counters[1].enable); + pas16_log("T1=%d, master bit 1=%x, counter0=%d, counter1=%d, pcm dma ena=%02x 16bit?=%02x.\n", pit->counters[1].enable, pit->counters[0].m & 0x02, pit->counters[0].l, pit->counters[1].l, pas16->pcm_ctrl & 0xc0, pas16->sys_conf_2 & PAS16_SC2_16BIT); if (pit->counters[1].enable) { - if (pas16->pcm_ctrl & PAS16_PCM_ENA) { + if ((pas16->pcm_ctrl & (PAS16_PCM_ENA | PAS16_PCM_DMA_ENA))) { if (pas16->sys_conf_2 & PAS16_SC2_16BIT) { - temp = pas16_readdma(pas16) << 8; - temp |= pas16_readdma(pas16); - } else - temp = (pas16_readdma(pas16) ^ 0x80) << 8; + data = pas16_readdma(pas16) << 8; + data |= pas16_readdma(pas16); + temp = data; + } else { + data = pas16_readdma(pas16); + temp = (data ^ 0x80) << 8; + } if (pas16->sys_conf_2 & PAS16_SC2_MSBINV) temp ^= 0x8000; @@ -619,41 +568,63 @@ pas16_pcm_poll(void *priv) pas16->stereo_lr = !pas16->stereo_lr; } } - if (pas16->sys_conf_2 & PAS16_SC2_16BIT) - pit->counters[1].rl -= 2; - else - pit->counters[1].rl--; - - pas16_log("RL=%d, mode=%x.\n", pit->counters[1].rl, pit->counters[1].m & 0x03); - if (pit->counters[1].rl == 0xffff) { - if (pit->counters[1].m & 2) { - if (pit->counters[1].l & 0xffff) - pit->counters[1].rl = pit->counters[1].l & 0xffff; - else - pit->counters[1].rl = 0; - } else { - pit->counters[1].enable = 0; - pit->counters[1].rl = 0; + if (pas16->sys_conf_2 & PAS16_SC2_16BIT) { + pit->counters[1].lback -= 2; + if (!pit->counters[1].lback) { + if (pit->counters[1].m & 0x02) { + if (pit->counters[1].lback2 & 0xfffe) + pit->counters[1].lback = pit->counters[1].lback2 & 0xfffe; + else + pit->counters[1].lback = 0; + } else { + pit->counters[1].lback = 0; + pit->counters[1].enable = 0; + } + pas16_log("16-bit: New counter=%d, mode=%x.\n", pit->counters[1].lback, pit->counters[1].m & 0x03); + pas16->irq_stat |= PAS16_INT_PCM; + if (pas16->irq_ena & PAS16_INT_PCM) { + pas16_log("16-bit: INT PCM.\n"); + picint(1 << pas16->irq); + } + } + } else { + pit->counters[1].lback--; + if (!pit->counters[1].lback) { + if (pit->counters[1].m & 0x02) { + if (pit->counters[1].lback2 & 0xffff) + pit->counters[1].lback = pit->counters[1].lback2 & 0xffff; + else + pit->counters[1].lback = 0; + } else { + pit->counters[1].lback = 0; + pit->counters[1].enable = 0; + } + pas16_log("8-bit: New counter=%d, mode=%x.\n", pit->counters[1].lback, pit->counters[1].m & 0x03); + pas16->irq_stat |= PAS16_INT_PCM; + if (pas16->irq_ena & PAS16_INT_PCM) { + pas16_log("8-bit: INT PCM.\n"); + picint(1 << pas16->irq); + } } - - pas16_log("New counter=%d, mode=%x.\n", pit->counters[1].rl, pit->counters[1].m & 0x03); - pas16->irq_stat |= PAS16_INT_PCM; - if (pas16->irq_ena & PAS16_INT_PCM) { - pclog("pas16_pcm_poll : cause IRQ %i %02X, enable timer 1 = %x\n", pas16->irq, 1 << pas16->irq, pit->counters[1].enable); - picint(1 << pas16->irq); - } else - picintc(1 << pas16->irq); } } } static void -pas16_pit_timer0(int new_out, int old_out, void *priv) +pas16_pit_timer0(int new_out, UNUSED(int old_out), void *priv) { pit_t *pit = (pit_t *)priv; - pclog("NewOut=%d, OldOut=%d.\n", new_out, old_out); - pit->counters[1].enable = new_out; + pas16_t *pas16 = (pas16_t *)pit->dev_priv; + + pas16_log("PAS16 pit timer0 out=%x, cnt0=%d, cnt1=%d.\n", new_out, pit->counters[0].l, pit->counters[1].l); pit_ctr_set_clock(&pit->counters[0], new_out, pit); + pit->counters[1].enable = new_out; + if (!timer_is_enabled(&pas16->timer)) { + if (pas16->dma >= 5) + timer_set_delay_u64(&pas16->timer, (pit->counters[0].l & 0xff) * (PITCONST << 1ULL)); + else + timer_set_delay_u64(&pas16->timer, (pit->counters[0].l & 0xff) * PITCONST); + } } static void @@ -661,48 +632,56 @@ pas16_out_base(UNUSED(uint16_t port), uint8_t val, void *priv) { pas16_t *pas16 = (pas16_t *) priv; - io_removehandler((pas16->base - 0x388) + 0x0388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x0788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x0b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x0f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - pit_handler(0, (pas16->base - 0x388) + 0x1388, 0x0004, pas16->pit); - io_removehandler((pas16->base - 0x388) + 0x1788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x1b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x2788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x7f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x8388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xbf88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xe388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xe788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xeb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xef88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xf388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xf788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xfb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xff88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + for (uint32_t addr = 0x000; addr < 0x10000; addr += 0x400) { + if (addr != 0x1000) { + io_removehandler(pas16->base + addr, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler(pas16->base + addr, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + } + } + pit_handler(0, pas16->base + 0x1000, 0x0004, pas16->pit); + pit_handler(1, pas16->base + 0x1000, 0x0004, pas16->pit); pas16->base = val << 2; - pclog("pas16_write_base : PAS16 base now at %04X\n", pas16->base); +} - io_sethandler((pas16->base - 0x388) + 0x0388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x0788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x0b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x0f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - pit_handler(1, (pas16->base - 0x388) + 0x1388, 0x0004, pas16->pit); - io_sethandler((pas16->base - 0x388) + 0x1788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x1b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x2788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x7f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x8388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xbf88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xe388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xe788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xeb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xef88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xf388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xf788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xfb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xff88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); +static void +pas16_input_msg(void *priv, uint8_t *msg, uint32_t len) +{ + pas16_t *pas16 = (pas16_t *) priv; + + if (pas16->sysex) + return; + + if (pas16->midi_uart_in) { + pas16->midi_stat |= 0x04; + + for (uint32_t i = 0; i < len; i++) { + pas16->midi_queue[pas16->midi_w++] = msg[i]; + pas16->midi_w &= 0xff; + } + + pas16_update_irq(pas16); + } +} + +static int +pas16_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) +{ + pas16_t *pas16 = (pas16_t *) priv; + + if (abort) { + pas16->sysex = 0; + return 0; + } + pas16->sysex = 1; + for (uint32_t i = 0; i < len; i++) { + if (pas16->midi_r == pas16->midi_w) + return (len - i); + pas16->midi_queue[pas16->midi_w++] = buffer[i]; + pas16->midi_w &= 0xff; + } + pas16->sysex = 0; + return 0; } static void @@ -756,6 +735,7 @@ pas16_init(UNUSED(const device_t *info)) memset(pas16, 0, sizeof(pas16_t)); fm_driver_get(FM_YMF262, &pas16->opl); + sb_dsp_set_real_opl(&pas16->dsp, 1); sb_dsp_init(&pas16->dsp, SB2, SB_SUBTYPE_DEFAULT, pas16); pas16->mpu = (mpu_t *) malloc(sizeof(mpu_t)); memset(pas16->mpu, 0, sizeof(mpu_t)); @@ -763,20 +743,25 @@ pas16_init(UNUSED(const device_t *info)) sb_dsp_set_mpu(&pas16->dsp, pas16->mpu); pas16->pit = device_add(&i8254_ext_io_device); - - pas16->midi_uart_out = 1; + pas16->pit->dev_priv = pas16; + pas16->irq = 10; + pas16->dma = 3; + pas16->base = 0x0388; io_sethandler(0x9a01, 0x0001, NULL, NULL, NULL, pas16_out_base, NULL, NULL, pas16); pit_ctr_set_out_func(pas16->pit, 0, pas16_pit_timer0); pit_ctr_set_using_timer(pas16->pit, 0, 1); pit_ctr_set_using_timer(pas16->pit, 1, 0); pit_ctr_set_using_timer(pas16->pit, 2, 0); - pas16->pit->dev_priv = pas16; - pas16->pit->dev_timer = pas16_pcm_poll; + + timer_add(&pas16->timer, pas16_pcm_poll, pas16, 0); sound_add_handler(pas16_get_buffer, pas16); music_add_handler(pas16_get_music_buffer, pas16); + if (device_get_config_int("receive_input")) + midi_in_handler(1, pas16_input_msg, pas16_input_sysex, pas16); + return pas16; } @@ -796,6 +781,13 @@ static const device_config_t pas16_config[] = { .default_string = "", .default_int = 0 }, + { + .name = "receive_input", + .description = "Receive input (PAS16 MIDI)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, { .name = "", .description = "", .type = CONFIG_END } }; From c176a116fb0237c49b1f2fc349f75dce9a3af954 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 21 Mar 2024 22:13:37 +0100 Subject: [PATCH 759/936] Remove deskpro386 and PAS16 from the dev branch. From the main CMakeLists.txt. --- CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1dfed3fb9..11265d09a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -151,7 +151,6 @@ endif() cmake_dependent_option(AMD_K5 "AMD K5" ON "DEV_BRANCH" OFF) cmake_dependent_option(AN430TX "Intel AN430TX" ON "DEV_BRANCH" OFF) cmake_dependent_option(CYRIX_6X86 "Cyrix 6x86" ON "DEV_BRANCH" OFF) -cmake_dependent_option(DESKPRO386 "Compaq Deskpro 386" ON "DEV_BRANCH" OFF) cmake_dependent_option(GUSMAX "Gravis UltraSound MAX" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF) @@ -160,7 +159,6 @@ cmake_dependent_option(LASERXT "VTech Laser XT" cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF) -cmake_dependent_option(PAS16 "Pro Audio Spectrum 16" ON "DEV_BRANCH" OFF) cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF) cmake_dependent_option(VGAWONDER "ATI VGA Wonder (ATI-18800)" ON "DEV_BRANCH" OFF) cmake_dependent_option(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF) From 882b65de48deb50af17fe70de5162268c772f1b9 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Thu, 21 Mar 2024 23:32:26 -0300 Subject: [PATCH 760/936] Implementing ESFM timer interface using 86Box's timers; dropping ESFMu's internal timer emulation Co-authored-by: OBattler --- src/sound/snd_opl_esfm.c | 216 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 204 insertions(+), 12 deletions(-) diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index cbd9a93a3..d7523da8b 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -38,11 +38,6 @@ #define RSM_FRAC 10 -enum { - FLAG_CYCLES = 0x02, - FLAG_OPL3 = 0x01 -}; - typedef struct { esfm_chip opl; int8_t flags; @@ -54,12 +49,53 @@ typedef struct { uint16_t timer_count[2]; uint16_t timer_cur_count[2]; + pc_timer_t timers[2]; + int16_t samples[2]; int pos; int32_t buffer[MUSICBUFLEN * 2]; } esfm_drv_t; +enum { + FLAG_CYCLES = 0x02, + FLAG_OPL3 = 0x01 +}; + +enum { + STAT_TMR_OVER = 0x60, + STAT_TMR1_OVER = 0x40, + STAT_TMR2_OVER = 0x20, + STAT_TMR_ANY = 0x80 +}; + +enum { + CTRL_RESET = 0x80, + CTRL_TMR_MASK = 0x60, + CTRL_TMR1_MASK = 0x40, + CTRL_TMR2_MASK = 0x20, + CTRL_TMR2_START = 0x02, + CTRL_TMR1_START = 0x01 +}; + +#ifdef ENABLE_OPL_LOG +int esfm_do_log = ENABLE_OPL_LOG; + +static void +esfm_log(const char *fmt, ...) +{ + va_list ap; + + if (esfm_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define esfm_log(fmt, ...) +#endif + void esfm_generate_raw(esfm_drv_t *dev, int32_t *bufp) { @@ -78,6 +114,60 @@ esfm_drv_generate_stream(esfm_drv_t *dev, int32_t *sndptr, uint32_t num) } } +static void +esfm_timer_tick(esfm_drv_t *dev, int tmr) +{ + dev->timer_cur_count[tmr] = (dev->timer_cur_count[tmr] + 1) & 0xff; + + esfm_log("Ticking timer %i, count now %02X...\n", tmr, dev->timer_cur_count[tmr]); + + if (dev->timer_cur_count[tmr] == 0x00) { + dev->status |= ((STAT_TMR1_OVER >> tmr) & ~dev->timer_ctrl); + dev->timer_cur_count[tmr] = dev->timer_count[tmr]; + + esfm_log("Count wrapped around to zero, reloading timer %i (%02X), status = %02X...\n", tmr, (STAT_TMR1_OVER >> tmr), dev->status); + } + + timer_on_auto(&dev->timers[tmr], (tmr == 1) ? 320.0 : 80.0); +} + +static void +esfm_timer_control(esfm_drv_t *dev, int tmr, int start) +{ + timer_on_auto(&dev->timers[tmr], 0.0); + + if (start) { + esfm_log("Loading timer %i count: %02X = %02X\n", tmr, dev->timer_cur_count[tmr], dev->timer_count[tmr]); + dev->timer_cur_count[tmr] = dev->timer_count[tmr]; + if (dev->flags & FLAG_OPL3) + esfm_timer_tick(dev, tmr); /* Per the YMF 262 datasheet, OPL3 starts counting immediately, unlike OPL2. */ + else + timer_on_auto(&dev->timers[tmr], (tmr == 1) ? 320.0 : 80.0); + } else { + esfm_log("Timer %i stopped\n", tmr); + if (tmr == 1) { + dev->status &= ~STAT_TMR2_OVER; + } else + dev->status &= ~STAT_TMR1_OVER; + } +} + +static void +esfm_timer_1(void *priv) +{ + esfm_drv_t *dev = (esfm_drv_t *) priv; + + esfm_timer_tick(dev, 0); +} + +static void +esfm_timer_2(void *priv) +{ + esfm_drv_t *dev = (esfm_drv_t *) priv; + + esfm_timer_tick(dev, 1); +} + static void esfm_drv_set_do_cycles(void *priv, int8_t do_cycles) { @@ -98,6 +188,9 @@ esfm_drv_init(const device_t *info) /* Initialize the ESFMu object. */ ESFM_init(&dev->opl); + timer_add(&dev->timers[0], esfm_timer_1, dev, 0); + timer_add(&dev->timers[1], esfm_timer_2, dev, 0); + return dev; } @@ -149,32 +242,131 @@ esfm_drv_read(uint16_t port, void *priv) uint8_t ret = 0xff; - ret = ESFM_read_port(&dev->opl, port & 3); + switch (port & 0x0003) + { + case 0x0000: + ret = dev->status; + if (dev->status & STAT_TMR_OVER) + ret |= STAT_TMR_ANY; + break; + case 0x0001: + ret = ESFM_read_port(&dev->opl, port & 3); + switch (dev->opl.addr_latch & 0x5ff) + { + case 0x402: + ret = dev->timer_count[0]; + break; + case 0x403: + ret = dev->timer_count[1]; + break; + case 0x404: + ret = dev->timer_ctrl; + break; + } + break; + case 0x0002: + case 0x0003: + ret = 0xff; + break; + } + + pclog("esfm: [%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, port, ret); return ret; } +static void +esfm_drv_write_buffered(esfm_drv_t *dev, uint8_t val) +{ + ESFM_write_reg_buffered_fast(&dev->opl, dev->opl.addr_latch, val); + + if (dev->opl.native_mode) + { + switch (dev->port & 0x5ff) + { + case 0x402: /* Timer 1 */ + dev->timer_count[0] = val; + esfm_log("Timer 0 count now: %i\n", dev->timer_count[0]); + break; + + case 0x403: /* Timer 2 */ + dev->timer_count[1] = val; + esfm_log("Timer 1 count now: %i\n", dev->timer_count[1]); + break; + + case 0x404: /* Timer control */ + if (val & CTRL_RESET) { + esfm_log("Resetting timer status...\n"); + dev->status &= ~STAT_TMR_OVER; + } else { + dev->timer_ctrl = val; + esfm_timer_control(dev, 0, val & CTRL_TMR1_START); + esfm_timer_control(dev, 1, val & CTRL_TMR2_START); + esfm_log("Status mask now %02X (val = %02X)\n", (val & ~CTRL_TMR_MASK) & CTRL_TMR_MASK, val); + } + break; + + default: + break; + } + } + else + { + switch (dev->port & 0x1ff) + { + case 0x002: /* Timer 1 */ + dev->timer_count[0] = val; + esfm_log("Timer 0 count now: %i\n", dev->timer_count[0]); + break; + + case 0x003: /* Timer 2 */ + dev->timer_count[1] = val; + esfm_log("Timer 1 count now: %i\n", dev->timer_count[1]); + break; + + case 0x004: /* Timer control */ + if (val & CTRL_RESET) { + esfm_log("Resetting timer status...\n"); + dev->status &= ~STAT_TMR_OVER; + } else { + dev->timer_ctrl = val; + esfm_timer_control(dev, 0, val & CTRL_TMR1_START); + esfm_timer_control(dev, 1, val & CTRL_TMR2_START); + esfm_log("Status mask now %02X (val = %02X)\n", (val & ~CTRL_TMR_MASK) & CTRL_TMR_MASK, val); + } + break; + + default: + break; + } + } +} + static void esfm_drv_write(uint16_t port, uint8_t val, void *priv) { esfm_drv_t *dev = (esfm_drv_t *) priv; + pclog("esfm: [%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, port, val); + if (dev->flags & FLAG_CYCLES) cycles -= ((int) (isa_timing * 8)); esfm_drv_update(dev); if (dev->opl.native_mode) { - if ((port & 3) == 1) { - ESFM_write_reg_buffered_fast(&dev->opl, dev->opl.addr_latch, val); - } else { + if ((port & 0x0003) == 0x0001) + esfm_drv_write_buffered(dev, val); + else { ESFM_write_port(&dev->opl, port & 3, val); + dev->port = dev->opl.addr_latch & 0x07ff; } } else { - if ((port & 3) == 1 || (port & 3) == 3) { - ESFM_write_reg_buffered_fast(&dev->opl, dev->opl.addr_latch, val); - } else { + if ((port & 0x0001) == 0x0001) + esfm_drv_write_buffered(dev, val); + else { ESFM_write_port(&dev->opl, port & 3, val); + dev->port = dev->opl.addr_latch & 0x01ff; } } } From c835a4d1560548051285dce9cca8616da1cbf7b1 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 00:32:57 -0300 Subject: [PATCH 761/936] Uncluttering logs; making ESFM output work again (oops) --- src/sound/snd_ess.c | 2 +- src/sound/snd_opl_esfm.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 55c6f9d60..6ba5a9db8 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -518,10 +518,10 @@ ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) ess->dsp.record_buffer[(c_record & 0xfffe) + 1] = 32767; } } +#endif buffer[c] += (int32_t) out_l; buffer[c + 1] += (int32_t) out_r; -#endif } #if 0 diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index d7523da8b..cf4e94cb1 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -270,7 +270,7 @@ esfm_drv_read(uint16_t port, void *priv) break; } - pclog("esfm: [%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, port, ret); + esfm_log("esfm: [%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, port, ret); return ret; } @@ -347,7 +347,7 @@ esfm_drv_write(uint16_t port, uint8_t val, void *priv) { esfm_drv_t *dev = (esfm_drv_t *) priv; - pclog("esfm: [%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, port, val); + esfm_log("esfm: [%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, port, val); if (dev->flags & FLAG_CYCLES) cycles -= ((int) (isa_timing * 8)); From 3e539c630b36e3c13fd5be620ed6ee615d97c659 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 01:31:13 -0300 Subject: [PATCH 762/936] Mixer code cleanup: fixing ESS volume calculation --- src/sound/snd_ess.c | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 6ba5a9db8..b2a67419a 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -50,7 +50,7 @@ #include <86box/plat_unused.h> - +// clang-format off static const double sb_att_4dbstep_3bits[] = { 164.0, 2067.0, 3276.0, 5193.0, 8230.0, 13045.0, 20675.0, 32767.0 }; @@ -64,6 +64,13 @@ static const double sb_att_1p4dbstep_4bits[] = { 10603.0, 12458.0, 14637.0, 17196.0, 20204.0, 23738.0, 27889.0, 32767.0 }; +static const double sb_att_2dbstep_4bits[] = { + 164.0, 1304.0, 1641.0, 2067.0, 2602.0, 3276.0, 4125.0, 5192.0, + 6537.0, 8230.0, 10362.0, 13044.0, 16422.0, 20674.0, 26027.0, 32767.0 +}; +// clang-format on + + /* SB PRO */ typedef struct ess_mixer_t { double master_l; @@ -118,27 +125,9 @@ typedef struct ess_t { void (*opl_mix)(void*, double*, double*); } ess_t; -static inline uint8_t expand16to32(const uint8_t t) { - /* 4-bit -> 5-bit expansion. - * - * 0 -> 0 - * 1 -> 2 - * 2 -> 4 - * 3 -> 6 - * .... - * 7 -> 14 - * 8 -> 17 - * 9 -> 19 - * 10 -> 21 - * 11 -> 23 - * .... - * 15 -> 31 */ - return (t << 1) | (t >> 3); -} - static double ess_mixer_get_vol_4bit(uint8_t vol) { - return (48.0 + (20.0 * log((vol & 0xF) / 15.0))) / 48.0; + return sb_att_2dbstep_4bits[vol] / 32767.0; } void From d41e791aecfe622b81bc020a9dc8e00bb59ef2cb Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 01:35:31 -0300 Subject: [PATCH 763/936] Fix bug introduced by last commit --- src/sound/snd_ess.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index b2a67419a..f70e508ed 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -127,7 +127,7 @@ typedef struct ess_t { static double ess_mixer_get_vol_4bit(uint8_t vol) { - return sb_att_2dbstep_4bits[vol] / 32767.0; + return sb_att_2dbstep_4bits[vol & 0x0F] / 32767.0; } void From 937537f78ead2243b71d7c60480b02d955acb3c1 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 11:17:34 -0300 Subject: [PATCH 764/936] Legacy microphone volume mapping --- src/sound/snd_ess.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index f70e508ed..3f544ec4f 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -59,11 +59,15 @@ static const double sb_att_7dbstep_2bits[] = { 164.0, 6537.0, 14637.0, 32767.0 }; +/* Attenuation table for 4-bit microphone volume. + * The last step is a jump to -48 dB. */ static const double sb_att_1p4dbstep_4bits[] = { 164.0, 3431.0, 4031.0, 4736.0, 5565.0, 6537.0, 7681.0, 9025.0, 10603.0, 12458.0, 14637.0, 17196.0, 20204.0, 23738.0, 27889.0, 32767.0 }; +/* Attenuation table for 4-bit mixer avolume. + * The last step is a jump to -48 dB. */ static const double sb_att_2dbstep_4bits[] = { 164.0, 1304.0, 1641.0, 2067.0, 2602.0, 3276.0, 4125.0, 5192.0, 6537.0, 8230.0, 10362.0, 13044.0, 16422.0, 20674.0, 26027.0, 32767.0 @@ -177,7 +181,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) { uint8_t mic_vol_2bit = (mixer->regs[0x0a] >> 1) & 0x3; mixer->mic_l = mixer->mic_r = sb_att_7dbstep_2bits[mic_vol_2bit] / 32768.0; - mixer->regs[0x1A] = mic_vol_2bit | (mic_vol_2bit << 2); + mixer->regs[0x1A] = mic_vol_2bit | (mic_vol_2bit << 2) | (mic_vol_2bit << 4) | (mic_vol_2bit << 6); break; } From d46e2ef7c8a3d3fc0bc87598bf25efa5b1624160 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 11:56:01 -0300 Subject: [PATCH 765/936] Refactored ESFM timers; removed 16-bit clipping from ESFMu Co-authored-by: OBattler --- src/sound/esfmu/esfm.c | 15 +++++-- src/sound/esfmu/esfm.h | 2 +- src/sound/snd_opl_esfm.c | 88 +++++++++++++--------------------------- 3 files changed, 40 insertions(+), 65 deletions(-) diff --git a/src/sound/esfmu/esfm.c b/src/sound/esfmu/esfm.c index 08beadb5a..274afd277 100644 --- a/src/sound/esfmu/esfm.c +++ b/src/sound/esfmu/esfm.c @@ -1741,6 +1741,10 @@ ESFM_slot_generate_emu(esfm_slot *slot) } /* ------------------------------------------------------------------------- */ +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wunused-variable" +#pragma clang diagnostic ignored "-Wunknown-pragmas" static void ESFM_process_feedback(esfm_chip *chip) { @@ -2226,7 +2230,7 @@ ESFM_update_write_buffer(esfm_chip *chip) /* ------------------------------------------------------------------------- */ void -ESFM_generate(esfm_chip *chip, int16_t *buf) +ESFM_generate(esfm_chip *chip, int32_t *buf) { int channel_idx; @@ -2259,8 +2263,8 @@ ESFM_generate(esfm_chip *chip, int16_t *buf) chip->output_accm[1] += channel->output[1]; } - buf[0] = ESFM_clip_sample(chip->output_accm[0]); - buf[1] = ESFM_clip_sample(chip->output_accm[1]); + buf[0] = chip->output_accm[0]; + buf[1] = chip->output_accm[1]; ESFM_update_timers(chip); ESFM_update_write_buffer(chip); @@ -2308,10 +2312,13 @@ void ESFM_generate_stream(esfm_chip *chip, int16_t *sndptr, uint32_t num_samples) { uint32_t i; + int32_t buf[2] = { 0 }; for (i = 0; i < num_samples; i++) { - ESFM_generate(chip, sndptr); + ESFM_generate(chip, buf); + sndptr[0] = ESFM_clip_sample(buf[0]); + sndptr[1] = ESFM_clip_sample(buf[1]); sndptr += 2; } } diff --git a/src/sound/esfmu/esfm.h b/src/sound/esfmu/esfm.h index 41ac6983f..eda8bcbb3 100644 --- a/src/sound/esfmu/esfm.h +++ b/src/sound/esfmu/esfm.h @@ -67,7 +67,7 @@ void ESFM_write_reg_buffered_fast (esfm_chip *chip, uint16_t address, uint8_t da void ESFM_write_port (esfm_chip *chip, uint8_t offset, uint8_t data); uint8_t ESFM_readback_reg (esfm_chip *chip, uint16_t address); uint8_t ESFM_read_port (esfm_chip *chip, uint8_t offset); -void ESFM_generate(esfm_chip *chip, int16_t *buf); +void ESFM_generate(esfm_chip *chip, int32_t *buf); void ESFM_generate_stream(esfm_chip *chip, int16_t *sndptr, uint32_t num_samples); int16_t ESFM_get_channel_output_native(esfm_chip *chip, int channel_idx); diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index cf4e94cb1..174830523 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -99,10 +99,7 @@ esfm_log(const char *fmt, ...) void esfm_generate_raw(esfm_drv_t *dev, int32_t *bufp) { - ESFM_generate(&dev->opl, &dev->samples[0]); - - bufp[0] = dev->samples[0]; - bufp[1] = dev->samples[1]; + ESFM_generate(&dev->opl, bufp); } void @@ -270,75 +267,48 @@ esfm_drv_read(uint16_t port, void *priv) break; } - esfm_log("esfm: [%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, port, ret); - return ret; } static void esfm_drv_write_buffered(esfm_drv_t *dev, uint8_t val) { + uint16_t p = dev->port; + ESFM_write_reg_buffered_fast(&dev->opl, dev->opl.addr_latch, val); if (dev->opl.native_mode) { - switch (dev->port & 0x5ff) - { - case 0x402: /* Timer 1 */ - dev->timer_count[0] = val; - esfm_log("Timer 0 count now: %i\n", dev->timer_count[0]); - break; - - case 0x403: /* Timer 2 */ - dev->timer_count[1] = val; - esfm_log("Timer 1 count now: %i\n", dev->timer_count[1]); - break; - - case 0x404: /* Timer control */ - if (val & CTRL_RESET) { - esfm_log("Resetting timer status...\n"); - dev->status &= ~STAT_TMR_OVER; - } else { - dev->timer_ctrl = val; - esfm_timer_control(dev, 0, val & CTRL_TMR1_START); - esfm_timer_control(dev, 1, val & CTRL_TMR2_START); - esfm_log("Status mask now %02X (val = %02X)\n", (val & ~CTRL_TMR_MASK) & CTRL_TMR_MASK, val); - } - break; - - default: - break; - } + p -= 0x400; + p &= 0x1ff; } - else + + switch (p) { - switch (dev->port & 0x1ff) - { - case 0x002: /* Timer 1 */ - dev->timer_count[0] = val; - esfm_log("Timer 0 count now: %i\n", dev->timer_count[0]); - break; + case 0x002: /* Timer 1 */ + dev->timer_count[0] = val; + esfm_log("Timer 0 count now: %i\n", dev->timer_count[0]); + break; - case 0x003: /* Timer 2 */ - dev->timer_count[1] = val; - esfm_log("Timer 1 count now: %i\n", dev->timer_count[1]); - break; + case 0x003: /* Timer 2 */ + dev->timer_count[1] = val; + esfm_log("Timer 1 count now: %i\n", dev->timer_count[1]); + break; - case 0x004: /* Timer control */ - if (val & CTRL_RESET) { - esfm_log("Resetting timer status...\n"); - dev->status &= ~STAT_TMR_OVER; - } else { - dev->timer_ctrl = val; - esfm_timer_control(dev, 0, val & CTRL_TMR1_START); - esfm_timer_control(dev, 1, val & CTRL_TMR2_START); - esfm_log("Status mask now %02X (val = %02X)\n", (val & ~CTRL_TMR_MASK) & CTRL_TMR_MASK, val); - } - break; + case 0x004: /* Timer control */ + if (val & CTRL_RESET) { + esfm_log("Resetting timer status...\n"); + dev->status &= ~STAT_TMR_OVER; + } else { + dev->timer_ctrl = val; + esfm_timer_control(dev, 0, val & CTRL_TMR1_START); + esfm_timer_control(dev, 1, val & CTRL_TMR2_START); + esfm_log("Status mask now %02X (val = %02X)\n", (val & ~CTRL_TMR_MASK) & CTRL_TMR_MASK, val); + } + break; - default: - break; - } + default: + break; } } @@ -347,8 +317,6 @@ esfm_drv_write(uint16_t port, uint8_t val, void *priv) { esfm_drv_t *dev = (esfm_drv_t *) priv; - esfm_log("esfm: [%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, port, val); - if (dev->flags & FLAG_CYCLES) cycles -= ((int) (isa_timing * 8)); From 5e318dfce9420f264f44ea4b0a1f165c4d2c2256 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 12:13:57 -0300 Subject: [PATCH 766/936] Updating ESFMu to version v1.2.6 --- src/sound/esfmu/esfm.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/sound/esfmu/esfm.c b/src/sound/esfmu/esfm.c index 274afd277..89fa82d4f 100644 --- a/src/sound/esfmu/esfm.c +++ b/src/sound/esfmu/esfm.c @@ -1783,7 +1783,7 @@ ESFM_process_feedback(esfm_chip *chip) eg_output = slot->in.eg_output; // ASM optimizaions! -#if defined(__GNUC__) && defined(__x86_64__) +#if defined(__GNUC__) && defined(__x86_64__) && !defined(_ESFMU_DISABLE_ASM_OPTIMIZATIONS) asm ( "movzbq %[wave], %%r8 \n\t" "shll $11, %%r8d \n\t" @@ -1848,11 +1848,14 @@ ESFM_process_feedback(esfm_chip *chip) [exprom] "m" (exprom) : "cc", "ax", "bx", "cx", "dx", "r8", "r9", "r10", "r11" ); -#elif defined(__GNUC__) && defined(__i386__) +#elif defined(__GNUC__) && defined(__i386__) && !defined(_ESFMU_DISABLE_ASM_OPTIMIZATIONS) + size_t logsinrom_addr = (size_t)logsinrom; + size_t exprom_addr = (size_t)exprom; + asm ( "movzbl %b[wave], %%eax \n\t" "shll $11, %%eax \n\t" - "leal %[sinrom], %%edi \n\t" + "movl %[sinrom], %%edi \n\t" "addl %%eax, %%edi \n\t" "shlw $3, %[eg_out] \n\t" "xorl %[out], %[out] \n\t" @@ -1887,7 +1890,7 @@ ESFM_process_feedback(esfm_chip *chip) // wave_out = exprom[level & 0xff] >> (level >> 8); "movb %%ah, %%cl \n\t" "movzbl %%al, %%eax \n\t" - "leal %[exprom], %[out] \n\t" + "movl %[exprom], %[out] \n\t" "movzwl (%[out], %%eax, 2), %[out] \n\t" "shrl %%cl, %[out] \n\t" // if (lookup & 0x8000) wave_out = -wave_out; @@ -1909,12 +1912,12 @@ ESFM_process_feedback(esfm_chip *chip) : [p_off] "m" (phase_offset), [mod_in] "m" (mod_in_shift), [wave] "m" (waveform), - [sinrom] "m" (logsinrom), - [exprom] "m" (exprom), + [sinrom] "m" (logsinrom_addr), + [exprom] "m" (exprom_addr), [i] "m" (iter_counter) : "cc", "ax", "bx", "cx", "di" ); -#elif defined(__GNUC__) && defined(__arm__) +#elif defined(__GNUC__) && defined(__arm__) && !defined(_ESFMU_DISABLE_ASM_OPTIMIZATIONS) asm ( "movs r3, #0 \n\t" "movs %[out], #0 \n\t" From 36ecc175513b910d683da5d5520d18e160faef36 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 22 Mar 2024 23:24:58 +0100 Subject: [PATCH 767/936] Fix incompatible pointers of the generic PIT and PCjr's So that the build compiles fine. --- src/machine/m_pcjr.c | 2 +- src/machine/machine.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index 80a0ffbc1..804da8e30 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -772,7 +772,7 @@ speed_changed(void *priv) } void -pit_irq0_timer_pcjr(int new_out, int old_out) +pit_irq0_timer_pcjr(int new_out, int old_out, UNUSED(void *priv)) { if (new_out && !old_out) { picint(1); diff --git a/src/machine/machine.c b/src/machine/machine.c index 9e530eb3b..b171dd505 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -156,7 +156,7 @@ machine_available(int m) } void -pit_irq0_timer(int new_out, int old_out) +pit_irq0_timer(int new_out, int old_out, UNUSED(void *priv)) { if (new_out && !old_out) picint(1); From 309786bc7aeb159600b21735fdc35a4ec1c9f6c2 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 22 Mar 2024 23:51:25 +0100 Subject: [PATCH 768/936] Add the Tandy 4000 AT compatible and SCAT-286-003 machines And a proper Compaq Portable III 386 BIOS. Note: The SCAT 286 003 machine is a SCAT-based AMI 286 machine. --- src/include/86box/machine.h | 2 + src/machine/m_at_286_386sx.c | 19 +++++++++ src/machine/m_at_386dx_486.c | 20 +++++++++ src/machine/m_at_compaq.c | 9 ++-- src/machine/machine_table.c | 81 +++++++++++++++++++++++++++++++++++- 5 files changed, 127 insertions(+), 4 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index ee18a89b1..f97d1a37c 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -451,6 +451,7 @@ extern int machine_at_quadt386sx_init(const machine_t *); extern int machine_at_award286_init(const machine_t *); extern int machine_at_gdc212m_init(const machine_t *); extern int machine_at_gw286ct_init(const machine_t *); +extern int machine_at_senor_scat286_init(const machine_t *); extern int machine_at_super286c_init(const machine_t *); extern int machine_at_super286tr_init(const machine_t *); extern int machine_at_spc4200p_init(const machine_t *); @@ -492,6 +493,7 @@ extern int machine_at_ecs386_init(const machine_t *); extern int machine_at_spc6000a_init(const machine_t *); extern int machine_at_micronics386_init(const machine_t *); extern int machine_at_ecs386v_init(const machine_t *); +extern int machine_at_tandy4000_init(const machine_t *); extern int machine_at_rycleopardlx_init(const machine_t *); diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index a688181b4..53df7f628 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -350,6 +350,25 @@ machine_at_gw286ct_init(const machine_t *model) return ret; } +int +machine_at_senor_scat286_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/senor286/AMI-DSC2-1115-061390-K8.rom", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_scat_init(model, 0, 1); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + int machine_at_super286c_init(const machine_t *model) { diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 3376e7b25..b89f77b18 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -90,6 +90,26 @@ machine_at_asus386_init(const machine_t *model) return ret; } +int +machine_at_tandy4000_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/tandy4000/BIOS Tandy 4000 v1.03.01.bin", + 0x000f8000, 32768, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&keyboard_at_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + static void machine_at_sis401_common_init(const machine_t *model) { diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index cd8c68764..7f31d4ecd 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -633,7 +633,10 @@ compaq_plasma_init(UNUSED(const device_t *info)) memset(self, 0, sizeof(compaq_plasma_t)); video_inform(VIDEO_FLAG_TYPE_CGA, &timing_compaq_plasma); - loadfont_ex("roms/machines/portableiii/K Combined.bin", 11, 0x4bb2); + if (compaq_machine_type == COMPAQ_PORTABLEIII) + loadfont_ex("roms/machines/portableiii/K Combined.bin", 11, 0x4bb2); + else + loadfont_ex("roms/machines/portableiii/P.2 Combined.bin", 11, 0x4b49); self->cga.composite = 0; self->cga.revision = 0; @@ -863,8 +866,8 @@ machine_at_portableiii386_init(const machine_t *model) { int ret; - ret = bios_load_linearr("roms/machines/portableiii/K Combined.bin", - 0x000f8000, 65536, 0); + ret = bios_load_linearr("roms/machines/portableiii/P.2 Combined.bin", + 0x000f0000, 131072, 0); if (bios_only || !ret) return ret; diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 5dad8b431..23c05bdf8 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -3726,6 +3726,45 @@ const machine_t machines[] = { .net_device = NULL }, + { + .name = "[SCAT] Senor Science Co. SCAT-286-003", + .internal_name = "senorscat286", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_SCAT, + .init = machine_at_senor_scat286_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_286, + .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_AT, + .flags = MACHINE_IDE, + .ram = { + .min = 1024, + .max = 4096, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* 286 machines that utilize the MCA bus */ /* Has IBM PS/2 Type 2 KBC firmware. */ { @@ -5013,7 +5052,7 @@ const machine_t machines[] = { .max = 14336, .step = 1024 }, - .nvrmask = 127, + .nvrmask = 63, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -5065,6 +5104,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has IBM AT KBC firmware. */ + { + .name = "[ISA] Tandy 4000", + .internal_name = "tandy4000", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_at_tandy4000_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX, + .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_AT, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 16384, + .step = 1024 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Has a Lance LT38C41 with AMI Megakey P KBC firmware */ { .name = "[ALi M1429] ECS Panda 386V", From 4b93999790191540bf0c274c2137dedcb79903b8 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 21:30:23 -0300 Subject: [PATCH 769/936] Cleanup: removing a bunch of logging statements --- src/sound/snd_ess.c | 12 +++------- src/sound/snd_sb_dsp.c | 52 +++--------------------------------------- 2 files changed, 6 insertions(+), 58 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 3f544ec4f..44106fa83 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -167,7 +167,6 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) sb_dsp_set_stereo(&ess->dsp, mixer->regs[0x0e] & 2); } else { mixer->regs[mixer->index] = val; - pclog("ess: Mixer Register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); switch (mixer->index) { /* Compatibility: chain registers 0x02 and 0x22 as well as 0x06 and 0x26 */ @@ -322,7 +321,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) } default: - pclog("ess: Unknown mixer register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + //pclog("ess: Unknown mixer register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } } @@ -378,30 +377,25 @@ ess_mixer_read(uint16_t addr, void *priv) case 0x36: case 0x38: case 0x3e: - pclog("ess: Mixer Register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); return mixer->regs[mixer->index]; case 0x40: - if (0) + if (ess->dsp.sb_subtype != SB_SUBTYPE_ESS_ES1688) { - /* not on ES1688 */ uint8_t val = mixer->ess_id_str[mixer->ess_id_str_pos]; - uint8_t pos_log = mixer->ess_id_str_pos; /* TODO remove */ mixer->ess_id_str_pos++; if (mixer->ess_id_str_pos >= 4) mixer->ess_id_str_pos = 0; - pclog("ess: ID READ: %02X (pos %d)\n", val, pos_log); return val; } else { - pclog("ess: Mixer Register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); return mixer->regs[mixer->index]; } default: - pclog("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + //pclog("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index f94724e68..03a6ba4ba 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -367,7 +367,6 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) if (IS_ESS(dsp) && dsp->sb_subtype != SB_SUBTYPE_ESS_ES1688 && !(ESSreg(0xB1) & 0x10)) // if ESS playback, and IRQ disabled, do not fire { - pclog("ess: IRQ was masked\n"); return; } @@ -394,7 +393,6 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) if (dsp->ess_playback_mode && bit <= 1 && set && !masked) { if (!(ESSreg(0xB1) & 0x40)) // if ESS playback, and IRQ disabled, do not fire { - pclog("ess: IRQ was masked\n"); return; } } @@ -409,7 +407,6 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) void sb_irq(sb_dsp_t *dsp, int irq8) { - pclog("sb: IRQ raised\n"); sb_update_status(dsp, !irq8, 1); } @@ -862,7 +859,6 @@ static uint8_t sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) { switch (reg) { default: - pclog("ESS register read reg=%02xh val=%02xh\n",reg, ESSreg(reg)); return ESSreg(reg); } @@ -876,7 +872,6 @@ static void sb_ess_update_autolen(sb_dsp_t *dsp) { static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) { uint8_t chg = 0x00; - pclog("ESS register write reg=%02xh val=%02xh\n",reg,data); switch (reg) { case 0xA1: /* Extended Mode Sample Rate Generator */ @@ -890,7 +885,6 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) temp = 1000000.0 / dsp->sb_freq; dsp->sblatchi = dsp->sblatcho = TIMER_USEC * temp; dsp->sb_timei = dsp->sb_timeo; - pclog("ess: Sample rate - %ihz (%f)\n", dsp->sb_freq, dsp->sblatcho); break; } case 0xA2: /* Filter divider (effectively, a hardware lowpass filter under S/W control) */ @@ -901,7 +895,6 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) case 0xA5: /* DMA Transfer Count Reload (high) */ ESSreg(reg) = data; sb_ess_update_autolen(dsp); - pclog("ess: DMA Transfer Count Reload length set to %d samples (0x%x)\n", sb_ess_get_dma_len(dsp), sb_ess_get_dma_counter(dsp)); if ((dsp->sb_16_length < 0 && !dsp->sb_16_enable) && (dsp->sb_8_length < 0 && !dsp->sb_8_enable)) dsp->ess_reload_len = 1; break; @@ -950,7 +943,6 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) dsp->sb_irqnum = 10; break; } - pclog("ess: IRQ set to %d\n", dsp->sb_irqnum); sb_ess_update_irq_drq_readback_regs(dsp, false); break; case 0xB2: /* DRQ Control */ @@ -971,7 +963,6 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) dsp->sb_8_dmanum = 3; break; } - pclog("ess: DMA set to %d\n", dsp->sb_8_dmanum); sb_ess_update_irq_drq_readback_regs(dsp, false); if (chg & 0x40) sb_ess_update_dma_status(dsp); break; @@ -1053,7 +1044,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) break; default: - pclog("UNKNOWN ESS register write reg=%02xh val=%02xh\n",reg,data); + sb_dsp_log("UNKNOWN ESS register write reg=%02xh val=%02xh\n",reg,data); break; } } @@ -1072,20 +1063,6 @@ sb_exec_command(sb_dsp_t *dsp) { dsp->sb_8051_ram[0x20] = dsp->sb_command; } - - { - int i, l, s = 0; - char data_s[256], *dsptr = data_s; - data_s[0] = '\0'; - - for (i = 0; i < sb_commands[dsp->sb_command]; i++) - { - l = snprintf(dsptr, 256 - s, " 0x%02X", dsp->sb_data[i]); - s += l; - dsptr += l; - } - pclog("dsp->sb_command = 0x%02X%s, length %d\n", dsp->sb_command, data_s, sb_commands[dsp->sb_command]); - } if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { if (dsp->sb_command == 0xC6 || dsp->sb_command == 0xC7) { @@ -1320,7 +1297,6 @@ sb_exec_command(sb_dsp_t *dsp) temp = 256 - dsp->sb_data[0]; temp = 1000000 / temp; sb_dsp_log("Sample rate - %ihz (%f)\n", temp, dsp->sblatcho); - pclog("Sample rate - %ihz (%f)\n", temp, dsp->sblatcho); // if ((dsp->sb_freq != temp) && (IS_ESS(dsp) || (dsp->sb_type >= SB16))) if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16)) recalc_sb16_filter(0, temp); @@ -1334,7 +1310,6 @@ sb_exec_command(sb_dsp_t *dsp) if (dsp->sb_type >= SB16) { dsp->sblatcho = (uint64_t) (TIMER_USEC * (1000000.0f / (float) (dsp->sb_data[1] + (dsp->sb_data[0] << 8)))); sb_dsp_log("Sample rate - %ihz (%f)\n", dsp->sb_data[1] + (dsp->sb_data[0] << 8), dsp->sblatcho); - pclog("Sample rate - %ihz (%f)\n", dsp->sb_data[1] + (dsp->sb_data[0] << 8), dsp->sblatcho); temp = dsp->sb_freq; dsp->sb_freq = dsp->sb_data[1] + (dsp->sb_data[0] << 8); dsp->sb_timeo = 256LL + dsp->sb_freq; @@ -1360,7 +1335,6 @@ sb_exec_command(sb_dsp_t *dsp) if (dsp->espcm_mode != ESPCM_4 || (dsp->sb_8_enable && dsp->sb_8_pause)) { - pclog("ess: ESPCM FIFO reset\n"); fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1375,7 +1349,6 @@ sb_exec_command(sb_dsp_t *dsp) if (dsp->espcm_mode != ESPCM_3 || (dsp->sb_8_enable && dsp->sb_8_pause)) { - pclog("ess: ESPCM FIFO reset\n"); fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1390,7 +1363,6 @@ sb_exec_command(sb_dsp_t *dsp) if (dsp->espcm_mode != ESPCM_1 || (dsp->sb_8_enable && dsp->sb_8_pause)) { - pclog("ess: ESPCM FIFO reset\n"); fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1405,7 +1377,6 @@ sb_exec_command(sb_dsp_t *dsp) if (dsp->espcm_mode != ESPCM_4E || (dsp->sb_8_enable && dsp->sb_8_pause)) { - pclog("ess: ESPCM FIFO reset\n"); fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1652,11 +1623,9 @@ sb_exec_command(sb_dsp_t *dsp) case 0xF2: /* Trigger 8-bit IRQ */ sb_dsp_log("Trigger IRQ\n"); if (IS_ESS(dsp)) { - if (timer_is_enabled(&dsp->irq_timer)) - pclog("F2 already written\n"); - else { + if (!timer_is_enabled(&dsp->irq_timer)) + { timer_set_delay_u64(&dsp->irq_timer, (100ULL * TIMER_USEC)); - pclog("F2 written\n"); } } else { sb_irq(dsp, 1); @@ -1665,7 +1634,6 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0xF3: /* Trigger 16-bit IRQ */ sb_dsp_log("Trigger IRQ\n"); - sb_irq(dsp, 0); dsp->ess_irq_generic = true; break; case 0xF8: @@ -1812,10 +1780,6 @@ sb_read(uint16_t a, void *priv) uint8_t ret = 0x00; /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ - if ((a & 0xF) == 0x9 || (a & 0xF) == 0xB) - { - pclog("ess: Read-Sequence-Key? port 0x%X", a); - } if (dsp->sb_type < SB16) { /* Exception: ESS AudioDrive does not alias port base+0xf */ @@ -1880,10 +1844,6 @@ sb_read(uint16_t a, void *priv) break; case 0xE: /* Read data ready */ dsp->irq_update(dsp->irq_priv, 0); - if (dsp->sb_irq8 || dsp->sb_irq16) - { - pclog("sb: IRQ acknowledged\n"); - } dsp->sb_irq8 = dsp->sb_irq16 = 0; dsp->ess_irq_generic = dsp->ess_irq_dmactr = false; /* Only bit 7 is defined but aztech diagnostics fail if the others are set. Keep the original behavior to not interfere with what's already working. */ @@ -1898,10 +1858,6 @@ sb_read(uint16_t a, void *priv) case 0xF: /* 16-bit ack */ if (!IS_ESS(dsp)) { - if (dsp->sb_irq16) - { - pclog("sb: 16-bit IRQ acknowledged"); - } dsp->sb_irq16 = 0; if (!dsp->sb_irq8) dsp->irq_update(dsp->irq_priv, 0); @@ -2107,7 +2063,6 @@ sb_ess_finish_dma(sb_dsp_t *dsp) return; ESSreg(0xB8) &= ~0x01; dma_set_drq(dsp->sb_8_dmanum, 0); - pclog("ess: DMA finished"); } void @@ -2615,7 +2570,6 @@ pollsb(void *priv) { sb_irq(dsp, 1); dsp->ess_irq_dmactr = true; - pclog("IRQ fired via ESS DMA counter, next IRQ in %d samples\n", sb_ess_get_dma_len(dsp)); } } uint32_t temp = dsp->ess_dma_counter & 0xffff; From f2091e349006ecc0118ce89557d3a1186f83f2b0 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 21:36:41 -0300 Subject: [PATCH 770/936] Cleanup: removing broken recording functionality --- src/sound/snd_ess.c | 103 +------------------------------------------- 1 file changed, 2 insertions(+), 101 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 44106fa83..b07c2d18f 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -66,7 +66,7 @@ static const double sb_att_1p4dbstep_4bits[] = { 10603.0, 12458.0, 14637.0, 17196.0, 20204.0, 23738.0, 27889.0, 32767.0 }; -/* Attenuation table for 4-bit mixer avolume. +/* Attenuation table for 4-bit mixer volume. * The last step is a jump to -48 dB. */ static const double sb_att_2dbstep_4bits[] = { 164.0, 1304.0, 1641.0, 2067.0, 2602.0, 3276.0, 4125.0, 5192.0, @@ -104,14 +104,8 @@ typedef struct ess_mixer_t { uint8_t index; uint8_t regs[256]; - uint8_t ess_id_str[256]; + uint8_t ess_id_str[4]; uint8_t ess_id_str_pos; - -#if 0 - int record_pos_write_cd; - double record_pos_write_cd_sigma; - int record_pos_write_music; -#endif } ess_mixer_t; typedef struct ess_t { @@ -448,12 +442,6 @@ ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) { ess_t *ess = (ess_t *) priv; const ess_mixer_t *mixer = &ess->mixer_sbpro; -#if 0 - int rec_pos = ess->mixer_sbpro.record_pos_write_music; - int c_record; - int32_t in_l; - int32_t in_r; -#endif double out_l = 0.0; double out_r = 0.0; const int32_t *opl_buf = NULL; @@ -475,52 +463,10 @@ ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) out_l *= mixer->master_l; out_r *= mixer->master_r; -#if 0 - // Pull input after applying mixer's master volume scaling - in_l = (mixer->input_selector & INPUT_MIXER_L) ? ((int32_t) out_l) : 0; - in_r = (mixer->input_selector & INPUT_MIXER_R) ? ((int32_t) out_l) : 0; - - if (ess->dsp.sb_enable_i) { - // NOTE: this is nearest-neighbor sampling. This is gonna generate aliasing like HECK. Is this what the real card does? - c_record = rec_pos + ((c * ess->dsp.sb_freq) / MUSIC_FREQ); - - ess->dsp.record_buffer[c_record & 0xfffe] += in_l; - ess->dsp.record_buffer[(c_record & 0xfffe) + 1] += in_r; - - if (ess->dsp.record_buffer[c_record & 0xfffe] < -32768) - { - ess->dsp.record_buffer[c_record & 0xfffe] = -32768; - } - else if (ess->dsp.record_buffer[c_record & 0xfffe] > 32767) - { - ess->dsp.record_buffer[c_record & 0xfffe] = 32767; - } - - if (ess->dsp.record_buffer[(c_record & 0xfffe) + 1] < -32768) - { - ess->dsp.record_buffer[(c_record & 0xfffe) + 1] = -32768; - } - else if (ess->dsp.record_buffer[(c_record & 0xfffe) + 1] > 32767) - { - ess->dsp.record_buffer[(c_record & 0xfffe) + 1] = 32767; - } - } -#endif - buffer[c] += (int32_t) out_l; buffer[c + 1] += (int32_t) out_r; } -#if 0 - ess->mixer_sbpro.record_pos_write_music += ((len * 2 * ess->dsp.sb_freq) / MUSIC_FREQ); - ess->mixer_sbpro.record_pos_write_music &= 0xfffe; - - if (ess->mixer_sbpro.record_pos_write_music < ess->mixer_sbpro.record_pos_write_cd) - { - ess->dsp.record_pos_write = ess->mixer_sbpro.record_pos_write_music; - } -#endif - ess->opl.reset_buffer(ess->opl.priv); } @@ -530,51 +476,11 @@ ess_filter_cd_audio(int channel, double *buffer, void *priv) const ess_t *ess = (ess_t *) priv; const ess_mixer_t *mixer = &ess->mixer_sbpro; double c; -#if 0 - double rec_pos = ess->mixer_sbpro.record_pos_write_cd; - double rec_pos_sigma = ess->mixer_sbpro.record_pos_write_cd_sigma; - int c_record; - int selector = channel ? INPUT_MIXER_R : INPUT_MIXER_L; - int rec_buf_pos; - int32_t in; -#endif double cd = channel ? mixer->cd_r : mixer->cd_l; double master = channel ? mixer->master_r : mixer->master_l; c = (*buffer * cd) / 3.0; *buffer = c * master; -#if 0 - in = (mixer->input_selector & selector) ? (int32_t)(c * master) : 0; - - if (ess->dsp.sb_enable_i) - { - // NOTE: this is nearest-neighbor sampling. This is gonna generate aliasing like HECK. Is this what the real card does? - c_record = (int)(rec_pos + rec_pos_sigma); - rec_buf_pos = channel ? ((c_record & 0xfffe) + 1) : (c_record & 0xfffe); - - ess->dsp.record_buffer[rec_buf_pos] += in; - - if (ess->dsp.record_buffer[rec_buf_pos] < -32768) - { - ess->dsp.record_buffer[rec_buf_pos] = -32768; - } - else if (ess->dsp.record_buffer[rec_buf_pos] > 32767) - { - ess->dsp.record_buffer[rec_buf_pos] = 32767; - } - } - - ess->mixer_sbpro.record_pos_write_cd += ((2 * (double)ess->dsp.sb_freq) / MUSIC_FREQ) + rec_pos_sigma; - ess->mixer_sbpro.record_pos_write_cd &= ~1; - ess->mixer_sbpro.record_pos_write_cd_sigma = (double)rec_pos + ((2 * (double)ess->dsp.sb_freq) / MUSIC_FREQ) + rec_pos_sigma - ess->mixer_sbpro.record_pos_write_cd; - - ess->mixer_sbpro.record_pos_write_cd &= 0xfffe; - - if (ess->mixer_sbpro.record_pos_write_cd < ess->mixer_sbpro.record_pos_write_music) - { - ess->dsp.record_pos_write = ess->mixer_sbpro.record_pos_write_cd; - } -#endif } static void * @@ -634,11 +540,6 @@ ess_1688_init(UNUSED(const device_t *info)) ess->mixer_sbpro.ess_id_str[3] = addr & 0xff; } -#if 0 - ess->mixer_sbpro.record_pos_write_cd = ess->dsp.record_pos_write; - ess->mixer_sbpro.record_pos_write_music = ess->dsp.record_pos_write; -#endif - ess->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); mpu401_init(ess->mpu, 0, -1, M_UART, 1); sb_dsp_set_mpu(&ess->dsp, ess->mpu); From 81029da95024678d7378d1fda1401cda2f063b8b Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 21:46:27 -0300 Subject: [PATCH 771/936] Cleanup: rolling back extraneous change in cpu.h --- src/cpu/cpu.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index f2e1242df..16a9eba10 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -21,14 +21,7 @@ #ifndef EMU_CPU_H #define EMU_CPU_H -#ifndef NO_SOFTFLOAT_INCLUDE #include "softfloat/softfloat.h" -#else -typedef struct floatx80 { // leave alignment to compiler - uint64_t exp; - uint16_t fraction; -} floatx80; -#endif enum { FPU_NONE, From ad616723859a1e4824fae0687958bc52a5fef943 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 22:21:27 -0300 Subject: [PATCH 772/936] Rename ESFMu flag type to ebit --- src/sound/esfmu/esfm.h | 96 +++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/src/sound/esfmu/esfm.h b/src/sound/esfmu/esfm.h index eda8bcbb3..766c7312d 100644 --- a/src/sound/esfmu/esfm.h +++ b/src/sound/esfmu/esfm.h @@ -74,7 +74,7 @@ int16_t ESFM_get_channel_output_native(esfm_chip *chip, int channel_idx); // These are fake types just for syntax sugar. // Beware of their underlying types when reading/writing to them. -typedef uint8_t flag; +typedef uint8_t ebit; typedef uint8_t uint2; typedef uint8_t uint3; typedef uint8_t uint4; @@ -110,7 +110,7 @@ typedef struct _esfm_write_buf uint64_t timestamp; uint16_t address; uint8_t data; - flag valid; + ebit valid; } esfm_write_buf; @@ -137,16 +137,16 @@ typedef struct _esfm_slot_internal uint19 phase_acc; uint10 phase_out; - flag phase_reset; - flag *key_on; - flag key_on_gate; + ebit phase_reset; + ebit *key_on; + ebit key_on_gate; uint2 eg_state; - flag eg_delay_run; - flag eg_delay_transitioned_10; - flag eg_delay_transitioned_10_gate; - flag eg_delay_transitioned_01; - flag eg_delay_transitioned_01_gate; + ebit eg_delay_run; + ebit eg_delay_transitioned_10; + ebit eg_delay_transitioned_10_gate; + ebit eg_delay_transitioned_01; + ebit eg_delay_transitioned_01_gate; uint16 eg_delay_counter; uint16 eg_delay_counter_compare; @@ -178,18 +178,18 @@ struct _esfm_slot uint4 sustain_lvl; uint4 release_rate; - flag tremolo_en; - flag tremolo_deep; - flag vibrato_en; - flag vibrato_deep; - flag emu_connection_typ; - flag env_sustaining; - flag ksr; + ebit tremolo_en; + ebit tremolo_deep; + ebit vibrato_en; + ebit vibrato_deep; + ebit emu_connection_typ; + ebit env_sustaining; + ebit ksr; uint2 ksl; uint3 env_delay; // overlaps with env_delay bit 0 // TODO: check if emu mode only uses this, or if it actually overwrites the channel field used by native mode - flag emu_key_on; + ebit emu_key_on; // Internal state esfm_slot_internal in; @@ -201,11 +201,11 @@ struct _esfm_channel esfm_slot slots[4]; uint5 channel_idx; int16 output[2]; - flag key_on; - flag emu_mode_4op_enable; + ebit key_on; + ebit emu_mode_4op_enable; // Only for 17th and 18th channels - flag key_on_2; - flag emu_mode_4op_enable_2; + ebit key_on_2; + ebit emu_mode_4op_enable_2; }; #define ESFM_WRITEBUF_SIZE 1024 @@ -217,66 +217,66 @@ struct _esfm_chip int32 output_accm[2]; uint16 addr_latch; - flag emu_wavesel_enable; - flag emu_newmode; - flag native_mode; + ebit emu_wavesel_enable; + ebit emu_newmode; + ebit native_mode; - flag keyscale_mode; + ebit keyscale_mode; // Global state uint36 eg_timer; uint10 global_timer; uint8 eg_clocks; - flag eg_tick; - flag eg_timer_overflow; + ebit eg_tick; + ebit eg_timer_overflow; uint8 tremolo; uint8 tremolo_pos; uint8 vibrato_pos; uint23 lfsr; - flag rm_hh_bit2; - flag rm_hh_bit3; - flag rm_hh_bit7; - flag rm_hh_bit8; - flag rm_tc_bit3; - flag rm_tc_bit5; + ebit rm_hh_bit2; + ebit rm_hh_bit3; + ebit rm_hh_bit7; + ebit rm_hh_bit8; + ebit rm_tc_bit3; + ebit rm_tc_bit5; // 0xbd register in emulation mode, exposed in 0x4bd in native mode // ("bass drum" register) uint8 emu_rhy_mode_flags; - flag emu_vibrato_deep; - flag emu_tremolo_deep; + ebit emu_vibrato_deep; + ebit emu_tremolo_deep; double timer_accumulator[2]; uint8 timer_reload[2]; uint8 timer_counter[2]; - flag timer_enable[2]; - flag timer_mask[2]; - flag timer_overflow[2]; - flag irq_bit; + ebit timer_enable[2]; + ebit timer_mask[2]; + ebit timer_overflow[2]; + ebit irq_bit; // -- Test bits (NOT IMPLEMENTED) -- // Halts the envelope generators from advancing. Written on bit 0, read back from bit 5. - flag test_bit_w0_r5_eg_halt; + ebit test_bit_w0_r5_eg_halt; /* * Activates some sort of waveform test mode that amplifies the output volume greatly * and continuously shifts the waveform table downwards, possibly also outputting the * waveform's derivative? (it's so weird!) */ - flag test_bit_1_distort; + ebit test_bit_1_distort; // Seems to do nothing. - flag test_bit_2; + ebit test_bit_2; // Seems to do nothing. - flag test_bit_3; + ebit test_bit_3; // Appears to attenuate the output by about 3 dB. - flag test_bit_4_attenuate; + ebit test_bit_4_attenuate; // Written on bit 5, read back from bit 0. Seems to do nothing. - flag test_bit_w5_r0; + ebit test_bit_w5_r0; // Resets all phase generators and holds them in the reset state while this bit is set. - flag test_bit_6_phase_stop_reset; + ebit test_bit_6_phase_stop_reset; // Seems to do nothing. - flag test_bit_7; + ebit test_bit_7; esfm_write_buf write_buf[ESFM_WRITEBUF_SIZE]; size_t write_buf_start; From 8bfcfec280c3c531bfded21e59733616acf193ac Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 23:07:12 -0300 Subject: [PATCH 773/936] Cleanup: clang-format --- src/sound/snd_ess.c | 226 +++++++------- src/sound/snd_opl_esfm.c | 30 +- src/sound/snd_sb_dsp.c | 645 +++++++++++++++++---------------------- 3 files changed, 392 insertions(+), 509 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index b07c2d18f..38610c6ee 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -13,7 +13,7 @@ * Authors: Sarah Walker, * Miran Grca, * TheCollector1995, - * Cacodemon345, + * Cacodemon345, * Kagamiin~, * * Copyright 2008-2020 Sarah Walker. @@ -49,7 +49,6 @@ #include <86box/snd_sb.h> #include <86box/plat_unused.h> - // clang-format off static const double sb_att_4dbstep_3bits[] = { 164.0, 2067.0, 3276.0, 5193.0, 8230.0, 13045.0, 20675.0, 32767.0 @@ -74,7 +73,6 @@ static const double sb_att_2dbstep_4bits[] = { }; // clang-format on - /* SB PRO */ typedef struct ess_mixer_t { double master_l; @@ -109,21 +107,22 @@ typedef struct ess_mixer_t { } ess_mixer_t; typedef struct ess_t { - uint8_t mixer_enabled; - fm_drv_t opl; - sb_dsp_t dsp; + uint8_t mixer_enabled; + fm_drv_t opl; + sb_dsp_t dsp; ess_mixer_t mixer_sbpro; - mpu_t *mpu; - void *gameport; + mpu_t *mpu; + void *gameport; uint16_t gameport_addr; - void *opl_mixer; - void (*opl_mix)(void*, double*, double*); + void *opl_mixer; + void (*opl_mix)(void *, double *, double *); } ess_t; -static double ess_mixer_get_vol_4bit(uint8_t vol) +static double +ess_mixer_get_vol_4bit(uint8_t vol) { return sb_att_2dbstep_4bits[vol & 0x0F] / 32767.0; } @@ -137,8 +136,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) if (!(addr & 1)) { mixer->index = val; mixer->regs[0x01] = val; - if (val == 0x40) - { + if (val == 0x40) { mixer->ess_id_str_pos = 0; } } else { @@ -153,10 +151,10 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) /* Initialize ESS regs. */ mixer->regs[0x14] = mixer->regs[0x32] = 0x88; - mixer->regs[0x36] = 0x88; - mixer->regs[0x38] = 0x88; - mixer->regs[0x3a] = 0x00; - mixer->regs[0x3e] = 0x00; + mixer->regs[0x36] = 0x88; + mixer->regs[0x38] = 0x88; + mixer->regs[0x3a] = 0x00; + mixer->regs[0x3e] = 0x00; sb_dsp_set_stereo(&ess->dsp, mixer->regs[0x0e] & 2); } else { @@ -171,24 +169,24 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) break; case 0x0A: - { - uint8_t mic_vol_2bit = (mixer->regs[0x0a] >> 1) & 0x3; - mixer->mic_l = mixer->mic_r = sb_att_7dbstep_2bits[mic_vol_2bit] / 32768.0; - mixer->regs[0x1A] = mic_vol_2bit | (mic_vol_2bit << 2) | (mic_vol_2bit << 4) | (mic_vol_2bit << 6); - break; - } + { + uint8_t mic_vol_2bit = (mixer->regs[0x0a] >> 1) & 0x3; + mixer->mic_l = mixer->mic_r = sb_att_7dbstep_2bits[mic_vol_2bit] / 32768.0; + mixer->regs[0x1A] = mic_vol_2bit | (mic_vol_2bit << 2) | (mic_vol_2bit << 4) | (mic_vol_2bit << 6); + break; + } case 0x0C: switch (mixer->regs[0x0C] & 6) { - case 2: - mixer->input_selector = INPUT_CD_L | INPUT_CD_R; - break; - case 6: - mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; - break; - default: - mixer->input_selector = INPUT_MIC; - break; + case 2: + mixer->input_selector = INPUT_CD_L | INPUT_CD_R; + break; + case 6: + mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; + break; + default: + mixer->input_selector = INPUT_MIC; + break; } break; @@ -202,20 +200,13 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) break; case 0x1C: - if ((mixer->regs[0x1C] & 0x07) == 0x07) - { + if ((mixer->regs[0x1C] & 0x07) == 0x07) { mixer->input_selector = INPUT_MIXER_L | INPUT_MIXER_R; - } - else if ((mixer->regs[0x1C] & 0x07) == 0x06) - { + } else if ((mixer->regs[0x1C] & 0x07) == 0x06) { mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; - } - else if ((mixer->regs[0x1C] & 0x06) == 0x02) - { + } else if ((mixer->regs[0x1C] & 0x06) == 0x02) { mixer->input_selector = INPUT_CD_L | INPUT_CD_R; - } - else if ((mixer->regs[0x1C] & 0x02) == 0) - { + } else if ((mixer->regs[0x1C] & 0x02) == 0) { mixer->input_selector = INPUT_MIC; } break; @@ -255,26 +246,22 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->regs[mixer->index] &= ~0x8; break; - case 0x40: { - /* TODO: Implement "Read-Sequence-Key" method of software address selection - * (needed for ESSCFG.EXE to work properly) */ - + case 0x40: + { uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] << 1) & 0x30); gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); - if (0) - { + if (0) { /* Not on ES1688. */ io_removehandler(0x0388, 0x0004, - ess->opl.read, NULL, NULL, - ess->opl.write, NULL, NULL, - ess->opl.priv); - if ((mixer->regs[0x40] & 0x1) != 0) - { + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + if ((mixer->regs[0x40] & 0x1) != 0) { io_sethandler(0x0388, 0x0004, - ess->opl.read, NULL, NULL, - ess->opl.write, NULL, NULL, - ess->opl.priv); + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); } } switch ((mixer->regs[0x40] >> 5) & 0x7) { @@ -315,7 +302,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) } default: - //pclog("ess: Unknown mixer register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + // pclog("ess: Unknown mixer register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } } @@ -375,21 +362,18 @@ ess_mixer_read(uint16_t addr, void *priv) case 0x40: - if (ess->dsp.sb_subtype != SB_SUBTYPE_ESS_ES1688) - { + if (ess->dsp.sb_subtype != SB_SUBTYPE_ESS_ES1688) { uint8_t val = mixer->ess_id_str[mixer->ess_id_str_pos]; mixer->ess_id_str_pos++; if (mixer->ess_id_str_pos >= 4) mixer->ess_id_str_pos = 0; return val; - } - else - { + } else { return mixer->regs[mixer->index]; } default: - //pclog("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + // pclog("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } @@ -406,10 +390,10 @@ ess_mixer_reset(ess_t *ess) void ess_get_buffer_sbpro(int32_t *buffer, int len, void *priv) { - ess_t *ess = (ess_t *) priv; - const ess_mixer_t *mixer = &ess->mixer_sbpro; - double out_l = 0.0; - double out_r = 0.0; + ess_t *ess = (ess_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_sbpro; + double out_l = 0.0; + double out_r = 0.0; sb_dsp_update(&ess->dsp); @@ -440,11 +424,11 @@ ess_get_buffer_sbpro(int32_t *buffer, int len, void *priv) void ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) { - ess_t *ess = (ess_t *) priv; - const ess_mixer_t *mixer = &ess->mixer_sbpro; - double out_l = 0.0; - double out_r = 0.0; - const int32_t *opl_buf = NULL; + ess_t *ess = (ess_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_sbpro; + double out_l = 0.0; + double out_r = 0.0; + const int32_t *opl_buf = NULL; opl_buf = ess->opl.update(ess->opl.priv); @@ -473,13 +457,13 @@ ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) void ess_filter_cd_audio(int channel, double *buffer, void *priv) { - const ess_t *ess = (ess_t *) priv; - const ess_mixer_t *mixer = &ess->mixer_sbpro; - double c; - double cd = channel ? mixer->cd_r : mixer->cd_l; - double master = channel ? mixer->master_r : mixer->master_l; + const ess_t *ess = (ess_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_sbpro; + double c; + double cd = channel ? mixer->cd_r : mixer->cd_l; + double master = channel ? mixer->master_r : mixer->master_l; - c = (*buffer * cd) / 3.0; + c = (*buffer * cd) / 3.0; *buffer = c * master; } @@ -492,8 +476,8 @@ ess_1688_init(UNUSED(const device_t *info)) 2x6, 2xA, 2xC, 2xE -> DSP chip 2x8, 2x9, 388 and 389 FM chip (9 voices) 2x0+10 to 2x0+13 CDROM interface. */ - ess_t *ess = calloc(sizeof(ess_t), 1); - uint16_t addr = device_get_config_hex16("base"); + ess_t *ess = calloc(sizeof(ess_t), 1); + uint16_t addr = device_get_config_hex16("base"); fm_driver_get(FM_ESFM, &ess->opl); @@ -544,7 +528,7 @@ ess_1688_init(UNUSED(const device_t *info)) mpu401_init(ess->mpu, 0, -1, M_UART, 1); sb_dsp_set_mpu(&ess->dsp, ess->mpu); - ess->gameport = gameport_add(&gameport_pnp_device); + ess->gameport = gameport_add(&gameport_pnp_device); ess->gameport_addr = 0x200; gameport_remap(ess->gameport, ess->gameport_addr); @@ -568,95 +552,97 @@ ess_speed_changed(void *priv) sb_dsp_speed_changed(&ess->dsp); } +// clang-format off static const device_config_t ess_config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, .default_string = "", - .default_int = 0x220, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .default_int = 0x220, + .file_filter = "", + .spinner = { 0 }, + .selection = { { .description = "0x220", - .value = 0x220 + .value = 0x220 }, { .description = "0x240", - .value = 0x240 + .value = 0x240 }, { .description = "" } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .default_int = 5, + .file_filter = "", + .spinner = { 0 }, + .selection = { { .description = "IRQ 2", - .value = 2 + .value = 2 }, { .description = "IRQ 5", - .value = 5 + .value = 5 }, { .description = "IRQ 7", - .value = 7 + .value = 7 }, { .description = "IRQ 10", - .value = 10 + .value = 10 }, { .description = "" } } }, { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, + .name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, .default_string = "", - .default_int = 1, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .default_int = 1, + .file_filter = "", + .spinner = { 0 }, + .selection = { { .description = "DMA 0", - .value = 0 + .value = 0 }, { .description = "DMA 1", - .value = 1 + .value = 1 }, { .description = "DMA 3", - .value = 3 + .value = 3 }, { .description = "" } } }, { - .name = "opl", - .description = "Enable OPL", - .type = CONFIG_BINARY, + .name = "opl", + .description = "Enable OPL", + .type = CONFIG_BINARY, .default_string = "", - .default_int = 1 + .default_int = 1 }, { - .name = "receive_input", - .description = "Receive input (SB MIDI)", - .type = CONFIG_BINARY, + .name = "receive_input", + .description = "Receive input (SB MIDI)", + .type = CONFIG_BINARY, .default_string = "", - .default_int = 1 + .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } }; +// clang-format on const device_t ess_1688_device = { .name = "ESS Technology ES1688", diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index 174830523..c36ec4160 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -7,8 +7,8 @@ * This file is part of the 86Box distribution. * * ESFMu ESFM emulator. - * - * + * + * * Authors: Fred N. van Kempen, * Miran Grca, * Alexey Khokholov (Nuke.YKT) @@ -29,19 +29,18 @@ #include "esfmu/esfm.h" #define HAVE_STDARG_H -#define NO_SOFTFLOAT_INCLUDE #include <86box/86box.h> #include <86box/sound.h> #include <86box/device.h> #include <86box/timer.h> #include <86box/snd_opl.h> -#define RSM_FRAC 10 +#define RSM_FRAC 10 typedef struct { esfm_chip opl; - int8_t flags; - int8_t pad; + int8_t flags; + int8_t pad; uint16_t port; uint8_t status; @@ -180,7 +179,7 @@ static void * esfm_drv_init(const device_t *info) { esfm_drv_t *dev = (esfm_drv_t *) calloc(1, sizeof(esfm_drv_t)); - dev->flags = FLAG_CYCLES | FLAG_OPL3; + dev->flags = FLAG_CYCLES | FLAG_OPL3; /* Initialize the ESFMu object. */ ESFM_init(&dev->opl); @@ -207,8 +206,8 @@ esfm_drv_update(void *priv) return dev->buffer; esfm_drv_generate_stream(dev, - &dev->buffer[dev->pos * 2], - music_pos_global - dev->pos); + &dev->buffer[dev->pos * 2], + music_pos_global - dev->pos); for (; dev->pos < music_pos_global; dev->pos++) { dev->buffer[dev->pos * 2] /= 2; @@ -218,7 +217,6 @@ esfm_drv_update(void *priv) return dev->buffer; } - static void esfm_drv_reset_buffer(void *priv) { @@ -239,8 +237,7 @@ esfm_drv_read(uint16_t port, void *priv) uint8_t ret = 0xff; - switch (port & 0x0003) - { + switch (port & 0x0003) { case 0x0000: ret = dev->status; if (dev->status & STAT_TMR_OVER) @@ -248,8 +245,7 @@ esfm_drv_read(uint16_t port, void *priv) break; case 0x0001: ret = ESFM_read_port(&dev->opl, port & 3); - switch (dev->opl.addr_latch & 0x5ff) - { + switch (dev->opl.addr_latch & 0x5ff) { case 0x402: ret = dev->timer_count[0]; break; @@ -277,14 +273,12 @@ esfm_drv_write_buffered(esfm_drv_t *dev, uint8_t val) ESFM_write_reg_buffered_fast(&dev->opl, dev->opl.addr_latch, val); - if (dev->opl.native_mode) - { + if (dev->opl.native_mode) { p -= 0x400; p &= 0x1ff; } - switch (p) - { + switch (p) { case 0x002: /* Timer 1 */ dev->timer_count[0] = val; esfm_log("Timer 0 count now: %i\n", dev->timer_count[0]); diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 03a6ba4ba..5290d6bc5 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -120,6 +120,7 @@ uint8_t adjustMap2[24] = { 252, 0, 252, 0 }; +// clang-format off /* Upper half only used for ESPCM_3 mode. */ /* TODO: Extract actual table (or exact ranges + range interpolation algo, whatever it is) from chip, someday, somehow. * This current table is part software reverse engineering, part guesswork/extrapolation. @@ -235,6 +236,7 @@ uint16_t espcm3_dpcm_tables[1024] = 5, 7, 8, 9, 10, 11, 12, 270, 5, 7, 8, 9, 10, 11, 12, 270, 6, 7, 8, 9, 10, 11, 13, 271, 6, 7, 8, 9, 10, 11, 13, 15 }; +// clang-format on double low_fir_sb16_coef[4][SB16_NCoef]; @@ -387,8 +389,7 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) } /* NOTE: not on ES1688, apparently; investigate on ES1868 */ - if (IS_ESS(dsp) && dsp->sb_subtype != SB_SUBTYPE_ESS_ES1688) - { + if (IS_ESS(dsp) && dsp->sb_subtype != SB_SUBTYPE_ESS_ES1688) { /* TODO: Investigate real hardware for this (the ES1887 datasheet documents this bit somewhat oddly.) */ if (dsp->ess_playback_mode && bit <= 1 && set && !masked) { if (!(ESSreg(0xB1) & 0x40)) // if ESS playback, and IRQ disabled, do not fire @@ -523,17 +524,19 @@ sb_add_data(sb_dsp_t *dsp, uint8_t v) dsp->sb_read_wp &= 0xff; } -static unsigned int sb_ess_get_dma_counter(sb_dsp_t *dsp) +static unsigned int +sb_ess_get_dma_counter(sb_dsp_t *dsp) { unsigned int c; - c = (unsigned int)ESSreg(0xA5) << 8U; - c |= (unsigned int)ESSreg(0xA4); + c = (unsigned int) ESSreg(0xA5) << 8U; + c |= (unsigned int) ESSreg(0xA4); return c; } -static unsigned int sb_ess_get_dma_len(sb_dsp_t *dsp) +static unsigned int +sb_ess_get_dma_len(sb_dsp_t *dsp) { return 0x10000U - sb_ess_get_dma_counter(dsp); } @@ -605,11 +608,11 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) } void -sb_start_dma_ess(sb_dsp_t* dsp) +sb_start_dma_ess(sb_dsp_t *dsp) { - uint8_t real_format = 0; + uint8_t real_format = 0; dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); - uint32_t len = sb_ess_get_dma_len(dsp); + uint32_t len = sb_ess_get_dma_len(dsp); if (IS_ESS(dsp)) { dma_set_drq(dsp->sb_8_dmanum, 0); @@ -627,26 +630,28 @@ sb_start_dma_ess(sb_dsp_t* dsp) } void -sb_stop_dma_ess(sb_dsp_t* dsp) +sb_stop_dma_ess(sb_dsp_t *dsp) { dsp->sb_8_enable = dsp->sb_16_enable = 0; dma_set_drq(dsp->sb_16_8_dmanum, 0); dma_set_drq(dsp->sb_8_dmanum, 0); } -static void sb_ess_update_dma_status(sb_dsp_t* dsp) +static void +sb_ess_update_dma_status(sb_dsp_t *dsp) { - bool dma_en = (ESSreg(0xB8) & 1)?true:false; + bool dma_en = (ESSreg(0xB8) & 1) ? true : false; // if the DRQ is disabled, do not start if (!(ESSreg(0xB2) & 0x40)) dma_en = false; if (dma_en) { - if (!dsp->sb_8_enable && !dsp->sb_16_enable) sb_start_dma_ess(dsp); - } - else { - if (dsp->sb_8_enable || dsp->sb_16_enable) sb_stop_dma_ess(dsp); + if (!dsp->sb_8_enable && !dsp->sb_16_enable) + sb_start_dma_ess(dsp); + } else { + if (dsp->sb_8_enable || dsp->sb_16_enable) + sb_stop_dma_ess(dsp); } } @@ -682,8 +687,8 @@ int sb_16_read_dma(void *priv) { const sb_dsp_t *dsp = (sb_dsp_t *) priv; - int temp, ret = 0; - int dma_flags, dma_ch = dsp->sb_16_dmanum; + int temp, ret = 0; + int dma_flags, dma_ch = dsp->sb_16_dmanum; if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate) ret = dma_channel_read(dma_ch); @@ -697,7 +702,7 @@ sb_16_read_dma(void *priv) /* High DMA channel disabled, always use the first 8-bit channel. */ dma_ch = dsp->sb_8_dmanum; temp = dma_channel_read(dma_ch); - ret = temp; + ret = temp; if ((temp != DMA_NODATA) && !(temp & DMA_OVER)) { temp = dma_channel_read(dma_ch); if (temp == DMA_NODATA) @@ -706,7 +711,7 @@ sb_16_read_dma(void *priv) dma_flags = temp & DMA_OVER; temp &= ~DMA_OVER; ret |= (temp << 8) | dma_flags; - } + } } } @@ -717,9 +722,9 @@ int sb_16_write_dma(void *priv, uint16_t val) { const sb_dsp_t *dsp = (sb_dsp_t *) priv; - int temp, ret = 0; - int dma_ch = dsp->sb_16_dmanum; - + int temp, ret = 0; + int dma_ch = dsp->sb_16_dmanum; + if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate) ret = dma_channel_write(dma_ch, val) == DMA_NODATA; else { @@ -732,10 +737,10 @@ sb_16_write_dma(void *priv, uint16_t val) /* High DMA channel disabled, always use the first 8-bit channel. */ dma_ch = dsp->sb_8_dmanum; temp = dma_channel_write(dma_ch, val & 0xff); - ret = temp; + ret = temp; if ((temp != DMA_NODATA) && (temp != DMA_OVER)) { temp = dma_channel_write(dma_ch, val >> 8); - ret = temp; + ret = temp; } } @@ -747,28 +752,40 @@ sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy) { uint8_t t = 0x00; /* IRQ control */ - if (legacy) - { + if (legacy) { t |= 0x80; } switch (dsp->sb_irqnum) { - case 9: t |= 0x0; break; - case 5: t |= 0x5; break; - case 7: t |= 0xA; break; - case 10: t |= 0xF; break; + case 9: + t |= 0x0; + break; + case 5: + t |= 0x5; + break; + case 7: + t |= 0xA; + break; + case 10: + t |= 0xF; + break; } ESSreg(0xB1) = (ESSreg(0xB1) & 0xF0) | t; /* DRQ control */ t = 0x00; - if (legacy) - { + if (legacy) { t |= 0x80; } switch (dsp->sb_8_dmanum) { - case 0: t |= 0x5; break; - case 1: t |= 0xA; break; - case 3: t |= 0xF; break; + case 0: + t |= 0x5; + break; + case 1: + t |= 0xA; + break; + case 3: + t |= 0xF; + break; } ESSreg(0xB2) = (ESSreg(0xB2) & 0xF0) | t; } @@ -830,10 +847,11 @@ sb_dsp_setdma16_translate(sb_dsp_t *dsp, int translate) dsp->sb_16_dma_translate = translate; } -static void sb_ess_update_reg_a2(sb_dsp_t *dsp, uint8_t val) +static void +sb_ess_update_reg_a2(sb_dsp_t *dsp, uint8_t val) { - double freq = (7160000.0 / (256.0 - ((double) val))) * 41.0; - int temp = (int) freq; + double freq = (7160000.0 / (256.0 - ((double) val))) * 41.0; + int temp = (int) freq; ESSreg(0xA2) = val; if (dsp->sb_freq != temp) @@ -843,7 +861,8 @@ static void sb_ess_update_reg_a2(sb_dsp_t *dsp, uint8_t val) /* TODO: Investigate ESS cards' filtering on real hardware as well. (DOSBox-X did it purely off some laptop's ESS chip, which isn't a good look.) */ -static void sb_ess_update_filter_freq(sb_dsp_t *dsp) +static void +sb_ess_update_filter_freq(sb_dsp_t *dsp) { double temp = (7160000.0 / (((((double) dsp->sb_freq) / 2.0) * 0.80) * 82.0)) - 256.0; @@ -855,7 +874,8 @@ static void sb_ess_update_filter_freq(sb_dsp_t *dsp) sb_ess_update_reg_a2(dsp, (uint8_t) temp); } -static uint8_t sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) +static uint8_t +sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) { switch (reg) { default: @@ -865,28 +885,31 @@ static uint8_t sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) return 0xFF; } -static void sb_ess_update_autolen(sb_dsp_t *dsp) { +static void +sb_ess_update_autolen(sb_dsp_t *dsp) +{ dsp->sb_8_autolen = dsp->sb_16_autolen = sb_ess_get_dma_len(dsp); } -static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) +static void +sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) { uint8_t chg = 0x00; switch (reg) { case 0xA1: /* Extended Mode Sample Rate Generator */ - { - double temp; - ESSreg(reg) = data; - if (data & 0x80) - dsp->sb_freq = 795500UL / (256ul - data); - else - dsp->sb_freq = 397700UL / (128ul - data); - temp = 1000000.0 / dsp->sb_freq; - dsp->sblatchi = dsp->sblatcho = TIMER_USEC * temp; - dsp->sb_timei = dsp->sb_timeo; - break; - } + { + double temp; + ESSreg(reg) = data; + if (data & 0x80) + dsp->sb_freq = 795500UL / (256ul - data); + else + dsp->sb_freq = 397700UL / (128ul - data); + temp = 1000000.0 / dsp->sb_freq; + dsp->sblatchi = dsp->sblatcho = TIMER_USEC * temp; + dsp->sb_timei = dsp->sb_timeo; + break; + } case 0xA2: /* Filter divider (effectively, a hardware lowpass filter under S/W control) */ sb_ess_update_reg_a2(dsp, data); break; @@ -909,7 +932,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) * 01=Stereo * 10=Mono * 11=Reserved */ - chg = ESSreg(reg) ^ data; + chg = ESSreg(reg) ^ data; ESSreg(reg) = data; if (chg & 0x3) { if (dsp->sb_16_enable || dsp->sb_8_enable) { @@ -926,45 +949,44 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) } break; - case 0xB1: /* Legacy Audio Interrupt Control */ + case 0xB1: /* Legacy Audio Interrupt Control */ ESSreg(reg) = (ESSreg(reg) & 0x0F) + (data & 0xF0); // lower 4 bits not writeable - switch (data & 0x0C) - { - case 0x00: - dsp->sb_irqnum = 2; - break; - case 0x04: - dsp->sb_irqnum = 5; - break; - case 0x08: - dsp->sb_irqnum = 7; - break; - case 0x0C: - dsp->sb_irqnum = 10; - break; + switch (data & 0x0C) { + case 0x00: + dsp->sb_irqnum = 2; + break; + case 0x04: + dsp->sb_irqnum = 5; + break; + case 0x08: + dsp->sb_irqnum = 7; + break; + case 0x0C: + dsp->sb_irqnum = 10; + break; } sb_ess_update_irq_drq_readback_regs(dsp, false); break; case 0xB2: /* DRQ Control */ - chg = ESSreg(reg) ^ data; + chg = ESSreg(reg) ^ data; ESSreg(reg) = (ESSreg(reg) & 0x0F) + (data & 0xF0); // lower 4 bits not writeable - switch (data & 0x0C) - { - case 0x00: - dsp->sb_8_dmanum = -1; - break; - case 0x04: - dsp->sb_8_dmanum = 0; - break; - case 0x08: - dsp->sb_8_dmanum = 1; - break; - case 0x0C: - dsp->sb_8_dmanum = 3; - break; + switch (data & 0x0C) { + case 0x00: + dsp->sb_8_dmanum = -1; + break; + case 0x04: + dsp->sb_8_dmanum = 0; + break; + case 0x08: + dsp->sb_8_dmanum = 1; + break; + case 0x0C: + dsp->sb_8_dmanum = 3; + break; } sb_ess_update_irq_drq_readback_regs(dsp, false); - if (chg & 0x40) sb_ess_update_dma_status(dsp); + if (chg & 0x40) + sb_ess_update_dma_status(dsp); break; case 0xB5: /* DAC Direct Access Holding (low) */ case 0xB6: /* DAC Direct Access Holding (high) */ @@ -980,7 +1002,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) * bit 2 FIFO 16-bit mode 1=Data is 16-bit * bit 1 Reserved Always write 0 * bit 0 Generate load signal */ - chg = ESSreg(reg) ^ data; + chg = ESSreg(reg) ^ data; ESSreg(reg) = data; if (chg & 4) @@ -1004,7 +1026,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) * 0=first DMA is write (for DAC) * bit 0 DMA xfer enable 1=DMA is allowed to proceed */ data &= 0xF; - chg = ESSreg(reg) ^ data; + chg = ESSreg(reg) ^ data; ESSreg(reg) = data; if (chg & 1) { @@ -1017,20 +1039,18 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) dsp->ess_reload_len = 1; } - if (chg & 0x4) - { - if (dsp->sb_16_enable) - { + if (chg & 0x4) { + if (dsp->sb_16_enable) { dsp->sb_16_autoinit = (ESSreg(0xB8) & 0x4) != 0; } - if (dsp->sb_8_enable) - { + if (dsp->sb_8_enable) { dsp->sb_8_autoinit = (ESSreg(0xB8) & 0x4) != 0; } } if (chg & 0xB) { - if (chg & 0xA) sb_stop_dma_ess(dsp); /* changing capture/playback direction? stop DMA to reinit */ + if (chg & 0xA) + sb_stop_dma_ess(dsp); /* changing capture/playback direction? stop DMA to reinit */ sb_ess_update_dma_status(dsp); } break; @@ -1044,7 +1064,7 @@ static void sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) break; default: - sb_dsp_log("UNKNOWN ESS register write reg=%02xh val=%02xh\n",reg,data); + sb_dsp_log("UNKNOWN ESS register write reg=%02xh val=%02xh\n", reg, data); break; } } @@ -1059,8 +1079,7 @@ sb_exec_command(sb_dsp_t *dsp) /* Update 8051 ram with the current DSP command. See https://github.com/joncampbell123/dosbox-x/issues/1044 */ - if (dsp->sb_type >= SB16) - { + if (dsp->sb_type >= SB16) { dsp->sb_8051_ram[0x20] = dsp->sb_command; } @@ -1068,27 +1087,17 @@ sb_exec_command(sb_dsp_t *dsp) if (dsp->sb_command == 0xC6 || dsp->sb_command == 0xC7) { dsp->ess_extended_mode = !!(dsp->sb_command == 0xC6); return; - } - else if (dsp->sb_command == 0xC2) - { + } else if (dsp->sb_command == 0xC2) { sb_ess_write_reg(dsp, 0xC3, dsp->sb_data[0]); - } - else if (dsp->sb_command == 0xC3) - { + } else if (dsp->sb_command == 0xC3) { sb_add_data(dsp, sb_ess_read_reg(dsp, 0xC3)); - } - else if (dsp->sb_command == 0xCE) - { + } else if (dsp->sb_command == 0xCE) { sb_add_data(dsp, sb_ess_read_reg(dsp, 0xCF)); - } - else if (dsp->sb_command == 0xCF) - { + } else if (dsp->sb_command == 0xCF) { sb_ess_write_reg(dsp, 0xCF, dsp->sb_data[0]); - } - else if (dsp->sb_command == 0xC0) { + } else if (dsp->sb_command == 0xC0) { sb_add_data(dsp, sb_ess_read_reg(dsp, dsp->sb_data[0])); - } - else if (dsp->sb_command < 0xC0 && dsp->ess_extended_mode) { + } else if (dsp->sb_command < 0xC0 && dsp->ess_extended_mode) { sb_ess_write_reg(dsp, dsp->sb_command, dsp->sb_data[0]); } return; @@ -1216,8 +1225,7 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; dsp->ess_dma_counter++; - if (dsp->sb_command == 0x17) - { + if (dsp->sb_command == 0x17) { dsp->sb_8_length--; dsp->ess_dma_counter++; } @@ -1330,11 +1338,9 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0x65: /* 4-bit ESPCM output with reference */ case 0x64: /* 4-bit ESPCM output */ - if (IS_ESS(dsp)) - { + if (IS_ESS(dsp)) { if (dsp->espcm_mode != ESPCM_4 - || (dsp->sb_8_enable && dsp->sb_8_pause)) - { + || (dsp->sb_8_enable && dsp->sb_8_pause)) { fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1344,11 +1350,9 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0x67: /* 3-bit ESPCM output with reference */ case 0x66: /* 3-bit ESPCM output */ - if (IS_ESS(dsp)) - { + if (IS_ESS(dsp)) { if (dsp->espcm_mode != ESPCM_3 - || (dsp->sb_8_enable && dsp->sb_8_pause)) - { + || (dsp->sb_8_enable && dsp->sb_8_pause)) { fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1358,11 +1362,9 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0x6D: /* 1-bit ESPCM output with reference */ case 0x6C: /* 1-bit ESPCM output */ - if (IS_ESS(dsp)) - { + if (IS_ESS(dsp)) { if (dsp->espcm_mode != ESPCM_1 - || (dsp->sb_8_enable && dsp->sb_8_pause)) - { + || (dsp->sb_8_enable && dsp->sb_8_pause)) { fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1372,11 +1374,9 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0x6F: /* 4-bit ESPCM input with reference */ case 0x6E: /* 4-bit ESPCM input */ - if (IS_ESS(dsp)) - { + if (IS_ESS(dsp)) { if (dsp->espcm_mode != ESPCM_4E - || (dsp->sb_8_enable && dsp->sb_8_pause)) - { + || (dsp->sb_8_enable && dsp->sb_8_pause)) { fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1394,8 +1394,7 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; dsp->ess_dma_counter++; - if (dsp->sb_command == 0x75) - { + if (dsp->sb_command == 0x75) { dsp->sb_8_length--; dsp->ess_dma_counter++; } @@ -1409,8 +1408,7 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; dsp->ess_dma_counter++; - if (dsp->sb_command == 0x77) - { + if (dsp->sb_command == 0x77) { dsp->sb_8_length--; dsp->ess_dma_counter++; } @@ -1561,9 +1559,9 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0xE1: /* Get DSP version */ if (IS_ESS(dsp)) { - sb_add_data(dsp, 0x3); - sb_add_data(dsp, 0x1); - break; + sb_add_data(dsp, 0x3); + sb_add_data(dsp, 0x1); + break; } if (IS_AZTECH(dsp)) { if (dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11) { @@ -1603,17 +1601,17 @@ sb_exec_command(sb_dsp_t *dsp) case 0xE7: /* ???? */ /* ESS detect/read config on ESS cards */ if (IS_ESS(dsp)) { switch (dsp->sb_subtype) { - default: - break; - case SB_SUBTYPE_ESS_ES688: - sb_add_data(dsp, 0x68); - sb_add_data(dsp, 0x80 | 0x04); - break; - case SB_SUBTYPE_ESS_ES1688: - // Determined via Windows driver debugging. - sb_add_data(dsp, 0x68); - sb_add_data(dsp, 0x80 | 0x09); - break; + default: + break; + case SB_SUBTYPE_ESS_ES688: + sb_add_data(dsp, 0x68); + sb_add_data(dsp, 0x80 | 0x04); + break; + case SB_SUBTYPE_ESS_ES1688: + // Determined via Windows driver debugging. + sb_add_data(dsp, 0x68); + sb_add_data(dsp, 0x80 | 0x09); + break; } } break; @@ -1623,8 +1621,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0xF2: /* Trigger 8-bit IRQ */ sb_dsp_log("Trigger IRQ\n"); if (IS_ESS(dsp)) { - if (!timer_is_enabled(&dsp->irq_timer)) - { + if (!timer_is_enabled(&dsp->irq_timer)) { timer_set_delay_u64(&dsp->irq_timer, (100ULL * TIMER_USEC)); } } else { @@ -1685,7 +1682,7 @@ sb_write(uint16_t a, uint8_t v, void *priv) if (dsp->sb_type < SB16 && (!IS_ESS(dsp) || (IS_ESS(dsp) && ((a & 0xF) != 0xE)))) a &= 0xfffe; - //pclog("sb: port write %03x %02x\n", a, v); + // pclog("sb: port write %03x %02x\n", a, v); switch (a & 0xF) { case 6: /* Reset */ @@ -1697,14 +1694,13 @@ sb_write(uint16_t a, uint8_t v, void *priv) dsp->sbreset = v; } - if (!(v & 2) && (dsp->espcm_fifo_reset & 2)) - { + if (!(v & 2) && (dsp->espcm_fifo_reset & 2)) { fifo_reset(dsp->espcm_fifo); } dsp->espcm_fifo_reset = v; - dsp->uart_midi = 0; - dsp->uart_irq = 0; - dsp->onebyte_midi = 0; + dsp->uart_midi = 0; + dsp->uart_irq = 0; + dsp->onebyte_midi = 0; return; case 0xC: /* Command/data write */ if (dsp->uart_midi || dsp->onebyte_midi) { @@ -1732,23 +1728,18 @@ sb_write(uint16_t a, uint8_t v, void *priv) else if (dsp->sb_command == 0x08 && dsp->sb_data_stat == 1 && dsp->sb_data[0] == 0x07) sb_commands[dsp->sb_command] = 2; } - if (IS_ESS(dsp) && dsp->sb_command >= 0x64 && dsp->sb_command <= 0x6F) - { - if (dsp->sb_subtype == SB_SUBTYPE_ESS_ES1688) - { + if (IS_ESS(dsp) && dsp->sb_command >= 0x64 && dsp->sb_command <= 0x6F) { + if (dsp->sb_subtype == SB_SUBTYPE_ESS_ES1688) { + sb_commands[dsp->sb_command] = 2; + } else { sb_commands[dsp->sb_command] = 2; } - else - { - sb_commands[dsp->sb_command] = 2; - } - } - else if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { + } else if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { if (dsp->sb_command <= 0xC0 || dsp->sb_command == 0xC2 || dsp->sb_command == 0xCF) { sb_commands[dsp->sb_command] = 1; } else if (dsp->sb_command == 0xC3 || dsp->sb_command == 0xC6 - || dsp->sb_command == 0xC7 || dsp->sb_command == 0xCE) { + || dsp->sb_command == 0xC7 || dsp->sb_command == 0xCE) { sb_commands[dsp->sb_command] = 0; } else { sb_commands[dsp->sb_command] = -1; @@ -1780,11 +1771,9 @@ sb_read(uint16_t a, void *priv) uint8_t ret = 0x00; /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ - if (dsp->sb_type < SB16) - { + if (dsp->sb_type < SB16) { /* Exception: ESS AudioDrive does not alias port base+0xf */ - if (!IS_ESS(dsp) || !((a & 0xF) == 0xF)) - { + if (!IS_ESS(dsp) || !((a & 0xF) == 0xF)) { a &= 0xfffe; } } @@ -1807,19 +1796,18 @@ sb_read(uint16_t a, void *priv) dsp->busy_count = (dsp->busy_count + 1) & 3; else dsp->busy_count = 0; - if (IS_ESS(dsp)) - { + if (IS_ESS(dsp)) { if (dsp->wb_full || (dsp->busy_count & 2)) { dsp->wb_full = timer_is_enabled(&dsp->wb_timer); } - uint8_t busy_flag = dsp->wb_full ? 0x80 : 0x00; - uint8_t data_rdy = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x40; - uint8_t fifo_full = 0; // Unimplemented - uint8_t fifo_empty = 0; - uint8_t fifo_half = 0; + uint8_t busy_flag = dsp->wb_full ? 0x80 : 0x00; + uint8_t data_rdy = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x40; + uint8_t fifo_full = 0; // Unimplemented + uint8_t fifo_empty = 0; + uint8_t fifo_half = 0; uint8_t irq_generic = dsp->ess_irq_generic ? 0x04 : 0x00; - uint8_t irq_fifohe = 0; // Unimplemented - uint8_t irq_dmactr = dsp->ess_irq_dmactr ? 0x01 : 0x00; + uint8_t irq_fifohe = 0; // Unimplemented + uint8_t irq_dmactr = dsp->ess_irq_dmactr ? 0x01 : 0x00; return busy_flag | data_rdy | fifo_full | fifo_empty | fifo_half | irq_generic | irq_fifohe | irq_dmactr; @@ -1856,8 +1844,7 @@ sb_read(uint16_t a, void *priv) } break; case 0xF: /* 16-bit ack */ - if (!IS_ESS(dsp)) - { + if (!IS_ESS(dsp)) { dsp->sb_irq16 = 0; if (!dsp->sb_irq8) dsp->irq_update(dsp->irq_priv, 0); @@ -1869,8 +1856,8 @@ sb_read(uint16_t a, void *priv) default: break; } - - //pclog("sb: port read %03x %02x\n", a, ret); + + // pclog("sb: port read %03x %02x\n", a, ret); return ret; } @@ -2068,16 +2055,13 @@ sb_ess_finish_dma(sb_dsp_t *dsp) void sb_espcm_fifoctl_run(sb_dsp_t *dsp) { - if (fifo_get_empty(dsp->espcm_fifo) && !dsp->sb_8_pause) - { - while (!fifo_get_full(dsp->espcm_fifo)) - { + if (fifo_get_empty(dsp->espcm_fifo) && !dsp->sb_8_pause) { + while (!fifo_get_full(dsp->espcm_fifo)) { int32_t val; val = dsp->dma_readb(dsp->dma_priv); dsp->ess_dma_counter++; fifo_write(val & 0xff, dsp->espcm_fifo); - if (val & DMA_OVER) - { + if (val & DMA_OVER) { break; } } @@ -2098,8 +2082,7 @@ pollsb(void *priv) switch (dsp->sb_8_format) { case 0x00: /* Mono unsigned */ - if (!dsp->sb_8_pause) - { + if (!dsp->sb_8_pause) { data[0] = dsp->dma_readb(dsp->dma_priv); /* Needed to prevent clicking in Worms, which programs the DSP to auto-init DMA but programs the DMA controller to single cycle */ @@ -2108,7 +2091,7 @@ pollsb(void *priv) dsp->sbdat = (data[0] ^ 0x80) << 8; if (dsp->stereo) { sb_dsp_log("pollsb: Mono unsigned, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); + dsp->sbleftright ? "left" : "right", dsp->sbdat); if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; else @@ -2121,15 +2104,14 @@ pollsb(void *priv) } break; case 0x10: /* Mono signed */ - if (!dsp->sb_8_pause) - { + if (!dsp->sb_8_pause) { data[0] = dsp->dma_readb(dsp->dma_priv); if (data[0] == DMA_NODATA) break; dsp->sbdat = data[0] << 8; if (dsp->stereo) { sb_dsp_log("pollsb: Mono signed, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", data[0], dsp->sbdat); + dsp->sbleftright ? "left" : "right", data[0], dsp->sbdat); if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; else @@ -2142,8 +2124,7 @@ pollsb(void *priv) } break; case 0x20: /* Stereo unsigned */ - if (!dsp->sb_8_pause) - { + if (!dsp->sb_8_pause) { data[0] = dsp->dma_readb(dsp->dma_priv); data[1] = dsp->dma_readb(dsp->dma_priv); if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) @@ -2155,8 +2136,7 @@ pollsb(void *priv) } break; case 0x30: /* Stereo signed */ - if (!dsp->sb_8_pause) - { + if (!dsp->sb_8_pause) { data[0] = dsp->dma_readb(dsp->dma_priv); data[1] = dsp->dma_readb(dsp->dma_priv); if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) @@ -2169,8 +2149,7 @@ pollsb(void *priv) break; case ADPCM_4: - if (!dsp->sb_8_pause) - { + if (!dsp->sb_8_pause) { if (dsp->sbdacpos) tempi = (dsp->sbdat2 & 0xF) + dsp->sbstep; else @@ -2202,7 +2181,7 @@ pollsb(void *priv) if (dsp->stereo) { sb_dsp_log("pollsb: ADPCM 4, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); + dsp->sbleftright ? "left" : "right", dsp->sbdat); if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; else @@ -2214,8 +2193,7 @@ pollsb(void *priv) break; case ADPCM_26: - if (!dsp->sb_8_pause) - { + if (!dsp->sb_8_pause) { if (!dsp->sbdacpos) tempi = (dsp->sbdat2 >> 5) + dsp->sbstep; else if (dsp->sbdacpos == 1) @@ -2249,7 +2227,7 @@ pollsb(void *priv) if (dsp->stereo) { sb_dsp_log("pollsb: ADPCM 26, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); + dsp->sbleftright ? "left" : "right", dsp->sbdat); if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; else @@ -2261,8 +2239,7 @@ pollsb(void *priv) break; case ADPCM_2: - if (!dsp->sb_8_pause) - { + if (!dsp->sb_8_pause) { tempi = ((dsp->sbdat2 >> ((3 - dsp->sbdacpos) * 2)) & 3) + dsp->sbstep; if (tempi < 0) tempi = 0; @@ -2290,7 +2267,7 @@ pollsb(void *priv) if (dsp->stereo) { sb_dsp_log("pollsb: ADPCM 2, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); + dsp->sbleftright ? "left" : "right", dsp->sbdat); if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; else @@ -2302,97 +2279,77 @@ pollsb(void *priv) break; case ESPCM_4: - if (dsp->espcm_sample_idx >= 19) - { + if (dsp->espcm_sample_idx >= 19) { dsp->espcm_sample_idx = 0; } - if (dsp->espcm_sample_idx == 0) - { + if (dsp->espcm_sample_idx == 0) { sb_espcm_fifoctl_run(dsp); - if (fifo_get_empty(dsp->espcm_fifo)) - { + if (fifo_get_empty(dsp->espcm_fifo)) { break; } dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; - tempi = dsp->espcm_byte_buffer[0] >> 4; - } - else if (dsp->espcm_sample_idx & 1) - { + tempi = dsp->espcm_byte_buffer[0] >> 4; + } else if (dsp->espcm_sample_idx & 1) { sb_espcm_fifoctl_run(dsp); - if (fifo_get_empty(dsp->espcm_fifo)) - { + if (fifo_get_empty(dsp->espcm_fifo)) { break; } dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; tempi = dsp->espcm_byte_buffer[0] & 0x0F; - } - else - { + } else { tempi = dsp->espcm_byte_buffer[0] >> 4; } - if (dsp->espcm_sample_idx == 18) - { + if (dsp->espcm_sample_idx == 18) { dsp->sb_8_length--; } dsp->espcm_sample_idx++; tempi |= (dsp->espcm_range << 4); - data[0] = espcm_range_map[tempi]; + data[0] = espcm_range_map[tempi]; dsp->sbdat = data[0] << 8; - if (dsp->stereo) - { + if (dsp->stereo) { sb_dsp_log("pollsb: ESPCM 4, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); + dsp->sbleftright ? "left" : "right", dsp->sbdat); if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; else dsp->sbdatr = dsp->sbdat; dsp->sbleftright = !dsp->sbleftright; - } - else - { + } else { dsp->sbdatl = dsp->sbdatr = dsp->sbdat; } break; case ESPCM_3: - if (dsp->espcm_sample_idx >= 19) - { + if (dsp->espcm_sample_idx >= 19) { dsp->espcm_sample_idx = 0; } - if (dsp->espcm_sample_idx == 0) - { + if (dsp->espcm_sample_idx == 0) { sb_espcm_fifoctl_run(dsp); - if (fifo_get_empty(dsp->espcm_fifo)) - { + if (fifo_get_empty(dsp->espcm_fifo)) { break; } dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); - dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; - tempi = dsp->espcm_byte_buffer[0] >> 4; + dsp->espcm_range = dsp->espcm_byte_buffer[0] & 0x0F; + tempi = dsp->espcm_byte_buffer[0] >> 4; dsp->espcm_last_value = tempi; - } - else if (dsp->espcm_sample_idx == 1) - { - for (tempi = 0; tempi < 4; tempi++) - { + } else if (dsp->espcm_sample_idx == 1) { + for (tempi = 0; tempi < 4; tempi++) { sb_espcm_fifoctl_run(dsp); - if (fifo_get_empty(dsp->espcm_fifo)) - { + if (fifo_get_empty(dsp->espcm_fifo)) { break; } dsp->espcm_byte_buffer[tempi] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; } - if (tempi < 4) - { + if (tempi < 4) { break; } @@ -2409,24 +2366,19 @@ pollsb(void *priv) dsp->espcm_code_buffer[8] = (dsp->espcm_byte_buffer[3] >> 2) & 0x07; dsp->espcm_code_buffer[9] = (dsp->espcm_byte_buffer[3] >> 5) & 0x07; - tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[0]; - tempi = espcm3_dpcm_tables[tempi]; + tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[0]; + tempi = espcm3_dpcm_tables[tempi]; dsp->espcm_last_value = tempi; - } - else if (dsp->espcm_sample_idx == 11) - { - for (tempi = 1; tempi < 4; tempi++) - { + } else if (dsp->espcm_sample_idx == 11) { + for (tempi = 1; tempi < 4; tempi++) { sb_espcm_fifoctl_run(dsp); - if (fifo_get_empty(dsp->espcm_fifo)) - { + if (fifo_get_empty(dsp->espcm_fifo)) { break; } dsp->espcm_byte_buffer[tempi] = fifo_read(dsp->espcm_fifo); dsp->sb_8_length--; } - if (tempi < 4) - { + if (tempi < 4) { break; } @@ -2439,53 +2391,44 @@ pollsb(void *priv) dsp->espcm_code_buffer[6] = (dsp->espcm_byte_buffer[3] >> 2) & 0x07; dsp->espcm_code_buffer[7] = (dsp->espcm_byte_buffer[3] >> 5) & 0x07; - tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[0]; - tempi = espcm3_dpcm_tables[tempi]; + tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[0]; + tempi = espcm3_dpcm_tables[tempi]; dsp->espcm_last_value = tempi; - } - else - { - tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[(dsp->espcm_sample_idx - 1) % 10]; - tempi = espcm3_dpcm_tables[tempi]; + } else { + tempi = (dsp->espcm_table_index << 8) | (dsp->espcm_last_value << 3) | dsp->espcm_code_buffer[(dsp->espcm_sample_idx - 1) % 10]; + tempi = espcm3_dpcm_tables[tempi]; dsp->espcm_last_value = tempi; } - if (dsp->espcm_sample_idx == 18) - { + if (dsp->espcm_sample_idx == 18) { dsp->sb_8_length--; } dsp->espcm_sample_idx++; tempi |= (dsp->espcm_range << 4); - data[0] = espcm_range_map[tempi]; + data[0] = espcm_range_map[tempi]; dsp->sbdat = data[0] << 8; - if (dsp->stereo) - { + if (dsp->stereo) { sb_dsp_log("pollsb: ESPCM 3, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); + dsp->sbleftright ? "left" : "right", dsp->sbdat); if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; else dsp->sbdatr = dsp->sbdat; dsp->sbleftright = !dsp->sbleftright; - } - else - { + } else { dsp->sbdatl = dsp->sbdatr = dsp->sbdat; } break; case ESPCM_1: - if (dsp->espcm_sample_idx >= 19) - { + if (dsp->espcm_sample_idx >= 19) { dsp->espcm_sample_idx = 0; } - if (dsp->espcm_sample_idx == 0) - { + if (dsp->espcm_sample_idx == 0) { sb_espcm_fifoctl_run(dsp); - if (fifo_get_empty(dsp->espcm_fifo)) - { + if (fifo_get_empty(dsp->espcm_fifo)) { break; } dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); @@ -2494,12 +2437,9 @@ pollsb(void *priv) dsp->espcm_byte_buffer[0] >>= 5; tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xC : 0x4; dsp->espcm_byte_buffer[0] >>= 1; - } - else if (dsp->espcm_sample_idx == 3 | dsp->espcm_sample_idx == 11) - { + } else if (dsp->espcm_sample_idx == 3 | dsp->espcm_sample_idx == 11) { sb_espcm_fifoctl_run(dsp); - if (fifo_get_empty(dsp->espcm_fifo)) - { + if (fifo_get_empty(dsp->espcm_fifo)) { break; } dsp->espcm_byte_buffer[0] = fifo_read(dsp->espcm_fifo); @@ -2507,35 +2447,29 @@ pollsb(void *priv) tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xC : 0x4; dsp->espcm_byte_buffer[0] >>= 1; - } - else - { + } else { tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xC : 0x4; dsp->espcm_byte_buffer[0] >>= 1; } - if (dsp->espcm_sample_idx == 18) - { + if (dsp->espcm_sample_idx == 18) { dsp->sb_8_length--; } dsp->espcm_sample_idx++; tempi |= (dsp->espcm_range << 4); - data[0] = espcm_range_map[tempi]; + data[0] = espcm_range_map[tempi]; dsp->sbdat = data[0] << 8; - if (dsp->stereo) - { + if (dsp->stereo) { sb_dsp_log("pollsb: ESPCM 1, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); + dsp->sbleftright ? "left" : "right", dsp->sbdat); if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; else dsp->sbdatr = dsp->sbdat; dsp->sbleftright = !dsp->sbleftright; - } - else - { + } else { dsp->sbdatl = dsp->sbdatr = dsp->sbdat; } break; @@ -2544,7 +2478,6 @@ pollsb(void *priv) break; } - if (dsp->sb_8_length < 0 && !dsp->ess_playback_mode) { if (dsp->sb_8_autoinit) dsp->sb_8_length = dsp->sb_8_origlength = dsp->sb_8_autolen; @@ -2556,23 +2489,19 @@ pollsb(void *priv) sb_irq(dsp, 1); dsp->ess_irq_generic = true; } - if (dsp->ess_dma_counter > 0xffff) - { - if (dsp->ess_playback_mode) - { - if (!dsp->sb_8_autoinit) - { + if (dsp->ess_dma_counter > 0xffff) { + if (dsp->ess_playback_mode) { + if (!dsp->sb_8_autoinit) { dsp->sb_8_enable = 0; timer_disable(&dsp->output_timer); sb_ess_finish_dma(dsp); } - if (ESSreg(0xB1) & 0x40) - { + if (ESSreg(0xB1) & 0x40) { sb_irq(dsp, 1); dsp->ess_irq_dmactr = true; } } - uint32_t temp = dsp->ess_dma_counter & 0xffff; + uint32_t temp = dsp->ess_dma_counter & 0xffff; dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); dsp->ess_dma_counter += temp; } @@ -2634,23 +2563,19 @@ pollsb(void *priv) sb_irq(dsp, 0); dsp->ess_irq_generic = true; } - if (dsp->ess_dma_counter > 0xffff) - { - if (dsp->ess_playback_mode) - { - if (!dsp->sb_16_autoinit) - { + if (dsp->ess_dma_counter > 0xffff) { + if (dsp->ess_playback_mode) { + if (!dsp->sb_16_autoinit) { dsp->sb_16_enable = 0; timer_disable(&dsp->output_timer); sb_ess_finish_dma(dsp); } - if (ESSreg(0xB1) & 0x40) - { + if (ESSreg(0xB1) & 0x40) { sb_irq(dsp, 0); dsp->ess_irq_dmactr = true; } } - uint32_t temp = dsp->ess_dma_counter & 0xffff; + uint32_t temp = dsp->ess_dma_counter & 0xffff; dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); dsp->ess_dma_counter += temp; } @@ -2714,60 +2639,47 @@ sb_poll_i(void *priv) dsp->espcm_sample_idx++; dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; - if (dsp->espcm_sample_idx >= 19) - { - int i, bit, table_addr, sigma, last_sigma; - int8_t min_sample = 127, max_sample = -128, s; + if (dsp->espcm_sample_idx >= 19) { + int i, bit, table_addr, sigma, last_sigma; + int8_t min_sample = 127, max_sample = -128, s; uint8_t b; - for (i = 0; i < 19; i++) - { + for (i = 0; i < 19; i++) { s = dsp->espcm_sample_buffer[i]; - if (s < min_sample) - { + if (s < min_sample) { min_sample = s; } - if (s > max_sample) - { + if (s > max_sample) { max_sample = s; } } - if (min_sample < 0) - { + if (min_sample < 0) { min_sample = -min_sample; } - if (max_sample < 0) - { + if (max_sample < 0) { max_sample = -max_sample; } - if (min_sample > max_sample) - { + if (min_sample > max_sample) { max_sample = min_sample; } - for (table_addr = 15; table_addr < 256; table_addr += 16) - { - if (max_sample <= espcm_range_map[table_addr]) - { + for (table_addr = 15; table_addr < 256; table_addr += 16) { + if (max_sample <= espcm_range_map[table_addr]) { break; } } dsp->espcm_range = table_addr >> 4; - for (i = 0; i < 19; i++) - { + for (i = 0; i < 19; i++) { table_addr = dsp->espcm_range << 4; last_sigma = 9999; - s = dsp->espcm_sample_buffer[i]; - for (; (table_addr >> 4) == dsp->espcm_range; table_addr++) - { + s = dsp->espcm_sample_buffer[i]; + for (; (table_addr >> 4) == dsp->espcm_range; table_addr++) { sigma = espcm_range_map[table_addr] - s; - if (sigma < 0) - { + if (sigma < 0) { sigma = -sigma; } - if (sigma > last_sigma) - { + if (sigma > last_sigma) { break; } last_sigma = sigma; @@ -2781,8 +2693,7 @@ sb_poll_i(void *priv) dsp->sb_8_length--; dsp->ess_dma_counter++; - for (i = 1; i < 10; i++) - { + for (i = 1; i < 10; i++) { b = dsp->espcm_code_buffer[i * 2 - 1] | (dsp->espcm_code_buffer[i * 2] << 4); dsp->dma_writeb(dsp->dma_priv, b); dsp->sb_8_length--; @@ -2807,23 +2718,19 @@ sb_poll_i(void *priv) sb_irq(dsp, 1); dsp->ess_irq_generic = true; } - if (dsp->ess_dma_counter > 0xffff) - { - if (dsp->ess_playback_mode) - { - if (!dsp->sb_8_autoinit) - { + if (dsp->ess_dma_counter > 0xffff) { + if (dsp->ess_playback_mode) { + if (!dsp->sb_8_autoinit) { dsp->sb_8_enable = 0; timer_disable(&dsp->input_timer); sb_ess_finish_dma(dsp); } - if (ESSreg(0xB1) & 0x40) - { + if (ESSreg(0xB1) & 0x40) { sb_irq(dsp, 1); dsp->ess_irq_dmactr = true; } } - uint32_t temp = dsp->ess_dma_counter & 0xffff; + uint32_t temp = dsp->ess_dma_counter & 0xffff; dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); dsp->ess_dma_counter += temp; } @@ -2881,23 +2788,19 @@ sb_poll_i(void *priv) sb_irq(dsp, 0); dsp->ess_irq_generic = true; } - if (dsp->ess_dma_counter > 0xffff) - { - if (dsp->ess_playback_mode) - { - if (!dsp->sb_16_autoinit) - { + if (dsp->ess_dma_counter > 0xffff) { + if (dsp->ess_playback_mode) { + if (!dsp->sb_16_autoinit) { dsp->sb_16_enable = 0; timer_disable(&dsp->input_timer); sb_ess_finish_dma(dsp); } - if (ESSreg(0xB1) & 0x40) - { + if (ESSreg(0xB1) & 0x40) { sb_irq(dsp, 0); dsp->ess_irq_dmactr = true; } } - uint32_t temp = dsp->ess_dma_counter & 0xffff; + uint32_t temp = dsp->ess_dma_counter & 0xffff; dsp->ess_dma_counter = sb_ess_get_dma_counter(dsp); dsp->ess_dma_counter += temp; } From d846a168260ef0b55e2450b7612d244753a43751 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 23:36:56 -0300 Subject: [PATCH 774/936] Cleanup: some touch-ups here and there --- src/sound/snd_ess.c | 6 +++-- src/sound/snd_sb_dsp.c | 57 ++++++++++++++++-------------------------- 2 files changed, 26 insertions(+), 37 deletions(-) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c index 38610c6ee..0239506bd 100644 --- a/src/sound/snd_ess.c +++ b/src/sound/snd_ess.c @@ -49,6 +49,8 @@ #include <86box/snd_sb.h> #include <86box/plat_unused.h> +# define sb_log(fmt, ...) + // clang-format off static const double sb_att_4dbstep_3bits[] = { 164.0, 2067.0, 3276.0, 5193.0, 8230.0, 13045.0, 20675.0, 32767.0 @@ -302,7 +304,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) } default: - // pclog("ess: Unknown mixer register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + sb_log("ess: Unknown mixer register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } } @@ -373,7 +375,7 @@ ess_mixer_read(uint16_t addr, void *priv) } default: - // pclog("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + sb_log("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 5290d6bc5..aae7dd458 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -35,7 +35,7 @@ #define ESPCM_4 4 #define ESPCM_3 5 #define ESPCM_1 7 -#define ESPCM_4E 8 // for encoding mode switching +#define ESPCM_4E 8 // for differentiating between 4-bit encoding and decoding modes /*The recording safety margin is intended for uneven "len" calls to the get_buffer mixer calls on sound_sb*/ #define SB_DSP_REC_SAFEFTY_MARGIN 4096 @@ -687,8 +687,9 @@ int sb_16_read_dma(void *priv) { const sb_dsp_t *dsp = (sb_dsp_t *) priv; - int temp, ret = 0; - int dma_flags, dma_ch = dsp->sb_16_dmanum; + + int temp, ret = 0; + int dma_flags, dma_ch = dsp->sb_16_dmanum; if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate) ret = dma_channel_read(dma_ch); @@ -722,8 +723,9 @@ int sb_16_write_dma(void *priv, uint16_t val) { const sb_dsp_t *dsp = (sb_dsp_t *) priv; - int temp, ret = 0; - int dma_ch = dsp->sb_16_dmanum; + + int temp, ret = 0; + int dma_ch = dsp->sb_16_dmanum; if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate) ret = dma_channel_write(dma_ch, val) == DMA_NODATA; @@ -793,7 +795,6 @@ sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy) void sb_dsp_setirq(sb_dsp_t *dsp, int irq) { - uint8_t t = 0x00; sb_dsp_log("IRQ now: %i\n", irq); dsp->sb_irqnum = irq; @@ -805,7 +806,6 @@ sb_dsp_setirq(sb_dsp_t *dsp, int irq) void sb_dsp_setdma8(sb_dsp_t *dsp, int dma) { - uint8_t t = 0x00; sb_dsp_log("8-bit DMA now: %i\n", dma); dsp->sb_8_dmanum = dma; @@ -881,8 +881,6 @@ sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) default: return ESSreg(reg); } - - return 0xFF; } static void @@ -907,7 +905,8 @@ sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) dsp->sb_freq = 397700UL / (128ul - data); temp = 1000000.0 / dsp->sb_freq; dsp->sblatchi = dsp->sblatcho = TIMER_USEC * temp; - dsp->sb_timei = dsp->sb_timeo; + + dsp->sb_timei = dsp->sb_timeo; break; } case 0xA2: /* Filter divider (effectively, a hardware lowpass filter under S/W control) */ @@ -1305,7 +1304,6 @@ sb_exec_command(sb_dsp_t *dsp) temp = 256 - dsp->sb_data[0]; temp = 1000000 / temp; sb_dsp_log("Sample rate - %ihz (%f)\n", temp, dsp->sblatcho); - // if ((dsp->sb_freq != temp) && (IS_ESS(dsp) || (dsp->sb_type >= SB16))) if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16)) recalc_sb16_filter(0, temp); dsp->sb_freq = temp; @@ -1339,8 +1337,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0x65: /* 4-bit ESPCM output with reference */ case 0x64: /* 4-bit ESPCM output */ if (IS_ESS(dsp)) { - if (dsp->espcm_mode != ESPCM_4 - || (dsp->sb_8_enable && dsp->sb_8_pause)) { + if (dsp->espcm_mode != ESPCM_4 || (dsp->sb_8_enable && dsp->sb_8_pause)) { fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1351,8 +1348,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0x67: /* 3-bit ESPCM output with reference */ case 0x66: /* 3-bit ESPCM output */ if (IS_ESS(dsp)) { - if (dsp->espcm_mode != ESPCM_3 - || (dsp->sb_8_enable && dsp->sb_8_pause)) { + if (dsp->espcm_mode != ESPCM_3 || (dsp->sb_8_enable && dsp->sb_8_pause)) { fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1363,8 +1359,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0x6D: /* 1-bit ESPCM output with reference */ case 0x6C: /* 1-bit ESPCM output */ if (IS_ESS(dsp)) { - if (dsp->espcm_mode != ESPCM_1 - || (dsp->sb_8_enable && dsp->sb_8_pause)) { + if (dsp->espcm_mode != ESPCM_1 || (dsp->sb_8_enable && dsp->sb_8_pause)) { fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } @@ -1375,14 +1370,12 @@ sb_exec_command(sb_dsp_t *dsp) case 0x6F: /* 4-bit ESPCM input with reference */ case 0x6E: /* 4-bit ESPCM input */ if (IS_ESS(dsp)) { - if (dsp->espcm_mode != ESPCM_4E - || (dsp->sb_8_enable && dsp->sb_8_pause)) { + if (dsp->espcm_mode != ESPCM_4E || (dsp->sb_8_enable && dsp->sb_8_pause)) { fifo_reset(dsp->espcm_fifo); dsp->espcm_sample_idx = 0; } dsp->espcm_mode = ESPCM_4E; sb_start_dma_i(dsp, 1, 0, ESPCM_4E, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - dsp->espcm_sample_idx = 0; } break; case 0x75: /* 4-bit ADPCM output with reference */ @@ -1598,7 +1591,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0xE4: /* Write test register */ dsp->sb_test = dsp->sb_data[0]; break; - case 0xE7: /* ???? */ /* ESS detect/read config on ESS cards */ + case 0xE7: /* ESS detect/read config on ESS cards */ if (IS_ESS(dsp)) { switch (dsp->sb_subtype) { default: @@ -1682,8 +1675,6 @@ sb_write(uint16_t a, uint8_t v, void *priv) if (dsp->sb_type < SB16 && (!IS_ESS(dsp) || (IS_ESS(dsp) && ((a & 0xF) != 0xE)))) a &= 0xfffe; - // pclog("sb: port write %03x %02x\n", a, v); - switch (a & 0xF) { case 6: /* Reset */ if (!dsp->uart_midi) { @@ -1729,17 +1720,16 @@ sb_write(uint16_t a, uint8_t v, void *priv) sb_commands[dsp->sb_command] = 2; } if (IS_ESS(dsp) && dsp->sb_command >= 0x64 && dsp->sb_command <= 0x6F) { - if (dsp->sb_subtype == SB_SUBTYPE_ESS_ES1688) { - sb_commands[dsp->sb_command] = 2; - } else { - sb_commands[dsp->sb_command] = 2; - } + sb_commands[dsp->sb_command] = 2; } else if (IS_ESS(dsp) && dsp->sb_command >= 0xA0 && dsp->sb_command <= 0xCF) { - if (dsp->sb_command <= 0xC0 || dsp->sb_command == 0xC2 + if (dsp->sb_command <= 0xC0 + || dsp->sb_command == 0xC2 || dsp->sb_command == 0xCF) { sb_commands[dsp->sb_command] = 1; - } else if (dsp->sb_command == 0xC3 || dsp->sb_command == 0xC6 - || dsp->sb_command == 0xC7 || dsp->sb_command == 0xCE) { + } else if (dsp->sb_command == 0xC3 + || dsp->sb_command == 0xC6 + || dsp->sb_command == 0xC7 + || dsp->sb_command == 0xCE) { sb_commands[dsp->sb_command] = 0; } else { sb_commands[dsp->sb_command] = -1; @@ -1809,8 +1799,7 @@ sb_read(uint16_t a, void *priv) uint8_t irq_fifohe = 0; // Unimplemented uint8_t irq_dmactr = dsp->ess_irq_dmactr ? 0x01 : 0x00; - return busy_flag | data_rdy | fifo_full | fifo_empty - | fifo_half | irq_generic | irq_fifohe | irq_dmactr; + return busy_flag | data_rdy | fifo_full | fifo_empty | fifo_half | irq_generic | irq_fifohe | irq_dmactr; } if (dsp->wb_full || (dsp->busy_count & 2)) { dsp->wb_full = timer_is_enabled(&dsp->wb_timer); @@ -1857,8 +1846,6 @@ sb_read(uint16_t a, void *priv) break; } - // pclog("sb: port read %03x %02x\n", a, ret); - return ret; } From eb6f4c1118191b232da802dac98a9984bb6a4093 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 22 Mar 2024 23:49:02 -0300 Subject: [PATCH 775/936] Fixing compiler warning about parentheses --- src/sound/snd_sb_dsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index aae7dd458..ad6209fb5 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -2424,7 +2424,7 @@ pollsb(void *priv) dsp->espcm_byte_buffer[0] >>= 5; tempi = dsp->espcm_byte_buffer[0] & 1 ? 0xC : 0x4; dsp->espcm_byte_buffer[0] >>= 1; - } else if (dsp->espcm_sample_idx == 3 | dsp->espcm_sample_idx == 11) { + } else if ((dsp->espcm_sample_idx == 3) | (dsp->espcm_sample_idx == 11)) { sb_espcm_fifoctl_run(dsp); if (fifo_get_empty(dsp->espcm_fifo)) { break; From 922a403eb33a580010aee091f93788d4a4a5f388 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sat, 23 Mar 2024 00:52:05 -0300 Subject: [PATCH 776/936] Cleanup: get rid of snd_ess.c; move ess to snd_sb.c/.h --- src/include/86box/snd_sb.h | 57 +++- src/sound/CMakeLists.txt | 2 +- src/sound/snd_ess.c | 661 ------------------------------------- src/sound/snd_sb.c | 536 ++++++++++++++++++++++++++++++ 4 files changed, 585 insertions(+), 671 deletions(-) delete mode 100644 src/sound/snd_ess.c diff --git a/src/include/86box/snd_sb.h b/src/include/86box/snd_sb.h index f236c284a..1ab94c9e1 100644 --- a/src/include/86box/snd_sb.h +++ b/src/include/86box/snd_sb.h @@ -105,15 +105,13 @@ typedef struct sb_ct1745_mixer_t { int input_selector_left; int input_selector_right; -#define INPUT_MIC 1 -#define INPUT_CD_R 2 -#define INPUT_CD_L 4 -#define INPUT_LINE_R 8 -#define INPUT_LINE_L 16 -#define INPUT_MIDI_R 32 -#define INPUT_MIDI_L 64 -#define INPUT_MIXER_L 128 -#define INPUT_MIXER_R 256 +#define INPUT_MIC 1 +#define INPUT_CD_R 2 +#define INPUT_CD_L 4 +#define INPUT_LINE_R 8 +#define INPUT_LINE_L 16 +#define INPUT_MIDI_R 32 +#define INPUT_MIDI_L 64 int mic_agc; @@ -128,6 +126,42 @@ typedef struct sb_ct1745_mixer_t { int output_filter; /* for clones */ } sb_ct1745_mixer_t; +/* ESS AudioDrive */ +typedef struct ess_mixer_t { + double master_l; + double master_r; + double voice_l; + double voice_r; + double fm_l; + double fm_r; + double cd_l; + double cd_r; + double line_l; + double line_r; + double mic_l; + double mic_r; + double auxb_l; + double auxb_r; + /*see sb_ct1745_mixer for values for input selector*/ + int32_t input_selector; + /* extra values for input selector */ + #define INPUT_MIXER_L 128 + #define INPUT_MIXER_R 256 + + int input_filter; + int in_filter_freq; + int output_filter; + + int stereo; + int stereo_isleft; + + uint8_t index; + uint8_t regs[256]; + + uint8_t ess_id_str[4]; + uint8_t ess_id_str_pos; +} ess_mixer_t; + typedef struct sb_t { uint8_t cms_enabled; uint8_t opl_enabled; @@ -140,6 +174,7 @@ typedef struct sb_t { sb_ct1335_mixer_t mixer_sb2; sb_ct1345_mixer_t mixer_sbpro; sb_ct1745_mixer_t mixer_sb16; + ess_mixer_t mixer_ess; }; mpu_t *mpu; emu8k_t emu8k; @@ -165,6 +200,10 @@ extern void sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv); extern uint8_t sb_ct1745_mixer_read(uint16_t addr, void *priv); extern void sb_ct1745_mixer_reset(sb_t *sb); +extern void sb_ess_mixer_write(uint16_t addr, uint8_t val, void *priv); +extern uint8_t sb_ess_mixer_read(uint16_t addr, void *priv); +extern void sb_ess_mixer_reset(sb_t *sb); + extern void sb_get_buffer_sbpro(int32_t *buffer, int len, void *priv); extern void sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv); extern void sbpro_filter_cd_audio(int channel, double *buffer, void *priv); diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index 9206f6be9..9b2cc1416 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -18,7 +18,7 @@ add_library(snd OBJECT sound.c snd_opl.c snd_opl_nuked.c snd_opl_ymfm.cpp snd_re snd_lpt_dss.c snd_ps1.c snd_adlib.c snd_adlibgold.c snd_ad1848.c snd_audiopci.c snd_azt2316a.c snd_cms.c snd_cmi8x38.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c snd_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c - snd_optimc.c esfmu/esfm.c esfmu/esfm_registers.c snd_opl_esfm.c snd_ess.c) + snd_optimc.c esfmu/esfm.c esfmu/esfm_registers.c snd_opl_esfm.c) if(OPENAL) if(VCPKG_TOOLCHAIN) diff --git a/src/sound/snd_ess.c b/src/sound/snd_ess.c deleted file mode 100644 index 0239506bd..000000000 --- a/src/sound/snd_ess.c +++ /dev/null @@ -1,661 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * ESS AudioDrive emulation. - * - * - * - * Authors: Sarah Walker, - * Miran Grca, - * TheCollector1995, - * Cacodemon345, - * Kagamiin~, - * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. - * Copyright 2024 Cacodemon345 - * Copyright 2024 Kagamiin~ - */ - -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H - -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/filters.h> -#include <86box/gameport.h> -#include <86box/hdc.h> -#include <86box/isapnp.h> -#include <86box/hdc_ide.h> -#include <86box/io.h> -#include <86box/mca.h> -#include <86box/mem.h> -#include <86box/midi.h> -#include <86box/pic.h> -#include <86box/rom.h> -#include <86box/sound.h> -#include <86box/timer.h> -#include <86box/snd_sb.h> -#include <86box/plat_unused.h> - -# define sb_log(fmt, ...) - -// clang-format off -static const double sb_att_4dbstep_3bits[] = { - 164.0, 2067.0, 3276.0, 5193.0, 8230.0, 13045.0, 20675.0, 32767.0 -}; - -static const double sb_att_7dbstep_2bits[] = { - 164.0, 6537.0, 14637.0, 32767.0 -}; - -/* Attenuation table for 4-bit microphone volume. - * The last step is a jump to -48 dB. */ -static const double sb_att_1p4dbstep_4bits[] = { - 164.0, 3431.0, 4031.0, 4736.0, 5565.0, 6537.0, 7681.0, 9025.0, - 10603.0, 12458.0, 14637.0, 17196.0, 20204.0, 23738.0, 27889.0, 32767.0 -}; - -/* Attenuation table for 4-bit mixer volume. - * The last step is a jump to -48 dB. */ -static const double sb_att_2dbstep_4bits[] = { - 164.0, 1304.0, 1641.0, 2067.0, 2602.0, 3276.0, 4125.0, 5192.0, - 6537.0, 8230.0, 10362.0, 13044.0, 16422.0, 20674.0, 26027.0, 32767.0 -}; -// clang-format on - -/* SB PRO */ -typedef struct ess_mixer_t { - double master_l; - double master_r; - double voice_l; - double voice_r; - double fm_l; - double fm_r; - double cd_l; - double cd_r; - double line_l; - double line_r; - double mic_l; - double mic_r; - double auxb_l; - double auxb_r; - /*see sb_ct1745_mixer for values for input selector*/ - int32_t input_selector; - - int input_filter; - int in_filter_freq; - int output_filter; - - int stereo; - int stereo_isleft; - - uint8_t index; - uint8_t regs[256]; - - uint8_t ess_id_str[4]; - uint8_t ess_id_str_pos; -} ess_mixer_t; - -typedef struct ess_t { - uint8_t mixer_enabled; - fm_drv_t opl; - sb_dsp_t dsp; - ess_mixer_t mixer_sbpro; - - mpu_t *mpu; - void *gameport; - - uint16_t gameport_addr; - - void *opl_mixer; - void (*opl_mix)(void *, double *, double *); -} ess_t; - -static double -ess_mixer_get_vol_4bit(uint8_t vol) -{ - return sb_att_2dbstep_4bits[vol & 0x0F] / 32767.0; -} - -void -ess_mixer_write(uint16_t addr, uint8_t val, void *priv) -{ - ess_t *ess = (ess_t *) priv; - ess_mixer_t *mixer = &ess->mixer_sbpro; - - if (!(addr & 1)) { - mixer->index = val; - mixer->regs[0x01] = val; - if (val == 0x40) { - mixer->ess_id_str_pos = 0; - } - } else { - if (mixer->index == 0) { - /* Reset */ - mixer->regs[0x0a] = mixer->regs[0x0c] = 0x00; - mixer->regs[0x0e] = 0x00; - /* Changed default from -11dB to 0dB */ - mixer->regs[0x04] = mixer->regs[0x22] = 0xee; - mixer->regs[0x26] = mixer->regs[0x28] = 0xee; - mixer->regs[0x2e] = 0x00; - - /* Initialize ESS regs. */ - mixer->regs[0x14] = mixer->regs[0x32] = 0x88; - mixer->regs[0x36] = 0x88; - mixer->regs[0x38] = 0x88; - mixer->regs[0x3a] = 0x00; - mixer->regs[0x3e] = 0x00; - - sb_dsp_set_stereo(&ess->dsp, mixer->regs[0x0e] & 2); - } else { - mixer->regs[mixer->index] = val; - - switch (mixer->index) { - /* Compatibility: chain registers 0x02 and 0x22 as well as 0x06 and 0x26 */ - case 0x02: - case 0x06: - case 0x08: - mixer->regs[mixer->index + 0x20] = ((val & 0xe) << 4) | (val & 0xe); - break; - - case 0x0A: - { - uint8_t mic_vol_2bit = (mixer->regs[0x0a] >> 1) & 0x3; - mixer->mic_l = mixer->mic_r = sb_att_7dbstep_2bits[mic_vol_2bit] / 32768.0; - mixer->regs[0x1A] = mic_vol_2bit | (mic_vol_2bit << 2) | (mic_vol_2bit << 4) | (mic_vol_2bit << 6); - break; - } - - case 0x0C: - switch (mixer->regs[0x0C] & 6) { - case 2: - mixer->input_selector = INPUT_CD_L | INPUT_CD_R; - break; - case 6: - mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; - break; - default: - mixer->input_selector = INPUT_MIC; - break; - } - break; - - case 0x14: - mixer->regs[0x4] = val & 0xee; - break; - - case 0x1A: - mixer->mic_l = sb_att_1p4dbstep_4bits[(mixer->regs[0x1A] >> 4) & 0xF]; - mixer->mic_r = sb_att_1p4dbstep_4bits[mixer->regs[0x1A] & 0xF]; - break; - - case 0x1C: - if ((mixer->regs[0x1C] & 0x07) == 0x07) { - mixer->input_selector = INPUT_MIXER_L | INPUT_MIXER_R; - } else if ((mixer->regs[0x1C] & 0x07) == 0x06) { - mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; - } else if ((mixer->regs[0x1C] & 0x06) == 0x02) { - mixer->input_selector = INPUT_CD_L | INPUT_CD_R; - } else if ((mixer->regs[0x1C] & 0x02) == 0) { - mixer->input_selector = INPUT_MIC; - } - break; - - case 0x22: - case 0x26: - case 0x28: - case 0x2E: - mixer->regs[mixer->index - 0x20] = (val & 0xe); - mixer->regs[mixer->index + 0x10] = val; - break; - - /* More compatibility: - SoundBlaster Pro selects register 020h for 030h, 022h for 032h, - 026h for 036h, and 028h for 038h. */ - case 0x30: - mixer->regs[mixer->index - 0x10] = (val & 0xee); - break; - case 0x32: - case 0x36: - case 0x38: - case 0x3e: - mixer->regs[mixer->index - 0x10] = (val & 0xee); - break; - - case 0x3a: - break; - - case 0x00: - case 0x04: - break; - - case 0x0e: - break; - - case 0x64: - mixer->regs[mixer->index] &= ~0x8; - break; - - case 0x40: - { - uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] << 1) & 0x30); - gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); - - if (0) { - /* Not on ES1688. */ - io_removehandler(0x0388, 0x0004, - ess->opl.read, NULL, NULL, - ess->opl.write, NULL, NULL, - ess->opl.priv); - if ((mixer->regs[0x40] & 0x1) != 0) { - io_sethandler(0x0388, 0x0004, - ess->opl.read, NULL, NULL, - ess->opl.write, NULL, NULL, - ess->opl.priv); - } - } - switch ((mixer->regs[0x40] >> 5) & 0x7) { - case 0: - mpu401_change_addr(ess->mpu, 0x00); - mpu401_setirq(ess->mpu, -1); - break; - case 1: - mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, -1); - break; - case 2: - mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, ess->dsp.sb_irqnum); - break; - case 3: - mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 11); - break; - case 4: - mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 9); - break; - case 5: - mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 5); - break; - case 6: - mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 7); - break; - case 7: - mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 10); - break; - } - break; - } - - default: - sb_log("ess: Unknown mixer register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); - break; - } - } - - mixer->voice_l = ess_mixer_get_vol_4bit(mixer->regs[0x14] >> 4); - mixer->voice_r = ess_mixer_get_vol_4bit(mixer->regs[0x14]); - mixer->master_l = ess_mixer_get_vol_4bit(mixer->regs[0x32] >> 4); - mixer->master_r = ess_mixer_get_vol_4bit(mixer->regs[0x32]); - mixer->fm_l = ess_mixer_get_vol_4bit(mixer->regs[0x36] >> 4); - mixer->fm_r = ess_mixer_get_vol_4bit(mixer->regs[0x36]); - mixer->cd_l = ess_mixer_get_vol_4bit(mixer->regs[0x38] >> 4); - mixer->cd_r = ess_mixer_get_vol_4bit(mixer->regs[0x38]); - mixer->line_l = ess_mixer_get_vol_4bit(mixer->regs[0x3e] >> 4); - mixer->line_r = ess_mixer_get_vol_4bit(mixer->regs[0x3e]); - mixer->auxb_l = ess_mixer_get_vol_4bit(mixer->regs[0x3a] >> 4); - mixer->auxb_r = ess_mixer_get_vol_4bit(mixer->regs[0x3a]); - - mixer->output_filter = !(mixer->regs[0xe] & 0x20); - mixer->input_filter = !(mixer->regs[0xc] & 0x20); - mixer->in_filter_freq = ((mixer->regs[0xc] & 0x8) == 0) ? 3200 : 8800; - mixer->stereo = mixer->regs[0xe] & 2; - if (mixer->index == 0xe) - sb_dsp_set_stereo(&ess->dsp, val & 2); - - /* TODO: pcspeaker volume? Or is it not worth? */ - } -} - -uint8_t -ess_mixer_read(uint16_t addr, void *priv) -{ - ess_t *ess = (ess_t *) priv; - ess_mixer_t *mixer = &ess->mixer_sbpro; - - if (!(addr & 1)) - return mixer->index; - - switch (mixer->index) { - case 0x00: - case 0x04: - case 0x0a: - case 0x0c: - case 0x0e: - case 0x14: - case 0x22: - case 0x26: - case 0x28: - case 0x2e: - case 0x02: - case 0x06: - case 0x30: - case 0x32: - case 0x36: - case 0x38: - case 0x3e: - return mixer->regs[mixer->index]; - - case 0x40: - - if (ess->dsp.sb_subtype != SB_SUBTYPE_ESS_ES1688) { - uint8_t val = mixer->ess_id_str[mixer->ess_id_str_pos]; - mixer->ess_id_str_pos++; - if (mixer->ess_id_str_pos >= 4) - mixer->ess_id_str_pos = 0; - return val; - } else { - return mixer->regs[mixer->index]; - } - - default: - sb_log("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); - break; - } - - return 0x0a; -} - -void -ess_mixer_reset(ess_t *ess) -{ - ess_mixer_write(4, 0, ess); - ess_mixer_write(5, 0, ess); -} - -void -ess_get_buffer_sbpro(int32_t *buffer, int len, void *priv) -{ - ess_t *ess = (ess_t *) priv; - const ess_mixer_t *mixer = &ess->mixer_sbpro; - double out_l = 0.0; - double out_r = 0.0; - - sb_dsp_update(&ess->dsp); - - for (int c = 0; c < len * 2; c += 2) { - out_l = 0.0; - out_r = 0.0; - - /* TODO: Implement the stereo switch on the mixer instead of on the dsp? */ - if (mixer->output_filter) { - out_l += (low_fir_sb16(0, 0, (double) ess->dsp.buffer[c]) * mixer->voice_l) / 3.0; - out_r += (low_fir_sb16(0, 1, (double) ess->dsp.buffer[c + 1]) * mixer->voice_r) / 3.0; - } else { - out_l += (ess->dsp.buffer[c] * mixer->voice_l) / 3.0; - out_r += (ess->dsp.buffer[c + 1] * mixer->voice_r) / 3.0; - } - - /* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */ - out_l *= mixer->master_l; - out_r *= mixer->master_r; - - buffer[c] += (int32_t) out_l; - buffer[c + 1] += (int32_t) out_r; - } - - ess->dsp.pos = 0; -} - -void -ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) -{ - ess_t *ess = (ess_t *) priv; - const ess_mixer_t *mixer = &ess->mixer_sbpro; - double out_l = 0.0; - double out_r = 0.0; - const int32_t *opl_buf = NULL; - - opl_buf = ess->opl.update(ess->opl.priv); - - for (int c = 0; c < len * 2; c += 2) { - out_l = 0.0; - out_r = 0.0; - - { - out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; - out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; - if (ess->opl_mix && ess->opl_mixer) - ess->opl_mix(ess->opl_mixer, &out_l, &out_r); - } - - /* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */ - out_l *= mixer->master_l; - out_r *= mixer->master_r; - - buffer[c] += (int32_t) out_l; - buffer[c + 1] += (int32_t) out_r; - } - - ess->opl.reset_buffer(ess->opl.priv); -} - -void -ess_filter_cd_audio(int channel, double *buffer, void *priv) -{ - const ess_t *ess = (ess_t *) priv; - const ess_mixer_t *mixer = &ess->mixer_sbpro; - double c; - double cd = channel ? mixer->cd_r : mixer->cd_l; - double master = channel ? mixer->master_r : mixer->master_l; - - c = (*buffer * cd) / 3.0; - *buffer = c * master; -} - -static void * -ess_1688_init(UNUSED(const device_t *info)) -{ - /* SB Pro 2 port mappings, 220h or 240h. - 2x0 to 2x3 -> FM chip (18 voices) - 2x4 to 2x5 -> Mixer interface - 2x6, 2xA, 2xC, 2xE -> DSP chip - 2x8, 2x9, 388 and 389 FM chip (9 voices) - 2x0+10 to 2x0+13 CDROM interface. */ - ess_t *ess = calloc(sizeof(ess_t), 1); - uint16_t addr = device_get_config_hex16("base"); - - fm_driver_get(FM_ESFM, &ess->opl); - - sb_dsp_set_real_opl(&ess->dsp, 1); - sb_dsp_init(&ess->dsp, SBPRO2, SB_SUBTYPE_ESS_ES1688, ess); - sb_dsp_setaddr(&ess->dsp, addr); - sb_dsp_setirq(&ess->dsp, device_get_config_int("irq")); - sb_dsp_setdma8(&ess->dsp, device_get_config_int("dma")); - sb_dsp_setdma16_8(&ess->dsp, device_get_config_int("dma")); - sb_dsp_setdma16_supported(&ess->dsp, 0); - ess_mixer_reset(ess); - - /* DSP I/O handler is activated in sb_dsp_setaddr */ - { - io_sethandler(addr, 0x0004, - ess->opl.read, NULL, NULL, - ess->opl.write, NULL, NULL, - ess->opl.priv); - io_sethandler(addr + 8, 0x0002, - ess->opl.read, NULL, NULL, - ess->opl.write, NULL, NULL, - ess->opl.priv); - io_sethandler(0x0388, 0x0004, - ess->opl.read, NULL, NULL, - ess->opl.write, NULL, NULL, - ess->opl.priv); - } - - ess->mixer_enabled = 1; - io_sethandler(addr + 4, 0x0002, - ess_mixer_read, NULL, NULL, - ess_mixer_write, NULL, NULL, - ess); - sound_add_handler(ess_get_buffer_sbpro, ess); - music_add_handler(ess_get_music_buffer_sbpro, ess); - sound_set_cd_audio_filter(ess_filter_cd_audio, ess); - - if (device_get_config_int("receive_input")) - midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &ess->dsp); - { - ess->mixer_sbpro.ess_id_str[0] = 0x16; - ess->mixer_sbpro.ess_id_str[1] = 0x88; - ess->mixer_sbpro.ess_id_str[2] = (addr >> 8) & 0xff; - ess->mixer_sbpro.ess_id_str[3] = addr & 0xff; - } - - ess->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); - mpu401_init(ess->mpu, 0, -1, M_UART, 1); - sb_dsp_set_mpu(&ess->dsp, ess->mpu); - - ess->gameport = gameport_add(&gameport_pnp_device); - ess->gameport_addr = 0x200; - gameport_remap(ess->gameport, ess->gameport_addr); - - return ess; -} - -void -ess_close(void *priv) -{ - ess_t *ess = (ess_t *) priv; - sb_dsp_close(&ess->dsp); - - free(ess); -} - -void -ess_speed_changed(void *priv) -{ - ess_t *ess = (ess_t *) priv; - - sb_dsp_speed_changed(&ess->dsp); -} - -// clang-format off -static const device_config_t ess_config[] = { - { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x220, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x240", - .value = 0x240 - }, - { .description = "" } - } - }, - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "IRQ 2", - .value = 2 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { .description = "" } - } - }, - { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 1, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "DMA 0", - .value = 0 - }, - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 3", - .value = 3 - }, - { .description = "" } - } - }, - { - .name = "opl", - .description = "Enable OPL", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 - }, - { - .name = "receive_input", - .description = "Receive input (SB MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 - }, - { .name = "", .description = "", .type = CONFIG_END } -}; -// clang-format on - -const device_t ess_1688_device = { - .name = "ESS Technology ES1688", - .internal_name = "ess_es1688", - .flags = DEVICE_ISA, - .local = 0, - .init = ess_1688_init, - .close = ess_close, - .reset = NULL, - { .available = NULL }, - .speed_changed = ess_speed_changed, - .force_redraw = NULL, - .config = ess_config -}; diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 2365419b1..1489cb769 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -75,6 +75,20 @@ static const double sb_att_4dbstep_3bits[] = { static const double sb_att_7dbstep_2bits[] = { 164.0, 6537.0, 14637.0, 32767.0 }; + +/* Attenuation table for ESS 4-bit microphone volume. + * The last step is a jump to -48 dB. */ +static const double sb_att_1p4dbstep_4bits[] = { + 164.0, 3431.0, 4031.0, 4736.0, 5565.0, 6537.0, 7681.0, 9025.0, + 10603.0, 12458.0, 14637.0, 17196.0, 20204.0, 23738.0, 27889.0, 32767.0 +}; + +/* Attenuation table for ESS 4-bit mixer volume. + * The last step is a jump to -48 dB. */ +static const double sb_att_2dbstep_4bits[] = { + 164.0, 1304.0, 1641.0, 2067.0, 2602.0, 3276.0, 4125.0, 5192.0, + 6537.0, 8230.0, 10362.0, 13044.0, 16422.0, 20674.0, 26027.0, 32767.0 +}; // clang-format on static const uint16_t sb_mcv_addr[8] = { 0x200, 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x270 }; @@ -667,6 +681,87 @@ sb16_awe32_filter_pc_speaker(int channel, double *buffer, void *priv) *buffer = c * output_gain; } +void +ess_get_buffer_sbpro(int32_t *buffer, int len, void *priv) +{ + sb_t *ess = (sb_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_ess; + double out_l = 0.0; + double out_r = 0.0; + + sb_dsp_update(&ess->dsp); + + for (int c = 0; c < len * 2; c += 2) { + out_l = 0.0; + out_r = 0.0; + + /* TODO: Implement the stereo switch on the mixer instead of on the dsp? */ + if (mixer->output_filter) { + out_l += (low_fir_sb16(0, 0, (double) ess->dsp.buffer[c]) * mixer->voice_l) / 3.0; + out_r += (low_fir_sb16(0, 1, (double) ess->dsp.buffer[c + 1]) * mixer->voice_r) / 3.0; + } else { + out_l += (ess->dsp.buffer[c] * mixer->voice_l) / 3.0; + out_r += (ess->dsp.buffer[c + 1] * mixer->voice_r) / 3.0; + } + + /* TODO: recording from the mixer. */ + out_l *= mixer->master_l; + out_r *= mixer->master_r; + + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; + } + + ess->dsp.pos = 0; +} + +void +ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) +{ + sb_t *ess = (sb_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_ess; + double out_l = 0.0; + double out_r = 0.0; + const int32_t *opl_buf = NULL; + + opl_buf = ess->opl.update(ess->opl.priv); + + for (int c = 0; c < len * 2; c += 2) { + out_l = 0.0; + out_r = 0.0; + + { + out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; + out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; + if (ess->opl_mix && ess->opl_mixer) + ess->opl_mix(ess->opl_mixer, &out_l, &out_r); + } + + /* TODO: recording from the mixer. */ + out_l *= mixer->master_l; + out_r *= mixer->master_r; + + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; + } + + ess->opl.reset_buffer(ess->opl.priv); +} + +void +ess_filter_cd_audio(int channel, double *buffer, void *priv) +{ + const sb_t *ess = (sb_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_ess; + double c; + double cd = channel ? mixer->cd_r : mixer->cd_l; + double master = channel ? mixer->master_r : mixer->master_l; + + /* TODO: recording from the mixer. */ + c = (*buffer * cd) / 3.0; + *buffer = c * master; +} + void sb_ct1335_mixer_write(uint16_t addr, uint8_t val, void *priv) { @@ -1304,6 +1399,265 @@ sb_ct1745_mixer_reset(sb_t *sb) sb_ct1745_mixer_write(5, 0, sb); } +void +ess_mixer_write(uint16_t addr, uint8_t val, void *priv) +{ + sb_t *ess = (sb_t *) priv; + ess_mixer_t *mixer = &ess->mixer_ess; + + if (!(addr & 1)) { + mixer->index = val; + mixer->regs[0x01] = val; + if (val == 0x40) { + mixer->ess_id_str_pos = 0; + } + } else { + if (mixer->index == 0) { + /* Reset */ + mixer->regs[0x0a] = mixer->regs[0x0c] = 0x00; + mixer->regs[0x0e] = 0x00; + /* Changed default from -11dB to 0dB */ + mixer->regs[0x04] = mixer->regs[0x22] = 0xee; + mixer->regs[0x26] = mixer->regs[0x28] = 0xee; + mixer->regs[0x2e] = 0x00; + + /* Initialize ESS regs. */ + mixer->regs[0x14] = mixer->regs[0x32] = 0x88; + mixer->regs[0x36] = 0x88; + mixer->regs[0x38] = 0x88; + mixer->regs[0x3a] = 0x00; + mixer->regs[0x3e] = 0x00; + + sb_dsp_set_stereo(&ess->dsp, mixer->regs[0x0e] & 2); + } else { + mixer->regs[mixer->index] = val; + + switch (mixer->index) { + /* Compatibility: chain registers 0x02 and 0x22 as well as 0x06 and 0x26 */ + case 0x02: + case 0x06: + case 0x08: + mixer->regs[mixer->index + 0x20] = ((val & 0xe) << 4) | (val & 0xe); + break; + + case 0x0A: + { + uint8_t mic_vol_2bit = (mixer->regs[0x0a] >> 1) & 0x3; + mixer->mic_l = mixer->mic_r = sb_att_7dbstep_2bits[mic_vol_2bit] / 32767.0; + mixer->regs[0x1A] = mic_vol_2bit | (mic_vol_2bit << 2) | (mic_vol_2bit << 4) | (mic_vol_2bit << 6); + break; + } + + case 0x0C: + switch (mixer->regs[0x0C] & 6) { + case 2: + mixer->input_selector = INPUT_CD_L | INPUT_CD_R; + break; + case 6: + mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; + break; + default: + mixer->input_selector = INPUT_MIC; + break; + } + break; + + case 0x14: + mixer->regs[0x4] = val & 0xee; + break; + + case 0x1A: + mixer->mic_l = sb_att_1p4dbstep_4bits[(mixer->regs[0x1A] >> 4) & 0xF] / 32767.0; + mixer->mic_r = sb_att_1p4dbstep_4bits[mixer->regs[0x1A] & 0xF] / 32767.0; + break; + + case 0x1C: + if ((mixer->regs[0x1C] & 0x07) == 0x07) { + mixer->input_selector = INPUT_MIXER_L | INPUT_MIXER_R; + } else if ((mixer->regs[0x1C] & 0x07) == 0x06) { + mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; + } else if ((mixer->regs[0x1C] & 0x06) == 0x02) { + mixer->input_selector = INPUT_CD_L | INPUT_CD_R; + } else if ((mixer->regs[0x1C] & 0x02) == 0) { + mixer->input_selector = INPUT_MIC; + } + break; + + case 0x22: + case 0x26: + case 0x28: + case 0x2E: + mixer->regs[mixer->index - 0x20] = (val & 0xe); + mixer->regs[mixer->index + 0x10] = val; + break; + + /* More compatibility: + SoundBlaster Pro selects register 020h for 030h, 022h for 032h, + 026h for 036h, and 028h for 038h. */ + case 0x30: + mixer->regs[mixer->index - 0x10] = (val & 0xee); + break; + case 0x32: + case 0x36: + case 0x38: + case 0x3e: + mixer->regs[mixer->index - 0x10] = (val & 0xee); + break; + + case 0x3a: + break; + + case 0x00: + case 0x04: + break; + + case 0x0e: + break; + + case 0x64: + mixer->regs[mixer->index] &= ~0x8; + break; + + case 0x40: + { + uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] << 1) & 0x30); + gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); + + if (0) { + /* Not on ES1688. */ + io_removehandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + if ((mixer->regs[0x40] & 0x1) != 0) { + io_sethandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + } + } + switch ((mixer->regs[0x40] >> 5) & 0x7) { + case 0: + mpu401_change_addr(ess->mpu, 0x00); + mpu401_setirq(ess->mpu, -1); + break; + case 1: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, -1); + break; + case 2: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, ess->dsp.sb_irqnum); + break; + case 3: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 11); + break; + case 4: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 9); + break; + case 5: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 5); + break; + case 6: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 7); + break; + case 7: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 10); + break; + } + break; + } + + default: + sb_log("ess: Unknown mixer register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + break; + } + } + + mixer->voice_l = sb_att_2dbstep_4bits[(mixer->regs[0x14] >> 4) & 0x0F] / 32767.0; + mixer->voice_r = sb_att_2dbstep_4bits[mixer->regs[0x14] & 0x0F] / 32767.0; + mixer->master_l = sb_att_2dbstep_4bits[(mixer->regs[0x32] >> 4) & 0x0F] / 32767.0; + mixer->master_r = sb_att_2dbstep_4bits[mixer->regs[0x32] & 0x0F] / 32767.0; + mixer->fm_l = sb_att_2dbstep_4bits[(mixer->regs[0x36] >> 4) & 0x0F] / 32767.0; + mixer->fm_r = sb_att_2dbstep_4bits[mixer->regs[0x36] & 0x0F] / 32767.0; + mixer->cd_l = sb_att_2dbstep_4bits[(mixer->regs[0x38] >> 4) & 0x0F] / 32767.0; + mixer->cd_r = sb_att_2dbstep_4bits[mixer->regs[0x38] & 0x0F] / 32767.0; + mixer->line_l = sb_att_2dbstep_4bits[(mixer->regs[0x3e] >> 4) & 0x0F] / 32767.0; + mixer->line_r = sb_att_2dbstep_4bits[mixer->regs[0x3e] & 0x0F] / 32767.0; + mixer->auxb_l = sb_att_2dbstep_4bits[(mixer->regs[0x3a] >> 4) & 0x0F] / 32767.0; + mixer->auxb_r = sb_att_2dbstep_4bits[mixer->regs[0x3a] & 0x0F] / 32767.0; + + mixer->output_filter = !(mixer->regs[0xe] & 0x20); + mixer->input_filter = !(mixer->regs[0xc] & 0x20); + mixer->in_filter_freq = ((mixer->regs[0xc] & 0x8) == 0) ? 3200 : 8800; + mixer->stereo = mixer->regs[0xe] & 2; + if (mixer->index == 0xe) + sb_dsp_set_stereo(&ess->dsp, val & 2); + + /* TODO: pcspeaker volume? Or is it not worth? */ + } +} + +uint8_t +ess_mixer_read(uint16_t addr, void *priv) +{ + sb_t *ess = (sb_t *) priv; + ess_mixer_t *mixer = &ess->mixer_ess; + + if (!(addr & 1)) + return mixer->index; + + switch (mixer->index) { + case 0x00: + case 0x04: + case 0x0a: + case 0x0c: + case 0x0e: + case 0x14: + case 0x22: + case 0x26: + case 0x28: + case 0x2e: + case 0x02: + case 0x06: + case 0x30: + case 0x32: + case 0x36: + case 0x38: + case 0x3e: + return mixer->regs[mixer->index]; + + case 0x40: + if (ess->dsp.sb_subtype != SB_SUBTYPE_ESS_ES1688) { + uint8_t val = mixer->ess_id_str[mixer->ess_id_str_pos]; + mixer->ess_id_str_pos++; + if (mixer->ess_id_str_pos >= 4) + mixer->ess_id_str_pos = 0; + return val; + } else { + return mixer->regs[mixer->index]; + } + + default: + sb_log("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + break; + } + + return 0x0a; +} + +void +ess_mixer_reset(sb_t *ess) +{ + ess_mixer_write(4, 0, ess); + ess_mixer_write(5, 0, ess); +} + uint8_t sb_mcv_read(int port, void *priv) { @@ -2755,6 +3109,76 @@ sb_awe32_pnp_init(const device_t *info) return sb; } +static void * +ess_1688_init(UNUSED(const device_t *info)) +{ + /* SB Pro 2 port mappings, 220h or 240h. + 2x0 to 2x3 -> FM chip (18 voices) + 2x4 to 2x5 -> Mixer interface + 2x6, 2xA, 2xC, 2xE -> DSP chip + 2x8, 2x9, 388 and 389 FM chip (9 voices) + 2x0+10 to 2x0+13 CDROM interface. */ + sb_t *ess = calloc(sizeof(sb_t), 1); + uint16_t addr = device_get_config_hex16("base"); + + fm_driver_get(FM_ESFM, &ess->opl); + + sb_dsp_set_real_opl(&ess->dsp, 1); + sb_dsp_init(&ess->dsp, SBPRO2, SB_SUBTYPE_ESS_ES1688, ess); + sb_dsp_setaddr(&ess->dsp, addr); + sb_dsp_setirq(&ess->dsp, device_get_config_int("irq")); + sb_dsp_setdma8(&ess->dsp, device_get_config_int("dma")); + sb_dsp_setdma16_8(&ess->dsp, device_get_config_int("dma")); + sb_dsp_setdma16_supported(&ess->dsp, 0); + ess_mixer_reset(ess); + + /* DSP I/O handler is activated in sb_dsp_setaddr */ + { + io_sethandler(addr, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_sethandler(addr + 8, 0x0002, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_sethandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + } + + ess->mixer_enabled = 1; + io_sethandler(addr + 4, 0x0002, + ess_mixer_read, NULL, NULL, + ess_mixer_write, NULL, NULL, + ess); + sound_add_handler(ess_get_buffer_sbpro, ess); + music_add_handler(ess_get_music_buffer_sbpro, ess); + sound_set_cd_audio_filter(ess_filter_cd_audio, ess); + + if (device_get_config_int("receive_input")) { + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &ess->dsp); + } + + ess->mixer_ess.ess_id_str[0] = 0x16; + ess->mixer_ess.ess_id_str[1] = 0x88; + ess->mixer_ess.ess_id_str[2] = (addr >> 8) & 0xff; + ess->mixer_ess.ess_id_str[3] = addr & 0xff; + + ess->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); + /* NOTE: The MPU is initialized disabled and with no IRQ assigned. + * It will be later initialized by the guest OS's drivers. */ + mpu401_init(ess->mpu, 0, -1, M_UART, 1); + sb_dsp_set_mpu(&ess->dsp, ess->mpu); + + ess->gameport = gameport_add(&gameport_pnp_device); + ess->gameport_addr = 0x200; + gameport_remap(ess->gameport, ess->gameport_addr); + + return ess; +} + void sb_close(void *priv) { @@ -4023,6 +4447,104 @@ static const device_config_t sb_awe64_gold_config[] = { }, { .name = "", .description = "", .type = CONFIG_END } }; + +static const device_config_t ess_1688_config[] = { + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x220, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "0x220", + .value = 0x220 + }, + { + .description = "0x240", + .value = 0x240 + }, + { + .description = "0x260", + .value = 0x260 + }, + { + .description = "0x280", + .value = 0x280 + }, + { .description = "" } + } + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 5, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "IRQ 2", + .value = 2 + }, + { + .description = "IRQ 5", + .value = 5 + }, + { + .description = "IRQ 7", + .value = 7 + }, + { + .description = "IRQ 10", + .value = 10 + }, + { .description = "" } + } + }, + { + .name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 1, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "DMA 0", + .value = 0 + }, + { + .description = "DMA 1", + .value = 1 + }, + { + .description = "DMA 3", + .value = 3 + }, + { .description = "" } + } + }, + { + .name = "opl", + .description = "Enable OPL", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, + { + .name = "receive_input", + .description = "Receive input (SB MIDI)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, + { .name = "", .description = "", .type = CONFIG_END } +}; // clang-format on const device_t sb_1_device = { @@ -4360,3 +4882,17 @@ const device_t sb_awe64_gold_device = { .force_redraw = NULL, .config = sb_awe64_gold_config }; + +const device_t ess_1688_device = { + .name = "ESS Technology ES1688", + .internal_name = "ess_es1688", + .flags = DEVICE_ISA, + .local = 0, + .init = ess_1688_init, + .close = sb_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = ess_1688_config +}; From eee63d7312f821631a27d88a655bef21de4fbbb8 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sat, 23 Mar 2024 00:58:31 -0300 Subject: [PATCH 777/936] Better function naming --- src/sound/snd_sb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 1489cb769..fc6b9c6e9 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -682,7 +682,7 @@ sb16_awe32_filter_pc_speaker(int channel, double *buffer, void *priv) } void -ess_get_buffer_sbpro(int32_t *buffer, int len, void *priv) +sb_get_buffer_ess(int32_t *buffer, int len, void *priv) { sb_t *ess = (sb_t *) priv; const ess_mixer_t *mixer = &ess->mixer_ess; @@ -716,7 +716,7 @@ ess_get_buffer_sbpro(int32_t *buffer, int len, void *priv) } void -ess_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) +sb_get_music_buffer_ess(int32_t *buffer, int len, void *priv) { sb_t *ess = (sb_t *) priv; const ess_mixer_t *mixer = &ess->mixer_ess; @@ -3153,8 +3153,8 @@ ess_1688_init(UNUSED(const device_t *info)) ess_mixer_read, NULL, NULL, ess_mixer_write, NULL, NULL, ess); - sound_add_handler(ess_get_buffer_sbpro, ess); - music_add_handler(ess_get_music_buffer_sbpro, ess); + sound_add_handler(sb_get_buffer_ess, ess); + music_add_handler(sb_get_music_buffer_ess, ess); sound_set_cd_audio_filter(ess_filter_cd_audio, ess); if (device_get_config_int("receive_input")) { From 639f05d07c26e5724741eff879f1144201f49c73 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sat, 23 Mar 2024 01:09:49 -0300 Subject: [PATCH 778/936] Small fixes --- src/sound/snd_sb.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index fc6b9c6e9..61dbc8c7a 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -1523,7 +1523,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] << 1) & 0x30); gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); - if (0) { + if (ess->dsp.sb_subtype != SB_SUBTYPE_ESS_ES1688) { /* Not on ES1688. */ io_removehandler(0x0388, 0x0004, ess->opl.read, NULL, NULL, @@ -3112,12 +3112,6 @@ sb_awe32_pnp_init(const device_t *info) static void * ess_1688_init(UNUSED(const device_t *info)) { - /* SB Pro 2 port mappings, 220h or 240h. - 2x0 to 2x3 -> FM chip (18 voices) - 2x4 to 2x5 -> Mixer interface - 2x6, 2xA, 2xC, 2xE -> DSP chip - 2x8, 2x9, 388 and 389 FM chip (9 voices) - 2x0+10 to 2x0+13 CDROM interface. */ sb_t *ess = calloc(sizeof(sb_t), 1); uint16_t addr = device_get_config_hex16("base"); @@ -4462,17 +4456,17 @@ static const device_config_t ess_1688_config[] = { .description = "0x220", .value = 0x220 }, + { + .description = "0x230", + .value = 0x230 + }, { .description = "0x240", .value = 0x240 }, { - .description = "0x260", - .value = 0x260 - }, - { - .description = "0x280", - .value = 0x280 + .description = "0x250", + .value = 0x250 }, { .description = "" } } From 2466da21618ee44cd0b9f4ccf35afe1e1ae18727 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 23 Mar 2024 06:15:34 +0100 Subject: [PATCH 779/936] Prepared the API to set the PIT constant. --- src/include/86box/pit.h | 9 ++++++ src/include/86box/pit_fast.h | 5 +++ src/pit.c | 38 ++++++++++++++++++---- src/pit_fast.c | 63 +++++++++++++++++++++++------------- src/sound/snd_pas16.c | 28 ++++++++++++++-- 5 files changed, 112 insertions(+), 31 deletions(-) diff --git a/src/include/86box/pit.h b/src/include/86box/pit.h index d9bce667d..ed60cfa29 100644 --- a/src/include/86box/pit.h +++ b/src/include/86box/pit.h @@ -71,6 +71,9 @@ typedef struct PIT { ctr_t counters[3]; uint8_t ctrl; + + uint64_t pit_const; + void *dev_priv; } pit_t; @@ -97,6 +100,7 @@ typedef struct pit_intf_t { /* Sets a counter's load count handler. */ void (*set_load_func)(void *data, int counter_id, void (*func)(uint8_t new_m, int new_count)); void (*ctr_clock)(void *data, int counter_id); + void (*set_pit_const)(void *data, uint64_t pit_const); void *data; } pit_intf_t; @@ -108,6 +112,7 @@ extern double PCICLK; extern double AGPCLK; extern uint64_t PITCONST; +extern uint64_t PAS16CONST; extern uint64_t ISACONST; extern uint64_t CGACONST; extern uint64_t MDACONST; @@ -118,6 +123,10 @@ extern uint64_t RTCCONST; extern int refresh_at_enable; +extern void pit_change_pas16_const(double prescale); + +extern void pit_set_pit_const(void *data, uint64_t pit_const); + /* Sets a counter's CLOCK input. */ extern void pit_ctr_set_clock(ctr_t *ctr, int clock, void *priv); diff --git a/src/include/86box/pit_fast.h b/src/include/86box/pit_fast.h index 845105185..2a8181a94 100644 --- a/src/include/86box/pit_fast.h +++ b/src/include/86box/pit_fast.h @@ -56,6 +56,9 @@ typedef struct ctrf_t { }; uint32_t l; + + uint64_t pit_const; + pc_timer_t timer; void (*load_func)(uint8_t new_m, int new_count); @@ -70,6 +73,8 @@ typedef struct pitf_t { uint8_t ctrl; } pitf_t; +extern void pitf_set_pit_const(void *data, uint64_t pit_const); + extern uint8_t pitf_read_reg(void *priv, uint8_t reg); extern const pit_intf_t pit_fast_intf; diff --git a/src/pit.c b/src/pit.c index 20baf3f66..7ab48bbd8 100644 --- a/src/pit.c +++ b/src/pit.c @@ -47,6 +47,7 @@ pit_intf_t pit_devs[2]; double cpuclock; double PITCONSTD; +double PAS16CONSTD; double SYSCLK; double isa_timing; double bus_timing; @@ -56,6 +57,7 @@ double PCICLK; double AGPCLK; uint64_t PITCONST; +uint64_t PAS16CONST; uint64_t ISACONST; uint64_t CGACONST; uint64_t MDACONST; @@ -523,7 +525,7 @@ pit_timer_over(void *priv) for (uint8_t i = 0; i < 3; i++) pit_ctr_set_clock_common(&dev->counters[i], dev->clock, dev); - timer_advance_u64(&dev->callback_timer, PITCONST >> 1ULL); + timer_advance_u64(&dev->callback_timer, dev->pit_const >> 1ULL); } static void @@ -873,6 +875,20 @@ pit_handler(int set, uint16_t base, int size, void *priv) io_handler(set, base, size, pit_read, NULL, NULL, pit_write, NULL, NULL, priv); } +void +pit_set_pit_const(void *data, uint64_t pit_const) +{ + pit_t *pit = (pit_t *) data; + + pit->pit_const = pit_const; +} + +static void +pit_speed_changed(void *priv) +{ + pit_set_pit_const(priv, PITCONST); +} + static void pit_close(void *priv) { @@ -896,7 +912,7 @@ pit_init(const device_t *info) if (!(dev->flags & PIT_PS2) && !(dev->flags & PIT_CUSTOM_CLOCK)) { timer_add(&dev->callback_timer, pit_timer_over, (void *) dev, 0); - timer_set_delay_u64(&dev->callback_timer, PITCONST >> 1ULL); + timer_set_delay_u64(&dev->callback_timer, dev->pit_const >> 1ULL); } dev->flags = info->local; @@ -919,7 +935,7 @@ const device_t i8253_device = { .close = pit_close, .reset = NULL, { .available = NULL }, - .speed_changed = NULL, + .speed_changed = pit_speed_changed, .force_redraw = NULL, .config = NULL }; @@ -947,7 +963,7 @@ const device_t i8254_device = { .close = pit_close, .reset = NULL, { .available = NULL }, - .speed_changed = NULL, + .speed_changed = pit_speed_changed, .force_redraw = NULL, .config = NULL }; @@ -961,7 +977,7 @@ const device_t i8254_sec_device = { .close = pit_close, .reset = NULL, { .available = NULL }, - .speed_changed = NULL, + .speed_changed = pit_speed_changed, .force_redraw = NULL, .config = NULL }; @@ -989,7 +1005,7 @@ const device_t i8254_ps2_device = { .close = pit_close, .reset = NULL, { .available = NULL }, - .speed_changed = NULL, + .speed_changed = pit_speed_changed, .force_redraw = NULL, .config = NULL }; @@ -1074,6 +1090,12 @@ pit_ps2_init(int type) return pit; } +void +pit_change_pas16_const(double prescale) +{ + PAS16CONST = (uint64_t) ((PITCONSTD / prescale) * (double) (1ULL << 32)); +} + void pit_set_clock(uint32_t clock) { @@ -1169,6 +1191,9 @@ pit_set_clock(uint32_t clock) TIMER_USEC = (uint64_t) ((cpuclock / 1000000.0) * (double) (1ULL << 32)); + PAS16CONSTD = (cpuclock / 441000.0); + PAS16CONST = (uint64_t) (PITCONSTD * (double) (1ULL << 32)); + isa_timing = (cpuclock / (double) cpu_isa_speed); if (cpu_64bitbus) bus_timing = (cpuclock / (cpu_busspeed / 2)); @@ -1200,5 +1225,6 @@ const pit_intf_t pit_classic_intf = { &pit_ctr_set_out_func, &pit_ctr_set_load_func, &ctr_clock, + &pit_set_pit_const, NULL, }; diff --git a/src/pit_fast.c b/src/pit_fast.c index 9c5d622ec..0a7e1db09 100644 --- a/src/pit_fast.c +++ b/src/pit_fast.c @@ -126,7 +126,7 @@ static int pitf_read_timer(ctrf_t *ctr) { if (ctr->using_timer && !(ctr->m == 3 && !ctr->gate) && timer_is_enabled(&ctr->timer)) { - int read = (int) ((timer_get_remaining_u64(&ctr->timer)) / PITCONST); + int read = (int) ((timer_get_remaining_u64(&ctr->timer)) / ctr->pit_const); if (ctr->m == 2) read++; if (read < 0) @@ -168,7 +168,7 @@ pitf_ctr_load(ctrf_t *ctr, void *priv) case 0: /*Interrupt on terminal count*/ ctr->count = l; if (ctr->using_timer) - timer_set_delay_u64(&ctr->timer, (uint64_t) (l * PITCONST)); + timer_set_delay_u64(&ctr->timer, (uint64_t) (l * ctr->pit_const)); pitf_ctr_set_out(ctr, 0, pit); ctr->thit = 0; ctr->enabled = ctr->gate; @@ -180,7 +180,7 @@ pitf_ctr_load(ctrf_t *ctr, void *priv) if (ctr->initial) { ctr->count = l - 1; if (ctr->using_timer) - timer_set_delay_u64(&ctr->timer, (uint64_t) ((l - 1) * PITCONST)); + timer_set_delay_u64(&ctr->timer, (uint64_t) ((l - 1) * ctr->pit_const)); pitf_ctr_set_out(ctr, 1, pit); ctr->thit = 0; } @@ -190,7 +190,7 @@ pitf_ctr_load(ctrf_t *ctr, void *priv) if (ctr->initial) { ctr->count = l; if (ctr->using_timer) - timer_set_delay_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * PITCONST)); + timer_set_delay_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * ctr->pit_const)); pitf_ctr_set_out(ctr, 1, pit); ctr->thit = 0; } @@ -202,7 +202,7 @@ pitf_ctr_load(ctrf_t *ctr, void *priv) else { ctr->count = l; if (ctr->using_timer) - timer_set_delay_u64(&ctr->timer, (uint64_t) (l * PITCONST)); + timer_set_delay_u64(&ctr->timer, (uint64_t) (l * ctr->pit_const)); pitf_ctr_set_out(ctr, 0, pit); ctr->thit = 0; } @@ -240,7 +240,7 @@ pitf_set_gate_no_timer(ctrf_t *ctr, int gate, void *priv) case 0: /*Interrupt on terminal count*/ case 4: /*Software triggered stobe*/ if (ctr->using_timer && !ctr->running) - timer_set_delay_u64(&ctr->timer, (uint64_t) (l * PITCONST)); + timer_set_delay_u64(&ctr->timer, (uint64_t) (l * ctr->pit_const)); ctr->enabled = gate; break; case 1: /*Hardware retriggerable one-shot*/ @@ -248,7 +248,7 @@ pitf_set_gate_no_timer(ctrf_t *ctr, int gate, void *priv) if (gate && !ctr->gate) { ctr->count = l; if (ctr->using_timer) - timer_set_delay_u64(&ctr->timer, (uint64_t) (l * PITCONST)); + timer_set_delay_u64(&ctr->timer, (uint64_t) (l * ctr->pit_const)); pitf_ctr_set_out(ctr, 0, pit); ctr->thit = 0; ctr->enabled = 1; @@ -258,7 +258,7 @@ pitf_set_gate_no_timer(ctrf_t *ctr, int gate, void *priv) if (gate && !ctr->gate) { ctr->count = l - 1; if (ctr->using_timer) - timer_set_delay_u64(&ctr->timer, (uint64_t) (l * PITCONST)); + timer_set_delay_u64(&ctr->timer, (uint64_t) (l * ctr->pit_const)); pitf_ctr_set_out(ctr, 1, pit); ctr->thit = 0; } @@ -268,7 +268,7 @@ pitf_set_gate_no_timer(ctrf_t *ctr, int gate, void *priv) if (gate && !ctr->gate) { ctr->count = l; if (ctr->using_timer) - timer_set_delay_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * PITCONST)); + timer_set_delay_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * ctr->pit_const)); pitf_ctr_set_out(ctr, 1, pit); ctr->thit = 0; } @@ -306,7 +306,7 @@ pitf_over(ctrf_t *ctr, void *priv) if (ctr->disabled) { ctr->count += 0xffff; if (ctr->using_timer) - timer_advance_u64(&ctr->timer, (uint64_t) (0xffff * PITCONST)); + timer_advance_u64(&ctr->timer, (uint64_t) (0xffff * ctr->pit_const)); return; } @@ -318,12 +318,12 @@ pitf_over(ctrf_t *ctr, void *priv) ctr->thit = 1; ctr->count += 0xffff; if (ctr->using_timer) - timer_advance_u64(&ctr->timer, (uint64_t) (0xffff * PITCONST)); + timer_advance_u64(&ctr->timer, (uint64_t) (0xffff * ctr->pit_const)); break; case 2: /*Rate generator*/ ctr->count += l; if (ctr->using_timer) - timer_advance_u64(&ctr->timer, (uint64_t) (l * PITCONST)); + timer_advance_u64(&ctr->timer, (uint64_t) (l * ctr->pit_const)); pitf_ctr_set_out(ctr, 0, pit); pitf_ctr_set_out(ctr, 1, pit); break; @@ -332,16 +332,16 @@ pitf_over(ctrf_t *ctr, void *priv) pitf_ctr_set_out(ctr, 0, pit); ctr->count += (l >> 1); if (ctr->using_timer) - timer_advance_u64(&ctr->timer, (uint64_t) ((l >> 1) * PITCONST)); + timer_advance_u64(&ctr->timer, (uint64_t) ((l >> 1) * ctr->pit_const)); } else { pitf_ctr_set_out(ctr, 1, pit); ctr->count += ((l + 1) >> 1); if (ctr->using_timer) - timer_advance_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * PITCONST)); + timer_advance_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * ctr->pit_const)); } #if 0 if (!t) - pclog("pit_over: square wave mode c=%x %lli %f\n", pit.c[t], tsc, PITCONST); + pclog("pit_over: square wave mode c=%x %lli %f\n", pit.c[t], tsc, ctr->pit_const); #endif break; case 4: /*Software triggered strove*/ @@ -353,12 +353,12 @@ pitf_over(ctrf_t *ctr, void *priv) ctr->newcount = 0; ctr->count += l; if (ctr->using_timer) - timer_advance_u64(&ctr->timer, (uint64_t) (l * PITCONST)); + timer_advance_u64(&ctr->timer, (uint64_t) (l * ctr->pit_const)); } else { ctr->thit = 1; ctr->count += 0xffff; if (ctr->using_timer) - timer_advance_u64(&ctr->timer, (uint64_t) (0xffff * PITCONST)); + timer_advance_u64(&ctr->timer, (uint64_t) (0xffff * ctr->pit_const)); } break; case 5: /*Hardware triggered strove*/ @@ -369,7 +369,7 @@ pitf_over(ctrf_t *ctr, void *priv) ctr->thit = 1; ctr->count += 0xffff; if (ctr->using_timer) - timer_advance_u64(&ctr->timer, (uint64_t) (0xffff * PITCONST)); + timer_advance_u64(&ctr->timer, (uint64_t) (0xffff * ctr->pit_const)); break; default: @@ -659,6 +659,24 @@ pitf_reset(pitf_t *dev) dev->counters[2].gate = 0; } +void +pitf_set_pit_const(void *data, uint64_t pit_const) +{ + pitf_t *pit = (pitf_t *) data; + ctrf_t *ctr; + + for (uint8_t i = 0; i < 3; i++) { + ctr = &pit->counters[i]; + ctr->pit_const = pit_const; + } +} + +static void +pitf_speed_changed(void *priv) +{ + pitf_set_pit_const(priv, PITCONST); +} + static void pitf_close(void *priv) { @@ -707,7 +725,7 @@ const device_t i8253_fast_device = { .close = pitf_close, .reset = NULL, { .available = NULL }, - .speed_changed = NULL, + .speed_changed = pitf_speed_changed, .force_redraw = NULL, .config = NULL }; @@ -721,7 +739,7 @@ const device_t i8254_fast_device = { .close = pitf_close, .reset = NULL, { .available = NULL }, - .speed_changed = NULL, + .speed_changed = pitf_speed_changed, .force_redraw = NULL, .config = NULL }; @@ -735,7 +753,7 @@ const device_t i8254_sec_fast_device = { .close = pitf_close, .reset = NULL, { .available = NULL }, - .speed_changed = NULL, + .speed_changed = pitf_speed_changed, .force_redraw = NULL, .config = NULL }; @@ -763,7 +781,7 @@ const device_t i8254_ps2_fast_device = { .close = pitf_close, .reset = NULL, { .available = NULL }, - .speed_changed = NULL, + .speed_changed = pitf_speed_changed, .force_redraw = NULL, .config = NULL }; @@ -777,5 +795,6 @@ const pit_intf_t pit_fast_intf = { &pitf_ctr_set_out_func, &pitf_ctr_set_load_func, &pitf_ctr_clock, + &pitf_set_pit_const, NULL, }; diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index d8187cf0f..45a18ff73 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -354,7 +354,6 @@ static void pas16_out(uint16_t port, uint8_t val, void *priv) { pas16_t *pas16 = (pas16_t *) priv; - pit_t *pit = (pit_t *) pas16->pit; pas16_log("pas16_out : port %04X val %02X %04X:%04X\n", port, val, CS, cpu_state.pc); switch (port) { case 0x388: @@ -728,6 +727,28 @@ pas16_get_music_buffer(int32_t *buffer, int len, void *priv) pas16->opl.reset_buffer(pas16->opl.priv); } +static void +pas16_speed_changed(void *priv) +{ + pas16_t *pas16 = (pas16_t *) priv; + + /* TODO: In PAS16 mode: + pit_change_pas16_const(prescale); + pit_set_pit_const(pas16->pit, PAS16CONST); + */ + + pit_set_pit_const(pas16->pit, PITCONST); +} + +static void +pas16_reset(void *priv) +{ + pas16_t *pas16 = (pas16_t *) priv; + + /* TODO: Reset the entire PAS16 state here. */ + pit_set_pit_const(pas16->pit, PITCONST); +} + static void * pas16_init(UNUSED(const device_t *info)) { @@ -743,6 +764,7 @@ pas16_init(UNUSED(const device_t *info)) sb_dsp_set_mpu(&pas16->dsp, pas16->mpu); pas16->pit = device_add(&i8254_ext_io_device); + pit_set_pit_const(pas16->pit, PITCONST); pas16->pit->dev_priv = pas16; pas16->irq = 10; pas16->dma = 3; @@ -798,9 +820,9 @@ const device_t pas16_device = { .local = 0, .init = pas16_init, .close = pas16_close, - .reset = NULL, + .reset = pas16_reset, { .available = NULL }, - .speed_changed = NULL, + .speed_changed = pas16_speed_changed, .force_redraw = NULL, .config = pas16_config }; From 4884f8664cfe2c88605f6a5ed365cc4798eea898 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 23 Mar 2024 06:18:11 +0100 Subject: [PATCH 780/936] Set PIT constant on PIT init. --- src/pit.c | 2 ++ src/pit_fast.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/pit.c b/src/pit.c index 7ab48bbd8..b41f2acc9 100644 --- a/src/pit.c +++ b/src/pit.c @@ -910,6 +910,8 @@ pit_init(const device_t *info) pit_t *dev = (pit_t *) malloc(sizeof(pit_t)); pit_reset(dev); + pit_set_pit_const(dev, PITCONST); + if (!(dev->flags & PIT_PS2) && !(dev->flags & PIT_CUSTOM_CLOCK)) { timer_add(&dev->callback_timer, pit_timer_over, (void *) dev, 0); timer_set_delay_u64(&dev->callback_timer, dev->pit_const >> 1ULL); diff --git a/src/pit_fast.c b/src/pit_fast.c index 0a7e1db09..fa643af8a 100644 --- a/src/pit_fast.c +++ b/src/pit_fast.c @@ -696,6 +696,9 @@ static void * pitf_init(const device_t *info) { pitf_t *dev = (pitf_t *) malloc(sizeof(pitf_t)); + + pitf_set_pit_const(dev, PITCONST); + pitf_reset(dev); dev->flags = info->local; From 1d2a7e3bca1ebf519a765fcaa997a905a48e2ba9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 23 Mar 2024 06:48:53 +0100 Subject: [PATCH 781/936] Set pit constant after PIT reset. --- src/pit.c | 1 + src/pit_fast.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pit.c b/src/pit.c index b41f2acc9..b5d402bb3 100644 --- a/src/pit.c +++ b/src/pit.c @@ -908,6 +908,7 @@ static void * pit_init(const device_t *info) { pit_t *dev = (pit_t *) malloc(sizeof(pit_t)); + pit_reset(dev); pit_set_pit_const(dev, PITCONST); diff --git a/src/pit_fast.c b/src/pit_fast.c index fa643af8a..acaa6c271 100644 --- a/src/pit_fast.c +++ b/src/pit_fast.c @@ -697,10 +697,10 @@ pitf_init(const device_t *info) { pitf_t *dev = (pitf_t *) malloc(sizeof(pitf_t)); - pitf_set_pit_const(dev, PITCONST); - pitf_reset(dev); + pitf_set_pit_const(dev, PITCONST); + dev->flags = info->local; if (!(dev->flags & PIT_PS2) && !(dev->flags & PIT_CUSTOM_CLOCK)) { From 6c519904fd43130a3e1e53fcafa5165cfe44b9c2 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sat, 23 Mar 2024 12:22:11 -0300 Subject: [PATCH 782/936] Cleanup: miscellaneous --- src/include/86box/snd_sb.h | 1 + src/include/86box/snd_sb_dsp.h | 17 +++++------ src/sound/snd_opl_esfm.c | 11 +++---- src/sound/snd_sb.c | 52 ++++++++++++++++++---------------- src/sound/snd_sb_dsp.c | 14 ++++----- 5 files changed, 47 insertions(+), 48 deletions(-) diff --git a/src/include/86box/snd_sb.h b/src/include/86box/snd_sb.h index 1ab94c9e1..b26c5f06e 100644 --- a/src/include/86box/snd_sb.h +++ b/src/include/86box/snd_sb.h @@ -142,6 +142,7 @@ typedef struct ess_mixer_t { double mic_r; double auxb_l; double auxb_r; + double speaker; /*see sb_ct1745_mixer for values for input selector*/ int32_t input_selector; /* extra values for input selector */ diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index f5905ccc2..a00f512a3 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -7,11 +7,10 @@ #define SB_SUBTYPE_DEFAULT 0 /*Handle as a Creative card*/ #define SB_SUBTYPE_CLONE_AZT2316A_0X11 1 /*Aztech Sound Galaxy Pro 16 AB, DSP 3.1 - SBPRO2 clone*/ #define SB_SUBTYPE_CLONE_AZT1605_0X0C 2 /*Aztech Sound Galaxy Nova 16 Extra / Packard Bell Forte 16, DSP 2.1 - SBPRO2 clone*/ -#define SB_SUBTYPE_ESS_ES688 3 /* ESS Technology ES688 */ -#define SB_SUBTYPE_ESS_ES1688 4 /* ESS Technology ES1688 */ +#define SB_SUBTYPE_ESS_ES1688 3 /* ESS Technology ES1688 */ /* ESS-related */ -#define IS_ESS(dsp) ((dsp)->sb_subtype == SB_SUBTYPE_ESS_ES688 || (dsp)->sb_subtype == SB_SUBTYPE_ESS_ES1688) /* check for future ESS cards here */ +#define IS_ESS(dsp) ((dsp)->sb_subtype == SB_SUBTYPE_ESS_ES1688) /* check for future ESS cards here */ /* aztech-related */ #define IS_AZTECH(dsp) ((dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11 || (dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) /* check for future AZT cards here */ @@ -149,13 +148,15 @@ typedef struct sb_dsp_t { uint8_t ess_extended_mode; uint8_t ess_reload_len; uint32_t ess_dma_counter; - int ess_irq_generic; - int ess_irq_dmactr; - // ESPCM + /* IRQ status flags (0x22C) */ + uint8_t ess_irq_generic; + uint8_t ess_irq_dmactr; + + /* ESPCM */ fifo64_t *espcm_fifo; - int espcm_fifo_reset; - int espcm_mode; + uint8_t espcm_fifo_reset; + uint8_t espcm_mode; /* see ESPCM in "NON-PCM SAMPLE FORMATS" deflist in snd_sb_dsp.c */ uint8_t espcm_sample_idx; uint8_t espcm_range; uint8_t espcm_byte_buffer[4]; diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index c36ec4160..78cbec11d 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -42,7 +42,6 @@ typedef struct { int8_t flags; int8_t pad; - uint16_t port; uint8_t status; uint8_t timer_ctrl; uint16_t timer_count[2]; @@ -269,14 +268,12 @@ esfm_drv_read(uint16_t port, void *priv) static void esfm_drv_write_buffered(esfm_drv_t *dev, uint8_t val) { - uint16_t p = dev->port; - - ESFM_write_reg_buffered_fast(&dev->opl, dev->opl.addr_latch, val); + uint16_t p = dev->opl.addr_latch & 0x07ff; if (dev->opl.native_mode) { p -= 0x400; - p &= 0x1ff; } + p &= 0x1ff; switch (p) { case 0x002: /* Timer 1 */ @@ -304,6 +301,8 @@ esfm_drv_write_buffered(esfm_drv_t *dev, uint8_t val) default: break; } + + ESFM_write_reg_buffered_fast(&dev->opl, dev->opl.addr_latch, val); } static void @@ -321,14 +320,12 @@ esfm_drv_write(uint16_t port, uint8_t val, void *priv) esfm_drv_write_buffered(dev, val); else { ESFM_write_port(&dev->opl, port & 3, val); - dev->port = dev->opl.addr_latch & 0x07ff; } } else { if ((port & 0x0001) == 0x0001) esfm_drv_write_buffered(dev, val); else { ESFM_write_port(&dev->opl, port & 3, val); - dev->port = dev->opl.addr_latch & 0x01ff; } } } diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 61dbc8c7a..f26fba1eb 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -89,6 +89,11 @@ static const double sb_att_2dbstep_4bits[] = { 164.0, 1304.0, 1641.0, 2067.0, 2602.0, 3276.0, 4125.0, 5192.0, 6537.0, 8230.0, 10362.0, 13044.0, 16422.0, 20674.0, 26027.0, 32767.0 }; + +/* Attenuation table for ESS 3-bit PC speaker volume. */ +static const double sb_att_3dbstep_3bits[] = { + 0.0, 4125.0, 5826.0, 8230.0, 11626.0, 16422.0, 23197.0, 32767.0 +}; // clang-format on static const uint16_t sb_mcv_addr[8] = { 0x200, 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x270 }; @@ -730,12 +735,10 @@ sb_get_music_buffer_ess(int32_t *buffer, int len, void *priv) out_l = 0.0; out_r = 0.0; - { - out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; - out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; - if (ess->opl_mix && ess->opl_mixer) - ess->opl_mix(ess->opl_mixer, &out_l, &out_r); - } + out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; + out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; + if (ess->opl_mix && ess->opl_mixer) + ess->opl_mix(ess->opl_mixer, &out_l, &out_r); /* TODO: recording from the mixer. */ out_l *= mixer->master_l; @@ -1421,11 +1424,12 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->regs[0x26] = mixer->regs[0x28] = 0xee; mixer->regs[0x2e] = 0x00; - /* Initialize ESS regs. */ - mixer->regs[0x14] = mixer->regs[0x32] = 0x88; - mixer->regs[0x36] = 0x88; - mixer->regs[0x38] = 0x88; + /* Initialize ESS regs + * Defaulting to 0dB instead of the standard -11dB. */ + mixer->regs[0x14] = mixer->regs[0x32] = 0xff; + mixer->regs[0x36] = mixer->regs[0x38] = 0xff; mixer->regs[0x3a] = 0x00; + mixer->regs[0x3c] = 0x05; mixer->regs[0x3e] = 0x00; sb_dsp_set_stereo(&ess->dsp, mixer->regs[0x0e] & 2); @@ -1460,6 +1464,14 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->input_selector = INPUT_MIC; break; } + mixer->input_filter = !(mixer->regs[0xC] & 0x20); + mixer->in_filter_freq = ((mixer->regs[0xC] & 0x8) == 0) ? 3200 : 8800; + break; + + case 0x0E: + mixer->output_filter = !(mixer->regs[0xE] & 0x20); + mixer->stereo = mixer->regs[0xE] & 2; + sb_dsp_set_stereo(&ess->dsp, val & 2); break; case 0x14: @@ -1495,8 +1507,6 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) SoundBlaster Pro selects register 020h for 030h, 022h for 032h, 026h for 036h, and 028h for 038h. */ case 0x30: - mixer->regs[mixer->index - 0x10] = (val & 0xee); - break; case 0x32: case 0x36: case 0x38: @@ -1505,15 +1515,13 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) break; case 0x3a: + case 0x3c: break; case 0x00: case 0x04: break; - case 0x0e: - break; - case 0x64: mixer->regs[mixer->index] &= ~0x8; break; @@ -1587,19 +1595,13 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->fm_r = sb_att_2dbstep_4bits[mixer->regs[0x36] & 0x0F] / 32767.0; mixer->cd_l = sb_att_2dbstep_4bits[(mixer->regs[0x38] >> 4) & 0x0F] / 32767.0; mixer->cd_r = sb_att_2dbstep_4bits[mixer->regs[0x38] & 0x0F] / 32767.0; - mixer->line_l = sb_att_2dbstep_4bits[(mixer->regs[0x3e] >> 4) & 0x0F] / 32767.0; - mixer->line_r = sb_att_2dbstep_4bits[mixer->regs[0x3e] & 0x0F] / 32767.0; mixer->auxb_l = sb_att_2dbstep_4bits[(mixer->regs[0x3a] >> 4) & 0x0F] / 32767.0; mixer->auxb_r = sb_att_2dbstep_4bits[mixer->regs[0x3a] & 0x0F] / 32767.0; + mixer->line_l = sb_att_2dbstep_4bits[(mixer->regs[0x3e] >> 4) & 0x0F] / 32767.0; + mixer->line_r = sb_att_2dbstep_4bits[mixer->regs[0x3e] & 0x0F] / 32767.0; + mixer->speaker = sb_att_3dbstep_3bits[mixer->regs[0x3c] & 0x07] / 32767.0; - mixer->output_filter = !(mixer->regs[0xe] & 0x20); - mixer->input_filter = !(mixer->regs[0xc] & 0x20); - mixer->in_filter_freq = ((mixer->regs[0xc] & 0x8) == 0) ? 3200 : 8800; - mixer->stereo = mixer->regs[0xe] & 2; - if (mixer->index == 0xe) - sb_dsp_set_stereo(&ess->dsp, val & 2); - - /* TODO: pcspeaker volume? Or is it not worth? */ + /* TODO: PC Speaker volume */ } } diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index ad6209fb5..332299c4f 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -29,11 +29,13 @@ #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> +/* NON-PCM SAMPLE FORMATS */ #define ADPCM_4 1 #define ADPCM_26 2 #define ADPCM_2 3 #define ESPCM_4 4 #define ESPCM_3 5 +/* ESPCM_2? */ #define ESPCM_1 7 #define ESPCM_4E 8 // for differentiating between 4-bit encoding and decoding modes @@ -1596,10 +1598,6 @@ sb_exec_command(sb_dsp_t *dsp) switch (dsp->sb_subtype) { default: break; - case SB_SUBTYPE_ESS_ES688: - sb_add_data(dsp, 0x68); - sb_add_data(dsp, 0x80 | 0x04); - break; case SB_SUBTYPE_ESS_ES1688: // Determined via Windows driver debugging. sb_add_data(dsp, 0x68); @@ -1792,11 +1790,11 @@ sb_read(uint16_t a, void *priv) } uint8_t busy_flag = dsp->wb_full ? 0x80 : 0x00; uint8_t data_rdy = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x40; - uint8_t fifo_full = 0; // Unimplemented - uint8_t fifo_empty = 0; - uint8_t fifo_half = 0; + uint8_t fifo_full = 0; /* Unimplemented */ + uint8_t fifo_empty = 0; /* (this is for the 256-byte extended mode FIFO, */ + uint8_t fifo_half = 0; /* not the standard 64-byte FIFO) */ uint8_t irq_generic = dsp->ess_irq_generic ? 0x04 : 0x00; - uint8_t irq_fifohe = 0; // Unimplemented + uint8_t irq_fifohe = 0; /* Unimplemented (ditto) */ uint8_t irq_dmactr = dsp->ess_irq_dmactr ? 0x01 : 0x00; return busy_flag | data_rdy | fifo_full | fifo_empty | fifo_half | irq_generic | irq_fifohe | irq_dmactr; From 0af83efb8f5e7f6c919d2f9b7a4dc7c02e074b16 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sat, 23 Mar 2024 12:47:41 -0300 Subject: [PATCH 783/936] Correcting device name --- src/sound/snd_sb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index f26fba1eb..13baa3621 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -4880,7 +4880,7 @@ const device_t sb_awe64_gold_device = { }; const device_t ess_1688_device = { - .name = "ESS Technology ES1688", + .name = "ESS AudioDrive ES1688", .internal_name = "ess_es1688", .flags = DEVICE_ISA, .local = 0, From f45fe7b1212a421da808d8bbc7d705cea6cbc8ab Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 23 Mar 2024 17:19:33 +0100 Subject: [PATCH 784/936] Bump version to 4.2. --- 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 11265d09a..5bafadcc1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,7 @@ if(MUNT_EXTERNAL) endif() project(86Box - VERSION 4.1.1 + VERSION 4.2 DESCRIPTION "Emulator of x86-based systems" HOMEPAGE_URL "https://86box.net" LANGUAGES C CXX) diff --git a/debian/changelog b/debian/changelog index 00179d466..fe8aa6821 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ -86box (4.1.1) UNRELEASED; urgency=medium +86box (4.2) UNRELEASED; urgency=medium * Bump release. - -- Jasmine Iwanek Fri, 23 Feb 2024 07:23:12 +0100 + -- Jasmine Iwanek Sat, 23 Mar 2024 17:19:08 +0100 diff --git a/src/unix/assets/86Box.spec b/src/unix/assets/86Box.spec index 99d01c594..fdd7bbf55 100644 --- a/src/unix/assets/86Box.spec +++ b/src/unix/assets/86Box.spec @@ -15,7 +15,7 @@ %global romver 4.1 Name: 86Box -Version: 4.1.1 +Version: 4.2 Release: 1%{?dist} Summary: Classic PC emulator License: GPLv2+ @@ -121,5 +121,5 @@ popd %{_datadir}/%{name}/roms %changelog -* Fri Feb 23 2024 Robert de Rooy 4.1.1-1 +* Sat Mar 23 2024 Robert de Rooy 4.2-1 - Bump release diff --git a/src/unix/assets/net.86box.86Box.metainfo.xml b/src/unix/assets/net.86box.86Box.metainfo.xml index 1f15f39a5..18df49703 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 d7d7ffd82..d9ea83dba 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,6 +1,6 @@ { "name": "86box", - "version-string": "4.1.1", + "version-string": "4.2", "homepage": "https://86box.net/", "documentation": "https://86box.readthedocs.io/", "license": "GPL-2.0-or-later", From f63cc093e12482136a2b3eeb2416ceeaef05a050 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 23 Mar 2024 17:22:36 +0100 Subject: [PATCH 785/936] net_modem and sb_dsp: Warning fixes. --- src/network/net_modem.c | 4 ---- src/sound/snd_sb_dsp.c | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index b1b6a2eca..082874f54 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -141,8 +141,6 @@ typedef struct modem_t netcard_t *card; } modem_t; -static modem_t *instance; - #define MREG_AUTOANSWER_COUNT 0 #define MREG_RING_COUNT 1 #define MREG_ESCAPE_CHAR 2 @@ -576,7 +574,6 @@ modem_dial(modem_t* modem, const char* str) else { char buf[128] = ""; - const char *destination = buf; strcpy(buf, str); // Scan host for port uint16_t port; @@ -1106,7 +1103,6 @@ modem_rx(void *priv, uint8_t *buf, int io_len) { #if 1 modem_t* modem = (modem_t*)priv; - uint8_t c = 0; uint32_t i = 0; if (modem->tcpIpMode) diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 332299c4f..927a06d8c 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -2625,7 +2625,7 @@ sb_poll_i(void *priv) dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; if (dsp->espcm_sample_idx >= 19) { - int i, bit, table_addr, sigma, last_sigma; + int i, table_addr, sigma, last_sigma; int8_t min_sample = 127, max_sample = -128, s; uint8_t b; From 50a2a479c158c85575b2e93513e5d1c33193db1f Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Sat, 23 Mar 2024 16:15:35 -0400 Subject: [PATCH 786/936] Revert earlier change to zip_load to fix an image load crash --- src/disk/zip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/disk/zip.c b/src/disk/zip.c index d4b644865..7045b1e41 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -531,7 +531,7 @@ zip_load(zip_t *dev, char *fn) if (fseek(dev->drv->fp, dev->drv->base, SEEK_SET) == -1) fatal("zip_load(): Error seeking to the beginning of the file\n"); - strncpy(dev->drv->image_path, fn, strlen(dev->drv->image_path) + 1); + strncpy(dev->drv->image_path, fn, sizeof(dev->drv->image_path) - 1); return 1; } From e5fe2dd1fa017c99a68624a9fa3cca7849123717 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 24 Mar 2024 01:50:39 +0500 Subject: [PATCH 787/936] CI, workflows: Add vulkan-headers for MSYS2 --- .ci/dependencies_msys.txt | 1 + .github/workflows/cmake_windows_msys2.yml | 3 +-- .github/workflows/codeql_windows_msys2.yml | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.ci/dependencies_msys.txt b/.ci/dependencies_msys.txt index 22601b643..694fe3e28 100644 --- a/.ci/dependencies_msys.txt +++ b/.ci/dependencies_msys.txt @@ -12,3 +12,4 @@ libslirp fluidsynth qt5-static qt5-translations +vulkan-headers diff --git a/.github/workflows/cmake_windows_msys2.yml b/.github/workflows/cmake_windows_msys2.yml index c7d77307c..c4cebaee3 100644 --- a/.github/workflows/cmake_windows_msys2.yml +++ b/.github/workflows/cmake_windows_msys2.yml @@ -63,8 +63,7 @@ jobs: slug: -Qt packages: >- qt5-static:p -# qt5-base:p -# qt5-tools:p + vulkan-headers:p environment: # - msystem: MSYS # toolchain: ./cmake/flags-gcc-x86_64.cmake diff --git a/.github/workflows/codeql_windows_msys2.yml b/.github/workflows/codeql_windows_msys2.yml index dda14a182..da368cd68 100644 --- a/.github/workflows/codeql_windows_msys2.yml +++ b/.github/workflows/codeql_windows_msys2.yml @@ -68,6 +68,7 @@ jobs: packages: >- qt5-base:p qt5-tools:p + vulkan-headers:p environment: # - msystem: MSYS # toolchain: ./cmake/flags-gcc-x86_64.cmake From f267a2f12a8ca62a28025980e397afac7a1c2dcc Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 24 Mar 2024 02:20:53 +0500 Subject: [PATCH 788/936] workflows: Remove the defunct legacy Makefile workflow --- .github/workflows/c-cpp.yml | 115 ------------------------------------ 1 file changed, 115 deletions(-) delete mode 100644 .github/workflows/c-cpp.yml diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml deleted file mode 100644 index fd81701a7..000000000 --- a/.github/workflows/c-cpp.yml +++ /dev/null @@ -1,115 +0,0 @@ -name: MSYS2 Makefile (Windows, Legacy) - -on: - - push: - paths: - - src/** - - .github/workflows/c-cpp.yml - - "!**/CMakeLists.txt" - - pull_request: - paths: - - src/** - - .github/workflows/c-cpp.yml - - "!**/CMakeLists.txt" - -jobs: - msys2: - # Negative condition disables the job - if: false - name: "Win32 GUI, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}" - - runs-on: windows-2022 - - defaults: - run: - shell: msys2 {0} - - strategy: - fail-fast: true - matrix: - build: -# - name: Regular -# debug: n -# dev: n - - name: Debug - debug: y - dev: n - slug: -Debug - - name: Dev - debug: y - dev: y - slug: -Dev - dynarec: - - name: ODR - new: n - slug: -ODR - - name: NDR - new: y - slug: -NDR - environment: -# - msystem: MSYS -# clang: n -# x64: y - - msystem: MINGW32 - prefix: mingw-w64-i686 - clang: n - x64: n - - msystem: MINGW64 - prefix: mingw-w64-x86_64 - clang: n - x64: y -# - msystem: CLANG32 -# prefix: mingw-w64-clang-i686 -# clang: y -# x64: n -# - msystem: CLANG64 -# prefix: mingw-w64-clang-x86_64 -# clang: y -# x64: y - - msystem: UCRT64 - prefix: mingw-w64-ucrt-x86_64 - clang: n - x64: y - - steps: - - name: Prepare MSYS2 environment - uses: msys2/setup-msys2@v2 - with: - release: false - update: true - msystem: ${{ matrix.environment.msystem }} - install: >- - make - pacboy: >- - gcc:p - clang:p - pkg-config:p - freetype:p - SDL2:p - zlib:p - libpng:p - openal:p - rtmidi:p - libslirp:p - fluidsynth:p - - - name: Checkout repository - uses: actions/checkout@v4 - - - name: make - run: >- - make -fwin/Makefile.mingw -j - DEV_BUILD=${{ matrix.build.dev }} - DEBUG=${{ matrix.build.debug }} - NEW_DYNAREC=${{ matrix.dynarec.new }} - CLANG=${{ matrix.environment.clang }} - X64=${{ matrix.environment.x64 }} - working-directory: ./src - - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: '86Box${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-${{ matrix.environment.msystem }}-gha${{ github.run_number }}' - path: src/86Box.exe From fb53ed47b06211c16878370da86610eafe46446c Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 24 Mar 2024 16:21:25 +0100 Subject: [PATCH 789/936] cdrom_image_backend: Fix sector header generation for non-raw sectors. --- src/cdrom/cdrom_image_backend.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index 151ddfe9f..1bc0fcf2d 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -422,11 +422,11 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) buffer += 12; FRAMES_TO_MSF(sector + 150, &m, &s, &f); /* These have to be BCD. */ - buffer[12] = CDROM_BCD(m & 0xff); - buffer[13] = CDROM_BCD(s & 0xff); - buffer[14] = CDROM_BCD(f & 0xff); + buffer[0] = CDROM_BCD(m & 0xff); + buffer[1] = CDROM_BCD(s & 0xff); + buffer[2] = CDROM_BCD(f & 0xff); /* Data, should reflect the actual sector type. */ - buffer[15] = trk->mode2 ? 2 : 1; + buffer[3] = trk->mode2 ? 2 : 1; return 1; } else if (!raw && track_is_raw) return trk->file->read(trk->file, buffer, seek + offset, length); From 31dee950ab3b0b52a82c46e13e608a02f38ecad1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 25 Mar 2024 14:37:04 +0100 Subject: [PATCH 790/936] PC330: Correct the on-board graphics card to VLB, fixes #4302. --- src/machine/machine_table.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 23c05bdf8..4338f741f 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -7299,7 +7299,7 @@ const machine_t machines[] = { .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = &gd5430_onboard_pci_device, + .vid_device = &gd5430_onboard_vlb_device, .snd_device = NULL, .net_device = NULL }, @@ -7339,7 +7339,7 @@ const machine_t machines[] = { .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = &gd5430_onboard_pci_device, + .vid_device = &gd5430_onboard_vlb_device, .snd_device = NULL, .net_device = NULL }, From 0b0cb84bf7a2052407c3fb07cfb08413ffe23082 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 25 Mar 2024 19:59:26 +0100 Subject: [PATCH 791/936] FPU: Re-enabled SoftFloat on 808x and implement the missing FBLD instruction, closes #4300. --- src/cpu/808x.c | 85 +++++++++++++++++++++--------- src/cpu/x87_ops.h | 84 ++++++++++++++--------------- src/cpu/x87_ops_loadstore.h | 83 +++++++++++++++++++++++++++++ src/cpu/x87_ops_sf_load_store.h | 93 +++++++++++++++++++++++++++++++++ 4 files changed, 278 insertions(+), 67 deletions(-) diff --git a/src/cpu/808x.c b/src/cpu/808x.c index caff0fa60..5b411dd66 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -3196,31 +3196,66 @@ execx86(int cycs) if (!hasfpu) geteaw(); else - switch (opcode) { - case 0xD8: - ops_fpu_8087_d8[(rmdat >> 3) & 0x1f]((uint32_t) rmdat); - break; - case 0xD9: - ops_fpu_8087_d9[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDA: - ops_fpu_8087_da[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDB: - ops_fpu_8087_db[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDC: - ops_fpu_8087_dc[(rmdat >> 3) & 0x1f]((uint32_t) rmdat); - break; - case 0xDD: - ops_fpu_8087_dd[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDE: - ops_fpu_8087_de[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDF: - ops_fpu_8087_df[rmdat & 0xff]((uint32_t) rmdat); - break; + if (fpu_softfloat) { + switch (opcode) { + case 0xD8: + ops_sf_fpu_8087_d8[(rmdat >> 3) & 0x1f](rmdat); + break; + case 0xD9: + ops_sf_fpu_8087_d9[rmdat & 0xff](rmdat); + break; + case 0xDA: + ops_sf_fpu_8087_da[rmdat & 0xff](rmdat); + break; + case 0xDB: + ops_sf_fpu_8087_db[rmdat & 0xff](rmdat); + break; + case 0xDC: + ops_sf_fpu_8087_dc[(rmdat >> 3) & 0x1f](rmdat); + break; + case 0xDD: + ops_sf_fpu_8087_dd[rmdat & 0xff](rmdat); + break; + case 0xDE: + ops_sf_fpu_8087_de[rmdat & 0xff](rmdat); + break; + case 0xDF: + ops_sf_fpu_8087_df[rmdat & 0xff](rmdat); + break; + + default: + break; + } + } else { + switch (opcode) { + case 0xD8: + ops_fpu_8087_d8[(rmdat >> 3) & 0x1f](rmdat); + break; + case 0xD9: + ops_fpu_8087_d9[rmdat & 0xff](rmdat); + break; + case 0xDA: + ops_fpu_8087_da[rmdat & 0xff](rmdat); + break; + case 0xDB: + ops_fpu_8087_db[rmdat & 0xff](rmdat); + break; + case 0xDC: + ops_fpu_8087_dc[(rmdat >> 3) & 0x1f](rmdat); + break; + case 0xDD: + ops_fpu_8087_dd[rmdat & 0xff](rmdat); + break; + case 0xDE: + ops_fpu_8087_de[rmdat & 0xff](rmdat); + break; + case 0xDF: + ops_fpu_8087_df[rmdat & 0xff](rmdat); + break; + + default: + break; + } } cpu_state.pc = tempw; /* Do this as the x87 code advances it, which is needed on the 286+ core, but not here. */ diff --git a/src/cpu/x87_ops.h b/src/cpu/x87_ops.h index 1d9220255..aef9289e7 100644 --- a/src/cpu/x87_ops.h +++ b/src/cpu/x87_ops.h @@ -797,7 +797,7 @@ const OpFn OP_TABLE(sf_fpu_8087_df)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -806,7 +806,7 @@ const OpFn OP_TABLE(sf_fpu_8087_df)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -815,7 +815,7 @@ const OpFn OP_TABLE(sf_fpu_8087_df)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -1055,7 +1055,7 @@ const OpFn OP_TABLE(fpu_8087_df)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -1064,7 +1064,7 @@ const OpFn OP_TABLE(fpu_8087_df)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -1073,7 +1073,7 @@ const OpFn OP_TABLE(fpu_8087_df)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -2114,7 +2114,7 @@ const OpFn OP_TABLE(sf_fpu_287_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -2123,7 +2123,7 @@ const OpFn OP_TABLE(sf_fpu_287_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -2132,7 +2132,7 @@ const OpFn OP_TABLE(sf_fpu_287_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -2154,7 +2154,7 @@ const OpFn OP_TABLE(sf_fpu_287_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, @@ -2163,7 +2163,7 @@ const OpFn OP_TABLE(sf_fpu_287_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, @@ -2172,7 +2172,7 @@ const OpFn OP_TABLE(sf_fpu_287_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, @@ -2194,7 +2194,7 @@ const OpFn OP_TABLE(sf_fpu_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -2203,7 +2203,7 @@ const OpFn OP_TABLE(sf_fpu_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -2212,7 +2212,7 @@ const OpFn OP_TABLE(sf_fpu_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -2234,7 +2234,7 @@ const OpFn OP_TABLE(sf_fpu_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, @@ -2243,7 +2243,7 @@ const OpFn OP_TABLE(sf_fpu_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, @@ -2252,7 +2252,7 @@ const OpFn OP_TABLE(sf_fpu_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, @@ -2275,7 +2275,7 @@ const OpFn OP_TABLE(sf_fpu_686_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -2284,7 +2284,7 @@ const OpFn OP_TABLE(sf_fpu_686_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -2293,7 +2293,7 @@ const OpFn OP_TABLE(sf_fpu_686_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, @@ -2315,7 +2315,7 @@ const OpFn OP_TABLE(sf_fpu_686_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, @@ -2324,7 +2324,7 @@ const OpFn OP_TABLE(sf_fpu_686_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, @@ -2333,7 +2333,7 @@ const OpFn OP_TABLE(sf_fpu_686_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, @@ -3373,7 +3373,7 @@ const OpFn OP_TABLE(fpu_287_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -3382,7 +3382,7 @@ const OpFn OP_TABLE(fpu_287_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -3391,7 +3391,7 @@ const OpFn OP_TABLE(fpu_287_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -3413,7 +3413,7 @@ const OpFn OP_TABLE(fpu_287_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, @@ -3422,7 +3422,7 @@ const OpFn OP_TABLE(fpu_287_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, @@ -3431,7 +3431,7 @@ const OpFn OP_TABLE(fpu_287_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, @@ -3453,7 +3453,7 @@ const OpFn OP_TABLE(fpu_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -3462,7 +3462,7 @@ const OpFn OP_TABLE(fpu_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -3471,7 +3471,7 @@ const OpFn OP_TABLE(fpu_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -3493,7 +3493,7 @@ const OpFn OP_TABLE(fpu_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, @@ -3502,7 +3502,7 @@ const OpFn OP_TABLE(fpu_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, @@ -3511,7 +3511,7 @@ const OpFn OP_TABLE(fpu_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, @@ -3534,7 +3534,7 @@ const OpFn OP_TABLE(fpu_686_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -3543,7 +3543,7 @@ const OpFn OP_TABLE(fpu_686_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -3552,7 +3552,7 @@ const OpFn OP_TABLE(fpu_686_df_a16)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -3574,7 +3574,7 @@ const OpFn OP_TABLE(fpu_686_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, @@ -3583,7 +3583,7 @@ const OpFn OP_TABLE(fpu_686_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, @@ -3592,7 +3592,7 @@ const OpFn OP_TABLE(fpu_686_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, diff --git a/src/cpu/x87_ops_loadstore.h b/src/cpu/x87_ops_loadstore.h index d77c0ca2b..0936f325b 100644 --- a/src/cpu/x87_ops_loadstore.h +++ b/src/cpu/x87_ops_loadstore.h @@ -144,6 +144,89 @@ opFILDiq_a32(uint32_t fetchdat) } #endif +static int +FBLD_a16(uint32_t fetchdat) +{ + uint16_t load_reg_hi = 0xffff; + uint64_t load_reg_lo = BX_CONST64(0xC000000000000000); + int64_t load_val = 0ULL; + uint64_t power; + int sign; + + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + load_reg_lo = readmemq(easeg, cpu_state.eaaddr); + load_reg_hi = readmemw(easeg, cpu_state.eaaddr + 8); + if (cpu_state.abrt) + return 1; + clear_C1(); + sign = (load_reg_hi & 0x8000) != 0; + load_val = 0ULL; + power = 1; + for (int i = 0; i < 16; i++) { + load_val += ((uint64_t) (load_reg_lo & 0xf)) * power; + load_reg_lo >>= 4; + power *= 10; + } + for (int i = 0; i < 2; i++) { + load_val += ((uint64_t) (load_reg_hi & 0xf)) * power; + load_reg_hi >>= 4; + power *= 10; + } + if (sign) + load_val = -load_val; + x87_push((double) load_val); + cpu_state.MM[cpu_state.TOP & 7].q = load_val; + FP_TAG_DEFAULT; + + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi)); + return 0; +} +#ifndef FPU_8087 +static int +FBLD_a32(uint32_t fetchdat) +{ + uint16_t load_reg_hi = 0xffff; + uint64_t load_reg_lo = BX_CONST64(0xC000000000000000); + int64_t load_val = 0ULL; + uint64_t power; + int sign; + + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + load_reg_lo = readmemq(easeg, cpu_state.eaaddr); + load_reg_hi = readmemw(easeg, cpu_state.eaaddr + 8); + if (cpu_state.abrt) + return 1; + clear_C1(); + sign = (load_reg_hi & 0x8000) != 0; + load_val = 0ULL; + power = 1; + for (int i = 0; i < 16; i++) { + load_val += ((uint64_t) (load_reg_lo & 0xf)) * power; + load_reg_lo >>= 4; + power *= 10; + } + for (int i = 0; i < 2; i++) { + load_val += ((uint64_t) (load_reg_hi & 0xf)) * power; + load_reg_hi >>= 4; + power *= 10; + } + if (sign) + load_val = -load_val; + x87_push((double) load_val); + cpu_state.MM[cpu_state.TOP & 7].q = load_val; + FP_TAG_DEFAULT; + + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi)); + return 0; +} +#endif + static int FBSTP_a16(uint32_t fetchdat) { diff --git a/src/cpu/x87_ops_sf_load_store.h b/src/cpu/x87_ops_sf_load_store.h index 383a7ee52..228d9fc06 100644 --- a/src/cpu/x87_ops_sf_load_store.h +++ b/src/cpu/x87_ops_sf_load_store.h @@ -183,6 +183,99 @@ sf_FILDiq_a32(uint32_t fetchdat) } #endif +static int +sf_FBLD_PACKED_BCD_a16(uint32_t fetchdat) +{ + floatx80 result; + uint16_t load_reg_hi = 0xffff; + uint64_t load_reg_lo = BX_CONST64(0xC000000000000000); + int64_t load_val = 0ULL; + uint64_t power; + int sign; + + FP_ENTER(); + FPU_check_pending_exceptions(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + load_reg_lo = readmemq(easeg, cpu_state.eaaddr); + load_reg_hi = readmemw(easeg, cpu_state.eaaddr + 8); + if (cpu_state.abrt) + return 1; + clear_C1(); + if (!IS_TAG_EMPTY(-1)) { + FPU_stack_overflow(fetchdat); + } else { + sign = (load_reg_hi & 0x8000) != 0; + load_val = 0ULL; + power = 1; + for (int i = 0; i < 16; i++) { + load_val += ((uint64_t) (load_reg_lo & 0xf)) * power; + load_reg_lo >>= 4; + power *= 10; + } + for (int i = 0; i < 2; i++) { + load_val += ((uint64_t) (load_reg_hi & 0xf)) * power; + load_reg_hi >>= 4; + power *= 10; + } + if (sign) + load_val = -load_val; + result = int64_to_floatx80(load_val); + FPU_push(); + FPU_save_regi(result, 0); + } + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi)); + return 0; +} +#ifndef FPU_8087 +static int +sf_FBLD_PACKED_BCD_a32(uint32_t fetchdat) +{ + floatx80 result; + uint16_t load_reg_hi = 0xffff; + uint64_t load_reg_lo = BX_CONST64(0xC000000000000000); + int64_t load_val = 0ULL; + uint64_t power; + int sign; + + FP_ENTER(); + FPU_check_pending_exceptions(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + load_reg_lo = readmemq(easeg, cpu_state.eaaddr); + load_reg_hi = readmemw(easeg, cpu_state.eaaddr + 8); + if (cpu_state.abrt) + return 1; + clear_C1(); + if (!IS_TAG_EMPTY(-1)) { + FPU_stack_overflow(fetchdat); + } else { + sign = (load_reg_hi & 0x8000) != 0; + load_val = 0ULL; + power = 1; + for (int i = 0; i < 16; i++) { + load_val += ((uint64_t) (load_reg_lo & 0xf)) * power; + load_reg_lo >>= 4; + power *= 10; + } + for (int i = 0; i < 2; i++) { + load_val += ((uint64_t) (load_reg_hi & 0xf)) * power; + load_reg_hi >>= 4; + power *= 10; + } + if (sign) + load_val = -load_val; + result = int64_to_floatx80(load_val); + FPU_push(); + FPU_save_regi(result, 0); + } + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi)); + return 0; +} +#endif + static int sf_FLDs_a16(uint32_t fetchdat) { From 12e4d1b0831d292b320ec4fc2b0b1ed9b77872e0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 26 Mar 2024 23:29:06 +0100 Subject: [PATCH 792/936] SoftFloat: Correctly treat +INF and -INF as equal on 8087 and 287, fixes 287 detection in MCPDiag. --- src/cpu/softfloat/softfloatx80.cc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/cpu/softfloat/softfloatx80.cc b/src/cpu/softfloat/softfloatx80.cc index 3ac3e61b3..b4ce88b3f 100644 --- a/src/cpu/softfloat/softfloatx80.cc +++ b/src/cpu/softfloat/softfloatx80.cc @@ -23,6 +23,11 @@ these four paragraphs for those parts of this code that are retained. * Stanislav Shwartsman [sshwarts at sourceforge net] * ==========================================================================*/ +#include +#include +#include <86box/86box.h> +#include "../cpu.h" + #include "softfloatx80.h" #include "softfloat-round-pack.h" #include "softfloat-macros.h" @@ -305,6 +310,18 @@ int floatx80_compare(floatx80 a, floatx80 b, int quiet, struct float_status_t *s float_class_t aClass = floatx80_class(a); float_class_t bClass = floatx80_class(b); + if (fpu_type < FPU_287XL) { + if ((aClass == float_positive_inf) || (bClass == float_negative_inf)) + { + return float_relation_equal; + } + + if ((aClass == float_negative_inf) || (bClass == float_positive_inf)) + { + return float_relation_equal; + } + } + if (aClass == float_SNaN || bClass == float_SNaN) { /* unsupported reported as SNaN */ From 8e21ba4699a2e8762c191e31cfc789487bde1e2c Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Mar 2024 13:59:37 +0100 Subject: [PATCH 793/936] SoftFloat: Fix 8087/287 comparison of infinites. --- src/cpu/softfloat/softfloatx80.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/softfloat/softfloatx80.cc b/src/cpu/softfloat/softfloatx80.cc index b4ce88b3f..fc2409601 100644 --- a/src/cpu/softfloat/softfloatx80.cc +++ b/src/cpu/softfloat/softfloatx80.cc @@ -311,12 +311,12 @@ int floatx80_compare(floatx80 a, floatx80 b, int quiet, struct float_status_t *s float_class_t bClass = floatx80_class(b); if (fpu_type < FPU_287XL) { - if ((aClass == float_positive_inf) || (bClass == float_negative_inf)) + if ((aClass == float_positive_inf) && (bClass == float_negative_inf)) { return float_relation_equal; } - if ((aClass == float_negative_inf) || (bClass == float_positive_inf)) + if ((aClass == float_negative_inf) && (bClass == float_positive_inf)) { return float_relation_equal; } From 7a4a44d1d1368721f3a18a5aabbab926b19e406d Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Mar 2024 17:24:06 +0100 Subject: [PATCH 794/936] Matrox: Apply DirectDraw transparency fixes by Cacodemon345. --- src/video/vid_mga.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 074303553..0de369b53 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5368,6 +5368,19 @@ blit_bitblt(mystique_t *mystique) int16_t x_start = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxright : mystique->dwgreg.fxleft; int16_t x_end = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxleft : mystique->dwgreg.fxright; const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; + uint32_t bltckey = mystique->dwgreg.fcol; + uint32_t bltcmsk = mystique->dwgreg.bcol; + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + bltckey &= 0xff; + bltcmsk &= 0xff; + break; + case MACCESS_PWIDTH_16: + bltckey &= 0xffff; + bltcmsk &= 0xffff; + break; + } switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { case DWGCTRL_ATYPE_BLK: @@ -5670,6 +5683,8 @@ blit_bitblt(mystique_t *mystique) case MACCESS_PWIDTH_8: src = svga->vram[src_addr & mystique->vram_mask]; dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; + if (!((!(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) || (src & bltcmsk) != bltckey))) + break; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); @@ -5680,6 +5695,8 @@ blit_bitblt(mystique_t *mystique) case MACCESS_PWIDTH_16: src = ((uint16_t *) svga->vram)[src_addr & mystique->vram_mask_w]; dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; + if (!((!(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) || (src & bltcmsk) != bltckey))) + break; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); @@ -5690,6 +5707,8 @@ blit_bitblt(mystique_t *mystique) case MACCESS_PWIDTH_24: src = *(uint32_t *) &svga->vram[(src_addr * 3) & mystique->vram_mask]; old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + if (!((!(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) || (src & bltcmsk) != bltckey))) + break; dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); @@ -5700,6 +5719,8 @@ blit_bitblt(mystique_t *mystique) case MACCESS_PWIDTH_32: src = ((uint32_t *) svga->vram)[src_addr & mystique->vram_mask_l]; dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; + if (!((!(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) || (src & bltcmsk) != bltckey))) + break; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); From 5445ef639f0d798acf8b810264af53f6589760b4 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:21:26 -0400 Subject: [PATCH 795/936] GHA: Disable UCRT64 in msys2 workflow --- .github/workflows/cmake_windows_msys2.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cmake_windows_msys2.yml b/.github/workflows/cmake_windows_msys2.yml index c4cebaee3..0ed29f0b7 100644 --- a/.github/workflows/cmake_windows_msys2.yml +++ b/.github/workflows/cmake_windows_msys2.yml @@ -79,9 +79,9 @@ jobs: # - msystem: CLANG64 # prefix: mingw-w64-clang-x86_64 # toolchain: ./cmake/llvm-win32-x86_64.cmake - - msystem: UCRT64 - prefix: mingw-w64-ucrt-x86_64 - toolchain: ./cmake/flags-gcc-x86_64.cmake +# - msystem: UCRT64 +# prefix: mingw-w64-ucrt-x86_64 +# toolchain: ./cmake/flags-gcc-x86_64.cmake steps: - name: Prepare MSYS2 environment From bf09f6c9fc82b3b5c51706b4a7a017bddffe30e8 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Wed, 27 Mar 2024 14:16:21 -0400 Subject: [PATCH 796/936] Fix gcc warning with use of strncpy --- src/disk/zip.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/disk/zip.c b/src/disk/zip.c index 7045b1e41..08d3baee3 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -532,6 +532,11 @@ zip_load(zip_t *dev, char *fn) fatal("zip_load(): Error seeking to the beginning of the file\n"); strncpy(dev->drv->image_path, fn, sizeof(dev->drv->image_path) - 1); + // After using strncpy, dev->drv->image_path needs to be explicitly null terminated to make gcc happy. + // In the event strlen(dev->drv->image_path) == sizeof(dev->drv->image_path) (no null terminator) + // it is placed at the very end. Otherwise, it is placed right after the string. + const size_t term = strlen(dev->drv->image_path) == sizeof(dev->drv->image_path) ? sizeof(dev->drv->image_path) - 1 : strlen(dev->drv->image_path); + dev->drv->image_path[term] = '\0'; return 1; } From f48b71020677ecd2c3442780b6139b0961daae51 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Mar 2024 19:55:34 +0100 Subject: [PATCH 797/936] Some changes in preparation for the not yet committable PAS16 changes. --- src/include/86box/filters.h | 27 ++++++++++++++++++ src/include/86box/pit.h | 9 +++++- src/include/86box/pit_fast.h | 12 ++++++++ src/include/86box/sound.h | 1 + src/pit.c | 53 ++++++++++++++++++++++++++---------- src/pit_fast.c | 14 +++++++--- 6 files changed, 97 insertions(+), 19 deletions(-) diff --git a/src/include/86box/filters.h b/src/include/86box/filters.h index 16c9c7221..0aa1c17f1 100644 --- a/src/include/86box/filters.h +++ b/src/include/86box/filters.h @@ -422,4 +422,31 @@ low_fir_sb16(int c, int i, double NewSample) return out; } +extern double low_fir_pas16_coef[4][SB16_NCoef]; + +static inline double +low_fir_pas16(int c, int i, double NewSample) +{ + static double x[4][2][SB16_NCoef + 1]; // input samples + static int pos[4] = { 0, 0, 0, 0 }; + double out = 0.0; + int n; + + /* Calculate the new output */ + x[c][i][pos[c]] = NewSample; + + for (n = 0; n < ((SB16_NCoef + 1) - pos[c]) && n < SB16_NCoef; n++) + out += low_fir_pas16_coef[c][n] * x[c][i][n + pos[c]]; + for (; n < SB16_NCoef; n++) + out += low_fir_pas16_coef[c][n] * x[c][i][(n + pos[c]) - (SB16_NCoef + 1)]; + + if (i == 1) { + pos[c]++; + if (pos[c] > SB16_NCoef) + pos[c] = 0; + } + + return out; +} + #endif /*EMU_FILTERS_H*/ diff --git a/src/include/86box/pit.h b/src/include/86box/pit.h index ed60cfa29..4129a1093 100644 --- a/src/include/86box/pit.h +++ b/src/include/86box/pit.h @@ -113,6 +113,7 @@ extern double AGPCLK; extern uint64_t PITCONST; extern uint64_t PAS16CONST; +extern uint64_t PAS16CONST2; extern uint64_t ISACONST; extern uint64_t CGACONST; extern uint64_t MDACONST; @@ -123,13 +124,19 @@ extern uint64_t RTCCONST; extern int refresh_at_enable; -extern void pit_change_pas16_const(double prescale); +extern void pit_device_reset(pit_t *dev); + +extern void pit_change_pas16_consts(double prescale); extern void pit_set_pit_const(void *data, uint64_t pit_const); +extern void ctr_clock(void *data, int counter_id); + /* Sets a counter's CLOCK input. */ extern void pit_ctr_set_clock(ctr_t *ctr, int clock, void *priv); +extern void pit_ctr_set_gate(void *data, int counter_id, int gate); + extern void pit_ctr_set_out_func(void *data, int counter_id, void (*func)(int new_out, int old_out, void *priv)); extern void pit_ctr_set_using_timer(void *data, int counter_id, int using_timer); diff --git a/src/include/86box/pit_fast.h b/src/include/86box/pit_fast.h index 2a8181a94..5650ffb4d 100644 --- a/src/include/86box/pit_fast.h +++ b/src/include/86box/pit_fast.h @@ -71,10 +71,22 @@ typedef struct pitf_t { ctrf_t counters[3]; uint8_t ctrl; + + void *dev_priv; } pitf_t; extern void pitf_set_pit_const(void *data, uint64_t pit_const); +extern void pitf_handler(int set, uint16_t base, int size, void *priv); + +extern void pitf_ctr_set_out_func(void *data, int counter_id, void (*func)(int new_out, int old_out, void *priv)); + +extern void pitf_ctr_set_using_timer(void *data, int counter_id, int using_timer); + +extern void pitf_ctr_set_gate(void *data, int counter_id, int gate); + +extern void pitf_ctr_clock(void *data, int counter_id); + extern uint8_t pitf_read_reg(void *priv, uint8_t reg); extern const pit_intf_t pit_fast_intf; diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index 005b56d13..5f04c10fe 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -124,6 +124,7 @@ extern const device_t cms_device; extern const device_t gus_device; /* Pro Audio Spectrum 16 */ +extern const device_t pasplus_device; extern const device_t pas16_device; /* IBM PS/1 Audio Card */ diff --git a/src/pit.c b/src/pit.c index b5d402bb3..340cdccde 100644 --- a/src/pit.c +++ b/src/pit.c @@ -48,6 +48,7 @@ pit_intf_t pit_devs[2]; double cpuclock; double PITCONSTD; double PAS16CONSTD; +double PAS16CONST2D; double SYSCLK; double isa_timing; double bus_timing; @@ -58,6 +59,7 @@ double AGPCLK; uint64_t PITCONST; uint64_t PAS16CONST; +uint64_t PAS16CONST2; uint64_t ISACONST; uint64_t CGACONST; uint64_t MDACONST; @@ -309,7 +311,7 @@ ctr_tick(ctr_t *ctr, void *priv) } } -static void +void ctr_clock(void *data, int counter_id) { pit_t *pit = (pit_t *) data; @@ -535,8 +537,9 @@ pit_write(uint16_t addr, uint8_t val, void *priv) int t = (addr & 3); ctr_t *ctr; - if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { pit_log("[%04X:%08X] pit_write(%04X, %02X, %08X)\n", CS, cpu_state.pc, addr, val, priv); + } switch (addr & 3) { case 3: /* control */ @@ -552,8 +555,9 @@ pit_write(uint16_t addr, uint8_t val, void *priv) ctr_latch_count(&dev->counters[1]); if (val & 8) ctr_latch_count(&dev->counters[2]); - if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { pit_log("PIT %i: Initiated readback command\n", t); + } } if (!(val & 0x10)) { if (val & 2) @@ -570,9 +574,10 @@ pit_write(uint16_t addr, uint8_t val, void *priv) if (!(dev->ctrl & 0x30)) { ctr_latch_count(ctr); - if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { pit_log("PIT %i: Initiated latched read, %i bytes latched\n", t, ctr->latched); + } } else { ctr->ctrl = val; ctr->rm = ctr->wm = (ctr->ctrl >> 4) & 3; @@ -584,13 +589,15 @@ pit_write(uint16_t addr, uint8_t val, void *priv) ctr_set_out(ctr, !!ctr->m, dev); ctr->state = 0; if (ctr->latched) { - if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { pit_log("PIT %i: Reload while counter is latched\n", t); + } ctr->rl--; } - if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { pit_log("PIT %i: M = %i, RM/WM = %i, State = %i, Out = %i\n", t, ctr->m, ctr->rm, ctr->state, ctr->out); + } } } break; @@ -608,8 +615,9 @@ pit_write(uint16_t addr, uint8_t val, void *priv) ctr->l = val; ctr->lback = ctr->l; ctr->lback2 = ctr->l; - if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { pit_log("PIT %i (1): Written byte %02X, latch now %04X\n", t, val, ctr->l); + } if (ctr->m == 0) ctr_set_out(ctr, 0, dev); ctr_load(ctr); @@ -618,8 +626,9 @@ pit_write(uint16_t addr, uint8_t val, void *priv) ctr->l = (val << 8); ctr->lback = ctr->l; ctr->lback2 = ctr->l; - if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { pit_log("PIT %i (2): Written byte %02X, latch now %04X\n", t, val, ctr->l); + } if (ctr->m == 0) ctr_set_out(ctr, 0, dev); ctr_load(ctr); @@ -630,15 +639,17 @@ pit_write(uint16_t addr, uint8_t val, void *priv) ctr->l = (ctr->l & 0x00ff) | (val << 8); ctr->lback = ctr->l; ctr->lback2 = ctr->l; - if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { pit_log("PIT %i (0x83): Written high byte %02X, latch now %04X\n", t, val, ctr->l); + } ctr_load(ctr); } else { ctr->l = (ctr->l & 0xff00) | val; ctr->lback = ctr->l; ctr->lback2 = ctr->l; - if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { pit_log("PIT %i (3): Written low byte %02X, latch now %04X\n", t, val, ctr->l); + } if (ctr->m == 0) { ctr->state = 0; ctr_set_out(ctr, 0, dev); @@ -774,8 +785,9 @@ pit_read(uint16_t addr, void *priv) break; } - if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) + if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { pit_log("[%04X:%08X] pit_read(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret); + } return ret; } @@ -855,6 +867,15 @@ ctr_reset(ctr_t *ctr) ctr->l_det = 0; } +void +pit_device_reset(pit_t *dev) +{ + dev->clock = 0; + + for (uint8_t i = 0; i < 3; i++) + ctr_reset(&dev->counters[i]); +} + void pit_reset(pit_t *dev) { @@ -1094,9 +1115,10 @@ pit_ps2_init(int type) } void -pit_change_pas16_const(double prescale) +pit_change_pas16_consts(double prescale) { - PAS16CONST = (uint64_t) ((PITCONSTD / prescale) * (double) (1ULL << 32)); + PAS16CONST = (uint64_t) ((PAS16CONSTD / prescale) * (double) (1ULL << 32)); + PAS16CONST2 = (uint64_t) ((PAS16CONST2D / prescale) * (double) (1ULL << 32)); } void @@ -1195,7 +1217,10 @@ pit_set_clock(uint32_t clock) TIMER_USEC = (uint64_t) ((cpuclock / 1000000.0) * (double) (1ULL << 32)); PAS16CONSTD = (cpuclock / 441000.0); - PAS16CONST = (uint64_t) (PITCONSTD * (double) (1ULL << 32)); + PAS16CONST = (uint64_t) (PAS16CONSTD * (double) (1ULL << 32)); + + PAS16CONST2D = (cpuclock / 1008000.0); + PAS16CONST2 = (uint64_t) (PAS16CONST2D * (double) (1ULL << 32)); isa_timing = (cpuclock / (double) cpu_isa_speed); if (cpu_64bitbus) diff --git a/src/pit_fast.c b/src/pit_fast.c index acaa6c271..0da671bfe 100644 --- a/src/pit_fast.c +++ b/src/pit_fast.c @@ -99,7 +99,7 @@ pitf_ctr_get_count(void *data, int counter_id) return (uint16_t) ctr->l; } -static void +void pitf_ctr_set_out_func(void *data, int counter_id, void (*func)(int new_out, int old_out, void *priv)) { if (data == NULL) @@ -111,7 +111,7 @@ pitf_ctr_set_out_func(void *data, int counter_id, void (*func)(int new_out, int ctr->out_func = func; } -static void +void pitf_ctr_set_using_timer(void *data, int counter_id, int using_timer) { if (tsc > 0) @@ -284,7 +284,7 @@ pitf_set_gate_no_timer(ctrf_t *ctr, int gate, void *priv) pitf_dump_and_disable_timer(ctr); } -static void +void pitf_ctr_set_gate(void *data, int counter_id, int gate) { pitf_t *pit = (pitf_t *) data; @@ -619,7 +619,7 @@ pitf_timer_over(void *priv) pitf_over(ctr, pit); } -static void +void pitf_ctr_clock(void *data, int counter_id) { pitf_t *pit = (pitf_t *) data; @@ -692,6 +692,12 @@ pitf_close(void *priv) free(dev); } +void +pitf_handler(int set, uint16_t base, int size, void *priv) +{ + io_handler(set, base, size, pitf_read, NULL, NULL, pitf_write, NULL, NULL, priv); +} + static void * pitf_init(const device_t *info) { From 8b3866b9933f0ccbbb1c1dfd0cb2e3662638f171 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Mar 2024 22:19:06 +0100 Subject: [PATCH 798/936] SiS 5595 PMU: Remove a pointless tautology. --- src/chipset/sis_5595_pmu.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/chipset/sis_5595_pmu.c b/src/chipset/sis_5595_pmu.c index 4c6dbf7c9..de351ad7c 100644 --- a/src/chipset/sis_5595_pmu.c +++ b/src/chipset/sis_5595_pmu.c @@ -140,7 +140,6 @@ sis_5595_pmu_trap_update_devctl(sis_5595_pmu_t *dev, uint8_t trap_id, uint8_t en uint16_t addr, uint16_t size) { sis_5595_pmu_io_trap_t *trap = &dev->io_traps[trap_id]; - enable = enable; /* Set up Device I/O traps dynamically. */ if (enable && !trap->trap) { From 7f4e8caefacf6c4f52f3164855ea068d1a024f74 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Mar 2024 22:23:33 +0100 Subject: [PATCH 799/936] IT86x1: Use PRIXPTR instead of the #ifdef's. --- src/sio/sio_it86x1f.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/sio/sio_it86x1f.c b/src/sio/sio_it86x1f.c index ece59501f..00524863a 100644 --- a/src/sio/sio_it86x1f.c +++ b/src/sio/sio_it86x1f.c @@ -808,18 +808,10 @@ it86x1f_init(UNUSED(const device_t *info)) break; } if (i >= (sizeof(it86x1f_models) / sizeof(it86x1f_models[0]))) { -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) - fatal("IT86x1F: Unknown type %04" PRIX64 " selected\n", info->local); -#else - fatal("IT86x1F: Unknown type %04X selected\n", info->local); -#endif + fatal("IT86x1F: Unknown type %04" PRIXPTR " selected\n", info->local); return NULL; } -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) - it86x1f_log("IT86x1F: init(%04" PRIX64 ")\n", info->local); -#else - it86x1f_log("IT86x1F: init(%04X)\n", info->local); -#endif + it86x1f_log("IT86x1F: init(%04" PRIXPTR ")\n", info->local); /* Let the resource data parser figure out the ROM size. */ dev->pnp_card = isapnp_add_card(it86x1f_models[i].pnp_rom, -1, it86x1f_models[i].pnp_config_changed, NULL, it86x1f_pnp_read_vendor_reg, it86x1f_pnp_write_vendor_reg, dev); From d290de418d14e50d311cac809cd66a46c09159a7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Mar 2024 23:56:55 +0100 Subject: [PATCH 800/936] Significantly reworked the Pro Audio Spectrum 16 and implemented a lot of missing stuff, and added the Pro Audio Spectrum Plus. --- src/dma.c | 23 + src/include/86box/dma.h | 2 + src/sound/snd_pas16.c | 1075 ++++++++++++++++++++++++++------------- src/sound/sound.c | 1 + 4 files changed, 737 insertions(+), 364 deletions(-) diff --git a/src/dma.c b/src/dma.c index 50ae598b8..b7c4b4863 100644 --- a/src/dma.c +++ b/src/dma.c @@ -1397,6 +1397,29 @@ dma_advance(dma_t *dma_c) dma_c->ac = ((dma_c->ac & 0xffff0000) & dma_mask) | ((dma_c->ac + as) & 0xffff); } +int +dma_channel_readable(int channel) +{ + dma_t *dma_c = &dma[channel]; + + if (channel < 4) { + if (dma_command[0] & 0x04) + return 0; + } else { + if (dma_command[1] & 0x04) + return 0; + } + + if (!(dma_e & (1 << channel))) + return 0; + if ((dma_m & (1 << channel)) && !dma_req_is_soft) + return 0; + if ((dma_c->mode & 0xC) != 8) + return 0; + + return 1; +} + int dma_channel_read(int channel) { diff --git a/src/include/86box/dma.h b/src/include/86box/dma.h index 7ead53ba0..ff0dc0b5d 100644 --- a/src/include/86box/dma.h +++ b/src/include/86box/dma.h @@ -118,4 +118,6 @@ void dma_high_page_init(void); void dma_remove_sg(void); void dma_set_sg_base(uint8_t sg_base); +extern int dma_channel_readable(int channel); + #endif /*EMU_DMA_H*/ diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 45a18ff73..0a5c046b7 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -1,3 +1,92 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Pro Audio Spectrum Plus and 16 emulation. + * + * Original PAS uses: + * - 2 x OPL2; + * - PIT - sample rate/count; + * - LMC835N/LMC1982 - mixer; + * - YM3802 - MIDI Control System. + * + * 9A01 - I/O base: + * - base >> 2. + * + * All below + I/O base. + * + * B89 - Interrupt status / clear: + * - Bit 2 - sample rate; + * - Bit 3 - PCM; + * - Bit 4 - MIDI. + * + * B88 - Audio mixer control register. + * + * B8A - Audio filter control: + * - Bit 5 - mute?. + * + * B8B - Interrupt mask / board ID: + * - Bits 5-7 - board ID (read only on PAS16). + * + * F88 - PCM data (low). + * + * F89 - PCM data (high). + * + * F8A - PCM control?: + * - Bit 4 - input/output select (1 = output); + * - Bit 5 - mono/stereo select; + * - Bit 6 - PCM enable. + * + * 1388-138B - PIT clocked at 1193180 Hz: + * - 1388 - Sample rate; + * - 1389 - Sample count. + * + * 178B - ????. + * 2789 - Board revision. + * + * 8389: + * - Bit 2 - 8/16 bit. + * + * BF88 - Wait states. + * + * EF8B: + * - Bit 3 - 16 bits okay ?. + * + * F388: + * - Bit 6 - joystick enable. + * + * F389: + * - Bits 0-2 - DMA. + * + * F38A: + * - Bits 0-3 - IRQ. + * + * F788: + * - Bit 1 - SB emulation; + * - Bit 0 - MPU401 emulation. + * + * F789 - SB base address: + * - Bits 0-3 - Address bits 4-7. + * + * FB8A - SB IRQ/DMA: + * - Bits 3-5 - IRQ; + * - Bits 6-7 - DMA. + * + * FF88 - board model: + * - 3 = PAS16. + * + * Authors: Sarah Walker, + * Miran Grca, + * TheCollector1995, + * + * Copyright 2008-2024 Sarah Walker. + * Copyright 2024 Miran Grca. + */ +#include #include #include #include @@ -16,6 +105,7 @@ #include <86box/pic.h> #include <86box/timer.h> #include <86box/pit.h> +#include <86box/pit_fast.h> #include <86box/snd_mpu401.h> #include <86box/sound.h> #include <86box/snd_opl.h> @@ -23,140 +113,69 @@ #include <86box/snd_sb_dsp.h> #include <86box/plat_unused.h> -/* Original PAS uses - 2 x OPL2 - PIT - sample rate/count - LMC835N/LMC1982 - mixer - YM3802 - MIDI Control System - - - 9A01 - IO base - base >> 2 - - All below + IO base - - B89 - interrupt status / clear - bit 2 - sample rate - bit 3 - PCM - bit 4 - MIDI - - B88 - Audio mixer control register - - B8A - Audio filter control - bit 5 - mute? - - B8B - interrupt mask / board ID - bits 5-7 - board ID (read only on PAS16) - - F88 - PCM data (low) - - F89 - PCM data (high) - - F8A - PCM control? - bit 4 - input/output select (1 = output) - bit 5 - mono/stereo select - bit 6 - PCM enable - - 1388-138b - PIT clocked at 1193180 Hz - 1388 - sample rate - 1389 - sample count - - 178b - - 2789 - board revision - - 8389 - - bit 2 - 8/16 bit - - BF88 - wait states - - EF8B - - bit 3 - 16 bits okay ? - - F388 - - bit 6 - joystick enable - - F389 - - bits 0-2 - DMA - - F38A - - bits 0-3 - IRQ - - F788 - - bit 1 - SB emulation - bit 0 - MPU401 emulation - - F789 - SB base addr - bits 0-3 - addr bits 4-7 - - FB8A - SB IRQ/DMA - bits 3-5 - IRQ - bits 6-7 - DMA - - FF88 - board model - 3 = PAS16 -*/ - typedef struct pas16_t { - uint16_t base; + uint8_t this_id; + uint8_t board_id; + uint8_t master_ff; + uint8_t irq; + uint8_t dma; + uint8_t sb_irqdma; + uint8_t type; + uint8_t filter; - int irq; - int dma; - - uint8_t audiofilt; - - uint8_t audio_mixer; - - uint8_t compat; - uint8_t compat_base; - - uint8_t enhancedscsi; - - uint8_t io_conf_1; - uint8_t io_conf_2; - uint8_t io_conf_3; - uint8_t io_conf_4; - - uint8_t irq_stat; - uint8_t irq_ena; + uint8_t audiofilt; + uint8_t audio_mixer; + uint8_t compat; + uint8_t compat_base; + uint8_t io_conf_1; + uint8_t io_conf_2; + uint8_t io_conf_3; + uint8_t io_conf_4; + uint8_t irq_stat; + uint8_t irq_ena; uint8_t pcm_ctrl; - uint16_t pcm_dat; + uint8_t prescale_div; + uint8_t stereo_lr; + uint8_t dma8_ff; + uint8_t waitstates; + uint8_t enhancedscsi; + uint8_t sys_conf_1; + uint8_t sys_conf_2; + uint8_t sys_conf_3; + uint8_t sys_conf_4; + uint8_t midi_ctrl; + uint8_t midi_stat; + uint8_t midi_data; + uint8_t fifo_stat; + + uint8_t midi_queue[256]; + + uint16_t base; + uint16_t new_base; uint16_t pcm_dat_l; uint16_t pcm_dat_r; - uint8_t sb_irqdma; + int16_t pcm_buffer[2][SOUNDBUFLEN * 2]; - int stereo_lr; - - uint8_t sys_conf_1; - uint8_t sys_conf_2; - uint8_t sys_conf_3; - uint8_t sys_conf_4; - uint8_t waitstates; - uint8_t midi_ctrl; - uint8_t midi_stat; - uint8_t midi_data; - uint8_t fifo_stat; - int midi_r; - int midi_w; - int midi_uart_out; - int midi_uart_in; - uint8_t midi_queue[256]; - int sysex; + int pos; + int midi_r; + int midi_w; + int midi_uart_out; + int midi_uart_in; + int sysex; fm_drv_t opl; sb_dsp_t dsp; - mpu_t *mpu; - pc_timer_t timer; - int16_t pcm_buffer[2][SOUNDBUFLEN]; + mpu_t * mpu; - int pos; - - pit_t *pit; + pitf_t * pit; } pas16_t; +static uint8_t pas16_next = 0; + static void pas16_update(pas16_t *pas16); static int pas16_dmas[8] = { 4, 1, 2, 3, 0, 5, 6, 7 }; @@ -166,7 +185,7 @@ static int pas16_sb_dmas[8] = { 0, 1, 2, 3 }; enum { PAS16_INT_SAMP = 0x04, PAS16_INT_PCM = 0x08, - PAS16_INT_MIDI = 0x10, + PAS16_INT_MIDI = 0x10 }; enum { @@ -184,6 +203,47 @@ enum { PAS16_FILT_MUTE = 0x20 }; +#define PAS16_PCM_AND_DMA_ENA (PAS16_PCM_ENA | PAS16_PCM_DMA_ENA) + +double low_fir_pas16_coef[4][SB16_NCoef]; + +static __inline double +sinc(double x) +{ + return sin(M_PI * x) / (M_PI * x); +} + +static void +recalc_pas16_filter(int c, int playback_freq) +{ + /* Cutoff frequency = playback / 2 */ + int n; + double w; + double h; + double fC = ((double) playback_freq) / (double) FREQ_96000; + double gain; + + for (n = 0; n < SB16_NCoef; n++) { + /* Blackman window */ + w = 0.42 - (0.5 * cos((2.0 * n * M_PI) / (double) (SB16_NCoef - 1))) + (0.08 * cos((4.0 * n * M_PI) / (double) (SB16_NCoef - 1))); + /* Sinc filter */ + h = sinc(2.0 * fC * ((double) n - ((double) (SB16_NCoef - 1) / 2.0))); + + /* Create windowed-sinc filter */ + low_fir_pas16_coef[c][n] = w * h; + } + + low_fir_pas16_coef[c][(SB16_NCoef - 1) / 2] = 1.0; + + gain = 0.0; + for (n = 0; n < SB16_NCoef; n++) + gain += low_fir_pas16_coef[c][n]; + + /* Normalise filter, to produce unity gain */ + for (n = 0; n < SB16_NCoef; n++) + low_fir_pas16_coef[c][n] /= gain; +} + #ifdef ENABLE_PAS16_LOG int pas16_do_log = ENABLE_PAS16_LOG; @@ -226,45 +286,45 @@ static uint8_t pas16_in(uint16_t port, void *priv) { pas16_t *pas16 = (pas16_t *) priv; - uint8_t temp = 0xff; + uint8_t ret = 0xff; + + port -= pas16->base; + switch (port) { - case 0x388: - case 0x389: - case 0x38a: - case 0x38b: - temp = pas16->opl.read(port, pas16->opl.priv); + case 0x0000 ... 0x0003: + ret = pas16->opl.read(port + 0x0388, pas16->opl.priv); break; - case 0xb88: - temp = pas16->audio_mixer; + case 0x0800: + ret = pas16->audio_mixer; break; - case 0xb89: - temp = pas16->irq_stat; + case 0x0801: + ret = pas16->irq_stat & 0xdf; break; - case 0xb8a: - temp = pas16->audiofilt; + case 0x0802: + ret = pas16->audiofilt; break; - case 0xb8b: - temp = pas16->irq_ena | 0x20; - pas16_log("IRQ Mask read=%02x.\n", temp); + case 0x0803: + ret = pas16->irq_ena | (pas16->type ? 0x20 : 0x00); + pas16_log("IRQ Mask read=%02x.\n", ret); break; - case 0xf8a: - temp = pas16->pcm_ctrl; + case 0x0c02: + ret = pas16->pcm_ctrl; break; - case 0x1789: - case 0x178b: - temp = pas16->midi_ctrl; + case 0x1401: + case 0x1403: + ret = pas16->midi_ctrl; break; - case 0x178a: - case 0x1b8a: - temp = 0; + case 0x1402: + case 0x1802: + ret = 0; if (pas16->midi_uart_in) { if ((pas16->midi_data == 0xaa) && (pas16->midi_ctrl & 0x04)) - temp = pas16->midi_data; + ret = pas16->midi_data; else { - temp = pas16->midi_queue[pas16->midi_r]; + ret = pas16->midi_queue[pas16->midi_r]; if (pas16->midi_r != pas16->midi_w) { pas16->midi_r++; pas16->midi_r &= 0xff; @@ -275,206 +335,386 @@ pas16_in(uint16_t port, void *priv) } break; - case 0x1b88: - temp = pas16->midi_stat; + case 0x1800: + ret = pas16->midi_stat; break; - case 0x1b89: - temp = pas16->fifo_stat; + case 0x1801: + ret = pas16->fifo_stat; break; - case 0x2789: /*Board revision*/ - temp = 0x00; + case 0x2401: /* Board revision */ + ret = 0x00; break; - case 0x7f89: - temp = pas16->enhancedscsi & ~0x01; + case 0x7c01: + ret = pas16->enhancedscsi & ~0x01; break; - case 0x8388: - temp = pas16->sys_conf_1; + case 0x8000: + ret = pas16->sys_conf_1; break; - case 0x8389: - temp = pas16->sys_conf_2; + case 0x8001: + ret = pas16->sys_conf_2; break; - case 0x838a: - temp = pas16->sys_conf_3; + case 0x8002: + ret = pas16->sys_conf_3; break; - case 0x838b: - temp = pas16->sys_conf_4; + case 0x8003: + ret = pas16->sys_conf_4; break; - case 0xbf88: - temp = pas16->waitstates; + case 0xbc00: + ret = pas16->waitstates; break; - case 0xef8b: - temp = 0x00; + case 0xbc02: + ret = pas16->prescale_div; break; - case 0xf388: - temp = pas16->io_conf_1; + case 0xec03: + ret = pas16->type ? 0x0c : 0x04; break; - case 0xf389: - temp = pas16->io_conf_2; + + case 0xf000: + ret = pas16->io_conf_1; + break; + case 0xf001: + ret = pas16->io_conf_2; pas16_log("pas16_in : set PAS DMA %i\n", pas16->dma); break; - case 0xf38a: - temp = pas16->io_conf_3; + case 0xf002: + ret = pas16->io_conf_3; pas16_log("pas16_in : set PAS IRQ %i\n", pas16->irq); break; - case 0xf38b: - temp = pas16->io_conf_4; + case 0xf003: + ret = pas16->io_conf_4; break; - case 0xf788: - temp = pas16->compat; + case 0xf400: + ret = pas16->compat; break; - case 0xf789: - temp = pas16->compat_base; + case 0xf401: + ret = pas16->compat_base; break; - case 0xfb8a: - temp = pas16->sb_irqdma; + case 0xf802: + ret = pas16->sb_irqdma; break; - case 0xff88: /*Board model*/ - temp = 0x04; /*PAS16*/ + case 0xfc00: /* Board model */ + /* PAS16 or PASPlus */ + ret = pas16->type ? 0x04 : 0x01; break; - case 0xff8b: /*Master mode read*/ - temp = 0x20 | 0x10 | 0x01; /*AT bus, XT/AT timing*/ + case 0xfc03: /* Master mode read */ + /* AT bus, XT/AT timing */ + ret = pas16->type ? (0x20 | 0x10 | 0x01) : (0x10 | 0x01); break; default: break; } - pas16_log("pas16_in : port %04X return %02X %04X:%04X\n", port, temp, CS, cpu_state.pc); - return temp; + + pas16_log("[%04X:%08X] PAS16: [R] %04X (%04X) = %02X\n", + CS, cpu_state.pc, port + pas16->base, port, ret); + + return ret; +} + +static void +pas16_change_pit_clock_speed(void *priv) +{ + pas16_t *pas16 = (pas16_t *) priv; + pitf_t *pit = (pitf_t *) pas16->pit; + + if (pas16->type && (pas16->sys_conf_1 & 0x02) && pas16->prescale_div) { + pit_change_pas16_consts((double) pas16->prescale_div); + if (pas16->sys_conf_3 & 0x02) + pitf_set_pit_const(pit, PAS16CONST2); + else + pitf_set_pit_const(pit, PAS16CONST); + } else + pitf_set_pit_const(pit, PITCONST); +} + +static void +pas16_io_handler(pas16_t *pas16, int set) +{ + if (pas16->base != 0x0000) { + for (uint32_t addr = 0x0000; addr <= 0xffff; addr += 0x0400) { + pas16_log("%04X-%04X: %i\n", pas16->base + addr, pas16->base + addr + 3, set); + if (addr != 0x1000) + io_handler(set, pas16->base + addr, 0x0004, + pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + } + + pitf_handler(set, pas16->base + 0x1000, 0x0004, pas16->pit); + } +} + +static void +pas16_reset_pcm(void *priv) +{ + pas16_t *pas16 = (pas16_t *) priv; + + pas16->pcm_ctrl = 0x00; + + pas16->stereo_lr = 0; + pas16->dma8_ff = 0; + + pas16->irq_stat &= 0xd7; + + if (!pas16->irq_stat) + picintc(1 << pas16->irq); +} + +static void +pas16_reset_regs(void *priv) +{ + pas16_t *pas16 = (pas16_t *) priv; + pitf_t *pit = (pitf_t *) pas16->pit; + + picintc(1 << pas16->irq); + + pas16->sys_conf_1 &= 0xfd; + + pas16->sys_conf_2 = 0x00; + pas16->sys_conf_3 = 0x00; + + pas16->prescale_div = 0x00; + + pitf_set_pit_const(pit, PITCONST); + + pas16->audiofilt = 0x00; + pas16->filter = 0; + + pitf_ctr_set_gate(pit, 0, 0); + pitf_ctr_set_gate(pit, 1, 0); + + pas16_reset_pcm(pas16); + + pas16->irq_ena = 0x00; + pas16->irq_stat = 0x00; +} + +static void +pas16_reset_common(void *priv) +{ + pas16_t *pas16 = (pas16_t *) priv; + + pas16_reset_regs(pas16); + + picintc(1 << pas16->irq); + + pas16_io_handler(pas16, 0); + pas16->base = 0x0000; +} + +static void +pas16_reset(void *priv) +{ + pas16_t *pas16 = (pas16_t *) priv; + + pas16_reset_common(priv); + + pas16->board_id = 0; + pas16->master_ff = 0; + + pas16->base = 0x0388; + pas16_io_handler(pas16, 1); + + pas16->new_base = 0x0388; } static void pas16_out(uint16_t port, uint8_t val, void *priv) { pas16_t *pas16 = (pas16_t *) priv; - pas16_log("pas16_out : port %04X val %02X %04X:%04X\n", port, val, CS, cpu_state.pc); + + pas16_log("[%04X:%08X] PAS16: [W] %04X (%04X) = %02X\n", + CS, cpu_state.pc, port, port - pas16->base, val); + + port -= pas16->base; + switch (port) { - case 0x388: - case 0x389: - case 0x38a: - case 0x38b: - pas16->opl.write(port, val, pas16->opl.priv); + case 0x0000 ... 0x0003: + pas16->opl.write(port + 0x0388, val, pas16->opl.priv); break; - case 0xb88: + case 0x0800: pas16->audio_mixer = val; + if (!(val & 0x01)) + pas16_reset_pcm(pas16); break; - case 0xb89: + case 0x0801: pas16->irq_stat &= ~val; break; - case 0xb8a: + case 0x0802: + if ((val & 0x20) && !(pas16->audiofilt & 0x20)) { + pas16_log("Reset.\n"); + val = 0x20; + pas16_reset_regs(pas16); + } + pas16_update(pas16); + pitf_ctr_set_gate(pas16->pit, 0, 1); + pitf_ctr_set_gate(pas16->pit, 1, 1); + // pas16->pit->counters[0].gate = !!(val & 0x40); + // pas16->pit->counters[0].enabled = !!(val & 0x40); + // pas16->pit->counters[1].gate = !!(val & 0x80); + // pas16->pit->counters[1].enabled = !!(val & 0x80); + pas16->stereo_lr = 0; + pas16->irq_stat &= 0xdf; + pas16->dma8_ff = 0; pas16->audiofilt = val; + if (val & 0x1f) { + pas16->filter = 1; + switch (val & 0x1f) { + default: + pas16->filter = 0; + break; + case 0x01: + recalc_pas16_filter(0, 17897); + break; + case 0x02: + recalc_pas16_filter(0, 15909); + break; + case 0x04: + recalc_pas16_filter(0, 2982); + break; + case 0x09: + recalc_pas16_filter(0, 11931); + break; + case 0x11: + recalc_pas16_filter(0, 8948); + break; + case 0x19: + recalc_pas16_filter(0, 5965); + break; + } + } else + pas16->filter = 0; break; - case 0xb8b: + case 0x0803: pas16->irq_ena = val & 0x1f; break; - case 0xf88: + case 0x0c00: pas16_update(pas16); - pas16->pcm_dat = (pas16->pcm_dat & 0xff00) | val; break; - case 0xf89: + case 0x0c01: pas16_update(pas16); - pas16->pcm_dat = (pas16->pcm_dat & 0x00ff) | (val << 8); break; - case 0xf8a: - if ((val & PAS16_PCM_ENA) && !(pas16->pcm_ctrl & PAS16_PCM_ENA)) /*Guess*/ + case 0x0c02: + if ((val & PAS16_PCM_ENA) && !(pas16->pcm_ctrl & PAS16_PCM_ENA)) { + /* Guess */ pas16->stereo_lr = 0; + pas16->irq_stat &= 0xdf; + /* Needed for 8-bit DMA to work correctly on a 16-bit DMA channel. */ + pas16->dma8_ff = 0; + } pas16->pcm_ctrl = val; + pas16_log("Now in: %s (%02X)\n", (pas16->pcm_ctrl & PAS16_PCM_MONO) ? "Mono" : "Stereo", val); break; - case 0x1789: - case 0x178b: + case 0x1401: + case 0x1403: pas16->midi_ctrl = val; if ((val & 0x60) == 0x60) { pas16->midi_uart_out = 0; pas16->midi_uart_in = 0; - } else if (val & 0x18) { + } else if (val & 0x18) pas16->midi_uart_out = 1; - } else if (val & 0x04) + else if (val & 0x04) pas16->midi_uart_in = 1; else pas16->midi_uart_out = 1; pas16_update_irq(pas16); break; - case 0x178a: - case 0x1b8a: + case 0x1402: + case 0x1802: pas16->midi_data = val; pas16_log("UART OUT=%d.\n", pas16->midi_uart_out); if (pas16->midi_uart_out) midi_raw_out_byte(val); break; - case 0x1b88: + case 0x1800: pas16->midi_stat = val; pas16_update_irq(pas16); break; - case 0x1b89: + case 0x1801: pas16->fifo_stat = val; break; - case 0x7f89: + case 0x7c01: pas16->enhancedscsi = val; break; - case 0x8388: + case 0x8000: if ((val & 0xc0) && !(pas16->sys_conf_1 & 0xc0)) { pas16_log("Reset.\n"); - picintc(1 << pas16->irq); val = 0x00; + pas16_reset_common(pas16); + pas16->base = pas16->new_base; + pas16_io_handler(pas16, 1); } + pas16->sys_conf_1 = val; + pas16_change_pit_clock_speed(pas16); + pas16_log("Now in: %s mode\n", (pas16->sys_conf_1 & 0x02) ? "native" : "compatibility"); break; - case 0x8389: + case 0x8001: pas16->sys_conf_2 = val; + pas16_log("Now in: %i bits (%02X)\n", + (pas16->sys_conf_2 & 0x04) ? ((pas16->sys_conf_2 & 0x08) ? 12 : 16) : 8, val); break; - case 0x838a: + case 0x8002: pas16->sys_conf_3 = val; + pas16_change_pit_clock_speed(pas16); + pas16_log("Use 1.008 MHz clok for PCM: %c\n", (val & 0x02) ? 'Y' : 'N'); break; - case 0x838b: + case 0x8003: pas16->sys_conf_4 = val; break; - case 0xbf88: + case 0xbc00: pas16->waitstates = val; break; + case 0xbc02: + pas16->prescale_div = val; + pas16_change_pit_clock_speed(pas16); + pas16_log("Prescale divider now: %i\n", val); + break; - case 0xf388: + case 0xf000: pas16->io_conf_1 = val; break; - case 0xf389: + case 0xf001: pas16->io_conf_2 = val; pas16->dma = pas16_dmas[val & 0x7]; + pas16_change_pit_clock_speed(pas16); pas16_log("pas16_out : set PAS DMA %i\n", pas16->dma); break; - case 0xf38a: + case 0xf002: pas16->io_conf_3 = val; pas16->irq = val & 0x0f; - if (pas16->irq <= 6) { + if (pas16->irq <= 6) pas16->irq++; - } else if ((pas16->irq > 6) && (pas16->irq < 0x0b)) + else if ((pas16->irq > 6) && (pas16->irq < 0x0b)) pas16->irq += 3; else pas16->irq += 4; pas16_log("pas16_out : set PAS IRQ %i, val=%02x\n", pas16->irq, val & 0x0f); break; - case 0xf38b: + case 0xf003: pas16->io_conf_4 = val; break; - case 0xf788: + case 0xf400: pas16->compat = val; + pas16_log("PCM compression is now %sabled\n", (val & 0x10) ? "en" : "dis"); if (pas16->compat & 0x02) sb_dsp_setaddr(&pas16->dsp, ((pas16->compat_base & 0xf) << 4) | 0x200); else @@ -484,7 +724,7 @@ pas16_out(uint16_t port, uint8_t val, void *priv) else mpu401_change_addr(pas16->mpu, 0); break; - case 0xf789: + case 0xf401: pas16->compat_base = val; if (pas16->compat & 0x02) sb_dsp_setaddr(&pas16->dsp, ((pas16->compat_base & 0xf) << 4) | 0x200); @@ -492,11 +732,12 @@ pas16_out(uint16_t port, uint8_t val, void *priv) mpu401_change_addr(pas16->mpu, ((pas16->compat_base & 0xf0) | 0x300)); break; - case 0xfb8a: + case 0xf802: pas16->sb_irqdma = val; sb_dsp_setirq(&pas16->dsp, pas16_sb_irqs[(val >> 3) & 7]); sb_dsp_setdma8(&pas16->dsp, pas16_sb_dmas[(val >> 6) & 3]); - pas16_log("pas16_out : set SB IRQ %i DMA %i.\n", pas16_sb_irqs[(val >> 3) & 7], pas16_sb_dmas[(val >> 6) & 3]); + pas16_log("pas16_out : set SB IRQ %i DMA %i.\n", pas16_sb_irqs[(val >> 3) & 7], + pas16_sb_dmas[(val >> 6) & 3]); break; default: @@ -504,35 +745,157 @@ pas16_out(uint16_t port, uint8_t val, void *priv) } } -static uint8_t -pas16_readdma(pas16_t *pas16) +/* + 8-bit mono: + - 8-bit DMA : On every timer 0 over, read the 8-bit sample and ctr_clock(); + (One ctr_clock() per timer 0 over) + - 16-bit DMA: On every even timer 0 over, read two 8-bit samples at once and ctr_clock(); + On every odd timer 0 over, read the MSB of the previously read sample word. + (One ctr_clock() per two timer 0 overs) + 8-bit stereo: + - 8-bit DMA : On every timer 0, read two 8-bit samples and ctr_clock() twice; + (Two ctr_clock()'s per timer 0 over) + - 16-bit DMA: On every timer 0, read two 8-bit samples and ctr_clock() once. + (One ctr_clock() per timer 0 over) + 16-bit mono (to be verified): + - 8-bit DMA : On every timer 0, read one 16-bit sample and ctr_clock() twice; + (Two ctr_clock()'s per timer 0 over) + - 16-bit DMA: On every timer 0, read one 16-bit sample and ctr_clock() once. + (One ctr_clock() per timer 0 over) + 16-bit stereo: + - 8-bit DMA : On every timer 0, read one 16-bit sample and ctr_clock() twice; + (Two ctr_clock()'s per timer 0 over) + - 16-bit DMA: On every timer 0, read one 16-bit sample and ctr_clock() twice. + (Two ctr_clock()'s per timer 0 over) + + What we can conclude from this is: + - Maximum 16 bits per timer 0 over; + - A 8-bit sample always takes one ctr_clock() tick, unless it has been read + alongside the previous sample; + - A 16-bit sample always takes two ctr_clock() ticks. + */ +static uint16_t +pas16_dma_readb(pas16_t *pas16, uint8_t timer1_ticks) { - return dma_channel_read(pas16->dma); + uint16_t ret; + + if (pas16->pcm_ctrl & PAS16_PCM_DMA_ENA) + ret = dma_channel_read(pas16->dma); + else + ret = 0x0000; + + for (uint8_t i = 0; i < timer1_ticks; i++) + pitf_ctr_clock(pas16->pit, 1); + + return ret; +} + +static uint16_t +pas16_dma_readw(pas16_t *pas16, uint8_t timer1_ticks) +{ + uint16_t ret; + + if (pas16->pcm_ctrl & PAS16_PCM_DMA_ENA) { + ret = dma_channel_read(pas16->dma); + + if (pas16->dma < 5) + ret |= (dma_channel_read(pas16->dma) << 8); + } else + ret = 0x0000; + + for (uint8_t i = 0; i < timer1_ticks; i++) + pitf_ctr_clock(pas16->pit, 1); + + return ret; +} + +static uint16_t +pas16_readdmab(pas16_t *pas16) +{ + static uint16_t temp; + uint16_t ret; + + if (pas16->dma >= 5) { + if (pas16->dma8_ff) + temp >>= 8; + else + temp = pas16_dma_readb(pas16, 1); + + pas16->dma8_ff = !pas16->dma8_ff; + } else + temp = pas16_dma_readb(pas16, 1); + + ret = ((temp & 0xff) ^ 0x80) << 8; + + return ret; +} + +static uint16_t +pas16_readdmaw_mono(pas16_t *pas16) +{ + uint16_t ret; + + ret = pas16_dma_readw(pas16, 1 + (pas16->dma < 5)); + + return ret; +} + +static uint16_t +pas16_readdmaw_stereo(pas16_t *pas16) +{ + uint16_t ret; + + ret = pas16_dma_readw(pas16, 2); + + return ret; +} + +static uint16_t +pas16_readdma_mono(pas16_t *pas16) +{ + uint16_t ret; + + if (pas16->sys_conf_2 & 0x04) { + ret = pas16_readdmaw_mono(pas16); + + if (pas16->sys_conf_2 & 0x08) + ret &= 0xfff0; + } else + ret = pas16_readdmab(pas16); + + if (pas16->sys_conf_2 & PAS16_SC2_MSBINV) + ret ^= 0x8000; + + return ret; +} + +static uint16_t +pas16_readdma_stereo(pas16_t *pas16) +{ + uint16_t ret; + + if (pas16->sys_conf_2 & 0x04) { + ret = pas16_readdmaw_stereo(pas16); + + if (pas16->sys_conf_2 & 0x08) + ret &= 0xfff0; + } else + ret = pas16_readdmab(pas16); + + if (pas16->sys_conf_2 & PAS16_SC2_MSBINV) + ret ^= 0x8000; + + return ret; } static void -pas16_pcm_poll(void *priv) +pas16_pit_timer0(int new_out, UNUSED(int old_out), void *priv) { - pas16_t *pas16 = (pas16_t *) priv; - pit_t *pit = (pit_t *) pas16->pit; - int data; - uint16_t temp = 0x0000; + pitf_t *pit = (pitf_t *) priv; + pas16_t *pas16 = (pas16_t *) pit->dev_priv; + uint16_t temp; pas16_update(pas16); - if (pit->counters[0].m & 0x02) { - if (pit->counters[0].l & 0xff) { - if (pas16->dma >= 5) - timer_advance_u64(&pas16->timer, (pit->counters[0].l & 0xff) * (PITCONST << 1ULL)); - else - timer_advance_u64(&pas16->timer, (pit->counters[0].l & 0xff) * PITCONST); - } else { - if (pas16->dma >= 5) - timer_advance_u64(&pas16->timer, 0x100 * (PITCONST << 1ULL)); - else - timer_advance_u64(&pas16->timer, 0x100 * PITCONST); - } - } - pas16_update_irq(pas16); pas16->irq_stat |= PAS16_INT_SAMP; @@ -541,88 +904,51 @@ pas16_pcm_poll(void *priv) picint(1 << pas16->irq); } - /*Update sample rate counter*/ - pas16_log("T1=%d, master bit 1=%x, counter0=%d, counter1=%d, pcm dma ena=%02x 16bit?=%02x.\n", pit->counters[1].enable, pit->counters[0].m & 0x02, pit->counters[0].l, pit->counters[1].l, pas16->pcm_ctrl & 0xc0, pas16->sys_conf_2 & PAS16_SC2_16BIT); - if (pit->counters[1].enable) { - if ((pas16->pcm_ctrl & (PAS16_PCM_ENA | PAS16_PCM_DMA_ENA))) { - if (pas16->sys_conf_2 & PAS16_SC2_16BIT) { - data = pas16_readdma(pas16) << 8; - data |= pas16_readdma(pas16); - temp = data; - } else { - data = pas16_readdma(pas16); - temp = (data ^ 0x80) << 8; - } + if (((pas16->pcm_ctrl & PAS16_PCM_AND_DMA_ENA) == PAS16_PCM_AND_DMA_ENA) && + dma_channel_readable(pas16->dma) && (pit->counters[1].m & 2) && new_out) { + if (pas16->pcm_ctrl & PAS16_PCM_MONO) { + temp = pas16_readdma_mono(pas16); - if (pas16->sys_conf_2 & PAS16_SC2_MSBINV) - temp ^= 0x8000; - if (pas16->pcm_ctrl & PAS16_PCM_MONO) - pas16->pcm_dat_l = pas16->pcm_dat_r = temp; - else { + pas16->pcm_dat_l = pas16->pcm_dat_r = temp; + } else { + temp = pas16_readdma_stereo(pas16); + + if (pas16->sys_conf_1 & 0x02) { + pas16->pcm_dat_l = temp; + + temp = pas16_readdma_stereo(pas16); + + pas16->pcm_dat_r = temp; + } else { if (pas16->stereo_lr) pas16->pcm_dat_r = temp; else pas16->pcm_dat_l = temp; pas16->stereo_lr = !pas16->stereo_lr; + pas16->irq_stat = (pas16->irq_stat & 0xdf) | (pas16->stereo_lr << 5); } } - if (pas16->sys_conf_2 & PAS16_SC2_16BIT) { - pit->counters[1].lback -= 2; - if (!pit->counters[1].lback) { - if (pit->counters[1].m & 0x02) { - if (pit->counters[1].lback2 & 0xfffe) - pit->counters[1].lback = pit->counters[1].lback2 & 0xfffe; - else - pit->counters[1].lback = 0; - } else { - pit->counters[1].lback = 0; - pit->counters[1].enable = 0; - } - pas16_log("16-bit: New counter=%d, mode=%x.\n", pit->counters[1].lback, pit->counters[1].m & 0x03); - pas16->irq_stat |= PAS16_INT_PCM; - if (pas16->irq_ena & PAS16_INT_PCM) { - pas16_log("16-bit: INT PCM.\n"); - picint(1 << pas16->irq); - } - } - } else { - pit->counters[1].lback--; - if (!pit->counters[1].lback) { - if (pit->counters[1].m & 0x02) { - if (pit->counters[1].lback2 & 0xffff) - pit->counters[1].lback = pit->counters[1].lback2 & 0xffff; - else - pit->counters[1].lback = 0; - } else { - pit->counters[1].lback = 0; - pit->counters[1].enable = 0; - } - pas16_log("8-bit: New counter=%d, mode=%x.\n", pit->counters[1].lback, pit->counters[1].m & 0x03); - pas16->irq_stat |= PAS16_INT_PCM; - if (pas16->irq_ena & PAS16_INT_PCM) { - pas16_log("8-bit: INT PCM.\n"); - picint(1 << pas16->irq); - } - } - } - } + } } static void -pas16_pit_timer0(int new_out, UNUSED(int old_out), void *priv) +pas16_pit_timer1(int new_out, UNUSED(int old_out), void *priv) { - pit_t *pit = (pit_t *)priv; - pas16_t *pas16 = (pas16_t *)pit->dev_priv; + pitf_t *pit = (pitf_t * )priv; + pas16_t *pas16 = (pas16_t *) pit->dev_priv; - pas16_log("PAS16 pit timer0 out=%x, cnt0=%d, cnt1=%d.\n", new_out, pit->counters[0].l, pit->counters[1].l); - pit_ctr_set_clock(&pit->counters[0], new_out, pit); - pit->counters[1].enable = new_out; - if (!timer_is_enabled(&pas16->timer)) { - if (pas16->dma >= 5) - timer_set_delay_u64(&pas16->timer, (pit->counters[0].l & 0xff) * (PITCONST << 1ULL)); - else - timer_set_delay_u64(&pas16->timer, (pit->counters[0].l & 0xff) * PITCONST); + /* At new_out = 0, it's in the counter reload phase. */ + if ((pas16->pcm_ctrl & PAS16_PCM_ENA) && (pit->counters[1].m & 2) && new_out) { + if (pas16->irq_ena & PAS16_INT_PCM) { + pas16->irq_stat |= PAS16_INT_PCM; + pas16_log("pas16_pcm_poll : cause IRQ %i %02X\n", pas16->irq, 1 << pas16->irq); + picint(1 << pas16->irq); + + pas16->stereo_lr = 0; + pas16->irq_stat &= 0xdf; + pas16->dma8_ff = 0; + } } } @@ -631,16 +957,14 @@ pas16_out_base(UNUSED(uint16_t port), uint8_t val, void *priv) { pas16_t *pas16 = (pas16_t *) priv; - for (uint32_t addr = 0x000; addr < 0x10000; addr += 0x400) { - if (addr != 0x1000) { - io_removehandler(pas16->base + addr, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler(pas16->base + addr, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - } - } - pit_handler(0, pas16->base + 0x1000, 0x0004, pas16->pit); - pit_handler(1, pas16->base + 0x1000, 0x0004, pas16->pit); + pas16_log("[%04X:%08X] PAS16: [W] %04X = %02X\n", CS, cpu_state.pc, port, val); - pas16->base = val << 2; + if (pas16->master_ff && (pas16->board_id == pas16->this_id)) + pas16->new_base = val << 2; + else if (!pas16->master_ff) + pas16->board_id = val; + + pas16->master_ff = !pas16->master_ff; } static void @@ -693,8 +1017,16 @@ pas16_update(pas16_t *pas16) } } else { for (; pas16->pos < sound_pos_global; pas16->pos++) { - pas16->pcm_buffer[0][pas16->pos] = (int16_t) pas16->pcm_dat_l; - pas16->pcm_buffer[1][pas16->pos] = (int16_t) pas16->pcm_dat_r; + pas16->pcm_buffer[0][pas16->pos] = 0; + pas16->pcm_buffer[1][pas16->pos] = 0; + if (pas16->pcm_ctrl & 0x08) + pas16->pcm_buffer[0][pas16->pos] += pas16->pcm_dat_l; + if (pas16->pcm_ctrl & 0x04) + pas16->pcm_buffer[0][pas16->pos] += pas16->pcm_dat_r; + if (pas16->pcm_ctrl & 0x02) + pas16->pcm_buffer[1][pas16->pos] += pas16->pcm_dat_l; + if (pas16->pcm_ctrl & 0x01) + pas16->pcm_buffer[1][pas16->pos] += pas16->pcm_dat_r; } } } @@ -708,7 +1040,10 @@ pas16_get_buffer(int32_t *buffer, int len, void *priv) pas16_update(pas16); for (int c = 0; c < len * 2; c++) { buffer[c] += (int16_t) (sb_iir(0, c & 1, (double) pas16->dsp.buffer[c]) / 1.3) / 2; - buffer[c] += (pas16->pcm_buffer[c & 1][c >> 1] / 2); + if (pas16->filter) + buffer[c] += (low_fir_pas16(0, c & 1, (double) pas16->pcm_buffer[c & 1][c >> 1])) / 2.0; + else + buffer[c] += (pas16->pcm_buffer[c & 1][c >> 1] / 2); } pas16->pos = 0; @@ -730,31 +1065,22 @@ pas16_get_music_buffer(int32_t *buffer, int len, void *priv) static void pas16_speed_changed(void *priv) { - pas16_t *pas16 = (pas16_t *) priv; - - /* TODO: In PAS16 mode: - pit_change_pas16_const(prescale); - pit_set_pit_const(pas16->pit, PAS16CONST); - */ - - pit_set_pit_const(pas16->pit, PITCONST); -} - -static void -pas16_reset(void *priv) -{ - pas16_t *pas16 = (pas16_t *) priv; - - /* TODO: Reset the entire PAS16 state here. */ - pit_set_pit_const(pas16->pit, PITCONST); + pas16_change_pit_clock_speed(priv); } static void * -pas16_init(UNUSED(const device_t *info)) +pas16_init(const device_t *info) { - pas16_t *pas16 = malloc(sizeof(pas16_t)); - memset(pas16, 0, sizeof(pas16_t)); + pas16_t *pas16 = calloc(1, sizeof(pas16_t)); + if (pas16_next > 3) { + fatal("Attempting to add a Pro Audio Spectrum instance beyond the maximum amount\n"); + + free(pas16); + return NULL; + } + + pas16->type = info->local & 0xff; fm_driver_get(FM_YMF262, &pas16->opl); sb_dsp_set_real_opl(&pas16->dsp, 1); sb_dsp_init(&pas16->dsp, SB2, SB_SUBTYPE_DEFAULT, pas16); @@ -763,20 +1089,22 @@ pas16_init(UNUSED(const device_t *info)) mpu401_init(pas16->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); sb_dsp_set_mpu(&pas16->dsp, pas16->mpu); - pas16->pit = device_add(&i8254_ext_io_device); - pit_set_pit_const(pas16->pit, PITCONST); - pas16->pit->dev_priv = pas16; - pas16->irq = 10; - pas16->dma = 3; - pas16->base = 0x0388; - io_sethandler(0x9a01, 0x0001, NULL, NULL, NULL, pas16_out_base, NULL, NULL, pas16); - pit_ctr_set_out_func(pas16->pit, 0, pas16_pit_timer0); - pit_ctr_set_using_timer(pas16->pit, 0, 1); - pit_ctr_set_using_timer(pas16->pit, 1, 0); - pit_ctr_set_using_timer(pas16->pit, 2, 0); + pas16->this_id = 0xbc + pas16_next; - timer_add(&pas16->timer, pas16_pcm_poll, pas16, 0); + pas16->pit = device_add(&i8254_ext_io_fast_device); + pas16_reset(pas16); + pas16->pit->dev_priv = pas16; + pas16->irq = pas16->type ? 10 : 5; + pas16->dma = 3; + for (uint8_t i = 0; i < 3; i++) + pitf_ctr_set_gate(pas16->pit, i, 0); + + pitf_ctr_set_out_func(pas16->pit, 0, pas16_pit_timer0); + pitf_ctr_set_out_func(pas16->pit, 1, pas16_pit_timer1); + pitf_ctr_set_using_timer(pas16->pit, 0, 1); + pitf_ctr_set_using_timer(pas16->pit, 1, 0); + pitf_ctr_set_using_timer(pas16->pit, 2, 0); sound_add_handler(pas16_get_buffer, pas16); music_add_handler(pas16_get_music_buffer, pas16); @@ -784,6 +1112,8 @@ pas16_init(UNUSED(const device_t *info)) if (device_get_config_int("receive_input")) midi_in_handler(1, pas16_input_msg, pas16_input_sysex, pas16); + pas16_next++; + return pas16; } @@ -793,6 +1123,8 @@ pas16_close(void *priv) pas16_t *pas16 = (pas16_t *) priv; free(pas16); + + pas16_next = 0; } static const device_config_t pas16_config[] = { @@ -805,7 +1137,7 @@ static const device_config_t pas16_config[] = { }, { .name = "receive_input", - .description = "Receive input (PAS16 MIDI)", + .description = "Receive input (PAS MIDI)", .type = CONFIG_BINARY, .default_string = "", .default_int = 1 @@ -813,10 +1145,10 @@ static const device_config_t pas16_config[] = { { .name = "", .description = "", .type = CONFIG_END } }; -const device_t pas16_device = { - .name = "Pro Audio Spectrum 16", - .internal_name = "pas16", - .flags = DEVICE_ISA | DEVICE_AT, +const device_t pasplus_device = { + .name = "Pro Audio Spectrum Plus", + .internal_name = "pasplus", + .flags = DEVICE_ISA, .local = 0, .init = pas16_init, .close = pas16_close, @@ -826,3 +1158,18 @@ const device_t pas16_device = { .force_redraw = NULL, .config = pas16_config }; + + +const device_t pas16_device = { + .name = "Pro Audio Spectrum 16", + .internal_name = "pas16", + .flags = DEVICE_ISA | DEVICE_AT, + .local = 1, + .init = pas16_init, + .close = pas16_close, + .reset = pas16_reset, + { .available = NULL }, + .speed_changed = pas16_speed_changed, + .force_redraw = NULL, + .config = pas16_config +}; diff --git a/src/sound/sound.c b/src/sound/sound.c index 9acf99460..cf7a7a33c 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -149,6 +149,7 @@ static const SOUND_CARD sound_cards[] = { { &sb_vibra16s_device }, { &sb_vibra16xv_device }, { &ssi2001_device }, + { &pasplus_device }, { &pas16_device }, { &pssj_isa_device }, { &tndy_device }, From 97ba1cd8e0e60018e5d55122f12cf2aa340cc5e5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 28 Mar 2024 00:18:30 +0100 Subject: [PATCH 801/936] Moved the ATi VGA Wonder 18800 out of the Dev branch. --- CMakeLists.txt | 1 - src/include/86box/video.h | 2 -- src/video/CMakeLists.txt | 4 ---- src/video/vid_ati18800.c | 43 +++++++++++++++++++++++++-------------- src/video/vid_table.c | 2 -- 5 files changed, 28 insertions(+), 24 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5bafadcc1..c0066e04a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -160,7 +160,6 @@ cmake_dependent_option(OLIVETTI "Olivetti M290" cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF) cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF) -cmake_dependent_option(VGAWONDER "ATI VGA Wonder (ATI-18800)" ON "DEV_BRANCH" OFF) cmake_dependent_option(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF) # Ditto but for Qt diff --git a/src/include/86box/video.h b/src/include/86box/video.h index e56498807..bf36bf7de 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -320,9 +320,7 @@ extern const device_t mach64gx_pci_device; extern const device_t mach64vt2_device; /* ATi 18800 */ -# if defined(DEV_BRANCH) && defined(USE_VGAWONDER) extern const device_t ati18800_wonder_device; -# endif extern const device_t ati18800_vga88_device; extern const device_t ati18800_device; diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index 8fbd62e35..12ba34a02 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -28,10 +28,6 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_mga.c vid_nga.c vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c) -if(VGAWONDER) - target_compile_definitions(vid PRIVATE USE_VGAWONDER) -endif() - if(XL24) target_compile_definitions(vid PRIVATE USE_XL24) endif() diff --git a/src/video/vid_ati18800.c b/src/video/vid_ati18800.c index b54f6b89e..7f0993ef8 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -32,21 +32,14 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> -#if defined(DEV_BRANCH) && defined(USE_VGAWONDER) -# define BIOS_ROM_PATH_WONDER "roms/video/ati18800/VGA_Wonder_V3-1.02.bin" -#endif +#define BIOS_ROM_PATH_WONDER "roms/video/ati18800/VGA_Wonder_V3-1.02.bin" #define BIOS_ROM_PATH_VGA88 "roms/video/ati18800/vga88.bin" #define BIOS_ROM_PATH_EDGE16 "roms/video/ati18800/vgaedge16.vbi" enum { -#if defined(DEV_BRANCH) && defined(USE_VGAWONDER) ATI18800_WONDER = 0, ATI18800_VGA88, ATI18800_EDGE16 -#else - ATI18800_VGA88 = 0, - ATI18800_EDGE16 -#endif }; typedef struct ati18800_t { @@ -257,11 +250,10 @@ ati18800_init(const device_t *info) switch (info->local) { default: -#if defined(DEV_BRANCH) && defined(USE_VGAWONDER) case ATI18800_WONDER: rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_WONDER, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + ati18800->memory = device_get_config_int("memory"); break; -#endif case ATI18800_VGA88: rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_VGA88, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); ati18800->memory = 256; @@ -291,13 +283,11 @@ ati18800_init(const device_t *info) return ati18800; } -#if defined(DEV_BRANCH) && defined(USE_VGAWONDER) static int ati18800_wonder_available(void) { return rom_present(BIOS_ROM_PATH_WONDER); } -#endif static int ati18800_vga88_available(void) @@ -337,7 +327,31 @@ ati18800_force_redraw(void *priv) ati18800->svga.fullchange = changeframecount; } -#if defined(DEV_BRANCH) && defined(USE_VGAWONDER) +static const device_config_t ati18800_wonder_config[] = { + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 512, + .selection = { + { + .description = "256 kB", + .value = 256 + }, + { + .description = "512 kB", + .value = 512 + }, + { + .description = "" + } + } + }, + { + .type = CONFIG_END + } +}; + const device_t ati18800_wonder_device = { .name = "ATI-18800", .internal_name = "ati18800w", @@ -349,9 +363,8 @@ const device_t ati18800_wonder_device = { { .available = ati18800_wonder_available }, .speed_changed = ati18800_speed_changed, .force_redraw = ati18800_force_redraw, - .config = NULL + .config = ati18800_wonder_config }; -#endif const device_t ati18800_vga88_device = { .name = "ATI 18800-1", diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 9992eff45..e526216c3 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -91,9 +91,7 @@ video_cards[] = { { &ati28800_wonderxl24_device }, #endif { &ati18800_device }, -#if defined(DEV_BRANCH) && defined(USE_VGAWONDER) { &ati18800_wonder_device }, -#endif { &cga_device }, { &sega_device }, { &gd5401_isa_device }, From 7bd510dc1013018ba6307e1cbe1f5eee8cede40f Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 28 Mar 2024 00:25:30 +0100 Subject: [PATCH 802/936] Actually take the Olivetti M290 Dev branched option into account. --- src/machine/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/machine/CMakeLists.txt b/src/machine/CMakeLists.txt index e88631044..ecc374e66 100644 --- a/src/machine/CMakeLists.txt +++ b/src/machine/CMakeLists.txt @@ -37,6 +37,10 @@ if(LASERXT) target_compile_definitions(mch PRIVATE USE_LASERXT) endif() +if(OLIVETTI) + target_compile_definitions(mch PRIVATE USE_OLIVETTI) +endif() + if(OPEN_AT) target_compile_definitions(mch PRIVATE USE_OPEN_AT) endif() From 2fd5fe86cd5e35ac089c79d4eb7ff49e682906b1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 28 Mar 2024 18:12:30 +0100 Subject: [PATCH 803/936] SiS 55xx: Add sanity check to the PCI to ISA bridge close code, fixes #4304. --- src/chipset/sis_5513_p2i.c | 3 ++- src/chipset/sis_5581.c | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chipset/sis_5513_p2i.c b/src/chipset/sis_5513_p2i.c index d0c423a8e..ef9a6746d 100644 --- a/src/chipset/sis_5513_p2i.c +++ b/src/chipset/sis_5513_p2i.c @@ -1197,7 +1197,8 @@ sis_5513_pci_to_isa_close(void *priv) sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; FILE *fp = NULL; - fp = nvr_fopen(dev->fn, "wb"); + if (dev->fn != NULL) + fp = nvr_fopen(dev->fn, "wb"); if (fp != NULL) { (void) fwrite(dev->apc_regs, 256, 1, fp); diff --git a/src/chipset/sis_5581.c b/src/chipset/sis_5581.c index 98b37897c..e2308c2d9 100644 --- a/src/chipset/sis_5581.c +++ b/src/chipset/sis_5581.c @@ -43,7 +43,6 @@ #include <86box/sis_55xx.h> #include <86box/chipset.h> -#define ENABLE_SIS_5581_LOG 1 #ifdef ENABLE_SIS_5581_LOG int sis_5581_do_log = ENABLE_SIS_5581_LOG; From 3ec5f6f4a32b1df702e783481fd833182671d624 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 31 Mar 2024 23:56:59 +0200 Subject: [PATCH 804/936] SiS 5571: Use the correct register for recalculating the SMRAM mapping, fixes #4318. --- src/chipset/sis_5571_h2p.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/chipset/sis_5571_h2p.c b/src/chipset/sis_5571_h2p.c index 26c74a3c0..4a4ee9b83 100644 --- a/src/chipset/sis_5571_h2p.c +++ b/src/chipset/sis_5571_h2p.c @@ -119,18 +119,18 @@ sis_5571_smram_recalc(sis_5571_host_to_pci_t *dev) { smram_disable_all(); - switch (dev->pci_conf[0x68] >> 6) { + switch (dev->pci_conf[0xa3] >> 6) { case 0: - smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); break; case 1: - smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); break; case 2: - smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); break; case 3: - smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0x68] & 0x10, 1); + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0xa3] & 0x10, 1); break; default: From 46840b239d55188a4df4d48b39a3fa1ca82d5365 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 1 Apr 2024 12:57:48 +0200 Subject: [PATCH 805/936] MGA: Implement hardware dithering modes by Cacodemon345, fixes Windows 3.1 dynamic resolution switching. --- src/video/vid_mga.c | 60 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 0de369b53..36df9e9e4 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -3579,6 +3579,12 @@ blit_fbitblt(mystique_t *mystique) mystique->blitter_complete_refcount++; } +static uint8_t +dither_24_to_8(int r, int g, int b) +{ + return ((b >> 6) & 3) | (((g >> 5) & 7) << 2) | (((r >> 5) & 7) << 5); +} + static void blit_iload_iload(mystique_t *mystique, uint32_t data, int size) { @@ -3811,6 +3817,26 @@ blit_iload_iload(mystique_t *mystique, uint32_t data, int size) while (size >= 24) { 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) { 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; + } case MACCESS_PWIDTH_32: dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; @@ -3852,13 +3878,39 @@ blit_iload_iload(mystique_t *mystique, uint32_t data, int size) data64 = mystique->dwgreg.iload_rem_data | ((uint64_t) data << mystique->dwgreg.iload_rem_count); while (size >= 32) { int draw = (!transc || (data & bltcmsk) != bltckey) && trans[mystique->dwgreg.xdst & 3]; + pclog("maccess = 0x%X\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); 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) { - dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + 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(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; + 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 = 0; From 05bbb2a807000424ab6feae799a6d7c09fd1dc71 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 31 Mar 2024 23:58:15 +0500 Subject: [PATCH 806/936] Modem: Increase phonebook size to 200 entries Also make some string operations (such as phonebook file parsing) safer --- src/network/net_modem.c | 138 +++++++++++++++++++++++----------------- 1 file changed, 79 insertions(+), 59 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 082874f54..4bc056ea1 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -74,11 +74,13 @@ typedef enum modem_slip_stage_t MODEM_SLIP_STAGE_USERNAME, MODEM_SLIP_STAGE_PASSWORD } modem_slip_stage_t; +#define NUMBER_BUFFER_SIZE 128 +#define PHONEBOOK_SIZE 200 typedef struct modem_phonebook_entry_t { - char phone[1024]; - char address[1024]; + char phone[NUMBER_BUFFER_SIZE]; + char address[NUMBER_BUFFER_SIZE]; } modem_phonebook_entry_t; typedef struct modem_t @@ -135,7 +137,7 @@ typedef struct modem_t uint8_t command; } telClient; - modem_phonebook_entry_t entries[20]; + modem_phonebook_entry_t entries[PHONEBOOK_SIZE]; uint32_t entries_num; netcard_t *card; @@ -155,39 +157,92 @@ static void modem_accept_incoming_call(modem_t* modem); extern ssize_t local_getline(char **buf, size_t *bufsiz, FILE *fp); +// https://stackoverflow.com/a/122974 +char *trim(char *str) +{ + size_t len = 0; + char *frontp = str; + char *endp = NULL; + + if( str == NULL ) { return NULL; } + if( str[0] == '\0' ) { return str; } + + len = strlen(str); + endp = str + len; + + /* Move the front and back pointers to address the first non-whitespace + * characters from each end. + */ + while( isspace((unsigned char) *frontp) ) { ++frontp; } + if( endp != frontp ) + { + while( isspace((unsigned char) *(--endp)) && endp != frontp ) {} + } + + if( frontp != str && endp == frontp ) + *str = '\0'; + else if( str + len - 1 != endp ) + *(endp + 1) = '\0'; + + /* Shift the string so that it starts at str so that if it's dynamically + * allocated, we can still free it on the returned pointer. Note the reuse + * of endp to mean the front of the string buffer now. + */ + endp = str; + if( frontp != str ) + { + while( *frontp ) { *endp++ = *frontp++; } + *endp = '\0'; + } + + return str; +} + static void modem_read_phonebook_file(modem_t* modem, const char* path) { FILE* file = plat_fopen(path, "r"); - char* buf = NULL; + char* buf = NULL; + char* buf2 = NULL; size_t size = 0; if (!file) return; modem->entries_num = 0; + pclog("Phonebook: Reading file %s...\n", path); while (local_getline(&buf, &size, file) != -1) { modem_phonebook_entry_t entry = { { 0 }, { 0 } }; - int res = 0; - buf[strcspn(buf, "\r\n")] = 0; + buf[strcspn(buf, "\r\n")] = '\0'; - res = sscanf(buf, "%s %s", entry.phone, entry.address); + /* Remove surrounding whitespace from the input line and find the address part. */ + buf = trim(buf); + buf2 = &buf[strcspn(buf, " \t")]; - if (res == 0 || res == 1) { + /* Remove surrounding whitespace and any extra text from the address part, then store it. */ + buf2 = trim(buf2); + buf2[strcspn(buf2, " \t")] = '\0'; + strncpy(entry.address, buf2, sizeof(entry.address) - 1); + + /* Split the line to get the phone number part, then store it. */ + buf2[0] = '\0'; + strncpy(entry.phone, buf, sizeof(entry.phone) - 1); + + if ((entry.phone[0] == '\0') || (entry.address[0] == '\0')) { /* Appears to be a bad line. */ + pclog("Phonebook: Skipped a bad line\n"); continue; } - if (res == EOF) - break; - if (strspn(entry.phone, "01234567890*=,;#+>") != strlen(entry.phone)) { /* Invalid characters. */ + pclog("Phonebook: Invalid character in phone number %s\n", entry.phone); continue; } + pclog("Phonebook: Mapped phone number %s to address %s\n", entry.phone, entry.address); modem->entries[modem->entries_num++] = entry; - if (modem->entries_num >= 20) + if (modem->entries_num >= PHONEBOOK_SIZE) break; } fclose(file); @@ -573,8 +628,8 @@ modem_dial(modem_t* modem, const char* str) } else { - char buf[128] = ""; - strcpy(buf, str); + char buf[NUMBER_BUFFER_SIZE] = ""; + strncpy(buf, str, sizeof(buf) - 1); // Scan host for port uint16_t port; char * hasport = strrchr(buf,':'); @@ -615,47 +670,6 @@ is_next_token(const char* a, size_t N, const char *b) return (strncmp(a, b, N_without_null) == 0); } -// https://stackoverflow.com/a/122974 -char *trim(char *str) -{ - size_t len = 0; - char *frontp = str; - char *endp = NULL; - - if( str == NULL ) { return NULL; } - if( str[0] == '\0' ) { return str; } - - len = strlen(str); - endp = str + len; - - /* Move the front and back pointers to address the first non-whitespace - * characters from each end. - */ - while( isspace((unsigned char) *frontp) ) { ++frontp; } - if( endp != frontp ) - { - while( isspace((unsigned char) *(--endp)) && endp != frontp ) {} - } - - if( frontp != str && endp == frontp ) - *str = '\0'; - else if( str + len - 1 != endp ) - *(endp + 1) = '\0'; - - /* Shift the string so that it starts at str so that if it's dynamically - * allocated, we can still free it on the returned pointer. Note the reuse - * of endp to mean the front of the string buffer now. - */ - endp = str; - if( frontp != str ) - { - while( *frontp ) { *endp++ = *frontp++; } - *endp = '\0'; - } - - return str; -} - static const char *modem_get_address_from_phonebook(modem_t* modem, const char *input) { int i = 0; for (i = 0; i < modem->entries_num; i++) { @@ -710,8 +724,8 @@ modem_do_command(modem_t* modem) modem_send_res(modem, ResERROR); return; case 'D': { // Dial. - char buffer[128]; - char obuffer[128]; + char buffer[NUMBER_BUFFER_SIZE]; + char obuffer[NUMBER_BUFFER_SIZE]; char * foundstr = &scanbuf[0]; const char *mappedaddr = NULL; size_t i = 0; @@ -719,7 +733,8 @@ modem_do_command(modem_t* modem) if (*foundstr == 'T' || *foundstr == 'P') foundstr++; - if ((!foundstr[0]) || (strlen(foundstr) > 253)) { + if ((!foundstr[0]) || (strlen(foundstr) > (NUMBER_BUFFER_SIZE - 1))) { + // Check for empty or too long strings modem_send_res(modem, ResERROR); return; } @@ -739,7 +754,12 @@ modem_do_command(modem_t* modem) for (i = 0; i < fl; i++) if (foundstr[i] < '0' || foundstr[i] > '9') isNum = false; - if (isNum) { + if (isNum && (fl > (NUMBER_BUFFER_SIZE - 5))) { + // Check if the number is long enough to cause buffer + // overflows during the number => IP transformation + modem_send_res(modem, ResERROR); + return; + } else if (isNum) { // Parameter is a number with at least 12 digits => this cannot // be a valid IP/name // Transform by adding dots From b63c1e04ebf655855498953e2d56050ae3ec41fd Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Apr 2024 00:08:47 +0500 Subject: [PATCH 807/936] Modem: Fix escape guard counter never resetting Escape sequence guard timer now actually works --- 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 4bc056ea1..4831faf60 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -391,6 +391,7 @@ modem_data_mode_process_byte(modem_t* modem, uint8_t data) modem->plusinc = 0; } } + modem->cmdpause = 0; if (modem->tx_count < 0x10000 && modem->connected) { modem->tx_pkt_ser_line[modem->tx_count++] = data; @@ -597,6 +598,7 @@ modem_reset(modem_t* modem) modem->cmdpos = 0; modem->cmdbuf[0] = 0; modem->flowcontrol = 0; + modem->cmdpause = 0; modem->plusinc = 0; modem->dtrmode = 2; From 2353d1f917dde8053e1d82f7db36cbde3ba03edf Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Apr 2024 00:10:45 +0500 Subject: [PATCH 808/936] Modem: Stop command line processing after dialing "Phone numbers" with letters in them, such as hostnames, are no longer interpreted as commands --- src/network/net_modem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 4831faf60..42862975f 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -795,7 +795,7 @@ modem_do_command(modem_t* modem) } } modem_dial(modem, foundstr); - break; + return; } case 'I': // Some strings about firmware switch (modem_scan_number(&scanbuf)) { From 94c917eaaf160d581d9aff051210d59ed355a1c9 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Apr 2024 11:41:21 +0500 Subject: [PATCH 809/936] Modem: Implement `ATD;` (return to command mode after dialing) To simulate the in-progress dialing, the number before the semicolon is appended to a temporary buffer; when an ATD command without a semicolon is issued, the buffer contents are prepended and the complete number is dialed at once. Fixes Windows 98 dialer being stuck if "wait for dial tone" option was enabled. --- src/network/net_modem.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 42862975f..6c0a8a7f1 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -105,6 +105,7 @@ typedef struct modem_t Fifo8 data_pending; /* Data yet to be sent to the host. */ char cmdbuf[512]; + char numberinprogress[NUMBER_BUFFER_SIZE]; uint32_t cmdpos; uint32_t port; int plusinc, flowcontrol; @@ -597,6 +598,7 @@ modem_reset(modem_t* modem) modem_enter_idle_state(modem); modem->cmdpos = 0; modem->cmdbuf[0] = 0; + modem->numberinprogress[0] = 0; modem->flowcontrol = 0; modem->cmdpause = 0; modem->plusinc = 0; @@ -626,6 +628,7 @@ modem_dial(modem_t* modem, const char* str) { pclog("Turning on SLIP\n"); modem_enter_connected_state(modem); + modem->numberinprogress[0] = 0; modem->tcpIpMode = false; } else @@ -643,6 +646,7 @@ modem_dial(modem_t* modem, const char* str) port = 23; } + modem->numberinprogress[0] = 0; modem->clientsocket = plat_netsocket_create(NET_SOCKET_TCP); if (modem->clientsocket == -1) { pclog("Failed to create client socket\n"); @@ -734,15 +738,28 @@ modem_do_command(modem_t* modem) if (*foundstr == 'T' || *foundstr == 'P') foundstr++; - - if ((!foundstr[0]) || (strlen(foundstr) > (NUMBER_BUFFER_SIZE - 1))) { + + if ((!foundstr[0] && !modem->numberinprogress[0]) || ((strlen(modem->numberinprogress) + strlen(foundstr)) > (NUMBER_BUFFER_SIZE - 1))) { // Check for empty or too long strings modem_send_res(modem, ResERROR); + modem->numberinprogress[0] = 0; return; } foundstr = trim(foundstr); + // Check for ; and return to command mode if found + char *semicolon = strchr(foundstr, ';'); + if (semicolon != NULL) { + pclog("Semicolon found in number, returning to command mode\n"); + strncat(modem->numberinprogress, foundstr, strcspn(foundstr, ";")); + scanbuf = semicolon + 1; + break; + } else { + strcat(modem->numberinprogress, foundstr); + foundstr = modem->numberinprogress; + } + mappedaddr = modem_get_address_from_phonebook(modem, foundstr); if (mappedaddr) { modem_dial(modem, mappedaddr); @@ -760,6 +777,7 @@ modem_do_command(modem_t* modem) // Check if the number is long enough to cause buffer // overflows during the number => IP transformation modem_send_res(modem, ResERROR); + modem->numberinprogress[0] = 0; return; } else if (isNum) { // Parameter is a number with at least 12 digits => this cannot @@ -818,6 +836,7 @@ modem_do_command(modem_t* modem) case 'H': // Hang up switch (modem_scan_number(&scanbuf)) { case 0: + modem->numberinprogress[0] = 0; if (modem->connected) { modem_send_res(modem, ResNOCARRIER); modem_enter_idle_state(modem); From e64136586663b230e04b39ca6cc0c4ec4bf19930 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Apr 2024 11:42:55 +0500 Subject: [PATCH 810/936] Modem: Implement `AT&C` (DCD signal control) --- src/network/net_modem.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 6c0a8a7f1..e2330ee37 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -110,6 +110,7 @@ typedef struct modem_t uint32_t port; int plusinc, flowcontrol; int in_warmup, dtrmode; + int dcdmode; bool connected, ringing; bool echo, numericresponse; @@ -571,7 +572,7 @@ modem_enter_idle_state(modem_t* modem) serial_set_cts(modem->serial, 1); serial_set_dsr(modem->serial, 1); - serial_set_dcd(modem->serial, 0); + serial_set_dcd(modem->serial, (!modem->dcdmode ? 1 : 0)); serial_set_ri(modem->serial, 0); } @@ -595,6 +596,7 @@ modem_enter_connected_state(modem_t* modem) void modem_reset(modem_t* modem) { + modem->dcdmode = 1; modem_enter_idle_state(modem); modem->cmdpos = 0; modem->cmdbuf[0] = 0; @@ -930,6 +932,16 @@ modem_do_command(modem_t* modem) case '&': { // & escaped commands char cmdchar = modem_fetch_character(&scanbuf); switch(cmdchar) { + case 'C': { + const uint32_t val = modem_scan_number(&scanbuf); + if (val < 2) + modem->dcdmode = val; + else { + modem_send_res(modem, ResERROR); + return; + } + break; + } case 'K': { const uint32_t val = modem_scan_number(&scanbuf); if (val < 5) From ba499b9563aa9870e1294b95d49a43071d4a70ec Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Apr 2024 11:56:01 +0500 Subject: [PATCH 811/936] Modem: Implement `ATDL` (dial last number) --- src/network/net_modem.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index e2330ee37..82810f97c 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -106,6 +106,7 @@ typedef struct modem_t char cmdbuf[512]; char numberinprogress[NUMBER_BUFFER_SIZE]; + char lastnumber[NUMBER_BUFFER_SIZE]; uint32_t cmdpos; uint32_t port; int plusinc, flowcontrol; @@ -600,6 +601,7 @@ modem_reset(modem_t* modem) modem_enter_idle_state(modem); modem->cmdpos = 0; modem->cmdbuf[0] = 0; + modem->lastnumber[0] = 0; modem->numberinprogress[0] = 0; modem->flowcontrol = 0; modem->cmdpause = 0; @@ -637,6 +639,7 @@ modem_dial(modem_t* modem, const char* str) { char buf[NUMBER_BUFFER_SIZE] = ""; strncpy(buf, str, sizeof(buf) - 1); + strncpy(modem->lastnumber, str, sizeof(modem->lastnumber) - 1); // Scan host for port uint16_t port; char * hasport = strrchr(buf,':'); @@ -738,8 +741,17 @@ modem_do_command(modem_t* modem) const char *mappedaddr = NULL; size_t i = 0; - if (*foundstr == 'T' || *foundstr == 'P') + if (*foundstr == 'T' || *foundstr == 'P') // Tone/pulse dialing foundstr++; + else if (*foundstr == 'L') { // Redial last number + if (modem->lastnumber[0] == 0) + modem_send_res(modem, ResERROR); + else { + pclog("Redialing number %s\n", modem->lastnumber); + modem_dial(modem, modem->lastnumber); + } + return; + } if ((!foundstr[0] && !modem->numberinprogress[0]) || ((strlen(modem->numberinprogress) + strlen(foundstr)) > (NUMBER_BUFFER_SIZE - 1))) { // Check for empty or too long strings From 9b8680b7cfe953367db0ec9929f7f5fb3e150cc0 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Apr 2024 12:49:30 +0500 Subject: [PATCH 812/936] Modem: Implement `A/` (repeat last command) --- src/network/net_modem.c | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 82810f97c..d0cd636ce 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -74,6 +74,8 @@ typedef enum modem_slip_stage_t MODEM_SLIP_STAGE_USERNAME, MODEM_SLIP_STAGE_PASSWORD } modem_slip_stage_t; + +#define COMMAND_BUFFER_SIZE 512 #define NUMBER_BUFFER_SIZE 128 #define PHONEBOOK_SIZE 200 @@ -104,7 +106,8 @@ typedef struct modem_t Fifo8 data_pending; /* Data yet to be sent to the host. */ - char cmdbuf[512]; + char cmdbuf[COMMAND_BUFFER_SIZE]; + char prevcmdbuf[COMMAND_BUFFER_SIZE]; char numberinprogress[NUMBER_BUFFER_SIZE]; char lastnumber[NUMBER_BUFFER_SIZE]; uint32_t cmdpos; @@ -155,7 +158,7 @@ typedef struct modem_t #define MREG_GUARD_TIME 12 #define MREG_DTR_DELAY 25 -static void modem_do_command(modem_t* modem); +static void modem_do_command(modem_t* modem, int repeat); static void modem_accept_incoming_call(modem_t* modem); extern ssize_t local_getline(char **buf, size_t *bufsiz, FILE *fp); @@ -454,8 +457,15 @@ modem_write(UNUSED(serial_t *s), void *priv, uint8_t txval) } if (modem->cmdpos == 1 && toupper(txval) != 'T') { - modem_echo(modem, modem->reg[MREG_BACKSPACE_CHAR]); - modem->cmdpos = 0; + if (txval == '/') { + // Repeat the last command. + modem_echo(modem, txval); + pclog("Repeat last command (%s)\n", modem->prevcmdbuf); + modem_do_command(modem, 1); + } else { + modem_echo(modem, modem->reg[MREG_BACKSPACE_CHAR]); + modem->cmdpos = 0; + } return; } } else { @@ -474,7 +484,7 @@ modem_write(UNUSED(serial_t *s), void *priv, uint8_t txval) if (txval == modem->reg[MREG_CR_CHAR]) { modem_echo(modem, txval); - modem_do_command(modem); + modem_do_command(modem, 0); return; } } @@ -601,6 +611,7 @@ modem_reset(modem_t* modem) modem_enter_idle_state(modem); modem->cmdpos = 0; modem->cmdbuf[0] = 0; + modem->prevcmdbuf[0] = 0; modem->lastnumber[0] = 0; modem->numberinprogress[0] = 0; modem->flowcontrol = 0; @@ -692,11 +703,26 @@ static const char *modem_get_address_from_phonebook(modem_t* modem, const char * } static void -modem_do_command(modem_t* modem) +modem_do_command(modem_t* modem, int repeat) { int i = 0; char *scanbuf = NULL; - modem->cmdbuf[modem->cmdpos] = 0; + + if (repeat) { + /* Handle the case of A/ being invoked without a previous command to run */ + if ((modem->prevcmdbuf[0] == '\0')) { + modem_send_res(modem, ResOK); + return; + } + /* Load the stored previous command line */ + strncpy(modem->cmdbuf, modem->prevcmdbuf, sizeof(modem->cmdbuf) - 1); + modem->cmdbuf[COMMAND_BUFFER_SIZE - 1] = '\0'; + } else { + /* Store the command line to be recalled */ + strncpy(modem->prevcmdbuf, modem->cmdbuf, sizeof(modem->prevcmdbuf) - 1); + modem->prevcmdbuf[COMMAND_BUFFER_SIZE - 1] = '\0'; + modem->cmdbuf[modem->cmdpos] = modem->prevcmdbuf[modem->cmdpos] = '\0'; + } modem->cmdpos = 0; for (i = 0; i < sizeof(modem->cmdbuf); i++) { modem->cmdbuf[i] = toupper(modem->cmdbuf[i]); From 93f7705c83fa68f74a061d7ab192a5cfa59b466a Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Apr 2024 12:50:23 +0500 Subject: [PATCH 813/936] Modem: Extra logging and misc improvements --- src/network/net_modem.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index d0cd636ce..6554bda0c 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -35,6 +35,7 @@ #include <86box/serial.h> #include <86box/plat.h> #include <86box/network.h> +#include <86box/version.h> #include <86box/plat_unused.h> #include <86box/plat_netsocket.h> @@ -523,6 +524,7 @@ void modem_send_res(modem_t* modem, const ResTypes response) { response == ResCONNECT || response == ResNOCARRIER)) { return; } + pclog("Modem response: %s\n", response_str); if (modem->numericresponse && code != ~0) { modem_send_number(modem, code); } else if (response_str != NULL) { @@ -651,6 +653,8 @@ modem_dial(modem_t* modem, const char* str) char buf[NUMBER_BUFFER_SIZE] = ""; strncpy(buf, str, sizeof(buf) - 1); strncpy(modem->lastnumber, str, sizeof(modem->lastnumber) - 1); + pclog("Connecting to %s...\n", buf); + // Scan host for port uint16_t port; char * hasport = strrchr(buf,':'); @@ -800,6 +804,7 @@ modem_do_command(modem_t* modem, int repeat) foundstr = modem->numberinprogress; } + pclog("Dialing number %s\n", foundstr); mappedaddr = modem_get_address_from_phonebook(modem, foundstr); if (mappedaddr) { modem_dial(modem, mappedaddr); @@ -858,7 +863,7 @@ modem_do_command(modem_t* modem, int repeat) case 'I': // Some strings about firmware switch (modem_scan_number(&scanbuf)) { case 3: modem_send_line(modem, "86Box Emulated Modem Firmware V1.00"); break; - case 4: modem_send_line(modem, "Modem compiled for 86Box"); break; + case 4: modem_send_line(modem, "Modem compiled for 86Box version " EMU_VERSION); break; } break; case 'E': // Echo on/off @@ -902,6 +907,8 @@ modem_do_command(modem_t* modem, int repeat) break; case 'M': // Monitor case 'L': // Volume + case 'W': + case 'X': modem_scan_number(&scanbuf); break; case 'A': // Answer call @@ -1039,13 +1046,16 @@ modem_dtr_callback_timer(void* priv) if (dev->connected) { switch (dev->dtrmode) { case 1: + pclog("DTR dropped, returning to command mode (dtrmode = %i)\n", dev->dtrmode); dev->mode = MODEM_MODE_COMMAND; break; case 2: + pclog("DTR dropped, hanging up (dtrmode = %i)\n", dev->dtrmode); modem_send_res(dev, ResNOCARRIER); modem_enter_idle_state(dev); break; case 3: + pclog("DTR dropped, resetting modem (dtrmode = %i)\n", dev->dtrmode); modem_send_res(dev, ResNOCARRIER); modem_reset(dev); break; @@ -1388,6 +1398,7 @@ modem_cmdpause_timer_callback(void *priv) if (modem->plusinc == 0) { modem->plusinc = 1; } else if (modem->plusinc == 4) { + pclog("Escape sequence triggered, returning to command mode\n"); modem->mode = MODEM_MODE_COMMAND; modem_send_res(modem, ResOK); modem->plusinc = 0; From 9a8bc1ab080899887e9a70463fff2a4dc64d4a9c Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Apr 2024 13:08:52 +0500 Subject: [PATCH 814/936] Modem: Disable most logging by default --- src/network/net_modem.c | 60 +++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 6554bda0c..b1acbb5ce 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -39,6 +39,24 @@ #include <86box/plat_unused.h> #include <86box/plat_netsocket.h> +#ifdef ENABLE_MODEM_LOG +int modem_do_log = ENABLE_MODEM_LOG; + +static void +modem_log(const char *fmt, ...) +{ + va_list ap; + + if (modem_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define modem_log(fmt, ...) +#endif + /* From RFC 1055. */ #define END 0300 /* indicates end of packet */ #define ESC 0333 /* indicates byte stuffing */ @@ -217,7 +235,7 @@ modem_read_phonebook_file(modem_t* modem, const char* path) modem->entries_num = 0; - pclog("Phonebook: Reading file %s...\n", path); + modem_log("Modem: Reading phone book file %s...\n", path); while (local_getline(&buf, &size, file) != -1) { modem_phonebook_entry_t entry = { { 0 }, { 0 } }; buf[strcspn(buf, "\r\n")] = '\0'; @@ -237,17 +255,17 @@ modem_read_phonebook_file(modem_t* modem, const char* path) if ((entry.phone[0] == '\0') || (entry.address[0] == '\0')) { /* Appears to be a bad line. */ - pclog("Phonebook: Skipped a bad line\n"); + modem_log("Modem: Skipped a bad line\n"); continue; } if (strspn(entry.phone, "01234567890*=,;#+>") != strlen(entry.phone)) { /* Invalid characters. */ - pclog("Phonebook: Invalid character in phone number %s\n", entry.phone); + modem_log("Modem: Invalid character in phone number %s\n", entry.phone); continue; } - pclog("Phonebook: Mapped phone number %s to address %s\n", entry.phone, entry.address); + modem_log("Modem: Mapped phone number %s to address %s\n", entry.phone, entry.address); modem->entries[modem->entries_num++] = entry; if (modem->entries_num >= PHONEBOOK_SIZE) break; @@ -338,7 +356,7 @@ process_tx_packet(modem_t *modem, uint8_t *p, uint32_t len) uint8_t *processed_tx_packet = calloc(len, 1); uint8_t c = 0; - pclog("Processing SLIP packet of %u bytes\n", len); + modem_log("Processing SLIP packet of %u bytes\n", len); while (pos < len) { c = p[pos]; @@ -461,7 +479,7 @@ modem_write(UNUSED(serial_t *s), void *priv, uint8_t txval) if (txval == '/') { // Repeat the last command. modem_echo(modem, txval); - pclog("Repeat last command (%s)\n", modem->prevcmdbuf); + modem_log("Repeat last command (%s)\n", modem->prevcmdbuf); modem_do_command(modem, 1); } else { modem_echo(modem, modem->reg[MREG_BACKSPACE_CHAR]); @@ -524,7 +542,7 @@ void modem_send_res(modem_t* modem, const ResTypes response) { response == ResCONNECT || response == ResNOCARRIER)) { return; } - pclog("Modem response: %s\n", response_str); + modem_log("Modem response: %s\n", response_str); if (modem->numericresponse && code != ~0) { modem_send_number(modem, code); } else if (response_str != NULL) { @@ -643,7 +661,7 @@ modem_dial(modem_t* modem, const char* str) modem->tcpIpMode = false; if (!strncmp(str, "0.0.0.0", sizeof("0.0.0.0") - 1)) { - pclog("Turning on SLIP\n"); + modem_log("Turning on SLIP\n"); modem_enter_connected_state(modem); modem->numberinprogress[0] = 0; modem->tcpIpMode = false; @@ -653,7 +671,7 @@ modem_dial(modem_t* modem, const char* str) char buf[NUMBER_BUFFER_SIZE] = ""; strncpy(buf, str, sizeof(buf) - 1); strncpy(modem->lastnumber, str, sizeof(modem->lastnumber) - 1); - pclog("Connecting to %s...\n", buf); + modem_log("Connecting to %s...\n", buf); // Scan host for port uint16_t port; @@ -738,7 +756,7 @@ modem_do_command(modem_t* modem, int repeat) return; } - pclog("Command received: %s (doresponse = %d)\n", modem->cmdbuf, modem->doresponse); + modem_log("Command received: %s (doresponse = %d)\n", modem->cmdbuf, modem->doresponse); scanbuf = &modem->cmdbuf[2]; @@ -777,7 +795,7 @@ modem_do_command(modem_t* modem, int repeat) if (modem->lastnumber[0] == 0) modem_send_res(modem, ResERROR); else { - pclog("Redialing number %s\n", modem->lastnumber); + modem_log("Redialing number %s\n", modem->lastnumber); modem_dial(modem, modem->lastnumber); } return; @@ -795,7 +813,7 @@ modem_do_command(modem_t* modem, int repeat) // Check for ; and return to command mode if found char *semicolon = strchr(foundstr, ';'); if (semicolon != NULL) { - pclog("Semicolon found in number, returning to command mode\n"); + modem_log("Semicolon found in number, returning to command mode\n"); strncat(modem->numberinprogress, foundstr, strcspn(foundstr, ";")); scanbuf = semicolon + 1; break; @@ -804,7 +822,7 @@ modem_do_command(modem_t* modem, int repeat) foundstr = modem->numberinprogress; } - pclog("Dialing number %s\n", foundstr); + modem_log("Dialing number %s\n", foundstr); mappedaddr = modem_get_address_from_phonebook(modem, foundstr); if (mappedaddr) { modem_dial(modem, mappedaddr); @@ -1046,16 +1064,16 @@ modem_dtr_callback_timer(void* priv) if (dev->connected) { switch (dev->dtrmode) { case 1: - pclog("DTR dropped, returning to command mode (dtrmode = %i)\n", dev->dtrmode); + modem_log("DTR dropped, returning to command mode (dtrmode = %i)\n", dev->dtrmode); dev->mode = MODEM_MODE_COMMAND; break; case 2: - pclog("DTR dropped, hanging up (dtrmode = %i)\n", dev->dtrmode); + modem_log("DTR dropped, hanging up (dtrmode = %i)\n", dev->dtrmode); modem_send_res(dev, ResNOCARRIER); modem_enter_idle_state(dev); break; case 3: - pclog("DTR dropped, resetting modem (dtrmode = %i)\n", dev->dtrmode); + modem_log("DTR dropped, resetting modem (dtrmode = %i)\n", dev->dtrmode); modem_send_res(dev, ResNOCARRIER); modem_reset(dev); break; @@ -1211,7 +1229,7 @@ modem_rx(void *priv, uint8_t *buf, int io_len) if (!modem->connected) { /* Drop packet. */ - pclog("Dropping %d bytes\n", io_len - 14); + modem_log("Dropping %d bytes\n", io_len - 14); return 0; } @@ -1220,11 +1238,11 @@ modem_rx(void *priv, uint8_t *buf, int io_len) } if (!(buf[12] == 0x08 && buf[13] == 0x00)) { - pclog("Dropping %d bytes (non-IP packet (ethtype 0x%02X%02X))\n", io_len - 14, buf[12], buf[13]); + modem_log("Dropping %d bytes (non-IP packet (ethtype 0x%02X%02X))\n", io_len - 14, buf[12], buf[13]); return 0; } - pclog("Receiving %d bytes\n", io_len - 14); + modem_log("Receiving %d bytes\n", io_len - 14); /* Strip the Ethernet header. */ io_len -= 14; buf += 14; @@ -1398,7 +1416,7 @@ modem_cmdpause_timer_callback(void *priv) if (modem->plusinc == 0) { modem->plusinc = 1; } else if (modem->plusinc == 4) { - pclog("Escape sequence triggered, returning to command mode\n"); + modem_log("Escape sequence triggered, returning to command mode\n"); modem->mode = MODEM_MODE_COMMAND; modem_send_res(modem, ResOK); modem->plusinc = 0; @@ -1453,6 +1471,7 @@ void modem_close(void *priv) free(priv); } +// clang-format off static const device_config_t modem_config[] = { { .name = "port", @@ -1522,6 +1541,7 @@ static const device_config_t modem_config[] = { }, { .name = "", .description = "", .type = CONFIG_END } }; +// clang-format on const device_t modem_device = { .name = "Standard Hayes-compliant Modem", From 0a1e92e239be366c2833470e2c6c11f631d9e2a1 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Apr 2024 13:13:19 +0500 Subject: [PATCH 815/936] clang-format modem and serial passthrough related files --- src/device/serial_passthrough.c | 12 +- src/include/86box/plat_netsocket.h | 19 +- src/network/net_modem.c | 1352 +++++++++++++++------------- src/qt/win_netsocket.c | 84 +- src/qt/win_serial_passthrough.c | 2 +- src/unix/unix_netsocket.c | 94 +- src/unix/unix_serial_passthrough.c | 2 +- 7 files changed, 814 insertions(+), 751 deletions(-) diff --git a/src/device/serial_passthrough.c b/src/device/serial_passthrough.c index 1b1c5e3bf..eec9fa62a 100644 --- a/src/device/serial_passthrough.c +++ b/src/device/serial_passthrough.c @@ -370,12 +370,12 @@ static const device_config_t serial_passthrough_config[] = { // clang-format on const device_t serial_passthrough_device = { - .name = "Serial Passthrough Device", - .flags = 0, - .local = 0, - .init = serial_passthrough_dev_init, - .close = serial_passthrough_dev_close, - .reset = NULL, + .name = "Serial Passthrough Device", + .flags = 0, + .local = 0, + .init = serial_passthrough_dev_init, + .close = serial_passthrough_dev_close, + .reset = NULL, { .poll = NULL }, .speed_changed = serial_passthrough_speed_changed, .force_redraw = NULL, diff --git a/src/include/86box/plat_netsocket.h b/src/include/86box/plat_netsocket.h index 9a2181ae1..c994ef9b9 100644 --- a/src/include/86box/plat_netsocket.h +++ b/src/include/86box/plat_netsocket.h @@ -1,24 +1,23 @@ #ifndef _WIN32 -#define SOCKET int +# define SOCKET int #else -#include -#include +# include +# include #endif -enum net_socket_types -{ +enum net_socket_types { /* Only TCP is supported for now. */ NET_SOCKET_TCP }; SOCKET plat_netsocket_create(int type); SOCKET plat_netsocket_create_server(int type, unsigned short port); -void plat_netsocket_close(SOCKET socket); +void plat_netsocket_close(SOCKET socket); SOCKET plat_netsocket_accept(SOCKET socket); -int plat_netsocket_connected(SOCKET socket); /* Returns -1 on trouble. */ -int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short port); +int plat_netsocket_connected(SOCKET socket); /* Returns -1 on trouble. */ +int plat_netsocket_connect(SOCKET socket, const char *hostname, unsigned short port); /* Returns 0 in case of inability to send. -1 in case of errors. */ -int plat_netsocket_send(SOCKET socket, const unsigned char* data, unsigned int size, int *wouldblock); -int plat_netsocket_receive(SOCKET socket, unsigned char* data, unsigned int size, int *wouldblock); \ No newline at end of file +int plat_netsocket_send(SOCKET socket, const unsigned char *data, unsigned int size, int *wouldblock); +int plat_netsocket_receive(SOCKET socket, unsigned char *data, unsigned int size, int *wouldblock); diff --git a/src/network/net_modem.c b/src/network/net_modem.c index b1acbb5ce..0555978af 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -58,89 +58,84 @@ modem_log(const char *fmt, ...) #endif /* From RFC 1055. */ -#define END 0300 /* indicates end of packet */ -#define ESC 0333 /* indicates byte stuffing */ -#define ESC_END 0334 /* ESC ESC_END means END data byte */ -#define ESC_ESC 0335 /* ESC ESC_ESC means ESC data byte */ +#define END 0300 /* indicates end of packet */ +#define ESC 0333 /* indicates byte stuffing */ +#define ESC_END 0334 /* ESC ESC_END means END data byte */ +#define ESC_ESC 0335 /* ESC ESC_ESC means ESC data byte */ typedef enum ResTypes { - ResNONE, - ResOK, - ResERROR, - ResCONNECT, - ResRING, - ResBUSY, - ResNODIALTONE, - ResNOCARRIER, - ResNOANSWER + ResNONE, + ResOK, + ResERROR, + ResCONNECT, + ResRING, + ResBUSY, + ResNODIALTONE, + ResNOCARRIER, + ResNOANSWER } ResTypes; -enum modem_types -{ +enum modem_types { MODEM_TYPE_SLIP = 1, MODEM_TYPE_PPP = 2, MODEM_TYPE_TCPIP = 3 }; -typedef enum modem_mode_t -{ +typedef enum modem_mode_t { MODEM_MODE_COMMAND = 0, - MODEM_MODE_DATA = 1 + MODEM_MODE_DATA = 1 } modem_mode_t; -typedef enum modem_slip_stage_t -{ +typedef enum modem_slip_stage_t { MODEM_SLIP_STAGE_USERNAME, MODEM_SLIP_STAGE_PASSWORD } modem_slip_stage_t; #define COMMAND_BUFFER_SIZE 512 -#define NUMBER_BUFFER_SIZE 128 -#define PHONEBOOK_SIZE 200 +#define NUMBER_BUFFER_SIZE 128 +#define PHONEBOOK_SIZE 200 -typedef struct modem_phonebook_entry_t -{ +typedef struct modem_phonebook_entry_t { char phone[NUMBER_BUFFER_SIZE]; char address[NUMBER_BUFFER_SIZE]; } modem_phonebook_entry_t; -typedef struct modem_t -{ +typedef struct modem_t { uint8_t mac[6]; serial_t *serial; uint32_t baudrate; modem_mode_t mode; - uint8_t esc_character_expected; + uint8_t esc_character_expected; pc_timer_t host_to_serial_timer; pc_timer_t dtr_timer; pc_timer_t cmdpause_timer; - uint8_t tx_pkt_ser_line[0x10000]; /* SLIP-encoded. */ + uint8_t tx_pkt_ser_line[0x10000]; /* SLIP-encoded. */ uint32_t tx_count; - Fifo8 rx_data; /* Data received from the network. */ - uint8_t reg[100]; + Fifo8 rx_data; /* Data received from the network. */ + uint8_t reg[100]; Fifo8 data_pending; /* Data yet to be sent to the host. */ - char cmdbuf[COMMAND_BUFFER_SIZE]; - char prevcmdbuf[COMMAND_BUFFER_SIZE]; - char numberinprogress[NUMBER_BUFFER_SIZE]; - char lastnumber[NUMBER_BUFFER_SIZE]; - uint32_t cmdpos; + char cmdbuf[COMMAND_BUFFER_SIZE]; + char prevcmdbuf[COMMAND_BUFFER_SIZE]; + char numberinprogress[NUMBER_BUFFER_SIZE]; + char lastnumber[NUMBER_BUFFER_SIZE]; + uint32_t cmdpos; uint32_t port; - int plusinc, flowcontrol; - int in_warmup, dtrmode; - int dcdmode; + int plusinc, flowcontrol; + int in_warmup, dtrmode; + int dcdmode; - bool connected, ringing; - bool echo, numericresponse; - bool tcpIpMode, tcpIpConnInProgress; - bool cooldown; - bool telnet_mode; - bool dtrstate; + bool connected, ringing; + bool echo, numericresponse; + bool tcpIpMode, tcpIpConnInProgress; + bool cooldown; + bool telnet_mode; + bool dtrstate; uint32_t tcpIpConnCounter; int doresponse; @@ -153,82 +148,89 @@ typedef struct modem_t SOCKET waitingclientsocket; struct { - bool binary[2]; - bool echo[2]; - bool supressGA[2]; - bool timingMark[2]; - bool inIAC; - bool recCommand; - uint8_t command; - } telClient; + bool binary[2]; + bool echo[2]; + bool supressGA[2]; + bool timingMark[2]; + bool inIAC; + bool recCommand; + uint8_t command; + } telClient; modem_phonebook_entry_t entries[PHONEBOOK_SIZE]; - uint32_t entries_num; - + uint32_t entries_num; + netcard_t *card; } modem_t; #define MREG_AUTOANSWER_COUNT 0 -#define MREG_RING_COUNT 1 -#define MREG_ESCAPE_CHAR 2 -#define MREG_CR_CHAR 3 -#define MREG_LF_CHAR 4 -#define MREG_BACKSPACE_CHAR 5 -#define MREG_GUARD_TIME 12 -#define MREG_DTR_DELAY 25 +#define MREG_RING_COUNT 1 +#define MREG_ESCAPE_CHAR 2 +#define MREG_CR_CHAR 3 +#define MREG_LF_CHAR 4 +#define MREG_BACKSPACE_CHAR 5 +#define MREG_GUARD_TIME 12 +#define MREG_DTR_DELAY 25 -static void modem_do_command(modem_t* modem, int repeat); -static void modem_accept_incoming_call(modem_t* modem); +static void modem_do_command(modem_t *modem, int repeat); +static void modem_accept_incoming_call(modem_t *modem); extern ssize_t local_getline(char **buf, size_t *bufsiz, FILE *fp); // https://stackoverflow.com/a/122974 -char *trim(char *str) +char * +trim(char *str) { - size_t len = 0; - char *frontp = str; - char *endp = NULL; + size_t len = 0; + char *frontp = str; + char *endp = NULL; - if( str == NULL ) { return NULL; } - if( str[0] == '\0' ) { return str; } + if (str == NULL) { + return NULL; + } + if (str[0] == '\0') { + return str; + } - len = strlen(str); + len = strlen(str); endp = str + len; /* Move the front and back pointers to address the first non-whitespace * characters from each end. */ - while( isspace((unsigned char) *frontp) ) { ++frontp; } - if( endp != frontp ) - { - while( isspace((unsigned char) *(--endp)) && endp != frontp ) {} + while (isspace((unsigned char) *frontp)) { + ++frontp; + } + if (endp != frontp) { + while (isspace((unsigned char) *(--endp)) && endp != frontp) { } } - if( frontp != str && endp == frontp ) - *str = '\0'; - else if( str + len - 1 != endp ) - *(endp + 1) = '\0'; + if (frontp != str && endp == frontp) + *str = '\0'; + else if (str + len - 1 != endp) + *(endp + 1) = '\0'; /* Shift the string so that it starts at str so that if it's dynamically * allocated, we can still free it on the returned pointer. Note the reuse * of endp to mean the front of the string buffer now. */ endp = str; - if( frontp != str ) - { - while( *frontp ) { *endp++ = *frontp++; } - *endp = '\0'; + if (frontp != str) { + while (*frontp) { + *endp++ = *frontp++; + } + *endp = '\0'; } return str; } static void -modem_read_phonebook_file(modem_t* modem, const char* path) +modem_read_phonebook_file(modem_t *modem, const char *path) { - FILE* file = plat_fopen(path, "r"); - char* buf = NULL; - char* buf2 = NULL; + FILE *file = plat_fopen(path, "r"); + char *buf = NULL; + char *buf2 = NULL; size_t size = 0; if (!file) return; @@ -238,14 +240,14 @@ modem_read_phonebook_file(modem_t* modem, const char* path) modem_log("Modem: Reading phone book file %s...\n", path); while (local_getline(&buf, &size, file) != -1) { modem_phonebook_entry_t entry = { { 0 }, { 0 } }; - buf[strcspn(buf, "\r\n")] = '\0'; + buf[strcspn(buf, "\r\n")] = '\0'; /* Remove surrounding whitespace from the input line and find the address part. */ - buf = trim(buf); + buf = trim(buf); buf2 = &buf[strcspn(buf, " \t")]; /* Remove surrounding whitespace and any extra text from the address part, then store it. */ - buf2 = trim(buf2); + buf2 = trim(buf2); buf2[strcspn(buf2, " \t")] = '\0'; strncpy(entry.address, buf2, sizeof(entry.address) - 1); @@ -264,7 +266,7 @@ modem_read_phonebook_file(modem_t* modem, const char* path) modem_log("Modem: Invalid character in phone number %s\n", entry.phone); continue; } - + modem_log("Modem: Mapped phone number %s to address %s\n", entry.phone, entry.address); modem->entries[modem->entries_num++] = entry; if (modem->entries_num >= PHONEBOOK_SIZE) @@ -274,36 +276,37 @@ modem_read_phonebook_file(modem_t* modem, const char* path) } static void -modem_echo(modem_t* modem, uint8_t c) +modem_echo(modem_t *modem, uint8_t c) { - if (modem->echo && fifo8_num_free(&modem->data_pending)) fifo8_push(&modem->data_pending, c); + if (modem->echo && fifo8_num_free(&modem->data_pending)) + fifo8_push(&modem->data_pending, c); } static uint32_t modem_scan_number(char **scan) { - char c = 0; - uint32_t ret = 0; - while (1) { + char c = 0; + uint32_t ret = 0; + while (1) { c = **scan; if (c == 0) break; - if (c >= '0' && c <= '9') { - ret*=10; - ret+=c-'0'; - *scan = *scan + 1; - } else - break; - } - return ret; + if (c >= '0' && c <= '9') { + ret *= 10; + ret += c - '0'; + *scan = *scan + 1; + } else + break; + } + return ret; } static uint8_t modem_fetch_character(char **scan) { uint8_t c = **scan; - *scan = *scan + 1; - return c; + *scan = *scan + 1; + return c; } static void @@ -315,37 +318,36 @@ modem_speed_changed(void *priv) timer_stop(&dev->host_to_serial_timer); /* FIXME: do something to dev->baudrate */ - timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / (double)dev->baudrate) * 9); + timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / (double) dev->baudrate) * 9); #if 0 serial_clear_fifo(dev->serial); #endif } static void -modem_send_line(modem_t* modem, const char* line) +modem_send_line(modem_t *modem, const char *line) { fifo8_push(&modem->data_pending, modem->reg[MREG_CR_CHAR]); fifo8_push(&modem->data_pending, modem->reg[MREG_LF_CHAR]); - fifo8_push_all(&modem->data_pending, (uint8_t*)line, strlen(line)); + fifo8_push_all(&modem->data_pending, (uint8_t *) line, strlen(line)); fifo8_push(&modem->data_pending, modem->reg[MREG_CR_CHAR]); fifo8_push(&modem->data_pending, modem->reg[MREG_LF_CHAR]); } - static void -modem_send_number(modem_t* modem, uint32_t val) +modem_send_number(modem_t *modem, uint32_t val) { - fifo8_push(&modem->data_pending, modem->reg[MREG_CR_CHAR]); - fifo8_push(&modem->data_pending, modem->reg[MREG_LF_CHAR]); + fifo8_push(&modem->data_pending, modem->reg[MREG_CR_CHAR]); + fifo8_push(&modem->data_pending, modem->reg[MREG_LF_CHAR]); - fifo8_push(&modem->data_pending, val / 100 + '0'); - val = val%100; - fifo8_push(&modem->data_pending, val / 10 + '0'); - val = val%10; - fifo8_push(&modem->data_pending, val + '0'); + fifo8_push(&modem->data_pending, val / 100 + '0'); + val = val % 100; + fifo8_push(&modem->data_pending, val / 10 + '0'); + val = val % 10; + fifo8_push(&modem->data_pending, val + '0'); - fifo8_push(&modem->data_pending, modem->reg[MREG_CR_CHAR]); - fifo8_push(&modem->data_pending, modem->reg[MREG_LF_CHAR]); + fifo8_push(&modem->data_pending, modem->reg[MREG_CR_CHAR]); + fifo8_push(&modem->data_pending, modem->reg[MREG_LF_CHAR]); } static void @@ -391,13 +393,12 @@ process_tx_packet(modem_t *modem, uint8_t *p, uint32_t len) } send_tx_packet: - if (received) - { - uint8_t* buf = calloc(received + 14, 1); + if (received) { + uint8_t *buf = calloc(received + 14, 1); buf[0] = buf[1] = buf[2] = buf[3] = buf[4] = buf[5] = 0xFF; buf[6] = buf[7] = buf[8] = buf[9] = buf[10] = buf[11] = 0xFC; - buf[12] = 0x08; - buf[13] = 0x00; + buf[12] = 0x08; + buf[13] = 0x00; memcpy(buf + 14, processed_tx_packet, received); network_tx(modem->card, buf, received + 14); free(buf); @@ -407,7 +408,7 @@ send_tx_packet: } static void -modem_data_mode_process_byte(modem_t* modem, uint8_t data) +modem_data_mode_process_byte(modem_t *modem, uint8_t data) { if (modem->reg[MREG_ESCAPE_CHAR] <= 127) { if (modem->plusinc >= 1 && modem->plusinc <= 3 && modem->reg[MREG_ESCAPE_CHAR] == data) { @@ -421,7 +422,7 @@ modem_data_mode_process_byte(modem_t* modem, uint8_t data) if (modem->tx_count < 0x10000 && modem->connected) { modem->tx_pkt_ser_line[modem->tx_count++] = data; if (data == END && !modem->tcpIpMode) { - process_tx_packet(modem, modem->tx_pkt_ser_line, (uint32_t)modem->tx_count); + process_tx_packet(modem, modem->tx_pkt_ser_line, (uint32_t) modem->tx_count); modem->tx_count = 0; } } @@ -430,7 +431,7 @@ modem_data_mode_process_byte(modem_t* modem, uint8_t data) static void host_to_modem_cb(void *priv) { - modem_t* modem = (modem_t*)priv; + modem_t *modem = (modem_t *) priv; if (modem->in_warmup) goto no_write_to_machine; @@ -460,143 +461,169 @@ host_to_modem_cb(void *priv) } no_write_to_machine: - timer_on_auto(&modem->host_to_serial_timer, (1000000.0 / (double)modem->baudrate) * (double)9); + timer_on_auto(&modem->host_to_serial_timer, (1000000.0 / (double) modem->baudrate) * (double) 9); } static void modem_write(UNUSED(serial_t *s), void *priv, uint8_t txval) { - modem_t* modem = (modem_t*)priv; + modem_t *modem = (modem_t *) priv; if (modem->mode == MODEM_MODE_COMMAND) { if (modem->cmdpos < 2) { - // Ignore everything until we see "AT" sequence. - if (modem->cmdpos == 0 && toupper(txval) != 'A') { - return; - } + // Ignore everything until we see "AT" sequence. + if (modem->cmdpos == 0 && toupper(txval) != 'A') { + return; + } - if (modem->cmdpos == 1 && toupper(txval) != 'T') { - if (txval == '/') { - // Repeat the last command. - modem_echo(modem, txval); - modem_log("Repeat last command (%s)\n", modem->prevcmdbuf); - modem_do_command(modem, 1); - } else { - modem_echo(modem, modem->reg[MREG_BACKSPACE_CHAR]); - modem->cmdpos = 0; - } - return; - } + if (modem->cmdpos == 1 && toupper(txval) != 'T') { + if (txval == '/') { + // Repeat the last command. + modem_echo(modem, txval); + modem_log("Repeat last command (%s)\n", modem->prevcmdbuf); + modem_do_command(modem, 1); + } else { + modem_echo(modem, modem->reg[MREG_BACKSPACE_CHAR]); + modem->cmdpos = 0; + } + return; + } } else { - // Now entering command. - if (txval == modem->reg[MREG_BACKSPACE_CHAR]) { - if (modem->cmdpos > 2) { - modem_echo(modem, txval); - modem->cmdpos--; - } - return; - } + // Now entering command. + if (txval == modem->reg[MREG_BACKSPACE_CHAR]) { + if (modem->cmdpos > 2) { + modem_echo(modem, txval); + modem->cmdpos--; + } + return; + } - if (txval == modem->reg[MREG_LF_CHAR]) { - return; // Real modem doesn't seem to skip this? - } + if (txval == modem->reg[MREG_LF_CHAR]) { + return; // Real modem doesn't seem to skip this? + } - if (txval == modem->reg[MREG_CR_CHAR]) { - modem_echo(modem, txval); - modem_do_command(modem, 0); - return; - } - } + if (txval == modem->reg[MREG_CR_CHAR]) { + modem_echo(modem, txval); + modem_do_command(modem, 0); + return; + } + } if (modem->cmdpos < 99) { - modem_echo(modem, txval); - modem->cmdbuf[modem->cmdpos] = txval; - modem->cmdpos++; - } + modem_echo(modem, txval); + modem->cmdbuf[modem->cmdpos] = txval; + modem->cmdpos++; + } } else { modem_data_mode_process_byte(modem, txval); } } -void modem_send_res(modem_t* modem, const ResTypes response) { - char response_str_connect[256] = { 0 }; - const char* response_str = NULL; - uint32_t code = -1; +void +modem_send_res(modem_t *modem, const ResTypes response) +{ + char response_str_connect[256] = { 0 }; + const char *response_str = NULL; + uint32_t code = -1; snprintf(response_str_connect, sizeof(response_str_connect), "CONNECT %u", modem->baudrate); - switch (response) { - case ResOK: code = 0; response_str = "OK"; break; - case ResCONNECT: code = 1; response_str = response_str_connect; break; - case ResRING: code = 2; response_str = "RING"; break; - case ResNOCARRIER: code = 3; response_str = "NO CARRIER"; break; - case ResERROR: code = 4; response_str = "ERROR"; break; - case ResNODIALTONE: code = 6; response_str = "NO DIALTONE"; break; - case ResBUSY: code = 7; response_str = "BUSY"; break; - case ResNOANSWER: code = 8; response_str = "NO ANSWER"; break; - case ResNONE: return; - } + switch (response) { + case ResOK: + code = 0; + response_str = "OK"; + break; + case ResCONNECT: + code = 1; + response_str = response_str_connect; + break; + case ResRING: + code = 2; + response_str = "RING"; + break; + case ResNOCARRIER: + code = 3; + response_str = "NO CARRIER"; + break; + case ResERROR: + code = 4; + response_str = "ERROR"; + break; + case ResNODIALTONE: + code = 6; + response_str = "NO DIALTONE"; + break; + case ResBUSY: + code = 7; + response_str = "BUSY"; + break; + case ResNOANSWER: + code = 8; + response_str = "NO ANSWER"; + break; + case ResNONE: + return; + } - if (modem->doresponse != 1) { - if (modem->doresponse == 2 && (response == ResRING || - response == ResCONNECT || response == ResNOCARRIER)) { - return; - } - modem_log("Modem response: %s\n", response_str); - if (modem->numericresponse && code != ~0) { - modem_send_number(modem, code); - } else if (response_str != NULL) { - modem_send_line(modem, response_str); - } + if (modem->doresponse != 1) { + if (modem->doresponse == 2 && (response == ResRING || response == ResCONNECT || response == ResNOCARRIER)) { + return; + } + modem_log("Modem response: %s\n", response_str); + if (modem->numericresponse && code != ~0) { + modem_send_number(modem, code); + } else if (response_str != NULL) { + modem_send_line(modem, response_str); + } - // if(CSerial::CanReceiveByte()) // very fast response - // if(rqueue->inuse() && CSerial::getRTS()) - // { uint8_t rbyte =rqueue->getb(); - // CSerial::receiveByte(rbyte); - // LOG_MSG("SERIAL: Port %" PRIu8 " modem sending byte %2x back to UART2", - // GetPortNumber(), rbyte); - // } - } + // if(CSerial::CanReceiveByte()) // very fast response + // if(rqueue->inuse() && CSerial::getRTS()) + // { uint8_t rbyte =rqueue->getb(); + // CSerial::receiveByte(rbyte); + // LOG_MSG("SERIAL: Port %" PRIu8 " modem sending byte %2x back to UART2", + // GetPortNumber(), rbyte); + // } + } } void -modem_enter_idle_state(modem_t* modem) +modem_enter_idle_state(modem_t *modem) { timer_disable(&modem->dtr_timer); - modem->connected = false; - modem->ringing = false; - modem->mode = MODEM_MODE_COMMAND; - modem->in_warmup = 0; + modem->connected = false; + modem->ringing = false; + modem->mode = MODEM_MODE_COMMAND; + modem->in_warmup = 0; modem->tcpIpConnInProgress = 0; - modem->tcpIpConnCounter = 0; + modem->tcpIpConnCounter = 0; - if (modem->waitingclientsocket != (SOCKET)-1) + if (modem->waitingclientsocket != (SOCKET) -1) plat_netsocket_close(modem->waitingclientsocket); - - if (modem->clientsocket != (SOCKET)-1) + + if (modem->clientsocket != (SOCKET) -1) plat_netsocket_close(modem->clientsocket); - modem->clientsocket = modem->waitingclientsocket = (SOCKET)-1; - if (modem->serversocket != (SOCKET)-1) { + modem->clientsocket = modem->waitingclientsocket = (SOCKET) -1; + if (modem->serversocket != (SOCKET) -1) { modem->waitingclientsocket = plat_netsocket_accept(modem->serversocket); - while (modem->waitingclientsocket != (SOCKET)-1) { + while (modem->waitingclientsocket != (SOCKET) -1) { plat_netsocket_close(modem->waitingclientsocket); modem->waitingclientsocket = plat_netsocket_accept(modem->serversocket); } plat_netsocket_close(modem->serversocket); - modem->serversocket = (SOCKET)-1; + modem->serversocket = (SOCKET) -1; } - if (modem->waitingclientsocket != (SOCKET)-1) + if (modem->waitingclientsocket != (SOCKET) -1) plat_netsocket_close(modem->waitingclientsocket); - modem->waitingclientsocket = (SOCKET)-1; - modem->tcpIpMode = false; + modem->waitingclientsocket = (SOCKET) -1; + modem->tcpIpMode = false; modem->tcpIpConnInProgress = false; if (modem->listen_port) { modem->serversocket = plat_netsocket_create_server(NET_SOCKET_TCP, modem->listen_port); - if (modem->serversocket == (SOCKET)-1) { + if (modem->serversocket == (SOCKET) -1) { pclog("Failed to set up server on port %d\n", modem->listen_port); } } @@ -608,15 +635,15 @@ modem_enter_idle_state(modem_t* modem) } void -modem_enter_connected_state(modem_t* modem) +modem_enter_connected_state(modem_t *modem) { modem_send_res(modem, ResCONNECT); - modem->mode = MODEM_MODE_DATA; - modem->ringing = false; + modem->mode = MODEM_MODE_DATA; + modem->ringing = false; modem->connected = true; modem->tcpIpMode = true; - modem->cooldown = true; - modem->tx_count = 0; + modem->cooldown = true; + modem->tx_count = 0; plat_netsocket_close(modem->serversocket); modem->serversocket = -1; memset(&modem->telClient, 0, sizeof(modem->telClient)); @@ -625,49 +652,46 @@ modem_enter_connected_state(modem_t* modem) } void -modem_reset(modem_t* modem) +modem_reset(modem_t *modem) { modem->dcdmode = 1; modem_enter_idle_state(modem); - modem->cmdpos = 0; - modem->cmdbuf[0] = 0; - modem->prevcmdbuf[0] = 0; - modem->lastnumber[0] = 0; + modem->cmdpos = 0; + modem->cmdbuf[0] = 0; + modem->prevcmdbuf[0] = 0; + modem->lastnumber[0] = 0; modem->numberinprogress[0] = 0; - modem->flowcontrol = 0; - modem->cmdpause = 0; - modem->plusinc = 0; - modem->dtrmode = 2; + modem->flowcontrol = 0; + modem->cmdpause = 0; + modem->plusinc = 0; + modem->dtrmode = 2; - memset(&modem->reg,0,sizeof(modem->reg)); - modem->reg[MREG_AUTOANSWER_COUNT] = 0; // no autoanswer - modem->reg[MREG_RING_COUNT] = 1; - modem->reg[MREG_ESCAPE_CHAR] = '+'; - modem->reg[MREG_CR_CHAR] = '\r'; - modem->reg[MREG_LF_CHAR] = '\n'; - modem->reg[MREG_BACKSPACE_CHAR] = '\b'; - modem->reg[MREG_GUARD_TIME] = 50; - modem->reg[MREG_DTR_DELAY] = 5; + memset(&modem->reg, 0, sizeof(modem->reg)); + modem->reg[MREG_AUTOANSWER_COUNT] = 0; // no autoanswer + modem->reg[MREG_RING_COUNT] = 1; + modem->reg[MREG_ESCAPE_CHAR] = '+'; + modem->reg[MREG_CR_CHAR] = '\r'; + modem->reg[MREG_LF_CHAR] = '\n'; + modem->reg[MREG_BACKSPACE_CHAR] = '\b'; + modem->reg[MREG_GUARD_TIME] = 50; + modem->reg[MREG_DTR_DELAY] = 5; - modem->echo = true; - modem->doresponse = 0; - modem->numericresponse = false; + modem->echo = true; + modem->doresponse = 0; + modem->numericresponse = false; } void -modem_dial(modem_t* modem, const char* str) +modem_dial(modem_t *modem, const char *str) { modem->tcpIpConnCounter = 0; - modem->tcpIpMode = false; - if (!strncmp(str, "0.0.0.0", sizeof("0.0.0.0") - 1)) - { + modem->tcpIpMode = false; + if (!strncmp(str, "0.0.0.0", sizeof("0.0.0.0") - 1)) { modem_log("Turning on SLIP\n"); modem_enter_connected_state(modem); modem->numberinprogress[0] = 0; - modem->tcpIpMode = false; - } - else - { + modem->tcpIpMode = false; + } else { char buf[NUMBER_BUFFER_SIZE] = ""; strncpy(buf, str, sizeof(buf) - 1); strncpy(modem->lastnumber, str, sizeof(modem->lastnumber) - 1); @@ -675,59 +699,60 @@ modem_dial(modem_t* modem, const char* str) // Scan host for port uint16_t port; - char * hasport = strrchr(buf,':'); + char *hasport = strrchr(buf, ':'); if (hasport) { *hasport++ = 0; - port = (uint16_t)atoi(hasport); - } - else { + port = (uint16_t) atoi(hasport); + } else { port = 23; } modem->numberinprogress[0] = 0; - modem->clientsocket = plat_netsocket_create(NET_SOCKET_TCP); + modem->clientsocket = plat_netsocket_create(NET_SOCKET_TCP); if (modem->clientsocket == -1) { pclog("Failed to create client socket\n"); - modem_send_res(modem, ResNOCARRIER); - modem_enter_idle_state(modem); + modem_send_res(modem, ResNOCARRIER); + modem_enter_idle_state(modem); return; } if (-1 == plat_netsocket_connect(modem->clientsocket, buf, port)) { pclog("Failed to connect to %s\n", buf); - modem_send_res(modem, ResNOCARRIER); - modem_enter_idle_state(modem); + modem_send_res(modem, ResNOCARRIER); + modem_enter_idle_state(modem); return; } modem->tcpIpConnInProgress = 1; - modem->tcpIpConnCounter = 0; + modem->tcpIpConnCounter = 0; } } static bool -is_next_token(const char* a, size_t N, const char *b) +is_next_token(const char *a, size_t N, const char *b) { - // Is 'b' at least as long as 'a'? - size_t N_without_null = N - 1; - if (strnlen(b, N) < N_without_null) - return false; - return (strncmp(a, b, N_without_null) == 0); + // Is 'b' at least as long as 'a'? + size_t N_without_null = N - 1; + if (strnlen(b, N) < N_without_null) + return false; + return (strncmp(a, b, N_without_null) == 0); } -static const char *modem_get_address_from_phonebook(modem_t* modem, const char *input) { +static const char * +modem_get_address_from_phonebook(modem_t *modem, const char *input) +{ int i = 0; - for (i = 0; i < modem->entries_num; i++) { - if (strcmp(input, modem->entries[i].phone) == 0) - return modem->entries[i].address; - } + for (i = 0; i < modem->entries_num; i++) { + if (strcmp(input, modem->entries[i].phone) == 0) + return modem->entries[i].address; + } - return NULL; + return NULL; } static void -modem_do_command(modem_t* modem, int repeat) +modem_do_command(modem_t *modem, int repeat) { - int i = 0; + int i = 0; char *scanbuf = NULL; if (repeat) { @@ -750,11 +775,11 @@ modem_do_command(modem_t* modem, int repeat) modem->cmdbuf[i] = toupper(modem->cmdbuf[i]); } - /* AT command set interpretation */ - if ((modem->cmdbuf[0] != 'A') || (modem->cmdbuf[1] != 'T')) { - modem_send_res(modem, ResERROR); - return; - } + /* AT command set interpretation */ + if ((modem->cmdbuf[0] != 'A') || (modem->cmdbuf[1] != 'T')) { + modem_send_res(modem, ResERROR); + return; + } modem_log("Command received: %s (doresponse = %d)\n", modem->cmdbuf, modem->doresponse); @@ -782,142 +807,159 @@ modem_do_command(modem_t* modem, int repeat) } modem_send_res(modem, ResERROR); return; - case 'D': { // Dial. - char buffer[NUMBER_BUFFER_SIZE]; - char obuffer[NUMBER_BUFFER_SIZE]; - char * foundstr = &scanbuf[0]; - const char *mappedaddr = NULL; - size_t i = 0; + case 'D': + { // Dial. + char buffer[NUMBER_BUFFER_SIZE]; + char obuffer[NUMBER_BUFFER_SIZE]; + char *foundstr = &scanbuf[0]; + const char *mappedaddr = NULL; + size_t i = 0; - if (*foundstr == 'T' || *foundstr == 'P') // Tone/pulse dialing - foundstr++; - else if (*foundstr == 'L') { // Redial last number - if (modem->lastnumber[0] == 0) - modem_send_res(modem, ResERROR); - else { - modem_log("Redialing number %s\n", modem->lastnumber); - modem_dial(modem, modem->lastnumber); + if (*foundstr == 'T' || *foundstr == 'P') // Tone/pulse dialing + foundstr++; + else if (*foundstr == 'L') { // Redial last number + if (modem->lastnumber[0] == 0) + modem_send_res(modem, ResERROR); + else { + modem_log("Redialing number %s\n", modem->lastnumber); + modem_dial(modem, modem->lastnumber); + } + return; } - return; - } - if ((!foundstr[0] && !modem->numberinprogress[0]) || ((strlen(modem->numberinprogress) + strlen(foundstr)) > (NUMBER_BUFFER_SIZE - 1))) { - // Check for empty or too long strings - modem_send_res(modem, ResERROR); - modem->numberinprogress[0] = 0; - return; - } - - foundstr = trim(foundstr); - - // Check for ; and return to command mode if found - char *semicolon = strchr(foundstr, ';'); - if (semicolon != NULL) { - modem_log("Semicolon found in number, returning to command mode\n"); - strncat(modem->numberinprogress, foundstr, strcspn(foundstr, ";")); - scanbuf = semicolon + 1; - break; - } else { - strcat(modem->numberinprogress, foundstr); - foundstr = modem->numberinprogress; - } - - modem_log("Dialing number %s\n", foundstr); - mappedaddr = modem_get_address_from_phonebook(modem, foundstr); - if (mappedaddr) { - modem_dial(modem, mappedaddr); - return; - } - - if (strlen(foundstr) >= 12) { - // Check if supplied parameter only consists of digits - bool isNum = true; - size_t fl = strlen(foundstr); - for (i = 0; i < fl; i++) - if (foundstr[i] < '0' || foundstr[i] > '9') - isNum = false; - if (isNum && (fl > (NUMBER_BUFFER_SIZE - 5))) { - // Check if the number is long enough to cause buffer - // overflows during the number => IP transformation + if ((!foundstr[0] && !modem->numberinprogress[0]) || ((strlen(modem->numberinprogress) + strlen(foundstr)) > (NUMBER_BUFFER_SIZE - 1))) { + // Check for empty or too long strings modem_send_res(modem, ResERROR); modem->numberinprogress[0] = 0; return; - } else if (isNum) { - // Parameter is a number with at least 12 digits => this cannot - // be a valid IP/name - // Transform by adding dots - size_t j = 0; - const size_t foundlen = strlen(foundstr); - for (i = 0; i < foundlen; i++) { - buffer[j++] = foundstr[i]; - // Add a dot after the third, sixth and ninth number - if (i == 2 || i == 5 || i == 8) - buffer[j++] = '.'; - // If the string is longer than 12 digits, - // interpret the rest as port - if (i == 11 && foundlen > 12) - buffer[j++] = ':'; - } - buffer[j] = 0; - foundstr = buffer; - - // Remove Zeros from beginning of octets - size_t k = 0; - size_t foundlen2 = strlen(foundstr); - for (i = 0; i < foundlen2; i++) { - if (i == 0 && foundstr[0] == '0') continue; - if (i == 1 && foundstr[0] == '0' && foundstr[1] == '0') continue; - if (foundstr[i] == '0' && foundstr[i-1] == '.') continue; - if (foundstr[i] == '0' && foundstr[i-1] == '0' && foundstr[i-2] == '.') continue; - obuffer[k++] = foundstr[i]; - } - obuffer[k] = 0; - foundstr = obuffer; } + + foundstr = trim(foundstr); + + // Check for ; and return to command mode if found + char *semicolon = strchr(foundstr, ';'); + if (semicolon != NULL) { + modem_log("Semicolon found in number, returning to command mode\n"); + strncat(modem->numberinprogress, foundstr, strcspn(foundstr, ";")); + scanbuf = semicolon + 1; + break; + } else { + strcat(modem->numberinprogress, foundstr); + foundstr = modem->numberinprogress; + } + + modem_log("Dialing number %s\n", foundstr); + mappedaddr = modem_get_address_from_phonebook(modem, foundstr); + if (mappedaddr) { + modem_dial(modem, mappedaddr); + return; + } + + if (strlen(foundstr) >= 12) { + // Check if supplied parameter only consists of digits + bool isNum = true; + size_t fl = strlen(foundstr); + for (i = 0; i < fl; i++) + if (foundstr[i] < '0' || foundstr[i] > '9') + isNum = false; + if (isNum && (fl > (NUMBER_BUFFER_SIZE - 5))) { + // Check if the number is long enough to cause buffer + // overflows during the number => IP transformation + modem_send_res(modem, ResERROR); + modem->numberinprogress[0] = 0; + return; + } else if (isNum) { + // Parameter is a number with at least 12 digits => this cannot + // be a valid IP/name + // Transform by adding dots + size_t j = 0; + const size_t foundlen = strlen(foundstr); + for (i = 0; i < foundlen; i++) { + buffer[j++] = foundstr[i]; + // Add a dot after the third, sixth and ninth number + if (i == 2 || i == 5 || i == 8) + buffer[j++] = '.'; + // If the string is longer than 12 digits, + // interpret the rest as port + if (i == 11 && foundlen > 12) + buffer[j++] = ':'; + } + buffer[j] = 0; + foundstr = buffer; + + // Remove Zeros from beginning of octets + size_t k = 0; + size_t foundlen2 = strlen(foundstr); + for (i = 0; i < foundlen2; i++) { + if (i == 0 && foundstr[0] == '0') + continue; + if (i == 1 && foundstr[0] == '0' && foundstr[1] == '0') + continue; + if (foundstr[i] == '0' && foundstr[i - 1] == '.') + continue; + if (foundstr[i] == '0' && foundstr[i - 1] == '0' && foundstr[i - 2] == '.') + continue; + obuffer[k++] = foundstr[i]; + } + obuffer[k] = 0; + foundstr = obuffer; + } + } + modem_dial(modem, foundstr); + return; } - modem_dial(modem, foundstr); - return; - } case 'I': // Some strings about firmware switch (modem_scan_number(&scanbuf)) { - case 3: modem_send_line(modem, "86Box Emulated Modem Firmware V1.00"); break; - case 4: modem_send_line(modem, "Modem compiled for 86Box version " EMU_VERSION); break; + case 3: + modem_send_line(modem, "86Box Emulated Modem Firmware V1.00"); + break; + case 4: + modem_send_line(modem, "Modem compiled for 86Box version " EMU_VERSION); + break; } break; case 'E': // Echo on/off switch (modem_scan_number(&scanbuf)) { - case 0: modem->echo = false; break; - case 1: modem->echo = true; break; + case 0: + modem->echo = false; + break; + case 1: + modem->echo = true; + break; } break; case 'V': switch (modem_scan_number(&scanbuf)) { - case 0: modem->numericresponse = true; break; - case 1: modem->numericresponse = false; break; + case 0: + modem->numericresponse = true; + break; + case 1: + modem->numericresponse = false; + break; } break; case 'H': // Hang up switch (modem_scan_number(&scanbuf)) { - case 0: - modem->numberinprogress[0] = 0; - if (modem->connected) { - modem_send_res(modem, ResNOCARRIER); - modem_enter_idle_state(modem); - return; - } - // else return ok + case 0: + modem->numberinprogress[0] = 0; + if (modem->connected) { + modem_send_res(modem, ResNOCARRIER); + modem_enter_idle_state(modem); + return; + } + // else return ok } break; case 'O': // Return to data mode switch (modem_scan_number(&scanbuf)) { - case 0: - if (modem->connected) { - modem->mode = MODEM_MODE_DATA; - return; - } else { - modem_send_res(modem, ResERROR); - return; - } + case 0: + if (modem->connected) { + modem->mode = MODEM_MODE_DATA; + return; + } else { + modem_send_res(modem, ResERROR); + return; + } } break; case 'T': // Tone Dial @@ -939,130 +981,137 @@ modem_do_command(modem_t* modem, int repeat) break; } return; - case 'Z': { // Reset and load profiles - // scan the number away, if any - modem_scan_number(&scanbuf); - if (modem->connected) - modem_send_res(modem, ResNOCARRIER); - modem_reset(modem); - break; - } + case 'Z': + { // Reset and load profiles + // scan the number away, if any + modem_scan_number(&scanbuf); + if (modem->connected) + modem_send_res(modem, ResNOCARRIER); + modem_reset(modem); + break; + } case ' ': // skip space break; - case 'Q': { - // Response options - // 0 = all on, 1 = all off, - // 2 = no ring and no connect/carrier in answermode - const uint32_t val = modem_scan_number(&scanbuf); - if (!(val > 2)) { - modem->doresponse = val; - break; - } else { - modem_send_res(modem, ResERROR); - return; + case 'Q': + { + // Response options + // 0 = all on, 1 = all off, + // 2 = no ring and no connect/carrier in answermode + const uint32_t val = modem_scan_number(&scanbuf); + if (!(val > 2)) { + modem->doresponse = val; + break; + } else { + modem_send_res(modem, ResERROR); + return; + } } - } - case 'S': { // Registers - const uint32_t index = modem_scan_number(&scanbuf); - if (index >= 100) { - modem_send_res(modem, ResERROR); - return; //goto ret_none; - } + case 'S': + { // Registers + const uint32_t index = modem_scan_number(&scanbuf); + if (index >= 100) { + modem_send_res(modem, ResERROR); + return; // goto ret_none; + } - while (scanbuf[0] == ' ') - scanbuf++; // skip spaces + while (scanbuf[0] == ' ') + scanbuf++; // skip spaces - if (scanbuf[0] == '=') { // set register - scanbuf++; - while (scanbuf[0] == ' ') - scanbuf++; // skip spaces - const uint32_t val = modem_scan_number(&scanbuf); - modem->reg[index] = val; - break; - } - else if (scanbuf[0] == '?') { // get register - modem_send_number(modem, modem->reg[index]); - scanbuf++; - break; - } - // else - // LOG_MSG("SERIAL: Port %" PRIu8 " print reg %" PRIu32 - // " with %" PRIu8 ".", - // GetPortNumber(), index, reg[index]); - } - break; - case '&': { // & escaped commands - char cmdchar = modem_fetch_character(&scanbuf); - switch(cmdchar) { - case 'C': { - const uint32_t val = modem_scan_number(&scanbuf); - if (val < 2) - modem->dcdmode = val; - else { - modem_send_res(modem, ResERROR); - return; - } - break; - } - case 'K': { - const uint32_t val = modem_scan_number(&scanbuf); - if (val < 5) - modem->flowcontrol = val; - else { - modem_send_res(modem, ResERROR); - return; - } - break; - } - case 'D': { - const uint32_t val = modem_scan_number(&scanbuf); - if (val < 4) - modem->dtrmode = val; - else { - modem_send_res(modem, ResERROR); - return; - } - break; - } - case '\0': - // end of string - modem_send_res(modem, ResERROR); - return; - } - break; - } - break; - case '\\': { // \ escaped commands - char cmdchar = modem_fetch_character(&scanbuf); - switch (cmdchar) { - case 'N': - // error correction stuff - not emulated - if (modem_scan_number(&scanbuf) > 5) { - modem_send_res(modem, ResERROR); - return; - } - break; - case '\0': - // end of string - modem_send_res(modem, ResERROR); - return; - } - break; - } - case '\0': - modem_send_res(modem, ResOK); - return; - } + if (scanbuf[0] == '=') { // set register + scanbuf++; + while (scanbuf[0] == ' ') + scanbuf++; // skip spaces + const uint32_t val = modem_scan_number(&scanbuf); + modem->reg[index] = val; + break; + } else if (scanbuf[0] == '?') { // get register + modem_send_number(modem, modem->reg[index]); + scanbuf++; + break; + } + // else + // LOG_MSG("SERIAL: Port %" PRIu8 " print reg %" PRIu32 + // " with %" PRIu8 ".", + // GetPortNumber(), index, reg[index]); + } + break; + case '&': + { // & escaped commands + char cmdchar = modem_fetch_character(&scanbuf); + switch (cmdchar) { + case 'C': + { + const uint32_t val = modem_scan_number(&scanbuf); + if (val < 2) + modem->dcdmode = val; + else { + modem_send_res(modem, ResERROR); + return; + } + break; + } + case 'K': + { + const uint32_t val = modem_scan_number(&scanbuf); + if (val < 5) + modem->flowcontrol = val; + else { + modem_send_res(modem, ResERROR); + return; + } + break; + } + case 'D': + { + const uint32_t val = modem_scan_number(&scanbuf); + if (val < 4) + modem->dtrmode = val; + else { + modem_send_res(modem, ResERROR); + return; + } + break; + } + case '\0': + // end of string + modem_send_res(modem, ResERROR); + return; + } + break; + } + break; + case '\\': + { // \ escaped commands + char cmdchar = modem_fetch_character(&scanbuf); + switch (cmdchar) { + case 'N': + // error correction stuff - not emulated + if (modem_scan_number(&scanbuf) > 5) { + modem_send_res(modem, ResERROR); + return; + } + break; + case '\0': + // end of string + modem_send_res(modem, ResERROR); + return; + } + break; + } + case '\0': + modem_send_res(modem, ResOK); + return; + } } } void -modem_dtr_callback_timer(void* priv) +modem_dtr_callback_timer(void *priv) { modem_t *dev = (modem_t *) priv; if (dev->connected) { - switch (dev->dtrmode) { + switch (dev->dtrmode) { case 1: modem_log("DTR dropped, returning to command mode (dtrmode = %i)\n", dev->dtrmode); dev->mode = MODEM_MODE_COMMAND; @@ -1082,9 +1131,9 @@ modem_dtr_callback_timer(void* priv) } void -modem_dtr_callback(serial_t* serial, int status, void *priv) +modem_dtr_callback(serial_t *serial, int status, void *priv) { - modem_t *dev = (modem_t *) priv; + modem_t *dev = (modem_t *) priv; dev->dtrstate = !!status; if (status == 1) timer_disable(&dev->dtr_timer); @@ -1093,15 +1142,15 @@ modem_dtr_callback(serial_t* serial, int status, void *priv) } static void -fifo8_resize_2x(Fifo8* fifo) +fifo8_resize_2x(Fifo8 *fifo) { - uint32_t pos = 0; + uint32_t pos = 0; uint32_t size = fifo->capacity * 2; uint32_t used = fifo8_num_used(fifo); if (!used) return; - uint8_t* temp_buf = calloc(fifo->capacity * 2, 1); + uint8_t *temp_buf = calloc(fifo->capacity * 2, 1); if (!temp_buf) { fatal("net_modem: Out Of Memory!\n"); } @@ -1118,111 +1167,117 @@ fifo8_resize_2x(Fifo8* fifo) #define TEL_CLIENT 0 #define TEL_SERVER 1 -void modem_process_telnet(modem_t* modem, uint8_t *data, uint32_t size) +void +modem_process_telnet(modem_t *modem, uint8_t *data, uint32_t size) { uint32_t i = 0; - for (i = 0; i < size; i++) { - uint8_t c = data[i]; - if (modem->telClient.inIAC) { - if (modem->telClient.recCommand) { - if ((c != 0) && (c != 1) && (c != 3)) { - if (modem->telClient.command > 250) { - /* Reject anything we don't recognize */ - modem_data_mode_process_byte(modem, 0xff); - modem_data_mode_process_byte(modem, 252); - modem_data_mode_process_byte(modem, c); /* We won't do crap! */ - } - } - switch (modem->telClient.command) { - case 251: /* Will */ - if (c == 0) modem->telClient.binary[TEL_SERVER] = true; - if (c == 1) modem->telClient.echo[TEL_SERVER] = true; - if (c == 3) modem->telClient.supressGA[TEL_SERVER] = true; - break; - case 252: /* Won't */ - if (c == 0) modem->telClient.binary[TEL_SERVER] = false; - if (c == 1) modem->telClient.echo[TEL_SERVER] = false; - if (c == 3) modem->telClient.supressGA[TEL_SERVER] = false; - break; - case 253: /* Do */ - if (c == 0) { - modem->telClient.binary[TEL_CLIENT] = true; - modem_data_mode_process_byte(modem, 0xff); - modem_data_mode_process_byte(modem, 251); - modem_data_mode_process_byte(modem, 0); /* Will do binary transfer */ - } - if (c == 1) { - modem->telClient.echo[TEL_CLIENT] = false; - modem_data_mode_process_byte(modem, 0xff); - modem_data_mode_process_byte(modem, 252); - modem_data_mode_process_byte(modem, 1); /* Won't echo (too lazy) */ - } - if (c == 3) { - modem->telClient.supressGA[TEL_CLIENT] = true; - modem_data_mode_process_byte(modem, 0xff); - modem_data_mode_process_byte(modem, 251); - modem_data_mode_process_byte(modem, 3); /* Will Suppress GA */ - } - break; - case 254: /* Don't */ - if (c == 0) { - modem->telClient.binary[TEL_CLIENT] = false; - modem_data_mode_process_byte(modem, 0xff); - modem_data_mode_process_byte(modem, 252); - modem_data_mode_process_byte(modem, 0); /* Won't do binary transfer */ - } - if (c == 1) { - modem->telClient.echo[TEL_CLIENT] = false; - modem_data_mode_process_byte(modem, 0xff); - modem_data_mode_process_byte(modem, 252); - modem_data_mode_process_byte(modem, 1); /* Won't echo (fine by me) */ - } - if (c == 3) { - modem->telClient.supressGA[TEL_CLIENT] = true; - modem_data_mode_process_byte(modem, 0xff); - modem_data_mode_process_byte(modem, 251); - modem_data_mode_process_byte(modem, 3); /* Will Suppress GA (too lazy) */ - } - break; - default: - break; - } - modem->telClient.inIAC = false; - modem->telClient.recCommand = false; - continue; - } else { - if (c == 249) { - /* Go Ahead received */ - modem->telClient.inIAC = false; - continue; - } - modem->telClient.command = c; - modem->telClient.recCommand = true; + for (i = 0; i < size; i++) { + uint8_t c = data[i]; + if (modem->telClient.inIAC) { + if (modem->telClient.recCommand) { + if ((c != 0) && (c != 1) && (c != 3)) { + if (modem->telClient.command > 250) { + /* Reject anything we don't recognize */ + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 252); + modem_data_mode_process_byte(modem, c); /* We won't do crap! */ + } + } + switch (modem->telClient.command) { + case 251: /* Will */ + if (c == 0) + modem->telClient.binary[TEL_SERVER] = true; + if (c == 1) + modem->telClient.echo[TEL_SERVER] = true; + if (c == 3) + modem->telClient.supressGA[TEL_SERVER] = true; + break; + case 252: /* Won't */ + if (c == 0) + modem->telClient.binary[TEL_SERVER] = false; + if (c == 1) + modem->telClient.echo[TEL_SERVER] = false; + if (c == 3) + modem->telClient.supressGA[TEL_SERVER] = false; + break; + case 253: /* Do */ + if (c == 0) { + modem->telClient.binary[TEL_CLIENT] = true; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 251); + modem_data_mode_process_byte(modem, 0); /* Will do binary transfer */ + } + if (c == 1) { + modem->telClient.echo[TEL_CLIENT] = false; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 252); + modem_data_mode_process_byte(modem, 1); /* Won't echo (too lazy) */ + } + if (c == 3) { + modem->telClient.supressGA[TEL_CLIENT] = true; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 251); + modem_data_mode_process_byte(modem, 3); /* Will Suppress GA */ + } + break; + case 254: /* Don't */ + if (c == 0) { + modem->telClient.binary[TEL_CLIENT] = false; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 252); + modem_data_mode_process_byte(modem, 0); /* Won't do binary transfer */ + } + if (c == 1) { + modem->telClient.echo[TEL_CLIENT] = false; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 252); + modem_data_mode_process_byte(modem, 1); /* Won't echo (fine by me) */ + } + if (c == 3) { + modem->telClient.supressGA[TEL_CLIENT] = true; + modem_data_mode_process_byte(modem, 0xff); + modem_data_mode_process_byte(modem, 251); + modem_data_mode_process_byte(modem, 3); /* Will Suppress GA (too lazy) */ + } + break; + default: + break; + } + modem->telClient.inIAC = false; + modem->telClient.recCommand = false; + continue; + } else { + if (c == 249) { + /* Go Ahead received */ + modem->telClient.inIAC = false; + continue; + } + modem->telClient.command = c; + modem->telClient.recCommand = true; - if ((modem->telClient.binary[TEL_SERVER]) && (c == 0xff)) { - /* Binary data with value of 255 */ - modem->telClient.inIAC = false; - modem->telClient.recCommand = false; - fifo8_push(&modem->rx_data, 0xff); - continue; - } - } - } else { - if (c == 0xff) { - modem->telClient.inIAC = true; - continue; - } - fifo8_push(&modem->rx_data, c); - } - } + if ((modem->telClient.binary[TEL_SERVER]) && (c == 0xff)) { + /* Binary data with value of 255 */ + modem->telClient.inIAC = false; + modem->telClient.recCommand = false; + fifo8_push(&modem->rx_data, 0xff); + continue; + } + } + } else { + if (c == 0xff) { + modem->telClient.inIAC = true; + continue; + } + fifo8_push(&modem->rx_data, c); + } + } } static int modem_rx(void *priv, uint8_t *buf, int io_len) { -#if 1 - modem_t* modem = (modem_t*)priv; - uint32_t i = 0; + modem_t *modem = (modem_t *) priv; + uint32_t i = 0; if (modem->tcpIpMode) return 0; @@ -1265,7 +1320,6 @@ modem_rx(void *priv, uint8_t *buf, int io_len) } fifo8_push(&modem->rx_data, END); return 1; -#endif } static void @@ -1275,17 +1329,17 @@ modem_rcr_cb(UNUSED(struct serial_s *serial), void *priv) timer_stop(&dev->host_to_serial_timer); /* FIXME: do something to dev->baudrate */ - timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / (double)dev->baudrate) * (double) 9); + timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / (double) dev->baudrate) * (double) 9); #if 0 serial_clear_fifo(dev->serial); #endif } static void -modem_accept_incoming_call(modem_t* modem) +modem_accept_incoming_call(modem_t *modem) { if (modem->waitingclientsocket != -1) { - modem->clientsocket = modem->waitingclientsocket; + modem->clientsocket = modem->waitingclientsocket; modem->waitingclientsocket = -1; modem_enter_connected_state(modem); modem->in_warmup = 250; @@ -1297,8 +1351,8 @@ modem_accept_incoming_call(modem_t* modem) static void modem_cmdpause_timer_callback(void *priv) { - modem_t *modem = (modem_t *) priv; - uint32_t guard_threashold = 0; + modem_t *modem = (modem_t *) priv; + uint32_t guard_threshold = 0; timer_on_auto(&modem->cmdpause_timer, 1000); if (modem->tcpIpConnInProgress) { @@ -1326,7 +1380,7 @@ modem_cmdpause_timer_callback(void *priv) modem_enter_idle_state(modem); modem_send_res(modem, ResNOANSWER); modem->tcpIpConnInProgress = 0; - modem->tcpIpMode = 0; + modem->tcpIpMode = 0; break; } } while (0); @@ -1341,26 +1395,25 @@ modem_cmdpause_timer_callback(void *priv) modem->ringing = true; modem_send_res(modem, ResRING); serial_set_ri(modem->serial, !serial_get_ri(modem->serial)); - modem->ringtimer = 3000; + modem->ringtimer = 3000; modem->reg[MREG_RING_COUNT] = 0; } } } - if (modem->ringing) { - if (modem->ringtimer <= 0) { - modem->reg[MREG_RING_COUNT]++; - if ((modem->reg[MREG_AUTOANSWER_COUNT] > 0) && - (modem->reg[MREG_RING_COUNT] >= modem->reg[MREG_AUTOANSWER_COUNT])) { - modem_accept_incoming_call(modem); - return; - } - modem_send_res(modem, ResRING); + if (modem->ringing) { + if (modem->ringtimer <= 0) { + modem->reg[MREG_RING_COUNT]++; + if ((modem->reg[MREG_AUTOANSWER_COUNT] > 0) && (modem->reg[MREG_RING_COUNT] >= modem->reg[MREG_AUTOANSWER_COUNT])) { + modem_accept_incoming_call(modem); + return; + } + modem_send_res(modem, ResRING); serial_set_ri(modem->serial, !serial_get_ri(modem->serial)); - modem->ringtimer = 3000; - } - --modem->ringtimer; - } + modem->ringtimer = 3000; + } + --modem->ringtimer; + } if (modem->in_warmup) { modem->in_warmup--; @@ -1368,12 +1421,11 @@ modem_cmdpause_timer_callback(void *priv) modem->tx_count = 0; fifo8_reset(&modem->rx_data); } - } - else if (modem->connected && modem->tcpIpMode) { + } else if (modem->connected && modem->tcpIpMode) { if (modem->tx_count) { int wouldblock = 0; - int res = plat_netsocket_send(modem->clientsocket, modem->tx_pkt_ser_line, modem->tx_count, &wouldblock); - + int res = plat_netsocket_send(modem->clientsocket, modem->tx_pkt_ser_line, modem->tx_count, &wouldblock); + if (res <= 0 && !wouldblock) { /* No bytes sent or error. */ modem->tx_count = 0; @@ -1390,8 +1442,8 @@ modem_cmdpause_timer_callback(void *priv) } if (modem->connected) { uint8_t buffer[16]; - int wouldblock = 0; - int res = plat_netsocket_receive(modem->clientsocket, buffer, sizeof(buffer), &wouldblock); + int wouldblock = 0; + int res = plat_netsocket_receive(modem->clientsocket, buffer, sizeof(buffer), &wouldblock); if (res > 0) { if (modem->telnet_mode) @@ -1410,31 +1462,30 @@ modem_cmdpause_timer_callback(void *priv) } } - modem->cmdpause++; - guard_threashold = (uint32_t)(modem->reg[MREG_GUARD_TIME] * 20); - if (modem->cmdpause > guard_threashold) { - if (modem->plusinc == 0) { - modem->plusinc = 1; - } else if (modem->plusinc == 4) { - modem_log("Escape sequence triggered, returning to command mode\n"); - modem->mode = MODEM_MODE_COMMAND; - modem_send_res(modem, ResOK); - modem->plusinc = 0; - } - } + modem->cmdpause++; + guard_threshold = (uint32_t) (modem->reg[MREG_GUARD_TIME] * 20); + if (modem->cmdpause > guard_threshold) { + if (modem->plusinc == 0) { + modem->plusinc = 1; + } else if (modem->plusinc == 4) { + modem_log("Escape sequence triggered, returning to command mode\n"); + modem->mode = MODEM_MODE_COMMAND; + modem_send_res(modem, ResOK); + modem->plusinc = 0; + } + } } /* Initialize the device for use by the user. */ static void * modem_init(const device_t *info) { - modem_t* modem = (modem_t*)calloc(1, sizeof(modem_t)); - const char* phonebook_file = NULL; + modem_t *modem = (modem_t *) calloc(1, sizeof(modem_t)); + const char *phonebook_file = NULL; memset(modem->mac, 0xfc, 6); - - modem->port = device_get_config_int("port"); - modem->baudrate = device_get_config_int("baudrate"); + modem->port = device_get_config_int("port"); + modem->baudrate = device_get_config_int("baudrate"); modem->listen_port = device_get_config_int("listen_port"); modem->telnet_mode = device_get_config_int("telnet_mode"); @@ -1456,13 +1507,14 @@ modem_init(const device_t *info) if (phonebook_file && phonebook_file[0] != 0) { modem_read_phonebook_file(modem, phonebook_file); } - + return modem; } -void modem_close(void *priv) +void +modem_close(void *priv) { - modem_t* modem = (modem_t*)priv; + modem_t *modem = (modem_t *) priv; modem->listen_port = 0; modem_reset(modem); fifo8_destroy(&modem->data_pending); diff --git a/src/qt/win_netsocket.c b/src/qt/win_netsocket.c index 902d5e6ff..55a84d414 100644 --- a/src/qt/win_netsocket.c +++ b/src/qt/win_netsocket.c @@ -19,50 +19,52 @@ #include #include -SOCKET plat_netsocket_create(int type) +SOCKET +plat_netsocket_create(int type) { SOCKET socket = -1; - u_long yes = 1; + u_long yes = 1; if (type != NET_SOCKET_TCP) return -1; - + socket = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); if (socket == INVALID_SOCKET) return -1; ioctlsocket(socket, FIONBIO, &yes); - + return socket; } -SOCKET plat_netsocket_create_server(int type, unsigned short port) +SOCKET +plat_netsocket_create_server(int type, unsigned short port) { struct sockaddr_in sock_addr; - SOCKET socket = -1; - u_long yes = 1; + SOCKET socket = -1; + u_long yes = 1; if (type != NET_SOCKET_TCP) return -1; - + socket = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); if (socket == INVALID_SOCKET) return -1; - - memset(&sock_addr, 0, sizeof(struct sockaddr_in)); - - sock_addr.sin_family = AF_INET; - sock_addr.sin_addr.s_addr = INADDR_ANY; - sock_addr.sin_port = htons(port); - if (bind(socket, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { + memset(&sock_addr, 0, sizeof(struct sockaddr_in)); + + sock_addr.sin_family = AF_INET; + sock_addr.sin_addr.s_addr = INADDR_ANY; + sock_addr.sin_port = htons(port); + + if (bind(socket, (struct sockaddr *) &sock_addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { plat_netsocket_close(socket); - return (SOCKET)-1; + return (SOCKET) -1; } if (listen(socket, 5) == SOCKET_ERROR) { plat_netsocket_close(socket); - return (SOCKET)-1; + return (SOCKET) -1; } ioctlsocket(socket, FIONBIO, &yes); @@ -70,28 +72,31 @@ SOCKET plat_netsocket_create_server(int type, unsigned short port) return socket; } -void plat_netsocket_close(SOCKET socket) +void +plat_netsocket_close(SOCKET socket) { - closesocket((SOCKET)socket); + closesocket((SOCKET) socket); } -SOCKET plat_netsocket_accept(SOCKET socket) +SOCKET +plat_netsocket_accept(SOCKET socket) { SOCKET clientsocket = accept(socket, NULL, NULL); if (clientsocket == INVALID_SOCKET) return -1; - + return clientsocket; } -int plat_netsocket_connected(SOCKET socket) +int +plat_netsocket_connected(SOCKET socket) { struct sockaddr addr; socklen_t len = sizeof(struct sockaddr); fd_set wrfds, exfds; struct timeval tv; - int res = SOCKET_ERROR; + int res = SOCKET_ERROR; int status = 0; int optlen = 4; @@ -107,21 +112,21 @@ int plat_netsocket_connected(SOCKET socket) if (res == SOCKET_ERROR) return -1; - + if (res >= 1 && FD_ISSET(socket, &exfds)) { - res = getsockopt(socket, SOL_SOCKET, SO_ERROR, (char*)&status, &optlen); + res = getsockopt(socket, SOL_SOCKET, SO_ERROR, (char *) &status, &optlen); pclog("Socket error %d\n", status); return -1; } if (res == 0 || !(res >= 1 && FD_ISSET(socket, &wrfds))) return 0; - - res = getsockopt(socket, SOL_SOCKET, SO_ERROR, (char*)&status, &optlen); + + res = getsockopt(socket, SOL_SOCKET, SO_ERROR, (char *) &status, &optlen); if (res == SOCKET_ERROR) return -1; - + if (status != 0) return -1; @@ -131,14 +136,15 @@ int plat_netsocket_connected(SOCKET socket) return 1; } -int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short port) +int +plat_netsocket_connect(SOCKET socket, const char *hostname, unsigned short port) { struct sockaddr_in sock_addr; - int res = -1; + int res = -1; - sock_addr.sin_family = AF_INET; + sock_addr.sin_family = AF_INET; sock_addr.sin_addr.s_addr = inet_addr(hostname); - sock_addr.sin_port = htons(port); + sock_addr.sin_port = htons(port); if (sock_addr.sin_addr.s_addr == INADDR_ANY || sock_addr.sin_addr.s_addr == INADDR_NONE) { struct hostent *hp; @@ -151,22 +157,23 @@ int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short p return -1; } - res = connect(socket, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)); + res = connect(socket, (struct sockaddr *) &sock_addr, sizeof(struct sockaddr_in)); if (res == SOCKET_ERROR) { int error = WSAGetLastError(); if (error == WSAEISCONN || error == WSAEWOULDBLOCK) return 0; - + res = -1; } return res; } -int plat_netsocket_send(SOCKET socket, const unsigned char* data, unsigned int size, int *wouldblock) +int +plat_netsocket_send(SOCKET socket, const unsigned char *data, unsigned int size, int *wouldblock) { - int res = send(socket, (const char*)data, size, 0); + int res = send(socket, (const char *) data, size, 0); if (res == SOCKET_ERROR) { int error = WSAGetLastError(); @@ -179,9 +186,10 @@ int plat_netsocket_send(SOCKET socket, const unsigned char* data, unsigned int s return res; } -int plat_netsocket_receive(SOCKET socket, unsigned char* data, unsigned int size, int *wouldblock) +int +plat_netsocket_receive(SOCKET socket, unsigned char *data, unsigned int size, int *wouldblock) { - int res = recv(socket, (char*)data, size, 0); + int res = recv(socket, (char *) data, size, 0); if (res == SOCKET_ERROR) { int error = WSAGetLastError(); diff --git a/src/qt/win_serial_passthrough.c b/src/qt/win_serial_passthrough.c index b2d09b1d0..2b77bd219 100644 --- a/src/qt/win_serial_passthrough.c +++ b/src/qt/win_serial_passthrough.c @@ -173,7 +173,7 @@ open_pseudo_terminal(serial_passthrough_t *dev) char ascii_pipe_name[1024] = { 0 }; strncpy(ascii_pipe_name, dev->named_pipe, sizeof(ascii_pipe_name)); ascii_pipe_name[1023] = '\0'; - dev->master_fd = (intptr_t) CreateNamedPipeA(ascii_pipe_name, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT, 1, 65536, 65536, NMPWAIT_USE_DEFAULT_WAIT, NULL); + dev->master_fd = (intptr_t) CreateNamedPipeA(ascii_pipe_name, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT, 1, 65536, 65536, NMPWAIT_USE_DEFAULT_WAIT, NULL); if (dev->master_fd == (intptr_t) INVALID_HANDLE_VALUE) { wchar_t errorMsg[1024] = { 0 }; wchar_t finalMsg[1024] = { 0 }; diff --git a/src/unix/unix_netsocket.c b/src/unix/unix_netsocket.c index e6ec6285f..d626d025b 100644 --- a/src/unix/unix_netsocket.c +++ b/src/unix/unix_netsocket.c @@ -19,91 +19,92 @@ #include #include #include -#include -#include -#include -#include #include #include #include #include #include -SOCKET plat_netsocket_create(int type) +SOCKET +plat_netsocket_create(int type) { - SOCKET fd = -1; - int yes = 1; + SOCKET fd = -1; + int yes = 1; if (type != NET_SOCKET_TCP) return -1; - + fd = socket(AF_INET, SOCK_STREAM, 0); if (fd == -1) return -1; fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); - setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&yes, sizeof(yes)); - + setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &yes, sizeof(yes)); + return fd; } -SOCKET plat_netsocket_create_server(int type, unsigned short port) +SOCKET +plat_netsocket_create_server(int type, unsigned short port) { struct sockaddr_in sock_addr; - SOCKET fd = -1; - int yes = 1; + SOCKET fd = -1; + int yes = 1; if (type != NET_SOCKET_TCP) return -1; - + fd = socket(AF_INET, SOCK_STREAM, 0); if (fd == -1) return -1; - - memset(&sock_addr, 0, sizeof(struct sockaddr_in)); - - sock_addr.sin_family = AF_INET; - sock_addr.sin_addr.s_addr = INADDR_ANY; - sock_addr.sin_port = htons(port); - if (bind(fd, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)) == -1) { + memset(&sock_addr, 0, sizeof(struct sockaddr_in)); + + sock_addr.sin_family = AF_INET; + sock_addr.sin_addr.s_addr = INADDR_ANY; + sock_addr.sin_port = htons(port); + + if (bind(fd, (struct sockaddr *) &sock_addr, sizeof(struct sockaddr_in)) == -1) { plat_netsocket_close(fd); - return (SOCKET)-1; + return (SOCKET) -1; } if (listen(fd, 5) == -1) { plat_netsocket_close(fd); - return (SOCKET)-1; + return (SOCKET) -1; } fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); - setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&yes, sizeof(yes)); + setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &yes, sizeof(yes)); return fd; } -void plat_netsocket_close(SOCKET socket) +void +plat_netsocket_close(SOCKET socket) { - close((SOCKET)socket); + close((SOCKET) socket); } -SOCKET plat_netsocket_accept(SOCKET socket) +SOCKET +plat_netsocket_accept(SOCKET socket) { SOCKET clientsocket = accept(socket, NULL, NULL); if (clientsocket == -1) return -1; - + return clientsocket; } -int plat_netsocket_connected(SOCKET socket) +int +plat_netsocket_connected(SOCKET socket) { struct sockaddr addr; socklen_t len = sizeof(struct sockaddr); fd_set wrfds; struct timeval tv; - int res = -1; + int res = -1; int status = 0; socklen_t optlen = 4; @@ -117,15 +118,15 @@ int plat_netsocket_connected(SOCKET socket) if (res == -1) return -1; - + if (res == 0 || !(res >= 1 && FD_ISSET(socket, &wrfds))) return 0; - - res = getsockopt(socket, SOL_SOCKET, SO_ERROR, (char*)&status, &optlen); + + res = getsockopt(socket, SOL_SOCKET, SO_ERROR, (char *) &status, &optlen); if (res == -1) return -1; - + if (status != 0) return -1; @@ -135,16 +136,17 @@ int plat_netsocket_connected(SOCKET socket) return 1; } -int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short port) +int +plat_netsocket_connect(SOCKET socket, const char *hostname, unsigned short port) { struct sockaddr_in sock_addr; - int res = -1; + int res = -1; - sock_addr.sin_family = AF_INET; + sock_addr.sin_family = AF_INET; sock_addr.sin_addr.s_addr = inet_addr(hostname); - sock_addr.sin_port = htons(port); + sock_addr.sin_port = htons(port); - if (sock_addr.sin_addr.s_addr == ((in_addr_t)-1) || sock_addr.sin_addr.s_addr == 0) { + if (sock_addr.sin_addr.s_addr == ((in_addr_t) -1) || sock_addr.sin_addr.s_addr == 0) { struct hostent *hp; hp = gethostbyname(hostname); @@ -155,22 +157,23 @@ int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short p return -1; } - res = connect(socket, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)); + res = connect(socket, (struct sockaddr *) &sock_addr, sizeof(struct sockaddr_in)); if (res == -1) { int error = errno; if (error == EISCONN || error == EWOULDBLOCK || error == EAGAIN || error == EINPROGRESS) return 0; - + res = -1; } return res; } -int plat_netsocket_send(SOCKET socket, const unsigned char* data, unsigned int size, int *wouldblock) +int +plat_netsocket_send(SOCKET socket, const unsigned char *data, unsigned int size, int *wouldblock) { - int res = send(socket, (const char*)data, size, 0); + int res = send(socket, (const char *) data, size, 0); if (res == -1) { int error = errno; @@ -183,9 +186,10 @@ int plat_netsocket_send(SOCKET socket, const unsigned char* data, unsigned int s return res; } -int plat_netsocket_receive(SOCKET socket, unsigned char* data, unsigned int size, int *wouldblock) +int +plat_netsocket_receive(SOCKET socket, unsigned char *data, unsigned int size, int *wouldblock) { - int res = recv(socket, (char*)data, size, 0); + int res = recv(socket, (char *) data, size, 0); if (res == -1) { int error = errno; diff --git a/src/unix/unix_serial_passthrough.c b/src/unix/unix_serial_passthrough.c index 646b77d6c..0184ebbc0 100644 --- a/src/unix/unix_serial_passthrough.c +++ b/src/unix/unix_serial_passthrough.c @@ -22,7 +22,7 @@ # define _BSD_SOURCE 1 #endif #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) -# define __BSD_VISIBLE 1 +# define __BSD_VISIBLE 1 #endif #include #include From 3f64d6d00ccbd42f0bd305c772c931913ead69d7 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Apr 2024 13:51:16 +0500 Subject: [PATCH 816/936] Simplify EditorConfig, add .ui Remove rules made redundant by the new indentation style Add Qt .ui files --- .editorconfig | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/.editorconfig b/.editorconfig index 29d9ac0ba..fa7defd57 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,34 +5,11 @@ indent_style = space indent_size = 4 tab_width = 4 -# Disabled for now since not all editors support setting a tab_width value different from indent_size -# Relevant VSCode extension issue: https://github.com/editorconfig/editorconfig-vscode/issues/190 -# [*.rc] -# indent_style = space -# indent_size = 4 -# tab_width = 4 - -# [Makefile.*] -# indent_style = space -# indent_size = 4 -# tab_width = 4 - [*.manifest] -indent_style = space indent_size = 2 [*.yml] -indent_style = space indent_size = 2 -[**/CMakeLists.txt] -indent_style = space -indent_size = 4 - -[*.cmake] -indent_style = space -indent_size = 4 - -[*.json] -indent_style = space -indent_size = 4 +[*.ui] +indent_size = 1 From 9c53413ca44cc7144e3bdfc96132604268b1113d Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 1 Apr 2024 23:35:55 +0200 Subject: [PATCH 817/936] Give the P5MP3 PS/2 keyboard and mouse latches, fixes #4320. --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 4338f741f..c2bb3925b 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -8705,7 +8705,7 @@ const machine_t machines[] = { .min_multi = MACHINE_MULTIPLIER_FIXED, .max_multi = MACHINE_MULTIPLIER_FIXED }, - .bus_flags = MACHINE_PCI, + .bus_flags = MACHINE_BUS_PS2_LATCH | MACHINE_PCI, .flags = MACHINE_APM, .ram = { .min = 2048, From 5d94a361f12ba39039fd279e14d82e6f90da1548 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 1 Apr 2024 23:36:38 +0200 Subject: [PATCH 818/936] net_modem: Remove excess parentheses. --- src/network/net_modem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 0555978af..078320fb4 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -757,7 +757,7 @@ modem_do_command(modem_t *modem, int repeat) if (repeat) { /* Handle the case of A/ being invoked without a previous command to run */ - if ((modem->prevcmdbuf[0] == '\0')) { + if (modem->prevcmdbuf[0] == '\0') { modem_send_res(modem, ResOK); return; } From 038871d998aae5d8f093d1e641bccbe0dac9be19 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 1 Apr 2024 23:54:49 +0200 Subject: [PATCH 819/936] SiS 496/497: Fix soft reset behavior, fixes #4319. --- src/chipset/sis_85c496.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/chipset/sis_85c496.c b/src/chipset/sis_85c496.c index 1e9b74f41..3c3d5bd8c 100644 --- a/src/chipset/sis_85c496.c +++ b/src/chipset/sis_85c496.c @@ -388,8 +388,7 @@ sis_85c49x_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) break; case 0x67: /* Miscellaneous Control */ dev->pci_conf[addr] = val & 0xf9; - if (valxor & 0x60) - port_92_set_features(dev->port_92, !!(val & 0x20), !!(val & 0x40)); + cpu_cpurst_on_sr = ((val & 0xa0) == 0x80) && !(dev->pci_conf[0xc6] & 0x08); break; /* 86C497 Specific Registers (80h ~ FFh) */ @@ -480,7 +479,7 @@ sis_85c49x_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) break; case 0xc6: /* 85C497 Post / INIT Configuration */ dev->pci_conf[addr] = val & 0x0f; - cpu_cpurst_on_sr = !(val & 0x08); + cpu_cpurst_on_sr = ((dev->pci_conf[0x67] & 0xa0) == 0x80) && !(val & 0x08); soft_reset_pci = !!(val & 0x04); break; case 0xc8: @@ -610,6 +609,9 @@ sis_85c496_reset(void *priv) sis_85c49x_pci_write(0, 0xd0, 0x78, dev); sis_85c49x_pci_write(0, 0xd4, 0x00, dev); + dev->pci_conf[0x67] = 0x00; + dev->pci_conf[0xc6] = 0x00; + ide_pri_disable(); ide_sec_disable(); @@ -617,7 +619,7 @@ sis_85c496_reset(void *priv) sis_85c497_isa_reset(dev); - cpu_cpurst_on_sr = 1; + cpu_cpurst_on_sr = 0; soft_reset_pci = 0; } From ee7df0616823c2386d052bd96de55d4c96cfc388 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 Apr 2024 00:08:40 +0200 Subject: [PATCH 820/936] Voodoo: Honor monitor overscan. --- src/video/vid_svga.c | 2 ++ src/video/vid_voodoo_display.c | 13 ++++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 6e32bdc40..a8bf76505 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -90,6 +90,7 @@ svga_set_override(svga_t *svga, int val) svga->fullchange = svga->monitor->mon_changeframecount; svga->override = val; +#ifdef OVERRIDE_OVERSCAN if (!val) { /* Override turned off, restore overscan X and Y per the CRTC. */ svga->monitor->mon_overscan_y = (svga->rowcount + 1) << 1; @@ -104,6 +105,7 @@ svga_set_override(svga_t *svga, int val) } else svga->monitor->mon_overscan_x = svga->monitor->mon_overscan_y = 16; /* Override turned off, fix overcan X and Y to 16. */ +#endif } void diff --git a/src/video/vid_voodoo_display.c b/src/video/vid_voodoo_display.c index e6cf13674..d04376941 100644 --- a/src/video/vid_voodoo_display.c +++ b/src/video/vid_voodoo_display.c @@ -511,6 +511,8 @@ voodoo_callback(void *priv) { voodoo_t *voodoo = (voodoo_t *) priv; const monitor_t *monitor = &monitors[voodoo->monitor_index]; + int v_y_add = (monitor->mon_overscan_y >> 1); + int v_x_add = (monitor->mon_overscan_x >> 1); if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) { if (voodoo->line < voodoo->v_disp) { @@ -534,7 +536,7 @@ voodoo_callback(void *priv) } if (draw_voodoo->dirty_line[draw_line]) { - uint32_t *p = &monitor->target_buffer->line[voodoo->line + 8][8]; + uint32_t *p = &monitor->target_buffer->line[voodoo->line + v_y_add][v_x_add]; uint16_t *src = (uint16_t *) &draw_voodoo->fb_mem[draw_voodoo->front_offset + draw_line * draw_voodoo->row_width]; int x; @@ -548,8 +550,8 @@ voodoo_callback(void *priv) voodoo->dirty_line_high = voodoo->line; /* Draw left overscan. */ - for (x = 0; x < 8; x++) - monitor->target_buffer->line[voodoo->line + 8][x] = 0x00000000; + for (x = 0; x < v_x_add; x++) + monitor->target_buffer->line[voodoo->line + v_y_add][x] = 0x00000000; if (voodoo->scrfilter && voodoo->scrfilterEnabled) { uint8_t fil[4096 * 3]; /* interleaved 24-bit RGB */ @@ -570,8 +572,9 @@ voodoo_callback(void *priv) } /* Draw right overscan. */ - for (x = 0; x < 8; x++) - monitor->target_buffer->line[voodoo->line + 8][voodoo->h_disp + x + 8] = 0x00000000; + for (x = 0; x < v_x_add; x++) + monitor->target_buffer->line[voodoo->line + v_y_add][voodoo->h_disp + x + v_x_add] = + 0x00000000; } } } From 42be0ab641d7ea2402c01a8118aac5b913cf553a Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 2 Apr 2024 00:20:27 +0200 Subject: [PATCH 821/936] Voodoo: vertical display programming fix. Apparently some software reprograms the vertical display wrong sometimes (in this case, vdisp + 2). This should fix software titles that use such techniques... --- src/video/vid_voodoo.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index 734179fa9..93bdd1a4c 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -505,6 +505,9 @@ voodoo_writel(uint32_t addr, uint32_t val, void *priv) voodoo->videoDimensions = val; voodoo->h_disp = (val & 0xfff) + 1; voodoo->v_disp = (val >> 16) & 0xfff; + if ((voodoo->v_disp == 386) || (voodoo->v_disp == 402) || + (voodoo->v_disp == 482) || (voodoo->v_disp == 602)) + voodoo->v_disp -= 2; break; case SST_fbiInit0: if (voodoo->initEnable & 0x01) { From e712f8060a433adc05f5e3f14d282cf5e06adab6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 Apr 2024 14:54:25 +0200 Subject: [PATCH 822/936] ET4000AX: Do not wrap row offset. --- src/video/vid_et4000.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 7ceacb823..1a28b767b 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -664,8 +664,6 @@ et4000_recalctimings(svga_t *svga) svga->vsyncstart |= 0x400; if (svga->crtc[0x35] & 0x10) svga->split |= 0x400; - if (!svga->rowoffset) - svga->rowoffset = 0x100; if (svga->crtc[0x3f] & 1) svga->htotal |= 0x100; if (svga->attrregs[0x16] & 0x20) { From 38e044ca34b40d77c66f1c525ce0c6fb0938756f Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 2 Apr 2024 15:09:18 +0200 Subject: [PATCH 823/936] Tseng Labs fixes and bug-compatible fixes too. ET3000AX: the chip in question should not support 1MB of video memory. ET4000AX: the early TC6058AF revision can support 1MB of video memory (e.g.: Diamond Speedstar BIOS D3.10, undumped anyway), and actually don't update the rowoffset to 256 when using such chip in 320x200x256 mode. Fixes the copper demo in said chip revision. --- src/include/86box/vid_svga.h | 1 + src/video/vid_et3000.c | 2 -- src/video/vid_et4000.c | 19 +++++++++---------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 2f8a83a1d..bc33ac746 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -129,6 +129,7 @@ typedef struct svga_t { int hblank_end_mask; int hblank_sub; int packed_4bpp; + int ps_bit_bug; int ati_4color; /*The three variables below allow us to implement memory maps like that seen on a 1MB Trio64 : diff --git a/src/video/vid_et3000.c b/src/video/vid_et3000.c index 97da08822..a7d2a749f 100644 --- a/src/video/vid_et3000.c +++ b/src/video/vid_et3000.c @@ -557,8 +557,6 @@ static const device_config_t et3000_config[] = { .value = 256 }, { .description = "512 KB", .value = 512 }, - { .description = "1 MB", - .value = 1024 }, { .description = "" } } }, { .type = CONFIG_END } }; diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 7ceacb823..583487c5f 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -652,7 +652,9 @@ et4000_recalctimings(svga_t *svga) svga->ma_latch |= (svga->crtc[0x33] & 3) << 16; - svga->hblankstart = (((svga->crtc[0x3f] & 0x4) >> 2) << 8) + svga->crtc[2]; + svga->hblankstart = (((svga->crtc[0x3f] & 0x4) >> 2) << 8) + svga->crtc[2]; + + svga->ps_bit_bug = (dev->type == ET4000_TYPE_TC6058AF) && svga->lowres && ((svga->gdcreg[5] & 0x60) >= 0x40); if (svga->crtc[0x35] & 1) svga->vblankstart |= 0x400; @@ -664,7 +666,7 @@ et4000_recalctimings(svga_t *svga) svga->vsyncstart |= 0x400; if (svga->crtc[0x35] & 0x10) svga->split |= 0x400; - if (!svga->rowoffset) + if (!svga->rowoffset && !svga->ps_bit_bug) svga->rowoffset = 0x100; if (svga->crtc[0x3f] & 1) svga->htotal |= 0x100; @@ -729,13 +731,6 @@ et4000_recalctimings(svga_t *svga) svga->rowoffset <<= 1; svga->render = svga_render_8bpp_highres; } - - if (dev->type == ET4000_TYPE_TC6058AF) { - if (svga->render == svga_render_8bpp_lowres) - svga->render = svga_render_8bpp_tseng_lowres; - else if (svga->render == svga_render_8bpp_highres) - svga->render = svga_render_8bpp_tseng_highres; - } } static void @@ -962,6 +957,10 @@ static const device_config_t et4000_tc6058af_config[] = { .description = "512 KB", .value = 512 }, + { + .description = "1 MB", + .value = 1024 + }, { .description = "" } @@ -1071,7 +1070,7 @@ const device_t et4000_tc6058af_isa_device = { .name = "Tseng Labs ET4000AX (TC6058AF) (ISA)", .internal_name = "et4000ax_tc6058af", .flags = DEVICE_ISA, - .local = 0, + .local = ET4000_TYPE_TC6058AF, .init = et4000_init, .close = et4000_close, .reset = NULL, From 57b064c412089a45e9fecccfe4258e8dc5974015 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Thu, 21 Mar 2024 07:54:09 -0400 Subject: [PATCH 824/936] ui: Warning for performance impact of softfloat --- src/qt/qt_settingsmachine.cpp | 15 ++ src/qt/qt_settingsmachine.hpp | 1 + src/qt/qt_settingsmachine.ui | 257 +++++++++++++++++++--------------- 3 files changed, 162 insertions(+), 111 deletions(-) diff --git a/src/qt/qt_settingsmachine.cpp b/src/qt/qt_settingsmachine.cpp index 475730db9..aff55203e 100644 --- a/src/qt/qt_settingsmachine.cpp +++ b/src/qt/qt_settingsmachine.cpp @@ -61,6 +61,11 @@ SettingsMachine::SettingsMachine(QWidget *parent) break; } + auto warning_icon = ui->softFloatWarningIcon->style()->standardIcon(QStyle::SP_MessageBoxWarning); + ui->softFloatWarningIcon->setPixmap(warning_icon.pixmap(warning_icon.actualSize(QSize(16, 16)))); + ui->softFloatWarningIcon->setVisible(false); + ui->softFloatWarningText->setVisible(false); + auto *waitStatesModel = ui->comboBoxWaitStates->model(); waitStatesModel->insertRows(0, 9); auto idx = waitStatesModel->index(0, 0); @@ -337,3 +342,13 @@ SettingsMachine::on_pushButtonConfigure_clicked() const auto *device = machine_get_device(machineId); DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); } + +void SettingsMachine::on_checkBoxFPUSoftfloat_stateChanged(int state) { + if(state == Qt::Checked) { + ui->softFloatWarningIcon->setVisible(true); + ui->softFloatWarningText->setVisible(true); + } else { + ui->softFloatWarningIcon->setVisible(false); + ui->softFloatWarningText->setVisible(false); + } +} \ No newline at end of file diff --git a/src/qt/qt_settingsmachine.hpp b/src/qt/qt_settingsmachine.hpp index 9d0ec62ff..7e89d7fa4 100644 --- a/src/qt/qt_settingsmachine.hpp +++ b/src/qt/qt_settingsmachine.hpp @@ -35,6 +35,7 @@ private slots: private slots: void on_comboBoxMachineType_currentIndexChanged(int index); + void on_checkBoxFPUSoftfloat_stateChanged(int state); private: Ui::SettingsMachine *ui; diff --git a/src/qt/qt_settingsmachine.ui b/src/qt/qt_settingsmachine.ui index 54bc06f5c..0c9c2708e 100644 --- a/src/qt/qt_settingsmachine.ui +++ b/src/qt/qt_settingsmachine.ui @@ -7,7 +7,7 @@ 0 0 458 - 434 + 459
@@ -41,13 +41,6 @@ 0 - - - - Wait states: - - - @@ -55,6 +48,13 @@ + + + + FPU: + + + @@ -69,55 +69,21 @@ - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 30 - - - - 0 - 0 - - - - - - - - PIT mode: - - - - - - - 30 - - - - 0 - 0 - - - - - + + + + + 0 + 0 + + + + + + + + Machine type: + @@ -144,15 +110,15 @@ - - 30 - 0 0 + + 30 + @@ -167,27 +133,31 @@ - - 30 - 0 0 + + 30 +
- - - - - 0 - 0 - + + + + Wait states: + + + + + + + Machine: @@ -229,55 +199,120 @@ - - - - Machine type: - - - - - - - Machine: - - - - - - - FPU: - + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 30 + + + + + + + PIT mode: + + + + + + + + 0 + 0 + + + + 30 + + + + - - - - 2 - 2 - - - - Dynamic Recompiler - - + + + + + + 2 + 2 + + + + Dynamic Recompiler + + + + - - - - 3 - 3 - - - - Softfloat FPU - - + + + + + + 3 + 3 + + + + Softfloat FPU + + + + + + + + + + + + + + High performance impact + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + From 3cf3865980014b179606d368c52ff1da7bb47920 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Thu, 21 Mar 2024 08:00:02 -0400 Subject: [PATCH 825/936] ui: Disable add-on voodoo when main voodoo is selected --- src/qt/qt_settingsdisplay.cpp | 20 ++++++++++++++++++++ src/qt/qt_settingsdisplay.ui | 14 +++++++------- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/qt/qt_settingsdisplay.cpp b/src/qt/qt_settingsdisplay.cpp index 4d8919a73..631e3b966 100644 --- a/src/qt/qt_settingsdisplay.cpp +++ b/src/qt/qt_settingsdisplay.cpp @@ -139,6 +139,7 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) if (index < 0) { return; } + static QRegularExpression voodooRegex("3dfx|voodoo|banshee", QRegularExpression::CaseInsensitiveOption); auto curVideoCard_2 = videoCard[1]; videoCard[0] = ui->comboBoxVideo->currentData().toInt(); if (videoCard[0] == VID_INTERNAL) @@ -207,6 +208,25 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) ui->comboBoxVideoSecondary->setCurrentIndex(0); ui->pushButtonConfigureSecondary->setEnabled(false); } + + // Is the currently selected video card a voodoo? + if (ui->comboBoxVideo->currentText().contains(voodooRegex)) { + // Get the name of the video card currently in use + const device_t *video_dev = video_card_getdevice(gfxcard[0]); + const QString currentVideoName = DeviceConfig::DeviceName(video_dev, video_get_internal_name(gfxcard[0]), 1); + // Is it a voodoo? + const bool currentCardIsVoodoo = currentVideoName.contains(voodooRegex); + // Don't uncheck if + // * Current card is voodoo + // * Add-on voodoo was manually overridden in config + if (ui->checkBoxVoodoo->isChecked() && !currentCardIsVoodoo) { + // Otherwise, uncheck the add-on voodoo when a main voodoo is selected + ui->checkBoxVoodoo->setCheckState(Qt::Unchecked); + } + ui->checkBoxVoodoo->setDisabled(true); + } else { + ui->checkBoxVoodoo->setDisabled(false); + } } void diff --git a/src/qt/qt_settingsdisplay.ui b/src/qt/qt_settingsdisplay.ui index 5dd76287f..a9b7e6e2c 100644 --- a/src/qt/qt_settingsdisplay.ui +++ b/src/qt/qt_settingsdisplay.ui @@ -61,15 +61,15 @@ - - 30 - 0 0 + + 30 + @@ -102,7 +102,7 @@ - Voodoo Graphics + Voodoo 1 or 2 Graphics @@ -122,15 +122,15 @@ - - 30 - 0 0 + + 30 + From 4d8e7bd24edc6377ccbc2e5a94b999e6975c3482 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Fri, 29 Mar 2024 08:23:55 -0400 Subject: [PATCH 826/936] qt: Add UUID features, MAC address configuration, machine move detection --- src/86box.c | 1 + src/config.c | 11 ++++++++ src/device.c | 3 +-- src/include/86box/86box.h | 12 ++++++--- src/qt/qt_deviceconfig.cpp | 39 ++++++++++++++++++++++++++++ src/qt/qt_main.cpp | 21 +++++++++++++++ src/qt/qt_util.cpp | 53 ++++++++++++++++++++++++++++++++++++++ src/qt/qt_util.hpp | 5 ++++ 8 files changed, 139 insertions(+), 6 deletions(-) diff --git a/src/86box.c b/src/86box.c index 88229a820..67d0bb165 100644 --- a/src/86box.c +++ b/src/86box.c @@ -206,6 +206,7 @@ int video_fullscreen_scale_maximized = 0; /* (C) Whether also apply when maximized. */ int do_auto_pause = 0; /* (C) Auto-pause the emulator on focus loss */ +char uuid[MAX_UUID_LEN] = { '\0' }; /* (C) UUID or machine identifier */ /* Statistics. */ extern int mmuflush; diff --git a/src/config.c b/src/config.c index da02a93b0..95d23cea3 100644 --- a/src/config.c +++ b/src/config.c @@ -209,6 +209,12 @@ load_general(void) ini_section_delete_var(cat, "window_coordinates"); do_auto_pause = ini_section_get_int(cat, "do_auto_pause", 0); + + p = ini_section_get_string(cat, "uuid", NULL); + if (p != NULL) + strncpy(uuid, p, sizeof(uuid) - 1); + else + strncpy(uuid, "", sizeof(uuid) - 1); } /* Load monitor section. */ @@ -1878,6 +1884,11 @@ save_general(void) else ini_section_delete_var(cat, "do_auto_pause"); + if (strnlen(uuid, sizeof(uuid) - 1) > 0) + ini_section_set_string(cat, "uuid", uuid); + else + ini_section_delete_var(cat, "uuid"); + ini_delete_section_if_empty(config, cat); } diff --git a/src/device.c b/src/device.c index b934e7246..321f105e5 100644 --- a/src/device.c +++ b/src/device.c @@ -467,8 +467,7 @@ device_has_config(const device_t *dev) config = dev->config; while (config->type != -1) { - if (config->type != CONFIG_MAC) - c++; + c++; config++; } diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index b34b95621..3f5f3f2ab 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -35,6 +35,9 @@ #define MAX_PREV_IMAGES 4 #define MAX_IMAGE_PATH_LEN 2048 +/* Max UUID Length */ +#define MAX_UUID_LEN 64 + /* Default language 0xFFFF = from system, 0x409 = en-US */ #define DEFAULT_LANGUAGE 0x0409 @@ -167,10 +170,11 @@ extern uint16_t key_prefix_2_2; extern uint16_t key_uncapture_1; extern uint16_t key_uncapture_2; -extern char exe_path[2048]; /* path (dir) of executable */ -extern char usr_path[1024]; /* path (dir) of user data */ -extern char cfg_path[1024]; /* full path of config file */ -extern int open_dir_usr_path; /* default file open dialog directory of usr_path */ +extern char exe_path[2048]; /* path (dir) of executable */ +extern char usr_path[1024]; /* path (dir) of user data */ +extern char cfg_path[1024]; /* full path of config file */ +extern int open_dir_usr_path; /* default file open dialog directory of usr_path */ +extern char uuid[MAX_UUID_LEN]; /* UUID or machine identifier */ #ifndef USE_NEW_DYNAREC extern FILE *stdlog; /* file to log output to */ #endif diff --git a/src/qt/qt_deviceconfig.cpp b/src/qt/qt_deviceconfig.cpp index 6c7db0f3d..d2ae70245 100644 --- a/src/qt/qt_deviceconfig.cpp +++ b/src/qt/qt_deviceconfig.cpp @@ -29,7 +29,9 @@ #include #include #include +#include #include +#include extern "C" { #include <86box/86box.h> @@ -38,6 +40,7 @@ extern "C" { #include <86box/device.h> #include <86box/midi_rtmidi.h> #include <86box/mem.h> +#include <86box/random.h> #include <86box/rom.h> } @@ -116,6 +119,7 @@ DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *se device_set_context(&device_context, device, instance); auto device_label = new QLabel(device->name); + device_label->setAlignment(Qt::AlignCenter); dc.ui->formLayout->addRow(device_label); auto line = new QFrame; line->setFrameShape(QFrame::HLine); @@ -291,6 +295,33 @@ DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *se cbox->setCurrentIndex(currentIndex); break; } + case CONFIG_MAC: + { + // QHBoxLayout for the line edit widget and the generate button + auto hboxLayout = new QHBoxLayout(); + auto generateButton = new QPushButton(tr("Generate")); + auto lineEdit = new QLineEdit; + // Allow the line edit to expand and fill available space + lineEdit->setSizePolicy(QSizePolicy::MinimumExpanding,QSizePolicy::Preferred); + lineEdit->setInputMask("HH:HH:HH;0"); + lineEdit->setObjectName(config->name); + // Display the current or generated MAC in uppercase + // When stored it will be converted to lowercase + if (config_get_mac(device_context.name, config->name, config->default_int) & 0xFF000000) { + lineEdit->setText(QString::asprintf("%02X:%02X:%02X", random_generate(), random_generate(), random_generate())); + } else { + auto current_mac = QString(config_get_string(device_context.name, config->name, const_cast(config->default_string))); + lineEdit->setText(current_mac.toUpper()); + } + // Action for the generate button + connect(generateButton, &QPushButton::clicked, [lineEdit] { + lineEdit->setText(QString::asprintf("%02X:%02X:%02X", random_generate(), random_generate(), random_generate())); + }); + hboxLayout->addWidget(lineEdit); + hboxLayout->addWidget(generateButton); + dc.ui->formLayout->addRow(config->description, hboxLayout); + break; + } } ++config; } @@ -362,6 +393,14 @@ DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *se config_set_int(device_context.name, const_cast(config->name), spinBox->value()); break; } + case CONFIG_MAC: + { + const auto *lineEdit = dc.findChild(config->name); + // Store the mac address as lowercase + auto macText = lineEdit->displayText().toLower(); + config_set_string(device_context.name, config->name, macText.toUtf8().constData()); + break; + } } config++; } diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index a621d1441..78eaff5e9 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #ifdef QT_STATIC /* Static builds need plugin imports */ @@ -71,6 +72,7 @@ extern "C" { #include "cocoa_mouse.hpp" #include "qt_styleoverride.hpp" #include "qt_unixmanagerfilter.hpp" +#include "qt_util.hpp" // Void Cast #define VC(x) const_cast(x) @@ -220,6 +222,25 @@ main(int argc, char *argv[]) return 6; } + // UUID / copy / move detection + if(!util::compareUuid()) { + QMessageBox movewarnbox; + movewarnbox.setIcon(QMessageBox::Icon::Warning); + movewarnbox.setText("This machine might have been moved or copied."); + movewarnbox.setInformativeText("In order to ensure proper networking functionality, 86Box needs to know if this machine was moved or copied.\n\nSelect \"I Copied It\" if you are not sure."); + const QPushButton *movedButton = movewarnbox.addButton(QObject::tr("I Moved It"), QMessageBox::AcceptRole); + const QPushButton *copiedButton = movewarnbox.addButton(QObject::tr("I Copied It"), QMessageBox::DestructiveRole); + QPushButton *cancelButton = movewarnbox.addButton(QObject::tr("Cancel"), QMessageBox::RejectRole); + movewarnbox.setDefaultButton(cancelButton); + movewarnbox.exec(); + if (movewarnbox.clickedButton() == copiedButton) { + util::storeCurrentUuid(); + util::generateNewMacAdresses(); + } else if (movewarnbox.clickedButton() == movedButton) { + util::storeCurrentUuid(); + } + } + #ifdef Q_OS_WINDOWS # if !defined(EMU_BUILD_NUM) || (EMU_BUILD_NUM != 5624) HWND winbox = FindWindow("TWinBoxMain", NULL); diff --git a/src/qt/qt_util.cpp b/src/qt/qt_util.cpp index b05b656bb..0a59cdf5d 100644 --- a/src/qt/qt_util.cpp +++ b/src/qt/qt_util.cpp @@ -21,8 +21,20 @@ #if QT_VERSION <= QT_VERSION_CHECK(5, 14, 0) # include #endif +#include #include "qt_util.hpp" +extern "C" { +#include <86box/86box.h> +#include <86box/config.h> +#include <86box/device.h> +#include <86box/ini.h> +#include <86box/random.h> +#include <86box/thread.h> +#include <86box/timer.h> +#include <86box/network.h> +} + namespace util { QScreen * screenOfWidget(QWidget *widget) @@ -56,4 +68,45 @@ DlgFilter(std::initializer_list extensions, bool last) return " (" % temp.join(' ') % ")" % (!last ? ";;" : ""); } +QString currentUuid() +{ + return QUuid::createUuidV5(QUuid{}, QString(usr_path)).toString(QUuid::WithoutBraces); +} + +bool compareUuid() +{ + // A uuid not set in the config file will have a zero length. + // Any uuid that is lower than the minimum length will be considered invalid + // and a new one will be generated + if (const auto currentUuidLength = QString(uuid).length(); currentUuidLength < UUID_MIN_LENGTH) { + storeCurrentUuid(); + return true; + } + // The uuid appears to be a valid, at least by length. + // Compare with a simple string match + return uuid == currentUuid(); +} + +void +storeCurrentUuid() +{ + strncpy(uuid, currentUuid().toUtf8().constData(), sizeof(uuid) - 1); +} + +void +generateNewMacAdresses() +{ + for (int i = 0; i < NET_CARD_MAX; ++i) { + auto net_card = net_cards_conf[i]; + if (net_card.device_num != 0) { + const auto network_device = network_card_getdevice(net_card.device_num); + device_context_t device_context; + + device_set_context(&device_context, network_device, i+1); + auto generatedMac = QString::asprintf("%02X:%02X:%02X", random_generate(), random_generate(), random_generate()).toLower(); + config_set_string(device_context.name, "mac", generatedMac.toUtf8().constData()); + } + } +} + } diff --git a/src/qt/qt_util.hpp b/src/qt/qt_util.hpp index 6ecd904b3..07e44b621 100644 --- a/src/qt/qt_util.hpp +++ b/src/qt/qt_util.hpp @@ -8,10 +8,15 @@ class QScreen; namespace util { +static constexpr auto UUID_MIN_LENGTH = 36; /* Creates extension list for qt filedialog */ QString DlgFilter(std::initializer_list extensions, bool last = false); /* Returns screen the widget is on */ QScreen *screenOfWidget(QWidget *widget); +QString currentUuid(); +void storeCurrentUuid(); +bool compareUuid(); +void generateNewMacAdresses(); }; #endif From 165ad489ef02087ead30f12ac184b2c0a403b88f Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Mon, 1 Apr 2024 08:58:43 -0400 Subject: [PATCH 827/936] Trim the newline from the resulting string on macOS --- src/qt/qt_platform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index c7cc76ffe..275d1df2e 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -686,7 +686,7 @@ plat_get_cpu_string(char *outbuf, uint8_t len) { return; } QByteArray result = process->readAll(); - auto command_result = QString(result).split(": ").last(); + auto command_result = QString(result).split(": ").last().trimmed(); if(!command_result.isEmpty()) { cpu_string = command_result; } From f637e72488de866d05b2af03daff94379fb79f42 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Mon, 1 Apr 2024 09:40:00 -0400 Subject: [PATCH 828/936] config: Add host_cpu and emu_build_num to general --- src/config.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/config.c b/src/config.c index da02a93b0..08edb4c59 100644 --- a/src/config.c +++ b/src/config.c @@ -77,6 +77,7 @@ #include <86box/plat_dir.h> #include <86box/ui.h> #include <86box/snd_opl.h> +#include <86box/version.h> static int cx; static int cy; @@ -1878,6 +1879,15 @@ save_general(void) else ini_section_delete_var(cat, "do_auto_pause"); + char cpu_buf[128] = { 0 }; + plat_get_cpu_string(cpu_buf, 128); + ini_section_set_string(cat, "host_cpu", cpu_buf); + + if (EMU_BUILD_NUM != 0) + ini_section_set_int(cat, "emu_build_num", EMU_BUILD_NUM); + else + ini_section_delete_var(cat, "emu_build_num"); + ini_delete_section_if_empty(config, cat); } From c8a1843cdf20b6edcb4f2b9bd123b7fb74c9b370 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 Apr 2024 23:31:44 +0200 Subject: [PATCH 829/936] FDC: Disable DSR reset on the PS/1-2011/2121 / PS/2-30 FDC. --- src/floppy/fdc.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index e16da138d..491df2f47 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -780,24 +780,26 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) } return; case 4: - if (!(val & 0x80)) { - timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC); - fdc->interrupt = -6; - } - if (fdc->power_down || ((val & 0x80) && !(fdc->dsr & 0x80))) { - if (fdc->power_down) { - timer_set_delay_u64(&fdc->timer, 1000 * TIMER_USEC); - fdc->interrupt = -5; - } else { + if (!(fdc->flags & FDC_FLAG_PS1)) { + if (!(val & 0x80)) { timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC); - fdc->interrupt = -1; + fdc->interrupt = -6; + } + if (fdc->power_down || ((val & 0x80) && !(fdc->dsr & 0x80))) { + if (fdc->power_down) { + timer_set_delay_u64(&fdc->timer, 1000 * TIMER_USEC); + fdc->interrupt = -5; + } else { + timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC); + fdc->interrupt = -1; - fdc->perp &= 0xfc; + fdc->perp &= 0xfc; - for (i = 0; i < FDD_NUM; i++) - ui_sb_update_icon(SB_FLOPPY | i, 0); + for (i = 0; i < FDD_NUM; i++) + ui_sb_update_icon(SB_FLOPPY | i, 0); - fdc_ctrl_reset(fdc); + fdc_ctrl_reset(fdc); + } } } fdc->dsr = val; From 48718eb169f8995853dac8923be5769ca3c809a0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 3 Apr 2024 14:08:05 +0200 Subject: [PATCH 830/936] MGA: Fixes hard freezes when using DynaView 3D on non-16-bpp modes on Windows 3.x. --- src/video/vid_mga.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 36df9e9e4..5c094c6c9 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -4505,6 +4505,19 @@ blit_line(mystique_t *mystique, int closed, int autoline) int b = 0; switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + if (!(mystique->dwgreg.dr[4] & (1 << 23))) + r = (mystique->dwgreg.dr[4] >> 20) & 0x7; + if (!(mystique->dwgreg.dr[8] & (1 << 23))) + g = (mystique->dwgreg.dr[8] >> 20) & 0x7; + if (!(mystique->dwgreg.dr[12] & (1 << 23))) + b = (mystique->dwgreg.dr[12] >> 21) & 0x3; + dst = (r << 5) | (g << 2) | b; + + ((uint8_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + break; + case MACCESS_PWIDTH_16: if (!(mystique->dwgreg.dr[4] & (1 << 23))) r = (mystique->dwgreg.dr[4] >> 18) & 0x1f; @@ -4518,6 +4531,33 @@ blit_line(mystique_t *mystique, int closed, int autoline) svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; break; + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + if (!(mystique->dwgreg.dr[4] & (1 << 23))) + r = (mystique->dwgreg.dr[4] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[8] & (1 << 23))) + g = (mystique->dwgreg.dr[8] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[12] & (1 << 23))) + b = (mystique->dwgreg.dr[12] >> 15) & 0xff; + dst = (r << 16) | (g << 8) | b; + + ((uint32_t *) svga->vram)[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = dst | (old_dst & 0xFF000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_32: + if (!(mystique->dwgreg.dr[4] & (1 << 23))) + r = (mystique->dwgreg.dr[4] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[8] & (1 << 23))) + g = (mystique->dwgreg.dr[8] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[12] & (1 << 23))) + b = (mystique->dwgreg.dr[12] >> 15) & 0xff; + dst = (r << 16) | (g << 8) | b; + + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + default: fatal("LINE I/ZI PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); } From fcbbae181f46e0365e71a95a9cced9b5553b2a9d Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 3 Apr 2024 14:09:27 +0200 Subject: [PATCH 831/936] MGA: fixes pitch mask to be correct according to the docs (it incorrectly stripped bit 11 of the pitch before). Reference: Page 3-74 (PDF page number 87), https://www.vgamuseum.info/images/doc/matrox/mga-2164w_dev_spec.pdf. --- src/video/vid_mga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 5c094c6c9..bbba9ca6f 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -337,7 +337,7 @@ #define MACCESS_NODITHER (1 << 30) #define MACCESS_DIT555 (1 << 31) -#define PITCH_MASK 0x7e0 +#define PITCH_MASK 0xfe0 #define PITCH_YLIN (1 << 15) #define SGN_SDYDXL (1 << 0) From 982c7c46f93282295bea44678a73845db4a20bc0 Mon Sep 17 00:00:00 2001 From: Sasamiya <117635969+kzmidze@users.noreply.github.com> Date: Thu, 4 Apr 2024 00:08:52 +0800 Subject: [PATCH 832/936] Update language modules --- src/qt/languages/zh-CN.po | 4 ++-- src/qt/languages/zh-TW.po | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index 7dd7be6d2..c8bd8f7bd 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -439,10 +439,10 @@ msgid "Standalone MPU-401" msgstr "独立 MPU-401" msgid "Use FLOAT32 sound" -msgstr "使用单精度浮点 (FLOAT32)" +msgstr "使用单精度浮点 (FLOAT32) 音频" msgid "FM synth driver" -msgstr "调频合成器驱动器" +msgstr "FM synth driver" msgid "Nuked (more accurate)" msgstr "Nuked (更准确)" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 8ea4d2290..3de6bf4c4 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -439,10 +439,10 @@ msgid "Standalone MPU-401" msgstr "獨立 MPU-401" msgid "Use FLOAT32 sound" -msgstr "使用單精度浮點 (FLOAT32)" +msgstr "使用單精度浮點 (FLOAT32) 音訊" msgid "FM synth driver" -msgstr "調頻合成器驅動器" +msgstr "FM synth driver" msgid "Nuked (more accurate)" msgstr "Nuked (更準確)" From f93692a045c9d558eb9a345e65d126239d3c8733 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 4 Apr 2024 03:09:35 +0200 Subject: [PATCH 833/936] More Pro Audio Spectrum 16 work, closes #4313. --- src/dma.c | 195 ++++++++++++++++++++++++++++++++++------ src/include/86box/dma.h | 2 + src/pit.c | 8 +- src/pit_fast.c | 28 ++++-- src/sound/snd_pas16.c | 188 +++++++++++++++++++++++++------------- 5 files changed, 322 insertions(+), 99 deletions(-) diff --git a/src/dma.c b/src/dma.c index b7c4b4863..ebe75bba6 100644 --- a/src/dma.c +++ b/src/dma.c @@ -42,6 +42,7 @@ static int dma_wp[2]; static uint8_t dma_stat; static uint8_t dma_stat_rq; static uint8_t dma_stat_rq_pc; +static uint8_t dma_stat_adv_pend; static uint8_t dma_command[2]; static uint8_t dma_req_is_soft; static uint8_t dma_advanced; @@ -457,6 +458,7 @@ dma_read(uint16_t addr, UNUSED(void *priv)) { int channel = (addr >> 1) & 3; uint8_t temp; + int count; switch (addr & 0xf) { case 0: @@ -473,10 +475,13 @@ dma_read(uint16_t addr, UNUSED(void *priv)) case 5: case 7: /*Count registers*/ dma_wp[0] ^= 1; + count = dma[channel].cc/* + 1*/; + // if (count > dma[channel].cb) + // count = 0x0000; if (dma_wp[0]) - temp = dma[channel].cc & 0xff; + temp = count & 0xff; else - temp = dma[channel].cc >> 8; + temp = count >> 8; return temp; case 8: /*Status register*/ @@ -529,8 +534,10 @@ dma_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) case 8: /*Control register*/ dma_command[0] = val; +#ifdef ENABLE_DMA_LOG if (val & 0x01) pclog("[%08X:%04X] Memory-to-memory enable\n", CS, cpu_state.pc); +#endif return; case 9: /*Request register */ @@ -538,7 +545,9 @@ dma_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) if (val & 4) { dma_stat_rq_pc |= (1 << channel); if ((channel == 0) && (dma_command[0] & 0x01)) { +#ifdef ENABLE_DMA_LOG pclog("Memory to memory transfer start\n"); +#endif dma_mem_to_mem_transfer(); } else dma_block_transfer(channel); @@ -767,9 +776,16 @@ static uint8_t dma16_read(uint16_t addr, UNUSED(void *priv)) { int channel = ((addr >> 2) & 3) + 4; - uint8_t temp; +#ifdef ENABLE_DMA_LOG + uint16_t port = addr; +#endif + uint8_t ret; + int count; addr >>= 1; + + ret = dmaregs[1][addr & 0xf]; + switch (addr & 0xf) { case 0: case 2: @@ -778,41 +794,53 @@ dma16_read(uint16_t addr, UNUSED(void *priv)) dma_wp[1] ^= 1; if (dma_ps2.is_ps2) { if (dma_wp[1]) - return (dma[channel].ac); - return ((dma[channel].ac >> 8) & 0xff); - } - if (dma_wp[1]) - return ((dma[channel].ac >> 1) & 0xff); - return ((dma[channel].ac >> 9) & 0xff); + ret = (dma[channel].ac); + else + ret = ((dma[channel].ac >> 8) & 0xff); + } else if (dma_wp[1]) + ret = ((dma[channel].ac >> 1) & 0xff); + else + ret = ((dma[channel].ac >> 9) & 0xff); + break; case 1: case 3: case 5: case 7: /*Count registers*/ dma_wp[1] ^= 1; + count = dma[channel].cc/* + 1*/; + // if (count > dma[channel].cb) + // count = 0x0000; if (dma_wp[1]) - temp = dma[channel].cc & 0xff; + ret = count & 0xff; else - temp = dma[channel].cc >> 8; - return temp; + ret = count >> 8; + break; case 8: /*Status register*/ - temp = (dma_stat_rq_pc & 0xf0); - temp |= dma_stat >> 4; + ret = (dma_stat_rq_pc & 0xf0); + ret |= dma_stat >> 4; dma_stat &= ~0xf0; - return temp; + break; default: break; } - return (dmaregs[1][addr & 0xf]); +#ifdef ENABLE_DMA_LOG + pclog("dma16_read(%08X) = %02X\n", port, ret); +#endif + + return ret; } static void dma16_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) { int channel = ((addr >> 2) & 3) + 4; +#ifdef ENABLE_DMA_LOG + pclog("dma16_write(%08X, %02X)\n", addr, val); +#endif addr >>= 1; dmaregs[1][addr & 0xf] = val; @@ -1076,11 +1104,12 @@ dma_reset(void) dma[c].transfer_mode = (c & 4) ? 0x0202 : 0x0101; } - dma_stat = 0x00; - dma_stat_rq = 0x00; - dma_stat_rq_pc = 0x00; - dma_req_is_soft = 0; - dma_advanced = 0; + dma_stat = 0x00; + dma_stat_rq = 0x00; + dma_stat_rq_pc = 0x00; + dma_stat_adv_pend = 0x00; + dma_req_is_soft = 0; + dma_advanced = 0; memset(dma_buffer, 0x00, sizeof(dma_buffer)); memset(dma16_buffer, 0x00, sizeof(dma16_buffer)); @@ -1401,23 +1430,130 @@ int dma_channel_readable(int channel) { dma_t *dma_c = &dma[channel]; + int ret = 1; if (channel < 4) { if (dma_command[0] & 0x04) - return 0; + ret = 0; } else { if (dma_command[1] & 0x04) - return 0; + ret = 0; } if (!(dma_e & (1 << channel))) - return 0; + ret = 0; if ((dma_m & (1 << channel)) && !dma_req_is_soft) - return 0; + ret = 0; if ((dma_c->mode & 0xC) != 8) - return 0; + ret = 0; - return 1; + return ret; +} + +int +dma_channel_read_only(int channel) +{ + dma_t *dma_c = &dma[channel]; + uint16_t temp; + + if (channel < 4) { + if (dma_command[0] & 0x04) + return (DMA_NODATA); + } else { + if (dma_command[1] & 0x04) + return (DMA_NODATA); + } + + if (!(dma_e & (1 << channel))) + return (DMA_NODATA); + if ((dma_m & (1 << channel)) && !dma_req_is_soft) + return (DMA_NODATA); + if ((dma_c->mode & 0xC) != 8) + return (DMA_NODATA); + + dma_channel_advance(channel); + + if (!dma_at && !channel) + refreshread(); + + if (!dma_c->size) { + temp = _dma_read(dma_c->ac, dma_c); + + if (dma_c->mode & 0x20) { + if (dma_ps2.is_ps2) + dma_c->ac--; + else if (dma_advanced) + dma_retreat(dma_c); + else + dma_c->ac = (dma_c->ac & 0xffff0000 & dma_mask) | ((dma_c->ac - 1) & 0xffff); + } else { + if (dma_ps2.is_ps2) + dma_c->ac++; + else if (dma_advanced) + dma_advance(dma_c); + else + dma_c->ac = (dma_c->ac & 0xffff0000 & dma_mask) | ((dma_c->ac + 1) & 0xffff); + } + } else { + temp = _dma_readw(dma_c->ac, dma_c); + + if (dma_c->mode & 0x20) { + if (dma_ps2.is_ps2) + dma_c->ac -= 2; + else if (dma_advanced) + dma_retreat(dma_c); + else + dma_c->ac = (dma_c->ac & 0xfffe0000 & dma_mask) | ((dma_c->ac - 2) & 0x1ffff); + } else { + if (dma_ps2.is_ps2) + dma_c->ac += 2; + else if (dma_advanced) + dma_advance(dma_c); + else + dma_c->ac = (dma_c->ac & 0xfffe0000 & dma_mask) | ((dma_c->ac + 2) & 0x1ffff); + } + } + + dma_stat_rq |= (1 << channel); + + dma_stat_adv_pend |= (1 << channel); + + return temp; +} + +int +dma_channel_advance(int channel) +{ + dma_t *dma_c = &dma[channel]; + int tc = 0; + + if (dma_stat_adv_pend & (1 << channel)) { + dma_c->cc--; + if (dma_c->cc < 0) { + if (dma_advanced && (dma_c->sg_status & 1) && !(dma_c->sg_status & 6)) + dma_sg_next_addr(dma_c); + else { + tc = 1; + if (dma_c->mode & 0x10) { /*Auto-init*/ + dma_c->cc = dma_c->cb; + dma_c->ac = dma_c->ab; + } else + dma_m |= (1 << channel); + dma_stat |= (1 << channel); + } + } + + if (tc) { + if (dma_advanced && (dma_c->sg_status & 1) && ((dma_c->sg_command & 0xc0) == 0x40)) { + picint(1 << 13); + dma_c->sg_status |= 8; + } + } + + dma_stat_adv_pend &= ~(1 << channel); + } + + return tc; } int @@ -1442,6 +1578,9 @@ dma_channel_read(int channel) if ((dma_c->mode & 0xC) != 8) return (DMA_NODATA); + if (dma_stat_adv_pend & (1 << channel)) + dma_channel_advance(channel); + if (!dma_at && !channel) refreshread(); @@ -1573,6 +1712,8 @@ dma_channel_write(int channel, uint16_t val) dma_stat_rq |= (1 << channel); + dma_stat_adv_pend &= ~(1 << channel); + dma_c->cc--; if (dma_c->cc < 0) { if (dma_advanced && (dma_c->sg_status & 1) && !(dma_c->sg_status & 6)) diff --git a/src/include/86box/dma.h b/src/include/86box/dma.h index ff0dc0b5d..23ce04898 100644 --- a/src/include/86box/dma.h +++ b/src/include/86box/dma.h @@ -96,6 +96,8 @@ extern void writedma2(uint8_t temp); extern int dma_get_drq(int channel); extern void dma_set_drq(int channel, int set); +extern int dma_channel_read_only(int channel); +extern int dma_channel_advance(int channel); extern int dma_channel_read(int channel); extern int dma_channel_write(int channel, uint16_t val); diff --git a/src/pit.c b/src/pit.c index 340cdccde..7ae50f413 100644 --- a/src/pit.c +++ b/src/pit.c @@ -246,9 +246,9 @@ ctr_tick(ctr_t *ctr, void *priv) } else ctr->count -= (ctr->newcount ? 1 : 2); if (ctr->count < 0) { + ctr_set_out(ctr, 0, pit); ctr_load_count(ctr); ctr->state = 3; - ctr_set_out(ctr, 0, pit); } else if (ctr->newcount) ctr->newcount = 0; } @@ -265,9 +265,9 @@ ctr_tick(ctr_t *ctr, void *priv) } else ctr->count -= (ctr->newcount ? 3 : 2); if (ctr->count < 0) { + ctr_set_out(ctr, 1, pit); ctr_load_count(ctr); ctr->state = 2; - ctr_set_out(ctr, 1, pit); } else if (ctr->newcount) ctr->newcount = 0; } @@ -443,8 +443,6 @@ pit_ctr_set_gate(void *data, int counter_id, int gate) int old = ctr->gate; uint8_t mode = ctr->m & 3; - ctr->gate = gate; - switch (mode) { case 1: case 2: @@ -470,6 +468,8 @@ pit_ctr_set_gate(void *data, int counter_id, int gate) default: break; } + + ctr->gate = gate; } static __inline void diff --git a/src/pit_fast.c b/src/pit_fast.c index 0da671bfe..e986600ee 100644 --- a/src/pit_fast.c +++ b/src/pit_fast.c @@ -133,7 +133,7 @@ pitf_read_timer(ctrf_t *ctr) read = 0; if (read > 0x10000) read = 0x10000; - if (ctr->m == 3) + if ((ctr->m == 3) && ctr->using_timer) read <<= 1; return read; } @@ -191,6 +191,8 @@ pitf_ctr_load(ctrf_t *ctr, void *priv) ctr->count = l; if (ctr->using_timer) timer_set_delay_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * ctr->pit_const)); + else + ctr->newcount = (l & 1); pitf_ctr_set_out(ctr, 1, pit); ctr->thit = 0; } @@ -269,6 +271,8 @@ pitf_set_gate_no_timer(ctrf_t *ctr, int gate, void *priv) ctr->count = l; if (ctr->using_timer) timer_set_delay_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * ctr->pit_const)); + else + ctr->newcount = (l & 1); pitf_ctr_set_out(ctr, 1, pit); ctr->thit = 0; } @@ -330,14 +334,23 @@ pitf_over(ctrf_t *ctr, void *priv) case 3: /*Square wave mode*/ if (ctr->out) { pitf_ctr_set_out(ctr, 0, pit); - ctr->count += (l >> 1); - if (ctr->using_timer) + if (ctr->using_timer) { + ctr->count += (l >> 1); timer_advance_u64(&ctr->timer, (uint64_t) ((l >> 1) * ctr->pit_const)); + } else { + ctr->count += l; + ctr->newcount = (l & 1); + } } else { pitf_ctr_set_out(ctr, 1, pit); ctr->count += ((l + 1) >> 1); - if (ctr->using_timer) + if (ctr->using_timer) { + ctr->count += (l >> 1); timer_advance_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * ctr->pit_const)); + } else { + ctr->count += l; + ctr->newcount = (l & 1); + } } #if 0 if (!t) @@ -631,7 +644,12 @@ pitf_ctr_clock(void *data, int counter_id) if (ctr->using_timer) return; - ctr->count -= (ctr->m == 3) ? 2 : 1; + if ((ctr->m == 3) && ctr->newcount) { + ctr->count -= ctr->out ? 1 : 3; + ctr->newcount = 0; + } else + ctr->count -= (ctr->m == 3) ? 2 : 1; + if (!ctr->count) pitf_over(ctr, pit); } diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 0a5c046b7..9812ced64 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -154,10 +154,14 @@ typedef struct pas16_t { uint16_t base; uint16_t new_base; + uint16_t sb_compat_base; + uint16_t mpu401_base; + uint16_t dma8_dat; + uint16_t ticks; uint16_t pcm_dat_l; uint16_t pcm_dat_r; - int16_t pcm_buffer[2][SOUNDBUFLEN * 2]; + int32_t pcm_buffer[2][SOUNDBUFLEN * 2]; int pos; int midi_r; @@ -371,7 +375,11 @@ pas16_in(uint16_t port, void *priv) break; case 0xec03: - ret = pas16->type ? 0x0c : 0x04; +#ifdef NEWER_PAS16 + ret = pas16->type ? 0x0c : 0x06; +#else + ret = pas16->type ? 0x0f : 0x06; +#endif break; case 0xf000: @@ -390,7 +398,13 @@ pas16_in(uint16_t port, void *priv) break; case 0xf400: - ret = pas16->compat; + ret = (pas16->compat & 0xf3); + + if (pas16->dsp.sb_irqm8 || pas16->dsp.sb_irqm16 || pas16->dsp.sb_irqm401) + ret |= 0x04; + + if (pas16->mpu->mode == M_UART) + ret |= 0x08; break; case 0xf401: ret = pas16->compat_base; @@ -402,11 +416,13 @@ pas16_in(uint16_t port, void *priv) case 0xfc00: /* Board model */ /* PAS16 or PASPlus */ - ret = pas16->type ? 0x04 : 0x01; + ret = pas16->type ? 0x0c : 0x01; break; case 0xfc03: /* Master mode read */ /* AT bus, XT/AT timing */ - ret = pas16->type ? (0x20 | 0x10 | 0x01) : (0x10 | 0x01); + ret = 0x11; + if (pas16->type) + ret |= 0x20; break; default: @@ -458,7 +474,6 @@ pas16_reset_pcm(void *priv) pas16->pcm_ctrl = 0x00; pas16->stereo_lr = 0; - pas16->dma8_ff = 0; pas16->irq_stat &= 0xd7; @@ -490,6 +505,7 @@ pas16_reset_regs(void *priv) pitf_ctr_set_gate(pit, 1, 0); pas16_reset_pcm(pas16); + pas16->dma8_ff = 0; pas16->irq_ena = 0x00; pas16->irq_stat = 0x00; @@ -522,6 +538,11 @@ pas16_reset(void *priv) pas16_io_handler(pas16, 1); pas16->new_base = 0x0388; + + pas16->sb_compat_base = 0x0220; + pas16->compat = 0x02; + pas16->compat_base = 0x02; + sb_dsp_setaddr(&pas16->dsp, pas16->sb_compat_base); } static void @@ -546,25 +567,25 @@ pas16_out(uint16_t port, uint8_t val, void *priv) break; case 0x0801: pas16->irq_stat &= ~val; + if (!(pas16->irq_stat & 0x1f)) + picintc(1 << pas16->irq); break; case 0x0802: + pas16_update(pas16); + + pitf_ctr_set_gate(pas16->pit, 1, !!(val & 0x80)); + pitf_ctr_set_gate(pas16->pit, 0, !!(val & 0x40)); + + pas16->stereo_lr = 0; + pas16->dma8_ff = 0; + if ((val & 0x20) && !(pas16->audiofilt & 0x20)) { pas16_log("Reset.\n"); - val = 0x20; pas16_reset_regs(pas16); } - pas16_update(pas16); - pitf_ctr_set_gate(pas16->pit, 0, 1); - pitf_ctr_set_gate(pas16->pit, 1, 1); - // pas16->pit->counters[0].gate = !!(val & 0x40); - // pas16->pit->counters[0].enabled = !!(val & 0x40); - // pas16->pit->counters[1].gate = !!(val & 0x80); - // pas16->pit->counters[1].enabled = !!(val & 0x80); - pas16->stereo_lr = 0; - pas16->irq_stat &= 0xdf; - pas16->dma8_ff = 0; pas16->audiofilt = val; + if (val & 0x1f) { pas16->filter = 1; switch (val & 0x1f) { @@ -595,6 +616,10 @@ pas16_out(uint16_t port, uint8_t val, void *priv) break; case 0x0803: pas16->irq_ena = val & 0x1f; + pas16->irq_stat &= ((val & 0x1f) | 0xe0); + + if (!(pas16->irq_stat & 0x1f)) + picintc(1 << pas16->irq); break; case 0x0c00: @@ -607,7 +632,7 @@ pas16_out(uint16_t port, uint8_t val, void *priv) if ((val & PAS16_PCM_ENA) && !(pas16->pcm_ctrl & PAS16_PCM_ENA)) { /* Guess */ pas16->stereo_lr = 0; - pas16->irq_stat &= 0xdf; + pas16->irq_stat &= 0xd7; /* Needed for 8-bit DMA to work correctly on a 16-bit DMA channel. */ pas16->dma8_ff = 0; } @@ -713,10 +738,10 @@ pas16_out(uint16_t port, uint8_t val, void *priv) break; case 0xf400: - pas16->compat = val; + pas16->compat = val & 0xf3; pas16_log("PCM compression is now %sabled\n", (val & 0x10) ? "en" : "dis"); if (pas16->compat & 0x02) - sb_dsp_setaddr(&pas16->dsp, ((pas16->compat_base & 0xf) << 4) | 0x200); + sb_dsp_setaddr(&pas16->dsp, pas16->sb_compat_base); else sb_dsp_setaddr(&pas16->dsp, 0); if (pas16->compat & 0x01) @@ -726,14 +751,17 @@ pas16_out(uint16_t port, uint8_t val, void *priv) break; case 0xf401: pas16->compat_base = val; + pas16->sb_compat_base = ((pas16->compat_base & 0xf) << 4) | 0x200; + pas16_log("SB Compatibility base: %04X\n", pas16->sb_compat_base); if (pas16->compat & 0x02) - sb_dsp_setaddr(&pas16->dsp, ((pas16->compat_base & 0xf) << 4) | 0x200); + sb_dsp_setaddr(&pas16->dsp, pas16->sb_compat_base); if (pas16->compat & 0x01) mpu401_change_addr(pas16->mpu, ((pas16->compat_base & 0xf0) | 0x300)); break; case 0xf802: pas16->sb_irqdma = val; + mpu401_setirq(pas16->mpu, pas16_sb_irqs[val & 7]); sb_dsp_setirq(&pas16->dsp, pas16_sb_irqs[(val >> 3) & 7]); sb_dsp_setdma8(&pas16->dsp, pas16_sb_dmas[(val >> 6) & 3]); pas16_log("pas16_out : set SB IRQ %i DMA %i.\n", pas16_sb_irqs[(val >> 3) & 7], @@ -774,18 +802,33 @@ pas16_out(uint16_t port, uint8_t val, void *priv) alongside the previous sample; - A 16-bit sample always takes two ctr_clock() ticks. */ +static uint16_t +pas16_dma_channel_read(pas16_t *pas16, int channel) +{ + int status; + uint16_t ret; + + if (pas16->pcm_ctrl & PAS16_PCM_DMA_ENA) { + if (pas16->dma >= 5) { + dma_channel_advance(pas16->dma); + status = dma_channel_read_only(pas16->dma); + } else + status = dma_channel_read(pas16->dma); + ret = (status == DMA_NODATA) ? 0x0000 : (status & 0xffff); + } else + ret = 0x0000; + + return ret; +} + static uint16_t pas16_dma_readb(pas16_t *pas16, uint8_t timer1_ticks) { uint16_t ret; - if (pas16->pcm_ctrl & PAS16_PCM_DMA_ENA) - ret = dma_channel_read(pas16->dma); - else - ret = 0x0000; + ret = pas16_dma_channel_read(pas16, pas16->dma); - for (uint8_t i = 0; i < timer1_ticks; i++) - pitf_ctr_clock(pas16->pit, 1); + pas16->ticks += timer1_ticks; return ret; } @@ -795,16 +838,14 @@ pas16_dma_readw(pas16_t *pas16, uint8_t timer1_ticks) { uint16_t ret; - if (pas16->pcm_ctrl & PAS16_PCM_DMA_ENA) { - ret = dma_channel_read(pas16->dma); + if (pas16->dma >= 5) + ret = pas16_dma_channel_read(pas16, pas16->dma); + else { + ret = pas16_dma_channel_read(pas16, pas16->dma); + ret |= (pas16_dma_channel_read(pas16, pas16->dma) << 8); + } - if (pas16->dma < 5) - ret |= (dma_channel_read(pas16->dma) << 8); - } else - ret = 0x0000; - - for (uint8_t i = 0; i < timer1_ticks; i++) - pitf_ctr_clock(pas16->pit, 1); + pas16->ticks += timer1_ticks; return ret; } @@ -812,20 +853,19 @@ pas16_dma_readw(pas16_t *pas16, uint8_t timer1_ticks) static uint16_t pas16_readdmab(pas16_t *pas16) { - static uint16_t temp; uint16_t ret; if (pas16->dma >= 5) { if (pas16->dma8_ff) - temp >>= 8; + pas16->dma8_dat >>= 8; else - temp = pas16_dma_readb(pas16, 1); + pas16->dma8_dat = pas16_dma_readb(pas16, 1); pas16->dma8_ff = !pas16->dma8_ff; } else - temp = pas16_dma_readb(pas16, 1); + pas16->dma8_dat = pas16_dma_readb(pas16, 1); - ret = ((temp & 0xff) ^ 0x80) << 8; + ret = ((pas16->dma8_dat & 0xff) ^ 0x80) << 8; return ret; } @@ -844,8 +884,9 @@ static uint16_t pas16_readdmaw_stereo(pas16_t *pas16) { uint16_t ret; + uint16_t ticks = (pas16->sys_conf_1 & 0x02) ? (1 + (pas16->dma < 5)) : 2; - ret = pas16_dma_readw(pas16, 2); + ret = pas16_dma_readw(pas16, ticks); return ret; } @@ -895,17 +936,17 @@ pas16_pit_timer0(int new_out, UNUSED(int old_out), void *priv) pas16_t *pas16 = (pas16_t *) pit->dev_priv; uint16_t temp; - pas16_update(pas16); + if (!pas16->pit->counters[0].gate) + return; + + if (!dma_channel_readable(pas16->dma)) + return; + pas16_update_irq(pas16); - pas16->irq_stat |= PAS16_INT_SAMP; - if (pas16->irq_ena & PAS16_INT_SAMP) { - pas16_log("INT SAMP.\n"); - picint(1 << pas16->irq); - } + if (((pas16->pcm_ctrl & PAS16_PCM_ENA) == PAS16_PCM_ENA) && (pit->counters[1].m & 2) && new_out) { + pas16->ticks = 0; - if (((pas16->pcm_ctrl & PAS16_PCM_AND_DMA_ENA) == PAS16_PCM_AND_DMA_ENA) && - dma_channel_readable(pas16->dma) && (pit->counters[1].m & 2) && new_out) { if (pas16->pcm_ctrl & PAS16_PCM_MONO) { temp = pas16_readdma_mono(pas16); @@ -929,7 +970,22 @@ pas16_pit_timer0(int new_out, UNUSED(int old_out), void *priv) pas16->irq_stat = (pas16->irq_stat & 0xdf) | (pas16->stereo_lr << 5); } } - } + + if (pas16->ticks) { + for (uint8_t i = 0; i < pas16->ticks; i++) + pitf_ctr_clock(pas16->pit, 1); + + pas16->ticks = 0; + } + + pas16->irq_stat |= PAS16_INT_SAMP; + if (pas16->irq_ena & PAS16_INT_SAMP) { + pas16_log("INT SAMP.\n"); + picint(1 << pas16->irq); + } + + pas16_update(pas16); + } } static void @@ -938,16 +994,15 @@ pas16_pit_timer1(int new_out, UNUSED(int old_out), void *priv) pitf_t *pit = (pitf_t * )priv; pas16_t *pas16 = (pas16_t *) pit->dev_priv; + if (!pas16->pit->counters[1].gate) + return; + /* At new_out = 0, it's in the counter reload phase. */ if ((pas16->pcm_ctrl & PAS16_PCM_ENA) && (pit->counters[1].m & 2) && new_out) { if (pas16->irq_ena & PAS16_INT_PCM) { pas16->irq_stat |= PAS16_INT_PCM; pas16_log("pas16_pcm_poll : cause IRQ %i %02X\n", pas16->irq, 1 << pas16->irq); picint(1 << pas16->irq); - - pas16->stereo_lr = 0; - pas16->irq_stat &= 0xdf; - pas16->dma8_ff = 0; } } } @@ -1019,14 +1074,19 @@ pas16_update(pas16_t *pas16) for (; pas16->pos < sound_pos_global; pas16->pos++) { pas16->pcm_buffer[0][pas16->pos] = 0; pas16->pcm_buffer[1][pas16->pos] = 0; +#ifdef CROSS_CHANNEL if (pas16->pcm_ctrl & 0x08) - pas16->pcm_buffer[0][pas16->pos] += pas16->pcm_dat_l; + pas16->pcm_buffer[0][pas16->pos] += (int16_t) pas16->pcm_dat_l; if (pas16->pcm_ctrl & 0x04) - pas16->pcm_buffer[0][pas16->pos] += pas16->pcm_dat_r; + pas16->pcm_buffer[0][pas16->pos] += (int16_t) pas16->pcm_dat_r; if (pas16->pcm_ctrl & 0x02) - pas16->pcm_buffer[1][pas16->pos] += pas16->pcm_dat_l; + pas16->pcm_buffer[1][pas16->pos] += (int16_t) pas16->pcm_dat_l; if (pas16->pcm_ctrl & 0x01) - pas16->pcm_buffer[1][pas16->pos] += pas16->pcm_dat_r; + pas16->pcm_buffer[1][pas16->pos] += (int16_t) pas16->pcm_dat_r; +#else + pas16->pcm_buffer[0][pas16->pos] += (int16_t) pas16->pcm_dat_l; + pas16->pcm_buffer[1][pas16->pos] += (int16_t) pas16->pcm_dat_r; +#endif } } } @@ -1039,11 +1099,11 @@ pas16_get_buffer(int32_t *buffer, int len, void *priv) sb_dsp_update(&pas16->dsp); pas16_update(pas16); for (int c = 0; c < len * 2; c++) { - buffer[c] += (int16_t) (sb_iir(0, c & 1, (double) pas16->dsp.buffer[c]) / 1.3) / 2; + buffer[c] += (int32_t) (sb_iir(0, c & 1, (double) pas16->dsp.buffer[c]) / 1.3) / 2; if (pas16->filter) - buffer[c] += (low_fir_pas16(0, c & 1, (double) pas16->pcm_buffer[c & 1][c >> 1])) / 2.0; + buffer[c] += (low_fir_pas16(0, c & 1, (double) pas16->pcm_buffer[c & 1][c >> 1]) / 1.3) / 2.0; else - buffer[c] += (pas16->pcm_buffer[c & 1][c >> 1] / 2); + buffer[c] += ((pas16->pcm_buffer[c & 1][c >> 1] / 1.3) / 2); } pas16->pos = 0; @@ -1086,9 +1146,11 @@ pas16_init(const device_t *info) sb_dsp_init(&pas16->dsp, SB2, SB_SUBTYPE_DEFAULT, pas16); pas16->mpu = (mpu_t *) malloc(sizeof(mpu_t)); memset(pas16->mpu, 0, sizeof(mpu_t)); - mpu401_init(pas16->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); + mpu401_init(pas16->mpu, 0, 0, M_INTELLIGENT, device_get_config_int("receive_input401")); sb_dsp_set_mpu(&pas16->dsp, pas16->mpu); + pas16->sb_compat_base = 0x0000; + io_sethandler(0x9a01, 0x0001, NULL, NULL, NULL, pas16_out_base, NULL, NULL, pas16); pas16->this_id = 0xbc + pas16_next; From d52b606cec97e70f428dc1593e68da0a44c7dcc3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 4 Apr 2024 03:10:29 +0200 Subject: [PATCH 834/936] SiS PCI flags corrections. --- src/machine/m_at_386dx_486.c | 2 +- src/machine/m_at_slot1.c | 4 ++-- src/machine/m_at_socket4.c | 4 ++-- src/machine/m_at_socket5.c | 8 ++++---- src/machine/m_at_socket7.c | 6 +++--- src/machine/m_at_socket7_3v.c | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index b89f77b18..ea7e00ddc 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -992,7 +992,7 @@ machine_at_sis_85c496_common_init(UNUSED(const machine_t *model)) { device_add(&ide_pci_2ch_device); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index a3c25d12b..c199be2e9 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -821,7 +821,7 @@ machine_at_p6f99_init(const machine_t *model) machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); @@ -854,7 +854,7 @@ machine_at_m747_init(const machine_t *model) machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index 02018949c..f7aad92ec 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -65,7 +65,7 @@ machine_at_sp4_common_init(const machine_t *model) { machine_at_common_init(model); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); /* Excluded: 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F, 10, 11, 12, 13, 14 */ @@ -422,7 +422,7 @@ machine_at_excaliburpci2_init(const machine_t *model) machine_at_common_init_ex(model, 2); device_add(&ami_1994_nvr_device); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x08, PCI_CARD_IDE, 0, 0, 0, 0); diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 916f8490b..773f8d980 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -465,7 +465,7 @@ machine_at_sq588_init(const machine_t *model) machine_at_common_init(model); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); /* Correct: 0D (01), 0F (02), 11 (03), 13 (04) */ @@ -496,7 +496,7 @@ machine_at_p54sps_init(const machine_t *model) machine_at_common_init(model); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x06, PCI_CARD_NORMAL, 1, 2, 3, 4); @@ -526,7 +526,7 @@ machine_at_ms5109_init(const machine_t *model) machine_at_common_init_ex(model, 2); device_add(&ami_1994_nvr_device); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x07, PCI_CARD_IDE, 0, 0, 0, 0); @@ -557,7 +557,7 @@ machine_at_torino_init(const machine_t *model) machine_at_common_init_ex(model, 2); device_add(&ami_1994_nvr_device); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x08, PCI_CARD_VIDEO, 0, 0, 0, 0); diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index ce21c6437..6ba7cb41d 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -1312,7 +1312,7 @@ machine_at_sp97xv_init(const machine_t *model) machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); @@ -1341,7 +1341,7 @@ machine_at_sq578_init(const machine_t *model) machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); @@ -1368,7 +1368,7 @@ machine_at_ms5172_init(const machine_t *model) machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index 676f50fb1..fdf155894 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -872,7 +872,7 @@ machine_at_5sbm2_init(const machine_t *model) machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); From b674619894817cebf3d6a0c4039a3b5237313f53 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 5 Apr 2024 14:11:49 +0200 Subject: [PATCH 835/936] Video7/Radius fixes. And cleanups as well. Htotal/hblankstart are now applicable to the HT216-32 card only. Re-apply the Radius ISA SVGA extensions port workaround until a proper ISA bios is found/dumped (warning: the HT209 may not work properly on the PS/1 2121 machine). --- src/video/vid_ht216.c | 83 ++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 48 deletions(-) diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index b87d93665..213cf9ed4 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -313,7 +313,8 @@ ht216_out(uint16_t addr, uint8_t val, void *priv) break; case 0xca: - svga_recalctimings(svga); + if (ht216->id == 0x7861) + svga_recalctimings(svga); break; case 0xc9: @@ -481,12 +482,14 @@ ht216_in(uint16_t addr, void *priv) if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; - if ((ht216->id == 0x7152) && ht216->isabus) { - if (addr == 0x105) - return ht216->extensions; - } - switch (addr) { + case 0x105: + if (ht216->isabus && (ht216->id == 0x7152)) { + ret &= ~0x03; + return ret; + } + break; + case 0x3c4: return svga->seqaddr; @@ -624,6 +627,16 @@ ht216_recalctimings(svga_t *svga) ht216_t *ht216 = (ht216_t *) svga->priv; int high_res_256 = 0; + + if (ht216->id == 0x7861) { + if (ht216->ht_regs[0xe0] & 0x20) { + if (ht216->ht_regs[0xca] & 0x01) + svga->htotal |= 0x200; + if (ht216->ht_regs[0xca] & 0x04) + svga->hblankstart |= 0x200; + } + } + switch ((((((svga->miscout >> 2) & 3) || ((ht216->ht_regs[0xa4] >> 2) & 3)) | ((ht216->ht_regs[0xa4] >> 2) & 4)) || ((ht216->ht_regs[0xf8] >> 5) & 0x0f)) | ((ht216->ht_regs[0xf8] << 1) & 8)) { case 0: case 1: @@ -644,12 +657,15 @@ ht216_recalctimings(svga_t *svga) svga->ma_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 12); - svga->interlace = ht216->ht_regs[0xe0] & 1; + if (ht216->ht_regs[0xf6] & 0x80) + svga->ma_latch = ((ht216->ht_regs[0xf6] & 0x30) << 12); + + svga->interlace = ht216->ht_regs[0xe0] & 0x01; if (svga->interlace) - high_res_256 = (svga->htotal * 8) > (svga->vtotal * 4); + high_res_256 = (svga->htotal << 3) > (svga->vtotal << 2); else - high_res_256 = (svga->htotal * 8) > (svga->vtotal * 2); + high_res_256 = (svga->htotal << 3) > (svga->vtotal << 1); ht216->adjust_cursor = 0; @@ -706,15 +722,10 @@ ht216_recalctimings(svga_t *svga) } } - svga->ma_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 14); - if (svga->crtc[0x17] == 0xeb) /*Looks like 1024x768 mono mode expects 512K of video memory*/ svga->vram_display_mask = 0x7ffff; else svga->vram_display_mask = (ht216->ht_regs[0xf6] & 0x40) ? ht216->vram_mask : 0x3ffff; - - if (ht216->ht_regs[0xe0] & 0x20) - svga->hblankstart = ((ht216->ht_regs[0xca] >> 2) << 8) + svga->crtc[4]; } static void @@ -737,9 +748,9 @@ ht216_hwcursor_draw(svga_t *svga, int displine) for (int x = 0; x < width; x++) { if (!(dat[0] & 0x80000000)) - (buffer32->line[displine])[svga->x_add + offset + x] = 0; + svga->monitor->target_buffer->line[displine][svga->x_add + offset + x] = 0; if (dat[1] & 0x80000000) - (buffer32->line[displine])[svga->x_add + offset + x] ^= 0xffffff; + svga->monitor->target_buffer->line[displine][svga->x_add + offset + x] ^= 0xffffff; dat[0] <<= shift; dat[1] <<= shift; @@ -1530,12 +1541,13 @@ ht216_init(const device_t *info, uint32_t mem_size, int has_rom) } break; case 4: - if ((info->local == 0x7152) && (info->flags & DEVICE_ISA)) - ht216->extensions = device_get_config_int("extensions"); - else if ((info->local == 0x7152) && (info->flags & DEVICE_MCA)) { - ht216->pos_regs[0] = 0xb7; - ht216->pos_regs[1] = 0x80; - mca_add(radius_mca_read, radius_mca_write, radius_mca_feedb, NULL, ht216); + if (info->local == 0x7152) { + if (info->flags & DEVICE_MCA) { + ht216->pos_regs[0] = 0xb7; + ht216->pos_regs[1] = 0x80; + mca_add(radius_mca_read, radius_mca_write, radius_mca_feedb, NULL, ht216); + } else + io_sethandler(0x0105, 0x0001, ht216_in, NULL, NULL, NULL, NULL, NULL, ht216); } rom_init(&ht216->bios_rom, BIOS_RADIUS_SVGA_MULTIVIEW_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); break; @@ -1723,31 +1735,6 @@ static const device_config_t ht216_32_standalone_config[] = { .type = CONFIG_END } }; - -static const device_config_t radius_svga_multiview_config[] = { - { - .name = "extensions", - .description = "Extensions", - .type = CONFIG_SELECTION, - .default_int = 0x00, - .selection = { - { - .description = "Extensions Enabled", - .value = 0x00 - }, - { - .description = "Extensions Disabled", - .value = 0x02 - }, - { - .description = "" - } - } - }, - { - .type = CONFIG_END - } -}; // clang-format on const device_t g2_gc205_device = { @@ -1817,7 +1804,7 @@ const device_t radius_svga_multiview_isa_device = { { .available = radius_svga_multiview_available }, .speed_changed = ht216_speed_changed, .force_redraw = ht216_force_redraw, - .config = radius_svga_multiview_config + .config = NULL }; const device_t radius_svga_multiview_mca_device = { From bc6aacec71e4535e6577b8bc320a102ac6926357 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 6 Apr 2024 02:44:50 +0200 Subject: [PATCH 836/936] PASPlus fix for PoP1 Okay, turns out bit 5 (for the board revision) is for all PAS2-based cards, which includes both Plus and 16. This should fix the PCM IRQ on PoP1 and board detection on Plus DOS drivers. --- src/sound/snd_pas16.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 9812ced64..4530bda86 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -309,7 +309,7 @@ pas16_in(uint16_t port, void *priv) ret = pas16->audiofilt; break; case 0x0803: - ret = pas16->irq_ena | (pas16->type ? 0x20 : 0x00); + ret = pas16->irq_ena | 0x20; pas16_log("IRQ Mask read=%02x.\n", ret); break; From b6ae0a0e5b91e331e6669469ae72c47e208f0211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Mon, 8 Apr 2024 17:28:53 +0200 Subject: [PATCH 837/936] Create SECURITY.md --- SECURITY.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..fe8394883 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,18 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +| --------- | ------------------ | +| >= master | :white_check_mark: | +| < master | :x: | + +Each version is supported in the form of patch releases until the next version is merged into master. + +## Reporting a Vulnerability + +To report a vulnerability, either open an issue here on GitHub or join our Discord server. If it is +accepted, that means we have begun working on it and it will be fixed if it is at all possible. If it +is declined, then that means we have either determined it to not actually be a vulnerability or we +have determined it is not feasible to fix it. On GitHub, we are going to notify you when a decision +taken, and if accepted, when it is fixed. On Discord, you get live updates. From da1ededb9383ae14ee72eed3ed5b809242ec31a6 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 10 Apr 2024 17:27:30 +0200 Subject: [PATCH 838/936] SCSI CD-ROM and 5380 fixes. CD-ROM side: fixed a mode sense page (0x08 Sony, used by both Sony and Texel drives) as well as corrected the Toshiba specific drive speeds (bytes_per_second). NCR 5380 side: split the work into the generic 5380 core and the ASICs into separate sources (53c400 and T128) and added the T228 MCA adapter based on the 128. --- src/include/86box/scsi_device.h | 4 +- src/include/86box/scsi_ncr5380.h | 114 ++- src/scsi/CMakeLists.txt | 4 +- src/scsi/scsi.c | 1 + src/scsi/scsi_cdrom.c | 2 +- src/scsi/scsi_ncr5380.c | 1595 +++--------------------------- src/scsi/scsi_ncr53c400.c | 998 +++++++++++++++++++ src/scsi/scsi_t128.c | 631 ++++++++++++ 8 files changed, 1865 insertions(+), 1484 deletions(-) create mode 100644 src/scsi/scsi_ncr53c400.c create mode 100644 src/scsi/scsi_t128.c diff --git a/src/include/86box/scsi_device.h b/src/include/86box/scsi_device.h index 09f9ee2d9..216fdb2ad 100644 --- a/src/include/86box/scsi_device.h +++ b/src/include/86box/scsi_device.h @@ -173,8 +173,8 @@ #define GPMODEP_RIGID_DISK_PAGE 0x0000000000000010LL #define GPMODEP_FLEXIBLE_DISK_PAGE 0x0000000000000020LL #define GPMODEP_CACHING_PAGE 0x0000000000000100LL -#define GPMODEP_CDROM_PAGE_SONY 0x0000000000000200LL -#define GPMODEP_CDROM_AUDIO_PAGE_SONY 0x0000000000000400LL +#define GPMODEP_CDROM_PAGE_SONY 0x0000000000000100LL +#define GPMODEP_CDROM_AUDIO_PAGE_SONY 0x0000000000000200LL #define GPMODEP_CDROM_PAGE 0x0000000000002000LL #define GPMODEP_CDROM_AUDIO_PAGE 0x0000000000004000LL #define GPMODEP_CAPABILITIES_PAGE 0x0000040000000000LL diff --git a/src/include/86box/scsi_ncr5380.h b/src/include/86box/scsi_ncr5380.h index ecf5660ef..a213e299d 100644 --- a/src/include/86box/scsi_ncr5380.h +++ b/src/include/86box/scsi_ncr5380.h @@ -6,9 +6,8 @@ * * This file is part of the 86Box distribution. * - * Implementation of the NCR 5380 series of SCSI Host Adapters - * made by NCR. These controllers were designed for - * the ISA bus. + * Implementation of the NCR 5380 chip made by NCR + * and used in various controllers. * * * @@ -17,21 +16,128 @@ * Fred N. van Kempen, * * Copyright 2017-2018 Sarah Walker. - * Copyright 2017-2018 TheCollector1995. * Copyright 2017-2018 Fred N. van Kempen. + * Copyright 2017-2024 TheCollector1995. */ #ifndef SCSI_NCR5380_H #define SCSI_NCR5380_H +#define NCR_CURDATA 0 /* current SCSI data (read only) */ +#define NCR_OUTDATA 0 /* output data (write only) */ +#define NCR_INITCOMMAND 1 /* initiator command (read/write) */ +#define NCR_MODE 2 /* mode (read/write) */ +#define NCR_TARGETCMD 3 /* target command (read/write) */ +#define NCR_SELENABLE 4 /* select enable (write only) */ +#define NCR_BUSSTATUS 4 /* bus status (read only) */ +#define NCR_STARTDMA 5 /* start DMA send (write only) */ +#define NCR_BUSANDSTAT 5 /* bus and status (read only) */ +#define NCR_DMATARGET 6 /* DMA target (write only) */ +#define NCR_INPUTDATA 6 /* input data (read only) */ +#define NCR_DMAINIRECV 7 /* DMA initiator receive (write only) */ +#define NCR_RESETPARITY 7 /* reset parity/interrupt (read only) */ + +#define ICR_DBP 0x01 +#define ICR_ATN 0x02 +#define ICR_SEL 0x04 +#define ICR_BSY 0x08 +#define ICR_ACK 0x10 +#define ICR_ARB_LOST 0x20 +#define ICR_ARB_IN_PROGRESS 0x40 + +#define MODE_ARBITRATE 0x01 +#define MODE_DMA 0x02 +#define MODE_MONITOR_BUSY 0x04 +#define MODE_ENA_EOP_INT 0x08 + +#define STATUS_ACK 0x01 +#define STATUS_BUSY_ERROR 0x04 +#define STATUS_PHASE_MATCH 0x08 +#define STATUS_INT 0x10 +#define STATUS_DRQ 0x40 +#define STATUS_END_OF_DMA 0x80 + +#define TCR_IO 0x01 +#define TCR_CD 0x02 +#define TCR_MSG 0x04 +#define TCR_REQ 0x08 +#define TCR_LAST_BYTE_SENT 0x80 + + +#define STATE_IDLE 0 +#define STATE_COMMAND 1 +#define STATE_DATAIN 2 +#define STATE_DATAOUT 3 +#define STATE_STATUS 4 +#define STATE_MESSAGEIN 5 +#define STATE_SELECT 6 +#define STATE_MESSAGEOUT 7 +#define STATE_MESSAGE_ID 8 + +#define DMA_IDLE 0 +#define DMA_SEND 1 +#define DMA_INITIATOR_RECEIVE 2 + +typedef struct ncr_t { + uint8_t icr; + uint8_t mode; + uint8_t tcr; + uint8_t data_wait; + uint8_t isr; + uint8_t output_data; + uint8_t target_id; + uint8_t tx_data; + uint8_t msglun; + + uint8_t command[20]; + uint8_t msgout[4]; + uint8_t bus; + + int msgout_pos; + int is_msgout; + + int dma_mode; + int cur_bus; + int bus_in; + int new_phase; + int state; + int clear_req; + int wait_data; + int wait_complete; + int command_pos; + int data_pos; + + int irq; + + double period; + + void *priv; + void (*dma_mode_ext)(void *priv, void *ext_priv); + int (*dma_send_ext)(void *priv, void *ext_priv); + int (*dma_initiator_receive_ext)(void *priv, void *ext_priv); + void (*timer)(void *ext_priv, double period); +} ncr_t; + +extern int ncr5380_cmd_len[8]; + +extern void ncr5380_irq(ncr_t *ncr, int set_irq); +extern uint32_t ncr5380_get_bus_host(ncr_t *ncr); +extern void ncr5380_bus_read(ncr_t *ncr); +extern void ncr5380_bus_update(ncr_t *ncr, int bus); +extern void ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr); +extern uint8_t ncr5380_read(uint16_t port, ncr_t *ncr); + +#ifdef EMU_DEVICE_H extern const device_t scsi_lcs6821n_device; extern const device_t scsi_rt1000b_device; extern const device_t scsi_rt1000mc_device; extern const device_t scsi_t128_device; +extern const device_t scsi_t228_device; extern const device_t scsi_t130b_device; extern const device_t scsi_ls2000_device; #if defined(DEV_BRANCH) && defined(USE_SUMO) extern const device_t scsi_scsiat_device; #endif +#endif #endif /*SCSI_NCR5380_H*/ diff --git a/src/scsi/CMakeLists.txt b/src/scsi/CMakeLists.txt index addde844e..01e20b929 100644 --- a/src/scsi/CMakeLists.txt +++ b/src/scsi/CMakeLists.txt @@ -14,5 +14,5 @@ # add_library(scsi OBJECT scsi.c scsi_device.c scsi_cdrom.c scsi_disk.c - scsi_x54x.c scsi_aha154x.c scsi_buslogic.c scsi_ncr5380.c - scsi_ncr53c8xx.c scsi_pcscsi.c scsi_spock.c) + scsi_x54x.c scsi_aha154x.c scsi_buslogic.c scsi_ncr5380.c scsi_ncr53c400.c + scsi_t128.c scsi_ncr53c8xx.c scsi_pcscsi.c scsi_spock.c) diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index 94c9048ef..328810a2f 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -82,6 +82,7 @@ static SCSI_CARD scsi_cards[] = { { &scsi_rt1000b_device, }, { &scsi_rt1000mc_device, }, { &scsi_t128_device, }, + { &scsi_t228_device, }, { &scsi_t130b_device, }, { &aha1640_device, }, { &buslogic_640a_device, }, diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index a6420fb01..3a49085ec 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -1001,7 +1001,7 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) case CDROM_TYPE_TOSHIBA_XM3301TA_0272: case CDROM_TYPE_TOSHIBA_XM5701TA_3136: case CDROM_TYPE_TOSHIBA_SDM1401_1008: - bytes_per_second = 176.0 * 1024.0; + bytes_per_second = 176400.0; bytes_per_second *= (double) dev->drv->cur_speed; break; } diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index e9ebe8504..d113d2cb3 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -6,8 +6,8 @@ * * This file is part of the 86Box distribution. * - * Implementation of the NCR 5380 series of SCSI Host Adapters - * made by NCR. These controllers were designed for the ISA bus. + * Implementation of the NCR 5380 chip made by NCR + * and used in various controllers. * * * @@ -16,8 +16,8 @@ * Fred N. van Kempen, * * Copyright 2017-2019 Sarah Walker. - * Copyright 2017-2019 TheCollector1995. * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2017-2024 TheCollector1995. */ #include #include @@ -42,156 +42,13 @@ #include <86box/scsi_device.h> #include <86box/scsi_ncr5380.h> -#define LCS6821N_ROM "roms/scsi/ncr5380/Longshine LCS-6821N - BIOS version 1.04.bin" -#define RT1000B_810R_ROM "roms/scsi/ncr5380/Rancho_RT1000_RTBios_version_8.10R.bin" -#define RT1000B_820R_ROM "roms/scsi/ncr5380/RTBIOS82.ROM" -#define T130B_ROM "roms/scsi/ncr5380/trantor_t130b_bios_v2.14.bin" -#define T128_ROM "roms/scsi/ncr5380/trantor_t128_bios_v1.12.bin" -#define COREL_LS2000_ROM "roms/scsi/ncr5380/Corel LS2000 - BIOS ROM - Ver 1.65.bin" - -#define NCR_CURDATA 0 /* current SCSI data (read only) */ -#define NCR_OUTDATA 0 /* output data (write only) */ -#define NCR_INITCOMMAND 1 /* initiator command (read/write) */ -#define NCR_MODE 2 /* mode (read/write) */ -#define NCR_TARGETCMD 3 /* target command (read/write) */ -#define NCR_SELENABLE 4 /* select enable (write only) */ -#define NCR_BUSSTATUS 4 /* bus status (read only) */ -#define NCR_STARTDMA 5 /* start DMA send (write only) */ -#define NCR_BUSANDSTAT 5 /* bus and status (read only) */ -#define NCR_DMATARGET 6 /* DMA target (write only) */ -#define NCR_INPUTDATA 6 /* input data (read only) */ -#define NCR_DMAINIRECV 7 /* DMA initiator receive (write only) */ -#define NCR_RESETPARITY 7 /* reset parity/interrupt (read only) */ - -#define ICR_DBP 0x01 -#define ICR_ATN 0x02 -#define ICR_SEL 0x04 -#define ICR_BSY 0x08 -#define ICR_ACK 0x10 -#define ICR_ARB_LOST 0x20 -#define ICR_ARB_IN_PROGRESS 0x40 - -#define MODE_ARBITRATE 0x01 -#define MODE_DMA 0x02 -#define MODE_MONITOR_BUSY 0x04 -#define MODE_ENA_EOP_INT 0x08 - -#define STATUS_ACK 0x01 -#define STATUS_BUSY_ERROR 0x04 -#define STATUS_PHASE_MATCH 0x08 -#define STATUS_INT 0x10 -#define STATUS_DRQ 0x40 -#define STATUS_END_OF_DMA 0x80 - -#define TCR_IO 0x01 -#define TCR_CD 0x02 -#define TCR_MSG 0x04 -#define TCR_REQ 0x08 -#define TCR_LAST_BYTE_SENT 0x80 - -#define CTRL_DATA_DIR 0x40 -#define STATUS_BUFFER_NOT_READY 0x04 -#define STATUS_53C80_ACCESSIBLE 0x80 - -typedef struct ncr_t { - uint8_t icr; - uint8_t mode; - uint8_t tcr; - uint8_t data_wait; - uint8_t isr; - uint8_t output_data; - uint8_t target_id; - uint8_t tx_data; - uint8_t msglun; - - uint8_t command[20]; - uint8_t msgout[4]; - int msgout_pos; - int is_msgout; - - int dma_mode; - int cur_bus; - int bus_in; - int new_phase; - int state; - int clear_req; - int wait_data; - int wait_complete; - int command_pos; - int data_pos; -} ncr_t; - -typedef struct t128_t { - uint8_t ctrl; - uint8_t status; - uint8_t buffer[512]; - uint8_t ext_ram[0x80]; - uint8_t block_count; - - int block_loaded; - int pos, host_pos; - - int bios_enabled; -} t128_t; - -typedef struct ncr5380_t { - ncr_t ncr; - t128_t t128; - - const char *name; - - uint8_t buffer[128]; - uint8_t int_ram[0x40]; - uint8_t ext_ram[0x600]; - - uint32_t rom_addr; - uint16_t base; - - int8_t irq; - int8_t type; - int8_t bios_ver; - uint8_t block_count; - uint8_t status_ctrl; - uint8_t bus, pad; - - rom_t bios_rom; - mem_mapping_t mapping; - - int block_count_loaded; - - int buffer_pos; - int buffer_host_pos; - - int dma_enabled; - - pc_timer_t timer; - double period; - - int ncr_busy; - uint8_t pos_regs[8]; -} ncr5380_t; - -#define STATE_IDLE 0 -#define STATE_COMMAND 1 -#define STATE_DATAIN 2 -#define STATE_DATAOUT 3 -#define STATE_STATUS 4 -#define STATE_MESSAGEIN 5 -#define STATE_SELECT 6 -#define STATE_MESSAGEOUT 7 -#define STATE_MESSAGE_ID 8 - -#define DMA_IDLE 0 -#define DMA_SEND 1 -#define DMA_INITIATOR_RECEIVE 2 - -static int cmd_len[8] = { 6, 10, 10, 6, 16, 12, 10, 6 }; +int ncr5380_cmd_len[8] = { 6, 10, 10, 6, 16, 12, 10, 6 }; #ifdef ENABLE_NCR5380_LOG int ncr5380_do_log = ENABLE_NCR5380_LOG; static void -ncr_log(const char *fmt, ...) +ncr5380_log(const char *fmt, ...) { va_list ap; @@ -202,28 +59,27 @@ ncr_log(const char *fmt, ...) } } #else -# define ncr_log(fmt, ...) +# define ncr5380_log(fmt, ...) #endif #define SET_BUS_STATE(ncr, state) ncr->cur_bus = (ncr->cur_bus & ~(SCSI_PHASE_MESSAGE_IN)) | (state & (SCSI_PHASE_MESSAGE_IN)) -static void -ncr_callback(void *priv); - -static void -ncr_irq(ncr5380_t *ncr_dev, ncr_t *ncr, int set_irq) +void +ncr5380_irq(ncr_t *ncr, int set_irq) { if (set_irq) { ncr->isr |= STATUS_INT; - picint(1 << ncr_dev->irq); + if (ncr->irq != -1) + picint(1 << ncr->irq); } else { ncr->isr &= ~STATUS_INT; - picintc(1 << ncr_dev->irq); + if (ncr->irq != 1) + picintc(1 << ncr->irq); } } static int -get_dev_id(uint8_t data) +ncr5380_get_dev_id(uint8_t data) { for (uint8_t c = 0; c < SCSI_ID_MAX; c++) { if (data & (1 << c)) @@ -234,7 +90,7 @@ get_dev_id(uint8_t data) } static int -getmsglen(uint8_t *msgp, int len) +ncr5380_getmsglen(uint8_t *msgp, int len) { uint8_t msg = msgp[0]; if (msg == 0 || (msg >= 0x02 && msg <= 0x1f) || msg >= 0x80) @@ -247,21 +103,32 @@ getmsglen(uint8_t *msgp, int len) } static void -ncr_reset(ncr5380_t *ncr_dev, ncr_t *ncr) +ncr5380_reset(ncr_t *ncr) { - memset(ncr, 0x00, sizeof(ncr_t)); - ncr_log("NCR Reset\n"); + ncr->command_pos = 0; + ncr->data_pos = 0; + ncr->state = STATE_IDLE; + ncr->clear_req = 0; + ncr->cur_bus = 0; + ncr->tx_data = 0; + ncr->output_data = 0; + ncr->data_wait = 0; + ncr->mode = 0; + ncr->tcr = 0; + ncr->icr = 0; + ncr->dma_mode = DMA_IDLE; + ncr5380_log("NCR Reset\n"); - timer_stop(&ncr_dev->timer); + ncr->timer(ncr->priv, 0.0); for (int i = 0; i < 8; i++) - scsi_device_reset(&scsi_devices[ncr_dev->bus][i]); + scsi_device_reset(&scsi_devices[ncr->bus][i]); - ncr_irq(ncr_dev, ncr, 0); + ncr5380_irq(ncr, 0); } -static uint32_t -get_bus_host(ncr_t *ncr) +uint32_t +ncr5380_get_bus_host(ncr_t *ncr) { uint32_t bus_host = 0; @@ -298,10 +165,9 @@ get_bus_host(ncr_t *ncr) return (bus_host | BUS_SETDATA(ncr->output_data)); } -static void -ncr_bus_read(ncr5380_t *ncr_dev) +void +ncr5380_bus_read(ncr_t *ncr) { - ncr_t *ncr = &ncr_dev->ncr; const scsi_device_t *dev; int phase; @@ -309,7 +175,7 @@ ncr_bus_read(ncr5380_t *ncr_dev) if (ncr->clear_req) { ncr->clear_req--; if (!ncr->clear_req) { - ncr_log("Prelude to command data\n"); + ncr5380_log("Prelude to command data\n"); SET_BUS_STATE(ncr, ncr->new_phase); ncr->cur_bus |= BUS_REQ; } @@ -318,7 +184,7 @@ ncr_bus_read(ncr5380_t *ncr_dev) if (ncr->wait_data) { ncr->wait_data--; if (!ncr->wait_data) { - dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + dev = &scsi_devices[ncr->bus][ncr->target_id]; SET_BUS_STATE(ncr, ncr->new_phase); phase = (ncr->cur_bus & SCSI_PHASE_MESSAGE_IN); @@ -354,12 +220,10 @@ ncr_bus_read(ncr5380_t *ncr_dev) } } -static void -ncr_bus_update(void *priv, int bus) +void +ncr5380_bus_update(ncr_t *ncr, int bus) { - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - ncr_t *ncr = &ncr_dev->ncr; - scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; double p; uint8_t sel_data; int msglen; @@ -368,25 +232,25 @@ ncr_bus_update(void *priv, int bus) if (bus & BUS_ARB) ncr->state = STATE_IDLE; - ncr_log("State = %i\n", ncr->state); + ncr5380_log("State = %i\n", ncr->state); switch (ncr->state) { case STATE_IDLE: ncr->clear_req = ncr->wait_data = ncr->wait_complete = 0; if ((bus & BUS_SEL) && !(bus & BUS_BSY)) { - ncr_log("Selection phase\n"); + ncr5380_log("Selection phase\n"); sel_data = BUS_GETDATA(bus); - ncr->target_id = get_dev_id(sel_data); + ncr->target_id = ncr5380_get_dev_id(sel_data); - ncr_log("Select - target ID = %i\n", ncr->target_id); + ncr5380_log("Select - target ID = %i\n", ncr->target_id); /*Once the device has been found and selected, mark it as busy*/ - if ((ncr->target_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[ncr_dev->bus][ncr->target_id])) { + if ((ncr->target_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[ncr->bus][ncr->target_id])) { ncr->cur_bus |= BUS_BSY; ncr->state = STATE_SELECT; } else { - ncr_log("Device not found at ID %i, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus); + ncr5380_log("Device not found at ID %i, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus); ncr->cur_bus = 0; } } @@ -394,11 +258,11 @@ ncr_bus_update(void *priv, int bus) case STATE_SELECT: if (!(bus & BUS_SEL)) { if (!(bus & BUS_ATN)) { - if ((ncr->target_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[ncr_dev->bus][ncr->target_id])) { - ncr_log("Device found at ID %i, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus); + if ((ncr->target_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[ncr->bus][ncr->target_id])) { + ncr5380_log("Device found at ID %i, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus); ncr->state = STATE_COMMAND; ncr->cur_bus = BUS_BSY | BUS_REQ; - ncr_log("CurBus BSY|REQ=%02x\n", ncr->cur_bus); + ncr5380_log("CurBus BSY|REQ=%02x\n", ncr->cur_bus); ncr->command_pos = 0; SET_BUS_STATE(ncr, SCSI_PHASE_COMMAND); } else { @@ -406,7 +270,7 @@ ncr_bus_update(void *priv, int bus) ncr->cur_bus = 0; } } else { - ncr_log("Set to SCSI Message Out\n"); + ncr5380_log("Set to SCSI Message Out\n"); ncr->new_phase = SCSI_PHASE_MESSAGE_OUT; ncr->wait_data = 4; ncr->msgout_pos = 0; @@ -422,9 +286,9 @@ ncr_bus_update(void *priv, int bus) ncr->new_phase = ncr->cur_bus & SCSI_PHASE_MESSAGE_IN; ncr->cur_bus &= ~BUS_REQ; - ncr_log("Command pos=%i, output data=%02x\n", ncr->command_pos, BUS_GETDATA(bus)); + ncr5380_log("Command pos=%i, output data=%02x\n", ncr->command_pos, BUS_GETDATA(bus)); - if (ncr->command_pos == cmd_len[(ncr->command[0] >> 5) & 7]) { + if (ncr->command_pos == ncr5380_cmd_len[(ncr->command[0] >> 5) & 7]) { if (ncr->is_msgout) { ncr->is_msgout = 0; #if 0 @@ -435,23 +299,23 @@ ncr_bus_update(void *priv, int bus) /*Reset data position to default*/ ncr->data_pos = 0; - dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + dev = &scsi_devices[ncr->bus][ncr->target_id]; - ncr_log("SCSI Command 0x%02X for ID %d, status code=%02x\n", ncr->command[0], ncr->target_id, dev->status); + ncr5380_log("SCSI Command 0x%02X for ID %d, status code=%02x\n", ncr->command[0], ncr->target_id, dev->status); dev->buffer_length = -1; scsi_device_command_phase0(dev, ncr->command); - ncr_log("SCSI ID %i: Command %02X: Buffer Length %i, SCSI Phase %02X\n", ncr->target_id, ncr->command[0], dev->buffer_length, dev->phase); + ncr5380_log("SCSI ID %i: Command %02X: Buffer Length %i, SCSI Phase %02X\n", ncr->target_id, ncr->command[0], dev->buffer_length, dev->phase); - ncr_dev->period = 1.0; + ncr->period = 1.0; ncr->wait_data = 4; ncr->data_wait = 0; if (dev->status == SCSI_STATUS_OK) { /*If the SCSI phase is Data In or Data Out, allocate the SCSI buffer based on the transfer length of the command*/ - if (dev->buffer_length && (dev->phase == SCSI_PHASE_DATA_IN || dev->phase == SCSI_PHASE_DATA_OUT)) { + if (dev->buffer_length && ((dev->phase == SCSI_PHASE_DATA_IN) || (dev->phase == SCSI_PHASE_DATA_OUT))) { p = scsi_device_get_callback(dev); - ncr_dev->period = (p > 0.0) ? p : (((double) dev->buffer_length) * 0.2); - ncr_log("SCSI ID %i: command 0x%02x for p = %lf, update = %lf, len = %i, dmamode = %x\n", ncr->target_id, ncr->command[0], scsi_device_get_callback(dev), ncr_dev->period, dev->buffer_length, ncr->dma_mode); + ncr->period = (p > 0.0) ? p : (((double) dev->buffer_length) * 0.2); + ncr5380_log("SCSI ID %i: command 0x%02x for p = %lf, update = %lf, len = %i, dmamode = %x\n", ncr->target_id, ncr->command[0], scsi_device_get_callback(dev), ncr->period, dev->buffer_length, ncr->dma_mode); } } ncr->new_phase = dev->phase; @@ -459,7 +323,7 @@ ncr_bus_update(void *priv, int bus) } break; case STATE_DATAIN: - dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + dev = &scsi_devices[ncr->bus][ncr->target_id]; if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { if (ncr->data_pos >= dev->buffer_length) { ncr->cur_bus &= ~BUS_REQ; @@ -472,10 +336,10 @@ ncr_bus_update(void *priv, int bus) ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(ncr->tx_data) | BUS_DBP | BUS_REQ; if (ncr->dma_mode == DMA_IDLE) { /*If a data in command that is not read 6/10 has been issued*/ ncr->data_wait |= 1; - ncr_log("DMA mode idle in\n"); - timer_on_auto(&ncr_dev->timer, ncr_dev->period); + ncr5380_log("DMA mode idle in\n"); + ncr->timer(ncr->priv, ncr->period); } else { - ncr_log("DMA mode IN.\n"); + ncr5380_log("DMA mode IN.\n"); ncr->clear_req = 3; } @@ -485,7 +349,7 @@ ncr_bus_update(void *priv, int bus) } break; case STATE_DATAOUT: - dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + dev = &scsi_devices[ncr->bus][ncr->target_id]; if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { dev->sc->temp_buffer[ncr->data_pos++] = BUS_GETDATA(bus); @@ -499,20 +363,20 @@ ncr_bus_update(void *priv, int bus) /*More data is to be transferred, place a request*/ if (ncr->dma_mode == DMA_IDLE) { /*If a data out command that is not write 6/10 has been issued*/ ncr->data_wait |= 1; - ncr_log("DMA mode idle out\n"); - timer_on_auto(&ncr_dev->timer, ncr_dev->period); + ncr5380_log("DMA mode idle out\n"); + ncr->timer(ncr->priv, ncr->period); } else ncr->clear_req = 3; ncr->cur_bus &= ~BUS_REQ; - ncr_log("CurBus ~REQ_DataOut=%02x\n", ncr->cur_bus); + ncr5380_log("CurBus ~REQ_DataOut=%02x\n", ncr->cur_bus); } } break; case STATE_STATUS: if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { /*All transfers done, wait until next transfer*/ - scsi_device_identify(&scsi_devices[ncr_dev->bus][ncr->target_id], SCSI_LUN_USE_CDB); + scsi_device_identify(&scsi_devices[ncr->bus][ncr->target_id], SCSI_LUN_USE_CDB); ncr->cur_bus &= ~BUS_REQ; ncr->new_phase = SCSI_PHASE_MESSAGE_IN; ncr->wait_data = 4; @@ -527,10 +391,10 @@ ncr_bus_update(void *priv, int bus) } break; case STATE_MESSAGEOUT: - ncr_log("Ack on MSGOUT = %02x\n", (bus & BUS_ACK)); + ncr5380_log("Ack on MSGOUT = %02x\n", (bus & BUS_ACK)); if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { ncr->msgout[ncr->msgout_pos++] = BUS_GETDATA(bus); - msglen = getmsglen(ncr->msgout, ncr->msgout_pos); + msglen = ncr5380_getmsglen(ncr->msgout, ncr->msgout_pos); if (ncr->msgout_pos >= msglen) { if ((ncr->msgout[0] & (0x80 | 0x20)) == 0x80) ncr->msglun = ncr->msgout[0] & 7; @@ -540,12 +404,12 @@ ncr_bus_update(void *priv, int bus) } break; case STATE_MESSAGE_ID: - if ((ncr->target_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[ncr_dev->bus][ncr->target_id])) { - ncr_log("Device found at ID %i on MSGOUT, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus); - scsi_device_identify(&scsi_devices[ncr_dev->bus][ncr->target_id], ncr->msglun); + if ((ncr->target_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[ncr->bus][ncr->target_id])) { + ncr5380_log("Device found at ID %i on MSGOUT, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus); + scsi_device_identify(&scsi_devices[ncr->bus][ncr->target_id], ncr->msglun); ncr->state = STATE_COMMAND; ncr->cur_bus = BUS_BSY | BUS_REQ; - ncr_log("CurBus BSY|REQ=%02x\n", ncr->cur_bus); + ncr5380_log("CurBus BSY|REQ=%02x\n", ncr->cur_bus); ncr->command_pos = 0; SET_BUS_STATE(ncr, SCSI_PHASE_COMMAND); } @@ -558,33 +422,30 @@ ncr_bus_update(void *priv, int bus) ncr->bus_in = bus; } -static void -ncr_write(uint16_t port, uint8_t val, void *priv) +void +ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr) { - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - ncr_t *ncr = &ncr_dev->ncr; - scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; int bus_host = 0; - ncr_log("NCR5380 write(%04x,%02x)\n", port & 7, val); + ncr5380_log("NCR5380 write(%04x,%02x)\n", port & 7, val); switch (port & 7) { case 0: /* Output data register */ - ncr_log("Write: Output data register, val = %02x\n", val); + ncr5380_log("Write: Output data register, val = %02x\n", val); ncr->output_data = val; break; case 1: /* Initiator Command Register */ - ncr_log("Write: Initiator command register\n"); + ncr5380_log("Write: Initiator command register\n"); if ((val & 0x80) && !(ncr->icr & 0x80)) { - ncr_log("Resetting the 5380\n"); - ncr_reset(ncr_dev, &ncr_dev->ncr); + ncr5380_log("Resetting the 5380\n"); + ncr5380_reset(ncr); } ncr->icr = val; break; case 2: /* Mode register */ - ncr_log("Write: Mode register, val=%02x.\n", val); + ncr5380_log("Write: Mode register, val=%02x.\n", val); if ((val & MODE_ARBITRATE) && !(ncr->mode & MODE_ARBITRATE)) { ncr->icr &= ~ICR_ARB_LOST; ncr->icr |= ICR_ARB_IN_PROGRESS; @@ -592,132 +453,85 @@ ncr_write(uint16_t port, uint8_t val, void *priv) ncr->mode = val; - if (ncr_dev->type == 3) { - /*Don't stop the timer until it finishes the transfer*/ - if (ncr_dev->t128.block_loaded && (ncr->mode & MODE_DMA)) { - ncr_log("Continuing DMA mode\n"); - timer_on_auto(&ncr_dev->timer, ncr_dev->period + 1.0); - } - - /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ - if (!ncr_dev->t128.block_loaded && !(ncr->mode & MODE_DMA)) { - ncr_log("No DMA mode\n"); - ncr->tcr &= ~TCR_LAST_BYTE_SENT; - ncr->isr &= ~STATUS_END_OF_DMA; - ncr->dma_mode = DMA_IDLE; - } - } else { - /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ - if (!ncr_dev->block_count_loaded && !(ncr->mode & MODE_DMA)) { - ncr_log("No DMA mode\n"); - ncr->tcr &= ~TCR_LAST_BYTE_SENT; - ncr->isr &= ~STATUS_END_OF_DMA; - ncr->dma_mode = DMA_IDLE; - } - } + ncr->dma_mode_ext(ncr, ncr->priv); break; case 3: /* Target Command Register */ - ncr_log("Write: Target Command register\n"); + ncr5380_log("Write: Target Command register\n"); ncr->tcr = val; break; case 4: /* Select Enable Register */ - ncr_log("Write: Select Enable register\n"); + ncr5380_log("Write: Select Enable register\n"); break; case 5: /* start DMA Send */ - ncr_log("Write: start DMA send register\n"); + ncr5380_log("Write: start DMA send register\n"); /*a Write 6/10 has occurred, start the timer when the block count is loaded*/ ncr->dma_mode = DMA_SEND; - if (ncr_dev->type == 3) { - if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer) && (dev->buffer_length > 0)) { - memset(ncr_dev->t128.buffer, 0, MIN(512, dev->buffer_length)); - ncr_dev->t128.status |= 0x04; - ncr_dev->t128.host_pos = 0; - ncr_dev->t128.block_count = dev->buffer_length >> 9; - - if (dev->buffer_length < 512) - ncr_dev->t128.block_count = 1; - - ncr_dev->t128.block_loaded = 1; - } - } + if (ncr->dma_send_ext) + ncr->dma_send_ext(ncr, ncr->priv); break; case 7: /* start DMA Initiator Receive */ - ncr_log("Write: start DMA initiator receive register, dma? = %02x\n", ncr->mode & MODE_DMA); + ncr5380_log("Write: start DMA initiator receive register, dma? = %02x\n", ncr->mode & MODE_DMA); /*a Read 6/10 has occurred, start the timer when the block count is loaded*/ ncr->dma_mode = DMA_INITIATOR_RECEIVE; - if (ncr_dev->type == 3) { - if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer) && (dev->buffer_length > 0)) { - memset(ncr_dev->t128.buffer, 0, MIN(512, dev->buffer_length)); - ncr_dev->t128.status |= 0x04; - ncr_dev->t128.host_pos = MIN(512, dev->buffer_length); - ncr_dev->t128.block_count = dev->buffer_length >> 9; - - if (dev->buffer_length < 512) - ncr_dev->t128.block_count = 1; - - ncr_dev->t128.block_loaded = 1; - timer_on_auto(&ncr_dev->timer, 0.02); - } - } + if (ncr->dma_initiator_receive_ext) + ncr->dma_initiator_receive_ext(ncr, ncr->priv); break; default: - ncr_log("NCR5380: bad write %04x %02x\n", port, val); + ncr5380_log("NCR5380: bad write %04x %02x\n", port, val); break; } - bus_host = get_bus_host(ncr); - ncr_bus_update(priv, bus_host); + bus_host = ncr5380_get_bus_host(ncr); + ncr5380_bus_update(ncr, bus_host); } -static uint8_t -ncr_read(uint16_t port, void *priv) +uint8_t +ncr5380_read(uint16_t port, ncr_t *ncr) { - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - ncr_t *ncr = &ncr_dev->ncr; - uint8_t ret = 0xff; + uint8_t ret = 0xff; int bus; int bus_state; switch (port & 7) { case 0: /* Current SCSI data */ - ncr_log("Read: Current SCSI data register\n"); + ncr5380_log("Read: Current SCSI data register\n"); if (ncr->icr & ICR_DBP) { /*Return the data from the output register if on data bus phase from ICR*/ - ncr_log("Data Bus Phase, ret = %02x\n", ncr->output_data); + ncr5380_log("Data Bus Phase, ret = %02x\n", ncr->output_data); ret = ncr->output_data; } else { /*Return the data from the SCSI bus*/ - ncr_bus_read(ncr_dev); - ncr_log("NCR GetData=%02x\n", BUS_GETDATA(ncr->cur_bus)); + ncr5380_bus_read(ncr); + ncr5380_log("NCR GetData=%02x\n", BUS_GETDATA(ncr->cur_bus)); ret = BUS_GETDATA(ncr->cur_bus); } break; case 1: /* Initiator Command Register */ - ncr_log("Read: Initiator Command register, NCR ICR Read=%02x\n", ncr->icr); + ncr5380_log("Read: Initiator Command register, NCR ICR Read=%02x\n", ncr->icr); ret = ncr->icr; break; case 2: /* Mode register */ - ncr_log("Read: Mode register = %02x.\n", ncr->mode); + ncr5380_log("Read: Mode register = %02x.\n", ncr->mode); ret = ncr->mode; break; case 3: /* Target Command Register */ - ncr_log("Read: Target Command register, NCR target stat=%02x\n", ncr->tcr); + ncr5380_log("Read: Target Command register, NCR target stat=%02x\n", ncr->tcr); ret = ncr->tcr; break; case 4: /* Current SCSI Bus status */ - ncr_log("Read: SCSI bus status register\n"); + ncr5380_log("Read: SCSI bus status register\n"); ret = 0; - ncr_bus_read(ncr_dev); - ncr_log("NCR cur bus stat=%02x\n", ncr->cur_bus & 0xff); + ncr5380_bus_read(ncr); + ncr5380_log("NCR cur bus stat=%02x\n", ncr->cur_bus & 0xff); ret |= (ncr->cur_bus & 0xff); if (ncr->icr & ICR_SEL) ret |= BUS_SEL; @@ -726,19 +540,19 @@ ncr_read(uint16_t port, void *priv) break; case 5: /* Bus and Status register */ - ncr_log("Read: Bus and Status register\n"); + ncr5380_log("Read: Bus and Status register\n"); ret = 0; - bus = get_bus_host(ncr); - ncr_log("Get host from Interrupt\n"); + bus = ncr5380_get_bus_host(ncr); + ncr5380_log("Get host from Interrupt\n"); /*Check if the phase in process matches with TCR's*/ if ((bus & SCSI_PHASE_MESSAGE_IN) == (ncr->cur_bus & SCSI_PHASE_MESSAGE_IN)) { - ncr_log("Phase match\n"); + ncr5380_log("Phase match\n"); ret |= STATUS_PHASE_MATCH; } - ncr_bus_read(ncr_dev); + ncr5380_bus_read(ncr); bus = ncr->cur_bus; if ((bus & BUS_ACK) || (ncr->icr & ICR_ACK)) @@ -747,7 +561,7 @@ ncr_read(uint16_t port, void *priv) ret |= 0x02; if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA)) { - ncr_log("Entering DMA mode\n"); + ncr5380_log("Entering DMA mode\n"); ret |= STATUS_DRQ; bus_state = 0; @@ -759,12 +573,12 @@ ncr_read(uint16_t port, void *priv) if (bus & BUS_MSG) bus_state |= TCR_MSG; if ((ncr->tcr & 7) != bus_state) { - ncr_irq(ncr_dev, ncr, 1); - ncr_log("IRQ issued\n"); + ncr5380_irq(ncr, 1); + ncr5380_log("IRQ issued\n"); } } if (!(bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) { - ncr_log("Busy error\n"); + ncr5380_log("Busy error\n"); ret |= STATUS_BUSY_ERROR; } ret |= (ncr->isr & (STATUS_INT | STATUS_END_OF_DMA)); @@ -776,1185 +590,16 @@ ncr_read(uint16_t port, void *priv) case 7: /* reset Parity/Interrupt */ ncr->isr &= ~(STATUS_BUSY_ERROR | 0x20); - ncr_irq(ncr_dev, ncr, 0); - ncr_log("Reset Interrupt\n"); + ncr5380_irq(ncr, 0); + ncr5380_log("Reset Interrupt\n"); break; default: - ncr_log("NCR5380: bad read %04x\n", port); + ncr5380_log("NCR5380: bad read %04x\n", port); break; } - ncr_log("NCR5380 read(%04x)=%02x\n", port & 7, ret); + ncr5380_log("NCR5380 read(%04x)=%02x\n", port & 7, ret); return ret; } - -/* Memory-mapped I/O READ handler. */ -static uint8_t -memio_read(uint32_t addr, void *priv) -{ - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - ncr_t *ncr = &ncr_dev->ncr; - scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; - uint8_t ret = 0xff; - - addr &= 0x3fff; - - if (addr < 0x2000) - ret = ncr_dev->bios_rom.rom[addr & 0x1fff]; - else if (addr < 0x3800) - ret = 0xff; - else if (addr >= 0x3a00) - ret = ncr_dev->ext_ram[addr - 0x3a00]; - else - switch (addr & 0x3f80) { - case 0x3800: -#if ENABLE_NCR5380_LOG - ncr_log("Read intRAM %02x %02x\n", addr & 0x3f, ncr_dev->int_ram[addr & 0x3f]); -#endif - ret = ncr_dev->int_ram[addr & 0x3f]; - break; - - case 0x3880: -#if ENABLE_NCR5380_LOG - ncr_log("Read 53c80 %04x\n", addr); -#endif - ret = ncr_read(addr, ncr_dev); - break; - - case 0x3900: - if (ncr_dev->buffer_host_pos >= MIN(128, dev->buffer_length) || (!(ncr_dev->status_ctrl & CTRL_DATA_DIR))) { - ret = 0xff; - ncr_log("No Read.\n"); - } else { - ret = ncr_dev->buffer[ncr_dev->buffer_host_pos++]; - ncr_log("Read host pos = %i, ret = %02x\n", ncr_dev->buffer_host_pos, ret); - - if (ncr_dev->buffer_host_pos == MIN(128, dev->buffer_length)) { - ncr_dev->status_ctrl |= STATUS_BUFFER_NOT_READY; - ncr_log("Transfer busy read, status = %02x\n", ncr_dev->status_ctrl); - } - } - break; - - case 0x3980: - switch (addr) { - case 0x3980: /* status */ - ret = ncr_dev->status_ctrl; - ncr_log("NCR status ctrl read=%02x\n", ncr_dev->status_ctrl & STATUS_BUFFER_NOT_READY); - if (!ncr_dev->ncr_busy) - ret |= STATUS_53C80_ACCESSIBLE; - if (ncr->mode & 0x30) { /*Parity bits*/ - if (!(ncr->mode & MODE_DMA)) { /*This is to avoid RTBios 8.10R BIOS problems with the hard disk and detection.*/ - ret |= 0x01; /*If the parity bits are set, bit 0 of the 53c400 status port should be set as well.*/ - ncr->mode = 0; /*Required by RTASPI10.SYS otherwise it won't initialize.*/ - } - } - ncr_log("NCR 53c400 status = %02x.\n", ret); - break; - - case 0x3981: /* block counter register*/ - ret = ncr_dev->block_count; - break; - - case 0x3982: /* switch register read */ - ret = 0xf8; - ret |= (ncr_dev->irq & 0x07); - ncr_log("Switches read=%02x.\n", ret); - break; - - default: - break; - } - break; - - default: - break; - } - -#if ENABLE_NCR5380_LOG - if (addr >= 0x3880) - ncr_log("memio_read(%08x)=%02x\n", addr, ret); -#endif - - return ret; -} - -/* Memory-mapped I/O WRITE handler. */ -static void -memio_write(uint32_t addr, uint8_t val, void *priv) -{ - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - ncr_t *ncr = &ncr_dev->ncr; - scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; - - addr &= 0x3fff; - - if (addr >= 0x3a00) - ncr_dev->ext_ram[addr - 0x3a00] = val; - else - switch (addr & 0x3f80) { - case 0x3800: - ncr_dev->int_ram[addr & 0x3f] = val; - break; - - case 0x3880: - ncr_write(addr, val, ncr_dev); - break; - - case 0x3900: - if (!(ncr_dev->status_ctrl & CTRL_DATA_DIR) && ncr_dev->buffer_host_pos < MIN(128, dev->buffer_length)) { - ncr_dev->buffer[ncr_dev->buffer_host_pos++] = val; - - ncr_log("Write host pos = %i, val = %02x\n", ncr_dev->buffer_host_pos, val); - - if (ncr_dev->buffer_host_pos == MIN(128, dev->buffer_length)) { - ncr_dev->status_ctrl |= STATUS_BUFFER_NOT_READY; - ncr_dev->ncr_busy = 1; - } - } - break; - - case 0x3980: - switch (addr) { - case 0x3980: /* Control */ - ncr_log("NCR 53c400 control = %02x, mode = %02x.\n", val, ncr->mode); - if ((val & CTRL_DATA_DIR) && !(ncr_dev->status_ctrl & CTRL_DATA_DIR)) { - ncr_dev->buffer_host_pos = MIN(128, dev->buffer_length); - ncr_dev->status_ctrl |= STATUS_BUFFER_NOT_READY; - } else if (!(val & CTRL_DATA_DIR) && (ncr_dev->status_ctrl & CTRL_DATA_DIR)) { - ncr_dev->buffer_host_pos = 0; - ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - } - ncr_dev->status_ctrl = (ncr_dev->status_ctrl & 0x87) | (val & 0x78); - break; - - case 0x3981: /* block counter register */ - ncr_log("Write block counter register: val=%d, dma mode=%x, period=%lf\n", val, ncr->dma_mode, ncr_dev->period); - ncr_dev->block_count = val; - ncr_dev->block_count_loaded = 1; - - if (ncr_dev->status_ctrl & CTRL_DATA_DIR) { - ncr_dev->buffer_host_pos = MIN(128, dev->buffer_length); - ncr_dev->status_ctrl |= STATUS_BUFFER_NOT_READY; - } else { - ncr_dev->buffer_host_pos = 0; - ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - } - if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer) && (dev->buffer_length > 0)) { - memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length)); - ncr_log("DMA timer on\n"); - timer_on_auto(&ncr_dev->timer, ncr_dev->period); - } - break; - - default: - break; - } - break; - - default: - break; - } -} - -/* Memory-mapped I/O READ handler for the Trantor T130B. */ -static uint8_t -t130b_read(uint32_t addr, void *priv) -{ - const ncr5380_t *ncr_dev = (ncr5380_t *) priv; - uint8_t ret = 0xff; - - addr &= 0x3fff; - if (addr < 0x1800) - ret = ncr_dev->bios_rom.rom[addr & 0x1fff]; - else if (addr >= 0x1800 && addr < 0x1880) - ret = ncr_dev->ext_ram[addr & 0x7f]; - - ncr_log("MEM: Reading %02X from %08X\n", ret, addr); - return ret; -} - -/* Memory-mapped I/O WRITE handler for the Trantor T130B. */ -static void -t130b_write(uint32_t addr, uint8_t val, void *priv) -{ - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - - addr &= 0x3fff; - ncr_log("MEM: Writing %02X to %08X\n", val, addr); - if (addr >= 0x1800 && addr < 0x1880) - ncr_dev->ext_ram[addr & 0x7f] = val; -} - -static uint8_t -t130b_in(uint16_t port, void *priv) -{ - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - uint8_t ret = 0xff; - - switch (port & 0x0f) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - ret = memio_read((port & 7) | 0x3980, ncr_dev); - break; - - case 0x04: - case 0x05: - ret = memio_read(0x3900, ncr_dev); - break; - - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x0c: - case 0x0d: - case 0x0e: - case 0x0f: - ret = ncr_read(port, ncr_dev); - break; - - default: - break; - } - - ncr_log("I/O: Reading %02X from %04X\n", ret, port); - return ret; -} - -static void -t130b_out(uint16_t port, uint8_t val, void *priv) -{ - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - - ncr_log("I/O: Writing %02X to %04X\n", val, port); - - switch (port & 0x0f) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - memio_write((port & 7) | 0x3980, val, ncr_dev); - break; - - case 0x04: - case 0x05: - memio_write(0x3900, val, ncr_dev); - break; - - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x0c: - case 0x0d: - case 0x0e: - case 0x0f: - ncr_write(port, val, ncr_dev); - break; - - default: - break; - } -} - -static void -ncr_callback(void *priv) -{ - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - ncr_t *ncr = &ncr_dev->ncr; - scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; - int bus; - int bytes_tx = 0; - int limit = 100; - uint8_t temp; - - if (ncr_dev->type != 3) { - if (ncr->dma_mode != DMA_IDLE) - timer_on_auto(&ncr_dev->timer, 1.0); - } else { - if ((ncr->dma_mode != DMA_IDLE) && (ncr->mode & MODE_DMA) && ncr_dev->t128.block_loaded) { - if ((ncr_dev->t128.host_pos == MIN(512, dev->buffer_length)) && ncr_dev->t128.block_count) - ncr_dev->t128.status |= 0x04; - - timer_on_auto(&ncr_dev->timer, ncr_dev->period / 55.0); - } - } - - if (ncr->data_wait & 1) { - ncr->clear_req = 3; - ncr->data_wait &= ~1; - if (ncr_dev->type == 3) { - if (ncr->dma_mode == DMA_IDLE) - return; - } - } - - if (ncr_dev->type != 3) { - if (ncr->dma_mode == DMA_IDLE) - return; - } - - switch (ncr->dma_mode) { - case DMA_SEND: - if (ncr_dev->type != 3) { - if (ncr_dev->status_ctrl & CTRL_DATA_DIR) { - ncr_log("DMA_SEND with DMA direction set wrong\n"); - break; - } - - if (!(ncr_dev->status_ctrl & STATUS_BUFFER_NOT_READY)) { - ncr_log("Write buffer status ready\n"); - break; - } - - if (!ncr_dev->block_count_loaded) - break; - - while (bytes_tx < limit) { - for (uint8_t c = 0; c < 10; c++) { - ncr_bus_read(ncr_dev); - if (ncr->cur_bus & BUS_REQ) - break; - } - - /* Data ready. */ - temp = ncr_dev->buffer[ncr_dev->buffer_pos]; - - bus = get_bus_host(ncr) & ~BUS_DATAMASK; - bus |= BUS_SETDATA(temp); - - ncr_bus_update(ncr_dev, bus | BUS_ACK); - ncr_bus_update(ncr_dev, bus & ~BUS_ACK); - - ncr_dev->buffer_pos++; - bytes_tx++; - ncr_log("Buffer pos for writing = %d\n", ncr_dev->buffer_pos); - - if (ncr_dev->buffer_pos == MIN(128, dev->buffer_length)) { - bytes_tx = 0; - ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - ncr_dev->buffer_pos = 0; - ncr_dev->buffer_host_pos = 0; - ncr_dev->ncr_busy = 0; - ncr_dev->block_count = (ncr_dev->block_count - 1) & 0xff; - ncr_log("Remaining blocks to be written=%d\n", ncr_dev->block_count); - if (!ncr_dev->block_count) { - ncr_dev->block_count_loaded = 0; - ncr_log("IO End of write transfer\n"); - ncr->tcr |= TCR_LAST_BYTE_SENT; - ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr_dev->timer); - if (ncr->mode & MODE_ENA_EOP_INT) { - ncr_log("NCR write irq\n"); - ncr_irq(ncr_dev, ncr, 1); - } - } - break; - } - } - } else { - if (!(ncr_dev->t128.status & 0x04)) { - ncr_log("Write status busy, block count = %i, host pos = %i\n", ncr_dev->t128.block_count, ncr_dev->t128.host_pos); - break; - } - - if (!ncr_dev->t128.block_loaded) { - ncr_log("Write block not loaded\n"); - break; - } - - if (ncr_dev->t128.host_pos < MIN(512, dev->buffer_length)) - break; - -write_again: - for (uint8_t c = 0; c < 10; c++) { - ncr_bus_read(ncr_dev); - if (ncr->cur_bus & BUS_REQ) - break; - } - - /* Data ready. */ - temp = ncr_dev->t128.buffer[ncr_dev->t128.pos]; - - bus = get_bus_host(ncr) & ~BUS_DATAMASK; - bus |= BUS_SETDATA(temp); - - ncr_bus_update(ncr_dev, bus | BUS_ACK); - ncr_bus_update(ncr_dev, bus & ~BUS_ACK); - - ncr_dev->t128.pos++; - ncr_log("Buffer pos for writing = %d\n", ncr_dev->t128.pos); - - if (ncr_dev->t128.pos == MIN(512, dev->buffer_length)) { - ncr_dev->t128.pos = 0; - ncr_dev->t128.host_pos = 0; - ncr_dev->t128.status &= ~0x02; - ncr_dev->ncr_busy = 0; - ncr_dev->t128.block_count = (ncr_dev->t128.block_count - 1) & 0xff; - ncr_log("Remaining blocks to be written=%d\n", ncr_dev->t128.block_count); - if (!ncr_dev->t128.block_count) { - ncr_dev->t128.block_loaded = 0; - ncr_log("IO End of write transfer\n"); - ncr->tcr |= TCR_LAST_BYTE_SENT; - ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr_dev->timer); - if (ncr->mode & MODE_ENA_EOP_INT) { - ncr_log("NCR write irq\n"); - ncr_irq(ncr_dev, ncr, 1); - } - } - break; - } else - goto write_again; - } - break; - - case DMA_INITIATOR_RECEIVE: - if (ncr_dev->type != 3) { - if (!(ncr_dev->status_ctrl & CTRL_DATA_DIR)) { - ncr_log("DMA_INITIATOR_RECEIVE with DMA direction set wrong\n"); - break; - } - - if (!(ncr_dev->status_ctrl & STATUS_BUFFER_NOT_READY)) { - ncr_log("Read buffer status ready\n"); - break; - } - - if (!ncr_dev->block_count_loaded) - break; - - while (bytes_tx < limit) { - for (uint8_t c = 0; c < 10; c++) { - ncr_bus_read(ncr_dev); - if (ncr->cur_bus & BUS_REQ) - break; - } - - /* Data ready. */ - ncr_bus_read(ncr_dev); - temp = BUS_GETDATA(ncr->cur_bus); - - bus = get_bus_host(ncr); - - ncr_bus_update(ncr_dev, bus | BUS_ACK); - ncr_bus_update(ncr_dev, bus & ~BUS_ACK); - - ncr_dev->buffer[ncr_dev->buffer_pos++] = temp; - ncr_log("Buffer pos for reading = %d\n", ncr_dev->buffer_pos); - bytes_tx++; - - if (ncr_dev->buffer_pos == MIN(128, dev->buffer_length)) { - bytes_tx = 0; - ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - ncr_dev->buffer_pos = 0; - ncr_dev->buffer_host_pos = 0; - ncr_dev->block_count = (ncr_dev->block_count - 1) & 0xff; - ncr_log("Remaining blocks to be read=%d\n", ncr_dev->block_count); - if (!ncr_dev->block_count) { - ncr_dev->block_count_loaded = 0; - ncr_log("IO End of read transfer\n"); - ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr_dev->timer); - if (ncr->mode & MODE_ENA_EOP_INT) { - ncr_log("NCR read irq\n"); - ncr_irq(ncr_dev, ncr, 1); - } - } - break; - } - } - } else { - if (!(ncr_dev->t128.status & 0x04)) { - ncr_log("Read status busy, block count = %i, host pos = %i\n", ncr_dev->t128.block_count, ncr_dev->t128.host_pos); - break; - } - - if (!ncr_dev->t128.block_loaded) { - ncr_log("Read block not loaded\n"); - break; - } - - if (ncr_dev->t128.host_pos < MIN(512, dev->buffer_length)) - break; - -read_again: - for (uint8_t c = 0; c < 10; c++) { - ncr_bus_read(ncr_dev); - if (ncr->cur_bus & BUS_REQ) - break; - } - - /* Data ready. */ - ncr_bus_read(ncr_dev); - temp = BUS_GETDATA(ncr->cur_bus); - - bus = get_bus_host(ncr); - - ncr_bus_update(ncr_dev, bus | BUS_ACK); - ncr_bus_update(ncr_dev, bus & ~BUS_ACK); - - ncr_dev->t128.buffer[ncr_dev->t128.pos++] = temp; - ncr_log("Buffer pos for reading=%d, temp=%02x, len=%d.\n", ncr_dev->t128.pos, temp, dev->buffer_length); - - if (ncr_dev->t128.pos == MIN(512, dev->buffer_length)) { - ncr_dev->t128.pos = 0; - ncr_dev->t128.host_pos = 0; - ncr_dev->t128.status &= ~0x02; - ncr_dev->t128.block_count = (ncr_dev->t128.block_count - 1) & 0xff; - ncr_log("Remaining blocks to be read=%d, status=%02x, len=%i, cdb[0] = %02x\n", ncr_dev->t128.block_count, ncr_dev->t128.status, dev->buffer_length, ncr->command[0]); - if (!ncr_dev->t128.block_count) { - ncr_dev->t128.block_loaded = 0; - ncr_log("IO End of read transfer\n"); - ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr_dev->timer); - if (ncr->mode & MODE_ENA_EOP_INT) { - ncr_log("NCR read irq\n"); - ncr_irq(ncr_dev, ncr, 1); - } - } - break; - } else - goto read_again; - } - break; - - default: - break; - } - - ncr_bus_read(ncr_dev); - - if (!(ncr->cur_bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) { - ncr_log("Updating DMA\n"); - ncr->mode &= ~MODE_DMA; - ncr->dma_mode = DMA_IDLE; - if (ncr_dev->type == 3) - timer_on_auto(&ncr_dev->timer, 10.0); - } -} - -static uint8_t -t128_read(uint32_t addr, void *priv) -{ - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - const ncr_t *ncr = &ncr_dev->ncr; - scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; - uint8_t ret = 0xff; - - addr &= 0x3fff; - if (ncr_dev->t128.bios_enabled && (addr >= 0) && (addr < 0x1800)) - ret = ncr_dev->bios_rom.rom[addr & 0x1fff]; - else if ((addr >= 0x1800) && (addr < 0x1880)) - ret = ncr_dev->t128.ext_ram[addr & 0x7f]; - else if ((addr >= 0x1c00) && (addr < 0x1c20)) { - ret = ncr_dev->t128.ctrl; - ncr_log("T128 ctrl read=%02x, dma=%02x\n", ret, ncr->mode & MODE_DMA); - } else if ((addr >= 0x1c20) && (addr < 0x1c40)) { - ret = ncr_dev->t128.status; - ncr_log("T128 status read=%02x, dma=%02x\n", ret, ncr->mode & MODE_DMA); - } else if ((addr >= 0x1d00) && (addr < 0x1e00)) - ret = ncr_read((addr - 0x1d00) >> 5, ncr_dev); - else if (addr >= 0x1e00 && addr < 0x2000) { - if ((ncr_dev->t128.host_pos >= MIN(512, dev->buffer_length)) || - (ncr->dma_mode != DMA_INITIATOR_RECEIVE)) - ret = 0xff; - else { - ret = ncr_dev->t128.buffer[ncr_dev->t128.host_pos++]; - - ncr_log("Read transfer, addr = %i, pos = %i\n", addr & 0x1ff, - ncr_dev->t128.host_pos); - - if (ncr_dev->t128.host_pos == MIN(512, dev->buffer_length)) { - ncr_dev->t128.status &= ~0x04; - ncr_log("Transfer busy read, status = %02x, period = %lf\n", - ncr_dev->t128.status, ncr_dev->period); - if ((ncr_dev->period == 0.2) || (ncr_dev->period == 0.02)) - timer_on_auto(&ncr_dev->timer, 40.2); - } else if ((ncr_dev->t128.host_pos < MIN(512, dev->buffer_length)) && - (scsi_device_get_callback(dev) > 100.0)) - cycles += 100; /*Needed to avoid timer de-syncing with transfers.*/ - } - } - - return ret; -} - -static void -t128_write(uint32_t addr, uint8_t val, void *priv) -{ - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - const ncr_t *ncr = &ncr_dev->ncr; - const scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; - - addr &= 0x3fff; - if ((addr >= 0x1800) && (addr < 0x1880)) - ncr_dev->t128.ext_ram[addr & 0x7f] = val; - else if ((addr >= 0x1c00) && (addr < 0x1c20)) { - if ((val & 0x02) && !(ncr_dev->t128.ctrl & 0x02)) - ncr_dev->t128.status |= 0x02; - - ncr_dev->t128.ctrl = val; - ncr_log("T128 ctrl write=%02x\n", val); - } else if ((addr >= 0x1d00) && (addr < 0x1e00)) - ncr_write((addr - 0x1d00) >> 5, val, ncr_dev); - else if ((addr >= 0x1e00) && (addr < 0x2000)) { - if ((ncr_dev->t128.host_pos < MIN(512, dev->buffer_length)) && - (ncr->dma_mode == DMA_SEND)) { - ncr_dev->t128.buffer[ncr_dev->t128.host_pos] = val; - ncr_dev->t128.host_pos++; - - ncr_log("Write transfer, addr = %i, pos = %i, val = %02x\n", - addr & 0x1ff, ncr_dev->t128.host_pos, val); - - if (ncr_dev->t128.host_pos == MIN(512, dev->buffer_length)) { - ncr_dev->t128.status &= ~0x04; - ncr_dev->ncr_busy = 1; - ncr_log("Transfer busy write, status = %02x\n", ncr_dev->t128.status); - timer_on_auto(&ncr_dev->timer, 0.02); - } - } - } -} - -static uint8_t -rt1000b_mc_read(int port, void *priv) -{ - const ncr5380_t *ncr_dev = (ncr5380_t *) priv; - - return (ncr_dev->pos_regs[port & 7]); -} - -static void -rt1000b_mc_write(int port, uint8_t val, void *priv) -{ - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - - /* MCA does not write registers below 0x0100. */ - if (port < 0x0102) - return; - - mem_mapping_disable(&ncr_dev->bios_rom.mapping); - mem_mapping_disable(&ncr_dev->mapping); - - /* Save the MCA register value. */ - ncr_dev->pos_regs[port & 7] = val; - - if (ncr_dev->pos_regs[2] & 1) { - switch (ncr_dev->pos_regs[2] & 0xe0) { - case 0: - ncr_dev->rom_addr = 0xd4000; - break; - case 0x20: - ncr_dev->rom_addr = 0xd0000; - break; - case 0x40: - ncr_dev->rom_addr = 0xcc000; - break; - case 0x60: - ncr_dev->rom_addr = 0xc8000; - break; - case 0xc0: - ncr_dev->rom_addr = 0xdc000; - break; - case 0xe0: - ncr_dev->rom_addr = 0xd8000; - break; - - default: - break; - } - - mem_mapping_set_addr(&ncr_dev->bios_rom.mapping, ncr_dev->rom_addr, 0x4000); - mem_mapping_set_addr(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000); - } -} - -static uint8_t -rt1000b_mc_feedb(void *priv) -{ - const ncr5380_t *ncr_dev = (ncr5380_t *) priv; - - return ncr_dev->pos_regs[2] & 1; -} - -static void * -ncr_init(const device_t *info) -{ - const char *fn = NULL; - char temp[128]; - ncr5380_t *ncr_dev; - - ncr_dev = malloc(sizeof(ncr5380_t)); - memset(ncr_dev, 0x00, sizeof(ncr5380_t)); - ncr_dev->name = info->name; - ncr_dev->type = info->local; - - ncr_dev->bus = scsi_get_bus(); - - switch (ncr_dev->type) { - case 0: /* Longshine LCS6821N */ - ncr_dev->rom_addr = device_get_config_hex20("bios_addr"); - ncr_dev->irq = device_get_config_int("irq"); - rom_init(&ncr_dev->bios_rom, LCS6821N_ROM, - ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000, - memio_read, NULL, NULL, - memio_write, NULL, NULL, - ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); - break; - - case 1: /* Rancho RT1000B/MC */ - ncr_dev->rom_addr = device_get_config_hex20("bios_addr"); - ncr_dev->irq = device_get_config_int("irq"); - ncr_dev->bios_ver = device_get_config_int("bios_ver"); - if (info->flags & DEVICE_MCA) { - ncr_dev->rom_addr = 0xd8000; - ncr_dev->bios_ver = 1; - } - - switch (ncr_dev->bios_ver) { - case 0: - fn = RT1000B_810R_ROM; - break; - case 1: - fn = RT1000B_820R_ROM; - break; - } - - rom_init(&ncr_dev->bios_rom, fn, - ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - if (info->flags & DEVICE_MCA) { - mem_mapping_add(&ncr_dev->mapping, 0, 0, - memio_read, NULL, NULL, - memio_write, NULL, NULL, - ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); - ncr_dev->pos_regs[0] = 0x8d; - ncr_dev->pos_regs[1] = 0x70; - mca_add(rt1000b_mc_read, rt1000b_mc_write, rt1000b_mc_feedb, NULL, ncr_dev); - } else { - mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000, - memio_read, NULL, NULL, - memio_write, NULL, NULL, - ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); - } - break; - - case 2: /* Trantor T130B */ - ncr_dev->rom_addr = device_get_config_hex20("bios_addr"); - ncr_dev->base = device_get_config_hex16("base"); - ncr_dev->irq = device_get_config_int("irq"); - - if (ncr_dev->rom_addr > 0x00000) { - rom_init(&ncr_dev->bios_rom, T130B_ROM, - ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000, - t130b_read, NULL, NULL, - t130b_write, NULL, NULL, - ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); - } - - io_sethandler(ncr_dev->base, 16, - t130b_in, NULL, NULL, t130b_out, NULL, NULL, ncr_dev); - break; - - case 3: /* Trantor T128 */ - ncr_dev->rom_addr = device_get_config_hex20("bios_addr"); - ncr_dev->irq = device_get_config_int("irq"); - ncr_dev->t128.bios_enabled = device_get_config_int("boot"); - - if (ncr_dev->t128.bios_enabled) - rom_init(&ncr_dev->bios_rom, T128_ROM, - ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000, - t128_read, NULL, NULL, - t128_write, NULL, NULL, - ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); - break; - - case 4: /* Corel LS2000 */ - ncr_dev->rom_addr = device_get_config_hex20("bios_addr"); - ncr_dev->irq = device_get_config_int("irq"); - rom_init(&ncr_dev->bios_rom, COREL_LS2000_ROM, - ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000, - memio_read, NULL, NULL, - memio_write, NULL, NULL, - ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); - break; - - default: - break; - } - - sprintf(temp, "%s: BIOS=%05X", ncr_dev->name, ncr_dev->rom_addr); - if (ncr_dev->base != 0) - sprintf(&temp[strlen(temp)], " I/O=%04x", ncr_dev->base); - if (ncr_dev->irq != 0) - sprintf(&temp[strlen(temp)], " IRQ=%d", ncr_dev->irq); - ncr_log("%s\n", temp); - - if ((ncr_dev->type < 3) || (ncr_dev->type == 4)) { - ncr_dev->status_ctrl = STATUS_BUFFER_NOT_READY; - ncr_dev->buffer_host_pos = 128; - } else { - ncr_dev->t128.status = 0x04; - ncr_dev->t128.host_pos = 512; - if (!ncr_dev->t128.bios_enabled) - ncr_dev->t128.status |= 0x80; - } - timer_add(&ncr_dev->timer, ncr_callback, ncr_dev, 0); - - scsi_bus_set_speed(ncr_dev->bus, 5000000.0); - - return ncr_dev; -} - -static void -ncr_close(void *priv) -{ - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - - if (ncr_dev) { - /* Tell the timer to terminate. */ - timer_stop(&ncr_dev->timer); - - free(ncr_dev); - ncr_dev = NULL; - } -} - -static int -lcs6821n_available(void) -{ - return (rom_present(LCS6821N_ROM)); -} - -static int -rt1000b_available(void) -{ - return (rom_present(RT1000B_820R_ROM) && rom_present(RT1000B_810R_ROM)); -} - -static int -rt1000b_820_available(void) -{ - return (rom_present(RT1000B_820R_ROM)); -} - -static int -t130b_available(void) -{ - return (rom_present(T130B_ROM)); -} - -static int -t128_available(void) -{ - return (rom_present(T128_ROM)); -} - -static int -corel_ls2000_available(void) -{ - return (rom_present(COREL_LS2000_ROM)); -} - -// clang-format off -static const device_config_t ncr5380_mmio_config[] = { - { - .name = "bios_addr", - .description = "BIOS Address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xD8000, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "C800H", .value = 0xc8000 }, - { .description = "CC00H", .value = 0xcc000 }, - { .description = "D000H", .value = 0xd0000 }, - { .description = "D400H", .value = 0xd4000 }, - { .description = "D800H", .value = 0xd8000 }, - { .description = "DC00H", .value = 0xdc000 }, - { .description = "" } - }, - }, - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "IRQ 3", .value = 3 }, - { .description = "IRQ 5", .value = 5 }, - { .description = "IRQ 7", .value = 7 }, - { .description = "" } - }, - }, - { .name = "", .description = "", .type = CONFIG_END } -}; - -static const device_config_t rancho_config[] = { - { - .name = "bios_addr", - .description = "BIOS Address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xD8000, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "C800H", .value = 0xc8000 }, - { .description = "CC00H", .value = 0xcc000 }, - { .description = "D000H", .value = 0xd0000 }, - { .description = "D400H", .value = 0xd4000 }, - { .description = "D800H", .value = 0xd8000 }, - { .description = "DC00H", .value = 0xdc000 }, - { .description = "" } - }, - }, - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "IRQ 3", .value = 3 }, - { .description = "IRQ 5", .value = 5 }, - { .description = "IRQ 7", .value = 7 }, - { .description = "" } - }, - }, - { - .name = "bios_ver", - .description = "BIOS Version", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 1, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "8.20R", .value = 1 }, - { .description = "8.10R", .value = 0 }, - { .description = "" } - }, - }, - { .name = "", .description = "", .type = CONFIG_END } -}; - -static const device_config_t rancho_mc_config[] = { - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "IRQ 3", .value = 3 }, - { .description = "IRQ 5", .value = 5 }, - { .description = "IRQ 7", .value = 7 }, - { .description = "" } - }, - }, - { .name = "", .description = "", .type = CONFIG_END } -}; - -static const device_config_t t130b_config[] = { - { - .name = "bios_addr", - .description = "BIOS Address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xD8000, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "Disabled", .value = 0 }, - { .description = "C800H", .value = 0xc8000 }, - { .description = "CC00H", .value = 0xcc000 }, - { .description = "D800H", .value = 0xd8000 }, - { .description = "DC00H", .value = 0xdc000 }, - { .description = "" } - }, - }, - { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x0350, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "240H", .value = 0x0240 }, - { .description = "250H", .value = 0x0250 }, - { .description = "340H", .value = 0x0340 }, - { .description = "350H", .value = 0x0350 }, - { .description = "" } - }, - }, - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "IRQ 3", .value = 3 }, - { .description = "IRQ 5", .value = 5 }, - { .description = "IRQ 7", .value = 7 }, - { .description = "" } - }, - }, - { .name = "", .description = "", .type = CONFIG_END } -}; - -static const device_config_t t128_config[] = { - { - .name = "bios_addr", - .description = "BIOS Address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xD8000, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "C800H", .value = 0xc8000 }, - { .description = "CC00H", .value = 0xcc000 }, - { .description = "D000H", .value = 0xd0000 }, - { .description = "D400H", .value = 0xd4000 }, - { .description = "D800H", .value = 0xd8000 }, - { .description = "DC00H", .value = 0xdc000 }, - { .description = "" } - }, - }, - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner ={ 0 }, - .selection = { - { .description = "IRQ 3", .value = 3 }, - { .description = "IRQ 5", .value = 5 }, - { .description = "IRQ 7", .value = 7 }, - { .description = "" } - }, - }, - { - .name = "boot", - .description = "Enable Boot ROM", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 - }, - { .name = "", .description = "", .type = CONFIG_END } -}; -// clang-format on - -const device_t scsi_lcs6821n_device = { - .name = "Longshine LCS-6821N", - .internal_name = "lcs6821n", - .flags = DEVICE_ISA, - .local = 0, - .init = ncr_init, - .close = ncr_close, - .reset = NULL, - { .available = lcs6821n_available }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = ncr5380_mmio_config -}; - -const device_t scsi_rt1000b_device = { - .name = "Rancho RT1000B", - .internal_name = "rt1000b", - .flags = DEVICE_ISA, - .local = 1, - .init = ncr_init, - .close = ncr_close, - .reset = NULL, - { .available = rt1000b_available }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = rancho_config -}; - -const device_t scsi_rt1000mc_device = { - .name = "Rancho RT1000B-MC", - .internal_name = "rt1000mc", - .flags = DEVICE_MCA, - .local = 1, - .init = ncr_init, - .close = ncr_close, - .reset = NULL, - { .available = rt1000b_820_available }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = rancho_mc_config -}; - -const device_t scsi_t130b_device = { - .name = "Trantor T130B", - .internal_name = "t130b", - .flags = DEVICE_ISA, - .local = 2, - .init = ncr_init, - .close = ncr_close, - .reset = NULL, - { .available = t130b_available }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = t130b_config -}; - -const device_t scsi_t128_device = { - .name = "Trantor T128", - .internal_name = "t128", - .flags = DEVICE_ISA, - .local = 3, - .init = ncr_init, - .close = ncr_close, - .reset = NULL, - { .available = t128_available }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = t128_config -}; - -const device_t scsi_ls2000_device = { - .name = "Corel LS2000", - .internal_name = "ls2000", - .flags = DEVICE_ISA, - .local = 4, - .init = ncr_init, - .close = ncr_close, - .reset = NULL, - { .available = corel_ls2000_available }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = ncr5380_mmio_config -}; diff --git a/src/scsi/scsi_ncr53c400.c b/src/scsi/scsi_ncr53c400.c new file mode 100644 index 000000000..d605f1bdb --- /dev/null +++ b/src/scsi/scsi_ncr53c400.c @@ -0,0 +1,998 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the NCR 53c400 series of SCSI Host Adapters + * made by NCR. These controllers were designed for the ISA and MCA bus. + * + * + * + * Authors: Sarah Walker, + * TheCollector1995, + * Fred N. van Kempen, + * + * Copyright 2017-2019 Sarah Walker. + * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2017-2024 TheCollector1995. + */ +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/pic.h> +#include <86box/mca.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/device.h> +#include <86box/nvr.h> +#include <86box/plat.h> +#include <86box/scsi.h> +#include <86box/scsi_device.h> +#include <86box/scsi_ncr5380.h> + +#define LCS6821N_ROM "roms/scsi/ncr5380/Longshine LCS-6821N - BIOS version 1.04.bin" +#define COREL_LS2000_ROM "roms/scsi/ncr5380/Corel LS2000 - BIOS ROM - Ver 1.65.bin" +#define RT1000B_810R_ROM "roms/scsi/ncr5380/Rancho_RT1000_RTBios_version_8.10R.bin" +#define RT1000B_820R_ROM "roms/scsi/ncr5380/RTBIOS82.ROM" +#define T130B_ROM "roms/scsi/ncr5380/trantor_t130b_bios_v2.14.bin" + +#define CTRL_DATA_DIR 0x40 +#define STATUS_BUFFER_NOT_READY 0x04 +#define STATUS_5380_ACCESSIBLE 0x80 + +enum { + ROM_LCS6821N = 0, + ROM_LS2000, + ROM_RT1000B, + ROM_T130B +}; + +typedef struct ncr53c400_t { + rom_t bios_rom; + mem_mapping_t mapping; + ncr_t ncr; + uint8_t buffer[128]; + uint8_t int_ram[0x40]; + uint8_t ext_ram[0x600]; + + uint32_t rom_addr; + uint16_t base; + + int8_t type; + uint8_t block_count; + uint8_t status_ctrl; + + int block_count_loaded; + + int buffer_pos; + int buffer_host_pos; + + int busy; + uint8_t pos_regs[8]; + + pc_timer_t timer; +} ncr53c400_t; + +#ifdef ENABLE_NCR53C400_LOG +int ncr53c400_do_log = ENABLE_NCR53C400_LOG; + +static void +ncr53c400_log(const char *fmt, ...) +{ + va_list ap; + + if (ncr53c400_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define ncr53c400_log(fmt, ...) +#endif + +/* Memory-mapped I/O WRITE handler. */ +static void +ncr53c400_write(uint32_t addr, uint8_t val, void *priv) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + ncr_t *ncr = &ncr400->ncr; + scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + + addr &= 0x3fff; + + if (addr >= 0x3a00) + ncr400->ext_ram[addr - 0x3a00] = val; + else { + switch (addr & 0x3f80) { + case 0x3800: + ncr400->int_ram[addr & 0x3f] = val; + break; + + case 0x3880: + ncr5380_write(addr, val, ncr); + break; + + case 0x3900: + if (!(ncr400->status_ctrl & CTRL_DATA_DIR) && (ncr400->buffer_host_pos < MIN(128, dev->buffer_length))) { + ncr400->buffer[ncr400->buffer_host_pos++] = val; + + ncr53c400_log("Write host pos = %i, val = %02x\n", ncr400->buffer_host_pos, val); + + if (ncr400->buffer_host_pos == MIN(128, dev->buffer_length)) { + ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; + ncr400->busy = 1; + } + } + break; + + case 0x3980: + switch (addr) { + case 0x3980: /* Control */ + ncr53c400_log("NCR 53c400 control = %02x, mode = %02x.\n", val, ncr->mode); + if ((val & CTRL_DATA_DIR) && !(ncr400->status_ctrl & CTRL_DATA_DIR)) { + ncr400->buffer_host_pos = MIN(128, dev->buffer_length); + ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; + } else if (!(val & CTRL_DATA_DIR) && (ncr400->status_ctrl & CTRL_DATA_DIR)) { + ncr400->buffer_host_pos = 0; + ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + } + ncr400->status_ctrl = (ncr400->status_ctrl & 0x87) | (val & 0x78); + break; + + case 0x3981: /* block counter register */ + ncr53c400_log("Write block counter register: val=%d, dma mode=%x, period=%lf\n", val, ncr->dma_mode, ncr->period); + ncr400->block_count = val; + ncr400->block_count_loaded = 1; + + if (ncr400->status_ctrl & CTRL_DATA_DIR) { + ncr400->buffer_host_pos = MIN(128, dev->buffer_length); + ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; + } else { + ncr400->buffer_host_pos = 0; + ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + } + if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr400->timer) && (dev->buffer_length > 0)) { + memset(ncr400->buffer, 0, MIN(128, dev->buffer_length)); + ncr53c400_log("DMA timer on\n"); + timer_on_auto(&ncr400->timer, ncr->period); + } + break; + + default: + break; + } + break; + + default: + break; + } + } +} + +/* Memory-mapped I/O READ handler. */ +static uint8_t +ncr53c400_read(uint32_t addr, void *priv) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + ncr_t *ncr = &ncr400->ncr; + scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + uint8_t ret = 0xff; + + addr &= 0x3fff; + + if (addr < 0x2000) + ret = ncr400->bios_rom.rom[addr & 0x1fff]; + else if (addr < 0x3800) + ret = 0xff; + else if (addr >= 0x3a00) + ret = ncr400->ext_ram[addr - 0x3a00]; + else { + switch (addr & 0x3f80) { + case 0x3800: + ncr53c400_log("Read intRAM %02x %02x\n", addr & 0x3f, ncr400->int_ram[addr & 0x3f]); + ret = ncr400->int_ram[addr & 0x3f]; + break; + + case 0x3880: + ncr53c400_log("Read 5380 %04x\n", addr); + ret = ncr5380_read(addr, ncr); + break; + + case 0x3900: + if (ncr400->buffer_host_pos >= MIN(128, dev->buffer_length) || (!(ncr400->status_ctrl & CTRL_DATA_DIR))) { + ret = 0xff; + ncr53c400_log("No Read.\n"); + } else { + ret = ncr400->buffer[ncr400->buffer_host_pos++]; + ncr53c400_log("Read host pos = %i, ret = %02x\n", ncr400->buffer_host_pos, ret); + + if (ncr400->buffer_host_pos == MIN(128, dev->buffer_length)) { + ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; + ncr53c400_log("Transfer busy read, status = %02x\n", ncr400->status_ctrl); + } + } + break; + + case 0x3980: + switch (addr) { + case 0x3980: /* status */ + ret = ncr400->status_ctrl; + ncr53c400_log("NCR status ctrl read=%02x\n", ncr400->status_ctrl & STATUS_BUFFER_NOT_READY); + if (!ncr400->busy) + ret |= STATUS_5380_ACCESSIBLE; + if (ncr->mode & 0x30) { /*Parity bits*/ + if (!(ncr->mode & MODE_DMA)) { /*This is to avoid RTBios 8.10R BIOS problems with the hard disk and detection.*/ + ret |= 0x01; /*If the parity bits are set, bit 0 of the 53c400 status port should be set as well.*/ + ncr->mode = 0; /*Required by RTASPI10.SYS otherwise it won't initialize.*/ + } + } + ncr53c400_log("NCR 53c400 status = %02x.\n", ret); + break; + + case 0x3981: /* block counter register*/ + ret = ncr400->block_count; + break; + + case 0x3982: /* switch register read */ + ret = 0xf8; + ret |= (ncr->irq & 0x07); + ncr53c400_log("Switches read=%02x.\n", ret); + break; + + default: + break; + } + break; + + default: + break; + } + } + + if (addr >= 0x3880) + ncr53c400_log("memio_read(%08x)=%02x\n", addr, ret); + + return ret; +} + + +/* Memory-mapped I/O WRITE handler for the Trantor T130B. */ +static void +t130b_write(uint32_t addr, uint8_t val, void *priv) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + + addr &= 0x3fff; + ncr53c400_log("MEM: Writing %02X to %08X\n", val, addr); + if (addr >= 0x1800 && addr < 0x1880) + ncr400->ext_ram[addr & 0x7f] = val; +} + +/* Memory-mapped I/O READ handler for the Trantor T130B. */ +static uint8_t +t130b_read(uint32_t addr, void *priv) +{ + const ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + uint8_t ret = 0xff; + + addr &= 0x3fff; + if (addr < 0x1800) + ret = ncr400->bios_rom.rom[addr & 0x1fff]; + else if (addr >= 0x1800 && addr < 0x1880) + ret = ncr400->ext_ram[addr & 0x7f]; + + ncr53c400_log("MEM: Reading %02X from %08X\n", ret, addr); + return ret; +} + +static void +t130b_out(uint16_t port, uint8_t val, void *priv) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + ncr_t *ncr = &ncr400->ncr; + + ncr53c400_log("I/O: Writing %02X to %04X\n", val, port); + + switch (port & 0x0f) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + ncr53c400_write((port & 7) | 0x3980, val, ncr400); + break; + + case 0x04: + case 0x05: + ncr53c400_write(0x3900, val, ncr400); + break; + + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + ncr5380_write(port, val, ncr); + break; + + default: + break; + } +} + +static uint8_t +t130b_in(uint16_t port, void *priv) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + ncr_t *ncr = &ncr400->ncr; + uint8_t ret = 0xff; + + switch (port & 0x0f) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + ret = ncr53c400_read((port & 7) | 0x3980, ncr400); + break; + + case 0x04: + case 0x05: + ret = ncr53c400_read(0x3900, ncr400); + break; + + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + ret = ncr5380_read(port, ncr); + break; + + default: + break; + } + + ncr53c400_log("I/O: Reading %02X from %04X\n", ret, port); + return ret; +} + +static void +ncr53c400_dma_mode_ext(void *priv, void *ext_priv) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) ext_priv; + ncr_t *ncr = (ncr_t *) priv; + + /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ + if (!ncr400->block_count_loaded && !(ncr->mode & MODE_DMA)) { + ncr53c400_log("No DMA mode\n"); + ncr->tcr &= ~TCR_LAST_BYTE_SENT; + ncr->isr &= ~STATUS_END_OF_DMA; + ncr->dma_mode = DMA_IDLE; + } +} + +static void +ncr53c400_timer_on_auto(void *ext_priv, double period) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) ext_priv; + + ncr53c400_log("53c400: PERIOD=%lf.\n", period); + if (period == 0.0) + timer_stop(&ncr400->timer); + else + timer_on_auto(&ncr400->timer, period); +} + +static void +ncr53c400_callback(void *priv) +{ + ncr53c400_t *ncr400 = (void *) priv; + ncr_t *ncr = &ncr400->ncr; + scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + int bus; + uint8_t c; + uint8_t temp; + + if (ncr->dma_mode != DMA_IDLE) + timer_on_auto(&ncr400->timer, 1.0); + + if (ncr->data_wait & 1) { + ncr->clear_req = 3; + ncr->data_wait &= ~1; + if (ncr->dma_mode == DMA_IDLE) { + timer_stop(&ncr400->timer); + return; + } + } + + if (ncr->dma_mode == DMA_IDLE) { + timer_stop(&ncr400->timer); + return; + } + + switch (ncr->dma_mode) { + case DMA_SEND: + if (ncr400->status_ctrl & CTRL_DATA_DIR) { + ncr53c400_log("DMA_SEND with DMA direction set wrong\n"); + break; + } + + if (!(ncr400->status_ctrl & STATUS_BUFFER_NOT_READY)) { + ncr53c400_log("Write buffer status ready\n"); + break; + } + + if (!ncr400->block_count_loaded) { + ncr53c400_log("Write block count not loaded.\n"); + break; + } + + while (1) { + for (c = 0; c < 10; c++) { + ncr5380_bus_read(ncr); + if (ncr->cur_bus & BUS_REQ) + break; + } + + /* Data ready. */ + temp = ncr400->buffer[ncr400->buffer_pos]; + + bus = ncr5380_get_bus_host(ncr) & ~BUS_DATAMASK; + bus |= BUS_SETDATA(temp); + + ncr5380_bus_update(ncr, bus | BUS_ACK); + ncr5380_bus_update(ncr, bus & ~BUS_ACK); + + ncr400->buffer_pos++; + ncr53c400_log("NCR 53c400 Buffer pos for writing = %d\n", ncr400->buffer_pos); + + if (ncr400->buffer_pos == MIN(128, dev->buffer_length)) { + ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + ncr400->buffer_pos = 0; + ncr400->buffer_host_pos = 0; + ncr400->busy = 0; + ncr400->block_count = (ncr400->block_count - 1) & 0xff; + ncr53c400_log("NCR 53c400 Remaining blocks to be written=%d\n", ncr400->block_count); + if (!ncr400->block_count) { + ncr400->block_count_loaded = 0; + ncr53c400_log("IO End of write transfer\n"); + ncr->tcr |= TCR_LAST_BYTE_SENT; + ncr->isr |= STATUS_END_OF_DMA; + timer_stop(&ncr400->timer); + if (ncr->mode & MODE_ENA_EOP_INT) { + ncr53c400_log("NCR 53c400 write irq\n"); + ncr5380_irq(ncr, 1); + } + } + break; + } + } + break; + + case DMA_INITIATOR_RECEIVE: + if (!(ncr400->status_ctrl & CTRL_DATA_DIR)) { + ncr53c400_log("DMA_INITIATOR_RECEIVE with DMA direction set wrong\n"); + break; + } + + if (!(ncr400->status_ctrl & STATUS_BUFFER_NOT_READY)) { + ncr53c400_log("Read buffer status ready\n"); + break; + } + + if (!ncr400->block_count_loaded) + break; + + while (1) { + for (c = 0; c < 10; c++) { + ncr5380_bus_read(ncr); + if (ncr->cur_bus & BUS_REQ) + break; + } + + /* Data ready. */ + ncr5380_bus_read(ncr); + temp = BUS_GETDATA(ncr->cur_bus); + + bus = ncr5380_get_bus_host(ncr); + + ncr5380_bus_update(ncr, bus | BUS_ACK); + ncr5380_bus_update(ncr, bus & ~BUS_ACK); + + ncr400->buffer[ncr400->buffer_pos++] = temp; + ncr53c400_log("NCR 53c400 Buffer pos for reading = %d\n", ncr400->buffer_pos); + + if (ncr400->buffer_pos == MIN(128, dev->buffer_length)) { + ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + ncr400->buffer_pos = 0; + ncr400->buffer_host_pos = 0; + ncr400->block_count = (ncr400->block_count - 1) & 0xff; + ncr53c400_log("NCR 53c400 Remaining blocks to be read=%d\n", ncr400->block_count); + if (!ncr400->block_count) { + ncr400->block_count_loaded = 0; + ncr53c400_log("IO End of read transfer\n"); + ncr->isr |= STATUS_END_OF_DMA; + timer_stop(&ncr400->timer); + if (ncr->mode & MODE_ENA_EOP_INT) { + ncr53c400_log("NCR read irq\n"); + ncr5380_irq(ncr, 1); + } + } + break; + } + } + break; + + default: + break; + } + + ncr5380_bus_read(ncr); + + if (!(ncr->cur_bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) { + ncr53c400_log("Updating DMA\n"); + ncr->mode &= ~MODE_DMA; + ncr->dma_mode = DMA_IDLE; + } +} + +static uint8_t +rt1000b_mc_read(int port, void *priv) +{ + const ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + + return (ncr400->pos_regs[port & 7]); +} + +static void +rt1000b_mc_write(int port, uint8_t val, void *priv) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + + /* MCA does not write registers below 0x0100. */ + if (port < 0x0102) + return; + + mem_mapping_disable(&ncr400->bios_rom.mapping); + mem_mapping_disable(&ncr400->mapping); + + /* Save the MCA register value. */ + ncr400->pos_regs[port & 7] = val; + + if (ncr400->pos_regs[2] & 1) { + switch (ncr400->pos_regs[2] & 0xe0) { + case 0: + ncr400->rom_addr = 0xd4000; + break; + case 0x20: + ncr400->rom_addr = 0xd0000; + break; + case 0x40: + ncr400->rom_addr = 0xcc000; + break; + case 0x60: + ncr400->rom_addr = 0xc8000; + break; + case 0xc0: + ncr400->rom_addr = 0xdc000; + break; + case 0xe0: + ncr400->rom_addr = 0xd8000; + break; + + default: + break; + } + + mem_mapping_set_addr(&ncr400->bios_rom.mapping, ncr400->rom_addr, 0x4000); + mem_mapping_set_addr(&ncr400->mapping, ncr400->rom_addr, 0x4000); + } +} + +static uint8_t +rt1000b_mc_feedb(void *priv) +{ + const ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + + return ncr400->pos_regs[2] & 1; +} + +static void * +ncr53c400_init(const device_t *info) +{ + const char *bios_ver = NULL; + const char *fn; + ncr53c400_t *ncr400; + ncr_t *ncr; + + ncr400 = malloc(sizeof(ncr53c400_t)); + memset(ncr400, 0x00, sizeof(ncr53c400_t)); + ncr = &ncr400->ncr; + + ncr400->type = info->local; + + ncr->bus = scsi_get_bus(); + + switch (ncr400->type) { + case ROM_LCS6821N: /* Longshine LCS6821N */ + ncr400->rom_addr = device_get_config_hex20("bios_addr"); + ncr->irq = device_get_config_int("irq"); + + rom_init(&ncr400->bios_rom, LCS6821N_ROM, + ncr400->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + mem_mapping_add(&ncr400->mapping, ncr400->rom_addr, 0x4000, + ncr53c400_read, NULL, NULL, + ncr53c400_write, NULL, NULL, + ncr400->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr400); + break; + + + case ROM_LS2000: /* Corel LS2000 */ + ncr400->rom_addr = device_get_config_hex20("bios_addr"); + ncr->irq = device_get_config_int("irq"); + + rom_init(&ncr400->bios_rom, COREL_LS2000_ROM, + ncr400->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + mem_mapping_add(&ncr400->mapping, ncr400->rom_addr, 0x4000, + ncr53c400_read, NULL, NULL, + ncr53c400_write, NULL, NULL, + ncr400->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr400); + break; + + case ROM_RT1000B: /* Rancho RT1000B/MC */ + ncr400->rom_addr = device_get_config_hex20("bios_addr"); + ncr->irq = device_get_config_int("irq"); + if (info->flags & DEVICE_MCA) { + rom_init(&ncr400->bios_rom, RT1000B_820R_ROM, + 0xd8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_add(&ncr400->mapping, 0xd8000, 0x4000, + ncr53c400_read, NULL, NULL, + ncr53c400_write, NULL, NULL, + ncr400->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr400); + mem_mapping_disable(&ncr400->bios_rom.mapping); + ncr400->pos_regs[0] = 0x8d; + ncr400->pos_regs[1] = 0x70; + mca_add(rt1000b_mc_read, rt1000b_mc_write, rt1000b_mc_feedb, NULL, ncr400); + } else { + bios_ver = (char *) device_get_config_bios("bios_ver"); + fn = (char *) device_get_bios_file(info, bios_ver, 0); + rom_init(&ncr400->bios_rom, fn, + ncr400->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_add(&ncr400->mapping, ncr400->rom_addr, 0x4000, + ncr53c400_read, NULL, NULL, + ncr53c400_write, NULL, NULL, + ncr400->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr400); + } + break; + + case ROM_T130B: /* Trantor T130B */ + ncr400->rom_addr = device_get_config_hex20("bios_addr"); + ncr400->base = device_get_config_hex16("base"); + ncr->irq = device_get_config_int("irq"); + + if (ncr400->rom_addr > 0x00000) { + rom_init(&ncr400->bios_rom, T130B_ROM, + ncr400->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + mem_mapping_add(&ncr400->mapping, ncr400->rom_addr, 0x4000, + t130b_read, NULL, NULL, + t130b_write, NULL, NULL, + ncr400->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr400); + } + + io_sethandler(ncr400->base, 16, + t130b_in, NULL, NULL, t130b_out, NULL, NULL, ncr400); + break; + + default: + break; + } + + ncr->priv = ncr400; + ncr->dma_mode_ext = ncr53c400_dma_mode_ext; + ncr->dma_send_ext = NULL; + ncr->dma_initiator_receive_ext = NULL; + ncr->timer = ncr53c400_timer_on_auto; + ncr400->status_ctrl = STATUS_BUFFER_NOT_READY; + ncr400->buffer_host_pos = 128; + timer_add(&ncr400->timer, ncr53c400_callback, ncr400, 0); + + scsi_bus_set_speed(ncr->bus, 5000000.0); + + return ncr400; +} + +static void +ncr53c400_close(void *priv) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + + if (ncr400) { + /* Tell the timer to terminate. */ + timer_stop(&ncr400->timer); + + free(ncr400); + ncr400 = NULL; + } +} + +static int +lcs6821n_available(void) +{ + return (rom_present(LCS6821N_ROM)); +} + +static int +rt1000b_mc_available(void) +{ + return (rom_present(RT1000B_820R_ROM)); +} + +static int +t130b_available(void) +{ + return (rom_present(T130B_ROM)); +} + +static int +corel_ls2000_available(void) +{ + return (rom_present(COREL_LS2000_ROM)); +} + +// clang-format off +static const device_config_t ncr53c400_mmio_config[] = { + { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = "", + .default_int = 0xD8000, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "C800H", .value = 0xc8000 }, + { .description = "CC00H", .value = 0xcc000 }, + { .description = "D000H", .value = 0xd0000 }, + { .description = "D400H", .value = 0xd4000 }, + { .description = "D800H", .value = 0xd8000 }, + { .description = "DC00H", .value = 0xdc000 }, + { .description = "" } + }, + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 5, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "None", .value = -1 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +static const device_config_t rt1000b_config[] = { + { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = "", + .default_int = 0xD8000, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "C800H", .value = 0xc8000 }, + { .description = "CC00H", .value = 0xcc000 }, + { .description = "D000H", .value = 0xd0000 }, + { .description = "D400H", .value = 0xd4000 }, + { .description = "D800H", .value = 0xd8000 }, + { .description = "DC00H", .value = 0xdc000 }, + { .description = "" } + }, + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 5, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "None", .value = -1 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } + }, + }, + { + .name = "bios_ver", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "v8_10r", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, /*W1*/ + .bios = { + { .name = "Version 8.10R", .internal_name = "v8_10r", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 8192, .files = { RT1000B_810R_ROM, "" } }, + { .name = "Version 8.20R", .internal_name = "v8_20r", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 8192, .files = { RT1000B_820R_ROM, "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +static const device_config_t rt1000b_mc_config[] = { + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 5, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "None", .value = -1 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +static const device_config_t t130b_config[] = { + { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = "", + .default_int = 0xD8000, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0 }, + { .description = "C800H", .value = 0xc8000 }, + { .description = "CC00H", .value = 0xcc000 }, + { .description = "D800H", .value = 0xd8000 }, + { .description = "DC00H", .value = 0xdc000 }, + { .description = "" } + }, + }, + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x0350, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "240H", .value = 0x0240 }, + { .description = "250H", .value = 0x0250 }, + { .description = "340H", .value = 0x0340 }, + { .description = "350H", .value = 0x0350 }, + { .description = "" } + }, + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 5, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "None", .value = -1 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + +const device_t scsi_lcs6821n_device = { + .name = "Longshine LCS-6821N", + .internal_name = "lcs6821n", + .flags = DEVICE_ISA, + .local = ROM_LCS6821N, + .init = ncr53c400_init, + .close = ncr53c400_close, + .reset = NULL, + { .available = lcs6821n_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ncr53c400_mmio_config +}; + +const device_t scsi_rt1000b_device = { + .name = "Rancho RT1000B", + .internal_name = "rt1000b", + .flags = DEVICE_ISA, + .local = ROM_RT1000B, + .init = ncr53c400_init, + .close = ncr53c400_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = rt1000b_config +}; + +const device_t scsi_rt1000mc_device = { + .name = "Rancho RT1000B-MC", + .internal_name = "rt1000mc", + .flags = DEVICE_MCA, + .local = ROM_RT1000B, + .init = ncr53c400_init, + .close = ncr53c400_close, + .reset = NULL, + { .available = rt1000b_mc_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = rt1000b_mc_config +}; + +const device_t scsi_t130b_device = { + .name = "Trantor T130B", + .internal_name = "t130b", + .flags = DEVICE_ISA, + .local = ROM_T130B, + .init = ncr53c400_init, + .close = ncr53c400_close, + .reset = NULL, + { .available = t130b_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = t130b_config +}; + +const device_t scsi_ls2000_device = { + .name = "Corel LS2000", + .internal_name = "ls2000", + .flags = DEVICE_ISA, + .local = ROM_LS2000, + .init = ncr53c400_init, + .close = ncr53c400_close, + .reset = NULL, + { .available = corel_ls2000_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ncr53c400_mmio_config +}; diff --git a/src/scsi/scsi_t128.c b/src/scsi/scsi_t128.c new file mode 100644 index 000000000..b13511eac --- /dev/null +++ b/src/scsi/scsi_t128.c @@ -0,0 +1,631 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Trantor 128/228 series of SCSI Host Adapters + * made by Trantor. These controllers were designed for the ISA and MCA bus. + * + * + * + * Authors: Sarah Walker, + * TheCollector1995, + * Fred N. van Kempen, + * + * Copyright 2017-2019 Sarah Walker. + * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2017-2024 TheCollector1995. + */ +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/pic.h> +#include <86box/mca.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/device.h> +#include <86box/nvr.h> +#include <86box/plat.h> +#include <86box/scsi.h> +#include <86box/scsi_device.h> +#include <86box/scsi_ncr5380.h> + +#define T128_ROM "roms/scsi/ncr5380/trantor_t128_bios_v1.12.bin" + +typedef struct t128_t { + ncr_t ncr; + rom_t bios_rom; + mem_mapping_t mapping; + + uint8_t ctrl; + uint8_t status; + uint8_t buffer[512]; + uint8_t ext_ram[0x80]; + uint8_t block_count; + + int block_loaded; + int pos, host_pos; + + uint32_t rom_addr; + + int bios_enabled; + uint8_t pos_regs[8]; + + pc_timer_t timer; +} t128_t; + +#ifdef ENABLE_T128_LOG +int t128_do_log = ENABLE_T128_LOG; + +static void +t128_log(const char *fmt, ...) +{ + va_list ap; + + if (t128_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define t128_log(fmt, ...) +#endif + +/* Memory-mapped I/O WRITE handler. */ +static void +t128_write(uint32_t addr, uint8_t val, void *priv) +{ + t128_t *t128 = (t128_t *) priv; + ncr_t *ncr = &t128->ncr; + const scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + + addr &= 0x3fff; + if ((addr >= 0x1800) && (addr < 0x1880)) + t128->ext_ram[addr & 0x7f] = val; + else if ((addr >= 0x1c00) && (addr < 0x1c20)) { + if ((val & 0x02) && !(t128->ctrl & 0x02)) + t128->status |= 0x02; + + t128->ctrl = val; + t128_log("T128 ctrl write=%02x\n", val); + } else if ((addr >= 0x1d00) && (addr < 0x1e00)) + ncr5380_write((addr - 0x1d00) >> 5, val, ncr); + else if ((addr >= 0x1e00) && (addr < 0x2000)) { + if ((t128->host_pos < MIN(512, dev->buffer_length)) && + (ncr->dma_mode == DMA_SEND)) { + t128->buffer[t128->host_pos] = val; + t128->host_pos++; + + t128_log("T128 Write transfer, addr = %i, pos = %i, val = %02x\n", + addr & 0x1ff, t128->host_pos, val); + + if (t128->host_pos == MIN(512, dev->buffer_length)) { + t128->status &= ~0x04; + t128_log("Transfer busy write, status = %02x\n", t128->status); + timer_on_auto(&t128->timer, 0.02); + } + } + } +} + +/* Memory-mapped I/O READ handler. */ +static uint8_t +t128_read(uint32_t addr, void *priv) +{ + t128_t *t128 = (t128_t *) priv; + ncr_t *ncr = &t128->ncr; + scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + uint8_t ret = 0xff; + + addr &= 0x3fff; + if (t128->bios_enabled && (addr >= 0) && (addr < 0x1800)) + ret = t128->bios_rom.rom[addr & 0x1fff]; + else if ((addr >= 0x1800) && (addr < 0x1880)) + ret = t128->ext_ram[addr & 0x7f]; + else if ((addr >= 0x1c00) && (addr < 0x1c20)) { + ret = t128->ctrl; + t128_log("T128 ctrl read=%02x, dma=%02x\n", ret, ncr->mode & MODE_DMA); + } else if ((addr >= 0x1c20) && (addr < 0x1c40)) { + ret = t128->status; + t128_log("T128 status read=%02x, dma=%02x\n", ret, ncr->mode & MODE_DMA); + } else if ((addr >= 0x1d00) && (addr < 0x1e00)) + ret = ncr5380_read((addr - 0x1d00) >> 5, ncr); + else if (addr >= 0x1e00 && addr < 0x2000) { + if ((t128->host_pos >= MIN(512, dev->buffer_length)) || + (ncr->dma_mode != DMA_INITIATOR_RECEIVE)) + ret = 0xff; + else { + ret = t128->buffer[t128->host_pos++]; + + t128_log("T128 Read transfer, addr = %i, pos = %i\n", addr & 0x1ff, + t128->host_pos); + + if (t128->host_pos == MIN(512, dev->buffer_length)) { + t128->status &= ~0x04; + t128_log("T128 Transfer busy read, status = %02x, period = %lf\n", + t128->status, ncr->period); + if ((ncr->period == 0.2) || (ncr->period == 0.02)) + timer_on_auto(&t128->timer, 40.2); + } else if ((t128->host_pos < MIN(512, dev->buffer_length)) && + (scsi_device_get_callback(dev) > 100.0)) + cycles += 100; /*Needed to avoid timer de-syncing with transfers.*/ + } + } + + return ret; +} + +static void +t128_dma_mode_ext(void *priv, void *ext_priv) +{ + t128_t *t128 = (t128_t *) ext_priv; + ncr_t *ncr = (ncr_t *) priv; + + /*Don't stop the timer until it finishes the transfer*/ + if (t128->block_loaded && (ncr->mode & MODE_DMA)) { + t128_log("Continuing DMA mode\n"); + timer_on_auto(&t128->timer, ncr->period + 1.0); + } + + /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ + if (!t128->block_loaded && !(ncr->mode & MODE_DMA)) { + t128_log("No DMA mode\n"); + ncr->tcr &= ~TCR_LAST_BYTE_SENT; + ncr->isr &= ~STATUS_END_OF_DMA; + ncr->dma_mode = DMA_IDLE; + } +} + +static int +t128_dma_send_ext(void *priv, void *ext_priv) +{ + t128_t *t128 = (t128_t *) ext_priv; + ncr_t *ncr = (ncr_t *) priv; + scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + + if ((ncr->mode & MODE_DMA) && !timer_is_on(&t128->timer) && (dev->buffer_length > 0)) { + memset(t128->buffer, 0, MIN(512, dev->buffer_length)); + t128->status |= 0x04; + t128->host_pos = 0; + t128->block_count = dev->buffer_length >> 9; + + if (dev->buffer_length < 512) + t128->block_count = 1; + + t128->block_loaded = 1; + } + return 1; +} + +static int +t128_dma_initiator_receive_ext(void *priv, void *ext_priv) +{ + t128_t *t128 = (t128_t *) ext_priv; + ncr_t *ncr = (ncr_t *) priv; + scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + + if ((ncr->mode & MODE_DMA) && !timer_is_on(&t128->timer) && (dev->buffer_length > 0)) { + memset(t128->buffer, 0, MIN(512, dev->buffer_length)); + t128->status |= 0x04; + t128->host_pos = MIN(512, dev->buffer_length); + t128->block_count = dev->buffer_length >> 9; + + if (dev->buffer_length < 512) + t128->block_count = 1; + + t128->block_loaded = 1; + timer_on_auto(&t128->timer, 0.02); + } + return 1; +} + +static void +t128_timer_on_auto(void *ext_priv, double period) +{ + t128_t *t128 = (t128_t *) ext_priv; + + if (period == 0.0) + timer_stop(&t128->timer); + else + timer_on_auto(&t128->timer, period); +} + +static void +t128_callback(void *priv) +{ + t128_t *t128 = (void *) priv; + ncr_t *ncr = &t128->ncr; + scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + int bus; + uint8_t c; + uint8_t temp; + + if ((ncr->dma_mode != DMA_IDLE) && (ncr->mode & MODE_DMA) && t128->block_loaded) { + if ((t128->host_pos == MIN(512, dev->buffer_length)) && t128->block_count) + t128->status |= 0x04; + + timer_on_auto(&t128->timer, ncr->period / 55.0); + } + + if (ncr->data_wait & 1) { + ncr->clear_req = 3; + ncr->data_wait &= ~1; + if (ncr->dma_mode == DMA_IDLE) + return; + } + + switch (ncr->dma_mode) { + case DMA_SEND: + if (!(t128->status & 0x04)) { + t128_log("Write status busy, block count = %i, host pos = %i\n", t128->block_count, t128->host_pos); + break; + } + + if (!t128->block_loaded) { + t128_log("Write block not loaded\n"); + break; + } + + if (t128->host_pos < MIN(512, dev->buffer_length)) + break; + +write_again: + for (c = 0; c < 10; c++) { + ncr5380_bus_read(ncr); + if (ncr->cur_bus & BUS_REQ) + break; + } + + /* Data ready. */ + temp = t128->buffer[t128->pos]; + + bus = ncr5380_get_bus_host(ncr) & ~BUS_DATAMASK; + bus |= BUS_SETDATA(temp); + + ncr5380_bus_update(ncr, bus | BUS_ACK); + ncr5380_bus_update(ncr, bus & ~BUS_ACK); + + t128->pos++; + t128_log("T128 Buffer pos for writing = %d\n", t128->pos); + + if (t128->pos == MIN(512, dev->buffer_length)) { + t128->pos = 0; + t128->host_pos = 0; + t128->status &= ~0x02; + t128->block_count = (t128->block_count - 1) & 0xff; + t128_log("T128 Remaining blocks to be written=%d\n", t128->block_count); + if (!t128->block_count) { + t128->block_loaded = 0; + t128_log("IO End of write transfer\n"); + ncr->tcr |= TCR_LAST_BYTE_SENT; + ncr->isr |= STATUS_END_OF_DMA; + timer_stop(&t128->timer); + if (ncr->mode & MODE_ENA_EOP_INT) { + t128_log("T128 write irq\n"); + ncr5380_irq(ncr, 1); + } + } + break; + } else + goto write_again; + break; + + case DMA_INITIATOR_RECEIVE: + if (!(t128->status & 0x04)) { + t128_log("Read status busy, block count = %i, host pos = %i\n", t128->block_count, t128->host_pos); + break; + } + + if (!t128->block_loaded) { + t128_log("Read block not loaded\n"); + break; + } + + if (t128->host_pos < MIN(512, dev->buffer_length)) + break; + +read_again: + for (c = 0; c < 10; c++) { + ncr5380_bus_read(ncr); + if (ncr->cur_bus & BUS_REQ) + break; + } + + /* Data ready. */ + ncr5380_bus_read(ncr); + temp = BUS_GETDATA(ncr->cur_bus); + + bus = ncr5380_get_bus_host(ncr); + + ncr5380_bus_update(ncr, bus | BUS_ACK); + ncr5380_bus_update(ncr, bus & ~BUS_ACK); + + t128->buffer[t128->pos++] = temp; + t128_log("T128 Buffer pos for reading=%d, temp=%02x, len=%d.\n", t128->pos, temp, dev->buffer_length); + + if (t128->pos == MIN(512, dev->buffer_length)) { + t128->pos = 0; + t128->host_pos = 0; + t128->status &= ~0x02; + t128->block_count = (t128->block_count - 1) & 0xff; + t128_log("T128 Remaining blocks to be read=%d, status=%02x, len=%i, cdb[0] = %02x\n", t128->block_count, t128->status, dev->buffer_length, ncr->command[0]); + if (!t128->block_count) { + t128->block_loaded = 0; + t128_log("IO End of read transfer\n"); + ncr->isr |= STATUS_END_OF_DMA; + timer_stop(&t128->timer); + if (ncr->mode & MODE_ENA_EOP_INT) { + t128_log("NCR read irq\n"); + ncr5380_irq(ncr, 1); + } + } + break; + } else + goto read_again; + break; + + default: + break; + } + + ncr5380_bus_read(ncr); + + if (!(ncr->cur_bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) { + t128_log("Updating DMA\n"); + ncr->mode &= ~MODE_DMA; + ncr->dma_mode = DMA_IDLE; + timer_on_auto(&t128->timer, 10.0); + } +} + +static uint8_t +t228_read(int port, void *priv) +{ + const t128_t *t128 = (t128_t *) priv; + + return (t128->pos_regs[port & 7]); +} + +static void +t228_write(int port, uint8_t val, void *priv) +{ + t128_t *t128 = (t128_t *) priv; + ncr_t *ncr = &t128->ncr; + + /* MCA does not write registers below 0x0100. */ + if (port < 0x0102) + return; + + mem_mapping_disable(&t128->bios_rom.mapping); + mem_mapping_disable(&t128->mapping); + + /* Save the MCA register value. */ + t128->pos_regs[port & 7] = val; + + if (t128->pos_regs[2] & 1) { + switch (t128->pos_regs[2] & 6) { + case 0: + t128->rom_addr = 0xcc000; + break; + case 2: + t128->rom_addr = 0xc8000; + break; + case 4: + t128->rom_addr = 0xdc000; + break; + case 6: + t128->rom_addr = 0xd8000; + break; + + default: + break; + } + + t128->bios_enabled = !(t128->pos_regs[2] & 8); + + switch (t128->pos_regs[2] & 0x70) { + case 0: + ncr->irq = -1; + break; + case 0x10: + ncr->irq = 3; + break; + case 0x20: + ncr->irq = 5; + break; + case 0x30: + ncr->irq = 7; + break; + case 0x40: + ncr->irq = 10; + break; + case 0x50: + ncr->irq = 12; + break; + case 0x60: + ncr->irq = 14; + break; + case 0x70: + ncr->irq = 15; + break; + + default: + break; + } + + if (t128->bios_enabled) { + t128->status &= ~0x80; + mem_mapping_set_addr(&t128->bios_rom.mapping, t128->rom_addr, 0x4000); + mem_mapping_set_addr(&t128->mapping, t128->rom_addr, 0x4000); + } else + t128->status |= 0x80; + } +} + +static uint8_t +t228_feedb(void *priv) +{ + const t128_t *t128 = (t128_t *) priv; + + return t128->pos_regs[2] & 1; +} + +static void * +t128_init(const device_t *info) +{ + t128_t *t128; + ncr_t *ncr; + + t128 = malloc(sizeof(t128_t)); + memset(t128, 0x00, sizeof(t128_t)); + ncr = &t128->ncr; + + ncr->bus = scsi_get_bus(); + + if (info->flags & DEVICE_MCA) { + rom_init(&t128->bios_rom, T128_ROM, + 0xd8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_add(&t128->mapping, 0xd8000, 0x4000, + t128_read, NULL, NULL, + t128_write, NULL, NULL, + t128->bios_rom.rom, MEM_MAPPING_EXTERNAL, t128); + mem_mapping_disable(&t128->bios_rom.mapping); + t128->pos_regs[0] = 0x8c; + t128->pos_regs[1] = 0x50; + mca_add(t228_read, t228_write, t228_feedb, NULL, t128); + } else { + ncr->irq = device_get_config_int("irq"); + t128->rom_addr = device_get_config_hex20("bios_addr"); + t128->bios_enabled = device_get_config_int("boot"); + if (t128->bios_enabled) + rom_init(&t128->bios_rom, T128_ROM, + t128->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + mem_mapping_add(&t128->mapping, t128->rom_addr, 0x4000, + t128_read, NULL, NULL, + t128_write, NULL, NULL, + t128->bios_rom.rom, MEM_MAPPING_EXTERNAL, t128); + } + + ncr->priv = t128; + ncr->dma_mode_ext = t128_dma_mode_ext; + ncr->dma_send_ext = t128_dma_send_ext; + ncr->dma_initiator_receive_ext = t128_dma_initiator_receive_ext; + ncr->timer = t128_timer_on_auto; + t128->status = 0x04; + t128->host_pos = 512; + if (!t128->bios_enabled && !(info->flags & DEVICE_MCA)) + t128->status |= 0x80; + + timer_add(&t128->timer, t128_callback, t128, 0); + + scsi_bus_set_speed(ncr->bus, 5000000.0); + + return t128; +} + +static void +t128_close(void *priv) +{ + t128_t *t128 = (t128_t *) priv; + + if (t128) { + /* Tell the timer to terminate. */ + timer_stop(&t128->timer); + + free(t128); + t128 = NULL; + } +} + +static int +t128_available(void) +{ + return (rom_present(T128_ROM)); +} + +// clang-format off +static const device_config_t t128_config[] = { + { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = "", + .default_int = 0xD8000, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "C800H", .value = 0xc8000 }, + { .description = "CC00H", .value = 0xcc000 }, + { .description = "D800H", .value = 0xd8000 }, + { .description = "DC00H", .value = 0xdc000 }, + { .description = "" } + }, + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 5, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "None", .value = -1 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } + }, + }, + { + .name = "boot", + .description = "Enable Boot ROM", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + +const device_t scsi_t128_device = { + .name = "Trantor T128", + .internal_name = "t128", + .flags = DEVICE_ISA, + .local = 0, + .init = t128_init, + .close = t128_close, + .reset = NULL, + { .available = t128_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = t128_config +}; + +const device_t scsi_t228_device = { + .name = "Trantor T228", + .internal_name = "t228", + .flags = DEVICE_MCA, + .local = 0, + .init = t128_init, + .close = t128_close, + .reset = NULL, + { .available = t128_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; From e5d1f3804923dbcfbba8485361da631f76fb6121 Mon Sep 17 00:00:00 2001 From: flama12333 <143599905+flama12333@users.noreply.github.com> Date: Wed, 10 Apr 2024 18:42:55 -0500 Subject: [PATCH 839/936] fix Error initializing Hard disK Controller in Siemens Nixdorf D824 since this machine has an internal ide controller --- src/machine/m_at_386dx_486.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index ea7e00ddc..b9f6b8cc8 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -400,7 +400,8 @@ machine_at_d824_init(const machine_t *model) device_add(&keyboard_ps2_device); device_add(&fdc37c651_device); - + device_add(&ide_isa_device); + return ret; } @@ -2293,4 +2294,4 @@ machine_at_atc1762_init(const machine_t *model) return ret; -} \ No newline at end of file +} From 5f846c348fa01304bf03a5fa4838af4940aea66b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Thu, 11 Apr 2024 02:32:57 +0200 Subject: [PATCH 840/936] Update m_at_386dx_486.c Move IDE initialization before the Super I/O chip initialization. --- src/machine/m_at_386dx_486.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index b9f6b8cc8..41fa3c946 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -399,8 +399,9 @@ machine_at_d824_init(const machine_t *model) device_add(&gd5428_onboard_device); device_add(&keyboard_ps2_device); - device_add(&fdc37c651_device); + device_add(&ide_isa_device); + device_add(&fdc37c651_device); return ret; } From 85c3eae1eeff53c83f85e2acdfd778d6028fab02 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Thu, 11 Apr 2024 10:20:21 -0400 Subject: [PATCH 841/936] qt: Make sure voodoo is only enabled for pci machines --- src/qt/qt_settingsdisplay.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/qt/qt_settingsdisplay.cpp b/src/qt/qt_settingsdisplay.cpp index 631e3b966..6969a1c2c 100644 --- a/src/qt/qt_settingsdisplay.cpp +++ b/src/qt/qt_settingsdisplay.cpp @@ -148,10 +148,6 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) else ui->pushButtonConfigure->setEnabled(video_card_has_config(videoCard[0]) > 0); bool machineHasPci = machine_has_bus(machineId, MACHINE_BUS_PCI) > 0; - ui->checkBoxVoodoo->setEnabled(machineHasPci); - if (machineHasPci) { - ui->checkBoxVoodoo->setChecked(voodoo_enabled); - } ui->pushButtonConfigureVoodoo->setEnabled(machineHasPci && ui->checkBoxVoodoo->isChecked()); bool machineHasIsa16 = machine_has_bus(machineId, MACHINE_BUS_ISA16) > 0; @@ -225,7 +221,10 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) } ui->checkBoxVoodoo->setDisabled(true); } else { - ui->checkBoxVoodoo->setDisabled(false); + ui->checkBoxVoodoo->setEnabled(machineHasPci); + if (machineHasPci) { + ui->checkBoxVoodoo->setChecked(voodoo_enabled); + } } } From 2b15d7c0e63f842b0a6acd09cec2cb3a28b43666 Mon Sep 17 00:00:00 2001 From: flama12333 <143599905+flama12333@users.noreply.github.com> Date: Sat, 13 Apr 2024 00:46:21 -0500 Subject: [PATCH 842/936] Rename dtk 386 clone to DTK PM-1630C the motherboard is listed https://theretroweb.com/motherboards/s/dtk-pm-1630c user in vcfed uploaded bios post pictures https://forum.vcfed.org/index.php?threads/getting-a-dtk-peer-2030-computer-running.1238827/page-4 --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index c2bb3925b..5020f3498 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -4416,7 +4416,7 @@ const machine_t machines[] = { }, /* Has IBM AT KBC firmware. */ { - .name = "[NEAT] DTK 386SX clone", + .name = "[NEAT] DTK PM-1630C", .internal_name = "dtk386", .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_NEAT, From e4c8fef511a46a2c2c8d087caf7398087677f9dc Mon Sep 17 00:00:00 2001 From: The Dax Date: Tue, 16 Apr 2024 00:43:32 -0400 Subject: [PATCH 843/936] Fix missing machines on Linux: -pravetz16: capitalization of BIOS_IMKO4_FE00.BIN corrected to BIOS_IMKO4_FE00.bin -s76p: capitalization of s76p.rom corrected to S76P.ROM -dellplato: capitalization of 1016AX1J.bio and 1016AX1J.bi1 corrected to .BIO and .BI1 respectively -pb450: capitalization of OPTI802.BIN corrected to OPTI802.bin --- src/machine/m_at_386dx_486.c | 4 ++-- src/machine/m_at_socket5.c | 4 ++-- src/machine/m_xt.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 41fa3c946..d4cd5fe16 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -687,7 +687,7 @@ machine_at_pb450_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/pb450/OPTI802.BIN", + ret = bios_load_linear("roms/machines/pb450/OPTI802.bin", 0x000e0000, 131072, 0); if (bios_only || !ret) @@ -1367,7 +1367,7 @@ machine_at_amis76_init(const machine_t *model) { int ret; - ret = bios_load_linear_inverted("roms/machines/s76p/s76p.rom", + ret = bios_load_linear_inverted("roms/machines/s76p/S76P.ROM", 0x000e0000, 131072, 0); if (bios_only || !ret) diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 773f8d980..ff59ec65f 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -64,8 +64,8 @@ machine_at_dellplato_init(const machine_t *model) { int ret; - ret = bios_load_linear_combined("roms/machines/dellplato/1016AX1J.bio", - "roms/machines/dellplato/1016AX1J.bi1", + ret = bios_load_linear_combined("roms/machines/dellplato/1016AX1J.BIO", + "roms/machines/dellplato/1016AX1J.BI1", 0x1d000, 128); if (bios_only || !ret) diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 9a0b39a89..ded68f5dc 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -339,7 +339,7 @@ machine_xt_pravetz16_imko4_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/pravetz16/BIOS_IMKO4_FE00.BIN", + ret = bios_load_linear("roms/machines/pravetz16/BIOS_IMKO4_FE00.bin", 0x000fe000, 65536, 0); if (ret) { bios_load_aux_linear("roms/machines/pravetz16/BIOS_IMKO4_F400.BIN", From 880abcb582ef11547b08b40e67e469a51f1ce91c Mon Sep 17 00:00:00 2001 From: The Dax Date: Tue, 16 Apr 2024 02:57:17 -0400 Subject: [PATCH 844/936] Fix capitalization of VideoMagic-BioS-HXIRTW32PWSRL.BIN to VideoMagic-BioS-HXIRTW32PWSRL.bin --- src/video/vid_et4000w32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 39b5b9ecc..2f086f3c7 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -42,7 +42,7 @@ #define BIOS_ROM_PATH_W32 "roms/video/et4000w32/ET4000W32VLB_bios_MX27C512.BIN" #define BIOS_ROM_PATH_W32I_ISA "roms/video/et4000w32/ET4KW32I.VBI" #define BIOS_ROM_PATH_W32I_VLB "roms/video/et4000w32/tseng.u41.bin" -#define BIOS_ROM_PATH_W32P_VIDEOMAGIC_REVB_VLB "roms/video/et4000w32/VideoMagic-BioS-HXIRTW32PWSRL.BIN" +#define BIOS_ROM_PATH_W32P_VIDEOMAGIC_REVB_VLB "roms/video/et4000w32/VideoMagic-BioS-HXIRTW32PWSRL.bin" #define BIOS_ROM_PATH_W32P "roms/video/et4000w32/ET4K_W32.BIN" #define BIOS_ROM_PATH_W32P_REVC "roms/video/et4000w32/et4000w32pcardex.BIN" From 22441a2302decc667870b5e4af0a68c00734af42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Tue, 16 Apr 2024 19:18:50 +0200 Subject: [PATCH 845/936] Add sanity check to Voodoo 3/Banshee hardware cursor drawing Fixes #4351. --- src/video/vid_voodoo_banshee.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index a333062e1..bbd14a4a0 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -2109,10 +2109,12 @@ banshee_hwcursor_draw(svga_t *svga, int displine) for (x = 0; x < 64; x += 8) { if (x_off > -8) { for (xx = 0; xx < 8; xx++) { - if (!(plane0[x >> 3] & (1 << 7))) - (svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0; - else if (plane1[x >> 3] & (1 << 7)) - (svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] ^= 0xffffff; + if (((x_off + xx + svga->x_add) >= 0) && ((x_off + xx + svga->x_add) <= 2047)) { + if (!(plane0[x >> 3] & (1 << 7))) + (svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0; + else if (plane1[x >> 3] & (1 << 7)) + (svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] ^= 0xffffff; + } plane0[x >> 3] <<= 1; plane1[x >> 3] <<= 1; From b92995b0395cc31ce4fcedda465c2c0bfaa48106 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Tue, 16 Apr 2024 19:34:06 +0200 Subject: [PATCH 846/936] Sanity check on reading NEAT registers. --- src/chipset/neat.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/chipset/neat.c b/src/chipset/neat.c index 3b00b4ffd..97c4b8f1a 100644 --- a/src/chipset/neat.c +++ b/src/chipset/neat.c @@ -646,7 +646,8 @@ neat_read(uint16_t port, void *priv) break; case 0x23: - ret = dev->regs[dev->indx]; + if ((dev->indx >= 0x60) && (dev->indx <= 0x6f)) + ret = dev->regs[dev->indx]; break; default: From 8756a70e38ea47816dd5e7a661a0ff3e34eb11e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Tue, 16 Apr 2024 19:40:21 +0200 Subject: [PATCH 847/936] Sanity check on reading SCAT registers. --- src/chipset/scat.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/chipset/scat.c b/src/chipset/scat.c index aa0c5511a..fe6c033cf 100644 --- a/src/chipset/scat.c +++ b/src/chipset/scat.c @@ -66,15 +66,17 @@ typedef struct ems_page_t { } ems_page_t; typedef struct scat_t { - int type; + uint8_t max_reg; + uint8_t reg_2xA; - int indx; - uint8_t regs[256]; - uint8_t reg_2xA; + uint8_t regs[256]; uint32_t xms_bound; - int external_is_RAS; + int type; + int indx; + + int external_is_RAS; ems_page_t null_page; ems_page_t page[32]; @@ -1233,7 +1235,8 @@ scat_in(uint16_t port, void *priv) break; default: - ret = dev->regs[dev->indx]; + if (dev->index <= dev->max_reg) + ret = dev->regs[dev->indx]; break; } break; @@ -1393,6 +1396,8 @@ scat_init(const device_t *info) sx = (dev->type == 32) ? 1 : 0; + dev->max_reg = sx ? 0x64 : 0x4f; + for (uint32_t i = 0; i < sizeof(dev->regs); i++) dev->regs[i] = 0xff; From b2000913223e612b9fa99fa58b80e350572e516c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Tue, 16 Apr 2024 21:49:24 +0200 Subject: [PATCH 848/936] Fixed a compile-breaking type in chipset/scat.c. --- src/chipset/scat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chipset/scat.c b/src/chipset/scat.c index fe6c033cf..02610efa2 100644 --- a/src/chipset/scat.c +++ b/src/chipset/scat.c @@ -1235,7 +1235,7 @@ scat_in(uint16_t port, void *priv) break; default: - if (dev->index <= dev->max_reg) + if (dev->indx <= dev->max_reg) ret = dev->regs[dev->indx]; break; } From 9947af00d4d3c58fb797c497a55f02d82901e029 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Apr 2024 03:47:49 +0200 Subject: [PATCH 849/936] Fixed the FORMAT command on almost every emulated hard disk controller. --- src/disk/hdc_esdi_at.c | 37 ++++++++++++++++++++- src/disk/hdc_esdi_mca.c | 15 ++++----- src/disk/hdc_ide.c | 64 ++++++++++++++++++++++++++++++++++--- src/disk/hdc_st506_at.c | 35 ++++++++++++++++++-- src/disk/hdc_st506_xt.c | 33 ++++++++++++++++++- src/include/86box/hdc_ide.h | 2 ++ 6 files changed, 169 insertions(+), 17 deletions(-) diff --git a/src/disk/hdc_esdi_at.c b/src/disk/hdc_esdi_at.c index 042a6020a..e16d4d729 100644 --- a/src/disk/hdc_esdi_at.c +++ b/src/disk/hdc_esdi_at.c @@ -214,6 +214,41 @@ get_sector(esdi_t *esdi, off64_t *addr) return 0; } +static int +get_sector_format(esdi_t *esdi, off64_t *addr) +{ + const drive_t *drive = &esdi->drives[esdi->drive_sel]; + int heads = drive->cfg_hpc; + int sectors = drive->cfg_spt; + int c; + int h; + int s; + + if (esdi->head > heads) { + esdi_at_log("esdi_get_sector: past end of configured heads\n"); + return 1; + } + + if (drive->cfg_spt == drive->real_spt && drive->cfg_hpc == drive->real_hpc) { + *addr = ((((off64_t) esdi->cylinder * heads) + esdi->head) * sectors); + } else { + /* + * When performing translation, the firmware seems to leave 1 + * sector per track inaccessible (spare sector) + */ + + *addr = ((((off64_t) esdi->cylinder * heads) + esdi->head) * sectors); + + s = *addr % (drive->real_spt - 1); + h = (*addr / (drive->real_spt - 1)) % drive->real_hpc; + c = (*addr / (drive->real_spt - 1)) / drive->real_hpc; + + *addr = ((((off64_t) c * drive->real_hpc) + h) * drive->real_spt) + s; + } + + return 0; +} + /* Move to the next sector using CHS addressing. */ static void next_sector(esdi_t *esdi) @@ -655,7 +690,7 @@ esdi_callback(void *priv) irq_raise(esdi); break; } else { - if (get_sector(esdi, &addr)) { + if (get_sector_format(esdi, &addr)) { esdi->error = ERR_ID_NOT_FOUND; esdi->status = STAT_READY | STAT_DSC | STAT_ERR; irq_raise(esdi); diff --git a/src/disk/hdc_esdi_mca.c b/src/disk/hdc_esdi_mca.c index 3714f93d4..c906c7ca1 100644 --- a/src/disk/hdc_esdi_mca.c +++ b/src/disk/hdc_esdi_mca.c @@ -831,14 +831,12 @@ esdi_callback(void *priv) switch (dev->cmd_state) { case 0: - dev->rba = (dev->cmd_data[2] | (dev->cmd_data[3] << 16)) & 0x0fffffff; + dev->rba = hdd_image_get_last_sector(drive->hdd_num); - dev->sector_count = dev->cmd_data[1]; - - if ((dev->rba + dev->sector_count) > hdd_image_get_last_sector(drive->hdd_num)) { - rba_out_of_range(dev); - return; - } + if (dev->command == CMD_FORMAT_UNIT) + dev->sector_count = dev->cmd_data[1]; + else + dev->sector_count = 0; dev->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; dev->irq_status = dev->cmd_dev | IRQ_DATA_TRANSFER_READY; @@ -855,7 +853,8 @@ esdi_callback(void *priv) return; } - hdd_image_zero(drive->hdd_num, dev->rba, dev->sector_count); + if (dev->command == CMD_FORMAT_UNIT) + hdd_image_zero(drive->hdd_num, 0, hdd_image_get_last_sector(drive->hdd_num) + 1); dev->status = STATUS_CMD_IN_PROGRESS; dev->cmd_state = 2; diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index a14f54e7d..428804b5a 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -738,6 +738,22 @@ ide_get_sector(ide_t *ide) } } +static off64_t +ide_get_sector_format(ide_t *ide) +{ + uint32_t heads; + uint32_t sectors; + + if (ide->tf->lba) + return (off64_t) ide->lba_addr; + else { + heads = ide->cfg_hpc; + sectors = ide->cfg_spt; + + return ((((off64_t) ide->tf->cylinder * heads) + (off64_t) ide->tf->head) * sectors); + } +} + /** * Move to the next sector using CHS addressing */ @@ -2147,8 +2163,9 @@ ide_callback(void *priv) if (ide->type == IDE_ATAPI) atapi_error_no_ready(ide); else { - if (chk_chs && ((ide->tf->cylinder >= ide->tracks) || (ide->tf->head >= ide->hpc) || - !ide->tf->sector || (ide->tf->sector > ide->spt))) + /* The J-Bond PCI400C-A Phoenix BIOS implies that this command is supposed to + ignore the sector number. */ + if (chk_chs && ((ide->tf->cylinder >= ide->tracks) || (ide->tf->head >= ide->hpc))) err = IDNF_ERR; else { ide->tf->atastat = DRDY_STAT | DSC_STAT; @@ -2434,7 +2451,7 @@ ide_callback(void *priv) else if (!ide->tf->lba && (ide->cfg_spt == 0)) err = IDNF_ERR; else { - hdd_image_zero(ide->hdd_num, ide_get_sector(ide), ide->tf->secount); + hdd_image_zero(ide->hdd_num, ide_get_sector_format(ide), ide->tf->secount); ide->tf->atastat = DRDY_STAT | DSC_STAT; ide_irq_raise(ide); @@ -2628,6 +2645,15 @@ ide_set_base_addr(int board, int base, uint16_t port) ide_boards[board]->base[base] = port; } +void +ide_set_irq(int board, int irq) +{ + ide_log("ide_set_irq(%i, %i)\n", board, irq); + + if (ide_boards[board] != NULL) + ide_boards[board]->irq = irq; +} + static void ide_clear_bus_master(int board) { @@ -2803,6 +2829,36 @@ ide_board_init(int board, int irq, int base_main, int side_main, int type, int b ide_boards[board]->inited = 1; } +/* Needed for ESS ES1688/968 PnP. */ +void +ide_pnp_config_changed_1addr(uint8_t ld, isapnp_device_config_t *config, void *priv) +{ + intptr_t board = (intptr_t) priv; + + if (ld) + return; + + if (ide_boards[board]->base[0] || ide_boards[board]->base[1]) { + ide_remove_handlers(board); + ide_boards[board]->base[0] = ide_boards[board]->base[1] = 0; + } + + ide_boards[board]->irq = -1; + + if (config->activate) { + ide_boards[board]->base[0] = (config->io[0].base != ISAPNP_IO_DISABLED) ? + config->io[0].base : 0x0000; + ide_boards[board]->base[1] = (config->io[0].base != ISAPNP_IO_DISABLED) ? + (config->io[0].base + 0x0206) : 0x0000; + + if (ide_boards[board]->base[0] && ide_boards[board]->base[1]) + ide_set_handlers(board); + + if (config->irq[0].irq != ISAPNP_IRQ_DISABLED) + ide_boards[board]->irq = config->irq[0].irq; + } +} + void ide_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) { @@ -3526,5 +3582,5 @@ const device_t ide_qua_pnp_device = { { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, - .config = ide_qua_config + .config = NULL }; diff --git a/src/disk/hdc_st506_at.c b/src/disk/hdc_st506_at.c index c8c35d7d5..67bea6a8e 100644 --- a/src/disk/hdc_st506_at.c +++ b/src/disk/hdc_st506_at.c @@ -187,7 +187,7 @@ get_sector(mfm_t *mfm, off64_t *addr) return 1; } - if (mfm->sector >= drive->cfg_spt + 1) { + if (mfm->sector >= (drive->cfg_spt + 1)) { st506_at_log("WD1003(%d) get_sector: past end of configured sectors\n", mfm->drvsel); return 1; @@ -199,7 +199,7 @@ get_sector(mfm_t *mfm, off64_t *addr) return 1; } - if (mfm->sector >= drive->spt + 1) { + if (mfm->sector >= (drive->spt + 1)) { st506_at_log("WD1003(%d) get_sector: past end of sectors\n", mfm->drvsel); return 1; } @@ -209,6 +209,35 @@ get_sector(mfm_t *mfm, off64_t *addr) return 0; } +static int +get_sector_format(mfm_t *mfm, off64_t *addr) +{ + const drive_t *drive = &mfm->drives[mfm->drvsel]; + + /* FIXME: See if this is even needed - if the code is present, IBM AT + diagnostics v2.07 will error with: ERROR 152 - SYSTEM BOARD. */ + if (drive->curcyl != mfm->cylinder) { + st506_at_log("WD1003(%d) sector: wrong cylinder\n"); + return 1; + } + + if (mfm->head > drive->cfg_hpc) { + st506_at_log("WD1003(%d) get_sector: past end of configured heads\n", + mfm->drvsel); + return 1; + } + + /* We should check this in the SET_DRIVE_PARAMETERS command! --FvK */ + if (mfm->head > drive->hpc) { + st506_at_log("WD1003(%d) get_sector: past end of heads\n", mfm->drvsel); + return 1; + } + + *addr = ((((off64_t) mfm->cylinder * drive->cfg_hpc) + mfm->head) * drive->cfg_spt); + + return 0; +} + /* Move to the next sector using CHS addressing. */ static void next_sector(mfm_t *mfm) @@ -634,7 +663,7 @@ do_callback(void *priv) st506_at_log("WD1003(%d) format(%d,%d)\n", mfm->drvsel, mfm->cylinder, mfm->head); do_seek(mfm); - if (get_sector(mfm, &addr)) { + if (get_sector_format(mfm, &addr)) { mfm->error = ERR_ID_NOT_FOUND; mfm->status = STAT_READY | STAT_DSC | STAT_ERR; irq_raise(mfm); diff --git a/src/disk/hdc_st506_xt.c b/src/disk/hdc_st506_xt.c index fc20350b0..f3ac48a36 100644 --- a/src/disk/hdc_st506_xt.c +++ b/src/disk/hdc_st506_xt.c @@ -457,6 +457,37 @@ get_chs(hdc_t *dev, drive_t *drive) return 1; } +static int +get_chs_format(hdc_t *dev, drive_t *drive) +{ + dev->err_bv = 0x80; + + dev->head = dev->command[1] & 0x1f; + /* 6 bits are used for the sector number even on the IBM PC controller. */ + dev->sector = 1; + dev->count = dev->command[4]; + if (((dev->type == ST506_XT_TYPE_ST11M) || (dev->type == ST506_XT_TYPE_ST11R)) && (dev->command[0] >= 0xf0)) + dev->cylinder = 0; + else { + dev->cylinder = dev->command[3] | ((dev->command[2] & 0xc0) << 2); + dev->cylinder += dev->cyl_off; /* for ST-11 */ + } + + if (dev->cylinder >= drive->cfg_cyl) { + /* + * This really is an error, we cannot move + * past the end of the drive, which should + * result in an ERR_ILLEGAL_ADDR. --FvK + */ + drive->cylinder = drive->cfg_cyl - 1; + return 0; + } + + drive->cylinder = dev->cylinder; + + return 1; +} + static void st506_callback(void *priv) { @@ -628,7 +659,7 @@ st506_callback(void *priv) case CMD_FORMAT_BAD_TRACK: switch (dev->state) { case STATE_START_COMMAND: - (void) get_chs(dev, drive); + (void) get_chs_format(dev, drive); st506_xt_log("ST506: FORMAT_%sTRACK(%i, %i/%i)\n", (dev->command[0] == CMD_FORMAT_BAD_TRACK) ? "BAD_" : "", dev->drive_sel, dev->cylinder, dev->head); diff --git a/src/include/86box/hdc_ide.h b/src/include/86box/hdc_ide.h index 1f7a78c9f..4ee808d69 100644 --- a/src/include/86box/hdc_ide.h +++ b/src/include/86box/hdc_ide.h @@ -205,12 +205,14 @@ extern void win_cdrom_eject(uint8_t id); extern void win_cdrom_reload(uint8_t id); extern void ide_set_base_addr(int board, int base, uint16_t port); +extern void ide_set_irq(int board, int irq); extern void ide_handlers(uint8_t board, int set); extern void ide_board_set_force_ata3(int board, int force_ata3); #ifdef EMU_ISAPNP_H extern void ide_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv); +extern void ide_pnp_config_changed_1addr(uint8_t ld, isapnp_device_config_t *config, void *priv); #endif extern double ide_atapi_get_period(uint8_t channel); From 75919a1cb97e425a8f0741eadb1416d30e051333 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Apr 2024 03:49:47 +0200 Subject: [PATCH 850/936] Fixed the SM(S)C) FDC37C93x NVR handling and make any non-PIIX4 machine that uses it, use its full NVR capabilities. --- src/include/86box/sio.h | 1 + src/machine/m_at_slot1.c | 3 +- src/machine/m_at_socket370.c | 28 ++++---- src/machine/m_at_socket7.c | 17 ++--- src/machine/m_at_socket7_3v.c | 10 +-- src/machine/m_at_socket8.c | 6 +- src/machine/machine_table.c | 18 ++--- src/nvr_at.c | 3 +- src/sio/sio_fdc37c93x.c | 129 ++++++++++++++++++++++++++++------ 9 files changed, 143 insertions(+), 72 deletions(-) diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index 31d5d12ae..c7098cfdb 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -43,6 +43,7 @@ extern const device_t fdc37c931apm_compaq_device; extern const device_t fdc37c932fr_device; extern const device_t fdc37c932qf_device; extern const device_t fdc37c935_device; +extern const device_t fdc37c935_no_nvr_device; extern const device_t fdc37m60x_device; extern const device_t fdc37m60x_370_device; extern const device_t it8661f_device; diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index c199be2e9..d1486b579 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -143,8 +143,7 @@ machine_at_spitfire_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440lx_device); device_add(&piix4e_device); - device_add(&keyboard_ps2_pci_device); - device_add(&fdc37c935_device); + device_add(&fdc37c935_no_nvr_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); device_add(&lm78_device); /* no reporting in BIOS */ diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index dce0034ff..9e686ae8b 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -127,13 +127,13 @@ machine_at_p6bap_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 3, 5); - pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 5); - pci_register_slot(0x0a, PCI_CARD_NORMAL, 2, 3, 5, 1); - pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 5, 1, 2); - pci_register_slot(0x0c, PCI_CARD_NORMAL, 5, 1, 2, 3); - pci_register_slot(0x0d, PCI_CARD_NORMAL, 5, 3, 2, 1); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 5); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0a, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0c, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0d, PCI_CARD_NORMAL, 4, 3, 2, 1); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&via_apro133a_device); /* Rebranded as ET82C693A */ device_add(&via_vt82c596b_device); /* Rebranded as ET82C696B */ device_add(&w83977ef_device); @@ -162,13 +162,13 @@ machine_at_p6bat_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 3, 5); - pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 5); - pci_register_slot(0x0a, PCI_CARD_NORMAL, 2, 3, 5, 1); - pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 5, 1, 2); - pci_register_slot(0x0c, PCI_CARD_NORMAL, 5, 1, 2, 3); - pci_register_slot(0x0d, PCI_CARD_NORMAL, 5, 3, 2, 1); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 5); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0a, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0c, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0d, PCI_CARD_NORMAL, 4, 3, 2, 1); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&via_apro133_device); device_add(&via_vt82c596b_device); device_add(&w83977ef_device); diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 6ba7cb41d..7bbf49edf 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -73,9 +73,7 @@ machine_at_acerv35n_init(const machine_t *model) pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&i430hx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_pci_device); device_add(&fdc37c932fr_device); - device_add(&sst_flash_29ee010_device); return ret; @@ -155,7 +153,7 @@ machine_at_m7shi_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); @@ -166,7 +164,6 @@ machine_at_m7shi_init(const machine_t *model) pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); device_add(&i430hx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c935_device); device_add(&intel_flash_bxt_device); @@ -574,7 +571,6 @@ machine_at_presario2240_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c932qf_device); device_add(&sst_flash_29ee020_device); @@ -605,7 +601,6 @@ machine_at_presario4500_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c931apm_compaq_device); device_add(&sst_flash_29ee020_device); @@ -623,7 +618,7 @@ machine_at_p55va_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -634,7 +629,6 @@ machine_at_p55va_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c932fr_device); device_add(&intel_flash_bxt_device); @@ -652,7 +646,7 @@ machine_at_brio80xx_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); @@ -663,7 +657,6 @@ machine_at_brio80xx_init(const machine_t *model) pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c935_device); device_add(&sst_flash_29ee020_device); @@ -719,7 +712,7 @@ machine_at_pb810_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -733,7 +726,6 @@ machine_at_pb810_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_device); device_add(&fdc37c935_device); device_add(&intel_flash_bxt_device); @@ -1469,7 +1461,6 @@ machine_at_thunderbolt_init(const machine_t *model) pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 0, 1, 2); device_add(&i430tx_device); device_add(&piix4_device); - device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c935_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x3, 128); diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index fdf155894..bd66c9a66 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -534,7 +534,7 @@ machine_at_acerm3a_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -546,7 +546,6 @@ machine_at_acerm3a_init(const machine_t *model) pci_register_slot(0x10, PCI_CARD_VIDEO, 4, 0, 0, 0); device_add(&i430hx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_pci_device); device_add(&fdc37c935_device); device_add(&sst_flash_29ee010_device); @@ -686,7 +685,7 @@ machine_at_dellhannibalp_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -698,7 +697,6 @@ machine_at_dellhannibalp_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c932fr_device); device_add(&intel_flash_bxt_ami_device); @@ -720,7 +718,7 @@ machine_at_gw2kte_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -732,7 +730,6 @@ machine_at_gw2kte_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c932fr_device); device_add(&intel_flash_bxt_ami_device); @@ -850,7 +847,6 @@ machine_at_vectra54_init(const machine_t *model) if (gfxcard[0] == VID_INTERNAL) device_add(&s3_phoenix_trio64_onboard_pci_device); - device_add(&keyboard_ps2_ami_pci_device); device_add(&i430fx_device); device_add(&piix_device); device_add(&fdc37c931apm_device); diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index e1dad68e7..e8262a6f4 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -175,7 +175,7 @@ machine_at_acerv60n_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model,2 ); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -187,7 +187,6 @@ machine_at_acerv60n_init(const machine_t *model) pci_register_slot(0x0C, PCI_CARD_NORMAL, 2, 3, 4, 1); device_add(&i440fx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_pci_device); device_add(&fdc37c935_device); device_add(&sst_flash_29ee010_device); @@ -366,7 +365,7 @@ machine_at_m6mi_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -377,7 +376,6 @@ machine_at_m6mi_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&i440fx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c935_device); device_add(&intel_flash_bxt_device); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 5020f3498..f7d46cec9 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -10513,7 +10513,7 @@ const machine_t machines[] = { .max = 196608, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 511, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -10678,7 +10678,7 @@ const machine_t machines[] = { .max = 131072, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 511, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -10760,7 +10760,7 @@ const machine_t machines[] = { .max = 131072, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 511, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -10967,7 +10967,7 @@ const machine_t machines[] = { .max = 196608, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 511, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -11616,7 +11616,7 @@ const machine_t machines[] = { .max = 131072, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 511, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -11656,7 +11656,7 @@ const machine_t machines[] = { .max = 131072, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 511, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -11738,7 +11738,7 @@ const machine_t machines[] = { .max = 131072, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 511, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -13217,7 +13217,7 @@ const machine_t machines[] = { .max = 524288, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 511, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -13541,7 +13541,7 @@ const machine_t machines[] = { .max = 786432, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 511, .kbc_device = NULL, .kbc_p1 = 0xff, .gpio = 0xffffffff, diff --git a/src/nvr_at.c b/src/nvr_at.c index 4ddec729f..9465839a7 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -309,7 +309,6 @@ typedef struct local_t { uint8_t irq_state; uint8_t smi_status; - uint8_t addr[8]; uint8_t wp[2]; uint8_t bank[8]; uint8_t *lock; @@ -317,6 +316,8 @@ typedef struct local_t { int16_t count; int16_t state; + uint16_t addr[8]; + int32_t smi_enable; uint64_t ecount; diff --git a/src/sio/sio_fdc37c93x.c b/src/sio/sio_fdc37c93x.c index 4acbfeff5..7d8e12795 100644 --- a/src/sio/sio_fdc37c93x.c +++ b/src/sio/sio_fdc37c93x.c @@ -31,6 +31,7 @@ #include <86box/hdc_ide.h> #include <86box/fdd.h> #include <86box/fdc.h> +#include <86box/keyboard.h> #include <86box/nvr.h> #include <86box/apm.h> #include <86box/acpi.h> @@ -51,11 +52,13 @@ typedef struct access_bus_t { typedef struct fdc37c93x_t { uint8_t chip_id; uint8_t is_apm; + uint8_t has_nvr; uint8_t tries; uint8_t gpio_regs[2]; uint8_t auxio_reg; uint8_t regs[48]; uint8_t ld_regs[11][256]; + uint16_t superio_base; uint16_t gpio_base; /* Set to EA */ uint16_t auxio_base; uint16_t nvr_sec_base; @@ -66,8 +69,23 @@ typedef struct fdc37c93x_t { access_bus_t *access_bus; nvr_t *nvr; acpi_t *acpi; + void *kbc; } fdc37c93x_t; +static void fdc37c93x_write(uint16_t port, uint8_t val, void *priv); +static uint8_t fdc37c93x_read(uint16_t port, void *priv); + +static uint16_t +make_port_superio(fdc37c93x_t *dev) +{ + uint16_t r0 = dev->regs[0x26]; + uint16_t r1 = dev->regs[0x27]; + + uint16_t p = (r1 << 8) + r0; + + return p; +} + static uint16_t make_port(fdc37c93x_t *dev, uint8_t ld) { @@ -126,6 +144,16 @@ fdc37c93x_gpio_write(uint16_t port, uint8_t val, void *priv) dev->gpio_regs[0] = (dev->gpio_regs[0] & 0xfc) | (val & 0x03); } +static void +fdc37c93x_superio_handler(fdc37c93x_t *dev) +{ + io_removehandler(dev->superio_base, 0x0002, + fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev); + dev->superio_base = make_port_superio(dev); + io_sethandler(dev->superio_base, 0x0002, + fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev); +} + static void fdc37c93x_fdc_handler(fdc37c93x_t *dev) { @@ -180,7 +208,9 @@ fdc37c93x_serial_handler(fdc37c93x_t *dev, int uart) static void fdc37c93x_nvr_pri_handler(fdc37c93x_t *dev) { - uint8_t local_enable = !!dev->ld_regs[6][0x30]; + uint8_t local_enable = !!dev->ld_regs[6][0x30]; + + local_enable &= ((dev->ld_regs[6][0xf0] & 0x90) != 0x80); nvr_at_handler(0, 0x70, dev->nvr); if (local_enable) @@ -193,6 +223,9 @@ fdc37c93x_nvr_sec_handler(fdc37c93x_t *dev) uint16_t ld_port = 0; uint8_t local_enable = !!dev->ld_regs[6][0x30]; + local_enable &= (((dev->ld_regs[6][0xf0] & 0xe0) == 0x80) || + ((dev->ld_regs[6][0xf0] & 0xe0) == 0xe0)); + nvr_at_sec_handler(0, dev->nvr_sec_base, dev->nvr); if (local_enable) { dev->nvr_sec_base = ld_port = make_port_sec(dev, 6) & 0xFFFE; @@ -203,6 +236,14 @@ fdc37c93x_nvr_sec_handler(fdc37c93x_t *dev) } } +static void +fdc37c93x_kbc_handler(fdc37c93x_t *dev) +{ + uint8_t local_enable = !!dev->ld_regs[7][0x30]; + + kbc_at_handler(local_enable, dev->kbc); +} + static void fdc37c93x_auxio_handler(fdc37c93x_t *dev) { @@ -401,10 +442,9 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) switch (dev->regs[7]) { case 0x01: case 0x02: - case 0x07: return; case 0x06: - if (dev->chip_id != 0x30) + if (!dev->has_nvr) return; /* Bits 0 to 3 of logical device 6 (RTC) register F0h must stay set once they are set. */ @@ -453,6 +493,10 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) fdc37c93x_access_bus_handler(dev); break; + case 0x27: + fdc37c93x_superio_handler(dev); + break; + default: break; } @@ -566,12 +610,15 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) break; case 6: /* RTC/NVR */ - if (dev->chip_id != 0x30) - break; + if (!dev->has_nvr) + return; switch (dev->cur_reg) { case 0x30: - if (valxor) + if (valxor) { fdc37c93x_nvr_pri_handler(dev); + fdc37c93x_nvr_sec_handler(dev); + } + break; case 0x62: case 0x63: if (valxor) @@ -617,6 +664,9 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) nvr_bank_set(0, 0, dev->nvr); nvr_bank_set(1, 0xff, dev->nvr); } + + fdc37c93x_nvr_pri_handler(dev); + fdc37c93x_nvr_sec_handler(dev); } break; @@ -624,6 +674,18 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) break; } break; + case 7: + /* Keyboard */ + switch (dev->cur_reg) { + case 0x30: + if (valxor) + fdc37c93x_kbc_handler(dev); + break; + + default: + break; + } + break; case 8: /* Auxiliary I/O */ switch (dev->cur_reg) { @@ -730,7 +792,7 @@ fdc37c93x_reset(fdc37c93x_t *dev) memset(dev->ld_regs[i], 0, 256); /* Logical device 0: FDD */ - dev->ld_regs[0][0x30] = 1; + dev->ld_regs[0][0x30] = 0; dev->ld_regs[0][0x60] = 3; dev->ld_regs[0][0x61] = 0xF0; dev->ld_regs[0][0x70] = 6; @@ -756,7 +818,7 @@ fdc37c93x_reset(fdc37c93x_t *dev) dev->ld_regs[2][0x70] = 0xF; /* Logical device 3: Parallel Port */ - dev->ld_regs[3][0x30] = 1; + dev->ld_regs[3][0x30] = 0; dev->ld_regs[3][0x60] = 3; dev->ld_regs[3][0x61] = 0x78; dev->ld_regs[3][0x70] = 7; @@ -764,7 +826,7 @@ fdc37c93x_reset(fdc37c93x_t *dev) dev->ld_regs[3][0xF0] = 0x3C; /* Logical device 4: Serial Port 1 */ - dev->ld_regs[4][0x30] = 1; + dev->ld_regs[4][0x30] = 0; dev->ld_regs[4][0x60] = 3; dev->ld_regs[4][0x61] = 0xf8; dev->ld_regs[4][0x70] = 4; @@ -772,7 +834,7 @@ fdc37c93x_reset(fdc37c93x_t *dev) serial_setup(dev->uart[0], COM1_ADDR, dev->ld_regs[4][0x70]); /* Logical device 5: Serial Port 2 */ - dev->ld_regs[5][0x30] = 1; + dev->ld_regs[5][0x30] = 0; dev->ld_regs[5][0x60] = 2; dev->ld_regs[5][0x61] = 0xf8; dev->ld_regs[5][0x70] = 3; @@ -782,12 +844,13 @@ fdc37c93x_reset(fdc37c93x_t *dev) serial_setup(dev->uart[1], COM2_ADDR, dev->ld_regs[5][0x70]); /* Logical device 6: RTC */ - dev->ld_regs[6][0x30] = 1; - dev->ld_regs[6][0x63] = (dev->chip_id == 0x30) ? 0x70 : 0x00; + dev->ld_regs[6][0x30] = 0; + dev->ld_regs[6][0x63] = (dev->has_nvr) ? 0x70 : 0x00; + dev->ld_regs[6][0xF0] = 0; dev->ld_regs[6][0xF4] = 3; /* Logical device 7: Keyboard */ - dev->ld_regs[7][0x30] = 1; + dev->ld_regs[7][0x30] = 0; dev->ld_regs[7][0x61] = 0x60; dev->ld_regs[7][0x70] = 1; @@ -810,13 +873,22 @@ fdc37c93x_reset(fdc37c93x_t *dev) fdc_reset(dev->fdc); fdc37c93x_fdc_handler(dev); - if (dev->chip_id == 0x30) { + if (dev->has_nvr) { fdc37c93x_nvr_pri_handler(dev); fdc37c93x_nvr_sec_handler(dev); nvr_bank_set(0, 0, dev->nvr); nvr_bank_set(1, 0xff, dev->nvr); + + nvr_lock_set(0x80, 0x20, 0, dev->nvr); + nvr_lock_set(0xa0, 0x20, 0, dev->nvr); + nvr_lock_set(0xc0, 0x20, 0, dev->nvr); + nvr_lock_set(0xe0, 0x20, 0, dev->nvr); } + fdc37c93x_kbc_handler(dev); + + fdc37c93x_superio_handler(dev); + dev->locked = 0; } @@ -874,6 +946,7 @@ fdc37c93x_init(const device_t *info) dev->chip_id = info->local & 0xff; dev->is_apm = (info->local >> 8) & 0x01; is_compaq = (info->local >> 8) & 0x02; + dev->has_nvr = !((info->local >> 8) & 0x04); dev->gpio_regs[0] = 0xff; #if 0 @@ -881,7 +954,7 @@ fdc37c93x_init(const device_t *info) #endif dev->gpio_regs[1] = (dev->chip_id == 0x30) ? 0xff : 0xfd; - if (dev->chip_id == 0x30) { + if (dev->has_nvr) { dev->nvr = device_add(&at_nvr_device); nvr_bank_set(0, 0, dev->nvr); @@ -901,20 +974,17 @@ fdc37c93x_init(const device_t *info) fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev); io_sethandler(0x0fb, 0x0001, fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev); - } else { - io_sethandler(FDC_SECONDARY_ADDR, 0x0002, - fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev); - io_sethandler(FDC_PRIMARY_ADDR, 0x0002, - fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev); } + dev->kbc = device_add(&keyboard_ps2_ami_pci_device); + fdc37c93x_reset(dev); return dev; } const device_t fdc37c931apm_device = { - .name = "SMC FDC37C932QF Super I/O", + .name = "SMC FDC37C931APM Super I/O", .internal_name = "fdc37c931apm", .flags = 0, .local = 0x130, /* Share the same ID with the 932QF. */ @@ -928,7 +998,7 @@ const device_t fdc37c931apm_device = { }; const device_t fdc37c931apm_compaq_device = { - .name = "SMC FDC37C932QF Super I/O (Compaq Presario 4500)", + .name = "SMC FDC37C931APM Super I/O (Compaq Presario 4500)", .internal_name = "fdc37c931apm_compaq", .flags = 0, .local = 0x330, /* Share the same ID with the 932QF. */ @@ -982,3 +1052,18 @@ const device_t fdc37c935_device = { .force_redraw = NULL, .config = NULL }; + +const device_t fdc37c935_no_nvr_device = { + .name = "SMC FDC37C935 Super I/O", + .internal_name = "fdc37c935", + .flags = 0, + .local = 0x402, + .init = fdc37c93x_init, + .close = fdc37c93x_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + From fed171ff4d93dd3f8df15e70b8a6e8c9479f0350 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Apr 2024 03:50:48 +0200 Subject: [PATCH 851/936] IBM PS/1 Model 2121 FDC fix. --- src/floppy/fdc.c | 16 +++++++++++++++- src/include/86box/fdc.h | 3 +++ src/machine/m_ps1.c | 2 +- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 491df2f47..1a0aa2f10 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -780,7 +780,7 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) } return; case 4: - if (!(fdc->flags & FDC_FLAG_PS1)) { + if (!(fdc->flags & FDC_FLAG_NO_DSR_RESET)) { if (!(val & 0x80)) { timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC); fdc->interrupt = -6; @@ -2608,6 +2608,20 @@ const device_t fdc_at_ps1_device = { .config = NULL }; +const device_t fdc_at_ps1_2121_device = { + .name = "PC/AT Floppy Drive Controller (PS/1, PS/2 ISA)", + .internal_name = "fdc_at_ps1", + .flags = 0, + .local = FDC_FLAG_NO_DSR_RESET | FDC_FLAG_DISKCHG_ACTLOW | FDC_FLAG_AT | FDC_FLAG_PS1, + .init = fdc_init, + .close = fdc_close, + .reset = fdc_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t fdc_at_smc_device = { .name = "PC/AT Floppy Drive Controller (SM(s)C FDC37Cxxx)", .internal_name = "fdc_at_smc", diff --git a/src/include/86box/fdc.h b/src/include/86box/fdc.h index 00de511f3..9529fde5c 100644 --- a/src/include/86box/fdc.h +++ b/src/include/86box/fdc.h @@ -55,6 +55,8 @@ extern int fdc_type; #define FDC_FLAG_SEC 0x1000 /* Is Secondary */ #define FDC_FLAG_TER 0x2000 /* Is Tertiary */ #define FDC_FLAG_QUA 0x3000 /* Is Quaternary */ +#define FDC_FLAG_CHANNEL 0x3000 /* Channel mask */ +#define FDC_FLAG_NO_DSR_RESET 0x4000 /* Has no DSR reset */ typedef struct fdc_t { uint8_t dor; @@ -251,6 +253,7 @@ extern const device_t fdc_at_ter_device; extern const device_t fdc_at_qua_device; extern const device_t fdc_at_actlow_device; extern const device_t fdc_at_ps1_device; +extern const device_t fdc_at_ps1_2121_device; extern const device_t fdc_at_smc_device; extern const device_t fdc_at_ali_device; extern const device_t fdc_at_winbond_device; diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c index e0a15126e..34691773f 100644 --- a/src/machine/m_ps1.c +++ b/src/machine/m_ps1.c @@ -378,7 +378,7 @@ ps1_setup(int model) if (gfxcard[0] == VID_INTERNAL) device_add(&ibm_ps1_2121_device); - device_add(&fdc_at_ps1_device); + device_add(&fdc_at_ps1_2121_device); device_add(&ide_isa_device); From d98751e40faf3ae9121aa722fc41b0457f000b6e Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Apr 2024 03:51:56 +0200 Subject: [PATCH 852/936] Added the ability to enable/disable the KBC (used by the FDC37C93x Super I/O chips). --- src/device/kbc_at.c | 15 +++++++++++++-- src/include/86box/keyboard.h | 1 + 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index bc4a1f366..d8b308d6b 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -1986,6 +1986,18 @@ kbc_at_close(void *priv) free(dev); } +void +kbc_at_handler(int set, void *priv) +{ + io_removehandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); + io_removehandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); + + if (set) { + io_sethandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); + io_sethandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); + } +} + static void * kbc_at_init(const device_t *info) { @@ -2003,8 +2015,7 @@ kbc_at_init(const device_t *info) if (info->flags & DEVICE_PCI) dev->misc_flags |= FLAG_PCI; - io_sethandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, dev); - io_sethandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, dev); + kbc_at_handler(1, dev); timer_add(&dev->kbc_poll_timer, kbc_at_poll, dev, 1); timer_add(&dev->pulse_cb, pulse_poll, dev, 0); diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 759fad714..0d8b2e745 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -276,6 +276,7 @@ extern int keyboard_isfsexit_up(void); extern int keyboard_ismsexit(void); extern void keyboard_set_is_amstrad(int ams); +extern void kbc_at_handler(int set, void *priv); extern uint8_t kbc_at_dev_queue_pos(atkbc_dev_t *dev, uint8_t main); extern void kbc_at_dev_queue_add(atkbc_dev_t *dev, uint8_t val, uint8_t main); extern void kbc_at_dev_reset(atkbc_dev_t *dev, int do_fa); From 8e0da9ef211fce049d50b3c142231245feec40d4 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Apr 2024 03:52:41 +0200 Subject: [PATCH 853/936] ISA PNP ROM parsing fixes (fixed DMA flags and added support for fixed-sized 10-bit I/O address). --- src/device/isapnp.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/device/isapnp.c b/src/device/isapnp.c index f9d10b380..da9e623c1 100644 --- a/src/device/isapnp.c +++ b/src/device/isapnp.c @@ -737,7 +737,7 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size) isapnp_log("ISAPnP: Parsing ROM resources for card %c%c%c%02X%02X (serial %08X)\n", '@' + ((vendor >> 10) & 0x1f), '@' + ((vendor >> 5) & 0x1f), '@' + (vendor & 0x1f), card->rom[2], card->rom[3], (card->rom[7] << 24) | (card->rom[6] << 16) | (card->rom[5] << 8) | card->rom[4]); const char *df_priority[] = { "good", "acceptable", "sub-optimal", "unknown priority" }; const char *mem_control[] = { "8-bit", "16-bit", "8/16-bit", "32-bit" }; - const char *dma_transfer[] = { "8-bit", "8/16-bit", "16-bit", "unknown" }; + const char *dma_transfer[] = { "8-bit", "8/16-bit", "16-bit", "Reserved" }; const char *dma_speed[] = { "compatibility", "Type A", "Type B", "Type F" }; #endif uint16_t i = 9; @@ -937,9 +937,9 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size) case 0x05: /* DMA */ isapnp_log("ISAPnP: >>%s DMA index %d with mask %02X, %s, %sbus master, %scount by byte, %scount by word, %s speed\n", in_df ? ">" : "", dma++, card->rom[i + 1], dma_transfer[card->rom[i + 2] & 3], - (card->rom[i + 2] & 0x04) ? "not " : "", - (card->rom[i + 2] & 0x08) ? "not " : "", - (card->rom[i + 2] & 0x10) ? "not " : "", + (card->rom[i + 2] & 0x04) ? "" : "not ", + (card->rom[i + 2] & 0x08) ? "" : "not ", + (card->rom[i + 2] & 0x10) ? "" : "not ", dma_speed[(card->rom[i + 2] >> 5) & 3]); break; #endif @@ -1004,6 +1004,29 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size) break; + case 0x09: /* Fixed I/O port */ + if (!ld) { + isapnp_log("ISAPnP: >>%s Fixed I/O descriptor with no logical device\n", in_df ? ">" : ""); + break; + } + + if (io > 7) { + isapnp_log("ISAPnP: >>%s Fixed I/O descriptor overflow (%d)\n", in_df ? ">" : "", io++); + break; + } + + isapnp_log("ISAPnP: >>%s Fixed I/O range %d with %d ports at %04X\n", in_df ? ">" : "", io, card->rom[i + 3], *((uint16_t *) &card->rom[i + 1])); + + /* Fixed I/O port ranges of this kind are always 10-bit. */ + ld->io_16bit &= ~(1 << io); + + if (card->rom[i + 3] > ld->io_len[io]) + ld->io_len[io] = card->rom[i + 3]; + + io++; + + break; + case 0x0f: /* end tag */ /* Calculate checksum. */ res = 0x00; From a2b3c4c8dc78c733cb534eb48b1c4d1d02338a28 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Apr 2024 03:54:12 +0200 Subject: [PATCH 854/936] ALi M1543(C) IDE fixes, fixes Windows 95 IDE driver. --- src/chipset/ali1543.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index fe3a0fda3..6f080b15b 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -197,6 +197,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) case 0x44: /* Set IRQ Line for Primary IDE if it's on native mode */ dev->pci_conf[addr] = val & 0xdf; soft_reset_pci = !!(val & 0x80); + pci_set_mirq_level(PCI_MIRQ0, !(val & 0x10)); pci_set_mirq_level(PCI_MIRQ2, !(val & 0x10)); ali1543_log("INTAJ = IRQ %i\n", ali1533_irq_routing[val & 0x0f]); pci_set_mirq_routing(PCI_MIRQ0, ali1533_irq_routing[val & 0x0f]); @@ -417,6 +418,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) case 0x75: /* Set IRQ Line for Secondary IDE if it's on native mode */ dev->pci_conf[addr] = val & 0x1f; + pci_set_mirq_level(PCI_MIRQ1, !(val & 0x10)); pci_set_mirq_level(PCI_MIRQ3, !(val & 0x10)); ali1543_log("INTBJ = IRQ %i\n", ali1533_irq_routing[val & 0x0f]); pci_set_mirq_routing(PCI_MIRQ1, ali1533_irq_routing[val & 0x0f]); @@ -704,7 +706,7 @@ ali5229_chip_reset(ali1543_t *dev) ali5229_write(0, 0x09, 0xfa, dev); ali5229_write(0, 0x52, 0x00, dev); - ali5229_write(0, 0x50, 0x00, dev); + ali5229_write(0, 0x50, 0x02, dev); sff_set_slot(dev->ide_controller[0], dev->ide_slot); sff_set_slot(dev->ide_controller[1], dev->ide_slot); @@ -717,7 +719,7 @@ static void ali5229_write(int func, int addr, uint8_t val, void *priv) { ali1543_t *dev = (ali1543_t *) priv; - ali1543_log("M5229: dev->ide_conf[%02x] = %02x\n", addr, val); + ali1543_log("M5229: [W] dev->ide_conf[%02x] = %02x\n", addr, val); if (func > 0) return; @@ -756,6 +758,10 @@ ali5229_write(int func, int addr, uint8_t val, void *priv) ali5229_ide_irq_handler(dev); break; + case 0x0d: /* LT - Latency Timer */ + dev->ide_conf[addr] = val; + break; + /* Primary Base Address */ case 0x10: case 0x11: @@ -887,13 +893,15 @@ ali5229_read(int func, int addr, void *priv) if (dev->ide_dev_enable && (func == 0)) { ret = dev->ide_conf[addr]; if ((addr == 0x09) && !(dev->ide_conf[0x50] & 0x02)) - ret &= 0x0f; + ret = (ret & 0x0f) | 0x80; else if (addr == 0x50) ret = (ret & 0xfe) | (dev->ide_dev_enable ? 0x01 : 0x00); else if (addr == 0x75) ret = ide_read_ali_75(); else if (addr == 0x76) ret = ide_read_ali_76(); + + ali1543_log("M5229: [R] dev->ide_conf[%02x] = %02x\n", addr, ret); } return ret; From 1e5800d5487e8ed980fd6a845593191cbe472c29 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Apr 2024 03:54:42 +0200 Subject: [PATCH 855/936] Intel 420TX-430TX cache control fixes. --- src/chipset/intel_4x0.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index a1f923e49..f2fa7aac2 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -493,16 +493,41 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case 0x52: /* Cache Control Register */ switch (dev->type) { default: + /* + 420TX/ZX: + Bit 7-6: 0, 0 = 64 kB, + 0, 1 = 128 kB, + 1, 0 = 256 kB, + 1, 1 = 512 kB. + Bit 5: 1 = L2 cache present, 0 = L2 cache absent. + Bit 1: 1 = Write back cache, 0 = write through cache. + Bit 0: 1 = L2 cache enable, 0 = L2 cache disable. + */ case INTEL_420TX: case INTEL_420ZX: + case INTEL_430NX: + pclog("52 = %02X\n", val); + regs[0x52] = (regs[0x52] & 0xe0) | (val & 0x1f); + cpu_cache_ext_enabled = val & 0x01; + cpu_update_waitstates(); + break; case INTEL_430LX: + regs[0x52] = (regs[0x52] & 0xe0) | (val & 0x1b); + cpu_cache_ext_enabled = val & 0x01; + cpu_update_waitstates(); + break; case INTEL_430FX: case INTEL_430VX: case INTEL_430TX: - regs[0x52] = (val & 0xfb); + regs[0x52] = (regs[0x52] & 0xf0) | (val & 0x0b); + cpu_cache_ext_enabled = ((val & 0x03) == 0x01); + cpu_update_waitstates(); break; - case INTEL_430NX: case INTEL_430HX: + regs[0x52] = (regs[0x52] & 0xf0) | (val & 0x0f); + cpu_cache_ext_enabled = ((val & 0x03) == 0x01); + cpu_update_waitstates(); + break; case INTEL_440FX: regs[0x52] = val; break; @@ -1630,7 +1655,7 @@ i4x0_init(const device_t *info) 0x00 = None, 0x01 = 64 kB, 0x41 = 128 kB, 0x81 = 256 kB, 0xc1 = 512 kB, If bit 0 is set, then if bit 2 is also set, the cache is write back, otherwise it's write through. */ - regs[0x52] = 0xc3; /* 512 kB writeback cache */ + regs[0x52] = 0xe0; /* 512 kB writeback cache */ regs[0x57] = 0x31; regs[0x59] = 0x0f; regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = 0x02; From ae834c1a2df50a87ca19b48e1f7f8b86af515dd3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Apr 2024 04:21:01 +0200 Subject: [PATCH 856/936] AT MFM/RLL: The SET DRIVE PARAMETERS and RESTORE commands no longer finish instantly, fixes MFM/RLL drives on the Arche AMA-2010. --- src/disk/hdc_st506_at.c | 86 +++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 38 deletions(-) diff --git a/src/disk/hdc_st506_at.c b/src/disk/hdc_st506_at.c index 67bea6a8e..d5bbf24d0 100644 --- a/src/disk/hdc_st506_at.c +++ b/src/disk/hdc_st506_at.c @@ -277,13 +277,9 @@ mfm_cmd(mfm_t *mfm, uint8_t val) switch (val & 0xf0) { case CMD_RESTORE: drive->steprate = (val & 0x0f); - st506_at_log("WD1003(%d) restore, step=%d\n", - mfm->drvsel, drive->steprate); - drive->curcyl = 0; - mfm->cylinder = 0; - mfm->status = STAT_READY | STAT_DSC; mfm->command &= 0xf0; - irq_raise(mfm); + mfm->status = STAT_BUSY; + timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME); break; case CMD_SEEK: @@ -340,38 +336,8 @@ mfm_cmd(mfm_t *mfm, uint8_t val) break; case CMD_SET_PARAMETERS: - /* - * NOTE: - * - * We currently just set these parameters, and - * never bother to check if they "fit within" - * the actual parameters, as determined by the - * image loader. - * - * The difference in parameters is OK, and - * occurs when the BIOS or operating system - * decides to use a different translation - * scheme, but either way, it SHOULD always - * fit within the actual parameters! - * - * We SHOULD check that here!! --FvK - */ - if (drive->cfg_spt == 0) { - /* Only accept after RESET or DIAG. */ - drive->cfg_spt = mfm->secount; - drive->cfg_hpc = mfm->head + 1; - st506_at_log("WD1003(%d) parameters: tracks=%d, spt=%i, hpc=%i\n", - mfm->drvsel, drive->tracks, - drive->cfg_spt, drive->cfg_hpc); - } else { - st506_at_log("WD1003(%d) parameters: tracks=%d,spt=%i,hpc=%i (IGNORED)\n", - mfm->drvsel, drive->tracks, - drive->cfg_spt, drive->cfg_hpc); - } - mfm->command = 0x00; - mfm->status = STAT_READY | STAT_DSC; - mfm->error = 1; - irq_raise(mfm); + mfm->status = STAT_BUSY; + timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME); break; default: @@ -596,6 +562,15 @@ do_callback(void *priv) } switch (mfm->command) { + case CMD_RESTORE: + st506_at_log("WD1003(%d) restore, step=%d\n", + mfm->drvsel, drive->steprate); + drive->curcyl = 0; + mfm->cylinder = 0; + mfm->status = STAT_READY | STAT_DSC; + irq_raise(mfm); + break; + case CMD_SEEK: st506_at_log("WD1003(%d) seek, step=%d\n", mfm->drvsel, drive->steprate); @@ -691,6 +666,41 @@ do_callback(void *priv) irq_raise(mfm); break; + case CMD_SET_PARAMETERS: + /* + * NOTE: + * + * We currently just set these parameters, and + * never bother to check if they "fit within" + * the actual parameters, as determined by the + * image loader. + * + * The difference in parameters is OK, and + * occurs when the BIOS or operating system + * decides to use a different translation + * scheme, but either way, it SHOULD always + * fit within the actual parameters! + * + * We SHOULD check that here!! --FvK + */ + if (drive->cfg_spt == 0) { + /* Only accept after RESET or DIAG. */ + drive->cfg_spt = mfm->secount; + drive->cfg_hpc = mfm->head + 1; + st506_at_log("WD1003(%d) parameters: tracks=%d, spt=%i, hpc=%i\n", + mfm->drvsel, drive->tracks, + drive->cfg_spt, drive->cfg_hpc); + } else { + st506_at_log("WD1003(%d) parameters: tracks=%d,spt=%i,hpc=%i (IGNORED)\n", + mfm->drvsel, drive->tracks, + drive->cfg_spt, drive->cfg_hpc); + } + mfm->command = 0x00; + mfm->status = STAT_READY | STAT_DSC; + mfm->error = 1; + irq_raise(mfm); + break; + default: st506_at_log("WD1003(%d) callback on unknown command %02x\n", mfm->drvsel, mfm->command); From c74f168c29d84c6f090a223bce4e39e4d4170d84 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Apr 2024 04:28:08 +0200 Subject: [PATCH 857/936] The AMA-932J now indicates it is an Arche machine and correctly uses the Acer/ALi M5105 Super I/O chip. --- src/machine/m_at_286_386sx.c | 4 +++- src/machine/machine_table.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index 53df7f628..b2470bae2 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -70,7 +70,7 @@ machine_at_headland_common_init(int type) { device_add(&keyboard_at_ami_device); - if (fdc_type == FDC_INTERNAL) + if ((type != 2) && (fdc_type == FDC_INTERNAL)) device_add(&fdc_at_device); if (type == 2) @@ -117,6 +117,8 @@ machine_at_ama932j_init(const machine_t *model) machine_at_headland_common_init(2); + device_add(&ali5105_device); + return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index f7d46cec9..3aafe237c 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -4253,7 +4253,7 @@ const machine_t machines[] = { for me to read what's on the KBC chip, so I'm going to assume AMI 'F' based on the other known HT18 AMI BIOS strings. */ { - .name = "[HT18] AMA-932J", + .name = "[HT18] Arche AMA-932J", .internal_name = "ama932j", .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_HT18, From 955297b9c44e01364ec20efaef145c43770d944d Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Apr 2024 04:33:20 +0200 Subject: [PATCH 858/936] Removed excess logging from the Intel 4x0 chipset emulation. --- src/chipset/intel_4x0.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index f2fa7aac2..8abbe50c1 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -506,7 +506,6 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_420TX: case INTEL_420ZX: case INTEL_430NX: - pclog("52 = %02X\n", val); regs[0x52] = (regs[0x52] & 0xe0) | (val & 0x1f); cpu_cache_ext_enabled = val & 0x01; cpu_update_waitstates(); From 373fe0f258a726bf616961a47e3b2e76da031aa0 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Sun, 24 Mar 2024 12:07:58 -0400 Subject: [PATCH 859/936] qt: Disable bus channels that are currently in use --- src/qt/qt_harddiskdialog.cpp | 2 +- src/qt/qt_harddrive_common.cpp | 24 +++++++++++++++++- src/qt/qt_harddrive_common.hpp | 3 ++- src/qt/qt_settings.cpp | 4 +++ src/qt/qt_settings_bus_tracking.cpp | 39 +++++++++++++++++++++++++++++ src/qt/qt_settings_bus_tracking.hpp | 2 ++ src/qt/qt_settingsfloppycdrom.cpp | 22 +++++++++++++++- src/qt/qt_settingsfloppycdrom.hpp | 4 +++ src/qt/qt_settingsharddisks.cpp | 26 ++++++++++++++++++- src/qt/qt_settingsharddisks.hpp | 5 ++++ 10 files changed, 126 insertions(+), 5 deletions(-) diff --git a/src/qt/qt_harddiskdialog.cpp b/src/qt/qt_harddiskdialog.cpp index 5efd895dc..df10a6d38 100644 --- a/src/qt/qt_harddiskdialog.cpp +++ b/src/qt/qt_harddiskdialog.cpp @@ -746,7 +746,7 @@ HarddiskDialog::on_comboBoxBus_currentIndexChanged(int index) ui->lineEditHeads->setValidator(new QIntValidator(1, max_heads, this)); ui->lineEditSectors->setValidator(new QIntValidator(1, max_sectors, this)); - Harddrives::populateBusChannels(ui->comboBoxChannel->model(), ui->comboBoxBus->currentData().toInt()); + Harddrives::populateBusChannels(ui->comboBoxChannel->model(), ui->comboBoxBus->currentData().toInt(), Harddrives::busTrackClass); Harddrives::populateSpeeds(ui->comboBoxSpeed->model(), ui->comboBoxBus->currentData().toInt()); switch (ui->comboBoxBus->currentData().toInt()) { diff --git a/src/qt/qt_harddrive_common.cpp b/src/qt/qt_harddrive_common.cpp index dda36917f..213ebf07b 100644 --- a/src/qt/qt_harddrive_common.cpp +++ b/src/qt/qt_harddrive_common.cpp @@ -24,6 +24,7 @@ extern "C" { } #include +#include void Harddrives::populateBuses(QAbstractItemModel *model) @@ -96,7 +97,7 @@ Harddrives::populateSpeeds(QAbstractItemModel *model, int bus) } void -Harddrives::populateBusChannels(QAbstractItemModel *model, int bus) +Harddrives::populateBusChannels(QAbstractItemModel *model, int bus, SettingsBusTracking *sbt) { model->removeRows(0, model->rowCount()); @@ -104,6 +105,8 @@ Harddrives::populateBusChannels(QAbstractItemModel *model, int bus) int shifter = 1; int orer = 1; int subChannelWidth = 1; + QList busesToCheck; + QList channelsInUse; switch (bus) { case HDD_BUS_MFM: case HDD_BUS_XTA: @@ -111,15 +114,29 @@ Harddrives::populateBusChannels(QAbstractItemModel *model, int bus) busRows = 2; break; case HDD_BUS_IDE: + busRows = 8; + busesToCheck.append(HDD_BUS_ATAPI); + busesToCheck.append(HDD_BUS_IDE); + break; case HDD_BUS_ATAPI: busRows = 8; + busesToCheck.append(HDD_BUS_IDE); + busesToCheck.append(HDD_BUS_ATAPI); break; case HDD_BUS_SCSI: shifter = 4; orer = 15; busRows = 64; subChannelWidth = 2; + busesToCheck.append(HDD_BUS_SCSI); break; + default: + break; + } + if(sbt != nullptr && !busesToCheck.empty()) { + for (auto const &checkBus : busesToCheck) { + channelsInUse.append(sbt->busChannelsInUse(checkBus)); + } } model->insertRows(0, busRows); @@ -127,6 +144,11 @@ Harddrives::populateBusChannels(QAbstractItemModel *model, int bus) auto idx = model->index(i, 0); model->setData(idx, QString("%1:%2").arg(i >> shifter).arg(i & orer, subChannelWidth, 10, QChar('0'))); model->setData(idx, ((i >> shifter) << shifter) | (i & orer), Qt::UserRole); + const auto *channelModel = qobject_cast(model); + auto *channelItem = channelModel->item(i); + if(channelItem) { + channelItem->setEnabled(!channelsInUse.contains(i)); + } } } diff --git a/src/qt/qt_harddrive_common.hpp b/src/qt/qt_harddrive_common.hpp index 2aca184b3..28189f328 100644 --- a/src/qt/qt_harddrive_common.hpp +++ b/src/qt/qt_harddrive_common.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include "qt_settings_bus_tracking.hpp" class QString; class QAbstractItemModel; @@ -9,7 +10,7 @@ class SettingsBusTracking; namespace Harddrives { void populateBuses(QAbstractItemModel *model); void populateRemovableBuses(QAbstractItemModel *model); -void populateBusChannels(QAbstractItemModel *model, int bus); +void populateBusChannels(QAbstractItemModel *model, int bus, SettingsBusTracking *sbt = nullptr); void populateSpeeds(QAbstractItemModel *model, int bus); QString BusChannelName(uint8_t bus, uint8_t channel); inline SettingsBusTracking *busTrackClass = nullptr; diff --git a/src/qt/qt_settings.cpp b/src/qt/qt_settings.cpp index c7cb99086..a7e52c342 100644 --- a/src/qt/qt_settings.cpp +++ b/src/qt/qt_settings.cpp @@ -153,6 +153,10 @@ Settings::Settings(QWidget *parent) &SettingsStorageControllers::onCurrentMachineChanged); connect(machine, &SettingsMachine::currentMachineChanged, otherPeripherals, &SettingsOtherPeripherals::onCurrentMachineChanged); + connect(floppyCdrom, &SettingsFloppyCDROM::cdromChannelChanged, harddisks, + &SettingsHarddisks::reloadBusChannels); + connect(harddisks, &SettingsHarddisks::driveChannelChanged, floppyCdrom, + &SettingsFloppyCDROM::reloadBusChannels); connect(ui->listView->selectionModel(), &QItemSelectionModel::currentChanged, this, [this](const QModelIndex ¤t, const QModelIndex &previous) { diff --git a/src/qt/qt_settings_bus_tracking.cpp b/src/qt/qt_settings_bus_tracking.cpp index 4fe112627..064fbe0b4 100644 --- a/src/qt/qt_settings_bus_tracking.cpp +++ b/src/qt/qt_settings_bus_tracking.cpp @@ -198,6 +198,45 @@ SettingsBusTracking::scsi_bus_full() return (count == 64); } +QList SettingsBusTracking::busChannelsInUse(const int bus) { + + QList channelsInUse; + int element; + uint64_t mask; + switch (bus) { + case HDD_BUS_IDE: + for (uint8_t i = 0; i < 32; i++) { + element = ((i << 3) >> 6); + mask = ((uint64_t) DEV_HDD) << ((uint64_t) ((i << 3) & 0x3f)); + if (ide_tracking[element] & mask) { + channelsInUse.append(i); + } + } + break; + case HDD_BUS_ATAPI: + for (uint8_t i = 0; i < 32; i++) { + element = ((i << 3) >> 6); + mask = ((uint64_t) DEV_CDROM) << ((uint64_t) ((i << 3) & 0x3f)); + if (ide_tracking[element] & mask) { + channelsInUse.append(i); + } + } + break; + case HDD_BUS_SCSI: + for (uint8_t i = 0; i < 64; i++) { + element = ((i << 3) >> 6); + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + if (scsi_tracking[element] & mask) + channelsInUse.append(i); + } + break; + default: + break; + } + + return channelsInUse; +} + void SettingsBusTracking::device_track(int set, uint8_t dev_type, int bus, int channel) { diff --git a/src/qt/qt_settings_bus_tracking.hpp b/src/qt/qt_settings_bus_tracking.hpp index 3ec61dfb7..279d3247e 100644 --- a/src/qt/qt_settings_bus_tracking.hpp +++ b/src/qt/qt_settings_bus_tracking.hpp @@ -28,6 +28,8 @@ public: explicit SettingsBusTracking(); ~SettingsBusTracking() = default; + QList busChannelsInUse(int bus); + /* These return 0xff is none is free. */ uint8_t next_free_mfm_channel(); uint8_t next_free_esdi_channel(); diff --git a/src/qt/qt_settingsfloppycdrom.cpp b/src/qt/qt_settingsfloppycdrom.cpp index 988f9e856..bb536e603 100644 --- a/src/qt/qt_settingsfloppycdrom.cpp +++ b/src/qt/qt_settingsfloppycdrom.cpp @@ -263,6 +263,7 @@ SettingsFloppyCDROM::onCDROMRowChanged(const QModelIndex ¤t) ui->comboBoxSpeed->setCurrentIndex(speed == 0 ? 7 : speed - 1); ui->comboBoxCDROMType->setCurrentIndex(type); + enableCurrentlySelectedChannel(); } void @@ -288,6 +289,13 @@ SettingsFloppyCDROM::on_comboBoxFloppyType_activated(int index) ui->tableViewFloppy->selectionModel()->currentIndex(), index); } +void SettingsFloppyCDROM::reloadBusChannels() { + auto selected = ui->comboBoxChannel->currentIndex(); + Harddrives::populateBusChannels(ui->comboBoxChannel->model(), ui->comboBoxBus->currentData().toInt(), Harddrives::busTrackClass); + ui->comboBoxChannel->setCurrentIndex(selected); + enableCurrentlySelectedChannel(); +} + void SettingsFloppyCDROM::on_comboBoxBus_currentIndexChanged(int index) { @@ -298,7 +306,7 @@ SettingsFloppyCDROM::on_comboBoxBus_currentIndexChanged(int index) ui->comboBoxSpeed->setEnabled((bus == CDROM_BUS_MITSUMI) ? 0 : enabled); ui->comboBoxCDROMType->setEnabled((bus == CDROM_BUS_MITSUMI) ? 0 : enabled); - Harddrives::populateBusChannels(ui->comboBoxChannel->model(), bus); + Harddrives::populateBusChannels(ui->comboBoxChannel->model(), bus, Harddrives::busTrackClass); } } @@ -362,6 +370,17 @@ SettingsFloppyCDROM::on_comboBoxBus_activated(int) ui->comboBoxCDROMType->currentData().toUInt()); } +void +SettingsFloppyCDROM::enableCurrentlySelectedChannel() +{ + const auto *item_model = qobject_cast(ui->comboBoxChannel->model()); + const auto index = ui->comboBoxChannel->currentIndex(); + auto *item = item_model->item(index); + if(item) { + item->setEnabled(true); + } +} + void SettingsFloppyCDROM::on_comboBoxChannel_activated(int) { @@ -376,6 +395,7 @@ SettingsFloppyCDROM::on_comboBoxChannel_activated(int) Harddrives::busTrackClass->device_track(1, DEV_CDROM, ui->tableViewCDROM->model()->data(i, Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, Qt::UserRole + 1).toInt()); + emit cdromChannelChanged(); } void diff --git a/src/qt/qt_settingsfloppycdrom.hpp b/src/qt/qt_settingsfloppycdrom.hpp index 3d6dd0e45..0a3424216 100644 --- a/src/qt/qt_settingsfloppycdrom.hpp +++ b/src/qt/qt_settingsfloppycdrom.hpp @@ -13,9 +13,12 @@ class SettingsFloppyCDROM : public QWidget { public: explicit SettingsFloppyCDROM(QWidget *parent = nullptr); ~SettingsFloppyCDROM(); + void reloadBusChannels(); void save(); +signals: + void cdromChannelChanged(); private slots: void on_comboBoxCDROMType_activated(int index); void on_comboBoxChannel_activated(int index); @@ -30,6 +33,7 @@ private slots: private: Ui::SettingsFloppyCDROM *ui; + void enableCurrentlySelectedChannel(); }; #endif // QT_SETTINGSFLOPPYCDROM_HPP diff --git a/src/qt/qt_settingsharddisks.cpp b/src/qt/qt_settingsharddisks.cpp index a66203406..3f02ffe54 100644 --- a/src/qt/qt_settingsharddisks.cpp +++ b/src/qt/qt_settingsharddisks.cpp @@ -166,6 +166,13 @@ SettingsHarddisks::save() } } +void SettingsHarddisks::reloadBusChannels() { + const auto selected = ui->comboBoxChannel->currentIndex(); + Harddrives::populateBusChannels(ui->comboBoxChannel->model(), ui->comboBoxBus->currentData().toInt(), Harddrives::busTrackClass); + ui->comboBoxChannel->setCurrentIndex(selected); + enableCurrentlySelectedChannel(); +} + void SettingsHarddisks::on_comboBoxBus_currentIndexChanged(int index) { @@ -184,7 +191,7 @@ SettingsHarddisks::on_comboBoxBus_currentIndexChanged(int index) model->setData(col, ui->comboBoxBus->currentData(Qt::UserRole), DataBusPrevious); } - Harddrives::populateBusChannels(ui->comboBoxChannel->model(), ui->comboBoxBus->currentData().toInt()); + Harddrives::populateBusChannels(ui->comboBoxChannel->model(), ui->comboBoxBus->currentData().toInt(), Harddrives::busTrackClass); Harddrives::populateSpeeds(ui->comboBoxSpeed->model(), ui->comboBoxBus->currentData().toInt()); int chanIdx = 0; @@ -233,6 +240,18 @@ SettingsHarddisks::on_comboBoxChannel_currentIndexChanged(int index) Harddrives::busTrackClass->device_track(0, DEV_HDD, model->data(col, DataBus).toInt(), model->data(col, DataBusChannelPrevious).toUInt()); Harddrives::busTrackClass->device_track(1, DEV_HDD, model->data(col, DataBus).toInt(), model->data(col, DataBusChannel).toUInt()); model->setData(col, ui->comboBoxChannel->currentData(Qt::UserRole), DataBusChannelPrevious); + emit driveChannelChanged(); + } +} + +void +SettingsHarddisks::enableCurrentlySelectedChannel() +{ + const auto *item_model = qobject_cast(ui->comboBoxChannel->model()); + const auto index = ui->comboBoxChannel->currentIndex(); + auto *item = item_model->item(index); + if(item) { + item->setEnabled(true); } } @@ -283,6 +302,7 @@ SettingsHarddisks::onTableRowChanged(const QModelIndex ¤t) if (!match.isEmpty()) { ui->comboBoxSpeed->setCurrentIndex(match.first().row()); } + reloadBusChannels(); } static void @@ -317,6 +337,7 @@ SettingsHarddisks::on_pushButtonNew_clicked() switch (dialog.exec()) { case QDialog::Accepted: addDriveFromDialog(ui, dialog); + reloadBusChannels(); break; } } @@ -328,6 +349,7 @@ SettingsHarddisks::on_pushButtonExisting_clicked() switch (dialog.exec()) { case QDialog::Accepted: addDriveFromDialog(ui, dialog); + reloadBusChannels(); break; } } @@ -341,6 +363,8 @@ SettingsHarddisks::on_pushButtonRemove_clicked() } auto *model = ui->tableView->model(); + const auto col = idx.siblingAtColumn(ColumnBus); + Harddrives::busTrackClass->device_track(0, DEV_HDD, model->data(col, DataBus).toInt(), model->data(col, DataBusChannel).toInt()); model->removeRow(idx.row()); ui->pushButtonNew->setEnabled(true); ui->pushButtonExisting->setEnabled(true); diff --git a/src/qt/qt_settingsharddisks.hpp b/src/qt/qt_settingsharddisks.hpp index 68d7ca3d6..4bd287d29 100644 --- a/src/qt/qt_settingsharddisks.hpp +++ b/src/qt/qt_settingsharddisks.hpp @@ -13,9 +13,13 @@ class SettingsHarddisks : public QWidget { public: explicit SettingsHarddisks(QWidget *parent = nullptr); ~SettingsHarddisks(); + void reloadBusChannels(); void save(); +signals: + void driveChannelChanged(); + private slots: void on_comboBoxChannel_currentIndexChanged(int index); void on_comboBoxSpeed_currentIndexChanged(int index); @@ -30,6 +34,7 @@ private slots: private: Ui::SettingsHarddisks *ui; + void enableCurrentlySelectedChannel(); bool buschangeinprogress = false; }; From 0a1888feec1f82ae82658e4f9bd40b419b9687f0 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 18 Apr 2024 20:39:05 +0200 Subject: [PATCH 860/936] the DEC 21143-based NIC expects a SROM Format version of 3 This fixes detection under various operating systems, including NT-based ones. --- src/network/net_tulip.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index ffc342e81..e34327eb5 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -1530,6 +1530,9 @@ nic_init(const device_t *info) s->eeprom_data[40] = 0x00; s->eeprom_data[41] = 0x00; } else { + /*SROM Format Version 3*/ + s->eeprom_data[18] = 0x03; + /*Block Count*/ s->eeprom_data[32] = 0x01; @@ -1677,7 +1680,7 @@ static const device_config_t dec_tulip_21140_config[] = { // clang-format on const device_t dec_tulip_device = { - .name = "DE500A Fast Ethernet (DECchip 21143 \"Tulip\")", + .name = "DEC DE-500A Fast Ethernet (DECchip 21143 \"Tulip\")", .internal_name = "dec_21143_tulip", .flags = DEVICE_PCI, .local = 0, From 50ca61dfd45b301d1e98003c76ea832154752fda Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 20 Apr 2024 23:43:27 +0200 Subject: [PATCH 861/936] ATI/IBM mode changes in the Mach8/32. Reworked the way the mode changes work in said chips (and way less hacky than before). --- src/video/vid_ati_mach8.c | 138 ++++++++++++++++++-------------------- 1 file changed, 67 insertions(+), 71 deletions(-) diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 2613de767..522df00a6 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2599,12 +2599,25 @@ mach_recalctimings(svga_t *svga) dev->h_total = dev->htotal + 1; dev->h_blankstart = dev->hblankstart; dev->h_blank_end_val = dev->hblank_end_val; - dev->v_total = dev->vtotal; - dev->v_syncstart = dev->vsyncstart; + dev->v_total = dev->v_total_reg + 1; + dev->v_syncstart = dev->v_sync_start + 1; dev->rowcount = !!(dev->disp_cntl & 0x08); - dev->h_disp = dev->hdisp; - dev->dispend = dev->vdisp; + mach_log("VDISP=%d.\n", dev->vdisp); + if ((dev->hdisp == 800) || (dev->hdisp == 1280)) { + /*For VESA modes in ATI 8514/A mode.*/ + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; + } else { + /*Default modes for 8514/A mode*/ + if (dev->accel.advfunc_cntl & 0x04) { + dev->h_disp = 1024; + dev->dispend = 768; + } else { + dev->h_disp = 640; + dev->dispend = 480; + } + } if (dev->dispend == 766) dev->dispend += 2; @@ -2709,13 +2722,6 @@ mach_recalctimings(svga_t *svga) svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); else svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; - - if (((mach->shadow_set & 0x03) != 0x02) || !(dev->accel.advfunc_cntl & 0x04)) { /*Shadow set of 2 and bit 2 of port 0x4ae8 mean 1024x768+*/ - if (!(mach->accel.clock_sel & 0x01)) { - dev->h_disp = 640; - dev->dispend = 480; - } - } } if (dev->interlace) { @@ -3620,84 +3626,63 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0x2e8: case 0x2e9: WRITE8(port, dev->htotal, val); + dev->htotal &= 0x1ff; break; case 0x6e8: - case 0x6e9: - if (!(port & 1)) { - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { - dev->hdisped = val; - dev->hdisp = (dev->hdisped + 1) << 3; - if ((dev->hdisp == 640) && ((mach->shadow_set & 0x03) == 0x02) && (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) - svga_recalctimings(svga); - else if ((dev->hdisp == 1024) && !(mach->accel.clock_sel & 0x01) && ((dev->disp_cntl & 0x60) == 0x40)) { - if (dev->accel.advfunc_cntl & 0x04) { - dev->hdisp = 1024; - dev->vdisp = 768; - } else { - dev->hdisp = 640; - dev->vdisp = 480; - } - svga_recalctimings(svga); - } - } - } + /*In preparation to switch from VGA to 8514/A mode*/ + if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) + dev->hdisped = val; + mach_log("[%04X:%08X]: ATI 8514/A: H_DISP write 06E8 = %d, actual val=%d, set lock=%x, shadow set=%x, advfunc bit 2=%x, dispcntl=%02x, clocksel bit 0=%x.\n", CS, cpu_state.pc, dev->hdisp, ((val + 1) << 3), mach->shadow_cntl, mach->shadow_set, dev->accel.advfunc_cntl & 0x04, dev->disp_cntl & 0x60, mach->accel.clock_sel & 0x01); + mach_log("ATI 8514/A: (0x%04x): hdisp=0x%02x.\n", port, val); + break; + case 0x6e9: + dev->hdisped = (dev->hdisp >> 3) - 1; + dev->v_disp = (dev->vdisp - 1) << 1; + mach_log("ATI 8514/A: (0x%04x): hdisp=0x%02x.\n", port, val); break; case 0xae8: - case 0xae9: - if (!(port & 1)) { - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { - dev->hsync_start = val; - dev->hblankstart = (dev->hsync_start & 0x07); - } - } + dev->hsync_start = val; + dev->hblankstart = (dev->hsync_start & 0x07); mach_log("ATI 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); break; case 0xee8: - case 0xee9: - if (!(port & 1)) { - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { - dev->hsync_width = val; - dev->hblank_end_val = (dev->hblankstart + (dev->hsync_width & 0x1f) - 1) & 0x3f; - } - } + dev->hsync_width = val; + dev->hblank_end_val = (dev->hblankstart + (dev->hsync_width & 0x1f) - 1) & 0x3f; mach_log("ATI 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); break; case 0x12e8: case 0x12e9: - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { + /*In preparation to switch from VGA to 8514/A mode*/ + if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) { WRITE8(port, dev->v_total_reg, val); dev->v_total_reg &= 0x1fff; - dev->vtotal = dev->v_total_reg; - dev->vtotal++; } break; case 0x16e8: case 0x16e9: - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { + /*In preparation to switch from VGA to 8514/A mode*/ + if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) { WRITE8(port, dev->v_disp, val); dev->v_disp &= 0x1fff; - dev->vdisp = dev->v_disp; - dev->vdisp >>= 1; - dev->vdisp++; } dev->modechange = dev->accel.advfunc_cntl & 0x04; mach->compat_mode = mach->shadow_set & 0x03; - mach_log("ATI 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp); + mach_log("ATI 8514/A: V_DISP write 16E8 = %d\n", dev->v_disp); + mach_log("ATI 8514/A: (0x%04x): vdisp=0x%02x.\n", port, val); break; case 0x1ae8: case 0x1ae9: - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { + /*In preparation to switch from VGA to 8514/A mode*/ + if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) { WRITE8(port, dev->v_sync_start, val); dev->v_sync_start &= 0x1fff; - dev->vsyncstart = dev->v_sync_start; - dev->vsyncstart++; } break; @@ -3709,7 +3694,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0x22e8: dev->disp_cntl = val; dev->interlace = !!(val & 0x10); - mach_log("ATI 8514/A: DISP_CNTL write 22E8 = %02x, interlace = %d\n", dev->disp_cntl, dev->interlace); + mach_log("ATI 8514/A: DISP_CNTL write %04x=%02x, interlace=%d.\n", port, dev->disp_cntl, dev->interlace); break; case 0x42e8: @@ -3747,7 +3732,10 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 mach->ext_on[port & 1] = dev->on[port & 1]; mach32_updatemapping(mach, svga); dev->vendor_mode[port & 1] = 0; - mach_log("ATI 8514/A: (0x%04x): ON=%d, shadow crt=%x, hdisp=%d.\n", port, dev->on[port & 1], dev->accel.advfunc_cntl & 4, dev->hdisp); + dev->hdisp = (dev->hdisped + 1) << 3; + dev->vdisp = (dev->v_disp >> 1) + 1; + mach_log("ATI 8514/A: (0x%04x): ON=%d, shadow crt=%x, hdisp=%d, vdisp=%d.\n", port, dev->on[port & 1], dev->accel.advfunc_cntl & 0x04, dev->hdisp, dev->vdisp); + mach_log("IBM mode set %s resolution.\n", (dev->accel.advfunc_cntl & 0x04) ? "2: 1024x768" : "1: 640x480"); svga_recalctimings(svga); break; @@ -3825,7 +3813,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 else dev->ext_crt_pitch <<= 1; } - mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); + mach_log("ATI 8514/A: (0x%04x) val=%04x.\n", port, val); svga_recalctimings(svga); break; @@ -3864,39 +3852,46 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0x46ee: case 0x46ef: - mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); WRITE8(port, mach->shadow_cntl, val); + mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); break; case 0x4aee: case 0x4aef: WRITE8(port, mach->accel.clock_sel, val); dev->on[port & 1] = mach->accel.clock_sel & 0x01; - mach_log("ATI 8514/A: (0x%04x): ON=%d.\n", port, dev->on[port & 1]); + mach_log("ATI 8514/A: (0x%04x): ON=%d, val=%04x, hdisp=%d, vdisp=%d.\n", port, dev->on[port & 1], val, dev->hdisp, dev->vdisp); + mach_log("ATI mode set %s resolution.\n", (dev->accel.advfunc_cntl & 0x04) ? "2: 1024x768" : "1: 640x480"); mach->ext_on[port & 1] = dev->on[port & 1]; vga_on = !dev->on[port & 1]; dev->vendor_mode[port & 1] = 1; + dev->hdisp = (dev->hdisped + 1) << 3; + dev->vdisp = (dev->v_disp >> 1) + 1; svga_recalctimings(svga); break; case 0x52ee: case 0x52ef: - mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); + mach_log("ATI 8514/A: (0x%04x) val=%04x.\n", port, val); WRITE8(port, mach->accel.scratch0, val); break; case 0x56ee: case 0x56ef: - mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); + mach_log("ATI 8514/A: (0x%04x) val=%04x.\n", port, val); WRITE8(port, mach->accel.scratch1, val); break; case 0x5aee: case 0x5aef: - if (!(mach->shadow_cntl & 0x3f)) { - WRITE8(port, mach->shadow_set, val); - mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); - } + WRITE8(port, mach->shadow_set, val); + mach_log("ATI 8514/A: (0x%04x) val=%04x.\n", port, val); + if ((mach->shadow_set & 0x03) == 0x00) + mach_log("Primary CRT register set.\n"); + else if ((mach->shadow_set & 0x03) == 0x01) + mach_log("Shadow Set 1: 640x480.\n"); + else if ((mach->shadow_set & 0x03) == 0x02) + mach_log("Shadow Set 2: 1024x768.\n"); break; case 0x5eee: @@ -3938,7 +3933,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0x76ef: WRITE8(port, mach->accel.ge_pitch, val); dev->ext_pitch = ((mach->accel.ge_pitch & 0xff) << 3); - mach_log("ATI 8514/A: (0x%04x) val = %04x, extpitch = %d.\n", port, val, dev->ext_pitch); + mach_log("ATI 8514/A: (0x%04x) val=%04x, extpitch=%d.\n", port, val, dev->ext_pitch); svga_recalctimings(svga); break; @@ -3971,7 +3966,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 svga_set_ramdac_type(svga, !!(mach->accel.ext_ge_config & 0x4000)); dev->vendor_mode[port & 1] = 1; mach32_updatemapping(mach, svga); - mach_log("ATI 8514/A: (0x%04x) val = %02x.\n", port, val); + mach_log("ATI 8514/A: (0x%04x) val=%02x.\n", port, val); svga_recalctimings(svga); } else { if (mach->accel.ext_ge_config & 0x8080) @@ -4285,6 +4280,7 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in temp = dev->hdisped & 0xff; temp |= (dev->htotal << 8); } + mach_log("B2EE read=%02x.\n", temp & 0xff); break; case 0xb2ef: if (len == 1) @@ -4301,15 +4297,15 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in case 0xc2ee: if (len == 1) - temp = dev->vtotal & 0xff; + temp = dev->v_total_reg & 0xff; else { - temp = dev->vtotal; + temp = dev->v_total_reg; mach_log("VTOTAL read=%d.\n", temp); } break; case 0xc2ef: if (len == 1) - temp = dev->vtotal >> 8; + temp = dev->v_total_reg >> 8; break; case 0xc6ee: From 10fd8fb0041bd3703e4aba5763fe40389236fb18 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 22 Apr 2024 02:04:57 +0200 Subject: [PATCH 862/936] Assorted CD-ROM fixes, fixes #4386. --- src/cdrom/cdrom.c | 3 +- src/cdrom/cdrom_image_backend.c | 145 ++++++++++-------------- src/include/86box/cdrom_image_backend.h | 4 +- src/scsi/scsi_cdrom.c | 2 +- 4 files changed, 67 insertions(+), 87 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index ea025de2a..e4e76ea66 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -1524,8 +1524,9 @@ static void read_sector_to_buffer(cdrom_t *dev, uint8_t *rbuf, uint32_t msf, uint32_t lba, int mode2, int len) { uint8_t *bb = rbuf; + const int offset = (!!(mode2 & 0x03)) ? 24 : 16; - dev->ops->read_sector(dev, CD_READ_DATA, rbuf + 16, lba); + dev->ops->read_sector(dev, CD_READ_DATA, rbuf + offset, lba); /* Sync bytes */ bb[0] = 0; diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index 1bc0fcf2d..482769799 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -70,12 +70,12 @@ cdrom_image_backend_log(const char *fmt, ...) static int bin_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count) { - track_file_t *tf = (track_file_t *) priv; + track_file_t *tf; cdrom_image_backend_log("CDROM: binary_read(%08lx, pos=%" PRIu64 " count=%lu\n", tf->fp, seek, count); - if (tf->fp == NULL) + if ((tf = (track_file_t *) priv)->fp == NULL) return 0; if (fseeko64(tf->fp, seek, SEEK_SET) == -1) { @@ -98,16 +98,15 @@ bin_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count) static uint64_t bin_get_length(void *priv) { - off64_t len; - track_file_t *tf = (track_file_t *) priv; + track_file_t *tf; cdrom_image_backend_log("CDROM: binary_length(%08lx)\n", tf->fp); - if (tf->fp == NULL) + if ((tf = (track_file_t *) priv)->fp == NULL) return 0; fseeko64(tf->fp, 0, SEEK_END); - len = ftello64(tf->fp); + const off64_t len = ftello64(tf->fp); cdrom_image_backend_log("CDROM: binary_length(%08lx) = %" PRIu64 "\n", tf->fp, len); return len; @@ -248,26 +247,20 @@ cdi_set_device(cd_img_t *cdi, const char *path) return 0; } -/* TODO: This never returns anything other than 1, should it even be an int? */ -int +void cdi_get_audio_tracks(cd_img_t *cdi, int *st_track, int *end, TMSF *lead_out) { *st_track = 1; *end = cdi->tracks_num - 1; FRAMES_TO_MSF(cdi->tracks[*end].start + 150, &lead_out->min, &lead_out->sec, &lead_out->fr); - - return 1; } -/* TODO: This never returns anything other than 1, should it even be an int? */ -int +void cdi_get_audio_tracks_lba(cd_img_t *cdi, int *st_track, int *end, uint32_t *lead_out) { *st_track = 1; *end = cdi->tracks_num - 1; *lead_out = cdi->tracks[*end].start; - - return 1; } int @@ -286,12 +279,11 @@ int cdi_get_audio_track_info(cd_img_t *cdi, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr) { const track_t *trk = &cdi->tracks[track - 1]; - int pos = trk->start + 150; if ((track < 1) || (track > cdi->tracks_num)) return 0; - pos = trk->start + 150; + const int pos = trk->start + 150; FRAMES_TO_MSF(pos, &start->min, &start->sec, &start->fr); @@ -320,9 +312,6 @@ cdi_get_audio_track_info_lba(cd_img_t *cdi, UNUSED(int end), int track, int *tra int cdi_get_track(cd_img_t *cdi, uint32_t sector) { - const track_t *cur; - const track_t *next; - /* There must be at least two tracks - data and lead out. */ if (cdi->tracks_num < 2) return -1; @@ -330,8 +319,8 @@ cdi_get_track(cd_img_t *cdi, uint32_t sector) /* This has a problem - the code skips the last track, which is lead out - is that correct? */ for (int i = 0; i < (cdi->tracks_num - 1); i++) { - cur = &cdi->tracks[i]; - next = &cdi->tracks[i + 1]; + const track_t *cur = &cdi->tracks[i]; + const track_t *next = &cdi->tracks[i + 1]; /* Take into account cue sheets that do not start on sector 0. */ if ((i == 0) && (sector < cur->start)) @@ -348,16 +337,15 @@ cdi_get_track(cd_img_t *cdi, uint32_t sector) int cdi_get_audio_sub(cd_img_t *cdi, uint32_t sector, uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos) { - int cur_track = cdi_get_track(cdi, sector); - const track_t *trk; + const int cur_track = cdi_get_track(cdi, sector); if (cur_track < 1) return 0; - *track = (uint8_t) cur_track; - trk = &cdi->tracks[*track - 1]; - *attr = trk->attr; - *index = 1; + *track = (uint8_t) cur_track; + const track_t *trk = &cdi->tracks[*track - 1]; + *attr = trk->attr; + *index = 1; FRAMES_TO_MSF(sector + 150, &abs_pos->min, &abs_pos->sec, &abs_pos->fr); @@ -370,16 +358,11 @@ cdi_get_audio_sub(cd_img_t *cdi, uint32_t sector, uint8_t *attr, uint8_t *track, int cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) { - size_t length; - int track = cdi_get_track(cdi, sector) - 1; - uint64_t sect = (uint64_t) sector; - uint64_t seek; - track_t *trk; - int track_is_raw; - int ret; + const int track = cdi_get_track(cdi, sector) - 1; + const uint64_t sect = (uint64_t) sector; int raw_size; int cooked_size; - uint64_t offset = 0ULL; + uint64_t offset; int m = 0; int s = 0; int f = 0; @@ -387,10 +370,10 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) if (track < 0) return 0; - trk = &cdi->tracks[track]; - track_is_raw = ((trk->sector_size == RAW_SECTOR_SIZE) || (trk->sector_size == 2448)); + const track_t *trk = &cdi->tracks[track]; + const int track_is_raw = ((trk->sector_size == RAW_SECTOR_SIZE) || (trk->sector_size == 2448)); - seek = trk->skip + ((sect - trk->start) * trk->sector_size); + const uint64_t seek = trk->skip + ((sect - trk->start) * trk->sector_size); if (track_is_raw) raw_size = trk->sector_size; @@ -405,7 +388,7 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) } else cooked_size = COOKED_SECTOR_SIZE; - length = (raw ? raw_size : cooked_size); + const size_t length = (raw ? raw_size : cooked_size); if (trk->mode2 && (trk->form >= 1)) offset = 24ULL; @@ -414,7 +397,7 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) if (raw && !track_is_raw) { memset(buffer, 0x00, 2448); - ret = trk->file->read(trk->file, buffer + offset, seek, length); + const int ret = trk->file->read(trk->file, buffer + offset, seek, length); if (!ret) return 0; /* Construct the rest of the raw sector. */ @@ -430,24 +413,20 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) return 1; } else if (!raw && track_is_raw) return trk->file->read(trk->file, buffer, seek + offset, length); - else { + else return trk->file->read(trk->file, buffer, seek, length); - } } int cdi_read_sectors(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector, uint32_t num) { - int sector_size; int success = 1; - uint8_t *buf; - uint32_t buf_len; /* TODO: This fails to account for Mode 2. Shouldn't we have a function to get sector size? */ - sector_size = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; - buf_len = num * sector_size; - buf = (uint8_t *) malloc(buf_len * sizeof(uint8_t)); + const int sector_size = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; + const uint32_t buf_len = num * sector_size; + uint8_t *buf = (uint8_t *) malloc(buf_len * sizeof(uint8_t)); for (uint32_t i = 0; i < num; i++) { success = cdi_read_sector(cdi, &buf[i * sector_size], raw, sector + i); @@ -455,7 +434,9 @@ cdi_read_sectors(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector, uint3 break; /* Based on the DOSBox patch, but check all 8 bytes and makes sure it's not an audio track. */ - if (raw && sector < cdi->tracks[0].length && !cdi->tracks[0].mode2 && (cdi->tracks[0].attr != AUDIO_TRACK) && *(uint64_t *) &(buf[i * sector_size + 2068])) + if (raw && (sector < cdi->tracks[0].length) && + !cdi->tracks[0].mode2 && (cdi->tracks[0].attr != AUDIO_TRACK) && + *(uint64_t *) &(buf[(i * sector_size) + 2068])) return 0; } @@ -470,16 +451,13 @@ cdi_read_sectors(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector, uint3 int cdi_read_sector_sub(cd_img_t *cdi, uint8_t *buffer, uint32_t sector) { - int track = cdi_get_track(cdi, sector) - 1; - track_t *trk; - uint64_t s = (uint64_t) sector; - uint64_t seek; + const int track = cdi_get_track(cdi, sector) - 1; if (track < 0) return 0; - trk = &cdi->tracks[track]; - seek = trk->skip + ((s - trk->start) * trk->sector_size); + const track_t *trk = &cdi->tracks[track]; + const uint64_t seek = trk->skip + (((uint64_t) sector - trk->start) * trk->sector_size); if (trk->sector_size != 2448) return 0; @@ -489,26 +467,24 @@ cdi_read_sector_sub(cd_img_t *cdi, uint8_t *buffer, uint32_t sector) int cdi_get_sector_size(cd_img_t *cdi, uint32_t sector) { - int track = cdi_get_track(cdi, sector) - 1; - const track_t *trk; + const int track = cdi_get_track(cdi, sector) - 1; if (track < 0) return 0; - trk = &cdi->tracks[track]; + const track_t *trk = &cdi->tracks[track]; return trk->sector_size; } int cdi_is_mode2(cd_img_t *cdi, uint32_t sector) { - int track = cdi_get_track(cdi, sector) - 1; - const track_t *trk; + const int track = cdi_get_track(cdi, sector) - 1; if (track < 0) return 0; - trk = &cdi->tracks[track]; + const track_t *trk = &cdi->tracks[track]; return !!(trk->mode2); } @@ -516,13 +492,12 @@ cdi_is_mode2(cd_img_t *cdi, uint32_t sector) int cdi_get_mode2_form(cd_img_t *cdi, uint32_t sector) { - int track = cdi_get_track(cdi, sector) - 1; - const track_t *trk; + const int track = cdi_get_track(cdi, sector) - 1; if (track < 0) return 0; - trk = &cdi->tracks[track]; + const track_t *trk = &cdi->tracks[track]; return trk->form; } @@ -533,10 +508,12 @@ cdi_can_read_pvd(track_file_t *file, uint64_t sector_size, int mode2, int form) uint8_t pvd[COOKED_SECTOR_SIZE]; uint64_t seek = 16ULL * sector_size; /* First VD is located at sector 16. */ - if ((!mode2 || (form == 0)) && (sector_size == RAW_SECTOR_SIZE)) - seek += 16; - if (mode2 && (form >= 1)) - seek += 24; + if (sector_size == RAW_SECTOR_SIZE) { + if (!mode2 || (form == 0)) + seek += 16; + else + seek += 24; + } file->read(file, pvd, seek, COOKED_SECTOR_SIZE); @@ -591,7 +568,7 @@ cdi_load_iso(cd_img_t *cdi, const char *filename) /* Try to detect ISO type. */ trk.form = 0; trk.mode2 = 0; - /* TODO: Merge the first and last cases since they result in the same thing. */ + if (cdi_can_read_pvd(trk.file, RAW_SECTOR_SIZE, 0, 0)) trk.sector_size = RAW_SECTOR_SIZE; else if (cdi_can_read_pvd(trk.file, 2336, 1, 0)) { @@ -601,9 +578,17 @@ cdi_load_iso(cd_img_t *cdi, const char *filename) trk.sector_size = 2324; trk.mode2 = 1; trk.form = 2; + } else if (cdi_can_read_pvd(trk.file, 2328, 1, 2)) { + trk.sector_size = 2328; + trk.mode2 = 1; + trk.form = 2; } else if (cdi_can_read_pvd(trk.file, RAW_SECTOR_SIZE, 1, 0)) { trk.sector_size = RAW_SECTOR_SIZE; trk.mode2 = 1; + } else if (cdi_can_read_pvd(trk.file, RAW_SECTOR_SIZE, 1, 1)) { + trk.sector_size = RAW_SECTOR_SIZE; + trk.mode2 = 1; + trk.form = 1; } else { /* We use 2048 mode 1 as the default. */ trk.sector_size = COOKED_SECTOR_SIZE; @@ -754,17 +739,12 @@ static int cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, uint64_t *total_pregap, uint64_t cur_pregap) { /* Frames between index 0 (prestart) and 1 (current track start) must be skipped. */ - uint64_t skip; - uint64_t temp; track_t *prev = NULL; /* Skip *MUST* be calculated even if prestart is 0. */ - if (prestart >= 0) { - if (prestart > cur->start) - return 0; - skip = cur->start - prestart; - } else - skip = 0ULL; + if (prestart > cur->start) + return 0; + const uint64_t skip = cur->start - prestart; if ((cdi->tracks != NULL) && (cdi->tracks_num != 0)) prev = &cdi->tracks[cdi->tracks_num - 1]; @@ -793,7 +773,7 @@ cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, u *total_pregap += cur_pregap; cur->start += *total_pregap; } else { - temp = prev->file->get_length(prev->file) - (prev->skip); + const uint64_t temp = prev->file->get_length(prev->file) - (prev->skip); prev->length = temp / ((uint64_t) prev->sector_size); if ((temp % prev->sector_size) != 0) prev->length++; @@ -823,8 +803,6 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) { track_t trk; char pathname[MAX_FILENAME_LENGTH]; - char filename[MAX_FILENAME_LENGTH]; - char temp[MAX_FILENAME_LENGTH]; uint64_t shift = 0ULL; uint64_t prestart = 0ULL; uint64_t cur_pregap = 0ULL; @@ -836,7 +814,6 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) int can_add_track = 0; FILE *fp; char buf[MAX_LINE_LENGTH]; - char ansi[MAX_FILENAME_LENGTH]; char *line; char *command; char *type; @@ -877,7 +854,7 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) } } - success = cdi_cue_get_keyword(&command, &line); + (void) cdi_cue_get_keyword(&command, &line); if (!strcmp(command, "TRACK")) { if (can_add_track) @@ -980,6 +957,9 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) break; } } else if (!strcmp(command, "FILE")) { + char filename[MAX_FILENAME_LENGTH]; + char ansi[MAX_FILENAME_LENGTH]; + if (can_add_track) success = cdi_add_track(cdi, &trk, &shift, prestart, &total_pregap, cur_pregap); else @@ -1002,7 +982,6 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) error = 1; if (!strcmp(type, "BINARY")) { - memset(temp, 0, MAX_FILENAME_LENGTH * sizeof(char)); path_append_filename(filename, pathname, ansi); trk.file = track_file_init(filename, &error); } diff --git a/src/include/86box/cdrom_image_backend.h b/src/include/86box/cdrom_image_backend.h index 39faf9f33..5222e8aa0 100644 --- a/src/include/86box/cdrom_image_backend.h +++ b/src/include/86box/cdrom_image_backend.h @@ -78,8 +78,8 @@ typedef struct cd_img_t { /* Binary file functions. */ extern void cdi_close(cd_img_t *cdi); extern int cdi_set_device(cd_img_t *cdi, const char *path); -extern int cdi_get_audio_tracks(cd_img_t *cdi, int *st_track, int *end, TMSF *lead_out); -extern int cdi_get_audio_tracks_lba(cd_img_t *cdi, int *st_track, int *end, uint32_t *lead_out); +extern void cdi_get_audio_tracks(cd_img_t *cdi, int *st_track, int *end, TMSF *lead_out); +extern void cdi_get_audio_tracks_lba(cd_img_t *cdi, int *st_track, int *end, uint32_t *lead_out); extern int cdi_get_audio_track_pre(cd_img_t *cdi, int track); extern int cdi_get_audio_track_info(cd_img_t *cdi, int end, int track, int *track_num, TMSF *start, uint8_t *attr); extern int cdi_get_audio_track_info_lba(cd_img_t *cdi, int end, int track, int *track_num, uint32_t *start, uint8_t *attr); diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 3a49085ec..8a9f72946 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -1393,7 +1393,7 @@ scsi_cdrom_read_blocks(scsi_cdrom_t *dev, int32_t *len, int first_batch, int ven type = (dev->current_cdb[1] >> 2) & 7; flags = dev->current_cdb[9] | (((uint32_t) dev->current_cdb[10]) << 8); } else { - type = 8; + type = 8; /* Internal type code indicating both Mode 1 and Mode 2 Form 1 are allowed. */ flags = 0x10; } From 3dbb0daa1742ea7c5bbe52f82a574af595285d2c Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 23 Apr 2024 03:14:12 +0200 Subject: [PATCH 863/936] AD1848 clean-ups and fixed DMA over a 16-bit channel. --- src/sound/snd_ad1848.c | 226 ++++++++++++++++++++++++----------------- 1 file changed, 133 insertions(+), 93 deletions(-) diff --git a/src/sound/snd_ad1848.c b/src/sound/snd_ad1848.c index d2a05fd6f..4b7941959 100644 --- a/src/sound/snd_ad1848.c +++ b/src/sound/snd_ad1848.c @@ -63,46 +63,85 @@ ad1848_updatevolmask(ad1848_t *ad1848) ad1848->wave_vol_mask = 0x7f; } +static double +ad1848_get_default_freq(ad1848_t *ad1848) +{ + double freq = (ad1848->regs[8] & 1) ? 16934400.0 : 24576000.0; + + switch ((ad1848->regs[8] >> 1) & 7) { + default: + break; + + case 0: + freq /= 3072.0; + break; + case 1: + freq /= 1536.0; + break; + case 2: + freq /= 896.0; + break; + case 3: + freq /= 768.0; + break; + case 4: + freq /= 448.0; + break; + case 5: + freq /= 384.0; + break; + case 6: + freq /= 512.0; + break; + case 7: + freq /= 2560.0; + break; + } + + return freq; +} + static void ad1848_updatefreq(ad1848_t *ad1848) { - double freq = 0.0; - uint8_t set = 0; + double freq; if (ad1848->type >= AD1848_TYPE_CS4235) { if (ad1848->xregs[11] & 0x20) { - freq = 16934400LL; + freq = 16934400.0; switch (ad1848->xregs[13]) { + default: + freq /= 16.0 * MAX(ad1848->xregs[13], 21); + break; case 1: - freq /= 353; + freq /= 353.0; break; case 2: - freq /= 529; + freq /= 529.0; break; case 3: - freq /= 617; + freq /= 617.0; break; case 4: - freq /= 1058; + freq /= 1058.0; break; case 5: - freq /= 1764; + freq /= 1764.0; break; case 6: - freq /= 2117; + freq /= 2117.0; break; case 7: - freq /= 2558; - break; - default: - freq /= 16 * MAX(ad1848->xregs[13], 21); + freq /= 2558.0; break; } - set = 1; } else if (ad1848->regs[22] & 0x80) { - freq = (ad1848->regs[22] & 1) ? 33868800LL : 49152000LL; - set = (ad1848->regs[22] >> 1) & 0x3f; + const uint8_t set = (ad1848->regs[22] >> 1) & 0x3f; + freq = (ad1848->regs[22] & 1) ? 33868800.0 : 49152000.0; switch (ad1848->regs[10] & 0x30) { + default: + break; + case 0x00: freq /= 128 * set; break; @@ -112,48 +151,13 @@ ad1848_updatefreq(ad1848_t *ad1848) case 0x20: freq /= 256 * set; break; - - default: - break; } - set = 1; - } - } + } else + freq = ad1848_get_default_freq(ad1848); + } else + freq = ad1848_get_default_freq(ad1848); - if (!set) { - freq = (ad1848->regs[8] & 1) ? 16934400LL : 24576000LL; - switch ((ad1848->regs[8] >> 1) & 7) { - case 0: - freq /= 3072; - break; - case 1: - freq /= 1536; - break; - case 2: - freq /= 896; - break; - case 3: - freq /= 768; - break; - case 4: - freq /= 448; - break; - case 5: - freq /= 384; - break; - case 6: - freq /= 512; - break; - case 7: - freq /= 2560; - break; - - default: - break; - } - } - - ad1848->freq = freq; + ad1848->freq = (int) trunc(freq); ad1848->timer_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) ad1848->freq)); } @@ -251,6 +255,7 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) case 9: if (!ad1848->enable && (val & 0x41) == 0x01) { ad1848->adpcm_pos = 0; + ad1848->dma_ff = 0; if (ad1848->timer_latch) timer_set_delay_u64(&ad1848->timer_count, ad1848->timer_latch); else @@ -450,18 +455,32 @@ static int16_t ad1848_process_mulaw(uint8_t byte) { byte = ~byte; - int16_t dec = ((byte & 0x0f) << 3) + 0x84; - dec <<= (byte & 0x70) >> 4; - return (byte & 0x80) ? (0x84 - dec) : (dec - 0x84); + int temp = (((byte & 0x0f) << 3) + 0x84); + int16_t dec; + temp <<= ((byte & 0x70) >> 4); + temp = (byte & 0x80) ? (0x84 - temp) : (temp - 0x84); + if (temp > 32767) + dec = 32767; + else if (temp < -32768) + dec = -32768; + else + dec = (int16_t) temp; + + return dec; } static int16_t ad1848_process_alaw(uint8_t byte) { byte ^= 0x55; - int16_t dec = (byte & 0x0f) << 4; - int seg = (byte & 0x70) >> 4; + int dec = ((byte & 0x0f) << 4);; + const int seg = (int) ((byte & 0x70) >> 4); switch (seg) { + default: + dec |= 0x108; + dec <<= seg - 1; + break; + case 0: dec |= 0x8; break; @@ -469,13 +488,34 @@ ad1848_process_alaw(uint8_t byte) case 1: dec |= 0x108; break; - - default: - dec |= 0x108; - dec <<= seg - 1; - break; } - return (byte & 0x80) ? dec : -dec; + dec = (byte & 0x80) ? dec : -dec; + return (int16_t) dec; +} + +static uint32_t +ad1848_dma_channel_read(ad1848_t *ad1848, int channel) +{ + uint32_t ret; + + if (channel >= 4) { + if (ad1848->dma_ff) { + ret = (ad1848->dma_data & 0xff00) >> 8; + ret |= (ad1848->dma_data & 0xffff0000); + } else { + ad1848->dma_data = dma_channel_read(channel); + + if (ad1848->dma_data == DMA_NODATA) + return DMA_NODATA; + + ret = ad1848->dma_data & 0xff; + } + + ad1848->dma_ff = !ad1848->dma_ff; + } else + ret = dma_channel_read(channel); + + return ret; } static int16_t @@ -485,7 +525,7 @@ ad1848_process_adpcm(ad1848_t *ad1848) if (ad1848->adpcm_pos++ & 1) { temp = (ad1848->adpcm_data & 0x0f) + ad1848->adpcm_step; } else { - ad1848->adpcm_data = dma_channel_read(ad1848->dma); + ad1848->adpcm_data = (int) (ad1848_dma_channel_read(ad1848, ad1848->dma) & 0xffff); temp = (ad1848->adpcm_data >> 4) + ad1848->adpcm_step; } if (temp < 0) @@ -499,9 +539,9 @@ ad1848_process_adpcm(ad1848_t *ad1848) else if (ad1848->adpcm_ref < 0x00) ad1848->adpcm_ref = 0x00; - ad1848->adpcm_step = (ad1848->adpcm_step + adjustMap4[temp]) & 0xff; + ad1848->adpcm_step = (int8_t) ((ad1848->adpcm_step + adjustMap4[temp]) & 0xff); - return (ad1848->adpcm_ref ^ 0x80) << 8; + return (int16_t) ((ad1848->adpcm_ref ^ 0x80) << 8); } static void @@ -521,42 +561,42 @@ ad1848_poll(void *priv) switch (ad1848->regs[8] & ad1848->fmt_mask) { case 0x00: /* Mono, 8-bit PCM */ - ad1848->out_l = ad1848->out_r = (dma_channel_read(ad1848->dma) ^ 0x80) << 8; + ad1848->out_l = ad1848->out_r = (int16_t) ((ad1848_dma_channel_read(ad1848, ad1848->dma) ^ 0x80) << 8); break; case 0x10: /* Stereo, 8-bit PCM */ - ad1848->out_l = (dma_channel_read(ad1848->dma) ^ 0x80) << 8; - ad1848->out_r = (dma_channel_read(ad1848->dma) ^ 0x80) << 8; + ad1848->out_l = (int16_t) ((ad1848_dma_channel_read(ad1848, ad1848->dma) ^ 0x80) << 8); + ad1848->out_r = (int16_t) ((ad1848_dma_channel_read(ad1848, ad1848->dma) ^ 0x80) << 8); break; case 0x20: /* Mono, 8-bit Mu-Law */ - ad1848->out_l = ad1848->out_r = ad1848_process_mulaw(dma_channel_read(ad1848->dma)); + ad1848->out_l = ad1848->out_r = ad1848_process_mulaw(ad1848_dma_channel_read(ad1848, ad1848->dma)); break; case 0x30: /* Stereo, 8-bit Mu-Law */ - ad1848->out_l = ad1848_process_mulaw(dma_channel_read(ad1848->dma)); - ad1848->out_r = ad1848_process_mulaw(dma_channel_read(ad1848->dma)); + ad1848->out_l = ad1848_process_mulaw(ad1848_dma_channel_read(ad1848, ad1848->dma)); + ad1848->out_r = ad1848_process_mulaw(ad1848_dma_channel_read(ad1848, ad1848->dma)); break; case 0x40: /* Mono, 16-bit PCM little endian */ - temp = dma_channel_read(ad1848->dma); - ad1848->out_l = ad1848->out_r = (dma_channel_read(ad1848->dma) << 8) | temp; + temp = (int32_t) ad1848_dma_channel_read(ad1848, ad1848->dma); + ad1848->out_l = ad1848->out_r = (int16_t) ((ad1848_dma_channel_read(ad1848, ad1848->dma) << 8) | temp); break; case 0x50: /* Stereo, 16-bit PCM little endian */ - temp = dma_channel_read(ad1848->dma); - ad1848->out_l = (dma_channel_read(ad1848->dma) << 8) | temp; - temp = dma_channel_read(ad1848->dma); - ad1848->out_r = (dma_channel_read(ad1848->dma) << 8) | temp; + temp = (int32_t) ad1848_dma_channel_read(ad1848, ad1848->dma); + ad1848->out_l = (int16_t) ((ad1848_dma_channel_read(ad1848, ad1848->dma) << 8) | temp); + temp = (int32_t) ad1848_dma_channel_read(ad1848, ad1848->dma); + ad1848->out_r = (int16_t) ((ad1848_dma_channel_read(ad1848, ad1848->dma) << 8) | temp); break; case 0x60: /* Mono, 8-bit A-Law */ - ad1848->out_l = ad1848->out_r = ad1848_process_alaw(dma_channel_read(ad1848->dma)); + ad1848->out_l = ad1848->out_r = ad1848_process_alaw(ad1848_dma_channel_read(ad1848, ad1848->dma)); break; case 0x70: /* Stereo, 8-bit A-Law */ - ad1848->out_l = ad1848_process_alaw(dma_channel_read(ad1848->dma)); - ad1848->out_r = ad1848_process_alaw(dma_channel_read(ad1848->dma)); + ad1848->out_l = ad1848_process_alaw(ad1848_dma_channel_read(ad1848, ad1848->dma)); + ad1848->out_r = ad1848_process_alaw(ad1848_dma_channel_read(ad1848, ad1848->dma)); break; /* 0x80 and 0x90 reserved */ @@ -571,15 +611,15 @@ ad1848_poll(void *priv) break; case 0xc0: /* Mono, 16-bit PCM big endian */ - temp = dma_channel_read(ad1848->dma); - ad1848->out_l = ad1848->out_r = dma_channel_read(ad1848->dma) | (temp << 8); + temp = (int32_t) ad1848_dma_channel_read(ad1848, ad1848->dma); + ad1848->out_l = ad1848->out_r = (int16_t) (ad1848_dma_channel_read(ad1848, ad1848->dma) | (temp << 8)); break; case 0xd0: /* Stereo, 16-bit PCM big endian */ - temp = dma_channel_read(ad1848->dma); - ad1848->out_l = dma_channel_read(ad1848->dma) | (temp << 8); - temp = dma_channel_read(ad1848->dma); - ad1848->out_r = dma_channel_read(ad1848->dma) | (temp << 8); + temp = (int32_t) ad1848_dma_channel_read(ad1848, ad1848->dma); + ad1848->out_l = (int16_t) (ad1848_dma_channel_read(ad1848, ad1848->dma) | (temp << 8)); + temp = (int32_t) ad1848_dma_channel_read(ad1848, ad1848->dma); + ad1848->out_r = (int16_t) (ad1848_dma_channel_read(ad1848, ad1848->dma) | (temp << 8)); break; /* 0xe0 and 0xf0 reserved */ @@ -591,12 +631,12 @@ ad1848_poll(void *priv) if (ad1848->regs[6] & 0x80) ad1848->out_l = 0; else - ad1848->out_l = (ad1848->out_l * ad1848_vols_7bits[ad1848->regs[6] & ad1848->wave_vol_mask]) >> 16; + ad1848->out_l = (int16_t) ((ad1848->out_l * ad1848_vols_7bits[ad1848->regs[6] & ad1848->wave_vol_mask]) >> 16); if (ad1848->regs[7] & 0x80) ad1848->out_r = 0; else - ad1848->out_r = (ad1848->out_r * ad1848_vols_7bits[ad1848->regs[7] & ad1848->wave_vol_mask]) >> 16; + ad1848->out_r = (int16_t) ((ad1848->out_r * ad1848_vols_7bits[ad1848->regs[7] & ad1848->wave_vol_mask]) >> 16); if (ad1848->count < 0) { ad1848->count = ad1848->regs[15] | (ad1848->regs[14] << 8); From 15ad2c199283ed3939c46d800be370f139af881a Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 23 Apr 2024 03:19:24 +0200 Subject: [PATCH 864/936] NCR 53c8xx: Set correct SCSI speeds. --- src/scsi/scsi_ncr53c8xx.c | 57 ++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/src/scsi/scsi_ncr53c8xx.c b/src/scsi/scsi_ncr53c8xx.c index ad1b31fe8..f640c49a6 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -2567,28 +2567,39 @@ ncr53c8xx_init(const device_t *info) else pci_add_card(PCI_ADD_NORMAL, ncr53c8xx_pci_read, ncr53c8xx_pci_write, dev, &dev->pci_slot); - if (dev->chip == CHIP_875) { - dev->chip_rev = 0x04; - dev->nvr_path = "ncr53c875.nvr"; - dev->wide = 1; - } else if (dev->chip == CHIP_860) { - dev->chip_rev = 0x04; - dev->nvr_path = "ncr53c860.nvr"; - dev->wide = 1; - } else if (dev->chip == CHIP_820) { - dev->nvr_path = "ncr53c820.nvr"; - dev->wide = 1; - } else if (dev->chip == CHIP_825) { - dev->chip_rev = 0x26; - dev->nvr_path = "ncr53c825a.nvr"; - dev->wide = 1; - } else if (dev->chip == CHIP_810) { - dev->nvr_path = "ncr53c810.nvr"; - dev->wide = 0; - } else if (dev->chip == CHIP_815) { - dev->chip_rev = 0x04; - dev->nvr_path = "ncr53c815.nvr"; - dev->wide = 0; + scsi_bus_set_speed(dev->bus, 10000000.0); + + switch (dev->chip) { + case CHIP_810: + dev->nvr_path = "ncr53c810.nvr"; + dev->wide = 0; + break; + case CHIP_815: + dev->chip_rev = 0x04; + dev->nvr_path = "ncr53c815.nvr"; + dev->wide = 0; + break; + case CHIP_820: + dev->nvr_path = "ncr53c820.nvr"; + dev->wide = 1; + break; + case CHIP_825: + dev->chip_rev = 0x26; + dev->nvr_path = "ncr53c825a.nvr"; + dev->wide = 1; + break; + case CHIP_860: + scsi_bus_set_speed(dev->bus, 20000000.0); + dev->chip_rev = 0x04; + dev->nvr_path = "ncr53c860.nvr"; + dev->wide = 1; + break; + case CHIP_875: + scsi_bus_set_speed(dev->bus, 40000000.0); + dev->chip_rev = 0x04; + dev->nvr_path = "ncr53c875.nvr"; + dev->wide = 1; + break; } ncr53c8xx_pci_bar[0].addr_regs[0] = 1; @@ -2629,8 +2640,6 @@ ncr53c8xx_init(const device_t *info) timer_add(&dev->timer, ncr53c8xx_callback, dev, 0); - scsi_bus_set_speed(dev->bus, 10000000.0); - return dev; } From 070c289562de474f4c389fa2052b1d766bb3ff8e Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 23 Apr 2024 12:06:59 +0200 Subject: [PATCH 865/936] The forgotten .h file. --- src/include/86box/snd_ad1848.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/include/86box/snd_ad1848.h b/src/include/86box/snd_ad1848.h index 6bdd2bf40..319f9bf24 100644 --- a/src/include/86box/snd_ad1848.h +++ b/src/include/86box/snd_ad1848.h @@ -61,6 +61,9 @@ typedef struct ad1848_t { int adpcm_data; int adpcm_pos; + uint8_t dma_ff; + uint32_t dma_data; + pc_timer_t timer_count; uint64_t timer_latch; From 7feb6f578df672550348d1269806b20d24a2d2f2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 23 Apr 2024 20:38:48 +0200 Subject: [PATCH 866/936] Changed the internal device name of the MT32 New device, fixes #4394. --- src/sound/midi_mt32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/midi_mt32.c b/src/sound/midi_mt32.c index 91d85e438..f38474ac8 100644 --- a/src/sound/midi_mt32.c +++ b/src/sound/midi_mt32.c @@ -435,7 +435,7 @@ const device_t mt32_old_device = { const device_t mt32_new_device = { .name = "Roland MT-32 (New) Emulation", - .internal_name = "mt32", + .internal_name = "mt32_new", .flags = 0, .local = 0, .init = mt32_new_init, From 15e3876e219b5448135740eabd97e926ab48f2bf Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 24 Apr 2024 06:06:09 +0200 Subject: [PATCH 867/936] Prepare WD76C10 for 286/386 interpreter selection, exempt IBM 486BL and all Cyrix'es from the 286/386 interpreter. --- src/chipset/wd76c10.c | 86 ++++++++++++++++++++++++++++++++++------- src/cpu/cpu.c | 3 +- src/include/86box/mem.h | 2 + src/mem/mem.c | 3 +- 4 files changed, 79 insertions(+), 15 deletions(-) diff --git a/src/chipset/wd76c10.c b/src/chipset/wd76c10.c index ef076b606..5b6ea28d2 100644 --- a/src/chipset/wd76c10.c +++ b/src/chipset/wd76c10.c @@ -84,6 +84,7 @@ typedef struct uint8_t bios_states[8]; uint8_t high_bios_states[8]; uint8_t mem_pages[1024]; + uint8_t ram_state[4192]; uint16_t toggle, cpuclk, fpu_ctl, mem_ctl, split_sa, sh_wp, hmwpb, npmdmt, @@ -225,6 +226,34 @@ wd76c10_write_ramw(uint32_t addr, uint16_t val, void *priv) mem_write_ramw(addr, val, priv); } +static void +wd76c10_set_mem_state(wd76c10_t *dev, uint32_t base, uint32_t size, uint32_t access, uint8_t present) +{ + mem_set_mem_state_both(base, size, access); + + for (uint32_t i = base; i < (base + size); i += 4096) + dev->ram_state[i >> 12] = present; +} + +static void +wd76c10_recalc_exec(wd76c10_t *dev, uint32_t base, uint32_t size) +{ + uint32_t logical_addr = wd76c10_calc_addr(dev, base); + void *exec; + + if (logical_addr != WD76C10_ADDR_INVALID) + exec = &(ram[logical_addr]); + else + exec = NULL; + + for (uint32_t i = base; i < (base + size); i += 4096) + if (dev->ram_state[i >> 12]) + _mem_exec[i >> 12] = exec; + + if (cpu_use_exec) + flushmmucache_nopc(); +} + static void wd76c10_banks_recalc(wd76c10_t *dev) { @@ -235,6 +264,9 @@ wd76c10_banks_recalc(wd76c10_t *dev) bit = i + 12; rb->enable = (dev->split_sa >> bit) & 0x01; rb->virt_addr = ((uint32_t) dev->bank_bases[i]) << 17; + + if (cpu_use_exec) + wd76c10_recalc_exec(dev, rb->virt_addr, rb->virt_size); } } @@ -245,8 +277,12 @@ wd76c10_split_recalc(wd76c10_t *dev) uint32_t split_size = ((sp_size - 1) * 65536); ram_bank_t *rb = &(dev->ram_banks[4]); - if (rb->enable && (rb->virt_size != 0x00000000)) - mem_set_mem_state(rb->virt_addr, rb->virt_size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + if (rb->enable && (rb->virt_size != 0x00000000)) { + wd76c10_set_mem_state(dev, rb->virt_addr, rb->virt_size, MEM_READ_EXTANY | MEM_WRITE_EXTANY, 0); + + if (cpu_use_exec) + wd76c10_recalc_exec(dev, rb->virt_addr, rb->virt_size); + } rb->virt_addr = ((uint32_t) ((dev->split_sa >> 2) & 0x3f)) << 19; switch (sp_size) { case 0x00: @@ -257,8 +293,12 @@ wd76c10_split_recalc(wd76c10_t *dev) break; } rb->enable = !!sp_size; - if (rb->enable && (rb->virt_size != 0x00000000)) - mem_set_mem_state(rb->virt_addr, rb->virt_size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + if (rb->enable && (rb->virt_size != 0x00000000)) { + wd76c10_set_mem_state(dev, rb->virt_addr, rb->virt_size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL, 1); + + if (cpu_use_exec) + wd76c10_recalc_exec(dev, rb->virt_addr, rb->virt_size); + } } static void @@ -287,7 +327,7 @@ wd76c10_dis_mem_recalc(wd76c10_t *dev) } static void -wd76c10_shadow_ram_do_recalc(uint8_t *new_st, uint8_t *old_st, uint8_t min, uint8_t max, uint32_t addr) +wd76c10_shadow_ram_do_recalc(wd76c10_t *dev, uint8_t *new_st, uint8_t *old_st, uint8_t min, uint8_t max, uint32_t addr) { uint32_t base = 0x00000000; int flags = 0; @@ -300,7 +340,9 @@ wd76c10_shadow_ram_do_recalc(uint8_t *new_st, uint8_t *old_st, uint8_t min, uint ((new_st[i] & 0x04) ? MEM_READ_ROMCS : MEM_READ_EXTERNAL); flags |= (new_st[i] & 0x02) ? MEM_WRITE_INTERNAL : ((new_st[i] & 0x04) ? MEM_WRITE_ROMCS : MEM_WRITE_EXTERNAL); - mem_set_mem_state_both(base, 0x00004000, flags); + wd76c10_set_mem_state(dev, base, 0x00004000, flags, new_st[i] & 0x01); + if (cpu_use_exec) + wd76c10_recalc_exec(dev, base, 0x000040000); } } } @@ -366,11 +408,11 @@ wd76c10_shadow_ram_recalc(wd76c10_t *dev) break; } - wd76c10_shadow_ram_do_recalc(vbios_states, dev->vbios_states, 0, 4, 0x000c0000); - wd76c10_shadow_ram_do_recalc(bios_states, dev->bios_states, 0, 8, 0x000e0000); + wd76c10_shadow_ram_do_recalc(dev, vbios_states, dev->vbios_states, 0, 4, 0x000c0000); + wd76c10_shadow_ram_do_recalc(dev, bios_states, dev->bios_states, 0, 8, 0x000e0000); /* This is not shadowed, but there is a CSPROM# (= ROMCS#) toggle. */ - wd76c10_shadow_ram_do_recalc(high_bios_states, dev->high_bios_states, 0, 8, 0x00fe0000); + wd76c10_shadow_ram_do_recalc(dev, high_bios_states, dev->high_bios_states, 0, 8, 0x00fe0000); flushmmucache_nopc(); } @@ -385,9 +427,15 @@ wd76c10_high_mem_wp_recalc(wd76c10_t *dev) /* ACCESS_NORMAL means both ACCESS_BUS and ACCESS_CPU are set. */ mem_set_wp(dev->hmwp_base, size, ACCESS_NORMAL, 0); + if (cpu_use_exec) + wd76c10_recalc_exec(dev, dev->hmwp_base, size); + size = 0x01000000 - base; mem_set_wp(base, size, ACCESS_NORMAL, hm_wp); + if (cpu_use_exec) + wd76c10_recalc_exec(dev, base, size); + dev->hmwp_base = base; } @@ -399,7 +447,10 @@ wd76c10_pf_loc_reset(wd76c10_t *dev) for (uint8_t i = 0x031; i <= 0x03b; i++) { dev->mem_pages[i] = 0xff; base = ((uint32_t) i) << 14; - mem_set_mem_state(base, 0x00004000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + wd76c10_set_mem_state(dev, base, 0x00004000, MEM_READ_EXTANY | MEM_WRITE_EXTANY, 0); + + if (cpu_use_exec) + wd76c10_recalc_exec(dev, base, 0x00004000); } /* Re-apply any ROMCS#, etc. flags. */ @@ -419,9 +470,13 @@ wd76c10_pf_loc_recalc(wd76c10_t *dev) dev->mem_pages[i] = ems_page; base = ((uint32_t) i) << 14; dev->ems_pages[ems_page].virt = base; - if ((ems_en >= 0x02) && dev->ems_pages[ems_page].enabled) - mem_set_mem_state(dev->ems_pages[ems_page].virt, 0x00004000, - MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + if ((ems_en >= 0x02) && dev->ems_pages[ems_page].enabled) { + wd76c10_set_mem_state(dev, dev->ems_pages[ems_page].virt, + 0x00004000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL, 1); + + if (cpu_use_exec) + wd76c10_recalc_exec(dev, dev->ems_pages[ems_page].virt, 0x00004000); + } } } @@ -436,6 +491,9 @@ wd76c10_low_pages_recalc(wd76c10_t *dev) dev->mem_pages[i] = ems_page; base = ((uint32_t) i) << 14; dev->ems_pages[ems_page].virt = base; + + if (cpu_use_exec) + wd76c10_recalc_exec(dev, dev->ems_pages[ems_page].virt, 0x00004000); } } @@ -948,6 +1006,8 @@ wd76c10_init(const device_t *info) mem_mapping_disable(&ram_high_mapping); mem_mapping_enable(&dev->ram_mapping); + memset(dev->ram_state, 0x00, sizeof(dev->ram_state)); + return dev; } diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 4398df36c..459d41231 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1803,7 +1803,8 @@ cpu_set(void) } else #endif /* Use exec386 for CPU_IBM486SLC because it can reach 100 MHz. */ - if ((cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type > CPU_486DLC)) { + if ((cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type == CPU_IBM486BL) || + cpu_iscyrix || (cpu_s->cpu_type > CPU_486DLC)) { cpu_exec = exec386; cpu_use_exec = 1; } else diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index bc949834f..a130309c4 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -302,6 +302,8 @@ extern int memspeed[11]; extern int mmu_perm; extern uint8_t high_page; /* if a high (> 4 gb) page was detected */ +extern uint8_t *_mem_exec[MEM_MAPPINGS_NO]; + extern uint32_t pages_sz; /* #pages in table */ extern int read_type; diff --git a/src/mem/mem.c b/src/mem/mem.c index 188aa49d0..1d373dafb 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -123,6 +123,8 @@ uint8_t high_page = 0; /* if a high (> 4 gb) page was detected */ mem_mapping_t *read_mapping[MEM_MAPPINGS_NO]; mem_mapping_t *write_mapping[MEM_MAPPINGS_NO]; +uint8_t *_mem_exec[MEM_MAPPINGS_NO]; + /* FIXME: re-do this with a 'mem_ops' struct. */ static uint8_t *page_lookupp; /* pagetable mmu_perm lookup */ static uint8_t *readlookupp; @@ -131,7 +133,6 @@ static mem_mapping_t *base_mapping; static mem_mapping_t *last_mapping; static mem_mapping_t *read_mapping_bus[MEM_MAPPINGS_NO]; static mem_mapping_t *write_mapping_bus[MEM_MAPPINGS_NO]; -static uint8_t *_mem_exec[MEM_MAPPINGS_NO]; static uint8_t _mem_wp[MEM_MAPPINGS_NO]; static uint8_t _mem_wp_bus[MEM_MAPPINGS_NO]; static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff }; From 0f71a56edbec75ae41482db287bb45bebb245df7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 24 Apr 2024 06:47:03 +0200 Subject: [PATCH 868/936] Some checks around a recalctimings check to fix some crashes. --- src/video/vid_mga.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index bbba9ca6f..aec571356 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -816,7 +816,10 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) } } } - svga_recalctimings(svga); + if (!((mystique->type >= MGA_1064SG) && (mystique->crtcext_idx == 0) && + (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE))) + svga_recalctimings(svga); + break; default: From d740a8c164019121e03d083b1cd21c3e74d1b8d8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 24 Apr 2024 12:25:17 +0200 Subject: [PATCH 869/936] WD76C10: A forgotten call to recalc exec. --- src/chipset/wd76c10.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/chipset/wd76c10.c b/src/chipset/wd76c10.c index 5b6ea28d2..df8558b05 100644 --- a/src/chipset/wd76c10.c +++ b/src/chipset/wd76c10.c @@ -324,6 +324,9 @@ wd76c10_dis_mem_recalc(wd76c10_t *dev) } dev->mem_top = mem_top; + + if (cpu_use_exec) + wd76c10_recalc_exec(dev, 128 * 1024, (640 - 128) * 1024); } static void From 0aa695c070174998af70a7b20dabb494252e55d1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 25 Apr 2024 10:55:07 +0200 Subject: [PATCH 870/936] Matrox FIFO status fix. --- src/video/vid_mga.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index aec571356..fdbb2e411 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -1562,14 +1562,14 @@ mystique_ctrl_read_b(uint32_t addr, void *priv) switch (addr & 0x3fff) { case REG_FIFOSTATUS: fifocount = FIFO_SIZE - FIFO_ENTRIES; - if (fifocount > 64) - fifocount = 64; + if (fifocount > (mystique->type <= MGA_1064SG ? 32 : 64)) + fifocount = (mystique->type <= MGA_1064SG ? 32 : 64); ret = fifocount; break; case REG_FIFOSTATUS + 1: if (FIFO_EMPTY) ret |= 2; - else if (FIFO_ENTRIES >= 64) + else if (FIFO_ENTRIES >= (mystique->type <= MGA_1064SG ? 32 : 64)) ret |= 1; break; case REG_FIFOSTATUS + 2: @@ -1583,6 +1583,10 @@ mystique_ctrl_read_b(uint32_t addr, void *priv) ret |= REG_STATUS_VSYNCSTS; if (ret & 1) mystique->softrap_status_read = 1; + if (mystique->softrap_status_read == 0 && !(ret & 1)) { + mystique->softrap_status_read = 1; + ret |= 1; + } break; case REG_STATUS + 1: ret = (mystique->status >> 8) & 0xff; From 8928f5d771cf3b4dae6bf0e0c07f7d69fc04830d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Thu, 25 Apr 2024 19:10:40 +0200 Subject: [PATCH 871/936] Variable to override the 286/386 interpreter. --- src/cpu/cpu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 459d41231..0f83a5e4b 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -187,6 +187,7 @@ int cpu_64bitbus; int cpu_cyrix_alignment; int cpu_cpurst_on_sr; int cpu_use_exec = 0; +int cpu_override_interpreter; int CPUID; int is186; @@ -1804,7 +1805,7 @@ cpu_set(void) #endif /* Use exec386 for CPU_IBM486SLC because it can reach 100 MHz. */ if ((cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type == CPU_IBM486BL) || - cpu_iscyrix || (cpu_s->cpu_type > CPU_486DLC)) { + cpu_iscyrix || (cpu_s->cpu_type > CPU_486DLC) || cpu_override_interpreter) { cpu_exec = exec386; cpu_use_exec = 1; } else From 54178355b84ccaef580548ddd5f7dcea7f6959ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Thu, 25 Apr 2024 19:11:25 +0200 Subject: [PATCH 872/936] And in cpu.h. --- src/cpu/cpu.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 16a9eba10..900d3d7e1 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -830,6 +830,7 @@ extern int lock_legal_f6[8]; extern int lock_legal_fe[8]; extern int in_lock; +extern int cpu_override_interpreter; extern int is_lock_legal(uint32_t fetchdat); From 68ec5c53a1063752e5e2976b244cbb21b96afcc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Thu, 25 Apr 2024 19:14:51 +0200 Subject: [PATCH 873/936] And in config.c. --- src/config.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/config.c b/src/config.c index 373ee130d..df0ae1c35 100644 --- a/src/config.c +++ b/src/config.c @@ -314,9 +314,10 @@ load_machine(void) } } - cpu_override = ini_section_get_int(cat, "cpu_override", 0); - cpu_f = NULL; - p = ini_section_get_string(cat, "cpu_family", NULL); + cpu_override = ini_section_get_int(cat, "cpu_override", 0); + cpu_override_interpreter = ini_section_get_int(cat, "cpu_override_interpreter", 0); + cpu_f = NULL; + p = ini_section_get_string(cat, "cpu_family", NULL); if (p) { /* Migrate CPU family changes. */ if ((!strcmp(machines[machine].internal_name, "deskpro386") || @@ -1626,6 +1627,8 @@ config_load(void) dpi_scale = 1; do_auto_pause = 0; + cpu_override_interpreter = 0; + fpu_type = fpu_get_type(cpu_f, cpu, "none"); gfxcard[0] = video_get_video_from_internal_name("cga"); vid_api = plat_vidapi("default"); @@ -1948,6 +1951,10 @@ save_machine(void) ini_section_set_int(cat, "cpu_override", cpu_override); else ini_section_delete_var(cat, "cpu_override"); + if (cpu_override_interpreter) + ini_section_set_int(cat, "cpu_override_interpreter", cpu_override); + else + ini_section_delete_var(cat, "cpu_override_interpreter"); /* Downgrade compatibility with the previous CPU model system. */ ini_section_delete_var(cat, "cpu_manufacturer"); From c931e4d4601171fcac62b15c9953003404a4e648 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 26 Apr 2024 19:28:03 +0200 Subject: [PATCH 874/936] Further fixes to the code related to the Mach8/32 mode changes. And 0x6e9 is an alias to 0x2e8 per the Mach32 manual (H_TOTAL). --- src/video/vid_ati_mach8.c | 44 ++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 522df00a6..29a687f24 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2597,15 +2597,13 @@ mach_recalctimings(svga_t *svga) if (dev->on[0] || dev->on[1]) { mach_log("8514/A ON.\n"); dev->h_total = dev->htotal + 1; - dev->h_blankstart = dev->hblankstart; - dev->h_blank_end_val = dev->hblank_end_val; dev->v_total = dev->v_total_reg + 1; dev->v_syncstart = dev->v_sync_start + 1; dev->rowcount = !!(dev->disp_cntl & 0x08); - mach_log("VDISP=%d.\n", dev->vdisp); - if ((dev->hdisp == 800) || (dev->hdisp == 1280)) { - /*For VESA modes in ATI 8514/A mode.*/ + mach_log("HDISP=%d, VDISP=%d, shadowset=%x, 8514/A mode=%x.\n", dev->hdisp, dev->vdisp, mach->shadow_set & 0x03, dev->accel.advfunc_cntl & 0x04); + if ((dev->hdisp == 640) || (dev->hdisp == 800) || (dev->hdisp == 1280) || dev->bpp) { + /*For VESA/ATI modes in 8514/A mode.*/ dev->h_disp = dev->hdisp; dev->dispend = dev->vdisp; } else { @@ -3624,9 +3622,11 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 switch (port) { case 0x2e8: - case 0x2e9: - WRITE8(port, dev->htotal, val); - dev->htotal &= 0x1ff; + case 0x6e9: + if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) + dev->htotal = val; + + svga_recalctimings(svga); break; case 0x6e8: @@ -3636,23 +3636,23 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 mach_log("[%04X:%08X]: ATI 8514/A: H_DISP write 06E8 = %d, actual val=%d, set lock=%x, shadow set=%x, advfunc bit 2=%x, dispcntl=%02x, clocksel bit 0=%x.\n", CS, cpu_state.pc, dev->hdisp, ((val + 1) << 3), mach->shadow_cntl, mach->shadow_set, dev->accel.advfunc_cntl & 0x04, dev->disp_cntl & 0x60, mach->accel.clock_sel & 0x01); mach_log("ATI 8514/A: (0x%04x): hdisp=0x%02x.\n", port, val); - break; - case 0x6e9: - dev->hdisped = (dev->hdisp >> 3) - 1; - dev->v_disp = (dev->vdisp - 1) << 1; - mach_log("ATI 8514/A: (0x%04x): hdisp=0x%02x.\n", port, val); + svga_recalctimings(svga); break; case 0xae8: - dev->hsync_start = val; - dev->hblankstart = (dev->hsync_start & 0x07); - mach_log("ATI 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); + if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) + dev->hsync_start = val; + + mach_log("ATI 8514/A: (0x%04x): val=%d, hsync_start=%d.\n", port, val, (val + 1) << 3); + svga_recalctimings(svga); break; case 0xee8: - dev->hsync_width = val; - dev->hblank_end_val = (dev->hblankstart + (dev->hsync_width & 0x1f) - 1) & 0x3f; - mach_log("ATI 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); + if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) + dev->hsync_width = val; + + mach_log("ATI 8514/A: (0x%04x): val=%d, hsync_width=%d, hsyncpol=%02x.\n", port, val & 0x1f, ((val & 0x1f) + 1) << 3, val & 0x20); + svga_recalctimings(svga); break; case 0x12e8: @@ -3662,6 +3662,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 WRITE8(port, dev->v_total_reg, val); dev->v_total_reg &= 0x1fff; } + svga_recalctimings(svga); break; case 0x16e8: @@ -3675,6 +3676,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 mach->compat_mode = mach->shadow_set & 0x03; mach_log("ATI 8514/A: V_DISP write 16E8 = %d\n", dev->v_disp); mach_log("ATI 8514/A: (0x%04x): vdisp=0x%02x.\n", port, val); + svga_recalctimings(svga); break; case 0x1ae8: @@ -3684,6 +3686,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 WRITE8(port, dev->v_sync_start, val); dev->v_sync_start &= 0x1fff; } + svga_recalctimings(svga); break; case 0x1ee8: @@ -4429,8 +4432,7 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) break; case 0x26e8: - case 0x26e9: - READ8(port, dev->htotal); + temp = dev->htotal; break; case 0x2ee8: From 20277f7090167e907d5e6ab9115693a9cea30578 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 26 Apr 2024 22:05:54 +0200 Subject: [PATCH 875/936] Workaround to prevent timeouts with the T130B driver on NT 3.1. And more logging cleanups. This should make the T130B driver for NT 3.1 work normally, at least. --- src/scsi/scsi_ncr53c400.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/scsi/scsi_ncr53c400.c b/src/scsi/scsi_ncr53c400.c index d605f1bdb..1ed8e520e 100644 --- a/src/scsi/scsi_ncr53c400.c +++ b/src/scsi/scsi_ncr53c400.c @@ -110,6 +110,7 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) ncr53c400_t *ncr400 = (ncr53c400_t *) priv; ncr_t *ncr = &ncr400->ncr; scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + int actual_block = 0; addr &= 0x3fff; @@ -129,7 +130,7 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) if (!(ncr400->status_ctrl & CTRL_DATA_DIR) && (ncr400->buffer_host_pos < MIN(128, dev->buffer_length))) { ncr400->buffer[ncr400->buffer_host_pos++] = val; - ncr53c400_log("Write host pos = %i, val = %02x\n", ncr400->buffer_host_pos, val); + ncr53c400_log("Write host pos=%i, val=%02x.\n", ncr400->buffer_host_pos, val); if (ncr400->buffer_host_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; @@ -141,7 +142,7 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) case 0x3980: switch (addr) { case 0x3980: /* Control */ - ncr53c400_log("NCR 53c400 control = %02x, mode = %02x.\n", val, ncr->mode); + ncr53c400_log("NCR 53c400 control=%02x, mode=%02x.\n", val, ncr->mode); if ((val & CTRL_DATA_DIR) && !(ncr400->status_ctrl & CTRL_DATA_DIR)) { ncr400->buffer_host_pos = MIN(128, dev->buffer_length); ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; @@ -153,7 +154,7 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) break; case 0x3981: /* block counter register */ - ncr53c400_log("Write block counter register: val=%d, dma mode=%x, period=%lf\n", val, ncr->dma_mode, ncr->period); + ncr53c400_log("Write block counter register: val=%d, dma mode=%x, period=%lf.\n", val, ncr->dma_mode, ncr->period); ncr400->block_count = val; ncr400->block_count_loaded = 1; @@ -164,10 +165,19 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) ncr400->buffer_host_pos = 0; ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; } - if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr400->timer) && (dev->buffer_length > 0)) { + if ((ncr->mode & MODE_DMA) && (dev->buffer_length > 0) && !timer_is_on(&ncr400->timer)) { memset(ncr400->buffer, 0, MIN(128, dev->buffer_length)); - ncr53c400_log("DMA timer on\n"); - timer_on_auto(&ncr400->timer, ncr->period); + ncr53c400_log("DMA timer on, callback=%lf, scsi buflen=%d.\n", scsi_device_get_callback(dev), dev->buffer_length); + actual_block = ncr400->block_count; + if (!actual_block) + actual_block = 256; + + /*Sometimes the actual block count doesn't match the SCSI buffer length / 128.*/ + if (actual_block != (dev->buffer_length / 128)) { + /*FIXME: To be improved further, this is just to workaround callback de-syncs when split transfers occur.*/ + timer_on_auto(&ncr400->timer, (ncr->period / ((double)(actual_block * 40.0)))); + } else + timer_on_auto(&ncr400->timer, ncr->period); } break; @@ -202,12 +212,12 @@ ncr53c400_read(uint32_t addr, void *priv) else { switch (addr & 0x3f80) { case 0x3800: - ncr53c400_log("Read intRAM %02x %02x\n", addr & 0x3f, ncr400->int_ram[addr & 0x3f]); + ncr53c400_log("Read intRAM %02x %02x.\n", addr & 0x3f, ncr400->int_ram[addr & 0x3f]); ret = ncr400->int_ram[addr & 0x3f]; break; case 0x3880: - ncr53c400_log("Read 5380 %04x\n", addr); + ncr53c400_log("Read 5380 %04x.\n", addr); ret = ncr5380_read(addr, ncr); break; @@ -217,11 +227,11 @@ ncr53c400_read(uint32_t addr, void *priv) ncr53c400_log("No Read.\n"); } else { ret = ncr400->buffer[ncr400->buffer_host_pos++]; - ncr53c400_log("Read host pos = %i, ret = %02x\n", ncr400->buffer_host_pos, ret); + ncr53c400_log("Read host pos=%i, ret=%02x.\n", ncr400->buffer_host_pos, ret); if (ncr400->buffer_host_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; - ncr53c400_log("Transfer busy read, status = %02x\n", ncr400->status_ctrl); + ncr53c400_log("Transfer busy read, status = %02x.\n", ncr400->status_ctrl); } } break; @@ -230,7 +240,7 @@ ncr53c400_read(uint32_t addr, void *priv) switch (addr) { case 0x3980: /* status */ ret = ncr400->status_ctrl; - ncr53c400_log("NCR status ctrl read=%02x\n", ncr400->status_ctrl & STATUS_BUFFER_NOT_READY); + ncr53c400_log("NCR status ctrl read=%02x.\n", ncr400->status_ctrl & STATUS_BUFFER_NOT_READY); if (!ncr400->busy) ret |= STATUS_5380_ACCESSIBLE; if (ncr->mode & 0x30) { /*Parity bits*/ @@ -239,11 +249,12 @@ ncr53c400_read(uint32_t addr, void *priv) ncr->mode = 0; /*Required by RTASPI10.SYS otherwise it won't initialize.*/ } } - ncr53c400_log("NCR 53c400 status = %02x.\n", ret); + ncr53c400_log("NCR 53c400 status=%02x.\n", ret); break; case 0x3981: /* block counter register*/ ret = ncr400->block_count; + ncr53c400_log("NCR 53c400 block count read=%02x.\n", ret); break; case 0x3982: /* switch register read */ @@ -394,7 +405,7 @@ ncr53c400_timer_on_auto(void *ext_priv, double period) { ncr53c400_t *ncr400 = (ncr53c400_t *) ext_priv; - ncr53c400_log("53c400: PERIOD=%lf.\n", period); + ncr53c400_log("53c400: PERIOD=%lf, timer=%x.\n", period, !!timer_is_on(&ncr400->timer)); if (period == 0.0) timer_stop(&ncr400->timer); else From 738446fea60bdaad2453c04c07b3d718d46b7e09 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 26 Apr 2024 22:52:58 +0200 Subject: [PATCH 876/936] Cleanup of the XGA mapping to be less messed up. As well as the cursor/sprite being finally fixed when the xoff goes from 0x20 onwards. This makes Win3.x' XGA cursor look normal and everything else as well. (as in, intact). --- src/video/vid_xga.c | 157 +++++++++++++++++++++++--------------------- 1 file changed, 81 insertions(+), 76 deletions(-) diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index fad5e4124..e62a14a61 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -151,37 +151,50 @@ xga_updatemapping(svga_t *svga) xga->aperture_cntl, xga->access_mode, svga->gdcreg[6] & 0x0c, xga->linear_endian_reverse, xga->a5_test, xga->on); - if (((xga->op_mode & 7) >= 4) || ((xga->op_mode & 7) == 0)) { - if ((xga->aperture_cntl == 1) || (xga->aperture_cntl == 2)) { - if (xga->aperture_cntl == 1) - mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000); - else - mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000); + switch (xga->op_mode & 7) { + case 0: + xga_log("XGA: VGA mode address decode disabled.\n"); + break; + case 1: + xga_log("XGA: VGA mode address decode enabled.\n"); + break; + case 2: + xga_log("XGA: 132-Column mode address decode disabled.\n"); + break; + case 3: + xga_log("XGA: 132-Column mode address decode enabled.\n"); + break; + default: + xga_log("XGA: Extended Graphics mode.\n"); + switch (xga->aperture_cntl) { + case 0: + xga_log("XGA: No 64KB aperture.\n"); + if (xga->base_addr_1mb) + mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000); + else if (xga->linear_base) + mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000); + else + mem_mapping_disable(&xga->linear_mapping); - mem_mapping_enable(&xga->video_mapping); - xga->banked_mask = 0xffff; - if (!xga->linear_endian_reverse) - mem_mapping_disable(&xga->linear_mapping); - } else if (xga->aperture_cntl == 0) { - mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000); - mem_mapping_enable(&xga->video_mapping); - xga->banked_mask = 0xffff; - if (xga->base_addr_1mb) - mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000); - else - mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000); - - if (xga->a5_test && (xga->access_mode & 8) && !xga->linear_endian_reverse) { - xga->on = 0; - vga_on = 1; - xga_log("A5 test valid.\n"); + mem_mapping_disable(&xga->video_mapping); + break; + case 1: + xga_log("XGA: 64KB aperture at A0000.\n"); + mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000); + mem_mapping_enable(&xga->video_mapping); + xga->banked_mask = 0xffff; + break; + case 2: + xga_log("XGA: 64KB aperture at B0000.\n"); + mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000); + mem_mapping_enable(&xga->video_mapping); + xga->banked_mask = 0xffff; + break; + default: + break; } - } - - xga_log("XGA opmode (extended) = %d, disp mode = %d, aperture = %d, on = %d, linear endian reverse = %d.\n", xga->op_mode & 7, - xga->disp_cntl_2 & 7, xga->aperture_cntl, xga->on, xga->linear_endian_reverse); + break; } - xga_log("VGA on = %d, map = %02x.\n", vga_on, svga->gdcreg[6] & 0x0c); } void @@ -410,28 +423,6 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) case 0x61: xga->sprite_pal_addr_idx = (xga->sprite_pal_addr_idx & 0xff) | ((val & 0x3f) << 8); xga->sprite_pos = xga->sprite_pal_addr_idx & 0x1ff; - if ((xga->sprite_pos >= 0) && (xga->sprite_pos <= 16)) { - if ((xga->op_mode & 7) >= 5) - xga->cursor_data_on = 1; - else if ((xga->sprite_pos >= 1) || (((xga->disp_cntl_2 & 7) == 2) || (xga->disp_cntl_2 & 7) == 4)) - xga->cursor_data_on = 1; - else if (!xga->aperture_cntl) { - if (xga->linear_endian_reverse && !(xga->access_mode & 8)) - xga->cursor_data_on = 0; - } - } - - if ((xga->sprite_pos > 16) && (xga->sprite_pos <= 0x1ff)) { - if (xga->aperture_cntl) { - if (xga->sprite_pos & 0x0f) - xga->cursor_data_on = 1; - else - xga->cursor_data_on = 0; - } else - xga->cursor_data_on = 0; - } else if (!xga->sprite_pos && xga->cursor_data_on && !xga->aperture_cntl && xga->linear_endian_reverse) - xga->cursor_data_on = 0; - xga_log("Sprite POS = %d, data on = %d, idx = %d, apcntl = %d\n", xga->sprite_pos, xga->cursor_data_on, xga->sprite_pal_addr_idx, xga->aperture_cntl); @@ -515,13 +506,12 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *priv) xga_t *xga = (xga_t *) svga->xga; xga_log("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val); - switch (addr & 0x0f) { case 0: xga->op_mode = val; break; case 1: - xga->aperture_cntl = val; + xga->aperture_cntl = val & 3; xga_updatemapping(svga); break; case 4: @@ -561,6 +551,7 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *priv) case 0x0e: case 0x0f: xga->regs[xga->regs_idx] = val; + xga_log("EXT OUT Reg=%02x, val=%02x.\n", xga->regs_idx, val); xga_ext_out_reg(xga, svga, xga->regs_idx, xga->regs[xga->regs_idx]); break; @@ -801,6 +792,8 @@ xga_ext_inb(uint16_t addr, void *priv) default: ret = xga->regs[xga->regs_idx]; + if ((xga->regs_idx == 0x0c) || (xga->regs_idx == 0x0d)) + xga_log("EXT IN Reg=%02x, val=%02x.\n", xga->regs_idx, ret); break; } break; @@ -1760,6 +1753,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) switch (addr & 0x7f) { case 0x11: xga->accel.control = val; + xga_log("Control=%02x.\n", val); break; case 0x12: @@ -2303,6 +2297,12 @@ xga_mem_read(uint32_t addr, xga_t *xga, UNUSED(svga_t *svga)) temp = xga->vga_bios_rom.rom[addr]; } else { switch (addr & 0x7f) { + case 0x0c: + temp = xga->regs[0x0c]; + break; + case 0x0d: + temp = xga->regs[0x0d]; + break; case 0x11: temp = xga->accel.control; if (xga->accel.control & 0x08) @@ -2423,42 +2423,45 @@ xga_memio_readl(uint32_t addr, void *priv) static void xga_hwcursor_draw(svga_t *svga, int displine) { - xga_t *xga = (xga_t *) svga->xga; - uint8_t dat = 0; - int offset = xga->hwcursor_latch.x - xga->hwcursor_latch.xoff; - int x_pos; - int y_pos; - int comb = 0; - uint32_t *p; - int idx = xga->cursor_data_on ? 32 : 0; + xga_t *xga = (xga_t *) svga->xga; + int comb; + uint8_t dat = 0; + int offset = xga->hwcursor_latch.x - xga->hwcursor_latch.xoff; + int idx = 0; + int x_pos; + int y_pos; + uint32_t *p; + const uint8_t *cd; + + if (xga->hwcursor_latch.xoff & 0x20) + idx = 32; + + cd = (uint8_t *) xga->sprite_data; if (xga->interlace && xga->hwcursor_oddeven) xga->hwcursor_latch.addr += 16; - y_pos = displine; - x_pos = offset + svga->x_add; - p = buffer32->line[y_pos]; + for (uint8_t x = 0; x < xga->hwcursor_latch.cur_xsize; x++) { + dat = cd[xga->hwcursor_latch.addr & 0x3ff]; + + comb = (dat >> ((x & 0x03) << 1)) & 0x03; + + y_pos = displine; + x_pos = offset + svga->x_add; + p = buffer32->line[y_pos]; - for (int x = 0; x < xga->hwcursor_latch.cur_xsize; x++) { if (x >= idx) { - if (!(x & 0x03)) - dat = xga->sprite_data[xga->hwcursor_latch.addr & 0x3ff]; - - comb = (dat >> ((x & 0x03) << 1)) & 0x03; - - x_pos = offset + svga->x_add + x; - switch (comb) { case 0x00: - /* Cursor Color 1 */ + /* Cursor Color 1 */ p[x_pos] = xga->hwc_color0; break; case 0x01: - /* Cursor Color 2 */ + /* Cursor Color 2 */ p[x_pos] = xga->hwc_color1; break; case 0x03: - /* Complement */ + /* Complement */ p[x_pos] ^= 0xffffff; break; @@ -2466,6 +2469,8 @@ xga_hwcursor_draw(svga_t *svga, int displine) break; } } + offset++; + xga_log("P=%08x, xpos=%d, comb=%x, ypos=%d, offset=%d, latchx=%d, latchxoff=%d.\n", p[x_pos], x_pos, comb, y_pos, offset, xga->hwcursor_latch.x, xga->hwcursor_latch.xoff); if ((x & 0x03) == 0x03) xga->hwcursor_latch.addr++; @@ -2927,12 +2932,12 @@ xga_poll(void *priv, svga_t *svga) if (!xga->linepos) { if (xga->displine == xga->hwcursor_latch.y && xga->hwcursor_latch.ena) { - xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - (xga->cursor_data_on ? 32 : 0); + xga->hwcursor_on = xga->hwcursor_latch.cur_ysize; 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->cursor_data_on ? 33 : 1); + xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - 1; xga->hwcursor_oddeven = 1; } From 4325c78fa81700125c21db8617030fcb9e026b51 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 26 Apr 2024 23:59:17 +0200 Subject: [PATCH 877/936] Just shut up the warning. See above. --- src/video/vid_xga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index e62a14a61..a908c3418 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -2441,7 +2441,7 @@ xga_hwcursor_draw(svga_t *svga, int displine) if (xga->interlace && xga->hwcursor_oddeven) xga->hwcursor_latch.addr += 16; - for (uint8_t x = 0; x < xga->hwcursor_latch.cur_xsize; x++) { + for (int x = 0; x < xga->hwcursor_latch.cur_xsize; x++) { dat = cd[xga->hwcursor_latch.addr & 0x3ff]; comb = (dat >> ((x & 0x03) << 1)) & 0x03; From f4d210273431338411588a8b57646645edaa076c Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 28 Apr 2024 16:47:32 +0200 Subject: [PATCH 878/936] Bochs VBE graphics card, originally by Cacodemon345, then extensively cleaned-up and improved. --- src/include/86box/video.h | 13 +- src/video/CMakeLists.txt | 3 +- src/video/vid_bochs_vbe.c | 941 ++++++++++++++++++++++++++++++++++++++ src/video/vid_table.c | 13 +- src/video/video.c | 2 +- 5 files changed, 959 insertions(+), 13 deletions(-) create mode 100644 src/video/vid_bochs_vbe.c diff --git a/src/include/86box/video.h b/src/include/86box/video.h index bf36bf7de..1c8b61015 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -223,7 +223,7 @@ extern void video_screenshot_monitor(uint32_t *buf, int start_x, int start_y, in extern void video_screenshot(uint32_t *buf, int start_x, int start_y, int row_len); #ifdef _WIN32 -extern void *__cdecl (*video_copy)(void *_Dst, const void *_Src, size_t _Size); +extern void * (__cdecl *video_copy)(void *_Dst, const void *_Src, size_t _Size); extern void *__cdecl video_transform_copy(void *_Dst, const void *_Src, size_t _Size); #else extern void *(*video_copy)(void *__restrict _Dst, const void *__restrict _Src, size_t _Size); @@ -334,6 +334,13 @@ extern const device_t compaq_ati28800_device; extern const device_t ati28800_wonderxl24_device; # endif +/* Bochs */ +extern const device_t bochs_svga_device; + +/* Chips & Technologies */ +extern const device_t chips_69000_device; +extern const device_t chips_69000_onboard_device; + /* Cirrus Logic GD54xx */ extern const device_t gd5401_isa_device; extern const device_t gd5402_isa_device; @@ -579,10 +586,6 @@ extern const device_t velocity_200_agp_device; /* Wyse 700 */ extern const device_t wy700_device; -/* Chips & Technologies */ -extern const device_t chips_69000_device; -extern const device_t chips_69000_onboard_device; - #endif #endif /*EMU_VIDEO_H*/ diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index 12ba34a02..c8fb7021d 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -26,7 +26,8 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c vid_rtg310x.c vid_f82c425.c vid_ti_cf62011.c vid_tvga.c vid_tgui9440.c vid_tkd8001_ramdac.c vid_att20c49x_ramdac.c vid_s3.c vid_s3_virge.c vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_mga.c vid_nga.c - vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c) + vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c + vid_bochs_vbe.c) if(XL24) target_compile_definitions(vid PRIVATE USE_XL24) diff --git a/src/video/vid_bochs_vbe.c b/src/video/vid_bochs_vbe.c new file mode 100644 index 000000000..c94049a1c --- /dev/null +++ b/src/video/vid_bochs_vbe.c @@ -0,0 +1,941 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Bochs VBE SVGA emulation. + * + * Uses code from libxcvt to calculate CRTC timings. + * + * Authors: Cacodemon345 + * The Bochs Project + * Fabrice Bellard + * The libxcvt authors + * + * Copyright 2024 Cacodemon345 + * Copyright 2003 Fabrice Bellard + * Copyright 2002-2024 The Bochs Project + * Copyright 2002-2003 Mike Nordell + * Copyright 2000-2021 The libxcvt authors + * + * See https://gitlab.freedesktop.org/xorg/lib/libxcvt/-/blob/master/COPYING for libxcvt license details + */ + +#include +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/device.h> +#include <86box/timer.h> +#include <86box/video.h> +#include <86box/vid_svga.h> +#include <86box/vid_svga_render.h> +#include <86box/pci.h> +#include <86box/i2c.h> +#include <86box/vid_ddc.h> + +#define VBE_DISPI_BANK_SIZE_KB 64 +#define VBE_DISPI_BANK_GRANULARITY_KB 32 + +#define VBE_DISPI_MAX_XRES 1920 +#define VBE_DISPI_MAX_YRES 1600 + +#define VBE_DISPI_IOPORT_INDEX 0x01CE +#define VBE_DISPI_IOPORT_DATA 0x01CF + +#define VBE_DISPI_INDEX_ID 0x0 +#define VBE_DISPI_INDEX_XRES 0x1 +#define VBE_DISPI_INDEX_YRES 0x2 +#define VBE_DISPI_INDEX_BPP 0x3 +#define VBE_DISPI_INDEX_ENABLE 0x4 +#define VBE_DISPI_INDEX_BANK 0x5 +#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6 +#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7 +#define VBE_DISPI_INDEX_X_OFFSET 0x8 +#define VBE_DISPI_INDEX_Y_OFFSET 0x9 +#define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa +#define VBE_DISPI_INDEX_DDC 0xb + +#define VBE_DISPI_ID0 0xB0C0 +#define VBE_DISPI_ID1 0xB0C1 +#define VBE_DISPI_ID2 0xB0C2 +#define VBE_DISPI_ID3 0xB0C3 +#define VBE_DISPI_ID4 0xB0C4 +#define VBE_DISPI_ID5 0xB0C5 + +#define VBE_DISPI_DISABLED 0x00 +#define VBE_DISPI_ENABLED 0x01 +#define VBE_DISPI_GETCAPS 0x02 +#define VBE_DISPI_BANK_GRANULARITY_32K 0x10 +#define VBE_DISPI_8BIT_DAC 0x20 +#define VBE_DISPI_LFB_ENABLED 0x40 +#define VBE_DISPI_NOCLEARMEM 0x80 + +#define VBE_DISPI_BANK_WR 0x4000 +#define VBE_DISPI_BANK_RD 0x8000 +#define VBE_DISPI_BANK_RW 0xc000 + + +typedef struct vbe_mode_info_t { + uint32_t hdisplay; + uint32_t vdisplay; + float vrefresh; + float hsync; + uint64_t dot_clock; + uint16_t hsync_start; + uint16_t hsync_end; + uint16_t htotal; + uint16_t vsync_start; + uint16_t vsync_end; + uint16_t vtotal; +} vbe_mode_info_t; + +static video_timings_t timing_bochs = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; + +typedef struct bochs_vbe_t { + svga_t svga; + + uint8_t pci_conf_status; + uint8_t pci_rom_enable; + uint8_t pci_line_interrupt; + uint8_t slot; + + uint8_t pci_regs[256]; + + uint16_t vbe_index; + uint16_t bank_gran; + uint16_t rom_addr; + uint16_t id5_val; + + uint16_t vbe_regs[16]; + + uint32_t vram_size; + + rom_t bios_rom; + + mem_mapping_t linear_mapping; + mem_mapping_t linear_mapping_2; + + void * i2c; + void * ddc; +} bochs_vbe_t; + +static bochs_vbe_t *reset_state = NULL; + +static void +gen_mode_info(int hdisplay, int vdisplay, float vrefresh, vbe_mode_info_t* mode_info) +{ + int vsync; + int vsync_and_back_porch; + + mode_info->hdisplay = hdisplay; + mode_info->vdisplay = vdisplay; + mode_info->vrefresh = vrefresh; + + /* 1) top/bottom margin size (% of height) - default: 1.8 */ +#define CVT_MARGIN_PERCENTAGE 1.8 + + /* 2) character cell horizontal granularity (pixels) - default 8 */ +#define CVT_H_GRANULARITY 8 + + /* 4) Minimum vertical front porch (lines) - default 3 */ +#define CVT_MIN_V_PORCH_RND 3 + + /* 4) Minimum number of vertical back porch lines - default 6 */ +#define CVT_MIN_V_BPORCH 6 + + /* Pixel Clock step (kHz) */ +#define CVT_CLOCK_STEP 250 + + /* CVT default is 60.0Hz */ + if (!mode_info->vrefresh) + mode_info->vrefresh = 60.0; + + /* 1. Required field rate */ + const float vfield_rate = mode_info->vrefresh; + + /* 2. Horizontal pixels */ + const int hdisplay_rnd = mode_info->hdisplay - (mode_info->hdisplay % CVT_H_GRANULARITY); + + /* 3. Determine left and right borders */ + const int hmargin = 0; + + /* 4. Find total active pixels */ + mode_info->hdisplay = hdisplay_rnd + (2 * hmargin); + + /* 5. Find number of lines per field */ + const int vdisplay_rnd = mode_info->vdisplay; + + /* 6. Find top and bottom margins */ + const int vmargin = 0; + + mode_info->vdisplay = mode_info->vdisplay + 2 * vmargin; + + /* 7. interlace */ + /* Please rename this */ + const float interlace = 0.0; + + /* Determine vsync Width from aspect ratio */ + if (!(mode_info->vdisplay % 3) && ((mode_info->vdisplay * 4 / 3) == mode_info->hdisplay)) + vsync = 4; + else if (!(mode_info->vdisplay % 9) && + ((mode_info->vdisplay * 16 / 9) == mode_info->hdisplay)) + vsync = 5; + else if (!(mode_info->vdisplay % 10) && + ((mode_info->vdisplay * 16 / 10) == mode_info->hdisplay)) + vsync = 6; + else if (!(mode_info->vdisplay % 4) && + ((mode_info->vdisplay * 5 / 4) == mode_info->hdisplay)) + vsync = 7; + else if (!(mode_info->vdisplay % 9) && + ((mode_info->vdisplay * 15 / 9) == mode_info->hdisplay)) + vsync = 7; + else /* Custom */ + vsync = 10; + + /* Simplified GTF calculation. */ + + /* 4) Minimum time of vertical sync + back porch interval (µs) + * default 550.0 */ +#define CVT_MIN_VSYNC_BP 550.0 + + /* 3) Nominal HSync width (% of line period) - default 8 */ +#define CVT_HSYNC_PERCENTAGE 8 + + /* 8. Estimated Horizontal period */ + const float hperiod = ((float) (1000000.0 / vfield_rate - CVT_MIN_VSYNC_BP)) / + (vdisplay_rnd + 2 * vmargin + CVT_MIN_V_PORCH_RND + interlace); + + /* 9. Find number of lines in sync + backporch */ + if (((int) (CVT_MIN_VSYNC_BP / hperiod) + 1) < (vsync + CVT_MIN_V_BPORCH)) + vsync_and_back_porch = vsync + CVT_MIN_V_BPORCH; + else + vsync_and_back_porch = (int) (CVT_MIN_VSYNC_BP / hperiod) + 1; + + /* 10. Find number of lines in back porch */ + + /* 11. Find total number of lines in vertical field */ + mode_info->vtotal = vdisplay_rnd + (2 * vmargin) + vsync_and_back_porch + interlace + + CVT_MIN_V_PORCH_RND; + + /* 5) Definition of Horizontal blanking time limitation */ + /* Gradient (%/kHz) - default 600 */ +#define CVT_M_FACTOR 600 + + /* Offset (%) - default 40 */ +#define CVT_C_FACTOR 40 + + /* Blanking time scaling factor - default 128 */ +#define CVT_K_FACTOR 128 + + /* Scaling factor weighting - default 20 */ +#define CVT_J_FACTOR 20 + +#define CVT_M_PRIME CVT_M_FACTOR * CVT_K_FACTOR / 256 +#define CVT_C_PRIME (CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \ + CVT_J_FACTOR + + /* 12. Find ideal blanking duty cycle from formula */ + float hblank_percentage = CVT_C_PRIME - CVT_M_PRIME * hperiod / 1000.0; + + /* 13. Blanking time */ + if (hblank_percentage < 20) + hblank_percentage = 20; + + int hblank = mode_info->hdisplay * hblank_percentage / (100.0 - hblank_percentage); + hblank -= hblank % (2 * CVT_H_GRANULARITY); + + /* 14. Find total number of pixels in a line. */ + mode_info->htotal = mode_info->hdisplay + hblank; + + /* Fill in HSync values */ + mode_info->hsync_end = mode_info->hdisplay + hblank / 2; + + int hsync_w = (mode_info->htotal * CVT_HSYNC_PERCENTAGE) / 100; + hsync_w -= hsync_w % CVT_H_GRANULARITY; + mode_info->hsync_start = mode_info->hsync_end - hsync_w; + + /* Fill in vsync values */ + mode_info->vsync_start = mode_info->vdisplay + CVT_MIN_V_PORCH_RND; + mode_info->vsync_end = mode_info->vsync_start + vsync; + + /* 15/13. Find pixel clock frequency (kHz for xf86) */ + mode_info->dot_clock = mode_info->htotal * 1000.0 / hperiod; + mode_info->dot_clock -= mode_info->dot_clock % CVT_CLOCK_STEP; + + /* 16/14. Find actual Horizontal Frequency (kHz) */ + mode_info->hsync = ((float) mode_info->dot_clock) / ((float) mode_info->htotal); + + /* 17/15. Find actual Field rate */ + mode_info->vrefresh = (1000.0 * ((float) mode_info->dot_clock)) / + ((float) (mode_info->htotal * mode_info->vtotal)); + + /* 18/16. Find actual vertical frame frequency */ + /* ignore - we don't do interlace here */ +} + +void +bochs_vbe_recalctimings(svga_t* svga) +{ + bochs_vbe_t *dev = (bochs_vbe_t *) svga->priv; + + if (dev->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) { + vbe_mode_info_t mode = { 0 }; + svga->bpp = dev->vbe_regs[VBE_DISPI_INDEX_BPP]; + dev->vbe_regs[VBE_DISPI_INDEX_XRES] &= ~7; + if (dev->vbe_regs[VBE_DISPI_INDEX_XRES] == 0) { + dev->vbe_regs[VBE_DISPI_INDEX_XRES] = 8; + } + if (dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] > VBE_DISPI_MAX_XRES) + dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = VBE_DISPI_MAX_XRES; + if (dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] < dev->vbe_regs[VBE_DISPI_INDEX_XRES]) + dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = dev->vbe_regs[VBE_DISPI_INDEX_XRES]; + if (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] > VBE_DISPI_MAX_XRES) + dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = VBE_DISPI_MAX_XRES; + if (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] > VBE_DISPI_MAX_YRES) + dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = VBE_DISPI_MAX_YRES; + + if (dev->vbe_regs[VBE_DISPI_INDEX_YRES] == 0) + dev->vbe_regs[VBE_DISPI_INDEX_YRES] = 1; + if (dev->vbe_regs[VBE_DISPI_INDEX_YRES] > VBE_DISPI_MAX_YRES) + dev->vbe_regs[VBE_DISPI_INDEX_YRES] = VBE_DISPI_MAX_YRES; + gen_mode_info(dev->vbe_regs[VBE_DISPI_INDEX_XRES], + dev->vbe_regs[VBE_DISPI_INDEX_YRES], 72.f, &mode); + svga->char_width = 1; + svga->dots_per_clock = 1; + svga->clock = (cpuclock * (double) (1ULL << 32)) / (mode.dot_clock * 1000.); + svga->dispend = mode.vdisplay; + svga->hdisp = mode.hdisplay; + svga->vsyncstart = mode.vsync_start; + svga->vtotal = mode.vtotal; + svga->htotal = mode.htotal; + svga->hblankstart = mode.hdisplay; + svga->hblankend = mode.hdisplay + (mode.htotal - mode.hdisplay - 1); + svga->vblankstart = svga->dispend; /* no vertical overscan. */ + svga->rowcount = 0; + if (dev->vbe_regs[VBE_DISPI_INDEX_BPP] != 4) { + svga->fb_only = 1; + svga->adv_flags |= FLAG_NO_SHIFT3; + + } else { + svga->fb_only = 0; + svga->adv_flags &= ~FLAG_NO_SHIFT3; + } + + svga->bpp = dev->vbe_regs[VBE_DISPI_INDEX_BPP]; + + if (svga->bpp == 4) { + svga->rowoffset = dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] >> 3; + svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) + + (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] >> 3); + } else { + svga->rowoffset = dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] * (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 / 8)); + } + + if ((svga->ma_latch + dev->vbe_regs[VBE_DISPI_INDEX_YRES] * svga->rowoffset) > + svga->vram_max) { + dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0; + svga->ma_latch = (svga->bpp == 4) ? (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] >> 3) : + (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * (svga->bpp / 8)); + if ((svga->ma_latch + dev->vbe_regs[VBE_DISPI_INDEX_YRES] * svga->rowoffset) > + svga->vram_max) { + svga->ma_latch = 0; + dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0; + } + } + svga->split = 0xffffff; + + switch (svga->bpp) { + case 4: + svga->render = svga_render_4bpp_highres; + break; + default: + case 8: + svga->render = svga_render_8bpp_clone_highres; + break; + case 15: + svga->render = svga_render_15bpp_highres; + break; + case 16: + svga->render = svga_render_16bpp_highres; + break; + case 24: + svga->render = svga_render_24bpp_highres; + break; + case 32: + svga->render = svga_render_32bpp_highres; + break; + } + } else { + svga->fb_only = 0; + svga->packed_4bpp = 0; + svga->adv_flags &= ~FLAG_NO_SHIFT3; + } +} + +uint16_t +bochs_vbe_inw(const uint16_t addr, void *priv) +{ + const bochs_vbe_t *dev = (bochs_vbe_t *) priv; + const bool vbe_get_caps = !!(dev->vbe_regs[VBE_DISPI_INDEX_ENABLE] & + VBE_DISPI_GETCAPS); + uint16_t ret; + + if (addr == 0x1ce) + ret = dev->vbe_index; + else switch (dev->vbe_index) { + default: + ret = dev->vbe_regs[dev->vbe_index]; + break; + case VBE_DISPI_INDEX_XRES: + ret = vbe_get_caps ? VBE_DISPI_MAX_XRES : dev->vbe_regs[dev->vbe_index]; + break; + case VBE_DISPI_INDEX_YRES: + ret = vbe_get_caps ? VBE_DISPI_MAX_YRES : dev->vbe_regs[dev->vbe_index]; + break; + case VBE_DISPI_INDEX_BPP: + ret = vbe_get_caps ? 32 : dev->vbe_regs[dev->vbe_index]; + break; + case VBE_DISPI_INDEX_VIDEO_MEMORY_64K: + ret = dev->vram_size >> 16; + break; + case VBE_DISPI_INDEX_BANK: + ret = vbe_get_caps ? (VBE_DISPI_BANK_GRANULARITY_32K << 8) : + dev->vbe_regs[dev->vbe_index]; + break; + case VBE_DISPI_INDEX_DDC: + if (dev->vbe_regs[dev->vbe_index] & (1 << 7)) { + ret = dev->vbe_regs[dev->vbe_index] & ((1 << 7) | 0x3); + ret |= i2c_gpio_get_scl(dev->i2c) << 2; + ret |= i2c_gpio_get_sda(dev->i2c) << 3; + } else + ret = 0x000f; + break; + } + + return ret; +} + +uint32_t +bochs_vbe_inl(const uint16_t addr, void *priv) +{ + const bochs_vbe_t *dev = (bochs_vbe_t *) priv; + uint32_t ret; + + if (addr == 0x1ce) + ret = dev->vbe_index; + else + ret = dev->vram_size; + + pclog("[%04X:%08X] [R] %04X = %08X\n", CS, cpu_state.pc, addr, ret); + + return ret; +} + +void +bochs_vbe_outw(const uint16_t addr, const uint16_t val, void *priv) +{ + bochs_vbe_t *dev = (bochs_vbe_t *) priv; + + if (addr == 0x1ce) + dev->vbe_index = val; + else if ((addr == 0x1cf) || (addr == 0x1d0)) switch (dev->vbe_index) { + default: + break; + case VBE_DISPI_INDEX_ID: + if ((val == VBE_DISPI_ID0) || (val == VBE_DISPI_ID1) || + (val == VBE_DISPI_ID2) || (val == VBE_DISPI_ID3) || + (val == VBE_DISPI_ID4)) + dev->vbe_regs[dev->vbe_index] = val; + else if (val == VBE_DISPI_ID5) + dev->vbe_regs[dev->vbe_index] = dev->id5_val; + break; + case VBE_DISPI_INDEX_XRES: + case VBE_DISPI_INDEX_YRES: + case VBE_DISPI_INDEX_BPP: + case VBE_DISPI_INDEX_VIRT_WIDTH: + case VBE_DISPI_INDEX_X_OFFSET: + case VBE_DISPI_INDEX_Y_OFFSET: + dev->vbe_regs[dev->vbe_index] = val; + svga_recalctimings(&dev->svga); + break; + + case VBE_DISPI_INDEX_BANK: + if (val & VBE_DISPI_BANK_RD) + dev->svga.read_bank = (val & 0x1ff) * (dev->bank_gran << 10); + if (val & VBE_DISPI_BANK_WR) + dev->svga.write_bank = (val & 0x1ff) * (dev->bank_gran << 10); + break; + + case VBE_DISPI_INDEX_DDC: + if (val & (1 << 7)) { + i2c_gpio_set(dev->i2c, !!(val & 1), !!(val & 2)); + dev->vbe_regs[dev->vbe_index] = val; + } else + dev->vbe_regs[dev->vbe_index] &= ~(1 << 7); + break; + + case VBE_DISPI_INDEX_ENABLE: { + uint32_t new_bank_gran; + dev->vbe_regs[dev->vbe_index] = val; + if ((val & VBE_DISPI_ENABLED) && + !(dev->vbe_regs[VBE_DISPI_ENABLED] & VBE_DISPI_ENABLED)) { + dev->vbe_regs[dev->vbe_index] = val; + dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0; + dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0; + dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = 0; + svga_recalctimings(&dev->svga); + if (!(val & VBE_DISPI_NOCLEARMEM)) { + memset(dev->svga.vram, 0, + dev->vbe_regs[VBE_DISPI_INDEX_YRES] * dev->svga.rowoffset); + } + } else + dev->svga.read_bank = dev->svga.write_bank = 0; + if ((val & VBE_DISPI_BANK_GRANULARITY_32K) != 0) + new_bank_gran = 32; + else + new_bank_gran = 64; + if (dev->bank_gran != new_bank_gran) { + dev->bank_gran = new_bank_gran; + dev->svga.read_bank = dev->svga.write_bank = 0; + } + if (val & VBE_DISPI_8BIT_DAC) + dev->svga.adv_flags &= ~FLAG_RAMDAC_SHIFT; + else + dev->svga.adv_flags |= FLAG_RAMDAC_SHIFT; + dev->vbe_regs[dev->vbe_index] &= ~VBE_DISPI_NOCLEARMEM; + } + } +} + +void +bochs_vbe_outl(const uint16_t addr, const uint32_t val, void *priv) +{ + bochs_vbe_outw(addr, val & 0xffff, priv); + bochs_vbe_outw(addr + 2, val >> 16, priv); +} + +void +bochs_vbe_out(uint16_t addr, uint8_t val, void *priv) +{ + bochs_vbe_t *dev = (bochs_vbe_t *) priv; + svga_t * svga = &dev->svga; + uint8_t old; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) { + case VBE_DISPI_IOPORT_INDEX: + dev->vbe_index = val; + return; + case VBE_DISPI_IOPORT_DATA: + bochs_vbe_outw(0x1cf, val | (bochs_vbe_inw(0x1cf, dev) & 0xFF00), dev); + return; + case VBE_DISPI_IOPORT_DATA + 1: + bochs_vbe_outw(0x1cf, (val << 8) | (bochs_vbe_inw(0x1cf, dev) & 0xFF), dev); + return; + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if (svga->crtcreg & 0x20) + return; + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + } + break; + + default: + break; + } + + svga_out(addr, val, svga); +} + +uint8_t +bochs_vbe_in(uint16_t addr, void *priv) +{ + bochs_vbe_t *dev = (bochs_vbe_t *) priv; + svga_t * svga = &dev->svga; + uint8_t ret; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) { + default: + ret = svga_in(addr, svga); + break; + case VBE_DISPI_IOPORT_INDEX: + ret = dev->vbe_index; + break; + case VBE_DISPI_IOPORT_DATA: + ret = bochs_vbe_inw(0x1cf, dev); + break; + case VBE_DISPI_IOPORT_DATA + 1: + ret = bochs_vbe_inw(0x1cf, dev) >> 8; + break; + case 0x3D4: + ret = svga->crtcreg; + break; + case 0x3D5: + if (svga->crtcreg & 0x20) + ret = 0xff; + else + ret = svga->crtc[svga->crtcreg]; + break; + } + + return ret; +} + +static uint8_t +bochs_vbe_pci_read(const int func, const int addr, void *priv) +{ + const bochs_vbe_t *dev = (bochs_vbe_t *) priv; + uint8_t ret = 0x00; + + if (func == 0x00) switch (addr) { + default: + break; + case 0x00: + ret = 0x34; + break; + case 0x01: + ret = 0x12; + break; + case 0x02: + ret = 0x11; + break; + case 0x03: + ret = 0x11; + break; + case 0x04: + ret = (dev->pci_conf_status & 0b11100011) | 0x80; + break; + case 0x06: + ret = 0x80; + break; + case 0x07: + ret = 0x02; + break; + case 0x0b: + ret = 0x03; + break; + case 0x13: + ret = dev->pci_regs[addr]; + break; + case 0x17: + ret = (dev->pci_regs[0x13] != 0x00) ? 0xe0 : 0x00; + break; + case 0x30: + ret = dev->pci_rom_enable & 0x01; + break; + case 0x32: + ret = dev->rom_addr & 0xff; + break; + case 0x33: + ret = (dev->rom_addr & 0xff00) >> 8; + break; + case 0x3c: + ret = dev->pci_line_interrupt; + break; + case 0x3d: + ret = 0x01; + break; + } else + ret = 0xff; + + if (func == 0x00) + pclog("[R] %02X = %02X\n", addr, ret); + + return ret; +} + +static void +bochs_vbe_disable_handlers(bochs_vbe_t *dev) +{ + io_removehandler(0x03c0, 0x0020, bochs_vbe_in, NULL, NULL, + bochs_vbe_out, NULL, NULL, dev); + io_removehandler(0x01ce, 0x0003, bochs_vbe_in, bochs_vbe_inw, + bochs_vbe_inl, bochs_vbe_out, bochs_vbe_outw, bochs_vbe_outl, dev); + + mem_mapping_disable(&dev->linear_mapping_2); + mem_mapping_disable(&dev->linear_mapping); + mem_mapping_disable(&dev->svga.mapping); + mem_mapping_disable(&dev->bios_rom.mapping); + + reset_state->linear_mapping_2 = dev->linear_mapping_2; + reset_state->linear_mapping = dev->linear_mapping; + reset_state->svga.mapping = dev->svga.mapping; + reset_state->bios_rom.mapping = dev->bios_rom.mapping; +} + +static void +bochs_vbe_pci_write(const int func, const int addr, const uint8_t val, void *priv) +{ + bochs_vbe_t *dev = (bochs_vbe_t *) priv; + + if (func == 0x00) + pclog("[W] %02X = %02X\n", addr, val); + + if (func == 0x00) switch (addr) { + default: + break; + case 0x04: + dev->pci_conf_status = val; + io_removehandler(0x03c0, 0x0020, bochs_vbe_in, NULL, NULL, + bochs_vbe_out, NULL, NULL, dev); + io_removehandler(0x01ce, 0x0003, bochs_vbe_in, bochs_vbe_inw, + bochs_vbe_inl, bochs_vbe_out, bochs_vbe_outw, bochs_vbe_outl, dev); + mem_mapping_disable(&dev->linear_mapping_2); + mem_mapping_disable(&dev->linear_mapping); + mem_mapping_disable(&dev->svga.mapping); + if (dev->pci_conf_status & PCI_COMMAND_IO) { + io_sethandler(0x03c0, 0x0020, bochs_vbe_in, NULL, NULL, + bochs_vbe_out, NULL, NULL, dev); + io_sethandler(0x01ce, 0x0003, bochs_vbe_in, bochs_vbe_inw, bochs_vbe_inl, + bochs_vbe_out, bochs_vbe_outw, bochs_vbe_outl, dev); + } + if (dev->pci_conf_status & PCI_COMMAND_MEM) { + mem_mapping_enable(&dev->svga.mapping); + if (dev->pci_regs[0x13] != 0x00) { + mem_mapping_enable(&dev->linear_mapping); + if (dev->pci_regs[0x13] != 0xe0) + mem_mapping_enable(&dev->linear_mapping_2); + } + } + break; + case 0x13: + dev->pci_regs[addr] = val; + + mem_mapping_disable(&dev->linear_mapping_2); + mem_mapping_disable(&dev->linear_mapping); + + if ((dev->pci_conf_status & PCI_COMMAND_MEM) && (val != 0x00)) { + mem_mapping_set_addr(&dev->linear_mapping, val << 24, 0x01000000); + if (val != 0xe0) + mem_mapping_set_addr(&dev->linear_mapping_2, 0xe0000000, 0x01000000); + } + break; + case 0x3c: + dev->pci_line_interrupt = val; + break; + case 0x30: + dev->pci_rom_enable = val & 0x01; + mem_mapping_disable(&dev->bios_rom.mapping); + if (dev->pci_rom_enable) + mem_mapping_set_addr(&dev->bios_rom.mapping, dev->rom_addr << 16, 0x10000); + break; + case 0x32: + dev->rom_addr = (dev->rom_addr & 0xff00) | (val & 0xfc); + if (dev->pci_rom_enable) + mem_mapping_set_addr(&dev->bios_rom.mapping, dev->rom_addr << 16, 0x10000); + break; + case 0x33: + dev->rom_addr = (dev->rom_addr & 0x00ff) | (val << 8); + if (dev->pci_rom_enable) + mem_mapping_set_addr(&dev->bios_rom.mapping, dev->rom_addr << 16, 0x10000); + break; + } +} + +static void +bochs_vbe_reset(void *priv) +{ + bochs_vbe_t *dev = (bochs_vbe_t *) priv; + + if (reset_state != NULL) { + bochs_vbe_disable_handlers(dev); + reset_state->slot = dev->slot; + + *dev = *reset_state; + } +} + +static void * +bochs_vbe_init(const device_t *info) +{ + bochs_vbe_t *dev = calloc(1, sizeof(bochs_vbe_t)); + reset_state = calloc(1, sizeof(bochs_vbe_t)); + + dev->id5_val = device_get_config_int("revision"); + dev->vram_size = device_get_config_int("memory") * (1 << 20); + + rom_init(&dev->bios_rom, "roms/video/bochs/VGABIOS-lgpl-latest.bin", + 0xc0000, 0x10000, 0xffff, 0x0000, + MEM_MAPPING_EXTERNAL); + + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_bochs); + + svga_init(info, &dev->svga, dev, dev->vram_size, + bochs_vbe_recalctimings, + bochs_vbe_in, bochs_vbe_out, + NULL, + NULL); + + mem_mapping_add(&dev->linear_mapping, 0, 0, + svga_readb_linear, svga_readw_linear, svga_readl_linear, + svga_writeb_linear, svga_writew_linear, svga_writel_linear, + NULL, MEM_MAPPING_EXTERNAL, &dev->svga); + /* Hack: If the mapping gets mapped anywhere other than at 0xe0000000, + enable this second copy of it at 0xe0000000 so michaln's driver works. */ + mem_mapping_add(&dev->linear_mapping_2, 0, 0, + svga_readb_linear, svga_readw_linear, svga_readl_linear, + svga_writeb_linear, svga_writew_linear, svga_writel_linear, + NULL, MEM_MAPPING_EXTERNAL, &dev->svga); + + mem_mapping_disable(&dev->bios_rom.mapping); + + mem_mapping_disable(&dev->svga.mapping); + + mem_mapping_disable(&dev->linear_mapping); + mem_mapping_disable(&dev->linear_mapping_2); + + dev->svga.bpp = 8; + dev->svga.miscout = 1; + + dev->bank_gran = 64; + + svga_set_ramdac_type(&dev->svga, RAMDAC_8BIT); + + dev->svga.adv_flags |= FLAG_RAMDAC_SHIFT; + dev->svga.decode_mask = 0xffffff; + + dev->i2c = i2c_gpio_init("ddc_bochs"); + dev->ddc = ddc_init(i2c_gpio_get_bus(dev->i2c)); + + pci_add_card(PCI_ADD_NORMAL, bochs_vbe_pci_read, bochs_vbe_pci_write, dev, &dev->slot); + + *reset_state = *dev; + + return dev; +} + +static int +bochs_vbe_available(void) +{ + return rom_present("roms/video/bochs/VGABIOS-lgpl-latest.bin"); +} + +void +bochs_vbe_close(void *priv) +{ + bochs_vbe_t *dev = (bochs_vbe_t *) priv; + + ddc_close(dev->ddc); + i2c_gpio_close(dev->i2c); + + svga_close(&dev->svga); + + free(reset_state); + reset_state = NULL; + + free(dev); +} + +void +bochs_vbe_speed_changed(void *priv) +{ + bochs_vbe_t *bochs_vbe = (bochs_vbe_t *) priv; + + svga_recalctimings(&bochs_vbe->svga); +} + +void +bochs_vbe_force_redraw(void *priv) +{ + bochs_vbe_t *bochs_vbe = (bochs_vbe_t *) priv; + + bochs_vbe->svga.fullchange = changeframecount; +} + +static const device_config_t bochs_vbe_config[] = { + // clang-format off + { + .name = "revision", + .description = "Revision", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "VirtualBox", + .value = VBE_DISPI_ID4 + }, + { + .description = "Bochs latest", + .value = VBE_DISPI_ID5 + }, + { + .description = "" + } + }, + .default_int = VBE_DISPI_ID5 + }, + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "4 MB", + .value = 4 + }, + { + .description = "8 MB", + .value = 8 + }, + { + .description = "16 MB", + .value = 16 + }, + { + .description = "" + } + }, + .default_int = 16 + }, + { + .type = CONFIG_END + } + // clang-format on +}; + +const device_t bochs_svga_device = { + .name = "Bochs SVGA", + .internal_name = "bochs_svga", + .flags = DEVICE_PCI, + .local = 0, + .init = bochs_vbe_init, + .close = bochs_vbe_close, + .reset = bochs_vbe_reset, + { .available = bochs_vbe_available }, + .speed_changed = bochs_vbe_speed_changed, + .force_redraw = bochs_vbe_force_redraw, + .config = bochs_vbe_config +}; diff --git a/src/video/vid_table.c b/src/video/vid_table.c index e526216c3..b2686b2f3 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -163,11 +163,8 @@ video_cards[] = { { &mach32_pci_device, VIDEO_FLAG_TYPE_8514 }, { &mach64gx_pci_device }, { &mach64vt2_device }, - { &et4000w32p_videomagic_revb_pci_device }, - { &et4000w32p_revc_pci_device }, - { &et4000w32p_cardex_pci_device }, - { &et4000w32p_noncardex_pci_device }, - { &et4000w32p_pci_device }, + { &bochs_svga_device }, + { &chips_69000_device }, { &gd5430_pci_device, }, { &gd5434_pci_device }, { &gd5436_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, @@ -175,6 +172,11 @@ video_cards[] = { { &gd5446_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, { &gd5446_stb_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, { &gd5480_pci_device }, + { &et4000w32p_videomagic_revb_pci_device }, + { &et4000w32p_revc_pci_device }, + { &et4000w32p_cardex_pci_device }, + { &et4000w32p_noncardex_pci_device }, + { &et4000w32p_pci_device }, { &s3_spea_mercury_lite_86c928_pci_device }, { &s3_diamond_stealth64_964_pci_device }, { &s3_elsa_winner2000_pro_x_964_pci_device }, @@ -206,7 +208,6 @@ video_cards[] = { { &s3_virge_357_pci_device }, { &s3_diamond_stealth_4000_pci_device }, { &s3_trio3d2x_pci_device }, - { &chips_69000_device }, { &millennium_device }, { &millennium_ii_device }, { &mystique_device }, diff --git a/src/video/video.c b/src/video/video.c index 01c398118..0773e61ce 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -104,7 +104,7 @@ monitor_settings_t monitor_settings[MONITORS_NUM]; atomic_bool doresize_monitors[MONITORS_NUM]; #ifdef _WIN32 -void *__cdecl (*video_copy)(void *_Dst, const void *_Src, size_t _Size) = memcpy; +void * (*__cdecl video_copy)(void *_Dst, const void *_Src, size_t _Size) = memcpy; #else void *(*video_copy)(void *__restrict, const void *__restrict, size_t); #endif From c33adcb7a46aa7791362bde5e0860d753cc15c20 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 28 Apr 2024 18:43:56 +0200 Subject: [PATCH 879/936] The forgotten vid_svga.h. --- src/include/86box/vid_svga.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index bc33ac746..9eecebf2c 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -29,6 +29,7 @@ # define FLAG_ATI 128 # define FLAG_S3_911_16BIT 256 # define FLAG_512K_MASK 512 +# define FLAG_NO_SHIFT3 1024 /* Needed for Bochs VBE. */ struct monitor_t; typedef struct hwcursor_t { From dde745d8786d8fd193445b251331ed522129d979 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 29 Apr 2024 00:01:14 +0200 Subject: [PATCH 880/936] Some Bochs VBE fixes. --- src/video/vid_bochs_vbe.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/video/vid_bochs_vbe.c b/src/video/vid_bochs_vbe.c index c94049a1c..bfd917a4a 100644 --- a/src/video/vid_bochs_vbe.c +++ b/src/video/vid_bochs_vbe.c @@ -438,8 +438,6 @@ bochs_vbe_inl(const uint16_t addr, void *priv) else ret = dev->vram_size; - pclog("[%04X:%08X] [R] %04X = %08X\n", CS, cpu_state.pc, addr, ret); - return ret; } @@ -672,9 +670,6 @@ bochs_vbe_pci_read(const int func, const int addr, void *priv) } else ret = 0xff; - if (func == 0x00) - pclog("[R] %02X = %02X\n", addr, ret); - return ret; } @@ -691,10 +686,14 @@ bochs_vbe_disable_handlers(bochs_vbe_t *dev) mem_mapping_disable(&dev->svga.mapping); mem_mapping_disable(&dev->bios_rom.mapping); + /* Save all the mappings and the timers because they are part of linked lists. */ reset_state->linear_mapping_2 = dev->linear_mapping_2; - reset_state->linear_mapping = dev->linear_mapping; - reset_state->svga.mapping = dev->svga.mapping; + reset_state->linear_mapping = dev->linear_mapping; + reset_state->svga.mapping = dev->svga.mapping; reset_state->bios_rom.mapping = dev->bios_rom.mapping; + + reset_state->svga.timer = dev->svga.timer; + reset_state->svga.timer8514 = dev->svga.timer8514; } static void @@ -702,9 +701,6 @@ bochs_vbe_pci_write(const int func, const int addr, const uint8_t val, void *pri { bochs_vbe_t *dev = (bochs_vbe_t *) priv; - if (func == 0x00) - pclog("[W] %02X = %02X\n", addr, val); - if (func == 0x00) switch (addr) { default: break; From 2e4366de8b2773194176222d1b0a980478280d6f Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 29 Apr 2024 00:06:47 +0200 Subject: [PATCH 881/936] And the PCI device ID. --- src/video/vid_bochs_vbe.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/video/vid_bochs_vbe.c b/src/video/vid_bochs_vbe.c index bfd917a4a..603e455d1 100644 --- a/src/video/vid_bochs_vbe.c +++ b/src/video/vid_bochs_vbe.c @@ -623,16 +623,16 @@ bochs_vbe_pci_read(const int func, const int addr, void *priv) default: break; case 0x00: - ret = 0x34; + ret = (dev->id5_val == VBE_DISPI_ID5) ? 0x34 : 0xee; break; case 0x01: - ret = 0x12; + ret = (dev->id5_val == VBE_DISPI_ID5) ? 0x12 : 0x80; break; case 0x02: - ret = 0x11; + ret = (dev->id5_val == VBE_DISPI_ID5) ? 0x11 : 0xef; break; case 0x03: - ret = 0x11; + ret = (dev->id5_val == VBE_DISPI_ID5) ? 0x11 : 0xbe; break; case 0x04: ret = (dev->pci_conf_status & 0b11100011) | 0x80; From 37996011248b6dbfd3697f039f0d70037e8f1c79 Mon Sep 17 00:00:00 2001 From: Barnacl437 Date: Thu, 2 May 2024 21:23:03 +0700 Subject: [PATCH 882/936] Adding Vietnamese language (vi-VN) translation file --- src/qt/languages/vi-VN.po | 1174 +++++++++++++++++++++++++++++++++++++ 1 file changed, 1174 insertions(+) create mode 100644 src/qt/languages/vi-VN.po diff --git a/src/qt/languages/vi-VN.po b/src/qt/languages/vi-VN.po new file mode 100644 index 000000000..ed483dec2 --- /dev/null +++ b/src/qt/languages/vi-VN.po @@ -0,0 +1,1174 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: vi_VN\n" +"X-Source-Language: en_US\n" + +msgid "&Action" +msgstr "&Thực hiện" + +msgid "&Keyboard requires capture" +msgstr "Bàn phím &hoạt động cần capture chuột" + +msgid "&Right CTRL is left ALT" +msgstr "Gắn CTRL p&hải vào ALT trái" + +msgid "&Hard Reset..." +msgstr "Buộc khởi độn&g lại" + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "Tạm &dừng" + +msgid "E&xit..." +msgstr "Th&oát..." + +msgid "&View" +msgstr "&Xem" + +msgid "&Hide status bar" +msgstr "Ẩn tha&nh trạng thái" + +msgid "Hide &toolbar" +msgstr "Ẩn thanh &công cụ" + +msgid "&Resizeable window" +msgstr "Tùy chỉnh cỡ cử&a sổ" + +msgid "R&emember size && position" +msgstr "Ghi nhớ vị trí và kíc&h thước cửa sổ" + +msgid "Re&nderer" +msgstr "Re&nderer" + +msgid "&Qt (Software)" +msgstr "&Qt (phần mềm)" + +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (3.0 Core)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "Tự nhập độ &phân giải..." + +msgid "F&orce 4:3 display ratio" +msgstr "Giữ n&guyên khung hình 4:3" + +msgid "&Window scale factor" +msgstr "Đổi &tỷ lệ cửa sổ" + +msgid "&0.5x" +msgstr "&0.5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1.&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + +msgid "Filter method" +msgstr "&Bộ lọc hình ảnh" + +msgid "&Nearest" +msgstr "&Cực cận" + +msgid "&Linear" +msgstr "Tu&yến tính" + +msgid "Hi&DPI scaling" +msgstr "Tỷ lệ hinh ảnh phân giải cao" + +msgid "&Fullscreen\tCtrl+Alt+PgUp" +msgstr "Toàn màn &hình\tCtrl+Alt+PgUp" + +msgid "Fullscreen &stretch mode" +msgstr "&Chế độ kéo giãn hình" + +msgid "&Full screen stretch" +msgstr "Kéo giãn hình" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "Điểm ảnh vuông (giữ tỷ lệ)" + +msgid "&Integer scale" +msgstr "Căn tỷ lệ số nguyên" + +msgid "4:&3 Integer scale" +msgstr "Căn tỷ lệ 4:3 số nguyên" + +msgid "E&GA/(S)VGA settings" +msgstr "Cài đặt EGA/(S)VGA" + +msgid "&Inverted VGA monitor" +msgstr "Đảo mà&u VGA" + +msgid "VGA screen &type" +msgstr "L&oại màn VGA" + +msgid "RGB &Color" +msgstr "Màu R&GB" + +msgid "&RGB Grayscale" +msgstr "Thang xám RG&B" + +msgid "&Amber monitor" +msgstr "Màn hình vàng hổ phách (amber)" + +msgid "&Green monitor" +msgstr "Màn hình lục" + +msgid "&White monitor" +msgstr "Màn hinh trắng" + +msgid "Grayscale &conversion type" +msgstr "Chuyển đổi thang &màu xám" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Trung bình" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "&Overscan CGA/PCjr/Tandy/EGA/(S)VGA" + +msgid "Change contrast for &monochrome display" +msgstr "Chỉnh tương phản cho màn hình đơn sắc" + +msgid "&Media" +msgstr "&Phương tiện" + +msgid "&Tools" +msgstr "&Công cụ" + +msgid "&Settings..." +msgstr "&Cài đặt..." + +msgid "&Update status bar icons" +msgstr "Cậ&p nhật biểu tượng thanh trạng thái" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "Chụp &màn hình\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Tùy biến..." + +msgid "Enable &Discord integration" +msgstr "Bật trình trạng thái cho Discord" + +msgid "Sound &gain..." +msgstr "Bộ &tăng âm..." + +msgid "Begin trace\tCtrl+T" +msgstr "Bắt đầu dò\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "Ngưng dò\tCtrl+T" + +msgid "&Help" +msgstr "&Trợ giúp" + +msgid "&Documentation..." +msgstr "&Trợ giúp..." + +msgid "&About 86Box..." +msgstr "&Về 86Box..." + +msgid "&New image..." +msgstr "Tạo file ảnh đĩa mới..." + +msgid "&Existing image..." +msgstr "Ảnh đĩa có sẵn..." + +msgid "Existing image (&Write-protected)..." +msgstr "Ảnh đĩa có sẵn (chống ghi đè)..." + +msgid "&Record" +msgstr "&Ghi lại" + +msgid "&Play" +msgstr "&Phát" + +msgid "&Rewind to the beginning" +msgstr "&Tua về đầu" + +msgid "&Fast forward to the end" +msgstr "T&iến về cuối" + +msgid "E&ject" +msgstr "Đẩy đĩ&a ra" + +msgid "&Image..." +msgstr "&Ảnh đĩa..." + +msgid "E&xport to 86F..." +msgstr "Xuất ra f&ile 86F..." + +msgid "&Mute" +msgstr "Tắt tiến&g" + +msgid "E&mpty" +msgstr "Làm trố&ng đĩa" + +msgid "&Reload previous image" +msgstr "Load đĩ&a trước đó" + +msgid "&Folder..." +msgstr "Thư mụ&c" + +msgid "Target &framerate" +msgstr "Số khung hình mục tiêu" + +msgid "&Sync with video" +msgstr "Đồng bộ &với video" + +msgid "&25 fps" +msgstr "&25 fps" + +msgid "&30 fps" +msgstr "&30 fps" + +msgid "&50 fps" +msgstr "&50 fps" + +msgid "&60 fps" +msgstr "&60 fps" + +msgid "&75 fps" +msgstr "&75 fps" + +msgid "&VSync" +msgstr "&VSync" + +msgid "&Select shader..." +msgstr "&Chọn shader..." + +msgid "&Remove shader" +msgstr "&Bỏ shader" + +msgid "Preferences" +msgstr "Tùy biến" + +msgid "Sound Gain" +msgstr "Tăng âm" + +msgid "New Image" +msgstr "Ảnh đĩa mới" + +msgid "Settings" +msgstr "Cài đặt" + +msgid "Specify Main Window Dimensions" +msgstr "Tùy biến kích thước cửa sổ chính" + +msgid "OK" +msgstr "Đồng ý" + +msgid "Cancel" +msgstr "Thôi" + +msgid "Save these settings as &global defaults" +msgstr "Lưu cài đặt làm mặc định chung" + +msgid "&Default" +msgstr "&Mặc định" + +msgid "Language:" +msgstr "Ngôn ngữ:" + +msgid "Icon set:" +msgstr "Bộ biểu tượng:" + +msgid "Gain" +msgstr "Tăng" + +msgid "File name:" +msgstr "Tên tập tin:" + +msgid "Disk size:" +msgstr "Kích thước đĩa:" + +msgid "RPM mode:" +msgstr "Tốc độ vòng quay:" + +msgid "Progress:" +msgstr "Tiến trình:" + +msgid "Width:" +msgstr "Chiều rộng:" + +msgid "Height:" +msgstr "Chiều cao:" + +msgid "Lock to this size" +msgstr "Cố định kích thước hình hiện tại" + +msgid "Machine type:" +msgstr "Loại máy:" + +msgid "Machine:" +msgstr "Mẫu máy:" + +msgid "Configure" +msgstr "Tinh chỉnh" + +msgid "CPU type:" +msgstr "Loại CPU:" + +msgid "Speed:" +msgstr "Tốc độ:" + +msgid "Frequency:" +msgstr "Tần số xung:" + +msgid "FPU:" +msgstr "FPU:" + +msgid "Wait states:" +msgstr "Trạng thái chờ:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "Bộ nhớ (RAM):" + +msgid "Time synchronization" +msgstr "Đồng bộ thời gian" + +msgid "Disabled" +msgstr "Vô hiệu hóa" + +msgid "Enabled (local time)" +msgstr "Bật (giờ địa phương)" + +msgid "Enabled (UTC)" +msgstr "Bật (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Bộ tái biên dịch động (Dynamic Recompiler)" + +msgid "Video:" +msgstr "Video:" + +msgid "Voodoo Graphics" +msgstr "Voodoo đồ họa" + +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A đồ họa" + +msgid "XGA Graphics" +msgstr "XGA đồ họa" + +msgid "Mouse:" +msgstr "Chuột:" + +msgid "Joystick:" +msgstr "Cần điều khiển:" + +msgid "Joystick 1..." +msgstr "Cần điều khiển 1..." + +msgid "Joystick 2..." +msgstr "Cần điều khiển 2..." + +msgid "Joystick 3..." +msgstr "Cần điều khiển 3..." + +msgid "Joystick 4..." +msgstr "Cần điều khiển 4..." + +msgid "Sound card #1:" +msgstr "Card âm thanh 1:" + +msgid "Sound card #2:" +msgstr "Card âm thanh 2:" + +msgid "Sound card #3:" +msgstr "Card âm thanh 3:" + +msgid "Sound card #4:" +msgstr "Card âm thanh 4:" + +msgid "MIDI Out Device:" +msgstr "Thiết bị MIDI out:" + +msgid "MIDI In Device:" +msgstr "Thiết bị MIDI in:" + +msgid "Standalone MPU-401" +msgstr "MPU-401 độc lập" + +msgid "Use FLOAT32 sound" +msgstr "Dùng âm FLOAT32" + +msgid "FM synth driver" +msgstr "Driver bộ tổng hợp (synth) FM" + +msgid "Nuked (more accurate)" +msgstr "Nuked (chính xác hơn)" + +msgid "YMFM (faster)" +msgstr "YMFM (nhanh hơn)" + +msgid "Network type:" +msgstr "Kiểu loại mạng:" + +msgid "PCap device:" +msgstr "Thiết bị PCap:" + +msgid "Network adapter:" +msgstr "Bộ thích ứng (adapter) mạng:" + +msgid "COM1 Device:" +msgstr "Thiết bị COM1:" + +msgid "COM2 Device:" +msgstr "Thiết bị COM2:" + +msgid "COM3 Device:" +msgstr "Thiết bị COM3:" + +msgid "COM4 Device:" +msgstr "Thiết bị COM4:" + +msgid "LPT1 Device:" +msgstr "Thiết bị LPT1:" + +msgid "LPT2 Device:" +msgstr "Thiết bị LPT2:" + +msgid "LPT3 Device:" +msgstr "Thiết bị LPT3:" + +msgid "LPT4 Device:" +msgstr "Thiết bị LPT4:" + +msgid "Serial port 1" +msgstr "Cổng serial 1" + +msgid "Serial port 2" +msgstr "Cổng serial 2" + +msgid "Serial port 3" +msgstr "Puerto serie 3" + +msgid "Serial port 4" +msgstr "Cổng serial 4" + +msgid "Parallel port 1" +msgstr "Cổng parallel 1" + +msgid "Parallel port 2" +msgstr "Cổng parallel 2" + +msgid "Parallel port 3" +msgstr "Cổng parallel 3" + +msgid "Parallel port 4" +msgstr "Cổng parallel 4" + +msgid "HD Controller:" +msgstr "Bộ điều khiển HD:" + +msgid "FD Controller:" +msgstr "Bộ điều khiển FD:" + +msgid "Tertiary IDE Controller" +msgstr "Bộ điều khiển IDE thứ ba" + +msgid "Quaternary IDE Controller" +msgstr "Bộ điều khiển IDE thứ tư" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Bộ điều khiển 1:" + +msgid "Controller 2:" +msgstr "Bộ điều khiển 2:" + +msgid "Controller 3:" +msgstr "Bộ điều khiển 3:" + +msgid "Controller 4:" +msgstr "Bộ điều khiển 4:" + +msgid "Cassette" +msgstr "Cassette" + +msgid "Hard disks:" +msgstr "Đĩa cứng:" + +msgid "&New..." +msgstr "Tạ&o mới..." + +msgid "&Existing..." +msgstr "&Có sẵn..." + +msgid "&Remove" +msgstr "Loạ&i bỏ" + +msgid "Bus:" +msgstr "Bus:" + +msgid "Channel:" +msgstr "Kênh:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "Chỉ &rõ..." + +msgid "Sectors:" +msgstr "Sector:" + +msgid "Heads:" +msgstr "Đầu ghi:" + +msgid "Cylinders:" +msgstr "Trụ:" + +msgid "Size (MB):" +msgstr "Kích thước (MB):" + +msgid "Type:" +msgstr "Loại:" + +msgid "Image Format:" +msgstr "Định dạng ảnh đĩa:" + +msgid "Block Size:" +msgstr "Kích thước bloc:" + +msgid "Floppy drives:" +msgstr "Ổ đĩa mềm:" + +msgid "Turbo timings" +msgstr "Thời gian turbo" + +msgid "Check BPB" +msgstr "Kiểm tra BPB" + +msgid "CD-ROM drives:" +msgstr "Ổ đĩa CD-ROM:" + +msgid "MO drives:" +msgstr "Ổ đĩa MO:" + +msgid "ZIP drives:" +msgstr "Ổ đĩa ZIP:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA RTC:" + +msgid "ISA Memory Expansion" +msgstr Mở rộng bộ nhớ qua ISA" + +msgid "Card 1:" +msgstr "Thẻ 1:" + +msgid "Card 2:" +msgstr "Thẻ 2:" + +msgid "Card 3:" +msgstr "Thẻ 3:" + +msgid "Card 4:" +msgstr "Thẻ 4:" + +msgid "ISABugger device" +msgstr "Thiết bị ISABugger" + +msgid "POST card" +msgstr "Thẻ POST" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Lỗi" + +msgid "Fatal error" +msgstr "Lỗi nghiêm trọng" + +msgid " - PAUSED" +msgstr " - TẠM DỪNG" + +msgid "Press Ctrl+Alt+PgDn to return to windowed mode." +msgstr "Bấm Ctrl+Alt+PgDn để quay lại chế độ cửa sổ." + +msgid "Speed" +msgstr "Vận tốc" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "Ảnh đĩa ZIP" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Box không tìm được bản ROM nào.\n\nVui lòng tải về bộ ROM và trích xuất về thư mục \"roms\"." + +msgid "(empty)" +msgstr "(trống trơn)" + +msgid "All files" +msgstr "Tất cả file" + +msgid "Turbo" +msgstr "Turbo" + +msgid "On" +msgstr "Bật" + +msgid "Off" +msgstr "Tắt" + +msgid "All images" +msgstr "Tất cả ảnh" + +msgid "Basic sector images" +msgstr "Ảnh sector cơ bản" + +msgid "Surface images" +msgstr "Ảnh bề mặt" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "Mẫu máy \"%hs\" không giả lập được do thiếu file ROM tương ứng trong mục roms/machines. Hãy chọn mẫu máy khác." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "Card đồ họa \"%hs\" không giả lập được do thiếu file ROM tương ứng trong mục roms/video. Hãy chọn card đồ họa khác." + +msgid "Machine" +msgstr "Mẫu máy" + +msgid "Display" +msgstr "Hiển thị" + +msgid "Input devices" +msgstr "Thiết bị nhập" + +msgid "Sound" +msgstr "Thanh âm" + +msgid "Network" +msgstr "Nối mạng" + +msgid "Ports (COM & LPT)" +msgstr "Cổng (COM và LPT)" + +msgid "Storage controllers" +msgstr "Vi điều khiển bộ nhớ ổ cứng" + +msgid "Hard disks" +msgstr "Ổ cứng" + +msgid "Floppy & CD-ROM drives" +msgstr "Ổ (đĩa) mềm và CD-ROM" + +msgid "Other removable devices" +msgstr "Thiết bị tháo rời được khác" + +msgid "Other peripherals" +msgstr "Thiết bị ngoại vi khác" + +msgid "Click to capture mouse" +msgstr "Bấm để capture ('nhốt') chuột vào" + +msgid "Press %1 to release mouse" +msgstr "Nhấn %1 để thả chuột" + +msgid "Press %1 or middle button to release mouse" +msgstr "Nhấn %1 hoặc nhấp chuột giữa để thả chuột" + +msgid "Bus" +msgstr "Bus" + +msgid "File" +msgstr "File" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "Không thể khởi tạo trình kết xuất (renderer) video ." + +msgid "Default" +msgstr "Mặc định" + +msgid "%i Wait state(s)" +msgstr "%i trạng thái chờ" + +msgid "Type" +msgstr "Loại" + +msgid "No PCap devices found" +msgstr "Không tìm thấy thiết bị PCap" + +msgid "Invalid PCap device" +msgstr "Thiết bị PCap không hợp quy" + +msgid "Standard 2-button joystick(s)" +msgstr "Cần điều khiển hai nút tiêu chuẩn" + +msgid "Standard 4-button joystick" +msgstr "Cần điều khiển bốn nút tiêu chuẩn" + +msgid "Standard 6-button joystick" +msgstr "Cần điều khiển sáu nút tiêu chuẩn" + +msgid "Standard 8-button joystick" +msgstr "Cần điều khiển tám nút tiêu chuẩn" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "None" +msgstr "Không có" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Đĩa mềm %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Ảnh (đĩa) sector nâng cao" + +msgid "Flux images" +msgstr "Ảnh thông lượng (flux)" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Bạn có thật sự buộc máy khởi động lại không?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Bạn có muốn thoát 86Box?" + +msgid "Unable to initialize Ghostscript" +msgstr "Không thể khởi tạo Ghostscript" + +msgid "MO %i (%ls): %ls" +msgstr "MO %i (%ls): %ls" + +msgid "MO images" +msgstr "Ảnh đĩa MO" + +msgid "Welcome to 86Box!" +msgstr "Chào mừng đến 86Box!" + +msgid "Internal controller" +msgstr "Vi điều khiển nội bộ" + +msgid "Exit" +msgstr "Thoát" + +msgid "No ROMs found" +msgstr "Không tìm thấy ROM" + +msgid "Do you want to save the settings?" +msgstr "Bạn có muốn lưu cài đặt không?" + +msgid "This will hard reset the emulated machine." +msgstr "Lệnh này sẽ buộc khởi động lại máy ảo." + +msgid "Save" +msgstr "Lưu" + +msgid "About 86Box" +msgstr "Về 86Box" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Trình giả lập các dòng máy tính cổ.\n\nTác giả: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, y otros.\n\nCùng với những đóng góp cốt cán từ Sarah Walker, leilei, JohnElliott, greatpsycho, và một số người khác.\n\nPhát hành dưới giấy phép GNU General Public License version 2 trở đi. Đọc LICENSE để biết thêm thông tin." + +msgid "Hardware not available" +msgstr "Phần cứng không có sẵn" + +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Đảm bảo rằng %1 đã được cài đặt vào và bạn đang dùng kết nối mạng tương thích %1." + +msgid "Invalid configuration" +msgstr "Tinh chỉnh không hợp lý" + +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "Cần có %1 để tự động chuyển đổi file PostScript qua PDF.\n\nMọi tài liệu được đưa qua máy in generic PostScript sẽ lưu ở dạng PostScript (.ps)." + +msgid "Entering fullscreen mode" +msgstr "Đang tiến vào chế độ toàn màn hình" + +msgid "Don't show this message again" +msgstr "Không hiện thông báo này nữa" + +msgid "Don't exit" +msgstr "Không thoát" + +msgid "Reset" +msgstr "Khởi động lại" + +msgid "Don't reset" +msgstr "Không khởi động lại" + +msgid "CD-ROM images" +msgstr "Ảnh đĩa CD-ROM" + +msgid "%1 Device Configuration" +msgstr "Tinh chỉnh thiết bị %1" + +msgid "Monitor in sleep mode" +msgstr "Màn hình chế độ chờ/ngủ" + +msgid "OpenGL Shaders" +msgstr "Shader OpenGL" + +msgid "OpenGL options" +msgstr "Tùy chọn OpenGL" + +msgid "You are loading an unsupported configuration" +msgstr "Bạn đang load tinh chỉnh không được hỗ trợ." + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "Phần chọn loại CPU dựa trên mẫu máy đã chọn bị vô hiệu hóa.\n\nỞ đây bạn có thể chọn loại CPU có thể không tương thích với mẫu máy hiện tại. Tuy nhiên bạn có thể gặp vấn đề tương khắc với BIOS hay phần mềm khác.\n\nViệc bật tùy chọn này lên không được khuyến cáo chính thức và các bản bug report (báo lỗi) với nội dung tương tự sẽ bị closed as invalid (đóng vì phạm quy)." + +msgid "Continue" +msgstr "Tiếp tục" + +msgid "Cassette: %s" +msgstr "Cassette: %s" + +msgid "Cassette images" +msgstr "Ảnh đĩa Cassette" + +msgid "Cartridge %i: %ls" +msgstr "Băng cartridge %i: %ls" + +msgid "Cartridge images" +msgstr "Ảnh đĩa băng cartridge" + +msgid "Error initializing renderer" +msgstr "Lỗi khởi tạo renderer (trình kết xuất)" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "Không khởi tạo được renderer OpenGL (3.0 Core). Hãy dùng renderer khác." + +msgid "Resume execution" +msgstr "Tiếp tục chạy thực thi" + +msgid "Pause execution" +msgstr "Dừng chạy thực thi" + +msgid "Press Ctrl+Alt+Del" +msgstr "Nhấn Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Nhấn Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Buộc khởi động lại" + +msgid "ACPI shutdown" +msgstr "Tắt máy theo ACPI" + +msgid "Hard disk (%1)" +msgstr "Ổ cứng (%1)" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "Không hề có ổ CD-ROM MFM/RLL hay ESDI nào tồn tại" + +msgid "Custom..." +msgstr "Tùy chỉnh..." + +msgid "Custom (large)..." +msgstr "Tùy chỉnh (dung tích lớn)..." + +msgid "Add New Hard Disk" +msgstr "Thêm ổ cứng mới" + +msgid "Add Existing Hard Disk" +msgstr "Thêm ổ cứng đã có" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "Ảnh đĩa ổ HDI không to hơn 4 GB." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "Ảnh đĩa không to hơn 127 GB." + +msgid "Hard disk images" +msgstr "Ảnh đĩa ổ cứng" + +msgid "Unable to read file" +msgstr "Không đọc được file" + +msgid "Unable to write file" +msgstr "Không ghi được vào file" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "Ảnh đĩa HDI hoặc HDX với kích thước sector khác 512 không được hỗ trợ." + +msgid "Disk image file already exists" +msgstr "Đã có file ảnh đĩa rồi" + +msgid "Please specify a valid file name." +msgstr "Vui lòng đặt tên hợp lệ." + +msgid "Disk image created" +msgstr "Đã tạo ảnh đĩa" + +msgid "Make sure the file exists and is readable." +msgstr "Chắc chắn rằng file tồn tại và đọc được." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Chắc chắn rằng file được lưu ở địa chỉ thư mục có thể ghi đè." + +msgid "Disk image too large" +msgstr "Ảnh đĩa quá to" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Nhớ phân vùng và định dạng ổ đĩa mới tạo." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "File được chọn sẽ bị ghi đè lên. Bạn có chắc muốn chọn dùng không?" + +msgid "Unsupported disk image" +msgstr "File ảnh đĩa không được hỗ trợ" + +msgid "Overwrite" +msgstr "Có ghi đè" + +msgid "Don't overwrite" +msgstr "Không ghi đè" + +msgid "Raw image (.img)" +msgstr "Ảnh đĩa thô (.img)" + +msgid "HDI image (.hdi)" +msgstr "Ảnh đĩa HDI (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "Ảnh đĩa HDX (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "Ảnh VHD kích thước cố định (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "Ảnh VHD kích thước tăng dần (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "Ảnh VHD đa chủng (differencing) (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Bloc lớn (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "Bloc bé (512 KB)" + +msgid "VHD files" +msgstr "File VHD" + +msgid "Select the parent VHD" +msgstr "Chọn file VHD cha (parent)" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "Ở đây tức là ảnh đĩa cha (parent) có thể đã bị chỉnh sửa sau khi ảnh đĩa đa chủng (differencing image) được tạo ra.\n\nCũng có thể do ảnh đĩa bị chuyển đi hay bị copy, hoặc do bug/lỗi của phần mềm tạo ảnh đĩa gây ra.\n\nBạn có muốn sửa lại mốc thời gian (timestamp) không?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Mốc timestamp của đĩa con (child) và đĩa cha (parent) không trùng khớp" + +msgid "Could not fix VHD timestamp." +msgstr "Không thể sửa mốc timestamp cho VHD." + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1.2 MB" + +msgid "1.25 MB" +msgstr "1.25 MB" + +msgid "1.44 MB" +msgstr "1.44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (cluster 1024)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (cluster 2048)" + +msgid "2.88 MB" +msgstr "2.88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128 MB (ISO 10090)" +msgstr "3.5\" 128 MB (ISO 10090)" + +msgid "3.5\" 230 MB (ISO 13963)" +msgstr "3.5\" 230 MB (ISO 13963)" + +msgid "3.5\" 540 MB (ISO 15498)" +msgstr "3.5\" 540 MB (ISO 15498)" + +msgid "3.5\" 640 MB (ISO 15498)" +msgstr "3.5\" 640 MB (ISO 15498)" + +msgid "3.5\" 1.3 GB (GigaMO)" +msgstr "3.5\" 1.3 GB (GigaMO)" + +msgid "3.5\" 2.3 GB (GigaMO 2)" +msgstr "3.5\" 2.3 GB (GigaMO 2)" + +msgid "5.25\" 600 MB" +msgstr "5.25\" 600 MB" + +msgid "5.25\" 650 MB" +msgstr "5.25\" 650 MB" + +msgid "5.25\" 1 GB" +msgstr "5.25\" 1 GB" + +msgid "5.25\" 1.3 GB" +msgstr "5.25\" 1.3 GB" + +msgid "Perfect RPM" +msgstr "Số RPM(vòng quay đĩa/phút) hoàn thiện" + +msgid "1% below perfect RPM" +msgstr "1% thấp hơn số RPM hoàn thiện" + +msgid "1.5% below perfect RPM" +msgstr "1.5% thấp hơn số RPM hoàn thiện" + +msgid "2% below perfect RPM" +msgstr "2% thấp hơn số RPM hoàn thiện" + +msgid "(System Default)" +msgstr "(Mặc định hệ thống)" + +msgid "Failed to initialize network driver" +msgstr "Không thể khởi tạo trình điều khiển (driver) mạng" + +msgid "The network configuration will be switched to the null driver" +msgstr "Cấu hình mạng sẽ chuyển sang null driver (không có mạng)" + +msgid "Mouse sensitivity:" +msgstr "Độ nhạy chuột:" + +msgid "Select media images from program working directory" +msgstr "Chọn ảnh đĩa phương tiện từ thư mục làm việc của chương trình" + +msgid "PIT mode:" +msgstr "Chế độ PIT:" + +msgid "Auto" +msgstr "Tự động" + +msgid "Slow" +msgstr "Chậm" + +msgid "Fast" +msgstr "Nhanh" + +msgid "&Auto-pause on focus loss" +msgstr "&Tự tạm dừng giả lập khi không tập trung ở cửa sổ" + +msgid "WinBox is no longer supported" +msgstr "WinBox không còn được hỗ trợ" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Trình quản lý phiên WinBox đã bị dừng phát triển năm 2022 do thiếu nhân sự duy trì. Vì những quyết định để cho 86Box trở nên tốt hơn, chúng tôi đã không còn hỗ trợ trình quản lý WinBox.\n\n Sẽ không có bản cập nhật mới cho WinBox nữa, và nếu bạn tiếp tục sử dụng với các bản 86Box mới hơn có thể gặp lỗi. Bất kì các bản bug report liên quan đến lỗi của WinBox sẽ bị coi là không hợp lệ và bị đóng.\n\nTruy cập 86Box.net để tìm qua các trình quản lý phiên/manager khác cho phù hợp." From b4174e07f05b69d5cabbe593daf7d398e4e1e552 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 3 May 2024 01:39:09 +0500 Subject: [PATCH 883/936] Fix up the vi-VN translation --- src/qt/languages/vi-VN.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/languages/vi-VN.po b/src/qt/languages/vi-VN.po index ed483dec2..6c4f772de 100644 --- a/src/qt/languages/vi-VN.po +++ b/src/qt/languages/vi-VN.po @@ -490,7 +490,7 @@ msgid "Serial port 2" msgstr "Cổng serial 2" msgid "Serial port 3" -msgstr "Puerto serie 3" +msgstr "Cổng serial 3" msgid "Serial port 4" msgstr "Cổng serial 4" @@ -607,7 +607,7 @@ msgid "ISA RTC:" msgstr "ISA RTC:" msgid "ISA Memory Expansion" -msgstr Mở rộng bộ nhớ qua ISA" +msgstr "Mở rộng bộ nhớ qua ISA" msgid "Card 1:" msgstr "Thẻ 1:" From eca80d375ab2df065a305c5e56e9c1754003b482 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 3 May 2024 01:39:35 +0500 Subject: [PATCH 884/936] Convert the new translation file to LF line endings --- src/qt/languages/vi-VN.po | 2348 ++++++++++++++++++------------------- 1 file changed, 1174 insertions(+), 1174 deletions(-) diff --git a/src/qt/languages/vi-VN.po b/src/qt/languages/vi-VN.po index 6c4f772de..9f5421ee9 100644 --- a/src/qt/languages/vi-VN.po +++ b/src/qt/languages/vi-VN.po @@ -1,1174 +1,1174 @@ -msgid "" -msgstr "" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Language: vi_VN\n" -"X-Source-Language: en_US\n" - -msgid "&Action" -msgstr "&Thực hiện" - -msgid "&Keyboard requires capture" -msgstr "Bàn phím &hoạt động cần capture chuột" - -msgid "&Right CTRL is left ALT" -msgstr "Gắn CTRL p&hải vào ALT trái" - -msgid "&Hard Reset..." -msgstr "Buộc khởi độn&g lại" - -msgid "&Ctrl+Alt+Del\tCtrl+F12" -msgstr "&Ctrl+Alt+Del\tCtrl+F12" - -msgid "Ctrl+Alt+&Esc" -msgstr "Ctrl+Alt+&Esc" - -msgid "&Pause" -msgstr "Tạm &dừng" - -msgid "E&xit..." -msgstr "Th&oát..." - -msgid "&View" -msgstr "&Xem" - -msgid "&Hide status bar" -msgstr "Ẩn tha&nh trạng thái" - -msgid "Hide &toolbar" -msgstr "Ẩn thanh &công cụ" - -msgid "&Resizeable window" -msgstr "Tùy chỉnh cỡ cử&a sổ" - -msgid "R&emember size && position" -msgstr "Ghi nhớ vị trí và kíc&h thước cửa sổ" - -msgid "Re&nderer" -msgstr "Re&nderer" - -msgid "&Qt (Software)" -msgstr "&Qt (phần mềm)" - -msgid "Qt (&OpenGL)" -msgstr "Qt (&OpenGL)" - -msgid "Open&GL (3.0 Core)" -msgstr "Open&GL (3.0 Core)" - -msgid "&VNC" -msgstr "&VNC" - -msgid "Specify dimensions..." -msgstr "Tự nhập độ &phân giải..." - -msgid "F&orce 4:3 display ratio" -msgstr "Giữ n&guyên khung hình 4:3" - -msgid "&Window scale factor" -msgstr "Đổi &tỷ lệ cửa sổ" - -msgid "&0.5x" -msgstr "&0.5x" - -msgid "&1x" -msgstr "&1x" - -msgid "1.&5x" -msgstr "1.&5x" - -msgid "&2x" -msgstr "&2x" - -msgid "&3x" -msgstr "&3x" - -msgid "&4x" -msgstr "&4x" - -msgid "&5x" -msgstr "&5x" - -msgid "&6x" -msgstr "&6x" - -msgid "&7x" -msgstr "&7x" - -msgid "&8x" -msgstr "&8x" - -msgid "Filter method" -msgstr "&Bộ lọc hình ảnh" - -msgid "&Nearest" -msgstr "&Cực cận" - -msgid "&Linear" -msgstr "Tu&yến tính" - -msgid "Hi&DPI scaling" -msgstr "Tỷ lệ hinh ảnh phân giải cao" - -msgid "&Fullscreen\tCtrl+Alt+PgUp" -msgstr "Toàn màn &hình\tCtrl+Alt+PgUp" - -msgid "Fullscreen &stretch mode" -msgstr "&Chế độ kéo giãn hình" - -msgid "&Full screen stretch" -msgstr "Kéo giãn hình" - -msgid "&4:3" -msgstr "&4:3" - -msgid "&Square pixels (Keep ratio)" -msgstr "Điểm ảnh vuông (giữ tỷ lệ)" - -msgid "&Integer scale" -msgstr "Căn tỷ lệ số nguyên" - -msgid "4:&3 Integer scale" -msgstr "Căn tỷ lệ 4:3 số nguyên" - -msgid "E&GA/(S)VGA settings" -msgstr "Cài đặt EGA/(S)VGA" - -msgid "&Inverted VGA monitor" -msgstr "Đảo mà&u VGA" - -msgid "VGA screen &type" -msgstr "L&oại màn VGA" - -msgid "RGB &Color" -msgstr "Màu R&GB" - -msgid "&RGB Grayscale" -msgstr "Thang xám RG&B" - -msgid "&Amber monitor" -msgstr "Màn hình vàng hổ phách (amber)" - -msgid "&Green monitor" -msgstr "Màn hình lục" - -msgid "&White monitor" -msgstr "Màn hinh trắng" - -msgid "Grayscale &conversion type" -msgstr "Chuyển đổi thang &màu xám" - -msgid "BT&601 (NTSC/PAL)" -msgstr "BT&601 (NTSC/PAL)" - -msgid "BT&709 (HDTV)" -msgstr "BT&709 (HDTV)" - -msgid "&Average" -msgstr "&Trung bình" - -msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" -msgstr "&Overscan CGA/PCjr/Tandy/EGA/(S)VGA" - -msgid "Change contrast for &monochrome display" -msgstr "Chỉnh tương phản cho màn hình đơn sắc" - -msgid "&Media" -msgstr "&Phương tiện" - -msgid "&Tools" -msgstr "&Công cụ" - -msgid "&Settings..." -msgstr "&Cài đặt..." - -msgid "&Update status bar icons" -msgstr "Cậ&p nhật biểu tượng thanh trạng thái" - -msgid "Take s&creenshot\tCtrl+F11" -msgstr "Chụp &màn hình\tCtrl+F11" - -msgid "&Preferences..." -msgstr "&Tùy biến..." - -msgid "Enable &Discord integration" -msgstr "Bật trình trạng thái cho Discord" - -msgid "Sound &gain..." -msgstr "Bộ &tăng âm..." - -msgid "Begin trace\tCtrl+T" -msgstr "Bắt đầu dò\tCtrl+T" - -msgid "End trace\tCtrl+T" -msgstr "Ngưng dò\tCtrl+T" - -msgid "&Help" -msgstr "&Trợ giúp" - -msgid "&Documentation..." -msgstr "&Trợ giúp..." - -msgid "&About 86Box..." -msgstr "&Về 86Box..." - -msgid "&New image..." -msgstr "Tạo file ảnh đĩa mới..." - -msgid "&Existing image..." -msgstr "Ảnh đĩa có sẵn..." - -msgid "Existing image (&Write-protected)..." -msgstr "Ảnh đĩa có sẵn (chống ghi đè)..." - -msgid "&Record" -msgstr "&Ghi lại" - -msgid "&Play" -msgstr "&Phát" - -msgid "&Rewind to the beginning" -msgstr "&Tua về đầu" - -msgid "&Fast forward to the end" -msgstr "T&iến về cuối" - -msgid "E&ject" -msgstr "Đẩy đĩ&a ra" - -msgid "&Image..." -msgstr "&Ảnh đĩa..." - -msgid "E&xport to 86F..." -msgstr "Xuất ra f&ile 86F..." - -msgid "&Mute" -msgstr "Tắt tiến&g" - -msgid "E&mpty" -msgstr "Làm trố&ng đĩa" - -msgid "&Reload previous image" -msgstr "Load đĩ&a trước đó" - -msgid "&Folder..." -msgstr "Thư mụ&c" - -msgid "Target &framerate" -msgstr "Số khung hình mục tiêu" - -msgid "&Sync with video" -msgstr "Đồng bộ &với video" - -msgid "&25 fps" -msgstr "&25 fps" - -msgid "&30 fps" -msgstr "&30 fps" - -msgid "&50 fps" -msgstr "&50 fps" - -msgid "&60 fps" -msgstr "&60 fps" - -msgid "&75 fps" -msgstr "&75 fps" - -msgid "&VSync" -msgstr "&VSync" - -msgid "&Select shader..." -msgstr "&Chọn shader..." - -msgid "&Remove shader" -msgstr "&Bỏ shader" - -msgid "Preferences" -msgstr "Tùy biến" - -msgid "Sound Gain" -msgstr "Tăng âm" - -msgid "New Image" -msgstr "Ảnh đĩa mới" - -msgid "Settings" -msgstr "Cài đặt" - -msgid "Specify Main Window Dimensions" -msgstr "Tùy biến kích thước cửa sổ chính" - -msgid "OK" -msgstr "Đồng ý" - -msgid "Cancel" -msgstr "Thôi" - -msgid "Save these settings as &global defaults" -msgstr "Lưu cài đặt làm mặc định chung" - -msgid "&Default" -msgstr "&Mặc định" - -msgid "Language:" -msgstr "Ngôn ngữ:" - -msgid "Icon set:" -msgstr "Bộ biểu tượng:" - -msgid "Gain" -msgstr "Tăng" - -msgid "File name:" -msgstr "Tên tập tin:" - -msgid "Disk size:" -msgstr "Kích thước đĩa:" - -msgid "RPM mode:" -msgstr "Tốc độ vòng quay:" - -msgid "Progress:" -msgstr "Tiến trình:" - -msgid "Width:" -msgstr "Chiều rộng:" - -msgid "Height:" -msgstr "Chiều cao:" - -msgid "Lock to this size" -msgstr "Cố định kích thước hình hiện tại" - -msgid "Machine type:" -msgstr "Loại máy:" - -msgid "Machine:" -msgstr "Mẫu máy:" - -msgid "Configure" -msgstr "Tinh chỉnh" - -msgid "CPU type:" -msgstr "Loại CPU:" - -msgid "Speed:" -msgstr "Tốc độ:" - -msgid "Frequency:" -msgstr "Tần số xung:" - -msgid "FPU:" -msgstr "FPU:" - -msgid "Wait states:" -msgstr "Trạng thái chờ:" - -msgid "MB" -msgstr "MB" - -msgid "Memory:" -msgstr "Bộ nhớ (RAM):" - -msgid "Time synchronization" -msgstr "Đồng bộ thời gian" - -msgid "Disabled" -msgstr "Vô hiệu hóa" - -msgid "Enabled (local time)" -msgstr "Bật (giờ địa phương)" - -msgid "Enabled (UTC)" -msgstr "Bật (UTC)" - -msgid "Dynamic Recompiler" -msgstr "Bộ tái biên dịch động (Dynamic Recompiler)" - -msgid "Video:" -msgstr "Video:" - -msgid "Voodoo Graphics" -msgstr "Voodoo đồ họa" - -msgid "IBM 8514/A Graphics" -msgstr "IBM 8514/A đồ họa" - -msgid "XGA Graphics" -msgstr "XGA đồ họa" - -msgid "Mouse:" -msgstr "Chuột:" - -msgid "Joystick:" -msgstr "Cần điều khiển:" - -msgid "Joystick 1..." -msgstr "Cần điều khiển 1..." - -msgid "Joystick 2..." -msgstr "Cần điều khiển 2..." - -msgid "Joystick 3..." -msgstr "Cần điều khiển 3..." - -msgid "Joystick 4..." -msgstr "Cần điều khiển 4..." - -msgid "Sound card #1:" -msgstr "Card âm thanh 1:" - -msgid "Sound card #2:" -msgstr "Card âm thanh 2:" - -msgid "Sound card #3:" -msgstr "Card âm thanh 3:" - -msgid "Sound card #4:" -msgstr "Card âm thanh 4:" - -msgid "MIDI Out Device:" -msgstr "Thiết bị MIDI out:" - -msgid "MIDI In Device:" -msgstr "Thiết bị MIDI in:" - -msgid "Standalone MPU-401" -msgstr "MPU-401 độc lập" - -msgid "Use FLOAT32 sound" -msgstr "Dùng âm FLOAT32" - -msgid "FM synth driver" -msgstr "Driver bộ tổng hợp (synth) FM" - -msgid "Nuked (more accurate)" -msgstr "Nuked (chính xác hơn)" - -msgid "YMFM (faster)" -msgstr "YMFM (nhanh hơn)" - -msgid "Network type:" -msgstr "Kiểu loại mạng:" - -msgid "PCap device:" -msgstr "Thiết bị PCap:" - -msgid "Network adapter:" -msgstr "Bộ thích ứng (adapter) mạng:" - -msgid "COM1 Device:" -msgstr "Thiết bị COM1:" - -msgid "COM2 Device:" -msgstr "Thiết bị COM2:" - -msgid "COM3 Device:" -msgstr "Thiết bị COM3:" - -msgid "COM4 Device:" -msgstr "Thiết bị COM4:" - -msgid "LPT1 Device:" -msgstr "Thiết bị LPT1:" - -msgid "LPT2 Device:" -msgstr "Thiết bị LPT2:" - -msgid "LPT3 Device:" -msgstr "Thiết bị LPT3:" - -msgid "LPT4 Device:" -msgstr "Thiết bị LPT4:" - -msgid "Serial port 1" -msgstr "Cổng serial 1" - -msgid "Serial port 2" -msgstr "Cổng serial 2" - -msgid "Serial port 3" -msgstr "Cổng serial 3" - -msgid "Serial port 4" -msgstr "Cổng serial 4" - -msgid "Parallel port 1" -msgstr "Cổng parallel 1" - -msgid "Parallel port 2" -msgstr "Cổng parallel 2" - -msgid "Parallel port 3" -msgstr "Cổng parallel 3" - -msgid "Parallel port 4" -msgstr "Cổng parallel 4" - -msgid "HD Controller:" -msgstr "Bộ điều khiển HD:" - -msgid "FD Controller:" -msgstr "Bộ điều khiển FD:" - -msgid "Tertiary IDE Controller" -msgstr "Bộ điều khiển IDE thứ ba" - -msgid "Quaternary IDE Controller" -msgstr "Bộ điều khiển IDE thứ tư" - -msgid "SCSI" -msgstr "SCSI" - -msgid "Controller 1:" -msgstr "Bộ điều khiển 1:" - -msgid "Controller 2:" -msgstr "Bộ điều khiển 2:" - -msgid "Controller 3:" -msgstr "Bộ điều khiển 3:" - -msgid "Controller 4:" -msgstr "Bộ điều khiển 4:" - -msgid "Cassette" -msgstr "Cassette" - -msgid "Hard disks:" -msgstr "Đĩa cứng:" - -msgid "&New..." -msgstr "Tạ&o mới..." - -msgid "&Existing..." -msgstr "&Có sẵn..." - -msgid "&Remove" -msgstr "Loạ&i bỏ" - -msgid "Bus:" -msgstr "Bus:" - -msgid "Channel:" -msgstr "Kênh:" - -msgid "ID:" -msgstr "ID:" - -msgid "&Specify..." -msgstr "Chỉ &rõ..." - -msgid "Sectors:" -msgstr "Sector:" - -msgid "Heads:" -msgstr "Đầu ghi:" - -msgid "Cylinders:" -msgstr "Trụ:" - -msgid "Size (MB):" -msgstr "Kích thước (MB):" - -msgid "Type:" -msgstr "Loại:" - -msgid "Image Format:" -msgstr "Định dạng ảnh đĩa:" - -msgid "Block Size:" -msgstr "Kích thước bloc:" - -msgid "Floppy drives:" -msgstr "Ổ đĩa mềm:" - -msgid "Turbo timings" -msgstr "Thời gian turbo" - -msgid "Check BPB" -msgstr "Kiểm tra BPB" - -msgid "CD-ROM drives:" -msgstr "Ổ đĩa CD-ROM:" - -msgid "MO drives:" -msgstr "Ổ đĩa MO:" - -msgid "ZIP drives:" -msgstr "Ổ đĩa ZIP:" - -msgid "ZIP 250" -msgstr "ZIP 250" - -msgid "ISA RTC:" -msgstr "ISA RTC:" - -msgid "ISA Memory Expansion" -msgstr "Mở rộng bộ nhớ qua ISA" - -msgid "Card 1:" -msgstr "Thẻ 1:" - -msgid "Card 2:" -msgstr "Thẻ 2:" - -msgid "Card 3:" -msgstr "Thẻ 3:" - -msgid "Card 4:" -msgstr "Thẻ 4:" - -msgid "ISABugger device" -msgstr "Thiết bị ISABugger" - -msgid "POST card" -msgstr "Thẻ POST" - -msgid "86Box" -msgstr "86Box" - -msgid "Error" -msgstr "Lỗi" - -msgid "Fatal error" -msgstr "Lỗi nghiêm trọng" - -msgid " - PAUSED" -msgstr " - TẠM DỪNG" - -msgid "Press Ctrl+Alt+PgDn to return to windowed mode." -msgstr "Bấm Ctrl+Alt+PgDn để quay lại chế độ cửa sổ." - -msgid "Speed" -msgstr "Vận tốc" - -msgid "ZIP %03i %i (%s): %ls" -msgstr "ZIP %03i %i (%s): %ls" - -msgid "ZIP images" -msgstr "Ảnh đĩa ZIP" - -msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." -msgstr "86Box không tìm được bản ROM nào.\n\nVui lòng tải về bộ ROM và trích xuất về thư mục \"roms\"." - -msgid "(empty)" -msgstr "(trống trơn)" - -msgid "All files" -msgstr "Tất cả file" - -msgid "Turbo" -msgstr "Turbo" - -msgid "On" -msgstr "Bật" - -msgid "Off" -msgstr "Tắt" - -msgid "All images" -msgstr "Tất cả ảnh" - -msgid "Basic sector images" -msgstr "Ảnh sector cơ bản" - -msgid "Surface images" -msgstr "Ảnh bề mặt" - -msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." -msgstr "Mẫu máy \"%hs\" không giả lập được do thiếu file ROM tương ứng trong mục roms/machines. Hãy chọn mẫu máy khác." - -msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." -msgstr "Card đồ họa \"%hs\" không giả lập được do thiếu file ROM tương ứng trong mục roms/video. Hãy chọn card đồ họa khác." - -msgid "Machine" -msgstr "Mẫu máy" - -msgid "Display" -msgstr "Hiển thị" - -msgid "Input devices" -msgstr "Thiết bị nhập" - -msgid "Sound" -msgstr "Thanh âm" - -msgid "Network" -msgstr "Nối mạng" - -msgid "Ports (COM & LPT)" -msgstr "Cổng (COM và LPT)" - -msgid "Storage controllers" -msgstr "Vi điều khiển bộ nhớ ổ cứng" - -msgid "Hard disks" -msgstr "Ổ cứng" - -msgid "Floppy & CD-ROM drives" -msgstr "Ổ (đĩa) mềm và CD-ROM" - -msgid "Other removable devices" -msgstr "Thiết bị tháo rời được khác" - -msgid "Other peripherals" -msgstr "Thiết bị ngoại vi khác" - -msgid "Click to capture mouse" -msgstr "Bấm để capture ('nhốt') chuột vào" - -msgid "Press %1 to release mouse" -msgstr "Nhấn %1 để thả chuột" - -msgid "Press %1 or middle button to release mouse" -msgstr "Nhấn %1 hoặc nhấp chuột giữa để thả chuột" - -msgid "Bus" -msgstr "Bus" - -msgid "File" -msgstr "File" - -msgid "C" -msgstr "C" - -msgid "H" -msgstr "H" - -msgid "S" -msgstr "S" - -msgid "KB" -msgstr "KB" - -msgid "Could not initialize the video renderer." -msgstr "Không thể khởi tạo trình kết xuất (renderer) video ." - -msgid "Default" -msgstr "Mặc định" - -msgid "%i Wait state(s)" -msgstr "%i trạng thái chờ" - -msgid "Type" -msgstr "Loại" - -msgid "No PCap devices found" -msgstr "Không tìm thấy thiết bị PCap" - -msgid "Invalid PCap device" -msgstr "Thiết bị PCap không hợp quy" - -msgid "Standard 2-button joystick(s)" -msgstr "Cần điều khiển hai nút tiêu chuẩn" - -msgid "Standard 4-button joystick" -msgstr "Cần điều khiển bốn nút tiêu chuẩn" - -msgid "Standard 6-button joystick" -msgstr "Cần điều khiển sáu nút tiêu chuẩn" - -msgid "Standard 8-button joystick" -msgstr "Cần điều khiển tám nút tiêu chuẩn" - -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" - -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" - -msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control System" - -msgid "None" -msgstr "Không có" - -msgid "%u MB (CHS: %i, %i, %i)" -msgstr "%u MB (CHS: %i, %i, %i)" - -msgid "Floppy %i (%s): %ls" -msgstr "Đĩa mềm %i (%s): %ls" - -msgid "Advanced sector images" -msgstr "Ảnh (đĩa) sector nâng cao" - -msgid "Flux images" -msgstr "Ảnh thông lượng (flux)" - -msgid "Are you sure you want to hard reset the emulated machine?" -msgstr "Bạn có thật sự buộc máy khởi động lại không?" - -msgid "Are you sure you want to exit 86Box?" -msgstr "Bạn có muốn thoát 86Box?" - -msgid "Unable to initialize Ghostscript" -msgstr "Không thể khởi tạo Ghostscript" - -msgid "MO %i (%ls): %ls" -msgstr "MO %i (%ls): %ls" - -msgid "MO images" -msgstr "Ảnh đĩa MO" - -msgid "Welcome to 86Box!" -msgstr "Chào mừng đến 86Box!" - -msgid "Internal controller" -msgstr "Vi điều khiển nội bộ" - -msgid "Exit" -msgstr "Thoát" - -msgid "No ROMs found" -msgstr "Không tìm thấy ROM" - -msgid "Do you want to save the settings?" -msgstr "Bạn có muốn lưu cài đặt không?" - -msgid "This will hard reset the emulated machine." -msgstr "Lệnh này sẽ buộc khởi động lại máy ảo." - -msgid "Save" -msgstr "Lưu" - -msgid "About 86Box" -msgstr "Về 86Box" - -msgid "86Box v" -msgstr "86Box v" - -msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "Trình giả lập các dòng máy tính cổ.\n\nTác giả: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, y otros.\n\nCùng với những đóng góp cốt cán từ Sarah Walker, leilei, JohnElliott, greatpsycho, và một số người khác.\n\nPhát hành dưới giấy phép GNU General Public License version 2 trở đi. Đọc LICENSE để biết thêm thông tin." - -msgid "Hardware not available" -msgstr "Phần cứng không có sẵn" - -msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." -msgstr "Đảm bảo rằng %1 đã được cài đặt vào và bạn đang dùng kết nối mạng tương thích %1." - -msgid "Invalid configuration" -msgstr "Tinh chỉnh không hợp lý" - -msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr "Cần có %1 để tự động chuyển đổi file PostScript qua PDF.\n\nMọi tài liệu được đưa qua máy in generic PostScript sẽ lưu ở dạng PostScript (.ps)." - -msgid "Entering fullscreen mode" -msgstr "Đang tiến vào chế độ toàn màn hình" - -msgid "Don't show this message again" -msgstr "Không hiện thông báo này nữa" - -msgid "Don't exit" -msgstr "Không thoát" - -msgid "Reset" -msgstr "Khởi động lại" - -msgid "Don't reset" -msgstr "Không khởi động lại" - -msgid "CD-ROM images" -msgstr "Ảnh đĩa CD-ROM" - -msgid "%1 Device Configuration" -msgstr "Tinh chỉnh thiết bị %1" - -msgid "Monitor in sleep mode" -msgstr "Màn hình chế độ chờ/ngủ" - -msgid "OpenGL Shaders" -msgstr "Shader OpenGL" - -msgid "OpenGL options" -msgstr "Tùy chọn OpenGL" - -msgid "You are loading an unsupported configuration" -msgstr "Bạn đang load tinh chỉnh không được hỗ trợ." - -msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." -msgstr "Phần chọn loại CPU dựa trên mẫu máy đã chọn bị vô hiệu hóa.\n\nỞ đây bạn có thể chọn loại CPU có thể không tương thích với mẫu máy hiện tại. Tuy nhiên bạn có thể gặp vấn đề tương khắc với BIOS hay phần mềm khác.\n\nViệc bật tùy chọn này lên không được khuyến cáo chính thức và các bản bug report (báo lỗi) với nội dung tương tự sẽ bị closed as invalid (đóng vì phạm quy)." - -msgid "Continue" -msgstr "Tiếp tục" - -msgid "Cassette: %s" -msgstr "Cassette: %s" - -msgid "Cassette images" -msgstr "Ảnh đĩa Cassette" - -msgid "Cartridge %i: %ls" -msgstr "Băng cartridge %i: %ls" - -msgid "Cartridge images" -msgstr "Ảnh đĩa băng cartridge" - -msgid "Error initializing renderer" -msgstr "Lỗi khởi tạo renderer (trình kết xuất)" - -msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "Không khởi tạo được renderer OpenGL (3.0 Core). Hãy dùng renderer khác." - -msgid "Resume execution" -msgstr "Tiếp tục chạy thực thi" - -msgid "Pause execution" -msgstr "Dừng chạy thực thi" - -msgid "Press Ctrl+Alt+Del" -msgstr "Nhấn Ctrl+Alt+Del" - -msgid "Press Ctrl+Alt+Esc" -msgstr "Nhấn Ctrl+Alt+Esc" - -msgid "Hard reset" -msgstr "Buộc khởi động lại" - -msgid "ACPI shutdown" -msgstr "Tắt máy theo ACPI" - -msgid "Hard disk (%1)" -msgstr "Ổ cứng (%1)" - -msgid "MFM/RLL or ESDI CD-ROM drives never existed" -msgstr "Không hề có ổ CD-ROM MFM/RLL hay ESDI nào tồn tại" - -msgid "Custom..." -msgstr "Tùy chỉnh..." - -msgid "Custom (large)..." -msgstr "Tùy chỉnh (dung tích lớn)..." - -msgid "Add New Hard Disk" -msgstr "Thêm ổ cứng mới" - -msgid "Add Existing Hard Disk" -msgstr "Thêm ổ cứng đã có" - -msgid "HDI disk images cannot be larger than 4 GB." -msgstr "Ảnh đĩa ổ HDI không to hơn 4 GB." - -msgid "Disk images cannot be larger than 127 GB." -msgstr "Ảnh đĩa không to hơn 127 GB." - -msgid "Hard disk images" -msgstr "Ảnh đĩa ổ cứng" - -msgid "Unable to read file" -msgstr "Không đọc được file" - -msgid "Unable to write file" -msgstr "Không ghi được vào file" - -msgid "HDI or HDX images with a sector size other than 512 are not supported." -msgstr "Ảnh đĩa HDI hoặc HDX với kích thước sector khác 512 không được hỗ trợ." - -msgid "Disk image file already exists" -msgstr "Đã có file ảnh đĩa rồi" - -msgid "Please specify a valid file name." -msgstr "Vui lòng đặt tên hợp lệ." - -msgid "Disk image created" -msgstr "Đã tạo ảnh đĩa" - -msgid "Make sure the file exists and is readable." -msgstr "Chắc chắn rằng file tồn tại và đọc được." - -msgid "Make sure the file is being saved to a writable directory." -msgstr "Chắc chắn rằng file được lưu ở địa chỉ thư mục có thể ghi đè." - -msgid "Disk image too large" -msgstr "Ảnh đĩa quá to" - -msgid "Remember to partition and format the newly-created drive." -msgstr "Nhớ phân vùng và định dạng ổ đĩa mới tạo." - -msgid "The selected file will be overwritten. Are you sure you want to use it?" -msgstr "File được chọn sẽ bị ghi đè lên. Bạn có chắc muốn chọn dùng không?" - -msgid "Unsupported disk image" -msgstr "File ảnh đĩa không được hỗ trợ" - -msgid "Overwrite" -msgstr "Có ghi đè" - -msgid "Don't overwrite" -msgstr "Không ghi đè" - -msgid "Raw image (.img)" -msgstr "Ảnh đĩa thô (.img)" - -msgid "HDI image (.hdi)" -msgstr "Ảnh đĩa HDI (.hdi)" - -msgid "HDX image (.hdx)" -msgstr "Ảnh đĩa HDX (.hdx)" - -msgid "Fixed-size VHD (.vhd)" -msgstr "Ảnh VHD kích thước cố định (.vhd)" - -msgid "Dynamic-size VHD (.vhd)" -msgstr "Ảnh VHD kích thước tăng dần (.vhd)" - -msgid "Differencing VHD (.vhd)" -msgstr "Ảnh VHD đa chủng (differencing) (.vhd)" - -msgid "Large blocks (2 MB)" -msgstr "Bloc lớn (2 MB)" - -msgid "Small blocks (512 KB)" -msgstr "Bloc bé (512 KB)" - -msgid "VHD files" -msgstr "File VHD" - -msgid "Select the parent VHD" -msgstr "Chọn file VHD cha (parent)" - -msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" -msgstr "Ở đây tức là ảnh đĩa cha (parent) có thể đã bị chỉnh sửa sau khi ảnh đĩa đa chủng (differencing image) được tạo ra.\n\nCũng có thể do ảnh đĩa bị chuyển đi hay bị copy, hoặc do bug/lỗi của phần mềm tạo ảnh đĩa gây ra.\n\nBạn có muốn sửa lại mốc thời gian (timestamp) không?" - -msgid "Parent and child disk timestamps do not match" -msgstr "Mốc timestamp của đĩa con (child) và đĩa cha (parent) không trùng khớp" - -msgid "Could not fix VHD timestamp." -msgstr "Không thể sửa mốc timestamp cho VHD." - -msgid "MFM/RLL" -msgstr "MFM/RLL" - -msgid "XTA" -msgstr "XTA" - -msgid "ESDI" -msgstr "ESDI" - -msgid "IDE" -msgstr "IDE" - -msgid "ATAPI" -msgstr "ATAPI" - -msgid "CD-ROM %i (%s): %s" -msgstr "CD-ROM %i (%s): %s" - -msgid "160 kB" -msgstr "160 kB" - -msgid "180 kB" -msgstr "180 kB" - -msgid "320 kB" -msgstr "320 kB" - -msgid "360 kB" -msgstr "360 kB" - -msgid "640 kB" -msgstr "640 kB" - -msgid "720 kB" -msgstr "720 kB" - -msgid "1.2 MB" -msgstr "1.2 MB" - -msgid "1.25 MB" -msgstr "1.25 MB" - -msgid "1.44 MB" -msgstr "1.44 MB" - -msgid "DMF (cluster 1024)" -msgstr "DMF (cluster 1024)" - -msgid "DMF (cluster 2048)" -msgstr "DMF (cluster 2048)" - -msgid "2.88 MB" -msgstr "2.88 MB" - -msgid "ZIP 100" -msgstr "ZIP 100" - -msgid "3.5\" 128 MB (ISO 10090)" -msgstr "3.5\" 128 MB (ISO 10090)" - -msgid "3.5\" 230 MB (ISO 13963)" -msgstr "3.5\" 230 MB (ISO 13963)" - -msgid "3.5\" 540 MB (ISO 15498)" -msgstr "3.5\" 540 MB (ISO 15498)" - -msgid "3.5\" 640 MB (ISO 15498)" -msgstr "3.5\" 640 MB (ISO 15498)" - -msgid "3.5\" 1.3 GB (GigaMO)" -msgstr "3.5\" 1.3 GB (GigaMO)" - -msgid "3.5\" 2.3 GB (GigaMO 2)" -msgstr "3.5\" 2.3 GB (GigaMO 2)" - -msgid "5.25\" 600 MB" -msgstr "5.25\" 600 MB" - -msgid "5.25\" 650 MB" -msgstr "5.25\" 650 MB" - -msgid "5.25\" 1 GB" -msgstr "5.25\" 1 GB" - -msgid "5.25\" 1.3 GB" -msgstr "5.25\" 1.3 GB" - -msgid "Perfect RPM" -msgstr "Số RPM(vòng quay đĩa/phút) hoàn thiện" - -msgid "1% below perfect RPM" -msgstr "1% thấp hơn số RPM hoàn thiện" - -msgid "1.5% below perfect RPM" -msgstr "1.5% thấp hơn số RPM hoàn thiện" - -msgid "2% below perfect RPM" -msgstr "2% thấp hơn số RPM hoàn thiện" - -msgid "(System Default)" -msgstr "(Mặc định hệ thống)" - -msgid "Failed to initialize network driver" -msgstr "Không thể khởi tạo trình điều khiển (driver) mạng" - -msgid "The network configuration will be switched to the null driver" -msgstr "Cấu hình mạng sẽ chuyển sang null driver (không có mạng)" - -msgid "Mouse sensitivity:" -msgstr "Độ nhạy chuột:" - -msgid "Select media images from program working directory" -msgstr "Chọn ảnh đĩa phương tiện từ thư mục làm việc của chương trình" - -msgid "PIT mode:" -msgstr "Chế độ PIT:" - -msgid "Auto" -msgstr "Tự động" - -msgid "Slow" -msgstr "Chậm" - -msgid "Fast" -msgstr "Nhanh" - -msgid "&Auto-pause on focus loss" -msgstr "&Tự tạm dừng giả lập khi không tập trung ở cửa sổ" - -msgid "WinBox is no longer supported" -msgstr "WinBox không còn được hỗ trợ" - -msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." -msgstr "Trình quản lý phiên WinBox đã bị dừng phát triển năm 2022 do thiếu nhân sự duy trì. Vì những quyết định để cho 86Box trở nên tốt hơn, chúng tôi đã không còn hỗ trợ trình quản lý WinBox.\n\n Sẽ không có bản cập nhật mới cho WinBox nữa, và nếu bạn tiếp tục sử dụng với các bản 86Box mới hơn có thể gặp lỗi. Bất kì các bản bug report liên quan đến lỗi của WinBox sẽ bị coi là không hợp lệ và bị đóng.\n\nTruy cập 86Box.net để tìm qua các trình quản lý phiên/manager khác cho phù hợp." +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: vi_VN\n" +"X-Source-Language: en_US\n" + +msgid "&Action" +msgstr "&Thực hiện" + +msgid "&Keyboard requires capture" +msgstr "Bàn phím &hoạt động cần capture chuột" + +msgid "&Right CTRL is left ALT" +msgstr "Gắn CTRL p&hải vào ALT trái" + +msgid "&Hard Reset..." +msgstr "Buộc khởi độn&g lại" + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "Tạm &dừng" + +msgid "E&xit..." +msgstr "Th&oát..." + +msgid "&View" +msgstr "&Xem" + +msgid "&Hide status bar" +msgstr "Ẩn tha&nh trạng thái" + +msgid "Hide &toolbar" +msgstr "Ẩn thanh &công cụ" + +msgid "&Resizeable window" +msgstr "Tùy chỉnh cỡ cử&a sổ" + +msgid "R&emember size && position" +msgstr "Ghi nhớ vị trí và kíc&h thước cửa sổ" + +msgid "Re&nderer" +msgstr "Re&nderer" + +msgid "&Qt (Software)" +msgstr "&Qt (phần mềm)" + +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (3.0 Core)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "Tự nhập độ &phân giải..." + +msgid "F&orce 4:3 display ratio" +msgstr "Giữ n&guyên khung hình 4:3" + +msgid "&Window scale factor" +msgstr "Đổi &tỷ lệ cửa sổ" + +msgid "&0.5x" +msgstr "&0.5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1.&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + +msgid "Filter method" +msgstr "&Bộ lọc hình ảnh" + +msgid "&Nearest" +msgstr "&Cực cận" + +msgid "&Linear" +msgstr "Tu&yến tính" + +msgid "Hi&DPI scaling" +msgstr "Tỷ lệ hinh ảnh phân giải cao" + +msgid "&Fullscreen\tCtrl+Alt+PgUp" +msgstr "Toàn màn &hình\tCtrl+Alt+PgUp" + +msgid "Fullscreen &stretch mode" +msgstr "&Chế độ kéo giãn hình" + +msgid "&Full screen stretch" +msgstr "Kéo giãn hình" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "Điểm ảnh vuông (giữ tỷ lệ)" + +msgid "&Integer scale" +msgstr "Căn tỷ lệ số nguyên" + +msgid "4:&3 Integer scale" +msgstr "Căn tỷ lệ 4:3 số nguyên" + +msgid "E&GA/(S)VGA settings" +msgstr "Cài đặt EGA/(S)VGA" + +msgid "&Inverted VGA monitor" +msgstr "Đảo mà&u VGA" + +msgid "VGA screen &type" +msgstr "L&oại màn VGA" + +msgid "RGB &Color" +msgstr "Màu R&GB" + +msgid "&RGB Grayscale" +msgstr "Thang xám RG&B" + +msgid "&Amber monitor" +msgstr "Màn hình vàng hổ phách (amber)" + +msgid "&Green monitor" +msgstr "Màn hình lục" + +msgid "&White monitor" +msgstr "Màn hinh trắng" + +msgid "Grayscale &conversion type" +msgstr "Chuyển đổi thang &màu xám" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Trung bình" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "&Overscan CGA/PCjr/Tandy/EGA/(S)VGA" + +msgid "Change contrast for &monochrome display" +msgstr "Chỉnh tương phản cho màn hình đơn sắc" + +msgid "&Media" +msgstr "&Phương tiện" + +msgid "&Tools" +msgstr "&Công cụ" + +msgid "&Settings..." +msgstr "&Cài đặt..." + +msgid "&Update status bar icons" +msgstr "Cậ&p nhật biểu tượng thanh trạng thái" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "Chụp &màn hình\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Tùy biến..." + +msgid "Enable &Discord integration" +msgstr "Bật trình trạng thái cho Discord" + +msgid "Sound &gain..." +msgstr "Bộ &tăng âm..." + +msgid "Begin trace\tCtrl+T" +msgstr "Bắt đầu dò\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "Ngưng dò\tCtrl+T" + +msgid "&Help" +msgstr "&Trợ giúp" + +msgid "&Documentation..." +msgstr "&Trợ giúp..." + +msgid "&About 86Box..." +msgstr "&Về 86Box..." + +msgid "&New image..." +msgstr "Tạo file ảnh đĩa mới..." + +msgid "&Existing image..." +msgstr "Ảnh đĩa có sẵn..." + +msgid "Existing image (&Write-protected)..." +msgstr "Ảnh đĩa có sẵn (chống ghi đè)..." + +msgid "&Record" +msgstr "&Ghi lại" + +msgid "&Play" +msgstr "&Phát" + +msgid "&Rewind to the beginning" +msgstr "&Tua về đầu" + +msgid "&Fast forward to the end" +msgstr "T&iến về cuối" + +msgid "E&ject" +msgstr "Đẩy đĩ&a ra" + +msgid "&Image..." +msgstr "&Ảnh đĩa..." + +msgid "E&xport to 86F..." +msgstr "Xuất ra f&ile 86F..." + +msgid "&Mute" +msgstr "Tắt tiến&g" + +msgid "E&mpty" +msgstr "Làm trố&ng đĩa" + +msgid "&Reload previous image" +msgstr "Load đĩ&a trước đó" + +msgid "&Folder..." +msgstr "Thư mụ&c" + +msgid "Target &framerate" +msgstr "Số khung hình mục tiêu" + +msgid "&Sync with video" +msgstr "Đồng bộ &với video" + +msgid "&25 fps" +msgstr "&25 fps" + +msgid "&30 fps" +msgstr "&30 fps" + +msgid "&50 fps" +msgstr "&50 fps" + +msgid "&60 fps" +msgstr "&60 fps" + +msgid "&75 fps" +msgstr "&75 fps" + +msgid "&VSync" +msgstr "&VSync" + +msgid "&Select shader..." +msgstr "&Chọn shader..." + +msgid "&Remove shader" +msgstr "&Bỏ shader" + +msgid "Preferences" +msgstr "Tùy biến" + +msgid "Sound Gain" +msgstr "Tăng âm" + +msgid "New Image" +msgstr "Ảnh đĩa mới" + +msgid "Settings" +msgstr "Cài đặt" + +msgid "Specify Main Window Dimensions" +msgstr "Tùy biến kích thước cửa sổ chính" + +msgid "OK" +msgstr "Đồng ý" + +msgid "Cancel" +msgstr "Thôi" + +msgid "Save these settings as &global defaults" +msgstr "Lưu cài đặt làm mặc định chung" + +msgid "&Default" +msgstr "&Mặc định" + +msgid "Language:" +msgstr "Ngôn ngữ:" + +msgid "Icon set:" +msgstr "Bộ biểu tượng:" + +msgid "Gain" +msgstr "Tăng" + +msgid "File name:" +msgstr "Tên tập tin:" + +msgid "Disk size:" +msgstr "Kích thước đĩa:" + +msgid "RPM mode:" +msgstr "Tốc độ vòng quay:" + +msgid "Progress:" +msgstr "Tiến trình:" + +msgid "Width:" +msgstr "Chiều rộng:" + +msgid "Height:" +msgstr "Chiều cao:" + +msgid "Lock to this size" +msgstr "Cố định kích thước hình hiện tại" + +msgid "Machine type:" +msgstr "Loại máy:" + +msgid "Machine:" +msgstr "Mẫu máy:" + +msgid "Configure" +msgstr "Tinh chỉnh" + +msgid "CPU type:" +msgstr "Loại CPU:" + +msgid "Speed:" +msgstr "Tốc độ:" + +msgid "Frequency:" +msgstr "Tần số xung:" + +msgid "FPU:" +msgstr "FPU:" + +msgid "Wait states:" +msgstr "Trạng thái chờ:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "Bộ nhớ (RAM):" + +msgid "Time synchronization" +msgstr "Đồng bộ thời gian" + +msgid "Disabled" +msgstr "Vô hiệu hóa" + +msgid "Enabled (local time)" +msgstr "Bật (giờ địa phương)" + +msgid "Enabled (UTC)" +msgstr "Bật (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Bộ tái biên dịch động (Dynamic Recompiler)" + +msgid "Video:" +msgstr "Video:" + +msgid "Voodoo Graphics" +msgstr "Voodoo đồ họa" + +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A đồ họa" + +msgid "XGA Graphics" +msgstr "XGA đồ họa" + +msgid "Mouse:" +msgstr "Chuột:" + +msgid "Joystick:" +msgstr "Cần điều khiển:" + +msgid "Joystick 1..." +msgstr "Cần điều khiển 1..." + +msgid "Joystick 2..." +msgstr "Cần điều khiển 2..." + +msgid "Joystick 3..." +msgstr "Cần điều khiển 3..." + +msgid "Joystick 4..." +msgstr "Cần điều khiển 4..." + +msgid "Sound card #1:" +msgstr "Card âm thanh 1:" + +msgid "Sound card #2:" +msgstr "Card âm thanh 2:" + +msgid "Sound card #3:" +msgstr "Card âm thanh 3:" + +msgid "Sound card #4:" +msgstr "Card âm thanh 4:" + +msgid "MIDI Out Device:" +msgstr "Thiết bị MIDI out:" + +msgid "MIDI In Device:" +msgstr "Thiết bị MIDI in:" + +msgid "Standalone MPU-401" +msgstr "MPU-401 độc lập" + +msgid "Use FLOAT32 sound" +msgstr "Dùng âm FLOAT32" + +msgid "FM synth driver" +msgstr "Driver bộ tổng hợp (synth) FM" + +msgid "Nuked (more accurate)" +msgstr "Nuked (chính xác hơn)" + +msgid "YMFM (faster)" +msgstr "YMFM (nhanh hơn)" + +msgid "Network type:" +msgstr "Kiểu loại mạng:" + +msgid "PCap device:" +msgstr "Thiết bị PCap:" + +msgid "Network adapter:" +msgstr "Bộ thích ứng (adapter) mạng:" + +msgid "COM1 Device:" +msgstr "Thiết bị COM1:" + +msgid "COM2 Device:" +msgstr "Thiết bị COM2:" + +msgid "COM3 Device:" +msgstr "Thiết bị COM3:" + +msgid "COM4 Device:" +msgstr "Thiết bị COM4:" + +msgid "LPT1 Device:" +msgstr "Thiết bị LPT1:" + +msgid "LPT2 Device:" +msgstr "Thiết bị LPT2:" + +msgid "LPT3 Device:" +msgstr "Thiết bị LPT3:" + +msgid "LPT4 Device:" +msgstr "Thiết bị LPT4:" + +msgid "Serial port 1" +msgstr "Cổng serial 1" + +msgid "Serial port 2" +msgstr "Cổng serial 2" + +msgid "Serial port 3" +msgstr "Cổng serial 3" + +msgid "Serial port 4" +msgstr "Cổng serial 4" + +msgid "Parallel port 1" +msgstr "Cổng parallel 1" + +msgid "Parallel port 2" +msgstr "Cổng parallel 2" + +msgid "Parallel port 3" +msgstr "Cổng parallel 3" + +msgid "Parallel port 4" +msgstr "Cổng parallel 4" + +msgid "HD Controller:" +msgstr "Bộ điều khiển HD:" + +msgid "FD Controller:" +msgstr "Bộ điều khiển FD:" + +msgid "Tertiary IDE Controller" +msgstr "Bộ điều khiển IDE thứ ba" + +msgid "Quaternary IDE Controller" +msgstr "Bộ điều khiển IDE thứ tư" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Bộ điều khiển 1:" + +msgid "Controller 2:" +msgstr "Bộ điều khiển 2:" + +msgid "Controller 3:" +msgstr "Bộ điều khiển 3:" + +msgid "Controller 4:" +msgstr "Bộ điều khiển 4:" + +msgid "Cassette" +msgstr "Cassette" + +msgid "Hard disks:" +msgstr "Đĩa cứng:" + +msgid "&New..." +msgstr "Tạ&o mới..." + +msgid "&Existing..." +msgstr "&Có sẵn..." + +msgid "&Remove" +msgstr "Loạ&i bỏ" + +msgid "Bus:" +msgstr "Bus:" + +msgid "Channel:" +msgstr "Kênh:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "Chỉ &rõ..." + +msgid "Sectors:" +msgstr "Sector:" + +msgid "Heads:" +msgstr "Đầu ghi:" + +msgid "Cylinders:" +msgstr "Trụ:" + +msgid "Size (MB):" +msgstr "Kích thước (MB):" + +msgid "Type:" +msgstr "Loại:" + +msgid "Image Format:" +msgstr "Định dạng ảnh đĩa:" + +msgid "Block Size:" +msgstr "Kích thước bloc:" + +msgid "Floppy drives:" +msgstr "Ổ đĩa mềm:" + +msgid "Turbo timings" +msgstr "Thời gian turbo" + +msgid "Check BPB" +msgstr "Kiểm tra BPB" + +msgid "CD-ROM drives:" +msgstr "Ổ đĩa CD-ROM:" + +msgid "MO drives:" +msgstr "Ổ đĩa MO:" + +msgid "ZIP drives:" +msgstr "Ổ đĩa ZIP:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA RTC:" + +msgid "ISA Memory Expansion" +msgstr "Mở rộng bộ nhớ qua ISA" + +msgid "Card 1:" +msgstr "Thẻ 1:" + +msgid "Card 2:" +msgstr "Thẻ 2:" + +msgid "Card 3:" +msgstr "Thẻ 3:" + +msgid "Card 4:" +msgstr "Thẻ 4:" + +msgid "ISABugger device" +msgstr "Thiết bị ISABugger" + +msgid "POST card" +msgstr "Thẻ POST" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Lỗi" + +msgid "Fatal error" +msgstr "Lỗi nghiêm trọng" + +msgid " - PAUSED" +msgstr " - TẠM DỪNG" + +msgid "Press Ctrl+Alt+PgDn to return to windowed mode." +msgstr "Bấm Ctrl+Alt+PgDn để quay lại chế độ cửa sổ." + +msgid "Speed" +msgstr "Vận tốc" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "Ảnh đĩa ZIP" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Box không tìm được bản ROM nào.\n\nVui lòng tải về bộ ROM và trích xuất về thư mục \"roms\"." + +msgid "(empty)" +msgstr "(trống trơn)" + +msgid "All files" +msgstr "Tất cả file" + +msgid "Turbo" +msgstr "Turbo" + +msgid "On" +msgstr "Bật" + +msgid "Off" +msgstr "Tắt" + +msgid "All images" +msgstr "Tất cả ảnh" + +msgid "Basic sector images" +msgstr "Ảnh sector cơ bản" + +msgid "Surface images" +msgstr "Ảnh bề mặt" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "Mẫu máy \"%hs\" không giả lập được do thiếu file ROM tương ứng trong mục roms/machines. Hãy chọn mẫu máy khác." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "Card đồ họa \"%hs\" không giả lập được do thiếu file ROM tương ứng trong mục roms/video. Hãy chọn card đồ họa khác." + +msgid "Machine" +msgstr "Mẫu máy" + +msgid "Display" +msgstr "Hiển thị" + +msgid "Input devices" +msgstr "Thiết bị nhập" + +msgid "Sound" +msgstr "Thanh âm" + +msgid "Network" +msgstr "Nối mạng" + +msgid "Ports (COM & LPT)" +msgstr "Cổng (COM và LPT)" + +msgid "Storage controllers" +msgstr "Vi điều khiển bộ nhớ ổ cứng" + +msgid "Hard disks" +msgstr "Ổ cứng" + +msgid "Floppy & CD-ROM drives" +msgstr "Ổ (đĩa) mềm và CD-ROM" + +msgid "Other removable devices" +msgstr "Thiết bị tháo rời được khác" + +msgid "Other peripherals" +msgstr "Thiết bị ngoại vi khác" + +msgid "Click to capture mouse" +msgstr "Bấm để capture ('nhốt') chuột vào" + +msgid "Press %1 to release mouse" +msgstr "Nhấn %1 để thả chuột" + +msgid "Press %1 or middle button to release mouse" +msgstr "Nhấn %1 hoặc nhấp chuột giữa để thả chuột" + +msgid "Bus" +msgstr "Bus" + +msgid "File" +msgstr "File" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "Không thể khởi tạo trình kết xuất (renderer) video ." + +msgid "Default" +msgstr "Mặc định" + +msgid "%i Wait state(s)" +msgstr "%i trạng thái chờ" + +msgid "Type" +msgstr "Loại" + +msgid "No PCap devices found" +msgstr "Không tìm thấy thiết bị PCap" + +msgid "Invalid PCap device" +msgstr "Thiết bị PCap không hợp quy" + +msgid "Standard 2-button joystick(s)" +msgstr "Cần điều khiển hai nút tiêu chuẩn" + +msgid "Standard 4-button joystick" +msgstr "Cần điều khiển bốn nút tiêu chuẩn" + +msgid "Standard 6-button joystick" +msgstr "Cần điều khiển sáu nút tiêu chuẩn" + +msgid "Standard 8-button joystick" +msgstr "Cần điều khiển tám nút tiêu chuẩn" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "None" +msgstr "Không có" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Đĩa mềm %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Ảnh (đĩa) sector nâng cao" + +msgid "Flux images" +msgstr "Ảnh thông lượng (flux)" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Bạn có thật sự buộc máy khởi động lại không?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Bạn có muốn thoát 86Box?" + +msgid "Unable to initialize Ghostscript" +msgstr "Không thể khởi tạo Ghostscript" + +msgid "MO %i (%ls): %ls" +msgstr "MO %i (%ls): %ls" + +msgid "MO images" +msgstr "Ảnh đĩa MO" + +msgid "Welcome to 86Box!" +msgstr "Chào mừng đến 86Box!" + +msgid "Internal controller" +msgstr "Vi điều khiển nội bộ" + +msgid "Exit" +msgstr "Thoát" + +msgid "No ROMs found" +msgstr "Không tìm thấy ROM" + +msgid "Do you want to save the settings?" +msgstr "Bạn có muốn lưu cài đặt không?" + +msgid "This will hard reset the emulated machine." +msgstr "Lệnh này sẽ buộc khởi động lại máy ảo." + +msgid "Save" +msgstr "Lưu" + +msgid "About 86Box" +msgstr "Về 86Box" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Trình giả lập các dòng máy tính cổ.\n\nTác giả: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, y otros.\n\nCùng với những đóng góp cốt cán từ Sarah Walker, leilei, JohnElliott, greatpsycho, và một số người khác.\n\nPhát hành dưới giấy phép GNU General Public License version 2 trở đi. Đọc LICENSE để biết thêm thông tin." + +msgid "Hardware not available" +msgstr "Phần cứng không có sẵn" + +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Đảm bảo rằng %1 đã được cài đặt vào và bạn đang dùng kết nối mạng tương thích %1." + +msgid "Invalid configuration" +msgstr "Tinh chỉnh không hợp lý" + +msgid "%1 is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr "Cần có %1 để tự động chuyển đổi file PostScript qua PDF.\n\nMọi tài liệu được đưa qua máy in generic PostScript sẽ lưu ở dạng PostScript (.ps)." + +msgid "Entering fullscreen mode" +msgstr "Đang tiến vào chế độ toàn màn hình" + +msgid "Don't show this message again" +msgstr "Không hiện thông báo này nữa" + +msgid "Don't exit" +msgstr "Không thoát" + +msgid "Reset" +msgstr "Khởi động lại" + +msgid "Don't reset" +msgstr "Không khởi động lại" + +msgid "CD-ROM images" +msgstr "Ảnh đĩa CD-ROM" + +msgid "%1 Device Configuration" +msgstr "Tinh chỉnh thiết bị %1" + +msgid "Monitor in sleep mode" +msgstr "Màn hình chế độ chờ/ngủ" + +msgid "OpenGL Shaders" +msgstr "Shader OpenGL" + +msgid "OpenGL options" +msgstr "Tùy chọn OpenGL" + +msgid "You are loading an unsupported configuration" +msgstr "Bạn đang load tinh chỉnh không được hỗ trợ." + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "Phần chọn loại CPU dựa trên mẫu máy đã chọn bị vô hiệu hóa.\n\nỞ đây bạn có thể chọn loại CPU có thể không tương thích với mẫu máy hiện tại. Tuy nhiên bạn có thể gặp vấn đề tương khắc với BIOS hay phần mềm khác.\n\nViệc bật tùy chọn này lên không được khuyến cáo chính thức và các bản bug report (báo lỗi) với nội dung tương tự sẽ bị closed as invalid (đóng vì phạm quy)." + +msgid "Continue" +msgstr "Tiếp tục" + +msgid "Cassette: %s" +msgstr "Cassette: %s" + +msgid "Cassette images" +msgstr "Ảnh đĩa Cassette" + +msgid "Cartridge %i: %ls" +msgstr "Băng cartridge %i: %ls" + +msgid "Cartridge images" +msgstr "Ảnh đĩa băng cartridge" + +msgid "Error initializing renderer" +msgstr "Lỗi khởi tạo renderer (trình kết xuất)" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "Không khởi tạo được renderer OpenGL (3.0 Core). Hãy dùng renderer khác." + +msgid "Resume execution" +msgstr "Tiếp tục chạy thực thi" + +msgid "Pause execution" +msgstr "Dừng chạy thực thi" + +msgid "Press Ctrl+Alt+Del" +msgstr "Nhấn Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Nhấn Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Buộc khởi động lại" + +msgid "ACPI shutdown" +msgstr "Tắt máy theo ACPI" + +msgid "Hard disk (%1)" +msgstr "Ổ cứng (%1)" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "Không hề có ổ CD-ROM MFM/RLL hay ESDI nào tồn tại" + +msgid "Custom..." +msgstr "Tùy chỉnh..." + +msgid "Custom (large)..." +msgstr "Tùy chỉnh (dung tích lớn)..." + +msgid "Add New Hard Disk" +msgstr "Thêm ổ cứng mới" + +msgid "Add Existing Hard Disk" +msgstr "Thêm ổ cứng đã có" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "Ảnh đĩa ổ HDI không to hơn 4 GB." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "Ảnh đĩa không to hơn 127 GB." + +msgid "Hard disk images" +msgstr "Ảnh đĩa ổ cứng" + +msgid "Unable to read file" +msgstr "Không đọc được file" + +msgid "Unable to write file" +msgstr "Không ghi được vào file" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "Ảnh đĩa HDI hoặc HDX với kích thước sector khác 512 không được hỗ trợ." + +msgid "Disk image file already exists" +msgstr "Đã có file ảnh đĩa rồi" + +msgid "Please specify a valid file name." +msgstr "Vui lòng đặt tên hợp lệ." + +msgid "Disk image created" +msgstr "Đã tạo ảnh đĩa" + +msgid "Make sure the file exists and is readable." +msgstr "Chắc chắn rằng file tồn tại và đọc được." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Chắc chắn rằng file được lưu ở địa chỉ thư mục có thể ghi đè." + +msgid "Disk image too large" +msgstr "Ảnh đĩa quá to" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Nhớ phân vùng và định dạng ổ đĩa mới tạo." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "File được chọn sẽ bị ghi đè lên. Bạn có chắc muốn chọn dùng không?" + +msgid "Unsupported disk image" +msgstr "File ảnh đĩa không được hỗ trợ" + +msgid "Overwrite" +msgstr "Có ghi đè" + +msgid "Don't overwrite" +msgstr "Không ghi đè" + +msgid "Raw image (.img)" +msgstr "Ảnh đĩa thô (.img)" + +msgid "HDI image (.hdi)" +msgstr "Ảnh đĩa HDI (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "Ảnh đĩa HDX (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "Ảnh VHD kích thước cố định (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "Ảnh VHD kích thước tăng dần (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "Ảnh VHD đa chủng (differencing) (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Bloc lớn (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "Bloc bé (512 KB)" + +msgid "VHD files" +msgstr "File VHD" + +msgid "Select the parent VHD" +msgstr "Chọn file VHD cha (parent)" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "Ở đây tức là ảnh đĩa cha (parent) có thể đã bị chỉnh sửa sau khi ảnh đĩa đa chủng (differencing image) được tạo ra.\n\nCũng có thể do ảnh đĩa bị chuyển đi hay bị copy, hoặc do bug/lỗi của phần mềm tạo ảnh đĩa gây ra.\n\nBạn có muốn sửa lại mốc thời gian (timestamp) không?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Mốc timestamp của đĩa con (child) và đĩa cha (parent) không trùng khớp" + +msgid "Could not fix VHD timestamp." +msgstr "Không thể sửa mốc timestamp cho VHD." + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1.2 MB" + +msgid "1.25 MB" +msgstr "1.25 MB" + +msgid "1.44 MB" +msgstr "1.44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (cluster 1024)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (cluster 2048)" + +msgid "2.88 MB" +msgstr "2.88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128 MB (ISO 10090)" +msgstr "3.5\" 128 MB (ISO 10090)" + +msgid "3.5\" 230 MB (ISO 13963)" +msgstr "3.5\" 230 MB (ISO 13963)" + +msgid "3.5\" 540 MB (ISO 15498)" +msgstr "3.5\" 540 MB (ISO 15498)" + +msgid "3.5\" 640 MB (ISO 15498)" +msgstr "3.5\" 640 MB (ISO 15498)" + +msgid "3.5\" 1.3 GB (GigaMO)" +msgstr "3.5\" 1.3 GB (GigaMO)" + +msgid "3.5\" 2.3 GB (GigaMO 2)" +msgstr "3.5\" 2.3 GB (GigaMO 2)" + +msgid "5.25\" 600 MB" +msgstr "5.25\" 600 MB" + +msgid "5.25\" 650 MB" +msgstr "5.25\" 650 MB" + +msgid "5.25\" 1 GB" +msgstr "5.25\" 1 GB" + +msgid "5.25\" 1.3 GB" +msgstr "5.25\" 1.3 GB" + +msgid "Perfect RPM" +msgstr "Số RPM(vòng quay đĩa/phút) hoàn thiện" + +msgid "1% below perfect RPM" +msgstr "1% thấp hơn số RPM hoàn thiện" + +msgid "1.5% below perfect RPM" +msgstr "1.5% thấp hơn số RPM hoàn thiện" + +msgid "2% below perfect RPM" +msgstr "2% thấp hơn số RPM hoàn thiện" + +msgid "(System Default)" +msgstr "(Mặc định hệ thống)" + +msgid "Failed to initialize network driver" +msgstr "Không thể khởi tạo trình điều khiển (driver) mạng" + +msgid "The network configuration will be switched to the null driver" +msgstr "Cấu hình mạng sẽ chuyển sang null driver (không có mạng)" + +msgid "Mouse sensitivity:" +msgstr "Độ nhạy chuột:" + +msgid "Select media images from program working directory" +msgstr "Chọn ảnh đĩa phương tiện từ thư mục làm việc của chương trình" + +msgid "PIT mode:" +msgstr "Chế độ PIT:" + +msgid "Auto" +msgstr "Tự động" + +msgid "Slow" +msgstr "Chậm" + +msgid "Fast" +msgstr "Nhanh" + +msgid "&Auto-pause on focus loss" +msgstr "&Tự tạm dừng giả lập khi không tập trung ở cửa sổ" + +msgid "WinBox is no longer supported" +msgstr "WinBox không còn được hỗ trợ" + +msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Trình quản lý phiên WinBox đã bị dừng phát triển năm 2022 do thiếu nhân sự duy trì. Vì những quyết định để cho 86Box trở nên tốt hơn, chúng tôi đã không còn hỗ trợ trình quản lý WinBox.\n\n Sẽ không có bản cập nhật mới cho WinBox nữa, và nếu bạn tiếp tục sử dụng với các bản 86Box mới hơn có thể gặp lỗi. Bất kì các bản bug report liên quan đến lỗi của WinBox sẽ bị coi là không hợp lệ và bị đóng.\n\nTruy cập 86Box.net để tìm qua các trình quản lý phiên/manager khác cho phù hợp." From 7ed68413568f4cbf02cfebec1ae8275f6387b1a1 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 3 May 2024 01:22:36 +0500 Subject: [PATCH 885/936] Hook up the new translation --- src/qt/qt_platform.cpp | 1 + src/qt/qt_translations.qrc | 1 + 2 files changed, 2 insertions(+) diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 275d1df2e..e0b11ad7b 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -455,6 +455,7 @@ QMap> ProgSettings::lcid_langcode = { { 0x0C0A, { "es-ES", "Spanish (Spain, Modern Sort)" } }, { 0x041F, { "tr-TR", "Turkish (Turkey)" } }, { 0x0422, { "uk-UA", "Ukrainian (Ukraine)" } }, + { 0x042A, { "vi-VN", "Vietnamese (Vietnam)" } }, { 0xFFFF, { "system", "(System Default)" } }, }; } diff --git a/src/qt/qt_translations.qrc b/src/qt/qt_translations.qrc index 017354f82..9f75fd6d6 100644 --- a/src/qt/qt_translations.qrc +++ b/src/qt/qt_translations.qrc @@ -21,6 +21,7 @@ 86box_sl-SI.qm 86box_tr-TR.qm 86box_uk-UA.qm + 86box_vi-VN.qm 86box_zh-CN.qm 86box_zh-TW.qm From 15b3c44cb7cbe002dd83e507f41292ee451bcbe6 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 3 May 2024 01:58:32 +0500 Subject: [PATCH 886/936] Update .gitattributes Declare CMake scripts, Windows resource scripts and manifests, .po translation files and Qt XML files as text --- .gitattributes | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.gitattributes b/.gitattributes index 32eb262c9..9b39a29c0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,12 +3,28 @@ # Explicitly declare text files you want to always be normalized and converted # to native line endings on checkout. +# Code *.c text *.cc text *.cpp text *.h text *.hpp text + +# CMake scripts +CMakeLists.txt text +*.cmake text + +# Windows resource scripts and manifests *.rc text +*.manifest text + +# Translation files +*.po text + +# Qt XML files +*.ui text +*.ts text +*.qrc text # Declare files that will always have CRLF line endings on checkout. From 56f7030c98172b7b96b05e2c4e05dbe6cebedd1f Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 00:23:08 +0200 Subject: [PATCH 887/936] IDE clean-ups. --- src/disk/hdc_ide.c | 519 +++++++++++++++------------------------------ 1 file changed, 170 insertions(+), 349 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 428804b5a..d203a52e8 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -91,15 +91,15 @@ #define WIN_SET_MULTIPLE_MODE 0xc6 #define WIN_READ_DMA 0xc8 #define WIN_READ_DMA_ALT 0xc9 -#define WIN_WRITE_DMA 0xcA -#define WIN_WRITE_DMA_ALT 0xcB +#define WIN_WRITE_DMA 0xca +#define WIN_WRITE_DMA_ALT 0xcb #define WIN_STANDBYNOW1 0xe0 #define WIN_IDLENOW1 0xe1 #define WIN_SETIDLE1 0xe3 #define WIN_CHECKPOWERMODE1 0xe5 #define WIN_SLEEP1 0xe6 -#define WIN_IDENTIFY 0xeC /* Ask drive to identify itself */ -#define WIN_SET_FEATURES 0xeF +#define WIN_IDENTIFY 0xec /* Ask drive to identify itself */ +#define WIN_SET_FEATURES 0xef #define WIN_READ_NATIVE_MAX 0xf8 #define FEATURE_SET_TRANSFER_MODE 0x03 @@ -377,7 +377,7 @@ ide_atapi_get_period(uint8_t channel) ide_log("ide_atapi_get_period(%i)\n", channel); - if (!ide) { + if (ide == NULL) { ide_log("Get period failed\n"); return -1.0; } @@ -411,7 +411,7 @@ ide_irq_update(ide_board_t *dev, int log) void ide_irq(ide_t *ide, int set, int log) { - if (!ide_boards[ide->board]) + if (ide_boards[ide->board] == NULL) return; #if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) @@ -437,7 +437,7 @@ ide_irq(ide_t *ide, int set, int log) * this length will be padded with spaces. */ void -ide_padstr(char *str, const char *src, int len) +ide_padstr(char *str, const char *src, const int len) { int v; @@ -471,37 +471,39 @@ ide_padstr8(uint8_t *buf, int buf_size, const char *src) } static int -ide_get_max(ide_t *ide, int type) +ide_is_ata4(const ide_board_t *board) { - int ret = -1; - ide_bm_t *bm = ide_boards[ide->board]->bm; - int ata_4 = (!ide_boards[ide->board]->force_ata3 && (bm != NULL)); - int max[2][4] = { { 0, -1, -1, -1 }, { 4, 2, 2, 5 } }; + const ide_bm_t *bm = board->bm; + + return (!board->force_ata3 && (bm != NULL)); +} + +static int +ide_get_max(const ide_t *ide, const int type) +{ + const int ata_4 = ide_is_ata4(ide_boards[ide->board]); + const int max[2][4] = { { 0, -1, -1, -1 }, { 4, 2, 2, 5 } }; + int ret; if (ide->type == IDE_ATAPI) ret = ide->get_max(!IDE_ATAPI_IS_EARLY && ata_4, type); - else if (type <= TYPE_UDMA) - ret = max[ata_4][type]; else - fatal("Unknown transfer type: %i\n", type); + ret = max[ata_4][type]; return ret; } static int -ide_get_timings(ide_t *ide, int type) +ide_get_timings(const ide_t *ide, const int type) { - int ret = 0; - ide_bm_t *bm = ide_boards[ide->board]->bm; - int ata_4 = (!ide_boards[ide->board]->force_ata3 && (bm != NULL)); - int timings[2][3] = { { 0, 0, 0 }, { 120, 120, 0 } }; + const int ata_4 = ide_is_ata4(ide_boards[ide->board]); + const int timings[2][3] = { { 0, 0, 0 }, { 120, 120, 0 } }; + int ret; if (ide->type == IDE_ATAPI) ret = ide->get_timings(!IDE_ATAPI_IS_EARLY && ata_4, type); - else if (type <= TIMINGS_PIO_FC) - ret = timings[ata_4][type]; else - fatal("Unknown transfer type: %i\n", type); + ret = timings[ata_4][type]; return ret; } @@ -510,22 +512,20 @@ ide_get_timings(ide_t *ide, int type) * Fill in ide->buffer with the output of the "IDENTIFY DEVICE" command */ static void -ide_hd_identify(ide_t *ide) +ide_hd_identify(const ide_t *ide) { char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; - ide_bm_t *bm = ide_boards[ide->board]->bm; - + const ide_bm_t *bm = ide_boards[ide->board]->bm; + const uint32_t d_spt = ide->spt; + uint64_t full_size = (((uint64_t) hdd[ide->hdd_num].tracks) * + hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); uint32_t d_hpc; - uint32_t d_spt; uint32_t d_tracks; - uint64_t full_size = (((uint64_t) hdd[ide->hdd_num].tracks) * - hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); device_identify[6] = (ide->hdd_num / 10) + 0x30; device_identify[7] = (ide->hdd_num % 10) + 0x30; ide_log("IDE Identify: %s\n", device_identify); - d_spt = ide->spt; if (ide->hpc <= 16) { /* HPC <= 16, report as needed. */ d_tracks = ide->tracks; @@ -973,7 +973,7 @@ ide_atapi_attach(ide_t *ide) void ide_set_callback(ide_t *ide, double callback) { - if (!ide) { + if (ide == NULL) { ide_log("ide_set_callback(NULL): Set callback failed\n"); return; } @@ -993,7 +993,7 @@ ide_set_board_callback(uint8_t board, double callback) ide_log("ide_set_board_callback(%i)\n", board); - if (!dev) { + if (dev == NULL) { ide_log("Set board callback failed\n"); return; } @@ -1086,13 +1086,15 @@ ide_atapi_callback(ide_t *ide) /* Else, DMA command without a bus master, ret = 0 (default). */ switch (ret) { + default: + break; case 0: if (ide->bus_master_error) ide->bus_master_error(ide->sc); break; case 1: if (out && ide->phase_data_out) - ret = ide->phase_data_out(ide->sc); + (void) ide->phase_data_out(ide->sc); else if (!out && ide->command_stop) ide->command_stop(ide->sc); @@ -1154,7 +1156,7 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out) } static uint16_t -ide_atapi_packet_read(ide_t *ide, int length) +ide_atapi_packet_read(ide_t *ide) { scsi_common_t *dev = ide->sc; const uint16_t *bufferw; @@ -1170,15 +1172,10 @@ ide_atapi_packet_read(ide_t *ide, int length) we're transferring bytes beyond it, which can happen when issuing media access commands with an allocated length below minimum request length (which is 1 sector = 2048 bytes). */ - if (length == 2) { - ret = (ide->tf->pos < dev->packet_len) ? bufferw[ide->tf->pos >> 1] : 0; - ide->tf->pos += 2; - dev->request_pos += 2; - } else { - ret = (ide->tf->pos < dev->packet_len) ? dev->temp_buffer[ide->tf->pos] : 0; - ide->tf->pos++; - dev->request_pos++; - } + ret = (ide->tf->pos < dev->packet_len) ? bufferw[ide->tf->pos >> 1] : 0; + ide->tf->pos += 2; + + dev->request_pos += 2; if ((dev->request_pos >= dev->max_transfer_len) || (ide->tf->pos >= dev->packet_len)) { /* Time for a DRQ. */ @@ -1190,7 +1187,7 @@ ide_atapi_packet_read(ide_t *ide, int length) } static void -ide_atapi_packet_write(ide_t *ide, uint16_t val, int length) +ide_atapi_packet_write(ide_t *ide, const uint16_t val) { scsi_common_t *dev = ide->sc; @@ -1207,15 +1204,10 @@ ide_atapi_packet_write(ide_t *ide, uint16_t val, int length) } if ((bufferb != NULL) && (dev->packet_status != PHASE_DATA_IN)) { - if (length == 2) { - bufferw[ide->tf->pos >> 1] = val & 0xffff; - ide->tf->pos += 2; - dev->request_pos += 2; - } else { - bufferb[ide->tf->pos] = val & 0xff; - ide->tf->pos++; - dev->request_pos++; - } + bufferw[ide->tf->pos >> 1] = val & 0xffff; + + ide->tf->pos += 2; + dev->request_pos += 2; if (dev->packet_status == PHASE_DATA_OUT) { if ((dev->request_pos >= dev->max_transfer_len) || (ide->tf->pos >= dev->packet_len)) { @@ -1234,32 +1226,26 @@ ide_atapi_packet_write(ide_t *ide, uint16_t val, int length) } static void -ide_write_data(ide_t *ide, uint16_t val, int length) +ide_write_data(ide_t *ide, const uint16_t val) { - uint8_t *idebufferb = (uint8_t *) ide->buffer; uint16_t *idebufferw = ide->buffer; if ((ide->type != IDE_NONE) && !(ide->type & IDE_SHADOW) && ide->buffer) { if (ide->command == WIN_PACKETCMD) { if (ide->type == IDE_ATAPI) - ide_atapi_packet_write(ide, val, length); + ide_atapi_packet_write(ide, val); else ide->tf->pos = 0; } else { - if (length == 2) { - idebufferw[ide->tf->pos >> 1] = val & 0xffff; - ide->tf->pos += 2; - } else { - idebufferb[ide->tf->pos] = val & 0xff; - ide->tf->pos++; - } + idebufferw[ide->tf->pos >> 1] = val & 0xffff; + ide->tf->pos += 2; if (ide->tf->pos >= 512) { ide->tf->pos = 0; ide->tf->atastat = BSY_STAT; - double seek_time = hdd_timing_write(&hdd[ide->hdd_num], ide_get_sector(ide), 1); - double xfer_time = ide_get_xfer_time(ide, 512); - double wait_time = seek_time + xfer_time; + const double seek_time = hdd_timing_write(&hdd[ide->hdd_num], ide_get_sector(ide), 1); + const double xfer_time = ide_get_xfer_time(ide, 512); + const double wait_time = seek_time + xfer_time; if (ide->command == WIN_WRITE_MULTIPLE) { if ((ide->blockcount + 1) >= ide->blocksize || ide->tf->secount == 1) { ide_set_callback(ide, seek_time + xfer_time + ide->pending_delay); @@ -1297,7 +1283,7 @@ ide_writew(uint16_t addr, uint16_t val, void *priv) switch (addr) { case 0x0: /* Data */ - ide_write_data(ide, val, 2); + ide_write_data(ide, val); break; case 0x7: ide_writeb(addr, val & 0xff, priv); @@ -1331,9 +1317,9 @@ ide_writel(uint16_t addr, uint32_t val, void *priv) switch (addr) { case 0x0: /* Data */ - ide_write_data(ide, val & 0xffff, 2); + ide_write_data(ide, val & 0xffff); if (dev->bit32) - ide_write_data(ide, val >> 16, 2); + ide_write_data(ide, val >> 16); else ide_writew(addr + 2, (val >> 16) & 0xffff, priv); break; @@ -1487,7 +1473,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) if ((ide->type != IDE_NONE) || ((addr != 0x0) && (addr != 0x7))) switch (addr) { case 0x0: /* Data */ - ide_write_data(ide, val | (val << 8), 2); + ide_write_data(ide, val | (val << 8)); break; /* Note to self: for ATAPI, bit 0 of this is DMA if set, PIO if clear. */ @@ -1605,8 +1591,8 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ide->tf->error = 0; switch (val) { - case WIN_RECAL ... 0x1F: - case WIN_SEEK ... 0x7F: + case WIN_RECAL ... 0x1f: + case WIN_SEEK ... 0x7f: if (ide->type == IDE_ATAPI) ide->tf->atastat = DRDY_STAT; else @@ -1655,7 +1641,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) uint32_t sec_count; double wait_time; if ((val == WIN_READ_DMA) || (val == WIN_READ_DMA_ALT)) { - /* TODO make DMA timing more accurate */ + /* TODO: Make DMA timing more accurate. */ sec_count = ide->tf->secount ? ide->tf->secount : 256; double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); @@ -1818,39 +1804,28 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) } static uint16_t -ide_read_data(ide_t *ide, int length) +ide_read_data(ide_t *ide) { - const uint8_t *idebufferb = (uint8_t *) ide->buffer; const uint16_t *idebufferw = ide->buffer; - uint16_t ret = 0; - double seek_us; - double xfer_us; + uint16_t ret = 0x0000; #if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) ide_log("ide_read_data(): ch = %i, board = %i, type = %i\n", ide->channel, ide->board, ide->type); #endif - if ((ide->type == IDE_NONE) || (ide->type & IDE_SHADOW) || !ide->buffer) { - if (length == 2) - ret = 0xff7f; - else - ret = 0x7f; - } else if (ide->command == WIN_PACKETCMD) { + if ((ide->type == IDE_NONE) || (ide->type & IDE_SHADOW) || (ide->buffer == NULL)) + ret = 0xff7f; + else if (ide->command == WIN_PACKETCMD) { if (ide->type == IDE_ATAPI) - ret = ide_atapi_packet_read(ide, length); + ret = ide_atapi_packet_read(ide); else { ide_log("Drive not ATAPI (position: %i)\n", ide->tf->pos); ide->tf->pos = 0; } } else { - if (length == 2) { - ret = idebufferw[ide->tf->pos >> 1]; - ide->tf->pos += 2; - } else { - ret = idebufferb[ide->tf->pos]; - ide->tf->pos++; - } + ret = idebufferw[ide->tf->pos >> 1]; + ide->tf->pos += 2; if (ide->tf->pos >= 512) { ide->tf->pos = 0; @@ -1861,6 +1836,7 @@ ide_read_data(ide_t *ide, int length) if ((ide->command == WIN_READ) || (ide->command == WIN_READ_NORETRY) || (ide->command == WIN_READ_MULTIPLE)) { + ide->tf->secount--; if (ide->tf->secount) { @@ -1872,16 +1848,16 @@ ide_read_data(ide_t *ide, int length) ide->tf->secount : 256; if (cnt > ide->blocksize) cnt = ide->blocksize; - seek_us = hdd_timing_read(&hdd[ide->hdd_num], - ide_get_sector(ide), cnt); - xfer_us = ide_get_xfer_time(ide, 512 * cnt); + const double seek_us = hdd_timing_read(&hdd[ide->hdd_num], + ide_get_sector(ide), cnt); + const double xfer_us = ide_get_xfer_time(ide, 512 * cnt); ide_set_callback(ide, seek_us + xfer_us); } else ide_callback(ide); } else { - seek_us = hdd_timing_read(&hdd[ide->hdd_num], - ide_get_sector(ide), 1); - xfer_us = ide_get_xfer_time(ide, 512); + const double seek_us = hdd_timing_read(&hdd[ide->hdd_num], + ide_get_sector(ide), 1); + const double xfer_us = ide_get_xfer_time(ide, 512); ide_set_callback(ide, seek_us + xfer_us); } } else @@ -1931,7 +1907,7 @@ ide_readb(uint16_t addr, void *priv) switch (addr & 0x7) { case 0x0: /* Data */ - ret = ide_read_data(ide, 2) & 0xff; + ret = ide_read_data(ide) & 0xff; break; /* For ATAPI: Bits 7-4 = sense key, bit 3 = MCR (media change requested), @@ -2012,53 +1988,45 @@ ide_readb(uint16_t addr, void *priv) } ide_log("ide_readb(%04X, %08X) = %02X\n", addr, priv, ret); + return ret; } uint8_t -ide_read_alt_status(UNUSED(uint16_t addr), void *priv) +ide_read_alt_status(UNUSED(const uint16_t addr), void *priv) { - uint8_t ret = 0xff; - const ide_board_t *dev = (ide_board_t *) priv; - ide_t *ide; - int ch; - - ch = dev->cur_dev; - ide = ide_drives[ch]; + const int ch = dev->cur_dev; + ide_t * ide = ide_drives[ch]; /* Per the Seagate ATA-3 specification: Reading the alternate status does *NOT* clear the IRQ. */ - ret = ide_status(ide, ide_drives[ch ^ 1], ch); + const uint8_t ret = ide_status(ide, ide_drives[ch ^ 1], ch); ide_log("ide_read_alt_status(%04X, %08X) = %02X\n", addr, priv, ret); + return ret; } uint16_t ide_readw(uint16_t addr, void *priv) { - uint16_t ret = 0xffff; - const ide_board_t *dev = (ide_board_t *) priv; - - ide_t *ide; - int ch; - - ch = dev->cur_dev; - ide = ide_drives[ch]; + const int ch = dev->cur_dev; + ide_t * ide = ide_drives[ch]; + uint16_t ret; switch (addr & 0x7) { + default: + ret = ide_readb(addr, priv) | (ide_readb(addr + 1, priv) << 8); + break; case 0x0: /* Data */ - ret = ide_read_data(ide, 2); + ret = ide_read_data(ide); break; case 0x7: ret = ide_readb(addr, priv) | 0xff00; break; - default: - ret = ide_readb(addr, priv) | (ide_readb(addr + 1, priv) << 8); - break; } #if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) @@ -2070,20 +2038,16 @@ ide_readw(uint16_t addr, void *priv) static uint32_t ide_readl(uint16_t addr, void *priv) { - ide_t *ide; - int ch; - uint32_t ret = 0xffffffff; - const ide_board_t *dev = (ide_board_t *) priv; - - ch = dev->cur_dev; - ide = ide_drives[ch]; + const int ch = dev->cur_dev; + ide_t * ide = ide_drives[ch]; + uint32_t ret; switch (addr & 0x7) { case 0x0: /* Data */ - ret = ide_read_data(ide, 2); + ret = ide_read_data(ide); if (dev->bit32) - ret |= (ide_read_data(ide, 2) << 16); + ret |= (ide_read_data(ide) << 16); else ret |= (ide_readw(addr + 2, priv) << 16); break; @@ -2148,12 +2112,11 @@ atapi_error_no_ready(ide_t *ide) static void ide_callback(void *priv) { - int snum; - int ret = 0; - uint8_t err = 0x00; - int chk_chs = 0; - ide_t *ide = (ide_t *) priv; - ide_bm_t *bm = ide_boards[ide->board]->bm; + ide_t * ide = (ide_t *) priv; + const ide_bm_t *bm = ide_boards[ide->board]->bm; + int chk_chs; + int ret; + uint8_t err = 0x00; ide_log("ide_callback(%i): %02X\n", ide->channel, ide->command); @@ -2187,7 +2150,7 @@ ide_callback(void *priv) Status = 00h, Error = 01h, Sector Count = 01h, Sector Number = 01h, Cylinder Low = 14h, Cylinder High = EBh and Drive/Head = 00h. */ case WIN_SRST: /*ATAPI Device Reset */ - ide->tf->error = 1; /*Device passed*/ + ide->tf->error = 1; /*Device passed*/ ide->tf->secount = 1; ide->tf->sector = 1; @@ -2269,7 +2232,7 @@ ide_callback(void *priv) ide->tf->pos = 0; - if (!ide_boards[ide->board]->force_ata3 && (bm != NULL) && bm->dma) { + if (!ide_boards[ide->board]->force_ata3 && bm->dma) { /* We should not abort - we should simply wait for the host to start DMA. */ ret = bm->dma(ide->sector_buffer, ide->sector_pos * 512, 0, bm->priv); if (ret == 2) { @@ -2365,7 +2328,7 @@ ide_callback(void *priv) ide_log("IDE %i: DMA write aborted (SPECIFY failed)\n", ide->channel); err = IDNF_ERR; } else { - if (!ide_boards[ide->board]->force_ata3 && (bm != NULL) && bm->dma) { + if (!ide_boards[ide->board]->force_ata3 && bm->dma) { if (ide->tf->secount) ide->sector_pos = ide->tf->secount; else @@ -2515,7 +2478,7 @@ ide_callback(void *priv) case WIN_READ_NATIVE_MAX: if (ide->type == IDE_HDD) { - snum = hdd[ide->hdd_num].spt; + int snum = hdd[ide->hdd_num].spt; snum *= hdd[ide->hdd_num].hpc; snum *= hdd[ide->hdd_num].tracks; ide_set_sector(ide, snum - 1); @@ -2725,10 +2688,8 @@ ide_board_close(int board) dev->buffer = NULL; } - if (dev) { - free(dev); - ide_drives[c] = NULL; - } + free(dev); + ide_drives[c] = NULL; } } @@ -2737,19 +2698,12 @@ ide_board_close(int board) } static void -ide_board_setup(int board) +ide_board_setup(const int board) { - ide_t *dev; - int c; - int d; - int ch; - int is_ide; - int valid_ch; - int min_ch; - int max_ch; - - min_ch = (board << 1); - max_ch = min_ch + 1; + const int min_ch = (board << 1); + const int max_ch = min_ch + 1; + int c; + int d; ide_log("IDE: board %i: loading disks...\n", board); for (d = 0; d < 2; d++) { @@ -2759,14 +2713,10 @@ ide_board_setup(int board) c = 0; for (d = 0; d < HDD_NUM; d++) { - is_ide = (hdd[d].bus == HDD_BUS_IDE); - ch = hdd[d].ide_channel; + const int is_ide = (hdd[d].bus == HDD_BUS_IDE); + const int ch = hdd[d].ide_channel; - if (board == 4) { - valid_ch = ((ch >= 0) && (ch <= 1)); - ch |= 8; - } else - valid_ch = ((ch >= min_ch) && (ch <= max_ch)); + const int valid_ch = ((ch >= min_ch) && (ch <= max_ch)); if (is_ide && valid_ch) { ide_log("Found IDE hard disk on channel %i\n", ch); @@ -2780,8 +2730,8 @@ ide_board_setup(int board) ide_log("IDE: board %i: done, loaded %d disks.\n", board, c); for (d = 0; d < 2; d++) { - c = (board << 1) + d; - dev = ide_drives[c]; + c = (board << 1) + d; + ide_t *dev = ide_drives[c]; if (dev->type == IDE_NONE) continue; @@ -3095,7 +3045,7 @@ ide_close(UNUSED(void *priv)) } static uint8_t -mcide_mca_read(int port, void *priv) +mcide_mca_read(const int port, void *priv) { const mcide_t *dev = (mcide_t *) priv; @@ -3105,196 +3055,67 @@ mcide_mca_read(int port, void *priv) } static void -mcide_mca_write(int port, uint8_t val, void *priv) +mcide_mca_write(const int port, const uint8_t val, void *priv) { - mcide_t *dev = (mcide_t *) priv; + mcide_t *dev = (mcide_t *) priv; + uint16_t bases[4] = { 0x01f0, 0x0170, 0x01e8, 0x0168 }; + int irqs[4] = { 10, 11, 14, 15 }; - ide_log("IDE: mcawr(%04x, %02x) pos[2]=%02x pos[3]=%02x\n", - port, val, dev->pos_regs[2], dev->pos_regs[3]); + if ((port >= 0x102) && (dev->pos_regs[port & 7] != val)) { + ide_log("IDE: mcawr(%04x, %02x) pos[2]=%02x pos[3]=%02x\n", + port, val, dev->pos_regs[2], dev->pos_regs[3]); - if (port < 0x102) - return; + /* Save the new value. */ + dev->pos_regs[port & 7] = val; - /* Save the new value. */ - dev->pos_regs[port & 7] = val; + mem_mapping_disable(&dev->bios_rom.mapping); + dev->bios_addr = 0x00000000; - io_handler(0, ide_boards[0]->base[0], 8, - ide_readb, ide_readw, ide_readl, - ide_writeb, ide_writew, ide_writel, - ide_boards[0]); - io_handler(0, ide_boards[0]->base[1], 1, - ide_read_alt_status, NULL, NULL, - ide_write_devctl, NULL, NULL, - ide_boards[0]); - io_handler(0, ide_boards[1]->base[0], 8, - ide_readb, ide_readw, ide_readl, - ide_writeb, ide_writew, ide_writel, - ide_boards[1]); - io_handler(0, ide_boards[1]->base[1], 1, - ide_read_alt_status, NULL, NULL, - ide_write_devctl, NULL, NULL, - ide_boards[1]); - mem_mapping_disable(&dev->bios_rom.mapping); + ide_remove_handlers(0); + ide_boards[0]->base[0] = ide_boards[0]->base[1] = 0x0000; - if (dev->pos_regs[2] & 0x80) { - switch ((dev->pos_regs[2] >> 4) & 7) { - case 0: - dev->bios_addr = 0xc0000; - break; - case 1: - dev->bios_addr = 0xc4000; - break; - case 2: - dev->bios_addr = 0xc8000; - break; - case 3: - dev->bios_addr = 0xcc000; - break; - case 4: - dev->bios_addr = 0xd0000; - break; - case 5: - dev->bios_addr = 0xd4000; - break; - case 6: - dev->bios_addr = 0xd8000; - break; - case 7: - dev->bios_addr = 0xd8000; - break; - default: - break; + ide_boards[0]->irq = -1; + + ide_remove_handlers(1); + ide_boards[1]->base[0] = ide_boards[1]->base[1] = 0x0000; + + ide_boards[1]->irq = -1; + + if (dev->pos_regs[2] & 1) { + if (dev->pos_regs[2] & 0x80) + dev->bios_addr = 0x000c0000 + (0x00004000 * (uint32_t) ((dev->pos_regs[2] >> 4) & 0x07)); + + if (dev->pos_regs[3] & 0x08) { + ide_boards[0]->base[0] = bases[dev->pos_regs[3] & 0x03]; + ide_boards[0]->base[1] = bases[dev->pos_regs[3] & 0x03] + 0x0206; + } + + if (dev->pos_regs[3] & 0x80) + ide_boards[0]->irq = irqs[(dev->pos_regs[3] >> 4) & 0x03]; + + if (dev->pos_regs[4] & 0x08) { + ide_boards[1]->base[0] = bases[dev->pos_regs[4] & 0x03]; + ide_boards[1]->base[1] = bases[dev->pos_regs[4] & 0x03] + 0x0206; + } + + if (dev->pos_regs[4] & 0x80) + ide_boards[1]->irq = irqs[(dev->pos_regs[4] >> 4) & 0x03]; + + ide_set_handlers(0); + + ide_set_handlers(1); + + if (dev->bios_addr) + mem_mapping_set_addr(&dev->bios_rom.mapping, dev->bios_addr, 0x00004000); + + /* Say hello. */ + ide_log("McIDE: Primary Master I/O=%03X, Primary IRQ=%02i, " + "Secondary Master I/O=%03X, Secondary IRQ=%02i, " + "BIOS @%05X\n", + ide_boards[0]->base[0], ide_boards[0]->irq, + ide_boards[1]->base[0], ide_boards[1]->irq, + dev->bios_addr); } - } else { - dev->bios_addr = 0; - } - - if (dev->pos_regs[3] & 0x08) { - switch (dev->pos_regs[3] & 3) { - case 0: - ide_boards[0]->base[0] = 0x1f0; - ide_boards[0]->base[1] = 0x3f6; - break; - case 1: - ide_boards[0]->base[0] = 0x170; - ide_boards[0]->base[1] = 0x376; - break; - case 2: - ide_boards[0]->base[0] = 0x1e8; - ide_boards[0]->base[1] = 0x3ee; - break; - case 3: - ide_boards[0]->base[0] = 0x168; - ide_boards[0]->base[1] = 0x36e; - break; - default: - break; - } - } else { - ide_boards[0]->base[0] = 0; - ide_boards[0]->base[1] = 0; - } - - if (dev->pos_regs[3] & 0x80) { - switch (dev->pos_regs[3] & 0x30) { - case 0x00: - ide_boards[0]->irq = 10; - break; - case 0x10: - ide_boards[0]->irq = 11; - break; - case 0x20: - ide_boards[0]->irq = 14; - break; - case 0x30: - ide_boards[0]->irq = 15; - break; - - default: - break; - } - } else - ide_boards[0]->irq = -1; - - if (dev->pos_regs[4] & 0x08) { - switch ((dev->pos_regs[4] & 3)) { - case 0: - ide_boards[1]->base[0] = 0x1f0; - ide_boards[1]->base[1] = 0x3f6; - break; - case 1: - ide_boards[1]->base[0] = 0x170; - ide_boards[1]->base[1] = 0x376; - break; - case 2: - ide_boards[1]->base[0] = 0x1e8; - ide_boards[1]->base[1] = 0x3ee; - break; - case 3: - ide_boards[1]->base[0] = 0x168; - ide_boards[1]->base[1] = 0x36e; - break; - default: - break; - } - } else { - ide_boards[1]->base[0] = 0; - ide_boards[1]->base[1] = 0; - } - - if (dev->pos_regs[4] & 0x80) { - switch (dev->pos_regs[4] & 0x30) { - case 0x00: - ide_boards[1]->irq = 10; - break; - case 0x10: - ide_boards[1]->irq = 11; - break; - case 0x20: - ide_boards[1]->irq = 14; - break; - case 0x30: - ide_boards[1]->irq = 15; - break; - - default: - break; - } - } else - ide_boards[1]->irq = -1; - - if (dev->pos_regs[2] & 1) { - if (ide_boards[0]->base[0] && ide_boards[0]->base[1]) { - io_handler(1, ide_boards[0]->base[0], 8, - ide_readb, ide_readw, ide_readl, - ide_writeb, ide_writew, ide_writel, - ide_boards[0]); - io_handler(1, ide_boards[0]->base[1], 1, - ide_read_alt_status, NULL, NULL, - ide_write_devctl, NULL, NULL, - ide_boards[0]); - } - - if (ide_boards[1]->base[0] && ide_boards[1]->base[1]) { - io_handler(1, ide_boards[1]->base[0], 8, - ide_readb, ide_readw, ide_readl, - ide_writeb, ide_writew, ide_writel, - ide_boards[1]); - io_handler(1, ide_boards[1]->base[1], 1, - ide_read_alt_status, NULL, NULL, - ide_write_devctl, NULL, NULL, - ide_boards[1]); - } - - if (dev->bios_addr) { - mem_mapping_enable(&dev->bios_rom.mapping); - mem_mapping_set_addr(&dev->bios_rom.mapping, - dev->bios_addr, 0x4000); - } - - /* Say hello. */ - ide_log("McIDE: Primary Master I/O=%03x, Primary IRQ=%i, Secondary Master I/O=%03x, Secondary IRQ=%d, BIOS @%05X\n", - ide_boards[0]->base[0], ide_boards[0]->irq, ide_boards[1]->base[0], ide_boards[1]->irq, dev->bios_addr); } } @@ -3464,7 +3285,7 @@ const device_t mcide_device = { .name = "MCA McIDE Controller", .internal_name = "ide_mcide", .flags = DEVICE_MCA, - .local = 0, + .local = 3, .init = mcide_init, .close = mcide_close, .reset = mcide_reset, From 3f6126f72dd83e34b01543fa84c259f51027f396 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 01:45:22 +0200 Subject: [PATCH 888/936] Bochs VBE fixes, fixes #4410. --- src/video/vid_bochs_vbe.c | 80 ++++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 17 deletions(-) diff --git a/src/video/vid_bochs_vbe.c b/src/video/vid_bochs_vbe.c index 603e455d1..a4459ce4c 100644 --- a/src/video/vid_bochs_vbe.c +++ b/src/video/vid_bochs_vbe.c @@ -124,6 +124,7 @@ typedef struct bochs_vbe_t { mem_mapping_t linear_mapping; mem_mapping_t linear_mapping_2; + uint32_t ma_latch_old; void * i2c; void * ddc; @@ -322,10 +323,10 @@ bochs_vbe_recalctimings(svga_t* svga) svga->hblankend = mode.hdisplay + (mode.htotal - mode.hdisplay - 1); svga->vblankstart = svga->dispend; /* no vertical overscan. */ svga->rowcount = 0; + svga->hoverride = 1; if (dev->vbe_regs[VBE_DISPI_INDEX_BPP] != 4) { svga->fb_only = 1; svga->adv_flags |= FLAG_NO_SHIFT3; - } else { svga->fb_only = 0; svga->adv_flags &= ~FLAG_NO_SHIFT3; @@ -334,26 +335,29 @@ bochs_vbe_recalctimings(svga_t* svga) svga->bpp = dev->vbe_regs[VBE_DISPI_INDEX_BPP]; if (svga->bpp == 4) { - svga->rowoffset = dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] >> 3; + 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); } else { - svga->rowoffset = dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] * (svga->bpp / 8); + 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 / 8)); + (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8))); } - - if ((svga->ma_latch + dev->vbe_regs[VBE_DISPI_INDEX_YRES] * svga->rowoffset) > - svga->vram_max) { - dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0; - svga->ma_latch = (svga->bpp == 4) ? (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] >> 3) : - (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * (svga->bpp / 8)); - if ((svga->ma_latch + dev->vbe_regs[VBE_DISPI_INDEX_YRES] * svga->rowoffset) > - svga->vram_max) { - svga->ma_latch = 0; - dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0; + 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; } } + + if (svga->bpp == 4) + dev->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = (svga->vram_max * 2) / dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH]; + else + dev->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = (svga->vram_max / ((svga->bpp == 15) ? 2 : (svga->bpp / 8))) / dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH]; svga->split = 0xffffff; switch (svga->bpp) { @@ -381,6 +385,7 @@ bochs_vbe_recalctimings(svga_t* svga) svga->fb_only = 0; svga->packed_4bpp = 0; svga->adv_flags &= ~FLAG_NO_SHIFT3; + svga->hoverride = 0; } } @@ -417,8 +422,10 @@ bochs_vbe_inw(const uint16_t addr, void *priv) case VBE_DISPI_INDEX_DDC: if (dev->vbe_regs[dev->vbe_index] & (1 << 7)) { ret = dev->vbe_regs[dev->vbe_index] & ((1 << 7) | 0x3); - ret |= i2c_gpio_get_scl(dev->i2c) << 2; - ret |= i2c_gpio_get_sda(dev->i2c) << 3; + if ((ret & 0x01) && i2c_gpio_get_scl(dev->i2c)) + ret |= 0x04; + if ((ret & 0x02) && i2c_gpio_get_sda(dev->i2c)) + ret |= 0x08; } else ret = 0x000f; break; @@ -466,7 +473,30 @@ bochs_vbe_outw(const uint16_t addr, const uint16_t val, void *priv) case VBE_DISPI_INDEX_X_OFFSET: case VBE_DISPI_INDEX_Y_OFFSET: dev->vbe_regs[dev->vbe_index] = val; - svga_recalctimings(&dev->svga); + if (dev->vbe_index == VBE_DISPI_INDEX_X_OFFSET || dev->vbe_index == VBE_DISPI_INDEX_Y_OFFSET) { + svga_t *svga = &dev->svga; + if (svga->bpp == 4) { + 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); + } 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; + } + } + } + else + svga_recalctimings(&dev->svga); break; case VBE_DISPI_INDEX_BANK: @@ -788,6 +818,21 @@ bochs_vbe_init(const device_t *info) 0xc0000, 0x10000, 0xffff, 0x0000, MEM_MAPPING_EXTERNAL); + if (dev->id5_val == VBE_DISPI_ID4) { + /* Patch the BIOS to match the PCI ID. */ + dev->bios_rom.rom[0x010c] = 0xee; + dev->bios_rom.rom[0x8dff] -= (0xee - 0x34); + + dev->bios_rom.rom[0x010d] = 0x80; + dev->bios_rom.rom[0x8dff] -= (0x80 - 0x12); + + dev->bios_rom.rom[0x010e] = 0xef; + dev->bios_rom.rom[0x8dff] -= (0xef - 0x11); + + dev->bios_rom.rom[0x010f] = 0xbe; + dev->bios_rom.rom[0x8dff] -= (0xbe - 0x11); + } + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_bochs); svga_init(info, &dev->svga, dev, dev->vram_size, @@ -826,6 +871,7 @@ bochs_vbe_init(const device_t *info) dev->i2c = i2c_gpio_init("ddc_bochs"); dev->ddc = ddc_init(i2c_gpio_get_bus(dev->i2c)); + dev->svga.packed_chain4 = 1; pci_add_card(PCI_ADD_NORMAL, bochs_vbe_pci_read, bochs_vbe_pci_write, dev, &dev->slot); From 656591d3851d480fc72a186fe7e845499cfb8108 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 11:18:28 +0200 Subject: [PATCH 889/936] The forgotten changes to video/vid_svga.c. --- src/video/vid_svga.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index a8bf76505..4632ab85e 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1130,9 +1130,9 @@ svga_poll(void *priv) svga->linecountff = 0; svga->sc = 0; - svga->maback += (svga->rowoffset << 3); + svga->maback += (svga->adv_flags & FLAG_NO_SHIFT3) ? svga->rowoffset : (svga->rowoffset << 3); if (svga->interlace) - svga->maback += (svga->rowoffset << 3); + svga->maback += (svga->adv_flags & FLAG_NO_SHIFT3) ? svga->rowoffset : (svga->rowoffset << 3); svga->maback &= svga->vram_display_mask; svga->ma = svga->maback; @@ -1237,8 +1237,10 @@ svga_poll(void *priv) svga->ma = svga->maback = svga->ma_latch + svga->hblank_sub; svga->ca = ((svga->crtc[0xe] << 8) | svga->crtc[0xf]) + ((svga->crtc[0xb] & 0x60) >> 5) + svga->ca_adj; - svga->ma = (svga->ma << 2); - svga->maback = (svga->maback << 2); + if (!(svga->adv_flags & FLAG_NO_SHIFT3)) { + svga->ma = (svga->ma << 2); + svga->maback = (svga->maback << 2); + } svga->ca = (svga->ca << 2); if (svga->vsync_callback) @@ -1341,6 +1343,7 @@ svga_init(const device_t *info, svga_t *svga, void *priv, int memsize, svga->hwcursor_draw = hwcursor_draw; svga->overlay_draw = overlay_draw; svga->conv_16to32 = svga_conv_16to32; + svga->render = svga_render_blank; svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = 32; From 2acb11d37c72a027f091df779590a1542f64d787 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 17:02:13 +0200 Subject: [PATCH 890/936] Implemented the Pro Audio Spectrum Plus serial mixer, Pro Audio Spectrum 16 parallel mixer, Pro Audio Spectrum Plus/16 SCSI, ESS ES688, all three ESS PnP AudioDrives, made the wavetables use a separate 44.1 kHz source, and made the Sound Blaster 16 PNP use a proper PNP ROM dump. --- src/86box.c | 18 +- src/config.c | 13 +- src/device.c | 6 + src/dma.c | 1 + src/include/86box/86box.h | 2 + src/include/86box/device.h | 1 + src/include/86box/filters.h | 50 +- src/include/86box/pit.h | 1 + src/include/86box/scsi.h | 10 +- src/include/86box/scsi_ncr5380.h | 8 + src/include/86box/scsi_ncr53c400.h | 62 + src/include/86box/snd_emu8k.h | 6 +- src/include/86box/snd_sb_dsp.h | 19 +- src/include/86box/sound.h | 91 +- src/pit.c | 5 + src/qt/qt_deviceconfig.cpp | 411 +++--- src/qt/qt_deviceconfig.hpp | 6 +- src/qt/qt_harddrive_common.cpp | 10 +- src/qt/qt_machinestatus.cpp | 4 +- src/qt/qt_main.cpp | 15 +- src/qt/qt_mainwindow.cpp | 89 +- src/qt/qt_mainwindow.hpp | 2 +- src/qt/qt_mediamenu.cpp | 66 +- src/qt/qt_rendererstack.cpp | 5 +- src/qt/qt_settings.cpp | 20 + src/qt/qt_settings_bus_tracking.cpp | 45 +- src/qt/qt_settings_bus_tracking.hpp | 6 +- src/qt/qt_settingsfloppycdrom.cpp | 1 + src/qt/qt_settingsotherremovable.cpp | 48 +- src/qt/qt_settingsotherremovable.hpp | 7 + src/qt/qt_settingssound.cpp | 31 +- src/qt/qt_settingsstoragecontrollers.cpp | 4 +- src/qt/qt_ui.cpp | 32 +- src/scsi/scsi.c | 8 +- src/scsi/scsi_ncr5380.c | 46 +- src/scsi/scsi_ncr53c400.c | 177 ++- src/sound/openal.c | 103 +- src/sound/snd_emu8k.c | 23 +- src/sound/snd_lpt_dac.c | 54 +- src/sound/snd_lpt_dss.c | 23 +- src/sound/snd_opl_ymfm.cpp | 48 +- src/sound/snd_optimc.c | 2 +- src/sound/snd_pas16.c | 1461 ++++++++++++++++++++-- src/sound/snd_sb.c | 1426 ++++++++++++++++----- src/sound/snd_sb_dsp.c | 511 ++++---- src/sound/sound.c | 290 +++-- src/sound/xaudio2.c | 76 +- 47 files changed, 4000 insertions(+), 1343 deletions(-) create mode 100644 src/include/86box/scsi_ncr53c400.h diff --git a/src/86box.c b/src/86box.c index 67d0bb165..61b81bbf3 100644 --- a/src/86box.c +++ b/src/86box.c @@ -208,6 +208,11 @@ int do_auto_pause = 0; /* (C) Auto-pa loss */ char uuid[MAX_UUID_LEN] = { '\0' }; /* (C) UUID or machine identifier */ +int other_ide_present = 0; /* IDE controllers from non-IDE cards are + present */ +int other_scsi_present = 0; /* SCSI controllers from non-SCSI cards are + present */ + /* Statistics. */ extern int mmuflush; extern int readlnum; @@ -1080,18 +1085,22 @@ pc_reset_hard_close(void) /* Close all the memory mappings. */ mem_close(); + suppress_overscan = 0; + /* Turn off timer processing to avoid potential segmentation faults. */ timer_close(); - suppress_overscan = 0; + lpt_devices_close(); + +#ifdef UNCOMMENT_LATER + lpt_close(); +#endif nvr_save(); nvr_close(); mouse_close(); - lpt_devices_close(); - device_close_all(); scsi_device_close_all(); @@ -1132,6 +1141,9 @@ pc_reset_hard_init(void) * modules that are. */ + /* Reset the IDE and SCSI presences */ + other_ide_present = other_scsi_present = 0; + /* Mark ACPI as unavailable */ acpi_enabled = 0; diff --git a/src/config.c b/src/config.c index df0ae1c35..02c1d276a 100644 --- a/src/config.c +++ b/src/config.c @@ -745,7 +745,6 @@ load_ports(void) char *p; char temp[512]; int c; - int d; memset(temp, 0, sizeof(temp)); @@ -768,14 +767,6 @@ load_ports(void) p = ini_section_get_string(cat, temp, "none"); lpt_ports[c].device = lpt_device_get_from_internal_name(p); } - - /* Legacy config compatibility. */ - d = ini_section_get_int(cat, "lpt_enabled", 2); - if (d < 2) { - for (c = 0; c < PARALLEL_MAX; c++) - lpt_ports[c].enabled = d; - } - ini_section_delete_var(cat, "lpt_enabled"); } /* Load "Storage Controllers" section. */ @@ -790,7 +781,7 @@ load_storage_controllers(void) int min = 0; int free_p = 0; - for (c = min; c < SCSI_BUS_MAX; c++) { + for (c = min; c < SCSI_CARD_MAX; c++) { sprintf(temp, "scsicard_%d", c + 1); p = ini_section_get_string(cat, temp, NULL); @@ -2288,7 +2279,7 @@ save_storage_controllers(void) ini_section_delete_var(cat, "scsicard"); - for (c = 0; c < SCSI_BUS_MAX; c++) { + for (c = 0; c < SCSI_CARD_MAX; c++) { sprintf(temp, "scsicard_%d", c + 1); if (scsi_card_current[c] == 0) diff --git a/src/device.c b/src/device.c index 321f105e5..14380f6c5 100644 --- a/src/device.c +++ b/src/device.c @@ -51,6 +51,8 @@ #include <86box/ini.h> #include <86box/config.h> #include <86box/device.h> +#include <86box/timer.h> +#include <86box/lpt.h> #include <86box/machine.h> #include <86box/mem.h> #include <86box/rom.h> @@ -345,6 +347,10 @@ device_reset_all(uint32_t match_flags) devices[c]->reset(device_priv[c]); } } + + /* TODO: Actually convert the LPT devices to device_t's. */ + if ((match_flags == DEVICE_ALL) || (match_flags == DEVICE_PCI)) + lpt_reset(); } void * diff --git a/src/dma.c b/src/dma.c index ebe75bba6..318c6cda2 100644 --- a/src/dma.c +++ b/src/dma.c @@ -22,6 +22,7 @@ #include #include #include +#define HAVE_STDARG_H #include <86box/86box.h> #include "cpu.h" #include "x86.h" diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index 3f5f3f2ab..f76d70797 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -149,6 +149,8 @@ extern int confirm_reset; /* (C) enable reset confirmation */ extern int confirm_exit; /* (C) enable exit confirmation */ extern int confirm_save; /* (C) enable save confirmation */ extern int enable_discord; /* (C) enable Discord integration */ +extern int other_ide_present; /* IDE controllers from non-IDE cards are present */ +extern int other_scsi_present; /* SCSI controllers from non-SCSI cards are present */ extern int fixed_size_x; extern int fixed_size_y; diff --git a/src/include/86box/device.h b/src/include/86box/device.h index bd39a02e4..cc564ceb2 100644 --- a/src/include/86box/device.h +++ b/src/include/86box/device.h @@ -57,6 +57,7 @@ #define CONFIG_MIDI_OUT (3 | CONFIG_TYPE_INT) /* config_get_int() */ #define CONFIG_SPINNER (4 | CONFIG_TYPE_INT) /* config_get_int() */ #define CONFIG_MIDI_IN (5 | CONFIG_TYPE_INT) /* config_get_int() */ +#define CONFIG_MEMORY (6 | CONFIG_TYPE_INT) /* config_get_int() */ #define CONFIG_STRING (0 | CONFIG_TYPE_STRING) /* config_get_string() */ #define CONFIG_FNAME (1 | CONFIG_TYPE_STRING) /* config_get_string() */ diff --git a/src/include/86box/filters.h b/src/include/86box/filters.h index 0aa1c17f1..d11e79512 100644 --- a/src/include/86box/filters.h +++ b/src/include/86box/filters.h @@ -197,8 +197,8 @@ low_iir(int c, int i, double NewSample) 0.93726236021404663000 }; - static double y[4][2][NCoef + 1]; /* output samples */ - static double x[4][2][NCoef + 1]; /* input samples */ + static double y[5][2][NCoef + 1]; /* output samples */ + static double x[5][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -232,8 +232,8 @@ low_cut_iir(int c, int i, double NewSample) 0.93726236021916731000 }; - static double y[4][2][NCoef + 1]; /* output samples */ - static double x[4][2][NCoef + 1]; /* input samples */ + static double y[5][2][NCoef + 1]; /* output samples */ + static double x[5][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -266,8 +266,8 @@ high_iir(int c, int i, double NewSample) -1.36640781670578510000, 0.52352474706139873000 }; - static double y[4][2][NCoef + 1]; /* output samples */ - static double x[4][2][NCoef + 1]; /* input samples */ + static double y[5][2][NCoef + 1]; /* output samples */ + static double x[5][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -300,8 +300,8 @@ high_cut_iir(int c, int i, double NewSample) -1.36640781666419950000, 0.52352474703279628000 }; - static double y[4][2][NCoef + 1]; /* output samples */ - static double x[4][2][NCoef + 1]; /* input samples */ + static double y[5][2][NCoef + 1]; /* output samples */ + static double x[5][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -334,8 +334,8 @@ deemph_iir(int i, double NewSample) -1.05429146278569141337, 0.26412280202756849290 }; - static double y[4][NCoef + 1]; /* output samples */ - static double x[4][NCoef + 1]; /* input samples */ + static double y[5][NCoef + 1]; /* output samples */ + static double x[5][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -372,8 +372,8 @@ sb_iir(int c, int i, double NewSample) 0.55326988968868285000 }; - static double y[4][2][NCoef + 1]; /* output samples */ - static double x[4][2][NCoef + 1]; /* input samples */ + static double y[5][2][NCoef + 1]; /* output samples */ + static double x[5][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -395,7 +395,7 @@ sb_iir(int c, int i, double NewSample) #define NCoef 1 #define SB16_NCoef 51 -extern double low_fir_sb16_coef[4][SB16_NCoef]; +extern double low_fir_sb16_coef[5][SB16_NCoef]; static inline double low_fir_sb16(int c, int i, double NewSample) @@ -422,28 +422,28 @@ low_fir_sb16(int c, int i, double NewSample) return out; } -extern double low_fir_pas16_coef[4][SB16_NCoef]; +extern double low_fir_pas16_coef[SB16_NCoef]; static inline double -low_fir_pas16(int c, int i, double NewSample) +low_fir_pas16(const int i, const double NewSample) { - static double x[4][2][SB16_NCoef + 1]; // input samples - static int pos[4] = { 0, 0, 0, 0 }; - double out = 0.0; + static double x[2][SB16_NCoef + 1]; // input samples + static int pos = 0; + double out = 0.0; int n; /* Calculate the new output */ - x[c][i][pos[c]] = NewSample; + x[i][pos] = NewSample; - for (n = 0; n < ((SB16_NCoef + 1) - pos[c]) && n < SB16_NCoef; n++) - out += low_fir_pas16_coef[c][n] * x[c][i][n + pos[c]]; + for (n = 0; n < ((SB16_NCoef + 1) - pos) && n < SB16_NCoef; n++) + out += low_fir_pas16_coef[n] * x[i][n + pos]; for (; n < SB16_NCoef; n++) - out += low_fir_pas16_coef[c][n] * x[c][i][(n + pos[c]) - (SB16_NCoef + 1)]; + out += low_fir_pas16_coef[n] * x[i][(n + pos) - (SB16_NCoef + 1)]; if (i == 1) { - pos[c]++; - if (pos[c] > SB16_NCoef) - pos[c] = 0; + pos++; + if (pos > SB16_NCoef) + pos = 0; } return out; diff --git a/src/include/86box/pit.h b/src/include/86box/pit.h index 4129a1093..eb03fd2c9 100644 --- a/src/include/86box/pit.h +++ b/src/include/86box/pit.h @@ -114,6 +114,7 @@ extern double AGPCLK; extern uint64_t PITCONST; extern uint64_t PAS16CONST; extern uint64_t PAS16CONST2; +extern uint64_t PASSCSICONST; extern uint64_t ISACONST; extern uint64_t CGACONST; extern uint64_t MDACONST; diff --git a/src/include/86box/scsi.h b/src/include/86box/scsi.h index 376ac79b9..32ad1f912 100644 --- a/src/include/86box/scsi.h +++ b/src/include/86box/scsi.h @@ -22,12 +22,14 @@ #define EMU_SCSI_H /* Configuration. */ -#define SCSI_BUS_MAX 4 /* currently we support up to 4 controllers */ +#define SCSI_CARD_MAX 4 +#define SCSI_BUS_MAX 9 /* currently we support up to 9 controllers: + up to 1 on-board + up to 4x pas plus/16 + up to 4 scsi controllers */ -#define SCSI_ID_MAX 16 /* 16 on wide buses */ -#define SCSI_LUN_MAX 8 /* always 8 */ +#define SCSI_ID_MAX 16 /* 16 on wide buses */ +#define SCSI_LUN_MAX 8 /* always 8 */ -extern int scsi_card_current[SCSI_BUS_MAX]; +extern int scsi_card_current[SCSI_CARD_MAX]; extern int scsi_card_available(int card); #ifdef EMU_DEVICE_H diff --git a/src/include/86box/scsi_ncr5380.h b/src/include/86box/scsi_ncr5380.h index a213e299d..55c3bf3c5 100644 --- a/src/include/86box/scsi_ncr5380.h +++ b/src/include/86box/scsi_ncr5380.h @@ -88,6 +88,7 @@ typedef struct ncr_t { uint8_t target_id; uint8_t tx_data; uint8_t msglun; + uint8_t irq_state; uint8_t command[20]; uint8_t msgout[4]; @@ -108,10 +109,14 @@ typedef struct ncr_t { int data_pos; int irq; + int simple_pseudo_dma; + + uint32_t block_count; double period; void *priv; + void (*dma_init_ext)(void *priv, void *ext_priv, int send); void (*dma_mode_ext)(void *priv, void *ext_priv); int (*dma_send_ext)(void *priv, void *ext_priv); int (*dma_initiator_receive_ext)(void *priv, void *ext_priv); @@ -121,10 +126,12 @@ typedef struct ncr_t { extern int ncr5380_cmd_len[8]; extern void ncr5380_irq(ncr_t *ncr, int set_irq); +extern void ncr5380_set_irq(ncr_t *ncr, int irq); extern uint32_t ncr5380_get_bus_host(ncr_t *ncr); extern void ncr5380_bus_read(ncr_t *ncr); extern void ncr5380_bus_update(ncr_t *ncr, int bus); extern void ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr); +extern uint8_t ncr5380_drq(ncr_t *ncr); extern uint8_t ncr5380_read(uint16_t port, ncr_t *ncr); #ifdef EMU_DEVICE_H @@ -138,6 +145,7 @@ extern const device_t scsi_ls2000_device; #if defined(DEV_BRANCH) && defined(USE_SUMO) extern const device_t scsi_scsiat_device; #endif +extern const device_t scsi_pas_device; #endif #endif /*SCSI_NCR5380_H*/ diff --git a/src/include/86box/scsi_ncr53c400.h b/src/include/86box/scsi_ncr53c400.h new file mode 100644 index 000000000..9a5315990 --- /dev/null +++ b/src/include/86box/scsi_ncr53c400.h @@ -0,0 +1,62 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the NCR 53c400 series of SCSI Host Adapters + * made by NCR. These controllers were designed for the ISA and MCA bus. + * + * Authors: Sarah Walker, + * TheCollector1995, + * Fred N. van Kempen, + * + * Copyright 2017-2018 Sarah Walker. + * Copyright 2017-2018 Fred N. van Kempen. + * Copyright 2017-2024 TheCollector1995. + */ + +#ifndef SCSI_NCR53C400_H +#define SCSI_NCR53C400_H + +typedef struct ncr53c400_t { + rom_t bios_rom; + mem_mapping_t mapping; + ncr_t ncr; + uint8_t buffer[512]; + uint8_t int_ram[0x40]; + uint8_t ext_ram[0x600]; + + uint32_t rom_addr; + uint16_t base; + + int8_t type; + uint8_t block_count; + uint8_t status_ctrl; + + int simple_ctrl; + + int block_count_loaded; + + int buffer_pos; + int buffer_host_pos; + + int busy; + uint8_t pos_regs[8]; + + pc_timer_t timer; +} ncr53c400_t; + +#define CTRL_DATA_DIR 0x40 +#define STATUS_BUFFER_NOT_READY 0x04 +#define STATUS_5380_ACCESSIBLE 0x80 + +extern void ncr53c400_simple_write(uint8_t val, void *priv); +extern void ncr53c400_write(uint32_t addr, uint8_t val, void *priv); +extern uint8_t ncr53c400_simple_read(void *priv); +extern uint8_t ncr53c400_read(uint32_t addr, void *priv); +extern void ncr53c400_callback(void *priv); + +#endif /*SCSI_NCR53C400_H*/ diff --git a/src/include/86box/snd_emu8k.h b/src/include/86box/snd_emu8k.h index d226ed8db..4bad23b97 100644 --- a/src/include/86box/snd_emu8k.h +++ b/src/include/86box/snd_emu8k.h @@ -390,12 +390,12 @@ typedef struct emu8k_t { int16_t out_r; emu8k_chorus_eng_t chorus_engine; - int32_t chorus_in_buffer[SOUNDBUFLEN]; + int32_t chorus_in_buffer[WTBUFLEN]; emu8k_reverb_eng_t reverb_engine; - int32_t reverb_in_buffer[SOUNDBUFLEN]; + int32_t reverb_in_buffer[WTBUFLEN]; int pos; - int32_t buffer[SOUNDBUFLEN * 2]; + int32_t buffer[WTBUFLEN * 2]; uint16_t addr; } emu8k_t; diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index a00f512a3..c179fd197 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -4,13 +4,16 @@ #include <86box/fifo.h> /*Sound Blaster Clones, for quirks*/ -#define SB_SUBTYPE_DEFAULT 0 /*Handle as a Creative card*/ -#define SB_SUBTYPE_CLONE_AZT2316A_0X11 1 /*Aztech Sound Galaxy Pro 16 AB, DSP 3.1 - SBPRO2 clone*/ -#define SB_SUBTYPE_CLONE_AZT1605_0X0C 2 /*Aztech Sound Galaxy Nova 16 Extra / Packard Bell Forte 16, DSP 2.1 - SBPRO2 clone*/ -#define SB_SUBTYPE_ESS_ES1688 3 /* ESS Technology ES1688 */ +#define SB_SUBTYPE_DEFAULT 0 /* Handle as a Creative card */ +#define SB_SUBTYPE_CLONE_AZT2316A_0X11 1 /* Aztech Sound Galaxy Pro 16 AB, DSP 3.1 - SBPRO2 clone */ +#define SB_SUBTYPE_CLONE_AZT1605_0X0C 2 /* Aztech Sound Galaxy Nova 16 Extra / + Packard Bell Forte 16, DSP 2.1 - SBPRO2 clone */ +#define SB_SUBTYPE_ESS_ES688 3 /* ESS Technology ES688 */ +#define SB_SUBTYPE_ESS_ES1688 4 /* ESS Technology ES1688 */ /* ESS-related */ -#define IS_ESS(dsp) ((dsp)->sb_subtype == SB_SUBTYPE_ESS_ES1688) /* check for future ESS cards here */ +#define IS_ESS(dsp) ((dsp)->sb_subtype >= SB_SUBTYPE_ESS_ES688) /* Check for future ESS cards here */ +#define IS_NOT_ESS(dsp) ((dsp)->sb_subtype < SB_SUBTYPE_ESS_ES688) /* Check for future ESS cards here */ /* aztech-related */ #define IS_AZTECH(dsp) ((dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11 || (dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) /* check for future AZT cards here */ @@ -51,6 +54,10 @@ typedef struct sb_dsp_t { void *dma_priv; uint8_t sb_read_data[256]; + + uint8_t dma_ff; + int dma_data; + int sb_read_wp; int sb_read_rp; int sb_speaker; @@ -116,6 +123,8 @@ typedef struct sb_dsp_t { int sbenable; int sb_enable_i; + int state; + pc_timer_t output_timer; pc_timer_t input_timer; diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index 5f04c10fe..9ede638e5 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -39,6 +39,9 @@ extern int sound_gain; #define CD_FREQ FREQ_44100 #define CD_BUFLEN (CD_FREQ / 10) +#define WT_FREQ FREQ_44100 +#define WTBUFLEN (MUSIC_FREQ / 45) + enum { SOUND_NONE = 0, SOUND_INTERNAL @@ -50,7 +53,9 @@ extern int speakval; extern int speakon; extern int sound_pos_global; + extern int music_pos_global; +extern int wavetable_pos_global; extern int sound_card_current[SOUND_CARD_MAX]; @@ -62,6 +67,10 @@ extern void music_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *priv), void *priv); +extern void wavetable_add_handler(void (*get_buffer)(int32_t *buffer, + int len, void *priv), + void *priv); + extern void sound_set_cd_audio_filter(void (*filter)(int channel, double *buffer, void *priv), void *priv); @@ -94,9 +103,10 @@ extern void sound_cd_thread_reset(void); extern void closeal(void); extern void inital(void); -extern void givealbuffer(void *buf); -extern void givealbuffer_music(void *buf); -extern void givealbuffer_cd(void *buf); +extern void givealbuffer(const void *buf); +extern void givealbuffer_music(const void *buf); +extern void givealbuffer_wt(const void *buf); +extern void givealbuffer_cd(const void *buf); #define sb_vibra16c_onboard_relocate_base sb_vibra16s_onboard_relocate_base extern void sb_vibra16s_onboard_relocate_base(uint16_t new_addr, void *priv); @@ -113,30 +123,16 @@ extern const device_t acermagic_s20_device; extern const device_t mirosound_pcm10_device; extern const device_t azt1605_device; -/* Ensoniq AudioPCI */ -extern const device_t es1371_device; -extern const device_t es1371_onboard_device; +/* C-Media CMI8x38 */ +extern const device_t cmi8338_device; +extern const device_t cmi8338_onboard_device; +extern const device_t cmi8738_device; +extern const device_t cmi8738_onboard_device; +extern const device_t cmi8738_6ch_onboard_device; /* Creative Labs Game Blaster */ extern const device_t cms_device; -/* Gravis UltraSound and UltraSound Max */ -extern const device_t gus_device; - -/* Pro Audio Spectrum 16 */ -extern const device_t pasplus_device; -extern const device_t pas16_device; - -/* IBM PS/1 Audio Card */ -extern const device_t ps1snd_device; - -/* Tandy PSSJ */ -extern const device_t pssj_device; -extern const device_t pssj_isa_device; - -/* Tandy PSG */ -extern const device_t tndy_device; - /* Creative Labs Sound Blaster */ extern const device_t sb_1_device; extern const device_t sb_15_device; @@ -163,13 +159,6 @@ extern const device_t sb_awe64_value_device; extern const device_t sb_awe64_device; extern const device_t sb_awe64_gold_device; -/* Innovation SSI-2001 */ -extern const device_t ssi2001_device; - -/* Windows Sound System */ -extern const device_t wss_device; -extern const device_t ncr_business_audio_device; - /* Crystal CS423x */ extern const device_t cs4235_device; extern const device_t cs4235_onboard_device; @@ -177,15 +166,43 @@ extern const device_t cs4236b_device; extern const device_t cs4237b_device; extern const device_t cs4238b_device; -/* C-Media CMI8x38 */ -extern const device_t cmi8338_device; -extern const device_t cmi8338_onboard_device; -extern const device_t cmi8738_device; -extern const device_t cmi8738_onboard_device; -extern const device_t cmi8738_6ch_onboard_device; - /* ESS Technology */ +extern const device_t ess_688_device; +extern const device_t ess_ess0100_pnp_device; extern const device_t ess_1688_device; +extern const device_t ess_ess0102_pnp_device; +extern const device_t ess_ess0968_pnp_device; +extern const device_t ess_soundpiper_16_mca_device; +extern const device_t ess_soundpiper_32_mca_device; +extern const device_t ess_chipchat_16_mca_device; + +/* Ensoniq AudioPCI */ +extern const device_t es1371_device; +extern const device_t es1371_onboard_device; + +/* Gravis UltraSound and UltraSound Max */ +extern const device_t gus_device; + +/* IBM PS/1 Audio Card */ +extern const device_t ps1snd_device; + +/* Innovation SSI-2001 */ +extern const device_t ssi2001_device; + +/* Pro Audio Spectrum 16 */ +extern const device_t pasplus_device; +extern const device_t pas16_device; + +/* Tandy PSSJ */ +extern const device_t pssj_device; +extern const device_t pssj_isa_device; + +/* Tandy PSG */ +extern const device_t tndy_device; + +/* Windows Sound System */ +extern const device_t wss_device; +extern const device_t ncr_business_audio_device; #endif diff --git a/src/pit.c b/src/pit.c index 7ae50f413..0816094cb 100644 --- a/src/pit.c +++ b/src/pit.c @@ -49,6 +49,7 @@ double cpuclock; double PITCONSTD; double PAS16CONSTD; double PAS16CONST2D; +double PASSCSICONSTD; double SYSCLK; double isa_timing; double bus_timing; @@ -60,6 +61,7 @@ double AGPCLK; uint64_t PITCONST; uint64_t PAS16CONST; uint64_t PAS16CONST2; +uint64_t PASSCSICONST; uint64_t ISACONST; uint64_t CGACONST; uint64_t MDACONST; @@ -1222,6 +1224,9 @@ pit_set_clock(uint32_t clock) PAS16CONST2D = (cpuclock / 1008000.0); PAS16CONST2 = (uint64_t) (PAS16CONST2D * (double) (1ULL << 32)); + PASSCSICONSTD = (cpuclock / (28224000.0 / 14.0)); + PASSCSICONST = (uint64_t) (PASSCSICONSTD * (double) (1ULL << 32)); + isa_timing = (cpuclock / (double) cpu_isa_speed); if (cpu_64bitbus) bus_timing = (cpuclock / (cpu_busspeed / 2)); diff --git a/src/qt/qt_deviceconfig.cpp b/src/qt/qt_deviceconfig.cpp index d2ae70245..def3a4385 100644 --- a/src/qt/qt_deviceconfig.cpp +++ b/src/qt/qt_deviceconfig.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -29,9 +30,7 @@ #include #include #include -#include #include -#include extern "C" { #include <86box/86box.h> @@ -87,10 +86,15 @@ EnumerateSerialDevices() #ifdef Q_OS_WINDOWS for (int i = 1; i < 256; i++) { devstr[0] = 0; - snprintf(devstr.data(), 1024, "\\\\.\\COM%d", i); - auto handle = CreateFileA(devstr.data(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, 0); - auto dwError = GetLastError(); - if (handle != INVALID_HANDLE_VALUE || (handle == INVALID_HANDLE_VALUE && ((dwError == ERROR_ACCESS_DENIED) || (dwError == ERROR_GEN_FAILURE) || (dwError == ERROR_SHARING_VIOLATION) || (dwError == ERROR_SEM_TIMEOUT)))) { + snprintf(devstr.data(), 1024, R"(\\.\COM%d)", i); + const auto handle = CreateFileA(devstr.data(), + GENERIC_READ | GENERIC_WRITE, 0, + nullptr, OPEN_EXISTING, + 0, nullptr); + const auto dwError = GetLastError(); + if ((handle != INVALID_HANDLE_VALUE) || (dwError == ERROR_ACCESS_DENIED) || + (dwError == ERROR_GEN_FAILURE) || (dwError == ERROR_SHARING_VIOLATION) || + (dwError == ERROR_SEM_TIMEOUT)) { if (handle != INVALID_HANDLE_VALUE) CloseHandle(handle); serialDevices.push_back(QString(devstr)); } @@ -108,233 +112,266 @@ EnumerateSerialDevices() } void -DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *settings) +DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) { - DeviceConfig dc(settings); - dc.setWindowTitle(QString("%1 Device Configuration").arg(device->name)); - int p; - int q; + auto * device_context = static_cast(dc); + const auto * config = static_cast(c); + const QString blank = ""; + int p; + int q; - device_context_t device_context; - device_set_context(&device_context, device, instance); - - auto device_label = new QLabel(device->name); - device_label->setAlignment(Qt::AlignCenter); - dc.ui->formLayout->addRow(device_label); - auto line = new QFrame; - line->setFrameShape(QFrame::HLine); - line->setFrameShadow(QFrame::Sunken); - dc.ui->formLayout->addRow(line); - const auto *config = device->config; while (config->type != -1) { + const int config_type = config->type & CONFIG_TYPE_MASK; + + /* Ignore options of the wrong class. */ + if (!!(config->type & CONFIG_DEP) != is_dep) + continue; + + /* If this is a BIOS-dependent option and it's BIOS, ignore it. */ + if (!!(config->type & CONFIG_DEP) && (config_type == CONFIG_BIOS)) + continue; + + const int config_major_type = (config_type >> CONFIG_SHIFT) << CONFIG_SHIFT; + + int value = 0; + auto selected = static_cast(blank.toStdString().c_str()); + + switch (config_major_type) { + default: + break; + case CONFIG_TYPE_INT: + value = config_get_int(device_context->name, const_cast(config->name), + config->default_int); + break; + case CONFIG_TYPE_HEX16: + value = config_get_hex16(device_context->name, const_cast(config->name), + config->default_int); + break; + case CONFIG_TYPE_HEX20: + value = config_get_hex20(device_context->name, const_cast(config->name), + config->default_int); + break; + case CONFIG_TYPE_STRING: + selected = config_get_string(device_context->name, const_cast(config->name), + const_cast(config->default_string)); + break; + } + switch (config->type) { + default: + break; case CONFIG_BINARY: - { - auto value = config_get_int(device_context.name, const_cast(config->name), config->default_int); - auto *cbox = new QCheckBox(); - cbox->setObjectName(config->name); - cbox->setChecked(value > 0); - dc.ui->formLayout->addRow(config->description, cbox); - break; - } + { + auto *cbox = new QCheckBox(); + cbox->setObjectName(config->name); + cbox->setChecked(value > 0); + this->ui->formLayout->addRow(config->description, cbox); + break; + } #ifdef USE_RTMIDI case CONFIG_MIDI_OUT: - { - auto *cbox = new QComboBox(); - cbox->setObjectName(config->name); - cbox->setMaxVisibleItems(30); - auto *model = cbox->model(); - int currentIndex = -1; - int selected = config_get_int(device_context.name, const_cast(config->name), config->default_int); - for (int i = 0; i < rtmidi_out_get_num_devs(); i++) { - char midiName[512] = { 0 }; - rtmidi_out_get_dev_name(i, midiName); + { + auto *cbox = new QComboBox(); + cbox->setObjectName(config->name); + cbox->setMaxVisibleItems(30); + auto *model = cbox->model(); + int currentIndex = -1; + for (int i = 0; i < rtmidi_out_get_num_devs(); i++) { + char midiName[512] = { 0 }; + rtmidi_out_get_dev_name(i, midiName); - Models::AddEntry(model, midiName, i); - if (selected == i) { - currentIndex = i; - } - } - dc.ui->formLayout->addRow(config->description, cbox); - cbox->setCurrentIndex(currentIndex); - break; + Models::AddEntry(model, midiName, i); + if (i == value) + currentIndex = i; } + this->ui->formLayout->addRow(config->description, cbox); + cbox->setCurrentIndex(currentIndex); + break; + } case CONFIG_MIDI_IN: - { - auto *cbox = new QComboBox(); - cbox->setObjectName(config->name); - cbox->setMaxVisibleItems(30); - auto *model = cbox->model(); - int currentIndex = -1; - int selected = config_get_int(device_context.name, const_cast(config->name), config->default_int); - for (int i = 0; i < rtmidi_in_get_num_devs(); i++) { - char midiName[512] = { 0 }; - rtmidi_in_get_dev_name(i, midiName); + { + auto *cbox = new QComboBox(); + cbox->setObjectName(config->name); + cbox->setMaxVisibleItems(30); + auto *model = cbox->model(); + int currentIndex = -1; + for (int i = 0; i < rtmidi_in_get_num_devs(); i++) { + char midiName[512] = { 0 }; + rtmidi_in_get_dev_name(i, midiName); - Models::AddEntry(model, midiName, i); - if (selected == i) { - currentIndex = i; - } - } - dc.ui->formLayout->addRow(config->description, cbox); - cbox->setCurrentIndex(currentIndex); - break; + Models::AddEntry(model, midiName, i); + if (i == value) + currentIndex = i; } + this->ui->formLayout->addRow(config->description, cbox); + cbox->setCurrentIndex(currentIndex); + break; + } #endif + case CONFIG_INT: case CONFIG_SELECTION: case CONFIG_HEX16: case CONFIG_HEX20: - { - auto *cbox = new QComboBox(); - cbox->setObjectName(config->name); - cbox->setMaxVisibleItems(30); - auto *model = cbox->model(); - int currentIndex = -1; - int selected = 0; - switch (config->type) { - case CONFIG_SELECTION: - selected = config_get_int(device_context.name, const_cast(config->name), config->default_int); - break; - case CONFIG_HEX16: - selected = config_get_hex16(device_context.name, const_cast(config->name), config->default_int); - break; - case CONFIG_HEX20: - selected = config_get_hex20(device_context.name, const_cast(config->name), config->default_int); - break; - } + { + auto *cbox = new QComboBox(); + cbox->setObjectName(config->name); + cbox->setMaxVisibleItems(30); + auto *model = cbox->model(); + int currentIndex = -1; - for (auto *sel = config->selection; (sel != nullptr) && (sel->description != nullptr) && (strlen(sel->description) > 0); ++sel) { - int row = Models::AddEntry(model, sel->description, sel->value); - if (selected == sel->value) { - currentIndex = row; - } - } - dc.ui->formLayout->addRow(config->description, cbox); - cbox->setCurrentIndex(currentIndex); - break; + for (auto *sel = config->selection; (sel != nullptr) && (sel->description != nullptr) && + (strlen(sel->description) > 0); ++sel) { + int row = Models::AddEntry(model, sel->description, sel->value); + + if (sel->value == value) + currentIndex = row; } + this->ui->formLayout->addRow(config->description, cbox); + cbox->setCurrentIndex(currentIndex); + break; + } case CONFIG_BIOS: - { - auto *cbox = new QComboBox(); - cbox->setObjectName(config->name); - cbox->setMaxVisibleItems(30); - auto *model = cbox->model(); - int currentIndex = -1; - char *selected; - selected = config_get_string(device_context.name, const_cast(config->name), const_cast(config->default_string)); + { + auto *cbox = new QComboBox(); + cbox->setObjectName(config->name); + cbox->setMaxVisibleItems(30); + auto *model = cbox->model(); + int currentIndex = -1; - q = 0; - for (auto *bios = config->bios; (bios != nullptr) && (bios->name != nullptr) && (strlen(bios->name) > 0); ++bios) { - p = 0; - for (int d = 0; d < bios->files_no; d++) - p += !!rom_present(const_cast(bios->files[d])); - if (p == bios->files_no) { - int row = Models::AddEntry(model, bios->name, q); - if (!strcmp(selected, bios->internal_name)) { - currentIndex = row; - } - } - q++; - } - dc.ui->formLayout->addRow(config->description, cbox); - cbox->setCurrentIndex(currentIndex); - break; - } - case CONFIG_SPINNER: - { - int value = config_get_int(device_context.name, const_cast(config->name), config->default_int); - auto *spinBox = new QSpinBox(); - spinBox->setObjectName(config->name); - spinBox->setMaximum(config->spinner.max); - spinBox->setMinimum(config->spinner.min); - if (config->spinner.step > 0) { - spinBox->setSingleStep(config->spinner.step); - } - spinBox->setValue(value); - dc.ui->formLayout->addRow(config->description, spinBox); - break; - } - case CONFIG_FNAME: - { - auto *fileName = config_get_string(device_context.name, const_cast(config->name), const_cast(config->default_string)); - auto *fileField = new FileField(); - fileField->setObjectName(config->name); - fileField->setFileName(fileName); - fileField->setFilter(QString(config->file_filter).left(strcspn(config->file_filter, "|"))); - dc.ui->formLayout->addRow(config->description, fileField); - break; - } - case CONFIG_STRING: - { - auto lineEdit = new QLineEdit; - lineEdit->setObjectName(config->name); - lineEdit->setCursor(Qt::IBeamCursor); - lineEdit->setText(config_get_string(device_context.name, const_cast(config->name), const_cast(config->default_string))); - dc.ui->formLayout->addRow(config->description, lineEdit); - break; - } - case CONFIG_SERPORT: - { - auto *cbox = new QComboBox(); - cbox->setObjectName(config->name); - cbox->setMaxVisibleItems(30); - auto *model = cbox->model(); - int currentIndex = 0; - auto serialDevices = EnumerateSerialDevices(); - char *selected = config_get_string(device_context.name, const_cast(config->name), const_cast(config->default_string)); - - Models::AddEntry(model, "None", -1); - for (int i = 0; i < serialDevices.size(); i++) { - int row = Models::AddEntry(model, serialDevices[i], i); - if (selected == serialDevices[i]) { + q = 0; + for (auto *bios = config->bios; (bios != nullptr) && (bios->name != nullptr) && + (strlen(bios->name) > 0); ++bios) { + p = 0; + for (int d = 0; d < bios->files_no; d++) + p += !!rom_present(const_cast(bios->files[d])); + if (p == bios->files_no) { + const int row = Models::AddEntry(model, bios->name, q); + if (!strcmp(selected, bios->internal_name)) currentIndex = row; - } } - - dc.ui->formLayout->addRow(config->description, cbox); - cbox->setCurrentIndex(currentIndex); - break; + q++; } + this->ui->formLayout->addRow(config->description, cbox); + cbox->setCurrentIndex(currentIndex); + break; + } + case CONFIG_SPINNER: + { + auto *spinBox = new QSpinBox(); + spinBox->setObjectName(config->name); + spinBox->setMaximum(config->spinner.max); + spinBox->setMinimum(config->spinner.min); + if (config->spinner.step > 0) + spinBox->setSingleStep(config->spinner.step); + spinBox->setValue(value); + this->ui->formLayout->addRow(config->description, spinBox); + break; + } + case CONFIG_FNAME: + { + auto *fileField = new FileField(); + fileField->setObjectName(config->name); + fileField->setFileName(selected); + fileField->setFilter(QString(config->file_filter).left(static_cast(strcspn(config->file_filter, + "|")))); + this->ui->formLayout->addRow(config->description, fileField); + break; + } + case CONFIG_STRING: + { + const auto lineEdit = new QLineEdit; + lineEdit->setObjectName(config->name); + lineEdit->setCursor(Qt::IBeamCursor); + lineEdit->setText(selected); + this->ui->formLayout->addRow(config->description, lineEdit); + break; + } + case CONFIG_SERPORT: + { + auto *cbox = new QComboBox(); + cbox->setObjectName(config->name); + cbox->setMaxVisibleItems(30); + auto *model = cbox->model(); + int currentIndex = 0; + auto serialDevices = EnumerateSerialDevices(); + + Models::AddEntry(model, "None", -1); + for (int i = 0; i < serialDevices.size(); i++) { + const int row = Models::AddEntry(model, serialDevices[i], i); + if (selected == serialDevices[i]) + currentIndex = row; + } + + this->ui->formLayout->addRow(config->description, cbox); + cbox->setCurrentIndex(currentIndex); + break; + } case CONFIG_MAC: { // QHBoxLayout for the line edit widget and the generate button - auto hboxLayout = new QHBoxLayout(); - auto generateButton = new QPushButton(tr("Generate")); - auto lineEdit = new QLineEdit; + const auto hboxLayout = new QHBoxLayout(); + const auto generateButton = new QPushButton(tr("Generate")); + const auto lineEdit = new QLineEdit; // Allow the line edit to expand and fill available space lineEdit->setSizePolicy(QSizePolicy::MinimumExpanding,QSizePolicy::Preferred); lineEdit->setInputMask("HH:HH:HH;0"); lineEdit->setObjectName(config->name); // Display the current or generated MAC in uppercase // When stored it will be converted to lowercase - if (config_get_mac(device_context.name, config->name, config->default_int) & 0xFF000000) { - lineEdit->setText(QString::asprintf("%02X:%02X:%02X", random_generate(), random_generate(), random_generate())); + if (config_get_mac(device_context->name, config->name, + config->default_int) & 0xFF000000) { + lineEdit->setText(QString::asprintf("%02X:%02X:%02X", random_generate(), + random_generate(), random_generate())); } else { - auto current_mac = QString(config_get_string(device_context.name, config->name, const_cast(config->default_string))); + auto current_mac = QString(config_get_string(device_context->name, config->name, + const_cast(config->default_string))); lineEdit->setText(current_mac.toUpper()); } // Action for the generate button connect(generateButton, &QPushButton::clicked, [lineEdit] { - lineEdit->setText(QString::asprintf("%02X:%02X:%02X", random_generate(), random_generate(), random_generate())); + lineEdit->setText(QString::asprintf("%02X:%02X:%02X", random_generate(), + random_generate(), random_generate())); }); hboxLayout->addWidget(lineEdit); hboxLayout->addWidget(generateButton); - dc.ui->formLayout->addRow(config->description, hboxLayout); + this->ui->formLayout->addRow(config->description, hboxLayout); break; } } ++config; } +} + +void +DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *settings) +{ + DeviceConfig dc(settings); + dc.setWindowTitle(QString("%1 Device Configuration").arg(device->name)); + + device_context_t device_context; + device_set_context(&device_context, device, instance); + + const auto device_label = new QLabel(device->name); + device_label->setAlignment(Qt::AlignCenter); + dc.ui->formLayout->addRow(device_label); + const auto line = new QFrame; + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + dc.ui->formLayout->addRow(line); + const _device_config_ *config = device->config; + + dc.ProcessConfig(&device_context, config, false); dc.setFixedSize(dc.minimumSizeHint()); - int res = dc.exec(); - if (res == QDialog::Accepted) { + if (dc.exec() == QDialog::Accepted) { config = device->config; while (config->type != -1) { switch (config->type) { + default: + break; case CONFIG_BINARY: { - auto *cbox = dc.findChild(config->name); + const auto *cbox = dc.findChild(config->name); config_set_int(device_context.name, const_cast(config->name), cbox->isChecked() ? 1 : 0); break; } @@ -408,15 +445,15 @@ DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *se } QString -DeviceConfig::DeviceName(const _device_ *device, const char *internalName, int bus) +DeviceConfig::DeviceName(const _device_ *device, const char *internalName, const int bus) { - if (QStringLiteral("none") == internalName) { + if (QStringLiteral("none") == internalName) return tr("None"); - } else if (QStringLiteral("internal") == internalName) { + else if (QStringLiteral("internal") == internalName) return tr("Internal controller"); - } else if (device == nullptr) { - return QString(); - } else { + else if (device == nullptr) + return ""; + else { char temp[512]; device_get_name(device, bus, temp); return tr(temp, nullptr, 512); diff --git a/src/qt/qt_deviceconfig.hpp b/src/qt/qt_deviceconfig.hpp index 1ed24d618..a16c152a6 100644 --- a/src/qt/qt_deviceconfig.hpp +++ b/src/qt/qt_deviceconfig.hpp @@ -20,13 +20,15 @@ class DeviceConfig : public QDialog { public: explicit DeviceConfig(QWidget *parent = nullptr); - ~DeviceConfig(); + ~DeviceConfig() override; - static void ConfigureDevice(const _device_ *device, int instance = 0, Settings *settings = nullptr); + static void ConfigureDevice(const _device_ *device, int instance = 0, + Settings *settings = nullptr); static QString DeviceName(const _device_ *device, const char *internalName, int bus); private: Ui::DeviceConfig *ui; + void ProcessConfig(void *dc, const void *c, bool is_dep); }; #endif // QT_DEVICECONFIG_HPP diff --git a/src/qt/qt_harddrive_common.cpp b/src/qt/qt_harddrive_common.cpp index 213ebf07b..e0b0233f1 100644 --- a/src/qt/qt_harddrive_common.cpp +++ b/src/qt/qt_harddrive_common.cpp @@ -20,6 +20,7 @@ extern "C" { #include <86box/hdd.h> +#include <86box/scsi.h> #include <86box/cdrom.h> } @@ -109,9 +110,16 @@ Harddrives::populateBusChannels(QAbstractItemModel *model, int bus, SettingsBusT QList channelsInUse; switch (bus) { case HDD_BUS_MFM: + busRows = 2; + busesToCheck.append(HDD_BUS_MFM); + break; case HDD_BUS_XTA: + busRows = 2; + busesToCheck.append(HDD_BUS_XTA); + break; case HDD_BUS_ESDI: busRows = 2; + busesToCheck.append(HDD_BUS_ESDI); break; case HDD_BUS_IDE: busRows = 8; @@ -126,7 +134,7 @@ Harddrives::populateBusChannels(QAbstractItemModel *model, int bus, SettingsBusT case HDD_BUS_SCSI: shifter = 4; orer = 15; - busRows = 64; + busRows = /*64*/ SCSI_BUS_MAX * SCSI_ID_MAX; subChannelWidth = 2; busesToCheck.append(HDD_BUS_SCSI); break; diff --git a/src/qt/qt_machinestatus.cpp b/src/qt/qt_machinestatus.cpp index dee487657..53e875e33 100644 --- a/src/qt/qt_machinestatus.cpp +++ b/src/qt/qt_machinestatus.cpp @@ -272,13 +272,13 @@ MachineStatus::hasCassette() bool MachineStatus::hasIDE() { - return machine_has_flags(machine, MACHINE_IDE_QUAD) > 0; + return (machine_has_flags(machine, MACHINE_IDE_QUAD) > 0) || other_ide_present; } bool MachineStatus::hasSCSI() { - return machine_has_flags(machine, MACHINE_SCSI) > 0; + return (machine_has_flags(machine, MACHINE_SCSI) > 0) || other_scsi_present; } void diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 78eaff5e9..dc8e1970f 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -91,26 +91,23 @@ void qt_set_sequence_auto_mnemonic(bool b); void main_thread_fn() { - uint64_t old_time; - uint64_t new_time; - int drawits; int frames; QThread::currentThread()->setPriority(QThread::HighestPriority); - plat_set_thread_name(NULL, "main_thread_fn"); + plat_set_thread_name(nullptr, "main_thread_fn"); framecountx = 0; // title_update = 1; - old_time = elapsed_timer.elapsed(); - drawits = frames = 0; + uint64_t old_time = elapsed_timer.elapsed(); + int drawits = frames = 0; while (!is_quit && cpu_thread_run) { /* See if it is time to run a frame of code. */ - new_time = elapsed_timer.elapsed(); + const uint64_t new_time = elapsed_timer.elapsed(); #ifdef USE_GDBSTUB if (gdbstub_next_asap && (drawits <= 0)) drawits = 10; else #endif - drawits += (new_time - old_time); + drawits += static_cast(new_time - old_time); old_time = new_time; if (drawits > 0 && !dopause) { /* Yes, so do one frame now. */ @@ -395,7 +392,7 @@ main(int argc, char *argv[]) plat_pause(0); }); - auto ret = app.exec(); + const auto ret = app.exec(); cpu_thread_run = 0; main_thread->join(); pc_close(nullptr); diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index f4c01b4a2..c48dfd052 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -91,6 +91,7 @@ extern int qt_nvr_save(void); #endif #include +#include #include #include "qt_settings.hpp" @@ -289,14 +290,15 @@ MainWindow::MainWindow(QWidget *parent) resizableonce = true; } if (!QApplication::platformName().contains("eglfs") && vid_resize != 1) { - w = (w / (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.)); + w = static_cast(w / (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.)); - int modifiedHeight = (h / (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.)) + const int modifiedHeight = + static_cast(h / (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.)) + menuBar()->height() + (statusBar()->height() * !hide_status_bar) + (ui->toolBar->height() * !hide_tool_bar); - ui->stackedWidget->resize(w, (h / (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.))); + ui->stackedWidget->resize(w, static_cast(h / (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.))); setFixedSize(w, modifiedHeight); } }); @@ -306,9 +308,9 @@ MainWindow::MainWindow(QWidget *parent) #ifdef QT_RESIZE_DEBUG qDebug() << "Resize"; #endif - w = (w / (!dpi_scale ? util::screenOfWidget(renderers[monitor_index].get())->devicePixelRatio() : 1.)); + w = static_cast(w / (!dpi_scale ? util::screenOfWidget(renderers[monitor_index].get())->devicePixelRatio() : 1.)); - int modifiedHeight = (h / (!dpi_scale ? util::screenOfWidget(renderers[monitor_index].get())->devicePixelRatio() : 1.)); + int modifiedHeight = static_cast(h / (!dpi_scale ? util::screenOfWidget(renderers[monitor_index].get())->devicePixelRatio() : 1.)); renderers[monitor_index]->setFixedSize(w, modifiedHeight); } @@ -394,9 +396,7 @@ MainWindow::MainWindow(QWidget *parent) ui->actionVulkan->setVisible(false); } - QActionGroup *actGroup = nullptr; - - actGroup = new QActionGroup(this); + auto actGroup = new QActionGroup(this); actGroup->addAction(ui->actionSoftware_Renderer); actGroup->addAction(ui->actionHardware_Renderer_OpenGL); actGroup->addAction(ui->actionHardware_Renderer_OpenGL_ES); @@ -418,6 +418,8 @@ MainWindow::MainWindow(QWidget *parent) #endif RendererStack::Renderer newVidApi = RendererStack::Renderer::Software; switch (vid_api) { + default: + break; case 0: newVidApi = RendererStack::Renderer::Software; break; @@ -457,7 +459,7 @@ MainWindow::MainWindow(QWidget *parent) }); /* Trigger initial renderer switch */ - for (auto action : actGroup->actions()) + for (const auto action : actGroup->actions()) if (action->property("vid_api").toInt() == vid_api) { action->setChecked(true); emit actGroup->triggered(action); @@ -465,6 +467,8 @@ MainWindow::MainWindow(QWidget *parent) } switch (scale) { + default: + break; case 0: ui->action0_5x->setChecked(true); break; @@ -508,6 +512,8 @@ MainWindow::MainWindow(QWidget *parent) actGroup->addAction(ui->action7x); actGroup->addAction(ui->action8x); switch (video_filter_method) { + default: + break; case 0: ui->actionNearest->setChecked(true); break; @@ -519,6 +525,8 @@ MainWindow::MainWindow(QWidget *parent) actGroup->addAction(ui->actionNearest); actGroup->addAction(ui->actionLinear); switch (video_fullscreen_scale) { + default: + break; case FULLSCR_SCALE_FULL: ui->actionFullScreen_stretch->setChecked(true); break; @@ -542,6 +550,8 @@ MainWindow::MainWindow(QWidget *parent) actGroup->addAction(ui->actionFullScreen_int); actGroup->addAction(ui->actionFullScreen_int43); switch (video_grayscale) { + default: + break; case 0: ui->actionRGB_Color->setChecked(true); break; @@ -565,6 +575,8 @@ MainWindow::MainWindow(QWidget *parent) actGroup->addAction(ui->actionWhite_monitor); actGroup->addAction(ui->actionRGB_Color); switch (video_graytype) { + default: + break; case 0: ui->actionBT601_NTSC_PAL->setChecked(true); break; @@ -722,7 +734,7 @@ MainWindow::closeEvent(QCloseEvent *event) if (confirm_exit && confirm_exit_cmdl && cpu_thread_run) { QMessageBox questionbox(QMessageBox::Icon::Question, "86Box", tr("Are you sure you want to exit 86Box?"), QMessageBox::Yes | QMessageBox::No, this); - QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); + auto chkbox = new QCheckBox(tr("Don't show this message again")); questionbox.setCheckBox(chkbox); chkbox->setChecked(!confirm_exit); @@ -771,7 +783,7 @@ void MainWindow::initRendererMonitorSlot(int monitor_index) { auto &secondaryRenderer = this->renderers[monitor_index]; - secondaryRenderer.reset(new RendererStack(nullptr, monitor_index)); + secondaryRenderer = std::make_unique(nullptr, monitor_index); if (secondaryRenderer) { connect(secondaryRenderer.get(), &RendererStack::rendererChanged, this, [this, monitor_index] { this->renderers[monitor_index]->show(); @@ -779,9 +791,8 @@ MainWindow::initRendererMonitorSlot(int monitor_index) secondaryRenderer->setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint); secondaryRenderer->setWindowTitle(QObject::tr("86Box Monitor #") + QString::number(monitor_index + 1)); - if (vid_resize == 2) { + if (vid_resize == 2) secondaryRenderer->setFixedSize(fixed_size_x, fixed_size_y); - } secondaryRenderer->setWindowIcon(this->windowIcon()); if (show_second_monitors) { secondaryRenderer->show(); @@ -791,9 +802,8 @@ MainWindow::initRendererMonitorSlot(int monitor_index) monitor_settings[monitor_index].mon_window_w > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_w, monitor_settings[monitor_index].mon_window_h > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_h); } - if (monitor_settings[monitor_index].mon_window_maximized) { + if (monitor_settings[monitor_index].mon_window_maximized) secondaryRenderer->showMaximized(); - } secondaryRenderer->switchRenderer((RendererStack::Renderer) vid_api); secondaryRenderer->setMouseTracking(true); @@ -877,7 +887,7 @@ MainWindow::on_actionHard_Reset_triggered() QMessageBox questionbox(QMessageBox::Icon::Question, "86Box", tr("Are you sure you want to hard reset the emulated machine?"), QMessageBox::NoButton, this); questionbox.addButton(tr("Reset"), QMessageBox::AcceptRole); questionbox.addButton(tr("Don't reset"), QMessageBox::RejectRole); - QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); + const auto chkbox = new QCheckBox(tr("Don't show this message again")); questionbox.setCheckBox(chkbox); chkbox->setChecked(!confirm_reset); @@ -921,7 +931,7 @@ MainWindow::on_actionExit_triggered() void MainWindow::on_actionSettings_triggered() { - int currentPause = dopause; + const int currentPause = dopause; plat_pause(1); Settings settings(this); settings.setModal(true); @@ -932,6 +942,8 @@ MainWindow::on_actionSettings_triggered() settings.exec(); switch (settings.result()) { + default: + break; case QDialog::Accepted: pc_reset_hard_close(); settings.save(); @@ -968,6 +980,9 @@ MainWindow::processKeyboardInput(bool down, uint32_t keycode) /* Apply special cases. */ switch (keycode) { + default: + break; + case 0x54: /* Alt + Print Screen (special case, i.e. evdev SELECTIVE_SCREENSHOT) */ /* Send Alt as well. */ if (down) { @@ -1333,18 +1348,18 @@ MainWindow::checkFullscreenHotkey() { if (!fs_off_signal && video_fullscreen && keyboard_isfsexit()) { /* Signal "exit fullscreen mode". */ - fs_off_signal = 1; + fs_off_signal = true; } else if (fs_off_signal && video_fullscreen && keyboard_isfsexit_up()) { ui->actionFullscreen->trigger(); - fs_off_signal = 0; + fs_off_signal = false; } if (!fs_on_signal && !video_fullscreen && keyboard_isfsenter()) { /* Signal "enter fullscreen mode". */ - fs_on_signal = 1; + fs_on_signal = true; } else if (fs_on_signal && !video_fullscreen && keyboard_isfsenter_up()) { ui->actionFullscreen->trigger(); - fs_on_signal = 0; + fs_on_signal = false; } } @@ -1699,7 +1714,7 @@ MainWindow::on_actionAbout_86Box_triggered() msgBox.setInformativeText(tr("An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information.")); msgBox.setWindowTitle("About 86Box"); msgBox.addButton("OK", QMessageBox::ButtonRole::AcceptRole); - auto webSiteButton = msgBox.addButton(EMU_SITE, QMessageBox::ButtonRole::HelpRole); + const auto webSiteButton = msgBox.addButton(EMU_SITE, QMessageBox::ButtonRole::HelpRole); webSiteButton->connect(webSiteButton, &QPushButton::released, []() { QDesktopServices::openUrl(QUrl("https://" EMU_SITE)); }); @@ -1847,8 +1862,8 @@ void MainWindow::on_actionTake_screenshot_triggered() { startblit(); - for (int i = 0; i < MONITORS_NUM; i++) - monitors[i].mon_screenshots++; + for (auto & monitor : monitors) + ++monitor.mon_screenshots; endblit(); device_force_redraw(); } @@ -1869,8 +1884,10 @@ MainWindow::setSendKeyboardInput(bool enabled) void MainWindow::updateUiPauseState() { - auto pause_icon = dopause ? QIcon(":/menuicons/qt/icons/run.ico") : QIcon(":/menuicons/qt/icons/pause.ico"); - auto tooltip_text = dopause ? QString(tr("Resume execution")) : QString(tr("Pause execution")); + const auto pause_icon = dopause ? QIcon(":/menuicons/qt/icons/run.ico") : + QIcon(":/menuicons/qt/icons/pause.ico"); + const auto tooltip_text = dopause ? QString(tr("Resume execution")) : + QString(tr("Pause execution")); ui->actionPause->setIcon(pause_icon); ui->actionPause->setToolTip(tooltip_text); } @@ -1932,9 +1949,7 @@ MainWindow::changeEvent(QEvent *event) void MainWindow::on_actionRenderer_options_triggered() { - auto dlg = ui->stackedWidget->getOptions(this); - - if (dlg) { + if (const auto dlg = ui->stackedWidget->getOptions(this)) { if (dlg->exec() == QDialog::Accepted) { for (int i = 1; i < MONITORS_NUM; i++) { if (renderers[i] && renderers[i]->hasOptions()) @@ -1947,20 +1962,18 @@ MainWindow::on_actionRenderer_options_triggered() void MainWindow::on_actionMCA_devices_triggered() { - auto dlg = new MCADeviceList(this); - - if (dlg) + if (const auto dlg = new MCADeviceList(this)) dlg->exec(); } void MainWindow::on_actionShow_non_primary_monitors_triggered() { - show_second_monitors = (int) ui->actionShow_non_primary_monitors->isChecked(); + show_second_monitors = static_cast(ui->actionShow_non_primary_monitors->isChecked()); if (show_second_monitors) { for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) { - auto &secondaryRenderer = renderers[monitor_index]; + const auto &secondaryRenderer = renderers[monitor_index]; if (!renderers[monitor_index]) continue; secondaryRenderer->show(); @@ -1970,8 +1983,8 @@ MainWindow::on_actionShow_non_primary_monitors_triggered() monitor_settings[monitor_index].mon_window_w > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_w, monitor_settings[monitor_index].mon_window_h > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_h); } - secondaryRenderer->switchRenderer((RendererStack::Renderer) vid_api); - ui->stackedWidget->switchRenderer((RendererStack::Renderer) vid_api); + secondaryRenderer->switchRenderer(static_cast(vid_api)); + ui->stackedWidget->switchRenderer(static_cast(vid_api)); } } else { for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) { @@ -1992,7 +2005,7 @@ MainWindow::on_actionShow_non_primary_monitors_triggered() void MainWindow::on_actionOpen_screenshots_folder_triggered() { - QDir(QString(usr_path) + QString("/screenshots/")).mkpath("."); + static_cast(QDir(QString(usr_path) + QString("/screenshots/")).mkpath(".")); QDesktopServices::openUrl(QUrl(QString("file:///") + usr_path + QString("/screenshots/"))); } @@ -2001,7 +2014,7 @@ MainWindow::on_actionApply_fullscreen_stretch_mode_when_maximized_triggered(bool { video_fullscreen_scale_maximized = checked; - auto widget = ui->stackedWidget->currentWidget(); + const auto widget = ui->stackedWidget->currentWidget(); ui->stackedWidget->onResize(widget->width(), widget->height()); for (int i = 1; i < MONITORS_NUM; i++) { diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 950d145c1..1fca09231 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -73,7 +73,7 @@ private slots: void on_actionCtrl_Alt_Esc_triggered(); void on_actionHard_Reset_triggered(); void on_actionRight_CTRL_is_left_ALT_triggered(); - void on_actionKeyboard_requires_capture_triggered(); + static void on_actionKeyboard_requires_capture_triggered(); void on_actionResizable_window_triggered(bool checked); void on_actionInverted_VGA_monitor_triggered(); void on_action0_5x_triggered(); diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index af6d40e79..c4fd50567 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -252,7 +252,7 @@ void MediaMenu::cassetteUpdateMenu() { QString name = cassette_fname; - QString mode = cassette_mode; + const QString mode = cassette_mode; auto childs = cassetteMenu->children(); auto *recordMenu = dynamic_cast(childs[cassetteRecordPos]); auto *playMenu = dynamic_cast(childs[cassettePlayPos]); @@ -266,11 +266,12 @@ MediaMenu::cassetteUpdateMenu() fastFwdMenu->setEnabled(!name.isEmpty()); ejectMenu->setEnabled(!name.isEmpty()); - bool isSaving = mode == QStringLiteral("save"); + const bool isSaving = (mode == QStringLiteral("save")); recordMenu->setChecked(isSaving); playMenu->setChecked(!isSaving); - cassetteMenu->setTitle(QString::asprintf(tr("Cassette: %s").toUtf8().constData(), (name.isEmpty() ? tr("(empty)") : name).toUtf8().constData())); + cassetteMenu->setTitle(QString::asprintf(tr("Cassette: %s").toUtf8().constData(), + (name.isEmpty() ? tr("(empty)") : name).toUtf8().constData())); } void @@ -289,7 +290,7 @@ MediaMenu::cartridgeMount(int i, const QString &filename) void MediaMenu::cartridgeSelectImage(int i) { - auto filename = QFileDialog::getOpenFileName( + const auto filename = QFileDialog::getOpenFileName( parentWidget, QString(), getMediaOpenDirectory(), @@ -314,8 +315,8 @@ MediaMenu::cartridgeEject(int i) void MediaMenu::cartridgeUpdateMenu(int i) { - QString name = cart_fns[i]; - auto *menu = cartridgeMenus[i]; + const QString name = cart_fns[i]; + auto *menu = cartridgeMenus[i]; auto childs = menu->children(); auto *ejectMenu = dynamic_cast(childs[cartridgeEjectPos]); ejectMenu->setEnabled(!name.isEmpty()); @@ -328,8 +329,10 @@ MediaMenu::floppyNewImage(int i) { NewFloppyDialog dialog(NewFloppyDialog::MediaType::Floppy, parentWidget); switch (dialog.exec()) { + default: + break; case QDialog::Accepted: - QByteArray filename = dialog.fileName().toUtf8(); + const QByteArray filename = dialog.fileName().toUtf8(); floppyMount(i, filename, false); break; } @@ -516,7 +519,7 @@ MediaMenu::cdromEject(int i) void MediaMenu::cdromReload(int index, int slot) { - QString filename = mhm.getImageForSlot(index, slot, ui::MediaType::Optical); + const QString filename = mhm.getImageForSlot(index, slot, ui::MediaType::Optical); cdromMount(index, filename.toUtf8().constData()); cdromUpdateMenu(index); ui_sb_update_tip(SB_CDROM | index); @@ -572,7 +575,7 @@ MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) return; } - QString menu_item_name = fi.fileName().isEmpty() ? tr("previous image").toUtf8().constData() : fi.fileName().toUtf8().constData(); + const QString menu_item_name = fi.fileName().isEmpty() ? tr("previous image").toUtf8().constData() : fi.fileName().toUtf8().constData(); imageHistoryUpdatePos->setText(QString::asprintf(tr("%s").toUtf8().constData(), menu_item_name.toUtf8().constData())); imageHistoryUpdatePos->setVisible(!fi.fileName().isEmpty()); imageHistoryUpdatePos->setVisible(fi.exists()); @@ -602,8 +605,8 @@ MediaMenu::cdromUpdateMenu(int i) auto *imageMenu = dynamic_cast(childs[cdromImagePos]); imageMenu->setEnabled(!name.isEmpty()); - QString menu_item_name = name.isEmpty() ? QString().toUtf8().constData() : fi.fileName().toUtf8().constData(); - auto menu_icon = fi.isDir() ? QApplication::style()->standardIcon(QStyle::SP_DirIcon) : ProgSettings::loadIcon("/cdrom.ico"); + const QString menu_item_name = name.isEmpty() ? QString().toUtf8().constData() : fi.fileName().toUtf8().constData(); + const auto menu_icon = fi.isDir() ? QApplication::style()->standardIcon(QStyle::SP_DirIcon) : ProgSettings::loadIcon("/cdrom.ico"); imageMenu->setIcon(menu_icon); imageMenu->setText(QString::asprintf(tr("Eject %s").toUtf8().constData(), menu_item_name.toUtf8().constData())); @@ -613,15 +616,17 @@ MediaMenu::cdromUpdateMenu(int i) QString busName = tr("Unknown Bus"); switch (cdrom[i].bus_type) { + default: + break; case CDROM_BUS_ATAPI: busName = "ATAPI"; break; case CDROM_BUS_SCSI: busName = "SCSI"; break; - case CDROM_BUS_MITSUMI: - busName = "Mitsumi"; - break; + case CDROM_BUS_MITSUMI: + busName = "Mitsumi"; + break; } // menu->setTitle(tr("CD-ROM %1 (%2): %3").arg(QString::number(i+1), busName, name.isEmpty() ? tr("(empty)") : name)); @@ -633,6 +638,8 @@ MediaMenu::zipNewImage(int i) { NewFloppyDialog dialog(NewFloppyDialog::MediaType::Zip, parentWidget); switch (dialog.exec()) { + default: + break; case QDialog::Accepted: QByteArray filename = dialog.fileName().toUtf8(); zipMount(i, filename, false); @@ -643,7 +650,7 @@ MediaMenu::zipNewImage(int i) void MediaMenu::zipSelectImage(int i, bool wp) { - auto filename = QFileDialog::getOpenFileName( + const auto filename = QFileDialog::getOpenFileName( parentWidget, QString(), QString(), @@ -656,7 +663,7 @@ MediaMenu::zipSelectImage(int i, bool wp) void MediaMenu::zipMount(int i, const QString &filename, bool wp) { - zip_t *dev = (zip_t *) zip_drives[i].priv; + const auto dev = static_cast(zip_drives[i].priv); zip_disk_close(dev); zip_drives[i].read_only = wp; @@ -676,7 +683,7 @@ MediaMenu::zipMount(int i, const QString &filename, bool wp) void MediaMenu::zipEject(int i) { - zip_t *dev = (zip_t *) zip_drives[i].priv; + const auto dev = static_cast(zip_drives[i].priv); zip_disk_close(dev); zip_drives[i].image_path[0] = 0; @@ -694,7 +701,7 @@ MediaMenu::zipEject(int i) void MediaMenu::zipReload(int i) { - zip_t *dev = (zip_t *) zip_drives[i].priv; + const auto dev = static_cast(zip_drives[i].priv); zip_disk_reload(dev); if (strlen(zip_drives[i].image_path) == 0) { @@ -712,8 +719,8 @@ MediaMenu::zipReload(int i) void MediaMenu::zipUpdateMenu(int i) { - QString name = zip_drives[i].image_path; - QString prev_name = zip_drives[i].prev_image_path; + const QString name = zip_drives[i].image_path; + const QString prev_name = zip_drives[i].prev_image_path; if (!zipMenus.contains(i)) return; auto *menu = zipMenus[i]; @@ -726,6 +733,8 @@ MediaMenu::zipUpdateMenu(int i) QString busName = tr("Unknown Bus"); switch (zip_drives[i].bus_type) { + default: + break; case ZIP_BUS_ATAPI: busName = "ATAPI"; break; @@ -743,6 +752,8 @@ MediaMenu::moNewImage(int i) { NewFloppyDialog dialog(NewFloppyDialog::MediaType::Mo, parentWidget); switch (dialog.exec()) { + default: + break; case QDialog::Accepted: QByteArray filename = dialog.fileName().toUtf8(); moMount(i, filename, false); @@ -753,7 +764,7 @@ MediaMenu::moNewImage(int i) void MediaMenu::moSelectImage(int i, bool wp) { - auto filename = QFileDialog::getOpenFileName( + const auto filename = QFileDialog::getOpenFileName( parentWidget, QString(), getMediaOpenDirectory(), @@ -769,7 +780,7 @@ MediaMenu::moSelectImage(int i, bool wp) void MediaMenu::moMount(int i, const QString &filename, bool wp) { - mo_t *dev = (mo_t *) mo_drives[i].priv; + const auto dev = static_cast(mo_drives[i].priv); mo_disk_close(dev); mo_drives[i].read_only = wp; @@ -789,7 +800,7 @@ MediaMenu::moMount(int i, const QString &filename, bool wp) void MediaMenu::moEject(int i) { - mo_t *dev = (mo_t *) mo_drives[i].priv; + const auto dev = static_cast(mo_drives[i].priv); mo_disk_close(dev); mo_drives[i].image_path[0] = 0; @@ -839,6 +850,8 @@ MediaMenu::moUpdateMenu(int i) QString busName = tr("Unknown Bus"); switch (mo_drives[i].bus_type) { + default: + break; case MO_BUS_ATAPI: busName = "ATAPI"; break; @@ -876,6 +889,8 @@ MediaMenu::nicUpdateMenu(int i) QString netType = tr("Null Driver"); switch (net_cards_conf[i].net_type) { + default: + break; case NET_TYPE_SLIRP: netType = "SLiRP"; break; @@ -901,9 +916,10 @@ QString MediaMenu::getMediaOpenDirectory() { QString openDirectory; - if (open_dir_usr_path > 0) { + + if (open_dir_usr_path > 0) openDirectory = QString::fromUtf8(usr_path); - } + return openDirectory; } diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 0f86e8ee6..bc4cb9c13 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -404,7 +404,10 @@ RendererStack::createRenderer(Renderer renderer) void RendererStack::blit(int x, int y, int w, int h) { - if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || imagebufs.empty() || std::get(imagebufs[currentBuf])->test_and_set()) { + if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || + (w > 2048) || (h > 2048) || + (monitors[m_monitor_index].target_buffer == NULL) || imagebufs.empty() || + std::get(imagebufs[currentBuf])->test_and_set()) { video_blit_complete_monitor(m_monitor_index); return; } diff --git a/src/qt/qt_settings.cpp b/src/qt/qt_settings.cpp index a7e52c342..e9767083a 100644 --- a/src/qt/qt_settings.cpp +++ b/src/qt/qt_settings.cpp @@ -155,8 +155,28 @@ Settings::Settings(QWidget *parent) &SettingsOtherPeripherals::onCurrentMachineChanged); connect(floppyCdrom, &SettingsFloppyCDROM::cdromChannelChanged, harddisks, &SettingsHarddisks::reloadBusChannels); + connect(floppyCdrom, &SettingsFloppyCDROM::cdromChannelChanged, otherRemovable, + &SettingsOtherRemovable::reloadBusChannels_MO); + connect(floppyCdrom, &SettingsFloppyCDROM::cdromChannelChanged, otherRemovable, + &SettingsOtherRemovable::reloadBusChannels_ZIP); connect(harddisks, &SettingsHarddisks::driveChannelChanged, floppyCdrom, &SettingsFloppyCDROM::reloadBusChannels); + connect(harddisks, &SettingsHarddisks::driveChannelChanged, otherRemovable, + &SettingsOtherRemovable::reloadBusChannels_MO); + connect(harddisks, &SettingsHarddisks::driveChannelChanged, otherRemovable, + &SettingsOtherRemovable::reloadBusChannels_ZIP); + connect(otherRemovable, &SettingsOtherRemovable::moChannelChanged, harddisks, + &SettingsHarddisks::reloadBusChannels); + connect(otherRemovable, &SettingsOtherRemovable::moChannelChanged, floppyCdrom, + &SettingsFloppyCDROM::reloadBusChannels); + connect(otherRemovable, &SettingsOtherRemovable::moChannelChanged, otherRemovable, + &SettingsOtherRemovable::reloadBusChannels_ZIP); + connect(otherRemovable, &SettingsOtherRemovable::zipChannelChanged, harddisks, + &SettingsHarddisks::reloadBusChannels); + connect(otherRemovable, &SettingsOtherRemovable::zipChannelChanged, floppyCdrom, + &SettingsFloppyCDROM::reloadBusChannels); + connect(otherRemovable, &SettingsOtherRemovable::zipChannelChanged, otherRemovable, + &SettingsOtherRemovable::reloadBusChannels_MO); connect(ui->listView->selectionModel(), &QItemSelectionModel::currentChanged, this, [this](const QModelIndex ¤t, const QModelIndex &previous) { diff --git a/src/qt/qt_settings_bus_tracking.cpp b/src/qt/qt_settings_bus_tracking.cpp index 064fbe0b4..6fb8637da 100644 --- a/src/qt/qt_settings_bus_tracking.cpp +++ b/src/qt/qt_settings_bus_tracking.cpp @@ -22,6 +22,7 @@ #include #include "86box/hdd.h" +#include "86box/scsi.h" #include "qt_settings_bus_tracking.hpp" SettingsBusTracking::SettingsBusTracking() @@ -30,12 +31,11 @@ SettingsBusTracking::SettingsBusTracking() esdi_tracking = 0x0000000000000000ULL; xta_tracking = 0x0000000000000000ULL; - for (uint8_t i = 0; i < 8; i++) { - if (i < 4) - ide_tracking[i] = 0x0000000000000000ULL; + for (uint8_t i = 0; i < 4; i++) + ide_tracking[i] = 0x0000000000000000ULL; + for (uint8_t i = 0; i < 32; i++) scsi_tracking[i] = 0x0000000000000000ULL; - } } uint8_t @@ -101,7 +101,7 @@ SettingsBusTracking::next_free_scsi_id() uint64_t mask; uint8_t ret = CHANNEL_NONE; - for (uint8_t i = 0; i < 64; i++) { + for (uint8_t i = 0; i < (SCSI_BUS_MAX * SCSI_ID_MAX); i++) { element = ((i << 3) >> 6); mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); @@ -187,7 +187,7 @@ SettingsBusTracking::scsi_bus_full() uint64_t mask; uint8_t count = 0; - for (uint8_t i = 0; i < 64; i++) { + for (uint8_t i = 0; i < (SCSI_BUS_MAX * SCSI_ID_MAX); i++) { element = ((i << 3) >> 6); mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); @@ -204,26 +204,45 @@ QList SettingsBusTracking::busChannelsInUse(const int bus) { int element; uint64_t mask; switch (bus) { + case HDD_BUS_MFM: + for (uint8_t i = 0; i < 32; i++) { + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + if (mfm_tracking & mask) + channelsInUse.append(i); + } + break; + case HDD_BUS_ESDI: + for (uint8_t i = 0; i < 32; i++) { + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + if (esdi_tracking & mask) + channelsInUse.append(i); + } + break; + case HDD_BUS_XTA: + for (uint8_t i = 0; i < 32; i++) { + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + if (xta_tracking & mask) + channelsInUse.append(i); + } + break; case HDD_BUS_IDE: for (uint8_t i = 0; i < 32; i++) { element = ((i << 3) >> 6); - mask = ((uint64_t) DEV_HDD) << ((uint64_t) ((i << 3) & 0x3f)); - if (ide_tracking[element] & mask) { + mask = ((uint64_t) 0xffULL) << ((uint64_t) ((i << 3) & 0x3f)); + if (ide_tracking[element] & mask) channelsInUse.append(i); - } } break; case HDD_BUS_ATAPI: for (uint8_t i = 0; i < 32; i++) { element = ((i << 3) >> 6); - mask = ((uint64_t) DEV_CDROM) << ((uint64_t) ((i << 3) & 0x3f)); - if (ide_tracking[element] & mask) { + mask = ((uint64_t) 0xffULL) << ((uint64_t) ((i << 3) & 0x3f)); + if (ide_tracking[element] & mask) channelsInUse.append(i); - } } break; case HDD_BUS_SCSI: - for (uint8_t i = 0; i < 64; i++) { + for (uint8_t i = 0; i < (SCSI_BUS_MAX * SCSI_ID_MAX); i++) { element = ((i << 3) >> 6); mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); if (scsi_tracking[element] & mask) diff --git a/src/qt/qt_settings_bus_tracking.hpp b/src/qt/qt_settings_bus_tracking.hpp index 279d3247e..917706428 100644 --- a/src/qt/qt_settings_bus_tracking.hpp +++ b/src/qt/qt_settings_bus_tracking.hpp @@ -57,8 +57,10 @@ private: uint64_t xta_tracking { 0 }; /* 16 channels (prepatation for that weird IDE card), 2 devices per channel, 8 bits per device = 256 bits. */ uint64_t ide_tracking[4] { 0, 0, 0, 0 }; - /* 4 buses, 16 devices per bus, 8 bits per device (future-proofing) = 512 bits. */ - uint64_t scsi_tracking[8] { 0, 0, 0, 0, 0, 0, 0, 0 }; + /* 9 buses (rounded upwards to 16for future-proofing), 16 devices per bus, + 8 bits per device (future-proofing) = 2048 bits. */ + uint64_t scsi_tracking[32] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; }; #endif // QT_SETTINGS_BUS_TRACKING_HPP diff --git a/src/qt/qt_settingsfloppycdrom.cpp b/src/qt/qt_settingsfloppycdrom.cpp index bb536e603..8f0ac81a9 100644 --- a/src/qt/qt_settingsfloppycdrom.cpp +++ b/src/qt/qt_settingsfloppycdrom.cpp @@ -368,6 +368,7 @@ SettingsFloppyCDROM::on_comboBoxBus_activated(int) setCDROMType(ui->tableViewCDROM->model(), ui->tableViewCDROM->selectionModel()->currentIndex(), ui->comboBoxCDROMType->currentData().toUInt()); + emit cdromChannelChanged(); } void diff --git a/src/qt/qt_settingsotherremovable.cpp b/src/qt/qt_settingsotherremovable.cpp index 36918ad99..1a6dceacb 100644 --- a/src/qt/qt_settingsotherremovable.cpp +++ b/src/qt/qt_settingsotherremovable.cpp @@ -201,6 +201,7 @@ SettingsOtherRemovable::onMORowChanged(const QModelIndex ¤t) if (!match.isEmpty()) ui->comboBoxMOChannel->setCurrentIndex(match.first().row()); ui->comboBoxMOType->setCurrentIndex(type); + enableCurrentlySelectedChannel_MO(); } void @@ -221,6 +222,16 @@ SettingsOtherRemovable::onZIPRowChanged(const QModelIndex ¤t) if (!match.isEmpty()) ui->comboBoxZIPChannel->setCurrentIndex(match.first().row()); ui->checkBoxZIP250->setChecked(is250); + enableCurrentlySelectedChannel_ZIP(); +} + +void +SettingsOtherRemovable::reloadBusChannels_MO() { + auto selected = ui->comboBoxMOChannel->currentIndex(); + Harddrives::populateBusChannels(ui->comboBoxMOChannel->model(), + ui->comboBoxMOBus->currentData().toInt(), Harddrives::busTrackClass); + ui->comboBoxMOChannel->setCurrentIndex(selected); + enableCurrentlySelectedChannel_MO(); } void @@ -231,7 +242,7 @@ SettingsOtherRemovable::on_comboBoxMOBus_currentIndexChanged(int index) bool enabled = (bus != MO_BUS_DISABLED); ui->comboBoxMOChannel->setEnabled(enabled); ui->comboBoxMOType->setEnabled(enabled); - Harddrives::populateBusChannels(ui->comboBoxMOChannel->model(), bus); + Harddrives::populateBusChannels(ui->comboBoxMOChannel->model(), bus, Harddrives::busTrackClass); } } @@ -258,6 +269,17 @@ SettingsOtherRemovable::on_comboBoxMOBus_activated(int) Harddrives::busTrackClass->device_track(1, DEV_MO, ui->tableViewMO->model()->data(i, Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, Qt::UserRole + 1).toInt()); + emit moChannelChanged(); +} + +void +SettingsOtherRemovable::enableCurrentlySelectedChannel_MO() +{ + const auto *item_model = qobject_cast(ui->comboBoxMOChannel->model()); + const auto index = ui->comboBoxMOChannel->currentIndex(); + auto *item = item_model->item(index); + if (item) + item->setEnabled(true); } void @@ -274,6 +296,7 @@ SettingsOtherRemovable::on_comboBoxMOChannel_activated(int) Harddrives::busTrackClass->device_track(1, DEV_MO, ui->tableViewMO->model()->data(i, Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, Qt::UserRole + 1).toInt()); + emit moChannelChanged(); } void @@ -286,6 +309,15 @@ SettingsOtherRemovable::on_comboBoxMOType_activated(int) ui->tableViewMO->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); } +void +SettingsOtherRemovable::reloadBusChannels_ZIP() { + auto selected = ui->comboBoxZIPChannel->currentIndex(); + Harddrives::populateBusChannels(ui->comboBoxZIPChannel->model(), + ui->comboBoxZIPBus->currentData().toInt(), Harddrives::busTrackClass); + ui->comboBoxZIPChannel->setCurrentIndex(selected); + enableCurrentlySelectedChannel_ZIP(); +} + void SettingsOtherRemovable::on_comboBoxZIPBus_currentIndexChanged(int index) { @@ -294,7 +326,7 @@ SettingsOtherRemovable::on_comboBoxZIPBus_currentIndexChanged(int index) bool enabled = (bus != ZIP_BUS_DISABLED); ui->comboBoxZIPChannel->setEnabled(enabled); ui->checkBoxZIP250->setEnabled(enabled); - Harddrives::populateBusChannels(ui->comboBoxZIPChannel->model(), bus); + Harddrives::populateBusChannels(ui->comboBoxZIPChannel->model(), bus, Harddrives::busTrackClass); } } @@ -315,6 +347,17 @@ SettingsOtherRemovable::on_comboBoxZIPBus_activated(int) Harddrives::busTrackClass->device_track(1, DEV_ZIP, ui->tableViewZIP->model()->data(i, Qt::UserRole).toInt(), ui->tableViewZIP->model()->data(i, Qt::UserRole + 1).toInt()); + emit zipChannelChanged(); +} + +void +SettingsOtherRemovable::enableCurrentlySelectedChannel_ZIP() +{ + const auto *item_model = qobject_cast(ui->comboBoxZIPChannel->model()); + const auto index = ui->comboBoxZIPChannel->currentIndex(); + auto *item = item_model->item(index); + if (item) + item->setEnabled(true); } void @@ -331,6 +374,7 @@ SettingsOtherRemovable::on_comboBoxZIPChannel_activated(int) Harddrives::busTrackClass->device_track(1, DEV_ZIP, ui->tableViewZIP->model()->data(i, Qt::UserRole).toInt(), ui->tableViewZIP->model()->data(i, Qt::UserRole + 1).toInt()); + emit zipChannelChanged(); } void diff --git a/src/qt/qt_settingsotherremovable.hpp b/src/qt/qt_settingsotherremovable.hpp index 8b81fb0f0..cea1d202b 100644 --- a/src/qt/qt_settingsotherremovable.hpp +++ b/src/qt/qt_settingsotherremovable.hpp @@ -13,9 +13,14 @@ class SettingsOtherRemovable : public QWidget { public: explicit SettingsOtherRemovable(QWidget *parent = nullptr); ~SettingsOtherRemovable(); + void reloadBusChannels_MO(); + void reloadBusChannels_ZIP(); void save(); +signals: + void moChannelChanged(); + void zipChannelChanged(); private slots: void on_checkBoxZIP250_stateChanged(int arg1); @@ -46,6 +51,8 @@ private slots: private: Ui::SettingsOtherRemovable *ui; + void enableCurrentlySelectedChannel_MO(); + void enableCurrentlySelectedChannel_ZIP(); }; #endif // QT_SETTINGSOTHERREMOVABLE_HPP diff --git a/src/qt/qt_settingssound.cpp b/src/qt/qt_settingssound.cpp index b4df4ff69..e0572c3d8 100644 --- a/src/qt/qt_settingssound.cpp +++ b/src/qt/qt_settingssound.cpp @@ -67,17 +67,17 @@ SettingsSound::save() } void -SettingsSound::onCurrentMachineChanged(int machineId) +SettingsSound::onCurrentMachineChanged(const int machineId) { this->machineId = machineId; - int c = 0; - int selectedRow = 0; + int c; + int selectedRow; for (uint8_t i = 0; i < SOUND_CARD_MAX; ++i) { - auto *cbox = findChild(QString("comboBoxSoundCard%1").arg(i + 1)); - auto *model = cbox->model(); - auto removeRows = model->rowCount(); + auto * cbox = findChild(QString("comboBoxSoundCard%1").arg(i + 1)); + auto * model = cbox->model(); + const auto removeRows = model->rowCount(); c = 0; selectedRow = 0; @@ -207,7 +207,7 @@ SettingsSound::on_pushButtonConfigureSoundCard1_clicked() auto *device = sound_card_getdevice(sndCard); if (sndCard == SOUND_INTERNAL) device = machine_get_snd_device(machineId); - DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); + DeviceConfig::ConfigureDevice(device, 1, qobject_cast(Settings::settings)); } void @@ -225,7 +225,7 @@ SettingsSound::on_pushButtonConfigureSoundCard2_clicked() { int sndCard = ui->comboBoxSoundCard2->currentData().toInt(); auto *device = sound_card_getdevice(sndCard); - DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); + DeviceConfig::ConfigureDevice(device, 2, qobject_cast(Settings::settings)); } void @@ -243,7 +243,7 @@ SettingsSound::on_pushButtonConfigureSoundCard3_clicked() { int sndCard = ui->comboBoxSoundCard3->currentData().toInt(); auto *device = sound_card_getdevice(sndCard); - DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); + DeviceConfig::ConfigureDevice(device, 3, qobject_cast(Settings::settings)); } void @@ -261,7 +261,7 @@ SettingsSound::on_pushButtonConfigureSoundCard4_clicked() { int sndCard = ui->comboBoxSoundCard4->currentData().toInt(); auto *device = sound_card_getdevice(sndCard); - DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); + DeviceConfig::ConfigureDevice(device, 4, qobject_cast(Settings::settings)); } void @@ -278,7 +278,8 @@ SettingsSound::on_comboBoxMidiOut_currentIndexChanged(int index) void SettingsSound::on_pushButtonConfigureMidiOut_clicked() { - DeviceConfig::ConfigureDevice(midi_out_device_getdevice(ui->comboBoxMidiOut->currentData().toInt()), 0, qobject_cast(Settings::settings)); + DeviceConfig::ConfigureDevice(midi_out_device_getdevice(ui->comboBoxMidiOut->currentData().toInt()), 0, + qobject_cast(Settings::settings)); } void @@ -295,7 +296,8 @@ SettingsSound::on_comboBoxMidiIn_currentIndexChanged(int index) void SettingsSound::on_pushButtonConfigureMidiIn_clicked() { - DeviceConfig::ConfigureDevice(midi_in_device_getdevice(ui->comboBoxMidiIn->currentData().toInt()), 0, qobject_cast(Settings::settings)); + DeviceConfig::ConfigureDevice(midi_in_device_getdevice(ui->comboBoxMidiIn->currentData().toInt()), 0, + qobject_cast(Settings::settings)); } void @@ -307,9 +309,8 @@ SettingsSound::on_checkBoxMPU401_stateChanged(int state) void SettingsSound::on_pushButtonConfigureMPU401_clicked() { - if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) { + if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) DeviceConfig::ConfigureDevice(&mpu401_mca_device, 0, qobject_cast(Settings::settings)); - } else { + else DeviceConfig::ConfigureDevice(&mpu401_device, 0, qobject_cast(Settings::settings)); - } } diff --git a/src/qt/qt_settingsstoragecontrollers.cpp b/src/qt/qt_settingsstoragecontrollers.cpp index 0f19d46fc..389e22852 100644 --- a/src/qt/qt_settingsstoragecontrollers.cpp +++ b/src/qt/qt_settingsstoragecontrollers.cpp @@ -52,7 +52,7 @@ void SettingsStorageControllers::save() { /* Storage devices category */ - for (int i = 0; i < SCSI_BUS_MAX; ++i) { + for (int i = 0; i < SCSI_CARD_MAX; ++i) { auto *cbox = findChild(QString("comboBoxSCSI%1").arg(i + 1)); scsi_card_current[i] = cbox->currentData().toInt(); } @@ -161,7 +161,7 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId) ui->comboBoxCDInterface->setCurrentIndex(-1); ui->comboBoxCDInterface->setCurrentIndex(selectedRow); - for (int i = 0; i < SCSI_BUS_MAX; ++i) { + for (int i = 0; i < SCSI_CARD_MAX; ++i) { auto *cbox = findChild(QString("comboBoxSCSI%1").arg(i + 1)); model = cbox->model(); removeRows = model->rowCount(); diff --git a/src/qt/qt_ui.cpp b/src/qt/qt_ui.cpp index 5412a0e4a..fc111e5b4 100644 --- a/src/qt/qt_ui.cpp +++ b/src/qt/qt_ui.cpp @@ -66,13 +66,13 @@ wchar_t * ui_window_title(wchar_t *str) { if (str == nullptr) { - static wchar_t title[512]; - memset(title, 0, sizeof(title)); + static wchar_t title[512] = { 0 }; + main_window->getTitle(title); str = title; - } else { + } else emit main_window->setTitle(QString::fromWCharArray(str)); - } + return str; } @@ -122,8 +122,10 @@ plat_mouse_capture(int on) int ui_msgbox_header(int flags, void *header, void *message) { - auto hdr = (flags & MBX_ANSI) ? QString((char *) header) : QString::fromWCharArray(reinterpret_cast(header)); - auto msg = (flags & MBX_ANSI) ? QString((char *) message) : QString::fromWCharArray(reinterpret_cast(message)); + const auto hdr = (flags & MBX_ANSI) ? QString(static_cast(header)) : + QString::fromWCharArray(static_cast(header)); + const auto msg = (flags & MBX_ANSI) ? QString(static_cast(message)) : + QString::fromWCharArray(static_cast(message)); // any error in early init if (main_window == nullptr) { @@ -220,9 +222,13 @@ ui_sb_set_ready(int ready) void ui_sb_update_icon_state(int tag, int state) { - int category = tag & 0xfffffff0; - int item = tag & 0xf; + const auto temp = static_cast(tag); + const int category = static_cast(temp & 0xfffffff0); + const int item = tag & 0xf; + switch (category) { + default: + break; case SB_CASSETTE: machine_status.cassette.empty = state > 0 ? true : false; break; @@ -247,7 +253,6 @@ ui_sb_update_icon_state(int tag, int state) machine_status.net[item].empty = state > 0 ? true : false; break; case SB_SOUND: - break; case SB_TEXT: break; } @@ -256,11 +261,13 @@ ui_sb_update_icon_state(int tag, int state) void ui_sb_update_icon(int tag, int active) { - int category = tag & 0xfffffff0; - int item = tag & 0xf; + const auto temp = static_cast(tag); + const int category = static_cast(temp & 0xfffffff0); + const int item = tag & 0xf; + switch (category) { + default: case SB_CASSETTE: - break; case SB_CARTRIDGE: break; case SB_FLOPPY: @@ -282,7 +289,6 @@ ui_sb_update_icon(int tag, int active) machine_status.net[item].active = active > 0 ? true : false; break; case SB_SOUND: - break; case SB_TEXT: break; } diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index 328810a2f..aecbcadec 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -42,7 +42,7 @@ #include <86box/scsi_pcscsi.h> #include <86box/scsi_spock.h> -int scsi_card_current[SCSI_BUS_MAX] = { 0, 0, 0, 0 }; +int scsi_card_current[SCSI_CARD_MAX] = { 0, 0, 0, 0 }; double scsi_bus_speed[SCSI_BUS_MAX] = { 0.0, 0.0, 0.0, 0.0 }; static uint8_t next_scsi_bus = 0; @@ -169,12 +169,12 @@ scsi_card_get_from_internal_name(char *s) void scsi_card_init(void) { - int max = SCSI_BUS_MAX; + int max = SCSI_CARD_MAX; /* On-board SCSI controllers get the first bus, so if one is present, increase our instance number here. */ - if (machine_has_flags(machine, MACHINE_SCSI)) - max--; + // if (machine_has_flags(machine, MACHINE_SCSI)) + // max--; /* Do not initialize any controllers if we have do not have any SCSI bus left. */ diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index d113d2cb3..d256de764 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -68,16 +68,24 @@ void ncr5380_irq(ncr_t *ncr, int set_irq) { if (set_irq) { + ncr->irq_state = 1; ncr->isr |= STATUS_INT; if (ncr->irq != -1) picint(1 << ncr->irq); } else { + ncr->irq_state = 0; ncr->isr &= ~STATUS_INT; if (ncr->irq != 1) picintc(1 << ncr->irq); } } +void +ncr5380_set_irq(ncr_t *ncr, int irq) +{ + ncr->irq = irq; +} + static int ncr5380_get_dev_id(uint8_t data) { @@ -318,6 +326,19 @@ ncr5380_bus_update(ncr_t *ncr, int bus) ncr5380_log("SCSI ID %i: command 0x%02x for p = %lf, update = %lf, len = %i, dmamode = %x\n", ncr->target_id, ncr->command[0], scsi_device_get_callback(dev), ncr->period, dev->buffer_length, ncr->dma_mode); } } + + if (ncr->simple_pseudo_dma) { + if (dev->phase == SCSI_PHASE_DATA_IN) { + ncr->block_count = dev->buffer_length / 512; + + ncr->dma_init_ext(ncr, ncr->priv, 1); + } else if (dev->phase == SCSI_PHASE_DATA_OUT) { + ncr->block_count = dev->buffer_length / 512; + + ncr->dma_init_ext(ncr, ncr->priv, 0); + } + } + ncr->new_phase = dev->phase; } } @@ -337,7 +358,10 @@ ncr5380_bus_update(ncr_t *ncr, int bus) if (ncr->dma_mode == DMA_IDLE) { /*If a data in command that is not read 6/10 has been issued*/ ncr->data_wait |= 1; ncr5380_log("DMA mode idle in\n"); - ncr->timer(ncr->priv, ncr->period); + if (ncr->simple_pseudo_dma) + ncr->dma_init_ext(ncr, ncr->priv, 1); + else + ncr->timer(ncr->priv, ncr->period); } else { ncr5380_log("DMA mode IN.\n"); ncr->clear_req = 3; @@ -364,7 +388,10 @@ ncr5380_bus_update(ncr_t *ncr, int bus) if (ncr->dma_mode == DMA_IDLE) { /*If a data out command that is not write 6/10 has been issued*/ ncr->data_wait |= 1; ncr5380_log("DMA mode idle out\n"); - ncr->timer(ncr->priv, ncr->period); + if (!ncr->simple_pseudo_dma) + ncr->timer(ncr->priv, ncr->period); + if (ncr->simple_pseudo_dma) + ncr->dma_init_ext(ncr, ncr->priv, 0); } else ncr->clear_req = 3; @@ -490,6 +517,21 @@ ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr) ncr5380_bus_update(ncr, bus_host); } +uint8_t +ncr5380_drq(ncr_t *ncr) +{ + uint8_t ret = 0; + int bus; + + ncr5380_bus_read(ncr); + bus = ncr->cur_bus; + + if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA)) + ret = 1; + + return ret; +} + uint8_t ncr5380_read(uint16_t port, ncr_t *ncr) { diff --git a/src/scsi/scsi_ncr53c400.c b/src/scsi/scsi_ncr53c400.c index 1ed8e520e..f4bd9de59 100644 --- a/src/scsi/scsi_ncr53c400.c +++ b/src/scsi/scsi_ncr53c400.c @@ -41,6 +41,7 @@ #include <86box/scsi.h> #include <86box/scsi_device.h> #include <86box/scsi_ncr5380.h> +#include <86box/scsi_ncr53c400.h> #define LCS6821N_ROM "roms/scsi/ncr5380/Longshine LCS-6821N - BIOS version 1.04.bin" #define COREL_LS2000_ROM "roms/scsi/ncr5380/Corel LS2000 - BIOS ROM - Ver 1.65.bin" @@ -48,43 +49,14 @@ #define RT1000B_820R_ROM "roms/scsi/ncr5380/RTBIOS82.ROM" #define T130B_ROM "roms/scsi/ncr5380/trantor_t130b_bios_v2.14.bin" -#define CTRL_DATA_DIR 0x40 -#define STATUS_BUFFER_NOT_READY 0x04 -#define STATUS_5380_ACCESSIBLE 0x80 - enum { ROM_LCS6821N = 0, ROM_LS2000, ROM_RT1000B, - ROM_T130B + ROM_T130B, + ROM_PAS }; -typedef struct ncr53c400_t { - rom_t bios_rom; - mem_mapping_t mapping; - ncr_t ncr; - uint8_t buffer[128]; - uint8_t int_ram[0x40]; - uint8_t ext_ram[0x600]; - - uint32_t rom_addr; - uint16_t base; - - int8_t type; - uint8_t block_count; - uint8_t status_ctrl; - - int block_count_loaded; - - int buffer_pos; - int buffer_host_pos; - - int busy; - uint8_t pos_regs[8]; - - pc_timer_t timer; -} ncr53c400_t; - #ifdef ENABLE_NCR53C400_LOG int ncr53c400_do_log = ENABLE_NCR53C400_LOG; @@ -103,8 +75,29 @@ ncr53c400_log(const char *fmt, ...) # define ncr53c400_log(fmt, ...) #endif +void +ncr53c400_simple_write(uint8_t val, void *priv) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + ncr_t *ncr = &ncr400->ncr; + scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + + if (ncr400->buffer_host_pos < MIN(512, dev->buffer_length)) { + ncr400->buffer[ncr400->buffer_host_pos++] = val; + + ncr53c400_log("Write host pos = %i, val = %02x\n", ncr400->buffer_host_pos, val); + + if (ncr400->buffer_host_pos == MIN(512, dev->buffer_length)) { + ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; + ncr400->busy = 1; + + ncr53c400_callback(priv); + } + } +} + /* Memory-mapped I/O WRITE handler. */ -static void +void ncr53c400_write(uint32_t addr, uint8_t val, void *priv) { ncr53c400_t *ncr400 = (ncr53c400_t *) priv; @@ -192,8 +185,30 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) } } +uint8_t +ncr53c400_simple_read(void *priv) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) priv; + ncr_t *ncr = &ncr400->ncr; + scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + uint8_t ret = 0xff; + + if (ncr400->buffer_host_pos < MIN(512, dev->buffer_length)) { + ret = ncr400->buffer[ncr400->buffer_host_pos++]; + ncr53c400_log("Read host pos = %i, ret = %02x\n", ncr400->buffer_host_pos, ret); + + if (ncr400->buffer_host_pos == MIN(512, dev->buffer_length)) { + ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; + ncr53c400_log("Transfer busy read, status = %02x\n", ncr400->status_ctrl); + ncr53c400_callback(priv); + } + } + + return ret; +} + /* Memory-mapped I/O READ handler. */ -static uint8_t +uint8_t ncr53c400_read(uint32_t addr, void *priv) { ncr53c400_t *ncr400 = (ncr53c400_t *) priv; @@ -385,6 +400,34 @@ t130b_in(uint16_t port, void *priv) return ret; } +static void +ncr53c400_dma_init_ext(void *priv, void *ext_priv, int send) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) ext_priv; + ncr_t *ncr = (ncr_t *) priv; + scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + uint8_t val = send ? CTRL_DATA_DIR : 0x00; + + ncr53c400_log("NCR 53c400 control = %02x, mode = %02x.\n", val, ncr->mode); + ncr400->status_ctrl = (ncr400->status_ctrl & 0x87) | (val & 0x78); + + ncr400->block_count_loaded = 1; + + if (ncr400->status_ctrl & CTRL_DATA_DIR) { + ncr400->buffer_host_pos = MIN(512, dev->buffer_length); + ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; + } else { + ncr400->buffer_host_pos = 0; + ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + } + if ((ncr->mode & MODE_DMA) && (dev->buffer_length > 0)) { + memset(ncr400->buffer, 0, MIN(512, dev->buffer_length)); + ncr53c400_log("DMA buffer init\n"); + ncr->timer(ncr->priv, ncr->period); + } + ncr53c400_log("NCR DMA init\n"); +} + static void ncr53c400_dma_mode_ext(void *priv, void *ext_priv) { @@ -412,17 +455,21 @@ ncr53c400_timer_on_auto(void *ext_priv, double period) timer_on_auto(&ncr400->timer, period); } -static void +void ncr53c400_callback(void *priv) { ncr53c400_t *ncr400 = (void *) priv; ncr_t *ncr = &ncr400->ncr; scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; int bus; + int blocks_left; uint8_t c; uint8_t temp; + const int buf_len = ncr400->simple_ctrl ? 512 : 128; - if (ncr->dma_mode != DMA_IDLE) + ncr53c400_log("DMA mode = %i\n", ncr->dma_mode); + + if (!ncr400->simple_ctrl && (ncr->dma_mode != DMA_IDLE)) timer_on_auto(&ncr400->timer, 1.0); if (ncr->data_wait & 1) { @@ -441,7 +488,7 @@ ncr53c400_callback(void *priv) switch (ncr->dma_mode) { case DMA_SEND: - if (ncr400->status_ctrl & CTRL_DATA_DIR) { + if (!ncr400->simple_ctrl && (ncr400->status_ctrl & CTRL_DATA_DIR)) { ncr53c400_log("DMA_SEND with DMA direction set wrong\n"); break; } @@ -475,14 +522,20 @@ ncr53c400_callback(void *priv) ncr400->buffer_pos++; ncr53c400_log("NCR 53c400 Buffer pos for writing = %d\n", ncr400->buffer_pos); - if (ncr400->buffer_pos == MIN(128, dev->buffer_length)) { + if (ncr400->buffer_pos == MIN(buf_len, dev->buffer_length)) { ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; ncr400->buffer_pos = 0; ncr400->buffer_host_pos = 0; ncr400->busy = 0; - ncr400->block_count = (ncr400->block_count - 1) & 0xff; - ncr53c400_log("NCR 53c400 Remaining blocks to be written=%d\n", ncr400->block_count); - if (!ncr400->block_count) { + if (ncr400->simple_ctrl) { + ncr->block_count = (ncr->block_count - 1) & 0xffffffff; + blocks_left = ncr->block_count; + } else { + ncr400->block_count = (ncr400->block_count - 1) & 0xff; + blocks_left = ncr400->block_count; + } + ncr53c400_log("NCR 53c400 Remaining blocks to be written=%d\n", blocks_left); + if (blocks_left == 0) { ncr400->block_count_loaded = 0; ncr53c400_log("IO End of write transfer\n"); ncr->tcr |= TCR_LAST_BYTE_SENT; @@ -499,7 +552,7 @@ ncr53c400_callback(void *priv) break; case DMA_INITIATOR_RECEIVE: - if (!(ncr400->status_ctrl & CTRL_DATA_DIR)) { + if (!ncr400->simple_ctrl && !(ncr400->status_ctrl & CTRL_DATA_DIR)) { ncr53c400_log("DMA_INITIATOR_RECEIVE with DMA direction set wrong\n"); break; } @@ -515,8 +568,10 @@ ncr53c400_callback(void *priv) while (1) { for (c = 0; c < 10; c++) { ncr5380_bus_read(ncr); - if (ncr->cur_bus & BUS_REQ) + if (ncr->cur_bus & BUS_REQ) { + ncr53c400_log("ncr->cur_bus & BUS_REQ\n"); break; + } } /* Data ready. */ @@ -531,13 +586,19 @@ ncr53c400_callback(void *priv) ncr400->buffer[ncr400->buffer_pos++] = temp; ncr53c400_log("NCR 53c400 Buffer pos for reading = %d\n", ncr400->buffer_pos); - if (ncr400->buffer_pos == MIN(128, dev->buffer_length)) { + if (ncr400->buffer_pos == MIN(buf_len, dev->buffer_length)) { ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; ncr400->buffer_pos = 0; ncr400->buffer_host_pos = 0; - ncr400->block_count = (ncr400->block_count - 1) & 0xff; - ncr53c400_log("NCR 53c400 Remaining blocks to be read=%d\n", ncr400->block_count); - if (!ncr400->block_count) { + if (ncr400->simple_ctrl) { + ncr->block_count = (ncr->block_count - 1) & 0xffffffff; + blocks_left = ncr->block_count; + } else { + ncr400->block_count = (ncr400->block_count - 1) & 0xff; + blocks_left = ncr400->block_count; + } + ncr53c400_log("NCR 53c400 Remaining blocks to be read=%d\n", blocks_left); + if (blocks_left == 0) { ncr400->block_count_loaded = 0; ncr53c400_log("IO End of read transfer\n"); ncr->isr |= STATUS_END_OF_DMA; @@ -562,6 +623,8 @@ ncr53c400_callback(void *priv) ncr53c400_log("Updating DMA\n"); ncr->mode &= ~MODE_DMA; ncr->dma_mode = DMA_IDLE; + if (ncr400->simple_ctrl) + ncr400->block_count_loaded = 0; } } @@ -656,7 +719,6 @@ ncr53c400_init(const device_t *info) ncr400->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr400); break; - case ROM_LS2000: /* Corel LS2000 */ ncr400->rom_addr = device_get_config_hex20("bios_addr"); ncr->irq = device_get_config_int("irq"); @@ -715,6 +777,13 @@ ncr53c400_init(const device_t *info) t130b_in, NULL, NULL, t130b_out, NULL, NULL, ncr400); break; + case ROM_PAS: /* Pro Audio Spectrum Plus/16 SCSI controller */ + ncr400->simple_ctrl = 1; + ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; + ncr->simple_pseudo_dma = 1; + ncr->dma_init_ext = ncr53c400_dma_init_ext; + break; + default: break; } @@ -1007,3 +1076,17 @@ const device_t scsi_ls2000_device = { .force_redraw = NULL, .config = ncr53c400_mmio_config }; + +const device_t scsi_pas_device = { + .name = "Pro Audio Spectrum Plus/16 SCSI", + .internal_name = "scsi_pas", + .flags = DEVICE_ISA, + .local = ROM_PAS, + .init = ncr53c400_init, + .close = ncr53c400_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/sound/openal.c b/src/sound/openal.c index f015205f6..f1ca74182 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -21,7 +21,6 @@ #include #include #include -#include #undef AL_API #undef ALC_API #define AL_LIBTYPE_STATIC @@ -40,9 +39,10 @@ ALuint buffers[4]; /* front and back buffers */ ALuint buffers_music[4]; /* front and back buffers */ +ALuint buffers_wt[4]; /* front and back buffers */ ALuint buffers_cd[4]; /* front and back buffers */ ALuint buffers_midi[4]; /* front and back buffers */ -static ALuint source[4]; /* audio source */ +static ALuint source[5]; /* audio source */ static int midi_freq = 44100; static int midi_buf_size = 4410; @@ -52,13 +52,12 @@ static ALCcontext *Context; static ALCdevice *Device; void -al_set_midi(int freq, int buf_size) +al_set_midi(const int freq, const int buf_size) { midi_freq = freq; midi_buf_size = buf_size; } -void closeal(void); ALvoid alutInit(UNUSED(ALint *argc), UNUSED(ALbyte **argv)) { @@ -116,14 +115,15 @@ inital(void) { float *buf = NULL; float *music_buf = NULL; + float *wt_buf = NULL; float *cd_buf = NULL; float *midi_buf = NULL; int16_t *buf_int16 = NULL; int16_t *music_buf_int16 = NULL; + int16_t *wt_buf_int16 = NULL; int16_t *cd_buf_int16 = NULL; int16_t *midi_buf_int16 = NULL; - const char *mdn; int init_midi = 0; if (initialized) @@ -132,21 +132,23 @@ inital(void) alutInit(0, 0); atexit(closeal); - mdn = midi_out_device_get_internal_name(midi_output_device_current); - if (strcmp(mdn, "none") && strcmp(mdn, SYSTEM_MIDI_INTERNAL_NAME)) + const char *mdn = midi_out_device_get_internal_name(midi_output_device_current); + if ((strcmp(mdn, "none") != 0) && (strcmp(mdn, SYSTEM_MIDI_INTERNAL_NAME) != 0)) init_midi = 1; /* If the device is neither none, nor system MIDI, initialize the - MIDI buffer and source, otherwise, do not. */ - sources = 3 + !!init_midi; + MIDI buffer and source, otherwise, do not. */ + sources = 4 + !!init_midi; if (sound_is_float) { buf = (float *) calloc((BUFLEN << 1), sizeof(float)); music_buf = (float *) calloc((MUSICBUFLEN << 1), sizeof(float)); + wt_buf = (float *) calloc((WTBUFLEN << 1), sizeof(float)); cd_buf = (float *) calloc((CD_BUFLEN << 1), sizeof(float)); if (init_midi) midi_buf = (float *) calloc(midi_buf_size, sizeof(float)); } else { buf_int16 = (int16_t *) calloc((BUFLEN << 1), sizeof(int16_t)); music_buf_int16 = (int16_t *) calloc((MUSICBUFLEN << 1), sizeof(int16_t)); + wt_buf_int16 = (int16_t *) calloc((WTBUFLEN << 1), sizeof(int16_t)); cd_buf_int16 = (int16_t *) calloc((CD_BUFLEN << 1), sizeof(int16_t)); if (init_midi) midi_buf_int16 = (int16_t *) calloc(midi_buf_size, sizeof(int16_t)); @@ -155,47 +157,55 @@ inital(void) alGenBuffers(4, buffers); alGenBuffers(4, buffers_cd); alGenBuffers(4, buffers_music); + alGenBuffers(4, buffers_wt); if (init_midi) alGenBuffers(4, buffers_midi); if (init_midi) - alGenSources(4, source); + alGenSources(5, source); else - alGenSources(3, source); + alGenSources(4, source); - alSource3f(source[0], AL_POSITION, 0.0, 0.0, 0.0); - alSource3f(source[0], AL_VELOCITY, 0.0, 0.0, 0.0); - alSource3f(source[0], AL_DIRECTION, 0.0, 0.0, 0.0); - alSourcef(source[0], AL_ROLLOFF_FACTOR, 0.0); + 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.0, 0.0, 0.0); - alSource3f(source[1], AL_VELOCITY, 0.0, 0.0, 0.0); - alSource3f(source[1], AL_DIRECTION, 0.0, 0.0, 0.0); - alSourcef(source[1], AL_ROLLOFF_FACTOR, 0.0); + 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.0, 0.0, 0.0); - alSource3f(source[2], AL_VELOCITY, 0.0, 0.0, 0.0); - alSource3f(source[2], AL_DIRECTION, 0.0, 0.0, 0.0); - alSourcef(source[2], AL_ROLLOFF_FACTOR, 0.0); + 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); if (init_midi) { - alSource3f(source[3], AL_POSITION, 0.0, 0.0, 0.0); - alSource3f(source[3], AL_VELOCITY, 0.0, 0.0, 0.0); - alSource3f(source[3], AL_DIRECTION, 0.0, 0.0, 0.0); - alSourcef(source[3], AL_ROLLOFF_FACTOR, 0.0); - alSourcei(source[3], AL_SOURCE_RELATIVE, AL_TRUE); + 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); } if (sound_is_float) { memset(buf, 0, BUFLEN * 2 * sizeof(float)); memset(cd_buf, 0, CD_BUFLEN * 2 * sizeof(float)); memset(music_buf, 0, MUSICBUFLEN * 2 * sizeof(float)); + memset(wt_buf, 0, WTBUFLEN * 2 * sizeof(float)); if (init_midi) memset(midi_buf, 0, midi_buf_size * sizeof(float)); } else { memset(buf_int16, 0, BUFLEN * 2 * sizeof(int16_t)); memset(cd_buf_int16, 0, CD_BUFLEN * 2 * sizeof(int16_t)); memset(music_buf_int16, 0, MUSICBUFLEN * 2 * sizeof(int16_t)); + memset(wt_buf_int16, 0, WTBUFLEN * 2 * sizeof(int16_t)); if (init_midi) memset(midi_buf_int16, 0, midi_buf_size * sizeof(int16_t)); } @@ -204,39 +214,45 @@ inital(void) if (sound_is_float) { alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN * 2 * sizeof(float), FREQ); alBufferData(buffers_music[c], AL_FORMAT_STEREO_FLOAT32, music_buf, MUSICBUFLEN * 2 * sizeof(float), MUSIC_FREQ); + alBufferData(buffers_wt[c], AL_FORMAT_STEREO_FLOAT32, wt_buf, WTBUFLEN * 2 * sizeof(float), WT_FREQ); alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, cd_buf, CD_BUFLEN * 2 * sizeof(float), CD_FREQ); if (init_midi) - alBufferData(buffers_midi[c], AL_FORMAT_STEREO_FLOAT32, midi_buf, midi_buf_size * sizeof(float), midi_freq); + alBufferData(buffers_midi[c], AL_FORMAT_STEREO_FLOAT32, midi_buf, midi_buf_size * (int) sizeof(float), midi_freq); } else { alBufferData(buffers[c], AL_FORMAT_STEREO16, buf_int16, BUFLEN * 2 * sizeof(int16_t), FREQ); alBufferData(buffers_music[c], AL_FORMAT_STEREO16, music_buf_int16, MUSICBUFLEN * 2 * sizeof(int16_t), MUSIC_FREQ); + alBufferData(buffers_wt[c], AL_FORMAT_STEREO16, wt_buf_int16, WTBUFLEN * 2 * sizeof(int16_t), WT_FREQ); alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, cd_buf_int16, CD_BUFLEN * 2 * sizeof(int16_t), CD_FREQ); if (init_midi) - alBufferData(buffers_midi[c], AL_FORMAT_STEREO16, midi_buf_int16, midi_buf_size * sizeof(int16_t), midi_freq); + alBufferData(buffers_midi[c], AL_FORMAT_STEREO16, midi_buf_int16, midi_buf_size * (int) sizeof(int16_t), midi_freq); } } alSourceQueueBuffers(source[0], 4, buffers); alSourceQueueBuffers(source[1], 4, buffers_music); - alSourceQueueBuffers(source[2], 4, buffers_cd); + alSourceQueueBuffers(source[2], 4, buffers_wt); + alSourceQueueBuffers(source[3], 4, buffers_cd); if (init_midi) - alSourceQueueBuffers(source[3], 4, buffers_midi); + alSourceQueueBuffers(source[4], 4, buffers_midi); alSourcePlay(source[0]); alSourcePlay(source[1]); alSourcePlay(source[2]); + alSourcePlay(source[3]); if (init_midi) - alSourcePlay(source[3]); + alSourcePlay(source[4]); if (sound_is_float) { if (init_midi) free(midi_buf); free(cd_buf); + free(wt_buf); free(music_buf); free(buf); } else { if (init_midi) free(midi_buf_int16); free(cd_buf_int16); + free(wt_buf_int16); free(music_buf_int16); free(buf_int16); } @@ -245,12 +261,11 @@ inital(void) } void -givealbuffer_common(void *buf, uint8_t src, int size, int freq) +givealbuffer_common(const void *buf, const uint8_t src, const int size, const int freq) { int processed; int state; ALuint buffer; - double gain; if (!initialized) return; @@ -263,40 +278,40 @@ givealbuffer_common(void *buf, uint8_t src, int size, int freq) alGetSourcei(source[src], AL_BUFFERS_PROCESSED, &processed); if (processed >= 1) { - gain = pow(10.0, (double) sound_gain / 20.0); - alListenerf(AL_GAIN, gain); + const double gain = pow(10.0, (double) sound_gain / 20.0); + alListenerf(AL_GAIN, (float) gain); alSourceUnqueueBuffers(source[src], 1, &buffer); if (sound_is_float) - alBufferData(buffer, AL_FORMAT_STEREO_FLOAT32, buf, size * sizeof(float), freq); + alBufferData(buffer, AL_FORMAT_STEREO_FLOAT32, buf, size * (int) sizeof(float), freq); else - alBufferData(buffer, AL_FORMAT_STEREO16, buf, size * sizeof(int16_t), freq); + alBufferData(buffer, AL_FORMAT_STEREO16, buf, size * (int) sizeof(int16_t), freq); alSourceQueueBuffers(source[src], 1, &buffer); } } void -givealbuffer(void *buf) +givealbuffer(const void *buf) { givealbuffer_common(buf, 0, BUFLEN << 1, FREQ); } void -givealbuffer_music(void *buf) +givealbuffer_music(const void *buf) { givealbuffer_common(buf, 1, MUSICBUFLEN << 1, MUSIC_FREQ); } void -givealbuffer_cd(void *buf) +givealbuffer_cd(const void *buf) { givealbuffer_common(buf, 2, CD_BUFLEN << 1, CD_FREQ); } void -givealbuffer_midi(void *buf, uint32_t size) +givealbuffer_midi(const void *buf, const uint32_t size) { - givealbuffer_common(buf, 3, size, midi_freq); + givealbuffer_common(buf, 3, (int) size, midi_freq); } diff --git a/src/sound/snd_emu8k.c b/src/sound/snd_emu8k.c index 793f8bcb7..cc01ff6dd 100644 --- a/src/sound/snd_emu8k.c +++ b/src/sound/snd_emu8k.c @@ -1758,8 +1758,7 @@ int32_t old_vol[32] = { 0 }; void emu8k_update(emu8k_t *emu8k) { - int new_pos = (sound_pos_global * FREQ_44100) / SOUND_FREQ; - if (emu8k->pos >= new_pos) + if (emu8k->pos >= wavetable_pos_global) return; int32_t *buf; @@ -1768,16 +1767,16 @@ emu8k_update(emu8k_t *emu8k) /* Clean the buffers since we will accumulate into them. */ buf = &emu8k->buffer[emu8k->pos * 2]; - memset(buf, 0, 2 * (new_pos - emu8k->pos) * sizeof(emu8k->buffer[0])); - memset(&emu8k->chorus_in_buffer[emu8k->pos], 0, (new_pos - emu8k->pos) * sizeof(emu8k->chorus_in_buffer[0])); - memset(&emu8k->reverb_in_buffer[emu8k->pos], 0, (new_pos - emu8k->pos) * sizeof(emu8k->reverb_in_buffer[0])); + memset(buf, 0, 2 * (wavetable_pos_global - emu8k->pos) * sizeof(emu8k->buffer[0])); + memset(&emu8k->chorus_in_buffer[emu8k->pos], 0, (wavetable_pos_global - emu8k->pos) * sizeof(emu8k->chorus_in_buffer[0])); + memset(&emu8k->reverb_in_buffer[emu8k->pos], 0, (wavetable_pos_global - emu8k->pos) * sizeof(emu8k->reverb_in_buffer[0])); /* Voices section */ for (uint8_t c = 0; c < 32; c++) { emu_voice = &emu8k->voice[c]; buf = &emu8k->buffer[emu8k->pos * 2]; - for (pos = emu8k->pos; pos < new_pos; pos++) { + for (pos = emu8k->pos; pos < wavetable_pos_global; pos++) { int32_t dat; if (emu_voice->cvcf_curr_volume) { @@ -2121,12 +2120,12 @@ emu8k_update(emu8k_t *emu8k) } buf = &emu8k->buffer[emu8k->pos * 2]; - emu8k_work_reverb(&emu8k->reverb_in_buffer[emu8k->pos], buf, &emu8k->reverb_engine, new_pos - emu8k->pos); - emu8k_work_chorus(&emu8k->chorus_in_buffer[emu8k->pos], buf, &emu8k->chorus_engine, new_pos - emu8k->pos); - emu8k_work_eq(buf, new_pos - emu8k->pos); + emu8k_work_reverb(&emu8k->reverb_in_buffer[emu8k->pos], buf, &emu8k->reverb_engine, wavetable_pos_global - emu8k->pos); + emu8k_work_chorus(&emu8k->chorus_in_buffer[emu8k->pos], buf, &emu8k->chorus_engine, wavetable_pos_global - emu8k->pos); + emu8k_work_eq(buf, wavetable_pos_global - emu8k->pos); // Clip signal - for (pos = emu8k->pos; pos < new_pos; pos++) { + for (pos = emu8k->pos; pos < wavetable_pos_global; pos++) { if (buf[0] < -32768) buf[0] = -32768; else if (buf[0] > 32767) @@ -2141,9 +2140,9 @@ emu8k_update(emu8k_t *emu8k) } /* Update EMU clock. */ - emu8k->wc += (new_pos - emu8k->pos); + emu8k->wc += (wavetable_pos_global - emu8k->pos); - emu8k->pos = new_pos; + emu8k->pos = wavetable_pos_global; } void diff --git a/src/sound/snd_lpt_dac.c b/src/sound/snd_lpt_dac.c index 8fb526f14..8d7dbba4e 100644 --- a/src/sound/snd_lpt_dac.c +++ b/src/sound/snd_lpt_dac.c @@ -5,12 +5,14 @@ #include #include "cpu.h" + +#include #include <86box/86box.h> #include <86box/filters.h> +#include <86box/timer.h> #include <86box/lpt.h> #include <86box/machine.h> #include <86box/sound.h> -#include <86box/timer.h> #include <86box/plat_unused.h> typedef struct lpt_dac_t { @@ -50,6 +52,14 @@ dac_write_data(uint8_t val, void *priv) dac_update(lpt_dac); } +static void +dac_strobe(uint8_t old, uint8_t val, void *priv) +{ + lpt_dac_t *lpt_dac = (lpt_dac_t *) priv; + + lpt_dac->channel = val; +} + static void dac_write_ctrl(uint8_t val, void *priv) { @@ -110,25 +120,31 @@ dac_close(void *priv) } const lpt_device_t lpt_dac_device = { - .name = "LPT DAC / Covox Speech Thing", - .internal_name = "lpt_dac", - .init = dac_init, - .close = dac_close, - .write_data = dac_write_data, - .write_ctrl = dac_write_ctrl, - .read_data = NULL, - .read_status = dac_read_status, - .read_ctrl = NULL + .name = "LPT DAC / Covox Speech Thing", + .internal_name = "lpt_dac", + .init = dac_init, + .close = dac_close, + .write_data = dac_write_data, + .write_ctrl = dac_write_ctrl, + .autofeed = NULL, + .strobe = dac_strobe, + .read_status = dac_read_status, + .read_ctrl = NULL, + .epp_write_data = NULL, + .epp_request_read = NULL }; const lpt_device_t lpt_dac_stereo_device = { - .name = "Stereo LPT DAC", - .internal_name = "lpt_dac_stereo", - .init = dac_stereo_init, - .close = dac_close, - .write_data = dac_write_data, - .write_ctrl = dac_write_ctrl, - .read_data = NULL, - .read_status = dac_read_status, - .read_ctrl = NULL + .name = "Stereo LPT DAC", + .internal_name = "lpt_dac_stereo", + .init = dac_stereo_init, + .close = dac_close, + .write_data = dac_write_data, + .write_ctrl = dac_write_ctrl, + .autofeed = NULL, + .strobe = dac_strobe, + .read_status = dac_read_status, + .read_ctrl = NULL, + .epp_write_data = NULL, + .epp_request_read = NULL }; diff --git a/src/sound/snd_lpt_dss.c b/src/sound/snd_lpt_dss.c index bd794fffb..5e5191e98 100644 --- a/src/sound/snd_lpt_dss.c +++ b/src/sound/snd_lpt_dss.c @@ -7,10 +7,10 @@ #include "cpu.h" #include <86box/86box.h> #include <86box/filters.h> +#include <86box/timer.h> #include <86box/lpt.h> #include <86box/machine.h> #include <86box/sound.h> -#include <86box/timer.h> #include <86box/plat_unused.h> typedef struct dss_t { @@ -134,13 +134,16 @@ dss_close(void *priv) } const lpt_device_t dss_device = { - .name = "Disney Sound Source", - .internal_name = "dss", - .init = dss_init, - .close = dss_close, - .write_data = dss_write_data, - .write_ctrl = dss_write_ctrl, - .read_data = NULL, - .read_status = dss_read_status, - .read_ctrl = NULL + .name = "Disney Sound Source", + .internal_name = "dss", + .init = dss_init, + .close = dss_close, + .write_data = dss_write_data, + .autofeed = NULL, + .strobe = NULL, + .write_ctrl = dss_write_ctrl, + .read_status = dss_read_status, + .read_ctrl = NULL, + .epp_write_data = NULL, + .epp_request_read = NULL }; diff --git a/src/sound/snd_opl_ymfm.cpp b/src/sound/snd_opl_ymfm.cpp index 55e7f1984..1da97adfa 100644 --- a/src/sound/snd_opl_ymfm.cpp +++ b/src/sound/snd_opl_ymfm.cpp @@ -74,7 +74,6 @@ public: virtual void write(uint16_t addr, uint8_t data) = 0; virtual void generate(int32_t *data, uint32_t num_samples) = 0; - virtual void generate_resampled(int32_t *data, uint32_t num_samples) = 0; virtual int32_t *update() = 0; virtual uint8_t read(uint16_t addr) = 0; virtual void set_clock(uint32_t clock) = 0; @@ -82,6 +81,7 @@ public: protected: int32_t m_buffer[MUSICBUFLEN * 2]; int m_buf_pos; + int *m_buf_pos_global; int8_t m_flags; fm_type m_type; uint32_t m_samplerate; @@ -99,11 +99,12 @@ public: { memset(m_samples, 0, sizeof(m_samples)); memset(m_oldsamples, 0, sizeof(m_oldsamples)); - m_rateratio = (samplerate << RSM_FRAC) / m_chip.sample_rate(m_clock); - m_clock_us = 1000000.0 / (double) m_clock; - m_subtract[0] = 80.0; - m_subtract[1] = 320.0; - m_type = type; + m_rateratio = (samplerate << RSM_FRAC) / m_chip.sample_rate(m_clock); + m_clock_us = 1000000.0 / (double) m_clock; + m_subtract[0] = 80.0; + m_subtract[1] = 320.0; + m_type = type; + m_buf_pos_global = (samplerate == FREQ_49716) ? &music_pos_global : &wavetable_pos_global; if (m_type == FM_YMF278B) { if (rom_load_linear("roms/sound/yamaha/yrw801.rom", 0, 0x200000, 0, m_yrw801) == 0) { @@ -170,9 +171,10 @@ public: } } +#if 0 virtual void generate_resampled(int32_t *data, uint32_t num_samples) override { - if (m_samplerate == FREQ_49716) { + if ((m_samplerate == FREQ_49716) || (m_samplerate == FREQ_44100)) { generate(data, num_samples); return; } @@ -210,29 +212,18 @@ public: m_samplecnt += 1 << RSM_FRAC; } } +#endif virtual int32_t *update() override { - if (m_samplerate == FREQ_49716) { - if (m_buf_pos >= music_pos_global) - return m_buffer; + if (m_buf_pos >= *m_buf_pos_global) + return m_buffer; - generate(&m_buffer[m_buf_pos * 2], music_pos_global - m_buf_pos); + generate(&m_buffer[m_buf_pos * 2], *m_buf_pos_global - m_buf_pos); - for (; m_buf_pos < music_pos_global; m_buf_pos++) { - m_buffer[m_buf_pos * 2] /= 2; - m_buffer[(m_buf_pos * 2) + 1] /= 2; - } - } else { - if (m_buf_pos >= sound_pos_global) - return m_buffer; - - generate_resampled(&m_buffer[m_buf_pos * 2], sound_pos_global - m_buf_pos); - - for (; m_buf_pos < sound_pos_global; m_buf_pos++) { - m_buffer[m_buf_pos * 2] /= 2; - m_buffer[(m_buf_pos * 2) + 1] /= 2; - } + for (; m_buf_pos < *m_buf_pos_global; m_buf_pos++) { + m_buffer[m_buf_pos * 2] /= 2; + m_buffer[(m_buf_pos * 2) + 1] /= 2; } return m_buffer; @@ -343,11 +334,11 @@ ymfm_drv_init(const device_t *info) case FM_YMF289B: /* According to the datasheet, we should be using 33868800, but YMFM appears to cheat and does it using the same values as the YMF262. */ - fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF289B, OPL_FREQ); + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF289B, FREQ_49716); break; case FM_YMF278B: - fm = (YMFMChipBase *) new YMFMChip(33868800, FM_YMF278B, OPL_FREQ); + fm = (YMFMChipBase *) new YMFMChip(33868800, FM_YMF278B, FREQ_44100); break; } @@ -422,7 +413,8 @@ static void ymfm_drv_generate(void *priv, int32_t *data, uint32_t num_samples) { YMFMChipBase *drv = (YMFMChipBase *) priv; - drv->generate_resampled(data, num_samples); + // drv->generate_resampled(data, num_samples); + drv->generate(data, num_samples); } const device_t ym3812_ymfm_device = { diff --git a/src/sound/snd_optimc.c b/src/sound/snd_optimc.c index 245d9590e..3b649639a 100644 --- a/src/sound/snd_optimc.c +++ b/src/sound/snd_optimc.c @@ -414,7 +414,7 @@ optimc_init(const device_t *info) sound_add_handler(optimc_get_buffer, optimc); if (optimc->fm_type == FM_YMF278B) - sound_add_handler(sb_get_music_buffer_sbpro, optimc->sb); + wavetable_add_handler(sb_get_music_buffer_sbpro, optimc->sb); else music_add_handler(sb_get_music_buffer_sbpro, optimc->sb); sound_set_cd_audio_filter(sbpro_filter_cd_audio, optimc->sb); /* CD audio filter for the default context */ diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 4530bda86..80d93dcbf 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -92,7 +92,6 @@ #include #include #include -#include #define HAVE_STDARG_H #include "cpu.h" @@ -100,24 +99,86 @@ #include <86box/device.h> #include <86box/dma.h> #include <86box/filters.h> +#include <86box/plat_unused.h> #include <86box/io.h> +#include <86box/mem.h> #include <86box/midi.h> #include <86box/pic.h> #include <86box/timer.h> #include <86box/pit.h> #include <86box/pit_fast.h> +#include <86box/rom.h> +#include <86box/scsi_ncr5380.h> +#include <86box/scsi_ncr53c400.h> #include <86box/snd_mpu401.h> #include <86box/sound.h> #include <86box/snd_opl.h> #include <86box/snd_sb.h> #include <86box/snd_sb_dsp.h> -#include <86box/plat_unused.h> +#include <86box/snd_sb_dsp.h> + +typedef struct nsc_mixer_t { + double master_l; + double master_r; + + int bass; + int treble; + + double fm_l; + double fm_r; + double imixer_l; + double imixer_r; + double line_l; + double line_r; + double cd_l; + double cd_r; + double mic_l; + double mic_r; + double pcm_l; + double pcm_r; + double speaker_l; + double speaker_r; + + uint8_t lmc1982_regs[8]; + uint8_t lmc835_regs[32]; + + uint8_t im_state; + uint16_t im_data[4]; +} nsc_mixer_t; + +typedef struct mv508_mixer_t { + double master_l; + double master_r; + + int bass; + int treble; + + double fm_l; + double fm_r; + double imixer_l; + double imixer_r; + double line_l; + double line_r; + double cd_l; + double cd_r; + double mic_l; + double mic_r; + double pcm_l; + double pcm_r; + double speaker_l; + double speaker_r; + double sb_l; + double sb_r; + + uint8_t index; + uint8_t regs[3][128]; +} mv508_mixer_t; typedef struct pas16_t { uint8_t this_id; uint8_t board_id; uint8_t master_ff; - uint8_t irq; + uint8_t has_scsi; uint8_t dma; uint8_t sb_irqdma; uint8_t type; @@ -150,6 +211,10 @@ typedef struct pas16_t { uint8_t midi_data; uint8_t fifo_stat; + uint8_t timeout_count; + uint8_t timeout_status; + uint8_t pad_array[6]; + uint8_t midi_queue[256]; uint16_t base; @@ -170,12 +235,22 @@ typedef struct pas16_t { int midi_uart_in; int sysex; + int irq; + int scsi_irq; + + nsc_mixer_t nsc_mixer; + mv508_mixer_t mv508_mixer; + fm_drv_t opl; sb_dsp_t dsp; mpu_t * mpu; pitf_t * pit; + + ncr53c400_t *scsi; + + pc_timer_t scsi_timer; } pas16_t; static uint8_t pas16_next = 0; @@ -207,45 +282,385 @@ enum { PAS16_FILT_MUTE = 0x20 }; +enum { + STATE_SM_IDLE = 0x00, + STATE_LMC1982_ADDR = 0x10, + STATE_LMC1982_ADDR_0 = 0x10, + STATE_LMC1982_ADDR_1, + STATE_LMC1982_ADDR_2, + STATE_LMC1982_ADDR_3, + STATE_LMC1982_ADDR_4, + STATE_LMC1982_ADDR_5, + STATE_LMC1982_ADDR_6, + STATE_LMC1982_ADDR_7, + STATE_LMC1982_ADDR_OVER, + STATE_LMC1982_DATA = 0x10, + STATE_LMC1982_DATA_0 = 0x20, + STATE_LMC1982_DATA_1, + STATE_LMC1982_DATA_2, + STATE_LMC1982_DATA_3, + STATE_LMC1982_DATA_4, + STATE_LMC1982_DATA_5, + STATE_LMC1982_DATA_6, + STATE_LMC1982_DATA_7, + STATE_LMC1982_DATA_8, + STATE_LMC1982_DATA_9, + STATE_LMC1982_DATA_A, + STATE_LMC1982_DATA_B, + STATE_LMC1982_DATA_C, + STATE_LMC1982_DATA_D, + STATE_LMC1982_DATA_E, + STATE_LMC1982_DATA_F, + STATE_LMC1982_DATA_OVER, + STATE_LMC835_DATA = 0x40, + STATE_LMC835_DATA_0 = 0x40, + STATE_LMC835_DATA_1, + STATE_LMC835_DATA_2, + STATE_LMC835_DATA_3, + STATE_LMC835_DATA_4, + STATE_LMC835_DATA_5, + STATE_LMC835_DATA_6, + STATE_LMC835_DATA_7, + STATE_LMC835_DATA_OVER, +}; + +#define STATE_DATA_MASK 0x07 +#define STATE_DATA_MASK_W 0x0f + +#define LMC1982_ADDR 0x00 +#define LMC1982_DATA 0x01 +#define LMC835_ADDR 0x02 +#define LMC835_DATA 0x03 + +#define LMC835_FLAG_ADDR 0x80 + +#define SERIAL_MIXER_IDENT 0x10 +#define SERIAL_MIXER_STROBE 0x04 +#define SERIAL_MIXER_CLOCK 0x02 +#define SERIAL_MIXER_DATA 0x01 +#define SERIAL_MIXER_RESET_PCM 0x01 + #define PAS16_PCM_AND_DMA_ENA (PAS16_PCM_ENA | PAS16_PCM_DMA_ENA) -double low_fir_pas16_coef[4][SB16_NCoef]; +/* + LMC1982CIN registers (data bits 7 and 6 are always don't care): + - 40 = Mode (0x01 = INPUT2); + - 41 = 0 = Loudness (1 = on, 0 = off), 1 = Stereo Enhance (1 = on, 0 = off) + (0x00); + - 42 = Bass, 00-0c (0x06); + - 43 = Treble, 00-0c (0x06); + - 45 [L] / 44 [R] = Master, 28-00, counting down (0x28, later 0xa8); + - 46 = ???? (0x05 = Stereo). + */ +#define LMC1982_REG_MASK 0xf8 /* LMC1982CIN: Register Mask */ +#define LMC1982_REG_VALID 0x40 /* LMC1982CIN: Register Valid Value */ + +#define LMC1982_REG_ISELECT 0x00 /* LMC1982CIN: Input Select + Mute */ +#define LMC1982_REG_LES 0x01 /* LMC1982CIN: Loudness, Enhanced Stereo */ +#define LMC1982_REG_BASS 0x02 /* LMC1982CIN: Bass */ +#define LMC1982_REG_TREBLE 0x03 /* LMC1982CIN: Treble */ +/* The Windows 95 driver indicates left and right are swapped in the wiring. */ +#define LMC1982_REG_VOL_L 0x04 /* LMC1982CIN: Left Volume */ +#define LMC1982_REG_VOL_R 0x05 /* LMC1982CIN: Right Volume */ +#define LMC1982_REG_MODE 0x06 /* LMC1982CIN: Mode */ +#define LMC1982_REG_DINPUT 0x07 /* LMC1982CIN: Digital Input 1 and 2 */ + +/* Bits 7-2: Don't care. */ +#define LMC1982_ISELECT_MASK 0x03 /* LMC1982CIN: Input Select: Mask */ +#define LMC1982_ISELECT_I1 0x00 /* LMC1982CIN: Input Select: INPUT1 */ +#define LMC1982_ISELECT_I2 0x01 /* LMC1982CIN: Input Select: INPUT2 */ +#define LMC1982_ISELECT_NA 0x02 /* LMC1982CIN: Input Select: N/A */ +#define LMC1982_ISELECT_MUTE 0x03 /* LMC1982CIN: Input Select: MUTE */ + +/* Bits 7-2: Don't care. */ +#define LMC1982_LES_MASK 0x03 /* LMC1982CIN: Loudness, Enhanced Stereo: Mask */ +#define LMC1982_LES_BOTH_OFF 0x00 /* LMC1982CIN: Loudness OFF, Enhanced Stereo OFF */ +#define LMC1982_L_ON_ES_OFF 0x01 /* LMC1982CIN: Loudness ON, Enhanced Stereo OFF */ +#define LMC1982_L_OFF_ES_ON 0x02 /* LMC1982CIN: Loudness OFF, Enhanced Stereo ON */ +#define LMC1982_LES_BOTH_ON 0x03 /* LMC1982CIN: Loudness OFF, Enhanced Stereo ON */ + +/* Bits 7-3: Don't care. */ +#define LMC1982_MODE_MASK 0x07 /* LMC1982CIN: Mode: Mask */ +#define LMC1982_MODE_MONO_L 0x04 /* LMC1982CIN: Mode: Left Mono */ +#define LMC1982_MODE_STEREO 0x05 /* LMC1982CIN: Mode: Stereo */ +#define LMC1982_MODE_MONO_R 0x06 /* LMC1982CIN: Mode: Right Mono */ +#define LMC1982_MODE_MONO_R_2 0x07 /* LMC1982CIN: Mode: Right Mono (Alternate value) */ + +/* Bits 7-2: Don't care. */ +#define LMC1982_DINPUT_MASK 0x03 /* LMC1982CIN: Digital Input 1 and 2: Mask */ +#define LMC1982_DINPUT_DI1 0x01 /* LMC1982CIN: Digital Input 1 */ +#define LMC1982_DINPUT_DI2 0x02 /* LMC1982CIN: Digital Input 2 */ + +/* + LMC835N registers: + - 01 [L] / 08 [R] = FM, 00-2f, bit 6 = clear, but the DOS driver sets + the bit, indicating a volume boost (0x69); + - 02 [L] / 09 [R] = Rec. monitor, 00-2f, bit 6 = clear (0x29); + - 03 [L] / 0A [R] = Line in, 00-2f, bit 6 = clear, except for the DOS + driver (0x69); + - 04 [L] / 0B [R] = CD, 00-2f, bit 6 = clear, except for the DOS driver + (0x69); + - 05 [L] / 0C [R] = Microphone, 00-2f, bit 6 = clear, except for the DOS + driver (0x44); + - 06 [L] / 0D [R] = Wave out, 00-2f, bit 6 = set, except for DOS driver, + which clears the bit (0x29); + - 07 [L] / 0E [R] = PC speaker, 00-2f, bit 6 = clear, except for the DOS + drive (0x06). + The registers for which the DOS driver sets the boost, also have bit 6 + set in the address, despite the fact it should be a don't care - why? + Apparently, no Sound Blaster control. +*/ +#define LMC835_REG_MODE 0x00 /* LMC835N: Mode, not an actual register, but our internal register + to store the mode for Channels A (1-7) and B (8-e). */ + +#define LMC835_REG_FM_L 0x01 /* LMC835N: FM Left */ +#define LMC835_REG_IMIXER_L 0x02 /* LMC835N: Record Monitor Left */ +#define LMC835_REG_LINE_L 0x03 /* LMC835N: Line in Left */ +#define LMC835_REG_CDROM_L 0x04 /* LMC835N: CD Left */ +#define LMC835_REG_MIC_L 0x05 /* LMC835N: Microphone Left */ +#define LMC835_REG_PCM_L 0x06 /* LMC835N: Wave out Left */ +#define LMC835_REG_SPEAKER_L 0x07 /* LMC83N5: PC speaker Left */ + +#define LMC835_REG_FM_R 0x08 /* LMC835N: FM Right */ +#define LMC835_REG_IMIXER_R 0x09 /* LMC835N: Record Monitor Right */ +#define LMC835_REG_LINE_R 0x0a /* LMC835N: Line in Right */ +#define LMC835_REG_CDROM_R 0x0b /* LMC835N: CD Right */ +#define LMC835_REG_MIC_R 0x0c /* LMC835N: Microphone Right */ +#define LMC835_REG_PCM_R 0x0d /* LMC835N: Wave out Right */ +#define LMC835_REG_SPEAKER_R 0x0e /* LMC83N5: PC speaker Right */ + +#define MV508_ADDRESS 0x80 /* Flag indicating it is the address */ +/* + I think this may actually operate as such: + - Bit 6: Mask left channel; + - Bit 5: Mask right channel. + */ +#define MV508_CHANNEL 0x60 +#define MV508_LEFT 0x20 +#define MV508_RIGHT 0x40 +#define MV508_BOTH 0x00 +#define MV508_MIXER 0x10 /* Flag indicating it is a mixer rather than a volume */ + +#define MV508_INPUT_MIX 0x20 /* Flag indicating the selected mixer is input */ + +#define MV508_MASTER_A 0x01 /* Volume: Output */ +#define MV508_MASTER_B 0x02 /* Volume: DSP input */ +#define MV508_BASS 0x03 /* Volume: Bass */ +#define MV508_TREBLE 0x04 /* Volume: Treble */ +#define MV508_MODE 0x05 /* Volume: Mode */ + +#define MV508_LOUDNESS 0x04 /* Mode: Loudness */ +#define MV508_ENH_MASK 0x03 /* Mode: Stereo enhancement bit mask */ +#define MV508_ENH_NONE 0x00 /* Mode: No stereo enhancement */ +#define MV508_ENH_40 0x01 /* Mode: 40% stereo enhancement */ +#define MV508_ENH_60 0x02 /* Mode: 60% stereo enhancement */ +#define MV508_ENH_80 0x03 /* Mode: 80% stereo enhancement */ + +#define MV508_FM 0x00 /* Mixer: FM */ +#define MV508_IMIXER 0x01 /* Mixer: Input mixer (recording monitor) */ +#define MV508_LINE 0x02 /* Mixer: Line in */ +#define MV508_CDROM 0x03 /* Mixer: CD-ROM */ +#define MV508_MIC 0x04 /* Mixer: Microphone */ +#define MV508_PCM 0x05 /* Mixer: PCM */ +#define MV508_SPEAKER 0x06 /* Mixer: PC Speaker */ +#define MV508_SB 0x07 /* Mixer: Sound Blaster DSP */ + +#define MV508_REG_MASTER_A_L (MV508_MASTER_A | MV508_LEFT) +#define MV508_REG_MASTER_A_R (MV508_MASTER_A | MV508_RIGHT) +#define MV508_REG_MASTER_B_L (MV508_MASTER_B | MV508_LEFT) +#define MV508_REG_MASTER_B_R (MV508_MASTER_B | MV508_RIGHT) +#define MV508_REG_BASS (MV508_BASS | MV508_LEFT) +#define MV508_REG_TREBLE (MV508_TREBLE | MV508_LEFT) + +#define MV508_REG_FM_L (MV508_MIXER | MV508_FM | MV508_LEFT) +#define MV508_REG_FM_R (MV508_MIXER | MV508_FM | MV508_RIGHT) +#define MV508_REG_IMIXER_L (MV508_MIXER | MV508_IMIXER | MV508_LEFT) +#define MV508_REG_IMIXER_R (MV508_MIXER | MV508_IMIXER | MV508_RIGHT) +#define MV508_REG_LINE_L (MV508_MIXER | MV508_LINE | MV508_LEFT) +#define MV508_REG_LINE_R (MV508_MIXER | MV508_LINE | MV508_RIGHT) +#define MV508_REG_CDROM_L (MV508_MIXER | MV508_CDROM | MV508_LEFT) +#define MV508_REG_CDROM_R (MV508_MIXER | MV508_CDROM | MV508_RIGHT) +#define MV508_REG_MIC_L (MV508_MIXER | MV508_MIC | MV508_LEFT) +#define MV508_REG_MIC_R (MV508_MIXER | MV508_MIC | MV508_RIGHT) +#define MV508_REG_PCM_L (MV508_MIXER | MV508_PCM | MV508_LEFT) +#define MV508_REG_PCM_R (MV508_MIXER | MV508_PCM | MV508_RIGHT) +#define MV508_REG_SPEAKER_L (MV508_MIXER | MV508_SPEAKER | MV508_LEFT) +#define MV508_REG_SPEAKER_R (MV508_MIXER | MV508_SPEAKER | MV508_RIGHT) +#define MV508_REG_SB_L (MV508_MIXER | MV508_SB | MV508_LEFT) +#define MV508_REG_SB_R (MV508_MIXER | MV508_SB | MV508_RIGHT) + +double low_fir_pas16_coef[SB16_NCoef]; + +/* + Also used for the MVA508. + */ +static double lmc1982_bass_treble_4bits[16]; + +/* + Copied from the Sound Blaster code: -62 dB to 0 dB in 2 dB steps. + Note that these are voltage dB's, so it corresonds in power dB + (formula for conversion to percentage: 10 ^ (dB / 10)) to -31 dB + to 0 dB in 1 dB steps. + + This is used for the MVA508 Volumes. + */ +static const double mva508_att_2dbstep_5bits[] = { + 25.0, 32.0, 41.0, 51.0, 65.0, 82.0, 103.0, 130.0, + 164.0, 206.0, 260.0, 327.0, 412.0, 519.0, 653.0, 822.0, + 1036.0, 1304.0, 1641.0, 2067.0, 2602.0, 3276.0, 4125.0, 5192.0, + 6537.0, 8230.0, 10362.0, 13044.0, 16422.0, 20674.0, 26027.0, 32767.0 +}; + +/* + The same but in 1 dB steps, used for the MVA508 Master Volume. + */ +static const double mva508_att_1dbstep_6bits[] = { + 18.0, 25.0, 29.0, 32.0, 36.0, 41.0, 46.0, 51.0, + 58.0, 65.0, 73.0, 82.0, 92.0, 103.0, 116.0, 130.0, + 146.0, 164.0, 184.0, 206.0, 231.0, 260.0, 292.0, 327.0, + 367.0, 412.0, 462.0, 519.0, 582.0, 653.0, 733.0, 822.0, + 923.0, 1036.0, 1162.0, 1304.0, 1463.0, 1641.0, 1842.0, 2067.0, + 2319.0, 2602.0, 2920.0, 3276.0, 3676.0, 4125.0, 4628.0, 5192.0, + 5826.0, 6537.0, 7335.0, 8230.0, 9234.0, 10362.0, 11626.0, 13044.0, + 14636.0, 16422.0, 18426.0, 20674.0, 23197.0, 26027.0, 29204.0, 32767.0 +}; + +/* + In 2 dB steps again, but to -80 dB and counting down (0 = Flat), used + for the LMC1982CIN Master Volume. + */ +static const double lmc1982_att_2dbstep_6bits[] = { + 32767.0, 26027.0, 20674.0, 16422.0, 13044.0, 10362.0, 8230.0, 6537.0, + 5192.0, 4125.0, 3276.0, 2602.0, 2067.0, 1641.0, 1304.0, 1036.0, + 822.0, 653.0, 519.0, 412.0, 327.0, 260.0, 206.0, 164.0, + 130.0, 103.0, 82.0, 65.0, 51.0, 41.0, 32.0, 25.0, + 20.0, 16.0, 13.0, 10.0, 8.0, 6.0, 5.0, 4.0, + 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, + 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, + 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0 +}; + +/* + LMC385N attenuation, both +/- 12 dB and +/- 6 dB. + + Since the DOS and Windows 95 driver diverge on boost vs. cut for + the various inputs, I think it is best to just do a 12 dB cut on + the input, and then apply cut or boost as needed. I have factored + in said cut in the below values. + */ +static const double lmc835_att_1dbstep_7bits[128] = { + 0.0, + /* Flat */ + [0x40] = 8230.0, /* Flat */ + /* Boost */ + [0x60] = 9234.0, /* 1 dB Boost */ + [0x50] = 10362.0, /* 2 dB Boost */ + [0x48] = 11626.0, /* 3 dB Boost */ + [0x44] = 13044.0, /* 4 dB Boost */ + [0x42] = 14636.0, /* 5 dB Boost */ + [0x52] = 16422.0, /* 6 dB Boost */ + [0x6a] = 18426.0, /* 7 dB Boost */ + [0x56] = 20674.0, /* 8 dB Boost */ + [0x41] = 23197.0, /* 9 dB Boost */ + [0x69] = 26027.0, /* 10 dB Boost */ + [0x6d] = 29204.0, /* 11 dB Boost */ + /* The Win95 drivers use D5-D0 = 1D instead of 2D, datasheet erratum? */ + [0x5d] = 29204.0, /* 11 dB Boost */ + [0x6f] = 32767.0, /* 12 dB Boost */ + /* Flat */ + /* The datasheet says this should be Flat (1.0) but the + Windows 95 drivers use this as basically mute (12 dB Cut). */ + [0x00] = 2067.0, /* 12 dB Cut */ + /* Cut - D5-D0 = 2F is minimum cut (0 dB) according to Windows 95 */ + [0x20] = 2319.0, /* 11 dB Cut */ + [0x10] = 2602.0, /* 10 dB Cut */ + [0x08] = 2920.0, /* 9 dB Cut */ + [0x04] = 3276.0, /* 8 dB Cut */ + [0x02] = 3676.0, /* 7 dB Cut */ + [0x12] = 4125.0, /* 6 dB Cut */ + [0x2a] = 4628.0, /* 5 dB Cut */ + [0x16] = 5192.0, /* 4 dB Cut */ + [0x01] = 5826.0, /* 3 dB Cut */ + [0x29] = 6537.0, /* 2 dB Cut */ + [0x2d] = 7335.0, /* 1 dB Cut */ + /* The Win95 drivers use D5-D0 = 1D instead of 2D, datasheet erratum? */ + [0x1d] = 7335.0, /* 1 dB Cut */ + [0x2f] = 8230.0, /* Flat */ +}; + +static const double lmc835_att_05dbstep_7bits[128] = { + 0.0 , + /* Flat */ + [0x40] = 8230.0, /* Flat */ + /* Boost */ + [0x60] = 8718.0, /* 0.5 dB Boost */ + [0x50] = 9234.0, /* 1.0 dB Boost */ + [0x48] = 9782.0, /* 1.5 dB Boost */ + [0x44] = 10362.0, /* 2.0 dB Boost */ + [0x42] = 10975.0, /* 2.5 dB Boost */ + [0x52] = 11626.0, /* 3.0 dB Boost */ + [0x6a] = 12315.0, /* 3.5 dB Boost */ + [0x56] = 13044.0, /* 4.0 dB Boost */ + [0x41] = 13817.0, /* 4.5 dB Boost */ + [0x69] = 14636.0, /* 5.0 dB Boost */ + [0x6d] = 15503.0, /* 5.5 dB Boost */ + /* The Win95 drivers use D5-D0 = 1D instead of 2D, datasheet erratum? */ + [0x5d] = 15503.0, /* 5.5 dB Boost */ + [0x6f] = 16422.0, /* 6.0 dB Boost */ + /* Flat */ + /* The datasheet says this should be Flat (1.0) but the + Windows 95 drivers use this as basically mute (12 dB Cut). */ + [0x00] = 4125.0, /* 6.0 dB Cut */ + /* Cut - D5-D0 = 2F is minimum cut (0 dB) according to Windows 95 */ + [0x20] = 4369.0, /* 5.5 dB Cut */ + [0x10] = 4628.0, /* 5.0 dB Cut */ + [0x08] = 4920.0, /* 4.5 dB Cut */ + [0x04] = 5192.0, /* 4.0 dB Cut */ + [0x02] = 5500.0, /* 3.5 dB Cut */ + [0x12] = 5826.0, /* 3.0 dB Cut */ + [0x2a] = 6172.0, /* 2.5 dB Cut */ + [0x16] = 6537.0, /* 2.0 dB Cut */ + [0x01] = 6925.0, /* 1.5 dB Cut */ + [0x29] = 7335.0, /* 1.0 dB Cut */ + [0x2d] = 7770.0, /* 0.5 dB Cut */ + /* The Win95 drivers use D5-D0 = 1D instead of 2D, datasheet erratum? */ + [0x1d] = 7770.0, /* 0.5 dB Cut */ + [0x2f] = 8230.0, /* Flat */ +}; static __inline double -sinc(double x) +sinc(const double x) { return sin(M_PI * x) / (M_PI * x); } static void -recalc_pas16_filter(int c, int playback_freq) +recalc_pas16_filter(const int playback_freq) { /* Cutoff frequency = playback / 2 */ - int n; - double w; - double h; - double fC = ((double) playback_freq) / (double) FREQ_96000; - double gain; + int n; + const double fC = ((double) playback_freq) / (double) FREQ_96000; + double gain = 0.0; for (n = 0; n < SB16_NCoef; n++) { /* Blackman window */ - w = 0.42 - (0.5 * cos((2.0 * n * M_PI) / (double) (SB16_NCoef - 1))) + (0.08 * cos((4.0 * n * M_PI) / (double) (SB16_NCoef - 1))); + const double w = 0.42 - (0.5 * cos((2.0 * n * M_PI) / (double) (SB16_NCoef - 1))) + + (0.08 * cos((4.0 * n * M_PI) / (double) (SB16_NCoef - 1))); /* Sinc filter */ - h = sinc(2.0 * fC * ((double) n - ((double) (SB16_NCoef - 1) / 2.0))); + const double h = sinc(2.0 * fC * ((double) n - ((double) (SB16_NCoef - 1) / 2.0))); /* Create windowed-sinc filter */ - low_fir_pas16_coef[c][n] = w * h; + low_fir_pas16_coef[n] = w * h; } - low_fir_pas16_coef[c][(SB16_NCoef - 1) / 2] = 1.0; + low_fir_pas16_coef[(SB16_NCoef - 1) / 2] = 1.0; - gain = 0.0; for (n = 0; n < SB16_NCoef; n++) - gain += low_fir_pas16_coef[c][n]; + gain += low_fir_pas16_coef[n]; /* Normalise filter, to produce unity gain */ for (n = 0; n < SB16_NCoef; n++) - low_fir_pas16_coef[c][n] /= gain; + low_fir_pas16_coef[n] /= gain; } #ifdef ENABLE_PAS16_LOG @@ -276,12 +691,12 @@ pas16_update_irq(pas16_t *pas16) { if (pas16->midi_uart_out && (pas16->midi_stat & 0x18)) { pas16->irq_stat |= PAS16_INT_MIDI; - if (pas16->irq_ena & PAS16_INT_MIDI) + if ((pas16->irq != -1) && (pas16->irq_ena & PAS16_INT_MIDI)) picint(1 << pas16->irq); } if (pas16->midi_uart_in && (pas16->midi_stat & 0x04)) { pas16->irq_stat |= PAS16_INT_MIDI; - if (pas16->irq_ena & PAS16_INT_MIDI) + if ((pas16->irq != -1) && (pas16->irq_ena & PAS16_INT_MIDI)) picint(1 << pas16->irq); } } @@ -291,6 +706,7 @@ pas16_in(uint16_t port, void *priv) { pas16_t *pas16 = (pas16_t *) priv; uint8_t ret = 0xff; + ncr53c400_t *dev = (ncr53c400_t *) pas16->scsi; port -= pas16->base; @@ -300,7 +716,7 @@ pas16_in(uint16_t port, void *priv) break; case 0x0800: - ret = pas16->audio_mixer; + ret = pas16->type ? pas16->audio_mixer : 0xff; break; case 0x0801: ret = pas16->irq_stat & 0xdf; @@ -346,10 +762,47 @@ pas16_in(uint16_t port, void *priv) ret = pas16->fifo_stat; break; + case 0x1c00 ... 0x1c03: /* NCR5380 ports 0 to 3. */ + case 0x3c00 ... 0x3c03: /* NCR5380 ports 4 to 7. */ + if (pas16->has_scsi) { + port = (port & 0x0003) | ((port & 0x2000) >> 11); + ret = ncr5380_read(port, &pas16->scsi->ncr); + } + break; + case 0x2401: /* Board revision */ ret = 0x00; break; + case 0x4000: + ret = pas16->timeout_count; + break; + case 0x4001: + ret = pas16->timeout_status; + break; + + case 0x5c00: + if (pas16->has_scsi) + ret = ncr53c400_simple_read(pas16->scsi); + break; + case 0x5c01: + if (pas16->has_scsi) { + ret = ((dev->ncr.dma_mode != DMA_IDLE) && !(dev->status_ctrl & STATUS_BUFFER_NOT_READY)) << 7; + if (!(ret & 0x80)) { + ncr53c400_callback(pas16->scsi); + if ((dev->ncr.dma_mode != DMA_IDLE) && !(dev->status_ctrl & STATUS_BUFFER_NOT_READY)) { + timer_stop(&pas16->scsi_timer); + pas16->timeout_status &= 0x7f; + } + + } + } + break; + case 0x5c03: + if (pas16->has_scsi) + ret = pas16->scsi->ncr.irq_state << 7; + break; + case 0x7c01: ret = pas16->enhancedscsi & ~0x01; break; @@ -375,11 +828,13 @@ pas16_in(uint16_t port, void *priv) break; case 0xec03: -#ifdef NEWER_PAS16 - ret = pas16->type ? 0x0c : 0x06; -#else - ret = pas16->type ? 0x0f : 0x06; -#endif + /* + Operation mode 1: + - 1,0 = CD-ROM (1,1 = SCSI, 1,0 = Sony, 0,0 = N/A); + - 2 = FM (1 = stereo, 0 = mono); + - 3 = Code (1 = 16-bit, 0 = 8-bit). + */ + ret = pas16->type ? pas16->type : 0x06; break; case 0xf000: @@ -477,17 +932,154 @@ pas16_reset_pcm(void *priv) pas16->irq_stat &= 0xd7; - if (!pas16->irq_stat) + if ((pas16->irq != -1) && !pas16->irq_stat) picintc(1 << pas16->irq); } +static void +lmc1982_recalc(nsc_mixer_t *mixer) +{ + /* LMC1982CIN */ + /* According to the Windows 95 driver, the two volumes are swapped. */ + if ((mixer->lmc1982_regs[LMC1982_REG_ISELECT] & LMC1982_ISELECT_MASK) == LMC1982_ISELECT_I2) { + switch (mixer->lmc1982_regs[LMC1982_REG_MODE] & LMC1982_MODE_MASK) { + case LMC1982_MODE_MONO_L: + mixer->master_l = mixer->master_r = lmc1982_att_2dbstep_6bits[mixer->lmc1982_regs[LMC1982_REG_VOL_R]] / 32767.0; + break; + case LMC1982_MODE_STEREO: + mixer->master_l = lmc1982_att_2dbstep_6bits[mixer->lmc1982_regs[LMC1982_REG_VOL_R]] / 32767.0; + mixer->master_r = lmc1982_att_2dbstep_6bits[mixer->lmc1982_regs[LMC1982_REG_VOL_L]] / 32767.0; + break; + case LMC1982_MODE_MONO_R: + case LMC1982_MODE_MONO_R_2: + mixer->master_l = mixer->master_r = lmc1982_att_2dbstep_6bits[mixer->lmc1982_regs[LMC1982_REG_VOL_L]] / 32767.0; + break; + default: + mixer->master_l = mixer->master_r = 0.0; + break; + } + + mixer->bass = mixer->lmc1982_regs[LMC1982_REG_BASS] & 0x0f; + mixer->treble = mixer->lmc1982_regs[LMC1982_REG_TREBLE] & 0x0f; + } else { + mixer->master_l = mixer->master_r = 0.0; + + mixer->bass = 0x06; + mixer->treble = 0x06; + } +} + +static void +lmc835_recalc(nsc_mixer_t *mixer) +{ + /* LMC835N */ + /* Channel A (1-7) */ + const double *lmc835_att = (const double *) ((mixer->lmc835_regs[LMC835_REG_MODE] & 0x20) ? + lmc835_att_05dbstep_7bits : lmc835_att_1dbstep_7bits); + + mixer->fm_l = lmc835_att[mixer->lmc835_regs[LMC835_REG_FM_L] & 0x7f] / 32767.0; + mixer->imixer_l = lmc835_att[mixer->lmc835_regs[LMC835_REG_IMIXER_L] & 0x7f] / 32767.0; + mixer->line_l = lmc835_att[mixer->lmc835_regs[LMC835_REG_LINE_L] & 0x7f] / 32767.0; + mixer->cd_l = lmc835_att[mixer->lmc835_regs[LMC835_REG_CDROM_L] & 0x7f] / 32767.0; + mixer->mic_l = lmc835_att[mixer->lmc835_regs[LMC835_REG_MIC_L] & 0x7f] / 32767.0; + mixer->pcm_l = lmc835_att[mixer->lmc835_regs[LMC835_REG_PCM_L] & 0x7f] / 32767.0; + mixer->speaker_l = lmc835_att[mixer->lmc835_regs[LMC835_REG_SPEAKER_L] & 0x7f] / 32767.0; + + /* Channel B (8-e) */ + lmc835_att = (const double *) ((mixer->lmc835_regs[LMC835_REG_MODE] & 0x08) ? + lmc835_att_05dbstep_7bits : lmc835_att_1dbstep_7bits); + + mixer->fm_r = lmc835_att[mixer->lmc835_regs[LMC835_REG_FM_R] & 0x7f] / 32767.0; + mixer->imixer_r = lmc835_att[mixer->lmc835_regs[LMC835_REG_IMIXER_R] & 0x7f] / 32767.0; + mixer->line_r = lmc835_att[mixer->lmc835_regs[LMC835_REG_LINE_R] & 0x7f] / 32767.0; + mixer->cd_r = lmc835_att[mixer->lmc835_regs[LMC835_REG_CDROM_R] & 0x7f] / 32767.0; + mixer->mic_r = lmc835_att[mixer->lmc835_regs[LMC835_REG_MIC_R] & 0x7f] / 32767.0; + mixer->pcm_r = lmc835_att[mixer->lmc835_regs[LMC835_REG_PCM_R] & 0x7f] / 32767.0; + mixer->speaker_r = lmc835_att[mixer->lmc835_regs[LMC835_REG_SPEAKER_R] & 0x7f] / 32767.0; +} + +static void +mv508_mixer_recalc(mv508_mixer_t *mixer) +{ + mixer->fm_l = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_FM_L]] / 32767.0; + mixer->fm_r = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_FM_R]] / 32767.0; + mixer->imixer_l = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_IMIXER_L]] / 32767.0; + mixer->imixer_r = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_IMIXER_R]] / 32767.0; + mixer->line_l = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_LINE_L]] / 32767.0; + mixer->line_r = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_LINE_R]] / 32767.0; + mixer->cd_l = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_CDROM_L]] / 32767.0; + mixer->cd_r = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_CDROM_R]] / 32767.0; + mixer->mic_l = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_MIC_L]] / 32767.0; + mixer->mic_r = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_MIC_R]] / 32767.0; + mixer->pcm_l = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_PCM_L]] / 32767.0; + mixer->pcm_r = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_PCM_R]] / 32767.0; + mixer->speaker_l = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_SPEAKER_L]] / 32767.0; + mixer->speaker_r = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_SPEAKER_R]] / 32767.0; + mixer->sb_l = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_SB_L]] / 32767.0; + mixer->sb_r = mva508_att_2dbstep_5bits[mixer->regs[0][MV508_REG_SB_R]] / 32767.0; + + mixer->master_l = mva508_att_1dbstep_6bits[mixer->regs[2][MV508_REG_MASTER_A_L]] / 32767.0; + mixer->master_r = mva508_att_1dbstep_6bits[mixer->regs[2][MV508_REG_MASTER_A_R]] / 32767.0; + + mixer->bass = mixer->regs[2][MV508_REG_BASS] & 0x0f; + mixer->treble = mixer->regs[2][MV508_REG_TREBLE] & 0x0f; +} + +static void +pas16_nsc_mixer_reset(nsc_mixer_t *mixer) +{ + mixer->lmc1982_regs[LMC1982_REG_ISELECT] = 0x01; + mixer->lmc1982_regs[LMC1982_REG_LES] = 0x00; + mixer->lmc1982_regs[LMC1982_REG_BASS] = mixer->lmc1982_regs[LMC1982_REG_TREBLE] = 0x06; + mixer->lmc1982_regs[LMC1982_REG_VOL_L] = mixer->lmc1982_regs[LMC1982_REG_VOL_R] = 0x28; + mixer->lmc1982_regs[LMC1982_REG_MODE] = 0x05; + + lmc1982_recalc(mixer); + + mixer->lmc835_regs[LMC835_REG_MODE] = 0x00; + + mixer->lmc835_regs[LMC835_REG_FM_L] = mixer->lmc835_regs[LMC835_REG_FM_R] = 0x69; + mixer->lmc835_regs[LMC835_REG_IMIXER_L] = mixer->lmc835_regs[LMC835_REG_IMIXER_R] = 0x29; + mixer->lmc835_regs[LMC835_REG_LINE_L] = mixer->lmc835_regs[LMC835_REG_LINE_R] = 0x69; + mixer->lmc835_regs[LMC835_REG_CDROM_L] = mixer->lmc835_regs[LMC835_REG_CDROM_R] = 0x69; + mixer->lmc835_regs[LMC835_REG_MIC_L] = mixer->lmc835_regs[LMC835_REG_MIC_R] = 0x44; + mixer->lmc835_regs[LMC835_REG_PCM_L] = mixer->lmc835_regs[LMC835_REG_PCM_R] = 0x29; + mixer->lmc835_regs[LMC835_REG_SPEAKER_L] = mixer->lmc835_regs[LMC835_REG_SPEAKER_R] = 0x06; + + lmc835_recalc(mixer); +} + +static void +pas16_mv508_mixer_reset(mv508_mixer_t *mixer) +{ + /* Based on the Linux driver - TODO: The actual card's defaults. */ + mixer->regs[0][MV508_REG_FM_L] = mixer->regs[0][MV508_REG_FM_R] = 0x18; + mixer->regs[0][MV508_REG_IMIXER_L] = mixer->regs[0][MV508_REG_IMIXER_R] = 0x1f; + mixer->regs[0][MV508_REG_LINE_L] = mixer->regs[0][MV508_REG_LINE_R] = 0x17; + mixer->regs[0][MV508_REG_CDROM_L] = mixer->regs[0][MV508_REG_CDROM_R] = 0x17; + mixer->regs[0][MV508_REG_MIC_L] = mixer->regs[0][MV508_REG_MIC_R] = 0x17; + mixer->regs[0][MV508_REG_PCM_L] = mixer->regs[0][MV508_REG_PCM_R] = 0x17; + mixer->regs[0][MV508_REG_SPEAKER_L] = mixer->regs[0][MV508_REG_SPEAKER_R] = 0x0f; + mixer->regs[0][MV508_REG_SB_L] = mixer->regs[0][MV508_REG_SB_R] = 0x17; + + mixer->regs[2][MV508_REG_MASTER_A_L] = mixer->regs[2][MV508_REG_MASTER_A_R] = 0x1f; + + mixer->regs[2][MV508_REG_BASS] = 0x06; + mixer->regs[2][MV508_REG_TREBLE] = 0x06; + + mv508_mixer_recalc(mixer); +} + static void pas16_reset_regs(void *priv) { pas16_t *pas16 = (pas16_t *) priv; + nsc_mixer_t *nsc_mixer = &pas16->nsc_mixer; + mv508_mixer_t *mv508_mixer = &pas16->mv508_mixer; pitf_t *pit = (pitf_t *) pas16->pit; - picintc(1 << pas16->irq); + if (pas16->irq != -1) + picintc(1 << pas16->irq); pas16->sys_conf_1 &= 0xfd; @@ -509,6 +1101,11 @@ pas16_reset_regs(void *priv) pas16->irq_ena = 0x00; pas16->irq_stat = 0x00; + + if (pas16->type) + pas16_mv508_mixer_reset(mv508_mixer); + else + pas16_nsc_mixer_reset(nsc_mixer); } static void @@ -518,7 +1115,8 @@ pas16_reset_common(void *priv) pas16_reset_regs(pas16); - picintc(1 << pas16->irq); + if (pas16->irq != -1) + picintc(1 << pas16->irq); pas16_io_handler(pas16, 0); pas16->base = 0x0000; @@ -545,10 +1143,70 @@ pas16_reset(void *priv) sb_dsp_setaddr(&pas16->dsp, pas16->sb_compat_base); } +static int +pas16_irq_convert(uint8_t val) +{ + int ret = val; + + if (ret == 0) + ret = -1; + else if (ret <= 6) + ret++; + else if (ret < 0x0b) + ret += 3; + else + ret += 4; + + return ret; +} + +static void +lmc1982_update_reg(nsc_mixer_t *mixer) +{ + pas16_log("LMC1982CIN register %02X = %04X\n", + mixer->im_data[LMC1982_ADDR], mixer->im_data[LMC1982_DATA]); + + if ((mixer->im_data[LMC1982_ADDR] & LMC1982_REG_MASK) == LMC1982_REG_VALID) { + mixer->im_data[LMC1982_ADDR] &= ~LMC1982_REG_MASK; + mixer->lmc1982_regs[mixer->im_data[LMC1982_ADDR]] = mixer->im_data[LMC1982_DATA] & 0xff; + lmc1982_recalc(mixer); + } + + mixer->im_state = STATE_SM_IDLE; +} + +static void +lmc835_update_reg(nsc_mixer_t *mixer) +{ + pas16_log("LMC835N register %02X = %02X\n", + mixer->im_data[LMC835_ADDR], mixer->im_data[LMC835_DATA]); + + mixer->lmc835_regs[LMC835_REG_MODE] = mixer->im_data[LMC835_ADDR] & 0xf0; + mixer->im_data[LMC835_ADDR] &= 0x0f; + if ((mixer->im_data[LMC835_ADDR] >= 0x01) && (mixer->im_data[LMC835_ADDR] <= 0x0e)) + mixer->lmc835_regs[mixer->im_data[LMC835_ADDR] & 0x0f] = mixer->im_data[LMC835_DATA]; + lmc835_recalc(mixer); +} + +static void +pas16_timeout_callback(void *priv) +{ + pas16_t * pas16 = (pas16_t *) priv; + + pas16->timeout_status |= 0x80; + + if ((pas16->timeout_status & 0x08) && (pas16->irq != -1)) + picint(1 << pas16->irq); + + timer_advance_u64(&pas16->scsi_timer, (pas16->timeout_count & 0x3f) * PASSCSICONST); +} + static void pas16_out(uint16_t port, uint8_t val, void *priv) { - pas16_t *pas16 = (pas16_t *) priv; + pas16_t * pas16 = (pas16_t *) priv; + nsc_mixer_t * nsc_mixer = &pas16->nsc_mixer; + mv508_mixer_t *mv508_mixer = &pas16->mv508_mixer; pas16_log("[%04X:%08X] PAS16: [W] %04X (%04X) = %02X\n", CS, cpu_state.pc, port, port - pas16->base, val); @@ -560,14 +1218,178 @@ pas16_out(uint16_t port, uint8_t val, void *priv) pas16->opl.write(port + 0x0388, val, pas16->opl.priv); break; + case 0x0400 ... 0x0402: + break; + case 0x0403: + if (val & MV508_ADDRESS) + mv508_mixer->index = val & ~MV508_ADDRESS; + else { + uint8_t bank; + uint8_t mask; + + pas16_log("MVA508 register %02X = %02X\n", + mv508_mixer->index, val); + + if (mv508_mixer->index & MV508_MIXER) { + bank = !!(val & MV508_INPUT_MIX); + mask = 0x1f; + } else { + bank = 2; + mask = 0x3f; + } + + if (mv508_mixer->index & MV508_CHANNEL) + mv508_mixer->regs[bank][mv508_mixer->index] = val & mask; + else { + mv508_mixer->regs[bank][mv508_mixer->index | MV508_LEFT] = val & mask; + mv508_mixer->regs[bank][mv508_mixer->index | MV508_RIGHT] = val & mask; + } + + mv508_mixer_recalc(mv508_mixer); + } + break; + case 0x0800: - pas16->audio_mixer = val; - if (!(val & 0x01)) + if (pas16->type && !(val & SERIAL_MIXER_RESET_PCM)) { + pas16->audio_mixer = val; pas16_reset_pcm(pas16); + } else if (!pas16->type) { + switch (nsc_mixer->im_state) { + default: + break; + case STATE_SM_IDLE: + /* Transmission initiated. */ + if (val & SERIAL_MIXER_IDENT) { + if (!(val & SERIAL_MIXER_CLOCK) && (pas16->audio_mixer & SERIAL_MIXER_CLOCK)) { + /* Prepare for receiving LMC835N data. */ + nsc_mixer->im_data[LMC835_DATA] = 0x0000; + nsc_mixer->im_state |= STATE_LMC835_DATA; + } + } else { + if ((pas16->audio_mixer & SERIAL_MIXER_IDENT)) { + /* + Prepare for receiving the LMC1982CIN address. + */ + nsc_mixer->im_data[LMC1982_ADDR] = 0x0000; + nsc_mixer->im_state |= STATE_LMC1982_ADDR; + } + if ((val & SERIAL_MIXER_CLOCK) && !(pas16->audio_mixer & SERIAL_MIXER_CLOCK)) { + /* + Clock the least siginificant bit of the LMC1982CIN address. + */ + nsc_mixer->im_data[LMC1982_ADDR] |= + ((val & SERIAL_MIXER_DATA) << (nsc_mixer->im_state & STATE_DATA_MASK)); + nsc_mixer->im_state++; + } + } + break; + case STATE_LMC1982_ADDR_0: + if (val & SERIAL_MIXER_IDENT) { + /* + IDENT went high in LM1982CIN address state 0, + behave as if we were in the idle state. + */ + if (!(val & SERIAL_MIXER_CLOCK) && (pas16->audio_mixer & SERIAL_MIXER_CLOCK)) { + nsc_mixer->im_data[LMC835_DATA] = 0x0000; + nsc_mixer->im_state = STATE_LMC835_DATA_0; + } + } else if ((val & SERIAL_MIXER_CLOCK) && + !(pas16->audio_mixer & SERIAL_MIXER_CLOCK)) { + /* + Clock the least siginificant bit of the LMC1982CIN address. + */ + nsc_mixer->im_data[LMC1982_ADDR] |= + ((val & SERIAL_MIXER_DATA) << (nsc_mixer->im_state & STATE_DATA_MASK)); + nsc_mixer->im_state++; + } + break; + case STATE_LMC1982_ADDR_1 ... STATE_LMC1982_ADDR_7: + if ((val & 0x02) && !(pas16->audio_mixer & 0x02)) { + /* + Clock the next bit of the LMC1982CIN address. + */ + nsc_mixer->im_data[LMC1982_ADDR] |= + ((val & SERIAL_MIXER_DATA) << (nsc_mixer->im_state & STATE_DATA_MASK)); + nsc_mixer->im_state++; + } + break; + case STATE_LMC1982_ADDR_OVER: + /* + Prepare for receiving the LMC1982CIN data. + */ + nsc_mixer->im_data[LMC1982_DATA] = 0x0000; + nsc_mixer->im_state = STATE_LMC1982_DATA_0; + break; + case STATE_LMC1982_DATA_0 ... STATE_LMC1982_DATA_7: + case STATE_LMC1982_DATA_9 ... STATE_LMC1982_DATA_F: + if ((val & SERIAL_MIXER_CLOCK) && !(pas16->audio_mixer & SERIAL_MIXER_CLOCK)) { + /* + Clock the next bit of the LMC1982CIN data. + */ + nsc_mixer->im_data[LMC1982_DATA] |= + ((val & SERIAL_MIXER_DATA) << (nsc_mixer->im_state & STATE_DATA_MASK_W)); + nsc_mixer->im_state++; + } + break; + case STATE_LMC1982_DATA_8: + if (val & SERIAL_MIXER_IDENT) { + if (!(pas16->audio_mixer & SERIAL_MIXER_IDENT)) + /* + LMC1982CIN data transfer ended after 8 bits, process the data and + reset the state back to idle. + */ + lmc1982_update_reg(nsc_mixer); + else if ((val & SERIAL_MIXER_CLOCK) && + !(pas16->audio_mixer & SERIAL_MIXER_CLOCK)) { + /* + Clock the next bit of the LMC1982CIN data. + */ + nsc_mixer->im_data[LMC1982_DATA] |= + ((val & SERIAL_MIXER_DATA) << (nsc_mixer->im_state & STATE_DATA_MASK_W)); + nsc_mixer->im_state++; + } + } + break; + case STATE_LMC1982_DATA_OVER: + if ((val & SERIAL_MIXER_IDENT) && !(pas16->audio_mixer & SERIAL_MIXER_IDENT)) + /* + LMC1982CIN data transfer ended, process the data and reset the state + back to idle. + */ + lmc1982_update_reg(nsc_mixer); + break; + case STATE_LMC835_DATA_0 ... STATE_LMC835_DATA_7: + if ((val & SERIAL_MIXER_CLOCK) && !(pas16->audio_mixer & SERIAL_MIXER_CLOCK)) { + /* + Clock the next bit of the LMC835N data. + */ + nsc_mixer->im_data[LMC835_DATA] |= + ((val & SERIAL_MIXER_DATA) << (nsc_mixer->im_state & STATE_DATA_MASK)); + nsc_mixer->im_state++; + } + break; + case STATE_LMC835_DATA_OVER: + if ((val & SERIAL_MIXER_STROBE) && !(pas16->audio_mixer & SERIAL_MIXER_STROBE)) { + if (nsc_mixer->im_data[LMC835_DATA] & LMC835_FLAG_ADDR) + /* + The LMC835N data is an address, copy it into its own space for usage + when processing it at the end and strip bits 7 (it's the address/data + indicator) and 6 (it's a "don't care" bit). + */ + nsc_mixer->im_data[LMC835_ADDR] = nsc_mixer->im_data[LMC835_DATA] & 0x7f; + else + lmc835_update_reg(nsc_mixer); + nsc_mixer->im_state = STATE_SM_IDLE; + } + break; + } + + pas16->audio_mixer = val; + } break; case 0x0801: pas16->irq_stat &= ~val; - if (!(pas16->irq_stat & 0x1f)) + if ((pas16->irq != -1) && !(pas16->irq_stat & 0x1f)) picintc(1 << pas16->irq); break; case 0x0802: @@ -593,22 +1415,22 @@ pas16_out(uint16_t port, uint8_t val, void *priv) pas16->filter = 0; break; case 0x01: - recalc_pas16_filter(0, 17897); + recalc_pas16_filter(17897); break; case 0x02: - recalc_pas16_filter(0, 15909); + recalc_pas16_filter(15909); break; case 0x04: - recalc_pas16_filter(0, 2982); + recalc_pas16_filter(2982); break; case 0x09: - recalc_pas16_filter(0, 11931); + recalc_pas16_filter(11931); break; case 0x11: - recalc_pas16_filter(0, 8948); + recalc_pas16_filter(8948); break; case 0x19: - recalc_pas16_filter(0, 5965); + recalc_pas16_filter(5965); break; } } else @@ -618,13 +1440,11 @@ pas16_out(uint16_t port, uint8_t val, void *priv) pas16->irq_ena = val & 0x1f; pas16->irq_stat &= ((val & 0x1f) | 0xe0); - if (!(pas16->irq_stat & 0x1f)) + if ((pas16->irq != -1) && !(pas16->irq_stat & 0x1f)) picintc(1 << pas16->irq); break; case 0x0c00: - pas16_update(pas16); - break; case 0x0c01: pas16_update(pas16); break; @@ -647,9 +1467,7 @@ pas16_out(uint16_t port, uint8_t val, void *priv) if ((val & 0x60) == 0x60) { pas16->midi_uart_out = 0; pas16->midi_uart_in = 0; - } else if (val & 0x18) - pas16->midi_uart_out = 1; - else if (val & 0x04) + } else if ((val & 0x1c) == 0x04) pas16->midi_uart_in = 1; else pas16->midi_uart_out = 1; @@ -672,6 +1490,45 @@ pas16_out(uint16_t port, uint8_t val, void *priv) pas16->fifo_stat = val; break; + case 0x1c00 ... 0x1c03: /* NCR5380 ports 0 to 3. */ + case 0x3c00 ... 0x3c03: /* NCR5380 ports 4 to 7. */ + if (pas16->has_scsi) { + port = (port & 0x0003) | ((port & 0x2000) >> 11); + ncr5380_write(port, val, &pas16->scsi->ncr); + } + break; + + case 0x4000: + if (pas16->has_scsi) { + pas16->timeout_count = val; + if (timer_is_enabled(&pas16->scsi_timer)) + timer_disable(&pas16->scsi_timer); + timer_set_delay_u64(&pas16->scsi_timer, (val & 0x3f) * PASSCSICONST); + } + break; + + case 0x4001: + if (pas16->has_scsi) { + pas16->timeout_status = val & 0x7f; + if (pas16->scsi_irq != -1) + picintc(1 << pas16->scsi_irq); + } + break; + + case 0x5c00: + if (pas16->has_scsi) + ncr53c400_simple_write(val, pas16->scsi); + break; + case 0x5c03: + if (pas16->has_scsi) { + if (val & 0x80) { + pas16->scsi->ncr.irq_state = 0; + if (pas16->scsi_irq != -1) + picintc(1 << pas16->scsi_irq); + } + } + break; + case 0x7c01: pas16->enhancedscsi = val; break; @@ -701,6 +1558,8 @@ pas16_out(uint16_t port, uint8_t val, void *priv) break; case 0x8003: pas16->sys_conf_4 = val; + if (pas16->has_scsi && (pas16->scsi_irq != -1) && !(val & 0x20)) + picintc(1 << pas16->scsi_irq); break; case 0xbc00: @@ -723,13 +1582,15 @@ pas16_out(uint16_t port, uint8_t val, void *priv) break; case 0xf002: pas16->io_conf_3 = val; - pas16->irq = val & 0x0f; - if (pas16->irq <= 6) - pas16->irq++; - else if ((pas16->irq > 6) && (pas16->irq < 0x0b)) - pas16->irq += 3; - else - pas16->irq += 4; + if (pas16->irq != -1) + picintc(1 << pas16->irq); + pas16->irq = pas16_irq_convert(val & 0x0f); + if (pas16->has_scsi) { + if (pas16->scsi_irq != -1) + picintc(1 << pas16->scsi_irq); + pas16->scsi_irq = pas16_irq_convert(val >> 4); + ncr5380_set_irq(&pas16->scsi->ncr, pas16->scsi_irq); + } pas16_log("pas16_out : set PAS IRQ %i, val=%02x\n", pas16->irq, val & 0x0f); break; @@ -822,19 +1683,17 @@ pas16_dma_channel_read(pas16_t *pas16, int channel) } static uint16_t -pas16_dma_readb(pas16_t *pas16, uint8_t timer1_ticks) +pas16_dma_readb(pas16_t *pas16) { - uint16_t ret; + const uint16_t ret = pas16_dma_channel_read(pas16, pas16->dma); - ret = pas16_dma_channel_read(pas16, pas16->dma); - - pas16->ticks += timer1_ticks; + pas16->ticks++; return ret; } static uint16_t -pas16_dma_readw(pas16_t *pas16, uint8_t timer1_ticks) +pas16_dma_readw(pas16_t *pas16, const uint8_t timer1_ticks) { uint16_t ret; @@ -853,29 +1712,23 @@ pas16_dma_readw(pas16_t *pas16, uint8_t timer1_ticks) static uint16_t pas16_readdmab(pas16_t *pas16) { - uint16_t ret; - if (pas16->dma >= 5) { if (pas16->dma8_ff) pas16->dma8_dat >>= 8; else - pas16->dma8_dat = pas16_dma_readb(pas16, 1); + pas16->dma8_dat = pas16_dma_readb(pas16); pas16->dma8_ff = !pas16->dma8_ff; } else - pas16->dma8_dat = pas16_dma_readb(pas16, 1); + pas16->dma8_dat = pas16_dma_readb(pas16); - ret = ((pas16->dma8_dat & 0xff) ^ 0x80) << 8; - - return ret; + return ((pas16->dma8_dat & 0xff) ^ 0x80) << 8; } static uint16_t pas16_readdmaw_mono(pas16_t *pas16) { - uint16_t ret; - - ret = pas16_dma_readw(pas16, 1 + (pas16->dma < 5)); + const uint16_t ret = pas16_dma_readw(pas16, 1 + (pas16->dma < 5)); return ret; } @@ -930,11 +1783,10 @@ pas16_readdma_stereo(pas16_t *pas16) } static void -pas16_pit_timer0(int new_out, UNUSED(int old_out), void *priv) +pas16_pit_timer0(const int new_out, UNUSED(int old_out), void *priv) { - pitf_t *pit = (pitf_t *) priv; - pas16_t *pas16 = (pas16_t *) pit->dev_priv; - uint16_t temp; + const pitf_t *pit = (const pitf_t *) priv; + pas16_t * pas16 = (pas16_t *) pit->dev_priv; if (!pas16->pit->counters[0].gate) return; @@ -945,6 +1797,8 @@ pas16_pit_timer0(int new_out, UNUSED(int old_out), void *priv) pas16_update_irq(pas16); if (((pas16->pcm_ctrl & PAS16_PCM_ENA) == PAS16_PCM_ENA) && (pit->counters[1].m & 2) && new_out) { + uint16_t temp; + pas16->ticks = 0; if (pas16->pcm_ctrl & PAS16_PCM_MONO) { @@ -981,7 +1835,8 @@ pas16_pit_timer0(int new_out, UNUSED(int old_out), void *priv) pas16->irq_stat |= PAS16_INT_SAMP; if (pas16->irq_ena & PAS16_INT_SAMP) { pas16_log("INT SAMP.\n"); - picint(1 << pas16->irq); + if (pas16->irq != -1) + picint(1 << pas16->irq); } pas16_update(pas16); @@ -989,10 +1844,10 @@ pas16_pit_timer0(int new_out, UNUSED(int old_out), void *priv) } static void -pas16_pit_timer1(int new_out, UNUSED(int old_out), void *priv) +pas16_pit_timer1(const int new_out, UNUSED(int old_out), void *priv) { - pitf_t *pit = (pitf_t * )priv; - pas16_t *pas16 = (pas16_t *) pit->dev_priv; + const pitf_t *pit = (pitf_t * )priv; + pas16_t * pas16 = (pas16_t *) pit->dev_priv; if (!pas16->pit->counters[1].gate) return; @@ -1002,7 +1857,8 @@ pas16_pit_timer1(int new_out, UNUSED(int old_out), void *priv) if (pas16->irq_ena & PAS16_INT_PCM) { pas16->irq_stat |= PAS16_INT_PCM; pas16_log("pas16_pcm_poll : cause IRQ %i %02X\n", pas16->irq, 1 << pas16->irq); - picint(1 << pas16->irq); + if (pas16->irq != -1) + picint(1 << pas16->irq); } } } @@ -1054,7 +1910,7 @@ pas16_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) pas16->sysex = 1; for (uint32_t i = 0; i < len; i++) { if (pas16->midi_r == pas16->midi_w) - return (len - i); + return (int) (len - i); pas16->midi_queue[pas16->midi_w++] = buffer[i]; pas16->midi_w &= 0xff; } @@ -1072,38 +1928,258 @@ pas16_update(pas16_t *pas16) } } else { for (; pas16->pos < sound_pos_global; pas16->pos++) { - pas16->pcm_buffer[0][pas16->pos] = 0; - pas16->pcm_buffer[1][pas16->pos] = 0; -#ifdef CROSS_CHANNEL - if (pas16->pcm_ctrl & 0x08) - pas16->pcm_buffer[0][pas16->pos] += (int16_t) pas16->pcm_dat_l; - if (pas16->pcm_ctrl & 0x04) - pas16->pcm_buffer[0][pas16->pos] += (int16_t) pas16->pcm_dat_r; - if (pas16->pcm_ctrl & 0x02) - pas16->pcm_buffer[1][pas16->pos] += (int16_t) pas16->pcm_dat_l; - if (pas16->pcm_ctrl & 0x01) - pas16->pcm_buffer[1][pas16->pos] += (int16_t) pas16->pcm_dat_r; -#else - pas16->pcm_buffer[0][pas16->pos] += (int16_t) pas16->pcm_dat_l; - pas16->pcm_buffer[1][pas16->pos] += (int16_t) pas16->pcm_dat_r; -#endif + pas16->pcm_buffer[0][pas16->pos] = (int16_t) pas16->pcm_dat_l; + pas16->pcm_buffer[1][pas16->pos] = (int16_t) pas16->pcm_dat_r; } } } void -pas16_get_buffer(int32_t *buffer, int len, void *priv) +pasplus_get_buffer(int32_t *buffer, int len, void *priv) { - pas16_t *pas16 = (pas16_t *) priv; + pas16_t * pas16 = (pas16_t *) priv; + const nsc_mixer_t *mixer = &pas16->nsc_mixer; + double out_l = 0.0; + double out_r = 0.0; + double bass_treble; sb_dsp_update(&pas16->dsp); pas16_update(pas16); - for (int c = 0; c < len * 2; c++) { - buffer[c] += (int32_t) (sb_iir(0, c & 1, (double) pas16->dsp.buffer[c]) / 1.3) / 2; - if (pas16->filter) - buffer[c] += (low_fir_pas16(0, c & 1, (double) pas16->pcm_buffer[c & 1][c >> 1]) / 1.3) / 2.0; + for (int c = 0; c < len * 2; c += 2) { + out_l = 0.0; + out_r = 0.0; + + out_l += pas16->dsp.buffer[c]; + out_r += pas16->dsp.buffer[c + 1]; + + if (pas16->filter) { + /* We divide by 3 to get the volume down to normal. */ + out_l += low_fir_pas16(0, (double) pas16->pcm_buffer[0][c >> 1]) * mixer->pcm_l; + out_r += low_fir_pas16(1, (double) pas16->pcm_buffer[1][c >> 1]) * mixer->pcm_r; + } else { + out_l += ((double) pas16->pcm_buffer[0][c >> 1]) * mixer->pcm_l; + out_r += ((double) pas16->pcm_buffer[1][c >> 1]) * mixer->pcm_r; + } + + out_l *= mixer->master_l; + out_r *= mixer->master_r; + + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (mixer->bass != 6) { + bass_treble = lmc1982_bass_treble_4bits[mixer->bass]; + + if (mixer->bass > 6) { + out_l += (low_iir(0, 0, out_l) * bass_treble); + out_r += (low_iir(0, 1, out_r) * bass_treble); + } else if (mixer->bass < 6) { + out_l = (out_l *bass_treble + low_cut_iir(0, 0, out_l) * (1.0 - bass_treble)); + out_r = (out_r *bass_treble + low_cut_iir(0, 1, out_r) * (1.0 - bass_treble)); + } + } + + if (mixer->treble != 6) { + bass_treble = lmc1982_bass_treble_4bits[mixer->treble]; + + if (mixer->treble > 6) { + out_l += (high_iir(0, 0, out_l) * bass_treble); + out_r += (high_iir(0, 1, out_r) * bass_treble); + } else if (mixer->treble < 6) { + out_l = (out_l *bass_treble + high_cut_iir(0, 0, out_l) * (1.0 - bass_treble)); + out_r = (out_r *bass_treble + high_cut_iir(0, 1, out_r) * (1.0 - bass_treble)); + } + } + + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; + } + + pas16->pos = 0; + pas16->dsp.pos = 0; +} + +void +pasplus_get_music_buffer(int32_t *buffer, int len, void *priv) +{ + const pas16_t * pas16 = (const pas16_t *) priv; + const nsc_mixer_t *mixer = &pas16->nsc_mixer; + const int32_t * opl_buf = pas16->opl.update(pas16->opl.priv); + double out_l = 0.0; + double out_r = 0.0; + double bass_treble; + + for (int c = 0; c < len * 2; c += 2) { + out_l = 0.0; + out_r = 0.0; + + out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; + out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; + + /* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */ + out_l *= mixer->master_l; + out_r *= mixer->master_r; + + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (mixer->bass != 6) { + bass_treble = lmc1982_bass_treble_4bits[mixer->bass]; + + if (mixer->bass > 6) { + out_l += (low_iir(1, 0, out_l) * bass_treble); + out_r += (low_iir(1, 1, out_r) * bass_treble); + } else if (mixer->bass < 6) { + out_l = (out_l *bass_treble + low_cut_iir(1, 0, out_l) * (1.0 - bass_treble)); + out_r = (out_r *bass_treble + low_cut_iir(1, 1, out_r) * (1.0 - bass_treble)); + } + } + + if (mixer->treble != 6) { + bass_treble = lmc1982_bass_treble_4bits[mixer->treble]; + + if (mixer->treble > 6) { + out_l += (high_iir(1, 0, out_l) * bass_treble); + out_r += (high_iir(1, 1, out_r) * bass_treble); + } else if (mixer->treble < 6) { + out_l = (out_l *bass_treble + high_cut_iir(1, 0, out_l) * (1.0 - bass_treble)); + out_r = (out_r *bass_treble + high_cut_iir(1, 1, out_r) * (1.0 - bass_treble)); + } + } + + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; + } + + pas16->opl.reset_buffer(pas16->opl.priv); +} + +void +pasplus_filter_cd_audio(int channel, double *buffer, void *priv) +{ + const pas16_t * pas16 = (const pas16_t *) priv; + const nsc_mixer_t *mixer = &pas16->nsc_mixer; + const double cd = channel ? mixer->cd_r : mixer->cd_l; + const double master = channel ? mixer->master_r : mixer->master_l; + const int32_t bass = mixer->bass; + const int32_t treble = mixer->treble; + double c = (*buffer) * cd * master; + double bass_treble; + + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (bass != 6) { + bass_treble = lmc1982_bass_treble_4bits[bass]; + + if (bass > 6) + c += (low_iir(2, channel, c) * bass_treble); else - buffer[c] += ((pas16->pcm_buffer[c & 1][c >> 1] / 1.3) / 2); + c = (c * bass_treble + low_cut_iir(2, channel, c) * (1.0 - bass_treble)); + } + + if (treble != 6) { + bass_treble = lmc1982_bass_treble_4bits[treble]; + + if (treble > 6) + c += (high_iir(2, channel, c) * bass_treble); + else + c = (c * bass_treble + high_cut_iir(2, channel, c) * (1.0 - bass_treble)); + } + + *buffer = c; +} + +void +pasplus_filter_pc_speaker(int channel, double *buffer, void *priv) +{ + const pas16_t * pas16 = (pas16_t *) priv; + const nsc_mixer_t *mixer = &pas16->nsc_mixer; + const double spk = channel ? mixer->speaker_r : mixer->speaker_l; + const double master = channel ? mixer->master_r : mixer->master_l; + const int32_t bass = mixer->bass; + const int32_t treble = mixer->treble; + double c = (*buffer) * spk * master; + double bass_treble; + + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (bass != 6) { + bass_treble = lmc1982_bass_treble_4bits[bass]; + + if (bass > 6) + c += (low_iir(3, channel, c) * bass_treble); + else + c = (c * bass_treble + low_cut_iir(3, channel, c) * (1.0 - bass_treble)); + } + + if (treble != 6) { + bass_treble = lmc1982_bass_treble_4bits[treble]; + + if (treble > 6) + c += (high_iir(3, channel, c) * bass_treble); + else + c = (c * bass_treble + high_cut_iir(3, channel, c) * (1.0 - bass_treble)); + } + + *buffer = c; +} + +void +pas16_get_buffer(int32_t *buffer, int len, void *priv) +{ + pas16_t * pas16 = (pas16_t *) priv; + const mv508_mixer_t *mixer = &pas16->mv508_mixer; + double out_l = 0.0; + double out_r = 0.0; + double bass_treble; + + sb_dsp_update(&pas16->dsp); + pas16_update(pas16); + for (int c = 0; c < len * 2; c += 2) { + out_l = 0.0; + out_r = 0.0; + + out_l += (pas16->dsp.buffer[c] * mixer->sb_l) / 3.0; + out_r += (pas16->dsp.buffer[c + 1] * mixer->sb_r) / 3.0; + + if (pas16->filter) { + /* We divide by 3 to get the volume down to normal. */ + out_l += (low_fir_pas16(0, (double) pas16->pcm_buffer[0][c >> 1]) * mixer->pcm_l) / 3.0; + out_r += (low_fir_pas16(1, (double) pas16->pcm_buffer[1][c >> 1]) * mixer->pcm_r) / 3.0; + } else { + out_l += (((double) pas16->pcm_buffer[0][c >> 1]) * mixer->pcm_l) / 3.0; + out_r += (((double) pas16->pcm_buffer[1][c >> 1]) * mixer->pcm_r) / 3.0; + } + + out_l *= mixer->master_l; + out_r *= mixer->master_r; + + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (mixer->bass != 6) { + bass_treble = lmc1982_bass_treble_4bits[mixer->bass]; + + if (mixer->bass > 6) { + out_l += (low_iir(0, 0, out_l) * bass_treble); + out_r += (low_iir(0, 1, out_r) * bass_treble); + } else if (mixer->bass < 6) { + out_l = (out_l *bass_treble + low_cut_iir(0, 0, out_l) * (1.0 - bass_treble)); + out_r = (out_r *bass_treble + low_cut_iir(0, 1, out_r) * (1.0 - bass_treble)); + } + } + + if (mixer->treble != 6) { + bass_treble = lmc1982_bass_treble_4bits[mixer->treble]; + + if (mixer->treble > 6) { + out_l += (high_iir(0, 0, out_l) * bass_treble); + out_r += (high_iir(0, 1, out_r) * bass_treble); + } else if (mixer->treble < 6) { + out_l = (out_l *bass_treble + high_cut_iir(0, 0, out_l) * (1.0 - bass_treble)); + out_r = (out_r *bass_treble + high_cut_iir(0, 1, out_r) * (1.0 - bass_treble)); + } + } + + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; } pas16->pos = 0; @@ -1113,15 +2189,127 @@ pas16_get_buffer(int32_t *buffer, int len, void *priv) void pas16_get_music_buffer(int32_t *buffer, int len, void *priv) { - pas16_t *pas16 = (pas16_t *) priv; + const pas16_t * pas16 = (const pas16_t *) priv; + const mv508_mixer_t *mixer = &pas16->mv508_mixer; + const int32_t * opl_buf = pas16->opl.update(pas16->opl.priv); + double out_l = 0.0; + double out_r = 0.0; + double bass_treble; - const int32_t *opl_buf = pas16->opl.update(pas16->opl.priv); - for (int c = 0; c < len * 2; c++) - buffer[c] += opl_buf[c]; + for (int c = 0; c < len * 2; c += 2) { + out_l = 0.0; + out_r = 0.0; + + out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; + out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; + + /* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */ + out_l *= mixer->master_l; + out_r *= mixer->master_r; + + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (mixer->bass != 6) { + bass_treble = lmc1982_bass_treble_4bits[mixer->bass]; + + if (mixer->bass > 6) { + out_l += (low_iir(1, 0, out_l) * bass_treble); + out_r += (low_iir(1, 1, out_r) * bass_treble); + } else if (mixer->bass < 6) { + out_l = (out_l *bass_treble + low_cut_iir(1, 0, out_l) * (1.0 - bass_treble)); + out_r = (out_r *bass_treble + low_cut_iir(1, 1, out_r) * (1.0 - bass_treble)); + } + } + + if (mixer->treble != 6) { + bass_treble = lmc1982_bass_treble_4bits[mixer->treble]; + + if (mixer->treble > 6) { + out_l += (high_iir(1, 0, out_l) * bass_treble); + out_r += (high_iir(1, 1, out_r) * bass_treble); + } else if (mixer->treble < 6) { + out_l = (out_l *bass_treble + high_cut_iir(1, 0, out_l) * (1.0 - bass_treble)); + out_r = (out_r *bass_treble + high_cut_iir(1, 1, out_r) * (1.0 - bass_treble)); + } + } + + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; + } pas16->opl.reset_buffer(pas16->opl.priv); } +void +pas16_filter_cd_audio(int channel, double *buffer, void *priv) +{ + const pas16_t * pas16 = (const pas16_t *) priv; + const mv508_mixer_t *mixer = &pas16->mv508_mixer; + const double cd = channel ? mixer->cd_r : mixer->cd_l; + const double master = channel ? mixer->master_r : mixer->master_l; + const int32_t bass = mixer->bass; + const int32_t treble = mixer->treble; + double c = (((*buffer) * cd) / 3.0) * master; + double bass_treble; + + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (bass != 6) { + bass_treble = lmc1982_bass_treble_4bits[bass]; + + if (bass > 6) + c += (low_iir(2, channel, c) * bass_treble); + else + c = (c * bass_treble + low_cut_iir(2, channel, c) * (1.0 - bass_treble)); + } + + if (treble != 6) { + bass_treble = lmc1982_bass_treble_4bits[treble]; + + if (treble > 6) + c += (high_iir(2, channel, c) * bass_treble); + else + c = (c * bass_treble + high_cut_iir(2, channel, c) * (1.0 - bass_treble)); + } + + *buffer = c; +} + +void +pas16_filter_pc_speaker(int channel, double *buffer, void *priv) +{ + const pas16_t * pas16 = (const pas16_t *) priv; + const mv508_mixer_t *mixer = &pas16->mv508_mixer; + const double spk = channel ? mixer->speaker_r : mixer->speaker_l; + const double master = channel ? mixer->master_r : mixer->master_l; + const int32_t bass = mixer->bass; + const int32_t treble = mixer->treble; + double c = (((*buffer) * spk) / 3.0) * master; + double bass_treble; + + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (bass != 6) { + bass_treble = lmc1982_bass_treble_4bits[bass]; + + if (bass > 6) + c += (low_iir(3, channel, c) * bass_treble); + else + c = (c * bass_treble + low_cut_iir(3, channel, c) * (1.0 - bass_treble)); + } + + if (treble != 6) { + bass_treble = lmc1982_bass_treble_4bits[treble]; + + if (treble > 6) + c += (high_iir(3, channel, c) * bass_treble); + else + c = (c * bass_treble + high_cut_iir(3, channel, c) * (1.0 - bass_treble)); + } + + *buffer = c; +} + static void pas16_speed_changed(void *priv) { @@ -1141,12 +2329,13 @@ pas16_init(const device_t *info) } pas16->type = info->local & 0xff; + pas16->has_scsi = (!pas16->type) || (pas16->type & 0x0f); fm_driver_get(FM_YMF262, &pas16->opl); sb_dsp_set_real_opl(&pas16->dsp, 1); sb_dsp_init(&pas16->dsp, SB2, SB_SUBTYPE_DEFAULT, pas16); pas16->mpu = (mpu_t *) malloc(sizeof(mpu_t)); memset(pas16->mpu, 0, sizeof(mpu_t)); - mpu401_init(pas16->mpu, 0, 0, M_INTELLIGENT, device_get_config_int("receive_input401")); + mpu401_init(pas16->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); sb_dsp_set_mpu(&pas16->dsp, pas16->mpu); pas16->sb_compat_base = 0x0000; @@ -1154,10 +2343,22 @@ pas16_init(const device_t *info) io_sethandler(0x9a01, 0x0001, NULL, NULL, NULL, pas16_out_base, NULL, NULL, pas16); pas16->this_id = 0xbc + pas16_next; + if (pas16->has_scsi) { + pas16->scsi = device_add(&scsi_pas_device); + timer_add(&pas16->scsi_timer, pas16_timeout_callback, pas16, 0); + other_scsi_present++; + } + pas16->pit = device_add(&i8254_ext_io_fast_device); pas16_reset(pas16); pas16->pit->dev_priv = pas16; pas16->irq = pas16->type ? 10 : 5; + pas16->io_conf_3 = pas16->type ? 0x07 : 0x04; + if (pas16->has_scsi) { + pas16->scsi_irq = pas16->type ? 11 : 7; + pas16->io_conf_3 |= (pas16->type ? 0x80 : 0x60); + ncr5380_set_irq(&pas16->scsi->ncr, pas16->scsi_irq); + } pas16->dma = 3; for (uint8_t i = 0; i < 3; i++) pitf_ctr_set_gate(pas16->pit, i, 0); @@ -1168,12 +2369,34 @@ pas16_init(const device_t *info) pitf_ctr_set_using_timer(pas16->pit, 1, 0); pitf_ctr_set_using_timer(pas16->pit, 2, 0); - sound_add_handler(pas16_get_buffer, pas16); - music_add_handler(pas16_get_music_buffer, pas16); + if (pas16->type) { + sound_add_handler(pas16_get_buffer, pas16); + music_add_handler(pas16_get_music_buffer, pas16); + sound_set_cd_audio_filter(pas16_filter_cd_audio, pas16); + if (device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(pas16_filter_pc_speaker, pas16); + } else { + sound_add_handler(pasplus_get_buffer, pas16); + music_add_handler(pasplus_get_music_buffer, pas16); + sound_set_cd_audio_filter(pasplus_filter_cd_audio, pas16); + if (device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(pasplus_filter_pc_speaker, pas16); + } if (device_get_config_int("receive_input")) midi_in_handler(1, pas16_input_msg, pas16_input_sysex, pas16); + for (uint8_t i = 0; i < 16; i++) { + if (i < 6) + lmc1982_bass_treble_4bits[i] = pow(10.0, (-((double) (12 - (i << 1))) / 10.0)); + else if (i == 6) + lmc1982_bass_treble_4bits[i] = 0.0; + else if ((i > 6) && (i <= 12)) + lmc1982_bass_treble_4bits[i] = 1.0 - pow(10.0, ((double) ((i - 6) << 1) / 10.0)); + else + lmc1982_bass_treble_4bits[i] = 1.0 - pow(10.0, 1.2); + } + pas16_next++; return pas16; @@ -1190,6 +2413,13 @@ pas16_close(void *priv) } static const device_config_t pas16_config[] = { + { + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, { .name = "receive_input401", .description = "Receive input (MPU-401)", @@ -1221,12 +2451,25 @@ const device_t pasplus_device = { .config = pas16_config }; - const device_t pas16_device = { .name = "Pro Audio Spectrum 16", .internal_name = "pas16", .flags = DEVICE_ISA | DEVICE_AT, - .local = 1, + .local = 0x0f, + .init = pas16_init, + .close = pas16_close, + .reset = pas16_reset, + { .available = NULL }, + .speed_changed = pas16_speed_changed, + .force_redraw = NULL, + .config = pas16_config +}; + +const device_t pas16d_device = { + .name = "Pro Audio Spectrum 16", + .internal_name = "pas16", + .flags = DEVICE_ISA | DEVICE_AT, + .local = 0x0c, .init = pas16_init, .close = pas16_close, .reset = pas16_reset, diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 13baa3621..9dc7724a4 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -43,6 +43,7 @@ #include <86box/snd_sb.h> #include <86box/plat_unused.h> +#define PNP_ROM_SB_16_PNP "roms/sound/creative/CTL0024A.BIN" #define PNP_ROM_SB_VIBRA16XV "roms/sound/creative/CT4170 PnP.BIN" #define PNP_ROM_SB_VIBRA16C "roms/sound/creative/CT4180 PnP.BIN" #define PNP_ROM_SB_32_PNP "roms/sound/creative/CT3600 PnP.BIN" @@ -50,6 +51,10 @@ #define PNP_ROM_SB_AWE64_VALUE "roms/sound/creative/CT4520 PnP.BIN" #define PNP_ROM_SB_AWE64 "roms/sound/creative/CTL009DA.BIN" #define PNP_ROM_SB_AWE64_GOLD "roms/sound/creative/CT4540 PnP.BIN" +/* TODO: Find real ESS PnP ROM dumps. */ +#define PNP_ROM_ESS0100 "roms/sound/ess/ESS0100.BIN" +#define PNP_ROM_ESS0102 "roms/sound/ess/ESS0102.BIN" +#define PNP_ROM_ESS0968 "roms/sound/ess/ESS0968.BIN" /* 0 to 7 -> -14dB to 0dB i 2dB steps. 8 to 15 -> 0 to +14dB in 2dB steps. Note that for positive dB values, this is not amplitude, it is amplitude - 1. */ @@ -99,92 +104,6 @@ static const double sb_att_3dbstep_3bits[] = { static const uint16_t sb_mcv_addr[8] = { 0x200, 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x270 }; static const int sb_pro_mcv_irqs[4] = { 7, 5, 3, 3 }; -/* Each card in the SB16 family has a million variants, and it shows in the large variety of device IDs for the PnP models. - This ROM was reconstructed in a best-effort basis around a pnpdump output log found in a forum. */ -static uint8_t sb_16_pnp_rom[] = { - // clang-format off - 0x0e, 0x8c, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, /* CTL0024, dummy checksum (filled in by isapnp_add_card) */ - 0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */ - 0x82, 0x11, 0x00, 'C', 'r', 'e', 'a', 't', 'i', 'v', 'e', ' ', 'S', 'B', '1', '6', ' ', 'P', 'n', 'P', /* ANSI identifier */ - - 0x16, 0x0e, 0x8c, 0x00, 0x31, 0x00, 0x65, /* logical device CTL0031, supports vendor-specific registers 0x39/0x3A/0x3D/0x3F */ - 0x82, 0x05, 0x00, 'A', 'u', 'd', 'i', 'o', /* ANSI identifier */ - 0x31, 0x00, /* start dependent functions, preferred */ - 0x22, 0x20, 0x00, /* IRQ 5 */ - 0x2a, 0x02, 0x08, /* DMA 1, compatibility, no count by word, count by byte, not bus master, 8-bit only */ - 0x2a, 0x20, 0x12, /* DMA 5, compatibility, count by word, no count by byte, not bus master, 16-bit only */ - 0x47, 0x01, 0x20, 0x02, 0x20, 0x02, 0x01, 0x10, /* I/O 0x220, decodes 16-bit, 1-byte alignment, 16 addresses */ - 0x47, 0x01, 0x30, 0x03, 0x30, 0x03, 0x01, 0x02, /* I/O 0x330, decodes 16-bit, 1-byte alignment, 2 addresses */ - 0x47, 0x01, 0x88, 0x03, 0x88, 0x03, 0x01, 0x04, /* I/O 0x388, decodes 16-bit, 1-byte alignment, 4 addresses */ - 0x31, 0x01, /* start dependent functions, acceptable */ - 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ - 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ - 0x2a, 0xe0, 0x12, /* DMA 5/6/7, compatibility, count by word, no count by byte, not bus master, 16-bit only */ - 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ - 0x47, 0x01, 0x00, 0x03, 0x30, 0x03, 0x30, 0x02, /* I/O 0x300-0x330, decodes 16-bit, 48-byte alignment, 2 addresses */ - 0x47, 0x01, 0x88, 0x03, 0x88, 0x03, 0x01, 0x04, /* I/O 0x388, decodes 16-bit, 1-byte alignment, 4 addresses */ - 0x31, 0x01, /* start dependent functions, acceptable */ - 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ - 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ - 0x2a, 0xe0, 0x12, /* DMA 5/6/7, compatibility, count by word, no count by byte, not bus master, 16-bit only */ - 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ - 0x47, 0x01, 0x00, 0x03, 0x30, 0x03, 0x30, 0x02, /* I/O 0x300-0x330, decodes 16-bit, 48-byte alignment, 2 addresses */ - 0x31, 0x02, /* start dependent functions, functional */ - 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ - 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ - 0x2a, 0xe0, 0x12, /* DMA 5/6/7, compatibility, count by word, no count by byte, not bus master, 16-bit only */ - 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ - 0x31, 0x02, /* start dependent functions, functional */ - 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ - 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ - 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ - 0x47, 0x01, 0x00, 0x03, 0x30, 0x03, 0x30, 0x02, /* I/O 0x300-0x330, decodes 16-bit, 48-byte alignment, 2 addresses */ - 0x47, 0x01, 0x88, 0x03, 0x88, 0x03, 0x01, 0x04, /* I/O 0x388, decodes 16-bit, 1-byte alignment, 4 addresses */ - 0x31, 0x02, /* start dependent functions, functional */ - 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ - 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ - 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ - 0x47, 0x01, 0x00, 0x03, 0x30, 0x03, 0x30, 0x02, /* I/O 0x300-0x330, decodes 16-bit, 48-byte alignment, 2 addresses */ - 0x31, 0x02, /* start dependent functions, functional */ - 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ - 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ - 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ - 0x38, /* end dependent functions */ - - 0x16, 0x0e, 0x8c, 0x20, 0x11, 0x00, 0x5a, /* logical device CTL2011, supports vendor-specific registers 0x39/0x3B/0x3C/0x3E */ - 0x1c, 0x41, 0xd0, 0x06, 0x00, /* compatible device PNP0600 */ - 0x82, 0x03, 0x00, 'I', 'D', 'E', /* ANSI identifier */ - 0x31, 0x00, /* start dependent functions, preferred */ - 0x22, 0x00, 0x04, /* IRQ 10 */ - 0x47, 0x01, 0x68, 0x01, 0x68, 0x01, 0x01, 0x08, /* I/O 0x168, decodes 16-bit, 1-byte alignment, 8 addresses */ - 0x47, 0x01, 0x6e, 0x03, 0x6e, 0x03, 0x01, 0x02, /* I/O 0x36E, decodes 16-bit, 1-byte alignment, 2 addresses */ - 0x31, 0x01, /* start dependent functions, acceptable */ - 0x22, 0x00, 0x08, /* IRQ 11 */ - 0x47, 0x01, 0xe8, 0x01, 0xe8, 0x01, 0x01, 0x08, /* I/O 0x1E8, decodes 16-bit, 1-byte alignment, 8 addresses */ - 0x47, 0x01, 0xee, 0x03, 0xee, 0x03, 0x01, 0x02, /* I/O 0x3EE, decodes 16-bit, 1-byte alignment, 2 addresses */ - 0x31, 0x01, /* start dependent functions, acceptable */ - 0x22, 0x00, 0x8c, /* IRQ 10/11/15 */ - 0x47, 0x01, 0x00, 0x01, 0xf8, 0x01, 0x08, 0x08, /* I/O 0x100-0x1F8, decodes 16-bit, 8-byte alignment, 8 addresses */ - 0x47, 0x01, 0x00, 0x03, 0xfe, 0x03, 0x02, 0x02, /* I/O 0x300-0x3FE, decodes 16-bit, 2-byte alignment, 2 addresses */ - 0x31, 0x02, /* start dependent functions, functional */ - 0x22, 0x00, 0x80, /* IRQ 15 */ - 0x47, 0x01, 0x70, 0x01, 0x70, 0x01, 0x01, 0x08, /* I/O 0x170, decodes 16-bit, 1-byte alignment, 8 addresses */ - 0x47, 0x01, 0x76, 0x03, 0x76, 0x03, 0x01, 0x02, /* I/O 0x376, decodes 16-bit, 1-byte alignment, 1 addresses */ - 0x38, /* end dependent functions */ - - 0x16, 0x41, 0xd0, 0xff, 0xff, 0x00, 0xda, /* logical device PNPFFFF, supports vendor-specific registers 0x38/0x39/0x3B/0x3C/0x3E */ - 0x82, 0x08, 0x00, 'R', 'e', 's', 'e', 'r', 'v', 'e', 'd', /* ANSI identifier */ - 0x47, 0x01, 0x00, 0x01, 0xf8, 0x03, 0x08, 0x01, /* I/O 0x100-0x3F8, decodes 16-bit, 8-byte alignment, 1 address */ - - 0x15, 0x0e, 0x8c, 0x70, 0x01, 0x00, /* logical device CTL7001 */ - 0x1c, 0x41, 0xd0, 0xb0, 0x2f, /* compatible device PNPB02F */ - 0x82, 0x04, 0x00, 'G', 'a', 'm', 'e', /* ANSI identifier */ - 0x47, 0x01, 0x00, 0x02, 0x00, 0x02, 0x01, 0x08, /* I/O 0x200, decodes 16-bit, 1-byte alignment, 8 addresses */ - - 0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */ - // clang-format on -}; - #ifdef ENABLE_SB_LOG int sb_do_log = ENABLE_SB_LOG; @@ -207,11 +126,9 @@ sb_log(const char *fmt, ...) static void sb_get_buffer_sb2(int32_t *buffer, int len, void *priv) { - sb_t *sb = (sb_t *) priv; - const sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; - double out_mono = 0.0; - double out_l = 0.0; - double out_r = 0.0; + sb_t *sb = (sb_t *) priv; + const sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; + double out_mono; sb_dsp_update(&sb->dsp); @@ -219,9 +136,8 @@ sb_get_buffer_sb2(int32_t *buffer, int len, void *priv) cms_update(&sb->cms); for (int c = 0; c < len * 2; c += 2) { - out_mono = 0.0; - out_l = 0.0; - out_r = 0.0; + double out_l = 0.0; + double out_r = 0.0; if (sb->cms_enabled) { out_l += sb->cms.buffer[c]; @@ -261,25 +177,17 @@ sb_get_buffer_sb2(int32_t *buffer, int len, void *priv) static void sb_get_music_buffer_sb2(int32_t *buffer, int len, void *priv) { - sb_t *sb = (sb_t *) priv; - const sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; - double out_mono = 0.0; - double out_l = 0.0; - double out_r = 0.0; - const int32_t *opl_buf = NULL; - - if (!sb->opl_enabled) - return; + const sb_t *sb = (const sb_t *) priv; + const sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; + const int32_t *opl_buf = NULL; opl_buf = sb->opl.update(sb->opl.priv); for (int c = 0; c < len * 2; c += 2) { - out_mono = 0.0; - out_l = 0.0; - out_r = 0.0; + double out_l = 0.0; + double out_r = 0.0; - if (sb->opl_enabled) - out_mono = ((double) opl_buf[c]) * 0.7171630859375; + const double out_mono = ((double) opl_buf[c]) * 0.7171630859375; out_l += out_mono; out_r += out_mono; @@ -318,18 +226,16 @@ sb2_filter_cd_audio(UNUSED(int channel), double *buffer, void *priv) } void -sb_get_buffer_sbpro(int32_t *buffer, int len, void *priv) +sb_get_buffer_sbpro(int32_t *buffer, const int len, void *priv) { sb_t *sb = (sb_t *) priv; const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; - double out_l = 0.0; - double out_r = 0.0; sb_dsp_update(&sb->dsp); for (int c = 0; c < len * 2; c += 2) { - out_l = 0.0; - out_r = 0.0; + double out_l = 0.0; + double out_r = 0.0; /* TODO: Implement the stereo switch on the mixer instead of on the dsp? */ if (mixer->output_filter) { @@ -354,11 +260,11 @@ sb_get_buffer_sbpro(int32_t *buffer, int len, void *priv) void sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) { - sb_t *sb = (sb_t *) priv; - const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; - double out_l = 0.0; - double out_r = 0.0; - const int32_t *opl_buf = NULL; + sb_t *sb = (sb_t *) priv; + const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; + double out_l = 0.0; + double out_r = 0.0; + const int32_t *opl_buf = NULL; const int32_t *opl2_buf = NULL; if (!sb->opl_enabled) @@ -380,7 +286,8 @@ sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) /* Two chips for LEFT and RIGHT channels. Each chip stores data into the LEFT channel only (no sample alternating.) */ out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; - out_r = (((double) opl2_buf[c]) * mixer->fm_r) * 0.7171630859375; + if (opl2_buf != NULL) + out_r = (((double) opl2_buf[c]) * mixer->fm_r) * 0.7171630859375; } else { out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; @@ -404,42 +311,27 @@ sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) void sbpro_filter_cd_audio(int channel, double *buffer, void *priv) { - const sb_t *sb = (sb_t *) priv; - const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; - double c; - double cd = channel ? mixer->cd_r : mixer->cd_l; - double master = channel ? mixer->master_r : mixer->master_l; + const sb_t *sb = (sb_t *) priv; + const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; + const double cd = channel ? mixer->cd_r : mixer->cd_l; + const double master = channel ? mixer->master_r : mixer->master_l; + double c = ((*buffer * cd) / 3.0) * master; - c = (*buffer * cd) / 3.0; - *buffer = c * master; + *buffer = c; } static void sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) { - sb_t *sb = (sb_t *) priv; - const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - int c_emu8k = 0; - double out_l = 0.0; - double out_r = 0.0; + sb_t *sb = (sb_t *) priv; + const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; double bass_treble; sb_dsp_update(&sb->dsp); - if (sb->dsp.sb_type > SB16) - emu8k_update(&sb->emu8k); - for (int c = 0; c < len * 2; c += 2) { - out_l = 0.0; - out_r = 0.0; - - if (sb->dsp.sb_type > SB16) - c_emu8k = ((((c / 2) * FREQ_44100) / SOUND_FREQ) * 2); - - if (sb->dsp.sb_type > SB16) { - out_l += (((double) sb->emu8k.buffer[c_emu8k]) * mixer->fm_l); - out_r += (((double) sb->emu8k.buffer[c_emu8k + 1]) * mixer->fm_r); - } + double out_l = 0.0; + double out_r = 0.0; if (mixer->output_filter) { /* We divide by 3 to get the volume down to normal. */ @@ -460,7 +352,7 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) if (mixer->bass_l > 8) out_l += (low_iir(0, 0, out_l) * bass_treble); - else if (mixer->bass_l < 8) + else out_l = (out_l *bass_treble + low_cut_iir(0, 0, out_l) * (1.0 - bass_treble)); } @@ -469,7 +361,7 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) if (mixer->bass_r > 8) out_r += (low_iir(0, 1, out_r) * bass_treble); - else if (mixer->bass_r < 8) + else out_r = (out_r *bass_treble + low_cut_iir(0, 1, out_r) * (1.0 - bass_treble)); } @@ -478,7 +370,7 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) if (mixer->treble_l > 8) out_l += (high_iir(0, 0, out_l) * bass_treble); - else if (mixer->treble_l < 8) + else out_l = (out_l *bass_treble + high_cut_iir(0, 0, out_l) * (1.0 - bass_treble)); } @@ -487,7 +379,7 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) if (mixer->treble_r > 8) out_r += (high_iir(0, 1, out_r) * bass_treble); - else if (mixer->treble_r < 8) + else out_r = (out_l *bass_treble + high_cut_iir(0, 1, out_r) * (1.0 - bass_treble)); } @@ -496,31 +388,23 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) } sb->dsp.pos = 0; - - if (sb->dsp.sb_type > SB16) - sb->emu8k.pos = 0; } static void -sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) +sb_get_music_buffer_sb16_awe32(int32_t *buffer, const int len, void *priv) { - sb_t *sb = (sb_t *) priv; - const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - int dsp_rec_pos = sb->dsp.record_pos_write; - int c_record; - int32_t in_l; - int32_t in_r; - double out_l = 0.0; - double out_r = 0.0; + sb_t *sb = (sb_t *) priv; + const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; + const int dsp_rec_pos = sb->dsp.record_pos_write; double bass_treble; - const int32_t *opl_buf = NULL; + const int32_t *opl_buf = NULL; if (sb->opl_enabled) opl_buf = sb->opl.update(sb->opl.priv); for (int c = 0; c < len * 2; c += 2) { - out_l = 0.0; - out_r = 0.0; + double out_l = 0.0; + double out_r = 0.0; if (sb->opl_enabled) { out_l = ((double) opl_buf[c]) * mixer->fm_l * 0.7171630859375; @@ -528,10 +412,10 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) } /* TODO: Multi-recording mic with agc/+20db, CD, and line in with channel inversion */ - in_l = (mixer->input_selector_left & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_left & INPUT_MIDI_R) ? ((int32_t) out_r) - : 0; - in_r = (mixer->input_selector_right & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_right & INPUT_MIDI_R) ? ((int32_t) out_r) - : 0; + int32_t in_l = (mixer->input_selector_left & INPUT_MIDI_L) ? + ((int32_t) out_l) : 0 + (mixer->input_selector_left & INPUT_MIDI_R) ? ((int32_t) out_r) : 0; + int32_t in_r = (mixer->input_selector_right & INPUT_MIDI_L) ? + ((int32_t) out_l) : 0 + (mixer->input_selector_right & INPUT_MIDI_R) ? ((int32_t) out_r) : 0; out_l *= mixer->master_l; out_r *= mixer->master_r; @@ -543,7 +427,7 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) if (mixer->bass_l > 8) out_l += (low_iir(1, 0, out_l) * bass_treble); - else if (mixer->bass_l < 8) + else out_l = (out_l *bass_treble + low_cut_iir(1, 0, out_l) * (1.0 - bass_treble)); } @@ -552,7 +436,7 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) if (mixer->bass_r > 8) out_r += (low_iir(1, 1, out_r) * bass_treble); - else if (mixer->bass_r < 8) + else out_r = (out_r *bass_treble + low_cut_iir(1, 1, out_r) * (1.0 - bass_treble)); } @@ -561,7 +445,7 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) if (mixer->treble_l > 8) out_l += (high_iir(1, 0, out_l) * bass_treble); - else if (mixer->treble_l < 8) + else out_l = (out_l *bass_treble + high_cut_iir(1, 0, out_l) * (1.0 - bass_treble)); } @@ -570,12 +454,13 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) if (mixer->treble_r > 8) out_r += (high_iir(1, 1, out_r) * bass_treble); - else if (mixer->treble_r < 8) + else out_r = (out_l *bass_treble + high_cut_iir(1, 1, out_r) * (1.0 - bass_treble)); } if (sb->dsp.sb_enable_i) { - c_record = dsp_rec_pos + ((c * sb->dsp.sb_freq) / MUSIC_FREQ); + const int c_record = dsp_rec_pos + ((c * sb->dsp.sb_freq) / MUSIC_FREQ); + in_l <<= mixer->input_gain_L; in_r <<= mixer->input_gain_R; @@ -590,8 +475,8 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) else if (in_r > 32767) in_r = 32767; - sb->dsp.record_buffer[c_record & 0xffff] = in_l; - sb->dsp.record_buffer[(c_record + 1) & 0xffff] = in_r; + sb->dsp.record_buffer[c_record & 0xffff] = (int16_t) in_l; + sb->dsp.record_buffer[(c_record + 1) & 0xffff] = (int16_t) in_r; } buffer[c] += (int32_t) (out_l * mixer->output_gain_L); @@ -605,21 +490,82 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) sb->opl.reset_buffer(sb->opl.priv); } +static void +sb_get_wavetable_buffer_sb16_awe32(int32_t *buffer, const int len, void *priv) +{ + sb_t *sb = (sb_t *) priv; + const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; + double bass_treble; + + emu8k_update(&sb->emu8k); + + for (int c = 0; c < len * 2; c += 2) { + double out_l = 0.0; + double out_r = 0.0; + + out_l += (((double) sb->emu8k.buffer[c]) * mixer->fm_l); + out_r += (((double) sb->emu8k.buffer[c + 1]) * mixer->fm_r); + + out_l *= mixer->master_l; + out_r *= mixer->master_r; + + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (mixer->bass_l != 8) { + bass_treble = sb_bass_treble_4bits[mixer->bass_l]; + + if (mixer->bass_l > 8) + out_l += (low_iir(4, 0, out_l) * bass_treble); + else + out_l = (out_l *bass_treble + low_cut_iir(4, 0, out_l) * (1.0 - bass_treble)); + } + + if (mixer->bass_r != 8) { + bass_treble = sb_bass_treble_4bits[mixer->bass_r]; + + if (mixer->bass_r > 8) + out_r += (low_iir(4, 1, out_r) * bass_treble); + else + out_r = (out_r *bass_treble + low_cut_iir(4, 1, out_r) * (1.0 - bass_treble)); + } + + if (mixer->treble_l != 8) { + bass_treble = sb_bass_treble_4bits[mixer->treble_l]; + + if (mixer->treble_l > 8) + out_l += (high_iir(4, 0, out_l) * bass_treble); + else + out_l = (out_l *bass_treble + high_cut_iir(4, 0, out_l) * (1.0 - bass_treble)); + } + + if (mixer->treble_r != 8) { + bass_treble = sb_bass_treble_4bits[mixer->treble_r]; + + if (mixer->treble_r > 8) + out_r += (high_iir(4, 1, out_r) * bass_treble); + else + out_r = (out_l *bass_treble + high_cut_iir(4, 1, out_r) * (1.0 - bass_treble)); + } + + buffer[c] += (int32_t) (out_l * mixer->output_gain_L); + buffer[c + 1] += (int32_t) (out_r * mixer->output_gain_R); + } + + sb->emu8k.pos = 0; +} + void sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv) { - const sb_t *sb = (sb_t *) priv; - const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - double c; - double cd = channel ? mixer->cd_r : mixer->cd_l /* / 3.0 */; - double master = channel ? mixer->master_r : mixer->master_l; - int32_t bass = channel ? mixer->bass_r : mixer->bass_l; - int32_t treble = channel ? mixer->treble_r : mixer->treble_l; + const sb_t *sb = (sb_t *) priv; + const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; + const double cd = channel ? mixer->cd_r : mixer->cd_l /* / 3.0 */; + const double master = channel ? mixer->master_r : mixer->master_l; + const int32_t bass = channel ? mixer->bass_r : mixer->bass_l; + const int32_t treble = channel ? mixer->treble_r : mixer->treble_l; + const double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L); double bass_treble; - double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L); - - c = ((*buffer) * cd) / 3.0; - c *= master; + double c = (((*buffer) * cd) / 3.0) * master; /* This is not exactly how one does bass/treble controls, but the end result is like it. A better implementation would reduce the CPU usage. */ @@ -628,7 +574,7 @@ sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv) if (bass > 8) c += (low_iir(2, channel, c) * bass_treble); - else if (bass < 8) + else c = (c * bass_treble + low_cut_iir(2, channel, c) * (1.0 - bass_treble)); } @@ -637,7 +583,7 @@ sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv) if (treble > 8) c += (high_iir(2, channel, c) * bass_treble); - else if (treble < 8) + else c = (c * bass_treble + high_cut_iir(2, channel, c) * (1.0 - bass_treble)); } @@ -647,15 +593,15 @@ sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv) void sb16_awe32_filter_pc_speaker(int channel, double *buffer, void *priv) { - const sb_t *sb = (sb_t *) priv; - const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - double c; - double spk = mixer->speaker; - double master = channel ? mixer->master_r : mixer->master_l; - int32_t bass = channel ? mixer->bass_r : mixer->bass_l; - int32_t treble = channel ? mixer->treble_r : mixer->treble_l; + const sb_t *sb = (sb_t *) priv; + const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; + const double spk = mixer->speaker; + const double master = channel ? mixer->master_r : mixer->master_l; + const int32_t bass = channel ? mixer->bass_r : mixer->bass_l; + const int32_t treble = channel ? mixer->treble_r : mixer->treble_l; + const double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L); double bass_treble; - double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L); + double c; if (mixer->output_filter) c = (low_fir_sb16(3, channel, *buffer) * spk) / 3.0; @@ -670,7 +616,7 @@ sb16_awe32_filter_pc_speaker(int channel, double *buffer, void *priv) if (bass > 8) c += (low_iir(3, channel, c) * bass_treble); - else if (bass < 8) + else c = (c * bass_treble + low_cut_iir(3, channel, c) * (1.0 - bass_treble)); } @@ -679,7 +625,7 @@ sb16_awe32_filter_pc_speaker(int channel, double *buffer, void *priv) if (treble > 8) c += (high_iir(3, channel, c) * bass_treble); - else if (treble < 8) + else c = (c * bass_treble + high_cut_iir(3, channel, c) * (1.0 - bass_treble)); } @@ -691,14 +637,12 @@ sb_get_buffer_ess(int32_t *buffer, int len, void *priv) { sb_t *ess = (sb_t *) priv; const ess_mixer_t *mixer = &ess->mixer_ess; - double out_l = 0.0; - double out_r = 0.0; sb_dsp_update(&ess->dsp); for (int c = 0; c < len * 2; c += 2) { - out_l = 0.0; - out_r = 0.0; + double out_l = 0.0; + double out_r = 0.0; /* TODO: Implement the stereo switch on the mixer instead of on the dsp? */ if (mixer->output_filter) { @@ -765,6 +709,24 @@ ess_filter_cd_audio(int channel, double *buffer, void *priv) *buffer = c * master; } +void +ess_filter_pc_speaker(int channel, double *buffer, void *priv) +{ + const sb_t *ess = (sb_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_ess; + double c; + double spk = mixer->speaker; + double master = channel ? mixer->master_r : mixer->master_l; + + if (mixer->output_filter) + c = (low_fir_sb16(3, channel, *buffer) * spk) / 3.0; + else + c = ((*buffer) * spk) / 3.0; + c *= master; + + *buffer = c; +} + void sb_ct1335_mixer_write(uint16_t addr, uint8_t val, void *priv) { @@ -839,7 +801,10 @@ void sb_ct1345_mixer_write(uint16_t addr, uint8_t val, void *priv) { sb_t *sb = (sb_t *) priv; - sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; + sb_ct1345_mixer_t *mixer = (sb == NULL) ? NULL : &sb->mixer_sbpro; + + if (mixer == NULL) + return; if (!(addr & 1)) { mixer->index = val; @@ -977,7 +942,10 @@ void sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv) { sb_t *sb = (sb_t *) priv; - sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; + sb_ct1745_mixer_t *mixer = (sb == NULL) ? NULL : &sb->mixer_sb16; + + if (mixer == NULL) + return; if (!(addr & 1)) mixer->index = val; @@ -1207,7 +1175,6 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) { const sb_t *sb = (sb_t *) priv; const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - uint8_t temp; uint8_t ret = 0xff; if (!(addr & 1)) @@ -1310,6 +1277,8 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) break; } switch (sb->dsp.sb_16_dmanum) { + default: + break; case 5: ret |= 0x20; break; @@ -1331,8 +1300,8 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) I haven't seen this making any difference, but I'm keeping it for now. */ /* If QEMU is any indication, then the values are actually 0x20, 0x40, and 0x80. */ /* http://the.earth.li/~tfm/oldpage/sb_mixer.html - 0x10, 0x20, 0x80. */ - temp = ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) | - ((sb->dsp.sb_irq401) ? 4 : 0); + const uint8_t temp = ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) | + ((sb->dsp.sb_irq401) ? 4 : 0); if (sb->dsp.sb_type >= SBAWE32) ret = temp | 0x80; else @@ -1398,15 +1367,22 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) void sb_ct1745_mixer_reset(sb_t *sb) { - sb_ct1745_mixer_write(4, 0, sb); - sb_ct1745_mixer_write(5, 0, sb); + if (sb != NULL) { + sb_ct1745_mixer_write(4, 0, sb); + sb_ct1745_mixer_write(5, 0, sb); + } } void ess_mixer_write(uint16_t addr, uint8_t val, void *priv) { sb_t *ess = (sb_t *) priv; - ess_mixer_t *mixer = &ess->mixer_ess; + ess_mixer_t *mixer = (ess == NULL) ? NULL : &ess->mixer_ess; + + sb_log("[%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, addr, val); + + if (mixer == NULL) + return; if (!(addr & 1)) { mixer->index = val; @@ -1506,20 +1482,12 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) /* More compatibility: SoundBlaster Pro selects register 020h for 030h, 022h for 032h, 026h for 036h, and 028h for 038h. */ - case 0x30: - case 0x32: - case 0x36: - case 0x38: + case 0x30: case 0x32: case 0x36: case 0x38: case 0x3e: mixer->regs[mixer->index - 0x10] = (val & 0xee); break; - case 0x3a: - case 0x3c: - break; - - case 0x00: - case 0x04: + case 0x00: case 0x04: case 0x3a: case 0x3c: break; case 0x64: @@ -1529,6 +1497,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) case 0x40: { uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] << 1) & 0x30); + sb_log("mpu401_base_addr = %04X\n", mpu401_base_addr); gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); if (ess->dsp.sb_subtype != SB_SUBTYPE_ESS_ES1688) { @@ -1545,6 +1514,8 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) } } switch ((mixer->regs[0x40] >> 5) & 0x7) { + default: + break; case 0: mpu401_change_addr(ess->mpu, 0x00); mpu401_setirq(ess->mpu, -1); @@ -1600,31 +1571,24 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->line_l = sb_att_2dbstep_4bits[(mixer->regs[0x3e] >> 4) & 0x0F] / 32767.0; mixer->line_r = sb_att_2dbstep_4bits[mixer->regs[0x3e] & 0x0F] / 32767.0; mixer->speaker = sb_att_3dbstep_3bits[mixer->regs[0x3c] & 0x07] / 32767.0; - - /* TODO: PC Speaker volume */ } } uint8_t ess_mixer_read(uint16_t addr, void *priv) { - sb_t *ess = (sb_t *) priv; - ess_mixer_t *mixer = &ess->mixer_ess; + const sb_t * ess = (sb_t *) priv; + const ess_mixer_t *mixer = &ess->mixer_ess; + uint8_t ret = 0x0a; if (!(addr & 1)) - return mixer->index; - - switch (mixer->index) { + ret = mixer->index; + else switch (mixer->index) { case 0x00: - case 0x04: case 0x0a: case 0x0c: case 0x0e: case 0x14: - case 0x22: - case 0x26: - case 0x28: - case 0x2e: case 0x02: case 0x06: case 0x30: @@ -1632,25 +1596,37 @@ ess_mixer_read(uint16_t addr, void *priv) case 0x36: case 0x38: case 0x3e: - return mixer->regs[mixer->index]; + ret = mixer->regs[mixer->index]; + break; + + case 0x04: + case 0x22: + case 0x26: + case 0x28: + case 0x2e: + ret = mixer->regs[mixer->index] | 0x11; + break; case 0x40: - if (ess->dsp.sb_subtype != SB_SUBTYPE_ESS_ES1688) { - uint8_t val = mixer->ess_id_str[mixer->ess_id_str_pos]; - mixer->ess_id_str_pos++; - if (mixer->ess_id_str_pos >= 4) - mixer->ess_id_str_pos = 0; - return val; - } else { - return mixer->regs[mixer->index]; - } + if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688) + ret = mixer->regs[mixer->index]; + else + ret = 0x0a; + break; + + /* Return 0x00 so it has bit 3 clear, so NT 5.x drivers don't misdetect it as ES1788. */ + case 0x64: + ret = 0x00; + break; default: sb_log("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } - return 0x0a; + sb_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, addr, ret); + + return ret; } void @@ -1806,12 +1782,9 @@ sb_16_reply_mca_read(int port, void *priv) } static void -sb_16_reply_mca_write(int port, uint8_t val, void *priv) +sb_16_reply_mca_write(const int port, const uint8_t val, void *priv) { uint16_t addr; - uint16_t mpu401_addr; - int low_dma; - int high_dma; sb_t *sb = (sb_t *) priv; if (port < 0x102) @@ -1865,6 +1838,8 @@ sb_16_reply_mca_write(int port, uint8_t val, void *priv) sb->pos_regs[port & 7] = val; if (sb->pos_regs[2] & 1) { + uint16_t mpu401_addr; + switch (sb->pos_regs[2] & 0xc4) { case 4: addr = 0x220; @@ -1883,6 +1858,7 @@ sb_16_reply_mca_write(int port, uint8_t val, void *priv) addr = 0; break; } + switch (sb->pos_regs[2] & 0x18) { case 8: mpu401_addr = 0x330; @@ -1935,8 +1911,8 @@ sb_16_reply_mca_write(int port, uint8_t val, void *priv) break; } - low_dma = sb->pos_regs[3] & 3; - high_dma = (sb->pos_regs[3] >> 4) & 7; + const int low_dma = sb->pos_regs[3] & 3; + int high_dma = (sb->pos_regs[3] >> 4) & 7; if (!high_dma) high_dma = low_dma; @@ -1984,13 +1960,16 @@ sb_vibra16s_onboard_relocate_base(uint16_t new_addr, void *priv) } static void -sb_16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) +sb_16_pnp_config_changed(const 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) { + default: + case 4: /* StereoEnhance (32) */ + break; + case 0: /* Audio */ io_removehandler(addr, 0x0004, sb->opl.read, NULL, NULL, @@ -2022,6 +2001,8 @@ sb_16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) mpu401_change_addr(sb->mpu, 0); if (config->activate) { + uint8_t val = config->irq[0].irq; + addr = config->io[0].base; if (addr != ISAPNP_IO_DISABLED) { io_sethandler(addr, 0x0004, @@ -2053,7 +2034,6 @@ sb_16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) sb->opl.priv); } - val = config->irq[0].irq; if (val != ISAPNP_IRQ_DISABLED) sb_dsp_setirq(&sb->dsp, val); @@ -2086,17 +2066,11 @@ sb_16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) case 3: /* Game */ gameport_remap(sb->gameport, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0); break; - - case 4: /* StereoEnhance (32) */ - break; - - default: - break; } } static void -sb_vibra16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) +sb_vibra16_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void *priv) { sb_t *sb = (sb_t *) priv; @@ -2112,7 +2086,7 @@ sb_vibra16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void * } static void -sb_awe32_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) +sb_awe32_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void *priv) { sb_t *sb = (sb_t *) priv; @@ -2133,7 +2107,7 @@ sb_awe32_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *pr } static void -sb_awe64_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) +sb_awe64_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void *priv) { sb_t *sb = (sb_t *) priv; @@ -2154,7 +2128,7 @@ sb_awe64_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *pr } static void -sb_awe64_gold_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) +sb_awe64_gold_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void *priv) { sb_t *sb = (sb_t *) priv; @@ -2173,6 +2147,333 @@ sb_awe64_gold_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, voi } } +static void +ess_x688_pnp_config_changed(UNUSED(const uint8_t ld), isapnp_device_config_t *config, void *priv) +{ + sb_t *ess = (sb_t *) priv; + uint16_t addr = ess->dsp.sb_addr; + uint8_t val; + + switch (ld) { + case 0: /* Audio */ + io_removehandler(addr, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_removehandler(addr + 8, 0x0002, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_removehandler(addr + 4, 0x0002, + ess_mixer_read, NULL, NULL, + ess_mixer_write, NULL, NULL, + ess); + + ess->mixer_ess.ess_id_str[2] = 0x00; + ess->mixer_ess.ess_id_str[3] = 0x00; + + addr = ess->opl_pnp_addr; + if (addr) { + ess->opl_pnp_addr = 0; + io_removehandler(addr, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + } + + if (ess->pnp == 3) + mpu401_change_addr(ess->mpu, 0); + + sb_dsp_setaddr(&ess->dsp, 0); + sb_dsp_setirq(&ess->dsp, 0); + if (ess->pnp == 3) + mpu401_setirq(ess->mpu, -1); + sb_dsp_setdma8(&ess->dsp, ISAPNP_DMA_DISABLED); + sb_dsp_setdma16_8(&ess->dsp, ISAPNP_DMA_DISABLED); + + if (config->activate) { + addr = config->io[0].base; + if (addr != ISAPNP_IO_DISABLED) { + io_sethandler(addr, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_sethandler(addr + 8, 0x0002, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_sethandler(addr + 4, 0x0002, + ess_mixer_read, NULL, NULL, + ess_mixer_write, NULL, NULL, + ess); + + sb_dsp_setaddr(&ess->dsp, addr); + + ess->mixer_ess.ess_id_str[2] = (addr >> 8) & 0xff; + ess->mixer_ess.ess_id_str[3] = addr & 0xff; + } + + addr = config->io[1].base; + if (addr != ISAPNP_IO_DISABLED) { + ess->opl_pnp_addr = addr; + io_sethandler(addr, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + } + + if (ess->pnp == 3) { + addr = config->io[2].base; + if (addr != ISAPNP_IO_DISABLED) + mpu401_change_addr(ess->mpu, addr); + } + + val = config->irq[0].irq; + if (val != ISAPNP_IRQ_DISABLED) { + sb_dsp_setirq(&ess->dsp, val); + if (ess->pnp == 3) + mpu401_setirq(ess->mpu, val); + } + + val = config->dma[0].dma; + if (val != ISAPNP_DMA_DISABLED) { + sb_dsp_setdma8(&ess->dsp, val); + sb_dsp_setdma16_8(&ess->dsp, val); + } + } + break; + + case 1: + if (ess->pnp == 3) { /* Game */ + gameport_remap(ess->gameport, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0); + } else { /* MPU-401 */ + mpu401_change_addr(ess->mpu, 0); + mpu401_setirq(ess->mpu, -1); + + if (config->activate) { + addr = config->io[0].base; + if (addr != ISAPNP_IO_DISABLED) + mpu401_change_addr(ess->mpu, addr); + + val = config->irq[0].irq; + if (val != ISAPNP_IRQ_DISABLED) + mpu401_setirq(ess->mpu, val); + } + } + break; + + case 2: + if (ess->pnp == 3) /* IDE */ + ide_pnp_config_changed_1addr(0, config, (void *) 3); + else /* Game */ + gameport_remap(ess->gameport, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0); + break; + + case 3: + if (ess->pnp <= 2) /* IDE */ + ide_pnp_config_changed_1addr(0, config, (void *) 3); + break; + + default: + break; + } +} + +/* This function is common to all the ESS MCA cards. */ +static uint8_t +ess_x688_mca_read(const int port, void *priv) +{ + const sb_t *ess = (sb_t *) priv; + const uint8_t ret = ess->pos_regs[port & 7]; + + sb_log("ess_mca_read: port=%04x ret=%02x\n", port, ret); + + return ret; +} + +static void +ess_soundpiper_mca_write(const int port, const uint8_t val, void *priv) +{ + sb_t *ess = (sb_t *) priv; + + if (port < 0x102) + return; + + sb_log("ess_soundpiper_mca_write: port=%04x val=%02x\n", port, val); + + if (ess->dsp.sb_addr != 0x0000) { + io_removehandler(ess->dsp.sb_addr, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_removehandler(ess->dsp.sb_addr + 8, 0x0002, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_removehandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_removehandler(ess->dsp.sb_addr + 4, 0x0002, + ess_mixer_read, NULL, NULL, + ess_mixer_write, NULL, NULL, + ess); + } + + /* DSP I/O handler is activated in sb_dsp_setaddr */ + sb_dsp_setaddr(&ess->dsp, 0); + gameport_remap(ess->gameport, 0); + + if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688) + mpu401_change_addr(ess->mpu, 0); + + ess->pos_regs[port & 7] = val; + + if (ess->pos_regs[2] & 1) { + switch (ess->pos_regs[2] & 0x0e) { + default: + ess->dsp.sb_addr = 0x0000; + break; + case 0x08: + ess->dsp.sb_addr = 0x0240; + break; + case 0x0c: + ess->dsp.sb_addr = 0x0220; + break; + } + + if (ess->dsp.sb_addr != 0x0000) { + io_sethandler(ess->dsp.sb_addr, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_sethandler(ess->dsp.sb_addr + 8, 0x0002, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_sethandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, ess->opl.priv); + io_sethandler(ess->dsp.sb_addr + 4, 0x0002, + ess_mixer_read, NULL, NULL, + ess_mixer_write, NULL, NULL, + ess); + + if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688) + mpu401_change_addr(ess->mpu, ess->pos_regs[3] & 0x02 ? 0x0330 : 0); + } + + /* DSP I/O handler is activated in sb_dsp_setaddr */ + sb_dsp_setaddr(&ess->dsp, ess->dsp.sb_addr); + gameport_remap(ess->gameport, (ess->pos_regs[3] & 0x01) ? 0x200 : 0); + } + + switch (ess->pos_regs[3] & 0xc0) { + default: + break; + case 0x80: + sb_dsp_setirq(&ess->dsp, 9); + if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688) + mpu401_setirq(ess->mpu, 9); + break; + case 0xa0: + sb_dsp_setirq(&ess->dsp, 5); + if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688) + mpu401_setirq(ess->mpu, 5); + break; + case 0xc0: + sb_dsp_setirq(&ess->dsp, 7); + if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688) + mpu401_setirq(ess->mpu, 7); + break; + case 0xe0: + sb_dsp_setirq(&ess->dsp, 10); + if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688) + mpu401_setirq(ess->mpu, 10); + break; + } + + if (ess->pos_regs[3] & 0x04) { + sb_dsp_setdma8(&ess->dsp, ess->pos_regs[2] >> 4); + sb_dsp_setdma16_8(&ess->dsp, ess->pos_regs[2] >> 4); + } +} + +static void +ess_chipchat_mca_write(int port, uint8_t val, void *priv) +{ + sb_t *ess = (sb_t *) priv; + + if (port < 0x102) + return; + + sb_log("ess_chipchat_mca_write: port=%04x val=%02x\n", port, val); + + if (ess->dsp.sb_addr != 0x0000) { + io_removehandler(ess->dsp.sb_addr, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_removehandler(ess->dsp.sb_addr + 8, 0x0002, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_removehandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_removehandler(ess->dsp.sb_addr + 4, 0x0002, + ess_mixer_read, NULL, NULL, + ess_mixer_write, NULL, NULL, + ess); + } + + /* DSP I/O handler is activated in sb_dsp_setaddr */ + sb_dsp_setaddr(&ess->dsp, 0); + gameport_remap(ess->gameport, 0); + + mpu401_change_addr(ess->mpu, 0); + + ess->pos_regs[port & 7] = val; + + if (ess->pos_regs[2] & 1) { + ess->dsp.sb_addr = (ess->pos_regs[2] == 0x51) ? 0x0220 : 0x0000; + + if (ess->dsp.sb_addr != 0x0000) { + io_sethandler(ess->dsp.sb_addr, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_sethandler(ess->dsp.sb_addr + 8, 0x0002, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, + ess->opl.priv); + io_sethandler(0x0388, 0x0004, + ess->opl.read, NULL, NULL, + ess->opl.write, NULL, NULL, ess->opl.priv); + io_sethandler(ess->dsp.sb_addr + 4, 0x0002, + ess_mixer_read, NULL, NULL, + ess_mixer_write, NULL, NULL, + ess); + + if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688) + mpu401_change_addr(ess->mpu, (ess->pos_regs[2] == 0x51) ? 0x0330 : 0); + } + + /* DSP I/O handler is activated in sb_dsp_setaddr */ + sb_dsp_setaddr(&ess->dsp, ess->dsp.sb_addr); + gameport_remap(ess->gameport, (ess->pos_regs[2] == 0x51) ? 0x200 : 0); + } + + if (ess->pos_regs[2] == 0x51) { + sb_dsp_setirq(&ess->dsp, 7); + mpu401_setirq(ess->mpu, 7); + + sb_dsp_setdma8(&ess->dsp, 1); + sb_dsp_setdma16_8(&ess->dsp, 1); + } +} + void * sb_1_init(UNUSED(const device_t *info)) { @@ -2180,8 +2481,8 @@ sb_1_init(UNUSED(const device_t *info)) 2x0 to 2x3 -> CMS chip 2x6, 2xA, 2xC, 2xE -> DSP chip 2x8, 2x9, 388 and 389 FM chip */ - sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_hex16("base"); + sb_t * sb = malloc(sizeof(sb_t)); + const uint16_t addr = device_get_config_hex16("base"); memset(sb, 0, sizeof(sb_t)); sb->opl_enabled = device_get_config_int("opl"); @@ -2231,8 +2532,8 @@ sb_15_init(UNUSED(const device_t *info)) 2x0 to 2x3 -> CMS chip 2x6, 2xA, 2xC, 2xE -> DSP chip 2x8, 2x9, 388 and 389 FM chip */ - sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_hex16("base"); + sb_t * sb = malloc(sizeof(sb_t)); + const uint16_t addr = device_get_config_hex16("base"); memset(sb, 0, sizeof(sb_t)); sb->opl_enabled = device_get_config_int("opl"); @@ -2550,8 +2851,7 @@ sb_pro_mcv_init(UNUSED(const device_t *info)) sb->mixer_enabled = 1; sound_add_handler(sb_get_buffer_sbpro, sb); - if (sb->opl_enabled) - music_add_handler(sb_get_music_buffer_sbpro, sb); + music_add_handler(sb_get_music_buffer_sbpro, sb); sound_set_cd_audio_filter(sbpro_filter_cd_audio, sb); /* I/O handlers activated in sb_pro_mcv_write */ @@ -2593,17 +2893,17 @@ sb_pro_compat_init(UNUSED(const device_t *info)) static void * sb_16_init(UNUSED(const device_t *info)) { - sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_hex16("base"); - uint16_t mpu_addr = device_get_config_hex16("base401"); + sb_t *sb = malloc(sizeof(sb_t)); + const uint16_t addr = device_get_config_hex16("base"); + const uint16_t mpu_addr = device_get_config_hex16("base401"); memset(sb, 0x00, sizeof(sb_t)); sb->opl_enabled = device_get_config_int("opl"); if (sb->opl_enabled) - fm_driver_get(info->local, &sb->opl); + fm_driver_get((int) (intptr_t) info->local, &sb->opl); - sb_dsp_set_real_opl(&sb->dsp, (info->local != FM_YMF289B)); + sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_init(&sb->dsp, (info->local == FM_YMF289B) ? SBAWE32PNP : SB16, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); @@ -2633,12 +2933,8 @@ sb_16_init(UNUSED(const device_t *info)) io_sethandler(addr + 4, 0x0002, sb_ct1745_mixer_read, NULL, NULL, sb_ct1745_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_sb16_awe32, sb); - if (sb->opl_enabled) { - if (info->local == FM_YMF289B) - sound_add_handler(sb_get_music_buffer_sb16_awe32, sb); - else - music_add_handler(sb_get_music_buffer_sb16_awe32, sb); - } + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); @@ -2679,8 +2975,7 @@ sb_16_reply_mca_init(UNUSED(const device_t *info)) sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); - if (sb->opl_enabled) - music_add_handler(sb_get_music_buffer_sb16_awe32, sb); + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); @@ -2705,6 +3000,12 @@ sb_16_reply_mca_init(UNUSED(const device_t *info)) return sb; } +static int +sb_16_pnp_available(void) +{ + return rom_present(PNP_ROM_SB_16_PNP); +} + static void * sb_16_pnp_init(UNUSED(const device_t *info)) { @@ -2723,8 +3024,7 @@ sb_16_pnp_init(UNUSED(const device_t *info)) sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); - if (sb->opl_enabled) - music_add_handler(sb_get_music_buffer_sb16_awe32, sb); + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); @@ -2740,8 +3040,19 @@ sb_16_pnp_init(UNUSED(const device_t *info)) sb->gameport = gameport_add(&gameport_pnp_device); device_add(&ide_qua_pnp_device); + other_ide_present++; - isapnp_add_card(sb_16_pnp_rom, sizeof(sb_16_pnp_rom), sb_16_pnp_config_changed, NULL, NULL, NULL, sb); + uint8_t *pnp_rom = NULL; + + FILE *fp = rom_fopen(PNP_ROM_SB_16_PNP, "rb"); + if (fp) { + if (fread(sb->pnp_rom, 1, 390, fp) == 390) + pnp_rom = sb->pnp_rom; + fclose(fp); + } + + isapnp_add_card(pnp_rom, 390, sb_16_pnp_config_changed, + NULL, NULL, NULL, sb); sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_setaddr(&sb->dsp, 0); @@ -2790,8 +3101,7 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info)) sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); - if (sb->opl_enabled) - music_add_handler(sb_get_music_buffer_sb16_awe32, sb); + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); @@ -2833,7 +3143,7 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info)) switch (info->local) { case 0: case 1: - isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_vibra16_pnp_config_changed, + isapnp_add_card(pnp_rom, 512, sb_vibra16_pnp_config_changed, NULL, NULL, NULL, sb); break; @@ -2868,14 +3178,14 @@ sb_16_compat_init(const device_t *info) sb_dsp_setdma16_enabled(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); + sb->opl_enabled = 1; sb->mixer_enabled = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); - if (sb->opl_enabled) - music_add_handler(sb_get_music_buffer_sb16_awe32, sb); + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); memset(sb->mpu, 0, sizeof(mpu_t)); - mpu401_init(sb->mpu, 0, 0, M_UART, info->local); + mpu401_init(sb->mpu, 0, 0, M_UART, (int) (intptr_t) info->local); sb_dsp_set_mpu(&sb->dsp, sb->mpu); sb->gameport = gameport_add(&gameport_pnp_device); @@ -2968,6 +3278,7 @@ sb_awe32_init(UNUSED(const device_t *info)) sound_add_handler(sb_get_buffer_sb16_awe32, sb); if (sb->opl_enabled) music_add_handler(sb_get_music_buffer_sb16_awe32, sb); + wavetable_add_handler(sb_get_wavetable_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); @@ -3014,8 +3325,8 @@ sb_awe32_pnp_init(const device_t *info) sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); - if (sb->opl_enabled) - music_add_handler(sb_get_music_buffer_sb16_awe32, sb); + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); + wavetable_add_handler(sb_get_wavetable_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); @@ -3032,8 +3343,10 @@ sb_awe32_pnp_init(const device_t *info) sb->gameport = gameport_add(&gameport_pnp_device); - if ((info->local != 2) && (info->local != 4)) + if ((info->local != 2) && (info->local != 4)) { device_add(&ide_qua_pnp_device); + other_ide_present++; + } const char *pnp_rom_file = NULL; switch (info->local) { @@ -3112,15 +3425,19 @@ sb_awe32_pnp_init(const device_t *info) } static void * -ess_1688_init(UNUSED(const device_t *info)) +ess_x688_init(UNUSED(const device_t *info)) { sb_t *ess = calloc(sizeof(sb_t), 1); - uint16_t addr = device_get_config_hex16("base"); + const uint16_t addr = device_get_config_hex16("base"); + const uint16_t ide_ctrl = (const uint16_t) device_get_config_int("ide_ctrl"); + const uint16_t ide_base = ide_ctrl & 0x0fff; + const uint16_t ide_side = ide_base + 0x0206; + const uint16_t ide_irq = ide_ctrl >> 12; - fm_driver_get(FM_ESFM, &ess->opl); + fm_driver_get(info->local ? FM_ESFM : FM_YMF262, &ess->opl); sb_dsp_set_real_opl(&ess->dsp, 1); - sb_dsp_init(&ess->dsp, SBPRO2, SB_SUBTYPE_ESS_ES1688, ess); + sb_dsp_init(&ess->dsp, SBPRO2, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess); sb_dsp_setaddr(&ess->dsp, addr); sb_dsp_setirq(&ess->dsp, device_get_config_int("irq")); sb_dsp_setdma8(&ess->dsp, device_get_config_int("dma")); @@ -3152,26 +3469,196 @@ ess_1688_init(UNUSED(const device_t *info)) sound_add_handler(sb_get_buffer_ess, ess); music_add_handler(sb_get_music_buffer_ess, ess); sound_set_cd_audio_filter(ess_filter_cd_audio, ess); + if (info->local && device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(ess_filter_pc_speaker, ess); - if (device_get_config_int("receive_input")) { + if (device_get_config_int("receive_input")) midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &ess->dsp); + + if (info->local) { + ess->mixer_ess.ess_id_str[0] = 0x16; + ess->mixer_ess.ess_id_str[1] = 0x88; + ess->mixer_ess.ess_id_str[2] = (addr >> 8) & 0xff; + ess->mixer_ess.ess_id_str[3] = addr & 0xff; + + ess->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); + /* NOTE: The MPU is initialized disabled and with no IRQ assigned. + * It will be later initialized by the guest OS's drivers. */ + mpu401_init(ess->mpu, 0, -1, M_UART, device_get_config_int("receive_input401")); + sb_dsp_set_mpu(&ess->dsp, ess->mpu); } - ess->mixer_ess.ess_id_str[0] = 0x16; - ess->mixer_ess.ess_id_str[1] = 0x88; - ess->mixer_ess.ess_id_str[2] = (addr >> 8) & 0xff; - ess->mixer_ess.ess_id_str[3] = addr & 0xff; - - ess->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); - /* NOTE: The MPU is initialized disabled and with no IRQ assigned. - * It will be later initialized by the guest OS's drivers. */ - mpu401_init(ess->mpu, 0, -1, M_UART, 1); - sb_dsp_set_mpu(&ess->dsp, ess->mpu); - ess->gameport = gameport_add(&gameport_pnp_device); ess->gameport_addr = 0x200; gameport_remap(ess->gameport, ess->gameport_addr); + if (ide_base > 0x0000) { + device_add(&ide_qua_pnp_device); + ide_set_base(4, ide_base); + ide_set_side(4, ide_side); + ide_set_irq(4, ide_irq); + other_ide_present++; + } + + return ess; +} + +static int +ess_688_pnp_available(void) +{ + return rom_present(PNP_ROM_ESS0100); +} + +static int +ess_1688_pnp_available(void) +{ + return rom_present(PNP_ROM_ESS0102); +} + +static int +ess_1688_968_pnp_available(void) +{ + return rom_present(PNP_ROM_ESS0968); +} + +static void * +ess_x688_pnp_init(UNUSED(const device_t *info)) +{ + sb_t *ess = calloc(sizeof(sb_t), 1); + int len = 512; + + ess->pnp = 1 + (int) info->local; + + fm_driver_get(info->local ? FM_ESFM : FM_YMF262, &ess->opl); + + sb_dsp_set_real_opl(&ess->dsp, 1); + sb_dsp_init(&ess->dsp, SBPRO2, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess); + sb_dsp_setdma16_supported(&ess->dsp, 0); + ess_mixer_reset(ess); + + ess->mixer_enabled = 1; + sound_add_handler(sb_get_buffer_ess, ess); + music_add_handler(sb_get_music_buffer_ess, ess); + sound_set_cd_audio_filter(ess_filter_cd_audio, ess); + if (info->local && device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(ess_filter_pc_speaker, ess); + + if (device_get_config_int("receive_input")) + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &ess->dsp); + + /* Not on ES688. */ + ess->mixer_ess.ess_id_str[0] = 0x16; + ess->mixer_ess.ess_id_str[1] = 0x88; + ess->mixer_ess.ess_id_str[2] = 0x00; + ess->mixer_ess.ess_id_str[3] = 0x00; + + ess->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); + /* NOTE: The MPU is initialized disabled and with no IRQ assigned. + * It will be later initialized by the guest OS's drivers. */ + mpu401_init(ess->mpu, 0, -1, M_UART, device_get_config_int("receive_input401")); + sb_dsp_set_mpu(&ess->dsp, ess->mpu); + + ess->gameport = gameport_add(&gameport_pnp_device); + + device_add(&ide_qua_pnp_device); + other_ide_present++; + + const char *pnp_rom_file = NULL; + switch (info->local) { + case 0: + pnp_rom_file = PNP_ROM_ESS0100; + len = 145; + break; + + case 1: + pnp_rom_file = PNP_ROM_ESS0102; + len = 145; + break; + + case 2: + pnp_rom_file = PNP_ROM_ESS0968; + len = 135; + break; + + default: + break; + } + + uint8_t *pnp_rom = NULL; + if (pnp_rom_file) { + FILE *fp = rom_fopen(pnp_rom_file, "rb"); + if (fp) { + if (fread(ess->pnp_rom, 1, len, fp) == len) + pnp_rom = ess->pnp_rom; + fclose(fp); + } + } + + isapnp_add_card(pnp_rom, len, ess_x688_pnp_config_changed, + NULL, NULL, NULL, ess); + + sb_dsp_setaddr(&ess->dsp, 0); + sb_dsp_setirq(&ess->dsp, 0); + sb_dsp_setdma8(&ess->dsp, ISAPNP_DMA_DISABLED); + sb_dsp_setdma16_8(&ess->dsp, ISAPNP_DMA_DISABLED); + + mpu401_change_addr(ess->mpu, 0); + + ess->gameport_addr = 0; + gameport_remap(ess->gameport, 0); + + ide_remove_handlers(3); + + return ess; +} + +static void * +ess_x688_mca_init(UNUSED(const device_t *info)) +{ + sb_t *ess = calloc(1, sizeof(sb_t)); + + ess->opl_enabled = 1; + fm_driver_get(info->local ? FM_ESFM : FM_YMF262, &ess->opl); + + sb_dsp_set_real_opl(&ess->dsp, 1); + sb_dsp_init(&ess->dsp, SBPRO2, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess); + sb_dsp_setdma16_supported(&ess->dsp, 0); + ess_mixer_reset(ess); + + ess->mixer_enabled = 1; + sound_add_handler(sb_get_buffer_ess, ess); + music_add_handler(sb_get_music_buffer_ess, ess); + sound_set_cd_audio_filter(ess_filter_cd_audio, ess); + if (info->local && device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(ess_filter_pc_speaker, ess); + + if (info->local) { + ess->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); + mpu401_init(ess->mpu, 0, -1, M_UART, device_get_config_int("receive_input401")); + sb_dsp_set_mpu(&ess->dsp, ess->mpu); + } + + ess->gameport = gameport_add(&gameport_device); + + mpu401_change_addr(ess->mpu, 0); + + if (device_get_config_int("receive_input")) + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &ess->dsp); + + ess->gameport_addr = 0; + gameport_remap(ess->gameport, 0); + + /* I/O handlers activated in sb_pro_mcv_write */ + if (info->local == 2) { + mca_add(ess_x688_mca_read, ess_chipchat_mca_write, sb_mcv_feedb, NULL, ess); + ess->pos_regs[0] = 0x50; + ess->pos_regs[1] = 0x51; + } else { + mca_add(ess_x688_mca_read, ess_soundpiper_mca_write, sb_mcv_feedb, NULL, ess); + ess->pos_regs[0] = 0x30; + ess->pos_regs[1] = 0x51; + } + return ess; } @@ -4444,6 +4931,130 @@ static const device_config_t sb_awe64_gold_config[] = { { .name = "", .description = "", .type = CONFIG_END } }; +static const device_config_t ess_688_config[] = { + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x220, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "0x220", + .value = 0x220 + }, + { + .description = "0x230", + .value = 0x230 + }, + { + .description = "0x240", + .value = 0x240 + }, + { + .description = "0x250", + .value = 0x250 + }, + { .description = "" } + } + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 5, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "IRQ 2", + .value = 2 + }, + { + .description = "IRQ 5", + .value = 5 + }, + { + .description = "IRQ 7", + .value = 7 + }, + { + .description = "IRQ 10", + .value = 10 + }, + { .description = "" } + } + }, + { + .name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 1, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "DMA 0", + .value = 0 + }, + { + .description = "DMA 1", + .value = 1 + }, + { + .description = "DMA 3", + .value = 3 + }, + { .description = "" } + } + }, + { + .name = "ide_ctrl", + .description = "IDE Controller", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x0000, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "Disabled", + .value = 0x0000 + }, + { + .description = "0x170, IRQ 15", + .value = 0xf170 + }, + { + .description = "0x1E8, IRQ 11", + .value = 0xb1e8 + }, + { + .description = "0x168, IRQ 9", + .value = 0x9168 + }, + { + .description = "0x168, IRQ 10", + .value = 0xa168 + }, + { .description = "" } + } + }, + { + .name = "receive_input", + .description = "Receive input (SB MIDI)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + static const device_config_t ess_1688_config[] = { { .name = "base", @@ -4526,18 +5137,95 @@ static const device_config_t ess_1688_config[] = { } }, { - .name = "opl", - .description = "Enable OPL", - .type = CONFIG_BINARY, + .name = "ide_ctrl", + .description = "IDE Controller", + .type = CONFIG_HEX16, .default_string = "", - .default_int = 1 + .default_int = 0x0000, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "Disabled", + .value = 0x0000 + }, + { + .description = "0x170, IRQ 15", + .value = 0xf170 + }, + { + .description = "0x1E8, IRQ 11", + .value = 0xb1e8 + }, + { + .description = "0x168, IRQ 9", + .value = 0x9168 + }, + { + .description = "0x168, IRQ 10", + .value = 0xa168 + }, + { .description = "" } + } }, { - .name = "receive_input", - .description = "Receive input (SB MIDI)", - .type = CONFIG_BINARY, + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, .default_string = "", - .default_int = 1 + .default_int = 0 + }, + { + .name = "receive_input", + .description = "Receive input (SB MIDI)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, + { + .name = "receive_input401", + .description = "Receive input (MPU-401)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + +static const device_config_t ess_688_pnp_config[] = { + { + .name = "receive_input", + .description = "Receive input (SB MIDI)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + +static const device_config_t ess_1688_pnp_config[] = { + { + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, + { + .name = "receive_input", + .description = "Receive input (SB MIDI)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, + { + .name = "receive_input401", + .description = "Receive input (MPU-401)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 }, { .name = "", .description = "", .type = CONFIG_END } }; @@ -4761,7 +5449,7 @@ const device_t sb_16_pnp_device = { .init = sb_16_pnp_init, .close = sb_close, .reset = NULL, - { .available = NULL }, + { .available = sb_16_pnp_available }, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = sb_16_pnp_config @@ -4879,12 +5567,40 @@ const device_t sb_awe64_gold_device = { .config = sb_awe64_gold_config }; +const device_t ess_688_device = { + .name = "ESS AudioDrive ES688", + .internal_name = "ess_es688", + .flags = DEVICE_ISA, + .local = 0, + .init = ess_x688_init, + .close = sb_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = ess_688_config +}; + +const device_t ess_ess0100_pnp_device = { + .name = "ESS AudioDrive ES688 (ESS0100) PnP", + .internal_name = "ess_ess0100_pnp", + .flags = DEVICE_ISA, + .local = 0, + .init = ess_x688_pnp_init, + .close = sb_close, + .reset = NULL, + { .available = ess_688_pnp_available }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = ess_688_pnp_config +}; + const device_t ess_1688_device = { .name = "ESS AudioDrive ES1688", .internal_name = "ess_es1688", .flags = DEVICE_ISA, - .local = 0, - .init = ess_1688_init, + .local = 1, + .init = ess_x688_init, .close = sb_close, .reset = NULL, { .available = NULL }, @@ -4892,3 +5608,75 @@ const device_t ess_1688_device = { .force_redraw = NULL, .config = ess_1688_config }; + +const device_t ess_ess0102_pnp_device = { + .name = "ESS AudioDrive ES1688 (ESS0102) PnP", + .internal_name = "ess_ess0102_pnp", + .flags = DEVICE_ISA, + .local = 1, + .init = ess_x688_pnp_init, + .close = sb_close, + .reset = NULL, + { .available = ess_1688_pnp_available }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = ess_1688_pnp_config +}; + +const device_t ess_ess0968_pnp_device = { + .name = "ESS AudioDrive ES1688 (ESS0968) PnP", + .internal_name = "ess_ess0968_pnp", + .flags = DEVICE_ISA, + .local = 2, + .init = ess_x688_pnp_init, + .close = sb_close, + .reset = NULL, + { .available = ess_1688_968_pnp_available }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = ess_1688_pnp_config +}; + +const device_t ess_soundpiper_16_mca_device = { + .name = "SoundPiper 16 (ESS AudioDrive ES688) MCA", + .internal_name = "soundpiper_16_mca", + .flags = DEVICE_MCA, + .local = 0, + .init = ess_x688_mca_init, + .close = sb_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = ess_688_pnp_config +}; + +const device_t ess_soundpiper_32_mca_device = { + .name = "SoundPiper 32 (ESS AudioDrive ES1688) MCA", + .internal_name = "soundpiper_32_mca", + .flags = DEVICE_MCA, + .local = 1, + .init = ess_x688_mca_init, + .close = sb_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = ess_1688_pnp_config +}; + +const device_t ess_chipchat_16_mca_device = { + .name = "ChipChat 16 (ESS AudioDrive ES1688) MCA", + .internal_name = "chipchat_16_mca", + .flags = DEVICE_MCA, + .local = 2, + .init = ess_x688_mca_init, + .close = sb_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = ess_1688_pnp_config +}; + + diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 927a06d8c..9c148339d 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -37,38 +37,44 @@ #define ESPCM_3 5 /* ESPCM_2? */ #define ESPCM_1 7 -#define ESPCM_4E 8 // for differentiating between 4-bit encoding and decoding modes +#define ESPCM_4E 8 /* For differentiating between 4-bit encoding and decoding modes. */ -/*The recording safety margin is intended for uneven "len" calls to the get_buffer mixer calls on sound_sb*/ +/* The recording safety margin is intended for uneven "len" calls to the get_buffer mixer calls on sound_sb. */ #define SB_DSP_REC_SAFEFTY_MARGIN 4096 +enum { + DSP_S_NORMAL = 0, + DSP_S_RESET, + DSP_S_RESET_WAIT +}; + void pollsb(void *priv); void sb_poll_i(void *priv); static int sbe2dat[4][9] = { - {0x01, -0x02, -0x04, 0x08, -0x10, 0x20, 0x40, -0x80, -106}, - { -0x01, 0x02, -0x04, 0x08, 0x10, -0x20, 0x40, -0x80, 165 }, - { -0x01, 0x02, 0x04, -0x08, 0x10, -0x20, -0x40, 0x80, -151}, - { 0x01, -0x02, 0x04, -0x08, -0x10, 0x20, -0x40, 0x80, 90 } + { 0x01, -0x02, -0x04, 0x08, -0x10, 0x20, 0x40, -0x80, -106 }, + { -0x01, 0x02, -0x04, 0x08, 0x10, -0x20, 0x40, -0x80, 165 }, + { -0x01, 0x02, 0x04, -0x08, 0x10, -0x20, -0x40, 0x80, -151 }, + { 0x01, -0x02, 0x04, -0x08, -0x10, 0x20, -0x40, 0x80, 90 } }; static int sb_commands[256] = { - -1, 2, -1, 0, 1, 2, -1, 0, 1, -1, -1, -1, -1, -1, 2, 1, - 1, -1, -1, -1, 2, -1, 2, 2, -1, -1, -1, -1, 0, -1, -1, 0, - 0, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, + -1, 2, -1, 0, 1, 2, -1, 0, 1, -1, -1, -1, -1, -1, 2, 1, + 1, -1, -1, -1, 2, -1, 2, 2, -1, -1, -1, -1, 0, -1, -1, 0, + 0, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 2, 2, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, + 1, 2, 2, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 2, 2, 2, 2, -1, -1, -1, -1, -1, 0, -1, 0, - 2, 2, -1, -1, -1, -1, -1, -1, 2, 2, -1, -1, -1, -1, -1, -1, - 0, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 2, 2, 2, 2, -1, -1, -1, -1, -1, 0, -1, 0, + 2, 2, -1, -1, -1, -1, -1, -1, 2, 2, -1, -1, -1, -1, -1, -1, + 0, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, -1, -1, -1, -1, -1, - 1, 0, 1, 0, 1, -1, -1, 0, 0, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 0, 0, -1, -1, -1, -1, -1, 1, 2, -1, -1, -1, -1, 0 + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, -1, -1, -1, -1, -1, + 1, 0, 1, 0, 1, -1, -1, 0, 0, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 0, 0, -1, -1, -1, -1, -1, 1, 2, -1, -1, -1, -1, 0 }; char sb16_copyright[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992."; @@ -76,33 +82,33 @@ uint16_t sb_dsp_versions[] = { 0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405, 0 /*These tables were 'borrowed' from DOSBox*/ int8_t scaleMap4[64] = { - 0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7, - 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15, - 2, 6, 10, 14, 18, 22, 26, 30, -2, -6, -10, -14, -18, -22, -26, -30, + 0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7, + 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15, + 2, 6, 10, 14, 18, 22, 26, 30, -2, -6, -10, -14, -18, -22, -26, -30, 4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60 }; uint8_t adjustMap4[64] = { - 0, 0, 0, 0, 0, 16, 16, 16, - 0, 0, 0, 0, 0, 16, 16, 16, + 0, 0, 0, 0, 0, 16, 16, 16, + 0, 0, 0, 0, 0, 16, 16, 16, 240, 0, 0, 0, 0, 16, 16, 16, 240, 0, 0, 0, 0, 16, 16, 16, 240, 0, 0, 0, 0, 16, 16, 16, 240, 0, 0, 0, 0, 16, 16, 16, - 240, 0, 0, 0, 0, 0, 0, 0, - 240, 0, 0, 0, 0, 0, 0, 0 + 240, 0, 0, 0, 0, 0, 0, 0, + 240, 0, 0, 0, 0, 0, 0, 0 }; int8_t scaleMap26[40] = { - 0, 1, 2, 3, 0, -1, -2, -3, - 1, 3, 5, 7, -1, -3, -5, -7, - 2, 6, 10, 14, -2, -6, -10, -14, + 0, 1, 2, 3, 0, -1, -2, -3, + 1, 3, 5, 7, -1, -3, -5, -7, + 2, 6, 10, 14, -2, -6, -10, -14, 4, 12, 20, 28, -4, -12, -20, -28, 5, 15, 25, 35, -5, -15, -25, -35 }; uint8_t adjustMap26[40] = { - 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 248, 0, 0, 8, 248, 0, 0, 8, 248, 0, 0, 8, 248, 0, 0, 8, 248, 0, 0, 8, 248, 0, 0, 8, @@ -110,15 +116,17 @@ uint8_t adjustMap26[40] = { }; int8_t scaleMap2[24] = { - 0, 1, 0, -1, 1, 3, -1, -3, - 2, 6, -2, -6, 4, 12, -4, -12, + 0, 1, 0, -1, 1, 3, -1, -3, + 2, 6, -2, -6, 4, 12, -4, -12, 8, 24, -8, -24, 6, 48, -16, -48 }; uint8_t adjustMap2[24] = { - 0, 4, 0, 4, - 252, 4, 252, 4, 252, 4, 252, 4, - 252, 4, 252, 4, 252, 4, 252, 4, + 0, 4, 0, 4, + 252, 4, 252, 4, + 252, 4, 252, 4, + 252, 4, 252, 4, + 252, 4, 252, 4, 252, 0, 252, 0 }; @@ -240,7 +248,7 @@ uint16_t espcm3_dpcm_tables[1024] = }; // clang-format on -double low_fir_sb16_coef[4][SB16_NCoef]; +double low_fir_sb16_coef[5][SB16_NCoef]; #ifdef ENABLE_SB_DSP_LOG int sb_dsp_do_log = ENABLE_SB_DSP_LOG; @@ -269,20 +277,18 @@ sinc(double x) } static void -recalc_sb16_filter(int c, int playback_freq) +recalc_sb16_filter(const int c, const int playback_freq) { /* Cutoff frequency = playback / 2 */ - int n; - double w; - double h; - double fC = ((double) playback_freq) / (double) FREQ_96000; - double gain; + int n; + const double fC = ((double) playback_freq) / (double) FREQ_96000; for (n = 0; n < SB16_NCoef; n++) { /* Blackman window */ - w = 0.42 - (0.5 * cos((2.0 * n * M_PI) / (double) (SB16_NCoef - 1))) + (0.08 * cos((4.0 * n * M_PI) / (double) (SB16_NCoef - 1))); + const double w = 0.42 - (0.5 * cos((2.0 * n * M_PI) / (double) (SB16_NCoef - 1))) + + (0.08 * cos((4.0 * n * M_PI) / (double) (SB16_NCoef - 1))); /* Sinc filter */ - h = sinc(2.0 * fC * ((double) n - ((double) (SB16_NCoef - 1) / 2.0))); + const double h = sinc(2.0 * fC * ((double) n - ((double) (SB16_NCoef - 1) / 2.0))); /* Create windowed-sinc filter */ low_fir_sb16_coef[c][n] = w * h; @@ -290,7 +296,7 @@ recalc_sb16_filter(int c, int playback_freq) low_fir_sb16_coef[c][(SB16_NCoef - 1) / 2] = 1.0; - gain = 0.0; + double gain = 0.0; for (n = 0; n < SB16_NCoef; n++) gain += low_fir_sb16_coef[c][n]; @@ -300,38 +306,36 @@ recalc_sb16_filter(int c, int playback_freq) } static void -recalc_opl_filter(int c, int playback_freq) +recalc_opl_filter(const int playback_freq) { /* Cutoff frequency = playback / 2 */ - int n; - double w; - double h; - double fC = ((double) playback_freq) / (double) (FREQ_49716 * 2); - double gain; + int n; + const double fC = ((double) playback_freq) / (double) (FREQ_49716 * 2); for (n = 0; n < SB16_NCoef; n++) { /* Blackman window */ - w = 0.42 - (0.5 * cos((2.0 * n * M_PI) / (double) (SB16_NCoef - 1))) + (0.08 * cos((4.0 * n * M_PI) / (double) (SB16_NCoef - 1))); + const double w = 0.42 - (0.5 * cos((2.0 * n * M_PI) / (double) (SB16_NCoef - 1))) + + (0.08 * cos((4.0 * n * M_PI) / (double) (SB16_NCoef - 1))); /* Sinc filter */ - h = sinc(2.0 * fC * ((double) n - ((double) (SB16_NCoef - 1) / 2.0))); + const double h = sinc(2.0 * fC * ((double) n - ((double) (SB16_NCoef - 1) / 2.0))); /* Create windowed-sinc filter */ - low_fir_sb16_coef[c][n] = w * h; + low_fir_sb16_coef[1][n] = w * h; } - low_fir_sb16_coef[c][(SB16_NCoef - 1) / 2] = 1.0; + low_fir_sb16_coef[1][(SB16_NCoef - 1) / 2] = 1.0; - gain = 0.0; + double gain = 0.0; for (n = 0; n < SB16_NCoef; n++) - gain += low_fir_sb16_coef[c][n]; + gain += low_fir_sb16_coef[1][n]; /* Normalise filter, to produce unity gain */ for (n = 0; n < SB16_NCoef; n++) - low_fir_sb16_coef[c][n] /= gain; + low_fir_sb16_coef[1][n] /= gain; } static void -sb_irq_update_pic(void *priv, int set) +sb_irq_update_pic(void *priv, const int set) { const sb_dsp_t *dsp = (sb_dsp_t *) priv; if (set) @@ -368,11 +372,9 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) return; /* NOTE: not on ES1688 or ES1868 */ - if (IS_ESS(dsp) && dsp->sb_subtype != SB_SUBTYPE_ESS_ES1688 - && !(ESSreg(0xB1) & 0x10)) // if ESS playback, and IRQ disabled, do not fire - { + if (IS_ESS(dsp) && (dsp->sb_subtype != SB_SUBTYPE_ESS_ES1688) && !(ESSreg(0xB1) & 0x10)) + /* If ESS playback, and IRQ disabled, do not fire. */ return; - } switch (bit) { default: @@ -391,7 +393,7 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) } /* NOTE: not on ES1688, apparently; investigate on ES1868 */ - if (IS_ESS(dsp) && dsp->sb_subtype != SB_SUBTYPE_ESS_ES1688) { + if (IS_ESS(dsp) && (dsp->sb_subtype > SB_SUBTYPE_ESS_ES1688)) { /* TODO: Investigate real hardware for this (the ES1887 datasheet documents this bit somewhat oddly.) */ if (dsp->ess_playback_mode && bit <= 1 && set && !masked) { if (!(ESSreg(0xB1) & 0x40)) // if ESS playback, and IRQ disabled, do not fire @@ -420,7 +422,7 @@ sb_irqc(sb_dsp_t *dsp, int irq8) } static void -sb_dsp_irq_update(void *priv, int set) +sb_dsp_irq_update(void *priv, const int set) { sb_dsp_t *dsp = (sb_dsp_t *) priv; @@ -509,14 +511,14 @@ void sb_dsp_speed_changed(sb_dsp_t *dsp) { if (dsp->sb_timeo < 256) - dsp->sblatcho = TIMER_USEC * (256 - dsp->sb_timeo); + dsp->sblatcho = (double) (TIMER_USEC * (256 - dsp->sb_timeo)); else - dsp->sblatcho = (uint64_t) (TIMER_USEC * (1000000.0f / (float) (dsp->sb_timeo - 256))); + dsp->sblatcho = ((double) TIMER_USEC * (1000000.0 / (double) (dsp->sb_timeo - 256))); if (dsp->sb_timei < 256) - dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_timei); + dsp->sblatchi = (double) (TIMER_USEC * (256 - dsp->sb_timei)); else - dsp->sblatchi = (uint64_t) (TIMER_USEC * (1000000.0f / (float) (dsp->sb_timei - 256))); + dsp->sblatchi = ((double) TIMER_USEC * (1000000.0 / (double) (dsp->sb_timei - 256))); } void @@ -527,18 +529,16 @@ sb_add_data(sb_dsp_t *dsp, uint8_t v) } static unsigned int -sb_ess_get_dma_counter(sb_dsp_t *dsp) +sb_ess_get_dma_counter(const sb_dsp_t *dsp) { - unsigned int c; - - c = (unsigned int) ESSreg(0xA5) << 8U; + unsigned int c = (unsigned int) ESSreg(0xA5) << 8U; c |= (unsigned int) ESSreg(0xA4); return c; } static unsigned int -sb_ess_get_dma_len(sb_dsp_t *dsp) +sb_ess_get_dma_len(const sb_dsp_t *dsp) { return 0x10000U - sb_ess_get_dma_counter(dsp); } @@ -554,12 +554,13 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) dsp->sb_8_autoinit = autoinit; dsp->sb_8_pause = 0; dsp->sb_8_enable = 1; + dsp->dma_ff = 0; if (dsp->sb_16_enable && dsp->sb_16_output) dsp->sb_16_enable = 0; dsp->sb_8_output = 1; if (!timer_is_enabled(&dsp->output_timer)) - timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); + timer_set_delay_u64(&dsp->output_timer, (uint64_t) dsp->sblatcho); dsp->sbleftright = dsp->sbleftright_default; dsp->sbdacpos = 0; } else { @@ -572,7 +573,7 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) dsp->sb_8_enable = 0; dsp->sb_16_output = 1; if (!timer_is_enabled(&dsp->output_timer)) - timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); + timer_set_delay_u64(&dsp->output_timer, (uint64_t) dsp->sblatcho); } /* This will be set later for ESS playback/record modes. */ @@ -592,7 +593,7 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) dsp->sb_16_enable = 0; dsp->sb_8_output = 0; if (!timer_is_enabled(&dsp->input_timer)) - timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); + timer_set_delay_u64(&dsp->input_timer, (uint64_t) dsp->sblatchi); } else { dsp->sb_16_length = dsp->sb_16_origlength = len; dsp->sb_16_format = format; @@ -603,7 +604,7 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) dsp->sb_8_enable = 0; dsp->sb_16_output = 0; if (!timer_is_enabled(&dsp->input_timer)) - timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); + timer_set_delay_u64(&dsp->input_timer, (uint64_t) dsp->sblatchi); } memset(dsp->record_buffer, 0, sizeof(dsp->record_buffer)); @@ -623,9 +624,9 @@ sb_start_dma_ess(sb_dsp_t *dsp) real_format |= !!(ESSreg(0xB7) & 0x20) ? 0x10 : 0; real_format |= !!(ESSreg(0xB7) & 0x8) ? 0x20 : 0; if (!!(ESSreg(0xB8) & 8)) - sb_start_dma_i(dsp, !(ESSreg(0xB7) & 4), (ESSreg(0xB8) >> 2) & 1, real_format, len); + sb_start_dma_i(dsp, !(ESSreg(0xB7) & 4), (ESSreg(0xB8) >> 2) & 1, real_format, (int) len); else - sb_start_dma(dsp, !(ESSreg(0xB7) & 4), (ESSreg(0xB8) >> 2) & 1, real_format, len); + sb_start_dma(dsp, !(ESSreg(0xB7) & 4), (ESSreg(0xB8) >> 2) & 1, real_format, (int) len); dsp->ess_playback_mode = 1; dma_set_drq(dsp->sb_8_dmanum, 1); dma_set_drq(dsp->sb_16_8_dmanum, 1); @@ -644,7 +645,7 @@ sb_ess_update_dma_status(sb_dsp_t *dsp) { bool dma_en = (ESSreg(0xB8) & 1) ? true : false; - // if the DRQ is disabled, do not start + /* If the DRQ is disabled, do not start. */ if (!(ESSreg(0xB2) & 0x40)) dma_en = false; @@ -660,9 +661,28 @@ sb_ess_update_dma_status(sb_dsp_t *dsp) int sb_8_read_dma(void *priv) { - const sb_dsp_t *dsp = (sb_dsp_t *) priv; + sb_dsp_t *dsp = (sb_dsp_t *) priv; + int ret; - return dma_channel_read(dsp->sb_8_dmanum); + if (dsp->sb_8_dmanum >= 4) { + if (dsp->dma_ff) { + uint32_t temp = (dsp->dma_data & 0xff00) >> 8; + temp |= (dsp->dma_data & 0xffff0000); + ret = (int) temp; + } else { + dsp->dma_data = dma_channel_read(dsp->sb_8_dmanum); + + if (dsp->dma_data == DMA_NODATA) + return DMA_NODATA; + + ret = dsp->dma_data & 0xff; + } + + dsp->dma_ff = !dsp->dma_ff; + } else + ret = dma_channel_read(dsp->sb_8_dmanum); + + return ret; } int @@ -690,8 +710,8 @@ sb_16_read_dma(void *priv) { const sb_dsp_t *dsp = (sb_dsp_t *) priv; - int temp, ret = 0; - int dma_flags, dma_ch = dsp->sb_16_dmanum; + int ret; + int dma_ch = dsp->sb_16_dmanum; if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate) ret = dma_channel_read(dma_ch); @@ -699,19 +719,18 @@ sb_16_read_dma(void *priv) if (dsp->sb_16_dma_enabled) { /* High DMA channel enabled, either translation is enabled or 16-bit transfers are not supported. */ - if (dsp->sb_16_dma_translate || !dsp->sb_16_dma_supported) - dma_ch = dsp->sb_16_8_dmanum; + dma_ch = dsp->sb_16_8_dmanum; } else /* High DMA channel disabled, always use the first 8-bit channel. */ dma_ch = dsp->sb_8_dmanum; - temp = dma_channel_read(dma_ch); + int temp = dma_channel_read(dma_ch); ret = temp; if ((temp != DMA_NODATA) && !(temp & DMA_OVER)) { temp = dma_channel_read(dma_ch); if (temp == DMA_NODATA) ret = DMA_NODATA; else { - dma_flags = temp & DMA_OVER; + const int dma_flags = temp & DMA_OVER; temp &= ~DMA_OVER; ret |= (temp << 8) | dma_flags; } @@ -725,9 +744,8 @@ int sb_16_write_dma(void *priv, uint16_t val) { const sb_dsp_t *dsp = (sb_dsp_t *) priv; - - int temp, ret = 0; int dma_ch = dsp->sb_16_dmanum; + int ret; if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate) ret = dma_channel_write(dma_ch, val) == DMA_NODATA; @@ -735,12 +753,11 @@ sb_16_write_dma(void *priv, uint16_t val) if (dsp->sb_16_dma_enabled) { /* High DMA channel enabled, either translation is enabled or 16-bit transfers are not supported. */ - if (dsp->sb_16_dma_translate || !dsp->sb_16_dma_supported) - dma_ch = dsp->sb_16_8_dmanum; + dma_ch = dsp->sb_16_8_dmanum; } else /* High DMA channel disabled, always use the first 8-bit channel. */ dma_ch = dsp->sb_8_dmanum; - temp = dma_channel_write(dma_ch, val & 0xff); + int temp = dma_channel_write(dma_ch, val & 0xff); ret = temp; if ((temp != DMA_NODATA) && (temp != DMA_OVER)) { temp = dma_channel_write(dma_ch, val >> 8); @@ -760,6 +777,8 @@ sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy) t |= 0x80; } switch (dsp->sb_irqnum) { + default: + break; case 9: t |= 0x0; break; @@ -781,6 +800,8 @@ sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy) t |= 0x80; } switch (dsp->sb_8_dmanum) { + default: + break; case 0: t |= 0x5; break; @@ -843,17 +864,17 @@ sb_dsp_setdma16_supported(sb_dsp_t *dsp, int supported) } void -sb_dsp_setdma16_translate(sb_dsp_t *dsp, int translate) +sb_dsp_setdma16_translate(sb_dsp_t *dsp, const int translate) { sb_dsp_log("16-bit to 8-bit translation now: %sabled\n", translate ? "en" : "dis"); dsp->sb_16_dma_translate = translate; } static void -sb_ess_update_reg_a2(sb_dsp_t *dsp, uint8_t val) +sb_ess_update_reg_a2(sb_dsp_t *dsp, const uint8_t val) { - double freq = (7160000.0 / (256.0 - ((double) val))) * 41.0; - int temp = (int) freq; + const double freq = (7160000.0 / (256.0 - ((double) val))) * 41.0; + const int temp = (int) freq; ESSreg(0xA2) = val; if (dsp->sb_freq != temp) @@ -866,7 +887,7 @@ sb_ess_update_reg_a2(sb_dsp_t *dsp, uint8_t val) static void sb_ess_update_filter_freq(sb_dsp_t *dsp) { - double temp = (7160000.0 / (((((double) dsp->sb_freq) / 2.0) * 0.80) * 82.0)) - 256.0; + const double temp = (7160000.0 / (((((double) dsp->sb_freq) / 2.0) * 0.80) * 82.0)) - 256.0; if (dsp->sb_freq >= 22050) ESSreg(0xA1) = 256 - (795500UL / dsp->sb_freq); @@ -877,36 +898,32 @@ sb_ess_update_filter_freq(sb_dsp_t *dsp) } static uint8_t -sb_ess_read_reg(sb_dsp_t *dsp, uint8_t reg) +sb_ess_read_reg(const sb_dsp_t *dsp, const uint8_t reg) { - switch (reg) { - default: - return ESSreg(reg); - } + return ESSreg(reg); } static void sb_ess_update_autolen(sb_dsp_t *dsp) { - dsp->sb_8_autolen = dsp->sb_16_autolen = sb_ess_get_dma_len(dsp); + dsp->sb_8_autolen = dsp->sb_16_autolen = (int) sb_ess_get_dma_len(dsp); } static void -sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) +sb_ess_write_reg(sb_dsp_t *dsp, const uint8_t reg, uint8_t data) { - uint8_t chg = 0x00; + uint8_t chg; switch (reg) { case 0xA1: /* Extended Mode Sample Rate Generator */ { - double temp; ESSreg(reg) = data; if (data & 0x80) - dsp->sb_freq = 795500UL / (256ul - data); + dsp->sb_freq = (int) (795500UL / (256ul - data)); else - dsp->sb_freq = 397700UL / (128ul - data); - temp = 1000000.0 / dsp->sb_freq; - dsp->sblatchi = dsp->sblatcho = TIMER_USEC * temp; + dsp->sb_freq = (int) (397700UL / (128ul - data)); + const double temp = 1000000.0 / dsp->sb_freq; + dsp->sblatchi = dsp->sblatcho = ((double) TIMER_USEC * temp); dsp->sb_timei = dsp->sb_timeo; break; @@ -953,6 +970,8 @@ sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) case 0xB1: /* Legacy Audio Interrupt Control */ ESSreg(reg) = (ESSreg(reg) & 0x0F) + (data & 0xF0); // lower 4 bits not writeable switch (data & 0x0C) { + default: + break; case 0x00: dsp->sb_irqnum = 2; break; @@ -972,6 +991,8 @@ sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) chg = ESSreg(reg) ^ data; ESSreg(reg) = (ESSreg(reg) & 0x0F) + (data & 0xF0); // lower 4 bits not writeable switch (data & 0x0C) { + default: + break; case 0x00: dsp->sb_8_dmanum = -1; break; @@ -1033,9 +1054,9 @@ sb_ess_write_reg(sb_dsp_t *dsp, uint8_t reg, uint8_t data) if (chg & 1) { if (dsp->sb_16_enable || dsp->sb_8_enable) { if (dsp->sb_16_enable) - dsp->sb_16_length = sb_ess_get_dma_len(dsp); + dsp->sb_16_length = (int) sb_ess_get_dma_len(dsp); if (dsp->sb_8_enable) - dsp->sb_8_length = sb_ess_get_dma_len(dsp); + dsp->sb_8_length = (int) sb_ess_get_dma_len(dsp); } else dsp->ess_reload_len = 1; } @@ -1122,8 +1143,9 @@ sb_exec_command(sb_dsp_t *dsp) } /* else DSP Status (Obsolete) */ break; case 0x05: /* ASP set codec parameter */ - if (dsp->sb_type >= SB16) + if (dsp->sb_type >= SB16) { sb_dsp_log("SB16 ASP unknown codec params %02X, %02X\n", dsp->sb_data[0], dsp->sb_data[1]); + } break; case 0x07: break; @@ -1209,7 +1231,7 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0x10: /* 8-bit direct mode */ sb_dsp_update(dsp); - dsp->sbdat = dsp->sbdatl = dsp->sbdatr = (dsp->sb_data[0] ^ 0x80) << 8; + dsp->sbdat = dsp->sbdatl = dsp->sbdatr = (int16_t) ((dsp->sb_data[0] ^ 0x80) << 8); // FIXME: What does the ESS AudioDrive do to its filter/sample rate divider registers when emulating this Sound Blaster command? ESSreg(0xA1) = 128 - (397700 / 22050); ESSreg(0xA2) = 256 - (7160000 / (82 * ((4 * 22050) / 10))); @@ -1249,10 +1271,10 @@ sb_exec_command(sb_dsp_t *dsp) mode does not imply such samplerate. Position is increased in sb_poll_i(). */ if (!timer_is_enabled(&dsp->input_timer)) { dsp->sb_timei = 256 - 22; - dsp->sblatchi = TIMER_USEC * 22; + dsp->sblatchi = (double) ((double) TIMER_USEC * 22.0); temp = 1000000 / 22; dsp->sb_freq = temp; - timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); + timer_set_delay_u64(&dsp->input_timer, (uint64_t) dsp->sblatchi); } break; case 0x24: /* 8-bit single cycle DMA input */ @@ -1275,7 +1297,6 @@ sb_exec_command(sb_dsp_t *dsp) dsp->uart_irq = 1; break; case 0x32: /* MIDI Read Timestamp Poll */ - break; case 0x33: /* MIDI Read Timestamp Interrupt */ break; case 0x34: /* MIDI In poll */ @@ -1302,7 +1323,7 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0x40: /* Set time constant */ dsp->sb_timei = dsp->sb_timeo = dsp->sb_data[0]; - dsp->sblatcho = dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_data[0]); + dsp->sblatcho = dsp->sblatchi = (double) (TIMER_USEC * (256 - dsp->sb_data[0])); temp = 256 - dsp->sb_data[0]; temp = 1000000 / temp; sb_dsp_log("Sample rate - %ihz (%f)\n", temp, dsp->sblatcho); @@ -1316,21 +1337,20 @@ sb_exec_command(sb_dsp_t *dsp) case 0x41: /* Set output sampling rate */ case 0x42: /* Set input sampling rate */ if (dsp->sb_type >= SB16) { - dsp->sblatcho = (uint64_t) (TIMER_USEC * (1000000.0f / (float) (dsp->sb_data[1] + (dsp->sb_data[0] << 8)))); + dsp->sblatcho = (double) ((double) TIMER_USEC * (1000000.0 / (double) (dsp->sb_data[1] + (dsp->sb_data[0] << 8)))); sb_dsp_log("Sample rate - %ihz (%f)\n", dsp->sb_data[1] + (dsp->sb_data[0] << 8), dsp->sblatcho); temp = dsp->sb_freq; dsp->sb_freq = dsp->sb_data[1] + (dsp->sb_data[0] << 8); - dsp->sb_timeo = 256LL + dsp->sb_freq; + dsp->sb_timeo = 256 + dsp->sb_freq; dsp->sblatchi = dsp->sblatcho; dsp->sb_timei = dsp->sb_timeo; - if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16)) + if (dsp->sb_freq != temp) recalc_sb16_filter(0, dsp->sb_freq); dsp->sb_8051_ram[0x13] = dsp->sb_freq & 0xff; dsp->sb_8051_ram[0x14] = (dsp->sb_freq >> 8) & 0xff; } break; case 0x45: /* Continue Auto-Initialize DMA, 8-bit */ - break; case 0x47: /* Continue Auto-Initialize DMA, 16-bit */ break; case 0x48: /* Set DSP block transfer size */ @@ -1427,7 +1447,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0x80: /* Pause DAC */ dsp->sb_pausetime = dsp->sb_data[0] + (dsp->sb_data[1] << 8); if (!timer_is_enabled(&dsp->output_timer)) - timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); + timer_set_delay_u64(&dsp->output_timer, (uint64_t) trunc(dsp->sblatcho)); break; case 0x90: /* High speed 8-bit autoinit DMA output */ if (dsp->sb_type >= SB2) @@ -1511,7 +1531,7 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sb_8_pause = 1; break; case 0xD1: /* Speaker on */ - if (!IS_ESS(dsp)) { + if (IS_NOT_ESS(dsp)) { if (dsp->sb_type < SB15) dsp->sb_8_pause = 1; else if (dsp->sb_type < SB16) @@ -1520,7 +1540,7 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sb_speaker = 1; break; case 0xD3: /* Speaker off */ - if (!IS_ESS(dsp)) { + if (IS_NOT_ESS(dsp)) { if (dsp->sb_type < SB15) dsp->sb_8_pause = 1; else if (dsp->sb_type < SB16) @@ -1578,7 +1598,10 @@ sb_exec_command(sb_dsp_t *dsp) } dsp->sbe2 += sbe2dat[dsp->sbe2count & 3][8]; dsp->sbe2count++; - dsp->dma_writeb(dsp->dma_priv, dsp->sbe2); + if (dsp->dma_writeb(dsp->dma_priv, dsp->sbe2)) + /* Undocumented behavior: If write to DMA fails, the byte is written + to the CPU instead. The NT 3.1 Sound Blaster Pro driver relies on this. */ + sb_add_data(dsp, dsp->sbe2); break; case 0xE3: /* DSP copyright */ if (dsp->sb_type >= SB16) { @@ -1598,6 +1621,10 @@ sb_exec_command(sb_dsp_t *dsp) switch (dsp->sb_subtype) { default: break; + case SB_SUBTYPE_ESS_ES688: + sb_add_data(dsp, 0x68); + sb_add_data(dsp, 0x80 | 0x04); + break; case SB_SUBTYPE_ESS_ES1688: // Determined via Windows driver debugging. sb_add_data(dsp, 0x68); @@ -1664,24 +1691,34 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sb_8051_ram[0x30] = dsp->sb_command; } +static void +sb_do_reset(sb_dsp_t *dsp, const uint8_t v) +{ + if (((v & 1) != 0) && (dsp->state != DSP_S_RESET)) { + sb_dsp_reset(dsp); + dsp->sb_read_rp = dsp->sb_read_wp = 0; + dsp->state = DSP_S_RESET; + } else if (((v & 1) == 0) && (dsp->state == DSP_S_RESET)) { + dsp->state = DSP_S_RESET_WAIT; + dsp->sb_read_rp = dsp->sb_read_wp = 0; + sb_add_data(dsp, 0xaa); + } +} + void sb_write(uint16_t a, uint8_t v, void *priv) { sb_dsp_t *dsp = (sb_dsp_t *) priv; + sb_dsp_log("[%04X:%08X] DSP: [W] %04X = %02X\n", CS, cpu_state.pc, a, v); + /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ - if (dsp->sb_type < SB16 && (!IS_ESS(dsp) || (IS_ESS(dsp) && ((a & 0xF) != 0xE)))) + if ((dsp->sb_type < SB16) && (IS_NOT_ESS(dsp) || ((a & 0xF) != 0xE))) a &= 0xfffe; switch (a & 0xF) { case 6: /* Reset */ - if (!dsp->uart_midi) { - if (!(v & 1) && (dsp->sbreset & 1)) { - sb_dsp_reset(dsp); - sb_add_data(dsp, 0xAA); - } - dsp->sbreset = v; - } + sb_do_reset(dsp, v); if (!(v & 2) && (dsp->espcm_fifo_reset & 2)) { fifo_reset(dsp->espcm_fifo); @@ -1759,79 +1796,101 @@ sb_read(uint16_t a, void *priv) uint8_t ret = 0x00; /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ - if (dsp->sb_type < SB16) { + if ((dsp->sb_type < SB16) && (IS_NOT_ESS(dsp) || ((a & 0xF) != 0xF))) /* Exception: ESS AudioDrive does not alias port base+0xf */ - if (!IS_ESS(dsp) || !((a & 0xF) == 0xF)) { a &= 0xfffe; - } - } switch (a & 0xf) { + case 0x6: + ret = 0xff; + break; case 0xA: /* Read data */ - if (dsp->mpu && dsp->uart_midi) { + if (dsp->mpu && dsp->uart_midi) ret = MPU401_ReadData(dsp->mpu); - } else { - dsp->sbreaddat = dsp->sb_read_data[dsp->sb_read_rp]; + else { if (dsp->sb_read_rp != dsp->sb_read_wp) { + dsp->sbreaddat = dsp->sb_read_data[dsp->sb_read_rp]; dsp->sb_read_rp++; dsp->sb_read_rp &= 0xff; } - return dsp->sbreaddat; + ret = dsp->sbreaddat; } + /* Advance the state just in case something reads from here + without reading the status first. */ + if (dsp->state == DSP_S_RESET_WAIT) + dsp->state = DSP_S_NORMAL; break; case 0xC: /* Write data ready */ - if (dsp->sb_8_enable || dsp->sb_type >= SB16) - dsp->busy_count = (dsp->busy_count + 1) & 3; - else - dsp->busy_count = 0; - if (IS_ESS(dsp)) { - if (dsp->wb_full || (dsp->busy_count & 2)) { - dsp->wb_full = timer_is_enabled(&dsp->wb_timer); - } - uint8_t busy_flag = dsp->wb_full ? 0x80 : 0x00; - uint8_t data_rdy = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x40; - uint8_t fifo_full = 0; /* Unimplemented */ - uint8_t fifo_empty = 0; /* (this is for the 256-byte extended mode FIFO, */ - uint8_t fifo_half = 0; /* not the standard 64-byte FIFO) */ - uint8_t irq_generic = dsp->ess_irq_generic ? 0x04 : 0x00; - uint8_t irq_fifohe = 0; /* Unimplemented (ditto) */ - uint8_t irq_dmactr = dsp->ess_irq_dmactr ? 0x01 : 0x00; + if (dsp->state == DSP_S_NORMAL) { + if (dsp->sb_8_enable || dsp->sb_type >= SB16) + dsp->busy_count = (dsp->busy_count + 1) & 3; + else + dsp->busy_count = 0; + if (IS_ESS(dsp)) { + if (dsp->wb_full || (dsp->busy_count & 2)) + dsp->wb_full = timer_is_enabled(&dsp->wb_timer); - return busy_flag | data_rdy | fifo_full | fifo_empty | fifo_half | irq_generic | irq_fifohe | irq_dmactr; - } - if (dsp->wb_full || (dsp->busy_count & 2)) { - dsp->wb_full = timer_is_enabled(&dsp->wb_timer); - if (IS_AZTECH(dsp)) { - sb_dsp_log("SB Write Data Aztech read 0x80\n"); - return 0x80; + const uint8_t busy_flag = dsp->wb_full ? 0x80 : 0x00; + const uint8_t data_rdy = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x40; + const uint8_t fifo_full = 0; /* Unimplemented */ + const uint8_t fifo_empty = 0; /* (this is for the 256-byte extended mode FIFO, */ + const uint8_t fifo_half = 0; /* not the standard 64-byte FIFO) */ + const uint8_t irq_generic = dsp->ess_irq_generic ? 0x04 : 0x00; + const uint8_t irq_fifohe = 0; /* Unimplemented (ditto) */ + const uint8_t irq_dmactr = dsp->ess_irq_dmactr ? 0x01 : 0x00; + + ret = busy_flag | data_rdy | fifo_full | fifo_empty | fifo_half | irq_generic | irq_fifohe | irq_dmactr; + } else if (dsp->wb_full || (dsp->busy_count & 2)) { + dsp->wb_full = timer_is_enabled(&dsp->wb_timer); + if (IS_AZTECH(dsp)) { + sb_dsp_log("SB Write Data Aztech read 0x80\n"); + ret = 0x80; + } else { + sb_dsp_log("SB Write Data Creative read 0xff\n"); + if ((dsp->sb_type >= SB2) && (dsp->sb_type < SB16) && IS_NOT_ESS(dsp)) + ret = 0xaa; + else + ret = 0xff; + } + } else if (IS_AZTECH(dsp)) { + sb_dsp_log("SB Write Data Aztech read 0x00\n"); + ret = 0x00; } else { - sb_dsp_log("SB Write Data Creative read 0xff\n"); - return 0xff; + sb_dsp_log("SB Write Data Creative read 0x7f\n"); + if ((dsp->sb_type >= SB2) && (dsp->sb_type < SB16) && IS_NOT_ESS(dsp)) + ret = 0x2a; + else + ret = 0x7f; } - } - if (IS_AZTECH(dsp)) { - sb_dsp_log("SB Write Data Aztech read 0x00\n"); - ret = 0x00; - } else { - sb_dsp_log("SB Write Data Creative read 0x7f\n"); - ret = 0x7f; - } + } else + ret = 0xff; break; case 0xE: /* Read data ready */ dsp->irq_update(dsp->irq_priv, 0); dsp->sb_irq8 = dsp->sb_irq16 = 0; dsp->ess_irq_generic = dsp->ess_irq_dmactr = false; - /* Only bit 7 is defined but aztech diagnostics fail if the others are set. Keep the original behavior to not interfere with what's already working. */ + /* + Only bit 7 is defined but aztech diagnostics fail if the others are set. + Keep the original behavior to not interfere with what's already working. + */ if (IS_AZTECH(dsp)) { - sb_dsp_log("SB Read Data Aztech read %02X, Read RP = %d, Read WP = %d\n", (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80, dsp->sb_read_rp, dsp->sb_read_wp); + sb_dsp_log("SB Read Data Aztech read %02X, Read RP = %d, Read WP = %d\n", + (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80, dsp->sb_read_rp, dsp->sb_read_wp); ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80; } else { sb_dsp_log("SB Read Data Creative read %02X\n", (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff); - ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff; + if ((dsp->sb_type < SB16) && IS_NOT_ESS(dsp)) + ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x2a : 0xaa; + else + ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff; + } + if (dsp->state == DSP_S_RESET_WAIT) { + ret &= 0x7f; + dsp->state = DSP_S_NORMAL; } break; case 0xF: /* 16-bit ack */ - if (!IS_ESS(dsp)) { + if (IS_NOT_ESS(dsp)) { dsp->sb_irq16 = 0; if (!dsp->sb_irq8) dsp->irq_update(dsp->irq_priv, 0); @@ -1844,6 +1903,8 @@ sb_read(uint16_t a, void *priv) break; } + sb_dsp_log("[%04X:%08X] DSP: [R] %04X = %02X\n", CS, cpu_state.pc, a, ret); + return ret; } @@ -1891,7 +1952,7 @@ sb_dsp_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) for (uint32_t i = 0; i < len; i++) { if (dsp->sb_read_rp == dsp->sb_read_wp) { sb_dsp_log("Length sysex SB = %d\n", len - i); - return (len - i); + return (int) (len - i); } sb_add_data(dsp, buffer[i]); @@ -1952,13 +2013,13 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) if (IS_ESS(dsp) || (dsp->sb_type >= SBPRO2)) { /* OPL3 or dual OPL2 is stereo. */ if (dsp->sb_has_real_opl) - recalc_opl_filter(1, FREQ_49716 * 2); + recalc_opl_filter(FREQ_49716 * 2); else recalc_sb16_filter(1, FREQ_48000 * 2); } else { /* OPL2 is mono. */ if (dsp->sb_has_real_opl) - recalc_opl_filter(1, FREQ_49716); + recalc_opl_filter(FREQ_49716); else recalc_sb16_filter(1, FREQ_48000); } @@ -1966,6 +2027,8 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) recalc_sb16_filter(2, FREQ_44100 * 2); /* PC speaker is mono. */ recalc_sb16_filter(3, 18939); + /* E-MU 8000 is stereo. */ + recalc_sb16_filter(4, FREQ_44100 * 2); /* Initialize SB16 8051 RAM and ASP internal RAM */ memset(dsp->sb_8051_ram, 0x00, sizeof(dsp->sb_8051_ram)); @@ -2061,7 +2124,7 @@ pollsb(void *priv) int ref; int data[2]; - timer_advance_u64(&dsp->output_timer, dsp->sblatcho); + timer_advance_u64(&dsp->output_timer, (uint64_t) dsp->sblatcho); if (dsp->sb_8_enable && dsp->sb_pausetime < 0 && dsp->sb_8_output) { sb_dsp_update(dsp); @@ -2073,7 +2136,7 @@ pollsb(void *priv) auto-init DMA but programs the DMA controller to single cycle */ if (data[0] == DMA_NODATA) break; - dsp->sbdat = (data[0] ^ 0x80) << 8; + dsp->sbdat = (int16_t) ((data[0] ^ 0x80) << 8); if (dsp->stereo) { sb_dsp_log("pollsb: Mono unsigned, dsp->stereo, %s channel, %04X\n", dsp->sbleftright ? "left" : "right", dsp->sbdat); @@ -2093,7 +2156,7 @@ pollsb(void *priv) data[0] = dsp->dma_readb(dsp->dma_priv); if (data[0] == DMA_NODATA) break; - dsp->sbdat = data[0] << 8; + dsp->sbdat = (int16_t) (data[0] << 8); if (dsp->stereo) { sb_dsp_log("pollsb: Mono signed, dsp->stereo, %s channel, %04X\n", dsp->sbleftright ? "left" : "right", data[0], dsp->sbdat); @@ -2114,8 +2177,8 @@ pollsb(void *priv) data[1] = dsp->dma_readb(dsp->dma_priv); if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) break; - dsp->sbdatl = (data[0] ^ 0x80) << 8; - dsp->sbdatr = (data[1] ^ 0x80) << 8; + dsp->sbdatl = (int16_t) ((data[0] ^ 0x80) << 8); + dsp->sbdatr = (int16_t) ((data[1] ^ 0x80) << 8); dsp->sb_8_length -= 2; dsp->ess_dma_counter += 2; } @@ -2126,8 +2189,8 @@ pollsb(void *priv) data[1] = dsp->dma_readb(dsp->dma_priv); if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) break; - dsp->sbdatl = data[0] << 8; - dsp->sbdatr = data[1] << 8; + dsp->sbdatl = (int16_t) (data[0] << 8); + dsp->sbdatr = (int16_t) (data[1] << 8); dsp->sb_8_length -= 2; dsp->ess_dma_counter += 2; } @@ -2152,8 +2215,8 @@ pollsb(void *priv) else dsp->sbref = ref; - dsp->sbstep = (dsp->sbstep + adjustMap4[tempi]) & 0xff; - dsp->sbdat = (dsp->sbref ^ 0x80) << 8; + dsp->sbstep = (int8_t) ((dsp->sbstep + adjustMap4[tempi]) & 0xff); + dsp->sbdat = (int16_t) ((dsp->sbref ^ 0x80) << 8); dsp->sbdacpos++; @@ -2198,9 +2261,9 @@ pollsb(void *priv) dsp->sbref = 0x00; else dsp->sbref = ref; - dsp->sbstep = (dsp->sbstep + adjustMap26[tempi]) & 0xff; + dsp->sbstep = (int8_t) ((dsp->sbstep + adjustMap26[tempi]) & 0xff); - dsp->sbdat = (dsp->sbref ^ 0x80) << 8; + dsp->sbdat = (int16_t) ((dsp->sbref ^ 0x80) << 8); dsp->sbdacpos++; if (dsp->sbdacpos >= 3) { @@ -2238,9 +2301,9 @@ pollsb(void *priv) dsp->sbref = 0x00; else dsp->sbref = ref; - dsp->sbstep = (dsp->sbstep + adjustMap2[tempi]) & 0xff; + dsp->sbstep = (int8_t) ((dsp->sbstep + adjustMap2[tempi]) & 0xff); - dsp->sbdat = (dsp->sbref ^ 0x80) << 8; + dsp->sbdat = (int16_t) ((dsp->sbref ^ 0x80) << 8); dsp->sbdacpos++; if (dsp->sbdacpos >= 4) { @@ -2296,8 +2359,8 @@ pollsb(void *priv) dsp->espcm_sample_idx++; tempi |= (dsp->espcm_range << 4); - data[0] = espcm_range_map[tempi]; - dsp->sbdat = data[0] << 8; + data[0] = (int) espcm_range_map[tempi]; + dsp->sbdat = (int16_t) (data[0] << 8); if (dsp->stereo) { sb_dsp_log("pollsb: ESPCM 4, dsp->stereo, %s channel, %04X\n", dsp->sbleftright ? "left" : "right", dsp->sbdat); @@ -2392,8 +2455,8 @@ pollsb(void *priv) dsp->espcm_sample_idx++; tempi |= (dsp->espcm_range << 4); - data[0] = espcm_range_map[tempi]; - dsp->sbdat = data[0] << 8; + data[0] = (int) (espcm_range_map[tempi]); + dsp->sbdat = (int16_t) (data[0] << 8); if (dsp->stereo) { sb_dsp_log("pollsb: ESPCM 3, dsp->stereo, %s channel, %04X\n", dsp->sbleftright ? "left" : "right", dsp->sbdat); @@ -2444,8 +2507,8 @@ pollsb(void *priv) dsp->espcm_sample_idx++; tempi |= (dsp->espcm_range << 4); - data[0] = espcm_range_map[tempi]; - dsp->sbdat = data[0] << 8; + data[0] = (int) espcm_range_map[tempi]; + dsp->sbdat = (int16_t) (data[0] << 8); if (dsp->stereo) { sb_dsp_log("pollsb: ESPCM 1, dsp->stereo, %s channel, %04X\n", dsp->sbleftright ? "left" : "right", dsp->sbdat); @@ -2499,7 +2562,7 @@ pollsb(void *priv) data[0] = dsp->dma_readw(dsp->dma_priv); if (data[0] == DMA_NODATA) break; - dsp->sbdatl = dsp->sbdatr = data[0] ^ 0x8000; + dsp->sbdatl = dsp->sbdatr = (int16_t) ((data[0] & 0xffff) ^ 0x8000); dsp->sb_16_length--; dsp->ess_dma_counter += 2; break; @@ -2507,7 +2570,7 @@ pollsb(void *priv) data[0] = dsp->dma_readw(dsp->dma_priv); if (data[0] == DMA_NODATA) break; - dsp->sbdatl = dsp->sbdatr = data[0]; + dsp->sbdatl = dsp->sbdatr = (int16_t) (data[0] & 0xffff); dsp->sb_16_length--; dsp->ess_dma_counter += 2; break; @@ -2516,8 +2579,8 @@ pollsb(void *priv) data[1] = dsp->dma_readw(dsp->dma_priv); if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) break; - dsp->sbdatl = data[0] ^ 0x8000; - dsp->sbdatr = data[1] ^ 0x8000; + dsp->sbdatl = (int16_t) ((data[0] & 0xffff) ^ 0x8000); + dsp->sbdatr = (int16_t) ((data[1] & 0xffff) ^ 0x8000); dsp->sb_16_length -= 2; dsp->ess_dma_counter += 4; break; @@ -2526,8 +2589,8 @@ pollsb(void *priv) data[1] = dsp->dma_readw(dsp->dma_priv); if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) break; - dsp->sbdatl = data[0]; - dsp->sbdatr = data[1]; + dsp->sbdatl = (int16_t) (data[0] & 0xffff); + dsp->sbdatr = (int16_t) (data[1] & 0xffff); dsp->sb_16_length -= 2; dsp->ess_dma_counter += 4; break; @@ -2583,7 +2646,7 @@ sb_poll_i(void *priv) sb_dsp_t *dsp = (sb_dsp_t *) priv; int processed = 0; - timer_advance_u64(&dsp->input_timer, dsp->sblatchi); + timer_advance_u64(&dsp->input_timer, (uint64_t) dsp->sblatchi); if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && !dsp->sb_8_output) { switch (dsp->sb_8_format) { @@ -2618,16 +2681,17 @@ sb_poll_i(void *priv) dsp->record_pos_read &= 0xFFFF; break; case ESPCM_4E: - // I assume the real hardware double-buffers the blocks or something like that. - // We're not gonna do that here. - dsp->espcm_sample_buffer[dsp->espcm_sample_idx] = dsp->record_buffer[dsp->record_pos_read] >> 8; + /* + I assume the real hardware double-buffers the blocks or something like that. + We're not gonna do that here. + */ + dsp->espcm_sample_buffer[dsp->espcm_sample_idx] = (int8_t) (dsp->record_buffer[dsp->record_pos_read] >> 8); dsp->espcm_sample_idx++; dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; if (dsp->espcm_sample_idx >= 19) { - int i, table_addr, sigma, last_sigma; + int i, table_addr; int8_t min_sample = 127, max_sample = -128, s; - uint8_t b; for (i = 0; i < 19; i++) { s = dsp->espcm_sample_buffer[i]; @@ -2639,14 +2703,19 @@ sb_poll_i(void *priv) } } if (min_sample < 0) { - min_sample = -min_sample; + if (min_sample == -128) + min_sample = 127; /* Clip it to make it fit into int8_t. */ + else + min_sample = (int8_t) -min_sample; } if (max_sample < 0) { - max_sample = -max_sample; + if (max_sample == -128) + max_sample = 127; /* Clip it to make it fit into int8_t. */ + else + max_sample = (int8_t) -max_sample; } - if (min_sample > max_sample) { + if (min_sample > max_sample) max_sample = min_sample; - } for (table_addr = 15; table_addr < 256; table_addr += 16) { if (max_sample <= espcm_range_map[table_addr]) { @@ -2656,11 +2725,11 @@ sb_poll_i(void *priv) dsp->espcm_range = table_addr >> 4; for (i = 0; i < 19; i++) { + int last_sigma = 9999; table_addr = dsp->espcm_range << 4; - last_sigma = 9999; s = dsp->espcm_sample_buffer[i]; for (; (table_addr >> 4) == dsp->espcm_range; table_addr++) { - sigma = espcm_range_map[table_addr] - s; + int sigma = espcm_range_map[table_addr] - s; if (sigma < 0) { sigma = -sigma; } @@ -2673,7 +2742,7 @@ sb_poll_i(void *priv) dsp->espcm_code_buffer[i] = table_addr & 0x0F; } - b = dsp->espcm_range | (dsp->espcm_code_buffer[0] << 4); + uint8_t b = dsp->espcm_range | (dsp->espcm_code_buffer[0] << 4); dsp->dma_writeb(dsp->dma_priv, b); dsp->sb_8_length--; dsp->ess_dma_counter++; diff --git a/src/sound/sound.c b/src/sound/sound.c index cf7a7a33c..0611909d8 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -22,25 +22,20 @@ #include #include #include -#include #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/cdrom.h> #include <86box/device.h> #include <86box/filters.h> -#include <86box/hdc_ide.h> #include <86box/machine.h> #include <86box/midi.h> #include <86box/plat.h> #include <86box/thread.h> #include <86box/snd_ac97.h> -#include <86box/snd_azt2316a.h> #include <86box/timer.h> #include <86box/snd_mpu401.h> #include <86box/sound.h> -#include <86box/snd_opl.h> -#include <86box/snd_sb_dsp.h> typedef struct { const device_t *device; @@ -54,10 +49,15 @@ typedef struct { int sound_card_current[SOUND_CARD_MAX] = { 0, 0, 0, 0 }; int sound_pos_global = 0; int music_pos_global = 0; +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]; + +static double cd_audio_volume_lut[256]; static thread_t *sound_cd_thread_h; static event_t *sound_cd_event; @@ -68,12 +68,18 @@ static int16_t *outbuffer_ex_int16; static int32_t *outbuffer_m; static float *outbuffer_m_ex; static int16_t *outbuffer_m_ex_int16; +static int32_t *outbuffer_w; +static float *outbuffer_w_ex; +static int16_t *outbuffer_w_ex_int16; static int sound_handlers_num; static int music_handlers_num; +static int wavetable_handlers_num; static pc_timer_t sound_poll_timer; static uint64_t sound_poll_latch; static pc_timer_t music_poll_timer; static uint64_t music_poll_latch; +static pc_timer_t wavetable_poll_timer; +static uint64_t wavetable_poll_latch; static int16_t cd_buffer[CDROM_NUM][CD_BUFLEN * 2]; static float cd_out_buffer[CD_BUFLEN * 2]; @@ -120,52 +126,59 @@ static const device_t sound_internal_device = { static const SOUND_CARD sound_cards[] = { // clang-format off - { &sound_none_device }, - { &sound_internal_device }, - { &acermagic_s20_device }, - { &mirosound_pcm10_device }, - { &adlib_device }, - { &adgold_device }, - { &azt2316a_device }, - { &azt1605_device }, - { &cms_device }, - { &cs4235_device }, - { &cs4236b_device }, - { &gus_device }, - { &sb_1_device }, - { &sb_15_device }, - { &sb_2_device }, - { &sb_pro_v1_device }, - { &sb_pro_v2_device }, - { &sb_16_device }, - { &sb_16_pnp_device }, - { &sb_32_pnp_device }, - { &sb_awe32_device }, - { &sb_awe32_pnp_device }, - { &sb_awe64_value_device }, - { &sb_awe64_device }, - { &sb_awe64_gold_device }, - { &sb_vibra16c_device }, - { &sb_vibra16s_device }, - { &sb_vibra16xv_device }, - { &ssi2001_device }, - { &pasplus_device }, - { &pas16_device }, - { &pssj_isa_device }, - { &tndy_device }, - { &wss_device }, - { &adlib_mca_device }, - { &ncr_business_audio_device }, - { &sb_mcv_device }, - { &sb_pro_mcv_device }, - { &sb_16_reply_mca_device }, - { &cmi8338_device }, - { &cmi8738_device }, - { &es1371_device }, - { &ad1881_device }, - { &cs4297a_device }, - { &ess_1688_device }, - { NULL } + { &sound_none_device }, + { &sound_internal_device }, + { &acermagic_s20_device }, + { &mirosound_pcm10_device }, + { &adlib_device }, + { &adgold_device }, + { &azt2316a_device }, + { &azt1605_device }, + { &cms_device }, + { &cs4235_device }, + { &cs4236b_device }, + { &gus_device }, + { &sb_1_device }, + { &sb_15_device }, + { &sb_2_device }, + { &sb_pro_v1_device }, + { &sb_pro_v2_device }, + { &sb_16_device }, + { &sb_16_pnp_device }, + { &sb_32_pnp_device }, + { &sb_awe32_device }, + { &sb_awe32_pnp_device }, + { &sb_awe64_value_device }, + { &sb_awe64_device }, + { &sb_awe64_gold_device }, + { &sb_vibra16c_device }, + { &sb_vibra16s_device }, + { &sb_vibra16xv_device }, + { &ssi2001_device }, + { &pasplus_device }, + { &pas16_device }, + { &pssj_isa_device }, + { &tndy_device }, + { &wss_device }, + { &adlib_mca_device }, + { &ess_chipchat_16_mca_device }, + { &ncr_business_audio_device }, + { &sb_mcv_device }, + { &sb_pro_mcv_device }, + { &sb_16_reply_mca_device }, + { &ess_soundpiper_16_mca_device }, + { &ess_soundpiper_32_mca_device }, + { &cmi8338_device }, + { &cmi8738_device }, + { &es1371_device }, + { &ad1881_device }, + { &cs4297a_device }, + { &ess_688_device }, + { &ess_ess0100_pnp_device }, + { &ess_1688_device }, + { &ess_ess0102_pnp_device }, + { &ess_ess0968_pnp_device }, + { NULL } // clang-format on }; @@ -205,7 +218,7 @@ sound_card_getdevice(int card) int sound_card_has_config(int card) { - if (!sound_cards[card].device) + if (sound_cards[card].device == NULL) return 0; return device_has_config(sound_cards[card].device) ? 1 : 0; } @@ -234,13 +247,13 @@ void sound_card_init(void) { if ((sound_card_current[0] > SOUND_INTERNAL) && (sound_cards[sound_card_current[0]].device)) - device_add(sound_cards[sound_card_current[0]].device); + device_add_inst(sound_cards[sound_card_current[0]].device, 1); if ((sound_card_current[1] > SOUND_INTERNAL) && (sound_cards[sound_card_current[1]].device)) - device_add(sound_cards[sound_card_current[1]].device); + device_add_inst(sound_cards[sound_card_current[1]].device, 2); if ((sound_card_current[2] > SOUND_INTERNAL) && (sound_cards[sound_card_current[2]].device)) - device_add(sound_cards[sound_card_current[2]].device); + device_add_inst(sound_cards[sound_card_current[2]].device, 3); if ((sound_card_current[3] > SOUND_INTERNAL) && (sound_cards[sound_card_current[3]].device)) - device_add(sound_cards[sound_card_current[3]].device); + device_add_inst(sound_cards[sound_card_current[3]].device, 4); } void @@ -262,9 +275,7 @@ sound_cd_clean_buffers(void) static void sound_cd_thread(UNUSED(void *param)) { - uint32_t lba; - int r; - int pre; + int temp_buffer[2]; int channel_select[2]; double audio_vol_l; double audio_vol_r; @@ -281,47 +292,35 @@ sound_cd_thread(UNUSED(void *param)) sound_cd_clean_buffers(); + temp_buffer[0] = temp_buffer[1] = 0; + for (uint8_t i = 0; i < CDROM_NUM; i++) { if ((cdrom[i].bus_type == CDROM_BUS_DISABLED) || (cdrom[i].cd_status == CD_STATUS_EMPTY)) continue; - lba = cdrom[i].seek_pos; - r = cdrom_audio_callback(&(cdrom[i]), cd_buffer[i], CD_BUFLEN * 2); - if (!cdrom[i].bus_type || !cdrom[i].sound_on || !r) + const uint32_t lba = cdrom[i].seek_pos; + const int r = cdrom_audio_callback(&(cdrom[i]), cd_buffer[i], CD_BUFLEN * 2); + if (!cdrom[i].sound_on || !r) continue; - pre = cdrom_is_pre(&(cdrom[i]), lba); + const int pre = cdrom_is_pre(&(cdrom[i]), lba); + if (cdrom[i].get_volume) { - audio_vol_l = (float) (cdrom[i].get_volume(cdrom[i].priv, 0)); - audio_vol_r = (float) (cdrom[i].get_volume(cdrom[i].priv, 1)); + audio_vol_l = cd_audio_volume_lut[cdrom[i].get_volume(cdrom[i].priv, 0)]; + audio_vol_r = cd_audio_volume_lut[cdrom[i].get_volume(cdrom[i].priv, 1)]; } else { - audio_vol_l = 255.0; - audio_vol_r = 255.0; + audio_vol_l = cd_audio_volume_lut[255]; + audio_vol_r = cd_audio_volume_lut[255]; } - /* Calculate attenuation per the specification. */ - if (audio_vol_l >= 255.0) - audio_vol_l = 1.0; - else if (audio_vol_l > 0.0) - audio_vol_l = (48.0 + (20.0 * log(audio_vol_l / 256.0))) / 48.0; - else - audio_vol_l = 0.0; - - if (audio_vol_r >= 255.0) - audio_vol_r = 1.0; - else if (audio_vol_r > 0.0) - audio_vol_r = (48.0 + (20.0 * log(audio_vol_r / 256.0))) / 48.0; - else - audio_vol_r = 0.0; - if (cdrom[i].get_channel) { - channel_select[0] = cdrom[i].get_channel(cdrom[i].priv, 0); - channel_select[1] = cdrom[i].get_channel(cdrom[i].priv, 1); + channel_select[0] = (int) cdrom[i].get_channel(cdrom[i].priv, 0); + channel_select[1] = (int) cdrom[i].get_channel(cdrom[i].priv, 1); } else { channel_select[0] = 1; channel_select[1] = 2; } - for (uint16_t c = 0; c < CD_BUFLEN * 2; c += 2) { + for (int c = 0; c < CD_BUFLEN * 2; c += 2) { /*Apply ATAPI channel select*/ cd_buffer_temp[0] = cd_buffer_temp[1] = 0.0; @@ -359,17 +358,20 @@ sound_cd_thread(UNUSED(void *param)) cd_out_buffer[c] += (float) (cd_buffer_temp[0] / 32768.0); cd_out_buffer[c + 1] += (float) (cd_buffer_temp[1] / 32768.0); } else { - if (cd_buffer_temp[0] > 32767) - cd_buffer_temp[0] = 32767; - if (cd_buffer_temp[0] < -32768) - cd_buffer_temp[0] = -32768; - if (cd_buffer_temp[1] > 32767) - cd_buffer_temp[1] = 32767; - if (cd_buffer_temp[1] < -32768) - cd_buffer_temp[1] = -32768; + temp_buffer[0] += (int) trunc(cd_buffer_temp[0]); + temp_buffer[1] += (int) trunc(cd_buffer_temp[1]); - cd_out_buffer_int16[c] += (int16_t) cd_buffer_temp[0]; - cd_out_buffer_int16[c + 1] += (int16_t) cd_buffer_temp[1]; + if (temp_buffer[0] > 32767) + temp_buffer[0] = 32767; + if (temp_buffer[0] < -32768) + temp_buffer[0] = -32768; + if (temp_buffer[1] > 32767) + temp_buffer[1] = 32767; + if (temp_buffer[1] < -32768) + temp_buffer[1] = -32768; + + cd_out_buffer_int16[c] = (int16_t) temp_buffer[0]; + cd_out_buffer_int16[c + 1] = (int16_t) temp_buffer[1]; } } } @@ -425,6 +427,28 @@ music_realloc_buffers(void) } } +static void +wavetable_realloc_buffers(void) +{ + if (outbuffer_w_ex != NULL) { + free(outbuffer_w_ex); + outbuffer_w_ex = NULL; + } + + if (outbuffer_w_ex_int16 != NULL) { + free(outbuffer_w_ex_int16); + outbuffer_w_ex_int16 = NULL; + } + + if (sound_is_float) { + outbuffer_w_ex = calloc(WTBUFLEN * 2, sizeof(float)); + memset(outbuffer_w_ex, 0x00, WTBUFLEN * 2 * sizeof(float)); + } else { + outbuffer_w_ex_int16 = calloc(WTBUFLEN * 2, sizeof(int16_t)); + memset(outbuffer_w_ex_int16, 0x00, WTBUFLEN * 2 * sizeof(int16_t)); + } +} + void sound_init(void) { @@ -436,6 +460,9 @@ sound_init(void) outbuffer_m_ex = NULL; outbuffer_m_ex_int16 = NULL; + outbuffer_w_ex = NULL; + outbuffer_w_ex_int16 = NULL; + outbuffer = NULL; outbuffer = calloc(SOUNDBUFLEN * 2, sizeof(int32_t)); memset(outbuffer, 0x00, SOUNDBUFLEN * 2 * sizeof(int32_t)); @@ -444,6 +471,22 @@ sound_init(void) outbuffer_m = calloc(MUSICBUFLEN * 2, sizeof(int32_t)); memset(outbuffer_m, 0x00, MUSICBUFLEN * 2 * sizeof(int32_t)); + outbuffer_w = NULL; + outbuffer_w = calloc(WTBUFLEN * 2, sizeof(int32_t)); + memset(outbuffer_w, 0x00, WTBUFLEN * 2 * sizeof(int32_t)); + + for (uint16_t i = 0; i < 256; i++) { + double di = (double) i; + + if (di >= 255.0) + di = 1.0; + else if (di > 0.0) + di = (48.0 + (20.0 * log(di / 256.0))) / 48.0; + else + di = 0.0; + + cd_audio_volume_lut[i] = di; + } for (uint8_t i = 0; i < CDROM_NUM; i++) { if (cdrom[i].bus_type != CDROM_BUS_DISABLED) @@ -484,6 +527,14 @@ music_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *priv), void music_handlers_num++; } +void +wavetable_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *priv), void *priv) +{ + wavetable_handlers[wavetable_handlers_num].get_buffer = get_buffer; + wavetable_handlers[wavetable_handlers_num].priv = priv; + wavetable_handlers_num++; +} + void sound_set_cd_audio_filter(void (*filter)(int channel, double *buffer, void *priv), void *priv) { @@ -527,7 +578,7 @@ sound_poll(UNUSED(void *priv)) if (outbuffer[c] < -32768) outbuffer[c] = -32768; - outbuffer_ex_int16[c] = outbuffer[c]; + outbuffer_ex_int16[c] = (int16_t) outbuffer[c]; } } @@ -571,7 +622,7 @@ music_poll(UNUSED(void *priv)) if (outbuffer_m[c] < -32768) outbuffer_m[c] = -32768; - outbuffer_m_ex_int16[c] = outbuffer_m[c]; + outbuffer_m_ex_int16[c] = (int16_t) outbuffer_m[c]; } } @@ -584,12 +635,50 @@ music_poll(UNUSED(void *priv)) } } +void +wavetable_poll(UNUSED(void *priv)) +{ + timer_advance_u64(&wavetable_poll_timer, wavetable_poll_latch); + + wavetable_pos_global++; + if (wavetable_pos_global == WTBUFLEN) { + int c; + + memset(outbuffer_w, 0x00, WTBUFLEN * 2 * sizeof(int32_t)); + + for (c = 0; c < wavetable_handlers_num; c++) + wavetable_handlers[c].get_buffer(outbuffer_w, WTBUFLEN, wavetable_handlers[c].priv); + + for (c = 0; c < WTBUFLEN * 2; c++) { + if (sound_is_float) + outbuffer_w_ex[c] = ((float) outbuffer_w[c]) / (float) 32768.0; + else { + if (outbuffer_w[c] > 32767) + outbuffer_w[c] = 32767; + if (outbuffer_w[c] < -32768) + outbuffer_w[c] = -32768; + + outbuffer_w_ex_int16[c] = (int16_t) outbuffer_w[c]; + } + } + + if (sound_is_float) + givealbuffer_wt(outbuffer_w_ex); + else + givealbuffer_wt(outbuffer_w_ex_int16); + + wavetable_pos_global = 0; + } +} + void sound_speed_changed(void) { sound_poll_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) SOUND_FREQ)); music_poll_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) MUSIC_FREQ)); + + wavetable_poll_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) WT_FREQ)); } void @@ -599,6 +688,8 @@ sound_reset(void) music_realloc_buffers(); + wavetable_realloc_buffers(); + midi_out_device_init(); midi_in_device_init(); @@ -614,6 +705,11 @@ sound_reset(void) music_handlers_num = 0; memset(music_handlers, 0x00, 8 * sizeof(sound_handler_t)); + timer_add(&wavetable_poll_timer, wavetable_poll, NULL, 1); + + wavetable_handlers_num = 0; + memset(wavetable_handlers, 0x00, 8 * sizeof(sound_handler_t)); + filter_cd_audio = NULL; filter_cd_audio_p = NULL; diff --git a/src/sound/xaudio2.c b/src/sound/xaudio2.c index 78c3e2d35..9b341f574 100644 --- a/src/sound/xaudio2.c +++ b/src/sound/xaudio2.c @@ -52,6 +52,7 @@ static IXAudio2 *xaudio2 = NULL; static IXAudio2MasteringVoice *mastervoice = NULL; static IXAudio2SourceVoice *srcvoice = NULL; static IXAudio2SourceVoice *srcvoicemusic = NULL; +static IXAudio2SourceVoice *srcvoicewt = NULL; static IXAudio2SourceVoice *srcvoicemidi = NULL; static IXAudio2SourceVoice *srcvoicecd = NULL; @@ -169,27 +170,34 @@ inital(void) fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; - IXAudio2_CreateSourceVoice(xaudio2, &srcvoicemusic, &fmt, 0, 2.0f, &callbacks, NULL, NULL); + (void) IXAudio2_CreateSourceVoice(xaudio2, &srcvoicemusic, &fmt, 0, 2.0f, &callbacks, NULL, NULL); + + fmt.nSamplesPerSec = WT_FREQ; + fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; + fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; + + (void) IXAudio2_CreateSourceVoice(xaudio2, &srcvoicewt, &fmt, 0, 2.0f, &callbacks, NULL, NULL); fmt.nSamplesPerSec = CD_FREQ; fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; - IXAudio2_CreateSourceVoice(xaudio2, &srcvoicecd, &fmt, 0, 2.0f, &callbacks, NULL, NULL); + (void) IXAudio2_CreateSourceVoice(xaudio2, &srcvoicecd, &fmt, 0, 2.0f, &callbacks, NULL, NULL); - IXAudio2SourceVoice_SetVolume(srcvoice, 1, XAUDIO2_COMMIT_NOW); - IXAudio2SourceVoice_Start(srcvoice, 0, XAUDIO2_COMMIT_NOW); - IXAudio2SourceVoice_Start(srcvoicecd, 0, XAUDIO2_COMMIT_NOW); - IXAudio2SourceVoice_Start(srcvoicemusic, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2SourceVoice_SetVolume(srcvoice, 1, XAUDIO2_COMMIT_NOW); + (void) IXAudio2SourceVoice_Start(srcvoice, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2SourceVoice_Start(srcvoicecd, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2SourceVoice_Start(srcvoicemusic, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2SourceVoice_Start(srcvoicewt, 0, XAUDIO2_COMMIT_NOW); const char *mdn = midi_out_device_get_internal_name(midi_output_device_current); - if (strcmp(mdn, "none") && strcmp(mdn, SYSTEM_MIDI_INTERNAL_NAME)) { + if ((strcmp(mdn, "none") != 0) && (strcmp(mdn, SYSTEM_MIDI_INTERNAL_NAME) != 0)) { fmt.nSamplesPerSec = midi_freq; fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; - IXAudio2_CreateSourceVoice(xaudio2, &srcvoicemidi, &fmt, 0, 2.0f, &callbacks, NULL, NULL); - IXAudio2SourceVoice_Start(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2_CreateSourceVoice(xaudio2, &srcvoicemidi, &fmt, 0, 2.0f, &callbacks, NULL, NULL); + (void) IXAudio2SourceVoice_Start(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW); } initialized = 1; @@ -202,17 +210,20 @@ closeal(void) if (!initialized) return; initialized = 0; - IXAudio2SourceVoice_Stop(srcvoice, 0, XAUDIO2_COMMIT_NOW); - IXAudio2SourceVoice_FlushSourceBuffers(srcvoice); - IXAudio2SourceVoice_Stop(srcvoicemusic, 0, XAUDIO2_COMMIT_NOW); - IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemusic); - IXAudio2SourceVoice_Stop(srcvoicecd, 0, XAUDIO2_COMMIT_NOW); - IXAudio2SourceVoice_FlushSourceBuffers(srcvoicecd); + (void) IXAudio2SourceVoice_Stop(srcvoice, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2SourceVoice_FlushSourceBuffers(srcvoice); + (void) IXAudio2SourceVoice_Stop(srcvoicemusic, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemusic); + (void) IXAudio2SourceVoice_Stop(srcvoicewt, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2SourceVoice_FlushSourceBuffers(srcvoicewt); + (void) IXAudio2SourceVoice_Stop(srcvoicecd, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2SourceVoice_FlushSourceBuffers(srcvoicecd); if (srcvoicemidi) { - IXAudio2SourceVoice_Stop(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW); - IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemidi); + (void) IXAudio2SourceVoice_Stop(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemidi); IXAudio2SourceVoice_DestroyVoice(srcvoicemidi); } + IXAudio2SourceVoice_DestroyVoice(srcvoicewt); IXAudio2SourceVoice_DestroyVoice(srcvoicecd); IXAudio2SourceVoice_DestroyVoice(srcvoicemusic); IXAudio2SourceVoice_DestroyVoice(srcvoice); @@ -229,12 +240,13 @@ closeal(void) } void -givealbuffer_common(void *buf, IXAudio2SourceVoice *sourcevoice, size_t buflen) +givealbuffer_common(const void *buf, IXAudio2SourceVoice *sourcevoice, const size_t buflen) { if (!initialized) return; - IXAudio2MasteringVoice_SetVolume(mastervoice, pow(10.0, (double) sound_gain / 20.0), XAUDIO2_COMMIT_NOW); + (void) IXAudio2MasteringVoice_SetVolume(mastervoice, pow(10.0, (double) sound_gain / 20.0), + XAUDIO2_COMMIT_NOW); XAUDIO2_BUFFER buffer = { 0 }; buffer.Flags = 0; if (sound_is_float) { @@ -251,37 +263,43 @@ givealbuffer_common(void *buf, IXAudio2SourceVoice *sourcevoice, size_t buflen) buffer.PlayBegin = buffer.PlayLength = 0; buffer.PlayLength = buflen >> 1; buffer.pContext = (void *) buffer.pAudioData; - IXAudio2SourceVoice_SubmitSourceBuffer(sourcevoice, &buffer, NULL); + (void) IXAudio2SourceVoice_SubmitSourceBuffer(sourcevoice, &buffer, NULL); } void -givealbuffer(void *buf) +givealbuffer(const void *buf) { givealbuffer_common(buf, srcvoice, BUFLEN << 1); } void -givealbuffer_music(void *buf) +givealbuffer_music(const void *buf) { givealbuffer_common(buf, srcvoicemusic, MUSICBUFLEN << 1); } void -givealbuffer_cd(void *buf) +givealbuffer_wt(const void *buf) +{ + givealbuffer_common(buf, srcvoicewt, WTBUFLEN << 1); +} + +void +givealbuffer_cd(const void *buf) { if (srcvoicecd) givealbuffer_common(buf, srcvoicecd, CD_BUFLEN << 1); } void -al_set_midi(int freq, int buf_size) +al_set_midi(const int freq, const int buf_size) { midi_freq = freq; midi_buf_size = buf_size; if (initialized && srcvoicemidi) { - IXAudio2SourceVoice_Stop(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW); - IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemidi); + (void) IXAudio2SourceVoice_Stop(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemidi); IXAudio2SourceVoice_DestroyVoice(srcvoicemidi); srcvoicemidi = NULL; WAVEFORMATEX fmt; @@ -297,13 +315,13 @@ al_set_midi(int freq, int buf_size) fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; fmt.cbSize = 0; - IXAudio2_CreateSourceVoice(xaudio2, &srcvoicemidi, &fmt, 0, 2.0f, &callbacks, NULL, NULL); - IXAudio2SourceVoice_Start(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW); + (void) IXAudio2_CreateSourceVoice(xaudio2, &srcvoicemidi, &fmt, 0, 2.0f, &callbacks, NULL, NULL); + (void) IXAudio2SourceVoice_Start(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW); } } void -givealbuffer_midi(void *buf, uint32_t size) +givealbuffer_midi(const void *buf, const uint32_t size) { givealbuffer_common(buf, srcvoicemidi, size); } From e3c2c01f9124672d98b62e71ff67345147aefd98 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 18:47:54 +0200 Subject: [PATCH 891/936] Commented out a call to lpt_reset() in device.c. --- src/device.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/device.c b/src/device.c index 14380f6c5..5e3b394c2 100644 --- a/src/device.c +++ b/src/device.c @@ -348,9 +348,11 @@ device_reset_all(uint32_t match_flags) } } +#ifdef UNCOMMENT_LATER /* TODO: Actually convert the LPT devices to device_t's. */ if ((match_flags == DEVICE_ALL) || (match_flags == DEVICE_PCI)) lpt_reset(); +#endif } void * From ad8173df733a9016cc50c040b7b022e3549c5c00 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 18:50:47 +0200 Subject: [PATCH 892/936] Disambiguated the Pro Audio Spectrum 16D from 16. --- src/sound/snd_pas16.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 80d93dcbf..65046f0fe 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -2466,8 +2466,8 @@ const device_t pas16_device = { }; const device_t pas16d_device = { - .name = "Pro Audio Spectrum 16", - .internal_name = "pas16", + .name = "Pro Audio Spectrum 16D", + .internal_name = "pas16d", .flags = DEVICE_ISA | DEVICE_AT, .local = 0x0c, .init = pas16_init, From 895c1cad668a6e56656beeef2c11a8296e5605c2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 18:52:54 +0200 Subject: [PATCH 893/936] Actually add the Pro Audio Spectrum 16D to the sound cards table. --- src/include/86box/sound.h | 3 ++- src/sound/sound.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index 9ede638e5..9896b5422 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -189,9 +189,10 @@ extern const device_t ps1snd_device; /* Innovation SSI-2001 */ extern const device_t ssi2001_device; -/* Pro Audio Spectrum 16 */ +/* Pro Audio Spectrum Plus, 16, and 16D */ extern const device_t pasplus_device; extern const device_t pas16_device; +extern const device_t pas16d_device; /* Tandy PSSJ */ extern const device_t pssj_device; diff --git a/src/sound/sound.c b/src/sound/sound.c index 0611909d8..f527cbc61 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -157,6 +157,7 @@ static const SOUND_CARD sound_cards[] = { { &ssi2001_device }, { &pasplus_device }, { &pas16_device }, + { &pas16d_device }, { &pssj_isa_device }, { &tndy_device }, { &wss_device }, From 907daed3b116289a5125c2b5ad0678eb1e36bd58 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 19:01:33 +0200 Subject: [PATCH 894/936] Removed a commented out section from scsi/scsi.c. --- src/scsi/scsi.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index aecbcadec..23c3e65f3 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -171,11 +171,6 @@ scsi_card_init(void) { int max = SCSI_CARD_MAX; - /* On-board SCSI controllers get the first bus, so if one is present, - increase our instance number here. */ - // if (machine_has_flags(machine, MACHINE_SCSI)) - // max--; - /* Do not initialize any controllers if we have do not have any SCSI bus left. */ if (max > 0) { From 93ffbdee51c8441e801d90430fb7b4b200f6bf06 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 19:06:31 +0200 Subject: [PATCH 895/936] Reverted the LPT DAC and DSS changes. --- src/sound/snd_lpt_dac.c | 54 +++++++++++++++-------------------------- src/sound/snd_lpt_dss.c | 23 ++++++++---------- 2 files changed, 29 insertions(+), 48 deletions(-) diff --git a/src/sound/snd_lpt_dac.c b/src/sound/snd_lpt_dac.c index 8d7dbba4e..8fb526f14 100644 --- a/src/sound/snd_lpt_dac.c +++ b/src/sound/snd_lpt_dac.c @@ -5,14 +5,12 @@ #include #include "cpu.h" - -#include #include <86box/86box.h> #include <86box/filters.h> -#include <86box/timer.h> #include <86box/lpt.h> #include <86box/machine.h> #include <86box/sound.h> +#include <86box/timer.h> #include <86box/plat_unused.h> typedef struct lpt_dac_t { @@ -52,14 +50,6 @@ dac_write_data(uint8_t val, void *priv) dac_update(lpt_dac); } -static void -dac_strobe(uint8_t old, uint8_t val, void *priv) -{ - lpt_dac_t *lpt_dac = (lpt_dac_t *) priv; - - lpt_dac->channel = val; -} - static void dac_write_ctrl(uint8_t val, void *priv) { @@ -120,31 +110,25 @@ dac_close(void *priv) } const lpt_device_t lpt_dac_device = { - .name = "LPT DAC / Covox Speech Thing", - .internal_name = "lpt_dac", - .init = dac_init, - .close = dac_close, - .write_data = dac_write_data, - .write_ctrl = dac_write_ctrl, - .autofeed = NULL, - .strobe = dac_strobe, - .read_status = dac_read_status, - .read_ctrl = NULL, - .epp_write_data = NULL, - .epp_request_read = NULL + .name = "LPT DAC / Covox Speech Thing", + .internal_name = "lpt_dac", + .init = dac_init, + .close = dac_close, + .write_data = dac_write_data, + .write_ctrl = dac_write_ctrl, + .read_data = NULL, + .read_status = dac_read_status, + .read_ctrl = NULL }; const lpt_device_t lpt_dac_stereo_device = { - .name = "Stereo LPT DAC", - .internal_name = "lpt_dac_stereo", - .init = dac_stereo_init, - .close = dac_close, - .write_data = dac_write_data, - .write_ctrl = dac_write_ctrl, - .autofeed = NULL, - .strobe = dac_strobe, - .read_status = dac_read_status, - .read_ctrl = NULL, - .epp_write_data = NULL, - .epp_request_read = NULL + .name = "Stereo LPT DAC", + .internal_name = "lpt_dac_stereo", + .init = dac_stereo_init, + .close = dac_close, + .write_data = dac_write_data, + .write_ctrl = dac_write_ctrl, + .read_data = NULL, + .read_status = dac_read_status, + .read_ctrl = NULL }; diff --git a/src/sound/snd_lpt_dss.c b/src/sound/snd_lpt_dss.c index 5e5191e98..bd794fffb 100644 --- a/src/sound/snd_lpt_dss.c +++ b/src/sound/snd_lpt_dss.c @@ -7,10 +7,10 @@ #include "cpu.h" #include <86box/86box.h> #include <86box/filters.h> -#include <86box/timer.h> #include <86box/lpt.h> #include <86box/machine.h> #include <86box/sound.h> +#include <86box/timer.h> #include <86box/plat_unused.h> typedef struct dss_t { @@ -134,16 +134,13 @@ dss_close(void *priv) } const lpt_device_t dss_device = { - .name = "Disney Sound Source", - .internal_name = "dss", - .init = dss_init, - .close = dss_close, - .write_data = dss_write_data, - .autofeed = NULL, - .strobe = NULL, - .write_ctrl = dss_write_ctrl, - .read_status = dss_read_status, - .read_ctrl = NULL, - .epp_write_data = NULL, - .epp_request_read = NULL + .name = "Disney Sound Source", + .internal_name = "dss", + .init = dss_init, + .close = dss_close, + .write_data = dss_write_data, + .write_ctrl = dss_write_ctrl, + .read_data = NULL, + .read_status = dss_read_status, + .read_ctrl = NULL }; From eb968014d99d7cd9d923c8d2185807f3de05f354 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 19:41:45 +0200 Subject: [PATCH 896/936] OpenAL implementation of givealbuffer_wt(). --- src/sound/openal.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sound/openal.c b/src/sound/openal.c index f1ca74182..83bb312ba 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -304,6 +304,12 @@ givealbuffer_music(const void *buf) givealbuffer_common(buf, 1, MUSICBUFLEN << 1, MUSIC_FREQ); } +void +givealbuffer_wt(const void *buf) +{ + givealbuffer_common(buf, 1, WTBUFLEN << 1, WT_FREQ); +} + void givealbuffer_cd(const void *buf) { From 660a33fe965ffb4798cc35e26c2825b3fbff1440 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 19:42:58 +0200 Subject: [PATCH 897/936] OpenAL: Fix the buffers' numeric ID's. --- src/sound/openal.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sound/openal.c b/src/sound/openal.c index 83bb312ba..a41199b23 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -307,17 +307,17 @@ givealbuffer_music(const void *buf) void givealbuffer_wt(const void *buf) { - givealbuffer_common(buf, 1, WTBUFLEN << 1, WT_FREQ); + givealbuffer_common(buf, 2, WTBUFLEN << 1, WT_FREQ); } void givealbuffer_cd(const void *buf) { - givealbuffer_common(buf, 2, CD_BUFLEN << 1, CD_FREQ); + givealbuffer_common(buf, 3, CD_BUFLEN << 1, CD_FREQ); } void givealbuffer_midi(const void *buf, const uint32_t size) { - givealbuffer_common(buf, 3, (int) size, midi_freq); + givealbuffer_common(buf, 4, (int) size, midi_freq); } From 49824894e8588b97c18841b06e004e0ab117bc4c Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 May 2024 20:08:10 +0200 Subject: [PATCH 898/936] Pro Audio Spectrum: Correct the SCSI flag. --- src/sound/snd_pas16.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 65046f0fe..feaa31d61 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -2329,7 +2329,7 @@ pas16_init(const device_t *info) } pas16->type = info->local & 0xff; - pas16->has_scsi = (!pas16->type) || (pas16->type & 0x0f); + pas16->has_scsi = (!pas16->type) || (pas16->type == 0x0f); fm_driver_get(FM_YMF262, &pas16->opl); sb_dsp_set_real_opl(&pas16->dsp, 1); sb_dsp_init(&pas16->dsp, SB2, SB_SUBTYPE_DEFAULT, pas16); From 19949b9a769f2e87f1d95c071690dca7bfa35324 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 4 May 2024 03:31:14 +0500 Subject: [PATCH 899/936] snd_sb.c: Fix compilation error Variable declarations, unlike statements, aren't allowed after labels (including case labels) according to the C standard, so insert a semicolon to make an empty statement that satisfies the requirement. Oddly, MSYS2/MinGW-w64 GCC, unlike other compilers, including GCC on other systems, seemed to accept them without errors... --- src/sound/snd_sb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 9dc7724a4..80642adbe 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -1292,6 +1292,7 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) break; case 0x82: + ; /* Empty statement to make compilers happy about the following variable declaration. */ /* The Interrupt status register, addressed as register 82h on the Mixer register map, is used by the ISR to determine whether the interrupt is meant for it or for some other ISR, in which case it should chain to the previous routine. */ From 8d6ea95f1489136316deb439f88a4c2f2483b5c2 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 4 May 2024 04:19:30 +0500 Subject: [PATCH 900/936] workflows: Fix workflows not triggering when the workflow file is updated --- .github/workflows/cmake_linux.yml | 4 ++-- .github/workflows/cmake_macos.yml | 4 ++-- .github/workflows/cmake_windows_llvm.yml | 4 ++-- .github/workflows/cmake_windows_msys2.yml | 4 ++-- .github/workflows/codeql_linux.yml | 4 ++-- .github/workflows/codeql_macos.yml | 4 ++-- .github/workflows/codeql_windows_msys2.yml | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/cmake_linux.yml b/.github/workflows/cmake_linux.yml index 12cb21303..51e577cfd 100644 --- a/.github/workflows/cmake_linux.yml +++ b/.github/workflows/cmake_linux.yml @@ -8,7 +8,7 @@ on: - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" - - .github/workflows/cmake.yml + - .github/workflows/cmake_linux.yml - vcpkg.json - "!**/Makefile*" @@ -19,7 +19,7 @@ on: - "**/CMakeLists.txt" - "CMakePresets.json" - .github/workflows/** - - .github/workflows/cmake.yml + - .github/workflows/cmake_linux.yml - vcpkg.json - "!**/Makefile*" diff --git a/.github/workflows/cmake_macos.yml b/.github/workflows/cmake_macos.yml index e51c652a4..f5233299b 100644 --- a/.github/workflows/cmake_macos.yml +++ b/.github/workflows/cmake_macos.yml @@ -8,7 +8,7 @@ on: - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" - - .github/workflows/cmake.yml + - .github/workflows/cmake_macos.yml - vcpkg.json - "!**/Makefile*" @@ -19,7 +19,7 @@ on: - "**/CMakeLists.txt" - "CMakePresets.json" - .github/workflows/** - - .github/workflows/cmake.yml + - .github/workflows/cmake_macos.yml - vcpkg.json - "!**/Makefile*" diff --git a/.github/workflows/cmake_windows_llvm.yml b/.github/workflows/cmake_windows_llvm.yml index a49f9488a..cbddf33ea 100644 --- a/.github/workflows/cmake_windows_llvm.yml +++ b/.github/workflows/cmake_windows_llvm.yml @@ -8,7 +8,7 @@ on: - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" - - .github/workflows/cmake.yml + - .github/workflows/cmake_windows_llvm.yml - vcpkg.json - "!**/Makefile*" @@ -19,7 +19,7 @@ on: - "**/CMakeLists.txt" - "CMakePresets.json" - .github/workflows/** - - .github/workflows/cmake.yml + - .github/workflows/cmake_windows_llvm.yml - vcpkg.json - "!**/Makefile*" diff --git a/.github/workflows/cmake_windows_msys2.yml b/.github/workflows/cmake_windows_msys2.yml index 0ed29f0b7..21df9f00a 100644 --- a/.github/workflows/cmake_windows_msys2.yml +++ b/.github/workflows/cmake_windows_msys2.yml @@ -8,7 +8,7 @@ on: - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" - - .github/workflows/cmake.yml + - .github/workflows/cmake_windows_msys2.yml - vcpkg.json - "!**/Makefile*" @@ -19,7 +19,7 @@ on: - "**/CMakeLists.txt" - "CMakePresets.json" - .github/workflows/** - - .github/workflows/cmake.yml + - .github/workflows/cmake_windows_msys2.yml - vcpkg.json - "!**/Makefile*" diff --git a/.github/workflows/codeql_linux.yml b/.github/workflows/codeql_linux.yml index d92d11767..54f2c06e6 100644 --- a/.github/workflows/codeql_linux.yml +++ b/.github/workflows/codeql_linux.yml @@ -8,7 +8,7 @@ on: - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" - - .github/workflows/codeql.yml + - .github/workflows/codeql_linux.yml - vcpkg.json - "!**/Makefile*" @@ -19,7 +19,7 @@ on: - "**/CMakeLists.txt" - "CMakePresets.json" - .github/workflows/** - - .github/workflows/codeql.yml + - .github/workflows/codeql_linux.yml - vcpkg.json - "!**/Makefile*" diff --git a/.github/workflows/codeql_macos.yml b/.github/workflows/codeql_macos.yml index cef8c4828..65633d073 100644 --- a/.github/workflows/codeql_macos.yml +++ b/.github/workflows/codeql_macos.yml @@ -8,7 +8,7 @@ on: - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" - - .github/workflows/codeql.yml + - .github/workflows/codeql_macos.yml - vcpkg.json - "!**/Makefile*" @@ -19,7 +19,7 @@ on: - "**/CMakeLists.txt" - "CMakePresets.json" - .github/workflows/** - - .github/workflows/codeql.yml + - .github/workflows/codeql_macos.yml - vcpkg.json - "!**/Makefile*" diff --git a/.github/workflows/codeql_windows_msys2.yml b/.github/workflows/codeql_windows_msys2.yml index da368cd68..069d70fcc 100644 --- a/.github/workflows/codeql_windows_msys2.yml +++ b/.github/workflows/codeql_windows_msys2.yml @@ -8,7 +8,7 @@ on: - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" - - .github/workflows/codeql.yml + - .github/workflows/codeql_windows_msys2.yml - vcpkg.json - "!**/Makefile*" @@ -19,7 +19,7 @@ on: - "**/CMakeLists.txt" - "CMakePresets.json" - .github/workflows/** - - .github/workflows/codeql.yml + - .github/workflows/codeql_windows_msys2.yml - vcpkg.json - "!**/Makefile*" From 217fb9ac66461e2e292841e4ccd27336c87ecb6b Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 4 May 2024 04:08:54 +0500 Subject: [PATCH 901/936] workflows: Bump upload-artifact to v4 --- .github/workflows/cmake_linux.yml | 2 +- .github/workflows/cmake_macos.yml | 2 +- .github/workflows/cmake_windows_llvm.yml | 2 +- .github/workflows/cmake_windows_msys2.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cmake_linux.yml b/.github/workflows/cmake_linux.yml index 51e577cfd..04238ece0 100644 --- a/.github/workflows/cmake_linux.yml +++ b/.github/workflows/cmake_linux.yml @@ -115,7 +115,7 @@ jobs: cmake --install build - name: Upload artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-UbuntuJammy-x86_64-gha${{ github.run_number }}' path: build/artifacts/** diff --git a/.github/workflows/cmake_macos.yml b/.github/workflows/cmake_macos.yml index f5233299b..5a9f31a01 100644 --- a/.github/workflows/cmake_macos.yml +++ b/.github/workflows/cmake_macos.yml @@ -120,7 +120,7 @@ jobs: cmake --install build - name: Upload artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-macOS-x86_64-gha${{ github.run_number }}' path: build/artifacts/** diff --git a/.github/workflows/cmake_windows_llvm.yml b/.github/workflows/cmake_windows_llvm.yml index cbddf33ea..93f4db241 100644 --- a/.github/workflows/cmake_windows_llvm.yml +++ b/.github/workflows/cmake_windows_llvm.yml @@ -157,7 +157,7 @@ jobs: cmake --install build - name: Upload artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-LLVM-${{ matrix.target.name }}-gha${{ github.run_number }}' path: build/artifacts/** diff --git a/.github/workflows/cmake_windows_msys2.yml b/.github/workflows/cmake_windows_msys2.yml index 21df9f00a..d3f679a78 100644 --- a/.github/workflows/cmake_windows_msys2.yml +++ b/.github/workflows/cmake_windows_msys2.yml @@ -138,7 +138,7 @@ jobs: run: cmake --install build - name: Upload artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-${{ matrix.environment.msystem }}-gha${{ github.run_number }}' path: build/artifacts/** From c1158affa3551d9df206ed2ffc9853c154908e0e Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 4 May 2024 04:09:13 +0500 Subject: [PATCH 902/936] workflows: Bump CodeQL actions to v3 --- .github/workflows/codeql_linux.yml | 4 ++-- .github/workflows/codeql_macos.yml | 4 ++-- .github/workflows/codeql_windows_msys2.yml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/codeql_linux.yml b/.github/workflows/codeql_linux.yml index 54f2c06e6..73ccfb214 100644 --- a/.github/workflows/codeql_linux.yml +++ b/.github/workflows/codeql_linux.yml @@ -89,7 +89,7 @@ jobs: uses: actions/checkout@v4 - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} config-file: ./.github/codeql/codeql-config.yml @@ -106,6 +106,6 @@ jobs: run: cmake --build build - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/codeql_macos.yml b/.github/workflows/codeql_macos.yml index 65633d073..6d2c3861f 100644 --- a/.github/workflows/codeql_macos.yml +++ b/.github/workflows/codeql_macos.yml @@ -82,7 +82,7 @@ jobs: uses: actions/checkout@v4 - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} config-file: ./.github/codeql/codeql-config.yml @@ -102,6 +102,6 @@ jobs: run: cmake --build build - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/codeql_windows_msys2.yml b/.github/workflows/codeql_windows_msys2.yml index 069d70fcc..2b468f996 100644 --- a/.github/workflows/codeql_windows_msys2.yml +++ b/.github/workflows/codeql_windows_msys2.yml @@ -114,7 +114,7 @@ jobs: uses: actions/checkout@v4 - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} config-file: ./.github/codeql/codeql-config.yml @@ -133,6 +133,6 @@ jobs: - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}" From 2d0b7f81d36d664a7335205823300d2d7563638f Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 4 May 2024 11:40:07 +0200 Subject: [PATCH 903/936] Pro Audio Spectrum: assorted clean-ups. --- src/sound/snd_pas16.c | 43 +++++++++++-------------------------------- 1 file changed, 11 insertions(+), 32 deletions(-) diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index feaa31d61..859a1fd17 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -115,7 +115,6 @@ #include <86box/snd_opl.h> #include <86box/snd_sb.h> #include <86box/snd_sb_dsp.h> -#include <86box/snd_sb_dsp.h> typedef struct nsc_mixer_t { double master_l; @@ -549,7 +548,6 @@ static const double lmc1982_att_2dbstep_6bits[] = { in said cut in the below values. */ static const double lmc835_att_1dbstep_7bits[128] = { - 0.0, /* Flat */ [0x40] = 8230.0, /* Flat */ /* Boost */ @@ -586,10 +584,10 @@ static const double lmc835_att_1dbstep_7bits[128] = { /* The Win95 drivers use D5-D0 = 1D instead of 2D, datasheet erratum? */ [0x1d] = 7335.0, /* 1 dB Cut */ [0x2f] = 8230.0, /* Flat */ + 0.0 }; static const double lmc835_att_05dbstep_7bits[128] = { - 0.0 , /* Flat */ [0x40] = 8230.0, /* Flat */ /* Boost */ @@ -626,6 +624,7 @@ static const double lmc835_att_05dbstep_7bits[128] = { /* The Win95 drivers use D5-D0 = 1D instead of 2D, datasheet erratum? */ [0x1d] = 7770.0, /* 0.5 dB Cut */ [0x2f] = 8230.0, /* Flat */ + 0.0 }; static __inline double @@ -1826,7 +1825,7 @@ pas16_pit_timer0(const int new_out, UNUSED(int old_out), void *priv) } if (pas16->ticks) { - for (uint8_t i = 0; i < pas16->ticks; i++) + for (uint16_t i = 0; i < pas16->ticks; i++) pitf_ctr_clock(pas16->pit, 1); pas16->ticks = 0; @@ -1939,18 +1938,13 @@ pasplus_get_buffer(int32_t *buffer, int len, void *priv) { pas16_t * pas16 = (pas16_t *) priv; const nsc_mixer_t *mixer = &pas16->nsc_mixer; - double out_l = 0.0; - double out_r = 0.0; double bass_treble; sb_dsp_update(&pas16->dsp); pas16_update(pas16); for (int c = 0; c < len * 2; c += 2) { - out_l = 0.0; - out_r = 0.0; - - out_l += pas16->dsp.buffer[c]; - out_r += pas16->dsp.buffer[c + 1]; + double out_l = pas16->dsp.buffer[c]; + double out_r = pas16->dsp.buffer[c + 1]; if (pas16->filter) { /* We divide by 3 to get the volume down to normal. */ @@ -2004,16 +1998,11 @@ pasplus_get_music_buffer(int32_t *buffer, int len, void *priv) const pas16_t * pas16 = (const pas16_t *) priv; const nsc_mixer_t *mixer = &pas16->nsc_mixer; const int32_t * opl_buf = pas16->opl.update(pas16->opl.priv); - double out_l = 0.0; - double out_r = 0.0; double bass_treble; for (int c = 0; c < len * 2; c += 2) { - out_l = 0.0; - out_r = 0.0; - - out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; - out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; + double out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; + double out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; /* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */ out_l *= mixer->master_l; @@ -2127,18 +2116,13 @@ pas16_get_buffer(int32_t *buffer, int len, void *priv) { pas16_t * pas16 = (pas16_t *) priv; const mv508_mixer_t *mixer = &pas16->mv508_mixer; - double out_l = 0.0; - double out_r = 0.0; double bass_treble; sb_dsp_update(&pas16->dsp); pas16_update(pas16); for (int c = 0; c < len * 2; c += 2) { - out_l = 0.0; - out_r = 0.0; - - out_l += (pas16->dsp.buffer[c] * mixer->sb_l) / 3.0; - out_r += (pas16->dsp.buffer[c + 1] * mixer->sb_r) / 3.0; + double out_l = (pas16->dsp.buffer[c] * mixer->sb_l) / 3.0; + double out_r = (pas16->dsp.buffer[c + 1] * mixer->sb_r) / 3.0; if (pas16->filter) { /* We divide by 3 to get the volume down to normal. */ @@ -2192,16 +2176,11 @@ pas16_get_music_buffer(int32_t *buffer, int len, void *priv) const pas16_t * pas16 = (const pas16_t *) priv; const mv508_mixer_t *mixer = &pas16->mv508_mixer; const int32_t * opl_buf = pas16->opl.update(pas16->opl.priv); - double out_l = 0.0; - double out_r = 0.0; double bass_treble; for (int c = 0; c < len * 2; c += 2) { - out_l = 0.0; - out_r = 0.0; - - out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; - out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; + double out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; + double out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; /* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */ out_l *= mixer->master_l; From ccc788ff9870ec4faba286f1e6cd0fd20e56155a Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 4 May 2024 18:48:44 +0200 Subject: [PATCH 904/936] Timer: Make sure timer_on_auto() to use timer_advance_u64() instead of timer_set_delay_u64() if it's called inside a callback. --- src/include/86box/timer.h | 2 +- src/timer.c | 27 ++++++++++++++++++--------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/include/86box/timer.h b/src/include/86box/timer.h index 4ade8aab0..91f903a0f 100644 --- a/src/include/86box/timer.h +++ b/src/include/86box/timer.h @@ -43,7 +43,7 @@ typedef struct pc_timer_t { ts_t ts; #endif int flags; /* The flags are defined above. */ - int pad; + int in_callback; double period; /* This is used for large period timers to count the microseconds and split the period. */ diff --git a/src/timer.c b/src/timer.c index fa8376bde..d7102ffc3 100644 --- a/src/timer.c +++ b/src/timer.c @@ -94,6 +94,7 @@ timer_disable(pc_timer_t *timer) fatal("timer_disable - !timer->next\n"); timer->flags &= ~TIMER_ENABLED; + timer->in_callback = 0; if (timer->prev) timer->prev->next = timer->next; @@ -127,11 +128,15 @@ timer_process(void) if (timer->flags & TIMER_SPLIT) timer_advance_ex(timer, 0); /* We're splitting a > 1 s period into - multiple <= 1 s periods. */ - else if (timer->callback != NULL) /* Make sure it's not NULL, so that we can - have a NULL callback when no operation - is needed. */ + multiple <= 1 s periods. */ + else if (timer->callback != NULL) { + /* Make sure it's not NULL, so that we can + have a NULL callback when no operation + is needed. */ + timer->in_callback = 1; timer->callback(timer->priv); + timer->in_callback = 0; + } } timer_target = timer_head->ts.ts32.integer; @@ -171,10 +176,11 @@ timer_add(pc_timer_t *timer, void (*callback)(void *priv), void *priv, int start { memset(timer, 0, sizeof(pc_timer_t)); - timer->callback = callback; - timer->priv = priv; - timer->flags = 0; - timer->prev = timer->next = NULL; + timer->callback = callback; + timer->in_callback = 0; + timer->priv = priv; + timer->flags = 0; + timer->prev = timer->next = NULL; if (start_timer) timer_set_delay_u64(timer, 0); } @@ -189,6 +195,7 @@ timer_stop(pc_timer_t *timer) timer->period = 0.0; timer_disable(timer); timer->flags &= ~TIMER_SPLIT; + timer->in_callback = 0; } static void @@ -240,7 +247,9 @@ timer_on_auto(pc_timer_t *timer, double period) return; if (period > 0.0) - timer_on(timer, period, timer->period <= 0.0); + /* If the timer is in the callback, signal that, so that timer_advance_u64() + is used instead of timer_set_delay_u64(). */ + timer_on(timer, period, (timer->period <= 0.0) && !timer->in_callback); else timer_stop(timer); } From c4ce5209b41e2b278df140ed46bb0f873f75469d Mon Sep 17 00:00:00 2001 From: Barnacl437 Date: Sun, 5 May 2024 21:15:48 +0700 Subject: [PATCH 905/936] minor fixes/corrections for vi-VN translation --- src/qt/languages/vi-VN.po | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/qt/languages/vi-VN.po b/src/qt/languages/vi-VN.po index 9f5421ee9..ee6d77849 100644 --- a/src/qt/languages/vi-VN.po +++ b/src/qt/languages/vi-VN.po @@ -391,13 +391,13 @@ msgid "Video:" msgstr "Video:" msgid "Voodoo Graphics" -msgstr "Voodoo đồ họa" +msgstr "Đồ họa Voodoo" msgid "IBM 8514/A Graphics" -msgstr "IBM 8514/A đồ họa" +msgstr "Đồ họa IBM 8514/A" msgid "XGA Graphics" -msgstr "XGA đồ họa" +msgstr "Đồ họa XGA" msgid "Mouse:" msgstr "Chuột:" @@ -442,7 +442,7 @@ msgid "Use FLOAT32 sound" msgstr "Dùng âm FLOAT32" msgid "FM synth driver" -msgstr "Driver bộ tổng hợp (synth) FM" +msgstr "Driver bộ tổng hợp âm FM" msgid "Nuked (more accurate)" msgstr "Nuked (chính xác hơn)" @@ -508,10 +508,10 @@ msgid "Parallel port 4" msgstr "Cổng parallel 4" msgid "HD Controller:" -msgstr "Bộ điều khiển HD:" +msgstr "Bộ điều khiển ổ cứng:" msgid "FD Controller:" -msgstr "Bộ điều khiển FD:" +msgstr "Bộ điều khiển ổ mềm:" msgid "Tertiary IDE Controller" msgstr "Bộ điều khiển IDE thứ ba" @@ -841,7 +841,7 @@ msgid "86Box v" msgstr "86Box v" msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "Trình giả lập các dòng máy tính cổ.\n\nTác giả: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, y otros.\n\nCùng với những đóng góp cốt cán từ Sarah Walker, leilei, JohnElliott, greatpsycho, và một số người khác.\n\nPhát hành dưới giấy phép GNU General Public License version 2 trở đi. Đọc LICENSE để biết thêm thông tin." +msgstr "Trình giả lập các dòng máy tính cổ.\n\nTác giả: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, cùng những người khác.\n\nCùng với những đóng góp cốt cán từ Sarah Walker, leilei, JohnElliott, greatpsycho, và một số người khác.\n\nPhát hành dưới giấy phép GNU General Public License version 2 trở đi. Đọc LICENSE để biết thêm thông tin." msgid "Hardware not available" msgstr "Phần cứng không có sẵn" @@ -889,7 +889,7 @@ msgid "You are loading an unsupported configuration" msgstr "Bạn đang load tinh chỉnh không được hỗ trợ." msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." -msgstr "Phần chọn loại CPU dựa trên mẫu máy đã chọn bị vô hiệu hóa.\n\nỞ đây bạn có thể chọn loại CPU có thể không tương thích với mẫu máy hiện tại. Tuy nhiên bạn có thể gặp vấn đề tương khắc với BIOS hay phần mềm khác.\n\nViệc bật tùy chọn này lên không được khuyến cáo chính thức và các bản bug report (báo lỗi) với nội dung tương tự sẽ bị closed as invalid (đóng vì phạm quy)." +msgstr "Phần chọn loại CPU dựa trên mẫu máy đã chọn bị vô hiệu hóa.\n\nỞ đây bạn có thể chọn loại CPU có thể không tương thích với mẫu máy hiện tại. Tuy nhiên bạn có thể gặp vấn đề tương khắc với BIOS hay phần mềm khác.\n\nViệc bật tùy chọn này lên không được khuyến cáo chính thức và các bản bug report (báo lỗi) với nội dung tương tự sẽ bị coi là phạm quy và đóng." msgid "Continue" msgstr "Tiếp tục" @@ -916,7 +916,7 @@ msgid "Resume execution" msgstr "Tiếp tục chạy thực thi" msgid "Pause execution" -msgstr "Dừng chạy thực thi" +msgstr "Tạm dừng thực thi" msgid "Press Ctrl+Alt+Del" msgstr "Nhấn Ctrl+Alt+Del" From 4c84cccae7f570701c8d787b70d05263a66de410 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 6 May 2024 13:09:08 +0200 Subject: [PATCH 906/936] The Pro Audio Spectrum SCSI controller is now based on the Trantor T128 (which it is considerable closer to), rather than on the 53c400. --- src/disk/mo.c | 4 +- src/disk/zip.c | 4 +- src/include/86box/scsi_device.h | 1 + src/include/86box/scsi_ncr5380.h | 7 +- .../86box/{scsi_ncr53c400.h => scsi_t128.h} | 49 ++--- src/scsi/scsi_cdrom.c | 14 +- src/scsi/scsi_disk.c | 5 +- src/scsi/scsi_ncr5380.c | 64 +++---- src/scsi/scsi_ncr53c400.c | 177 +++++------------- src/scsi/scsi_t128.c | 51 +++-- src/sound/snd_pas16.c | 51 ++--- 11 files changed, 165 insertions(+), 262 deletions(-) rename src/include/86box/{scsi_ncr53c400.h => scsi_t128.h} (55%) diff --git a/src/disk/mo.c b/src/disk/mo.c index c93f4b055..e90267b95 100644 --- a/src/disk/mo.c +++ b/src/disk/mo.c @@ -1677,8 +1677,8 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) size_idx = 4; memset(dev->buffer, 0, 8); - if (cdb[1] & 0xe0) - dev->buffer[0] = 0x60; /*No physical device on this LUN*/ + if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff))) + dev->buffer[0] = 0x7f; /*No physical device on this LUN*/ else dev->buffer[0] = 0x07; /*Optical disk*/ dev->buffer[1] = 0x80; /*Removable*/ diff --git a/src/disk/zip.c b/src/disk/zip.c index 08d3baee3..d4cbd0b41 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -1865,8 +1865,8 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) size_idx = 4; memset(dev->buffer, 0, 8); - if (cdb[1] & 0xe0) - dev->buffer[0] = 0x60; /*No physical device on this LUN*/ + if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff))) + dev->buffer[0] = 0x7f; /*No physical device on this LUN*/ else dev->buffer[0] = 0x00; /*Hard disk*/ dev->buffer[1] = 0x80; /*Removable*/ diff --git a/src/include/86box/scsi_device.h b/src/include/86box/scsi_device.h index 216fdb2ad..2d6d60ac7 100644 --- a/src/include/86box/scsi_device.h +++ b/src/include/86box/scsi_device.h @@ -309,6 +309,7 @@ #define BUS_BSY 0x40 #define BUS_RST 0x80 #define BUS_ACK 0x200 +/* TODO: Why is this defined to the same value as BUS_ACK?! */ #define BUS_ATN 0x200 #define BUS_ARB 0x8000 #define BUS_SETDATA(val) ((uint32_t) val << 16) diff --git a/src/include/86box/scsi_ncr5380.h b/src/include/86box/scsi_ncr5380.h index 55c3bf3c5..8baa4f9d8 100644 --- a/src/include/86box/scsi_ncr5380.h +++ b/src/include/86box/scsi_ncr5380.h @@ -109,14 +109,10 @@ typedef struct ncr_t { int data_pos; int irq; - int simple_pseudo_dma; - - uint32_t block_count; double period; void *priv; - void (*dma_init_ext)(void *priv, void *ext_priv, int send); void (*dma_mode_ext)(void *priv, void *ext_priv); int (*dma_send_ext)(void *priv, void *ext_priv); int (*dma_initiator_receive_ext)(void *priv, void *ext_priv); @@ -131,11 +127,11 @@ extern uint32_t ncr5380_get_bus_host(ncr_t *ncr); extern void ncr5380_bus_read(ncr_t *ncr); extern void ncr5380_bus_update(ncr_t *ncr, int bus); extern void ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr); -extern uint8_t ncr5380_drq(ncr_t *ncr); extern uint8_t ncr5380_read(uint16_t port, ncr_t *ncr); #ifdef EMU_DEVICE_H extern const device_t scsi_lcs6821n_device; +extern const device_t scsi_pas_device; extern const device_t scsi_rt1000b_device; extern const device_t scsi_rt1000mc_device; extern const device_t scsi_t128_device; @@ -145,7 +141,6 @@ extern const device_t scsi_ls2000_device; #if defined(DEV_BRANCH) && defined(USE_SUMO) extern const device_t scsi_scsiat_device; #endif -extern const device_t scsi_pas_device; #endif #endif /*SCSI_NCR5380_H*/ diff --git a/src/include/86box/scsi_ncr53c400.h b/src/include/86box/scsi_t128.h similarity index 55% rename from src/include/86box/scsi_ncr53c400.h rename to src/include/86box/scsi_t128.h index 9a5315990..65148a5d1 100644 --- a/src/include/86box/scsi_ncr53c400.h +++ b/src/include/86box/scsi_t128.h @@ -18,45 +18,34 @@ * Copyright 2017-2024 TheCollector1995. */ -#ifndef SCSI_NCR53C400_H -#define SCSI_NCR53C400_H +#ifndef SCSI_T128_H +#define SCSI_T128_H -typedef struct ncr53c400_t { - rom_t bios_rom; - mem_mapping_t mapping; +typedef struct t128_t { ncr_t ncr; + rom_t bios_rom; + mem_mapping_t mapping; + + uint8_t ctrl; + uint8_t status; uint8_t buffer[512]; - uint8_t int_ram[0x40]; - uint8_t ext_ram[0x600]; + uint8_t ext_ram[0x80]; + uint8_t block_count; + + int block_loaded; + int pos, host_pos; uint32_t rom_addr; - uint16_t base; - int8_t type; - uint8_t block_count; - uint8_t status_ctrl; - - int simple_ctrl; - - int block_count_loaded; - - int buffer_pos; - int buffer_host_pos; - - int busy; + int bios_enabled; uint8_t pos_regs[8]; pc_timer_t timer; -} ncr53c400_t; +} t128_t; -#define CTRL_DATA_DIR 0x40 -#define STATUS_BUFFER_NOT_READY 0x04 -#define STATUS_5380_ACCESSIBLE 0x80 +extern void t128_write(uint32_t addr, uint8_t val, void *priv); +extern uint8_t t128_read(uint32_t addr, void *priv); -extern void ncr53c400_simple_write(uint8_t val, void *priv); -extern void ncr53c400_write(uint32_t addr, uint8_t val, void *priv); -extern uint8_t ncr53c400_simple_read(void *priv); -extern uint8_t ncr53c400_read(uint32_t addr, void *priv); -extern void ncr53c400_callback(void *priv); +extern void t128_callback(void *priv); -#endif /*SCSI_NCR53C400_H*/ +#endif /*SCSI_T128_H*/ diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 8a9f72946..47ba0535e 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -2794,6 +2794,15 @@ begin: return; } + if (max_len <= 0) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + scsi_cdrom_buf_free(dev); + return; + } + if (!(cdb[2] & 0x40)) alloc_length = 4; else @@ -3189,7 +3198,10 @@ begin: size_idx = 4; memset(dev->buffer, 0, 8); - dev->buffer[0] = 5; /*CD-ROM*/ + if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff))) + dev->buffer[0] = 0x7f; /*No physical device on this LUN*/ + else + dev->buffer[0] = 5; /*CD-ROM*/ dev->buffer[1] = 0x80; /*Removable*/ if (dev->drv->bus_type == CDROM_BUS_SCSI) { diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 39a69ea32..f29e85431 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -1328,7 +1328,10 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) size_idx = 4; memset(dev->temp_buffer, 0, 8); - dev->temp_buffer[0] = 0; /*SCSI HD*/ + if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff))) + dev->temp_buffer[0] = 0x7f; /*No physical device on this LUN*/ + else + dev->temp_buffer[0] = 0; /*SCSI HD*/ dev->temp_buffer[1] = 0; /*Fixed*/ dev->temp_buffer[2] = (dev->drv->bus == HDD_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ dev->temp_buffer[3] = (dev->drv->bus == HDD_BUS_SCSI) ? 0x02 : 0x21; diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index d256de764..fefb7b9a2 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -161,8 +161,28 @@ ncr5380_get_bus_host(ncr_t *ncr) if (ncr->icr & ICR_BSY) bus_host |= BUS_BSY; - if (ncr->icr & ICR_ATN) - bus_host |= BUS_ATN; + /* + TODO: See which method of fixing this is the most correct. + + The #define's come from PCem and, for some reason, define + BUS_ATN to the same value as BUS_ACK (0x200). This breaks + the Corel driver for the Pro Audio Spectrum Trantor SCSI + controller, as it first asserts ATN without ACK, then ACK + without ATN, which should by definition result in ACK going + ON and OFF but because of these ambiguous #define's, it + instead manifests as ACK stuck on, therefore never clearing + BUS_REQ and progressing to the next phase. + + Since I have no idea why BUS_ATN was #define's to the same + value as BUS_ACK, and the problem appears to only occur in + the Message Out phase, where ATN is not used, I have decided + to solve this by never asserting ATN in the Message Out phase + for time being. + */ + if (ncr->state != STATE_MESSAGEOUT) { + if (ncr->icr & ICR_ATN) + bus_host |= BUS_ATN; + } if (ncr->icr & ICR_ACK) bus_host |= BUS_ACK; @@ -326,19 +346,6 @@ ncr5380_bus_update(ncr_t *ncr, int bus) ncr5380_log("SCSI ID %i: command 0x%02x for p = %lf, update = %lf, len = %i, dmamode = %x\n", ncr->target_id, ncr->command[0], scsi_device_get_callback(dev), ncr->period, dev->buffer_length, ncr->dma_mode); } } - - if (ncr->simple_pseudo_dma) { - if (dev->phase == SCSI_PHASE_DATA_IN) { - ncr->block_count = dev->buffer_length / 512; - - ncr->dma_init_ext(ncr, ncr->priv, 1); - } else if (dev->phase == SCSI_PHASE_DATA_OUT) { - ncr->block_count = dev->buffer_length / 512; - - ncr->dma_init_ext(ncr, ncr->priv, 0); - } - } - ncr->new_phase = dev->phase; } } @@ -358,10 +365,7 @@ ncr5380_bus_update(ncr_t *ncr, int bus) if (ncr->dma_mode == DMA_IDLE) { /*If a data in command that is not read 6/10 has been issued*/ ncr->data_wait |= 1; ncr5380_log("DMA mode idle in\n"); - if (ncr->simple_pseudo_dma) - ncr->dma_init_ext(ncr, ncr->priv, 1); - else - ncr->timer(ncr->priv, ncr->period); + ncr->timer(ncr->priv, ncr->period); } else { ncr5380_log("DMA mode IN.\n"); ncr->clear_req = 3; @@ -388,10 +392,7 @@ ncr5380_bus_update(ncr_t *ncr, int bus) if (ncr->dma_mode == DMA_IDLE) { /*If a data out command that is not write 6/10 has been issued*/ ncr->data_wait |= 1; ncr5380_log("DMA mode idle out\n"); - if (!ncr->simple_pseudo_dma) - ncr->timer(ncr->priv, ncr->period); - if (ncr->simple_pseudo_dma) - ncr->dma_init_ext(ncr, ncr->priv, 0); + ncr->timer(ncr->priv, ncr->period); } else ncr->clear_req = 3; @@ -517,21 +518,6 @@ ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr) ncr5380_bus_update(ncr, bus_host); } -uint8_t -ncr5380_drq(ncr_t *ncr) -{ - uint8_t ret = 0; - int bus; - - ncr5380_bus_read(ncr); - bus = ncr->cur_bus; - - if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA)) - ret = 1; - - return ret; -} - uint8_t ncr5380_read(uint16_t port, ncr_t *ncr) { @@ -579,6 +565,8 @@ ncr5380_read(uint16_t port, ncr_t *ncr) ret |= BUS_SEL; if (ncr->icr & ICR_BSY) ret |= BUS_BSY; + // if ((ret & SCSI_PHASE_MESSAGE_IN) == SCSI_PHASE_MESSAGE_IN) + // ret &= ~BUS_REQ; break; case 5: /* Bus and Status register */ diff --git a/src/scsi/scsi_ncr53c400.c b/src/scsi/scsi_ncr53c400.c index f4bd9de59..1ed8e520e 100644 --- a/src/scsi/scsi_ncr53c400.c +++ b/src/scsi/scsi_ncr53c400.c @@ -41,7 +41,6 @@ #include <86box/scsi.h> #include <86box/scsi_device.h> #include <86box/scsi_ncr5380.h> -#include <86box/scsi_ncr53c400.h> #define LCS6821N_ROM "roms/scsi/ncr5380/Longshine LCS-6821N - BIOS version 1.04.bin" #define COREL_LS2000_ROM "roms/scsi/ncr5380/Corel LS2000 - BIOS ROM - Ver 1.65.bin" @@ -49,14 +48,43 @@ #define RT1000B_820R_ROM "roms/scsi/ncr5380/RTBIOS82.ROM" #define T130B_ROM "roms/scsi/ncr5380/trantor_t130b_bios_v2.14.bin" +#define CTRL_DATA_DIR 0x40 +#define STATUS_BUFFER_NOT_READY 0x04 +#define STATUS_5380_ACCESSIBLE 0x80 + enum { ROM_LCS6821N = 0, ROM_LS2000, ROM_RT1000B, - ROM_T130B, - ROM_PAS + ROM_T130B }; +typedef struct ncr53c400_t { + rom_t bios_rom; + mem_mapping_t mapping; + ncr_t ncr; + uint8_t buffer[128]; + uint8_t int_ram[0x40]; + uint8_t ext_ram[0x600]; + + uint32_t rom_addr; + uint16_t base; + + int8_t type; + uint8_t block_count; + uint8_t status_ctrl; + + int block_count_loaded; + + int buffer_pos; + int buffer_host_pos; + + int busy; + uint8_t pos_regs[8]; + + pc_timer_t timer; +} ncr53c400_t; + #ifdef ENABLE_NCR53C400_LOG int ncr53c400_do_log = ENABLE_NCR53C400_LOG; @@ -75,29 +103,8 @@ ncr53c400_log(const char *fmt, ...) # define ncr53c400_log(fmt, ...) #endif -void -ncr53c400_simple_write(uint8_t val, void *priv) -{ - ncr53c400_t *ncr400 = (ncr53c400_t *) priv; - ncr_t *ncr = &ncr400->ncr; - scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; - - if (ncr400->buffer_host_pos < MIN(512, dev->buffer_length)) { - ncr400->buffer[ncr400->buffer_host_pos++] = val; - - ncr53c400_log("Write host pos = %i, val = %02x\n", ncr400->buffer_host_pos, val); - - if (ncr400->buffer_host_pos == MIN(512, dev->buffer_length)) { - ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; - ncr400->busy = 1; - - ncr53c400_callback(priv); - } - } -} - /* Memory-mapped I/O WRITE handler. */ -void +static void ncr53c400_write(uint32_t addr, uint8_t val, void *priv) { ncr53c400_t *ncr400 = (ncr53c400_t *) priv; @@ -185,30 +192,8 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) } } -uint8_t -ncr53c400_simple_read(void *priv) -{ - ncr53c400_t *ncr400 = (ncr53c400_t *) priv; - ncr_t *ncr = &ncr400->ncr; - scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; - uint8_t ret = 0xff; - - if (ncr400->buffer_host_pos < MIN(512, dev->buffer_length)) { - ret = ncr400->buffer[ncr400->buffer_host_pos++]; - ncr53c400_log("Read host pos = %i, ret = %02x\n", ncr400->buffer_host_pos, ret); - - if (ncr400->buffer_host_pos == MIN(512, dev->buffer_length)) { - ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; - ncr53c400_log("Transfer busy read, status = %02x\n", ncr400->status_ctrl); - ncr53c400_callback(priv); - } - } - - return ret; -} - /* Memory-mapped I/O READ handler. */ -uint8_t +static uint8_t ncr53c400_read(uint32_t addr, void *priv) { ncr53c400_t *ncr400 = (ncr53c400_t *) priv; @@ -400,34 +385,6 @@ t130b_in(uint16_t port, void *priv) return ret; } -static void -ncr53c400_dma_init_ext(void *priv, void *ext_priv, int send) -{ - ncr53c400_t *ncr400 = (ncr53c400_t *) ext_priv; - ncr_t *ncr = (ncr_t *) priv; - scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; - uint8_t val = send ? CTRL_DATA_DIR : 0x00; - - ncr53c400_log("NCR 53c400 control = %02x, mode = %02x.\n", val, ncr->mode); - ncr400->status_ctrl = (ncr400->status_ctrl & 0x87) | (val & 0x78); - - ncr400->block_count_loaded = 1; - - if (ncr400->status_ctrl & CTRL_DATA_DIR) { - ncr400->buffer_host_pos = MIN(512, dev->buffer_length); - ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; - } else { - ncr400->buffer_host_pos = 0; - ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - } - if ((ncr->mode & MODE_DMA) && (dev->buffer_length > 0)) { - memset(ncr400->buffer, 0, MIN(512, dev->buffer_length)); - ncr53c400_log("DMA buffer init\n"); - ncr->timer(ncr->priv, ncr->period); - } - ncr53c400_log("NCR DMA init\n"); -} - static void ncr53c400_dma_mode_ext(void *priv, void *ext_priv) { @@ -455,21 +412,17 @@ ncr53c400_timer_on_auto(void *ext_priv, double period) timer_on_auto(&ncr400->timer, period); } -void +static void ncr53c400_callback(void *priv) { ncr53c400_t *ncr400 = (void *) priv; ncr_t *ncr = &ncr400->ncr; scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; int bus; - int blocks_left; uint8_t c; uint8_t temp; - const int buf_len = ncr400->simple_ctrl ? 512 : 128; - ncr53c400_log("DMA mode = %i\n", ncr->dma_mode); - - if (!ncr400->simple_ctrl && (ncr->dma_mode != DMA_IDLE)) + if (ncr->dma_mode != DMA_IDLE) timer_on_auto(&ncr400->timer, 1.0); if (ncr->data_wait & 1) { @@ -488,7 +441,7 @@ ncr53c400_callback(void *priv) switch (ncr->dma_mode) { case DMA_SEND: - if (!ncr400->simple_ctrl && (ncr400->status_ctrl & CTRL_DATA_DIR)) { + if (ncr400->status_ctrl & CTRL_DATA_DIR) { ncr53c400_log("DMA_SEND with DMA direction set wrong\n"); break; } @@ -522,20 +475,14 @@ ncr53c400_callback(void *priv) ncr400->buffer_pos++; ncr53c400_log("NCR 53c400 Buffer pos for writing = %d\n", ncr400->buffer_pos); - if (ncr400->buffer_pos == MIN(buf_len, dev->buffer_length)) { + if (ncr400->buffer_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; ncr400->buffer_pos = 0; ncr400->buffer_host_pos = 0; ncr400->busy = 0; - if (ncr400->simple_ctrl) { - ncr->block_count = (ncr->block_count - 1) & 0xffffffff; - blocks_left = ncr->block_count; - } else { - ncr400->block_count = (ncr400->block_count - 1) & 0xff; - blocks_left = ncr400->block_count; - } - ncr53c400_log("NCR 53c400 Remaining blocks to be written=%d\n", blocks_left); - if (blocks_left == 0) { + ncr400->block_count = (ncr400->block_count - 1) & 0xff; + ncr53c400_log("NCR 53c400 Remaining blocks to be written=%d\n", ncr400->block_count); + if (!ncr400->block_count) { ncr400->block_count_loaded = 0; ncr53c400_log("IO End of write transfer\n"); ncr->tcr |= TCR_LAST_BYTE_SENT; @@ -552,7 +499,7 @@ ncr53c400_callback(void *priv) break; case DMA_INITIATOR_RECEIVE: - if (!ncr400->simple_ctrl && !(ncr400->status_ctrl & CTRL_DATA_DIR)) { + if (!(ncr400->status_ctrl & CTRL_DATA_DIR)) { ncr53c400_log("DMA_INITIATOR_RECEIVE with DMA direction set wrong\n"); break; } @@ -568,10 +515,8 @@ ncr53c400_callback(void *priv) while (1) { for (c = 0; c < 10; c++) { ncr5380_bus_read(ncr); - if (ncr->cur_bus & BUS_REQ) { - ncr53c400_log("ncr->cur_bus & BUS_REQ\n"); + if (ncr->cur_bus & BUS_REQ) break; - } } /* Data ready. */ @@ -586,19 +531,13 @@ ncr53c400_callback(void *priv) ncr400->buffer[ncr400->buffer_pos++] = temp; ncr53c400_log("NCR 53c400 Buffer pos for reading = %d\n", ncr400->buffer_pos); - if (ncr400->buffer_pos == MIN(buf_len, dev->buffer_length)) { + if (ncr400->buffer_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; ncr400->buffer_pos = 0; ncr400->buffer_host_pos = 0; - if (ncr400->simple_ctrl) { - ncr->block_count = (ncr->block_count - 1) & 0xffffffff; - blocks_left = ncr->block_count; - } else { - ncr400->block_count = (ncr400->block_count - 1) & 0xff; - blocks_left = ncr400->block_count; - } - ncr53c400_log("NCR 53c400 Remaining blocks to be read=%d\n", blocks_left); - if (blocks_left == 0) { + ncr400->block_count = (ncr400->block_count - 1) & 0xff; + ncr53c400_log("NCR 53c400 Remaining blocks to be read=%d\n", ncr400->block_count); + if (!ncr400->block_count) { ncr400->block_count_loaded = 0; ncr53c400_log("IO End of read transfer\n"); ncr->isr |= STATUS_END_OF_DMA; @@ -623,8 +562,6 @@ ncr53c400_callback(void *priv) ncr53c400_log("Updating DMA\n"); ncr->mode &= ~MODE_DMA; ncr->dma_mode = DMA_IDLE; - if (ncr400->simple_ctrl) - ncr400->block_count_loaded = 0; } } @@ -719,6 +656,7 @@ ncr53c400_init(const device_t *info) ncr400->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr400); break; + case ROM_LS2000: /* Corel LS2000 */ ncr400->rom_addr = device_get_config_hex20("bios_addr"); ncr->irq = device_get_config_int("irq"); @@ -777,13 +715,6 @@ ncr53c400_init(const device_t *info) t130b_in, NULL, NULL, t130b_out, NULL, NULL, ncr400); break; - case ROM_PAS: /* Pro Audio Spectrum Plus/16 SCSI controller */ - ncr400->simple_ctrl = 1; - ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; - ncr->simple_pseudo_dma = 1; - ncr->dma_init_ext = ncr53c400_dma_init_ext; - break; - default: break; } @@ -1076,17 +1007,3 @@ const device_t scsi_ls2000_device = { .force_redraw = NULL, .config = ncr53c400_mmio_config }; - -const device_t scsi_pas_device = { - .name = "Pro Audio Spectrum Plus/16 SCSI", - .internal_name = "scsi_pas", - .flags = DEVICE_ISA, - .local = ROM_PAS, - .init = ncr53c400_init, - .close = ncr53c400_close, - .reset = NULL, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; diff --git a/src/scsi/scsi_t128.c b/src/scsi/scsi_t128.c index b13511eac..7e42a089d 100644 --- a/src/scsi/scsi_t128.c +++ b/src/scsi/scsi_t128.c @@ -41,31 +41,10 @@ #include <86box/scsi.h> #include <86box/scsi_device.h> #include <86box/scsi_ncr5380.h> +#include <86box/scsi_t128.h> #define T128_ROM "roms/scsi/ncr5380/trantor_t128_bios_v1.12.bin" -typedef struct t128_t { - ncr_t ncr; - rom_t bios_rom; - mem_mapping_t mapping; - - uint8_t ctrl; - uint8_t status; - uint8_t buffer[512]; - uint8_t ext_ram[0x80]; - uint8_t block_count; - - int block_loaded; - int pos, host_pos; - - uint32_t rom_addr; - - int bios_enabled; - uint8_t pos_regs[8]; - - pc_timer_t timer; -} t128_t; - #ifdef ENABLE_T128_LOG int t128_do_log = ENABLE_T128_LOG; @@ -85,7 +64,7 @@ t128_log(const char *fmt, ...) #endif /* Memory-mapped I/O WRITE handler. */ -static void +void t128_write(uint32_t addr, uint8_t val, void *priv) { t128_t *t128 = (t128_t *) priv; @@ -122,7 +101,7 @@ t128_write(uint32_t addr, uint8_t val, void *priv) } /* Memory-mapped I/O READ handler. */ -static uint8_t +uint8_t t128_read(uint32_t addr, void *priv) { t128_t *t128 = (t128_t *) priv; @@ -243,7 +222,7 @@ t128_timer_on_auto(void *ext_priv, double period) timer_on_auto(&t128->timer, period); } -static void +void t128_callback(void *priv) { t128_t *t128 = (void *) priv; @@ -506,7 +485,7 @@ t128_init(const device_t *info) t128->pos_regs[0] = 0x8c; t128->pos_regs[1] = 0x50; mca_add(t228_read, t228_write, t228_feedb, NULL, t128); - } else { + } else if (info->local == 0) { ncr->irq = device_get_config_int("irq"); t128->rom_addr = device_get_config_hex20("bios_addr"); t128->bios_enabled = device_get_config_int("boot"); @@ -525,12 +504,13 @@ t128_init(const device_t *info) ncr->dma_send_ext = t128_dma_send_ext; ncr->dma_initiator_receive_ext = t128_dma_initiator_receive_ext; ncr->timer = t128_timer_on_auto; - t128->status = 0x04; + t128->status = 0x00 /*0x04*/; t128->host_pos = 512; if (!t128->bios_enabled && !(info->flags & DEVICE_MCA)) t128->status |= 0x80; - timer_add(&t128->timer, t128_callback, t128, 0); + if (info->local == 0) + timer_add(&t128->timer, t128_callback, t128, 0); scsi_bus_set_speed(ncr->bus, 5000000.0); @@ -616,6 +596,7 @@ const device_t scsi_t128_device = { .config = t128_config }; + const device_t scsi_t228_device = { .name = "Trantor T228", .internal_name = "t228", @@ -629,3 +610,17 @@ const device_t scsi_t228_device = { .force_redraw = NULL, .config = NULL }; + +const device_t scsi_pas_device = { + .name = "Pro Audio Spectrum Plus/16 SCSI", + .internal_name = "scsi_pas", + .flags = DEVICE_ISA, + .local = 1, + .init = t128_init, + .close = t128_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 859a1fd17..243332257 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -108,8 +108,9 @@ #include <86box/pit.h> #include <86box/pit_fast.h> #include <86box/rom.h> +#include <86box/scsi_device.h> #include <86box/scsi_ncr5380.h> -#include <86box/scsi_ncr53c400.h> +#include <86box/scsi_t128.h> #include <86box/snd_mpu401.h> #include <86box/sound.h> #include <86box/snd_opl.h> @@ -247,7 +248,7 @@ typedef struct pas16_t { pitf_t * pit; - ncr53c400_t *scsi; + t128_t * scsi; pc_timer_t scsi_timer; } pas16_t; @@ -705,7 +706,6 @@ pas16_in(uint16_t port, void *priv) { pas16_t *pas16 = (pas16_t *) priv; uint8_t ret = 0xff; - ncr53c400_t *dev = (ncr53c400_t *) pas16->scsi; port -= pas16->base; @@ -763,10 +763,8 @@ pas16_in(uint16_t port, void *priv) case 0x1c00 ... 0x1c03: /* NCR5380 ports 0 to 3. */ case 0x3c00 ... 0x3c03: /* NCR5380 ports 4 to 7. */ - if (pas16->has_scsi) { - port = (port & 0x0003) | ((port & 0x2000) >> 11); - ret = ncr5380_read(port, &pas16->scsi->ncr); - } + if (pas16->has_scsi) + ret = ncr5380_read((port & 0x0003) | ((port & 0x2000) >> 11), &pas16->scsi->ncr); break; case 0x2401: /* Board revision */ @@ -782,20 +780,12 @@ pas16_in(uint16_t port, void *priv) case 0x5c00: if (pas16->has_scsi) - ret = ncr53c400_simple_read(pas16->scsi); + ret = t128_read(0x1e00, pas16->scsi); break; case 0x5c01: - if (pas16->has_scsi) { - ret = ((dev->ncr.dma_mode != DMA_IDLE) && !(dev->status_ctrl & STATUS_BUFFER_NOT_READY)) << 7; - if (!(ret & 0x80)) { - ncr53c400_callback(pas16->scsi); - if ((dev->ncr.dma_mode != DMA_IDLE) && !(dev->status_ctrl & STATUS_BUFFER_NOT_READY)) { - timer_stop(&pas16->scsi_timer); - pas16->timeout_status &= 0x7f; - } - - } - } + if (pas16->has_scsi) + /* Bits 0-6 must absolutely be set for SCSI hard disk drivers to work. */ + ret = (((pas16->scsi->ncr.dma_mode != DMA_IDLE) && (pas16->scsi->status & 0x04)) << 7) | 0x7f; break; case 0x5c03: if (pas16->has_scsi) @@ -1187,6 +1177,20 @@ lmc835_update_reg(nsc_mixer_t *mixer) lmc835_recalc(mixer); } +static void +pas16_scsi_callback(void *priv) +{ + pas16_t * pas16 = (pas16_t *) priv; + t128_t * dev = pas16->scsi; + + t128_callback(pas16->scsi); + + if ((dev->ncr.dma_mode != DMA_IDLE) && (dev->status & 0x04)) { + timer_stop(&pas16->scsi_timer); + pas16->timeout_status &= 0x7f; + } +} + static void pas16_timeout_callback(void *priv) { @@ -1491,10 +1495,8 @@ pas16_out(uint16_t port, uint8_t val, void *priv) case 0x1c00 ... 0x1c03: /* NCR5380 ports 0 to 3. */ case 0x3c00 ... 0x3c03: /* NCR5380 ports 4 to 7. */ - if (pas16->has_scsi) { - port = (port & 0x0003) | ((port & 0x2000) >> 11); - ncr5380_write(port, val, &pas16->scsi->ncr); - } + if (pas16->has_scsi) + ncr5380_write((port & 0x0003) | ((port & 0x2000) >> 11), val, &pas16->scsi->ncr); break; case 0x4000: @@ -1516,7 +1518,7 @@ pas16_out(uint16_t port, uint8_t val, void *priv) case 0x5c00: if (pas16->has_scsi) - ncr53c400_simple_write(val, pas16->scsi); + t128_write(0x1e00, val, pas16->scsi); break; case 0x5c03: if (pas16->has_scsi) { @@ -2324,6 +2326,7 @@ pas16_init(const device_t *info) if (pas16->has_scsi) { pas16->scsi = device_add(&scsi_pas_device); + timer_add(&pas16->scsi->timer, pas16_scsi_callback, pas16, 0); timer_add(&pas16->scsi_timer, pas16_timeout_callback, pas16, 0); other_scsi_present++; } From 71c16a4481fc3657c4f36468688b511de684dd07 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 6 May 2024 13:24:04 +0200 Subject: [PATCH 907/936] Remove the previous kludge and #define BUS_ACK to 0x100 so it's different from BUS_ATN. --- src/include/86box/scsi_device.h | 3 +-- src/scsi/scsi_ncr5380.c | 24 ++---------------------- 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/src/include/86box/scsi_device.h b/src/include/86box/scsi_device.h index 2d6d60ac7..64d3bc853 100644 --- a/src/include/86box/scsi_device.h +++ b/src/include/86box/scsi_device.h @@ -308,8 +308,7 @@ #define BUS_REQ 0x20 #define BUS_BSY 0x40 #define BUS_RST 0x80 -#define BUS_ACK 0x200 -/* TODO: Why is this defined to the same value as BUS_ACK?! */ +#define BUS_ACK 0x100 #define BUS_ATN 0x200 #define BUS_ARB 0x8000 #define BUS_SETDATA(val) ((uint32_t) val << 16) diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index fefb7b9a2..527ff373f 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -161,28 +161,8 @@ ncr5380_get_bus_host(ncr_t *ncr) if (ncr->icr & ICR_BSY) bus_host |= BUS_BSY; - /* - TODO: See which method of fixing this is the most correct. - - The #define's come from PCem and, for some reason, define - BUS_ATN to the same value as BUS_ACK (0x200). This breaks - the Corel driver for the Pro Audio Spectrum Trantor SCSI - controller, as it first asserts ATN without ACK, then ACK - without ATN, which should by definition result in ACK going - ON and OFF but because of these ambiguous #define's, it - instead manifests as ACK stuck on, therefore never clearing - BUS_REQ and progressing to the next phase. - - Since I have no idea why BUS_ATN was #define's to the same - value as BUS_ACK, and the problem appears to only occur in - the Message Out phase, where ATN is not used, I have decided - to solve this by never asserting ATN in the Message Out phase - for time being. - */ - if (ncr->state != STATE_MESSAGEOUT) { - if (ncr->icr & ICR_ATN) - bus_host |= BUS_ATN; - } + if (ncr->icr & ICR_ATN) + bus_host |= BUS_ATN; if (ncr->icr & ICR_ACK) bus_host |= BUS_ACK; From 509305f2f1efdccaff5b837571e7010913ac01dd Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 7 May 2024 20:09:30 +0200 Subject: [PATCH 908/936] Make the SMC FDC37c935 Super I/O chip on the HP Brio 80xx and Packard Bell PB810 correctly use port 370h instead of the standard 3F0h, fixes #4427. --- src/include/86box/sio.h | 1 + src/machine/m_at_socket7.c | 4 ++-- src/sio/sio_fdc37c93x.c | 30 +++++++++++++++++++++++------- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index c7098cfdb..d5fc88fb4 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -43,6 +43,7 @@ extern const device_t fdc37c931apm_compaq_device; extern const device_t fdc37c932fr_device; extern const device_t fdc37c932qf_device; extern const device_t fdc37c935_device; +extern const device_t fdc37c935_370_device; extern const device_t fdc37c935_no_nvr_device; extern const device_t fdc37m60x_device; extern const device_t fdc37m60x_370_device; diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 7bbf49edf..9e2ed9a26 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -657,7 +657,7 @@ machine_at_brio80xx_init(const machine_t *model) pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&fdc37c935_device); + device_add(&fdc37c935_370_device); device_add(&sst_flash_29ee020_device); return ret; @@ -726,7 +726,7 @@ machine_at_pb810_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); - device_add(&fdc37c935_device); + device_add(&fdc37c935_370_device); device_add(&intel_flash_bxt_device); return ret; diff --git a/src/sio/sio_fdc37c93x.c b/src/sio/sio_fdc37c93x.c index 7d8e12795..97fcb3fbd 100644 --- a/src/sio/sio_fdc37c93x.c +++ b/src/sio/sio_fdc37c93x.c @@ -54,6 +54,7 @@ typedef struct fdc37c93x_t { uint8_t is_apm; uint8_t has_nvr; uint8_t tries; + uint8_t port_370; uint8_t gpio_regs[2]; uint8_t auxio_reg; uint8_t regs[48]; @@ -785,7 +786,7 @@ fdc37c93x_reset(fdc37c93x_t *dev) dev->regs[0x21] = 0x01; dev->regs[0x22] = 0x39; dev->regs[0x24] = 0x04; - dev->regs[0x26] = 0xF0; + dev->regs[0x26] = dev->port_370 ? 0x70 : 0xF0; dev->regs[0x27] = 0x03; for (uint8_t i = 0; i < 11; i++) @@ -940,13 +941,14 @@ fdc37c93x_init(const device_t *info) dev->fdc = device_add(&fdc_at_smc_device); - dev->uart[0] = device_add_inst(&ns16550_device, 1); - dev->uart[1] = device_add_inst(&ns16550_device, 2); + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); - dev->chip_id = info->local & 0xff; - dev->is_apm = (info->local >> 8) & 0x01; - is_compaq = (info->local >> 8) & 0x02; - dev->has_nvr = !((info->local >> 8) & 0x04); + dev->chip_id = info->local & 0xff; + dev->is_apm = (info->local >> 8) & 0x01; + is_compaq = (info->local >> 8) & 0x02; + dev->has_nvr = !((info->local >> 8) & 0x04); + dev->port_370 = ((info->local >> 8) & 0x08); dev->gpio_regs[0] = 0xff; #if 0 @@ -1053,6 +1055,20 @@ const device_t fdc37c935_device = { .config = NULL }; +const device_t fdc37c935_370_device = { + .name = "SMC FDC37C935 Super I/O (Port 370h)", + .internal_name = "fdc37c935_370", + .flags = 0, + .local = 0x802, + .init = fdc37c93x_init, + .close = fdc37c93x_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t fdc37c935_no_nvr_device = { .name = "SMC FDC37C935 Super I/O", .internal_name = "fdc37c935", From c89e92fafd3204899956b2180c590272d6fe8546 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 8 May 2024 00:34:51 +0200 Subject: [PATCH 909/936] Fixed the BCM SQ-588 with a kludged, fixes #4431. --- src/chipset/sis_85c50x.c | 2 ++ src/device/kbc_at.c | 43 +++++++++++++++++++----------------- src/include/86box/keyboard.h | 2 ++ 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/chipset/sis_85c50x.c b/src/chipset/sis_85c50x.c index 8ec0498ff..137ddb5cf 100644 --- a/src/chipset/sis_85c50x.c +++ b/src/chipset/sis_85c50x.c @@ -39,6 +39,7 @@ #include <86box/spd.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> +#include <86box/keyboard.h> #include <86box/chipset.h> #ifdef ENABLE_SIS_85C50X_LOG @@ -257,6 +258,7 @@ sis_85c50x_write(int func, int addr, uint8_t val, void *priv) break; case 0x5b: dev->pci_conf[addr] = val; + kbc_at_set_fast_reset(!!(val & 0x40)); break; case 0x60: /* SMI */ if ((dev->pci_conf[0x68] & 0x01) && !(dev->pci_conf[addr] & 0x02) && (val & 0x02)) { diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index d8b308d6b..f596211cf 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -202,6 +202,14 @@ static const uint8_t nont_to_t[256] = { 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; +static uint8_t fast_reset = 0x00; + +void +kbc_at_set_fast_reset(const uint8_t new_fast_reset) +{ + fast_reset = new_fast_reset; +} + #ifdef ENABLE_KBC_AT_LOG int kbc_at_do_log = ENABLE_KBC_AT_LOG; @@ -748,7 +756,10 @@ write_p2(atkbc_t *dev, uint8_t val) /* AT, PS/2: Handle reset. */ /* 0 holds the CPU in the RESET state, 1 releases it. To simplify this, we just do everything on release. */ - if (!cpu_cpurst_on_sr && ((old ^ val) & 0x01)) { /*Reset*/ + /* TODO: The fast reset flag's condition should be reversed - the BCM SQ-588 + enables the flag and the CPURST on soft reset flag but expects this + to still soft reset instead. */ + if ((fast_reset || !cpu_cpurst_on_sr) && ((old ^ val) & 0x01)) { /*Reset*/ if (!(val & 0x01)) { /* Pin 0 selected. */ /* Pin 0 selected. */ kbc_at_log("write_p2(): Pulse reset!\n"); @@ -765,11 +776,12 @@ write_p2(atkbc_t *dev, uint8_t val) flushmmucache(); if (kbc_ven == KBC_VEN_ALI) smbase = 0x00030000; + /* Yes, this is a hack, but until someone gets ahold of the real PCD-2L and can find out what they actually did to make it boot from FFFFF0 correctly despite A20 being gated when the CPU is reset, this will have to do. */ - else if (kbc_ven == KBC_VEN_SIEMENS) + if (kbc_ven == KBC_VEN_SIEMENS) is486 ? loadcs(0xf000) : loadcs_2386(0xf000); } } @@ -778,10 +790,10 @@ write_p2(atkbc_t *dev, uint8_t val) /* Do this here to avoid an infinite reset loop. */ dev->p2 = val; - if (cpu_cpurst_on_sr && ((old ^ val) & 0x01)) { /*Reset*/ + if (!fast_reset && cpu_cpurst_on_sr && ((old ^ val) & 0x01)) { /*Reset*/ if (!(val & 0x01)) { /* Pin 0 selected. */ /* Pin 0 selected. */ - pclog("write_p2(): Pulse reset!\n"); + kbc_at_log("write_p2(): Pulse reset!\n"); dma_reset(); dma_set_at(1); @@ -1833,24 +1845,8 @@ kbc_at_write(uint16_t port, uint8_t val, void *priv) if (fast_a20 && dev->wantdata && (dev->command == 0xd1)) { kbc_at_log("ATkbc: write P2\n"); -#if 0 - /* Fast A20 - ignore all other bits. */ - val = (val & 0x02) | (dev->p2 & 0xfd); - - /* Bit 2 of AMI flags is P22-P23 blocked (1 = yes, 0 = no), - discovered by reverse-engineering the AOpeN Vi15G BIOS. */ - if (dev->ami_flags & 0x04) { - /* If keyboard controller lines P22-P23 are blocked, - we force them to remain unchanged. */ - val &= ~0x0c; - val |= (dev->p2 & 0x0c); - } - - write_p2_fast_a20(dev, val | 0x01); -#else /* Fast A20 - ignore all other bits. */ write_p2_fast_a20(dev, (dev->p2 & 0xfd) | (val & 0x02)); -#endif dev->wantdata = 0; dev->state = STATE_MAIN_IBF; @@ -1866,6 +1862,11 @@ kbc_at_write(uint16_t port, uint8_t val, void *priv) dev->state = STATE_KBC_PARAM; dev->command = 0xd1; return; + } else if (fast_reset && ((val & 0xf0) == 0xf0)) { + pulse_output(dev, val & 0x0f); + + dev->state = STATE_MAIN_IBF; + return; } break; @@ -2113,6 +2114,8 @@ kbc_at_init(const device_t *info) /* The actual keyboard. */ device_add(&keyboard_at_generic_device); + fast_reset = 0x00; + return dev; } diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 0d8b2e745..94146d692 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -276,7 +276,9 @@ extern int keyboard_isfsexit_up(void); extern int keyboard_ismsexit(void); extern void keyboard_set_is_amstrad(int ams); +extern void kbc_at_set_fast_reset(uint8_t new_fast_reset); extern void kbc_at_handler(int set, void *priv); + extern uint8_t kbc_at_dev_queue_pos(atkbc_dev_t *dev, uint8_t main); extern void kbc_at_dev_queue_add(atkbc_dev_t *dev, uint8_t val, uint8_t main); extern void kbc_at_dev_reset(atkbc_dev_t *dev, int do_fa); From 2912e7d746ab2aacad60f255f304becc5fe84078 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 8 May 2024 03:23:00 +0200 Subject: [PATCH 910/936] E-MU 8000: Remove some useless clipping - the audio already gets clipped before being passed to the output buffer, so this is no longer necessary. --- src/sound/snd_emu8k.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/sound/snd_emu8k.c b/src/sound/snd_emu8k.c index cc01ff6dd..5f13d2f8e 100644 --- a/src/sound/snd_emu8k.c +++ b/src/sound/snd_emu8k.c @@ -2124,21 +2124,6 @@ emu8k_update(emu8k_t *emu8k) emu8k_work_chorus(&emu8k->chorus_in_buffer[emu8k->pos], buf, &emu8k->chorus_engine, wavetable_pos_global - emu8k->pos); emu8k_work_eq(buf, wavetable_pos_global - emu8k->pos); - // Clip signal - for (pos = emu8k->pos; pos < wavetable_pos_global; pos++) { - if (buf[0] < -32768) - buf[0] = -32768; - else if (buf[0] > 32767) - buf[0] = 32767; - - if (buf[1] < -32768) - buf[1] = -32768; - else if (buf[1] > 32767) - buf[1] = 32767; - - buf += 2; - } - /* Update EMU clock. */ emu8k->wc += (wavetable_pos_global - emu8k->pos); From 404def23e8fa7db9b1702a4d2740613753af8c01 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 8 May 2024 03:35:51 +0200 Subject: [PATCH 911/936] Voodoo 3 1000 and Velocity 200: Hardcoded to 16 MB because our BIOS'es are 16 MB-only BIOS'es with the RAM amount check gutted out, closes #4406. --- src/video/vid_voodoo_banshee.c | 63 ++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index bbd14a4a0..5b6dbb434 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -3103,6 +3103,61 @@ static const device_config_t banshee_sgram_config[] = { } }; +static const device_config_t banshee_sgram_16mbonly_config[] = { + { + .name = "bilinear", + .description = "Bilinear filtering", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + .name = "dithersub", + .description = "Dither subtraction", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + .name = "dacfilter", + .description = "Screen Filter", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .name = "render_threads", + .description = "Render threads", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "1", + .value = 1 + }, + { + .description = "2", + .value = 2 + }, + { + .description = "4", + .value = 4 + }, + { + .description = "" + } + }, + .default_int = 2 + }, +#ifndef NO_CODEGEN + { + .name = "recompiler", + .description = "Recompiler", + .type = CONFIG_BINARY, + .default_int = 1 + }, +#endif + { + .type = CONFIG_END + } +}; + static const device_config_t banshee_sdram_config[] = { { .name = "bilinear", @@ -3181,7 +3236,9 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int #endif mem_size = device_get_config_int("memory"); /* MS-6168 / Bora Pro can do both 8 and 16 MB. */ else if (has_sgram) { - if (banshee->type == TYPE_VELOCITY100) + if ((banshee->type == TYPE_V3_1000) || (banshee->type == TYPE_VELOCITY200)) + mem_size = 16; /* Our Voodoo 3 1000 and Velocity 200 bios'es are hardcoded to 16 MB. */ + else if (banshee->type == TYPE_VELOCITY100) mem_size = 8; /* Velocity 100 only supports 8 MB */ else mem_size = device_get_config_int("memory"); @@ -3600,7 +3657,7 @@ const device_t voodoo_3_1000_agp_device = { { .available = v3_1000_agp_available }, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, - .config = banshee_sgram_config + .config = banshee_sgram_16mbonly_config }; const device_t voodoo_3_2000_device = { @@ -3768,5 +3825,5 @@ const device_t velocity_200_agp_device = { { .available = velocity_200_available }, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, - .config = banshee_sgram_config + .config = banshee_sgram_16mbonly_config }; From dd77ae1b779b4b80d51ebc1dfb3f4e5dadbe4dce Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Wed, 8 May 2024 13:55:21 -0400 Subject: [PATCH 912/936] qt: Clean up warning in DeviceConfig --- src/qt/qt_deviceconfig.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_deviceconfig.cpp b/src/qt/qt_deviceconfig.cpp index def3a4385..b031e6544 100644 --- a/src/qt/qt_deviceconfig.cpp +++ b/src/qt/qt_deviceconfig.cpp @@ -134,7 +134,7 @@ DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) const int config_major_type = (config_type >> CONFIG_SHIFT) << CONFIG_SHIFT; int value = 0; - auto selected = static_cast(blank.toStdString().c_str()); + auto selected = blank; switch (config_major_type) { default: @@ -246,7 +246,7 @@ DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) p += !!rom_present(const_cast(bios->files[d])); if (p == bios->files_no) { const int row = Models::AddEntry(model, bios->name, q); - if (!strcmp(selected, bios->internal_name)) + if (!strcmp(selected.toUtf8().constData(), bios->internal_name)) currentIndex = row; } q++; From b159cd5b12ed7106c8de7479320a280a136ddff7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 8 May 2024 23:42:20 +0200 Subject: [PATCH 913/936] Implemented the Phoenix keyboard controller with a Packard Bell specific workaround, fixes #4415. --- src/device/kbc_at.c | 235 ++++++++++++++++++++++++++++++++++- src/include/86box/keyboard.h | 1 + src/machine/m_at_386dx_486.c | 6 +- 3 files changed, 237 insertions(+), 5 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index f596211cf..85c0ff04a 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -133,9 +133,9 @@ typedef struct atkbc_t { uint8_t stat_hi; uint8_t pending; uint8_t irq_state; + uint8_t suppress_cmd_intr; uint8_t pad; uint8_t pad0; - uint8_t pad1; uint8_t mem[0x100]; @@ -202,6 +202,11 @@ static const uint8_t nont_to_t[256] = { 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; +static const uint8_t multikey_vars[0x0b] = { + 0x0a, + 0x03, 0x1e, 0x27, 0x28, 0x29, 0x38, 0x39, 0x18, 0x19, 0x35 +}; + static uint8_t fast_reset = 0x00; void @@ -367,7 +372,7 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) picint_common(1 << 12, 0, 1, NULL); picint_common(1 << 1, 0, 0, NULL); } else { - if (dev->mem[0x20] & 0x01) + if ((!dev->suppress_cmd_intr || (dev->channel == 1)) && (dev->mem[0x20] & 0x01)) picint_common(1 << 1, 0, 1, NULL); picint_common(1 << 12, 0, 0, NULL); } @@ -1348,6 +1353,206 @@ write64_ami(void *priv, uint8_t val) return write64_generic(dev, val); } +static uint8_t +write60_phoenix(void *priv, uint8_t val) +{ + atkbc_t *dev = (atkbc_t *) priv; + + switch (dev->command) { + /* TODO: Make this actually load the password. */ + case 0xa3: /* Load Extended Password */ + kbc_at_log("ATkbc: Phoenix - Load Extended Password\n"); + if (val == 0x00) + dev->command_phase = 0; + else { + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + } + return 0; + + case 0xaf: /* Set Inactivity Timer */ + kbc_at_log("ATkbc: Phoenix - Set Inactivity Timer\n"); + dev->mem[0x3a] = val; + dev->command_phase = 0; + return 0; + + case 0xb8: /* Set Extended Memory Access Index */ + kbc_at_log("ATkbc: Phoenix - Set Extended Memory Access Index\n"); + dev->mem_addr = val; + dev->command_phase = 0; + return 0; + + case 0xbb: /* Set Extended Memory */ + kbc_at_log("ATkbc: Phoenix - Set Extended Memory\n"); + dev->mem[dev->mem_addr] = val; + dev->command_phase = 0; + return 0; + + case 0xbd: /* Set MultiKey Variable */ + kbc_at_log("ATkbc: Phoenix - Set MultiKey Variable\n"); + if ((dev->mem_addr > 0) && (dev->mem_addr <= multikey_vars[0x00])) + dev->mem[multikey_vars[dev->mem_addr]] = val; + else if (dev->mem_addr == 0x29) + dev->suppress_cmd_intr = !val; + dev->command_phase = 0; + return 0; + + case 0xc7: /* Set Port1 bits */ + kbc_at_log("ATkbc: Phoenix - Set Port1 bits\n"); + dev->p1 |= val; + dev->command_phase = 0; + return 0; + + case 0xc8: /* Clear Port1 bits */ + kbc_at_log("ATkbc: Phoenix - Clear Port1 bits\n"); + dev->p1 &= ~val; + dev->command_phase = 0; + return 0; + + case 0xc9: /* Set Port2 bits */ + kbc_at_log("ATkbc: Phoenix - Set Port2 bits\n"); + write_p2(dev, dev->p2 | val); + dev->command_phase = 0; + return 0; + + case 0xca: /* Clear Port2 bits */ + kbc_at_log("ATkbc: Phoenix - Clear Port2 bits\n"); + write_p2(dev, dev->p2 & ~val); + dev->command_phase = 0; + return 0; + + default: + break; + } + + return 1; +} + +static uint8_t +write64_phoenix(void *priv, uint8_t val) +{ + atkbc_t *dev = (atkbc_t *) priv; + + switch (val) { + case 0x00 ... 0x1f: + kbc_at_log("ATkbc: Phoenix - alias read from %08X\n", val); + kbc_delay_to_ob(dev, dev->mem[val + 0x20], 0, 0x00); + return 0; + + case 0x40 ... 0x5f: + kbc_at_log("ATkbc: Phoenix - alias write to %08X\n", dev->command); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xa2: /* Test Extended Password */ + kbc_at_log("ATkbc: Phoenix - Test Extended Password\n"); + kbc_at_queue_add(dev, 0xf1); /* Extended Password not loaded */ + return 0; + + /* TODO: Make this actually load the password. */ + case 0xa3: /* Load Extended Password */ + kbc_at_log("ATkbc: Phoenix - Load Extended Password\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xaf: /* Set Inactivity Timer */ + kbc_at_log("ATkbc: Phoenix - Set Inactivity Timer\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xb8: /* Set Extended Memory Access Index */ + kbc_at_log("ATkbc: Phoenix - Set Extended Memory Access Index\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xb9: /* Get Extended Memory Access Index */ + kbc_at_log("ATkbc: Phoenix - Get Extended Memory Access Index\n"); + kbc_at_queue_add(dev, dev->mem_addr); + return 0; + + case 0xba: /* Get Extended Memory */ + kbc_at_log("ATkbc: Phoenix - Get Extended Memory\n"); + kbc_at_queue_add(dev, dev->mem[dev->mem_addr]); + return 0; + + case 0xbb: /* Set Extended Memory */ + kbc_at_log("ATkbc: Phoenix - Set Extended Memory\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xbc: /* Get MultiKey Variable */ + kbc_at_log("ATkbc: Phoenix - Get MultiKey Variable\n"); + if (dev->mem_addr == 0) + kbc_at_queue_add(dev, multikey_vars[dev->mem_addr]); + else if (dev->mem_addr <= multikey_vars[dev->mem_addr]) + kbc_at_queue_add(dev, dev->mem[multikey_vars[dev->mem_addr]]); + else + kbc_at_queue_add(dev, 0xff); + return 0; + + case 0xbd: /* Set MultiKey Variable */ + kbc_at_log("ATkbc: Phoenix - Set MultiKey Variable\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xc7: /* Set Port1 bits */ + kbc_at_log("ATkbc: Phoenix - Set Port1 bits\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xc8: /* Clear Port1 bits */ + kbc_at_log("ATkbc: Phoenix - Clear Port1 bits\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xc9: /* Set Port2 bits */ + kbc_at_log("ATkbc: Phoenix - Set Port2 bits\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xca: /* Clear Port2 bits */ + kbc_at_log("ATkbc: Phoenix - Clear Port2 bits\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + /* TODO: Handle these three commands properly - configurable + revision level and proper CPU bits. */ + case 0xd5: /* Read MultiKey code revision level */ + kbc_at_log("ATkbc: Phoenix - Read MultiKey code revision level\n"); + kbc_at_queue_add(dev, 0x04); + kbc_at_queue_add(dev, 0x16); + return 0; + + case 0xd6: /* Read Version Information */ + kbc_at_log("ATkbc: Phoenix - Read Version Information\n"); + kbc_at_queue_add(dev, 0x81); + kbc_at_queue_add(dev, 0xac); + return 0; + + case 0xd7: /* Read MultiKey model numbers */ + kbc_at_log("ATkbc: Phoenix - Read MultiKey model numbers\n"); + kbc_at_queue_add(dev, 0x02); + kbc_at_queue_add(dev, 0x87); + kbc_at_queue_add(dev, 0x02); + return 0; + + default: + break; + } + + return write64_generic(dev, val); +} + static uint8_t write64_siemens(void *priv, uint8_t val) { @@ -1895,6 +2100,11 @@ kbc_at_read(uint16_t port, void *priv) This also means that in AT mode, the IRQ is level-triggered. */ if (!(dev->misc_flags & FLAG_PS2)) picintclevel(1 << 1, &dev->irq_state); + /* I"m not even sure if this is correct but the PB450 absolutely requires this. */ + if (dev->suppress_cmd_intr) { + picint_common(1 << 1, 0, 1, NULL); + dev->suppress_cmd_intr = 0; + } if ((strstr(machine_get_internal_name(), "pb") != NULL) && (cpu_override_dynarec == 1)) cpu_override_dynarec = 0; break; @@ -1937,6 +2147,8 @@ kbc_at_reset(void *priv) kbc_at_queue_reset(dev); + dev->suppress_cmd_intr = 0; + dev->sc_or = 0; dev->ami_flags = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) ? 0x01 : 0x00; @@ -2086,6 +2298,11 @@ kbc_at_init(const device_t *info) dev->write64_ven = write64_ami; break; + case KBC_VEN_PHOENIX: + dev->write60_ven = write60_phoenix; + dev->write64_ven = write64_phoenix; + break; + case KBC_VEN_QUADTEL: dev->write60_ven = write60_quadtel; dev->write64_ven = write64_quadtel; @@ -2301,6 +2518,20 @@ const device_t keyboard_ps2_ami_device = { .config = NULL }; +const device_t keyboard_ps2_phoenix_device = { + .name = "PS/2 Keyboard (Phoenix)", + .internal_name = "keyboard_ps2_phoenix", + .flags = DEVICE_KBC, + .local = KBC_TYPE_PS2_1 | KBC_VEN_PHOENIX, + .init = kbc_at_init, + .close = kbc_at_close, + .reset = kbc_at_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t keyboard_ps2_tg_ami_device = { .name = "PS/2 Keyboard (TriGem AMI)", .internal_name = "keyboard_ps2_tg_ami", diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 94146d692..79665c9a9 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -245,6 +245,7 @@ extern const device_t keyboard_ps2_ami_device; extern const device_t keyboard_ps2_tg_ami_device; extern const device_t keyboard_ps2_tg_ami_green_device; extern const device_t keyboard_ps2_olivetti_device; +extern const device_t keyboard_ps2_phoenix_device; extern const device_t keyboard_ps2_mca_2_device; extern const device_t keyboard_ps2_quadtel_device; extern const device_t keyboard_ps2_pci_device; diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index d4cd5fe16..d494a7302 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -704,11 +704,11 @@ machine_at_pb450_init(const machine_t *model) if (gfxcard[0] == VID_INTERNAL) device_add(&gd5428_vlb_onboard_device); - device_add(&opti602_device); device_add(&opti895_device); + device_add(&opti602_device); device_add(&opti822_device); - device_add(&keyboard_ps2_ami_device); - device_add(&fdc37c661_ide_device); + device_add(&keyboard_ps2_phoenix_device); + device_add(&fdc37c665_ide_device); device_add(&ide_opti611_vlb_sec_device); device_add(&intel_flash_bxt_device); device_add(&phoenix_486_jumper_pci_device); From 4fe7ee9675d2c6936597442ed8c0a0576cee4336 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 8 May 2024 23:44:43 +0200 Subject: [PATCH 914/936] Added a PC Partner MB500N specific workaround to the i4x0 cache control register write. --- src/chipset/intel_4x0.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index 8abbe50c1..26a973be0 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -518,7 +518,10 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430FX: case INTEL_430VX: case INTEL_430TX: - regs[0x52] = (regs[0x52] & 0xf0) | (val & 0x0b); + if (!strcmp(machine_get_internal_name(), "mb500n")) + regs[0x52] = val; + else + regs[0x52] = (regs[0x52] & 0xf4) | (val & 0x0b); cpu_cache_ext_enabled = ((val & 0x03) == 0x01); cpu_update_waitstates(); break; From b0542322bfd7bc84fe8572f7536fe48a96e70b57 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 9 May 2024 00:47:45 +0200 Subject: [PATCH 915/936] Fixed DRB DIMM splitting (AMI Apollo now boots with 8 MB RAM), and extended the MB500N workaround to MR BIOS'es as well. --- src/chipset/intel_4x0.c | 2 +- src/mem/spd.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index 26a973be0..9a2635b12 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -518,7 +518,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430FX: case INTEL_430VX: case INTEL_430TX: - if (!strcmp(machine_get_internal_name(), "mb500n")) + if (!strcmp(machine_get_internal_name(), "mb500n") || (strstr(machine_get_internal_name(), "mr") != NULL)) regs[0x52] = val; else regs[0x52] = (regs[0x52] & 0xf4) | (val & 0x0b); diff --git a/src/mem/spd.c b/src/mem/spd.c index a3bcba46d..a0896a05a 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -136,7 +136,7 @@ spd_populate(uint16_t *rows, uint8_t slot_count, uint16_t total_size, uint16_t m /* Look for a module to split. */ split = 0; for (row = 0; row < slot_count; row++) { - if ((rows[row] < (min_module_size << 1)) || (rows[row] != (1 << log2i(rows[row])))) + if ((rows[row] <= (min_module_size << 1)) || (rows[row] != (1 << log2i(rows[row])))) continue; /* no module here, module is too small to be split, or asymmetric module */ /* Find next empty row. */ From 179c4fc279634c29c59cc78d749be37938e22ee0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 9 May 2024 01:28:54 +0200 Subject: [PATCH 916/936] SiS 471: Register 69h is read/write, not read/write clear, fixes hangs in SMM on the DEC Venturis 4xx. --- src/chipset/sis_85c4xx.c | 4 +--- src/machine/m_at_386dx_486.c | 6 +++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/chipset/sis_85c4xx.c b/src/chipset/sis_85c4xx.c index cf4ff42d7..f80ecf99e 100644 --- a/src/chipset/sis_85c4xx.c +++ b/src/chipset/sis_85c4xx.c @@ -174,9 +174,7 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv) case 0x23: if ((dev->cur_reg >= dev->reg_base) && (dev->cur_reg <= dev->reg_last)) { valxor = val ^ dev->regs[rel_reg]; - if (rel_reg == 0x19) - dev->regs[rel_reg] &= ~val; - else if (rel_reg == 0x00) + if (rel_reg == 0x00) dev->regs[rel_reg] = (dev->regs[rel_reg] & 0x1f) | (val & 0xe0); else dev->regs[rel_reg] = val; diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index d494a7302..1a6a6db67 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -702,7 +702,7 @@ machine_at_pb450_init(const machine_t *model) pci_register_slot(0x12, PCI_CARD_NORMAL, 5, 6, 7, 8); if (gfxcard[0] == VID_INTERNAL) - device_add(&gd5428_vlb_onboard_device); + device_add(machine_get_vid_device(machine)); device_add(&opti895_device); device_add(&opti602_device); @@ -2223,10 +2223,10 @@ machine_at_dvent4xx_init(const machine_t *model) device_add(&sis_85c471_device); device_add(&ide_cmd640_vlb_pri_device); device_add(&fdc37c665_ide_device); - device_add(&keyboard_ps2_device); + device_add(&keyboard_ps2_phoenix_device); if (gfxcard[0] == VID_INTERNAL) - device_add(&s3_phoenix_trio32_onboard_vlb_device); + device_add(machine_get_vid_device(machine)); return ret; } From 3995d1d786de2889d3d61b1a8dadc88b1841a137 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 9 May 2024 01:29:18 +0200 Subject: [PATCH 917/936] Some Machine table entry fixes. --- src/machine/machine_table.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 3aafe237c..2f1d690e7 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -6522,10 +6522,10 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = &gd5428_vlb_onboard_device, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &gd5428_vlb_onboard_device, .snd_device = NULL, .net_device = NULL }, @@ -6804,10 +6804,10 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = &s3_phoenix_trio32_onboard_vlb_device, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &s3_phoenix_trio32_onboard_vlb_device, .snd_device = NULL, .net_device = NULL }, From a4fe16c9a02e1cd70f978827d64d97f39ce59fc3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 9 May 2024 01:41:24 +0200 Subject: [PATCH 918/936] AT KBC: Do not attempt to remove the I/O handlers if they had not been set first, fixes crash when attempting to use the Compaq Presario 4500. --- src/device/kbc_at.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 85c0ff04a..7a720f948 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -164,6 +164,8 @@ kbc_at_port_t *kbc_at_ports[2] = { NULL, NULL }; static uint8_t kbc_ami_revision = '8'; static uint8_t kbc_award_revision = 0x42; +static uint8_t kbc_handler_set = 0; + static void (*kbc_at_do_poll)(atkbc_t *dev); /* Non-translated to translated scan codes. */ @@ -2202,10 +2204,14 @@ kbc_at_close(void *priv) void kbc_at_handler(int set, void *priv) { - io_removehandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); - io_removehandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); + if (kbc_handler_set) { + io_removehandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); + io_removehandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); + } - if (set) { + kbc_handler_set = set; + + if (kbc_handler_set) { io_sethandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); io_sethandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); } @@ -2228,6 +2234,7 @@ kbc_at_init(const device_t *info) if (info->flags & DEVICE_PCI) dev->misc_flags |= FLAG_PCI; + kbc_handler_set = 0; kbc_at_handler(1, dev); timer_add(&dev->kbc_poll_timer, kbc_at_poll, dev, 1); From 72ff4501f7ecda6be2a003f9cd725e6d6f6dc4ec Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 9 May 2024 18:02:27 +0200 Subject: [PATCH 919/936] IDE: Hard disks now have a valid default configuration, per ATA-2 and later. --- src/disk/hdc_ide.c | 47 ++++++++++++++++++++++++++++--------- src/include/86box/hdc_ide.h | 2 +- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index d203a52e8..3793f778b 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -516,24 +516,29 @@ ide_hd_identify(const ide_t *ide) { char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; const ide_bm_t *bm = ide_boards[ide->board]->bm; - const uint32_t d_spt = ide->spt; uint64_t full_size = (((uint64_t) hdd[ide->hdd_num].tracks) * hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); - uint32_t d_hpc; - uint32_t d_tracks; device_identify[6] = (ide->hdd_num / 10) + 0x30; device_identify[7] = (ide->hdd_num % 10) + 0x30; ide_log("IDE Identify: %s\n", device_identify); - if (ide->hpc <= 16) { + uint32_t d_hpc = ide->hpc; + uint32_t d_spt = ide->spt; + uint32_t d_tracks; + + if ((ide->hpc <= 16) && (ide->spt <= 63)) { /* HPC <= 16, report as needed. */ d_tracks = ide->tracks; - d_hpc = ide->hpc; } else { /* HPC > 16, convert to 16 HPC. */ - d_hpc = 16; - d_tracks = (ide->tracks * ide->hpc) / 16; + if (ide->hpc > 16) + d_hpc = 16; + if (ide->spt > 63) + d_spt = 63; + d_tracks = (ide->tracks * ide->hpc * ide->spt) / (16 * 63); + if (d_tracks > 16383) + d_tracks = 16383; } /* Specify default CHS translation */ @@ -579,7 +584,7 @@ ide_hd_identify(const ide_t *ide) */ ide->buffer[53] = 1; - if (ide->cfg_spt != 0) { + if (ide->params_specified) { ide->buffer[54] = (full_size / ide->cfg_hpc) / ide->cfg_spt; ide->buffer[55] = ide->cfg_hpc; ide->buffer[56] = ide->cfg_spt; @@ -2427,10 +2432,12 @@ ide_callback(void *priv) if (ide->type == IDE_ATAPI) err = ABRT_ERR; else { - if (ide->cfg_spt == 0) { - /* Only accept after RESET or DIAG. */ + /* Only accept after RESET or DIAG. */ + if (ide->params_specified) { ide->cfg_spt = ide->tf->secount; ide->cfg_hpc = ide->tf->head + 1; + + ide->params_specified = 1; } ide->command = 0x00; ide->tf->atastat = DRDY_STAT | DSC_STAT; @@ -2744,8 +2751,26 @@ ide_board_setup(const int board) dev->tf->error = 1; if (dev->type != IDE_HDD) dev->cfg_spt = dev->cfg_hpc = 0; - if (dev->type == IDE_HDD) + if (dev->type == IDE_HDD) { dev->blocksize = hdd[dev->hdd_num].max_multiple_block; + + /* Calculate the default heads and sectors. */ + uint32_t d_hpc = dev->hpc; + uint32_t d_spt = dev->spt; + + if ((dev->hpc > 16) || (dev->spt > 63)) { + /* HPC > 16, convert to 16 HPC. */ + if (dev->hpc > 16) + d_hpc = 16; + if (dev->spt > 63) + d_spt = 63; + } + + dev->cfg_spt = d_spt; + dev->cfg_hpc = d_hpc; + } + + dev->params_specified = 0; } } diff --git a/src/include/86box/hdc_ide.h b/src/include/86box/hdc_ide.h index 4ee808d69..9094f7f00 100644 --- a/src/include/86box/hdc_ide.h +++ b/src/include/86box/hdc_ide.h @@ -82,7 +82,7 @@ typedef struct ide_s { uint8_t selected; uint8_t command; uint8_t head; - uint8_t pad; + uint8_t params_specified; int type; int board; int irqstat; From 62193ab2591d431d888bc3010a376646ab39b946 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 9 May 2024 18:10:32 +0200 Subject: [PATCH 920/936] Intel i4x0: Extended the old register 52h behavior to all 430FX, 430HX, 430VX, and 430TX machines. --- src/chipset/intel_4x0.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index 9a2635b12..2f6afa940 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -518,15 +518,12 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430FX: case INTEL_430VX: case INTEL_430TX: - if (!strcmp(machine_get_internal_name(), "mb500n") || (strstr(machine_get_internal_name(), "mr") != NULL)) - regs[0x52] = val; - else - regs[0x52] = (regs[0x52] & 0xf4) | (val & 0x0b); + regs[0x52] = (regs[0x52] & 0x04) | (val & 0xfb); cpu_cache_ext_enabled = ((val & 0x03) == 0x01); cpu_update_waitstates(); break; case INTEL_430HX: - regs[0x52] = (regs[0x52] & 0xf0) | (val & 0x0f); + regs[0x52] = val; cpu_cache_ext_enabled = ((val & 0x03) == 0x01); cpu_update_waitstates(); break; From 544ea87764c62916b63f11c5791030aca3ecfb99 Mon Sep 17 00:00:00 2001 From: luennix <99608219+luennix@users.noreply.github.com> Date: Thu, 9 May 2024 19:57:11 +0300 Subject: [PATCH 921/936] Add the IBM PC 140 (type 6260) --- src/include/86box/machine.h | 1 + src/machine/m_at_socket7_3v.c | 31 +++++++++++++++++++++++++++ src/machine/machine_table.c | 40 +++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index f97d1a37c..c0d60c221 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -677,6 +677,7 @@ extern int machine_at_dellhannibalp_init(const machine_t *); extern int machine_at_gw2kte_init(const machine_t *); extern int machine_at_ap5s_init(const machine_t *); +extern int machine_at_pc140_6260_init(const machine_t *); extern int machine_at_ms5124_init(const machine_t *); extern int machine_at_amis727_init(const machine_t *); extern int machine_at_vectra54_init(const machine_t *); diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index bd66c9a66..b1a9515f3 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -882,3 +882,34 @@ machine_at_5sbm2_init(const machine_t *model) return ret; } + +int +machine_at_pc140_6260_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/pc140_6260/LYKT32A.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x14, PCI_CARD_VIDEO, 0, 0, 0, 0); /* Onboard video */ + + if (gfxcard[0] == VID_INTERNAL) + device_add(&gd5436_onboard_pci_device); + + device_add(&sis_5511_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c669_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 3aafe237c..7fbae3a32 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -10856,6 +10856,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has an SMC FDC37C669QF Super I/O. */ + { + .name = "[SiS 5511] IBM PC 140 (type 6260)", + .internal_name = "pc140_6260", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_SIS_5511, + .init = machine_at_pc140_6260_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_WINCHIP, CPU_WINCHIP2, CPU_Cx6x86, CPU_Cx6x86L, CPU_Cx6x86MX, CPU_PENTIUMMMX), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5436_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL + }, /* Has AMIKey H KBC firmware (AMIKey-2). */ { .name = "[SiS 5511] MSI MS-5124", From b22b2af411b63fa93523debfc6a47038058a43fc Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 10 May 2024 00:29:35 +0200 Subject: [PATCH 922/936] ALi M1543(C) and SiS 551x IDE fixes. --- src/chipset/ali1543.c | 4 ++-- src/chipset/sis_5513_ide.c | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index 6f080b15b..5598f30fb 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -782,9 +782,9 @@ ali5229_write(int func, int addr, uint8_t val, void *priv) /* Datasheet erratum: the PCI BAR's actually have different sizes. */ if (addr == 0x20) dev->ide_conf[addr] = (val & 0xe0) | 0x01; - else if ((addr & 0x43) == 0x00) + else if ((addr & 0x07) == 0x00) dev->ide_conf[addr] = (val & 0xf8) | 0x01; - else if ((addr & 0x43) == 0x40) + else if ((addr & 0x07) == 0x04) dev->ide_conf[addr] = (val & 0xfc) | 0x01; else dev->ide_conf[addr] = val; diff --git a/src/chipset/sis_5513_ide.c b/src/chipset/sis_5513_ide.c index 130f2abd5..5cbfbdea8 100644 --- a/src/chipset/sis_5513_ide.c +++ b/src/chipset/sis_5513_ide.c @@ -224,6 +224,10 @@ sis_5513_ide_write(int addr, uint8_t val, void *priv) case 0x20 ... 0x21: if (addr == 0x20) dev->pci_conf[addr] = (val & 0xe0) | 0x01; + else if ((addr & 0x07) == 0x00) + dev->pci_conf[addr] = (val & 0xf8) | 0x01; + else if ((addr & 0x07) == 0x04) + dev->pci_conf[addr] = (val & 0xfc) | 0x01; else dev->pci_conf[addr] = val; sis_5513_ide_handler(dev); From b67c234569f4bd743c70dcac0daa14d9b293b7d5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 10 May 2024 00:31:58 +0200 Subject: [PATCH 923/936] The PS/2 keyboard controllers now simulate the real hardware behavior of there being a slight delay between OBF and IRQ, fixes, amnong other things, PB640 Windows 95 mouse (and PB450 CMOS Setup now works without the workaround). --- src/device/kbc_at.c | 87 +++++++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 35 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 7a720f948..c0ce537c2 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -108,7 +108,11 @@ enum { STATE_SEND_KBD, /* KBC is sending command to the keyboard. */ STATE_SCAN_KBD, /* KBC is waiting for the keyboard command response. */ STATE_SEND_AUX, /* KBC is sending command to the auxiliary device. */ - STATE_SCAN_AUX /* KBC is waiting for the auxiliary command response. */ + STATE_SCAN_AUX, /* KBC is waiting for the auxiliary command response. */ + STATE_IRQ, /* KBC is raising the IRQ. */ + STATE_KBC_IRQ, + STATE_AUX_IRQ, + STATE_KBC_DELAY_IRQ }; typedef struct atkbc_t { @@ -133,9 +137,9 @@ typedef struct atkbc_t { uint8_t stat_hi; uint8_t pending; uint8_t irq_state; - uint8_t suppress_cmd_intr; uint8_t pad; uint8_t pad0; + uint8_t pad1; uint8_t mem[0x100]; @@ -352,8 +356,10 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; int temp = (channel == 1) ? kbc_translate(dev, val) : ((int) val); - if (temp == -1) + if (temp == -1) { + dev->state = STATE_MAIN_IBF; return; + } if ((kbc_ven == KBC_VEN_AMI) || (kbc_ven == KBC_VEN_TRIGEM_AMI) || (dev->misc_flags & FLAG_PS2)) @@ -369,15 +375,9 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) if (dev->misc_flags & FLAG_PS2) { if (channel >= 2) { dev->status |= STAT_MFULL; - - if (dev->mem[0x20] & 0x02) - picint_common(1 << 12, 0, 1, NULL); - picint_common(1 << 1, 0, 0, NULL); - } else { - if ((!dev->suppress_cmd_intr || (dev->channel == 1)) && (dev->mem[0x20] & 0x01)) - picint_common(1 << 1, 0, 1, NULL); - picint_common(1 << 12, 0, 0, NULL); - } + dev->state = STATE_AUX_IRQ; + } else if (channel == 1) + dev->state = STATE_IRQ; } else if (dev->mem[0x20] & 0x01) picintlevel(1 << 1, &dev->irq_state); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */ @@ -575,7 +575,6 @@ kbc_scan_kbd_ps2(atkbc_t *dev) kbc_at_log("ATkbc: %02X coming from channel 1\n", dev->ports[0]->out_new & 0xff); kbc_send_to_ob(dev, dev->ports[0]->out_new, 1, 0x00); dev->ports[0]->out_new = -1; - dev->state = STATE_MAIN_IBF; return 1; } @@ -589,7 +588,6 @@ kbc_scan_aux_ps2(atkbc_t *dev) kbc_at_log("ATkbc: %02X coming from channel 2\n", dev->ports[1]->out_new & 0xff); kbc_send_to_ob(dev, dev->ports[1]->out_new, 2, 0x00); dev->ports[1]->out_new = -1; - dev->state = STATE_MAIN_IBF; return 1; } @@ -637,22 +635,20 @@ ps2_main_ibf: if (dev->status & STAT_IFULL) kbc_ibf_process(dev); else { - (void) kbc_scan_kbd_ps2(dev); - dev->state = STATE_MAIN_IBF; + if (!kbc_scan_kbd_ps2(dev)) + dev->state = STATE_MAIN_IBF; } break; case STATE_MAIN_AUX: if (dev->status & STAT_IFULL) kbc_ibf_process(dev); else { - (void) kbc_scan_aux_ps2(dev); - dev->state = STATE_MAIN_IBF; + if (!kbc_scan_aux_ps2(dev)) + dev->state = STATE_MAIN_IBF; } break; case STATE_MAIN_BOTH: - if (kbc_scan_kbd_ps2(dev)) - dev->state = STATE_MAIN_IBF; - else + if (!kbc_scan_kbd_ps2(dev)) dev->state = STATE_MAIN_AUX; break; case STATE_KBC_DELAY_OUT: @@ -662,8 +658,29 @@ ps2_main_ibf: #if 0 dev->state = (dev->pending == 2) ? STATE_KBC_AMI_OUT : STATE_MAIN_IBF; #endif - dev->state = STATE_MAIN_IBF; dev->pending = 0; + dev->state = STATE_KBC_DELAY_IRQ; + break; + case STATE_IRQ: + kbc_at_log("ATkbc: Raising IRQ 1 (keyboard)...\n"); + if (dev->mem[0x20] & 0x01) + picint_common(1 << 1, 0, 1, NULL); + picint_common(1 << 12, 0, 0, NULL); + dev->state = STATE_MAIN_IBF; + break; + case STATE_AUX_IRQ: + kbc_at_log("ATkbc: Raising IRQ 12 (mouse)...\n"); + if (dev->mem[0x20] & 0x02) + picint_common(1 << 12, 0, 1, NULL); + picint_common(1 << 1, 0, 0, NULL); + dev->state = STATE_MAIN_IBF; + break; + case STATE_KBC_DELAY_IRQ: + kbc_at_log("ATkbc: Raising IRQ 1 (KBC delay)...\n"); + if (dev->mem[0x20] & 0x01) + picint_common(1 << 1, 0, 1, NULL); + picint_common(1 << 12, 0, 0, NULL); + dev->state = STATE_MAIN_IBF; goto ps2_main_ibf; case STATE_KBC_OUT: /* Keyboard controller command want to output multiple bytes. */ @@ -676,11 +693,18 @@ ps2_main_ibf: if (!(dev->status & STAT_OFULL)) { kbc_at_log("ATkbc: %02X coming from channel 0\n", dev->key_ctrl_queue[dev->key_ctrl_queue_start] & 0xff); kbc_send_to_ob(dev, dev->key_ctrl_queue[dev->key_ctrl_queue_start], 0, 0x00); - dev->key_ctrl_queue_start = (dev->key_ctrl_queue_start + 1) & 0x3f; - if (dev->key_ctrl_queue_start == dev->key_ctrl_queue_end) - dev->state = STATE_MAIN_IBF; + dev->state = STATE_KBC_IRQ; } break; + case STATE_KBC_IRQ: + kbc_at_log("ATkbc: Raising IRQ 1 (KBC)...\n"); + if (dev->mem[0x20] & 0x01) + picint_common(1 << 1, 0, 1, NULL); + picint_common(1 << 12, 0, 0, NULL); + dev->key_ctrl_queue_start = (dev->key_ctrl_queue_start + 1) & 0x3f; + if (dev->key_ctrl_queue_start == dev->key_ctrl_queue_end) + dev->state = STATE_MAIN_IBF; + break; case STATE_KBC_PARAM: /* Keyboard controller command wants data, wait for said data. */ if (dev->status & STAT_IFULL) { @@ -1394,8 +1418,6 @@ write60_phoenix(void *priv, uint8_t val) kbc_at_log("ATkbc: Phoenix - Set MultiKey Variable\n"); if ((dev->mem_addr > 0) && (dev->mem_addr <= multikey_vars[0x00])) dev->mem[multikey_vars[dev->mem_addr]] = val; - else if (dev->mem_addr == 0x29) - dev->suppress_cmd_intr = !val; dev->command_phase = 0; return 0; @@ -2006,7 +2028,7 @@ kbc_at_process_cmd(void *priv) if (dev->ib == 0xbb) break; - if (strstr(machine_get_internal_name(), "pb") != NULL) + if (strstr(machine_get_internal_name(), "pb41") != NULL) cpu_override_dynarec = 1; if (dev->misc_flags & FLAG_PS2) { @@ -2103,11 +2125,8 @@ kbc_at_read(uint16_t port, void *priv) if (!(dev->misc_flags & FLAG_PS2)) picintclevel(1 << 1, &dev->irq_state); /* I"m not even sure if this is correct but the PB450 absolutely requires this. */ - if (dev->suppress_cmd_intr) { - picint_common(1 << 1, 0, 1, NULL); - dev->suppress_cmd_intr = 0; - } - if ((strstr(machine_get_internal_name(), "pb") != NULL) && (cpu_override_dynarec == 1)) + if ((strstr(machine_get_internal_name(), "pb41") != NULL) && + (cpu_override_dynarec == 1)) cpu_override_dynarec = 0; break; @@ -2149,8 +2168,6 @@ kbc_at_reset(void *priv) kbc_at_queue_reset(dev); - dev->suppress_cmd_intr = 0; - dev->sc_or = 0; dev->ami_flags = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) ? 0x01 : 0x00; From 723c4229ed3bb99505034cd506c3cc8b564fdd42 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 10 May 2024 00:33:15 +0200 Subject: [PATCH 924/936] PCI: Force the PCI_ADD_STRICT flag when adding PCI devices, in order to prevent on-board devices from being added onto non-on-board slots. --- src/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pci.c b/src/pci.c index 15a119cb7..13b780050 100644 --- a/src/pci.c +++ b/src/pci.c @@ -767,7 +767,7 @@ pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), if (next_pci_card < PCI_CARDS_NUM) { dev = &pci_card_descs[next_pci_card]; - dev->type = add_type; + dev->type = add_type | PCI_ADD_STRICT; dev->read = read; dev->write = write; dev->priv = priv; From 97b41adc22fc39809685111f8b85ba73434d88d5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 10 May 2024 00:49:21 +0200 Subject: [PATCH 925/936] AT KBC: IBM variants now revert to old IRQ behavior. --- src/device/kbc_at.c | 37 ++++++++++++++++++++++++++++++++---- src/include/86box/keyboard.h | 1 + 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index c0ce537c2..6a5c306e1 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -88,6 +88,7 @@ #define KBC_VEN_ALI 0x28 #define KBC_VEN_SIEMENS 0x2c #define KBC_VEN_COMPAQ 0x30 +#define KBC_VEN_IBM 0x34 #define KBC_VEN_MASK 0x7c #define FLAG_CLOCK 0x01 @@ -375,9 +376,22 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) if (dev->misc_flags & FLAG_PS2) { if (channel >= 2) { dev->status |= STAT_MFULL; - dev->state = STATE_AUX_IRQ; - } else if (channel == 1) - dev->state = STATE_IRQ; + if ((kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM)) { + if (dev->mem[0x20] & 0x02) + picint_common(1 << 12, 0, 1, NULL); + picint_common(1 << 1, 0, 0, NULL); + dev->state = STATE_MAIN_IBF; + } else + dev->state = STATE_AUX_IRQ; + } else if (channel == 1) { + if ((kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM)) { + if (dev->mem[0x20] & 0x01) + picint_common(1 << 1, 0, 1, NULL); + picint_common(1 << 12, 0, 0, NULL); + dev->state = STATE_MAIN_IBF; + } else + dev->state = STATE_IRQ; + } } else if (dev->mem[0x20] & 0x01) picintlevel(1 << 1, &dev->irq_state); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */ @@ -2275,6 +2289,7 @@ kbc_at_init(const device_t *info) case KBC_VEN_ACER: case KBC_VEN_GENERIC: + case KBC_VEN_IBM: case KBC_VEN_NCR: case KBC_VEN_IBM_PS1: case KBC_VEN_COMPAQ: @@ -2570,11 +2585,25 @@ const device_t keyboard_ps2_tg_ami_device = { .config = NULL }; +const device_t keyboard_ps2_mca_1_device = { + .name = "PS/2 Keyboard", + .internal_name = "keyboard_ps2", + .flags = DEVICE_KBC, + .local = KBC_TYPE_PS2_1 | KBC_VEN_IBM, + .init = kbc_at_init, + .close = kbc_at_close, + .reset = kbc_at_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t keyboard_ps2_mca_2_device = { .name = "PS/2 Keyboard", .internal_name = "keyboard_ps2_mca_2", .flags = DEVICE_KBC, - .local = KBC_TYPE_PS2_2 | KBC_VEN_GENERIC, + .local = KBC_TYPE_PS2_2 | KBC_VEN_IBM, .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 79665c9a9..5058c821e 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -246,6 +246,7 @@ extern const device_t keyboard_ps2_tg_ami_device; extern const device_t keyboard_ps2_tg_ami_green_device; extern const device_t keyboard_ps2_olivetti_device; extern const device_t keyboard_ps2_phoenix_device; +extern const device_t keyboard_ps2_mca_1_device; extern const device_t keyboard_ps2_mca_2_device; extern const device_t keyboard_ps2_quadtel_device; extern const device_t keyboard_ps2_pci_device; From c9e27e7e70f1e39d21b550809cd6cf0df7e71534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Fri, 10 May 2024 00:50:23 +0200 Subject: [PATCH 926/936] Update m_ps2_mca.c. --- src/machine/m_ps2_mca.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index a6fc30e1c..8ad69e314 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -1054,7 +1054,7 @@ ps2_mca_board_model_55sx_init(int has_sec_nvram, int slots) } mca_init(slots); - device_add(&keyboard_ps2_device); + device_add(&keyboard_ps2_mca_1_device); if (has_sec_nvram) device_add(&ps2_nvr_55ls_device); @@ -1228,7 +1228,7 @@ ps2_mca_board_model_70_type34_init(int is_type4, int slots) ps2.split_addr = mem_size * 1024; mca_init(slots); - device_add(&keyboard_ps2_device); + device_add(&keyboard_ps2_mca_1_device); ps2.planar_read = model_70_type3_read; ps2.planar_write = model_70_type3_write; @@ -1321,7 +1321,7 @@ ps2_mca_board_model_80_type2_init(void) ps2.split_addr = mem_size * 1024; mca_init(8); - device_add(&keyboard_ps2_device); + device_add(&keyboard_ps2_mca_1_device); ps2.planar_read = model_80_read; ps2.planar_write = model_80_write; From 6442c116f80d27d2f6f5478950aaaa48851d4f42 Mon Sep 17 00:00:00 2001 From: Jester Date: Sun, 12 May 2024 00:40:22 +0200 Subject: [PATCH 927/936] Update Olivetti M240 BIOS to 2.11 Dumped BIOS 2.11 Updating the BIOS from 2.04 to 2.11 fixes several bugs: - "Format Failure" message during hard disk formatting under MS DOS - WANGTEK 40 MB streaming tape unit management - I/O errors in floppy disk after an ON/OFF sequence - Clock problems after using "GOSLOW" - Possibility of testing system from a remote work station - Possibility of programming in RTCC - Solves FUJITSU 8284 problem --- src/machine/m_xt_olivetti.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/machine/m_xt_olivetti.c b/src/machine/m_xt_olivetti.c index 0b5a3eab0..7806d378b 100644 --- a/src/machine/m_xt_olivetti.c +++ b/src/machine/m_xt_olivetti.c @@ -1853,8 +1853,8 @@ machine_xt_m240_init(const machine_t *model) m24_kbd_t *m24_kbd; nvr_t *nvr; - ret = bios_load_interleaved("roms/machines/m240/olivetti_m240_pch6_2.04_low.bin", - "roms/machines/m240/olivetti_m240_pch5_2.04_high.bin", + ret = bios_load_interleaved("roms/machines/m240/olivetti_m240_pchj_2.11_low.bin", + "roms/machines/m240/olivetti_m240_pchk_2.11_high.bin", 0x000f8000, 32768, 0); if (bios_only || !ret) From d786cf3aa747c71192a239f3606d3d7343869406 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 12 May 2024 16:48:43 +0200 Subject: [PATCH 928/936] ESS AudioDrive: Fix some regressions and implement DRQ setting in compatibility mode, fixes Windows 3.1x ES1688 drivers. --- src/sound/snd_sb.c | 10 ++++++++-- src/sound/snd_sb_dsp.c | 26 +++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 80642adbe..364c01557 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -1492,7 +1492,8 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) break; case 0x64: - mixer->regs[mixer->index] &= ~0x8; + mixer->regs[mixer->index] = (mixer->regs[mixer->index] & 0xf7) | 0x20; + // mixer->regs[mixer->index] &= ~0x8; break; case 0x40: @@ -1615,9 +1616,13 @@ ess_mixer_read(uint16_t addr, void *priv) ret = 0x0a; break; + case 0x48: + ret = mixer->regs[mixer->index]; + break; + /* Return 0x00 so it has bit 3 clear, so NT 5.x drivers don't misdetect it as ES1788. */ case 0x64: - ret = 0x00; + ret = (mixer->regs[mixer->index] & 0xf7) | 0x20; break; default: @@ -3463,6 +3468,7 @@ ess_x688_init(UNUSED(const device_t *info)) } ess->mixer_enabled = 1; + ess->mixer_ess.regs[0x40] = 0x0a; io_sethandler(addr + 4, 0x0002, ess_mixer_read, NULL, NULL, ess_mixer_write, NULL, NULL, diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 9c148339d..e5c2359a0 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -563,6 +563,8 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) timer_set_delay_u64(&dsp->output_timer, (uint64_t) dsp->sblatcho); dsp->sbleftright = dsp->sbleftright_default; dsp->sbdacpos = 0; + + dma_set_drq(dsp->sb_8_dmanum, 1); } else { dsp->sb_16_length = dsp->sb_16_origlength = len; dsp->sb_16_format = format; @@ -574,6 +576,11 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) dsp->sb_16_output = 1; if (!timer_is_enabled(&dsp->output_timer)) timer_set_delay_u64(&dsp->output_timer, (uint64_t) dsp->sblatcho); + + if (dsp->sb_16_dma_supported) + dma_set_drq(dsp->sb_16_dmanum, 1); + else + dma_set_drq(dsp->sb_16_8_dmanum, 1); } /* This will be set later for ESS playback/record modes. */ @@ -594,6 +601,8 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) dsp->sb_8_output = 0; if (!timer_is_enabled(&dsp->input_timer)) timer_set_delay_u64(&dsp->input_timer, (uint64_t) dsp->sblatchi); + + dma_set_drq(dsp->sb_8_dmanum, 1); } else { dsp->sb_16_length = dsp->sb_16_origlength = len; dsp->sb_16_format = format; @@ -605,6 +614,11 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) dsp->sb_16_output = 0; if (!timer_is_enabled(&dsp->input_timer)) timer_set_delay_u64(&dsp->input_timer, (uint64_t) dsp->sblatchi); + + if (dsp->sb_16_dma_supported) + dma_set_drq(dsp->sb_16_dmanum, 1); + else + dma_set_drq(dsp->sb_16_8_dmanum, 1); } memset(dsp->record_buffer, 0, sizeof(dsp->record_buffer)); @@ -771,7 +785,10 @@ sb_16_write_dma(void *priv, uint16_t val) void sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy) { - uint8_t t = 0x00; + sb_t *ess = (sb_t *) dsp->parent; + ess_mixer_t *mixer = &ess->mixer_ess; + uint8_t t = 0x00; + /* IRQ control */ if (legacy) { t |= 0x80; @@ -779,6 +796,7 @@ sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy) switch (dsp->sb_irqnum) { default: break; + case 2: case 9: t |= 0x0; break; @@ -793,6 +811,8 @@ sb_ess_update_irq_drq_readback_regs(sb_dsp_t *dsp, bool legacy) break; } ESSreg(0xB1) = (ESSreg(0xB1) & 0xF0) | t; + if ((mixer != NULL) && (ess->mpu != NULL) && (((mixer->regs[0x40] >> 5) & 0x7) == 2)) + mpu401_setirq(ess->mpu, ess->dsp.sb_irqnum); /* DRQ control */ t = 0x00; @@ -1802,7 +1822,7 @@ sb_read(uint16_t a, void *priv) switch (a & 0xf) { case 0x6: - ret = 0xff; + ret = IS_ESS(dsp) ? 0x00 : 0xff; break; case 0xA: /* Read data */ if (dsp->mpu && dsp->uart_midi) @@ -1821,7 +1841,7 @@ sb_read(uint16_t a, void *priv) dsp->state = DSP_S_NORMAL; break; case 0xC: /* Write data ready */ - if (dsp->state == DSP_S_NORMAL) { + if ((dsp->state == DSP_S_NORMAL) || IS_ESS(dsp)) { if (dsp->sb_8_enable || dsp->sb_type >= SB16) dsp->busy_count = (dsp->busy_count + 1) & 3; else From 01b2d14a49f9c924306951f1e0c6e12b685060c7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 12 May 2024 19:11:52 +0200 Subject: [PATCH 929/936] PS/2 KBC: Clear IRQ's upon returning to main loop, fixes input in Windows 3.1x on eg. the Soyo 4SAW2. --- src/device/kbc_at.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 6a5c306e1..c630960ae 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -625,6 +625,8 @@ kbc_at_poll_ps2(atkbc_t *dev) fallthrough; case STATE_MAIN_IBF: default: + picint_common(1 << 1, 0, 0, NULL); + picint_common(1 << 12, 0, 0, NULL); ps2_main_ibf: if (dev->status & STAT_IFULL) kbc_ibf_process(dev); From 3cac44a0337c13555393dd34ffaba551313b073e Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 13 May 2024 00:42:35 +0200 Subject: [PATCH 930/936] PS/2 KBC: Added a 2-cycle wait before clearing the IRQ's, fixes keyboard during NTLDR. --- src/device/kbc_at.c | 89 ++++++++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 38 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index c630960ae..74c5d83d1 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -99,7 +99,7 @@ enum { STATE_RESET = 0, /* KBC reset state, only accepts command AA. */ STATE_KBC_DELAY_OUT, /* KBC is sending one single byte. */ - STATE_KBC_AMI_OUT, /* KBC waiting for OBF - needed for AMIKey commands that require clearing of the output byte. */ + STATE_IRQC_MAIN_IBF, /* KBC checking if the input buffer is full, clear IRQ's first. */ STATE_MAIN_IBF, /* KBC checking if the input buffer is full. */ STATE_MAIN_KBD, /* KBC checking if the keyboard has anything to send. */ STATE_MAIN_AUX, /* KBC checking if the auxiliary has anything to send. */ @@ -113,7 +113,8 @@ enum { STATE_IRQ, /* KBC is raising the IRQ. */ STATE_KBC_IRQ, STATE_AUX_IRQ, - STATE_KBC_DELAY_IRQ + STATE_KBC_DELAY_IRQ, + STATE_IRQC_WAIT, }; typedef struct atkbc_t { @@ -371,25 +372,29 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) kbc_at_log("ATkbc: Sending %02X to the output buffer on channel %i...\n", temp, channel); dev->status = (dev->status & ~0xf0) | STAT_OFULL | stat_hi; + dev->state = STATE_MAIN_IBF; + /* WARNING: On PS/2, all IRQ's are level-triggered, but the IBM PS/2 KBC firmware is explicitly written to pulse its P2 IRQ bits, so they should be kept as as edge-triggered here. */ if (dev->misc_flags & FLAG_PS2) { if (channel >= 2) { dev->status |= STAT_MFULL; if ((kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM)) { - if (dev->mem[0x20] & 0x02) + if (dev->mem[0x20] & 0x02) { picint_common(1 << 12, 0, 1, NULL); - picint_common(1 << 1, 0, 0, NULL); - dev->state = STATE_MAIN_IBF; - } else + dev->state = STATE_IRQC_WAIT; + } + // picint_common(1 << 1, 0, 0, NULL); + } else if (dev->mem[0x20] & 0x02) dev->state = STATE_AUX_IRQ; } else if (channel == 1) { if ((kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM)) { - if (dev->mem[0x20] & 0x01) + if (dev->mem[0x20] & 0x01) { picint_common(1 << 1, 0, 1, NULL); - picint_common(1 << 12, 0, 0, NULL); - dev->state = STATE_MAIN_IBF; - } else + dev->state = STATE_IRQC_WAIT; + } + // picint_common(1 << 12, 0, 0, NULL); + } else if (dev->mem[0x20] & 0x01) dev->state = STATE_IRQ; } } else if (dev->mem[0x20] & 0x01) @@ -499,10 +504,6 @@ kbc_at_poll_at(atkbc_t *dev) kbc_at_process_cmd(dev); } break; - case STATE_KBC_AMI_OUT: - if (dev->status & STAT_OFULL) - break; - fallthrough; case STATE_MAIN_IBF: default: at_main_ibf: @@ -530,9 +531,6 @@ at_main_ibf: /* Keyboard controller command want to output a single byte. */ kbc_at_log("ATkbc: %02X coming from channel %i with high status %02X\n", dev->val, dev->channel, dev->stat_hi); kbc_send_to_ob(dev, dev->val, dev->channel, dev->stat_hi); -#if 0 - dev->state = (dev->pending == 2) ? STATE_KBC_AMI_OUT : STATE_MAIN_IBF; -#endif dev->state = STATE_MAIN_IBF; dev->pending = 0; goto at_main_ibf; @@ -611,6 +609,8 @@ kbc_scan_aux_ps2(atkbc_t *dev) static void kbc_at_poll_ps2(atkbc_t *dev) { + static uint8_t phase = 0; + switch (dev->state) { case STATE_RESET: if (dev->status & STAT_IFULL) { @@ -619,14 +619,19 @@ kbc_at_poll_ps2(atkbc_t *dev) kbc_at_process_cmd(dev); } break; - case STATE_KBC_AMI_OUT: - if (dev->status & STAT_OFULL) - break; + case STATE_IRQC_WAIT: + kbc_at_log("ATkbc: IRQ clear wait...\n"); + phase = (phase + 1) & 1; + if (phase) + dev->state = STATE_IRQC_MAIN_IBF; + break; + case STATE_IRQC_MAIN_IBF: + kbc_at_log("ATkbc: Clearing IRQ 1 and 12 (Main/IBF)...\n"); + picint_common(1 << 1, 0, 0, NULL); + picint_common(1 << 12, 0, 0, NULL); fallthrough; case STATE_MAIN_IBF: default: - picint_common(1 << 1, 0, 0, NULL); - picint_common(1 << 12, 0, 0, NULL); ps2_main_ibf: if (dev->status & STAT_IFULL) kbc_ibf_process(dev); @@ -671,34 +676,41 @@ ps2_main_ibf: /* Keyboard controller command want to output a single byte. */ kbc_at_log("ATkbc: %02X coming from channel %i with high status %02X\n", dev->val, dev->channel, dev->stat_hi); kbc_send_to_ob(dev, dev->val, dev->channel, dev->stat_hi); -#if 0 - dev->state = (dev->pending == 2) ? STATE_KBC_AMI_OUT : STATE_MAIN_IBF; -#endif dev->pending = 0; dev->state = STATE_KBC_DELAY_IRQ; break; case STATE_IRQ: - kbc_at_log("ATkbc: Raising IRQ 1 (keyboard)...\n"); - if (dev->mem[0x20] & 0x01) + if (dev->mem[0x20] & 0x01) { + kbc_at_log("ATkbc: Raising IRQ 1 (keyboard)...\n"); picint_common(1 << 1, 0, 1, NULL); - picint_common(1 << 12, 0, 0, NULL); - dev->state = STATE_MAIN_IBF; + dev->state = STATE_IRQC_WAIT; + } else { + kbc_at_log("ATkbc: Noping IRQ 1 (keyboard)...\n"); + dev->state = STATE_MAIN_IBF; + } break; case STATE_AUX_IRQ: kbc_at_log("ATkbc: Raising IRQ 12 (mouse)...\n"); - if (dev->mem[0x20] & 0x02) + if (dev->mem[0x20] & 0x02) { picint_common(1 << 12, 0, 1, NULL); - picint_common(1 << 1, 0, 0, NULL); - dev->state = STATE_MAIN_IBF; + dev->state = STATE_IRQC_WAIT; + } else + dev->state = STATE_MAIN_IBF; break; case STATE_KBC_DELAY_IRQ: kbc_at_log("ATkbc: Raising IRQ 1 (KBC delay)...\n"); - if (dev->mem[0x20] & 0x01) + if (dev->mem[0x20] & 0x01) { picint_common(1 << 1, 0, 1, NULL); - picint_common(1 << 12, 0, 0, NULL); - dev->state = STATE_MAIN_IBF; - goto ps2_main_ibf; + dev->state = STATE_IRQC_WAIT; + break; + } else { + dev->state = STATE_MAIN_IBF; + goto ps2_main_ibf; + } case STATE_KBC_OUT: + kbc_at_log("ATkbc: Clearing IRQ 1 and 12 (KBC out)...\n"); + picint_common(1 << 1, 0, 0, NULL); + picint_common(1 << 12, 0, 0, NULL); /* Keyboard controller command want to output multiple bytes. */ if (dev->status & STAT_IFULL) { /* Data from host aborts dumping. */ @@ -716,10 +728,11 @@ ps2_main_ibf: kbc_at_log("ATkbc: Raising IRQ 1 (KBC)...\n"); if (dev->mem[0x20] & 0x01) picint_common(1 << 1, 0, 1, NULL); - picint_common(1 << 12, 0, 0, NULL); dev->key_ctrl_queue_start = (dev->key_ctrl_queue_start + 1) & 0x3f; if (dev->key_ctrl_queue_start == dev->key_ctrl_queue_end) - dev->state = STATE_MAIN_IBF; + dev->state = STATE_IRQC_WAIT; + else + dev->state = STATE_KBC_OUT; break; case STATE_KBC_PARAM: /* Keyboard controller command wants data, wait for said data. */ From 4e67a4fdd32b9e6e6e1e8f554a9df7eefc487c26 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 13 May 2024 00:57:53 +0200 Subject: [PATCH 931/936] DMA speed fixes in place on the 53c400. See above, so that the CD-ROM speed is accurate enough on both ends (T13B and the MMIO variants) and, at the same time, not timing out abnormally. --- src/scsi/scsi_ncr53c400.c | 66 ++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 39 deletions(-) diff --git a/src/scsi/scsi_ncr53c400.c b/src/scsi/scsi_ncr53c400.c index 1ed8e520e..6576e79ab 100644 --- a/src/scsi/scsi_ncr53c400.c +++ b/src/scsi/scsi_ncr53c400.c @@ -103,6 +103,18 @@ ncr53c400_log(const char *fmt, ...) # define ncr53c400_log(fmt, ...) #endif +static void +ncr53c400_timer_on_auto(void *ext_priv, double period) +{ + ncr53c400_t *ncr400 = (ncr53c400_t *) ext_priv; + + ncr53c400_log("53c400: PERIOD=%lf, timer=%x.\n", period, timer_is_enabled(&ncr400->timer)); + if (period <= 0.0) + timer_stop(&ncr400->timer); + else if ((period > 0.0) && !timer_is_enabled(&ncr400->timer)) + timer_on_auto(&ncr400->timer, period); +} + /* Memory-mapped I/O WRITE handler. */ static void ncr53c400_write(uint32_t addr, uint8_t val, void *priv) @@ -110,7 +122,6 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) ncr53c400_t *ncr400 = (ncr53c400_t *) priv; ncr_t *ncr = &ncr400->ncr; scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; - int actual_block = 0; addr &= 0x3fff; @@ -135,6 +146,8 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) if (ncr400->buffer_host_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; ncr400->busy = 1; + if (!(ncr->mode & MODE_MONITOR_BUSY)) + timer_on_auto(&ncr400->timer, ncr->period / 280.0); } } break; @@ -165,19 +178,13 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) ncr400->buffer_host_pos = 0; ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; } - if ((ncr->mode & MODE_DMA) && (dev->buffer_length > 0) && !timer_is_on(&ncr400->timer)) { + if ((ncr->mode & MODE_DMA) && (dev->buffer_length > 0)) { memset(ncr400->buffer, 0, MIN(128, dev->buffer_length)); - ncr53c400_log("DMA timer on, callback=%lf, scsi buflen=%d.\n", scsi_device_get_callback(dev), dev->buffer_length); - actual_block = ncr400->block_count; - if (!actual_block) - actual_block = 256; - - /*Sometimes the actual block count doesn't match the SCSI buffer length / 128.*/ - if (actual_block != (dev->buffer_length / 128)) { - /*FIXME: To be improved further, this is just to workaround callback de-syncs when split transfers occur.*/ - timer_on_auto(&ncr400->timer, (ncr->period / ((double)(actual_block * 40.0)))); - } else + if (ncr->mode & MODE_MONITOR_BUSY) timer_on_auto(&ncr400->timer, ncr->period); + else + timer_on_auto(&ncr400->timer, 40.0); + ncr53c400_log("DMA timer on, callback=%lf, scsi buflen=%d, waitdata=%d, waitcomplete=%d, clearreq=%d, datawait=%d, enabled=%d.\n", scsi_device_get_callback(dev), dev->buffer_length, ncr->wait_complete, ncr->wait_data, ncr->wait_complete, ncr->clear_req, ncr->data_wait, timer_is_enabled(&ncr400->timer)); } break; @@ -232,6 +239,8 @@ ncr53c400_read(uint32_t addr, void *priv) if (ncr400->buffer_host_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; ncr53c400_log("Transfer busy read, status = %02x.\n", ncr400->status_ctrl); + if (!(ncr->mode & MODE_MONITOR_BUSY)) + timer_on_auto(&ncr400->timer, ncr->period / 280.0); } } break; @@ -258,8 +267,7 @@ ncr53c400_read(uint32_t addr, void *priv) break; case 0x3982: /* switch register read */ - ret = 0xf8; - ret |= (ncr->irq & 0x07); + ret = 0xff; ncr53c400_log("Switches read=%02x.\n", ret); break; @@ -392,24 +400,13 @@ ncr53c400_dma_mode_ext(void *priv, void *ext_priv) ncr_t *ncr = (ncr_t *) priv; /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ - if (!ncr400->block_count_loaded && !(ncr->mode & MODE_DMA)) { + if (!(ncr->mode & MODE_DMA)) { ncr53c400_log("No DMA mode\n"); ncr->tcr &= ~TCR_LAST_BYTE_SENT; ncr->isr &= ~STATUS_END_OF_DMA; ncr->dma_mode = DMA_IDLE; - } -} - -static void -ncr53c400_timer_on_auto(void *ext_priv, double period) -{ - ncr53c400_t *ncr400 = (ncr53c400_t *) ext_priv; - - ncr53c400_log("53c400: PERIOD=%lf, timer=%x.\n", period, !!timer_is_on(&ncr400->timer)); - if (period == 0.0) - timer_stop(&ncr400->timer); - else - timer_on_auto(&ncr400->timer, period); + } else + ncr53c400_log("Continuing DMA, mode bit=%02x, block loaded=%d, waitcomplete=%d.\n", ncr->mode, ncr400->block_count_loaded, ncr->wait_complete); } static void @@ -428,16 +425,10 @@ ncr53c400_callback(void *priv) if (ncr->data_wait & 1) { ncr->clear_req = 3; ncr->data_wait &= ~1; - if (ncr->dma_mode == DMA_IDLE) { - timer_stop(&ncr400->timer); - return; - } } - if (ncr->dma_mode == DMA_IDLE) { - timer_stop(&ncr400->timer); + if (ncr->dma_mode == DMA_IDLE) return; - } switch (ncr->dma_mode) { case DMA_SEND: @@ -462,7 +453,6 @@ ncr53c400_callback(void *priv) if (ncr->cur_bus & BUS_REQ) break; } - /* Data ready. */ temp = ncr400->buffer[ncr400->buffer_pos]; @@ -487,7 +477,6 @@ ncr53c400_callback(void *priv) ncr53c400_log("IO End of write transfer\n"); ncr->tcr |= TCR_LAST_BYTE_SENT; ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr400->timer); if (ncr->mode & MODE_ENA_EOP_INT) { ncr53c400_log("NCR 53c400 write irq\n"); ncr5380_irq(ncr, 1); @@ -518,7 +507,6 @@ ncr53c400_callback(void *priv) if (ncr->cur_bus & BUS_REQ) break; } - /* Data ready. */ ncr5380_bus_read(ncr); temp = BUS_GETDATA(ncr->cur_bus); @@ -541,7 +529,6 @@ ncr53c400_callback(void *priv) ncr400->block_count_loaded = 0; ncr53c400_log("IO End of read transfer\n"); ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr400->timer); if (ncr->mode & MODE_ENA_EOP_INT) { ncr53c400_log("NCR read irq\n"); ncr5380_irq(ncr, 1); @@ -562,6 +549,7 @@ ncr53c400_callback(void *priv) ncr53c400_log("Updating DMA\n"); ncr->mode &= ~MODE_DMA; ncr->dma_mode = DMA_IDLE; + ncr400->block_count_loaded = 0; } } From 1856696cd250314b1415bc4591adb246d6d1cabb Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 13 May 2024 01:02:27 +0200 Subject: [PATCH 932/936] Warning fix --- src/scsi/scsi_ncr53c400.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/scsi/scsi_ncr53c400.c b/src/scsi/scsi_ncr53c400.c index 6576e79ab..ca4d28ffb 100644 --- a/src/scsi/scsi_ncr53c400.c +++ b/src/scsi/scsi_ncr53c400.c @@ -394,9 +394,8 @@ t130b_in(uint16_t port, void *priv) } static void -ncr53c400_dma_mode_ext(void *priv, void *ext_priv) +ncr53c400_dma_mode_ext(void *priv, UNUSED(void *ext_priv)) { - ncr53c400_t *ncr400 = (ncr53c400_t *) ext_priv; ncr_t *ncr = (ncr_t *) priv; /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ @@ -405,8 +404,7 @@ ncr53c400_dma_mode_ext(void *priv, void *ext_priv) ncr->tcr &= ~TCR_LAST_BYTE_SENT; ncr->isr &= ~STATUS_END_OF_DMA; ncr->dma_mode = DMA_IDLE; - } else - ncr53c400_log("Continuing DMA, mode bit=%02x, block loaded=%d, waitcomplete=%d.\n", ncr->mode, ncr400->block_count_loaded, ncr->wait_complete); + } } static void From 3c3e53e8b0e2c25711b3bccdb313ebefe2598b3b Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 13 May 2024 02:03:49 +0200 Subject: [PATCH 933/936] PS/2 KBC: Different approach to fix the Soyo 4SAW2 - it's only ever seen with ASIC KBC's (Holtek, MB-300E, and VIA VT82C42N), so I have added a Holtek controller that's basically an AMI with an ASIC flag. --- src/device/kbc_at.c | 115 +++++++++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 50 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 74c5d83d1..179cca5ec 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -91,6 +91,8 @@ #define KBC_VEN_IBM 0x34 #define KBC_VEN_MASK 0x7c +#define KBC_IS_ASIC 0x80000000 + #define FLAG_CLOCK 0x01 #define FLAG_CACHE 0x02 #define FLAG_PS2 0x04 @@ -99,7 +101,7 @@ enum { STATE_RESET = 0, /* KBC reset state, only accepts command AA. */ STATE_KBC_DELAY_OUT, /* KBC is sending one single byte. */ - STATE_IRQC_MAIN_IBF, /* KBC checking if the input buffer is full, clear IRQ's first. */ + STATE_KBC_AMI_OUT, /* KBC waiting for OBF - needed for AMIKey commands that require clearing of the output byte. */ STATE_MAIN_IBF, /* KBC checking if the input buffer is full. */ STATE_MAIN_KBD, /* KBC checking if the keyboard has anything to send. */ STATE_MAIN_AUX, /* KBC checking if the auxiliary has anything to send. */ @@ -110,11 +112,10 @@ enum { STATE_SCAN_KBD, /* KBC is waiting for the keyboard command response. */ STATE_SEND_AUX, /* KBC is sending command to the auxiliary device. */ STATE_SCAN_AUX, /* KBC is waiting for the auxiliary command response. */ - STATE_IRQ, /* KBC is raising the IRQ. */ + STATE_IRQ = 0x10, /* KBC is raising the IRQ. */ STATE_KBC_IRQ, STATE_AUX_IRQ, - STATE_KBC_DELAY_IRQ, - STATE_IRQC_WAIT, + STATE_KBC_DELAY_IRQ }; typedef struct atkbc_t { @@ -379,23 +380,23 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) if (dev->misc_flags & FLAG_PS2) { if (channel >= 2) { dev->status |= STAT_MFULL; - if ((kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM)) { - if (dev->mem[0x20] & 0x02) { + if ((kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM) || (dev->flags & KBC_IS_ASIC)) { + if (dev->mem[0x20] & 0x02) picint_common(1 << 12, 0, 1, NULL); - dev->state = STATE_IRQC_WAIT; - } - // picint_common(1 << 1, 0, 0, NULL); + picint_common(1 << 1, 0, 0, NULL); } else if (dev->mem[0x20] & 0x02) dev->state = STATE_AUX_IRQ; } else if (channel == 1) { - if ((kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM)) { - if (dev->mem[0x20] & 0x01) { + if ((kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM) || (dev->flags & KBC_IS_ASIC)) { + if (dev->mem[0x20] & 0x01) picint_common(1 << 1, 0, 1, NULL); - dev->state = STATE_IRQC_WAIT; - } - // picint_common(1 << 12, 0, 0, NULL); + picint_common(1 << 12, 0, 0, NULL); } else if (dev->mem[0x20] & 0x01) dev->state = STATE_IRQ; + } else if ((channel == 0) && (dev->flags & KBC_IS_ASIC)) { + if (dev->mem[0x20] & 0x01) + picint_common(1 << 1, 0, 1, NULL); + picint_common(1 << 12, 0, 0, NULL); } } else if (dev->mem[0x20] & 0x01) picintlevel(1 << 1, &dev->irq_state); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */ @@ -504,6 +505,10 @@ kbc_at_poll_at(atkbc_t *dev) kbc_at_process_cmd(dev); } break; + case STATE_KBC_AMI_OUT: + if (dev->status & STAT_OFULL) + break; + fallthrough; case STATE_MAIN_IBF: default: at_main_ibf: @@ -531,6 +536,9 @@ at_main_ibf: /* Keyboard controller command want to output a single byte. */ kbc_at_log("ATkbc: %02X coming from channel %i with high status %02X\n", dev->val, dev->channel, dev->stat_hi); kbc_send_to_ob(dev, dev->val, dev->channel, dev->stat_hi); +#if 0 + dev->state = (dev->pending == 2) ? STATE_KBC_AMI_OUT : STATE_MAIN_IBF; +#endif dev->state = STATE_MAIN_IBF; dev->pending = 0; goto at_main_ibf; @@ -609,8 +617,6 @@ kbc_scan_aux_ps2(atkbc_t *dev) static void kbc_at_poll_ps2(atkbc_t *dev) { - static uint8_t phase = 0; - switch (dev->state) { case STATE_RESET: if (dev->status & STAT_IFULL) { @@ -619,16 +625,9 @@ kbc_at_poll_ps2(atkbc_t *dev) kbc_at_process_cmd(dev); } break; - case STATE_IRQC_WAIT: - kbc_at_log("ATkbc: IRQ clear wait...\n"); - phase = (phase + 1) & 1; - if (phase) - dev->state = STATE_IRQC_MAIN_IBF; - break; - case STATE_IRQC_MAIN_IBF: - kbc_at_log("ATkbc: Clearing IRQ 1 and 12 (Main/IBF)...\n"); - picint_common(1 << 1, 0, 0, NULL); - picint_common(1 << 12, 0, 0, NULL); + case STATE_KBC_AMI_OUT: + if (dev->status & STAT_OFULL) + break; fallthrough; case STATE_MAIN_IBF: default: @@ -676,41 +675,37 @@ ps2_main_ibf: /* Keyboard controller command want to output a single byte. */ kbc_at_log("ATkbc: %02X coming from channel %i with high status %02X\n", dev->val, dev->channel, dev->stat_hi); kbc_send_to_ob(dev, dev->val, dev->channel, dev->stat_hi); +#if 0 + dev->state = (dev->pending == 2) ? STATE_KBC_AMI_OUT : STATE_MAIN_IBF; +#endif dev->pending = 0; - dev->state = STATE_KBC_DELAY_IRQ; + if (dev->flags & KBC_IS_ASIC) + dev->state = STATE_MAIN_IBF; + else + dev->state = STATE_KBC_DELAY_IRQ; break; case STATE_IRQ: - if (dev->mem[0x20] & 0x01) { - kbc_at_log("ATkbc: Raising IRQ 1 (keyboard)...\n"); + kbc_at_log("ATkbc: Raising IRQ 1 (keyboard)...\n"); + if (dev->mem[0x20] & 0x01) picint_common(1 << 1, 0, 1, NULL); - dev->state = STATE_IRQC_WAIT; - } else { - kbc_at_log("ATkbc: Noping IRQ 1 (keyboard)...\n"); - dev->state = STATE_MAIN_IBF; - } + picint_common(1 << 12, 0, 0, NULL); + dev->state = STATE_MAIN_IBF; break; case STATE_AUX_IRQ: kbc_at_log("ATkbc: Raising IRQ 12 (mouse)...\n"); - if (dev->mem[0x20] & 0x02) { + if (dev->mem[0x20] & 0x02) picint_common(1 << 12, 0, 1, NULL); - dev->state = STATE_IRQC_WAIT; - } else - dev->state = STATE_MAIN_IBF; + picint_common(1 << 1, 0, 0, NULL); + dev->state = STATE_MAIN_IBF; break; case STATE_KBC_DELAY_IRQ: kbc_at_log("ATkbc: Raising IRQ 1 (KBC delay)...\n"); - if (dev->mem[0x20] & 0x01) { + if (dev->mem[0x20] & 0x01) picint_common(1 << 1, 0, 1, NULL); - dev->state = STATE_IRQC_WAIT; - break; - } else { - dev->state = STATE_MAIN_IBF; - goto ps2_main_ibf; - } - case STATE_KBC_OUT: - kbc_at_log("ATkbc: Clearing IRQ 1 and 12 (KBC out)...\n"); - picint_common(1 << 1, 0, 0, NULL); picint_common(1 << 12, 0, 0, NULL); + dev->state = STATE_MAIN_IBF; + goto ps2_main_ibf; + case STATE_KBC_OUT: /* Keyboard controller command want to output multiple bytes. */ if (dev->status & STAT_IFULL) { /* Data from host aborts dumping. */ @@ -721,16 +716,22 @@ ps2_main_ibf: if (!(dev->status & STAT_OFULL)) { kbc_at_log("ATkbc: %02X coming from channel 0\n", dev->key_ctrl_queue[dev->key_ctrl_queue_start] & 0xff); kbc_send_to_ob(dev, dev->key_ctrl_queue[dev->key_ctrl_queue_start], 0, 0x00); - dev->state = STATE_KBC_IRQ; + if (dev->flags & KBC_IS_ASIC) { + dev->key_ctrl_queue_start = (dev->key_ctrl_queue_start + 1) & 0x3f; + if (dev->key_ctrl_queue_start == dev->key_ctrl_queue_end) + dev->state = STATE_MAIN_IBF; + } else + dev->state = STATE_KBC_IRQ; } break; case STATE_KBC_IRQ: kbc_at_log("ATkbc: Raising IRQ 1 (KBC)...\n"); if (dev->mem[0x20] & 0x01) picint_common(1 << 1, 0, 1, NULL); + picint_common(1 << 12, 0, 0, NULL); dev->key_ctrl_queue_start = (dev->key_ctrl_queue_start + 1) & 0x3f; if (dev->key_ctrl_queue_start == dev->key_ctrl_queue_end) - dev->state = STATE_IRQC_WAIT; + dev->state = STATE_MAIN_IBF; else dev->state = STATE_KBC_OUT; break; @@ -2572,6 +2573,20 @@ const device_t keyboard_ps2_ami_device = { .config = NULL }; +const device_t keyboard_ps2_holtek_device = { + .name = "PS/2 Keyboard (Holtek)", + .internal_name = "keyboard_ps2_holtek", + .flags = DEVICE_KBC, + .local = KBC_TYPE_PS2_1 | KBC_VEN_AMI | KBC_IS_ASIC, + .init = kbc_at_init, + .close = kbc_at_close, + .reset = kbc_at_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t keyboard_ps2_phoenix_device = { .name = "PS/2 Keyboard (Phoenix)", .internal_name = "keyboard_ps2_phoenix", From 55e1ca7dc14a650d7997b727ed04807acfeb945f Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 13 May 2024 02:22:05 +0200 Subject: [PATCH 934/936] PS/2 ASIC KBC: A minor fix. --- src/device/kbc_at.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 179cca5ec..20f94f942 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -679,9 +679,10 @@ ps2_main_ibf: dev->state = (dev->pending == 2) ? STATE_KBC_AMI_OUT : STATE_MAIN_IBF; #endif dev->pending = 0; - if (dev->flags & KBC_IS_ASIC) + if (dev->flags & KBC_IS_ASIC) { dev->state = STATE_MAIN_IBF; - else + goto ps2_main_ibf; + } else dev->state = STATE_KBC_DELAY_IRQ; break; case STATE_IRQ: From 1a255693e9fcb777cfd1cfa73e54ea24ae3d61fa Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 14 May 2024 21:25:25 +0200 Subject: [PATCH 935/936] PS/2 KBC: Changed the way the IRQ delay is done, fixes #4451. --- src/device/kbc_at.c | 151 ++++++++++++++++++-------------------------- 1 file changed, 63 insertions(+), 88 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 20f94f942..74ade4cd3 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -91,7 +91,7 @@ #define KBC_VEN_IBM 0x34 #define KBC_VEN_MASK 0x7c -#define KBC_IS_ASIC 0x80000000 +#define KBC_FLAG_IS_ASIC 0x80000000 #define FLAG_CLOCK 0x01 #define FLAG_CACHE 0x02 @@ -111,11 +111,7 @@ enum { STATE_SEND_KBD, /* KBC is sending command to the keyboard. */ STATE_SCAN_KBD, /* KBC is waiting for the keyboard command response. */ STATE_SEND_AUX, /* KBC is sending command to the auxiliary device. */ - STATE_SCAN_AUX, /* KBC is waiting for the auxiliary command response. */ - STATE_IRQ = 0x10, /* KBC is raising the IRQ. */ - STATE_KBC_IRQ, - STATE_AUX_IRQ, - STATE_KBC_DELAY_IRQ + STATE_SCAN_AUX /* KBC is waiting for the auxiliary command response. */ }; typedef struct atkbc_t { @@ -140,9 +136,9 @@ typedef struct atkbc_t { uint8_t stat_hi; uint8_t pending; uint8_t irq_state; + uint8_t do_irq; + uint8_t is_asic; uint8_t pad; - uint8_t pad0; - uint8_t pad1; uint8_t mem[0x100]; @@ -353,16 +349,38 @@ kbc_translate(atkbc_t *dev, uint8_t val) return ret; } +static void +kbc_set_do_irq(atkbc_t *dev, uint8_t channel) +{ + dev->channel = channel; + dev->do_irq = 1; +} + +static void +kbc_do_irq(atkbc_t *dev) +{ + if (dev->do_irq) { + /* WARNING: On PS/2, all IRQ's are level-triggered, but the IBM PS/2 KBC firmware is explicitly + written to pulse its P2 IRQ bits, so they should be kept as as edge-triggered here. */ + picint_common(1 << 1, 0, 0, NULL); + picint_common(1 << 12, 0, 0, NULL); + if (dev->channel >= 2) + picint_common(1 << 12, 0, 1, NULL); + else + picint_common(1 << 1, 0, 1, NULL); + + dev->do_irq = 0; + } +} + static void kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) { uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; int temp = (channel == 1) ? kbc_translate(dev, val) : ((int) val); - if (temp == -1) { - dev->state = STATE_MAIN_IBF; + if (temp == -1) return; - } if ((kbc_ven == KBC_VEN_AMI) || (kbc_ven == KBC_VEN_TRIGEM_AMI) || (dev->misc_flags & FLAG_PS2)) @@ -373,34 +391,24 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) kbc_at_log("ATkbc: Sending %02X to the output buffer on channel %i...\n", temp, channel); dev->status = (dev->status & ~0xf0) | STAT_OFULL | stat_hi; - dev->state = STATE_MAIN_IBF; + dev->do_irq = 0; /* WARNING: On PS/2, all IRQ's are level-triggered, but the IBM PS/2 KBC firmware is explicitly written to pulse its P2 IRQ bits, so they should be kept as as edge-triggered here. */ if (dev->misc_flags & FLAG_PS2) { if (channel >= 2) { dev->status |= STAT_MFULL; - if ((kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM) || (dev->flags & KBC_IS_ASIC)) { - if (dev->mem[0x20] & 0x02) - picint_common(1 << 12, 0, 1, NULL); - picint_common(1 << 1, 0, 0, NULL); - } else if (dev->mem[0x20] & 0x02) - dev->state = STATE_AUX_IRQ; - } else if (channel == 1) { - if ((kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM) || (dev->flags & KBC_IS_ASIC)) { - if (dev->mem[0x20] & 0x01) - picint_common(1 << 1, 0, 1, NULL); - picint_common(1 << 12, 0, 0, NULL); - } else if (dev->mem[0x20] & 0x01) - dev->state = STATE_IRQ; - } else if ((channel == 0) && (dev->flags & KBC_IS_ASIC)) { - if (dev->mem[0x20] & 0x01) - picint_common(1 << 1, 0, 1, NULL); - picint_common(1 << 12, 0, 0, NULL); - } + + if (dev->mem[0x20] & 0x02) + kbc_set_do_irq(dev, channel); + } else if (dev->mem[0x20] & 0x01) + kbc_set_do_irq(dev, channel); } else if (dev->mem[0x20] & 0x01) picintlevel(1 << 1, &dev->irq_state); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */ + if (dev->is_asic || (kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM)) + kbc_do_irq(dev); + dev->ob = temp; } @@ -595,6 +603,7 @@ kbc_scan_kbd_ps2(atkbc_t *dev) kbc_at_log("ATkbc: %02X coming from channel 1\n", dev->ports[0]->out_new & 0xff); kbc_send_to_ob(dev, dev->ports[0]->out_new, 1, 0x00); dev->ports[0]->out_new = -1; + dev->state = STATE_MAIN_IBF; return 1; } @@ -608,6 +617,7 @@ kbc_scan_aux_ps2(atkbc_t *dev) kbc_at_log("ATkbc: %02X coming from channel 2\n", dev->ports[1]->out_new & 0xff); kbc_send_to_ob(dev, dev->ports[1]->out_new, 2, 0x00); dev->ports[1]->out_new = -1; + dev->state = STATE_MAIN_IBF; return 1; } @@ -617,6 +627,8 @@ kbc_scan_aux_ps2(atkbc_t *dev) static void kbc_at_poll_ps2(atkbc_t *dev) { + kbc_do_irq(dev); + switch (dev->state) { case STATE_RESET: if (dev->status & STAT_IFULL) { @@ -631,7 +643,6 @@ kbc_at_poll_ps2(atkbc_t *dev) fallthrough; case STATE_MAIN_IBF: default: -ps2_main_ibf: if (dev->status & STAT_IFULL) kbc_ibf_process(dev); else if (!(dev->status & STAT_OFULL)) { @@ -655,20 +666,22 @@ ps2_main_ibf: if (dev->status & STAT_IFULL) kbc_ibf_process(dev); else { - if (!kbc_scan_kbd_ps2(dev)) - dev->state = STATE_MAIN_IBF; + (void) kbc_scan_kbd_ps2(dev); + dev->state = STATE_MAIN_IBF; } break; case STATE_MAIN_AUX: if (dev->status & STAT_IFULL) kbc_ibf_process(dev); else { - if (!kbc_scan_aux_ps2(dev)) - dev->state = STATE_MAIN_IBF; + (void) kbc_scan_aux_ps2(dev); + dev->state = STATE_MAIN_IBF; } break; case STATE_MAIN_BOTH: - if (!kbc_scan_kbd_ps2(dev)) + if (kbc_scan_kbd_ps2(dev)) + dev->state = STATE_MAIN_IBF; + else dev->state = STATE_MAIN_AUX; break; case STATE_KBC_DELAY_OUT: @@ -678,34 +691,10 @@ ps2_main_ibf: #if 0 dev->state = (dev->pending == 2) ? STATE_KBC_AMI_OUT : STATE_MAIN_IBF; #endif + dev->state = STATE_MAIN_IBF; dev->pending = 0; - if (dev->flags & KBC_IS_ASIC) { - dev->state = STATE_MAIN_IBF; - goto ps2_main_ibf; - } else - dev->state = STATE_KBC_DELAY_IRQ; + // goto ps2_main_ibf; break; - case STATE_IRQ: - kbc_at_log("ATkbc: Raising IRQ 1 (keyboard)...\n"); - if (dev->mem[0x20] & 0x01) - picint_common(1 << 1, 0, 1, NULL); - picint_common(1 << 12, 0, 0, NULL); - dev->state = STATE_MAIN_IBF; - break; - case STATE_AUX_IRQ: - kbc_at_log("ATkbc: Raising IRQ 12 (mouse)...\n"); - if (dev->mem[0x20] & 0x02) - picint_common(1 << 12, 0, 1, NULL); - picint_common(1 << 1, 0, 0, NULL); - dev->state = STATE_MAIN_IBF; - break; - case STATE_KBC_DELAY_IRQ: - kbc_at_log("ATkbc: Raising IRQ 1 (KBC delay)...\n"); - if (dev->mem[0x20] & 0x01) - picint_common(1 << 1, 0, 1, NULL); - picint_common(1 << 12, 0, 0, NULL); - dev->state = STATE_MAIN_IBF; - goto ps2_main_ibf; case STATE_KBC_OUT: /* Keyboard controller command want to output multiple bytes. */ if (dev->status & STAT_IFULL) { @@ -717,25 +706,11 @@ ps2_main_ibf: if (!(dev->status & STAT_OFULL)) { kbc_at_log("ATkbc: %02X coming from channel 0\n", dev->key_ctrl_queue[dev->key_ctrl_queue_start] & 0xff); kbc_send_to_ob(dev, dev->key_ctrl_queue[dev->key_ctrl_queue_start], 0, 0x00); - if (dev->flags & KBC_IS_ASIC) { - dev->key_ctrl_queue_start = (dev->key_ctrl_queue_start + 1) & 0x3f; - if (dev->key_ctrl_queue_start == dev->key_ctrl_queue_end) - dev->state = STATE_MAIN_IBF; - } else - dev->state = STATE_KBC_IRQ; + dev->key_ctrl_queue_start = (dev->key_ctrl_queue_start + 1) & 0x3f; + if (dev->key_ctrl_queue_start == dev->key_ctrl_queue_end) + dev->state = STATE_MAIN_IBF; } break; - case STATE_KBC_IRQ: - kbc_at_log("ATkbc: Raising IRQ 1 (KBC)...\n"); - if (dev->mem[0x20] & 0x01) - picint_common(1 << 1, 0, 1, NULL); - picint_common(1 << 12, 0, 0, NULL); - dev->key_ctrl_queue_start = (dev->key_ctrl_queue_start + 1) & 0x3f; - if (dev->key_ctrl_queue_start == dev->key_ctrl_queue_end) - dev->state = STATE_MAIN_IBF; - else - dev->state = STATE_KBC_OUT; - break; case STATE_KBC_PARAM: /* Keyboard controller command wants data, wait for said data. */ if (dev->status & STAT_IFULL) { @@ -2108,7 +2083,7 @@ kbc_at_write(uint16_t port, uint8_t val, void *priv) /* Fast A20 - ignore all other bits. */ write_p2_fast_a20(dev, (dev->p2 & 0xfd) | (val & 0x02)); - dev->wantdata = 0; + dev->wantdata = 0; dev->state = STATE_MAIN_IBF; return; } @@ -2155,9 +2130,7 @@ kbc_at_read(uint16_t port, void *priv) This also means that in AT mode, the IRQ is level-triggered. */ if (!(dev->misc_flags & FLAG_PS2)) picintclevel(1 << 1, &dev->irq_state); - /* I"m not even sure if this is correct but the PB450 absolutely requires this. */ - if ((strstr(machine_get_internal_name(), "pb41") != NULL) && - (cpu_override_dynarec == 1)) + if ((strstr(machine_get_internal_name(), "pb41") != NULL) && (cpu_override_dynarec == 1)) cpu_override_dynarec = 0; break; @@ -2276,6 +2249,8 @@ kbc_at_init(const device_t *info) dev->flags = info->local; + dev->is_asic = !!(info->local & KBC_FLAG_IS_ASIC); + video_reset(gfxcard[0]); kbc_at_reset(dev); @@ -2306,9 +2281,9 @@ kbc_at_init(const device_t *info) case KBC_VEN_ACER: case KBC_VEN_GENERIC: - case KBC_VEN_IBM: case KBC_VEN_NCR: case KBC_VEN_IBM_PS1: + case KBC_VEN_IBM: case KBC_VEN_COMPAQ: dev->write64_ven = write64_generic; break; @@ -2578,7 +2553,7 @@ const device_t keyboard_ps2_holtek_device = { .name = "PS/2 Keyboard (Holtek)", .internal_name = "keyboard_ps2_holtek", .flags = DEVICE_KBC, - .local = KBC_TYPE_PS2_1 | KBC_VEN_AMI | KBC_IS_ASIC, + .local = KBC_TYPE_PS2_1 | KBC_VEN_AMI | KBC_FLAG_IS_ASIC, .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, @@ -2617,8 +2592,8 @@ const device_t keyboard_ps2_tg_ami_device = { }; const device_t keyboard_ps2_mca_1_device = { - .name = "PS/2 Keyboard", - .internal_name = "keyboard_ps2", + .name = "PS/2 Keyboard (IBM PS/2 MCA Type 1)", + .internal_name = "keyboard_ps2_mca_1", .flags = DEVICE_KBC, .local = KBC_TYPE_PS2_1 | KBC_VEN_IBM, .init = kbc_at_init, @@ -2631,7 +2606,7 @@ const device_t keyboard_ps2_mca_1_device = { }; const device_t keyboard_ps2_mca_2_device = { - .name = "PS/2 Keyboard", + .name = "PS/2 Keyboard (IBM PS/2 MCA Type 2)", .internal_name = "keyboard_ps2_mca_2", .flags = DEVICE_KBC, .local = KBC_TYPE_PS2_2 | KBC_VEN_IBM, From 5af50e22edcf981b23e2d3b697f920fdd5fe0525 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 14 May 2024 21:25:54 +0200 Subject: [PATCH 936/936] And the forgotten keyboard.h. --- src/include/86box/keyboard.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 5058c821e..846123627 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -242,6 +242,7 @@ extern const device_t keyboard_ps2_ps1_device; extern const device_t keyboard_ps2_ps1_pci_device; extern const device_t keyboard_ps2_xi8088_device; extern const device_t keyboard_ps2_ami_device; +extern const device_t keyboard_ps2_holtek_device; extern const device_t keyboard_ps2_tg_ami_device; extern const device_t keyboard_ps2_tg_ami_green_device; extern const device_t keyboard_ps2_olivetti_device;