From 012a450c9b5f3ded0110232b0cceb2e11ea97990 Mon Sep 17 00:00:00 2001 From: conan7123 Date: Thu, 2 Jan 2025 22:34:18 +0100 Subject: [PATCH 01/16] Add machine Compaq Presario 7100/7200 Series Machine (486) --- src/include/86box/machine.h | 1 + src/machine/m_at_386dx_486.c | 43 ++++++++++++++++++++++++++++++++++++ src/machine/machine_table.c | 39 ++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index c976d15a7..44a55d94f 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -593,6 +593,7 @@ extern int machine_at_pcm5330_init(const machine_t *); extern int machine_at_ecs486_init(const machine_t *); extern int machine_at_hot433a_init(const machine_t *); +extern int machine_at_pl4600c_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 *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 253f7522a..1c35d7290 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -48,6 +48,7 @@ #include <86box/hwm.h> #include <86box/machine.h> #include <86box/plat_unused.h> +#include <86box/sound.h> int machine_at_acc386_init(const machine_t *model) @@ -1962,6 +1963,48 @@ machine_at_hot433a_init(const machine_t *model) return ret; } +int +machine_at_pl4600c_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/pl4600c/SST29EE010.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); /* Slot 01 */ + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); /* Slot 02 */ + pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); /* Onboard */ + pci_register_slot(0x13, PCI_CARD_VIDEO, 0, 0, 0, 0); /* Onboard */ + + + device_add(&umc_hb4_device); + device_add(&umc_8886af_device); + device_add(&um8663af_device); + device_add(&sst_flash_29ee010_device); + device_add(&keyboard_ps2_ami_pci_device); + + if (gfxcard[0] == VID_INTERNAL) + device_add(&gd5430_onboard_pci_device); + + if (sound_card_current[0] == SOUND_INTERNAL) + device_add(&ess_1688_device); + + if (fdc_current[0] == FDC_INTERNAL){ + fdd_set_turbo(0, 1); + fdd_set_turbo(1, 1); + } + + return ret; +} + int machine_at_atc1415_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index ad0844cdc..a414bbd0d 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -8668,6 +8668,45 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + { + .name = "[UMC 8881] Compaq Presario 7100/7200 Series 486", + .internal_name = "pl4600c", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_UMC_UM8881, + .init = machine_at_pl4600c_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_IDE_DUAL | MACHINE_VIDEO | MACHINE_SOUND | 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 = &ess_1688_device, + .net_device = NULL + }, /* Has a VIA VT82C406 KBC+RTC that likely has identical commands to the VT82C42N. */ { .name = "[VIA VT82C496G] DFI G486VPA", From 45d952c8cf1e6dde31919e2ca882f8cf4a4166dd Mon Sep 17 00:00:00 2001 From: conan7123 Date: Thu, 2 Jan 2025 22:51:55 +0100 Subject: [PATCH 02/16] Add comment for pl4600c / Compaq Presario 7100 in machine table --- src/machine/machine_table.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index a414bbd0d..f5a0a9d1c 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -8668,6 +8668,8 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Compaq Presario 7100 / 7200 Series, using MiTAC/Trigon PL4600C (486). */ + /* Has a VIA VT82C42N KBC. */ { .name = "[UMC 8881] Compaq Presario 7100/7200 Series 486", .internal_name = "pl4600c", From cc73c0efe4b404af946041b9faf1f2c85afdca07 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 2 Jan 2025 23:49:50 +0100 Subject: [PATCH 03/16] Late day changes (January 2nd, 2025) Actually recognize the Trantor 228 MCA SCSI controller as such (bit 3 of status is for the PS/2 MCA bus type of the 128 controller) --- src/scsi/scsi_t128.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/scsi/scsi_t128.c b/src/scsi/scsi_t128.c index 3a49f599f..c878bbb91 100644 --- a/src/scsi/scsi_t128.c +++ b/src/scsi/scsi_t128.c @@ -509,6 +509,9 @@ t128_init(const device_t *info) if (!t128->bios_enabled && !(info->flags & DEVICE_MCA)) t128->status |= 0x80; + if (info->flags & DEVICE_MCA) + t128->status |= 0x08; + if (info->local == 0) timer_add(&t128->timer, t128_callback, t128, 0); From 06923a28007550bc8d060399382f513c7ffb850d Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 Jan 2025 00:15:28 +0100 Subject: [PATCH 04/16] Switched back to raw input - it appears it *does* work with the hook. --- src/86box.c | 10 ++++--- src/include/86box/86box.h | 2 +- src/qt/qt_main.cpp | 48 +++++++-------------------------- src/qt/qt_winrawinputfilter.cpp | 9 ++----- 4 files changed, 19 insertions(+), 50 deletions(-) diff --git a/src/86box.c b/src/86box.c index fc698a5ee..8fa74fd4b 100644 --- a/src/86box.c +++ b/src/86box.c @@ -206,7 +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 */ -int raw_input = 0; /* (C) Use raw input */ +int hook_enabled = 1; /* (C) Keyboard hook is enabled */ char uuid[MAX_UUID_LEN] = { '\0' }; /* (C) UUID or machine identifier */ int other_ide_present = 0; /* IDE controllers from non-IDE cards are @@ -453,6 +453,8 @@ delete_nvr_file(uint8_t flash) fn = NULL; } +extern void device_find_all_descs(void); + /* * Perform initial startup of the PC. * @@ -562,7 +564,7 @@ usage: 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("-W or --raw - uses raw input (compatibility-only outside Windows)\n"); + printf("-W or --nohook - disables keyboard hook (compatibility-only outside Windows)\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"); printf("-Z or --lastvmpath - the last parameter is VM path rather than config\n"); @@ -638,8 +640,8 @@ usage: dump_missing = 1; } else if (!strcasecmp(argv[c], "--donothing") || !strcasecmp(argv[c], "-Y")) { do_nothing = 1; - } else if (!strcasecmp(argv[c], "--raw") || !strcasecmp(argv[c], "-W")) { - raw_input = 1; + } else if (!strcasecmp(argv[c], "--nohook") || !strcasecmp(argv[c], "-W")) { + hook_enabled = 0; } else if (!strcasecmp(argv[c], "--keycodes") || !strcasecmp(argv[c], "-K")) { if ((c + 1) == argc) goto usage; diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index fb4a182a0..ffa670b7e 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -165,7 +165,7 @@ extern _Atomic double mouse_y_error; /* Mouse error accumulator - Y */ #endif extern int pit_mode; /* (C) force setting PIT mode */ extern int fm_driver; /* (C) select FM sound driver */ -extern int raw_input; /* (C) Use raw input */ +extern int hook_enabled; /* (C) Keyboard hook is enabled */ /* Keyboard variables for future key combination redefinition. */ extern uint16_t key_prefix_1_1; diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index c602b9ea1..6da0b0285 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -43,6 +43,7 @@ Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin) #endif #ifdef Q_OS_WINDOWS +# include "qt_rendererstack.hpp" # include "qt_winrawinputfilter.hpp" # include "qt_winmanagerfilter.hpp" # include <86box/win.h> @@ -143,50 +144,20 @@ keyboard_getkeymap() } } -static void -kbd_handle(uint16_t scancode, uint16_t flags) -{ - if (flags & LLKHF_EXTENDED) - 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 < (sizeof(scancode_map) / sizeof(scancode_map[0]))) && (scancode != scancode_map[scancode])) { - // pclog("Scan code remap: %03X -> %03X\n", scancode, scancode_map[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. */ - /* 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(!(flags & LLKHF_UP), scancode); - - main_window->checkFullscreenHotkey(); -} - static LRESULT CALLBACK emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { LPKBDLLHOOKSTRUCT lpKdhs = (LPKBDLLHOOKSTRUCT) lParam; /* Checks if CTRL was pressed. */ BOOL bCtrlDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1); + BOOL is_over_window = (GetForegroundWindow() == ((HWND) main_window->winId())); - if ((GetForegroundWindow() == ((HWND) main_window->winId())) && !(lpKdhs->scanCode & 0xff00)) - kbd_handle(lpKdhs->scanCode, lpKdhs->flags); + if (show_second_monitors) for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) { + const auto &secondaryRenderer = main_window->renderers[monitor_index]; + is_over_window = is_over_window && (GetForegroundWindow() == ((HWND) secondaryRenderer->winId())); + } - if ((nCode < 0) || (nCode != HC_ACTION) || (!mouse_capture && !video_fullscreen)) + if ((nCode < 0) || (nCode != HC_ACTION)/* || (!mouse_capture && !video_fullscreen)*/ || !is_over_window) return CallNextHookEx(NULL, nCode, wParam, lParam); else if ((lpKdhs->scanCode == 0x01) && (lpKdhs->flags & LLKHF_ALTDOWN) && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) @@ -480,7 +451,7 @@ main(int argc, char *argv[]) /* Force raw input if a debugger is present. */ if (IsDebuggerPresent()) { pclog("WARNING: Debugged detected, forcing raw input\n"); - raw_input = 1; + hook_enabled = 0; } /* Setup raw input */ @@ -547,7 +518,8 @@ main(int argc, char *argv[]) }); #ifdef Q_OS_WINDOWS - if (!raw_input) { + if (hook_enabled) { + /* Yes, low-level hooks *DO* work raw input, at least global ones. */ llhook = SetWindowsHookEx(WH_KEYBOARD_LL, emu_LowLevelKeyboardProc, NULL, 0); atexit([] () -> void { if (llhook) diff --git a/src/qt/qt_winrawinputfilter.cpp b/src/qt/qt_winrawinputfilter.cpp index 4ff515c49..2c11a068a 100644 --- a/src/qt/qt_winrawinputfilter.cpp +++ b/src/qt/qt_winrawinputfilter.cpp @@ -64,9 +64,7 @@ WindowsRawInputFilter::Register(MainWindow *window) .hwndTarget = nullptr} }; - if (raw_input && (RegisterRawInputDevices(rid, 2, sizeof(rid[0])) == FALSE)) - return std::unique_ptr(nullptr); - else if (!raw_input && RegisterRawInputDevices(&(rid[1]), 1, sizeof(rid[0])) == FALSE) + if (RegisterRawInputDevices(rid, 2, sizeof(rid[0])) == FALSE) return std::unique_ptr(nullptr); std::unique_ptr inputfilter(new WindowsRawInputFilter(window)); @@ -97,10 +95,7 @@ WindowsRawInputFilter::~WindowsRawInputFilter() .hwndTarget = NULL} }; - if (raw_input) - RegisterRawInputDevices(rid, 2, sizeof(rid[0])); - else - RegisterRawInputDevices(&(rid[1]), 1, sizeof(rid[0])); + RegisterRawInputDevices(rid, 2, sizeof(rid[0])); } bool From 509e1e596151d70eb5d52ab0c52a2def83485e05 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 Jan 2025 00:27:21 +0100 Subject: [PATCH 05/16] cdrom/cdrom.c that I forgot to commit before. --- src/cdrom/cdrom.c | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index ac002ab65..4b01a109d 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -1426,33 +1426,11 @@ cdrom_get_track_buffer(cdrom_t *dev, uint8_t *buf) buf[8] = 0x00; } +/* TODO: Actually implement this properly. */ void cdrom_get_q(cdrom_t *dev, uint8_t *buf, int *curtoctrk, uint8_t mode) { - track_info_t ti; - int first_track; - int last_track; - - if (dev != NULL) { - dev->ops->get_tracks(dev, &first_track, &last_track); - dev->ops->get_track_info(dev, *curtoctrk, 0, &ti); - buf[0] = (ti.attr << 4) & 0xf0; - buf[1] = ti.number; - buf[2] = bin2bcd(*curtoctrk + 1); - buf[3] = ti.m; - buf[4] = ti.s; - buf[5] = ti.f; - buf[6] = 0x00; - dev->ops->get_track_info(dev, 1, 0, &ti); - buf[7] = ti.m; - buf[8] = ti.s; - buf[9] = ti.f; - if (*curtoctrk >= (last_track + 1)) - *curtoctrk = 0; - else if (mode) - *curtoctrk = *curtoctrk + 1; - } else - memset(buf, 0x00, 10); + memset(buf, 0x00, 10); } uint8_t From 92e5ed6aaeaad4d665bce1f15d7e42067bc4ae53 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 Jan 2025 00:47:35 +0100 Subject: [PATCH 06/16] Keyboard hook: Fixed segmentation fault when non-primary monitors are enabled but none is actually in use. --- src/qt/qt_main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 6da0b0285..20af6a13d 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -154,7 +154,8 @@ emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) if (show_second_monitors) for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) { const auto &secondaryRenderer = main_window->renderers[monitor_index]; - is_over_window = is_over_window && (GetForegroundWindow() == ((HWND) secondaryRenderer->winId())); + is_over_window = is_over_window && (secondaryRenderer != nullptr) && + (GetForegroundWindow() == ((HWND) secondaryRenderer->winId())); } if ((nCode < 0) || (nCode != HC_ACTION)/* || (!mouse_capture && !video_fullscreen)*/ || !is_over_window) From 370c560c3423d40747bd8051febb17a39bce2197 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 Jan 2025 01:19:52 +0100 Subject: [PATCH 07/16] Only attempt Cue sheet parsing on files that end in .cue (in any letter case), fixes errors with some .ISO images. --- src/cdrom/cdrom.c | 4 ++-- src/cdrom/cdrom_image_backend.c | 16 +++++++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 4b01a109d..6d993f24a 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -2174,7 +2174,7 @@ cdrom_exit(uint8_t id) memset(dev->image_path, 0, sizeof(dev->image_path)); - pclog("cdrom_exit(%i): cdrom_insert(%i)\n", id, id); + cdrom_log("cdrom_exit(%i): cdrom_insert(%i)\n", id, id); cdrom_insert(id); } @@ -2252,7 +2252,7 @@ cdrom_reload(uint8_t id) #endif /* Signal media change to the emulated machine. */ - pclog("cdrom_reload(%i): cdrom_insert(%i)\n", id, id); + cdrom_log("cdrom_reload(%i): cdrom_insert(%i)\n", id, id); cdrom_insert(id); /* The drive was previously empty, transition directly to UNIT ATTENTION. */ diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index 3c09cb56c..9d065a0cb 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -436,7 +436,7 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) const uint64_t seek = (sect + 150 - idx->start + idx->file_start) * trk->sector_size; cdrom_image_backend_log("cdrom_read_sector(%08X): track %02X, index %02X, %016" PRIX64 ", %016" PRIX64 ", %i\n", - sector, track, index, trk->start, trk->sector_size); + sector, track, index, idx->start, trk->sector_size); if (track_is_raw) raw_size = trk->sector_size; @@ -1477,12 +1477,18 @@ cdi_close(cd_img_t *cdi) int cdi_set_device(cd_img_t *cdi, const char *path) { - int ret; + uintptr_t ext = path + strlen(path) - strrchr(path, '.'); + int ret; - if ((ret = cdi_load_cue(cdi, path))) - return ret; + cdrom_image_backend_log("cdi_set_device(): %" PRIu64 ", %lli, %s\n", + ext, strlen(path), path + strlen(path) - ext + 1); - cdi_clear_tracks(cdi); + if ((ext == 4) && !stricmp(path + strlen(path) - ext + 1, "CUE")) { + if ((ret = cdi_load_cue(cdi, path))) + return ret; + + cdi_clear_tracks(cdi); + } if ((ret = cdi_load_iso(cdi, path))) return ret; From 15715bbb79ad1b37cc00281a78c33422564343fd Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Wed, 7 Feb 2024 22:30:08 -0500 Subject: [PATCH 08/16] Add Ensoniq ES1370 Co-Authored-By: Cacodemon345 <38420290+Cacodemon345@users.noreply.github.com> --- src/include/86box/snd_akm4531.h | 22 + src/include/86box/sound.h | 1 + src/sound/snd_audiopci.c | 836 ++++++++++++++++++++++++-------- src/sound/sound.c | 1 + 4 files changed, 665 insertions(+), 195 deletions(-) create mode 100644 src/include/86box/snd_akm4531.h diff --git a/src/include/86box/snd_akm4531.h b/src/include/86box/snd_akm4531.h new file mode 100644 index 000000000..96f87b396 --- /dev/null +++ b/src/include/86box/snd_akm4531.h @@ -0,0 +1,22 @@ +/* + * 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. + * + * Ensoniq AudioPCI family emulation. + * + * Authors: Cacodemon345 + * + * Copyright 2024-2025 Cacodemon345. + */ +struct akm4531_t +{ + unsigned char registers[256]; +}; + +typedef struct akm4531_t akm4531_t; + +double akm4531_apply_master_vol(unsigned short sample); \ No newline at end of file diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index e5ae227fd..645d974dd 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -185,6 +185,7 @@ extern const device_t ess_soundpiper_32_mca_device; extern const device_t ess_chipchat_16_mca_device; /* Ensoniq AudioPCI */ +extern const device_t es1370_device; extern const device_t es1371_device; extern const device_t es1371_onboard_device; extern const device_t es1373_device; diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 7338a11fc..45b8d4c8c 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -8,15 +8,17 @@ * * Ensoniq AudioPCI family emulation. * - * - * * Authors: Sarah Walker, * RichardG, * Miran Grca, + * Jasmine Iwanek, + * Cacodemon345 * * Copyright 2008-2021 Sarah Walker. * Copyright 2021-2024 RichardG. - * Copyright 2021 Miran Grca. + * Copyright 2021 Miran Grca. + * Copyright 2024-2025 Jasmine Iwanek. + * Copyright 2024-2025 Cacodemon345. */ #include #include @@ -39,14 +41,15 @@ #include <86box/sound.h> #include <86box/timer.h> #include <86box/plat_unused.h> +#include <86box/snd_akm4531.h> #define N 16 -#define ES1371_NCoef 91 +#define ES137x_NCoef 91 -static float low_fir_es1371_coef[ES1371_NCoef]; +static float low_fir_es137x_coef[ES137x_NCoef]; -typedef struct es1371_t { +typedef struct es137x_t { uint8_t pci_command; uint8_t pci_serr; @@ -111,6 +114,9 @@ typedef struct es1371_t { int16_t out_l; int16_t out_r; + int16_t prev_out_l; + int16_t prev_out_r; + int32_t vol_l; int32_t vol_r; } dac[2], adc; @@ -130,11 +136,35 @@ typedef struct es1371_t { uint8_t pci_slot; int pos; - int16_t buffer[SOUNDBUFLEN * 2]; + int16_t buffer[WTBUFLEN * 2]; uint32_t type; -} es1371_t; + akm4531_t akm_codec; + + uint32_t calc_sample_rate; + uint32_t calc_sample_rate_synth; + + double interp_factor; + uint32_t interp_step; + + double interp_factor_synth; + uint32_t interp_step_synth; + + uint32_t step_pcm; + uint32_t step_synth; +} es137x_t; + +static const double akm4531_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 +}; + +static double akm4531_gain_2dbstep_5bits[0x20]; + +#define AUDIOPCI_ES1370 0x50001271 #define AUDIOPCI_ES1371 0x13710200 #define AUDIOPCI_ES1373 0x13710400 #define AUDIOPCI_CT5880 0x58800400 @@ -204,8 +234,8 @@ typedef struct es1371_t { #define FORMAT_MONO_16 2 #define FORMAT_STEREO_16 3 -static void es1371_fetch(es1371_t *dev, int dac_nr); -static void update_legacy(es1371_t *dev, uint32_t old_legacy_ctrl); +static void es137x_fetch(es137x_t *dev, int dac_nr); +static void update_legacy(es137x_t *dev, uint32_t old_legacy_ctrl); #ifdef ENABLE_AUDIOPCI_LOG int audiopci_do_log = ENABLE_AUDIOPCI_LOG; @@ -226,7 +256,7 @@ audiopci_log(const char *fmt, ...) #endif static void -es1371_update_irqs(es1371_t *dev) +es137x_update_irqs(es137x_t *dev) { int irq = 0; @@ -257,63 +287,63 @@ es1371_update_irqs(es1371_t *dev) } static void -es1371_update_tx_irq(es1371_t *dev) +es137x_update_tx_irq(es137x_t *dev) { dev->uart_status &= ~UART_STATUS_TXINT; if (((dev->uart_ctrl & UART_CTRL_TXINTEN) == 0x20) && (dev->uart_status & UART_STATUS_TXRDY)) dev->uart_status |= UART_STATUS_TXINT; - es1371_update_irqs(dev); + es137x_update_irqs(dev); } static void -es1371_set_tx_irq(es1371_t *dev, int set) +es137x_set_tx_irq(es137x_t *dev, int set) { dev->uart_status &= ~UART_STATUS_TXRDY; if (set) dev->uart_status |= UART_STATUS_TXRDY; - es1371_update_tx_irq(dev); + es137x_update_tx_irq(dev); } static void -es1371_update_rx_irq(es1371_t *dev) +es137x_update_rx_irq(es137x_t *dev) { dev->uart_status &= ~UART_STATUS_RXINT; if ((dev->uart_ctrl & UART_CTRL_RXINTEN) && (dev->uart_status & UART_STATUS_RXRDY)) dev->uart_status |= UART_STATUS_RXINT; - es1371_update_irqs(dev); + es137x_update_irqs(dev); } static void -es1371_set_rx_irq(es1371_t *dev, int set) +es137x_set_rx_irq(es137x_t *dev, int set) { dev->uart_status &= ~UART_STATUS_RXRDY; if (set) dev->uart_status |= UART_STATUS_RXRDY; - es1371_update_rx_irq(dev); + es137x_update_rx_irq(dev); } static void -es1371_scan_fifo(es1371_t *dev) +es137x_scan_fifo(es137x_t *dev) { if (dev->read_fifo_pos != dev->write_fifo_pos) { dev->uart_data = dev->uart_fifo[dev->read_fifo_pos]; dev->read_fifo_pos = (dev->read_fifo_pos + 1) & 7; - es1371_set_rx_irq(dev, 1); + es137x_set_rx_irq(dev, 1); } else - es1371_set_rx_irq(dev, 0); + es137x_set_rx_irq(dev, 0); } static void -es1371_write_fifo(es1371_t *dev, uint8_t val) +es137x_write_fifo(es137x_t *dev, uint8_t val) { if (dev->write_fifo_pos < 8) { dev->uart_fifo[dev->write_fifo_pos] = val | UART_FIFO_BYTE_VALID; @@ -322,27 +352,89 @@ es1371_write_fifo(es1371_t *dev, uint8_t val) } static void -es1371_reset_fifo(es1371_t *dev) +es137x_reset_fifo(es137x_t *dev) { for (uint8_t i = 0; i < 8; i++) dev->uart_fifo[i] = 0x00000000; dev->read_fifo_pos = dev->write_fifo_pos = 0; - es1371_set_rx_irq(dev, 0); + es137x_set_rx_irq(dev, 0); } static void -es1371_reset(void *priv) +akm4531_reset(es137x_t *dev) { - es1371_t *dev = (es1371_t *) priv; + akm4531_t* codec = &dev->akm_codec; + + memset(codec->registers, 0, sizeof(codec->registers)); + + codec->registers[0] = 0x80; + codec->registers[1] = 0x80; + + for (int i = 0x02; i <= 0x0E; i++) { + codec->registers[i] = 0b10000110; + } + + codec->registers[0xf] = 0x80; + + codec->registers[0x17] = 0x3; + codec->registers[0x16] = 0x3; +} + +static double lerp(double v0, double v1, double t) { + return (1. - t) * v0 + t * v1; +} + +static void +es1370_calc_sample_rate(es137x_t *dev) +{ + if (dev->type != AUDIOPCI_ES1370) + return; + + dev->calc_sample_rate = 1411200 / (((dev->int_ctrl >> 16) & 0x1fff) + 2); + + //pclog("ES1370 calc sample rate %u\n", dev->calc_sample_rate); + + dev->interp_factor = 1.0; + dev->interp_step = 1; + + if (dev->calc_sample_rate >= 44100 || dev->calc_sample_rate < 11025) { + dev->interp_factor = 1.0; + dev->interp_step = 1; + dev->calc_sample_rate = 44100; + } + if (dev->calc_sample_rate == 22050) { + dev->interp_factor = 0.5; + dev->interp_step = 2; + } + if (dev->calc_sample_rate == 11025) { + dev->interp_factor = 0.25; + dev->interp_step = 4; + } + if ((((dev->int_ctrl >> 16) & 0x1fff) + 2) == 256) { + /* 5512.5 Hz */ + dev->interp_factor = 0.125; + dev->interp_step = 8; + dev->calc_sample_rate = 5512; + } + + dev->calc_sample_rate_synth = 44100 / (1 << ((dev->int_ctrl >> 12) & 3)); + dev->interp_factor_synth = 1. / (double)(1 << ((dev->int_ctrl >> 12) & 3)); + dev->interp_step_synth = (1 << ((dev->int_ctrl >> 12) & 3)); +} + +static void +es137x_reset(void *priv) +{ + es137x_t *dev = (es137x_t *) priv; nmi = 0; /* Default subsystem ID. */ dev->subsys_lock = 0x00; - *((uint16_t *) &dev->subsys_id[0]) = 0x1274; - *((uint16_t *) &dev->subsys_id[2]) = 0x1371; + *((uint16_t *) &dev->subsys_id[0]) = (dev->type == AUDIOPCI_ES1370) ? 0x4942 : 0x1274; + *((uint16_t *) &dev->subsys_id[2]) = (dev->type == AUDIOPCI_ES1370) ? 0x4c4c : 0x1371; /* Interrupt/Chip Select Control Register, Address 00H Addressable as byte, word, longword */ @@ -352,7 +444,7 @@ es1371_reset(void *priv) Addressable as longword only */ if (dev->type >= AUDIOPCI_CT5880) dev->int_status = 0x52080ec0; - else if (dev->type >= AUDIOPCI_ES1373) + else if (dev->type >= AUDIOPCI_ES1373 && dev->type != AUDIOPCI_ES1370) dev->int_status = 0x7f080ec0; else dev->int_status = 0x7ffffec0; @@ -441,17 +533,20 @@ es1371_reset(void *priv) dev->uart_fifo[i] = 0xffff0000; /* Reset the UART TX. */ - es1371_set_tx_irq(dev, 0); + es137x_set_tx_irq(dev, 0); /* Reset the UART (RX) FIFO. */ - es1371_reset_fifo(dev); + es137x_reset_fifo(dev); /* Update interrupts to ensure they're all correctly cleared. */ - es1371_update_irqs(dev); + es137x_update_irqs(dev); + + /* Reset the codec. */ + akm4531_reset(dev); } static uint32_t -es1371_read_frame_reg(es1371_t *dev, int frame, int page) +es137x_read_frame_reg(es137x_t *dev, int frame, int page) { uint32_t ret = 0xffffffff; @@ -559,7 +654,7 @@ es1371_read_frame_reg(es1371_t *dev, int frame, int page) } static void -es1371_write_frame_reg(es1371_t *dev, int frame, int page, uint32_t val) +es137x_write_frame_reg(es137x_t *dev, int frame, int page, uint32_t val) { switch (frame) { case 0x30: @@ -666,9 +761,9 @@ es1371_write_frame_reg(es1371_t *dev, int frame, int page, uint32_t val) } static uint8_t -es1371_inb(uint16_t port, void *priv) +es137x_inb(uint16_t port, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; uint8_t ret = 0xff; switch (port & 0x3f) { @@ -685,7 +780,7 @@ es1371_inb(uint16_t port, void *priv) break; case 0x03: ret = dev->int_ctrl >> 24; - if (dev->type < AUDIOPCI_ES1373) + if (dev->type < AUDIOPCI_ES1373 && dev->type != AUDIOPCI_ES1370) ret |= 0xfc; break; @@ -713,7 +808,7 @@ es1371_inb(uint16_t port, void *priv) Addressable as byte only */ case 0x08: ret = dev->uart_data; - es1371_set_rx_irq(dev, 0); + es137x_set_rx_irq(dev, 0); audiopci_log("[R] UART DATA = %02X\n", ret); break; @@ -758,19 +853,19 @@ es1371_inb(uint16_t port, void *priv) /* S/PDIF Channel Status Control Register, Address 1CH Addressable as byte, word, longword */ case 0x1c: - if (dev->type >= AUDIOPCI_ES1373) + if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) ret = dev->spdif_chstatus & 0xff; break; case 0x1d: - if (dev->type >= AUDIOPCI_ES1373) + if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) ret = dev->spdif_chstatus >> 8; break; case 0x1e: - if (dev->type >= AUDIOPCI_ES1373) + if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) ret = dev->spdif_chstatus >> 16; break; case 0x1f: - if (dev->type >= AUDIOPCI_ES1373) + if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) ret = dev->spdif_chstatus >> 24; break; @@ -790,17 +885,17 @@ es1371_inb(uint16_t port, void *priv) break; default: - audiopci_log("Bad es1371_inb: port=%04x\n", port); + audiopci_log("Bad es137x_inb: port=%04x\n", port); } - audiopci_log("es1371_inb: port=%04x ret=%02x\n", port, ret); + audiopci_log("es137x_inb: port=%04x ret=%02x\n", port, ret); return ret; } static uint16_t -es1371_inw(uint16_t port, void *priv) +es137x_inw(uint16_t port, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; uint16_t ret = 0xffff; switch (port & 0x3e) { @@ -811,7 +906,7 @@ es1371_inw(uint16_t port, void *priv) break; case 0x02: ret = (dev->int_ctrl >> 16) & 0xff0f; - if (dev->type < AUDIOPCI_ES1373) + if (dev->type < AUDIOPCI_ES1373 && dev->type != AUDIOPCI_ES1370) ret |= 0xfc00; break; @@ -836,11 +931,11 @@ es1371_inw(uint16_t port, void *priv) /* S/PDIF Channel Status Control Register, Address 1CH Addressable as byte, word, longword */ case 0x1c: - if (dev->type >= AUDIOPCI_ES1373) + if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) ret = dev->spdif_chstatus & 0xffff; break; case 0x1e: - if (dev->type >= AUDIOPCI_ES1373) + if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) ret = dev->spdif_chstatus >> 16; break; @@ -884,36 +979,39 @@ es1371_inw(uint16_t port, void *priv) case 0x34: case 0x38: case 0x3c: - ret = es1371_read_frame_reg(dev, port & 0x3c, dev->mem_page) & 0xffff; + ret = es137x_read_frame_reg(dev, port & 0x3c, dev->mem_page) & 0xffff; break; case 0x32: case 0x36: case 0x3a: case 0x3e: - ret = es1371_read_frame_reg(dev, port & 0x3c, dev->mem_page) >> 16; + ret = es137x_read_frame_reg(dev, port & 0x3c, dev->mem_page) >> 16; break; default: break; } - audiopci_log("es1371_inw: port=%04x ret=%04x\n", port, ret); + audiopci_log("es137x_inw: port=%04x ret=%04x\n", port, ret); return ret; } static uint32_t -es1371_inl(uint16_t port, void *priv) +es137x_inl(uint16_t port, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; uint32_t ret = 0xffffffff; + if (dev->type == AUDIOPCI_ES1370 && (port & 0x3c) == 0x14) + port = 0x10; + switch (port & 0x3c) { /* Interrupt/Chip Select Control Register, Address 00H Addressable as byte, word, longword */ case 0x00: ret = dev->int_ctrl & 0xff0fffff; - if (ret < AUDIOPCI_ES1373) + if (ret < AUDIOPCI_ES1373 && ret != AUDIOPCI_ES1370) ret |= 0xfc000000; break; @@ -940,6 +1038,8 @@ es1371_inl(uint16_t port, void *priv) /* CODEC Read Register, Address 14H Addressable as longword only */ case 0x14: + if (dev->type == AUDIOPCI_ES1370) + break; ret = dev->codec_ctrl | CODEC_READY; break; @@ -952,7 +1052,7 @@ es1371_inl(uint16_t port, void *priv) /* S/PDIF Channel Status Control Register, Address 1CH Addressable as byte, word, longword */ case 0x1c: - if (dev->type >= AUDIOPCI_ES1373) + if (dev->type >= AUDIOPCI_ES1373 || dev->type == AUDIOPCI_ES1370) ret = dev->spdif_chstatus; break; @@ -984,24 +1084,24 @@ es1371_inl(uint16_t port, void *priv) case 0x34: case 0x38: case 0x3c: - ret = es1371_read_frame_reg(dev, port & 0x3c, dev->mem_page); + ret = es137x_read_frame_reg(dev, port & 0x3c, dev->mem_page); break; default: break; } - audiopci_log("es1371_inl: port=%04x ret=%08x\n", port, ret); + audiopci_log("es137x_inl: port=%04x ret=%08x\n", port, ret); return ret; } static void -es1371_outb(uint16_t port, uint8_t val, void *priv) +es137x_outb(uint16_t port, uint8_t val, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; uint32_t old_legacy_ctrl; - audiopci_log("es1371_outb: port=%04x val=%02x\n", port, val); + audiopci_log("es137x_outb: port=%04x val=%02x\n", port, val); switch (port & 0x3f) { /* Interrupt/Chip Select Control Register, Address 00H @@ -1011,36 +1111,44 @@ es1371_outb(uint16_t port, uint8_t val, void *priv) dev->dac[0].addr = dev->dac[0].addr_latch; dev->dac[0].buffer_pos = 0; dev->dac[0].buffer_pos_end = 0; - es1371_fetch(dev, 0); + dev->dac[0].prev_out_l = 0; + dev->dac[0].prev_out_r = 0; + es137x_fetch(dev, 0); } if (!(dev->int_ctrl & INT_DAC2_EN) && (val & INT_DAC2_EN)) { dev->dac[1].addr = dev->dac[1].addr_latch; dev->dac[1].buffer_pos = 0; dev->dac[1].buffer_pos_end = 0; - es1371_fetch(dev, 1); + dev->dac[1].prev_out_l = 0; + dev->dac[1].prev_out_r = 0; + es137x_fetch(dev, 1); } + //pclog("INTCTRL 0x%02X\n", val & 0xff); dev->int_ctrl = (dev->int_ctrl & 0xffffff00) | val; break; case 0x01: dev->int_ctrl = (dev->int_ctrl & 0xffff00ff) | (val << 8); + es1370_calc_sample_rate(dev); break; case 0x02: dev->int_ctrl = (dev->int_ctrl & 0xff00ffff) | (val << 16); + es1370_calc_sample_rate(dev); break; case 0x03: dev->int_ctrl = (dev->int_ctrl & 0x00ffffff) | (val << 24); gameport_remap(dev->gameport, 0x200 | ((val & 0x03) << 3)); + es1370_calc_sample_rate(dev); break; /* Interrupt/Chip Select Status Register, Address 04H Addressable as longword only, but PCem implements byte access, which must be for a reason */ case 0x06: - if (dev->type >= AUDIOPCI_ES1373) + if (dev->type >= AUDIOPCI_ES1373 || dev->type == AUDIOPCI_ES1370) dev->int_status = (dev->int_status & 0xff08ffff) | (val << 16); break; case 0x07: - if (dev->type >= AUDIOPCI_CT5880) + if (dev->type >= AUDIOPCI_CT5880 || dev->type == AUDIOPCI_ES1370) dev->int_status = (dev->int_status & 0xd2ffffff) | (val << 24); break; @@ -1050,7 +1158,7 @@ es1371_outb(uint16_t port, uint8_t val, void *priv) audiopci_log("MIDI data = %02x\n", val); /* TX does not use FIFO. */ midi_raw_out_byte(val); - es1371_set_tx_irq(dev, 1); + es137x_set_tx_irq(dev, 1); break; /* UART Control Register, Address 09H @@ -1061,15 +1169,15 @@ es1371_outb(uint16_t port, uint8_t val, void *priv) if ((val & 0x03) == 0x03) { /* Reset TX */ - es1371_set_tx_irq(dev, 1); + es137x_set_tx_irq(dev, 1); /* Software reset */ - es1371_reset_fifo(dev); + es137x_reset_fifo(dev); } else { - es1371_set_tx_irq(dev, 1); + es137x_set_tx_irq(dev, 1); - es1371_update_tx_irq(dev); - es1371_update_rx_irq(dev); + es137x_update_tx_irq(dev); + es137x_update_rx_irq(dev); } break; @@ -1101,7 +1209,7 @@ es1371_outb(uint16_t port, uint8_t val, void *priv) case 0x1b: old_legacy_ctrl = dev->legacy_ctrl; dev->legacy_ctrl = (dev->legacy_ctrl & 0x00ffffff) | (val << 24); - es1371_update_irqs(dev); + es137x_update_irqs(dev); update_legacy(dev, old_legacy_ctrl); break; @@ -1131,21 +1239,21 @@ es1371_outb(uint16_t port, uint8_t val, void *priv) dev->int_status &= ~INT_STATUS_DAC1; if (!(dev->si_cr & SI_P2_INTR_EN)) dev->int_status &= ~INT_STATUS_DAC2; - es1371_update_irqs(dev); + es137x_update_irqs(dev); break; case 0x22: dev->si_cr = (dev->si_cr & 0xff80ffff) | ((val & 0x7f) << 16); break; default: - audiopci_log("Bad es1371_outb: port=%04x val=%02x\n", port, val); + audiopci_log("Bad es137x_outb: port=%04x val=%02x\n", port, val); } } static void -es1371_outw(uint16_t port, uint16_t val, void *priv) +es137x_outw(uint16_t port, uint16_t val, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; uint32_t old_legacy_ctrl; switch (port & 0x3f) { @@ -1156,19 +1264,27 @@ es1371_outw(uint16_t port, uint16_t val, void *priv) dev->dac[0].addr = dev->dac[0].addr_latch; dev->dac[0].buffer_pos = 0; dev->dac[0].buffer_pos_end = 0; - es1371_fetch(dev, 0); + dev->dac[0].prev_out_l = 0; + dev->dac[0].prev_out_r = 0; + dev->step_synth = dev->interp_step_synth; + es137x_fetch(dev, 0); } if (!(dev->int_ctrl & INT_DAC2_EN) && (val & INT_DAC2_EN)) { dev->dac[1].addr = dev->dac[1].addr_latch; dev->dac[1].buffer_pos = 0; dev->dac[1].buffer_pos_end = 0; - es1371_fetch(dev, 1); + dev->dac[1].prev_out_l = 0; + dev->dac[1].prev_out_r = 0; + dev->step_pcm = dev->interp_step; + es137x_fetch(dev, 1); } + //pclog("INTCTRL 0x%02X\n", val & 0xff); dev->int_ctrl = (dev->int_ctrl & 0xffff0000) | val; break; case 0x02: dev->int_ctrl = (dev->int_ctrl & 0x0000ffff) | (val << 16); gameport_remap(dev->gameport, 0x200 | ((val & 0x0300) >> 5)); + es1370_calc_sample_rate(dev); break; /* Memory Page Register, Address 0CH @@ -1179,6 +1295,17 @@ es1371_outw(uint16_t port, uint16_t val, void *priv) case 0x0e: break; + /* CODEC Write Register, Address 10H + Addressable as word, longword */ + case 0x10: + if (dev->type != AUDIOPCI_ES1370) + break; + + dev->akm_codec.registers[(val >> 8) & 0xFF] = val & 0xFF; + if ((val >> 8) == 0x16 && !(val & 1)) + akm4531_reset(dev); + break; + /* Legacy Control/Status Register, Address 18H Addressable as byte, word, longword */ case 0x18: @@ -1187,7 +1314,7 @@ es1371_outw(uint16_t port, uint16_t val, void *priv) case 0x1a: old_legacy_ctrl = dev->legacy_ctrl; dev->legacy_ctrl = (dev->legacy_ctrl & 0x0000ffff) | (val << 16); - es1371_update_irqs(dev); + es137x_update_irqs(dev); update_legacy(dev, old_legacy_ctrl); break; @@ -1208,7 +1335,7 @@ es1371_outw(uint16_t port, uint16_t val, void *priv) dev->int_status &= ~INT_STATUS_DAC1; if (!(dev->si_cr & SI_P2_INTR_EN)) dev->int_status &= ~INT_STATUS_DAC2; - es1371_update_irqs(dev); + es137x_update_irqs(dev); break; case 0x22: dev->si_cr = (dev->si_cr & 0xff80ffff) | ((val & 0x007f) << 16); @@ -1238,32 +1365,47 @@ es1371_outw(uint16_t port, uint16_t val, void *priv) } static void -es1371_outl(uint16_t port, uint32_t val, void *priv) +es137x_outl(uint16_t port, uint32_t val, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; uint32_t old_legacy_ctrl; - audiopci_log("es1371_outl: port=%04x val=%08x\n", port, val); + audiopci_log("es137x_outl: port=%04x val=%08x\n", port, val); switch (port & 0x3f) { /* Interrupt/Chip Select Control Register, Address 00H Addressable as byte, word, longword */ case 0x00: + { + uint8_t dac1start = 0, dac2start = 0; if (!(dev->int_ctrl & INT_DAC1_EN) && (val & INT_DAC1_EN)) { dev->dac[0].addr = dev->dac[0].addr_latch; dev->dac[0].buffer_pos = 0; dev->dac[0].buffer_pos_end = 0; - es1371_fetch(dev, 0); + dev->dac[0].prev_out_l = 0; + dev->dac[0].prev_out_r = 0; + dac1start = 1; + es137x_fetch(dev, 0); } if (!(dev->int_ctrl & INT_DAC2_EN) && (val & INT_DAC2_EN)) { dev->dac[1].addr = dev->dac[1].addr_latch; dev->dac[1].buffer_pos = 0; dev->dac[1].buffer_pos_end = 0; - es1371_fetch(dev, 1); + dev->dac[1].prev_out_l = 0; + dev->dac[1].prev_out_r = 0; + dac2start = 1; + es137x_fetch(dev, 1); } + //pclog("INTCTRL 0x%02X\n", val & 0xff); dev->int_ctrl = val; gameport_remap(dev->gameport, 0x200 | ((val & 0x03000000) >> 21)); + es1370_calc_sample_rate(dev); + if (dac1start) + dev->step_synth = dev->interp_step_synth; + if (dac2start) + dev->step_pcm = dev->interp_step; break; + } /* Interrupt/Chip Select Status Register, Address 04H Addressable as longword only */ @@ -1271,7 +1413,7 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) audiopci_log("[W] STATUS = %08X\n", val); if (dev->type >= AUDIOPCI_CT5880) dev->int_status = (dev->int_status & 0xd208ffff) | (val & 0x2df70000); - else if (dev->type >= AUDIOPCI_ES1373) + else if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) dev->int_status = (dev->int_status & 0xff08ffff) | (val & 0x00f70000); break; @@ -1284,6 +1426,13 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) /* Sample Rate Converter Interface Register, Address 10H Addressable as longword only */ case 0x10: + if (dev->type == AUDIOPCI_ES1370) + { + dev->akm_codec.registers[(val >> 8) & 0xFF] = val & 0xFF; + if ((val >> 8) == 0x16 && !(val & 1)) + akm4531_reset(dev); + break; + } dev->sr_cir = val & 0xfff8ffff; /*Bits 16 to 18 are undefined*/ if (dev->sr_cir & SRC_RAM_WE) { dev->sr_ram[dev->sr_cir >> 25] = val & 0xffff; @@ -1334,6 +1483,8 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) /* CODEC Write Register, Address 14H Addressable as longword only */ case 0x14: + if (dev->type == AUDIOPCI_ES1370) + break; if (val & CODEC_READ) { dev->codec_ctrl &= 0x00ff0000; dev->codec_ctrl |= ac97_codec_readw(dev->codec, val >> 16); @@ -1354,7 +1505,7 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) old_legacy_ctrl = dev->legacy_ctrl; dev->legacy_ctrl = (dev->legacy_ctrl & 0x0000ffff) | (val & 0xffff0000); dev->legacy_ctrl |= LEGACY_INT; - es1371_update_irqs(dev); + es137x_update_irqs(dev); update_legacy(dev, old_legacy_ctrl); break; @@ -1372,7 +1523,7 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) dev->int_status &= ~INT_STATUS_DAC1; if (!(dev->si_cr & SI_P2_INTR_EN)) dev->int_status &= ~INT_STATUS_DAC2; - es1371_update_irqs(dev); + es137x_update_irqs(dev); break; /* DAC1 Channel Sample Count Register, Address 24H @@ -1397,7 +1548,7 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) case 0x34: case 0x38: case 0x3c: - es1371_write_frame_reg(dev, port & 0x3c, dev->mem_page, val); + es137x_write_frame_reg(dev, port & 0x3c, dev->mem_page, val); break; default: @@ -1406,7 +1557,7 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) } static void -capture_event(es1371_t *dev, int type, int rw, uint16_t port) +capture_event(es137x_t *dev, int type, int rw, uint16_t port) { dev->legacy_ctrl &= ~(LEGACY_EVENT_MASK | LEGACY_EVENT_ADDR_MASK); dev->legacy_ctrl |= type; @@ -1524,7 +1675,7 @@ capture_read_slave_dma(uint16_t port, void *priv) } static void -update_legacy(es1371_t *dev, uint32_t old_legacy_ctrl) +update_legacy(es137x_t *dev, uint32_t old_legacy_ctrl) { if (old_legacy_ctrl & LEGACY_CAPTURE_SSCAPE) { switch ((old_legacy_ctrl >> LEGACY_SSCAPE_ADDR_SHIFT) & 3) { @@ -1713,10 +1864,112 @@ update_legacy(es1371_t *dev, uint32_t old_legacy_ctrl) } } +static uint8_t +es1370_pci_read(int func, int addr, void *priv) +{ + const es137x_t *dev = (es137x_t *) priv; + + if (func > 0) + return 0xff; + + if ((addr > 0x3f) && ((addr < 0xdc) || (addr > 0xe1))) + return 0x00; + + switch (addr) { + case 0x00: /* Vendor ID */ + return 0x74; /* Ensoniq */ + case 0x01: + return 0x12; + + case 0x02: /* Device ID */ + return 0x00; /* ES1370 */ + case 0x03: + return 0x50; + + case 0x04: /* Command TODO */ + return dev->pci_command; + case 0x05: + return dev->pci_serr; + + case 0x06: /* Status TODO */ + return 0x10; /* Supports ACPI */ + case 0x07: + return 0x00; + + case 0x08: /* Class Code & Revision ID */ + return 0x00; /* Revision ID - 0x00 is actual Ensoniq-branded ES1370 */ + case 0x09: + return 0x00; /* Multimedia audio device */ + case 0x0a: + return 0x01; + case 0x0b: + return 0x04; + +// case 0x0c: /* Cache Line Size TODO */ +// case 0x0d: /* Latency Timer TODO */ +// case 0x0e: /* Header Type TODO */ +// case 0x0f: /* BIST TODO */ + + case 0x10: /* Base Address TODO */ + return 0x01 | (dev->base_addr & 0xc0); /* memBaseAddr */ + case 0x11: + return dev->base_addr >> 8; + case 0x12: + return dev->base_addr >> 16; + case 0x13: + return dev->base_addr >> 24; + + case 0x2c: + return 0x42; /* Subsystem vendor ID */ + case 0x2d: + return 0x49; + case 0x2e: + return 0x4c; /* Subsystem product ID */ + case 0x2f: + return 0x4c; + +#if 0 + case 0x34: // TODO + return 0xdc; /* Capabilites pointer */ +#endif + + case 0x3c: + return dev->int_line; + case 0x3d: + return 0x01; /* INTA */ + + case 0x3e: + return 0xc; /* Minimum grant */ + case 0x3f: + return 0x80; /* Maximum latency */ + +#if 0 + case 0xdc: + return 0x01; /* Capabilities identifier */ + case 0xdd: + return 0x00; /* Next item pointer */ + case 0xde: + return 0x31; /* Power management capabilities */ + case 0xdf: + return 0x6c; + + case 0xe0: + return dev->pmcsr & 0xff; + case 0xe1: + return dev->pmcsr >> 8; +#endif + + default: + break; + } + + return 0x00; +} + static uint8_t es1371_pci_read(int func, int addr, void *priv) { - const es1371_t *dev = (es1371_t *) priv; + const es137x_t *dev = (es137x_t *) priv; if (func > 0) return 0xff; @@ -1780,7 +2033,7 @@ es1371_pci_read(int func, int addr, void *priv) return 0x80; /* Maximum latency */ case 0x40: - if (dev->type >= AUDIOPCI_ES1373) + if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) return dev->subsys_lock; break; @@ -1806,42 +2059,93 @@ es1371_pci_read(int func, int addr, void *priv) } static void -es1371_io_set(es1371_t *dev, int set) +es137x_io_set(es137x_t *dev, int set) { if (dev->pci_command & PCI_COMMAND_IO) { io_handler(set, dev->base_addr, 0x0040, - es1371_inb, es1371_inw, es1371_inl, - es1371_outb, es1371_outw, es1371_outl, dev); + es137x_inb, es137x_inw, es137x_inl, + es137x_outb, es137x_outw, es137x_outl, dev); } } static void -es1371_pci_write(int func, int addr, uint8_t val, void *priv) +es1370_pci_write(int func, int addr, uint8_t val, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; if (func) return; switch (addr) { case 0x04: - es1371_io_set(dev, 0); + es137x_io_set(dev, 0); dev->pci_command = val & 0x05; - es1371_io_set(dev, 1); + es137x_io_set(dev, 1); break; case 0x05: dev->pci_serr = val & 1; break; case 0x10: - es1371_io_set(dev, 0); + es137x_io_set(dev, 0); dev->base_addr = (dev->base_addr & 0xffffff00) | (val & 0xc0); - es1371_io_set(dev, 1); + es137x_io_set(dev, 1); break; case 0x11: - es1371_io_set(dev, 0); + es137x_io_set(dev, 0); dev->base_addr = (dev->base_addr & 0xffff00c0) | (val << 8); - es1371_io_set(dev, 1); + es137x_io_set(dev, 1); + break; + case 0x12: + dev->base_addr = (dev->base_addr & 0xff00ffc0) | (val << 16); + break; + case 0x13: + dev->base_addr = (dev->base_addr & 0x00ffffc0) | (val << 24); + break; + + case 0x3c: + dev->int_line = val; + break; + + case 0xe0: + dev->pmcsr = (dev->pmcsr & 0xff00) | (val & 0x03); + break; + case 0xe1: + dev->pmcsr = (dev->pmcsr & 0x00ff) | ((val & 0x01) << 8); + break; + + default: + break; + } +} + +static void +es1371_pci_write(int func, int addr, uint8_t val, void *priv) +{ + es137x_t *dev = (es137x_t *) priv; + + if (func) + return; + + switch (addr) { + case 0x04: + es137x_io_set(dev, 0); + dev->pci_command = val & 0x05; + es137x_io_set(dev, 1); + break; + case 0x05: + dev->pci_serr = val & 1; + break; + + case 0x10: + es137x_io_set(dev, 0); + dev->base_addr = (dev->base_addr & 0xffffff00) | (val & 0xc0); + es137x_io_set(dev, 1); + break; + case 0x11: + es137x_io_set(dev, 0); + dev->base_addr = (dev->base_addr & 0xffff00c0) | (val << 8); + es137x_io_set(dev, 1); break; case 0x12: dev->base_addr = (dev->base_addr & 0xff00ffc0) | (val << 16); @@ -1860,7 +2164,7 @@ es1371_pci_write(int func, int addr, uint8_t val, void *priv) break; case 0x40: - if (dev->type >= AUDIOPCI_ES1373) + if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) dev->subsys_lock = val; break; @@ -1877,7 +2181,7 @@ es1371_pci_write(int func, int addr, uint8_t val, void *priv) } static void -es1371_fetch(es1371_t *dev, int dac_nr) +es137x_fetch(es137x_t *dev, int dac_nr) { if (dev->si_cr & (dac_nr ? SI_P2_PAUSE : SI_P1_PAUSE)) return; @@ -1981,8 +2285,8 @@ low_fir_es1371(int dac_nr, int i, float NewSample) read_pos = (pos + 15) & (127 & ~15); n_coef = (16 - pos) & 15; - while (n_coef < ES1371_NCoef) { - out += low_fir_es1371_coef[n_coef] * x[dac_nr][i][read_pos]; + while (n_coef < ES137x_NCoef) { + out += low_fir_es137x_coef[n_coef] * x[dac_nr][i][read_pos]; read_pos = (read_pos + 16) & (127 & ~15); n_coef += 16; } @@ -1997,13 +2301,13 @@ low_fir_es1371(int dac_nr, int i, float NewSample) } static void -es1371_next_sample_filtered(es1371_t *dev, int dac_nr, int out_idx) +es137x_next_sample_filtered(es137x_t *dev, int dac_nr, int out_idx) { int out_l; int out_r; if ((dev->dac[dac_nr].buffer_pos - dev->dac[dac_nr].buffer_pos_end) >= 0) - es1371_fetch(dev, dac_nr); + es137x_fetch(dev, dac_nr); out_l = dev->dac[dac_nr].buffer_l[dev->dac[dac_nr].buffer_pos & 63]; out_r = dev->dac[dac_nr].buffer_r[dev->dac[dac_nr].buffer_pos & 63]; @@ -2020,21 +2324,35 @@ es1371_next_sample_filtered(es1371_t *dev, int dac_nr, int out_idx) } static void -es1371_update(es1371_t *dev) +es137x_update(es137x_t *dev) { int32_t l; int32_t r; - l = (dev->dac[0].out_l * dev->dac[0].vol_l) >> 12; - l += ((dev->dac[1].out_l * dev->dac[1].vol_l) >> 12); - r = (dev->dac[0].out_r * dev->dac[0].vol_r) >> 12; - r += ((dev->dac[1].out_r * dev->dac[1].vol_r) >> 12); + if (dev->type == AUDIOPCI_ES1370) { + l = dev->dac[0].out_l * (((dev->akm_codec.registers[0x4] & 0x80) ? 0 : akm4531_gain_2dbstep_5bits[(dev->akm_codec.registers[0x4] & 0x1f)]) / 32767.0); + r = dev->dac[0].out_r * (((dev->akm_codec.registers[0x5] & 0x80) ? 0 : akm4531_gain_2dbstep_5bits[(dev->akm_codec.registers[0x5] & 0x1f)]) / 32767.0); - l >>= 1; - r >>= 1; + l += dev->dac[1].out_l * (((dev->akm_codec.registers[0x2] & 0x80) ? 0 : akm4531_gain_2dbstep_5bits[(dev->akm_codec.registers[0x2] & 0x1f)]) / 32767.0); + r += dev->dac[1].out_r * (((dev->akm_codec.registers[0x3] & 0x80) ? 0 : akm4531_gain_2dbstep_5bits[(dev->akm_codec.registers[0x3] & 0x1f)]) / 32767.0); - l = (((l * dev->pcm_vol_l) >> 15) * dev->master_vol_l) >> 15; - r = (((r * dev->pcm_vol_r) >> 15) * dev->master_vol_r) >> 15; + l >>= 1; + r >>= 1; + + l *= (((dev->akm_codec.registers[0x0] & 0x80) ? 0 : akm4531_att_2dbstep_5bits[(dev->akm_codec.registers[0x0] & 0x1f) ^ 0x1f]) / 32767.0); + r *= (((dev->akm_codec.registers[0x1] & 0x80) ? 0 : akm4531_att_2dbstep_5bits[(dev->akm_codec.registers[0x1] & 0x1f) ^ 0x1f]) / 32767.0); + } else { + l = (dev->dac[0].out_l * dev->dac[0].vol_l) >> 12; + l += ((dev->dac[1].out_l * dev->dac[1].vol_l) >> 12); + r = (dev->dac[0].out_r * dev->dac[0].vol_r) >> 12; + r += ((dev->dac[1].out_r * dev->dac[1].vol_r) >> 12); + + l >>= 1; + r >>= 1; + + l = (((l * dev->pcm_vol_l) >> 15) * dev->master_vol_l) >> 15; + r = (((r * dev->pcm_vol_r) >> 15) * dev->master_vol_r) >> 15; + } if (l < -32768) l = -32768; @@ -2045,16 +2363,16 @@ es1371_update(es1371_t *dev) else if (r > 32767) r = 32767; - for (; dev->pos < sound_pos_global; dev->pos++) { + for (; dev->pos < ((dev->type == AUDIOPCI_ES1370) ? wavetable_pos_global : sound_pos_global); dev->pos++) { dev->buffer[dev->pos * 2] = l; dev->buffer[dev->pos * 2 + 1] = r; } } static void -es1371_poll(void *priv) +es137x_poll(void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; int frac; int idx; int samp1_l; @@ -2064,21 +2382,42 @@ es1371_poll(void *priv) timer_advance_u64(&dev->dac[1].timer, dev->dac[1].latch); - es1371_scan_fifo(dev); + es137x_scan_fifo(dev); - es1371_update(dev); + es137x_update(dev); if (dev->int_ctrl & INT_DAC1_EN) { - if ((dev->type >= AUDIOPCI_ES1373) && (dev->int_ctrl & INT_DAC1_BYPASS)) { - /* SRC bypass. */ - if ((dev->dac[0].buffer_pos - dev->dac[0].buffer_pos_end) >= 0) - es1371_fetch(dev, 0); + if (((dev->type >= AUDIOPCI_ES1373) && (dev->int_ctrl & INT_DAC1_BYPASS)) || dev->type == AUDIOPCI_ES1370) { + if (dev->calc_sample_rate_synth != 44100 && dev->type == AUDIOPCI_ES1370) + { + if ((dev->dac[0].buffer_pos - dev->dac[0].buffer_pos_end) >= 0 && dev->step_synth >= dev->interp_step_synth) + es137x_fetch(dev, 0); - dev->dac[0].out_l = dev->dac[0].buffer_l[dev->dac[0].buffer_pos & 63]; - dev->dac[0].out_r = dev->dac[0].buffer_r[dev->dac[0].buffer_pos & 63]; - dev->dac[0].buffer_pos++; + if (dev->step_synth >= dev->interp_step_synth) { + dev->step_synth = 0; + } - goto dac0_count; + dev->dac[0].out_l = lerp(dev->dac[0].prev_out_l, dev->dac[0].buffer_l[(dev->dac[0].buffer_pos) & 63], (dev->step_synth + 1) * dev->interp_factor_synth); + dev->dac[0].out_r = lerp(dev->dac[0].prev_out_r, dev->dac[0].buffer_r[(dev->dac[0].buffer_pos) & 63], (dev->step_synth + 1) * dev->interp_factor_synth); + + dev->step_synth++; + if (dev->step_synth >= dev->interp_step_synth) { + dev->dac[0].prev_out_l = dev->dac[0].out_l; + dev->dac[0].prev_out_r = dev->dac[0].out_r; + dev->dac[0].buffer_pos++; + goto dac0_count; + } + } else { + /* SRC bypass. */ + if ((dev->dac[0].buffer_pos - dev->dac[0].buffer_pos_end) >= 0) + es137x_fetch(dev, 0); + + dev->dac[0].out_l = dev->dac[0].buffer_l[dev->dac[0].buffer_pos & 63]; + dev->dac[0].out_r = dev->dac[0].buffer_r[dev->dac[0].buffer_pos & 63]; + dev->dac[0].buffer_pos++; + + goto dac0_count; + } } else { frac = dev->dac[0].ac & 0x7fff; idx = dev->dac[0].ac >> 15; @@ -2092,14 +2431,14 @@ es1371_poll(void *priv) dev->dac[0].ac += dev->dac[0].vf; dev->dac[0].ac &= ((32 << 15) - 1); if ((dev->dac[0].ac >> (15 + 4)) != dev->dac[0].f_pos) { - es1371_next_sample_filtered(dev, 0, dev->dac[0].f_pos ? 16 : 0); + es137x_next_sample_filtered(dev, 0, dev->dac[0].f_pos ? 16 : 0); dev->dac[0].f_pos = (dev->dac[0].f_pos + 1) & 1; dac0_count: dev->dac[0].curr_samp_ct--; if (dev->dac[0].curr_samp_ct < 0) { dev->int_status |= INT_STATUS_DAC1; - es1371_update_irqs(dev); + es137x_update_irqs(dev); dev->dac[0].curr_samp_ct = dev->dac[0].samp_ct; } } @@ -2107,16 +2446,37 @@ dac0_count: } if (dev->int_ctrl & INT_DAC2_EN) { - if ((dev->type >= AUDIOPCI_ES1373) && (dev->int_ctrl & INT_DAC2_BYPASS)) { - /* SRC bypass. */ - if ((dev->dac[1].buffer_pos - dev->dac[1].buffer_pos_end) >= 0) - es1371_fetch(dev, 1); + if (((dev->type >= AUDIOPCI_ES1373) && (dev->int_ctrl & INT_DAC2_BYPASS)) || dev->type == AUDIOPCI_ES1370) { + if (dev->calc_sample_rate != 44100 && dev->type == AUDIOPCI_ES1370) + { + if ((dev->dac[1].buffer_pos - dev->dac[1].buffer_pos_end) >= 0 && dev->step_pcm >= dev->interp_step) + es137x_fetch(dev, 1); - dev->dac[1].out_l = dev->dac[1].buffer_l[dev->dac[1].buffer_pos & 63]; - dev->dac[1].out_r = dev->dac[1].buffer_r[dev->dac[1].buffer_pos & 63]; - dev->dac[1].buffer_pos++; + if (dev->step_pcm >= dev->interp_step) { + dev->step_pcm = 0; + } - goto dac1_count; + dev->dac[1].out_l = lerp(dev->dac[1].prev_out_l, dev->dac[1].buffer_l[(dev->dac[1].buffer_pos) & 63], (dev->step_pcm + 1) * dev->interp_factor); + dev->dac[1].out_r = lerp(dev->dac[1].prev_out_r, dev->dac[1].buffer_r[(dev->dac[1].buffer_pos) & 63], (dev->step_pcm + 1) * dev->interp_factor); + + dev->step_pcm++; + if (dev->step_pcm >= dev->interp_step) { + dev->dac[1].prev_out_l = dev->dac[1].out_l; + dev->dac[1].prev_out_r = dev->dac[1].out_r; + dev->dac[1].buffer_pos++; + goto dac1_count; + } + } else { + /* SRC bypass. */ + if ((dev->dac[1].buffer_pos - dev->dac[1].buffer_pos_end) >= 0) + es137x_fetch(dev, 1); + + dev->dac[1].out_l = dev->dac[1].buffer_l[dev->dac[1].buffer_pos & 63]; + dev->dac[1].out_r = dev->dac[1].buffer_r[dev->dac[1].buffer_pos & 63]; + dev->dac[1].buffer_pos++; + + goto dac1_count; + } } else { frac = dev->dac[1].ac & 0x7fff; idx = dev->dac[1].ac >> 15; @@ -2130,14 +2490,14 @@ dac0_count: dev->dac[1].ac += dev->dac[1].vf; dev->dac[1].ac &= ((32 << 15) - 1); if ((dev->dac[1].ac >> (15 + 4)) != dev->dac[1].f_pos) { - es1371_next_sample_filtered(dev, 1, dev->dac[1].f_pos ? 16 : 0); + es137x_next_sample_filtered(dev, 1, dev->dac[1].f_pos ? 16 : 0); dev->dac[1].f_pos = (dev->dac[1].f_pos + 1) & 1; dac1_count: dev->dac[1].curr_samp_ct--; if (dev->dac[1].curr_samp_ct < 0) { dev->int_status |= INT_STATUS_DAC2; - es1371_update_irqs(dev); + es137x_update_irqs(dev); dev->dac[1].curr_samp_ct = dev->dac[1].samp_ct; } } @@ -2146,11 +2506,11 @@ dac1_count: } static void -es1371_get_buffer(int32_t *buffer, int len, void *priv) +es137x_get_buffer(int32_t *buffer, int len, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; - es1371_update(dev); + es137x_update(dev); for (int c = 0; c < len * 2; c++) buffer[c] += (dev->buffer[c] / 2); @@ -2158,10 +2518,22 @@ es1371_get_buffer(int32_t *buffer, int len, void *priv) dev->pos = 0; } +static void +es1370_filter_cd_audio(int channel, double *buffer, void *priv) +{ + const es137x_t *dev = (es137x_t *) priv; + double c = 0.0; + double mastervol = ((dev->akm_codec.registers[channel] & 0x80) ? 0 : akm4531_att_2dbstep_5bits[(dev->akm_codec.registers[channel] & 0x1f) ^ 0x1f]) / 32767.0; + double cdvol = ((dev->akm_codec.registers[channel + 0x6] & 0x80) ? 0 : akm4531_gain_2dbstep_5bits[(dev->akm_codec.registers[channel + 0x6] & 0x1f)]) / 32767.0; + + c = *buffer * mastervol * cdvol; + *buffer = c; +} + static void es1371_filter_cd_audio(int channel, double *buffer, void *priv) { - const es1371_t *dev = (es1371_t *) priv; + const es137x_t *dev = (es137x_t *) priv; double c; int cd = channel ? dev->cd_vol_r : dev->cd_vol_l; int master = channel ? dev->master_vol_r : dev->master_vol_l; @@ -2177,49 +2549,49 @@ sinc(double x) } static void -generate_es1371_filter(void) +generate_es137x_filter(void) { /* Cutoff frequency = 1 / 32 */ float fC = 1.0 / 32.0; float gain; int n; - for (n = 0; n < ES1371_NCoef; n++) { + for (n = 0; n < ES137x_NCoef; n++) { /* Blackman window */ - double w = 0.42 - (0.5 * cos((2.0 * n * M_PI) / (double) (ES1371_NCoef - 1))) + (0.08 * cos((4.0 * n * M_PI) / (double) (ES1371_NCoef - 1))); + double w = 0.42 - (0.5 * cos((2.0 * n * M_PI) / (double) (ES137x_NCoef - 1))) + (0.08 * cos((4.0 * n * M_PI) / (double) (ES137x_NCoef - 1))); /* Sinc filter */ - double h = sinc(2.0 * fC * ((double) n - ((double) (ES1371_NCoef - 1) / 2.0))); + double h = sinc(2.0 * fC * ((double) n - ((double) (ES137x_NCoef - 1) / 2.0))); /* Create windowed-sinc filter */ - low_fir_es1371_coef[n] = w * h; + low_fir_es137x_coef[n] = w * h; } - low_fir_es1371_coef[(ES1371_NCoef - 1) / 2] = 1.0; + low_fir_es137x_coef[(ES137x_NCoef - 1) / 2] = 1.0; gain = 0.0; - for (n = 0; n < ES1371_NCoef; n++) - gain += low_fir_es1371_coef[n] / (float) N; + for (n = 0; n < ES137x_NCoef; n++) + gain += low_fir_es137x_coef[n] / (float) N; gain /= 0.65; /* Normalise filter, to produce unity gain */ - for (n = 0; n < ES1371_NCoef; n++) - low_fir_es1371_coef[n] /= gain; + for (n = 0; n < ES137x_NCoef; n++) + low_fir_es137x_coef[n] /= gain; } static void -es1371_input_msg(void *priv, uint8_t *msg, uint32_t len) +es137x_input_msg(void *priv, uint8_t *msg, uint32_t len) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; for (uint32_t i = 0; i < len; i++) - es1371_write_fifo(dev, msg[i]); + es137x_write_fifo(dev, msg[i]); } static int -es1371_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) +es137x_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; uint32_t i = -1; audiopci_log("Abort = %i\n", abort); @@ -2229,7 +2601,7 @@ es1371_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) if (!abort) { for (i = 0; i < len; i++) { - es1371_write_fifo(dev, buffer[i]); + es137x_write_fifo(dev, buffer[i]); if (dev->uart_status & UART_STATUS_RXRDY) break; } @@ -2240,17 +2612,64 @@ es1371_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) return 7 - i; } +static void es137x_speed_changed(void *priv); + +static void * +es1370_init(const device_t *info) +{ + es137x_t *dev = malloc(sizeof(es137x_t)); + memset(dev, 0x00, sizeof(es137x_t)); + + if (device_get_config_int("receive_input")) + midi_in_handler(1, es137x_input_msg, es137x_input_sysex, dev); + + wavetable_add_handler(es137x_get_buffer, dev); + sound_set_cd_audio_filter(es1370_filter_cd_audio, dev); + + dev->gameport = gameport_add(&gameport_pnp_device); + gameport_remap(dev->gameport, 0x200); + + pci_add_card(info->local ? PCI_ADD_SOUND : PCI_ADD_NORMAL, es1370_pci_read, es1370_pci_write, dev, &dev->pci_slot); + + timer_add(&dev->dac[1].timer, es137x_poll, dev, 1); + + generate_es137x_filter(); + + dev->dac[0].vol_l = 1 << 12; + dev->dac[0].vol_r = 1 << 12; + dev->dac[1].vol_l = 1 << 12; + dev->dac[1].vol_r = 1 << 12; + + dev->pcm_vol_l = 1 << 15; + dev->pcm_vol_r = 1 << 15; + dev->master_vol_l = 1 << 15; + dev->master_vol_r = 1 << 15; + + dev->type = AUDIOPCI_ES1370; + + es137x_reset(dev); + + es137x_speed_changed(dev); + + for (int i = 0; i < 0x20; i++) { + double attn = (12.0 - (i * 2.0)); + akm4531_gain_2dbstep_5bits[i] = pow(10, attn / 10.) * 32767.0; + } + + return dev; +} + static void * es1371_init(const device_t *info) { - es1371_t *dev = malloc(sizeof(es1371_t)); - memset(dev, 0x00, sizeof(es1371_t)); + es137x_t *dev = malloc(sizeof(es137x_t)); + memset(dev, 0x00, sizeof(es137x_t)); dev->type = info->local & 0xffffff00; if (device_get_config_int("receive_input")) - midi_in_handler(1, es1371_input_msg, es1371_input_sysex, dev); + midi_in_handler(1, es137x_input_msg, es137x_input_sysex, dev); - sound_add_handler(es1371_get_buffer, dev); + sound_add_handler(es137x_get_buffer, dev); sound_set_cd_audio_filter(es1371_filter_cd_audio, dev); dev->gameport = gameport_add(&gameport_pnp_device); @@ -2258,9 +2677,9 @@ es1371_init(const device_t *info) pci_add_card((info->local & 1) ? PCI_ADD_SOUND : PCI_ADD_NORMAL, es1371_pci_read, es1371_pci_write, dev, &dev->pci_slot); - timer_add(&dev->dac[1].timer, es1371_poll, dev, 1); + timer_add(&dev->dac[1].timer, es137x_poll, dev, 1); - generate_es1371_filter(); + generate_es137x_filter(); ac97_codec = &dev->codec; ac97_codec_count = 1; @@ -2269,27 +2688,40 @@ es1371_init(const device_t *info) if (!(info->local & 1)) device_add(ac97_codec_get(device_get_config_int("codec"))); - es1371_reset(dev); + es137x_reset(dev); return dev; } static void -es1371_close(void *priv) +es137x_close(void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; free(dev); } static void -es1371_speed_changed(void *priv) +es137x_speed_changed(void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; - dev->dac[1].latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) SOUND_FREQ)); + dev->dac[1].latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) (dev->type == AUDIOPCI_ES1370 ? WT_FREQ : SOUND_FREQ))); } +static const device_config_t es1370_config[] = { + // clang-format off + { + .name = "receive_input", + .description = "Receive input (MIDI)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + static const device_config_t es1371_config[] = { // clang-format off { @@ -2397,16 +2829,30 @@ static const device_config_t es1371_onboard_config[] = { // clang-format on }; +const device_t es1370_device = { + .name = "Ensoniq AudioPCI (ES1370)", + .internal_name = "es1370", + .flags = DEVICE_PCI, + .local = 0, + .init = es1370_init, + .close = es137x_close, + .reset = es137x_reset, + { .available = NULL }, + .speed_changed = es137x_speed_changed, + .force_redraw = NULL, + .config = es1370_config +}; + const device_t es1371_device = { .name = "Ensoniq AudioPCI (ES1371)", .internal_name = "es1371", .flags = DEVICE_PCI, .local = AUDIOPCI_ES1371, .init = es1371_init, - .close = es1371_close, - .reset = es1371_reset, + .close = es137x_close, + .reset = es137x_reset, .available = NULL, - .speed_changed = es1371_speed_changed, + .speed_changed = es137x_speed_changed, .force_redraw = NULL, .config = es1371_config }; @@ -2417,10 +2863,10 @@ const device_t es1371_onboard_device = { .flags = DEVICE_PCI, .local = AUDIOPCI_ES1371 | 1, .init = es1371_init, - .close = es1371_close, - .reset = es1371_reset, + .close = es137x_close, + .reset = es137x_reset, .available = NULL, - .speed_changed = es1371_speed_changed, + .speed_changed = es137x_speed_changed, .force_redraw = NULL, .config = es1371_onboard_config }; @@ -2431,10 +2877,10 @@ const device_t es1373_device = { .flags = DEVICE_PCI, .local = AUDIOPCI_ES1373, .init = es1371_init, - .close = es1371_close, - .reset = es1371_reset, + .close = es137x_close, + .reset = es137x_reset, .available = NULL, - .speed_changed = es1371_speed_changed, + .speed_changed = es137x_speed_changed, .force_redraw = NULL, .config = es1373_config }; @@ -2445,10 +2891,10 @@ const device_t es1373_onboard_device = { .flags = DEVICE_PCI, .local = AUDIOPCI_ES1373 | 1, .init = es1371_init, - .close = es1371_close, - .reset = es1371_reset, + .close = es137x_close, + .reset = es137x_reset, .available = NULL, - .speed_changed = es1371_speed_changed, + .speed_changed = es137x_speed_changed, .force_redraw = NULL, .config = es1371_onboard_config }; @@ -2459,10 +2905,10 @@ const device_t ct5880_device = { .flags = DEVICE_PCI, .local = AUDIOPCI_CT5880, .init = es1371_init, - .close = es1371_close, - .reset = es1371_reset, + .close = es137x_close, + .reset = es137x_reset, .available = NULL, - .speed_changed = es1371_speed_changed, + .speed_changed = es137x_speed_changed, .force_redraw = NULL, .config = ct5880_config }; @@ -2473,10 +2919,10 @@ const device_t ct5880_onboard_device = { .flags = DEVICE_PCI, .local = AUDIOPCI_CT5880 | 1, .init = es1371_init, - .close = es1371_close, - .reset = es1371_reset, + .close = es137x_close, + .reset = es137x_reset, .available = NULL, - .speed_changed = es1371_speed_changed, + .speed_changed = es137x_speed_changed, .force_redraw = NULL, .config = es1371_onboard_config }; diff --git a/src/sound/sound.c b/src/sound/sound.c index b1762eaff..28cb96629 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -153,6 +153,7 @@ static const SOUND_CARD sound_cards[] = { { &ess_soundpiper_32_mca_device }, { &cmi8338_device }, { &cmi8738_device }, + { &es1370_device }, { &es1371_device }, { &es1373_device }, { &ct5880_device }, From e9ea707f70403064ef9baf89aa0e917abf8aa146 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Thu, 2 Jan 2025 20:26:37 -0500 Subject: [PATCH 09/16] Fix some conditions, also parens Update snd_audiopci.c --- src/sound/snd_audiopci.c | 51 +++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 45b8d4c8c..6a6d22b32 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -164,7 +164,7 @@ static const double akm4531_att_2dbstep_5bits[] = { static double akm4531_gain_2dbstep_5bits[0x20]; -#define AUDIOPCI_ES1370 0x50001271 +#define AUDIOPCI_ES1370 0x50001274 #define AUDIOPCI_ES1371 0x13710200 #define AUDIOPCI_ES1373 0x13710400 #define AUDIOPCI_CT5880 0x58800400 @@ -444,7 +444,7 @@ es137x_reset(void *priv) Addressable as longword only */ if (dev->type >= AUDIOPCI_CT5880) dev->int_status = 0x52080ec0; - else if (dev->type >= AUDIOPCI_ES1373 && dev->type != AUDIOPCI_ES1370) + else if ((dev->type >= AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) dev->int_status = 0x7f080ec0; else dev->int_status = 0x7ffffec0; @@ -780,7 +780,7 @@ es137x_inb(uint16_t port, void *priv) break; case 0x03: ret = dev->int_ctrl >> 24; - if (dev->type < AUDIOPCI_ES1373 && dev->type != AUDIOPCI_ES1370) + if ((dev->type < AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) ret |= 0xfc; break; @@ -853,19 +853,19 @@ es137x_inb(uint16_t port, void *priv) /* S/PDIF Channel Status Control Register, Address 1CH Addressable as byte, word, longword */ case 0x1c: - if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) + if ((dev->type >= AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) ret = dev->spdif_chstatus & 0xff; break; case 0x1d: - if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) + if (dev->type >= AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) ret = dev->spdif_chstatus >> 8; break; case 0x1e: - if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) + if ((dev->type >= AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) ret = dev->spdif_chstatus >> 16; break; case 0x1f: - if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) + if ((dev->type >= AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) ret = dev->spdif_chstatus >> 24; break; @@ -906,7 +906,7 @@ es137x_inw(uint16_t port, void *priv) break; case 0x02: ret = (dev->int_ctrl >> 16) & 0xff0f; - if (dev->type < AUDIOPCI_ES1373 && dev->type != AUDIOPCI_ES1370) + if ((dev->type < AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) ret |= 0xfc00; break; @@ -931,11 +931,11 @@ es137x_inw(uint16_t port, void *priv) /* S/PDIF Channel Status Control Register, Address 1CH Addressable as byte, word, longword */ case 0x1c: - if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) + if ((dev->type >= AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) ret = dev->spdif_chstatus & 0xffff; break; case 0x1e: - if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) + if ((dev->type >= AUDIOPCI_ES1373) && dev->type != AUDIOPCI_ES1370)) ret = dev->spdif_chstatus >> 16; break; @@ -1003,7 +1003,7 @@ es137x_inl(uint16_t port, void *priv) es137x_t *dev = (es137x_t *) priv; uint32_t ret = 0xffffffff; - if (dev->type == AUDIOPCI_ES1370 && (port & 0x3c) == 0x14) + if ((dev->type == AUDIOPCI_ES1370) && (port & 0x3c) == 0x14) port = 0x10; switch (port & 0x3c) { @@ -1011,7 +1011,7 @@ es137x_inl(uint16_t port, void *priv) Addressable as byte, word, longword */ case 0x00: ret = dev->int_ctrl & 0xff0fffff; - if (ret < AUDIOPCI_ES1373 && ret != AUDIOPCI_ES1370) + if ((ret < AUDIOPCI_ES1373) && (ret != AUDIOPCI_ES1370)) ret |= 0xfc000000; break; @@ -1052,7 +1052,7 @@ es137x_inl(uint16_t port, void *priv) /* S/PDIF Channel Status Control Register, Address 1CH Addressable as byte, word, longword */ case 0x1c: - if (dev->type >= AUDIOPCI_ES1373 || dev->type == AUDIOPCI_ES1370) + if ((dev->type >= AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_ES1370)) ret = dev->spdif_chstatus; break; @@ -1144,11 +1144,11 @@ es137x_outb(uint16_t port, uint8_t val, void *priv) Addressable as longword only, but PCem implements byte access, which must be for a reason */ case 0x06: - if (dev->type >= AUDIOPCI_ES1373 || dev->type == AUDIOPCI_ES1370) + if ((dev->type >= AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_ES1370)) dev->int_status = (dev->int_status & 0xff08ffff) | (val << 16); break; case 0x07: - if (dev->type >= AUDIOPCI_CT5880 || dev->type == AUDIOPCI_ES1370) + if ((dev->type >= AUDIOPCI_CT5880) || (dev->type == AUDIOPCI_ES1370)) dev->int_status = (dev->int_status & 0xd2ffffff) | (val << 24); break; @@ -1413,7 +1413,7 @@ es137x_outl(uint16_t port, uint32_t val, void *priv) audiopci_log("[W] STATUS = %08X\n", val); if (dev->type >= AUDIOPCI_CT5880) dev->int_status = (dev->int_status & 0xd208ffff) | (val & 0x2df70000); - else if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) + else if ((dev->type >= AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) dev->int_status = (dev->int_status & 0xff08ffff) | (val & 0x00f70000); break; @@ -1426,8 +1426,7 @@ es137x_outl(uint16_t port, uint32_t val, void *priv) /* Sample Rate Converter Interface Register, Address 10H Addressable as longword only */ case 0x10: - if (dev->type == AUDIOPCI_ES1370) - { + if (dev->type == AUDIOPCI_ES1370) { dev->akm_codec.registers[(val >> 8) & 0xFF] = val & 0xFF; if ((val >> 8) == 0x16 && !(val & 1)) akm4531_reset(dev); @@ -2033,7 +2032,7 @@ es1371_pci_read(int func, int addr, void *priv) return 0x80; /* Maximum latency */ case 0x40: - if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) + if ((dev->type >= AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) return dev->subsys_lock; break; @@ -2164,7 +2163,7 @@ es1371_pci_write(int func, int addr, uint8_t val, void *priv) break; case 0x40: - if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) + if ((dev->type >= AUDIOPCI_ES1373) && dev->type != AUDIOPCI_ES1370)) dev->subsys_lock = val; break; @@ -2387,9 +2386,8 @@ es137x_poll(void *priv) es137x_update(dev); if (dev->int_ctrl & INT_DAC1_EN) { - if (((dev->type >= AUDIOPCI_ES1373) && (dev->int_ctrl & INT_DAC1_BYPASS)) || dev->type == AUDIOPCI_ES1370) { - if (dev->calc_sample_rate_synth != 44100 && dev->type == AUDIOPCI_ES1370) - { + if (((dev->type >= AUDIOPCI_ES1373) && (dev->int_ctrl & INT_DAC1_BYPASS)) || (dev->type == AUDIOPCI_ES1370)) { + if ((dev->calc_sample_rate_synth != 44100) && (dev->type == AUDIOPCI_ES1370)) { if ((dev->dac[0].buffer_pos - dev->dac[0].buffer_pos_end) >= 0 && dev->step_synth >= dev->interp_step_synth) es137x_fetch(dev, 0); @@ -2446,9 +2444,8 @@ dac0_count: } if (dev->int_ctrl & INT_DAC2_EN) { - if (((dev->type >= AUDIOPCI_ES1373) && (dev->int_ctrl & INT_DAC2_BYPASS)) || dev->type == AUDIOPCI_ES1370) { - if (dev->calc_sample_rate != 44100 && dev->type == AUDIOPCI_ES1370) - { + if (((dev->type >= AUDIOPCI_ES1373) && (dev->int_ctrl & INT_DAC2_BYPASS)) || (dev->type == AUDIOPCI_ES1370)) { + if (dev->calc_sample_rate != 44100 && dev->type == AUDIOPCI_ES1370) { if ((dev->dac[1].buffer_pos - dev->dac[1].buffer_pos_end) >= 0 && dev->step_pcm >= dev->interp_step) es137x_fetch(dev, 1); @@ -2706,7 +2703,7 @@ es137x_speed_changed(void *priv) { es137x_t *dev = (es137x_t *) priv; - dev->dac[1].latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) (dev->type == AUDIOPCI_ES1370 ? WT_FREQ : SOUND_FREQ))); + dev->dac[1].latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) ((dev->type == AUDIOPCI_ES1370) ? WT_FREQ : SOUND_FREQ))); } static const device_config_t es1370_config[] = { From 04520db27fe7ec7b43ac41f252f7488caa2dcece Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Thu, 2 Jan 2025 20:29:40 -0500 Subject: [PATCH 10/16] Formatting in snd_audiopci.c --- src/sound/snd_audiopci.c | 144 ++++++++++++++++++++------------------- 1 file changed, 74 insertions(+), 70 deletions(-) diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 6a6d22b32..44f6dbc2c 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -145,10 +145,10 @@ typedef struct es137x_t { uint32_t calc_sample_rate; uint32_t calc_sample_rate_synth; - double interp_factor; + double interp_factor; uint32_t interp_step; - double interp_factor_synth; + double interp_factor_synth; uint32_t interp_step_synth; uint32_t step_pcm; @@ -156,18 +156,20 @@ typedef struct es137x_t { } es137x_t; static const double akm4531_att_2dbstep_5bits[] = { + // clang-format off 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 + // clang-format on }; static double akm4531_gain_2dbstep_5bits[0x20]; -#define AUDIOPCI_ES1370 0x50001274 -#define AUDIOPCI_ES1371 0x13710200 -#define AUDIOPCI_ES1373 0x13710400 -#define AUDIOPCI_CT5880 0x58800400 +#define AUDIOPCI_ES1370 0x50001274 +#define AUDIOPCI_ES1371 0x13710200 +#define AUDIOPCI_ES1373 0x13710400 +#define AUDIOPCI_CT5880 0x58800400 #define LEGACY_SB_ADDR (1 << 29) #define LEGACY_SSCAPE_ADDR_SHIFT 27 @@ -365,7 +367,7 @@ es137x_reset_fifo(es137x_t *dev) static void akm4531_reset(es137x_t *dev) { - akm4531_t* codec = &dev->akm_codec; + akm4531_t *codec = &dev->akm_codec; memset(codec->registers, 0, sizeof(codec->registers)); @@ -382,8 +384,10 @@ akm4531_reset(es137x_t *dev) codec->registers[0x16] = 0x3; } -static double lerp(double v0, double v1, double t) { - return (1. - t) * v0 + t * v1; +static double +lerp(double v0, double v1, double t) +{ + return (1. - t) * v0 + t * v1; } static void @@ -394,34 +398,34 @@ es1370_calc_sample_rate(es137x_t *dev) dev->calc_sample_rate = 1411200 / (((dev->int_ctrl >> 16) & 0x1fff) + 2); - //pclog("ES1370 calc sample rate %u\n", dev->calc_sample_rate); + // pclog("ES1370 calc sample rate %u\n", dev->calc_sample_rate); dev->interp_factor = 1.0; - dev->interp_step = 1; + dev->interp_step = 1; if (dev->calc_sample_rate >= 44100 || dev->calc_sample_rate < 11025) { - dev->interp_factor = 1.0; - dev->interp_step = 1; + dev->interp_factor = 1.0; + dev->interp_step = 1; dev->calc_sample_rate = 44100; } if (dev->calc_sample_rate == 22050) { dev->interp_factor = 0.5; - dev->interp_step = 2; + dev->interp_step = 2; } if (dev->calc_sample_rate == 11025) { dev->interp_factor = 0.25; - dev->interp_step = 4; + dev->interp_step = 4; } if ((((dev->int_ctrl >> 16) & 0x1fff) + 2) == 256) { /* 5512.5 Hz */ - dev->interp_factor = 0.125; - dev->interp_step = 8; + dev->interp_factor = 0.125; + dev->interp_step = 8; dev->calc_sample_rate = 5512; } dev->calc_sample_rate_synth = 44100 / (1 << ((dev->int_ctrl >> 12) & 3)); - dev->interp_factor_synth = 1. / (double)(1 << ((dev->int_ctrl >> 12) & 3)); - dev->interp_step_synth = (1 << ((dev->int_ctrl >> 12) & 3)); + dev->interp_factor_synth = 1. / (double) (1 << ((dev->int_ctrl >> 12) & 3)); + dev->interp_step_synth = (1 << ((dev->int_ctrl >> 12) & 3)); } static void @@ -432,7 +436,7 @@ es137x_reset(void *priv) nmi = 0; /* Default subsystem ID. */ - dev->subsys_lock = 0x00; + dev->subsys_lock = 0x00; *((uint16_t *) &dev->subsys_id[0]) = (dev->type == AUDIOPCI_ES1370) ? 0x4942 : 0x1274; *((uint16_t *) &dev->subsys_id[2]) = (dev->type == AUDIOPCI_ES1370) ? 0x4c4c : 0x1371; @@ -1123,7 +1127,7 @@ es137x_outb(uint16_t port, uint8_t val, void *priv) dev->dac[1].prev_out_r = 0; es137x_fetch(dev, 1); } - //pclog("INTCTRL 0x%02X\n", val & 0xff); + // pclog("INTCTRL 0x%02X\n", val & 0xff); dev->int_ctrl = (dev->int_ctrl & 0xffffff00) | val; break; case 0x01: @@ -1278,7 +1282,7 @@ es137x_outw(uint16_t port, uint16_t val, void *priv) dev->step_pcm = dev->interp_step; es137x_fetch(dev, 1); } - //pclog("INTCTRL 0x%02X\n", val & 0xff); + // pclog("INTCTRL 0x%02X\n", val & 0xff); dev->int_ctrl = (dev->int_ctrl & 0xffff0000) | val; break; case 0x02: @@ -1300,7 +1304,7 @@ es137x_outw(uint16_t port, uint16_t val, void *priv) case 0x10: if (dev->type != AUDIOPCI_ES1370) break; - + dev->akm_codec.registers[(val >> 8) & 0xFF] = val & 0xFF; if ((val >> 8) == 0x16 && !(val & 1)) akm4531_reset(dev); @@ -1376,36 +1380,36 @@ es137x_outl(uint16_t port, uint32_t val, void *priv) /* Interrupt/Chip Select Control Register, Address 00H Addressable as byte, word, longword */ case 0x00: - { - uint8_t dac1start = 0, dac2start = 0; - if (!(dev->int_ctrl & INT_DAC1_EN) && (val & INT_DAC1_EN)) { - dev->dac[0].addr = dev->dac[0].addr_latch; - dev->dac[0].buffer_pos = 0; - dev->dac[0].buffer_pos_end = 0; - dev->dac[0].prev_out_l = 0; - dev->dac[0].prev_out_r = 0; - dac1start = 1; - es137x_fetch(dev, 0); + { + uint8_t dac1start = 0, dac2start = 0; + if (!(dev->int_ctrl & INT_DAC1_EN) && (val & INT_DAC1_EN)) { + dev->dac[0].addr = dev->dac[0].addr_latch; + dev->dac[0].buffer_pos = 0; + dev->dac[0].buffer_pos_end = 0; + dev->dac[0].prev_out_l = 0; + dev->dac[0].prev_out_r = 0; + dac1start = 1; + es137x_fetch(dev, 0); + } + if (!(dev->int_ctrl & INT_DAC2_EN) && (val & INT_DAC2_EN)) { + dev->dac[1].addr = dev->dac[1].addr_latch; + dev->dac[1].buffer_pos = 0; + dev->dac[1].buffer_pos_end = 0; + dev->dac[1].prev_out_l = 0; + dev->dac[1].prev_out_r = 0; + dac2start = 1; + es137x_fetch(dev, 1); + } + // pclog("INTCTRL 0x%02X\n", val & 0xff); + dev->int_ctrl = val; + gameport_remap(dev->gameport, 0x200 | ((val & 0x03000000) >> 21)); + es1370_calc_sample_rate(dev); + if (dac1start) + dev->step_synth = dev->interp_step_synth; + if (dac2start) + dev->step_pcm = dev->interp_step; + break; } - if (!(dev->int_ctrl & INT_DAC2_EN) && (val & INT_DAC2_EN)) { - dev->dac[1].addr = dev->dac[1].addr_latch; - dev->dac[1].buffer_pos = 0; - dev->dac[1].buffer_pos_end = 0; - dev->dac[1].prev_out_l = 0; - dev->dac[1].prev_out_r = 0; - dac2start = 1; - es137x_fetch(dev, 1); - } - //pclog("INTCTRL 0x%02X\n", val & 0xff); - dev->int_ctrl = val; - gameport_remap(dev->gameport, 0x200 | ((val & 0x03000000) >> 21)); - es1370_calc_sample_rate(dev); - if (dac1start) - dev->step_synth = dev->interp_step_synth; - if (dac2start) - dev->step_pcm = dev->interp_step; - break; - } /* Interrupt/Chip Select Status Register, Address 04H Addressable as longword only */ @@ -1875,12 +1879,12 @@ es1370_pci_read(int func, int addr, void *priv) return 0x00; switch (addr) { - case 0x00: /* Vendor ID */ + case 0x00: /* Vendor ID */ return 0x74; /* Ensoniq */ case 0x01: return 0x12; - case 0x02: /* Device ID */ + case 0x02: /* Device ID */ return 0x00; /* ES1370 */ case 0x03: return 0x50; @@ -1890,12 +1894,12 @@ es1370_pci_read(int func, int addr, void *priv) case 0x05: return dev->pci_serr; - case 0x06: /* Status TODO */ + case 0x06: /* Status TODO */ return 0x10; /* Supports ACPI */ case 0x07: return 0x00; - case 0x08: /* Class Code & Revision ID */ + case 0x08: /* Class Code & Revision ID */ return 0x00; /* Revision ID - 0x00 is actual Ensoniq-branded ES1370 */ case 0x09: return 0x00; /* Multimedia audio device */ @@ -1909,7 +1913,7 @@ es1370_pci_read(int func, int addr, void *priv) // case 0x0e: /* Header Type TODO */ // case 0x0f: /* BIST TODO */ - case 0x10: /* Base Address TODO */ + case 0x10: /* Base Address TODO */ return 0x01 | (dev->base_addr & 0xc0); /* memBaseAddr */ case 0x11: return dev->base_addr >> 8; @@ -2637,8 +2641,8 @@ es1370_init(const device_t *info) dev->dac[1].vol_l = 1 << 12; dev->dac[1].vol_r = 1 << 12; - dev->pcm_vol_l = 1 << 15; - dev->pcm_vol_r = 1 << 15; + dev->pcm_vol_l = 1 << 15; + dev->pcm_vol_r = 1 << 15; dev->master_vol_l = 1 << 15; dev->master_vol_r = 1 << 15; @@ -2649,7 +2653,7 @@ es1370_init(const device_t *info) es137x_speed_changed(dev); for (int i = 0; i < 0x20; i++) { - double attn = (12.0 - (i * 2.0)); + double attn = (12.0 - (i * 2.0)); akm4531_gain_2dbstep_5bits[i] = pow(10, attn / 10.) * 32767.0; } @@ -2707,7 +2711,7 @@ es137x_speed_changed(void *priv) } static const device_config_t es1370_config[] = { - // clang-format off + // clang-format off { .name = "receive_input", .description = "Receive input (MIDI)", @@ -2716,11 +2720,11 @@ static const device_config_t es1370_config[] = { .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } - // clang-format on + // clang-format on }; static const device_config_t es1371_config[] = { - // clang-format off + // clang-format off { .name = "codec", .description = "Codec", @@ -2746,11 +2750,11 @@ static const device_config_t es1371_config[] = { .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } - // clang-format on + // clang-format on }; static const device_config_t es1373_config[] = { - // clang-format off + // clang-format off { .name = "codec", .description = "Codec", @@ -2780,11 +2784,11 @@ static const device_config_t es1373_config[] = { .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } - // clang-format on + // clang-format on }; static const device_config_t ct5880_config[] = { - // clang-format off + // clang-format off { .name = "codec", .description = "Codec", @@ -2810,11 +2814,11 @@ static const device_config_t ct5880_config[] = { .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } - // clang-format on + // clang-format on }; static const device_config_t es1371_onboard_config[] = { - // clang-format off + // clang-format off { .name = "receive_input", .description = "Receive MIDI input", @@ -2823,7 +2827,7 @@ static const device_config_t es1371_onboard_config[] = { .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } - // clang-format on + // clang-format on }; const device_t es1370_device = { From 2ca36cdc7d8895fc7bb1457def9e57e92cc95388 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 Jan 2025 05:21:45 +0100 Subject: [PATCH 11/16] Fixed a typo in a comment. --- 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 20af6a13d..e489ad93b 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -520,7 +520,7 @@ main(int argc, char *argv[]) #ifdef Q_OS_WINDOWS if (hook_enabled) { - /* Yes, low-level hooks *DO* work raw input, at least global ones. */ + /* Yes, low-level hooks *DO* work with raw input, at least global ones. */ llhook = SetWindowsHookEx(WH_KEYBOARD_LL, emu_LowLevelKeyboardProc, NULL, 0); atexit([] () -> void { if (llhook) From 6c24662c8d177ccd584f65f274b5a033458282b4 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Thu, 2 Jan 2025 22:24:15 -0500 Subject: [PATCH 12/16] More fixes to parens and normalization of es1370 --- src/sound/snd_audiopci.c | 79 +++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 42 deletions(-) diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 44f6dbc2c..ca929fc14 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -1,24 +1,24 @@ /* - * 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. + * 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. + * This file is part of the 86Box distribution. * - * Ensoniq AudioPCI family emulation. + * Ensoniq AudioPCI family emulation. * - * Authors: Sarah Walker, - * RichardG, - * Miran Grca, - * Jasmine Iwanek, - * Cacodemon345 + * Authors: Sarah Walker, + * RichardG, + * Miran Grca, + * Jasmine Iwanek, + * Cacodemon345 * - * Copyright 2008-2021 Sarah Walker. - * Copyright 2021-2024 RichardG. - * Copyright 2021 Miran Grca. - * Copyright 2024-2025 Jasmine Iwanek. - * Copyright 2024-2025 Cacodemon345. + * Copyright 2008-2021 Sarah Walker. + * Copyright 2021-2024 RichardG. + * Copyright 2021 Miran Grca. + * Copyright 2024-2025 Jasmine Iwanek. + * Copyright 2024-2025 Cacodemon345. */ #include #include @@ -166,7 +166,7 @@ static const double akm4531_att_2dbstep_5bits[] = { static double akm4531_gain_2dbstep_5bits[0x20]; -#define AUDIOPCI_ES1370 0x50001274 +#define AUDIOPCI_ES1370 0x50000000 #define AUDIOPCI_ES1371 0x13710200 #define AUDIOPCI_ES1373 0x13710400 #define AUDIOPCI_CT5880 0x58800400 @@ -861,7 +861,7 @@ es137x_inb(uint16_t port, void *priv) ret = dev->spdif_chstatus & 0xff; break; case 0x1d: - if (dev->type >= AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) + if ((dev->type >= AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) ret = dev->spdif_chstatus >> 8; break; case 0x1e: @@ -939,7 +939,7 @@ es137x_inw(uint16_t port, void *priv) ret = dev->spdif_chstatus & 0xffff; break; case 0x1e: - if ((dev->type >= AUDIOPCI_ES1373) && dev->type != AUDIOPCI_ES1370)) + if ((dev->type >= AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) ret = dev->spdif_chstatus >> 16; break; @@ -1056,7 +1056,7 @@ es137x_inl(uint16_t port, void *priv) /* S/PDIF Channel Status Control Register, Address 1CH Addressable as byte, word, longword */ case 0x1c: - if ((dev->type >= AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_ES1370)) + if ((dev->type >= AUDIOPCI_ES1373) || (dev->type != AUDIOPCI_ES1370)) ret = dev->spdif_chstatus; break; @@ -1127,7 +1127,7 @@ es137x_outb(uint16_t port, uint8_t val, void *priv) dev->dac[1].prev_out_r = 0; es137x_fetch(dev, 1); } - // pclog("INTCTRL 0x%02X\n", val & 0xff); + // audiopci_log("INTCTRL 0x%02X\n", val & 0xff); dev->int_ctrl = (dev->int_ctrl & 0xffffff00) | val; break; case 0x01: @@ -1148,11 +1148,11 @@ es137x_outb(uint16_t port, uint8_t val, void *priv) Addressable as longword only, but PCem implements byte access, which must be for a reason */ case 0x06: - if ((dev->type >= AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_ES1370)) + if ((dev->type >= AUDIOPCI_ES1373) || (dev->type != AUDIOPCI_ES1370)) dev->int_status = (dev->int_status & 0xff08ffff) | (val << 16); break; case 0x07: - if ((dev->type >= AUDIOPCI_CT5880) || (dev->type == AUDIOPCI_ES1370)) + if ((dev->type >= AUDIOPCI_CT5880) || (dev->type != AUDIOPCI_ES1370)) dev->int_status = (dev->int_status & 0xd2ffffff) | (val << 24); break; @@ -1282,7 +1282,7 @@ es137x_outw(uint16_t port, uint16_t val, void *priv) dev->step_pcm = dev->interp_step; es137x_fetch(dev, 1); } - // pclog("INTCTRL 0x%02X\n", val & 0xff); + // audiopci_log("INTCTRL 0x%02X\n", val & 0xff); dev->int_ctrl = (dev->int_ctrl & 0xffff0000) | val; break; case 0x02: @@ -1381,7 +1381,9 @@ es137x_outl(uint16_t port, uint32_t val, void *priv) Addressable as byte, word, longword */ case 0x00: { - uint8_t dac1start = 0, dac2start = 0; + uint8_t dac1start = 0; + uint8_t dac2start = 0; + if (!(dev->int_ctrl & INT_DAC1_EN) && (val & INT_DAC1_EN)) { dev->dac[0].addr = dev->dac[0].addr_latch; dev->dac[0].buffer_pos = 0; @@ -1400,7 +1402,7 @@ es137x_outl(uint16_t port, uint32_t val, void *priv) dac2start = 1; es137x_fetch(dev, 1); } - // pclog("INTCTRL 0x%02X\n", val & 0xff); + // audiopci_log("INTCTRL 0x%02X\n", val & 0xff); dev->int_ctrl = val; gameport_remap(dev->gameport, 0x200 | ((val & 0x03000000) >> 21)); es1370_calc_sample_rate(dev); @@ -1885,9 +1887,9 @@ es1370_pci_read(int func, int addr, void *priv) return 0x12; case 0x02: /* Device ID */ - return 0x00; /* ES1370 */ + return dev->type >> 16; /* ES1370 */ case 0x03: - return 0x50; + return dev->type >> 24; case 0x04: /* Command TODO */ return dev->pci_command; @@ -1900,7 +1902,7 @@ es1370_pci_read(int func, int addr, void *priv) return 0x00; case 0x08: /* Class Code & Revision ID */ - return 0x00; /* Revision ID - 0x00 is actual Ensoniq-branded ES1370 */ + return dev->type >> 8; /* Revision ID - 0x00 is actual Ensoniq-branded ES1370 */ case 0x09: return 0x00; /* Multimedia audio device */ case 0x0a: @@ -1922,14 +1924,8 @@ es1370_pci_read(int func, int addr, void *priv) case 0x13: return dev->base_addr >> 24; - case 0x2c: - return 0x42; /* Subsystem vendor ID */ - case 0x2d: - return 0x49; - case 0x2e: - return 0x4c; /* Subsystem product ID */ - case 0x2f: - return 0x4c; + case 0x2c ... 0x2f: + return dev->subsys_id[addr & 3]; /* Subsystem vendor ID */ #if 0 case 0x34: // TODO @@ -2167,7 +2163,7 @@ es1371_pci_write(int func, int addr, uint8_t val, void *priv) break; case 0x40: - if ((dev->type >= AUDIOPCI_ES1373) && dev->type != AUDIOPCI_ES1370)) + if ((dev->type >= AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) dev->subsys_lock = val; break; @@ -2449,7 +2445,7 @@ dac0_count: if (dev->int_ctrl & INT_DAC2_EN) { if (((dev->type >= AUDIOPCI_ES1373) && (dev->int_ctrl & INT_DAC2_BYPASS)) || (dev->type == AUDIOPCI_ES1370)) { - if (dev->calc_sample_rate != 44100 && dev->type == AUDIOPCI_ES1370) { + if ((dev->calc_sample_rate != 44100) && (dev->type == AUDIOPCI_ES1370)) { if ((dev->dac[1].buffer_pos - dev->dac[1].buffer_pos_end) >= 0 && dev->step_pcm >= dev->interp_step) es137x_fetch(dev, 1); @@ -2620,6 +2616,7 @@ es1370_init(const device_t *info) { es137x_t *dev = malloc(sizeof(es137x_t)); memset(dev, 0x00, sizeof(es137x_t)); + dev->type = info->local; if (device_get_config_int("receive_input")) midi_in_handler(1, es137x_input_msg, es137x_input_sysex, dev); @@ -2646,8 +2643,6 @@ es1370_init(const device_t *info) dev->master_vol_l = 1 << 15; dev->master_vol_r = 1 << 15; - dev->type = AUDIOPCI_ES1370; - es137x_reset(dev); es137x_speed_changed(dev); @@ -2834,7 +2829,7 @@ const device_t es1370_device = { .name = "Ensoniq AudioPCI (ES1370)", .internal_name = "es1370", .flags = DEVICE_PCI, - .local = 0, + .local = AUDIOPCI_ES1370, .init = es1370_init, .close = es137x_close, .reset = es137x_reset, From f1d25fc9d6eede852933d75589747f6e275ef521 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Thu, 2 Jan 2025 23:44:53 -0500 Subject: [PATCH 13/16] Cleaning in snd_sb.c --- src/sound/snd_sb.c | 347 +++++++++++++++++++++++---------------------- 1 file changed, 175 insertions(+), 172 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 8ac27882b..3213e3cf0 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -144,8 +144,8 @@ 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; + sb_t *sb = (sb_t *) priv; + const sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; double out_mono; sb_dsp_update(&sb->dsp); @@ -154,8 +154,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) { - double out_l = 0.0; - double out_r = 0.0; + double out_l = 0.0; + double out_r = 0.0; if (sb->cms_enabled) { out_l += sb->cms.buffer[c]; @@ -195,15 +195,15 @@ 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) { - const sb_t *sb = (const sb_t *) priv; - const sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; - const int32_t *opl_buf = NULL; + 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) { - double out_l = 0.0; - double out_r = 0.0; + double out_l = 0.0; + double out_r = 0.0; const double out_mono = ((double) opl_buf[c]) * 0.7171630859375; @@ -341,8 +341,8 @@ sbpro_filter_cd_audio(int channel, double *buffer, void *priv) 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; + sb_t *sb = (sb_t *) priv; + const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; double bass_treble; sb_dsp_update(&sb->dsp); @@ -415,7 +415,7 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, const int len, void *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); @@ -508,7 +508,6 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, const int len, void *priv) sb->opl.reset_buffer(sb->opl.priv); } -// TODO: Goldfinch static void sb_get_wavetable_buffer_goldfinch(int32_t *buffer, const int len, void *priv) { @@ -533,8 +532,8 @@ sb_get_wavetable_buffer_goldfinch(int32_t *buffer, const int len, void *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; + sb_t *sb = (sb_t *) priv; + const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; double bass_treble; emu8k_update(&sb->emu8k); @@ -1215,7 +1214,7 @@ 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 ret = 0xff; + uint8_t ret = 0xff; sb_log("sb_ct1745: received register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); @@ -1343,9 +1342,9 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) 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; + ret = temp | 0x80; else - ret = temp | 0x40; + ret = temp | 0x40; break; case 0x83: @@ -1371,22 +1370,22 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) ret |= 0x01; break; - case 0x49: /* Undocumented register used by some Creative drivers. */ - case 0x4a: /* Undocumented register used by some Creative drivers. */ - case 0x8c: /* Undocumented register used by some Creative drivers. */ - case 0x8e: /* Undocumented register used by some Creative drivers. */ - case 0x90: /* 3D Enhancement switch. */ - case 0xfd: /* Undocumented register used by some Creative drivers. */ - case 0xfe: /* Undocumented register used by some Creative drivers. */ + case 0x49: /* Undocumented register used by some Creative drivers. */ + case 0x4a: /* Undocumented register used by some Creative drivers. */ + case 0x8c: /* Undocumented register used by some Creative drivers. */ + case 0x8e: /* Undocumented register used by some Creative drivers. */ + case 0x90: /* 3D Enhancement switch. */ + case 0xfd: /* Undocumented register used by some Creative drivers. */ + case 0xfe: /* Undocumented register used by some Creative drivers. */ ret = mixer->regs[mixer->index]; break; - case 0xff: /* Undocumented register used by some Creative drivers. - This and the upper bits of 0x82 seem to affect the - playback volume: - - Register FF = FF: Volume playback normal. - - Register FF = Not FF: Volume playback low unless - bit 6 of 82h is set. */ + case 0xff: /* Undocumented register used by some Creative drivers. + This and the upper bits of 0x82 seem to affect the + playback volume: + - Register FF = FF: Volume playback normal. + - Register FF = Not FF: Volume playback low unless + bit 6 of 82h is set. */ if (sb->dsp.sb_type > SBAWE32) ret = mixer->regs[mixer->index]; break; @@ -1416,7 +1415,7 @@ sb_ct1745_mixer_reset(sb_t *sb) static void ess_base_write(uint16_t addr, uint8_t val, void *priv) { - sb_t * ess = (sb_t *) priv; + sb_t *ess = (sb_t *) priv; switch (addr & 0x000f) { case 0x0002: @@ -1435,7 +1434,7 @@ ess_base_write(uint16_t addr, uint8_t val, void *priv) static uint8_t ess_base_read(uint16_t addr, void *priv) { - sb_t * ess = (sb_t *) priv; + sb_t *ess = (sb_t *) priv; switch (addr & 0x000f) { case 0x0002: @@ -1462,7 +1461,7 @@ ess_base_read(uint16_t addr, void *priv) static void ess_fm_midi_write(uint16_t addr, uint8_t val, void *priv) { - sb_t * ess = (sb_t *) priv; + sb_t *ess = (sb_t *) priv; ess->dsp.activity &= 0x7f; } @@ -1470,7 +1469,7 @@ ess_fm_midi_write(uint16_t addr, uint8_t val, void *priv) static uint8_t ess_fm_midi_read(uint16_t addr, void *priv) { - sb_t * ess = (sb_t *) priv; + sb_t *ess = (sb_t *) priv; ess->dsp.activity &= 0x7f; @@ -1548,8 +1547,8 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) break; case 0x0E: - mixer->output_filter = !(mixer->regs[0xE] & 0x20); - mixer->stereo = mixer->regs[0xE] & 2; + mixer->output_filter = !(mixer->regs[0xE] & 0x20); + mixer->stereo = mixer->regs[0xE] & 2; sb_dsp_set_stereo(&ess->dsp, val & 2); break; @@ -1586,12 +1585,18 @@ 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 0x00: case 0x04: case 0x3a: case 0x3c: + case 0x00: + case 0x04: + case 0x3a: + case 0x3c: break; case 0x64: @@ -1625,43 +1630,44 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) } } - if (ess->mpu != NULL) switch ((mixer->regs[0x40] >> 5) & 0x7) { - default: - break; - case 0: - mpu401_base_addr = 0x0000; - mpu401_change_addr(ess->mpu, mpu401_base_addr); - 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; - } + if (ess->mpu != NULL) + switch ((mixer->regs[0x40] >> 5) & 0x7) { + default: + break; + case 0: + mpu401_base_addr = 0x0000; + mpu401_change_addr(ess->mpu, mpu401_base_addr); + 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; + } ess->midi_addr = mpu401_base_addr; io_sethandler(addr, 0x0002, ess_fm_midi_read, NULL, NULL, @@ -1696,85 +1702,86 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) uint8_t ess_mixer_read(uint16_t addr, void *priv) { - const sb_t * ess = (sb_t *) priv; + const sb_t *ess = (sb_t *) priv; const ess_mixer_t *mixer = &ess->mixer_ess; uint8_t ret = 0x0a; if (!(addr & 1)) ret = mixer->index; - else switch (mixer->index) { - case 0x00: - case 0x0a: - case 0x0c: - case 0x0e: - case 0x14: - case 0x1a: - case 0x02: - case 0x06: - case 0x30: - case 0x32: - case 0x36: - case 0x38: - case 0x3e: - ret = mixer->regs[mixer->index]; - break; - - case 0x04: - case 0x22: - case 0x26: - case 0x28: - case 0x2e: - ret = mixer->regs[mixer->index] | 0x11; - break; - - /* Bit 1 always set, bits 7-6 always clear on both the real ES688 and ES1688. */ - case 0x1c: - ret = mixer->regs[mixer->index] | 0x10; - break; - - /* - Real ES688: Always 0x00; - Real ES1688: Bit 2 always clear. - */ - case 0x40: - if (ess->dsp.sb_subtype > SB_SUBTYPE_ESS_ES1688) + else + switch (mixer->index) { + case 0x00: + case 0x0a: + case 0x0c: + case 0x0e: + case 0x14: + case 0x1a: + case 0x02: + case 0x06: + case 0x30: + case 0x32: + case 0x36: + case 0x38: + case 0x3e: ret = mixer->regs[mixer->index]; - else if (ess->dsp.sb_subtype >= SB_SUBTYPE_ESS_ES1688) - ret = mixer->regs[mixer->index] & 0xfb; - else - ret = 0x00; - break; + break; - /* - Real ES688: Always 0x00; - Real ES1688: All bits writable. - */ - case 0x48: - if (ess->dsp.sb_subtype >= SB_SUBTYPE_ESS_ES1688) - ret = mixer->regs[mixer->index]; - else - ret = 0x00; - break; + case 0x04: + case 0x22: + case 0x26: + case 0x28: + case 0x2e: + ret = mixer->regs[mixer->index] | 0x11; + break; - /* - Return 0x00 so it has bit 3 clear, so NT 5.x drivers don't misdetect it as ES1788. - Bit 3 set and writable: ESSCFG detects the card as ES1788 if register 70h is read-only, - otherwise, as ES1887. - Bit 3 set and read-only: ESSCFG detects the card as ES1788 if register 70h is read-only, - otherwise, as ES1888. - Real ES688 and ES1688: Always 0x00. - */ - case 0x64: - if (ess->dsp.sb_subtype > SB_SUBTYPE_ESS_ES1688) - ret = (mixer->regs[mixer->index] & 0xf7) | 0x20; - else - ret = 0x00; - break; + /* Bit 1 always set, bits 7-6 always clear on both the real ES688 and ES1688. */ + case 0x1c: + ret = mixer->regs[mixer->index] | 0x10; + break; - default: - sb_log("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); - break; - } + /* + Real ES688: Always 0x00; + Real ES1688: Bit 2 always clear. + */ + case 0x40: + if (ess->dsp.sb_subtype > SB_SUBTYPE_ESS_ES1688) + ret = mixer->regs[mixer->index]; + else if (ess->dsp.sb_subtype >= SB_SUBTYPE_ESS_ES1688) + ret = mixer->regs[mixer->index] & 0xfb; + else + ret = 0x00; + break; + + /* + Real ES688: Always 0x00; + Real ES1688: All bits writable. + */ + case 0x48: + if (ess->dsp.sb_subtype >= SB_SUBTYPE_ESS_ES1688) + ret = mixer->regs[mixer->index]; + else + ret = 0x00; + break; + + /* + Return 0x00 so it has bit 3 clear, so NT 5.x drivers don't misdetect it as ES1788. + Bit 3 set and writable: ESSCFG detects the card as ES1788 if register 70h is read-only, + otherwise, as ES1887. + Bit 3 set and read-only: ESSCFG detects the card as ES1788 if register 70h is read-only, + otherwise, as ES1888. + Real ES688 and ES1688: Always 0x00. + */ + case 0x64: + if (ess->dsp.sb_subtype > SB_SUBTYPE_ESS_ES1688) + ret = (mixer->regs[mixer->index] & 0xf7) | 0x20; + else + ret = 0x00; + break; + + default: + sb_log("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + break; + } sb_log("[%04X:%08X] [R] %04X = %02X (%02X)\n", CS, cpu_state.pc, addr, ret, mixer->index); @@ -1854,8 +1861,8 @@ sb_mcv_feedb(void *priv) static uint8_t sb_pro_mcv_read(int port, void *priv) { - const sb_t *sb = (sb_t *) priv; - uint8_t ret = sb->pos_regs[port & 7]; + const sb_t *sb = (sb_t *) priv; + uint8_t ret = sb->pos_regs[port & 7]; sb_log("sb_pro_mcv_read: port=%04x ret=%02x\n", port, ret); @@ -1925,8 +1932,8 @@ sb_pro_mcv_write(int port, uint8_t val, void *priv) static uint8_t sb_16_reply_mca_read(int port, void *priv) { - const sb_t *sb = (sb_t *) priv; - uint8_t ret = sb->pos_regs[port & 7]; + const sb_t *sb = (sb_t *) priv; + uint8_t ret = sb->pos_regs[port & 7]; sb_log("sb_16_reply_mca_read: port=%04x ret=%02x\n", port, ret); @@ -2153,7 +2160,7 @@ sb_16_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void mpu401_change_addr(sb->mpu, 0); if (config->activate) { - uint8_t val = config->irq[0].irq; + uint8_t val = config->irq[0].irq; addr = config->io[0].base; if (addr != ISAPNP_IO_DISABLED) { @@ -2225,7 +2232,7 @@ sb_16_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void static void sb_vibra16_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void *priv) { - sb_t *sb = (sb_t *) priv; + sb_t *sb = (sb_t *) priv; switch (ld) { case 0: /* Audio */ @@ -2248,7 +2255,7 @@ goldfinch_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, v break; case 0: /* WaveTable */ - emu8k_change_addr(&goldfinch->emu8k, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0); + emu8k_change_addr(&goldfinch->emu8k, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0); break; } } @@ -2513,7 +2520,7 @@ ess_x688_mca_read(const int port, void *priv) static void ess_soundpiper_mca_write(const int port, const uint8_t val, void *priv) { - sb_t *ess = (sb_t *) priv; + sb_t *ess = (sb_t *) priv; if (port < 0x102) return; @@ -2676,7 +2683,7 @@ ess_soundpiper_mca_write(const int port, const uint8_t val, void *priv) static void ess_chipchat_mca_write(int port, uint8_t val, void *priv) { - sb_t *ess = (sb_t *) priv; + sb_t *ess = (sb_t *) priv; if (port < 0x102) return; @@ -2811,7 +2818,7 @@ 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)); + sb_t *sb = malloc(sizeof(sb_t)); const uint16_t addr = device_get_config_hex16("base"); memset(sb, 0, sizeof(sb_t)); @@ -2862,7 +2869,7 @@ 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)); + sb_t *sb = malloc(sizeof(sb_t)); const uint16_t addr = device_get_config_hex16("base"); memset(sb, 0, sizeof(sb_t)); @@ -3223,7 +3230,7 @@ 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)); + 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"); @@ -3281,7 +3288,7 @@ sb_16_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, &sb->dsp); - sb->gameport = gameport_add(&gameport_pnp_device); + sb->gameport = gameport_add(&gameport_pnp_device); sb->gameport_addr = 0x200; gameport_remap(sb->gameport, sb->gameport_addr); @@ -3385,7 +3392,7 @@ sb_16_pnp_init(UNUSED(const device_t *info)) } const char *pnp_rom_file = NULL; - uint16_t pnp_rom_len = 512; + uint16_t pnp_rom_len = 512; switch (info->local) { case SB_16_PNP_NOIDE: pnp_rom_file = PNP_ROM_SB_16_PNP_NOIDE; @@ -3447,7 +3454,6 @@ sb_vibra16xv_available(void) return rom_present(PNP_ROM_SB_VIBRA16XV); } - static void * sb_vibra16_pnp_init(UNUSED(const device_t *info)) { @@ -3482,7 +3488,7 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info)) midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); switch (info->local) { - case SB_VIBRA16C: /* CTL7001 */ + case SB_VIBRA16C: /* CTL7001 */ case SB_VIBRA16CL: /* CTL7002 */ sb->gameport = gameport_add(&gameport_pnp_device); break; @@ -3563,7 +3569,7 @@ 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->opl_enabled = 1; sb->mixer_enabled = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); music_add_handler(sb_get_music_buffer_sb16_awe32, sb); @@ -3573,7 +3579,7 @@ sb_16_compat_init(const device_t *info) 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); + sb->gameport = gameport_add(&gameport_pnp_device); sb->gameport_addr = 0x200; gameport_remap(sb->gameport, sb->gameport_addr); @@ -3694,7 +3700,7 @@ sb_awe32_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, &sb->dsp); - sb->gameport = gameport_add(&gameport_pnp_device); + sb->gameport = gameport_add(&gameport_pnp_device); sb->gameport_addr = 0x200; gameport_remap(sb->gameport, sb->gameport_addr); @@ -3887,7 +3893,7 @@ sb_awe32_pnp_init(const device_t *info) static void * ess_x688_init(UNUSED(const device_t *info)) { - sb_t *ess = calloc(sizeof(sb_t), 1); + sb_t *ess = calloc(sizeof(sb_t), 1); 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; @@ -4001,7 +4007,7 @@ ess_1688_968_pnp_available(void) static void * ess_x688_pnp_init(UNUSED(const device_t *info)) { - sb_t *ess = calloc(sizeof(sb_t), 1); + sb_t *ess = calloc(sizeof(sb_t), 1); ess->pnp = 1 + (int) info->local; @@ -4012,7 +4018,7 @@ ess_x688_pnp_init(UNUSED(const device_t *info)) sb_dsp_setdma16_supported(&ess->dsp, 0); ess_mixer_reset(ess); - ess->mixer_enabled = 1; + 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); @@ -4098,7 +4104,7 @@ ess_x688_mca_init(UNUSED(const device_t *info)) sb_dsp_setdma16_supported(&ess->dsp, 0); ess_mixer_reset(ess); - ess->mixer_enabled = 1; + 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); @@ -5584,7 +5590,6 @@ static const device_config_t ess_688_config[] = { }, { .name = "", .description = "", .type = CONFIG_END } }; -// clang-format on static const device_config_t ess_1688_config[] = { { @@ -5722,7 +5727,6 @@ static const device_config_t ess_1688_config[] = { }, { .name = "", .description = "", .type = CONFIG_END } }; -// clang-format on static const device_config_t ess_688_pnp_config[] = { { @@ -5734,7 +5738,6 @@ static const device_config_t ess_688_pnp_config[] = { }, { .name = "", .description = "", .type = CONFIG_END } }; -// clang-format on static const device_config_t ess_1688_pnp_config[] = { { From a2b4a4c5a06db4ebd93fb795df4b61fedeb5ccff Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 Jan 2025 09:18:15 +0100 Subject: [PATCH 14/16] ES1370: Fix detection. --- src/sound/snd_audiopci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index ca929fc14..81c979723 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -2627,7 +2627,7 @@ es1370_init(const device_t *info) dev->gameport = gameport_add(&gameport_pnp_device); gameport_remap(dev->gameport, 0x200); - pci_add_card(info->local ? PCI_ADD_SOUND : PCI_ADD_NORMAL, es1370_pci_read, es1370_pci_write, dev, &dev->pci_slot); + pci_add_card((info->local & 1) ? PCI_ADD_SOUND : PCI_ADD_NORMAL, es1370_pci_read, es1370_pci_write, dev, &dev->pci_slot); timer_add(&dev->dac[1].timer, es137x_poll, dev, 1); From c9f028095172af4e9307f9277b87526c7dce931c Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 3 Jan 2025 03:33:02 -0500 Subject: [PATCH 15/16] Cleanups I missed in ES137x --- src/sound/snd_audiopci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 81c979723..c4f1c2f90 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -398,7 +398,7 @@ es1370_calc_sample_rate(es137x_t *dev) dev->calc_sample_rate = 1411200 / (((dev->int_ctrl >> 16) & 0x1fff) + 2); - // pclog("ES1370 calc sample rate %u\n", dev->calc_sample_rate); + // audiopci_log("ES1370 calc sample rate %u\n", dev->calc_sample_rate); dev->interp_factor = 1.0; dev->interp_step = 1; @@ -2833,7 +2833,7 @@ const device_t es1370_device = { .init = es1370_init, .close = es137x_close, .reset = es137x_reset, - { .available = NULL }, + .available = NULL, .speed_changed = es137x_speed_changed, .force_redraw = NULL, .config = es1370_config From ff098f6c7e9c140fbe5be1b793ac1dc03be079bf Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 Jan 2025 13:03:56 +0100 Subject: [PATCH 16/16] Fix the condition of the hook. --- src/qt/qt_main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index e489ad93b..c24f9f8ba 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -154,8 +154,8 @@ emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) if (show_second_monitors) for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) { const auto &secondaryRenderer = main_window->renderers[monitor_index]; - is_over_window = is_over_window && (secondaryRenderer != nullptr) && - (GetForegroundWindow() == ((HWND) secondaryRenderer->winId())); + is_over_window = is_over_window || ((secondaryRenderer != nullptr) && + (GetForegroundWindow() == ((HWND) secondaryRenderer->winId()))); } if ((nCode < 0) || (nCode != HC_ACTION)/* || (!mouse_capture && !video_fullscreen)*/ || !is_over_window)