From 6e8d4356dfa0aaddd82f21f3eb7e810379a914e6 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 25 Feb 2022 21:52:44 -0500 Subject: [PATCH 01/37] Update CMakeLists.txt --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0aa4c7b56..8d1923a6f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -143,7 +143,7 @@ cmake_dependent_option(MGA "Matrox Mystique graphics adapters" cmake_dependent_option(NO_SIO "Machines without emulated Super I/O chips" ON "DEV_BRANCH" OFF) cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF) -cmake_dependent_option(PAS16 "Pro Audio Spectrum 16" OFF "DEV_BRANCH" OFF) +cmake_dependent_option(PAS16 "Pro Audio Spectrum 16" ON "DEV_BRANCH" OFF) cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF) cmake_dependent_option(TANDY_ISA "Tandy PSG ISA clone boards" ON "DEV_BRANCH" OFF) cmake_dependent_option(VGAWONDER "ATI VGA Wonder (ATI-18800)" ON "DEV_BRANCH" OFF) From f7084993c38899d446692f26598ab94a3b471a36 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Tue, 22 Feb 2022 20:28:56 -0500 Subject: [PATCH 02/37] Formatting updates in src/sound + related includes --- .clang-format | 18 + .editorconfig | 10 +- src/include/86box/midi.h | 99 +- src/include/86box/midi_rtmidi.h | 13 +- src/include/86box/snd_ac97.h | 178 +- src/include/86box/snd_ad1848.h | 54 +- src/include/86box/snd_azt2316a.h | 2 +- src/include/86box/snd_cms.h | 42 +- src/include/86box/snd_emu8k.h | 468 ++-- src/include/86box/snd_mpu401.h | 210 +- src/include/86box/snd_opl.h | 45 +- src/include/86box/snd_opl_nuked.h | 21 +- src/include/86box/snd_resid.h | 14 +- src/include/86box/snd_sb.h | 214 +- src/include/86box/snd_sb_dsp.h | 128 +- src/include/86box/snd_sn76489.h | 40 +- src/include/86box/snd_speaker.h | 15 +- src/include/86box/snd_ym7128.h | 31 +- src/include/86box/sound.h | 98 +- src/sound/midi.c | 558 ++-- src/sound/midi_fluidsynth.c | 904 ++++--- src/sound/midi_mt32.c | 641 ++--- src/sound/midi_rtmidi.cpp | 124 +- src/sound/openal.c | 261 +- src/sound/snd_ac97_codec.c | 837 +++--- src/sound/snd_ac97_via.c | 771 +++--- src/sound/snd_ad1848.c | 798 +++--- src/sound/snd_adlib.c | 193 +- src/sound/snd_adlibgold.c | 1782 +++++++------ src/sound/snd_audiopci.c | 2517 +++++++++--------- src/sound/snd_azt2316a.c | 2315 ++++++++-------- src/sound/snd_cms.c | 394 +-- src/sound/snd_cs423x.c | 1043 ++++---- src/sound/snd_emu8k.c | 4068 ++++++++++++++--------------- src/sound/snd_gus.c | 2431 +++++++++-------- src/sound/snd_lpt_dac.c | 180 +- src/sound/snd_lpt_dss.c | 174 +- src/sound/snd_mpu401.c | 2512 +++++++++--------- src/sound/snd_opl.c | 219 +- src/sound/snd_opl_nuked.c | 1369 +++++----- src/sound/snd_pas16.c | 1095 ++++---- src/sound/snd_ps1.c | 169 +- src/sound/snd_pssj.c | 157 +- src/sound/snd_resid.cc | 154 +- src/sound/snd_sb.c | 3524 +++++++++++-------------- src/sound/snd_sb_dsp.c | 2095 ++++++++------- src/sound/snd_sn76489.c | 472 ++-- src/sound/snd_speaker.c | 89 +- src/sound/snd_ssi2001.c | 150 +- src/sound/snd_wss.c | 195 +- src/sound/snd_ym7128.c | 221 +- src/sound/sound.c | 587 ++--- src/sound/xaudio2.c | 213 +- 53 files changed, 17085 insertions(+), 17827 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..7e38e8e4b --- /dev/null +++ b/.clang-format @@ -0,0 +1,18 @@ +BasedOnStyle: WebKit +AlignAfterOpenBracket: Align +AlignArrayOfStructures: Left +AlignConsecutiveMacros: AcrossEmptyLines +AlignConsecutiveAssignments: Consecutive +AlignConsecutiveBitFields: AcrossEmptyLines +AlignConsecutiveDeclarations: Consecutive +AlignEscapedNewlines: Left +AlignTrailingComments: true +AlwaysBreakAfterReturnType: TopLevelDefinitions +BreakBeforeTernaryOperators: true +IndentCaseLabels: true +IndentCaseBlocks: true +IndentGotoLabels: false +IndentPPDirectives: AfterHash +IndentExternBlock: NoIndent +PointerAlignment: Right +SpaceAfterCStyleCast: true diff --git a/.editorconfig b/.editorconfig index 1cb9087ec..29d9ac0ba 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,21 +1,21 @@ [*] charset = utf-8 end_of_line = lf -indent_style = tab -indent_size = 8 -tab_width = 8 +indent_style = space +indent_size = 4 +tab_width = 4 # Disabled for now since not all editors support setting a tab_width value different from indent_size # Relevant VSCode extension issue: https://github.com/editorconfig/editorconfig-vscode/issues/190 # [*.rc] # indent_style = space # indent_size = 4 -# tab_width = 8 +# tab_width = 4 # [Makefile.*] # indent_style = space # indent_size = 4 -# tab_width = 8 +# tab_width = 4 [*.manifest] indent_style = space diff --git a/src/include/86box/midi.h b/src/include/86box/midi.h index 155965b5a..3eec73234 100644 --- a/src/include/86box/midi.h +++ b/src/include/86box/midi.h @@ -1,6 +1,5 @@ #ifndef EMU_SOUND_MIDI_H -# define EMU_SOUND_MIDI_H - +#define EMU_SOUND_MIDI_H #define SYSEX_SIZE 8192 @@ -14,34 +13,31 @@ extern void (*input_msg)(void *p, uint8_t *msg, uint32_t len); extern int (*input_sysex)(void *p, uint8_t *buf, uint32_t len, int abort); extern void *midi_in_p; -extern int midi_device_available(int card); -extern int midi_in_device_available(int card); +extern int midi_device_available(int card); +extern int midi_in_device_available(int card); #ifdef EMU_DEVICE_H const device_t *midi_device_getdevice(int card); const device_t *midi_in_device_getdevice(int card); #endif -extern int midi_device_has_config(int card); -extern int midi_in_device_has_config(int card); -extern char * midi_device_get_internal_name(int card); -extern char * midi_in_device_get_internal_name(int card); -extern int midi_device_get_from_internal_name(char *s); -extern int midi_in_device_get_from_internal_name(char *s); -extern void midi_device_init(); -extern void midi_in_device_init(); +extern int midi_device_has_config(int card); +extern int midi_in_device_has_config(int card); +extern char *midi_device_get_internal_name(int card); +extern char *midi_in_device_get_internal_name(int card); +extern int midi_device_get_from_internal_name(char *s); +extern int midi_in_device_get_from_internal_name(char *s); +extern void midi_device_init(); +extern void midi_in_device_init(); - -typedef struct midi_device_t -{ +typedef struct midi_device_t { void (*play_sysex)(uint8_t *sysex, unsigned int len); void (*play_msg)(uint8_t *msg); void (*poll)(); int (*write)(uint8_t val); } midi_device_t; -typedef struct midi_in_handler_t -{ +typedef struct midi_in_handler_t { uint8_t *buf; - int cnt; + int cnt; uint32_t len; void (*msg)(void *p, uint8_t *msg, uint32_t len); @@ -50,60 +46,59 @@ typedef struct midi_in_handler_t struct midi_in_handler_t *prev, *next; } midi_in_handler_t; -typedef struct midi_t -{ +typedef struct midi_t { uint8_t midi_rt_buf[8], midi_cmd_buf[8], - midi_status, midi_sysex_data[SYSEX_SIZE]; + midi_status, midi_sysex_data[SYSEX_SIZE]; int midi_cmd_pos, midi_cmd_len, midi_cmd_r, - midi_realtime, thruchan, midi_clockout; + midi_realtime, thruchan, midi_clockout; unsigned int midi_sysex_start, midi_sysex_delay, - midi_pos; - midi_device_t *m_out_device, *m_in_device; + midi_pos; + midi_device_t *m_out_device, *m_in_device; } midi_t; extern midi_t *midi, *midi_in; -extern void midi_init(midi_device_t* device); -extern void midi_in_init(midi_device_t* device, midi_t **mididev); -extern void midi_close(); -extern void midi_in_close(void); -extern void midi_raw_out_rt_byte(uint8_t val); -extern void midi_raw_out_thru_rt_byte(uint8_t val); -extern void midi_raw_out_byte(uint8_t val); -extern void midi_clear_buffer(void); -extern void midi_poll(); +extern void midi_init(midi_device_t *device); +extern void midi_in_init(midi_device_t *device, midi_t **mididev); +extern void midi_close(); +extern void midi_in_close(void); +extern void midi_raw_out_rt_byte(uint8_t val); +extern void midi_raw_out_thru_rt_byte(uint8_t val); +extern void midi_raw_out_byte(uint8_t val); +extern void midi_clear_buffer(void); +extern void midi_poll(); -extern void midi_in_handler(int set, void (*msg)(void *p, uint8_t *msg, uint32_t len), int (*sysex)(void *p, uint8_t *buffer, uint32_t len, int abort), void *p); -extern void midi_in_handlers_clear(void); -extern void midi_in_msg(uint8_t *msg, uint32_t len); -extern void midi_in_sysex(uint8_t *buffer, uint32_t len); +extern void midi_in_handler(int set, void (*msg)(void *p, uint8_t *msg, uint32_t len), int (*sysex)(void *p, uint8_t *buffer, uint32_t len, int abort), void *p); +extern void midi_in_handlers_clear(void); +extern void midi_in_msg(uint8_t *msg, uint32_t len); +extern void midi_in_sysex(uint8_t *buffer, uint32_t len); #if 0 -#ifdef _WIN32 -#define SYSTEM_MIDI_NAME "Windows MIDI" -#define SYSTEM_MIDI_INTERNAL_NAME "windows_midi" +# ifdef _WIN32 +# define SYSTEM_MIDI_NAME "Windows MIDI" +# define SYSTEM_MIDI_INTERNAL_NAME "windows_midi" +# else +# define SYSTEM_MIDI_NAME "System MIDI" +# define SYSTEM_MIDI_INTERNAL_NAME "system_midi" +# endif #else -#define SYSTEM_MIDI_NAME "System MIDI" -#define SYSTEM_MIDI_INTERNAL_NAME "system_midi" -#endif -#else -#define SYSTEM_MIDI_NAME "System MIDI" -#define SYSTEM_MIDI_INTERNAL_NAME "system_midi" +# define SYSTEM_MIDI_NAME "System MIDI" +# define SYSTEM_MIDI_INTERNAL_NAME "system_midi" #endif -#define MIDI_INPUT_NAME "MIDI Input Device" +#define MIDI_INPUT_NAME "MIDI Input Device" #define MIDI_INPUT_INTERNAL_NAME "midi_in" #ifdef EMU_DEVICE_H extern const device_t rtmidi_device; extern const device_t rtmidi_input_device; -#ifdef USE_FLUIDSYNTH +# ifdef USE_FLUIDSYNTH extern const device_t fluidsynth_device; -#endif -#ifdef USE_MUNT +# endif +# ifdef USE_MUNT extern const device_t mt32_device; extern const device_t cm32l_device; -#endif +# endif #endif -#endif /*EMU_SOUND_MIDI_H*/ +#endif /*EMU_SOUND_MIDI_H*/ diff --git a/src/include/86box/midi_rtmidi.h b/src/include/86box/midi_rtmidi.h index 5224b83e9..d2d3869e3 100644 --- a/src/include/86box/midi_rtmidi.h +++ b/src/include/86box/midi_rtmidi.h @@ -1,15 +1,14 @@ #ifndef EMU_SOUND_RTMIDI_H -# define EMU_SOUND_RTMIDI_H +#define EMU_SOUND_RTMIDI_H #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif -extern int rtmidi_get_num_devs(void); -extern void rtmidi_get_dev_name(int num, char *s); -extern int rtmidi_in_get_num_devs(void); -extern void rtmidi_in_get_dev_name(int num, char *s); +extern int rtmidi_get_num_devs(void); +extern void rtmidi_get_dev_name(int num, char *s); +extern int rtmidi_in_get_num_devs(void); +extern void rtmidi_in_get_dev_name(int num, char *s); #ifdef __cplusplus } diff --git a/src/include/86box/snd_ac97.h b/src/include/86box/snd_ac97.h index a9341f8ef..600dd84d8 100644 --- a/src/include/86box/snd_ac97.h +++ b/src/include/86box/snd_ac97.h @@ -15,82 +15,81 @@ * Copyright 2021 RichardG. */ #ifndef SOUND_AC97_H -# define SOUND_AC97_H +#define SOUND_AC97_H -#define AC97_VENDOR_ID(f, s, t, dev) ((((f) & 0xff) << 24) | (((s) & 0xff) << 16) | (((t) & 0xff) << 8) | ((dev) & 0xff)) +#define AC97_VENDOR_ID(f, s, t, dev) ((((f) &0xff) << 24) | (((s) &0xff) << 16) | (((t) &0xff) << 8) | ((dev) &0xff)) /* Misc support bits (misc_flags). Most of these are not part of any registers, but control enabling/disabling of registers and bits. */ -#define AC97_MASTER_6B (1 << 0) /* register 02 bits [13,5] (ML5/MR5) */ -#define AC97_AUXOUT (1 << 1) /* register 04 */ -#define AC97_AUXOUT_6B (1 << 2) /* register 04 bits [13,5] (ML5/MR5) */ -#define AC97_MONOOUT (1 << 3) /* register 06 */ -#define AC97_MONOOUT_6B (1 << 4) /* register 06 bit 5 (MM5) */ -#define AC97_PCBEEP (1 << 5) /* register 0A */ -#define AC97_PCBEEP_GEN (1 << 6) /* register 0A bits [12:5] (F[7:0]) */ -#define AC97_PHONE (1 << 9) /* register 0C */ -#define AC97_VIDEO (1 << 10) /* register 14 */ -#define AC97_AUXIN (1 << 11) /* register 16 */ -#define AC97_POP (1 << 15) /* register 20 bit 15 (POP) - definition shared with General Purpose bits */ -#define AC97_MS (1 << 8) /* register 20 bit 8 (MS) - definition shared with General Purpose bits */ -#define AC97_LPBK (1 << 7) /* register 20 bit 7 (LPBK) - definition shared with General Purpose bits */ -#define AC97_DSA (1 << 12) /* register 28 bits [5:4] (DSA[1:0]) */ -#define AC97_LFE_6B (1 << 13) /* register 36 bit 13 (LFE5) */ -#define AC97_CENTER_6B (1 << 14) /* register 36 bit 5 (CNT5) */ -#define AC97_SURR_6B (1 << 16) /* register 38 bits [13,5] (LSR5/RSR5) */ +#define AC97_MASTER_6B (1 << 0) /* register 02 bits [13,5] (ML5/MR5) */ +#define AC97_AUXOUT (1 << 1) /* register 04 */ +#define AC97_AUXOUT_6B (1 << 2) /* register 04 bits [13,5] (ML5/MR5) */ +#define AC97_MONOOUT (1 << 3) /* register 06 */ +#define AC97_MONOOUT_6B (1 << 4) /* register 06 bit 5 (MM5) */ +#define AC97_PCBEEP (1 << 5) /* register 0A */ +#define AC97_PCBEEP_GEN (1 << 6) /* register 0A bits [12:5] (F[7:0]) */ +#define AC97_PHONE (1 << 9) /* register 0C */ +#define AC97_VIDEO (1 << 10) /* register 14 */ +#define AC97_AUXIN (1 << 11) /* register 16 */ +#define AC97_POP (1 << 15) /* register 20 bit 15 (POP) - definition shared with General Purpose bits */ +#define AC97_MS (1 << 8) /* register 20 bit 8 (MS) - definition shared with General Purpose bits */ +#define AC97_LPBK (1 << 7) /* register 20 bit 7 (LPBK) - definition shared with General Purpose bits */ +#define AC97_DSA (1 << 12) /* register 28 bits [5:4] (DSA[1:0]) */ +#define AC97_LFE_6B (1 << 13) /* register 36 bit 13 (LFE5) */ +#define AC97_CENTER_6B (1 << 14) /* register 36 bit 5 (CNT5) */ +#define AC97_SURR_6B (1 << 16) /* register 38 bits [13,5] (LSR5/RSR5) */ /* Reset bits (reset_flags), register 00. */ -#define AC97_MICPCM (1 << 0) -#define AC97_MODEMLINE (1 << 1) -#define AC97_TONECTL (1 << 2) -#define AC97_SIMSTEREO (1 << 3) -#define AC97_HPOUT (1 << 4) -#define AC97_LOUDNESS (1 << 5) -#define AC97_DAC_18B (1 << 6) -#define AC97_DAC_20B (1 << 7) -#define AC97_ADC_18B (1 << 8) -#define AC97_ADC_20B (1 << 9) -#define AC97_3D_SHIFT 10 +#define AC97_MICPCM (1 << 0) +#define AC97_MODEMLINE (1 << 1) +#define AC97_TONECTL (1 << 2) +#define AC97_SIMSTEREO (1 << 3) +#define AC97_HPOUT (1 << 4) +#define AC97_LOUDNESS (1 << 5) +#define AC97_DAC_18B (1 << 6) +#define AC97_DAC_20B (1 << 7) +#define AC97_ADC_18B (1 << 8) +#define AC97_ADC_20B (1 << 9) +#define AC97_3D_SHIFT 10 /* Extended Audio ID bits (extid_flags), register 28. */ -#define AC97_VRA (1 << 0) -#define AC97_DRA (1 << 1) -#define AC97_SPDIF (1 << 2) -#define AC97_VRM (1 << 3) -#define AC97_CDAC (1 << 6) -#define AC97_SDAC (1 << 7) -#define AC97_LDAC (1 << 8) -#define AC97_AMAP (1 << 9) -#define AC97_REV_2_1 (0 << 10) -#define AC97_REV_2_2 (1 << 10) -#define AC97_REV_2_3 (2 << 10) -#define AC97_REV_MASK (3 << 10) +#define AC97_VRA (1 << 0) +#define AC97_DRA (1 << 1) +#define AC97_SPDIF (1 << 2) +#define AC97_VRM (1 << 3) +#define AC97_CDAC (1 << 6) +#define AC97_SDAC (1 << 7) +#define AC97_LDAC (1 << 8) +#define AC97_AMAP (1 << 9) +#define AC97_REV_2_1 (0 << 10) +#define AC97_REV_2_2 (1 << 10) +#define AC97_REV_2_3 (2 << 10) +#define AC97_REV_MASK (3 << 10) /* Volume bits. */ -#define AC97_MUTE (1 << 15) -#define AC97_MUTE_L (1 << 15) -#define AC97_MUTE_R (1 << 7) +#define AC97_MUTE (1 << 15) +#define AC97_MUTE_L (1 << 15) +#define AC97_MUTE_R (1 << 7) /* General Purpose bits, register 20. */ /* POP already defined */ -#define AC97_ST (1 << 14) -#define AC97_3D (1 << 13) -#define AC97_LD (1 << 12) -#define AC97_DRSS_MASK (3 << 10) -#define AC97_MIX (1 << 9) +#define AC97_ST (1 << 14) +#define AC97_3D (1 << 13) +#define AC97_LD (1 << 12) +#define AC97_DRSS_MASK (3 << 10) +#define AC97_MIX (1 << 9) /* MS already defined */ /* LPBK already defined */ /* Extended Audio Status/Control bits, register 2A. */ -#define AC97_SPSA_SHIFT 4 -#define AC97_SPSA_MASK 3 -#define AC97_MADC (1 << 9) -#define AC97_SPCV (1 << 10) -#define AC97_PRI (1 << 11) -#define AC97_PRJ (1 << 12) -#define AC97_PRK (1 << 13) -#define AC97_PRL (1 << 14) - +#define AC97_SPSA_SHIFT 4 +#define AC97_SPSA_MASK 3 +#define AC97_MADC (1 << 9) +#define AC97_SPCV (1 << 10) +#define AC97_PRI (1 << 11) +#define AC97_PRJ (1 << 12) +#define AC97_PRK (1 << 13) +#define AC97_PRL (1 << 14) /* New codecs should be added to the end of this enum to avoid breaking configs. */ enum { @@ -104,52 +103,49 @@ enum { AC97_CODEC_AK4540 }; - typedef struct { const uint16_t index, value, write_mask; } ac97_vendor_reg_t; typedef struct { - uint32_t vendor_id, min_rate, max_rate, misc_flags; - uint16_t reset_flags, extid_flags, - powerdown_mask, regs[64]; - uint8_t codec_id, vendor_reg_page_max; + uint32_t vendor_id, min_rate, max_rate, misc_flags; + uint16_t reset_flags, extid_flags, + powerdown_mask, regs[64]; + uint8_t codec_id, vendor_reg_page_max; const ac97_vendor_reg_t *vendor_regs; - uint16_t *vendor_reg_pages; + uint16_t *vendor_reg_pages; } ac97_codec_t; - -extern uint16_t ac97_codec_readw(ac97_codec_t *dev, uint8_t reg); -extern void ac97_codec_writew(ac97_codec_t *dev, uint8_t reg, uint16_t val); -extern void ac97_codec_reset(void *priv); -extern void ac97_codec_getattn(void *priv, uint8_t reg, int *l, int *r); -extern uint32_t ac97_codec_getrate(void *priv, uint8_t reg); +extern uint16_t ac97_codec_readw(ac97_codec_t *dev, uint8_t reg); +extern void ac97_codec_writew(ac97_codec_t *dev, uint8_t reg, uint16_t val); +extern void ac97_codec_reset(void *priv); +extern void ac97_codec_getattn(void *priv, uint8_t reg, int *l, int *r); +extern uint32_t ac97_codec_getrate(void *priv, uint8_t reg); extern const device_t *ac97_codec_get(int model); -extern void ac97_via_set_slot(void *priv, int slot, int irq_pin); -extern uint8_t ac97_via_read_status(void *priv, uint8_t modem); -extern void ac97_via_write_control(void *priv, uint8_t modem, uint8_t val); -extern void ac97_via_remap_audio_sgd(void *priv, uint16_t new_io_base, uint8_t enable); -extern void ac97_via_remap_modem_sgd(void *priv, uint16_t new_io_base, uint8_t enable); -extern void ac97_via_remap_audio_codec(void *priv, uint16_t new_io_base, uint8_t enable); -extern void ac97_via_remap_modem_codec(void *priv, uint16_t new_io_base, uint8_t enable); +extern void ac97_via_set_slot(void *priv, int slot, int irq_pin); +extern uint8_t ac97_via_read_status(void *priv, uint8_t modem); +extern void ac97_via_write_control(void *priv, uint8_t modem, uint8_t val); +extern void ac97_via_remap_audio_sgd(void *priv, uint16_t new_io_base, uint8_t enable); +extern void ac97_via_remap_modem_sgd(void *priv, uint16_t new_io_base, uint8_t enable); +extern void ac97_via_remap_audio_codec(void *priv, uint16_t new_io_base, uint8_t enable); +extern void ac97_via_remap_modem_codec(void *priv, uint16_t new_io_base, uint8_t enable); - -extern ac97_codec_t **ac97_codec, **ac97_modem_codec; -extern int ac97_codec_count, ac97_modem_codec_count, - ac97_codec_id, ac97_modem_codec_id; +extern ac97_codec_t **ac97_codec, **ac97_modem_codec; +extern int ac97_codec_count, ac97_modem_codec_count, + ac97_codec_id, ac97_modem_codec_id; #ifdef EMU_DEVICE_H -extern const device_t ad1881_device; -extern const device_t ak4540_device; -extern const device_t alc100_device; -extern const device_t cs4297_device; -extern const device_t cs4297a_device; -extern const device_t stac9708_device; -extern const device_t stac9721_device; -extern const device_t wm9701a_device; +extern const device_t ad1881_device; +extern const device_t ak4540_device; +extern const device_t alc100_device; +extern const device_t cs4297_device; +extern const device_t cs4297a_device; +extern const device_t stac9708_device; +extern const device_t stac9721_device; +extern const device_t wm9701a_device; -extern const device_t ac97_via_device; +extern const device_t ac97_via_device; #endif #endif /*SOUND_AC97_H*/ diff --git a/src/include/86box/snd_ad1848.h b/src/include/86box/snd_ad1848.h index 0e93f7533..c74ba064c 100644 --- a/src/include/86box/snd_ad1848.h +++ b/src/include/86box/snd_ad1848.h @@ -20,7 +20,7 @@ */ #ifndef SOUND_AD1848_H -# define SOUND_AD1848_H +#define SOUND_AD1848_H enum { AD1848_TYPE_DEFAULT = 0, @@ -30,44 +30,42 @@ enum { AD1848_TYPE_CS4236 }; - typedef struct { - uint8_t type, index, xindex, regs[32], xregs[32], status; /* 16 original registers + 16 CS4231A extensions + 32 CS4236 extensions */ + uint8_t type, index, xindex, regs[32], xregs[32], status; /* 16 original registers + 16 CS4231A extensions + 32 CS4236 extensions */ - int count; - uint8_t trd, mce, wten: 1; + int count; + uint8_t trd, mce, wten : 1; - int16_t out_l, out_r; - double cd_vol_l, cd_vol_r; - int fm_vol_l, fm_vol_r; - uint8_t fmt_mask, wave_vol_mask; + int16_t out_l, out_r; + double cd_vol_l, cd_vol_r; + int fm_vol_l, fm_vol_r; + uint8_t fmt_mask, wave_vol_mask; - uint8_t enable: 1, irq: 4, dma: 3; - int freq; + uint8_t enable : 1, irq : 4, dma : 3; + int freq; - pc_timer_t timer_count; - uint64_t timer_latch; + pc_timer_t timer_count; + uint64_t timer_latch; - int16_t buffer[SOUNDBUFLEN * 2]; - int pos; + int16_t buffer[SOUNDBUFLEN * 2]; + int pos; - void *cram_priv, - (*cram_write)(uint16_t addr, uint8_t val, void *priv); - uint8_t (*cram_read)(uint16_t addr, void *priv); + void *cram_priv, + (*cram_write)(uint16_t addr, uint8_t val, void *priv); + uint8_t (*cram_read)(uint16_t addr, void *priv); } ad1848_t; +extern void ad1848_setirq(ad1848_t *ad1848, int irq); +extern void ad1848_setdma(ad1848_t *ad1848, int dma); +extern void ad1848_updatevolmask(ad1848_t *ad1848); -extern void ad1848_setirq(ad1848_t *ad1848, int irq); -extern void ad1848_setdma(ad1848_t *ad1848, int dma); -extern void ad1848_updatevolmask(ad1848_t *ad1848); +extern uint8_t ad1848_read(uint16_t addr, void *priv); +extern void ad1848_write(uint16_t addr, uint8_t val, void *priv); -extern uint8_t ad1848_read(uint16_t addr, void *priv); -extern void ad1848_write(uint16_t addr, uint8_t val, void *priv); +extern void ad1848_update(ad1848_t *ad1848); +extern void ad1848_speed_changed(ad1848_t *ad1848); +extern void ad1848_filter_cd_audio(int channel, double *buffer, void *priv); -extern void ad1848_update(ad1848_t *ad1848); -extern void ad1848_speed_changed(ad1848_t *ad1848); -extern void ad1848_filter_cd_audio(int channel, double *buffer, void *priv); - -extern void ad1848_init(ad1848_t *ad1848, uint8_t type); +extern void ad1848_init(ad1848_t *ad1848, uint8_t type); #endif /*SOUND_AD1848_H*/ diff --git a/src/include/86box/snd_azt2316a.h b/src/include/86box/snd_azt2316a.h index 9dafa13f9..63a0ff243 100644 --- a/src/include/86box/snd_azt2316a.h +++ b/src/include/86box/snd_azt2316a.h @@ -1,5 +1,5 @@ #ifndef SOUND_AZT2316A_H -# define SOUND_AZT2316A_H +#define SOUND_AZT2316A_H extern void azt2316a_enable_wss(uint8_t enable, void *p); diff --git a/src/include/86box/snd_cms.h b/src/include/86box/snd_cms.h index a400a026c..0da6fcdab 100644 --- a/src/include/86box/snd_cms.h +++ b/src/include/86box/snd_cms.h @@ -1,35 +1,33 @@ #ifndef SOUND_CMS_H -# define SOUND_CMS_H +#define SOUND_CMS_H -#include #include <86box/sound.h> +#include #define MASTER_CLOCK 7159090 -typedef struct cms_t -{ - int addrs[2]; - uint8_t regs[2][32]; - uint16_t latch[2][6]; - int freq[2][6]; - float count[2][6]; - int vol[2][6][2]; - int stat[2][6]; - uint16_t noise[2][2]; - uint16_t noisefreq[2][2]; - int noisecount[2][2]; - int noisetype[2][2]; +typedef struct cms_t { + int addrs[2]; + uint8_t regs[2][32]; + uint16_t latch[2][6]; + int freq[2][6]; + float count[2][6]; + int vol[2][6][2]; + int stat[2][6]; + uint16_t noise[2][2]; + uint16_t noisefreq[2][2]; + int noisecount[2][2]; + int noisetype[2][2]; - uint8_t latched_data; + uint8_t latched_data; - int16_t buffer[SOUNDBUFLEN * 2]; + int16_t buffer[SOUNDBUFLEN * 2]; - int pos; + int pos; } cms_t; - -extern void cms_update(cms_t *cms); -extern void cms_write(uint16_t addr, uint8_t val, void *p); +extern void cms_update(cms_t *cms); +extern void cms_write(uint16_t addr, uint8_t val, void *p); extern uint8_t cms_read(uint16_t addr, void *p); -#endif /*SOUND_CMS_H*/ +#endif /*SOUND_CMS_H*/ diff --git a/src/include/86box/snd_emu8k.h b/src/include/86box/snd_emu8k.h index 9371826c6..a163bdeaf 100644 --- a/src/include/86box/snd_emu8k.h +++ b/src/include/86box/snd_emu8k.h @@ -1,37 +1,37 @@ #ifndef SOUND_EMU8K_H -# define SOUND_EMU8K_H +#define SOUND_EMU8K_H /* All these defines are in samples, not in bytes. */ -#define EMU8K_MEM_ADDRESS_MASK 0xFFFFFF -#define EMU8K_RAM_MEM_START 0x200000 -#define EMU8K_FM_MEM_ADDRESS 0xFFFFE0 +#define EMU8K_MEM_ADDRESS_MASK 0xFFFFFF +#define EMU8K_RAM_MEM_START 0x200000 +#define EMU8K_FM_MEM_ADDRESS 0xFFFFE0 #define EMU8K_RAM_POINTERS_MASK 0x3F -#define EMU8K_LFOCHORUS_SIZE 0x4000 +#define EMU8K_LFOCHORUS_SIZE 0x4000 /* * Everything in this file assumes little endian */ /* used for the increment of oscillator position*/ typedef struct emu8k_mem_internal_t { - union { - uint64_t addr; - struct { - uint16_t fract_lw_address; - uint16_t fract_address; - uint32_t int_address; - }; + union { + uint64_t addr; + struct { + uint16_t fract_lw_address; + uint16_t fract_address; + uint32_t int_address; }; + }; } emu8k_mem_internal_t; /* used for access to ram pointers from oscillator position. */ typedef struct emu8k_mem_pointers_t { - union { - uint32_t addr; - struct { - uint16_t lw_address; - uint8_t hb_address; - uint8_t unused_address; - }; + union { + uint32_t addr; + struct { + uint16_t lw_address; + uint8_t hb_address; + uint8_t unused_address; }; + }; } emu8k_mem_pointers_t; /* @@ -84,33 +84,30 @@ typedef struct emu8k_mem_pointers_t { * This allows to operate db values by simply adding them. */ typedef struct emu8k_envelope_t { - int state; - int32_t delay_samples, hold_samples, attack_samples; - int32_t value_amp_hz, value_db_oct; - int32_t sustain_value_db_oct; - int32_t attack_amount_amp_hz, ramp_amount_db_oct; + int state; + int32_t delay_samples, hold_samples, attack_samples; + int32_t value_amp_hz, value_db_oct; + int32_t sustain_value_db_oct; + int32_t attack_amount_amp_hz, ramp_amount_db_oct; } emu8k_envelope_t; - - typedef struct emu8k_chorus_eng_t { - int32_t write; - int32_t feedback; - int32_t delay_samples_central; - double lfodepth_multip; - double delay_offset_samples_right; - emu8k_mem_internal_t lfo_inc; - emu8k_mem_internal_t lfo_pos; + int32_t write; + int32_t feedback; + int32_t delay_samples_central; + double lfodepth_multip; + double delay_offset_samples_right; + emu8k_mem_internal_t lfo_inc; + emu8k_mem_internal_t lfo_pos; - int32_t chorus_left_buffer[EMU8K_LFOCHORUS_SIZE]; - int32_t chorus_right_buffer[EMU8K_LFOCHORUS_SIZE]; + int32_t chorus_left_buffer[EMU8K_LFOCHORUS_SIZE]; + int32_t chorus_right_buffer[EMU8K_LFOCHORUS_SIZE]; } emu8k_chorus_eng_t; /* 32 * 242. 32 comes from the "right" room resso case.*/ #define MAX_REFL_SIZE 7744 - /* Reverb parameters description, extracted from AST sources. Mix level Decay @@ -133,267 +130,258 @@ typedef struct emu8k_chorus_eng_t { Ref 6 feedback L&R */ typedef struct emu8k_reverb_combfilter_t { - int read_pos; - int32_t reflection[MAX_REFL_SIZE]; - float output_gain; - float feedback; - float damp1; - float damp2; - int bufsize; - int32_t filterstore; + int read_pos; + int32_t reflection[MAX_REFL_SIZE]; + float output_gain; + float feedback; + float damp1; + float damp2; + int bufsize; + int32_t filterstore; } emu8k_reverb_combfilter_t; typedef struct emu8k_reverb_eng_t { - int16_t out_mix; - int16_t link_return_amp; /* tail part output gain ? */ - int8_t link_return_type; + int16_t out_mix; + int16_t link_return_amp; /* tail part output gain ? */ + int8_t link_return_type; - uint8_t refl_in_amp; + uint8_t refl_in_amp; - emu8k_reverb_combfilter_t reflections[6]; - emu8k_reverb_combfilter_t allpass[8]; - emu8k_reverb_combfilter_t tailL; - emu8k_reverb_combfilter_t tailR; + emu8k_reverb_combfilter_t reflections[6]; + emu8k_reverb_combfilter_t allpass[8]; + emu8k_reverb_combfilter_t tailL; + emu8k_reverb_combfilter_t tailR; - emu8k_reverb_combfilter_t damper; + emu8k_reverb_combfilter_t damper; } emu8k_reverb_eng_t; typedef struct emu8k_slide_t { - int32_t last; + int32_t last; } emu8k_slide_t; - -typedef struct emu8k_voice_t -{ - union { - uint32_t cpf; - struct { - uint16_t cpf_curr_frac_addr; /* fractional part of the playing cursor. */ - uint16_t cpf_curr_pitch; /* 0x4000 = no shift. Linear increment */ - }; +typedef struct emu8k_voice_t { + union { + uint32_t cpf; + struct { + uint16_t cpf_curr_frac_addr; /* fractional part of the playing cursor. */ + uint16_t cpf_curr_pitch; /* 0x4000 = no shift. Linear increment */ }; - union { - uint32_t ptrx; - struct { - uint8_t ptrx_pan_aux; - uint8_t ptrx_revb_send; - uint16_t ptrx_pit_target; /* target pitch to which slide at curr_pitch speed. */ - }; + }; + union { + uint32_t ptrx; + struct { + uint8_t ptrx_pan_aux; + uint8_t ptrx_revb_send; + uint16_t ptrx_pit_target; /* target pitch to which slide at curr_pitch speed. */ }; - union { - uint32_t cvcf; - struct { - uint16_t cvcf_curr_filt_ctoff; - uint16_t cvcf_curr_volume; - }; + }; + union { + uint32_t cvcf; + struct { + uint16_t cvcf_curr_filt_ctoff; + uint16_t cvcf_curr_volume; }; - emu8k_slide_t volumeslide; - union { - uint32_t vtft; - struct { - uint16_t vtft_filter_target; - uint16_t vtft_vol_target; /* written to by the envelope engine. */ - }; + }; + emu8k_slide_t volumeslide; + union { + uint32_t vtft; + struct { + uint16_t vtft_filter_target; + uint16_t vtft_vol_target; /* written to by the envelope engine. */ }; - /* These registers are used at least by the Windows drivers, and seem to be resetting - * something, similarly to targets and current, but... of what? - * what is curious is that if they are already zero, they are not written to, so it really - * looks like they are information about the status of the channel. (lfo position maybe?) */ - uint32_t unknown_data0_4; - uint32_t unknown_data0_5; - union { - uint32_t psst; - struct { - uint16_t psst_lw_address; - uint8_t psst_hw_address; - uint8_t psst_pan; - }; - #define PSST_LOOP_START_MASK 0x00FFFFFF /* In samples, i.e. uint16_t array[BOARD_RAM/2]; */ + }; + /* These registers are used at least by the Windows drivers, and seem to be resetting + * something, similarly to targets and current, but... of what? + * what is curious is that if they are already zero, they are not written to, so it really + * looks like they are information about the status of the channel. (lfo position maybe?) */ + uint32_t unknown_data0_4; + uint32_t unknown_data0_5; + union { + uint32_t psst; + struct { + uint16_t psst_lw_address; + uint8_t psst_hw_address; + uint8_t psst_pan; }; - union { - uint32_t csl; - struct { - uint16_t csl_lw_address; - uint8_t csl_hw_address; - uint8_t csl_chor_send; - }; - #define CSL_LOOP_END_MASK 0x00FFFFFF /* In samples, i.e. uint16_t array[BOARD_RAM/2]; */ +#define PSST_LOOP_START_MASK 0x00FFFFFF /* In samples, i.e. uint16_t array[BOARD_RAM/2]; */ + }; + union { + uint32_t csl; + struct { + uint16_t csl_lw_address; + uint8_t csl_hw_address; + uint8_t csl_chor_send; }; - union { - uint32_t ccca; - struct { - uint16_t ccca_lw_addr; - uint8_t ccca_hb_addr; - uint8_t ccca_qcontrol; - }; +#define CSL_LOOP_END_MASK 0x00FFFFFF /* In samples, i.e. uint16_t array[BOARD_RAM/2]; */ + }; + union { + uint32_t ccca; + struct { + uint16_t ccca_lw_addr; + uint8_t ccca_hb_addr; + uint8_t ccca_qcontrol; }; - #define CCCA_FILTQ_GET(ccca) (ccca>>28) - #define CCCA_FILTQ_SET(ccca,q) ccca = (ccca&0x0FFFFFFF) | (q<<28) - /* Bit 27 should always be zero */ - #define CCCA_DMA_ACTIVE(ccca) (ccca&0x04000000) - #define CCCA_DMA_WRITE_MODE(ccca) (ccca&0x02000000) - #define CCCA_DMA_WRITE_RIGHT(ccca) (ccca&0x01000000) + }; +#define CCCA_FILTQ_GET(ccca) (ccca >> 28) +#define CCCA_FILTQ_SET(ccca, q) ccca = (ccca & 0x0FFFFFFF) | (q << 28) +/* Bit 27 should always be zero */ +#define CCCA_DMA_ACTIVE(ccca) (ccca & 0x04000000) +#define CCCA_DMA_WRITE_MODE(ccca) (ccca & 0x02000000) +#define CCCA_DMA_WRITE_RIGHT(ccca) (ccca & 0x01000000) - uint16_t envvol; - #define ENVVOL_NODELAY(envol) (envvol&0x8000) - /* Verified with a soundfont bank. 7FFF is the minimum delay time, and 0 is the max delay time */ - #define ENVVOL_TO_EMU_SAMPLES(envvol) (envvol&0x8000) ? 0 : ((0x8000-(envvol&0x7FFF)) <<5) + uint16_t envvol; +#define ENVVOL_NODELAY(envol) (envvol & 0x8000) +/* Verified with a soundfont bank. 7FFF is the minimum delay time, and 0 is the max delay time */ +#define ENVVOL_TO_EMU_SAMPLES(envvol) (envvol & 0x8000) ? 0 : ((0x8000 - (envvol & 0x7FFF)) << 5) - uint16_t dcysusv; - #define DCYSUSV_IS_RELEASE(dcysusv) (dcysusv&0x8000) - #define DCYSUSV_GENERATOR_ENGINE_ON(dcysusv) !(dcysusv&0x0080) - #define DCYSUSV_SUSVALUE_GET(dcysusv) ((dcysusv>>8)&0x7F) - /* Inverting the range compared to documentation because the envelope runs from 0dBFS = 0 to -96dBFS = (1 <<21) */ - #define DCYSUSV_SUS_TO_ENV_RANGE(susvalue) (((0x7F-susvalue) << 21)/0x7F) - #define DCYSUSV_DECAYRELEASE_GET(dcysusv) (dcysusv&0x7F) + uint16_t dcysusv; +#define DCYSUSV_IS_RELEASE(dcysusv) (dcysusv & 0x8000) +#define DCYSUSV_GENERATOR_ENGINE_ON(dcysusv) !(dcysusv & 0x0080) +#define DCYSUSV_SUSVALUE_GET(dcysusv) ((dcysusv >> 8) & 0x7F) +/* Inverting the range compared to documentation because the envelope runs from 0dBFS = 0 to -96dBFS = (1 <<21) */ +#define DCYSUSV_SUS_TO_ENV_RANGE(susvalue) (((0x7F - susvalue) << 21) / 0x7F) +#define DCYSUSV_DECAYRELEASE_GET(dcysusv) (dcysusv & 0x7F) - uint16_t envval; - #define ENVVAL_NODELAY(enval) (envval&0x8000) - /* Verified with a soundfont bank. 7FFF is the minimum delay time, and 0 is the max delay time */ - #define ENVVAL_TO_EMU_SAMPLES(envval)(envval&0x8000) ? 0 : ((0x8000-(envval&0x7FFF)) <<5) + uint16_t envval; +#define ENVVAL_NODELAY(enval) (envval & 0x8000) +/* Verified with a soundfont bank. 7FFF is the minimum delay time, and 0 is the max delay time */ +#define ENVVAL_TO_EMU_SAMPLES(envval) (envval & 0x8000) ? 0 : ((0x8000 - (envval & 0x7FFF)) << 5) - uint16_t dcysus; - #define DCYSUS_IS_RELEASE(dcysus) (dcysus&0x8000) - #define DCYSUS_SUSVALUE_GET(dcysus) ((dcysus>>8)&0x7F) - #define DCYSUS_SUS_TO_ENV_RANGE(susvalue) ((susvalue << 21)/0x7F) - #define DCYSUS_DECAYRELEASE_GET(dcysus) (dcysus&0x7F) + uint16_t dcysus; +#define DCYSUS_IS_RELEASE(dcysus) (dcysus & 0x8000) +#define DCYSUS_SUSVALUE_GET(dcysus) ((dcysus >> 8) & 0x7F) +#define DCYSUS_SUS_TO_ENV_RANGE(susvalue) ((susvalue << 21) / 0x7F) +#define DCYSUS_DECAYRELEASE_GET(dcysus) (dcysus & 0x7F) - uint16_t atkhldv; - #define ATKHLDV_TRIGGER(atkhldv) !(atkhldv&0x8000) - #define ATKHLDV_HOLD(atkhldv) ((atkhldv>>8)&0x7F) - #define ATKHLDV_HOLD_TO_EMU_SAMPLES(atkhldv) (4096*(0x7F-((atkhldv>>8)&0x7F))) - #define ATKHLDV_ATTACK(atkhldv) (atkhldv&0x7F) + uint16_t atkhldv; +#define ATKHLDV_TRIGGER(atkhldv) !(atkhldv & 0x8000) +#define ATKHLDV_HOLD(atkhldv) ((atkhldv >> 8) & 0x7F) +#define ATKHLDV_HOLD_TO_EMU_SAMPLES(atkhldv) (4096 * (0x7F - ((atkhldv >> 8) & 0x7F))) +#define ATKHLDV_ATTACK(atkhldv) (atkhldv & 0x7F) - uint16_t lfo1val, lfo2val; - #define LFOxVAL_NODELAY(lfoxval) (lfoxval&0x8000) - #define LFOxVAL_TO_EMU_SAMPLES(lfoxval) (lfoxval&0x8000) ? 0 : ((0x8000-(lfoxval&0x7FFF)) <<5) + uint16_t lfo1val, lfo2val; +#define LFOxVAL_NODELAY(lfoxval) (lfoxval & 0x8000) +#define LFOxVAL_TO_EMU_SAMPLES(lfoxval) (lfoxval & 0x8000) ? 0 : ((0x8000 - (lfoxval & 0x7FFF)) << 5) - uint16_t atkhld; - #define ATKHLD_TRIGGER(atkhld) !(atkhld&0x8000) - #define ATKHLD_HOLD(atkhld) ((atkhld>>8)&0x7F) - #define ATKHLD_HOLD_TO_EMU_SAMPLES(atkhld) (4096*(0x7F-((atkhld>>8)&0x7F))) - #define ATKHLD_ATTACK(atkhld) (atkhld&0x7F) + uint16_t atkhld; +#define ATKHLD_TRIGGER(atkhld) !(atkhld & 0x8000) +#define ATKHLD_HOLD(atkhld) ((atkhld >> 8) & 0x7F) +#define ATKHLD_HOLD_TO_EMU_SAMPLES(atkhld) (4096 * (0x7F - ((atkhld >> 8) & 0x7F))) +#define ATKHLD_ATTACK(atkhld) (atkhld & 0x7F) + uint16_t ip; +#define INTIAL_PITCH_CENTER 0xE000 +#define INTIAL_PITCH_OCTAVE 0x1000 - uint16_t ip; - #define INTIAL_PITCH_CENTER 0xE000 - #define INTIAL_PITCH_OCTAVE 0x1000 - - union { - uint16_t ifatn; - struct{ - uint8_t ifatn_attenuation; - uint8_t ifatn_init_filter; - }; + union { + uint16_t ifatn; + struct { + uint8_t ifatn_attenuation; + uint8_t ifatn_init_filter; }; - union { - uint16_t pefe; - struct { - int8_t pefe_modenv_filter_height; - int8_t pefe_modenv_pitch_height; - }; + }; + union { + uint16_t pefe; + struct { + int8_t pefe_modenv_filter_height; + int8_t pefe_modenv_pitch_height; }; - union { - uint16_t fmmod; - struct { - int8_t fmmod_lfo1_filt_mod; - int8_t fmmod_lfo1_vibrato; - }; + }; + union { + uint16_t fmmod; + struct { + int8_t fmmod_lfo1_filt_mod; + int8_t fmmod_lfo1_vibrato; }; - union { - uint16_t tremfrq; - struct { - uint8_t tremfrq_lfo1_freq; - int8_t tremfrq_lfo1_tremolo; - }; + }; + union { + uint16_t tremfrq; + struct { + uint8_t tremfrq_lfo1_freq; + int8_t tremfrq_lfo1_tremolo; }; - union { - uint16_t fm2frq2; - struct { - uint8_t fm2frq2_lfo2_freq; - int8_t fm2frq2_lfo2_vibrato; - }; + }; + union { + uint16_t fm2frq2; + struct { + uint8_t fm2frq2_lfo2_freq; + int8_t fm2frq2_lfo2_vibrato; }; + }; - int env_engine_on; + int env_engine_on; - emu8k_mem_internal_t addr, loop_start, loop_end; + emu8k_mem_internal_t addr, loop_start, loop_end; - int32_t initial_att; - int32_t initial_filter; + int32_t initial_att; + int32_t initial_filter; - emu8k_envelope_t vol_envelope; - emu8k_envelope_t mod_envelope; + emu8k_envelope_t vol_envelope; + emu8k_envelope_t mod_envelope; - int64_t lfo1_speed, lfo2_speed; - emu8k_mem_internal_t lfo1_count, lfo2_count; - int32_t lfo1_delay_samples, lfo2_delay_samples; - int vol_l, vol_r; + int64_t lfo1_speed, lfo2_speed; + emu8k_mem_internal_t lfo1_count, lfo2_count; + int32_t lfo1_delay_samples, lfo2_delay_samples; + int vol_l, vol_r; - int16_t fixed_modenv_filter_height; - int16_t fixed_modenv_pitch_height; - int16_t fixed_lfo1_filt_mod; - int16_t fixed_lfo1_vibrato; - int16_t fixed_lfo1_tremolo; - int16_t fixed_lfo2_vibrato; + int16_t fixed_modenv_filter_height; + int16_t fixed_modenv_pitch_height; + int16_t fixed_lfo1_filt_mod; + int16_t fixed_lfo1_vibrato; + int16_t fixed_lfo1_tremolo; + int16_t fixed_lfo2_vibrato; - /* filter internal data. */ - int filterq_idx; - int32_t filt_att; - int64_t filt_buffer[5]; + /* filter internal data. */ + int filterq_idx; + int32_t filt_att; + int64_t filt_buffer[5]; } emu8k_voice_t; -typedef struct emu8k_t -{ - emu8k_voice_t voice[32]; +typedef struct emu8k_t { + emu8k_voice_t voice[32]; - uint16_t hwcf1, hwcf2, hwcf3; - uint32_t hwcf4, hwcf5, hwcf6, hwcf7; + uint16_t hwcf1, hwcf2, hwcf3; + uint32_t hwcf4, hwcf5, hwcf6, hwcf7; - uint16_t init1[32], init2[32], init3[32], init4[32]; + uint16_t init1[32], init2[32], init3[32], init4[32]; - uint32_t smalr, smarr, smalw, smarw; - uint16_t smld_buffer, smrd_buffer; + uint32_t smalr, smarr, smalw, smarw; + uint16_t smld_buffer, smrd_buffer; - uint16_t wc; + uint16_t wc; - uint16_t id; + uint16_t id; - /* The empty block is used to act as an unallocated memory returning zero. */ - int16_t *ram, *rom, *empty; + /* The empty block is used to act as an unallocated memory returning zero. */ + int16_t *ram, *rom, *empty; - /* RAM pointers are a way to avoid checking ram boundaries on read */ - int16_t *ram_pointers[0x100]; - uint32_t ram_end_addr; + /* RAM pointers are a way to avoid checking ram boundaries on read */ + int16_t *ram_pointers[0x100]; + uint32_t ram_end_addr; - int cur_reg, cur_voice; + int cur_reg, cur_voice; - int16_t out_l, out_r; + int16_t out_l, out_r; - emu8k_chorus_eng_t chorus_engine; - int32_t chorus_in_buffer[SOUNDBUFLEN]; - emu8k_reverb_eng_t reverb_engine; - int32_t reverb_in_buffer[SOUNDBUFLEN]; + emu8k_chorus_eng_t chorus_engine; + int32_t chorus_in_buffer[SOUNDBUFLEN]; + emu8k_reverb_eng_t reverb_engine; + int32_t reverb_in_buffer[SOUNDBUFLEN]; - int pos; - int32_t buffer[SOUNDBUFLEN * 2]; + int pos; + int32_t buffer[SOUNDBUFLEN * 2]; - uint16_t addr; + uint16_t addr; } emu8k_t; - - void emu8k_change_addr(emu8k_t *emu8k, uint16_t emu_addr); void emu8k_init(emu8k_t *emu8k, uint16_t emu_addr, int onboard_ram); void emu8k_close(emu8k_t *emu8k); void emu8k_update(emu8k_t *emu8k); - - - /* Section E - Introduction to the EMU8000 Chip @@ -656,12 +644,12 @@ Short Delay Short Delay + Feedback // Chorus Params typedef struct { - WORD FbkLevel; // Feedback Level (0xE600-0xE6FF) - WORD Delay; // Delay (0-0x0DA3) [1/44100 sec] - WORD LfoDepth; // LFO Depth (0xBC00-0xBCFF) - DWORD DelayR; // Right Delay (0-0xFFFFFFFF) [1/256/44100 sec] - DWORD LfoFreq; // LFO Frequency (0-0xFFFFFFFF) - } CHORUS_TYPE; + WORD FbkLevel; // Feedback Level (0xE600-0xE6FF) + WORD Delay; // Delay (0-0x0DA3) [1/44100 sec] + WORD LfoDepth; // LFO Depth (0xBC00-0xBCFF) + DWORD DelayR; // Right Delay (0-0xFFFFFFFF) [1/256/44100 sec] + DWORD LfoFreq; // LFO Frequency (0-0xFFFFFFFF) + } CHORUS_TYPE; Registers to write the Reverb Parameters to (they are all 16-bit): diff --git a/src/include/86box/snd_mpu401.h b/src/include/86box/snd_mpu401.h index 8846ee2dd..97b0de5fd 100644 --- a/src/include/86box/snd_mpu401.h +++ b/src/include/86box/snd_mpu401.h @@ -21,30 +21,28 @@ */ #ifndef SOUND_MPU401_H -# define SOUND_MPU401_H +#define SOUND_MPU401_H -#define MPU401_VERSION 0x15 -#define MPU401_REVISION 0x01 -#define MPU401_QUEUE 64 -#define MPU401_INPUT_QUEUE 1024 -#define MPU401_TIMECONSTANT (60000000/1000.0f) -#define MPU401_RESETBUSY 27.0f +#define MPU401_VERSION 0x15 +#define MPU401_REVISION 0x01 +#define MPU401_QUEUE 64 +#define MPU401_INPUT_QUEUE 1024 +#define MPU401_TIMECONSTANT (60000000 / 1000.0f) +#define MPU401_RESETBUSY 27.0f /*helpers*/ -#define M_GETKEY key[key/32]&(1<<(key%32)) -#define M_SETKEY key[key/32]|=(1<<(key%32)) -#define M_DELKEY key[key/32]&=~(1<<(key%32)) +#define M_GETKEY key[key / 32] & (1 << (key % 32)) +#define M_SETKEY key[key / 32] |= (1 << (key % 32)) +#define M_DELKEY key[key / 32] &= ~(1 << (key % 32)) -typedef enum MpuMode -{ +typedef enum MpuMode { M_UART, M_INTELLIGENT } MpuMode; #define M_MCA 0x10 -typedef enum MpuDataType -{ +typedef enum MpuDataType { T_OVERFLOW, T_MARK, T_MIDI_SYS, @@ -52,116 +50,112 @@ typedef enum MpuDataType T_COMMAND } MpuDataType; -typedef enum RecState -{ - M_RECOFF, - M_RECSTB, - M_RECON +typedef enum RecState { + M_RECOFF, + M_RECSTB, + M_RECON } RecState; /* Messages sent to MPU-401 from host */ -#define MSG_EOX 0xf7 -#define MSG_OVERFLOW 0xf8 -#define MSG_MARK 0xfc +#define MSG_EOX 0xf7 +#define MSG_OVERFLOW 0xf8 +#define MSG_MARK 0xfc /* Messages sent to host from MPU-401 */ -#define MSG_MPU_OVERFLOW 0xf8 -#define MSG_MPU_COMMAND_REQ 0xf9 -#define MSG_MPU_END 0xfc -#define MSG_MPU_CLOCK 0xfd -#define MSG_MPU_ACK 0xfe +#define MSG_MPU_OVERFLOW 0xf8 +#define MSG_MPU_COMMAND_REQ 0xf9 +#define MSG_MPU_END 0xfc +#define MSG_MPU_CLOCK 0xfd +#define MSG_MPU_ACK 0xfe -typedef struct mpu_t -{ +typedef struct mpu_t { uint16_t addr; - int uart_mode, intelligent, - irq, midi_thru, - queue_pos, queue_used; + int uart_mode, intelligent, + irq, midi_thru, + queue_pos, queue_used; uint8_t rx_data, is_mca, - status, - queue[MPU401_QUEUE], pos_regs[8]; - MpuMode mode; - uint8_t rec_queue[MPU401_INPUT_QUEUE]; - int rec_queue_pos, rec_queue_used; - uint32_t ch_toref[16]; - struct track - { - int counter; - uint8_t value[3], sys_val, - vlength,length; - MpuDataType type; + status, + queue[MPU401_QUEUE], pos_regs[8]; + MpuMode mode; + uint8_t rec_queue[MPU401_INPUT_QUEUE]; + int rec_queue_pos, rec_queue_used; + uint32_t ch_toref[16]; + struct track { + int counter; + uint8_t value[3], sys_val, + vlength, length; + MpuDataType type; } playbuf[8], condbuf; struct { - int conductor, cond_req, - cond_set, block_ack, - playing, reset, - wsd, wsm, wsd_start, - run_irq, irq_pending, - track_req, - send_now, eoi_scheduled, - data_onoff, clock_to_host, - sync_in, sysex_in_finished, - rec_copy; - RecState rec; - uint8_t tmask, cmask, - amask, - last_rtcmd; - uint16_t midi_mask, req_mask; - uint32_t command_byte, cmd_pending, - track, old_track; + int conductor, cond_req, + cond_set, block_ack, + playing, reset, + wsd, wsm, wsd_start, + run_irq, irq_pending, + track_req, + send_now, eoi_scheduled, + data_onoff, clock_to_host, + sync_in, sysex_in_finished, + rec_copy; + RecState rec; + uint8_t tmask, cmask, + amask, + last_rtcmd; + uint16_t midi_mask, req_mask; + uint32_t command_byte, cmd_pending, + track, old_track; } state; struct { - uint8_t timebase, old_timebase, - tempo, old_tempo, - tempo_rel, old_tempo_rel, - tempo_grad, cth_rate[4], - cth_mode, midimetro, - metromeas; - uint32_t cth_counter, cth_old, - rec_counter; - int32_t measure_counter, meas_old, - freq; - int ticks_in, active; - float freq_mod; + uint8_t timebase, old_timebase, + tempo, old_tempo, + tempo_rel, old_tempo_rel, + tempo_grad, cth_rate[4], + cth_mode, midimetro, + metromeas; + uint32_t cth_counter, cth_old, + rec_counter; + int32_t measure_counter, meas_old, + freq; + int ticks_in, active; + float freq_mod; } clock; - struct { - int all_thru, midi_thru, - sysex_thru, commonmsgs_thru, - modemsgs_in, commonmsgs_in, - bender_in, sysex_in, - allnotesoff_out, rt_affection, - rt_out, rt_in, - timing_in_stop, data_in_stop, - rec_measure_end; - uint8_t prchg_buf[16]; - uint16_t prchg_mask; - } filter; - struct { - int on; - uint8_t chan, trmask; - uint32_t key[4]; - } chanref[5], inputref[16]; - pc_timer_t mpu401_event_callback, mpu401_eoi_callback, - mpu401_reset_callback; - void (*ext_irq_update)(void *priv, int set); - int (*ext_irq_pending)(void *priv); - void *priv; + struct { + int all_thru, midi_thru, + sysex_thru, commonmsgs_thru, + modemsgs_in, commonmsgs_in, + bender_in, sysex_in, + allnotesoff_out, rt_affection, + rt_out, rt_in, + timing_in_stop, data_in_stop, + rec_measure_end; + uint8_t prchg_buf[16]; + uint16_t prchg_mask; + } filter; + struct { + int on; + uint8_t chan, trmask; + uint32_t key[4]; + } chanref[5], inputref[16]; + pc_timer_t mpu401_event_callback, mpu401_eoi_callback, + mpu401_reset_callback; + void (*ext_irq_update)(void *priv, int set); + int (*ext_irq_pending)(void *priv); + void *priv; } mpu_t; -extern int mpu401_standalone_enable, mpu401_already_loaded; +extern int mpu401_standalone_enable, mpu401_already_loaded; -extern const device_t mpu401_device; -extern const device_t mpu401_mca_device; +extern const device_t mpu401_device; +extern const device_t mpu401_mca_device; +extern uint8_t MPU401_ReadData(mpu_t *mpu); +extern void mpu401_setirq(mpu_t *mpu, int irq); +extern void mpu401_change_addr(mpu_t *mpu, uint16_t addr); +extern void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode, int receive_input); +extern void mpu401_device_add(void); +extern void mpu401_irq_attach(mpu_t *mpu, void (*ext_irq_update)(void *priv, int set), int (*ext_irq_pending)(void *priv), void *priv); -extern uint8_t MPU401_ReadData(mpu_t *mpu); -extern void mpu401_setirq(mpu_t *mpu, int irq); -extern void mpu401_change_addr(mpu_t *mpu, uint16_t addr); -extern void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode, int receive_input); -extern void mpu401_device_add(void); -extern void mpu401_irq_attach(mpu_t *mpu, void (*ext_irq_update)(void *priv, int set), int (*ext_irq_pending)(void *priv), void *priv); +extern int MPU401_InputSysex(void *p, uint8_t *buffer, uint32_t len, int abort); +extern void MPU401_InputMsg(void *p, uint8_t *msg, uint32_t len); -extern int MPU401_InputSysex(void *p, uint8_t *buffer, uint32_t len, int abort); -extern void MPU401_InputMsg(void *p, uint8_t *msg, uint32_t len); - -#endif /*SOUND_MPU401_H*/ +#endif /*SOUND_MPU401_H*/ diff --git a/src/include/86box/snd_opl.h b/src/include/86box/snd_opl.h index 6145376ec..ac8eef6fd 100644 --- a/src/include/86box/snd_opl.h +++ b/src/include/86box/snd_opl.h @@ -15,41 +15,40 @@ * Copyright 2016-2020 Miran Grca. */ #ifndef SOUND_OPL_H -# define SOUND_OPL_H +#define SOUND_OPL_H -typedef void (*tmrfunc)(void *priv, int timer, uint64_t period); +typedef void (*tmrfunc)(void *priv, int timer, uint64_t period); /* Define an OPLx chip. */ typedef struct { #ifdef SOUND_OPL_NUKED_H - nuked_t *opl; + nuked_t *opl; #else - void *opl; + void *opl; #endif - int8_t flags, pad; + int8_t flags, pad; - uint16_t port; - uint8_t status, timer_ctrl; - uint16_t timer_count[2], - timer_cur_count[2]; + uint16_t port; + uint8_t status, timer_ctrl; + uint16_t timer_count[2], + timer_cur_count[2]; - pc_timer_t timers[2]; + pc_timer_t timers[2]; - int pos; - int32_t buffer[SOUNDBUFLEN * 2]; + int pos; + int32_t buffer[SOUNDBUFLEN * 2]; } opl_t; +extern void opl_set_do_cycles(opl_t *dev, int8_t do_cycles); -extern void opl_set_do_cycles(opl_t *dev, int8_t do_cycles); +extern uint8_t opl2_read(uint16_t port, void *); +extern void opl2_write(uint16_t port, uint8_t val, void *); +extern void opl2_init(opl_t *); +extern void opl2_update(opl_t *); -extern uint8_t opl2_read(uint16_t port, void *); -extern void opl2_write(uint16_t port, uint8_t val, void *); -extern void opl2_init(opl_t *); -extern void opl2_update(opl_t *); +extern uint8_t opl3_read(uint16_t port, void *); +extern void opl3_write(uint16_t port, uint8_t val, void *); +extern void opl3_init(opl_t *); +extern void opl3_update(opl_t *); -extern uint8_t opl3_read(uint16_t port, void *); -extern void opl3_write(uint16_t port, uint8_t val, void *); -extern void opl3_init(opl_t *); -extern void opl3_update(opl_t *); - -#endif /*SOUND_OPL_H*/ +#endif /*SOUND_OPL_H*/ diff --git a/src/include/86box/snd_opl_nuked.h b/src/include/86box/snd_opl_nuked.h index 827b52fc2..af65d266b 100644 --- a/src/include/86box/snd_opl_nuked.h +++ b/src/include/86box/snd_opl_nuked.h @@ -18,18 +18,17 @@ */ #ifndef SOUND_OPL_NUKED_H -# define SOUND_OPL_NUKED_H +#define SOUND_OPL_NUKED_H +extern void *nuked_init(uint32_t sample_rate); +extern void nuked_close(void *); -extern void * nuked_init(uint32_t sample_rate); -extern void nuked_close(void *); +extern uint16_t nuked_write_addr(void *, uint16_t port, uint8_t val); +extern void nuked_write_reg(void *, uint16_t reg, uint8_t v); +extern void nuked_write_reg_buffered(void *, uint16_t reg, uint8_t v); -extern uint16_t nuked_write_addr(void *, uint16_t port, uint8_t val); -extern void nuked_write_reg(void *, uint16_t reg, uint8_t v); -extern void nuked_write_reg_buffered(void *, uint16_t reg, uint8_t v); +extern void nuked_generate(void *, int32_t *buf); +extern void nuked_generate_resampled(void *, int32_t *buf); +extern void nuked_generate_stream(void *, int32_t *sndptr, uint32_t num); -extern void nuked_generate(void *, int32_t *buf); -extern void nuked_generate_resampled(void *, int32_t *buf); -extern void nuked_generate_stream(void *, int32_t *sndptr, uint32_t num); - -#endif /*SOUND_OPL_NUKED_H*/ +#endif /*SOUND_OPL_NUKED_H*/ diff --git a/src/include/86box/snd_resid.h b/src/include/86box/snd_resid.h index 0a8b2edcd..b8763ad15 100644 --- a/src/include/86box/snd_resid.h +++ b/src/include/86box/snd_resid.h @@ -1,15 +1,15 @@ #ifndef SOUND_RESID_H -# define SOUND_RESID_H +#define SOUND_RESID_H #ifdef __cplusplus extern "C" { #endif - void *sid_init(); - void sid_close(void *p); - void sid_reset(void *p); - uint8_t sid_read(uint16_t addr, void *p); - void sid_write(uint16_t addr, uint8_t val, void *p); - void sid_fillbuf(int16_t *buf, int len, void *p); +void *sid_init(); +void sid_close(void *p); +void sid_reset(void *p); +uint8_t sid_read(uint16_t addr, void *p); +void sid_write(uint16_t addr, uint8_t val, void *p); +void sid_fillbuf(int16_t *buf, int len, void *p); #ifdef __cplusplus } #endif diff --git a/src/include/86box/snd_sb.h b/src/include/86box/snd_sb.h index 90e3e4355..d2498e363 100644 --- a/src/include/86box/snd_sb.h +++ b/src/include/86box/snd_sb.h @@ -1,145 +1,159 @@ /* - * 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. * - * Sound Blaster emulation. + * Sound Blaster emulation. * - * Authors: Sarah Walker, - * Miran Grca, - * TheCollector1995, + * Authors: Sarah Walker, + * Miran Grca, + * TheCollector1995, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #ifndef SOUND_SND_SB_H -# define SOUND_SND_SB_H +#define SOUND_SND_SB_H +#include <86box/snd_cms.h> #include <86box/snd_emu8k.h> #include <86box/snd_mpu401.h> #include <86box/snd_opl.h> #include <86box/snd_sb_dsp.h> -#include <86box/snd_cms.h> -#define SADLIB 1 /* No DSP */ -#define SB1 2 /* DSP v1.05 */ -#define SB15 3 /* DSP v2.00 */ -#define SB2 4 /* DSP v2.01 - needed for high-speed DMA */ -#define SBPRO 5 /* DSP v3.00 */ -#define SBPRO2 6 /* DSP v3.02 + OPL3 */ -#define SB16 7 /* DSP v4.05 + OPL3 */ -#define SBAWE32 8 /* DSP v4.13 + OPL3 */ -#define SBAWE64 9 /* DSP v4.16 + OPL3 */ +#define SADLIB 1 /* No DSP */ +#define SB1 2 /* DSP v1.05 */ +#define SB15 3 /* DSP v2.00 */ +#define SB2 4 /* DSP v2.01 - needed for high-speed DMA */ +#define SBPRO 5 /* DSP v3.00 */ +#define SBPRO2 6 /* DSP v3.02 + OPL3 */ +#define SB16 7 /* DSP v4.05 + OPL3 */ +#define SBAWE32 8 /* DSP v4.13 + OPL3 */ +#define SBAWE64 9 /* DSP v4.16 + OPL3 */ /* SB 2.0 CD version */ -typedef struct sb_ct1335_mixer_t -{ - double master; - double voice; - double fm; - double cd; +typedef struct sb_ct1335_mixer_t { + double master; + double voice; + double fm; + double cd; - uint8_t index; - uint8_t regs[256]; + uint8_t index; + uint8_t regs[256]; } sb_ct1335_mixer_t; + /* SB PRO */ -typedef struct sb_ct1345_mixer_t -{ - double master_l, master_r; - double voice_l, voice_r; - double fm_l, fm_r; - double cd_l, cd_r; - double line_l, line_r; - double mic; - /*see sb_ct1745_mixer for values for input selector*/ - int32_t input_selector; +typedef struct sb_ct1345_mixer_t { + double master_l, + master_r; + double voice_l, + voice_r; + double fm_l, + fm_r; + double cd_l, + cd_r; + double line_l, + line_r; + double mic; + /*see sb_ct1745_mixer for values for input selector*/ + int32_t input_selector; - int input_filter; - int in_filter_freq; - int output_filter; + int input_filter; + int in_filter_freq; + int output_filter; - int stereo; - int stereo_isleft; + int stereo; + int stereo_isleft; - uint8_t index; - uint8_t regs[256]; + uint8_t index; + uint8_t regs[256]; } sb_ct1345_mixer_t; + /* SB16 and AWE32 */ -typedef struct sb_ct1745_mixer_t -{ - double master_l, master_r; - double voice_l, voice_r; - double fm_l, fm_r; - double cd_l, cd_r; - double line_l, line_r; - double mic; - double speaker; +typedef struct sb_ct1745_mixer_t { + double master_l, + master_r; + double voice_l, + voice_r; + double fm_l, + fm_r; + double cd_l, + cd_r; + double line_l, + line_r; + double mic; + double speaker; - int bass_l, bass_r; - int treble_l, treble_r; + int bass_l, + bass_r; + int treble_l, + treble_r; - int output_selector; - #define OUTPUT_MIC 1 - #define OUTPUT_CD_R 2 - #define OUTPUT_CD_L 4 - #define OUTPUT_LINE_R 8 - #define OUTPUT_LINE_L 16 + int output_selector; +#define OUTPUT_MIC 1 +#define OUTPUT_CD_R 2 +#define OUTPUT_CD_L 4 +#define OUTPUT_LINE_R 8 +#define OUTPUT_LINE_L 16 - int input_selector_left; - int input_selector_right; - #define INPUT_MIC 1 - #define INPUT_CD_R 2 - #define INPUT_CD_L 4 - #define INPUT_LINE_R 8 - #define INPUT_LINE_L 16 - #define INPUT_MIDI_R 32 - #define INPUT_MIDI_L 64 + int input_selector_left; + int input_selector_right; +#define INPUT_MIC 1 +#define INPUT_CD_R 2 +#define INPUT_CD_L 4 +#define INPUT_LINE_R 8 +#define INPUT_LINE_L 16 +#define INPUT_MIDI_R 32 +#define INPUT_MIDI_L 64 - int mic_agc; + int mic_agc; - int32_t input_gain_L; - int32_t input_gain_R; - double output_gain_L; - double output_gain_R; + int32_t input_gain_L; + int32_t input_gain_R; + double output_gain_L; + double output_gain_R; - uint8_t index; - uint8_t regs[256]; + uint8_t index; + uint8_t regs[256]; } sb_ct1745_mixer_t; -typedef struct sb_t -{ - uint8_t cms_enabled, opl_enabled, mixer_enabled; - cms_t cms; - opl_t opl, opl2; - sb_dsp_t dsp; - union { - sb_ct1335_mixer_t mixer_sb2; - sb_ct1345_mixer_t mixer_sbpro; - sb_ct1745_mixer_t mixer_sb16; - }; - mpu_t *mpu; - emu8k_t emu8k; - void *gameport; +typedef struct sb_t { + uint8_t cms_enabled, + opl_enabled, + mixer_enabled; + cms_t cms; + opl_t opl, + opl2; + sb_dsp_t dsp; + union { + sb_ct1335_mixer_t mixer_sb2; + sb_ct1345_mixer_t mixer_sbpro; + sb_ct1745_mixer_t mixer_sb16; + }; + mpu_t *mpu; + emu8k_t emu8k; + void *gameport; - int pos; + int pos; - uint8_t pos_regs[8], pnp_rom[512]; + uint8_t pos_regs[8], + pnp_rom[512]; - uint16_t opl_pnp_addr; + uint16_t opl_pnp_addr; } sb_t; -extern void sb_ct1345_mixer_write(uint16_t addr, uint8_t val, void *p); +extern void sb_ct1345_mixer_write(uint16_t addr, uint8_t val, void *p); extern uint8_t sb_ct1345_mixer_read(uint16_t addr, void *p); -extern void sb_ct1345_mixer_reset(sb_t* sb); +extern void sb_ct1345_mixer_reset(sb_t *sb); extern void sb_get_buffer_sbpro(int32_t *buffer, int len, void *p); extern void sbpro_filter_cd_audio(int channel, double *buffer, void *p); extern void sb_close(void *p); extern void sb_speed_changed(void *p); -#endif /*SOUND_SND_SB_H*/ +#endif /*SOUND_SND_SB_H*/ diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index 740d05ca0..eff16373d 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -1,5 +1,5 @@ #ifndef SOUND_SND_SB_DSP_H -# define SOUND_SND_SB_DSP_H +#define SOUND_SND_SB_DSP_H /*Sound Blaster Clones, for quirks*/ #define SB_SUBTYPE_DEFAULT 0 /*Handle as a Creative card*/ @@ -7,101 +7,99 @@ #define SB_SUBTYPE_CLONE_AZT1605_0X0C 2 /*Aztech Sound Galaxy Nova 16 Extra / Packard Bell Forte 16, DSP 2.1 - SBPRO2 clone*/ /* aztech-related */ -#define IS_AZTECH(dsp) ((dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11 || (dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) /* check for future AZT cards here */ -#define AZTECH_EEPROM_SIZE 16 +#define IS_AZTECH(dsp) ((dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11 || (dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) /* check for future AZT cards here */ +#define AZTECH_EEPROM_SIZE 16 -typedef struct sb_dsp_t -{ - int sb_type; - int sb_subtype; /* which clone */ - void *parent; /* "sb_t *" if default subtype, "azt2316a_t *" if aztech. */ +typedef struct sb_dsp_t { + int sb_type; + int sb_subtype; /* which clone */ + void *parent; /* "sb_t *" if default subtype, "azt2316a_t *" if aztech. */ - int sb_8_length, sb_8_format, sb_8_autoinit, sb_8_pause, sb_8_enable, sb_8_autolen, sb_8_output; - int sb_8_dmanum; - int sb_16_length, sb_16_format, sb_16_autoinit, sb_16_pause, sb_16_enable, sb_16_autolen, sb_16_output; - int sb_16_dmanum; - int sb_pausetime; + int sb_8_length, sb_8_format, sb_8_autoinit, sb_8_pause, sb_8_enable, sb_8_autolen, sb_8_output; + int sb_8_dmanum; + int sb_16_length, sb_16_format, sb_16_autoinit, sb_16_pause, sb_16_enable, sb_16_autolen, sb_16_output; + int sb_16_dmanum; + int sb_pausetime; - uint8_t sb_read_data[256]; - int sb_read_wp, sb_read_rp; - int sb_speaker; - int muted; + uint8_t sb_read_data[256]; + int sb_read_wp, sb_read_rp; + int sb_speaker; + int muted; - int sb_data_stat; + int sb_data_stat; - int midi_in_sysex; - int midi_in_poll; - int uart_midi; - int uart_irq; - int onebyte_midi; - int midi_in_timestamp; + int midi_in_sysex; + int midi_in_poll; + int uart_midi; + int uart_irq; + int onebyte_midi; + int midi_in_timestamp; - int sb_irqnum; + int sb_irqnum; - uint8_t sbe2; - int sbe2count; + uint8_t sbe2; + int sbe2count; - uint8_t sb_data[8]; + uint8_t sb_data[8]; - int sb_freq; + int sb_freq; - int16_t sbdat; - int sbdat2; - int16_t sbdatl, sbdatr; + int16_t sbdat; + int sbdat2; + int16_t sbdatl, sbdatr; - uint8_t sbref; - int8_t sbstep; + uint8_t sbref; + int8_t sbstep; - int sbdacpos; + int sbdacpos; - int sbleftright; + int sbleftright; - int sbreset; - uint8_t sbreaddat; - uint8_t sb_command; - uint8_t sb_test; - int sb_timei, sb_timeo; + int sbreset; + uint8_t sbreaddat; + uint8_t sb_command; + uint8_t sb_test; + int sb_timei, sb_timeo; - int sb_irq8, sb_irq16, sb_irq401; - int sb_irqm8, sb_irqm16, sb_irqm401; + int sb_irq8, sb_irq16, sb_irq401; + int sb_irqm8, sb_irqm16, sb_irqm401; - uint8_t sb_asp_regs[256]; - uint8_t sb_asp_mode; + uint8_t sb_asp_regs[256]; + uint8_t sb_asp_mode; - uint8_t sb_asp_ram[2048]; - int sb_asp_ram_index; + uint8_t sb_asp_ram[2048]; + int sb_asp_ram_index; - uint8_t sb_8051_ram[256]; + uint8_t sb_8051_ram[256]; - int sbenable, sb_enable_i; + int sbenable, sb_enable_i; - pc_timer_t output_timer, input_timer; + pc_timer_t output_timer, input_timer; - uint64_t sblatcho, sblatchi; + uint64_t sblatcho, sblatchi; - uint16_t sb_addr; + uint16_t sb_addr; - int stereo; + int stereo; - int asp_data_len; + int asp_data_len; - pc_timer_t wb_timer; - int wb_full; + pc_timer_t wb_timer; + int wb_full; - int busy_count; + int busy_count; - int record_pos_read; - int record_pos_write; - int16_t record_buffer[0xFFFF]; - int16_t buffer[SOUNDBUFLEN * 2]; - int pos; + int record_pos_read; + int record_pos_write; + int16_t record_buffer[0xFFFF]; + int16_t buffer[SOUNDBUFLEN * 2]; + int pos; - uint8_t azt_eeprom[AZTECH_EEPROM_SIZE]; /* the eeprom in the Aztech cards is attached to the DSP */ + uint8_t azt_eeprom[AZTECH_EEPROM_SIZE]; /* the eeprom in the Aztech cards is attached to the DSP */ - mpu_t *mpu; + mpu_t *mpu; } sb_dsp_t; - void sb_dsp_input_msg(void *p, uint8_t *msg, uint32_t len); int sb_dsp_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort); diff --git a/src/include/86box/snd_sn76489.h b/src/include/86box/snd_sn76489.h index 0a30ae531..c8a3a567c 100644 --- a/src/include/86box/snd_sn76489.h +++ b/src/include/86box/snd_sn76489.h @@ -1,11 +1,10 @@ #ifndef SOUND_SN76489_H -# define SOUND_SN76489_H +#define SOUND_SN76489_H -enum -{ - SN76496, - NCR8496, - PSSJ +enum { + SN76496, + NCR8496, + PSSJ }; extern const device_t sn76489_device; @@ -13,23 +12,22 @@ extern const device_t ncr8496_device; extern int sn76489_mute; -typedef struct sn76489_t -{ - int stat[4]; - int latch[4], count[4]; - int freqlo[4], freqhi[4]; - int vol[4]; - uint32_t shift; - uint8_t noise; - int lasttone; - uint8_t firstdat; - int type; - int extra_divide; +typedef struct sn76489_t { + int stat[4]; + int latch[4], count[4]; + int freqlo[4], freqhi[4]; + int vol[4]; + uint32_t shift; + uint8_t noise; + int lasttone; + uint8_t firstdat; + int type; + int extra_divide; - int16_t buffer[SOUNDBUFLEN]; - int pos; + int16_t buffer[SOUNDBUFLEN]; + int pos; - double psgconst; + double psgconst; } sn76489_t; void sn76489_init(sn76489_t *sn76489, uint16_t base, uint16_t size, int type, int freq); diff --git a/src/include/86box/snd_speaker.h b/src/include/86box/snd_speaker.h index 534696208..0b368268e 100644 --- a/src/include/86box/snd_speaker.h +++ b/src/include/86box/snd_speaker.h @@ -18,17 +18,16 @@ */ #ifndef SOUND_SPEAKER_H -# define SOUND_SPEAKER_H +#define SOUND_SPEAKER_H -extern int speaker_mute; +extern int speaker_mute; -extern int speaker_gated; -extern int speaker_enable, was_speaker_enable; +extern int speaker_gated; +extern int speaker_enable, was_speaker_enable; +extern void speaker_init(); -extern void speaker_init(); - -extern void speaker_set_count(uint8_t new_m, int new_count); -extern void speaker_update(void); +extern void speaker_set_count(uint8_t new_m, int new_count); +extern void speaker_update(void); #endif /*SOUND_SPEAKER_H*/ diff --git a/src/include/86box/snd_ym7128.h b/src/include/86box/snd_ym7128.h index 6957e9d30..4d5400f34 100644 --- a/src/include/86box/snd_ym7128.h +++ b/src/include/86box/snd_ym7128.h @@ -1,26 +1,25 @@ #ifndef SOUND_YM7128_H -# define SOUND_YM7128_H +#define SOUND_YM7128_H -typedef struct ym7128_t -{ - int a0, sci; - uint8_t dat; +typedef struct ym7128_t { + int a0, sci; + uint8_t dat; - int reg_sel; - uint8_t regs[32]; + int reg_sel; + uint8_t regs[32]; - int gl[8], gr[8]; - int vm, vc, vl, vr; - int c0, c1; - int t[9]; + int gl[8], gr[8]; + int vm, vc, vl, vr; + int c0, c1; + int t[9]; - int16_t filter_dat; - int16_t prev_l, prev_r; + int16_t filter_dat; + int16_t prev_l, prev_r; - int16_t delay_buffer[2400]; - int delay_pos; + int16_t delay_buffer[2400]; + int delay_pos; - int16_t last_samp; + int16_t last_samp; } ym7128_t; void ym7128_init(ym7128_t *ym7128); diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index f4a80fd08..558c472ed 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -1,78 +1,76 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 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. * - * Sound emulation core. + * Sound emulation core. * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Sarah Walker, + * Miran Grca, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #ifndef EMU_SOUND_H -# define EMU_SOUND_H +#define EMU_SOUND_H extern int sound_gain; -#define SOUNDBUFLEN (48000/50) - -#define CD_FREQ 44100 -#define CD_BUFLEN (CD_FREQ / 10) +#define SOUNDBUFLEN (48000 / 50) +#define CD_FREQ 44100 +#define CD_BUFLEN (CD_FREQ / 10) enum { SOUND_NONE = 0, SOUND_INTERNAL }; +extern int ppispeakon; +extern int gated, + speakval, + speakon; -extern int ppispeakon; -extern int gated, - speakval, - speakon; +extern int sound_pos_global; +extern int sound_card_current; -extern int sound_pos_global; -extern int sound_card_current; +extern void sound_add_handler(void (*get_buffer)(int32_t *buffer, + int len, void *p), + void *p); +extern void sound_set_cd_audio_filter(void (*filter)(int channel, + double *buffer, void *p), + void *p); - -extern void sound_add_handler(void (*get_buffer)(int32_t *buffer, \ - int len, void *p), void *p); -extern void sound_set_cd_audio_filter(void (*filter)(int channel, \ - double *buffer, void *p), void *p); - -extern int sound_card_available(int card); +extern int sound_card_available(int card); #ifdef EMU_DEVICE_H -extern const device_t *sound_card_getdevice(int card); +extern const device_t *sound_card_getdevice(int card); #endif -extern int sound_card_has_config(int card); -extern char *sound_card_get_internal_name(int card); -extern int sound_card_get_from_internal_name(char *s); -extern void sound_card_init(void); -extern void sound_set_cd_volume(unsigned int vol_l, unsigned int vol_r); +extern int sound_card_has_config(int card); +extern char *sound_card_get_internal_name(int card); +extern int sound_card_get_from_internal_name(char *s); +extern void sound_card_init(void); +extern void sound_set_cd_volume(unsigned int vol_l, unsigned int vol_r); -extern void sound_speed_changed(void); +extern void sound_speed_changed(void); -extern void sound_init(void); -extern void sound_reset(void); +extern void sound_init(void); +extern void sound_reset(void); -extern void sound_card_reset(void); +extern void sound_card_reset(void); -extern void sound_cd_thread_end(void); -extern void sound_cd_thread_reset(void); - -extern void closeal(void); -extern void inital(void); -extern void givealbuffer(void *buf); -extern void givealbuffer_cd(void *buf); +extern void sound_cd_thread_end(void); +extern void sound_cd_thread_reset(void); +extern void closeal(void); +extern void inital(void); +extern void givealbuffer(void *buf); +extern void givealbuffer_cd(void *buf); #ifdef EMU_DEVICE_H /* AdLib and AdLib Gold */ @@ -94,20 +92,20 @@ extern const device_t cms_device; /* Gravis UltraSound and UltraSound Max */ extern const device_t gus_device; -#if defined(DEV_BRANCH) && defined(USE_PAS16) +# if defined(DEV_BRANCH) && defined(USE_PAS16) /* Pro Audio Spectrum 16 */ extern const device_t pas16_device; -#endif +# endif /* IBM PS/1 Audio Card */ extern const device_t ps1snd_device; /* Tandy PSSJ */ extern const device_t pssj_device; -#if defined(DEV_BRANCH) && defined(USE_TANDY_ISA) +# if defined(DEV_BRANCH) && defined(USE_TANDY_ISA) extern const device_t pssj_isa_device; extern const device_t tndy_device; -#endif +# endif /* Creative Labs Sound Blaster */ extern const device_t sb_1_device; @@ -142,4 +140,4 @@ extern const device_t cs4237b_device; extern const device_t cs4238b_device; #endif -#endif /*EMU_SOUND_H*/ +#endif /*EMU_SOUND_H*/ diff --git a/src/sound/midi.c b/src/sound/midi.c index 05ac861f8..e225a1301 100644 --- a/src/sound/midi.c +++ b/src/sound/midi.c @@ -1,69 +1,69 @@ /* - * 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. * - * MIDI device core module. + * MIDI device core module. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Bit, - * DOSBox Team, + * Authors: Sarah Walker, + * Miran Grca, + * Bit, + * DOSBox Team, * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. - * Copyright 2016-2020 Bit. - * Copyright 2008-2020 DOSBox Team. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2016-2020 Bit. + * Copyright 2008-2020 DOSBox Team. */ -#include #include -#include +#include #include +#include #include + #include <86box/86box.h> #include <86box/device.h> -#include <86box/plat.h> #include <86box/midi.h> +#include <86box/plat.h> - -int midi_device_current = 0; -static int midi_device_last = 0; -int midi_input_device_current = 0; -static int midi_input_device_last = 0; +int midi_device_current = 0; +static int midi_device_last = 0; +int midi_input_device_current = 0; +static int midi_input_device_last = 0; midi_t *midi = NULL, *midi_in = NULL; midi_in_handler_t *mih_first = NULL, *mih_last = NULL, - *mih_cur = NULL; + *mih_cur = NULL; uint8_t MIDI_InSysexBuf[SYSEX_SIZE]; uint8_t MIDI_evt_len[256] = { - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 0x00 */ - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 0x10 */ - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 0x20 */ - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 0x30 */ - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 0x40 */ - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 0x50 */ - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 0x60 */ - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 0x70 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 */ - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, /* 0x80 */ - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, /* 0x90 */ - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, /* 0xa0 */ - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, /* 0xb0 */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x80 */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x90 */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xa0 */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xb0 */ - 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, /* 0xc0 */ - 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, /* 0xd0 */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xc0 */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xd0 */ - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, /* 0xe0 */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xe0 */ - 0,2,3,2, 0,0,1,0, 1,0,1,1, 1,0,1,0 /* 0xf0 */ + 0, 2, 3, 2, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0 /* 0xf0 */ }; typedef struct @@ -72,104 +72,109 @@ typedef struct } MIDI_DEVICE, MIDI_IN_DEVICE; static const device_t midi_none_device = { - "None", - "none", - 0, 0, - NULL, NULL, NULL, - { NULL }, NULL, NULL, - NULL + "None", + "none", + 0, + 0, + NULL, + NULL, + NULL, + { NULL }, + NULL, + NULL, + NULL }; -static const MIDI_DEVICE devices[] = -{ - { &midi_none_device }, +static const MIDI_DEVICE devices[] = { + // clang-format off + { &midi_none_device }, #ifdef USE_FLUIDSYNTH - { &fluidsynth_device }, + { &fluidsynth_device }, #endif #ifdef USE_MUNT - { &mt32_device }, - { &cm32l_device }, + { &mt32_device }, + { &cm32l_device }, #endif - { &rtmidi_device }, - { NULL } + { &rtmidi_device }, + { NULL } + // clang-format on }; static const device_t midi_in_none_device = { - "None", - "none", - 0, 0, - NULL, NULL, NULL, - { NULL }, NULL, NULL, - NULL + "None", + "none", + 0, + 0, + NULL, + NULL, + NULL, + { NULL }, + NULL, + NULL, + NULL }; -static const MIDI_IN_DEVICE midi_in_devices[] = -{ - { &midi_in_none_device }, - { &rtmidi_input_device }, - { NULL } +static const MIDI_IN_DEVICE midi_in_devices[] = { + // clang-format off + { &midi_in_none_device }, + { &rtmidi_input_device }, + { NULL } + // clang-format on }; - int midi_device_available(int card) { if (devices[card].device) - return device_available(devices[card].device); + return device_available(devices[card].device); return 1; } - const device_t * midi_device_getdevice(int card) { return devices[card].device; } - int midi_device_has_config(int card) { if (!devices[card].device) - return 0; + return 0; return devices[card].device->config ? 1 : 0; } - char * midi_device_get_internal_name(int card) { return device_get_internal_name(devices[card].device); } - int midi_device_get_from_internal_name(char *s) { int c = 0; while (devices[c].device != NULL) { - if (!strcmp(devices[c].device->internal_name, s)) - return c; - c++; + if (!strcmp(devices[c].device->internal_name, s)) + return c; + c++; } return 0; } - void midi_device_init() { if (devices[midi_device_current].device) - device_add(devices[midi_device_current].device); + device_add(devices[midi_device_current].device); midi_device_last = midi_device_current; } - void -midi_init(midi_device_t* device) +midi_init(midi_device_t *device) { midi = (midi_t *) malloc(sizeof(midi_t)); memset(midi, 0, sizeof(midi_t)); @@ -178,26 +183,25 @@ midi_init(midi_device_t* device) } void -midi_in_init(midi_device_t* device, midi_t **mididev) +midi_in_init(midi_device_t *device, midi_t **mididev) { - *mididev = (midi_t *)malloc(sizeof(midi_t)); + *mididev = (midi_t *) malloc(sizeof(midi_t)); memset(*mididev, 0, sizeof(midi_t)); (*mididev)->m_in_device = device; } - void midi_close(void) { if (midi && midi->m_out_device) { - free(midi->m_out_device); - midi->m_out_device = NULL; + free(midi->m_out_device); + midi->m_out_device = NULL; } if (midi) { - free(midi); - midi = NULL; + free(midi); + midi = NULL; } } @@ -205,416 +209,394 @@ void midi_in_close(void) { if (midi_in && midi_in->m_in_device) { - free(midi_in->m_in_device); - midi_in->m_in_device = NULL; + free(midi_in->m_in_device); + midi_in->m_in_device = NULL; } if (midi_in) { - free(midi_in); - midi_in = NULL; + free(midi_in); + midi_in = NULL; } } - void midi_poll(void) { if (midi && midi->m_out_device && midi->m_out_device->poll) - midi->m_out_device->poll(); + midi->m_out_device->poll(); } - void play_msg(uint8_t *msg) { if (midi->m_out_device->play_msg) - midi->m_out_device->play_msg(msg); + midi->m_out_device->play_msg(msg); } - void play_sysex(uint8_t *sysex, unsigned int len) { if (midi->m_out_device->play_sysex) - midi->m_out_device->play_sysex(sysex, len); + midi->m_out_device->play_sysex(sysex, len); } - int midi_in_device_available(int card) { if (midi_in_devices[card].device) - return device_available(midi_in_devices[card].device); + return device_available(midi_in_devices[card].device); return 1; } - const device_t * midi_in_device_getdevice(int card) { return midi_in_devices[card].device; } - int midi_in_device_has_config(int card) { if (!midi_in_devices[card].device) - return 0; + return 0; return midi_in_devices[card].device->config ? 1 : 0; } - char * midi_in_device_get_internal_name(int card) { return device_get_internal_name(midi_in_devices[card].device); } - int midi_in_device_get_from_internal_name(char *s) { int c = 0; while (midi_in_devices[c].device != NULL) { - if (!strcmp(midi_in_devices[c].device->internal_name, s)) - return c; - c++; + if (!strcmp(midi_in_devices[c].device->internal_name, s)) + return c; + c++; } return 0; } - void midi_in_device_init() { if (midi_in_devices[midi_input_device_current].device) - device_add(midi_in_devices[midi_input_device_current].device); + device_add(midi_in_devices[midi_input_device_current].device); midi_input_device_last = midi_input_device_current; } - void midi_raw_out_rt_byte(uint8_t val) { if (!midi_in) - return; + return; if (!midi_in->midi_realtime) - return; + return; if ((!midi_in->midi_clockout && (val == 0xf8))) - return; + return; midi_in->midi_cmd_r = val << 24; /* pclog("Play RT Byte msg\n"); */ - play_msg((uint8_t *)&midi_in->midi_cmd_r); + play_msg((uint8_t *) &midi_in->midi_cmd_r); } - void midi_raw_out_thru_rt_byte(uint8_t val) { if (midi_in && midi_in->thruchan) - midi_raw_out_rt_byte(val); + midi_raw_out_rt_byte(val); } - void midi_raw_out_byte(uint8_t val) { uint32_t passed_ticks; if (!midi || !midi->m_out_device) - return; + return; if ((midi->m_out_device->write && midi->m_out_device->write(val))) - return; + return; if (midi->midi_sysex_start) { - passed_ticks = plat_get_ticks() - midi->midi_sysex_start; - if (passed_ticks < midi->midi_sysex_delay) - plat_delay_ms(midi->midi_sysex_delay - passed_ticks); + passed_ticks = plat_get_ticks() - midi->midi_sysex_start; + if (passed_ticks < midi->midi_sysex_delay) + plat_delay_ms(midi->midi_sysex_delay - passed_ticks); } /* Test for a realtime MIDI message */ if (val >= 0xf8) { - midi->midi_rt_buf[0] = val; - play_msg(midi->midi_rt_buf); - return; + midi->midi_rt_buf[0] = val; + play_msg(midi->midi_rt_buf); + return; } /* Test for a active sysex transfer */ if (midi->midi_status == 0xf0) { - if (!(val & 0x80)) { - if (midi->midi_pos < (SYSEX_SIZE-1)) - midi->midi_sysex_data[midi->midi_pos++] = val; - return; - } else { - midi->midi_sysex_data[midi->midi_pos++] = 0xf7; + if (!(val & 0x80)) { + if (midi->midi_pos < (SYSEX_SIZE - 1)) + midi->midi_sysex_data[midi->midi_pos++] = val; + return; + } else { + midi->midi_sysex_data[midi->midi_pos++] = 0xf7; - if ((midi->midi_sysex_start) && (midi->midi_pos >= 4) && (midi->midi_pos <= 9) && - (midi->midi_sysex_data[1] == 0x41) && (midi->midi_sysex_data[3] == 0x16)) { - /* pclog("MIDI: Skipping invalid MT-32 SysEx MIDI message\n"); */ - } else { - play_sysex(midi->midi_sysex_data, midi->midi_pos); - if (midi->midi_sysex_start) { - if (midi-> midi_sysex_data[5] == 0x7f) - midi->midi_sysex_delay = 290; /* All parameters reset */ - else if ((midi->midi_sysex_data[5] == 0x10) && (midi->midi_sysex_data[6] == 0x00) && - (midi->midi_sysex_data[7] == 0x04)) - midi->midi_sysex_delay = 145; /* Viking Child */ - else if ((midi->midi_sysex_data[5] == 0x10) && (midi->midi_sysex_data[6] == 0x00) && - (midi->midi_sysex_data[7] == 0x01)) - midi->midi_sysex_delay = 30; /* Dark Sun 1 */ - else - midi->midi_sysex_delay = (unsigned int) (((float) (midi->midi_pos) * 1.25f) * 1000.0f / 3125.0f) + 2; + if ((midi->midi_sysex_start) && (midi->midi_pos >= 4) && (midi->midi_pos <= 9) && (midi->midi_sysex_data[1] == 0x41) && (midi->midi_sysex_data[3] == 0x16)) { + /* pclog("MIDI: Skipping invalid MT-32 SysEx MIDI message\n"); */ + } else { + play_sysex(midi->midi_sysex_data, midi->midi_pos); + if (midi->midi_sysex_start) { + if (midi->midi_sysex_data[5] == 0x7f) + midi->midi_sysex_delay = 290; /* All parameters reset */ + else if ((midi->midi_sysex_data[5] == 0x10) && (midi->midi_sysex_data[6] == 0x00) && (midi->midi_sysex_data[7] == 0x04)) + midi->midi_sysex_delay = 145; /* Viking Child */ + else if ((midi->midi_sysex_data[5] == 0x10) && (midi->midi_sysex_data[6] == 0x00) && (midi->midi_sysex_data[7] == 0x01)) + midi->midi_sysex_delay = 30; /* Dark Sun 1 */ + else + midi->midi_sysex_delay = (unsigned int) (((float) (midi->midi_pos) * 1.25f) * 1000.0f / 3125.0f) + 2; - midi->midi_sysex_start = plat_get_ticks(); - } - } - } + midi->midi_sysex_start = plat_get_ticks(); + } + } + } } if (val & 0x80) { - midi->midi_status = val; - midi->midi_cmd_pos = 0; - midi->midi_cmd_len = MIDI_evt_len[val]; - if (midi->midi_status == 0xf0) { - midi->midi_sysex_data[0] = 0xf0; - midi->midi_pos = 1; - } + midi->midi_status = val; + midi->midi_cmd_pos = 0; + midi->midi_cmd_len = MIDI_evt_len[val]; + if (midi->midi_status == 0xf0) { + midi->midi_sysex_data[0] = 0xf0; + midi->midi_pos = 1; + } } if (midi->midi_cmd_len) { - midi->midi_cmd_buf[midi->midi_cmd_pos++] = val; - if (midi->midi_cmd_pos >= midi->midi_cmd_len) { - play_msg(midi->midi_cmd_buf); - midi->midi_cmd_pos = 1; - } + midi->midi_cmd_buf[midi->midi_cmd_pos++] = val; + if (midi->midi_cmd_pos >= midi->midi_cmd_len) { + play_msg(midi->midi_cmd_buf); + midi->midi_cmd_pos = 1; + } } } - void midi_clear_buffer(void) { if (!midi) - return; + return; - midi->midi_pos = 0; - midi->midi_status = 0x00; + midi->midi_pos = 0; + midi->midi_status = 0x00; midi->midi_cmd_pos = 0; midi->midi_cmd_len = 0; } - void midi_in_handler(int set, void (*msg)(void *p, uint8_t *msg, uint32_t len), int (*sysex)(void *p, uint8_t *buffer, uint32_t len, int abort), void *p) { midi_in_handler_t *temp = NULL, *next; if (set) { - /* Add MIDI IN handler. */ - if ((mih_first == NULL) && (mih_last != NULL)) - fatal("Last MIDI IN handler present with no first MIDI IN handler\n"); + /* Add MIDI IN handler. */ + if ((mih_first == NULL) && (mih_last != NULL)) + fatal("Last MIDI IN handler present with no first MIDI IN handler\n"); - if ((mih_first != NULL) && (mih_last == NULL)) - fatal("First MIDI IN handler present with no last MIDI IN handler\n"); + if ((mih_first != NULL) && (mih_last == NULL)) + fatal("First MIDI IN handler present with no last MIDI IN handler\n"); - temp = (midi_in_handler_t *) malloc(sizeof(midi_in_handler_t)); - memset(temp, 0, sizeof(midi_in_handler_t)); - temp->msg = msg; - temp->sysex = sysex; - temp->p = p; + temp = (midi_in_handler_t *) malloc(sizeof(midi_in_handler_t)); + memset(temp, 0, sizeof(midi_in_handler_t)); + temp->msg = msg; + temp->sysex = sysex; + temp->p = p; - if (mih_last == NULL) - mih_first = mih_last = temp; - else { - temp->prev = mih_last; - mih_last = temp; - } + if (mih_last == NULL) + mih_first = mih_last = temp; + else { + temp->prev = mih_last; + mih_last = temp; + } } else if ((mih_first != NULL) && (mih_last != NULL)) { - temp = mih_first; + temp = mih_first; - while(1) { - if (temp == NULL) - break; + while (1) { + if (temp == NULL) + break; - if ((temp->msg == msg) && (temp->sysex == sysex) && (temp->p == p)) { - if (temp->prev != NULL) - temp->prev->next = temp->next; + if ((temp->msg == msg) && (temp->sysex == sysex) && (temp->p == p)) { + if (temp->prev != NULL) + temp->prev->next = temp->next; - if (temp->next != NULL) - temp->next->prev = temp->prev; + if (temp->next != NULL) + temp->next->prev = temp->prev; - next = temp->next; + next = temp->next; - if (temp == mih_first) { - mih_first = NULL; - if (next == NULL) - mih_last = NULL; - } + if (temp == mih_first) { + mih_first = NULL; + if (next == NULL) + mih_last = NULL; + } - if (temp == mih_last) - mih_last = NULL; + if (temp == mih_last) + mih_last = NULL; - free(temp); - temp = next; + free(temp); + temp = next; - if (next == NULL) - break; - } - } + if (next == NULL) + break; + } + } } } - void midi_in_handlers_clear(void) { midi_in_handler_t *temp = mih_first, *next; - while(1) { - if (temp == NULL) - break; + while (1) { + if (temp == NULL) + break; - next = temp->next; - free(temp); + next = temp->next; + free(temp); - temp = next; + temp = next; - if (next == NULL) - break; + if (next == NULL) + break; } mih_first = mih_last = NULL; } - void midi_in_msg(uint8_t *msg, uint32_t len) { midi_in_handler_t *temp = mih_first; - while(1) { - if (temp == NULL) - break; + while (1) { + if (temp == NULL) + break; - if (temp->msg) - temp->msg(temp->p, msg, len); + if (temp->msg) + temp->msg(temp->p, msg, len); - temp = temp->next; + temp = temp->next; - if (temp == NULL) - break; + if (temp == NULL) + break; } } - static void midi_start_sysex(uint8_t *buffer, uint32_t len) { midi_in_handler_t *temp = mih_first; - while(1) { - if (temp == NULL) - break; + while (1) { + if (temp == NULL) + break; - temp->cnt = 5; - temp->buf = buffer; - temp->len = len; + temp->cnt = 5; + temp->buf = buffer; + temp->len = len; - temp = temp->next; + temp = temp->next; - if (temp == NULL) - break; + if (temp == NULL) + break; } } - /* Returns: - 0 = All handlers have returnd 0; - 1 = There are still handlers to go. */ + 0 = All handlers have returnd 0; + 1 = There are still handlers to go. */ static int midi_do_sysex(void) { midi_in_handler_t *temp = mih_first; - int ret, cnt_acc = 0; + int ret, cnt_acc = 0; - while(1) { - if (temp == NULL) - break; + while (1) { + if (temp == NULL) + break; - /* Do nothing if the handler has a zero count. */ - if ((temp->cnt > 0) || (temp->len > 0)) { - ret = 0; - if (temp->sysex) { - if (temp->cnt == 0) - ret = temp->sysex(temp->p, temp->buf, 0, 0); - else - ret = temp->sysex(temp->p, temp->buf, temp->len, 0); - } + /* Do nothing if the handler has a zero count. */ + if ((temp->cnt > 0) || (temp->len > 0)) { + ret = 0; + if (temp->sysex) { + if (temp->cnt == 0) + ret = temp->sysex(temp->p, temp->buf, 0, 0); + else + ret = temp->sysex(temp->p, temp->buf, temp->len, 0); + } - /* If count is 0 and length is 0, then this is just a finishing - call to temp->sysex(), so skip this entire block. */ - if (temp->cnt > 0) { - if (ret) { - /* Decrease or reset the counter. */ - if (temp->len == ret) - temp->cnt--; - else - temp->cnt = 5; + /* If count is 0 and length is 0, then this is just a finishing + call to temp->sysex(), so skip this entire block. */ + if (temp->cnt > 0) { + if (ret) { + /* Decrease or reset the counter. */ + if (temp->len == ret) + temp->cnt--; + else + temp->cnt = 5; - /* Advance the buffer pointer and remember the - remaining length. */ - temp->buf += (temp->len - ret); - temp->len = ret; - } else { - /* Set count to 0 so that this handler will be - ignored on the next interation. */ - temp->cnt = 0; + /* Advance the buffer pointer and remember the + remaining length. */ + temp->buf += (temp->len - ret); + temp->len = ret; + } else { + /* Set count to 0 so that this handler will be + ignored on the next interation. */ + temp->cnt = 0; - /* Reset the buffer pointer and length. */ - temp->buf = NULL; - temp->len = 0; - } + /* Reset the buffer pointer and length. */ + temp->buf = NULL; + temp->len = 0; + } - /* If the remaining count is above zero, add it to the - accumulator. */ - if (temp->cnt > 0) - cnt_acc |= temp->cnt; - } - } + /* If the remaining count is above zero, add it to the + accumulator. */ + if (temp->cnt > 0) + cnt_acc |= temp->cnt; + } + } - temp = temp->next; + temp = temp->next; - if (temp == NULL) - break; + if (temp == NULL) + break; } /* Return 0 if all handlers have returned 0 or all the counts are otherwise 0. */ if (cnt_acc == 0) - return 0; + return 0; else - return 1; + return 1; } - void midi_in_sysex(uint8_t *buffer, uint32_t len) { midi_start_sysex(buffer, len); while (1) { - /* This will return 0 if all theh handlers have either - timed out or otherwise indicated it is time to stop. */ - if (midi_do_sysex()) - plat_delay_ms(5); /* msec */ - else - break; + /* This will return 0 if all theh handlers have either + timed out or otherwise indicated it is time to stop. */ + if (midi_do_sysex()) + plat_delay_ms(5); /* msec */ + else + break; } } diff --git a/src/sound/midi_fluidsynth.c b/src/sound/midi_fluidsynth.c index 14093efb4..52d21ac47 100644 --- a/src/sound/midi_fluidsynth.c +++ b/src/sound/midi_fluidsynth.c @@ -1,566 +1,556 @@ /* some code borrowed from scummvm */ #ifdef USE_FLUIDSYNTH -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/config.h> -#include <86box/device.h> -#include <86box/plat.h> -#include <86box/plat_dynld.h> -#include <86box/ui.h> -#include <86box/midi.h> -#include <86box/sound.h> +# include +# include +# include +# include +# include +# include <86box/86box.h> +# include <86box/config.h> +# include <86box/device.h> +# include <86box/midi.h> +# include <86box/plat.h> +# include <86box/plat_dynld.h> +# include <86box/sound.h> +# include <86box/ui.h> -#define FLUID_CHORUS_DEFAULT_N 3 -#define FLUID_CHORUS_DEFAULT_LEVEL 2.0f -#define FLUID_CHORUS_DEFAULT_SPEED 0.3f -#define FLUID_CHORUS_DEFAULT_DEPTH 8.0f -#define FLUID_CHORUS_DEFAULT_TYPE FLUID_CHORUS_MOD_SINE - -#define RENDER_RATE 100 -#define BUFFER_SEGMENTS 10 +# define FLUID_CHORUS_DEFAULT_N 3 +# define FLUID_CHORUS_DEFAULT_LEVEL 2.0f +# define FLUID_CHORUS_DEFAULT_SPEED 0.3f +# define FLUID_CHORUS_DEFAULT_DEPTH 8.0f +# define FLUID_CHORUS_DEFAULT_TYPE FLUID_CHORUS_MOD_SINE +# define RENDER_RATE 100 +# define BUFFER_SEGMENTS 10 enum fluid_chorus_mod { - FLUID_CHORUS_MOD_SINE = 0, - FLUID_CHORUS_MOD_TRIANGLE = 1 + FLUID_CHORUS_MOD_SINE = 0, + FLUID_CHORUS_MOD_TRIANGLE = 1 }; enum fluid_interp { - FLUID_INTERP_NONE = 0, - FLUID_INTERP_LINEAR = 1, - FLUID_INTERP_DEFAULT = 4, - FLUID_INTERP_4THORDER = 4, - FLUID_INTERP_7THORDER = 7, - FLUID_INTERP_HIGHEST = 7 + FLUID_INTERP_NONE = 0, + FLUID_INTERP_LINEAR = 1, + FLUID_INTERP_DEFAULT = 4, + FLUID_INTERP_4THORDER = 4, + FLUID_INTERP_7THORDER = 7, + FLUID_INTERP_HIGHEST = 7 }; - extern void givealbuffer_midi(void *buf, uint32_t size); extern void al_set_midi(int freq, int buf_size); -static void *fluidsynth_handle; /* handle to FluidSynth DLL */ +static void *fluidsynth_handle; /* handle to FluidSynth DLL */ /* Pointers to the real functions. */ -static void * (*f_new_fluid_settings)(void); -static void (*f_delete_fluid_settings)(void *settings); -static int (*f_fluid_settings_setnum)(void *settings, const char *name, double val); -static int (*f_fluid_settings_getnum)(void *settings, const char *name, double *val); -static void * (*f_new_fluid_synth)(void *settings); -static int (*f_delete_fluid_synth)(void *synth); -static int (*f_fluid_synth_noteon)(void *synth, int chan, int key, int vel); -static int (*f_fluid_synth_noteoff)(void *synth, int chan, int key); -static int (*f_fluid_synth_cc)(void *synth, int chan, int ctrl, int val); -static int (*f_fluid_synth_sysex)(void *synth, const char *data, int len, char *response, int *response_len, int *handled, int dryrun); -static int (*f_fluid_synth_pitch_bend)(void *synth, int chan, int val); -static int (*f_fluid_synth_program_change)(void *synth, int chan, int program); -static int (*f_fluid_synth_sfload)(void *synth, const char *filename, int reset_presets); -static int (*f_fluid_synth_set_interp_method)(void *synth, int chan, int interp_method); -static void (*f_fluid_synth_set_reverb)(void *synth, double roomsize, double damping, double width, double level); -static void (*f_fluid_synth_set_reverb_on)(void *synth, int on); -static void (*f_fluid_synth_set_chorus)(void *synth, int nr, double level, double speed, double depth_ms, int type); -static void (*f_fluid_synth_set_chorus_on)(void *synth, int on); -static int (*f_fluid_synth_write_s16)(void *synth, int len, void *lout, int loff, int lincr, void *rout, int roff, int rincr); -static int (*f_fluid_synth_write_float)(void *synth, int len, void *lout, int loff, int lincr, void *rout, int roff, int rincr); -static char* (*f_fluid_version_str)(void); +// clang-format off +static void *(*f_new_fluid_settings)(void); +static void (*f_delete_fluid_settings)(void *settings); +static int (*f_fluid_settings_setnum)(void *settings, const char *name, double val); +static int (*f_fluid_settings_getnum)(void *settings, const char *name, double *val); +static void *(*f_new_fluid_synth)(void *settings); +static int (*f_delete_fluid_synth)(void *synth); +static int (*f_fluid_synth_noteon)(void *synth, int chan, int key, int vel); +static int (*f_fluid_synth_noteoff)(void *synth, int chan, int key); +static int (*f_fluid_synth_cc)(void *synth, int chan, int ctrl, int val); +static int (*f_fluid_synth_sysex)(void *synth, const char *data, int len, char *response, int *response_len, int *handled, int dryrun); +static int (*f_fluid_synth_pitch_bend)(void *synth, int chan, int val); +static int (*f_fluid_synth_program_change)(void *synth, int chan, int program); +static int (*f_fluid_synth_sfload)(void *synth, const char *filename, int reset_presets); +static int (*f_fluid_synth_set_interp_method)(void *synth, int chan, int interp_method); +static void (*f_fluid_synth_set_reverb)(void *synth, double roomsize, double damping, double width, double level); +static void (*f_fluid_synth_set_reverb_on)(void *synth, int on); +static void (*f_fluid_synth_set_chorus)(void *synth, int nr, double level, double speed, double depth_ms, int type); +static void (*f_fluid_synth_set_chorus_on)(void *synth, int on); +static int (*f_fluid_synth_write_s16)(void *synth, int len, void *lout, int loff, int lincr, void *rout, int roff, int rincr); +static int (*f_fluid_synth_write_float)(void *synth, int len, void *lout, int loff, int lincr, void *rout, int roff, int rincr); +static char *(*f_fluid_version_str)(void); +// clang-format on + static dllimp_t fluidsynth_imports[] = { - { "new_fluid_settings", &f_new_fluid_settings }, - { "delete_fluid_settings", &f_delete_fluid_settings }, - { "fluid_settings_setnum", &f_fluid_settings_setnum }, - { "fluid_settings_getnum", &f_fluid_settings_getnum }, - { "new_fluid_synth", &f_new_fluid_synth }, - { "delete_fluid_synth", &f_delete_fluid_synth }, - { "fluid_synth_noteon", &f_fluid_synth_noteon }, - { "fluid_synth_noteoff", &f_fluid_synth_noteoff }, - { "fluid_synth_cc", &f_fluid_synth_cc }, - { "fluid_synth_sysex", &f_fluid_synth_sysex }, - { "fluid_synth_pitch_bend", &f_fluid_synth_pitch_bend }, - { "fluid_synth_program_change", &f_fluid_synth_program_change }, - { "fluid_synth_sfload", &f_fluid_synth_sfload }, - { "fluid_synth_set_interp_method", &f_fluid_synth_set_interp_method }, - { "fluid_synth_set_reverb", &f_fluid_synth_set_reverb }, - { "fluid_synth_set_reverb_on", &f_fluid_synth_set_reverb_on }, - { "fluid_synth_set_chorus", &f_fluid_synth_set_chorus }, - { "fluid_synth_set_chorus_on", &f_fluid_synth_set_chorus_on }, - { "fluid_synth_write_s16", &f_fluid_synth_write_s16 }, - { "fluid_synth_write_float", &f_fluid_synth_write_float }, - { "fluid_version_str", &f_fluid_version_str }, - { NULL, NULL }, + // clang-format off + { "new_fluid_settings", &f_new_fluid_settings }, + { "delete_fluid_settings", &f_delete_fluid_settings }, + { "fluid_settings_setnum", &f_fluid_settings_setnum }, + { "fluid_settings_getnum", &f_fluid_settings_getnum }, + { "new_fluid_synth", &f_new_fluid_synth }, + { "delete_fluid_synth", &f_delete_fluid_synth }, + { "fluid_synth_noteon", &f_fluid_synth_noteon }, + { "fluid_synth_noteoff", &f_fluid_synth_noteoff }, + { "fluid_synth_cc", &f_fluid_synth_cc }, + { "fluid_synth_sysex", &f_fluid_synth_sysex }, + { "fluid_synth_pitch_bend", &f_fluid_synth_pitch_bend }, + { "fluid_synth_program_change", &f_fluid_synth_program_change }, + { "fluid_synth_sfload", &f_fluid_synth_sfload }, + { "fluid_synth_set_interp_method", &f_fluid_synth_set_interp_method }, + { "fluid_synth_set_reverb", &f_fluid_synth_set_reverb }, + { "fluid_synth_set_reverb_on", &f_fluid_synth_set_reverb_on }, + { "fluid_synth_set_chorus", &f_fluid_synth_set_chorus }, + { "fluid_synth_set_chorus_on", &f_fluid_synth_set_chorus_on }, + { "fluid_synth_write_s16", &f_fluid_synth_write_s16 }, + { "fluid_synth_write_float", &f_fluid_synth_write_float }, + { "fluid_version_str", &f_fluid_version_str }, + { NULL, NULL }, + // clang-format on }; +typedef struct fluidsynth { + void *settings; + void *synth; + int samplerate; + int sound_font; -typedef struct fluidsynth -{ - void* settings; - void* synth; - int samplerate; - int sound_font; + thread_t *thread_h; + event_t *event, *start_event; + int buf_size; + float *buffer; + int16_t *buffer_int16; + int midi_pos; - thread_t *thread_h; - event_t *event, *start_event; - int buf_size; - float* buffer; - int16_t* buffer_int16; - int midi_pos; - - int on; + int on; } fluidsynth_t; fluidsynth_t fsdev; -int fluidsynth_available(void) +int +fluidsynth_available(void) { - return 1; + return 1; } -void fluidsynth_poll(void) +void +fluidsynth_poll(void) { - fluidsynth_t* data = &fsdev; - data->midi_pos++; - if (data->midi_pos == 48000/RENDER_RATE) - { - data->midi_pos = 0; - thread_set_event(data->event); + fluidsynth_t *data = &fsdev; + data->midi_pos++; + if (data->midi_pos == 48000 / RENDER_RATE) { + data->midi_pos = 0; + thread_set_event(data->event); + } +} + +static void +fluidsynth_thread(void *param) +{ + fluidsynth_t *data = (fluidsynth_t *) param; + int buf_pos = 0; + int buf_size = data->buf_size / BUFFER_SEGMENTS; + + thread_set_event(data->start_event); + + while (data->on) { + thread_wait_event(data->event, -1); + thread_reset_event(data->event); + + if (sound_is_float) { + float *buf = (float *) ((uint8_t *) data->buffer + buf_pos); + memset(buf, 0, buf_size); + if (data->synth) + f_fluid_synth_write_float(data->synth, buf_size / (2 * sizeof(float)), buf, 0, 2, buf, 1, 2); + buf_pos += buf_size; + if (buf_pos >= data->buf_size) { + givealbuffer_midi(data->buffer, data->buf_size / sizeof(float)); + buf_pos = 0; + } + } else { + int16_t *buf = (int16_t *) ((uint8_t *) data->buffer_int16 + buf_pos); + memset(buf, 0, buf_size); + if (data->synth) + f_fluid_synth_write_s16(data->synth, buf_size / (2 * sizeof(int16_t)), buf, 0, 2, buf, 1, 2); + buf_pos += buf_size; + if (buf_pos >= data->buf_size) { + givealbuffer_midi(data->buffer_int16, data->buf_size / sizeof(int16_t)); + buf_pos = 0; + } } + } } -static void fluidsynth_thread(void *param) +void +fluidsynth_msg(uint8_t *msg) { - fluidsynth_t* data = (fluidsynth_t*)param; - int buf_pos = 0; - int buf_size = data->buf_size / BUFFER_SEGMENTS; + fluidsynth_t *data = &fsdev; - thread_set_event(data->start_event); + uint32_t val = *((uint32_t *) msg); - while (data->on) - { - thread_wait_event(data->event, -1); - thread_reset_event(data->event); + uint32_t param2 = (uint8_t) ((val >> 16) & 0xFF); + uint32_t param1 = (uint8_t) ((val >> 8) & 0xFF); + uint8_t cmd = (uint8_t) (val & 0xF0); + uint8_t chan = (uint8_t) (val & 0x0F); - if (sound_is_float) - { - float *buf = (float*)((uint8_t*)data->buffer + buf_pos); - memset(buf, 0, buf_size); - if (data->synth) - f_fluid_synth_write_float(data->synth, buf_size/(2 * sizeof(float)), buf, 0, 2, buf, 1, 2); - buf_pos += buf_size; - if (buf_pos >= data->buf_size) - { - givealbuffer_midi(data->buffer, data->buf_size / sizeof(float)); - buf_pos = 0; - } - } - else - { - int16_t *buf = (int16_t*)((uint8_t*)data->buffer_int16 + buf_pos); - memset(buf, 0, buf_size); - if (data->synth) - f_fluid_synth_write_s16(data->synth, buf_size/(2 * sizeof(int16_t)), buf, 0, 2, buf, 1, 2); - buf_pos += buf_size; - if (buf_pos >= data->buf_size) - { - givealbuffer_midi(data->buffer_int16, data->buf_size / sizeof(int16_t)); - buf_pos = 0; - } - } - } -} - -void fluidsynth_msg(uint8_t *msg) -{ - fluidsynth_t* data = &fsdev; - - uint32_t val = *((uint32_t*)msg); - - uint32_t param2 = (uint8_t) ((val >> 16) & 0xFF); - uint32_t param1 = (uint8_t) ((val >> 8) & 0xFF); - uint8_t cmd = (uint8_t) (val & 0xF0); - uint8_t chan = (uint8_t) (val & 0x0F); - - switch (cmd) { - case 0x80: /* Note Off */ - f_fluid_synth_noteoff(data->synth, chan, param1); - break; - case 0x90: /* Note On */ - f_fluid_synth_noteon(data->synth, chan, param1, param2); - break; - case 0xA0: /* Aftertouch */ - break; - case 0xB0: /* Control Change */ - f_fluid_synth_cc(data->synth, chan, param1, param2); - break; - case 0xC0: /* Program Change */ - f_fluid_synth_program_change(data->synth, chan, param1); - break; - case 0xD0: /* Channel Pressure */ - break; - case 0xE0: /* Pitch Bend */ - f_fluid_synth_pitch_bend(data->synth, chan, (param2 << 7) | param1); - break; - case 0xF0: /* SysEx */ - break; + switch (cmd) { + case 0x80: /* Note Off */ + f_fluid_synth_noteoff(data->synth, chan, param1); + break; + case 0x90: /* Note On */ + f_fluid_synth_noteon(data->synth, chan, param1, param2); + break; + case 0xA0: /* Aftertouch */ + break; + case 0xB0: /* Control Change */ + f_fluid_synth_cc(data->synth, chan, param1, param2); + break; + case 0xC0: /* Program Change */ + f_fluid_synth_program_change(data->synth, chan, param1); + break; + case 0xD0: /* Channel Pressure */ + break; + case 0xE0: /* Pitch Bend */ + f_fluid_synth_pitch_bend(data->synth, chan, (param2 << 7) | param1); + break; + case 0xF0: /* SysEx */ + break; default: - break; - } + break; + } } -void fluidsynth_sysex(uint8_t* data, unsigned int len) +void +fluidsynth_sysex(uint8_t *data, unsigned int len) { - fluidsynth_t* d = &fsdev; + fluidsynth_t *d = &fsdev; - f_fluid_synth_sysex(d->synth, (const char *) data, len, 0, 0, 0, 0); + f_fluid_synth_sysex(d->synth, (const char *) data, len, 0, 0, 0, 0); } -void* fluidsynth_init(const device_t *info) +void * +fluidsynth_init(const device_t *info) { - fluidsynth_t* data = &fsdev; - midi_device_t* dev; + fluidsynth_t *data = &fsdev; + midi_device_t *dev; - memset(data, 0, sizeof(fluidsynth_t)); + memset(data, 0, sizeof(fluidsynth_t)); - /* Try loading the DLL. */ -#ifdef _WIN32 -# if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - fluidsynth_handle = dynld_module("libfluidsynth.dll", fluidsynth_imports); -# else - fluidsynth_handle = dynld_module("libfluidsynth64.dll", fluidsynth_imports); -# endif -#elif defined __APPLE__ - fluidsynth_handle = dynld_module("libfluidsynth.dylib", fluidsynth_imports); -#else - fluidsynth_handle = dynld_module("libfluidsynth.so.3", fluidsynth_imports); - if (fluidsynth_handle == NULL) - fluidsynth_handle = dynld_module("libfluidsynth.so.2", fluidsynth_imports); -#endif - if (fluidsynth_handle == NULL) - { - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2080, (wchar_t *) IDS_2133); - return NULL; - } + /* Try loading the DLL. */ +# ifdef _WIN32 +# if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) + fluidsynth_handle = dynld_module("libfluidsynth.dll", fluidsynth_imports); +# else + fluidsynth_handle = dynld_module("libfluidsynth64.dll", fluidsynth_imports); +# endif +# elif defined __APPLE__ + fluidsynth_handle = dynld_module("libfluidsynth.dylib", fluidsynth_imports); +# else + fluidsynth_handle = dynld_module("libfluidsynth.so.3", fluidsynth_imports); + if (fluidsynth_handle == NULL) + fluidsynth_handle = dynld_module("libfluidsynth.so.2", fluidsynth_imports); +# endif + if (fluidsynth_handle == NULL) { + ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2080, (wchar_t *) IDS_2133); + return NULL; + } - data->settings = f_new_fluid_settings(); + data->settings = f_new_fluid_settings(); - f_fluid_settings_setnum(data->settings, "synth.sample-rate", 44100); - f_fluid_settings_setnum(data->settings, "synth.gain", device_get_config_int("output_gain")/100.0f); + f_fluid_settings_setnum(data->settings, "synth.sample-rate", 44100); + f_fluid_settings_setnum(data->settings, "synth.gain", device_get_config_int("output_gain") / 100.0f); - data->synth = f_new_fluid_synth(data->settings); + data->synth = f_new_fluid_synth(data->settings); - char* sound_font = (char *) device_get_config_string("sound_font"); - data->sound_font = f_fluid_synth_sfload(data->synth, sound_font, 1); + char *sound_font = (char *) device_get_config_string("sound_font"); + data->sound_font = f_fluid_synth_sfload(data->synth, sound_font, 1); - if (device_get_config_int("chorus")) - { - f_fluid_synth_set_chorus_on(data->synth, 1); + if (device_get_config_int("chorus")) { + f_fluid_synth_set_chorus_on(data->synth, 1); - int chorus_voices = device_get_config_int("chorus_voices"); - double chorus_level = device_get_config_int("chorus_level") / 100.0; - double chorus_speed = device_get_config_int("chorus_speed") / 100.0; - double chorus_depth = device_get_config_int("chorus_depth") / 10.0; + int chorus_voices = device_get_config_int("chorus_voices"); + double chorus_level = device_get_config_int("chorus_level") / 100.0; + double chorus_speed = device_get_config_int("chorus_speed") / 100.0; + double chorus_depth = device_get_config_int("chorus_depth") / 10.0; - int chorus_waveform = FLUID_CHORUS_MOD_SINE; - if (device_get_config_int("chorus_waveform") == 0) - chorus_waveform = FLUID_CHORUS_MOD_SINE; - else - chorus_waveform = FLUID_CHORUS_MOD_TRIANGLE; - - f_fluid_synth_set_chorus(data->synth, chorus_voices, chorus_level, chorus_speed, chorus_depth, chorus_waveform); - } + int chorus_waveform = FLUID_CHORUS_MOD_SINE; + if (device_get_config_int("chorus_waveform") == 0) + chorus_waveform = FLUID_CHORUS_MOD_SINE; else - f_fluid_synth_set_chorus_on(data->synth, 0); + chorus_waveform = FLUID_CHORUS_MOD_TRIANGLE; - if (device_get_config_int("reverb")) - { - f_fluid_synth_set_reverb_on(data->synth, 1); + f_fluid_synth_set_chorus(data->synth, chorus_voices, chorus_level, chorus_speed, chorus_depth, chorus_waveform); + } else + f_fluid_synth_set_chorus_on(data->synth, 0); - double reverb_room_size = device_get_config_int("reverb_room_size") / 100.0; - double reverb_damping = device_get_config_int("reverb_damping") / 100.0; - int reverb_width = device_get_config_int("reverb_width"); - double reverb_level = device_get_config_int("reverb_level") / 100.0; + if (device_get_config_int("reverb")) { + f_fluid_synth_set_reverb_on(data->synth, 1); - f_fluid_synth_set_reverb(data->synth, reverb_room_size, reverb_damping, reverb_width, reverb_level); - } - else - f_fluid_synth_set_reverb_on(data->synth, 0); + double reverb_room_size = device_get_config_int("reverb_room_size") / 100.0; + double reverb_damping = device_get_config_int("reverb_damping") / 100.0; + int reverb_width = device_get_config_int("reverb_width"); + double reverb_level = device_get_config_int("reverb_level") / 100.0; - int interpolation = device_get_config_int("interpolation"); - int fs_interpolation = FLUID_INTERP_4THORDER; + f_fluid_synth_set_reverb(data->synth, reverb_room_size, reverb_damping, reverb_width, reverb_level); + } else + f_fluid_synth_set_reverb_on(data->synth, 0); - if (interpolation == 0) - fs_interpolation = FLUID_INTERP_NONE; - else if (interpolation == 1) - fs_interpolation = FLUID_INTERP_LINEAR; - else if (interpolation == 2) - fs_interpolation = FLUID_INTERP_4THORDER; - else if (interpolation == 3) - fs_interpolation = FLUID_INTERP_7THORDER; + int interpolation = device_get_config_int("interpolation"); + int fs_interpolation = FLUID_INTERP_4THORDER; - f_fluid_synth_set_interp_method(data->synth, -1, fs_interpolation); + if (interpolation == 0) + fs_interpolation = FLUID_INTERP_NONE; + else if (interpolation == 1) + fs_interpolation = FLUID_INTERP_LINEAR; + else if (interpolation == 2) + fs_interpolation = FLUID_INTERP_4THORDER; + else if (interpolation == 3) + fs_interpolation = FLUID_INTERP_7THORDER; - double samplerate; - f_fluid_settings_getnum(data->settings, "synth.sample-rate", &samplerate); - data->samplerate = (int)samplerate; - if (sound_is_float) - { - data->buf_size = (data->samplerate/RENDER_RATE)*2*sizeof(float)*BUFFER_SEGMENTS; - data->buffer = malloc(data->buf_size); - data->buffer_int16 = NULL; - } - else - { - data->buf_size = (data->samplerate/RENDER_RATE)*2*sizeof(int16_t)*BUFFER_SEGMENTS; - data->buffer = NULL; - data->buffer_int16 = malloc(data->buf_size); - } + f_fluid_synth_set_interp_method(data->synth, -1, fs_interpolation); - al_set_midi(data->samplerate, data->buf_size); + double samplerate; + f_fluid_settings_getnum(data->settings, "synth.sample-rate", &samplerate); + data->samplerate = (int) samplerate; + if (sound_is_float) { + data->buf_size = (data->samplerate / RENDER_RATE) * 2 * sizeof(float) * BUFFER_SEGMENTS; + data->buffer = malloc(data->buf_size); + data->buffer_int16 = NULL; + } else { + data->buf_size = (data->samplerate / RENDER_RATE) * 2 * sizeof(int16_t) * BUFFER_SEGMENTS; + data->buffer = NULL; + data->buffer_int16 = malloc(data->buf_size); + } - dev = malloc(sizeof(midi_device_t)); - memset(dev, 0, sizeof(midi_device_t)); + al_set_midi(data->samplerate, data->buf_size); - dev->play_msg = fluidsynth_msg; - dev->play_sysex = fluidsynth_sysex; - dev->poll = fluidsynth_poll; + dev = malloc(sizeof(midi_device_t)); + memset(dev, 0, sizeof(midi_device_t)); - midi_init(dev); + dev->play_msg = fluidsynth_msg; + dev->play_sysex = fluidsynth_sysex; + dev->poll = fluidsynth_poll; - data->on = 1; + midi_init(dev); - data->start_event = thread_create_event(); + data->on = 1; - data->event = thread_create_event(); - data->thread_h = thread_create(fluidsynth_thread, data); + data->start_event = thread_create_event(); - thread_wait_event(data->start_event, -1); - thread_reset_event(data->start_event); + data->event = thread_create_event(); + data->thread_h = thread_create(fluidsynth_thread, data); - return dev; + thread_wait_event(data->start_event, -1); + thread_reset_event(data->start_event); + + return dev; } -void fluidsynth_close(void* p) +void +fluidsynth_close(void *p) { - if (!p) return; + if (!p) + return; - fluidsynth_t* data = &fsdev; + fluidsynth_t *data = &fsdev; - data->on = 0; - thread_set_event(data->event); - thread_wait(data->thread_h); + data->on = 0; + thread_set_event(data->event); + thread_wait(data->thread_h); - if (data->synth) { - f_delete_fluid_synth(data->synth); - data->synth = NULL; - } + if (data->synth) { + f_delete_fluid_synth(data->synth); + data->synth = NULL; + } - if (data->settings) { - f_delete_fluid_settings(data->settings); - data->settings = NULL; - } + if (data->settings) { + f_delete_fluid_settings(data->settings); + data->settings = NULL; + } - if (data->buffer) - { - free(data->buffer); - data->buffer = NULL; - } + if (data->buffer) { + free(data->buffer); + data->buffer = NULL; + } - if (data->buffer_int16) - { - free(data->buffer_int16); - data->buffer_int16 = NULL; - } + if (data->buffer_int16) { + free(data->buffer_int16); + data->buffer_int16 = NULL; + } - /* Unload the DLL if possible. */ - if (fluidsynth_handle != NULL) - { - dynld_close(fluidsynth_handle); - fluidsynth_handle = NULL; - } + /* Unload the DLL if possible. */ + if (fluidsynth_handle != NULL) { + dynld_close(fluidsynth_handle); + fluidsynth_handle = NULL; + } } -static const device_config_t fluidsynth_config[] = -{ +static const device_config_t fluidsynth_config[] = { + // clang-format off + { + .name = "sound_font", + .description = "Sound Font", + .type = CONFIG_FNAME, + .default_string = "", + .file_filter = "SF2 Sound Fonts (*.sf2)|*.sf2" + }, + { + .name = "output_gain", + .description = "Output Gain", + .type = CONFIG_SPINNER, + .spinner = { - .name = "sound_font", - .description = "Sound Font", - .type = CONFIG_FNAME, - .default_string = "", - .file_filter = "SF2 Sound Fonts (*.sf2)|*.sf2" + .min = 0, + .max = 100 }, + .default_int = 100 + }, + { + .name = "chorus", + .description = "Chorus", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .name = "chorus_voices", + .description = "Chorus Voices", + .type = CONFIG_SPINNER, + .spinner = { - .name = "output_gain", - .description = "Output Gain", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, - .max = 100 - }, - .default_int = 100 + .min = 0, + .max = 99 }, + .default_int = 3 + }, + { + .name = "chorus_level", + .description = "Chorus Level", + .type = CONFIG_SPINNER, + .spinner = { - .name = "chorus", - .description = "Chorus", - .type = CONFIG_BINARY, - .default_int = 0 + .min = 0, + .max = 100 }, + .default_int = 100 + }, + { + .name = "chorus_speed", + .description = "Chorus Speed", + .type = CONFIG_SPINNER, + .spinner = { - .name = "chorus_voices", - .description = "Chorus Voices", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, - .max = 99 - }, - .default_int = 3 + .min = 30, + .max = 500 }, + .default_int = 30 + }, + { + .name = "chorus_depth", + .description = "Chorus Depth", + .type = CONFIG_SPINNER, + .spinner = { - .name = "chorus_level", - .description = "Chorus Level", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, - .max = 100 - }, - .default_int = 100 + .min = 0, + .max = 210 }, + .default_int = 80 + }, + { + .name = "chorus_waveform", + .description = "Chorus Waveform", + .type = CONFIG_SELECTION, + .selection = { - .name = "chorus_speed", - .description = "Chorus Speed", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 30, - .max = 500 - }, - .default_int = 30 + { + .description = "Sine", + .value = 0 + }, + { + .description = "Triangle", + .value = 1 + } }, + .default_int = 0 + }, + { + .name = "reverb", + .description = "Reverb", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .name = "reverb_room_size", + .description = "Reverb Room Size", + .type = CONFIG_SPINNER, + .spinner = { - .name = "chorus_depth", - .description = "Chorus Depth", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, - .max = 210 - }, - .default_int = 80 + .min = 0, + .max = 120 }, + .default_int = 20 + }, + { + .name = "reverb_damping", + .description = "Reverb Damping", + .type = CONFIG_SPINNER, + .spinner = { - .name = "chorus_waveform", - .description = "Chorus Waveform", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Sine", - .value = 0 - }, - { - .description = "Triangle", - .value = 1 - } - }, - .default_int = 0 + .min = 0, + .max = 100 }, + .default_int = 0 + }, + { + .name = "reverb_width", + .description = "Reverb Width", + .type = CONFIG_SPINNER, + .spinner = { - .name = "reverb", - .description = "Reverb", - .type = CONFIG_BINARY, - .default_int = 0 + .min = 0, + .max = 100 }, + .default_int = 1 + }, + { + .name = "reverb_level", + .description = "Reverb Level", + .type = CONFIG_SPINNER, + .spinner = { - .name = "reverb_room_size", - .description = "Reverb Room Size", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, - .max = 120 - }, - .default_int = 20 + .min = 0, + .max = 100 }, + .default_int = 90 + }, + { + .name = "interpolation", + .description = "Interpolation Method", + .type = CONFIG_SELECTION, + .selection = { - .name = "reverb_damping", - .description = "Reverb Damping", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, - .max = 100 - }, - .default_int = 0 + { + .description = "None", + .value = 0 + }, + { + .description = "Linear", + .value = 1 + }, + { + .description = "4th Order", + .value = 2 + }, + { + .description = "7th Order", + .value = 3 + } }, - { - .name = "reverb_width", - .description = "Reverb Width", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, - .max = 100 - }, - .default_int = 1 - }, - { - .name = "reverb_level", - .description = "Reverb Level", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, - .max = 100 - }, - .default_int = 90 - }, - { - .name = "interpolation", - .description = "Interpolation Method", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "None", - .value = 0 - }, - { - .description = "Linear", - .value = 1 - }, - { - .description = "4th Order", - .value = 2 - }, - { - .description = "7th Order", - .value = 3 - } - }, - .default_int = 2 - }, - { - .type = -1 - } + .default_int = 2 + }, + { + .type = -1 + } + // clang-format on }; -const device_t fluidsynth_device = -{ - "FluidSynth", - "fluidsynth", - 0, - 0, - fluidsynth_init, - fluidsynth_close, - NULL, - { fluidsynth_available }, - NULL, - NULL, - fluidsynth_config +const device_t fluidsynth_device = { + "FluidSynth", + "fluidsynth", + 0, + 0, + fluidsynth_init, + fluidsynth_close, + NULL, + { fluidsynth_available }, + NULL, + NULL, + fluidsynth_config }; - -#endif /*USE_FLUIDSYNTH*/ +#endif /*USE_FLUIDSYNTH*/ diff --git a/src/sound/midi_mt32.c b/src/sound/midi_mt32.c index e1812a733..c0a0bc81a 100644 --- a/src/sound/midi_mt32.c +++ b/src/sound/midi_mt32.c @@ -1,18 +1,18 @@ -#include #include -#include +#include #include +#include #include -#include + #include <86box/86box.h> #include <86box/device.h> #include <86box/mem.h> -#include <86box/rom.h> -#include <86box/plat.h> -#include <86box/ui.h> -#include <86box/sound.h> #include <86box/midi.h> - +#include <86box/plat.h> +#include <86box/rom.h> +#include <86box/sound.h> +#include <86box/ui.h> +#include extern void givealbuffer_midi(void *buf, uint32_t size); extern void al_set_midi(int freq, int buf_size); @@ -20,375 +20,384 @@ extern void al_set_midi(int freq, int buf_size); static void display_mt32_message(void *instance_data, const char *message); static const mt32emu_report_handler_i_v0 handler_mt32_v0 = { - /** Returns the actual interface version ID */ - NULL, //mt32emu_report_handler_version (*getVersionID)(mt32emu_report_handler_i i); + /** Returns the actual interface version ID */ + NULL, // mt32emu_report_handler_version (*getVersionID)(mt32emu_report_handler_i i); - /** Callback for debug messages, in vprintf() format */ - NULL, //void (*printDebug)(void *instance_data, const char *fmt, va_list list); - /** Callbacks for reporting errors */ - NULL, //void (*onErrorControlROM)(void *instance_data); - NULL, //void (*onErrorPCMROM)(void *instance_data); - /** Callback for reporting about displaying a new custom message on LCD */ - display_mt32_message, //void (*showLCDMessage)(void *instance_data, const char *message); - /** Callback for reporting actual processing of a MIDI message */ - NULL, //void (*onMIDIMessagePlayed)(void *instance_data); - /** - * Callback for reporting an overflow of the input MIDI queue. - * Returns MT32EMU_BOOL_TRUE if a recovery action was taken - * and yet another attempt to enqueue the MIDI event is desired. - */ - NULL, //mt32emu_boolean (*onMIDIQueueOverflow)(void *instance_data); - /** - * Callback invoked when a System Realtime MIDI message is detected in functions - * mt32emu_parse_stream and mt32emu_play_short_message and the likes. - */ - NULL, //void (*onMIDISystemRealtime)(void *instance_data, mt32emu_bit8u system_realtime); - /** Callbacks for reporting system events */ - NULL, //void (*onDeviceReset)(void *instance_data); - NULL, //void (*onDeviceReconfig)(void *instance_data); - /** Callbacks for reporting changes of reverb settings */ - NULL, //void (*onNewReverbMode)(void *instance_data, mt32emu_bit8u mode); - NULL, //void (*onNewReverbTime)(void *instance_data, mt32emu_bit8u time); - NULL, //void (*onNewReverbLevel)(void *instance_data, mt32emu_bit8u level); - /** Callbacks for reporting various information */ - NULL, //void (*onPolyStateChanged)(void *instance_data, mt32emu_bit8u part_num); - NULL, //void (*onProgramChanged)(void *instance_data, mt32emu_bit8u part_num, const char *sound_group_name, const char *patch_name); + /** Callback for debug messages, in vprintf() format */ + NULL, // void (*printDebug)(void *instance_data, const char *fmt, va_list list); + /** Callbacks for reporting errors */ + NULL, // void (*onErrorControlROM)(void *instance_data); + NULL, // void (*onErrorPCMROM)(void *instance_data); + /** Callback for reporting about displaying a new custom message on LCD */ + display_mt32_message, // void (*showLCDMessage)(void *instance_data, const char *message); + /** Callback for reporting actual processing of a MIDI message */ + NULL, // void (*onMIDIMessagePlayed)(void *instance_data); + /** + * Callback for reporting an overflow of the input MIDI queue. + * Returns MT32EMU_BOOL_TRUE if a recovery action was taken + * and yet another attempt to enqueue the MIDI event is desired. + */ + NULL, // mt32emu_boolean (*onMIDIQueueOverflow)(void *instance_data); + /** + * Callback invoked when a System Realtime MIDI message is detected in functions + * mt32emu_parse_stream and mt32emu_play_short_message and the likes. + */ + NULL, // void (*onMIDISystemRealtime)(void *instance_data, mt32emu_bit8u system_realtime); + /** Callbacks for reporting system events */ + NULL, // void (*onDeviceReset)(void *instance_data); + NULL, // void (*onDeviceReconfig)(void *instance_data); + /** Callbacks for reporting changes of reverb settings */ + NULL, // void (*onNewReverbMode)(void *instance_data, mt32emu_bit8u mode); + NULL, // void (*onNewReverbTime)(void *instance_data, mt32emu_bit8u time); + NULL, // void (*onNewReverbLevel)(void *instance_data, mt32emu_bit8u level); + /** Callbacks for reporting various information */ + NULL, // void (*onPolyStateChanged)(void *instance_data, mt32emu_bit8u part_num); + NULL, // void (*onProgramChanged)(void *instance_data, mt32emu_bit8u part_num, const char *sound_group_name, const char *patch_name); }; /** Alternate report handler for Roland CM-32L */ static const mt32emu_report_handler_i_v0 handler_cm32l_v0 = { - /** Returns the actual interface version ID */ - NULL, //mt32emu_report_handler_version (*getVersionID)(mt32emu_report_handler_i i); + /** Returns the actual interface version ID */ + NULL, // mt32emu_report_handler_version (*getVersionID)(mt32emu_report_handler_i i); - /** Callback for debug messages, in vprintf() format */ - NULL, //void (*printDebug)(void *instance_data, const char *fmt, va_list list); - /** Callbacks for reporting errors */ - NULL, //void (*onErrorControlROM)(void *instance_data); - NULL, //void (*onErrorPCMROM)(void *instance_data); - /** Callback for reporting about displaying a new custom message on LCD */ - NULL, //void (*showLCDMessage)(void *instance_data, const char *message); - /** Callback for reporting actual processing of a MIDI message */ - NULL, //void (*onMIDIMessagePlayed)(void *instance_data); - /** - * Callback for reporting an overflow of the input MIDI queue. - * Returns MT32EMU_BOOL_TRUE if a recovery action was taken - * and yet another attempt to enqueue the MIDI event is desired. - */ - NULL, //mt32emu_boolean (*onMIDIQueueOverflow)(void *instance_data); - /** - * Callback invoked when a System Realtime MIDI message is detected in functions - * mt32emu_parse_stream and mt32emu_play_short_message and the likes. - */ - NULL, //void (*onMIDISystemRealtime)(void *instance_data, mt32emu_bit8u system_realtime); - /** Callbacks for reporting system events */ - NULL, //void (*onDeviceReset)(void *instance_data); - NULL, //void (*onDeviceReconfig)(void *instance_data); - /** Callbacks for reporting changes of reverb settings */ - NULL, //void (*onNewReverbMode)(void *instance_data, mt32emu_bit8u mode); - NULL, //void (*onNewReverbTime)(void *instance_data, mt32emu_bit8u time); - NULL, //void (*onNewReverbLevel)(void *instance_data, mt32emu_bit8u level); - /** Callbacks for reporting various information */ - NULL, //void (*onPolyStateChanged)(void *instance_data, mt32emu_bit8u part_num); - NULL, //void (*onProgramChanged)(void *instance_data, mt32emu_bit8u part_num, const char *sound_group_name, const char *patch_name); + /** Callback for debug messages, in vprintf() format */ + NULL, // void (*printDebug)(void *instance_data, const char *fmt, va_list list); + /** Callbacks for reporting errors */ + NULL, // void (*onErrorControlROM)(void *instance_data); + NULL, // void (*onErrorPCMROM)(void *instance_data); + /** Callback for reporting about displaying a new custom message on LCD */ + NULL, // void (*showLCDMessage)(void *instance_data, const char *message); + /** Callback for reporting actual processing of a MIDI message */ + NULL, // void (*onMIDIMessagePlayed)(void *instance_data); + /** + * Callback for reporting an overflow of the input MIDI queue. + * Returns MT32EMU_BOOL_TRUE if a recovery action was taken + * and yet another attempt to enqueue the MIDI event is desired. + */ + NULL, // mt32emu_boolean (*onMIDIQueueOverflow)(void *instance_data); + /** + * Callback invoked when a System Realtime MIDI message is detected in functions + * mt32emu_parse_stream and mt32emu_play_short_message and the likes. + */ + NULL, // void (*onMIDISystemRealtime)(void *instance_data, mt32emu_bit8u system_realtime); + /** Callbacks for reporting system events */ + NULL, // void (*onDeviceReset)(void *instance_data); + NULL, // void (*onDeviceReconfig)(void *instance_data); + /** Callbacks for reporting changes of reverb settings */ + NULL, // void (*onNewReverbMode)(void *instance_data, mt32emu_bit8u mode); + NULL, // void (*onNewReverbTime)(void *instance_data, mt32emu_bit8u time); + NULL, // void (*onNewReverbLevel)(void *instance_data, mt32emu_bit8u level); + /** Callbacks for reporting various information */ + NULL, // void (*onPolyStateChanged)(void *instance_data, mt32emu_bit8u part_num); + NULL, // void (*onProgramChanged)(void *instance_data, mt32emu_bit8u part_num, const char *sound_group_name, const char *patch_name); }; -static const mt32emu_report_handler_i handler_mt32 = { &handler_mt32_v0 }; +static const mt32emu_report_handler_i handler_mt32 = { &handler_mt32_v0 }; static const mt32emu_report_handler_i handler_cm32l = { &handler_cm32l_v0 }; -static mt32emu_context context = NULL; -static int roms_present[2] = {-1, -1}; +static mt32emu_context context = NULL; +static int roms_present[2] = { -1, -1 }; -mt32emu_return_code mt32_check(const char* func, mt32emu_return_code ret, mt32emu_return_code expected) +mt32emu_return_code +mt32_check(const char *func, mt32emu_return_code ret, mt32emu_return_code expected) { - if (ret != expected) - { - return 0; - } - return 1; + if (ret != expected) { + return 0; + } + return 1; } -int mt32_available() +int +mt32_available() { - if (roms_present[0] < 0) - roms_present[0] = (rom_present("roms/sound/mt32/MT32_CONTROL.ROM") && rom_present("roms/sound/mt32/MT32_PCM.ROM")); - return roms_present[0]; + if (roms_present[0] < 0) + roms_present[0] = (rom_present("roms/sound/mt32/MT32_CONTROL.ROM") && rom_present("roms/sound/mt32/MT32_PCM.ROM")); + return roms_present[0]; } -int cm32l_available() +int +cm32l_available() { - if (roms_present[1] < 0) - roms_present[1] = (rom_present("roms/sound/cm32l/CM32L_CONTROL.ROM") && rom_present("roms/sound/cm32l/CM32L_PCM.ROM")); - return roms_present[1]; + if (roms_present[1] < 0) + roms_present[1] = (rom_present("roms/sound/cm32l/CM32L_CONTROL.ROM") && rom_present("roms/sound/cm32l/CM32L_PCM.ROM")); + return roms_present[1]; } -static thread_t *thread_h = NULL; -static event_t *event = NULL; -static event_t *start_event = NULL; -static int mt32_on = 0; +static thread_t *thread_h = NULL; +static event_t *event = NULL; +static event_t *start_event = NULL; +static int mt32_on = 0; -#define RENDER_RATE 100 +#define RENDER_RATE 100 #define BUFFER_SEGMENTS 10 -static uint32_t samplerate = 44100; -static int buf_size = 0; -static float* buffer = NULL; -static int16_t* buffer_int16 = NULL; -static int midi_pos = 0; +static uint32_t samplerate = 44100; +static int buf_size = 0; +static float *buffer = NULL; +static int16_t *buffer_int16 = NULL; +static int midi_pos = 0; -static void display_mt32_message(void *instance_data, const char *message) +static void +display_mt32_message(void *instance_data, const char *message) { - int sz = 0; - char* ui_msg = NULL; + int sz = 0; + char *ui_msg = NULL; - sz = snprintf(NULL, 0, "MT-32: %s", message); + sz = snprintf(NULL, 0, "MT-32: %s", message); ui_msg = calloc(sz + 1, 1); - if (ui_msg) - { + if (ui_msg) { snprintf(ui_msg, sz, "MT-32: %s", message); ui_sb_mt32lcd(ui_msg); } } -void mt32_stream(float* stream, int len) +void +mt32_stream(float *stream, int len) { - if (context) mt32emu_render_float(context, stream, len); + if (context) + mt32emu_render_float(context, stream, len); } -void mt32_stream_int16(int16_t* stream, int len) +void +mt32_stream_int16(int16_t *stream, int len) { - if (context) mt32emu_render_bit16s(context, stream, len); + if (context) + mt32emu_render_bit16s(context, stream, len); } -void mt32_poll() +void +mt32_poll() { - midi_pos++; - if (midi_pos == 48000/RENDER_RATE) - { - midi_pos = 0; - thread_set_event(event); + midi_pos++; + if (midi_pos == 48000 / RENDER_RATE) { + midi_pos = 0; + thread_set_event(event); + } +} + +static void +mt32_thread(void *param) +{ + int buf_pos = 0; + int bsize = buf_size / BUFFER_SEGMENTS; + float *buf; + int16_t *buf16; + + thread_set_event(start_event); + + while (mt32_on) { + thread_wait_event(event, -1); + thread_reset_event(event); + + if (sound_is_float) { + buf = (float *) ((uint8_t *) buffer + buf_pos); + memset(buf, 0, bsize); + mt32_stream(buf, bsize / (2 * sizeof(float))); + buf_pos += bsize; + if (buf_pos >= buf_size) { + givealbuffer_midi(buffer, buf_size / sizeof(float)); + buf_pos = 0; + } + } else { + buf16 = (int16_t *) ((uint8_t *) buffer_int16 + buf_pos); + memset(buf16, 0, bsize); + mt32_stream_int16(buf16, bsize / (2 * sizeof(int16_t))); + buf_pos += bsize; + if (buf_pos >= buf_size) { + givealbuffer_midi(buffer_int16, buf_size / sizeof(int16_t)); + buf_pos = 0; + } } + } } -static void mt32_thread(void *param) +void +mt32_msg(uint8_t *val) { - int buf_pos = 0; - int bsize = buf_size / BUFFER_SEGMENTS; - float *buf; - int16_t *buf16; - - thread_set_event(start_event); - - while (mt32_on) - { - thread_wait_event(event, -1); - thread_reset_event(event); - - if (sound_is_float) - { - buf = (float *) ((uint8_t*)buffer + buf_pos); - memset(buf, 0, bsize); - mt32_stream(buf, bsize / (2 * sizeof(float))); - buf_pos += bsize; - if (buf_pos >= buf_size) - { - givealbuffer_midi(buffer, buf_size / sizeof(float)); - buf_pos = 0; - } - } - else - { - buf16 = (int16_t *) ((uint8_t*)buffer_int16 + buf_pos); - memset(buf16, 0, bsize); - mt32_stream_int16(buf16, bsize / (2 * sizeof(int16_t))); - buf_pos += bsize; - if (buf_pos >= buf_size) - { - givealbuffer_midi(buffer_int16, buf_size / sizeof(int16_t)); - buf_pos = 0; - } - } - } + if (context) + mt32_check("mt32emu_play_msg", mt32emu_play_msg(context, *(uint32_t *) val), MT32EMU_RC_OK); } -void mt32_msg(uint8_t* val) +void +mt32_sysex(uint8_t *data, unsigned int len) { - if (context) mt32_check("mt32emu_play_msg", mt32emu_play_msg(context, *(uint32_t*)val), MT32EMU_RC_OK); + if (context) + mt32_check("mt32emu_play_sysex", mt32emu_play_sysex(context, data, len), MT32EMU_RC_OK); } -void mt32_sysex(uint8_t* data, unsigned int len) +void * +mt32emu_init(char *control_rom, char *pcm_rom) { - if (context) mt32_check("mt32emu_play_sysex", mt32emu_play_sysex(context, data, len), MT32EMU_RC_OK); -} + midi_device_t *dev; + char fn[512]; -void* mt32emu_init(char *control_rom, char *pcm_rom) -{ - midi_device_t* dev; - char fn[512]; + context = mt32emu_create_context(strstr(control_rom, "CM32L_CONTROL.ROM") ? handler_cm32l : handler_mt32, NULL); - context = mt32emu_create_context(strstr(control_rom, "CM32L_CONTROL.ROM") ? handler_cm32l : handler_mt32, NULL); + if (!rom_getfile(control_rom, fn, 512)) + return 0; + if (!mt32_check("mt32emu_add_rom_file", mt32emu_add_rom_file(context, fn), MT32EMU_RC_ADDED_CONTROL_ROM)) + return 0; + if (!rom_getfile(pcm_rom, fn, 512)) + return 0; + if (!mt32_check("mt32emu_add_rom_file", mt32emu_add_rom_file(context, fn), MT32EMU_RC_ADDED_PCM_ROM)) + return 0; - if (!rom_getfile(control_rom, fn, 512)) return 0; - if (!mt32_check("mt32emu_add_rom_file", mt32emu_add_rom_file(context, fn), MT32EMU_RC_ADDED_CONTROL_ROM)) return 0; - if (!rom_getfile(pcm_rom, fn, 512)) return 0; - if (!mt32_check("mt32emu_add_rom_file", mt32emu_add_rom_file(context, fn), MT32EMU_RC_ADDED_PCM_ROM)) return 0; + if (!mt32_check("mt32emu_open_synth", mt32emu_open_synth(context), MT32EMU_RC_OK)) + return 0; - if (!mt32_check("mt32emu_open_synth", mt32emu_open_synth(context), MT32EMU_RC_OK)) return 0; - - samplerate = mt32emu_get_actual_stereo_output_samplerate(context); - /* buf_size = samplerate/RENDER_RATE*2; */ - if (sound_is_float) - { - buf_size = (samplerate/RENDER_RATE)*2*BUFFER_SEGMENTS*sizeof(float); - buffer = malloc(buf_size); - buffer_int16 = NULL; - } - else - { - buf_size = (samplerate/RENDER_RATE)*2*BUFFER_SEGMENTS*sizeof(int16_t); - buffer = NULL; - buffer_int16 = malloc(buf_size); - } - - mt32emu_set_output_gain(context, device_get_config_int("output_gain")/100.0f); - mt32emu_set_reverb_enabled(context, device_get_config_int("reverb")); - mt32emu_set_reverb_output_gain(context, device_get_config_int("reverb_output_gain")/100.0f); - mt32emu_set_reversed_stereo_enabled(context, device_get_config_int("reversed_stereo")); - mt32emu_set_nice_amp_ramp_enabled(context, device_get_config_int("nice_ramp")); - - al_set_midi(samplerate, buf_size); - - dev = malloc(sizeof(midi_device_t)); - memset(dev, 0, sizeof(midi_device_t)); - - dev->play_msg = mt32_msg; - dev->play_sysex = mt32_sysex; - dev->poll = mt32_poll; - - midi_init(dev); - - mt32_on = 1; - - start_event = thread_create_event(); - - event = thread_create_event(); - thread_h = thread_create(mt32_thread, 0); - - thread_wait_event(start_event, -1); - thread_reset_event(start_event); - - return dev; -} - -void *mt32_init(const device_t *info) -{ - return mt32emu_init("roms/sound/mt32/MT32_CONTROL.ROM", "roms/sound/mt32/MT32_PCM.ROM"); -} - -void *cm32l_init(const device_t *info) -{ - return mt32emu_init("roms/sound/cm32l/CM32L_CONTROL.ROM", "roms/sound/cm32l/CM32L_PCM.ROM"); -} - -void mt32_close(void* p) -{ - if (!p) return; - - mt32_on = 0; - thread_set_event(event); - thread_wait(thread_h); - - event = NULL; - start_event = NULL; - thread_h = NULL; - - if (context) { - mt32emu_close_synth(context); - mt32emu_free_context(context); - } - context = NULL; - - if (buffer) - free(buffer); - buffer = NULL; - - if (buffer_int16) - free(buffer_int16); + samplerate = mt32emu_get_actual_stereo_output_samplerate(context); + /* buf_size = samplerate/RENDER_RATE*2; */ + if (sound_is_float) { + buf_size = (samplerate / RENDER_RATE) * 2 * BUFFER_SEGMENTS * sizeof(float); + buffer = malloc(buf_size); buffer_int16 = NULL; + } else { + buf_size = (samplerate / RENDER_RATE) * 2 * BUFFER_SEGMENTS * sizeof(int16_t); + buffer = NULL; + buffer_int16 = malloc(buf_size); + } + + mt32emu_set_output_gain(context, device_get_config_int("output_gain") / 100.0f); + mt32emu_set_reverb_enabled(context, device_get_config_int("reverb")); + mt32emu_set_reverb_output_gain(context, device_get_config_int("reverb_output_gain") / 100.0f); + mt32emu_set_reversed_stereo_enabled(context, device_get_config_int("reversed_stereo")); + mt32emu_set_nice_amp_ramp_enabled(context, device_get_config_int("nice_ramp")); + + al_set_midi(samplerate, buf_size); + + dev = malloc(sizeof(midi_device_t)); + memset(dev, 0, sizeof(midi_device_t)); + + dev->play_msg = mt32_msg; + dev->play_sysex = mt32_sysex; + dev->poll = mt32_poll; + + midi_init(dev); + + mt32_on = 1; + + start_event = thread_create_event(); + + event = thread_create_event(); + thread_h = thread_create(mt32_thread, 0); + + thread_wait_event(start_event, -1); + thread_reset_event(start_event); + + return dev; } -static const device_config_t mt32_config[] = +void * +mt32_init(const device_t *info) { - { - .name = "output_gain", - .description = "Output Gain", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, - .max = 100 - }, - .default_int = 100 + return mt32emu_init("roms/sound/mt32/MT32_CONTROL.ROM", "roms/sound/mt32/MT32_PCM.ROM"); +} + +void * +cm32l_init(const device_t *info) +{ + return mt32emu_init("roms/sound/cm32l/CM32L_CONTROL.ROM", "roms/sound/cm32l/CM32L_PCM.ROM"); +} + +void +mt32_close(void *p) +{ + if (!p) + return; + + mt32_on = 0; + thread_set_event(event); + thread_wait(thread_h); + + event = NULL; + start_event = NULL; + thread_h = NULL; + + if (context) { + mt32emu_close_synth(context); + mt32emu_free_context(context); + } + context = NULL; + + if (buffer) + free(buffer); + buffer = NULL; + + if (buffer_int16) + free(buffer_int16); + buffer_int16 = NULL; +} + +static const device_config_t mt32_config[] = { +// clang-format off + { + .name = "output_gain", + .description = "Output Gain", + .type = CONFIG_SPINNER, + .spinner = { + .min = 0, + .max = 100 }, - { - .name = "reverb", - .description = "Reverb", - .type = CONFIG_BINARY, - .default_int = 1 + .default_int = 100 + }, + { + .name = "reverb", + .description = "Reverb", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + .name = "reverb_output_gain", + .description = "Reverb Output Gain", + .type = CONFIG_SPINNER, + .spinner = { + .min = 0, + .max = 100 }, - { - .name = "reverb_output_gain", - .description = "Reverb Output Gain", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, - .max = 100 - }, - .default_int = 100 - }, - { - .name = "reversed_stereo", - .description = "Reversed stereo", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "nice_ramp", - .description = "Nice ramp", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .type = -1 - } + .default_int = 100 + }, + { + .name = "reversed_stereo", + .description = "Reversed stereo", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .name = "nice_ramp", + .description = "Nice ramp", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + .type = -1 + } +// clang-format on }; -const device_t mt32_device = -{ - "Roland MT-32 Emulation", - "mt32", - 0, - 0, - mt32_init, - mt32_close, - NULL, - { mt32_available }, - NULL, - NULL, - mt32_config +const device_t mt32_device = { + "Roland MT-32 Emulation", + "mt32", + 0, + 0, + mt32_init, + mt32_close, + NULL, + { mt32_available }, + NULL, + NULL, + mt32_config }; -const device_t cm32l_device = -{ - "Roland CM-32L Emulation", - "cm32l", - 0, - 0, - cm32l_init, - mt32_close, - NULL, - { cm32l_available }, - NULL, - NULL, - mt32_config +const device_t cm32l_device = { + "Roland CM-32L Emulation", + "cm32l", + 0, + 0, + cm32l_init, + mt32_close, + NULL, + { cm32l_available }, + NULL, + NULL, + mt32_config }; diff --git a/src/sound/midi_rtmidi.cpp b/src/sound/midi_rtmidi.cpp index ec943a43f..e4c292ee9 100644 --- a/src/sound/midi_rtmidi.cpp +++ b/src/sound/midi_rtmidi.cpp @@ -1,17 +1,17 @@ /* - * 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. * - * MIDI backend implemented using the RtMidi library. + * MIDI backend implemented using the RtMidi library. * - * Author: Cacodemon345, - * Miran Grca, - * Copyright 2021 Cacodemon345. - * Copyright 2021 Miran Grca. + * Author: Cacodemon345, + * Miran Grca, + * Copyright 2021 Cacodemon345. + * Copyright 2021 Miran Grca. */ #if defined __has_include # if __has_include () @@ -36,10 +36,10 @@ extern "C" #include <86box/config.h> -static RtMidiOut * midiout = nullptr; -static RtMidiIn * midiin = nullptr; -static int midi_out_id = 0, midi_in_id = 0; -static const int midi_lengths[8] = {3, 3, 3, 3, 2, 2, 3, 1}; +static RtMidiOut * midiout = nullptr; +static RtMidiIn * midiin = nullptr; +static int midi_out_id = 0, midi_in_id = 0; +static const int midi_lengths[8] = {3, 3, 3, 3, 2, 2, 3, 1}; int @@ -53,7 +53,7 @@ void rtmidi_play_msg(uint8_t *msg) { if (midiout) - midiout->sendMessage(msg, midi_lengths[(msg[0] >> 4) & 7]); + midiout->sendMessage(msg, midi_lengths[(msg[0] >> 4) & 7]); } @@ -61,7 +61,7 @@ void rtmidi_play_sysex(uint8_t *sysex, unsigned int len) { if (midiout) - midiout->sendMessage(sysex, len); + midiout->sendMessage(sysex, len); } @@ -76,27 +76,27 @@ rtmidi_init(const device_t *info) dev->write = rtmidi_write; try { - if (!midiout) midiout = new RtMidiOut; + if (!midiout) midiout = new RtMidiOut; } catch (RtMidiError& error) { - pclog("Failed to initialize MIDI output: %s\n", error.getMessage().c_str()); - return nullptr; + pclog("Failed to initialize MIDI output: %s\n", error.getMessage().c_str()); + return nullptr; } midi_out_id = config_get_int((char*)SYSTEM_MIDI_NAME, (char*)"midi", 0); try { - midiout->openPort(midi_out_id); + midiout->openPort(midi_out_id); } catch (RtMidiError& error) { - pclog("Fallback to default MIDI output port: %s\n", error.getMessage().c_str()); + pclog("Fallback to default MIDI output port: %s\n", error.getMessage().c_str()); - try { - midiout->openPort(0); - } catch (RtMidiError& error) { - pclog("Failed to initialize MIDI output: %s\n", error.getMessage().c_str()); - delete midiout; - midiout = nullptr; - return nullptr; - } + try { + midiout->openPort(0); + } catch (RtMidiError& error) { + pclog("Failed to initialize MIDI output: %s\n", error.getMessage().c_str()); + delete midiout; + midiout = nullptr; + return nullptr; + } } midi_init(dev); @@ -109,7 +109,7 @@ void rtmidi_close(void *p) { if (!midiout) - return; + return; midiout->closePort(); @@ -124,11 +124,11 @@ int rtmidi_get_num_devs(void) { if (!midiout) { - try { - midiout = new RtMidiOut; - } catch (RtMidiError& error) { - pclog("Failed to initialize MIDI output: %s\n", error.getMessage().c_str()); - } + try { + midiout = new RtMidiOut; + } catch (RtMidiError& error) { + pclog("Failed to initialize MIDI output: %s\n", error.getMessage().c_str()); + } } return midiout ? midiout->getPortCount() : 0; @@ -148,7 +148,7 @@ rtmidi_input_callback(double timeStamp, std::vector *message, voi if (message->front() == 0xF0) midi_in_sysex(message->data(), message->size()); else - midi_in_msg(message->data(), message->size()); + midi_in_msg(message->data(), message->size()); } @@ -159,28 +159,28 @@ rtmidi_input_init(const device_t *info) memset(dev, 0, sizeof(midi_device_t)); try { - if (!midiin) - midiin = new RtMidiIn; + if (!midiin) + midiin = new RtMidiIn; } catch (RtMidiError& error) { - pclog("Failed to initialize MIDI input: %s\n", error.getMessage().c_str()); - return nullptr; + pclog("Failed to initialize MIDI input: %s\n", error.getMessage().c_str()); + return nullptr; } midi_in_id = config_get_int((char*)MIDI_INPUT_NAME, (char*)"midi_input", 0); try { - midiin->openPort(midi_in_id); + midiin->openPort(midi_in_id); } catch (RtMidiError& error) { - pclog("Fallback to default MIDI input port: %s\n", error.getMessage().c_str()); + pclog("Fallback to default MIDI input port: %s\n", error.getMessage().c_str()); - try { - midiin->openPort(0); - } catch (RtMidiError& error) { - pclog("Failed to initialize MIDI input: %s\n", error.getMessage().c_str()); - delete midiin; - midiin = nullptr; - return nullptr; - } + try { + midiin->openPort(0); + } catch (RtMidiError& error) { + pclog("Failed to initialize MIDI input: %s\n", error.getMessage().c_str()); + delete midiin; + midiin = nullptr; + return nullptr; + } } midiin->setCallback(&rtmidi_input_callback); @@ -215,11 +215,11 @@ int rtmidi_in_get_num_devs(void) { if (!midiin) { - try { - midiin = new RtMidiIn; - } catch (RtMidiError& error) { - pclog("Failed to initialize MIDI input: %s\n", error.getMessage().c_str()); - } + try { + midiin = new RtMidiIn; + } catch (RtMidiError& error) { + pclog("Failed to initialize MIDI input: %s\n", error.getMessage().c_str()); + } } return midiin ? midiin->getPortCount() : 0; @@ -235,29 +235,29 @@ rtmidi_in_get_dev_name(int num, char *s) static const device_config_t system_midi_config[] = { { - "midi", "MIDI out device", CONFIG_MIDI_OUT, "", 0 + "midi", "MIDI out device", CONFIG_MIDI_OUT, "", 0 }, { - "", "", -1 + "", "", -1 } }; static const device_config_t midi_input_config[] = { { - "midi_input", "MIDI in device", CONFIG_MIDI_IN, "", 0 + "midi_input", "MIDI in device", CONFIG_MIDI_IN, "", 0 }, { - "realtime", "MIDI Real time", CONFIG_BINARY, "", 0 + "realtime", "MIDI Real time", CONFIG_BINARY, "", 0 }, { - "thruchan", "MIDI Thru", CONFIG_BINARY, "", 1 + "thruchan", "MIDI Thru", CONFIG_BINARY, "", 1 }, { - "clockout", "MIDI Clockout", CONFIG_BINARY, "", 1 + "clockout", "MIDI Clockout", CONFIG_BINARY, "", 1 }, { - "", "", -1 + "", "", -1 } }; diff --git a/src/sound/openal.c b/src/sound/openal.c index 37ee211cd..a570e070d 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -1,109 +1,105 @@ /* - * 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. * - * Interface to the OpenAL sound processing library. + * Interface to the OpenAL sound processing library. * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Sarah Walker, + * Miran Grca, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. */ #include -#include #include -#include +#include #include +#include #include -# undef AL_API -# undef ALC_API -# define AL_LIBTYPE_STATIC -# define ALC_LIBTYPE_STATIC -# include "AL/al.h" -# include "AL/alc.h" -# include "AL/alext.h" +#undef AL_API +#undef ALC_API +#define AL_LIBTYPE_STATIC +#define ALC_LIBTYPE_STATIC + +#include "AL/al.h" +#include "AL/alc.h" +#include "AL/alext.h" #include <86box/86box.h> -#include <86box/sound.h> #include <86box/midi.h> +#include <86box/sound.h> +#define FREQ 48000 +#define BUFLEN SOUNDBUFLEN -#define FREQ 48000 -#define BUFLEN SOUNDBUFLEN +ALuint buffers[4]; /* front and back buffers */ +ALuint buffers_cd[4]; /* front and back buffers */ +ALuint buffers_midi[4]; /* front and back buffers */ +static ALuint source[3]; /* audio source */ - -ALuint buffers[4]; /* front and back buffers */ -ALuint buffers_cd[4]; /* front and back buffers */ -ALuint buffers_midi[4]; /* front and back buffers */ -static ALuint source[3]; /* audio source */ - - -static int midi_freq = 44100; -static int midi_buf_size = 4410; -static int initialized = 0; -static int sources = 2; +static int midi_freq = 44100; +static int midi_buf_size = 4410; +static int initialized = 0; +static int sources = 2; static ALCcontext *Context; -static ALCdevice *Device; +static ALCdevice *Device; void al_set_midi(int freq, int buf_size) { - midi_freq = freq; + midi_freq = freq; midi_buf_size = buf_size; } - void closeal(void); -ALvoid alutInit(ALint *argc,ALbyte **argv) +ALvoid +alutInit(ALint *argc, ALbyte **argv) { /* Open device */ - Device = alcOpenDevice((ALCchar *)""); + Device = alcOpenDevice((ALCchar *) ""); if (Device != NULL) { - /* Create context(s) */ - Context = alcCreateContext(Device, NULL); - if (Context != NULL) { - /* Set active context */ - alcMakeContextCurrent(Context); - } + /* Create context(s) */ + Context = alcCreateContext(Device, NULL); + if (Context != NULL) { + /* Set active context */ + alcMakeContextCurrent(Context); + } } } - ALvoid alutExit(ALvoid) { if (Context != NULL) { - /* Disable context */ - alcMakeContextCurrent(NULL); + /* Disable context */ + alcMakeContextCurrent(NULL); - /* Release context(s) */ - alcDestroyContext(Context); + /* Release context(s) */ + alcDestroyContext(Context); - if (Device != NULL) { - /* Close device */ - alcCloseDevice(Device); - } + if (Device != NULL) { + /* Close device */ + alcCloseDevice(Device); + } } } - void closeal(void) { if (!initialized) - return; + return; alSourceStopv(sources, source); alDeleteSources(sources, source); if (sources == 3) - alDeleteBuffers(4, buffers_midi); + alDeleteBuffers(4, buffers_midi); alDeleteBuffers(4, buffers_cd); alDeleteBuffers(4, buffers); @@ -112,168 +108,163 @@ closeal(void) initialized = 0; } - void inital(void) { - float *buf = NULL, *cd_buf = NULL, *midi_buf = NULL; + float *buf = NULL, *cd_buf = NULL, *midi_buf = NULL; int16_t *buf_int16 = NULL, *cd_buf_int16 = NULL, *midi_buf_int16 = NULL; - int c; + int c; char *mdn; - int init_midi = 0; + int init_midi = 0; if (initialized) - return; + return; alutInit(0, 0); atexit(closeal); mdn = midi_device_get_internal_name(midi_device_current); if (strcmp(mdn, "none") && strcmp(mdn, SYSTEM_MIDI_INTERNAL_NAME)) - init_midi = 1; /* If the device is neither none, nor system MIDI, initialize the - MIDI buffer and source, otherwise, do not. */ + init_midi = 1; /* If the device is neither none, nor system MIDI, initialize the + MIDI buffer and source, otherwise, do not. */ sources = 2 + !!init_midi; if (sound_is_float) { - buf = (float *) malloc((BUFLEN << 1) * sizeof(float)); - cd_buf = (float *) malloc((CD_BUFLEN << 1) * sizeof(float)); - if (init_midi) - midi_buf = (float *) malloc(midi_buf_size * sizeof(float)); + buf = (float *) malloc((BUFLEN << 1) * sizeof(float)); + cd_buf = (float *) malloc((CD_BUFLEN << 1) * sizeof(float)); + if (init_midi) + midi_buf = (float *) malloc(midi_buf_size * sizeof(float)); } else { - buf_int16 = (int16_t *) malloc((BUFLEN << 1) * sizeof(int16_t)); - cd_buf_int16 = (int16_t *) malloc((CD_BUFLEN << 1) * sizeof(int16_t)); - if (init_midi) - midi_buf_int16 = (int16_t *) malloc(midi_buf_size * sizeof(int16_t)); + buf_int16 = (int16_t *) malloc((BUFLEN << 1) * sizeof(int16_t)); + cd_buf_int16 = (int16_t *) malloc((CD_BUFLEN << 1) * sizeof(int16_t)); + if (init_midi) + midi_buf_int16 = (int16_t *) malloc(midi_buf_size * sizeof(int16_t)); } alGenBuffers(4, buffers); alGenBuffers(4, buffers_cd); if (init_midi) - alGenBuffers(4, buffers_midi); + alGenBuffers(4, buffers_midi); if (init_midi) - alGenSources(3, source); + alGenSources(3, source); else - alGenSources(2, source); + alGenSources(2, source); - alSource3f(source[0], AL_POSITION, 0.0, 0.0, 0.0); - alSource3f(source[0], AL_VELOCITY, 0.0, 0.0, 0.0); - alSource3f(source[0], AL_DIRECTION, 0.0, 0.0, 0.0); - alSourcef (source[0], AL_ROLLOFF_FACTOR, 0.0 ); - alSourcei (source[0], AL_SOURCE_RELATIVE, AL_TRUE ); - alSource3f(source[1], AL_POSITION, 0.0, 0.0, 0.0); - alSource3f(source[1], AL_VELOCITY, 0.0, 0.0, 0.0); - alSource3f(source[1], AL_DIRECTION, 0.0, 0.0, 0.0); - alSourcef (source[1], AL_ROLLOFF_FACTOR, 0.0 ); - alSourcei (source[1], AL_SOURCE_RELATIVE, AL_TRUE ); + alSource3f(source[0], AL_POSITION, 0.0, 0.0, 0.0); + alSource3f(source[0], AL_VELOCITY, 0.0, 0.0, 0.0); + alSource3f(source[0], AL_DIRECTION, 0.0, 0.0, 0.0); + alSourcef(source[0], AL_ROLLOFF_FACTOR, 0.0); + alSourcei(source[0], AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f(source[1], AL_POSITION, 0.0, 0.0, 0.0); + alSource3f(source[1], AL_VELOCITY, 0.0, 0.0, 0.0); + alSource3f(source[1], AL_DIRECTION, 0.0, 0.0, 0.0); + alSourcef(source[1], AL_ROLLOFF_FACTOR, 0.0); + alSourcei(source[1], AL_SOURCE_RELATIVE, AL_TRUE); if (init_midi) { - alSource3f(source[2], AL_POSITION, 0.0, 0.0, 0.0); - alSource3f(source[2], AL_VELOCITY, 0.0, 0.0, 0.0); - alSource3f(source[2], AL_DIRECTION, 0.0, 0.0, 0.0); - alSourcef (source[2], AL_ROLLOFF_FACTOR, 0.0 ); - alSourcei (source[2], AL_SOURCE_RELATIVE, AL_TRUE ); + alSource3f(source[2], AL_POSITION, 0.0, 0.0, 0.0); + alSource3f(source[2], AL_VELOCITY, 0.0, 0.0, 0.0); + alSource3f(source[2], AL_DIRECTION, 0.0, 0.0, 0.0); + alSourcef(source[2], AL_ROLLOFF_FACTOR, 0.0); + alSourcei(source[2], AL_SOURCE_RELATIVE, AL_TRUE); } if (sound_is_float) { - memset(buf,0,BUFLEN*2*sizeof(float)); - memset(cd_buf,0,BUFLEN*2*sizeof(float)); - if (init_midi) - memset(midi_buf,0,midi_buf_size*sizeof(float)); + memset(buf, 0, BUFLEN * 2 * sizeof(float)); + memset(cd_buf, 0, BUFLEN * 2 * sizeof(float)); + if (init_midi) + memset(midi_buf, 0, midi_buf_size * sizeof(float)); } else { - memset(buf_int16,0,BUFLEN*2*sizeof(int16_t)); - memset(cd_buf_int16,0,BUFLEN*2*sizeof(int16_t)); - if (init_midi) - memset(midi_buf_int16,0,midi_buf_size*sizeof(int16_t)); + memset(buf_int16, 0, BUFLEN * 2 * sizeof(int16_t)); + memset(cd_buf_int16, 0, BUFLEN * 2 * sizeof(int16_t)); + if (init_midi) + memset(midi_buf_int16, 0, midi_buf_size * sizeof(int16_t)); } - for (c=0; c<4; c++) { - if (sound_is_float) { - alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN*2*sizeof(float), FREQ); - alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, cd_buf, CD_BUFLEN*2*sizeof(float), CD_FREQ); - if (init_midi) - alBufferData(buffers_midi[c], AL_FORMAT_STEREO_FLOAT32, midi_buf, midi_buf_size*sizeof(float), midi_freq); - } else { - alBufferData(buffers[c], AL_FORMAT_STEREO16, buf_int16, BUFLEN*2*sizeof(int16_t), FREQ); - alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, cd_buf_int16, CD_BUFLEN*2*sizeof(int16_t), CD_FREQ); - if (init_midi) - alBufferData(buffers_midi[c], AL_FORMAT_STEREO16, midi_buf_int16, midi_buf_size*sizeof(int16_t), midi_freq); - } + for (c = 0; c < 4; c++) { + if (sound_is_float) { + alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN * 2 * sizeof(float), FREQ); + alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, cd_buf, CD_BUFLEN * 2 * sizeof(float), CD_FREQ); + if (init_midi) + alBufferData(buffers_midi[c], AL_FORMAT_STEREO_FLOAT32, midi_buf, midi_buf_size * sizeof(float), midi_freq); + } else { + alBufferData(buffers[c], AL_FORMAT_STEREO16, buf_int16, BUFLEN * 2 * sizeof(int16_t), FREQ); + alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, cd_buf_int16, CD_BUFLEN * 2 * sizeof(int16_t), CD_FREQ); + if (init_midi) + alBufferData(buffers_midi[c], AL_FORMAT_STEREO16, midi_buf_int16, midi_buf_size * sizeof(int16_t), midi_freq); + } } alSourceQueueBuffers(source[0], 4, buffers); alSourceQueueBuffers(source[1], 4, buffers_cd); if (init_midi) - alSourceQueueBuffers(source[2], 4, buffers_midi); + alSourceQueueBuffers(source[2], 4, buffers_midi); alSourcePlay(source[0]); alSourcePlay(source[1]); if (init_midi) - alSourcePlay(source[2]); + alSourcePlay(source[2]); if (sound_is_float) { - if (init_midi) - free(midi_buf); - free(cd_buf); - free(buf); + if (init_midi) + free(midi_buf); + free(cd_buf); + free(buf); } else { - if (init_midi) - free(midi_buf_int16); - free(cd_buf_int16); - free(buf_int16); + if (init_midi) + free(midi_buf_int16); + free(cd_buf_int16); + free(buf_int16); } initialized = 1; } - void givealbuffer_common(void *buf, uint8_t src, int size, int freq) { - int processed; - int state; + int processed; + int state; ALuint buffer; double gain; if (!initialized) - return; + return; alGetSourcei(source[src], AL_SOURCE_STATE, &state); if (state == 0x1014) { - alSourcePlay(source[src]); + alSourcePlay(source[src]); } alGetSourcei(source[src], AL_BUFFERS_PROCESSED, &processed); if (processed >= 1) { - gain = pow(10.0, (double)sound_gain / 20.0); - alListenerf(AL_GAIN, gain); + gain = pow(10.0, (double) sound_gain / 20.0); + alListenerf(AL_GAIN, gain); - alSourceUnqueueBuffers(source[src], 1, &buffer); + alSourceUnqueueBuffers(source[src], 1, &buffer); - if (sound_is_float) - alBufferData(buffer, AL_FORMAT_STEREO_FLOAT32, buf, size * sizeof(float), freq); - else - alBufferData(buffer, AL_FORMAT_STEREO16, buf, size * sizeof(int16_t), freq); + if (sound_is_float) + alBufferData(buffer, AL_FORMAT_STEREO_FLOAT32, buf, size * sizeof(float), freq); + else + alBufferData(buffer, AL_FORMAT_STEREO16, buf, size * sizeof(int16_t), freq); - alSourceQueueBuffers(source[src], 1, &buffer); + alSourceQueueBuffers(source[src], 1, &buffer); } } - void givealbuffer(void *buf) { givealbuffer_common(buf, 0, BUFLEN << 1, FREQ); } - void givealbuffer_cd(void *buf) { givealbuffer_common(buf, 1, CD_BUFLEN << 1, CD_FREQ); } - void givealbuffer_midi(void *buf, uint32_t size) { diff --git a/src/sound/snd_ac97_codec.c b/src/sound/snd_ac97_codec.c index dbccb2c9f..d59db5656 100644 --- a/src/sound/snd_ac97_codec.c +++ b/src/sound/snd_ac97_codec.c @@ -1,110 +1,111 @@ /* - * 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. * - * AC'97 audio codec emulation. + * AC'97 audio codec emulation. * * * - * Authors: RichardG, + * Authors: RichardG, * - * Copyright 2021 RichardG. + * Copyright 2021 RichardG. */ #include -#include #include -#include +#include #include +#include #define HAVE_STDARG_H + #include <86box/86box.h> #include <86box/device.h> #include <86box/io.h> #include <86box/snd_ac97.h> - static const struct { - const uint32_t vendor_id, min_rate, max_rate, misc_flags; /* definitions for misc_flags in snd_ac97.h */ - const uint16_t reset_flags, extid_flags, /* definitions in snd_ac97.h */ - powerdown_mask; /* bits [7:0] => register 26 bits [15:8]; bits [11:8] => register 2A bits [14:11] */ - const ac97_vendor_reg_t *vendor_regs; /* bits [11:8] of index are the page number if applicable (registers [60:6F]) */ - const device_t *device; + const uint32_t vendor_id, min_rate, max_rate, misc_flags; /* definitions for misc_flags in snd_ac97.h */ + const uint16_t reset_flags, extid_flags, /* definitions in snd_ac97.h */ + powerdown_mask; /* bits [7:0] => register 26 bits [15:8]; bits [11:8] => register 2A bits [14:11] */ + const ac97_vendor_reg_t *vendor_regs; /* bits [11:8] of index are the page number if applicable (registers [60:6F]) */ + const device_t *device; } ac97_codecs[] = { + // clang-format off [AC97_CODEC_AD1881] = { - .vendor_id = AC97_VENDOR_ID('A', 'D', 'S', 0x40), - .min_rate = 7000, - .max_rate = 48000, - .misc_flags = AC97_MASTER_6B | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_POP | AC97_MS | AC97_LPBK, - .reset_flags = (1 << AC97_3D_SHIFT), /* datasheet contradicts itself on AC97_HPOUT */ - .extid_flags = AC97_VRA, - .powerdown_mask = 0x0bf, - .vendor_regs = (const ac97_vendor_reg_t[]) {{0x74, 0x0000, 0xff07}, {0x76, 0x0404, 0xdde5}, {0x78, 48000, 0x0000}, {0x7a, 48000, 0x0000}, {0}}, - .device = &ad1881_device + .vendor_id = AC97_VENDOR_ID('A', 'D', 'S', 0x40), + .min_rate = 7000, + .max_rate = 48000, + .misc_flags = AC97_MASTER_6B | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_POP | AC97_MS | AC97_LPBK, + .reset_flags = (1 << AC97_3D_SHIFT), /* datasheet contradicts itself on AC97_HPOUT */ + .extid_flags = AC97_VRA, + .powerdown_mask = 0x0bf, + .vendor_regs = (const ac97_vendor_reg_t[]) {{0x74, 0x0000, 0xff07}, {0x76, 0x0404, 0xdde5}, {0x78, 48000, 0x0000}, {0x7a, 48000, 0x0000}, {0}}, + .device = &ad1881_device }, [AC97_CODEC_AK4540] = { - .vendor_id = AC97_VENDOR_ID('A', 'K', 'M', 0x00), - .misc_flags = AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, - .powerdown_mask = 0x01f, - .device = &ak4540_device + .vendor_id = AC97_VENDOR_ID('A', 'K', 'M', 0x00), + .misc_flags = AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, + .powerdown_mask = 0x01f, + .device = &ak4540_device }, [AC97_CODEC_ALC100] = { - .vendor_id = AC97_VENDOR_ID('A', 'L', 'C', 0x20), - .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_POP | AC97_MS | AC97_LPBK, - .reset_flags = (22 << AC97_3D_SHIFT), - .extid_flags = AC97_AMAP, - .powerdown_mask = 0x0bf, - .device = &alc100_device + .vendor_id = AC97_VENDOR_ID('A', 'L', 'C', 0x20), + .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_POP | AC97_MS | AC97_LPBK, + .reset_flags = (22 << AC97_3D_SHIFT), + .extid_flags = AC97_AMAP, + .powerdown_mask = 0x0bf, + .device = &alc100_device }, [AC97_CODEC_CS4297] = { - .vendor_id = AC97_VENDOR_ID('C', 'R', 'Y', 0x03), - .misc_flags = AC97_MASTER_6B | AC97_AUXOUT | AC97_AUXOUT_6B | AC97_MONOOUT | AC97_MONOOUT_6B | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, - .reset_flags = AC97_HPOUT | AC97_DAC_18B | AC97_ADC_18B, - .extid_flags = 0, - .powerdown_mask = 0x07f, - .vendor_regs = (const ac97_vendor_reg_t[]) {{0x5a, 0x0301, 0x0000}, {0}}, - .device = &cs4297_device + .vendor_id = AC97_VENDOR_ID('C', 'R', 'Y', 0x03), + .misc_flags = AC97_MASTER_6B | AC97_AUXOUT | AC97_AUXOUT_6B | AC97_MONOOUT | AC97_MONOOUT_6B | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, + .reset_flags = AC97_HPOUT | AC97_DAC_18B | AC97_ADC_18B, + .extid_flags = 0, + .powerdown_mask = 0x07f, + .vendor_regs = (const ac97_vendor_reg_t[]) {{0x5a, 0x0301, 0x0000}, {0}}, + .device = &cs4297_device }, [AC97_CODEC_CS4297A] = { - .vendor_id = AC97_VENDOR_ID('C', 'R', 'Y', 0x11), - .misc_flags = AC97_MASTER_6B | AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, - .reset_flags = AC97_HPOUT | AC97_DAC_20B | AC97_ADC_18B | (6 << AC97_3D_SHIFT), - .extid_flags = AC97_AMAP, - .powerdown_mask = 0x0ff, - .vendor_regs = (const ac97_vendor_reg_t[]) {{0x5e, 0x0000, 0x01b0}, {0x60, 0x0023, 0x0001}, {0x68, 0x0000, 0xdfff}, {0}}, - .device = &cs4297a_device + .vendor_id = AC97_VENDOR_ID('C', 'R', 'Y', 0x11), + .misc_flags = AC97_MASTER_6B | AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, + .reset_flags = AC97_HPOUT | AC97_DAC_20B | AC97_ADC_18B | (6 << AC97_3D_SHIFT), + .extid_flags = AC97_AMAP, + .powerdown_mask = 0x0ff, + .vendor_regs = (const ac97_vendor_reg_t[]) {{0x5e, 0x0000, 0x01b0}, {0x60, 0x0023, 0x0001}, {0x68, 0x0000, 0xdfff}, {0}}, + .device = &cs4297a_device }, [AC97_CODEC_STAC9708] = { - .vendor_id = AC97_VENDOR_ID(0x83, 0x84, 0x76, 0x08), - .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, - .reset_flags = (26 << AC97_3D_SHIFT) | AC97_DAC_18B | AC97_ADC_18B, - .extid_flags = AC97_SDAC, - .powerdown_mask = 0x2ff, - .vendor_regs = (const ac97_vendor_reg_t []) {{0x6c, 0x0000, 0x0003}, {0x74, 0x0000, 0x0003}, {0}}, - .device = &stac9708_device + .vendor_id = AC97_VENDOR_ID(0x83, 0x84, 0x76, 0x08), + .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, + .reset_flags = (26 << AC97_3D_SHIFT) | AC97_DAC_18B | AC97_ADC_18B, + .extid_flags = AC97_SDAC, + .powerdown_mask = 0x2ff, + .vendor_regs = (const ac97_vendor_reg_t []) {{0x6c, 0x0000, 0x0003}, {0x74, 0x0000, 0x0003}, {0}}, + .device = &stac9708_device }, [AC97_CODEC_STAC9721] = { - .vendor_id = AC97_VENDOR_ID(0x83, 0x84, 0x76, 0x09), - .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, - .reset_flags = (26 << AC97_3D_SHIFT) | AC97_DAC_18B | AC97_ADC_18B, - .extid_flags = AC97_AMAP, - .powerdown_mask = 0x0ff, - .vendor_regs = (const ac97_vendor_reg_t []) {{0x6c, 0x0000, 0x0000}, {0x6e, 0x0000, 0x0003}, {0x70, 0x0000, 0xffff}, {0x72, 0x0000, 0x0006}, {0x74, 0x0000, 0x0003}, {0x76, 0x0000, 0xffff}, {0x78, 0x0000, 0x3802}, {0}}, - .device = &stac9721_device + .vendor_id = AC97_VENDOR_ID(0x83, 0x84, 0x76, 0x09), + .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, + .reset_flags = (26 << AC97_3D_SHIFT) | AC97_DAC_18B | AC97_ADC_18B, + .extid_flags = AC97_AMAP, + .powerdown_mask = 0x0ff, + .vendor_regs = (const ac97_vendor_reg_t []) {{0x6c, 0x0000, 0x0000}, {0x6e, 0x0000, 0x0003}, {0x70, 0x0000, 0xffff}, {0x72, 0x0000, 0x0006}, {0x74, 0x0000, 0x0003}, {0x76, 0x0000, 0xffff}, {0x78, 0x0000, 0x3802}, {0}}, + .device = &stac9721_device }, [AC97_CODEC_WM9701A] = { - .vendor_id = AC97_VENDOR_ID('W', 'M', 'L', 0x00), - .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, - .reset_flags = AC97_DAC_18B | AC97_ADC_18B, - .extid_flags = 0, - .powerdown_mask = 0x03f, - .device = &wm9701a_device + .vendor_id = AC97_VENDOR_ID('W', 'M', 'L', 0x00), + .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, + .reset_flags = AC97_DAC_18B | AC97_ADC_18B, + .extid_flags = 0, + .powerdown_mask = 0x03f, + .device = &wm9701a_device } + // clang-format on }; - #ifdef ENABLE_AC97_CODEC_LOG int ac97_codec_do_log = ENABLE_AC97_CODEC_LOG; @@ -114,27 +115,28 @@ ac97_codec_log(const char *fmt, ...) va_list ap; if (ac97_codec_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define ac97_codec_log(fmt, ...) +# define ac97_codec_log(fmt, ...) #endif static const int32_t codec_attn[] = { + // clang-format off 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 25, 32, 41, 51, 65, 82, 103, 130, 164, 206, 260, 327, 412, 519, 653, 822, 1036, 1304, 1641, 2067, 2602, 3276, 4125, 5192, 6537, 8230, 10362, 13044, 16422, 20674, 26027, 32767, - 41305, 52068, 65636, 82739, 104299, 131477, 165737, 208925 + 41305, 52068, 65636, 82739, 104299, 131477, 165737, 208925 + // clang-format on }; -ac97_codec_t **ac97_codec = NULL, **ac97_modem_codec = NULL; -int ac97_codec_count = 0, ac97_modem_codec_count = 0, - ac97_codec_id = 0, ac97_modem_codec_id = 0; - +ac97_codec_t **ac97_codec = NULL, **ac97_modem_codec = NULL; +int ac97_codec_count = 0, ac97_modem_codec_count = 0, + ac97_codec_id = 0, ac97_modem_codec_id = 0; uint16_t ac97_codec_readw(ac97_codec_t *dev, uint8_t reg) @@ -143,16 +145,15 @@ ac97_codec_readw(ac97_codec_t *dev, uint8_t reg) reg &= 0x7e; uint16_t ret = dev->regs[0x24 >> 1] & 0x000f; if ((ret > 0) && (reg >= 0x60) && (reg < 0x6f)) - ret = (ret <= dev->vendor_reg_page_max) ? dev->vendor_reg_pages[(ret << 3) | ((reg & 0x0e) >> 1)] : 0; + ret = (ret <= dev->vendor_reg_page_max) ? dev->vendor_reg_pages[(ret << 3) | ((reg & 0x0e) >> 1)] : 0; else - ret = dev->regs[reg >> 1]; + ret = dev->regs[reg >> 1]; ac97_codec_log("AC97 Codec %d: readw(%02X) = %04X\n", dev->codec_id, reg, ret); return ret; } - void ac97_codec_writew(ac97_codec_t *dev, uint8_t reg, uint16_t val) { @@ -160,294 +161,296 @@ ac97_codec_writew(ac97_codec_t *dev, uint8_t reg, uint16_t val) reg &= 0x7e; uint16_t i = 0, prev = dev->regs[reg >> 1]; - int j; + int j; switch (reg) { - case 0x00: /* Reset / ID code */ - ac97_codec_reset(dev); - return; + case 0x00: /* Reset / ID code */ + ac97_codec_reset(dev); + return; - case 0x02: /* Master Volume */ - val &= 0xbf3f; + case 0x02: /* Master Volume */ + val &= 0xbf3f; - /* Convert 1xxxxx to 011111 where unsupported, per specification. */ - if (!(dev->misc_flags & AC97_MASTER_6B)) { -clamp_5b: if (val & 0x2000) - val = (val & ~0x2000) | 0x1f00; -clamp_5b_r: if (val & 0x0020) - val = (val & ~0x0020) | 0x001f; - } - break; + /* Convert 1xxxxx to 011111 where unsupported, per specification. */ + if (!(dev->misc_flags & AC97_MASTER_6B)) { +clamp_5b: + if (val & 0x2000) + val = (val & ~0x2000) | 0x1f00; +clamp_5b_r: + if (val & 0x0020) + val = (val & ~0x0020) | 0x001f; + } + break; - case 0x04: /* Aux Out Volume */ - if (!(dev->misc_flags & AC97_AUXOUT)) - return; - val &= 0xbf3f; + case 0x04: /* Aux Out Volume */ + if (!(dev->misc_flags & AC97_AUXOUT)) + return; + val &= 0xbf3f; - /* Convert 1xxxxx to 011111 where unsupported, per specification. */ - if (!(dev->misc_flags & AC97_AUXOUT_6B)) - goto clamp_5b; - break; + /* Convert 1xxxxx to 011111 where unsupported, per specification. */ + if (!(dev->misc_flags & AC97_AUXOUT_6B)) + goto clamp_5b; + break; - case 0x06: /* Mono Out Volume */ - if (!(dev->misc_flags & AC97_MONOOUT)) - return; - val &= 0x803f; + case 0x06: /* Mono Out Volume */ + if (!(dev->misc_flags & AC97_MONOOUT)) + return; + val &= 0x803f; - /* Convert 1xxxxx to 011111 where unsupported, per specification. */ - if (!(dev->misc_flags & AC97_MONOOUT_6B)) - goto clamp_5b_r; - break; + /* Convert 1xxxxx to 011111 where unsupported, per specification. */ + if (!(dev->misc_flags & AC97_MONOOUT_6B)) + goto clamp_5b_r; + break; - case 0x08: /* Master Tone Control */ - if (!(dev->reset_flags & AC97_TONECTL)) - return; - val &= 0x0f0f; - break; + case 0x08: /* Master Tone Control */ + if (!(dev->reset_flags & AC97_TONECTL)) + return; + val &= 0x0f0f; + break; - case 0x0a: /* PC Beep Volume */ - if (dev->misc_flags & AC97_PCBEEP) - i |= 0x801e; - if (dev->misc_flags & AC97_PCBEEP_GEN) - i |= 0x1fe0; - val &= i; - break; + case 0x0a: /* PC Beep Volume */ + if (dev->misc_flags & AC97_PCBEEP) + i |= 0x801e; + if (dev->misc_flags & AC97_PCBEEP_GEN) + i |= 0x1fe0; + val &= i; + break; - case 0x0c: /* Phone Volume */ - if (!(dev->misc_flags & AC97_PHONE)) - return; - val &= 0x801f; - break; + case 0x0c: /* Phone Volume */ + if (!(dev->misc_flags & AC97_PHONE)) + return; + val &= 0x801f; + break; - case 0x0e: /* Mic Volume */ - val &= 0x805f; - break; + case 0x0e: /* Mic Volume */ + val &= 0x805f; + break; - case 0x10: /* Line In Volume */ - case 0x12: /* CD Volume */ - case 0x18: /* PCM Out Volume */ -line_gain: val &= 0x9f1f; - break; + case 0x10: /* Line In Volume */ + case 0x12: /* CD Volume */ + case 0x18: /* PCM Out Volume */ +line_gain: + val &= 0x9f1f; + break; - case 0x14: /* Video Volume */ - if (!(dev->misc_flags & AC97_VIDEO)) - return; - goto line_gain; + case 0x14: /* Video Volume */ + if (!(dev->misc_flags & AC97_VIDEO)) + return; + goto line_gain; - case 0x16: /* Aux In Volume */ - if (!(dev->misc_flags & AC97_AUXIN)) - return; - goto line_gain; + case 0x16: /* Aux In Volume */ + if (!(dev->misc_flags & AC97_AUXIN)) + return; + goto line_gain; - case 0x1a: /* Record Select Control */ - val &= 0x0707; - break; + case 0x1a: /* Record Select Control */ + val &= 0x0707; + break; - case 0x1c: /* Record Gain */ - val &= 0x8f0f; - break; + case 0x1c: /* Record Gain */ + val &= 0x8f0f; + break; - case 0x1e: /* Record Gain Mic */ - if (!(dev->reset_flags & AC97_MICPCM)) - return; - val &= 0x800f; - break; + case 0x1e: /* Record Gain Mic */ + if (!(dev->reset_flags & AC97_MICPCM)) + return; + val &= 0x800f; + break; - case 0x20: /* General Purpose */ - i = AC97_MIX | (dev->misc_flags & (AC97_POP | AC97_MS | AC97_LPBK)); - if (dev->reset_flags >> AC97_3D_SHIFT) - i |= AC97_3D; - if (dev->reset_flags & AC97_SIMSTEREO) - i |= AC97_ST; - if (dev->reset_flags & AC97_LOUDNESS) - i |= AC97_LD; - if (dev->extid_flags & AC97_DRA) - i |= AC97_DRSS_MASK; - val &= i; - break; + case 0x20: /* General Purpose */ + i = AC97_MIX | (dev->misc_flags & (AC97_POP | AC97_MS | AC97_LPBK)); + if (dev->reset_flags >> AC97_3D_SHIFT) + i |= AC97_3D; + if (dev->reset_flags & AC97_SIMSTEREO) + i |= AC97_ST; + if (dev->reset_flags & AC97_LOUDNESS) + i |= AC97_LD; + if (dev->extid_flags & AC97_DRA) + i |= AC97_DRSS_MASK; + val &= i; + break; - case 0x22: /* 3D Control */ - switch (dev->reset_flags >> AC97_3D_SHIFT) { - case 1: /* Analog Devices */ - case 6: /* Crystal */ - val &= 0x000f; - break; + case 0x22: /* 3D Control */ + switch (dev->reset_flags >> AC97_3D_SHIFT) { + case 1: /* Analog Devices */ + case 6: /* Crystal */ + val &= 0x000f; + break; - case 22: /* Avance Logic / Realtek */ - val &= 0x0003; - break; + case 22: /* Avance Logic / Realtek */ + val &= 0x0003; + break; - case 26: /* SigmaTel */ - i = 0x0003; - if (dev->extid_flags & AC97_SDAC) - i |= 0x000c; - val &= i; - break; + case 26: /* SigmaTel */ + i = 0x0003; + if (dev->extid_flags & AC97_SDAC) + i |= 0x000c; + val &= i; + break; - default: - return; - } - break; + default: + return; + } + break; - case 0x24: /* Audio Interrupt and Paging Mechanism */ - if ((dev->extid_flags & AC97_REV_MASK) < AC97_REV_2_3) - return; - val &= 0x000f; - break; + case 0x24: /* Audio Interrupt and Paging Mechanism */ + if ((dev->extid_flags & AC97_REV_MASK) < AC97_REV_2_3) + return; + val &= 0x000f; + break; - case 0x26: /* Powerdown Control/Status */ - i = dev->powerdown_mask << 8; - val = (val & i) | (prev & ~i); + case 0x26: /* Powerdown Control/Status */ + i = dev->powerdown_mask << 8; + val = (val & i) | (prev & ~i); - /* Update status bits to reflect powerdowns. */ - val = (val & ~0x000f) | (~(val >> 8) & 0x000f); - if (val & 0x0800) /* PR3 clears both ANL and REF */ - val &= ~0x0004; - break; + /* Update status bits to reflect powerdowns. */ + val = (val & ~0x000f) | (~(val >> 8) & 0x000f); + if (val & 0x0800) /* PR3 clears both ANL and REF */ + val &= ~0x0004; + break; - case 0x28: /* Extended Audio ID */ - if (dev->misc_flags & AC97_DSA) - i |= 0x0030; - val = (val & i) | (prev & ~i); - break; + case 0x28: /* Extended Audio ID */ + if (dev->misc_flags & AC97_DSA) + i |= 0x0030; + val = (val & i) | (prev & ~i); + break; - case 0x2a: /* Extended Audio Status/Control */ - i = dev->extid_flags & (AC97_VRA | AC97_DRA | AC97_SPDIF | AC97_VRM); - if (dev->extid_flags & AC97_SPDIF) - i |= AC97_SPSA_MASK << AC97_SPSA_SHIFT; - i |= (dev->powerdown_mask << 3) & 0x7800; /* multichannel powerdowns */ - val = (val & i) | (prev & ~i); + case 0x2a: /* Extended Audio Status/Control */ + i = dev->extid_flags & (AC97_VRA | AC97_DRA | AC97_SPDIF | AC97_VRM); + if (dev->extid_flags & AC97_SPDIF) + i |= AC97_SPSA_MASK << AC97_SPSA_SHIFT; + i |= (dev->powerdown_mask << 3) & 0x7800; /* multichannel powerdowns */ + val = (val & i) | (prev & ~i); - /* Reset DAC sample rates to 48 KHz (96 KHz with DRA) if VRA is being cleared. */ - if (!(val & AC97_VRA)) { - for (i = 0x2c; i <= 0x30; i += 2) - dev->regs[i >> 1] = 48000; - } + /* Reset DAC sample rates to 48 KHz (96 KHz with DRA) if VRA is being cleared. */ + if (!(val & AC97_VRA)) { + for (i = 0x2c; i <= 0x30; i += 2) + dev->regs[i >> 1] = 48000; + } - /* Reset ADC sample rates to 48 KHz if VRM is being cleared. */ - if (!(val & AC97_VRM)) { - for (i = 0x32; i <= 0x34; i += 2) - dev->regs[i >> 1] = 48000; - } - break; + /* Reset ADC sample rates to 48 KHz if VRM is being cleared. */ + if (!(val & AC97_VRM)) { + for (i = 0x32; i <= 0x34; i += 2) + dev->regs[i >> 1] = 48000; + } + break; - case 0x2c: /* PCM Front DAC Rate */ - case 0x32: /* PCM L/R ADC Rate */ -rate: /* Writable only if VRA/VRM is set. */ - i = (reg >= 0x32) ? AC97_VRM : AC97_VRA; - if (!(dev->extid_flags & i)) - return; + case 0x2c: /* PCM Front DAC Rate */ + case 0x32: /* PCM L/R ADC Rate */ +rate: /* Writable only if VRA/VRM is set. */ + i = (reg >= 0x32) ? AC97_VRM : AC97_VRA; + if (!(dev->extid_flags & i)) + return; - /* Limit to supported sample rate range. */ - if (val < dev->min_rate) - val = dev->min_rate; - else if (val > dev->max_rate) - val = dev->max_rate; - break; + /* Limit to supported sample rate range. */ + if (val < dev->min_rate) + val = dev->min_rate; + else if (val > dev->max_rate) + val = dev->max_rate; + break; - case 0x2e: /* PCM Surround DAC Rate */ - if (!(dev->extid_flags & AC97_SDAC)) - return; - goto rate; + case 0x2e: /* PCM Surround DAC Rate */ + if (!(dev->extid_flags & AC97_SDAC)) + return; + goto rate; - case 0x30: /* PCM LFE DAC Rate */ - if (!(dev->extid_flags & AC97_LDAC)) - return; - goto rate; + case 0x30: /* PCM LFE DAC Rate */ + if (!(dev->extid_flags & AC97_LDAC)) + return; + goto rate; - case 0x34: /* Mic ADC Rate */ - if (!(dev->reset_flags & AC97_MICPCM)) - return; - goto rate; + case 0x34: /* Mic ADC Rate */ + if (!(dev->reset_flags & AC97_MICPCM)) + return; + goto rate; - case 0x36: /* Center/LFE Volume */ - if (dev->extid_flags & AC97_LDAC) - i |= 0xbf00; - if (dev->extid_flags & AC97_CDAC) - i |= 0x00bf; - val &= i; + case 0x36: /* Center/LFE Volume */ + if (dev->extid_flags & AC97_LDAC) + i |= 0xbf00; + if (dev->extid_flags & AC97_CDAC) + i |= 0x00bf; + val &= i; - /* Convert 1xxxxx to 011111 where unsupported, per specification. */ - if (!(dev->misc_flags & AC97_LFE_6B) && (val & 0x2000)) - val = (val & ~0x2000) | 0x1f00; - if (!(dev->misc_flags & AC97_CENTER_6B)) - goto clamp_5b_r; - break; + /* Convert 1xxxxx to 011111 where unsupported, per specification. */ + if (!(dev->misc_flags & AC97_LFE_6B) && (val & 0x2000)) + val = (val & ~0x2000) | 0x1f00; + if (!(dev->misc_flags & AC97_CENTER_6B)) + goto clamp_5b_r; + break; - case 0x38: /* Surround Volume */ - if (!(dev->extid_flags & AC97_SDAC)) - return; - val &= 0xbfbf; + case 0x38: /* Surround Volume */ + if (!(dev->extid_flags & AC97_SDAC)) + return; + val &= 0xbfbf; - /* Convert 1xxxxx to 011111 where unsupported, per specification. */ - if (!(dev->misc_flags & AC97_SURR_6B)) - goto clamp_5b; - break; + /* Convert 1xxxxx to 011111 where unsupported, per specification. */ + if (!(dev->misc_flags & AC97_SURR_6B)) + goto clamp_5b; + break; - case 0x3a: /* S/PDIF Control */ - if (!(dev->extid_flags & AC97_SPDIF)) - return; - break; + case 0x3a: /* S/PDIF Control */ + if (!(dev->extid_flags & AC97_SPDIF)) + return; + break; - case 0x60 ... 0x6e: /* Extended */ - /* Get extended register page. */ - i = dev->regs[0x24 >> 1] & 0x000f; + case 0x60 ... 0x6e: /* Extended */ + /* Get extended register page. */ + i = dev->regs[0x24 >> 1] & 0x000f; - /* Redirect a write to page 1+ to the right array, part 1. */ - if (i > 0) { - /* Don't overflow the pages. */ - if (i > dev->vendor_reg_page_max) - return; + /* Redirect a write to page 1+ to the right array, part 1. */ + if (i > 0) { + /* Don't overflow the pages. */ + if (i > dev->vendor_reg_page_max) + return; - /* Get actual previous value. */ - prev = dev->vendor_reg_pages[(i << 3) | ((reg & 0x0e) >> 1)]; - } + /* Get actual previous value. */ + prev = dev->vendor_reg_pages[(i << 3) | ((reg & 0x0e) >> 1)]; + } - i <<= 8; - /* fall-through */ + i <<= 8; + /* fall-through */ - case 0x5a ... 0x5e: /* Vendor Reserved */ - case 0x70 ... 0x7a: - /* Stop if no vendor-specific registers are defined. */ - if (!dev->vendor_regs) - return; + case 0x5a ... 0x5e: /* Vendor Reserved */ + case 0x70 ... 0x7a: + /* Stop if no vendor-specific registers are defined. */ + if (!dev->vendor_regs) + return; - /* Look for a matching vendor-specific register. */ - i |= reg; - for (j = 0; dev->vendor_regs[j].index; j++) { - /* If a match was found, inject written bits. */ - if (dev->vendor_regs[j].index == i) { - val = (val & dev->vendor_regs[j].write_mask) | (prev & ~dev->vendor_regs[j].write_mask); - break; - } - } + /* Look for a matching vendor-specific register. */ + i |= reg; + for (j = 0; dev->vendor_regs[j].index; j++) { + /* If a match was found, inject written bits. */ + if (dev->vendor_regs[j].index == i) { + val = (val & dev->vendor_regs[j].write_mask) | (prev & ~dev->vendor_regs[j].write_mask); + break; + } + } - /* No match found. */ - if (!dev->vendor_regs[j].index) - return; + /* No match found. */ + if (!dev->vendor_regs[j].index) + return; - /* Redirect a write to page 1+ to the right array, part 2. */ - i >>= 8; - if (i > 0) { - dev->vendor_reg_pages[(i << 3) | ((reg & 0x0e) >> 1)] = val; - return; - } - break; + /* Redirect a write to page 1+ to the right array, part 2. */ + i >>= 8; + if (i > 0) { + dev->vendor_reg_pages[(i << 3) | ((reg & 0x0e) >> 1)] = val; + return; + } + break; - case 0x7c: /* Vendor ID1 */ - case 0x7e: /* Vendor ID2 */ - return; + case 0x7c: /* Vendor ID1 */ + case 0x7e: /* Vendor ID2 */ + return; } dev->regs[reg >> 1] = val; } - void ac97_codec_reset(void *priv) { ac97_codec_t *dev = (ac97_codec_t *) priv; - uint16_t i, j; + uint16_t i, j; ac97_codec_log("AC97 Codec %d: reset()\n", dev->codec_id); @@ -456,26 +459,26 @@ ac97_codec_reset(void *priv) /* Set default level and gain values. */ dev->regs[0x02 >> 1] = AC97_MUTE; if (dev->misc_flags & AC97_AUXOUT) - dev->regs[0x04 >> 1] = AC97_MUTE; + dev->regs[0x04 >> 1] = AC97_MUTE; if (dev->misc_flags & AC97_MONOOUT) - dev->regs[0x06 >> 1] = AC97_MUTE; + dev->regs[0x06 >> 1] = AC97_MUTE; if (dev->misc_flags & AC97_PHONE) - dev->regs[0x0c >> 1] = AC97_MUTE | 0x0008; - dev->regs[0x0e >> 1] = AC97_MUTE | 0x0008; /* mic */ + dev->regs[0x0c >> 1] = AC97_MUTE | 0x0008; + dev->regs[0x0e >> 1] = AC97_MUTE | 0x0008; /* mic */ dev->regs[0x10 >> 1] = dev->regs[0x12 >> 1] = dev->regs[0x18 >> 1] = AC97_MUTE | 0x0808; /* line in, CD, PCM out */ if (dev->misc_flags & AC97_VIDEO) - dev->regs[0x14 >> 1] = AC97_MUTE | 0x0808; + dev->regs[0x14 >> 1] = AC97_MUTE | 0x0808; if (dev->misc_flags & AC97_AUXIN) - dev->regs[0x14 >> 1] = AC97_MUTE | 0x0808; + dev->regs[0x14 >> 1] = AC97_MUTE | 0x0808; dev->regs[0x1c >> 1] = AC97_MUTE; /* record gain */ if (dev->reset_flags & AC97_MICPCM) - dev->regs[0x1e >> 1] = AC97_MUTE; /* mic record gain */ + dev->regs[0x1e >> 1] = AC97_MUTE; /* mic record gain */ if (dev->misc_flags & AC97_LDAC) - dev->regs[0x36 >> 1] = AC97_MUTE_L; + dev->regs[0x36 >> 1] = AC97_MUTE_L; if (dev->misc_flags & AC97_CDAC) - dev->regs[0x36 >> 1] |= AC97_MUTE_R; + dev->regs[0x36 >> 1] |= AC97_MUTE_R; if (dev->misc_flags & AC97_SDAC) - dev->regs[0x38 >> 1] = AC97_MUTE_L | AC97_MUTE_R; + dev->regs[0x38 >> 1] = AC97_MUTE_L | AC97_MUTE_R; /* Set flags. */ dev->regs[0x00 >> 1] = dev->reset_flags; @@ -485,9 +488,9 @@ ac97_codec_reset(void *priv) i = dev->extid_flags & (AC97_CDAC | AC97_SDAC | AC97_LDAC); dev->regs[0x2a >> 1] |= i | (i << 5); /* any additional DACs are ready but powered down */ if (dev->extid_flags & AC97_SPDIF) - dev->regs[0x2a >> 1] |= AC97_SPCV; + dev->regs[0x2a >> 1] |= AC97_SPCV; if (dev->reset_flags & AC97_MICPCM) - dev->regs[0x2a >> 1] |= AC97_MADC | AC97_PRL; + dev->regs[0x2a >> 1] |= AC97_MADC | AC97_PRL; /* Set vendor ID. */ dev->regs[0x7c >> 1] = dev->vendor_id >> 16; @@ -495,56 +498,54 @@ ac97_codec_reset(void *priv) /* Set vendor-specific registers. */ if (dev->vendor_regs) { - for (j = 0; dev->vendor_regs[j].index; j++) { - i = (dev->vendor_regs[j].index >> 8) & 0x000f; - if (i > 0) - dev->vendor_reg_pages[(i << 3) | (dev->vendor_regs[j].index >> 1)] = dev->vendor_regs[j].value; - else - dev->regs[dev->vendor_regs[j].index >> 1] = dev->vendor_regs[j].value; - } + for (j = 0; dev->vendor_regs[j].index; j++) { + i = (dev->vendor_regs[j].index >> 8) & 0x000f; + if (i > 0) + dev->vendor_reg_pages[(i << 3) | (dev->vendor_regs[j].index >> 1)] = dev->vendor_regs[j].value; + else + dev->regs[dev->vendor_regs[j].index >> 1] = dev->vendor_regs[j].value; + } } } - void ac97_codec_getattn(void *priv, uint8_t reg, int *l, int *r) { ac97_codec_t *dev = (ac97_codec_t *) priv; - uint16_t val = dev->regs[reg >> 1]; + uint16_t val = dev->regs[reg >> 1]; /* Apply full mute and powerdowns. */ int full_mute = (reg < 0x36); - if ((full_mute && (val & AC97_MUTE)) || /* full mute */ - (dev->regs[0x26 >> 1] & 0x3e00) || /* DAC powerdown */ - ((reg == 0x38) && (dev->regs[0x2a >> 1] & AC97_PRJ))) { /* surround DAC powerdown */ - *l = 0; - *r = 0; + if ((full_mute && (val & AC97_MUTE)) || /* full mute */ + (dev->regs[0x26 >> 1] & 0x3e00) || /* DAC powerdown */ + ((reg == 0x38) && (dev->regs[0x2a >> 1] & AC97_PRJ))) { /* surround DAC powerdown */ + *l = 0; + *r = 0; } else { /* per-channel mute */ - /* Determine attenuation value. */ - uint8_t l_val = val >> 8, r_val = val; - if (reg <= 0x06) { /* 6-bit level */ - *l = codec_attn[0x3f - (l_val & 0x3f)]; - *r = codec_attn[0x3f - (r_val & 0x3f)]; - } else { /* 5-bit gain */ - *l = codec_attn[0x47 - (l_val & 0x1f)]; - *r = codec_attn[0x47 - (r_val & 0x1f)]; - } + /* Determine attenuation value. */ + uint8_t l_val = val >> 8, r_val = val; + if (reg <= 0x06) { /* 6-bit level */ + *l = codec_attn[0x3f - (l_val & 0x3f)]; + *r = codec_attn[0x3f - (r_val & 0x3f)]; + } else { /* 5-bit gain */ + *l = codec_attn[0x47 - (l_val & 0x1f)]; + *r = codec_attn[0x47 - (r_val & 0x1f)]; + } - /* Apply per-channel mute and center/LFE powerdowns where applicable. */ - if (!full_mute) { - if ((val & AC97_MUTE_L) || /* left mute */ - ((reg == 0x36) && (dev->regs[0x2a >> 1] & AC97_PRK))) /* LFE DAC powerdown */ - *l = 0; - if ((val & AC97_MUTE_R) || /* right mute */ - ((reg == 0x36) && (dev->regs[0x2a >> 1] & AC97_PRI))) /* center DAC powerdown */ - *r = 0; - } + /* Apply per-channel mute and center/LFE powerdowns where applicable. */ + if (!full_mute) { + if ((val & AC97_MUTE_L) || /* left mute */ + ((reg == 0x36) && (dev->regs[0x2a >> 1] & AC97_PRK))) /* LFE DAC powerdown */ + *l = 0; + if ((val & AC97_MUTE_R) || /* right mute */ + ((reg == 0x36) && (dev->regs[0x2a >> 1] & AC97_PRI))) /* center DAC powerdown */ + *r = 0; + } } ac97_codec_log("AC97 Codec %d: getattn(%02X) = %d %d\n", dev->codec_id, reg, *l, *r); } - uint32_t ac97_codec_getrate(void *priv, uint8_t reg) { @@ -555,60 +556,59 @@ ac97_codec_getrate(void *priv, uint8_t reg) /* If this is the PCM DAC, double sample rate if DRA is set. */ if ((reg == 0x2c) && (dev->regs[0x2a >> 1] & AC97_DRA)) - ret <<= 1; + ret <<= 1; ac97_codec_log("AC97 Codec %d: getrate(%02X) = %d\n", dev->codec_id, reg, ret); return ret; } - static void * ac97_codec_init(const device_t *info) { ac97_codec_t *dev = malloc(sizeof(ac97_codec_t)); memset(dev, 0, sizeof(ac97_codec_t)); - dev->vendor_id = ac97_codecs[info->local].vendor_id; - dev->min_rate = ac97_codecs[info->local].min_rate; - dev->max_rate = ac97_codecs[info->local].max_rate; - dev->reset_flags = ac97_codecs[info->local].reset_flags; - dev->extid_flags = ac97_codecs[info->local].extid_flags; - dev->misc_flags = ac97_codecs[info->local].misc_flags; + dev->vendor_id = ac97_codecs[info->local].vendor_id; + dev->min_rate = ac97_codecs[info->local].min_rate; + dev->max_rate = ac97_codecs[info->local].max_rate; + dev->reset_flags = ac97_codecs[info->local].reset_flags; + dev->extid_flags = ac97_codecs[info->local].extid_flags; + dev->misc_flags = ac97_codecs[info->local].misc_flags; dev->powerdown_mask = ac97_codecs[info->local].powerdown_mask; - dev->vendor_regs = ac97_codecs[info->local].vendor_regs; + dev->vendor_regs = ac97_codecs[info->local].vendor_regs; ac97_codec_log("AC97 Codec %d: init(%c%c%c%02X)\n", ac97_codec_id, (dev->vendor_id >> 24) & 0xff, (dev->vendor_id >> 16) & 0xff, (dev->vendor_id >> 8) & 0xff, dev->vendor_id & 0xff); /* Associate this codec to the current controller. */ if (!ac97_codec || (ac97_codec_count <= 0)) { - pclog("AC97 Codec %d: No controller to associate codec\n", ac97_codec_id); - return NULL; + pclog("AC97 Codec %d: No controller to associate codec\n", ac97_codec_id); + return NULL; } *ac97_codec = dev; if (--ac97_codec_count == 0) - ac97_codec = NULL; + ac97_codec = NULL; else - ac97_codec += sizeof(ac97_codec_t *); + ac97_codec += sizeof(ac97_codec_t *); dev->codec_id = ac97_codec_id++; /* Allocate vendor-specific register pages if required. */ if (dev->vendor_regs) { - /* Get the highest vendor-specific register page number. */ - int i, j; - dev->vendor_reg_page_max = 0; - for (j = 0; dev->vendor_regs[j].index; j++) { - i = (dev->vendor_regs[j].index >> 8) & 0x000f; - if (i > dev->vendor_reg_page_max) - dev->vendor_reg_page_max = i; - } + /* Get the highest vendor-specific register page number. */ + int i, j; + dev->vendor_reg_page_max = 0; + for (j = 0; dev->vendor_regs[j].index; j++) { + i = (dev->vendor_regs[j].index >> 8) & 0x000f; + if (i > dev->vendor_reg_page_max) + dev->vendor_reg_page_max = i; + } - /* Allocate pages 1+. */ - if (dev->vendor_reg_page_max > 0) { - ac97_codec_log("AC97 Codec %d: Allocating %d vendor-specific register pages\n", dev->codec_id, dev->vendor_reg_page_max); - i = 16 * dev->vendor_reg_page_max; - dev->vendor_reg_pages = (uint16_t *) malloc(i); - memset(dev->vendor_reg_pages, 0, i); - } + /* Allocate pages 1+. */ + if (dev->vendor_reg_page_max > 0) { + ac97_codec_log("AC97 Codec %d: Allocating %d vendor-specific register pages\n", dev->codec_id, dev->vendor_reg_page_max); + i = 16 * dev->vendor_reg_page_max; + dev->vendor_reg_pages = (uint16_t *) malloc(i); + memset(dev->vendor_reg_pages, 0, i); + } } /* Initialize codec registers. */ @@ -617,130 +617,135 @@ ac97_codec_init(const device_t *info) return dev; } - static void ac97_codec_close(void *priv) { ac97_codec_t *dev = (ac97_codec_t *) priv; if (!dev) - return; + return; ac97_codec_log("AC97 Codec %d: close()\n", dev->codec_id); if (dev->vendor_reg_pages) - free(dev->vendor_reg_pages); + free(dev->vendor_reg_pages); free(dev); } - const device_t * ac97_codec_get(int model) { if ((model >= 0) && (model < (sizeof(ac97_codecs) / sizeof(ac97_codecs[0])))) - return ac97_codecs[model].device; + return ac97_codecs[model].device; else - return &cs4297a_device; /* fallback */ + return &cs4297a_device; /* fallback */ } - -const device_t ad1881_device = -{ +const device_t ad1881_device = { "Analog Devices AD1881", "ad1881", DEVICE_AC97, AC97_CODEC_AD1881, - ac97_codec_init, ac97_codec_close, ac97_codec_reset, + ac97_codec_init, + ac97_codec_close, + ac97_codec_reset, { NULL }, NULL, NULL, NULL }; -const device_t ak4540_device = -{ +const device_t ak4540_device = { "Asahi Kasei AK4540", "ak4540", DEVICE_AC97, AC97_CODEC_AK4540, - ac97_codec_init, ac97_codec_close, ac97_codec_reset, + ac97_codec_init, + ac97_codec_close, + ac97_codec_reset, { NULL }, NULL, NULL, NULL }; -const device_t alc100_device = -{ +const device_t alc100_device = { "Avance Logic ALC100", "alc100", DEVICE_AC97, AC97_CODEC_ALC100, - ac97_codec_init, ac97_codec_close, ac97_codec_reset, + ac97_codec_init, + ac97_codec_close, + ac97_codec_reset, { NULL }, NULL, NULL, NULL }; -const device_t cs4297_device = -{ +const device_t cs4297_device = { "Crystal CS4297", "cs4297", DEVICE_AC97, AC97_CODEC_CS4297, - ac97_codec_init, ac97_codec_close, ac97_codec_reset, + ac97_codec_init, + ac97_codec_close, + ac97_codec_reset, { NULL }, NULL, NULL, NULL }; -const device_t cs4297a_device = -{ +const device_t cs4297a_device = { "Crystal CS4297A", "cs4297a", DEVICE_AC97, AC97_CODEC_CS4297A, - ac97_codec_init, ac97_codec_close, ac97_codec_reset, + ac97_codec_init, + ac97_codec_close, + ac97_codec_reset, { NULL }, NULL, NULL, NULL }; -const device_t stac9708_device = -{ +const device_t stac9708_device = { "SigmaTel STAC9708", "stac9708", DEVICE_AC97, AC97_CODEC_STAC9708, - ac97_codec_init, ac97_codec_close, ac97_codec_reset, + ac97_codec_init, + ac97_codec_close, + ac97_codec_reset, { NULL }, NULL, NULL, NULL }; -const device_t stac9721_device = -{ +const device_t stac9721_device = { "SigmaTel STAC9721", "stac9721", DEVICE_AC97, AC97_CODEC_STAC9721, - ac97_codec_init, ac97_codec_close, ac97_codec_reset, + ac97_codec_init, + ac97_codec_close, + ac97_codec_reset, { NULL }, NULL, NULL, NULL }; -const device_t wm9701a_device = -{ +const device_t wm9701a_device = { "Wolfson WM9701A", "wm9701a", DEVICE_AC97, AC97_CODEC_WM9701A, - ac97_codec_init, ac97_codec_close, ac97_codec_reset, + ac97_codec_init, + ac97_codec_close, + ac97_codec_reset, { NULL }, NULL, NULL, diff --git a/src/sound/snd_ac97_via.c b/src/sound/snd_ac97_via.c index f1feaa99b..53afbdf25 100644 --- a/src/sound/snd_ac97_via.c +++ b/src/sound/snd_ac97_via.c @@ -1,70 +1,69 @@ /* - * 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. * - * VIA AC'97 audio controller emulation. + * VIA AC'97 audio controller emulation. * * * - * Authors: RichardG, + * Authors: RichardG, * - * Copyright 2021 RichardG. + * Copyright 2021 RichardG. */ #include -#include #include -#include +#include #include +#include #define HAVE_STDARG_H + #include <86box/86box.h> #include <86box/device.h> #include <86box/io.h> #include <86box/mem.h> -#include <86box/pic.h> -#include <86box/timer.h> #include <86box/pci.h> -#include <86box/sound.h> +#include <86box/pic.h> #include <86box/snd_ac97.h> - +#include <86box/sound.h> +#include <86box/timer.h> typedef struct { - uint8_t id, always_run; + uint8_t id, always_run; struct _ac97_via_ *dev; - uint32_t entry_ptr, sample_ptr, fifo_pos, fifo_end; - int32_t sample_count; - uint8_t entry_flags, fifo[32], restart; + uint32_t entry_ptr, sample_ptr, fifo_pos, fifo_end; + int32_t sample_count; + uint8_t entry_flags, fifo[32], restart; - int16_t out_l, out_r; - int vol_l, vol_r, pos; - int32_t buffer[SOUNDBUFLEN * 2]; - uint64_t timer_latch; + int16_t out_l, out_r; + int vol_l, vol_r, pos; + int32_t buffer[SOUNDBUFLEN * 2]; + uint64_t timer_latch; - pc_timer_t dma_timer, poll_timer; + pc_timer_t dma_timer, poll_timer; } ac97_via_sgd_t; typedef struct _ac97_via_ { - uint16_t audio_sgd_base, audio_codec_base, modem_sgd_base, modem_codec_base; - uint8_t sgd_regs[256], pcm_enabled: 1, fm_enabled: 1, vsr_enabled: 1; + uint16_t audio_sgd_base, audio_codec_base, modem_sgd_base, modem_codec_base; + uint8_t sgd_regs[256], pcm_enabled : 1, fm_enabled : 1, vsr_enabled : 1; struct { - union { - uint8_t regs_codec[2][128]; - uint8_t regs_linear[256]; - }; + union { + uint8_t regs_codec[2][128]; + uint8_t regs_linear[256]; + }; } codec_shadow[2]; - int slot, irq_pin; + int slot, irq_pin; - ac97_codec_t *codec[2][2]; + ac97_codec_t *codec[2][2]; ac97_via_sgd_t sgd[6]; - int master_vol_l, master_vol_r, cd_vol_l, cd_vol_r; + int master_vol_l, master_vol_r, cd_vol_l, cd_vol_r; } ac97_via_t; - #ifdef ENABLE_AC97_VIA_LOG int ac97_via_do_log = ENABLE_AC97_VIA_LOG; @@ -74,21 +73,19 @@ ac97_via_log(const char *fmt, ...) va_list ap; if (ac97_via_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define ac97_via_log(fmt, ...) +# define ac97_via_log(fmt, ...) #endif - -static void ac97_via_sgd_process(void *priv); -static void ac97_via_update_codec(ac97_via_t *dev); -static void ac97_via_speed_changed(void *priv); -static void ac97_via_filter_cd_audio(int channel, double *buffer, void *priv); - +static void ac97_via_sgd_process(void *priv); +static void ac97_via_update_codec(ac97_via_t *dev); +static void ac97_via_speed_changed(void *priv); +static void ac97_via_filter_cd_audio(int channel, double *buffer, void *priv); void ac97_via_set_slot(void *priv, int slot, int irq_pin) @@ -97,21 +94,20 @@ ac97_via_set_slot(void *priv, int slot, int irq_pin) ac97_via_log("AC97 VIA: set_slot(%d, %d)\n", slot, irq_pin); - dev->slot = slot; + dev->slot = slot; dev->irq_pin = irq_pin; } - uint8_t ac97_via_read_status(void *priv, uint8_t modem) { ac97_via_t *dev = (ac97_via_t *) priv; - uint8_t ret = 0x00; + uint8_t ret = 0x00; /* Flag each codec as ready if present. */ for (uint8_t i = 0; i <= 1; i++) { - if (dev->codec[modem][i]) - ret |= 0x01 << (i << 1); + if (dev->codec[modem][i]) + ret |= 0x01 << (i << 1); } ac97_via_log("AC97 VIA %d: read_status() = %02X\n", modem, ret); @@ -119,63 +115,60 @@ ac97_via_read_status(void *priv, uint8_t modem) return ret; } - void ac97_via_write_control(void *priv, uint8_t modem, uint8_t val) { ac97_via_t *dev = (ac97_via_t *) priv; - uint8_t i; + uint8_t i; ac97_via_log("AC97 VIA %d: write_control(%02X)\n", modem, val); /* Reset codecs if requested. */ if (!(val & 0x40)) { - for (i = 0; i <= 1; i++) { - if (dev->codec[modem][i]) - ac97_codec_reset(dev->codec[modem][i]); - } + for (i = 0; i <= 1; i++) { + if (dev->codec[modem][i]) + ac97_codec_reset(dev->codec[modem][i]); + } } if (!modem) { - /* Set the variable sample rate flag. */ - dev->vsr_enabled = (val & 0xf8) == 0xc8; + /* Set the variable sample rate flag. */ + dev->vsr_enabled = (val & 0xf8) == 0xc8; - /* Start or stop PCM playback. */ - i = (val & 0xf4) == 0xc4; - if (i && !dev->pcm_enabled) - timer_advance_u64(&dev->sgd[0].poll_timer, dev->sgd[0].timer_latch); - dev->pcm_enabled = i; + /* Start or stop PCM playback. */ + i = (val & 0xf4) == 0xc4; + if (i && !dev->pcm_enabled) + timer_advance_u64(&dev->sgd[0].poll_timer, dev->sgd[0].timer_latch); + dev->pcm_enabled = i; - /* Start or stop FM playback. */ - i = (val & 0xf2) == 0xc2; - if (i && !dev->fm_enabled) - timer_advance_u64(&dev->sgd[2].poll_timer, dev->sgd[2].timer_latch); - dev->fm_enabled = i; + /* Start or stop FM playback. */ + i = (val & 0xf2) == 0xc2; + if (i && !dev->fm_enabled) + timer_advance_u64(&dev->sgd[2].poll_timer, dev->sgd[2].timer_latch); + dev->fm_enabled = i; - /* Update primary audio codec state. */ - if (dev->codec[0][0]) - ac97_via_update_codec(dev); + /* Update primary audio codec state. */ + if (dev->codec[0][0]) + ac97_via_update_codec(dev); } } - static void ac97_via_update_irqs(ac97_via_t *dev) { /* Check interrupt flags in all SGDs. */ for (uint8_t i = 0x00; i < ((sizeof(dev->sgd) / sizeof(dev->sgd[0])) << 4); i += 0x10) { - /* Stop immediately if any flag is set. Doing it this way optimizes - rising edges for the playback SGD (0 - first to be checked). */ - if (dev->sgd_regs[i] & (dev->sgd_regs[i | 0x2] & 0x03)) { - pci_set_irq(dev->slot, dev->irq_pin); - return; - } + /* Stop immediately if any flag is set. Doing it this way optimizes + rising edges for the playback SGD (0 - first to be checked). */ + if (dev->sgd_regs[i] & (dev->sgd_regs[i | 0x2] & 0x03)) { + pci_set_irq(dev->slot, dev->irq_pin); + return; + } } pci_clear_irq(dev->slot, dev->irq_pin); } - static void ac97_via_update_codec(ac97_via_t *dev) { @@ -191,7 +184,6 @@ ac97_via_update_codec(ac97_via_t *dev) ac97_via_speed_changed(dev); } - uint8_t ac97_via_sgd_read(uint16_t addr, void *priv) { @@ -203,83 +195,83 @@ ac97_via_sgd_read(uint16_t addr, void *priv) uint8_t ret; if (!(addr & 0x80)) { - /* Process SGD channel registers. */ - switch (addr & 0xf) { - case 0x4: - ret = dev->sgd[addr >> 4].entry_ptr; - break; + /* Process SGD channel registers. */ + switch (addr & 0xf) { + case 0x4: + ret = dev->sgd[addr >> 4].entry_ptr; + break; - case 0x5: - ret = dev->sgd[addr >> 4].entry_ptr >> 8; - break; + case 0x5: + ret = dev->sgd[addr >> 4].entry_ptr >> 8; + break; - case 0x6: - ret = dev->sgd[addr >> 4].entry_ptr >> 16; - break; + case 0x6: + ret = dev->sgd[addr >> 4].entry_ptr >> 16; + break; - case 0x7: - ret = dev->sgd[addr >> 4].entry_ptr >> 24; - break; + case 0x7: + ret = dev->sgd[addr >> 4].entry_ptr >> 24; + break; - case 0xc: - ret = dev->sgd[addr >> 4].sample_count; - break; + case 0xc: + ret = dev->sgd[addr >> 4].sample_count; + break; - case 0xd: - ret = dev->sgd[addr >> 4].sample_count >> 8; - break; + case 0xd: + ret = dev->sgd[addr >> 4].sample_count >> 8; + break; - case 0xe: - ret = dev->sgd[addr >> 4].sample_count >> 16; - break; + case 0xe: + ret = dev->sgd[addr >> 4].sample_count >> 16; + break; - default: - ret = dev->sgd_regs[addr]; - break; - } + default: + ret = dev->sgd_regs[addr]; + break; + } } else { - /* Process regular registers. */ - switch (addr) { - case 0x84: - ret = (dev->sgd_regs[0x00] & 0x01); - ret |= (dev->sgd_regs[0x10] & 0x01) << 1; - ret |= (dev->sgd_regs[0x20] & 0x01) << 2; + /* Process regular registers. */ + switch (addr) { + case 0x84: + ret = (dev->sgd_regs[0x00] & 0x01); + ret |= (dev->sgd_regs[0x10] & 0x01) << 1; + ret |= (dev->sgd_regs[0x20] & 0x01) << 2; - ret |= (dev->sgd_regs[0x00] & 0x02) << 3; - ret |= (dev->sgd_regs[0x10] & 0x02) << 4; - ret |= (dev->sgd_regs[0x20] & 0x02) << 5; - break; + ret |= (dev->sgd_regs[0x00] & 0x02) << 3; + ret |= (dev->sgd_regs[0x10] & 0x02) << 4; + ret |= (dev->sgd_regs[0x20] & 0x02) << 5; + break; - case 0x85: - ret = (dev->sgd_regs[0x00] & 0x04) >> 2; - ret |= (dev->sgd_regs[0x10] & 0x04) >> 1; - ret |= (dev->sgd_regs[0x20] & 0x04); + case 0x85: + ret = (dev->sgd_regs[0x00] & 0x04) >> 2; + ret |= (dev->sgd_regs[0x10] & 0x04) >> 1; + ret |= (dev->sgd_regs[0x20] & 0x04); - ret |= (dev->sgd_regs[0x00] & 0x80) >> 3; - ret |= (dev->sgd_regs[0x10] & 0x80) >> 2; - ret |= (dev->sgd_regs[0x20] & 0x80) >> 1; - break; + ret |= (dev->sgd_regs[0x00] & 0x80) >> 3; + ret |= (dev->sgd_regs[0x10] & 0x80) >> 2; + ret |= (dev->sgd_regs[0x20] & 0x80) >> 1; + break; - case 0x86: - ret = (dev->sgd_regs[0x40] & 0x01); - ret |= (dev->sgd_regs[0x50] & 0x01) << 1; + case 0x86: + ret = (dev->sgd_regs[0x40] & 0x01); + ret |= (dev->sgd_regs[0x50] & 0x01) << 1; - ret |= (dev->sgd_regs[0x40] & 0x02) << 3; - ret |= (dev->sgd_regs[0x50] & 0x02) << 4; - break; + ret |= (dev->sgd_regs[0x40] & 0x02) << 3; + ret |= (dev->sgd_regs[0x50] & 0x02) << 4; + break; - case 0x87: - ret = (dev->sgd_regs[0x40] & 0x04) >> 2; - ret |= (dev->sgd_regs[0x50] & 0x04) >> 1; + case 0x87: + ret = (dev->sgd_regs[0x40] & 0x04) >> 2; + ret |= (dev->sgd_regs[0x50] & 0x04) >> 1; - ret |= (dev->sgd_regs[0x40] & 0x80) >> 3; - ret |= (dev->sgd_regs[0x50] & 0x80) >> 2; - break; + ret |= (dev->sgd_regs[0x40] & 0x80) >> 3; + ret |= (dev->sgd_regs[0x50] & 0x80) >> 2; + break; - default: - ret = dev->sgd_regs[addr]; - break; - } + default: + ret = dev->sgd_regs[addr]; + break; + } } ac97_via_log("AC97 VIA %d: sgd_read(%02X) = %02X\n", modem, addr, ret); @@ -287,12 +279,11 @@ ac97_via_sgd_read(uint16_t addr, void *priv) return ret; } - void ac97_via_sgd_write(uint16_t addr, uint8_t val, void *priv) { - ac97_via_t *dev = (ac97_via_t *) priv; - uint8_t modem = (addr & 0xff00) == dev->modem_sgd_base, i; + ac97_via_t *dev = (ac97_via_t *) priv; + uint8_t modem = (addr & 0xff00) == dev->modem_sgd_base, i; ac97_codec_t *codec; addr &= 0xff; @@ -300,161 +291,158 @@ ac97_via_sgd_write(uint16_t addr, uint8_t val, void *priv) /* Check function-specific read only registers. */ if ((addr >= (modem ? 0x00 : 0x40)) && (addr < (modem ? 0x40 : 0x60))) - return; + return; if (addr >= (modem ? 0x90 : 0x88)) - return; + return; if (!(addr & 0x80)) { - /* Process SGD channel registers. */ - switch (addr & 0xf) { - case 0x0: - /* Clear RWC status bits. */ - dev->sgd_regs[addr] &= ~(val & 0x07); + /* Process SGD channel registers. */ + switch (addr & 0xf) { + case 0x0: + /* Clear RWC status bits. */ + dev->sgd_regs[addr] &= ~(val & 0x07); - /* Update status interrupts. */ - ac97_via_update_irqs(dev); + /* Update status interrupts. */ + ac97_via_update_irqs(dev); - return; + return; - case 0x1: - /* Start SGD if requested. */ - if (val & 0x80) { - if (dev->sgd_regs[addr & 0xf0] & 0x80) { - /* Queue SGD trigger if already running. */ - dev->sgd_regs[addr & 0xf0] |= 0x08; - } else { - /* Start SGD immediately. */ - dev->sgd_regs[addr & 0xf0] |= 0x80; - dev->sgd_regs[addr & 0xf0] &= ~0x44; + case 0x1: + /* Start SGD if requested. */ + if (val & 0x80) { + if (dev->sgd_regs[addr & 0xf0] & 0x80) { + /* Queue SGD trigger if already running. */ + dev->sgd_regs[addr & 0xf0] |= 0x08; + } else { + /* Start SGD immediately. */ + dev->sgd_regs[addr & 0xf0] |= 0x80; + dev->sgd_regs[addr & 0xf0] &= ~0x44; - /* Start at the specified entry pointer. */ - dev->sgd[addr >> 4].sample_ptr = 0; - dev->sgd[addr >> 4].entry_ptr = *((uint32_t *) &dev->sgd_regs[(addr & 0xf0) | 0x4]) & 0xfffffffe; - dev->sgd[addr >> 4].restart = 1; + /* Start at the specified entry pointer. */ + dev->sgd[addr >> 4].sample_ptr = 0; + dev->sgd[addr >> 4].entry_ptr = *((uint32_t *) &dev->sgd_regs[(addr & 0xf0) | 0x4]) & 0xfffffffe; + dev->sgd[addr >> 4].restart = 1; - /* Start the actual SGD process. */ - ac97_via_sgd_process(&dev->sgd[addr >> 4]); - } - } - /* Stop SGD if requested. */ - if (val & 0x40) - dev->sgd_regs[addr & 0xf0] &= ~0x88; + /* Start the actual SGD process. */ + ac97_via_sgd_process(&dev->sgd[addr >> 4]); + } + } + /* Stop SGD if requested. */ + if (val & 0x40) + dev->sgd_regs[addr & 0xf0] &= ~0x88; - val &= 0x08; + val &= 0x08; - /* (Un)pause SGD if requested. */ - if (val & 0x08) - dev->sgd_regs[addr & 0xf0] |= 0x40; - else - dev->sgd_regs[addr & 0xf0] &= ~0x40; + /* (Un)pause SGD if requested. */ + if (val & 0x08) + dev->sgd_regs[addr & 0xf0] |= 0x40; + else + dev->sgd_regs[addr & 0xf0] &= ~0x40; - break; + break; - case 0x2: - if (addr & 0x10) - val &= 0xf3; - break; + case 0x2: + if (addr & 0x10) + val &= 0xf3; + break; - case 0x3: case 0x8 ... 0xf: - /* Read-only registers. */ - return; - } + case 0x3: + case 0x8 ... 0xf: + /* Read-only registers. */ + return; + } } else { - /* Process regular registers. */ - switch (addr) { - case 0x30 ... 0x3f: - case 0x60 ... 0x7f: - case 0x84 ... 0x87: - /* Read-only registers. */ - return; + /* Process regular registers. */ + switch (addr) { + case 0x30 ... 0x3f: + case 0x60 ... 0x7f: + case 0x84 ... 0x87: + /* Read-only registers. */ + return; - case 0x82: - /* Determine the selected codec. */ - i = !!(dev->sgd_regs[0x83] & 0x40); - codec = dev->codec[modem][i]; + case 0x82: + /* Determine the selected codec. */ + i = !!(dev->sgd_regs[0x83] & 0x40); + codec = dev->codec[modem][i]; - /* Keep value in register if this codec is not present. */ - if (codec) { - /* Read from or write to codec. */ - if (val & 0x80) { - if (val & 1) { /* return 0x0000 on unaligned reads (real 686B behavior) */ - dev->sgd_regs[0x80] = dev->sgd_regs[0x81] = 0x00; - } else { - *((uint16_t *) &dev->codec_shadow[modem].regs_codec[i][val & 0x7f]) = *((uint16_t *) &dev->sgd_regs[0x80]) = - ac97_codec_readw(codec, val); - } + /* Keep value in register if this codec is not present. */ + if (codec) { + /* Read from or write to codec. */ + if (val & 0x80) { + if (val & 1) { /* return 0x0000 on unaligned reads (real 686B behavior) */ + dev->sgd_regs[0x80] = dev->sgd_regs[0x81] = 0x00; + } else { + *((uint16_t *) &dev->codec_shadow[modem].regs_codec[i][val & 0x7f]) = *((uint16_t *) &dev->sgd_regs[0x80]) = ac97_codec_readw(codec, val); + } - /* Flag data/status/index for this codec as valid. */ - dev->sgd_regs[0x83] |= 0x02 << (i << 1); - } else if (!(val & 1)) { /* do nothing on unaligned writes */ - ac97_codec_writew(codec, val, - *((uint16_t *) &dev->codec_shadow[modem].regs_codec[i][val & 0x7f]) = *((uint16_t *) &dev->sgd_regs[0x80])); + /* Flag data/status/index for this codec as valid. */ + dev->sgd_regs[0x83] |= 0x02 << (i << 1); + } else if (!(val & 1)) { /* do nothing on unaligned writes */ + ac97_codec_writew(codec, val, + *((uint16_t *) &dev->codec_shadow[modem].regs_codec[i][val & 0x7f]) = *((uint16_t *) &dev->sgd_regs[0x80])); - /* Update primary audio codec state if that codec was written to. */ - if (!modem && !i) { - ac97_via_update_codec(dev); + /* Update primary audio codec state if that codec was written to. */ + if (!modem && !i) { + ac97_via_update_codec(dev); - /* Set up CD audio filter if CD volume was written to. Setting it - up at init prevents CD audio from working on other cards, but - this works as the CD channel is muted by default per AC97 spec. */ - if (val == 0x12) - sound_set_cd_audio_filter(ac97_via_filter_cd_audio, dev); - } - } - } + /* Set up CD audio filter if CD volume was written to. Setting it + up at init prevents CD audio from working on other cards, but + this works as the CD channel is muted by default per AC97 spec. */ + if (val == 0x12) + sound_set_cd_audio_filter(ac97_via_filter_cd_audio, dev); + } + } + } - break; + break; - case 0x83: - /* Clear RWC status bits. */ + case 0x83: + /* Clear RWC status bits. */ #if 0 /* race condition with Linux accessing a register and clearing status bits on the same dword write */ - val = (dev->sgd_regs[addr] & ~(val & 0x0a)) | (val & 0xc0); + val = (dev->sgd_regs[addr] & ~(val & 0x0a)) | (val & 0xc0); #else - val = dev->sgd_regs[addr] | (val & 0xc0); + val = dev->sgd_regs[addr] | (val & 0xc0); #endif - break; - } + break; + } } dev->sgd_regs[addr] = val; } - void ac97_via_remap_audio_sgd(void *priv, uint16_t new_io_base, uint8_t enable) { ac97_via_t *dev = (ac97_via_t *) priv; if (dev->audio_sgd_base) - io_removehandler(dev->audio_sgd_base, 256, ac97_via_sgd_read, NULL, NULL, ac97_via_sgd_write, NULL, NULL, dev); + io_removehandler(dev->audio_sgd_base, 256, ac97_via_sgd_read, NULL, NULL, ac97_via_sgd_write, NULL, NULL, dev); dev->audio_sgd_base = new_io_base; if (dev->audio_sgd_base && enable) - io_sethandler(dev->audio_sgd_base, 256, ac97_via_sgd_read, NULL, NULL, ac97_via_sgd_write, NULL, NULL, dev); + io_sethandler(dev->audio_sgd_base, 256, ac97_via_sgd_read, NULL, NULL, ac97_via_sgd_write, NULL, NULL, dev); } - void ac97_via_remap_modem_sgd(void *priv, uint16_t new_io_base, uint8_t enable) { ac97_via_t *dev = (ac97_via_t *) priv; if (dev->modem_sgd_base) - io_removehandler(dev->modem_sgd_base, 256, ac97_via_sgd_read, NULL, NULL, ac97_via_sgd_write, NULL, NULL, dev); + io_removehandler(dev->modem_sgd_base, 256, ac97_via_sgd_read, NULL, NULL, ac97_via_sgd_write, NULL, NULL, dev); dev->modem_sgd_base = new_io_base; if (dev->modem_sgd_base && enable) - io_sethandler(dev->modem_sgd_base, 256, ac97_via_sgd_read, NULL, NULL, ac97_via_sgd_write, NULL, NULL, dev); + io_sethandler(dev->modem_sgd_base, 256, ac97_via_sgd_read, NULL, NULL, ac97_via_sgd_write, NULL, NULL, dev); } - uint8_t ac97_via_codec_read(uint16_t addr, void *priv) { - ac97_via_t *dev = (ac97_via_t *) priv; - uint8_t modem = (addr & 0xff00) == dev->modem_codec_base; + ac97_via_t *dev = (ac97_via_t *) priv; + uint8_t modem = (addr & 0xff00) == dev->modem_codec_base; addr &= 0xff; uint8_t ret = 0xff; @@ -465,12 +453,11 @@ ac97_via_codec_read(uint16_t addr, void *priv) return ret; } - void ac97_via_codec_write(uint16_t addr, uint8_t val, void *priv) { - ac97_via_t *dev = (ac97_via_t *) priv; - uint8_t modem = (addr & 0xff00) == dev->modem_codec_base; + ac97_via_t *dev = (ac97_via_t *) priv; + uint8_t modem = (addr & 0xff00) == dev->modem_codec_base; addr &= 0xff; ac97_via_log("AC97 VIA %d: codec_write(%02X, %02X)\n", modem, addr, val); @@ -479,239 +466,232 @@ ac97_via_codec_write(uint16_t addr, uint8_t val, void *priv) dev->codec_shadow[modem].regs_linear[addr] = val; } - void ac97_via_remap_audio_codec(void *priv, uint16_t new_io_base, uint8_t enable) { ac97_via_t *dev = (ac97_via_t *) priv; if (dev->audio_codec_base) - io_removehandler(dev->audio_codec_base, 256, ac97_via_codec_read, NULL, NULL, ac97_via_codec_write, NULL, NULL, dev); + io_removehandler(dev->audio_codec_base, 256, ac97_via_codec_read, NULL, NULL, ac97_via_codec_write, NULL, NULL, dev); dev->audio_codec_base = new_io_base; if (dev->audio_codec_base && enable) - io_sethandler(dev->audio_codec_base, 256, ac97_via_codec_read, NULL, NULL, ac97_via_codec_write, NULL, NULL, dev); + io_sethandler(dev->audio_codec_base, 256, ac97_via_codec_read, NULL, NULL, ac97_via_codec_write, NULL, NULL, dev); } - void ac97_via_remap_modem_codec(void *priv, uint16_t new_io_base, uint8_t enable) { ac97_via_t *dev = (ac97_via_t *) priv; if (dev->modem_codec_base) - io_removehandler(dev->modem_codec_base, 256, ac97_via_codec_read, NULL, NULL, ac97_via_codec_write, NULL, NULL, dev); + io_removehandler(dev->modem_codec_base, 256, ac97_via_codec_read, NULL, NULL, ac97_via_codec_write, NULL, NULL, dev); dev->modem_codec_base = new_io_base; if (dev->modem_codec_base && enable) - io_sethandler(dev->modem_codec_base, 256, ac97_via_codec_read, NULL, NULL, ac97_via_codec_write, NULL, NULL, dev); + io_sethandler(dev->modem_codec_base, 256, ac97_via_codec_read, NULL, NULL, ac97_via_codec_write, NULL, NULL, dev); } - static void ac97_via_update_stereo(ac97_via_t *dev, ac97_via_sgd_t *sgd) { int32_t l = (((sgd->out_l * sgd->vol_l) >> 15) * dev->master_vol_l) >> 15, - r = (((sgd->out_r * sgd->vol_r) >> 15) * dev->master_vol_r) >> 15; + r = (((sgd->out_r * sgd->vol_r) >> 15) * dev->master_vol_r) >> 15; if (l < -32768) - l = -32768; + l = -32768; else if (l > 32767) - l = 32767; + l = 32767; if (r < -32768) - r = -32768; + r = -32768; else if (r > 32767) - r = 32767; + r = 32767; for (; sgd->pos < sound_pos_global; sgd->pos++) { - sgd->buffer[sgd->pos*2] = l; - sgd->buffer[sgd->pos*2 + 1] = r; + sgd->buffer[sgd->pos * 2] = l; + sgd->buffer[sgd->pos * 2 + 1] = r; } } - static void ac97_via_sgd_process(void *priv) { ac97_via_sgd_t *sgd = (ac97_via_sgd_t *) priv; - ac97_via_t *dev = sgd->dev; + ac97_via_t *dev = sgd->dev; /* Stop if this SGD is not active. */ uint8_t sgd_status = dev->sgd_regs[sgd->id] & 0xc4; if (!(sgd_status & 0x80)) - return; + return; /* Schedule next run. */ timer_on_auto(&sgd->dma_timer, 10.0); /* Process SGD if it's active, and the FIFO has room or is disabled. */ if ((sgd_status == 0x80) && (sgd->always_run || ((sgd->fifo_end - sgd->fifo_pos) <= (sizeof(sgd->fifo) - 4)))) { - /* Move on to the next block if no entry is present. */ - if (sgd->restart) { - sgd->restart = 0; + /* Move on to the next block if no entry is present. */ + if (sgd->restart) { + sgd->restart = 0; - /* Start at first entry if no pointer is present. */ - if (!sgd->entry_ptr) - sgd->entry_ptr = *((uint32_t *) &dev->sgd_regs[sgd->id | 0x4]) & 0xfffffffe; + /* Start at first entry if no pointer is present. */ + if (!sgd->entry_ptr) + sgd->entry_ptr = *((uint32_t *) &dev->sgd_regs[sgd->id | 0x4]) & 0xfffffffe; - /* Read entry. */ - sgd->sample_ptr = mem_readl_phys(sgd->entry_ptr); - sgd->entry_ptr += 4; - sgd->sample_count = mem_readl_phys(sgd->entry_ptr); - sgd->entry_ptr += 4; + /* Read entry. */ + sgd->sample_ptr = mem_readl_phys(sgd->entry_ptr); + sgd->entry_ptr += 4; + sgd->sample_count = mem_readl_phys(sgd->entry_ptr); + sgd->entry_ptr += 4; #ifdef ENABLE_AC97_VIA_LOG - if (((sgd->sample_ptr == 0xffffffff) && (sgd->sample_count == 0xffffffff)) || - ((sgd->sample_ptr == 0x00000000) && (sgd->sample_count == 0x00000000))) - fatal("AC97 VIA: Invalid SGD %d entry %08X%08X at %08X\n", sgd->id >> 4, - sgd->sample_ptr, sgd->sample_count, sgd->entry_ptr - 8); + if (((sgd->sample_ptr == 0xffffffff) && (sgd->sample_count == 0xffffffff)) || ((sgd->sample_ptr == 0x00000000) && (sgd->sample_count == 0x00000000))) + fatal("AC97 VIA: Invalid SGD %d entry %08X%08X at %08X\n", sgd->id >> 4, + sgd->sample_ptr, sgd->sample_count, sgd->entry_ptr - 8); #endif - /* Extract flags from the most significant byte. */ - sgd->entry_flags = sgd->sample_count >> 24; - sgd->sample_count &= 0xffffff; + /* Extract flags from the most significant byte. */ + sgd->entry_flags = sgd->sample_count >> 24; + sgd->sample_count &= 0xffffff; - ac97_via_log("AC97 VIA: Starting SGD %d block at %08X start %08X len %06X flags %02X\n", sgd->id >> 4, - sgd->entry_ptr - 8, sgd->sample_ptr, sgd->sample_count, sgd->entry_flags); - } + ac97_via_log("AC97 VIA: Starting SGD %d block at %08X start %08X len %06X flags %02X\n", sgd->id >> 4, + sgd->entry_ptr - 8, sgd->sample_ptr, sgd->sample_count, sgd->entry_flags); + } - if (sgd->id & 0x10) { - /* Write channel: read data from FIFO. */ - mem_writel_phys(sgd->sample_ptr, *((uint32_t *) &sgd->fifo[sgd->fifo_end & (sizeof(sgd->fifo) - 1)])); - } else { - /* Read channel: write data to FIFO. */ - *((uint32_t *) &sgd->fifo[sgd->fifo_end & (sizeof(sgd->fifo) - 1)]) = mem_readl_phys(sgd->sample_ptr); - } - sgd->fifo_end += 4; - sgd->sample_ptr += 4; - sgd->sample_count -= 4; + if (sgd->id & 0x10) { + /* Write channel: read data from FIFO. */ + mem_writel_phys(sgd->sample_ptr, *((uint32_t *) &sgd->fifo[sgd->fifo_end & (sizeof(sgd->fifo) - 1)])); + } else { + /* Read channel: write data to FIFO. */ + *((uint32_t *) &sgd->fifo[sgd->fifo_end & (sizeof(sgd->fifo) - 1)]) = mem_readl_phys(sgd->sample_ptr); + } + sgd->fifo_end += 4; + sgd->sample_ptr += 4; + sgd->sample_count -= 4; - /* Check if we've hit the end of this block. */ - if (sgd->sample_count <= 0) { - ac97_via_log("AC97 VIA: Ending SGD %d block", sgd->id >> 4); + /* Check if we've hit the end of this block. */ + if (sgd->sample_count <= 0) { + ac97_via_log("AC97 VIA: Ending SGD %d block", sgd->id >> 4); - if (sgd->entry_flags & 0x20) { - ac97_via_log(" with STOP"); + if (sgd->entry_flags & 0x20) { + ac97_via_log(" with STOP"); - /* Raise STOP to pause SGD. */ - dev->sgd_regs[sgd->id] |= 0x04; - } + /* Raise STOP to pause SGD. */ + dev->sgd_regs[sgd->id] |= 0x04; + } - if (sgd->entry_flags & 0x40) { - ac97_via_log(" with FLAG"); + if (sgd->entry_flags & 0x40) { + ac97_via_log(" with FLAG"); - /* Raise FLAG and STOP. */ - dev->sgd_regs[sgd->id] |= 0x05; + /* Raise FLAG and STOP. */ + dev->sgd_regs[sgd->id] |= 0x05; #ifdef ENABLE_AC97_VIA_LOG - if (dev->sgd_regs[sgd->id | 0x2] & 0x01) - ac97_via_log(" interrupt"); + if (dev->sgd_regs[sgd->id | 0x2] & 0x01) + ac97_via_log(" interrupt"); #endif - } + } - if (sgd->entry_flags & 0x80) { - ac97_via_log(" with EOL"); + if (sgd->entry_flags & 0x80) { + ac97_via_log(" with EOL"); - /* Raise EOL. */ - dev->sgd_regs[sgd->id] |= 0x02; + /* Raise EOL. */ + dev->sgd_regs[sgd->id] |= 0x02; #ifdef ENABLE_AC97_VIA_LOG - if (dev->sgd_regs[sgd->id | 0x2] & 0x02) - ac97_via_log(" interrupt"); + if (dev->sgd_regs[sgd->id | 0x2] & 0x02) + ac97_via_log(" interrupt"); #endif - /* Restart SGD if a trigger is queued or auto-start is enabled. */ - if ((dev->sgd_regs[sgd->id] & 0x08) || (dev->sgd_regs[sgd->id | 0x2] & 0x80)) { - ac97_via_log(" restart"); + /* Restart SGD if a trigger is queued or auto-start is enabled. */ + if ((dev->sgd_regs[sgd->id] & 0x08) || (dev->sgd_regs[sgd->id | 0x2] & 0x80)) { + ac97_via_log(" restart"); - /* Un-queue trigger. */ - dev->sgd_regs[sgd->id] &= ~0x08; + /* Un-queue trigger. */ + dev->sgd_regs[sgd->id] &= ~0x08; - /* Go back to the starting block. */ - sgd->entry_ptr = 0; /* ugly, but Windows XP plays too fast if the pointer is reloaded now */ - } else { - ac97_via_log(" finish"); + /* Go back to the starting block. */ + sgd->entry_ptr = 0; /* ugly, but Windows XP plays too fast if the pointer is reloaded now */ + } else { + ac97_via_log(" finish"); - /* Terminate SGD. */ - dev->sgd_regs[sgd->id] &= ~0x80; - } - } - ac97_via_log("\n"); + /* Terminate SGD. */ + dev->sgd_regs[sgd->id] &= ~0x80; + } + } + ac97_via_log("\n"); - /* Fire any requested status interrupts. */ - ac97_via_update_irqs(dev); + /* Fire any requested status interrupts. */ + ac97_via_update_irqs(dev); - /* Move on to a new block on the next run. */ - sgd->restart = 1; - } + /* Move on to a new block on the next run. */ + sgd->restart = 1; + } } } - static void ac97_via_poll_stereo(void *priv) { - ac97_via_t *dev = (ac97_via_t *) priv; + ac97_via_t *dev = (ac97_via_t *) priv; ac97_via_sgd_t *sgd = &dev->sgd[0]; /* Audio Read */ /* Schedule next run if PCM playback is enabled. */ if (dev->pcm_enabled) - timer_advance_u64(&sgd->poll_timer, sgd->timer_latch); + timer_advance_u64(&sgd->poll_timer, sgd->timer_latch); /* Update stereo audio buffer. */ ac97_via_update_stereo(dev, sgd); /* Feed next sample from the FIFO. */ switch (dev->sgd_regs[sgd->id | 0x2] & 0x30) { - case 0x00: /* Mono, 8-bit PCM */ - if ((sgd->fifo_end - sgd->fifo_pos) >= 1) { - sgd->out_l = sgd->out_r = (sgd->fifo[sgd->fifo_pos++ & (sizeof(sgd->fifo) - 1)] ^ 0x80) << 8; - return; - } - break; + case 0x00: /* Mono, 8-bit PCM */ + if ((sgd->fifo_end - sgd->fifo_pos) >= 1) { + sgd->out_l = sgd->out_r = (sgd->fifo[sgd->fifo_pos++ & (sizeof(sgd->fifo) - 1)] ^ 0x80) << 8; + return; + } + break; - case 0x10: /* Stereo, 8-bit PCM */ - if ((sgd->fifo_end - sgd->fifo_pos) >= 2) { - sgd->out_l = (sgd->fifo[sgd->fifo_pos++ & (sizeof(sgd->fifo) - 1)] ^ 0x80) << 8; - sgd->out_r = (sgd->fifo[sgd->fifo_pos++ & (sizeof(sgd->fifo) - 1)] ^ 0x80) << 8; - return; - } - break; + case 0x10: /* Stereo, 8-bit PCM */ + if ((sgd->fifo_end - sgd->fifo_pos) >= 2) { + sgd->out_l = (sgd->fifo[sgd->fifo_pos++ & (sizeof(sgd->fifo) - 1)] ^ 0x80) << 8; + sgd->out_r = (sgd->fifo[sgd->fifo_pos++ & (sizeof(sgd->fifo) - 1)] ^ 0x80) << 8; + return; + } + break; - case 0x20: /* Mono, 16-bit PCM */ - if ((sgd->fifo_end - sgd->fifo_pos) >= 2) { - sgd->out_l = sgd->out_r = *((uint16_t *) &sgd->fifo[sgd->fifo_pos & (sizeof(sgd->fifo) - 1)]); - sgd->fifo_pos += 2; - return; - } - break; + case 0x20: /* Mono, 16-bit PCM */ + if ((sgd->fifo_end - sgd->fifo_pos) >= 2) { + sgd->out_l = sgd->out_r = *((uint16_t *) &sgd->fifo[sgd->fifo_pos & (sizeof(sgd->fifo) - 1)]); + sgd->fifo_pos += 2; + return; + } + break; - case 0x30: /* Stereo, 16-bit PCM */ - if ((sgd->fifo_end - sgd->fifo_pos) >= 4) { - sgd->out_l = *((uint16_t *) &sgd->fifo[sgd->fifo_pos & (sizeof(sgd->fifo) - 1)]); - sgd->fifo_pos += 2; - sgd->out_r = *((uint16_t *) &sgd->fifo[sgd->fifo_pos & (sizeof(sgd->fifo) - 1)]); - sgd->fifo_pos += 2; - return; - } - break; + case 0x30: /* Stereo, 16-bit PCM */ + if ((sgd->fifo_end - sgd->fifo_pos) >= 4) { + sgd->out_l = *((uint16_t *) &sgd->fifo[sgd->fifo_pos & (sizeof(sgd->fifo) - 1)]); + sgd->fifo_pos += 2; + sgd->out_r = *((uint16_t *) &sgd->fifo[sgd->fifo_pos & (sizeof(sgd->fifo) - 1)]); + sgd->fifo_pos += 2; + return; + } + break; } /* Feed silence if the FIFO is empty. */ sgd->out_l = sgd->out_r = 0; } - static void ac97_via_poll_fm(void *priv) { - ac97_via_t *dev = (ac97_via_t *) priv; + ac97_via_t *dev = (ac97_via_t *) priv; ac97_via_sgd_t *sgd = &dev->sgd[2]; /* FM Read */ /* Schedule next run if FM playback is enabled. */ if (dev->fm_enabled) - timer_advance_u64(&sgd->poll_timer, sgd->timer_latch); + timer_advance_u64(&sgd->poll_timer, sgd->timer_latch); /* Update FM audio buffer. */ ac97_via_update_stereo(dev, sgd); @@ -719,18 +699,17 @@ ac97_via_poll_fm(void *priv) /* Feed next sample from the FIFO. The data format is not documented, but it probes as 16-bit stereo at 24 KHz. */ if ((sgd->fifo_end - sgd->fifo_pos) >= 4) { - sgd->out_l = *((uint16_t *) &sgd->fifo[sgd->fifo_pos & (sizeof(sgd->fifo) - 1)]); - sgd->fifo_pos += 2; - sgd->out_r = *((uint16_t *) &sgd->fifo[sgd->fifo_pos & (sizeof(sgd->fifo) - 1)]); - sgd->fifo_pos += 2; - return; + sgd->out_l = *((uint16_t *) &sgd->fifo[sgd->fifo_pos & (sizeof(sgd->fifo) - 1)]); + sgd->fifo_pos += 2; + sgd->out_r = *((uint16_t *) &sgd->fifo[sgd->fifo_pos & (sizeof(sgd->fifo) - 1)]); + sgd->fifo_pos += 2; + return; } /* Feed silence if the FIFO is empty. */ sgd->out_l = sgd->out_r = 0; } - static void ac97_via_get_buffer(int32_t *buffer, int len, void *priv) { @@ -740,42 +719,39 @@ ac97_via_get_buffer(int32_t *buffer, int len, void *priv) ac97_via_update_stereo(dev, &dev->sgd[2]); for (int c = 0; c < len * 2; c++) { - buffer[c] += dev->sgd[0].buffer[c] / 2; - buffer[c] += dev->sgd[2].buffer[c] / 2; + buffer[c] += dev->sgd[0].buffer[c] / 2; + buffer[c] += dev->sgd[2].buffer[c] / 2; } dev->sgd[0].pos = dev->sgd[2].pos = 0; } - static void ac97_via_filter_cd_audio(int channel, double *buffer, void *priv) { ac97_via_t *dev = (ac97_via_t *) priv; - double c, volume = channel ? dev->cd_vol_r : dev->cd_vol_l; + double c, volume = channel ? dev->cd_vol_r : dev->cd_vol_l; - c = ((*buffer) * volume) / 65536.0; + c = ((*buffer) * volume) / 65536.0; *buffer = c; } - static void ac97_via_speed_changed(void *priv) { ac97_via_t *dev = (ac97_via_t *) priv; - double freq; + double freq; /* Get variable sample rate if enabled. */ if (dev->vsr_enabled && dev->codec[0][0]) - freq = ac97_codec_getrate(dev->codec[0][0], 0x2c); + freq = ac97_codec_getrate(dev->codec[0][0], 0x2c); else - freq = 48000.0; + freq = 48000.0; dev->sgd[0].timer_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / freq)); dev->sgd[2].timer_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / 24000.0)); } - static void * ac97_via_init(const device_t *info) { @@ -785,25 +761,25 @@ ac97_via_init(const device_t *info) ac97_via_log("AC97 VIA: init()\n"); /* Set up codecs. */ - ac97_codec = &dev->codec[0][0]; + ac97_codec = &dev->codec[0][0]; ac97_modem_codec = &dev->codec[1][0]; ac97_codec_count = ac97_modem_codec_count = sizeof(dev->codec[0]) / sizeof(dev->codec[0][0]); ac97_codec_id = ac97_modem_codec_id = 0; /* Set up SGD channels. */ for (uint8_t i = 0; i < (sizeof(dev->sgd) / sizeof(dev->sgd[0])); i++) { - dev->sgd[i].id = i << 4; - dev->sgd[i].dev = dev; + dev->sgd[i].id = i << 4; + dev->sgd[i].dev = dev; - /* Disable the FIFO on SGDs we don't care about. */ - if ((i != 0) && (i != 2)) - dev->sgd[i].always_run = 1; + /* Disable the FIFO on SGDs we don't care about. */ + if ((i != 0) && (i != 2)) + dev->sgd[i].always_run = 1; - /* No volume control on FM SGD that I know of. */ - if (i == 2) - dev->sgd[i].vol_l = dev->sgd[i].vol_r = 32767; + /* No volume control on FM SGD that I know of. */ + if (i == 2) + dev->sgd[i].vol_l = dev->sgd[i].vol_r = 32767; - timer_add(&dev->sgd[i].dma_timer, ac97_via_sgd_process, &dev->sgd[i], 0); + timer_add(&dev->sgd[i].dma_timer, ac97_via_sgd_process, &dev->sgd[i], 0); } /* Set up playback pollers. */ @@ -817,7 +793,6 @@ ac97_via_init(const device_t *info) return dev; } - static void ac97_via_close(void *priv) { @@ -828,14 +803,14 @@ ac97_via_close(void *priv) free(dev); } - -const device_t ac97_via_device = -{ +const device_t ac97_via_device = { "VIA VT82C686 Integrated AC97 Controller", "ac97_via", DEVICE_PCI, 0, - ac97_via_init, ac97_via_close, NULL, + ac97_via_init, + ac97_via_close, + NULL, { NULL }, ac97_via_speed_changed, NULL, diff --git a/src/sound/snd_ad1848.c b/src/sound/snd_ad1848.c index 903bede5e..a72e1472b 100644 --- a/src/sound/snd_ad1848.c +++ b/src/sound/snd_ad1848.c @@ -1,28 +1,29 @@ /* - * 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. * - * AD1848 / CS4248 / CS4231 (Windows Sound System) codec emulation. + * AD1848 / CS4248 / CS4231 (Windows Sound System) codec emulation. * * * - * Authors: Sarah Walker, - * TheCollector1995, - * RichardG, + * Authors: Sarah Walker, + * TheCollector1995, + * RichardG, * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2018-2020 TheCollector1995. - * Copyright 2021-2022 RichardG. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2018-2020 TheCollector1995. + * Copyright 2021-2022 RichardG. */ -#include +#include #include +#include #include #include -#include + #include <86box/86box.h> #include <86box/dma.h> #include <86box/pic.h> @@ -30,14 +31,11 @@ #include <86box/sound.h> #include <86box/snd_ad1848.h> +#define CS4231 0x80 +#define CS4236 0x03 -#define CS4231 0x80 -#define CS4236 0x03 - - -static int ad1848_vols_7bits[128]; -static double ad1848_vols_5bits_aux_gain[32]; - +static int ad1848_vols_7bits[128]; +static double ad1848_vols_5bits_aux_gain[32]; void ad1848_setirq(ad1848_t *ad1848, int irq) @@ -45,485 +43,519 @@ ad1848_setirq(ad1848_t *ad1848, int irq) ad1848->irq = irq; } - void ad1848_setdma(ad1848_t *ad1848, int dma) { ad1848->dma = dma; } - void ad1848_updatevolmask(ad1848_t *ad1848) { if ((ad1848->type >= AD1848_TYPE_CS4235) && ((ad1848->xregs[4] & 0x10) || ad1848->wten)) - ad1848->wave_vol_mask = 0x3f; + ad1848->wave_vol_mask = 0x3f; else - ad1848->wave_vol_mask = 0x7f; + ad1848->wave_vol_mask = 0x7f; } - static void ad1848_updatefreq(ad1848_t *ad1848) { - double freq; + double freq; uint8_t set = 0; if (ad1848->type >= AD1848_TYPE_CS4235) { - if (ad1848->xregs[11] & 0x20) { - freq = 16934400LL; - switch (ad1848->xregs[13]) { - case 1: freq /= 353; break; - case 2: freq /= 529; break; - case 3: freq /= 617; break; - case 4: freq /= 1058; break; - case 5: freq /= 1764; break; - case 6: freq /= 2117; break; - case 7: freq /= 2558; break; - default: freq /= 16 * MAX(ad1848->xregs[13], 21); break; - } - set = 1; - } else if (ad1848->regs[22] & 0x80) { - freq = (ad1848->regs[22] & 1) ? 33868800LL : 49152000LL; - set = (ad1848->regs[22] >> 1) & 0x3f; - switch (ad1848->regs[10] & 0x30) { - case 0x00: freq /= 128 * set; break; - case 0x10: freq /= 64 * set; break; - case 0x20: freq /= 256 * set; break; - } - set = 1; - } + if (ad1848->xregs[11] & 0x20) { + freq = 16934400LL; + switch (ad1848->xregs[13]) { + case 1: + freq /= 353; + break; + case 2: + freq /= 529; + break; + case 3: + freq /= 617; + break; + case 4: + freq /= 1058; + break; + case 5: + freq /= 1764; + break; + case 6: + freq /= 2117; + break; + case 7: + freq /= 2558; + break; + default: + freq /= 16 * MAX(ad1848->xregs[13], 21); + break; + } + set = 1; + } else if (ad1848->regs[22] & 0x80) { + freq = (ad1848->regs[22] & 1) ? 33868800LL : 49152000LL; + set = (ad1848->regs[22] >> 1) & 0x3f; + switch (ad1848->regs[10] & 0x30) { + case 0x00: + freq /= 128 * set; + break; + case 0x10: + freq /= 64 * set; + break; + case 0x20: + freq /= 256 * set; + break; + } + set = 1; + } } if (!set) { - freq = (ad1848->regs[8] & 1) ? 16934400LL : 24576000LL; - switch ((ad1848->regs[8] >> 1) & 7) { - case 0: freq /= 3072; break; - case 1: freq /= 1536; break; - case 2: freq /= 896; break; - case 3: freq /= 768; break; - case 4: freq /= 448; break; - case 5: freq /= 384; break; - case 6: freq /= 512; break; - case 7: freq /= 2560; break; - } + freq = (ad1848->regs[8] & 1) ? 16934400LL : 24576000LL; + switch ((ad1848->regs[8] >> 1) & 7) { + case 0: + freq /= 3072; + break; + case 1: + freq /= 1536; + break; + case 2: + freq /= 896; + break; + case 3: + freq /= 768; + break; + case 4: + freq /= 448; + break; + case 5: + freq /= 384; + break; + case 6: + freq /= 512; + break; + case 7: + freq /= 2560; + break; + } } - ad1848->freq = freq; + ad1848->freq = freq; ad1848->timer_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) ad1848->freq)); } - uint8_t ad1848_read(uint16_t addr, void *priv) { ad1848_t *ad1848 = (ad1848_t *) priv; - uint8_t ret = 0xff; + uint8_t ret = 0xff; switch (addr & 3) { - case 0: /* Index */ - ret = ad1848->index | ad1848->trd | ad1848->mce; - break; + case 0: /* Index */ + ret = ad1848->index | ad1848->trd | ad1848->mce; + break; - case 1: - ret = ad1848->regs[ad1848->index]; - switch (ad1848->index) { - case 11: - ret ^= 0x20; - ad1848->regs[ad1848->index] = ret; - break; + case 1: + ret = ad1848->regs[ad1848->index]; + switch (ad1848->index) { + case 11: + ret ^= 0x20; + ad1848->regs[ad1848->index] = ret; + break; - case 18: case 19: - if (ad1848->type >= AD1848_TYPE_CS4235) { - if ((ad1848->xregs[4] & 0x14) == 0x14) /* FM remapping */ - ret = ad1848->xregs[ad1848->index - 12]; /* real FM volume on registers 6 and 7 */ - else if (ad1848->wten && !(ad1848->xregs[4] & 0x08)) /* wavetable remapping */ - ret = ad1848->xregs[ad1848->index - 2]; /* real wavetable volume on registers 16 and 17 */ - } - break; + case 18: + case 19: + if (ad1848->type >= AD1848_TYPE_CS4235) { + if ((ad1848->xregs[4] & 0x14) == 0x14) /* FM remapping */ + ret = ad1848->xregs[ad1848->index - 12]; /* real FM volume on registers 6 and 7 */ + else if (ad1848->wten && !(ad1848->xregs[4] & 0x08)) /* wavetable remapping */ + ret = ad1848->xregs[ad1848->index - 2]; /* real wavetable volume on registers 16 and 17 */ + } + break; - case 20: case 21: - /* Backdoor to the Control/RAM registers on CS4235. */ - if ((ad1848->type == AD1848_TYPE_CS4235) && (ad1848->xregs[18] & 0x80)) - ret = ad1848->cram_read(ad1848->index - 15, ad1848->cram_priv); - break; + case 20: + case 21: + /* Backdoor to the Control/RAM registers on CS4235. */ + if ((ad1848->type == AD1848_TYPE_CS4235) && (ad1848->xregs[18] & 0x80)) + ret = ad1848->cram_read(ad1848->index - 15, ad1848->cram_priv); + break; - case 23: - if ((ad1848->type >= AD1848_TYPE_CS4235) && (ad1848->regs[23] & 0x08)) { - if ((ad1848->xindex & 0xfe) == 0x00) /* remapped line volume */ - ret = ad1848->regs[18 + ad1848->xindex]; - else - ret = ad1848->xregs[ad1848->xindex]; - } - break; - } - break; + case 23: + if ((ad1848->type >= AD1848_TYPE_CS4235) && (ad1848->regs[23] & 0x08)) { + if ((ad1848->xindex & 0xfe) == 0x00) /* remapped line volume */ + ret = ad1848->regs[18 + ad1848->xindex]; + else + ret = ad1848->xregs[ad1848->xindex]; + } + break; + } + break; - case 2: - ret = ad1848->status; - break; + case 2: + ret = ad1848->status; + break; } return ret; } - void ad1848_write(uint16_t addr, uint8_t val, void *priv) { ad1848_t *ad1848 = (ad1848_t *) priv; - uint8_t temp = 0, updatefreq = 0; + uint8_t temp = 0, updatefreq = 0; switch (addr & 3) { - case 0: /* Index */ - if ((ad1848->regs[12] & 0x40) && (ad1848->type >= AD1848_TYPE_CS4231)) - ad1848->index = val & 0x1f; /* cs4231a extended mode enabled */ - else - ad1848->index = val & 0x0f; /* ad1848/cs4248 mode TODO: some variants/clones DO NOT mirror, just ignore the writes? */ - if (ad1848->type >= AD1848_TYPE_CS4235) - ad1848->regs[23] &= ~0x08; /* clear XRAE */ - ad1848->trd = val & 0x20; - ad1848->mce = val & 0x40; - break; + case 0: /* Index */ + if ((ad1848->regs[12] & 0x40) && (ad1848->type >= AD1848_TYPE_CS4231)) + ad1848->index = val & 0x1f; /* cs4231a extended mode enabled */ + else + ad1848->index = val & 0x0f; /* ad1848/cs4248 mode TODO: some variants/clones DO NOT mirror, just ignore the writes? */ + if (ad1848->type >= AD1848_TYPE_CS4235) + ad1848->regs[23] &= ~0x08; /* clear XRAE */ + ad1848->trd = val & 0x20; + ad1848->mce = val & 0x40; + break; - case 1: - switch (ad1848->index) { - case 10: - if (ad1848->type < AD1848_TYPE_CS4235) - break; - /* fall-through */ + case 1: + switch (ad1848->index) { + case 10: + if (ad1848->type < AD1848_TYPE_CS4235) + break; + /* fall-through */ - case 8: - updatefreq = 1; - break; + case 8: + updatefreq = 1; + break; - case 9: - if (!ad1848->enable && (val & 0x41) == 0x01) { - if (ad1848->timer_latch) - timer_set_delay_u64(&ad1848->timer_count, ad1848->timer_latch); - else - timer_set_delay_u64(&ad1848->timer_count, TIMER_USEC); - } - ad1848->enable = ((val & 0x41) == 0x01); - if (!ad1848->enable) { - timer_disable(&ad1848->timer_count); - ad1848->out_l = ad1848->out_r = 0; - } - break; + case 9: + if (!ad1848->enable && (val & 0x41) == 0x01) { + if (ad1848->timer_latch) + timer_set_delay_u64(&ad1848->timer_count, ad1848->timer_latch); + else + timer_set_delay_u64(&ad1848->timer_count, TIMER_USEC); + } + ad1848->enable = ((val & 0x41) == 0x01); + if (!ad1848->enable) { + timer_disable(&ad1848->timer_count); + ad1848->out_l = ad1848->out_r = 0; + } + break; - case 11: - return; + case 11: + return; - case 12: - if (ad1848->type != AD1848_TYPE_DEFAULT) - ad1848->regs[12] = ((ad1848->regs[12] & 0x0f) + (val & 0xf0)) | 0x80; - return; + case 12: + if (ad1848->type != AD1848_TYPE_DEFAULT) + ad1848->regs[12] = ((ad1848->regs[12] & 0x0f) + (val & 0xf0)) | 0x80; + return; - case 14: - ad1848->count = ad1848->regs[15] | (val << 8); - break; + case 14: + ad1848->count = ad1848->regs[15] | (val << 8); + break; - case 17: - if (ad1848->type >= AD1848_TYPE_CS4231) /* enable additional data formats on modes 2 and 3 */ - ad1848->fmt_mask = (val & 0x40) ? 0xf0 : 0x70; - break; + case 17: + if (ad1848->type >= AD1848_TYPE_CS4231) /* enable additional data formats on modes 2 and 3 */ + ad1848->fmt_mask = (val & 0x40) ? 0xf0 : 0x70; + break; - case 18: case 19: - if (ad1848->type >= AD1848_TYPE_CS4235) { - if ((ad1848->xregs[4] & 0x14) == 0x14) { /* FM remapping */ - ad1848->xregs[ad1848->index - 12] = val; /* real FM volume on extended registers 6 and 7 */ - temp = 1; + case 18: + case 19: + if (ad1848->type >= AD1848_TYPE_CS4235) { + if ((ad1848->xregs[4] & 0x14) == 0x14) { /* FM remapping */ + ad1848->xregs[ad1848->index - 12] = val; /* real FM volume on extended registers 6 and 7 */ + temp = 1; - if (ad1848->index == 18) { - if (val & 0x80) - ad1848->fm_vol_l = 0; - else - ad1848->fm_vol_l = ad1848_vols_7bits[val & 0x3f]; - } else { - if (val & 0x80) - ad1848->fm_vol_r = 0; - else - ad1848->fm_vol_r = ad1848_vols_7bits[val & 0x3f]; - } - } - if (ad1848->wten && !(ad1848->xregs[4] & 0x08)) { /* wavetable remapping */ - ad1848->xregs[ad1848->index - 2] = val; /* real wavetable volume on extended registers 16 and 17 */ - temp = 1; - } + if (ad1848->index == 18) { + if (val & 0x80) + ad1848->fm_vol_l = 0; + else + ad1848->fm_vol_l = ad1848_vols_7bits[val & 0x3f]; + } else { + if (val & 0x80) + ad1848->fm_vol_r = 0; + else + ad1848->fm_vol_r = ad1848_vols_7bits[val & 0x3f]; + } + } + if (ad1848->wten && !(ad1848->xregs[4] & 0x08)) { /* wavetable remapping */ + ad1848->xregs[ad1848->index - 2] = val; /* real wavetable volume on extended registers 16 and 17 */ + temp = 1; + } - /* Stop here if any remapping is enabled. */ - if (temp) - return; + /* Stop here if any remapping is enabled. */ + if (temp) + return; - /* HACK: the Windows 9x driver's "Synth" control writes to this - register with no remapping, even if internal FM is enabled. */ - if (ad1848->index == 18) { - if (val & 0x80) - ad1848->fm_vol_l = 0; - else - ad1848->fm_vol_l = (int) ad1848_vols_5bits_aux_gain[val & 0x1f]; - } else { - if (val & 0x80) - ad1848->fm_vol_r = 0; - else - ad1848->fm_vol_r = (int) ad1848_vols_5bits_aux_gain[val & 0x1f]; - } - } - break; + /* HACK: the Windows 9x driver's "Synth" control writes to this + register with no remapping, even if internal FM is enabled. */ + if (ad1848->index == 18) { + if (val & 0x80) + ad1848->fm_vol_l = 0; + else + ad1848->fm_vol_l = (int) ad1848_vols_5bits_aux_gain[val & 0x1f]; + } else { + if (val & 0x80) + ad1848->fm_vol_r = 0; + else + ad1848->fm_vol_r = (int) ad1848_vols_5bits_aux_gain[val & 0x1f]; + } + } + break; - case 20: case 21: - /* Backdoor to the Control/RAM registers on CS4235. */ - if ((ad1848->type == AD1848_TYPE_CS4235) && (ad1848->xregs[18] & 0x80)) { - ad1848->cram_write(ad1848->index - 15, val, ad1848->cram_priv); - val = ad1848->regs[ad1848->index]; - } - break; + case 20: + case 21: + /* Backdoor to the Control/RAM registers on CS4235. */ + if ((ad1848->type == AD1848_TYPE_CS4235) && (ad1848->xregs[18] & 0x80)) { + ad1848->cram_write(ad1848->index - 15, val, ad1848->cram_priv); + val = ad1848->regs[ad1848->index]; + } + break; - case 22: - updatefreq = 1; - break; + case 22: + updatefreq = 1; + break; - case 23: - if ((ad1848->type >= AD1848_TYPE_CS4235) && ((ad1848->regs[12] & 0x60) == 0x60)) { - if (!(ad1848->regs[23] & 0x08)) { /* existing (not new) XRAE is clear */ - ad1848->xindex = ((val & 0x04) << 2) | (val >> 4); - break; - } + case 23: + if ((ad1848->type >= AD1848_TYPE_CS4235) && ((ad1848->regs[12] & 0x60) == 0x60)) { + if (!(ad1848->regs[23] & 0x08)) { /* existing (not new) XRAE is clear */ + ad1848->xindex = ((val & 0x04) << 2) | (val >> 4); + break; + } - switch (ad1848->xindex) { - case 0: case 1: /* remapped line volume */ - ad1848->regs[18 + ad1848->xindex] = val; - return; + switch (ad1848->xindex) { + case 0: + case 1: /* remapped line volume */ + ad1848->regs[18 + ad1848->xindex] = val; + return; - case 6: - if (val & 0x80) - ad1848->fm_vol_l = 0; - else - ad1848->fm_vol_l = ad1848_vols_7bits[val & 0x3f]; - break; + case 6: + if (val & 0x80) + ad1848->fm_vol_l = 0; + else + ad1848->fm_vol_l = ad1848_vols_7bits[val & 0x3f]; + break; - case 7: - if (val & 0x80) - ad1848->fm_vol_r = 0; - else - ad1848->fm_vol_r = ad1848_vols_7bits[val & 0x3f]; - break; + case 7: + if (val & 0x80) + ad1848->fm_vol_r = 0; + else + ad1848->fm_vol_r = ad1848_vols_7bits[val & 0x3f]; + break; - case 11: case 13: - updatefreq = 1; - break; + case 11: + case 13: + updatefreq = 1; + break; - case 25: - return; - } - ad1848->xregs[ad1848->xindex] = val; + case 25: + return; + } + ad1848->xregs[ad1848->xindex] = val; - if (updatefreq) - ad1848_updatefreq(ad1848); + if (updatefreq) + ad1848_updatefreq(ad1848); - return; - } - break; + return; + } + break; - case 24: - val = ad1848->regs[24] & ((val & 0x70) | 0x0f); - if (!(val & 0x70)) { - ad1848->status &= 0xfe; - picintc(1 << ad1848->irq); - } - break; + case 24: + val = ad1848->regs[24] & ((val & 0x70) | 0x0f); + if (!(val & 0x70)) { + ad1848->status &= 0xfe; + picintc(1 << ad1848->irq); + } + break; - case 25: - return; - } - ad1848->regs[ad1848->index] = val; + case 25: + return; + } + ad1848->regs[ad1848->index] = val; - if (updatefreq) - ad1848_updatefreq(ad1848); + if (updatefreq) + ad1848_updatefreq(ad1848); - if (ad1848->type >= AD1848_TYPE_CS4231) { /* TODO: configure CD volume for CS4248/AD1848 too */ - temp = (ad1848->type == AD1848_TYPE_CS4231) ? 18 : 4; - if (ad1848->regs[temp] & 0x80) - ad1848->cd_vol_l = 0; - else - ad1848->cd_vol_l = ad1848_vols_5bits_aux_gain[ad1848->regs[temp] & 0x1f]; - temp++; - if (ad1848->regs[temp] & 0x80) - ad1848->cd_vol_r = 0; - else - ad1848->cd_vol_r = ad1848_vols_5bits_aux_gain[ad1848->regs[temp] & 0x1f]; - } - break; + if (ad1848->type >= AD1848_TYPE_CS4231) { /* TODO: configure CD volume for CS4248/AD1848 too */ + temp = (ad1848->type == AD1848_TYPE_CS4231) ? 18 : 4; + if (ad1848->regs[temp] & 0x80) + ad1848->cd_vol_l = 0; + else + ad1848->cd_vol_l = ad1848_vols_5bits_aux_gain[ad1848->regs[temp] & 0x1f]; + temp++; + if (ad1848->regs[temp] & 0x80) + ad1848->cd_vol_r = 0; + else + ad1848->cd_vol_r = ad1848_vols_5bits_aux_gain[ad1848->regs[temp] & 0x1f]; + } + break; - case 2: - ad1848->status &= 0xfe; - ad1848->regs[24] &= 0x0f; - break; + case 2: + ad1848->status &= 0xfe; + ad1848->regs[24] &= 0x0f; + break; } } - void ad1848_speed_changed(ad1848_t *ad1848) { ad1848->timer_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) ad1848->freq)); } - void ad1848_update(ad1848_t *ad1848) { for (; ad1848->pos < sound_pos_global; ad1848->pos++) { - ad1848->buffer[ad1848->pos*2] = ad1848->out_l; - ad1848->buffer[ad1848->pos*2 + 1] = ad1848->out_r; + ad1848->buffer[ad1848->pos * 2] = ad1848->out_l; + ad1848->buffer[ad1848->pos * 2 + 1] = ad1848->out_r; } } - static void ad1848_poll(void *priv) { ad1848_t *ad1848 = (ad1848_t *) priv; if (ad1848->timer_latch) - timer_advance_u64(&ad1848->timer_count, ad1848->timer_latch); + timer_advance_u64(&ad1848->timer_count, ad1848->timer_latch); else - timer_advance_u64(&ad1848->timer_count, TIMER_USEC * 1000); + timer_advance_u64(&ad1848->timer_count, TIMER_USEC * 1000); ad1848_update(ad1848); if (ad1848->enable) { - int32_t temp; + int32_t temp; - switch (ad1848->regs[8] & ad1848->fmt_mask) { - case 0x00: /* Mono, 8-bit PCM */ - ad1848->out_l = ad1848->out_r = (dma_channel_read(ad1848->dma) ^ 0x80) * 256; - break; + switch (ad1848->regs[8] & ad1848->fmt_mask) { + case 0x00: /* Mono, 8-bit PCM */ + ad1848->out_l = ad1848->out_r = (dma_channel_read(ad1848->dma) ^ 0x80) * 256; + break; - case 0x10: /* Stereo, 8-bit PCM */ - ad1848->out_l = (dma_channel_read(ad1848->dma) ^ 0x80) * 256; - ad1848->out_r = (dma_channel_read(ad1848->dma) ^ 0x80) * 256; - break; + case 0x10: /* Stereo, 8-bit PCM */ + ad1848->out_l = (dma_channel_read(ad1848->dma) ^ 0x80) * 256; + ad1848->out_r = (dma_channel_read(ad1848->dma) ^ 0x80) * 256; + break; - case 0x40: /* Mono, 16-bit PCM little endian */ - temp = dma_channel_read(ad1848->dma); - ad1848->out_l = ad1848->out_r = (dma_channel_read(ad1848->dma) << 8) | temp; - break; + case 0x40: /* Mono, 16-bit PCM little endian */ + temp = dma_channel_read(ad1848->dma); + ad1848->out_l = ad1848->out_r = (dma_channel_read(ad1848->dma) << 8) | temp; + break; - case 0x50: /* Stereo, 16-bit PCM little endian */ - temp = dma_channel_read(ad1848->dma); - ad1848->out_l = (dma_channel_read(ad1848->dma) << 8) | temp; - temp = dma_channel_read(ad1848->dma); - ad1848->out_r = (dma_channel_read(ad1848->dma) << 8) | temp; - break; + case 0x50: /* Stereo, 16-bit PCM little endian */ + temp = dma_channel_read(ad1848->dma); + ad1848->out_l = (dma_channel_read(ad1848->dma) << 8) | temp; + temp = dma_channel_read(ad1848->dma); + ad1848->out_r = (dma_channel_read(ad1848->dma) << 8) | temp; + break; - case 0xc0: /* Mono, 16-bit PCM big endian */ - temp = dma_channel_read(ad1848->dma); - ad1848->out_l = ad1848->out_r = dma_channel_read(ad1848->dma) | (temp << 8); - break; + case 0xc0: /* Mono, 16-bit PCM big endian */ + temp = dma_channel_read(ad1848->dma); + ad1848->out_l = ad1848->out_r = dma_channel_read(ad1848->dma) | (temp << 8); + break; - case 0xd0: /* Stereo, 16-bit PCM big endian */ - temp = dma_channel_read(ad1848->dma); - ad1848->out_l = dma_channel_read(ad1848->dma) | (temp << 8); - temp = dma_channel_read(ad1848->dma); - ad1848->out_r = dma_channel_read(ad1848->dma) | (temp << 8); - break; - } + case 0xd0: /* Stereo, 16-bit PCM big endian */ + temp = dma_channel_read(ad1848->dma); + ad1848->out_l = dma_channel_read(ad1848->dma) | (temp << 8); + temp = dma_channel_read(ad1848->dma); + ad1848->out_r = dma_channel_read(ad1848->dma) | (temp << 8); + break; + } - if (ad1848->regs[6] & 0x80) - ad1848->out_l = 0; - else - ad1848->out_l = (ad1848->out_l * ad1848_vols_7bits[ad1848->regs[6] & ad1848->wave_vol_mask]) >> 16; + if (ad1848->regs[6] & 0x80) + ad1848->out_l = 0; + else + ad1848->out_l = (ad1848->out_l * ad1848_vols_7bits[ad1848->regs[6] & ad1848->wave_vol_mask]) >> 16; - if (ad1848->regs[7] & 0x80) - ad1848->out_r = 0; - else - ad1848->out_r = (ad1848->out_r * ad1848_vols_7bits[ad1848->regs[7] & ad1848->wave_vol_mask]) >> 16; + if (ad1848->regs[7] & 0x80) + ad1848->out_r = 0; + else + ad1848->out_r = (ad1848->out_r * ad1848_vols_7bits[ad1848->regs[7] & ad1848->wave_vol_mask]) >> 16; - if (ad1848->count < 0) { - ad1848->count = ad1848->regs[15] | (ad1848->regs[14] << 8); - if (!(ad1848->status & 0x01)) { - ad1848->status |= 0x01; - ad1848->regs[24] |= 0x10; - if (ad1848->regs[10] & 2) - picint(1 << ad1848->irq); - } - } + if (ad1848->count < 0) { + ad1848->count = ad1848->regs[15] | (ad1848->regs[14] << 8); + if (!(ad1848->status & 0x01)) { + ad1848->status |= 0x01; + ad1848->regs[24] |= 0x10; + if (ad1848->regs[10] & 2) + picint(1 << ad1848->irq); + } + } - ad1848->count--; + ad1848->count--; } else { - ad1848->out_l = ad1848->out_r = 0; - ad1848->cd_vol_l = ad1848->cd_vol_r = 0; + ad1848->out_l = ad1848->out_r = 0; + ad1848->cd_vol_l = ad1848->cd_vol_r = 0; } } - void ad1848_filter_cd_audio(int channel, double *buffer, void *priv) { ad1848_t *ad1848 = (ad1848_t *) priv; - double c; - double volume = channel ? ad1848->cd_vol_r : ad1848->cd_vol_l; + double c; + double volume = channel ? ad1848->cd_vol_r : ad1848->cd_vol_l; - c = ((*buffer) * volume) / 65536.0; + c = ((*buffer) * volume) / 65536.0; *buffer = c; } - void ad1848_init(ad1848_t *ad1848, uint8_t type) { uint8_t c; - double attenuation; + double attenuation; ad1848->status = 0xcc; ad1848->index = ad1848->trd = 0; - ad1848->mce = 0x40; - ad1848->wten = 0; + ad1848->mce = 0x40; + ad1848->wten = 0; ad1848->regs[0] = ad1848->regs[1] = 0; ad1848->regs[2] = ad1848->regs[3] = 0x80; /* Line-in */ ad1848->regs[4] = ad1848->regs[5] = 0x80; ad1848->regs[6] = ad1848->regs[7] = 0x80; /* Left/right Output */ - ad1848->regs[8] = 0; - ad1848->regs[9] = 0x08; + ad1848->regs[8] = 0; + ad1848->regs[9] = 0x08; ad1848->regs[10] = ad1848->regs[11] = 0; if ((type == AD1848_TYPE_CS4248) || (type == AD1848_TYPE_CS4231) || (type >= AD1848_TYPE_CS4235)) - ad1848->regs[12] = 0x8a; + ad1848->regs[12] = 0x8a; else - ad1848->regs[12] = 0xa; + ad1848->regs[12] = 0xa; ad1848->regs[13] = 0; ad1848->regs[14] = ad1848->regs[15] = 0; if (type == AD1848_TYPE_CS4231) { - ad1848->regs[16] = ad1848->regs[17] = 0; - ad1848->regs[18] = ad1848->regs[19] = 0x88; - ad1848->regs[22] = 0x80; - ad1848->regs[24] = 0; - ad1848->regs[25] = CS4231; - ad1848->regs[26] = 0x80; - ad1848->regs[29] = 0x80; + ad1848->regs[16] = ad1848->regs[17] = 0; + ad1848->regs[18] = ad1848->regs[19] = 0x88; + ad1848->regs[22] = 0x80; + ad1848->regs[24] = 0; + ad1848->regs[25] = CS4231; + ad1848->regs[26] = 0x80; + ad1848->regs[29] = 0x80; } else if (type >= AD1848_TYPE_CS4235) { - ad1848->regs[16] = ad1848->regs[17] = 0; - ad1848->regs[18] = ad1848->regs[19] = 0; - ad1848->regs[20] = ad1848->regs[21] = 0; - ad1848->regs[22] = ad1848->regs[23] = 0; - ad1848->regs[24] = 0; - ad1848->regs[25] = CS4236; - ad1848->regs[26] = 0xa0; - ad1848->regs[27] = ad1848->regs[29] = 0; - ad1848->regs[30] = ad1848->regs[31] = 0; + ad1848->regs[16] = ad1848->regs[17] = 0; + ad1848->regs[18] = ad1848->regs[19] = 0; + ad1848->regs[20] = ad1848->regs[21] = 0; + ad1848->regs[22] = ad1848->regs[23] = 0; + ad1848->regs[24] = 0; + ad1848->regs[25] = CS4236; + ad1848->regs[26] = 0xa0; + ad1848->regs[27] = ad1848->regs[29] = 0; + ad1848->regs[30] = ad1848->regs[31] = 0; - ad1848->xregs[0] = ad1848->xregs[1] = 0xe8; - ad1848->xregs[2] = ad1848->xregs[3] = 0xcf; - ad1848->xregs[4] = 0x84; - ad1848->xregs[5] = 0; - ad1848->xregs[6] = ad1848->xregs[7] = 0x80; - ad1848->xregs[8] = ad1848->xregs[9] = 0; - ad1848->xregs[10] = 0x3f; - ad1848->xregs[11] = 0xc0; - ad1848->xregs[14] = ad1848->xregs[15] = 0; - ad1848->xregs[16] = ad1848->xregs[17] = 0; + ad1848->xregs[0] = ad1848->xregs[1] = 0xe8; + ad1848->xregs[2] = ad1848->xregs[3] = 0xcf; + ad1848->xregs[4] = 0x84; + ad1848->xregs[5] = 0; + ad1848->xregs[6] = ad1848->xregs[7] = 0x80; + ad1848->xregs[8] = ad1848->xregs[9] = 0; + ad1848->xregs[10] = 0x3f; + ad1848->xregs[11] = 0xc0; + ad1848->xregs[14] = ad1848->xregs[15] = 0; + ad1848->xregs[16] = ad1848->xregs[17] = 0; } ad1848_updatefreq(ad1848); @@ -534,34 +566,46 @@ ad1848_init(ad1848_t *ad1848, uint8_t type) ad1848->fmt_mask = 0x70; for (c = 0; c < 128; c++) { - attenuation = 0.0; - if (c & 0x40) { - if (c < 72) attenuation = (c - 72) * -1.5; - } else { - if (c & 0x01) attenuation -= 1.5; - if (c & 0x02) attenuation -= 3.0; - if (c & 0x04) attenuation -= 6.0; - if (c & 0x08) attenuation -= 12.0; - if (c & 0x10) attenuation -= 24.0; - if (c & 0x20) attenuation -= 48.0; - } + attenuation = 0.0; + if (c & 0x40) { + if (c < 72) + attenuation = (c - 72) * -1.5; + } else { + if (c & 0x01) + attenuation -= 1.5; + if (c & 0x02) + attenuation -= 3.0; + if (c & 0x04) + attenuation -= 6.0; + if (c & 0x08) + attenuation -= 12.0; + if (c & 0x10) + attenuation -= 24.0; + if (c & 0x20) + attenuation -= 48.0; + } - attenuation = pow(10, attenuation / 10); + attenuation = pow(10, attenuation / 10); - ad1848_vols_7bits[c] = (int) (attenuation * 65536); + ad1848_vols_7bits[c] = (int) (attenuation * 65536); } for (c = 0; c < 32; c++) { - attenuation = 12.0; - if (c & 0x01) attenuation -= 1.5; - if (c & 0x02) attenuation -= 3.0; - if (c & 0x04) attenuation -= 6.0; - if (c & 0x08) attenuation -= 12.0; - if (c & 0x10) attenuation -= 24.0; + attenuation = 12.0; + if (c & 0x01) + attenuation -= 1.5; + if (c & 0x02) + attenuation -= 3.0; + if (c & 0x04) + attenuation -= 6.0; + if (c & 0x08) + attenuation -= 12.0; + if (c & 0x10) + attenuation -= 24.0; - attenuation = pow(10, attenuation / 10); + attenuation = pow(10, attenuation / 10); - ad1848_vols_5bits_aux_gain[c] = (attenuation * 65536); + ad1848_vols_5bits_aux_gain[c] = (attenuation * 65536); } ad1848->type = type; @@ -569,5 +613,5 @@ ad1848_init(ad1848_t *ad1848, uint8_t type) timer_add(&ad1848->timer_count, ad1848_poll, ad1848, 0); if ((ad1848->type != AD1848_TYPE_DEFAULT) && (ad1848->type != AD1848_TYPE_CS4248)) - sound_set_cd_audio_filter(ad1848_filter_cd_audio, ad1848); + sound_set_cd_audio_filter(ad1848_filter_cd_audio, ad1848); } diff --git a/src/sound/snd_adlib.c b/src/sound/snd_adlib.c index 4ea851d6b..f4326f87b 100644 --- a/src/sound/snd_adlib.c +++ b/src/sound/snd_adlib.c @@ -1,147 +1,170 @@ #include #include #include -#include #include +#include #include #define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/io.h> -#include <86box/timer.h> -#include <86box/mca.h> -#include <86box/device.h> -#include <86box/sound.h> -#include <86box/snd_opl.h> +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/mca.h> +#include <86box/sound.h> +#include <86box/timer.h> +#include <86box/snd_opl.h> #ifdef ENABLE_ADLIB_LOG int adlib_do_log = ENABLE_ADLIB_LOG; - static void adlib_log(const char *fmt, ...) { va_list ap; if (adlib_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define adlib_log(fmt, ...) +# define adlib_log(fmt, ...) #endif +typedef struct adlib_t { + opl_t opl; -typedef struct adlib_t -{ - opl_t opl; - - uint8_t pos_regs[8]; + uint8_t pos_regs[8]; } adlib_t; - -static void adlib_get_buffer(int32_t *buffer, int len, void *p) +static void +adlib_get_buffer(int32_t *buffer, int len, void *p) { - adlib_t *adlib = (adlib_t *)p; - int c; + adlib_t *adlib = (adlib_t *) p; + int c; - opl2_update(&adlib->opl); + opl2_update(&adlib->opl); - for (c = 0; c < len * 2; c++) - buffer[c] += (int32_t)adlib->opl.buffer[c]; + for (c = 0; c < len * 2; c++) + buffer[c] += (int32_t) adlib->opl.buffer[c]; - adlib->opl.pos = 0; + adlib->opl.pos = 0; } -uint8_t adlib_mca_read(int port, void *p) +uint8_t +adlib_mca_read(int port, void *p) { - adlib_t *adlib = (adlib_t *)p; + adlib_t *adlib = (adlib_t *) p; - adlib_log("adlib_mca_read: port=%04x\n", port); + adlib_log("adlib_mca_read: port=%04x\n", port); - return adlib->pos_regs[port & 7]; + return adlib->pos_regs[port & 7]; } -void adlib_mca_write(int port, uint8_t val, void *p) +void +adlib_mca_write(int port, uint8_t val, void *p) { - adlib_t *adlib = (adlib_t *)p; + adlib_t *adlib = (adlib_t *) p; - if (port < 0x102) - return; + if (port < 0x102) + return; - adlib_log("adlib_mca_write: port=%04x val=%02x\n", port, val); + adlib_log("adlib_mca_write: port=%04x val=%02x\n", port, val); - switch (port) - { - case 0x102: - if ((adlib->pos_regs[2] & 1) && !(val & 1)) - io_removehandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &adlib->opl); - if (!(adlib->pos_regs[2] & 1) && (val & 1)) - io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &adlib->opl); - break; - } - adlib->pos_regs[port & 7] = val; + switch (port) { + case 0x102: + if ((adlib->pos_regs[2] & 1) && !(val & 1)) + io_removehandler(0x0388, 0x0002, + opl2_read, NULL, NULL, + opl2_write, NULL, NULL, + &adlib->opl); + if (!(adlib->pos_regs[2] & 1) && (val & 1)) + io_sethandler(0x0388, 0x0002, + opl2_read, NULL, NULL, + opl2_write, NULL, NULL, + &adlib->opl); + break; + } + adlib->pos_regs[port & 7] = val; } -uint8_t adlib_mca_feedb(void *p) +uint8_t +adlib_mca_feedb(void *p) { - adlib_t *adlib = (adlib_t *)p; + adlib_t *adlib = (adlib_t *) p; - return (adlib->pos_regs[2] & 1); + return (adlib->pos_regs[2] & 1); } - -void *adlib_init(const device_t *info) +void * +adlib_init(const device_t *info) { - adlib_t *adlib = malloc(sizeof(adlib_t)); - memset(adlib, 0, sizeof(adlib_t)); + adlib_t *adlib = malloc(sizeof(adlib_t)); + memset(adlib, 0, sizeof(adlib_t)); - adlib_log("adlib_init\n"); - opl2_init(&adlib->opl); - io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &adlib->opl); - sound_add_handler(adlib_get_buffer, adlib); - return adlib; + adlib_log("adlib_init\n"); + opl2_init(&adlib->opl); + io_sethandler(0x0388, 0x0002, + opl2_read, NULL, NULL, + opl2_write, NULL, NULL, + &adlib->opl); + sound_add_handler(adlib_get_buffer, adlib); + return adlib; } -void *adlib_mca_init(const device_t *info) +void * +adlib_mca_init(const device_t *info) { - adlib_t *adlib = adlib_init(info); + adlib_t *adlib = adlib_init(info); - io_removehandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &adlib->opl); - mca_add(adlib_mca_read, adlib_mca_write, adlib_mca_feedb, NULL, adlib); - adlib->pos_regs[0] = 0xd7; - adlib->pos_regs[1] = 0x70; + io_removehandler(0x0388, 0x0002, + opl2_read, NULL, NULL, + opl2_write, NULL, NULL, + &adlib->opl); + mca_add(adlib_mca_read, + adlib_mca_write, + adlib_mca_feedb, + NULL, + adlib); + adlib->pos_regs[0] = 0xd7; + adlib->pos_regs[1] = 0x70; - return adlib; + return adlib; } -void adlib_close(void *p) +void +adlib_close(void *p) { - adlib_t *adlib = (adlib_t *)p; + adlib_t *adlib = (adlib_t *) p; - free(adlib); + free(adlib); } -const device_t adlib_device = -{ - "AdLib", - "adlib", - DEVICE_ISA, - 0, - adlib_init, adlib_close, NULL, - { NULL }, NULL, NULL, - NULL +const device_t adlib_device = { + "AdLib", + "adlib", + DEVICE_ISA, + 0, + adlib_init, + adlib_close, + NULL, + { NULL }, + NULL, + NULL, + NULL }; -const device_t adlib_mca_device = -{ - "AdLib (MCA)", - "adlib_mca", - DEVICE_MCA, - 0, - adlib_init, adlib_close, NULL, - { NULL }, NULL, NULL, - NULL +const device_t adlib_mca_device = { + "AdLib (MCA)", + "adlib_mca", + DEVICE_MCA, + 0, + adlib_init, + adlib_close, + NULL, + { NULL }, + NULL, + NULL, + NULL }; diff --git a/src/sound/snd_adlibgold.c b/src/sound/snd_adlibgold.c index 1c4c678b0..fc169d5e0 100644 --- a/src/sound/snd_adlibgold.c +++ b/src/sound/snd_adlibgold.c @@ -1,1036 +1,1004 @@ -#include #include -#include +#include #include +#include #include + #include <86box/86box.h> -#include <86box/io.h> -#include <86box/timer.h> -#include <86box/dma.h> -#include <86box/pic.h> #include <86box/device.h> -#include <86box/gameport.h> -#include <86box/nvr.h> -#include <86box/sound.h> +#include <86box/dma.h> #include <86box/filters.h> +#include <86box/gameport.h> +#include <86box/io.h> #include <86box/midi.h> +#include <86box/timer.h> +#include <86box/nvr.h> +#include <86box/pic.h> +#include <86box/sound.h> #include <86box/snd_opl.h> #include <86box/snd_ym7128.h> +typedef struct adgold_t { + int adgold_irq_status; -typedef struct adgold_t -{ - int adgold_irq_status; + uint8_t adgold_eeprom[0x1a]; - uint8_t adgold_eeprom[0x1a]; + uint8_t adgold_status; + int adgold_38x_state, adgold_38x_addr; + uint8_t adgold_38x_regs[0x1a]; - uint8_t adgold_status; - int adgold_38x_state, adgold_38x_addr; - uint8_t adgold_38x_regs[0x1a]; + int adgold_mma_addr; + uint8_t adgold_mma_regs[2][0xe]; - int adgold_mma_addr; - uint8_t adgold_mma_regs[2][0xe]; + int adgold_mma_enable[2]; + uint8_t adgold_mma_fifo[2][256]; + int adgold_mma_fifo_start[2], adgold_mma_fifo_end[2]; + uint8_t adgold_mma_status; - int adgold_mma_enable[2]; - uint8_t adgold_mma_fifo[2][256]; - int adgold_mma_fifo_start[2], adgold_mma_fifo_end[2]; - uint8_t adgold_mma_status; + int16_t adgold_mma_out[2]; + int adgold_mma_intpos[2]; - int16_t adgold_mma_out[2]; - int adgold_mma_intpos[2]; + pc_timer_t adgold_mma_timer_count; - pc_timer_t adgold_mma_timer_count; + uint8_t adgold_midi_ctrl, midi_queue[16]; + int midi_r, midi_w; + int uart_in, uart_out, sysex; - uint8_t adgold_midi_ctrl, midi_queue[16]; - int midi_r, midi_w; - int uart_in, uart_out, sysex; + struct + { + int timer0_latch, timer0_count; + int timerbase_latch, timerbase_count; + int timer1_latch, timer1_count; + int timer2_latch, timer2_count, timer2_read; - struct - { - int timer0_latch, timer0_count; - int timerbase_latch, timerbase_count; - int timer1_latch, timer1_count; - int timer2_latch, timer2_count, timer2_read; + int voice_count[2], voice_latch[2]; + } adgold_mma; - int voice_count[2], voice_latch[2]; - } adgold_mma; + opl_t opl; + ym7128_t ym7128; - opl_t opl; - ym7128_t ym7128; + int fm_vol_l, fm_vol_r; + int samp_vol_l, samp_vol_r; + int aux_vol_l, aux_vol_r; + int vol_l, vol_r; + int treble, bass; - int fm_vol_l, fm_vol_r; - int samp_vol_l, samp_vol_r; - int aux_vol_l, aux_vol_r; - int vol_l, vol_r; - int treble, bass; + int16_t opl_buffer[SOUNDBUFLEN * 2]; + int16_t mma_buffer[2][SOUNDBUFLEN]; - int16_t opl_buffer[SOUNDBUFLEN * 2]; - int16_t mma_buffer[2][SOUNDBUFLEN]; + int pos; - int pos; + int gameport_enabled; - int gameport_enabled; - - int surround_enabled; + int surround_enabled; } adgold_t; static int attenuation[0x40]; -static int bass_attenuation[0x10] = -{ - (int)(1.995 * 16384), /*12 dB - filter output is at +6 dB so we use 6 dB here*/ - (int)(1.995 * 16384), - (int)(1.995 * 16384), - (int)(1.413 * 16384), /*9 dB*/ - (int)(1 * 16384), /*6 dB*/ - (int)(0.708 * 16384), /*3 dB*/ - (int)(0 * 16384), /*0 dB*/ - (int)(0.708 * 16384), /*3 dB*/ - (int)(1 * 16384), /*6 dB*/ - (int)(1.413 * 16384), /*9 dB*/ - (int)(1.995 * 16384), /*12 dB*/ - (int)(2.819 * 16384), /*15 dB*/ - (int)(2.819 * 16384), - (int)(2.819 * 16384), - (int)(2.819 * 16384), - (int)(2.819 * 16384) +static int bass_attenuation[0x10] = { + (int) (1.995 * 16384), /*12 dB - filter output is at +6 dB so we use 6 dB here*/ + (int) (1.995 * 16384), + (int) (1.995 * 16384), + (int) (1.413 * 16384), /*9 dB*/ + (int) (1 * 16384), /*6 dB*/ + (int) (0.708 * 16384), /*3 dB*/ + (int) (0 * 16384), /*0 dB*/ + (int) (0.708 * 16384), /*3 dB*/ + (int) (1 * 16384), /*6 dB*/ + (int) (1.413 * 16384), /*9 dB*/ + (int) (1.995 * 16384), /*12 dB*/ + (int) (2.819 * 16384), /*15 dB*/ + (int) (2.819 * 16384), + (int) (2.819 * 16384), + (int) (2.819 * 16384), + (int) (2.819 * 16384) }; -static int bass_cut[6] = -{ - (int)(0.126 * 16384), /*-12 dB*/ - (int)(0.126 * 16384), /*-12 dB*/ - (int)(0.126 * 16384), /*-12 dB*/ - (int)(0.178 * 16384), /*-9 dB*/ - (int)(0.251 * 16384), /*-6 dB*/ - (int)(0.354 * 16384) /*-3 dB - filter output is at +6 dB*/ +static int bass_cut[6] = { + (int) (0.126 * 16384), /*-12 dB*/ + (int) (0.126 * 16384), /*-12 dB*/ + (int) (0.126 * 16384), /*-12 dB*/ + (int) (0.178 * 16384), /*-9 dB*/ + (int) (0.251 * 16384), /*-6 dB*/ + (int) (0.354 * 16384) /*-3 dB - filter output is at +6 dB*/ }; -static int treble_attenuation[0x10] = -{ - (int)(1.995 * 16384), /*12 dB - filter output is at +6 dB so we use 6 dB here*/ - (int)(1.995 * 16384), - (int)(1.995 * 16384), - (int)(1.413 * 16384), /*9 dB*/ - (int)(1 * 16384), /*6 dB*/ - (int)(0.708 * 16384), /*3 dB*/ - (int)(0 * 16384), /*0 dB*/ - (int)(0.708 * 16384), /*3 dB*/ - (int)(1 * 16384), /*6 dB*/ - (int)(1.413 * 16384), /*9 dB*/ - (int)(1.995 * 16384), /*12 dB*/ - (int)(1.995 * 16384), - (int)(1.995 * 16384), - (int)(1.995 * 16384), - (int)(1.995 * 16384), - (int)(1.995 * 16384) +static int treble_attenuation[0x10] = { + (int) (1.995 * 16384), /*12 dB - filter output is at +6 dB so we use 6 dB here*/ + (int) (1.995 * 16384), + (int) (1.995 * 16384), + (int) (1.413 * 16384), /*9 dB*/ + (int) (1 * 16384), /*6 dB*/ + (int) (0.708 * 16384), /*3 dB*/ + (int) (0 * 16384), /*0 dB*/ + (int) (0.708 * 16384), /*3 dB*/ + (int) (1 * 16384), /*6 dB*/ + (int) (1.413 * 16384), /*9 dB*/ + (int) (1.995 * 16384), /*12 dB*/ + (int) (1.995 * 16384), + (int) (1.995 * 16384), + (int) (1.995 * 16384), + (int) (1.995 * 16384), + (int) (1.995 * 16384) }; -static int treble_cut[6] = -{ - (int)(0.126 * 16384), /*-12 dB*/ - (int)(0.126 * 16384), /*-12 dB*/ - (int)(0.126 * 16384), /*-12 dB*/ - (int)(0.178 * 16384), /*-9 dB*/ - (int)(0.251 * 16384), /*-6 dB*/ - (int)(0.354 * 16384) /*-3 dB - filter output is at +6 dB*/ +static int treble_cut[6] = { + (int) (0.126 * 16384), /*-12 dB*/ + (int) (0.126 * 16384), /*-12 dB*/ + (int) (0.126 * 16384), /*-12 dB*/ + (int) (0.178 * 16384), /*-9 dB*/ + (int) (0.251 * 16384), /*-6 dB*/ + (int) (0.354 * 16384) /*-3 dB - filter output is at +6 dB*/ }; void adgold_timer_poll(); void adgold_update(adgold_t *adgold); -void adgold_update_irq_status(adgold_t *adgold) +void +adgold_update_irq_status(adgold_t *adgold) { - uint8_t temp = 0xf; + uint8_t temp = 0xf; - if (!(adgold->adgold_mma_regs[0][8] & 0x10) && (adgold->adgold_mma_status & 0x10)) /*Timer 0*/ - temp &= ~2; - if (!(adgold->adgold_mma_regs[0][8] & 0x20) && (adgold->adgold_mma_status & 0x20)) /*Timer 1*/ - temp &= ~2; - if (!(adgold->adgold_mma_regs[0][8] & 0x40) && (adgold->adgold_mma_status & 0x40)) /*Timer 2*/ - temp &= ~2; - if (!(adgold->adgold_mma_regs[0][0xd] & 0x01) && (adgold->adgold_mma_status & 0x04)) - temp &= ~2; - if (!(adgold->adgold_mma_regs[0][0xd] & 0x04) && (adgold->adgold_mma_status & 0x08)) - temp &= ~2; - if (!(adgold->adgold_mma_regs[0][0xd] & 0x10) && (adgold->adgold_mma_status & 0x80)) - temp &= ~2; - if ((adgold->adgold_mma_status & 0x01) && !(adgold->adgold_mma_regs[0][0xc] & 2)) - temp &= ~2; - if ((adgold->adgold_mma_status & 0x02) && !(adgold->adgold_mma_regs[1][0xc] & 2)) - temp &= ~2; - adgold->adgold_status = temp; + if (!(adgold->adgold_mma_regs[0][8] & 0x10) && (adgold->adgold_mma_status & 0x10)) /*Timer 0*/ + temp &= ~2; + if (!(adgold->adgold_mma_regs[0][8] & 0x20) && (adgold->adgold_mma_status & 0x20)) /*Timer 1*/ + temp &= ~2; + if (!(adgold->adgold_mma_regs[0][8] & 0x40) && (adgold->adgold_mma_status & 0x40)) /*Timer 2*/ + temp &= ~2; + if (!(adgold->adgold_mma_regs[0][0xd] & 0x01) && (adgold->adgold_mma_status & 0x04)) + temp &= ~2; + if (!(adgold->adgold_mma_regs[0][0xd] & 0x04) && (adgold->adgold_mma_status & 0x08)) + temp &= ~2; + if (!(adgold->adgold_mma_regs[0][0xd] & 0x10) && (adgold->adgold_mma_status & 0x80)) + temp &= ~2; + if ((adgold->adgold_mma_status & 0x01) && !(adgold->adgold_mma_regs[0][0xc] & 2)) + temp &= ~2; + if ((adgold->adgold_mma_status & 0x02) && !(adgold->adgold_mma_regs[1][0xc] & 2)) + temp &= ~2; + adgold->adgold_status = temp; - if ((adgold->adgold_status ^ 0xf) && !adgold->adgold_irq_status) - { - picint(0x80); - } + if ((adgold->adgold_status ^ 0xf) && !adgold->adgold_irq_status) { + picint(0x80); + } - adgold->adgold_irq_status = adgold->adgold_status ^ 0xf; + adgold->adgold_irq_status = adgold->adgold_status ^ 0xf; } -void adgold_getsamp_dma(adgold_t *adgold, int channel) +void +adgold_getsamp_dma(adgold_t *adgold, int channel) { - int temp; + int temp; - if ((adgold->adgold_mma_regs[channel][0xc] & 0x60) && (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) >= 127)) - return; + if ((adgold->adgold_mma_regs[channel][0xc] & 0x60) && (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) >= 127)) + return; - temp = dma_channel_read(1); - if (temp == DMA_NODATA) return; + temp = dma_channel_read(1); + if (temp == DMA_NODATA) + return; + adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp; + adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255; + if (adgold->adgold_mma_regs[channel][0xc] & 0x60) { + temp = dma_channel_read(1); adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp; - adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255; - if (adgold->adgold_mma_regs[channel][0xc] & 0x60) - { - temp = dma_channel_read(1); - adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp; - adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255; - } - if (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) >= adgold->adgold_mma_intpos[channel]) - { - adgold->adgold_mma_status &= ~(0x01 << channel); - adgold_update_irq_status(adgold); - } + adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255; + } + if (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) >= adgold->adgold_mma_intpos[channel]) { + adgold->adgold_mma_status &= ~(0x01 << channel); + adgold_update_irq_status(adgold); + } } -void adgold_write(uint16_t addr, uint8_t val, void *p) +void +adgold_write(uint16_t addr, uint8_t val, void *p) { - adgold_t *adgold = (adgold_t *)p; - switch (addr & 7) - { - case 0: case 1: + adgold_t *adgold = (adgold_t *) p; + switch (addr & 7) { + case 0: + case 1: + opl3_write(addr, val, &adgold->opl); + break; + + case 2: + if (val == 0xff) { + adgold->adgold_38x_state = 1; + return; + } + if (val == 0xfe) { + adgold->adgold_38x_state = 0; + return; + } + if (adgold->adgold_38x_state) /*Write to control chip*/ + adgold->adgold_38x_addr = val; + else opl3_write(addr, val, &adgold->opl); - break; - - case 2: - if (val == 0xff) - { - adgold->adgold_38x_state = 1; - return; - } - if (val == 0xfe) - { - adgold->adgold_38x_state = 0; - return; - } - if (adgold->adgold_38x_state) /*Write to control chip*/ - adgold->adgold_38x_addr = val; - else - opl3_write(addr, val, &adgold->opl); - break; - case 3: - if (adgold->adgold_38x_state) - { - if (adgold->adgold_38x_addr >= 0x19) break; - switch (adgold->adgold_38x_addr) - { - case 0x00: /*Control/ID*/ - if (val & 1) - memcpy(adgold->adgold_38x_regs, adgold->adgold_eeprom, 0x1a); - if (val & 2) - memcpy(adgold->adgold_eeprom, adgold->adgold_38x_regs, 0x1a); - break; - - case 0x04: /*Final output volume left*/ - adgold->adgold_38x_regs[0x04] = val; - adgold->vol_l = attenuation[val & 0x3f]; - break; - case 0x05: /*Final output volume right*/ - adgold->adgold_38x_regs[0x05] = val; - adgold->vol_r = attenuation[val & 0x3f]; - break; - case 0x06: /*Bass*/ - adgold->adgold_38x_regs[0x06] = val; - adgold->bass = val & 0xf; - break; - case 0x07: /*Treble*/ - adgold->adgold_38x_regs[0x07] = val; - adgold->treble = val & 0xf; - break; - - case 0x09: /*FM volume left*/ - adgold->adgold_38x_regs[0x09] = val; - adgold->fm_vol_l = (int)(int8_t)(val - 128); - break; - case 0x0a: /*FM volume right*/ - adgold->adgold_38x_regs[0x0a] = val; - adgold->fm_vol_r = (int)(int8_t)(val - 128); - break; - case 0x0b: /*Sample volume left*/ - adgold->adgold_38x_regs[0x0b] = val; - adgold->samp_vol_l = (int)(int8_t)(val - 128); - break; - case 0x0c: /*Sample volume right*/ - adgold->adgold_38x_regs[0x0c] = val; - adgold->samp_vol_r = (int)(int8_t)(val - 128); - break; - case 0x0d: /*Aux volume left*/ - adgold->adgold_38x_regs[0x0d] = val; - adgold->aux_vol_l = (int)(int8_t)(val - 128); - break; - case 0x0e: /*Aux volume right*/ - adgold->adgold_38x_regs[0x0e] = val; - adgold->aux_vol_r = (int)(int8_t)(val - 128); - break; - - case 0x18: /*Surround*/ - adgold->adgold_38x_regs[0x18] = val; - ym7128_write(&adgold->ym7128, val); - break; - - default: - adgold->adgold_38x_regs[adgold->adgold_38x_addr] = val; - break; - } - } - else - opl3_write(addr, val, &adgold->opl); - break; - case 4: case 6: - adgold->adgold_mma_addr = val; - break; - case 5: - if (adgold->adgold_mma_addr >= 0xf) break; - switch (adgold->adgold_mma_addr) - { - case 0x2: - adgold->adgold_mma.timer0_latch = (adgold->adgold_mma.timer0_latch & 0xff00) | val; - break; - case 0x3: - adgold->adgold_mma.timer0_latch = (adgold->adgold_mma.timer0_latch & 0xff) | (val << 8); - break; - case 0x4: - adgold->adgold_mma.timerbase_latch = (adgold->adgold_mma.timerbase_latch & 0xf00) | val; - break; - case 0x5: - adgold->adgold_mma.timerbase_latch = (adgold->adgold_mma.timerbase_latch & 0xff) | ((val & 0xf) << 8); - adgold->adgold_mma.timer1_latch = val >> 4; - break; - case 0x6: - adgold->adgold_mma.timer2_latch = (adgold->adgold_mma.timer2_latch & 0xff00) | val; - break; - case 0x7: - adgold->adgold_mma.timer2_latch = (adgold->adgold_mma.timer2_latch & 0xff) | (val << 8); + break; + case 3: + if (adgold->adgold_38x_state) { + if (adgold->adgold_38x_addr >= 0x19) + break; + switch (adgold->adgold_38x_addr) { + case 0x00: /*Control/ID*/ + if (val & 1) + memcpy(adgold->adgold_38x_regs, adgold->adgold_eeprom, 0x1a); + if (val & 2) + memcpy(adgold->adgold_eeprom, adgold->adgold_38x_regs, 0x1a); break; - case 0x8: - if ((val & 1) && !(adgold->adgold_mma_regs[0][8] & 1)) /*Reload timer 0*/ - adgold->adgold_mma.timer0_count = adgold->adgold_mma.timer0_latch; - - if ((val & 2) && !(adgold->adgold_mma_regs[0][8] & 2)) /*Reload timer 1*/ - adgold->adgold_mma.timer1_count = adgold->adgold_mma.timer1_latch; - - if ((val & 4) && !(adgold->adgold_mma_regs[0][8] & 4)) /*Reload timer 2*/ - adgold->adgold_mma.timer2_count = adgold->adgold_mma.timer2_latch; - - if ((val & 8) && !(adgold->adgold_mma_regs[0][8] & 8)) /*Reload base timer*/ - adgold->adgold_mma.timerbase_count = adgold->adgold_mma.timerbase_latch; + case 0x04: /*Final output volume left*/ + adgold->adgold_38x_regs[0x04] = val; + adgold->vol_l = attenuation[val & 0x3f]; + break; + case 0x05: /*Final output volume right*/ + adgold->adgold_38x_regs[0x05] = val; + adgold->vol_r = attenuation[val & 0x3f]; + break; + case 0x06: /*Bass*/ + adgold->adgold_38x_regs[0x06] = val; + adgold->bass = val & 0xf; + break; + case 0x07: /*Treble*/ + adgold->adgold_38x_regs[0x07] = val; + adgold->treble = val & 0xf; break; - case 0x9: - switch (val & 0x18) - { - case 0x00: adgold->adgold_mma.voice_latch[0] = 12; break; /*44100 Hz*/ - case 0x08: adgold->adgold_mma.voice_latch[0] = 24; break; /*22050 Hz*/ - case 0x10: adgold->adgold_mma.voice_latch[0] = 48; break; /*11025 Hz*/ - case 0x18: adgold->adgold_mma.voice_latch[0] = 72; break; /* 7350 Hz*/ - } - if (val & 0x80) - { - adgold->adgold_mma_enable[0] = 0; - adgold->adgold_mma_fifo_end[0] = adgold->adgold_mma_fifo_start[0] = 0; - adgold->adgold_mma_status &= ~0x01; - adgold_update_irq_status(adgold); - } - if ((val & 0x01)) /*Start playback*/ - { - if (!(adgold->adgold_mma_regs[0][0x9] & 1)) - adgold->adgold_mma.voice_count[0] = adgold->adgold_mma.voice_latch[0]; - - if (adgold->adgold_mma_regs[0][0xc] & 1) - { - if (adgold->adgold_mma_regs[0][0xc] & 0x80) - { - adgold->adgold_mma_enable[1] = 1; - adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1]; - - while (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) - { - adgold_getsamp_dma(adgold, 0); - adgold_getsamp_dma(adgold, 1); - } - if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) - { - adgold->adgold_mma_status &= ~0x01; - adgold_update_irq_status(adgold); - } - if (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) >= adgold->adgold_mma_intpos[1]) - { - adgold->adgold_mma_status &= ~0x02; - adgold_update_irq_status(adgold); - } - } - else - { - while (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) - { - adgold_getsamp_dma(adgold, 0); - } - if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) - { - adgold->adgold_mma_status &= ~0x01; - adgold_update_irq_status(adgold); - } - } - } - } - adgold->adgold_mma_enable[0] = val & 0x01; + case 0x09: /*FM volume left*/ + adgold->adgold_38x_regs[0x09] = val; + adgold->fm_vol_l = (int) (int8_t) (val - 128); + break; + case 0x0a: /*FM volume right*/ + adgold->adgold_38x_regs[0x0a] = val; + adgold->fm_vol_r = (int) (int8_t) (val - 128); + break; + case 0x0b: /*Sample volume left*/ + adgold->adgold_38x_regs[0x0b] = val; + adgold->samp_vol_l = (int) (int8_t) (val - 128); + break; + case 0x0c: /*Sample volume right*/ + adgold->adgold_38x_regs[0x0c] = val; + adgold->samp_vol_r = (int) (int8_t) (val - 128); + break; + case 0x0d: /*Aux volume left*/ + adgold->adgold_38x_regs[0x0d] = val; + adgold->aux_vol_l = (int) (int8_t) (val - 128); + break; + case 0x0e: /*Aux volume right*/ + adgold->adgold_38x_regs[0x0e] = val; + adgold->aux_vol_r = (int) (int8_t) (val - 128); break; - case 0xb: - if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) - { - adgold->adgold_mma_fifo[0][adgold->adgold_mma_fifo_end[0]] = val; - adgold->adgold_mma_fifo_end[0] = (adgold->adgold_mma_fifo_end[0] + 1) & 255; - if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) - { - adgold->adgold_mma_status &= ~0x01; - adgold_update_irq_status(adgold); - } - } + case 0x18: /*Surround*/ + adgold->adgold_38x_regs[0x18] = val; + ym7128_write(&adgold->ym7128, val); break; - case 0xc: - adgold->adgold_mma_intpos[0] = (7 - ((val >> 2) & 7)) * 8; - break; - - case 0xd: - adgold->adgold_midi_ctrl = val & 0x3f; - - if ((adgold->adgold_midi_ctrl & 0x0f) != 0x0f) { - if ((adgold->adgold_midi_ctrl & 0x0f) == 0x00) { - adgold->uart_out = 0; - adgold->uart_in = 0; - adgold->midi_w = 0; - adgold->midi_r = 0; - adgold->adgold_mma_status &= ~0x8c; - } else { - if (adgold->adgold_midi_ctrl & 0x01) - adgold->uart_in = 1; - if (adgold->adgold_midi_ctrl & 0x04) - adgold->uart_out = 1; - if (adgold->adgold_midi_ctrl & 0x02) { - adgold->uart_in = 0; - adgold->midi_w = 0; - adgold->midi_r = 0; - } - if (adgold->adgold_midi_ctrl & 0x08) - adgold->uart_out = 0; - adgold->adgold_mma_status &= ~0x80; - } - } else - adgold->adgold_mma_status &= ~0x8c; - - adgold_update_irq_status(adgold); - break; - - case 0xe: - if (adgold->uart_out) { - midi_raw_out_byte(val); - - adgold->adgold_mma_status &= ~0x08; - adgold_update_irq_status(adgold); - } - break; - } - adgold->adgold_mma_regs[0][adgold->adgold_mma_addr] = val; - break; - case 7: - if (adgold->adgold_mma_addr >= 0xe) break; - switch (adgold->adgold_mma_addr) - { - case 0x9: - adgold_update(adgold); - switch (val & 0x18) - { - case 0x00: adgold->adgold_mma.voice_latch[1] = 12; break; /*44100 Hz*/ - case 0x08: adgold->adgold_mma.voice_latch[1] = 24; break; /*22050 Hz*/ - case 0x10: adgold->adgold_mma.voice_latch[1] = 48; break; /*11025 Hz*/ - case 0x18: adgold->adgold_mma.voice_latch[1] = 72; break; /* 7350 Hz*/ - } - if (val & 0x80) - { - adgold->adgold_mma_enable[1] = 0; - adgold->adgold_mma_fifo_end[1] = adgold->adgold_mma_fifo_start[1] = 0; - adgold->adgold_mma_status &= ~0x02; - adgold_update_irq_status(adgold); - } - if ((val & 0x01)) /*Start playback*/ - { - if (!(adgold->adgold_mma_regs[1][0x9] & 1)) - adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1]; - - if (adgold->adgold_mma_regs[1][0xc] & 1) - { - while (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) < 128) - { - adgold_getsamp_dma(adgold, 1); - } - } - } - adgold->adgold_mma_enable[1] = val & 0x01; - break; - - case 0xb: - if (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) < 128) - { - adgold->adgold_mma_fifo[1][adgold->adgold_mma_fifo_end[1]] = val; - adgold->adgold_mma_fifo_end[1] = (adgold->adgold_mma_fifo_end[1] + 1) & 255; - if (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) >= adgold->adgold_mma_intpos[1]) - { - adgold->adgold_mma_status &= ~0x02; - adgold_update_irq_status(adgold); - } - } - break; - - case 0xc: - adgold->adgold_mma_intpos[1] = (7 - ((val >> 2) & 7)) * 8; + default: + adgold->adgold_38x_regs[adgold->adgold_38x_addr] = val; break; } - adgold->adgold_mma_regs[1][adgold->adgold_mma_addr] = val; + } else + opl3_write(addr, val, &adgold->opl); + break; + case 4: + case 6: + adgold->adgold_mma_addr = val; + break; + case 5: + if (adgold->adgold_mma_addr >= 0xf) break; - } -} + switch (adgold->adgold_mma_addr) { + case 0x2: + adgold->adgold_mma.timer0_latch = (adgold->adgold_mma.timer0_latch & 0xff00) | val; + break; + case 0x3: + adgold->adgold_mma.timer0_latch = (adgold->adgold_mma.timer0_latch & 0xff) | (val << 8); + break; + case 0x4: + adgold->adgold_mma.timerbase_latch = (adgold->adgold_mma.timerbase_latch & 0xf00) | val; + break; + case 0x5: + adgold->adgold_mma.timerbase_latch = (adgold->adgold_mma.timerbase_latch & 0xff) | ((val & 0xf) << 8); + adgold->adgold_mma.timer1_latch = val >> 4; + break; + case 0x6: + adgold->adgold_mma.timer2_latch = (adgold->adgold_mma.timer2_latch & 0xff00) | val; + break; + case 0x7: + adgold->adgold_mma.timer2_latch = (adgold->adgold_mma.timer2_latch & 0xff) | (val << 8); + break; -uint8_t adgold_read(uint16_t addr, void *p) -{ - adgold_t *adgold = (adgold_t *)p; - uint8_t temp = 0; + case 0x8: + if ((val & 1) && !(adgold->adgold_mma_regs[0][8] & 1)) /*Reload timer 0*/ + adgold->adgold_mma.timer0_count = adgold->adgold_mma.timer0_latch; - switch (addr & 7) - { - case 0: case 1: - temp = opl3_read(addr, &adgold->opl); - break; + if ((val & 2) && !(adgold->adgold_mma_regs[0][8] & 2)) /*Reload timer 1*/ + adgold->adgold_mma.timer1_count = adgold->adgold_mma.timer1_latch; - case 2: - if (adgold->adgold_38x_state) /*Read from control chip*/ - temp = adgold->adgold_status; - else - temp = opl3_read(addr, &adgold->opl); - break; + if ((val & 4) && !(adgold->adgold_mma_regs[0][8] & 4)) /*Reload timer 2*/ + adgold->adgold_mma.timer2_count = adgold->adgold_mma.timer2_latch; - case 3: - if (adgold->adgold_38x_state) - { - if (adgold->adgold_38x_addr >= 0x19) temp = 0xff; - switch (adgold->adgold_38x_addr) - { - case 0x00: /*Control/ID*/ - if (adgold->surround_enabled) - temp = 0x51; /*8-bit ISA, surround module, no telephone/CD-ROM*/ - else - temp = 0x71; /*8-bit ISA, no telephone/surround/CD-ROM*/ - break; + if ((val & 8) && !(adgold->adgold_mma_regs[0][8] & 8)) /*Reload base timer*/ + adgold->adgold_mma.timerbase_count = adgold->adgold_mma.timerbase_latch; + break; - default: - temp = adgold->adgold_38x_regs[adgold->adgold_38x_addr]; - } - } - else - temp = opl3_read(addr, &adgold->opl); - break; - - case 4: case 6: - temp = adgold->adgold_mma_status; - adgold->adgold_mma_status &= ~0xf3; /*JUKEGOLD expects timer status flags to auto-clear*/ - adgold_update_irq_status(adgold); - break; - case 5: - if (adgold->adgold_mma_addr >= 0xf) temp = 0xff; - switch (adgold->adgold_mma_addr) - { - case 6: /*Timer 2 low*/ - adgold->adgold_mma.timer2_read = adgold->adgold_mma.timer2_count; - adgold->adgold_mma_status |= 0x40; - temp = adgold->adgold_mma.timer2_read & 0xff; - break; - case 7: /*Timer 2 high*/ - temp = adgold->adgold_mma.timer2_read >> 8; - break; - - case 0xe: - temp = 0; - if (adgold->uart_in) { - temp = adgold->midi_queue[adgold->midi_r]; - if (adgold->midi_r != adgold->midi_w) { - adgold->midi_r++; - adgold->midi_r &= 0x0f; - } - adgold->adgold_mma_status &= ~0x04; - adgold_update_irq_status(adgold); - } - break; - - default: - temp = adgold->adgold_mma_regs[0][adgold->adgold_mma_addr]; - break; - } - break; - case 7: - if (adgold->adgold_mma_addr >= 0xf) - temp = 0xff; - else - temp = adgold->adgold_mma_regs[1][adgold->adgold_mma_addr]; - break; - } - return temp; -} - -void adgold_update(adgold_t *adgold) -{ - for (; adgold->pos < sound_pos_global; adgold->pos++) - { - adgold->mma_buffer[0][adgold->pos] = adgold->mma_buffer[1][adgold->pos] = 0; - - if (adgold->adgold_mma_regs[0][9] & 0x20) - adgold->mma_buffer[0][adgold->pos] += adgold->adgold_mma_out[0] / 2; - if (adgold->adgold_mma_regs[0][9] & 0x40) - adgold->mma_buffer[1][adgold->pos] += adgold->adgold_mma_out[0] / 2; - - if (adgold->adgold_mma_regs[1][9] & 0x20) - adgold->mma_buffer[0][adgold->pos] += adgold->adgold_mma_out[1] / 2; - if (adgold->adgold_mma_regs[1][9] & 0x40) - adgold->mma_buffer[1][adgold->pos] += adgold->adgold_mma_out[1] / 2; - } -} - -void adgold_mma_poll(adgold_t *adgold, int channel) -{ - int16_t dat; - - adgold_update(adgold); - - if (adgold->adgold_mma_fifo_start[channel] != adgold->adgold_mma_fifo_end[channel]) - { - switch (adgold->adgold_mma_regs[channel][0xc] & 0x60) - { - case 0x00: /*8-bit*/ - dat = adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_start[channel]] * 256; - adgold->adgold_mma_out[channel] = dat; - adgold->adgold_mma_fifo_start[channel] = (adgold->adgold_mma_fifo_start[channel] + 1) & 255; - break; - - case 0x40: /*12-bit sensible format*/ - if (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) < 2) - return; - - dat = adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_start[channel]] & 0xf0; - adgold->adgold_mma_fifo_start[channel] = (adgold->adgold_mma_fifo_start[channel] + 1) & 255; - dat |= (adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_start[channel]] << 8); - adgold->adgold_mma_fifo_start[channel] = (adgold->adgold_mma_fifo_start[channel] + 1) & 255; - adgold->adgold_mma_out[channel] = dat; - break; - } - - if (adgold->adgold_mma_regs[channel][0xc] & 1) - { - adgold_getsamp_dma(adgold, channel); - } - if (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) < adgold->adgold_mma_intpos[channel] && !(adgold->adgold_mma_status & 0x01)) - { - adgold->adgold_mma_status |= 1 << channel; + case 0x9: + switch (val & 0x18) { + case 0x00: + adgold->adgold_mma.voice_latch[0] = 12; + break; /*44100 Hz*/ + case 0x08: + adgold->adgold_mma.voice_latch[0] = 24; + break; /*22050 Hz*/ + case 0x10: + adgold->adgold_mma.voice_latch[0] = 48; + break; /*11025 Hz*/ + case 0x18: + adgold->adgold_mma.voice_latch[0] = 72; + break; /* 7350 Hz*/ + } + if (val & 0x80) { + adgold->adgold_mma_enable[0] = 0; + adgold->adgold_mma_fifo_end[0] = adgold->adgold_mma_fifo_start[0] = 0; + adgold->adgold_mma_status &= ~0x01; adgold_update_irq_status(adgold); - } - } - if (adgold->adgold_mma_fifo_start[channel] == adgold->adgold_mma_fifo_end[channel]) - { - adgold->adgold_mma_enable[channel] = 0; - } + } + if ((val & 0x01)) /*Start playback*/ + { + if (!(adgold->adgold_mma_regs[0][0x9] & 1)) + adgold->adgold_mma.voice_count[0] = adgold->adgold_mma.voice_latch[0]; + + if (adgold->adgold_mma_regs[0][0xc] & 1) { + if (adgold->adgold_mma_regs[0][0xc] & 0x80) { + adgold->adgold_mma_enable[1] = 1; + adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1]; + + while (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) { + adgold_getsamp_dma(adgold, 0); + adgold_getsamp_dma(adgold, 1); + } + if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) { + adgold->adgold_mma_status &= ~0x01; + adgold_update_irq_status(adgold); + } + if (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) >= adgold->adgold_mma_intpos[1]) { + adgold->adgold_mma_status &= ~0x02; + adgold_update_irq_status(adgold); + } + } else { + while (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) { + adgold_getsamp_dma(adgold, 0); + } + if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) { + adgold->adgold_mma_status &= ~0x01; + adgold_update_irq_status(adgold); + } + } + } + } + adgold->adgold_mma_enable[0] = val & 0x01; + break; + + case 0xb: + if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) { + adgold->adgold_mma_fifo[0][adgold->adgold_mma_fifo_end[0]] = val; + adgold->adgold_mma_fifo_end[0] = (adgold->adgold_mma_fifo_end[0] + 1) & 255; + if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) { + adgold->adgold_mma_status &= ~0x01; + adgold_update_irq_status(adgold); + } + } + break; + + case 0xc: + adgold->adgold_mma_intpos[0] = (7 - ((val >> 2) & 7)) * 8; + break; + + case 0xd: + adgold->adgold_midi_ctrl = val & 0x3f; + + if ((adgold->adgold_midi_ctrl & 0x0f) != 0x0f) { + if ((adgold->adgold_midi_ctrl & 0x0f) == 0x00) { + adgold->uart_out = 0; + adgold->uart_in = 0; + adgold->midi_w = 0; + adgold->midi_r = 0; + adgold->adgold_mma_status &= ~0x8c; + } else { + if (adgold->adgold_midi_ctrl & 0x01) + adgold->uart_in = 1; + if (adgold->adgold_midi_ctrl & 0x04) + adgold->uart_out = 1; + if (adgold->adgold_midi_ctrl & 0x02) { + adgold->uart_in = 0; + adgold->midi_w = 0; + adgold->midi_r = 0; + } + if (adgold->adgold_midi_ctrl & 0x08) + adgold->uart_out = 0; + adgold->adgold_mma_status &= ~0x80; + } + } else + adgold->adgold_mma_status &= ~0x8c; + + adgold_update_irq_status(adgold); + break; + + case 0xe: + if (adgold->uart_out) { + midi_raw_out_byte(val); + + adgold->adgold_mma_status &= ~0x08; + adgold_update_irq_status(adgold); + } + break; + } + adgold->adgold_mma_regs[0][adgold->adgold_mma_addr] = val; + break; + case 7: + if (adgold->adgold_mma_addr >= 0xe) + break; + switch (adgold->adgold_mma_addr) { + case 0x9: + adgold_update(adgold); + switch (val & 0x18) { + case 0x00: + adgold->adgold_mma.voice_latch[1] = 12; + break; /*44100 Hz*/ + case 0x08: + adgold->adgold_mma.voice_latch[1] = 24; + break; /*22050 Hz*/ + case 0x10: + adgold->adgold_mma.voice_latch[1] = 48; + break; /*11025 Hz*/ + case 0x18: + adgold->adgold_mma.voice_latch[1] = 72; + break; /* 7350 Hz*/ + } + if (val & 0x80) { + adgold->adgold_mma_enable[1] = 0; + adgold->adgold_mma_fifo_end[1] = adgold->adgold_mma_fifo_start[1] = 0; + adgold->adgold_mma_status &= ~0x02; + adgold_update_irq_status(adgold); + } + if ((val & 0x01)) /*Start playback*/ + { + if (!(adgold->adgold_mma_regs[1][0x9] & 1)) + adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1]; + + if (adgold->adgold_mma_regs[1][0xc] & 1) { + while (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) < 128) { + adgold_getsamp_dma(adgold, 1); + } + } + } + adgold->adgold_mma_enable[1] = val & 0x01; + break; + + case 0xb: + if (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) < 128) { + adgold->adgold_mma_fifo[1][adgold->adgold_mma_fifo_end[1]] = val; + adgold->adgold_mma_fifo_end[1] = (adgold->adgold_mma_fifo_end[1] + 1) & 255; + if (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) >= adgold->adgold_mma_intpos[1]) { + adgold->adgold_mma_status &= ~0x02; + adgold_update_irq_status(adgold); + } + } + break; + + case 0xc: + adgold->adgold_mma_intpos[1] = (7 - ((val >> 2) & 7)) * 8; + break; + } + adgold->adgold_mma_regs[1][adgold->adgold_mma_addr] = val; + break; + } } -void adgold_timer_poll(void *p) +uint8_t +adgold_read(uint16_t addr, void *p) { - adgold_t *adgold = (adgold_t *)p; + adgold_t *adgold = (adgold_t *) p; + uint8_t temp = 0; - timer_advance_u64(&adgold->adgold_mma_timer_count, (uint64_t)((double)TIMER_USEC * 1.88964)); + switch (addr & 7) { + case 0: + case 1: + temp = opl3_read(addr, &adgold->opl); + break; - if (adgold->adgold_midi_ctrl & 0x3f) { - if ((adgold->adgold_midi_ctrl & 0x3f) != 0x3f) { - if (adgold->uart_out) - adgold->adgold_mma_status |= 0x08; - if (adgold->adgold_midi_ctrl & 0x10) - adgold->adgold_mma_status |= 0x80; - } - adgold_update_irq_status(adgold); - } + case 2: + if (adgold->adgold_38x_state) /*Read from control chip*/ + temp = adgold->adgold_status; + else + temp = opl3_read(addr, &adgold->opl); + break; - if (adgold->adgold_mma_regs[0][8] & 0x01) /*Timer 0*/ - { - adgold->adgold_mma.timer0_count--; - if (!adgold->adgold_mma.timer0_count) - { - adgold->adgold_mma.timer0_count = adgold->adgold_mma.timer0_latch; - adgold->adgold_mma_status |= 0x10; - adgold_update_irq_status(adgold); - } - } - if (adgold->adgold_mma_regs[0][8] & 0x08) /*Base timer*/ - { - adgold->adgold_mma.timerbase_count--; - if (!adgold->adgold_mma.timerbase_count) - { - adgold->adgold_mma.timerbase_count = adgold->adgold_mma.timerbase_latch; - if (adgold->adgold_mma_regs[0][8] & 0x02) /*Timer 1*/ - { - adgold->adgold_mma.timer1_count--; - if (!adgold->adgold_mma.timer1_count) - { - adgold->adgold_mma.timer1_count = adgold->adgold_mma.timer1_latch; - adgold->adgold_mma_status |= 0x20; - adgold_update_irq_status(adgold); - } - } - if (adgold->adgold_mma_regs[0][8] & 0x04) /*Timer 2*/ - { - adgold->adgold_mma.timer2_count--; - if (!adgold->adgold_mma.timer2_count) - { - adgold->adgold_mma.timer2_count = adgold->adgold_mma.timer2_latch; - adgold->adgold_mma_status |= 0x40; - adgold_update_irq_status(adgold); - } - } - } - } + case 3: + if (adgold->adgold_38x_state) { + if (adgold->adgold_38x_addr >= 0x19) + temp = 0xff; + switch (adgold->adgold_38x_addr) { + case 0x00: /*Control/ID*/ + if (adgold->surround_enabled) + temp = 0x51; /*8-bit ISA, surround module, no telephone/CD-ROM*/ + else + temp = 0x71; /*8-bit ISA, no telephone/surround/CD-ROM*/ + break; - if (adgold->adgold_mma_enable[0]) - { - adgold->adgold_mma.voice_count[0]--; - if (!adgold->adgold_mma.voice_count[0]) - { - adgold->adgold_mma.voice_count[0] = adgold->adgold_mma.voice_latch[0]; - adgold_mma_poll(adgold, 0); - } - } - if (adgold->adgold_mma_enable[1]) - { - adgold->adgold_mma.voice_count[1]--; - if (!adgold->adgold_mma.voice_count[1]) - { - adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1]; - adgold_mma_poll(adgold, 1); - } - } + default: + temp = adgold->adgold_38x_regs[adgold->adgold_38x_addr]; + } + } else + temp = opl3_read(addr, &adgold->opl); + break; + + case 4: + case 6: + temp = adgold->adgold_mma_status; + adgold->adgold_mma_status &= ~0xf3; /*JUKEGOLD expects timer status flags to auto-clear*/ + adgold_update_irq_status(adgold); + break; + case 5: + if (adgold->adgold_mma_addr >= 0xf) + temp = 0xff; + switch (adgold->adgold_mma_addr) { + case 6: /*Timer 2 low*/ + adgold->adgold_mma.timer2_read = adgold->adgold_mma.timer2_count; + adgold->adgold_mma_status |= 0x40; + temp = adgold->adgold_mma.timer2_read & 0xff; + break; + case 7: /*Timer 2 high*/ + temp = adgold->adgold_mma.timer2_read >> 8; + break; + + case 0xe: + temp = 0; + if (adgold->uart_in) { + temp = adgold->midi_queue[adgold->midi_r]; + if (adgold->midi_r != adgold->midi_w) { + adgold->midi_r++; + adgold->midi_r &= 0x0f; + } + adgold->adgold_mma_status &= ~0x04; + adgold_update_irq_status(adgold); + } + break; + + default: + temp = adgold->adgold_mma_regs[0][adgold->adgold_mma_addr]; + break; + } + break; + case 7: + if (adgold->adgold_mma_addr >= 0xf) + temp = 0xff; + else + temp = adgold->adgold_mma_regs[1][adgold->adgold_mma_addr]; + break; + } + return temp; } -static void adgold_get_buffer(int32_t *buffer, int len, void *p) +void +adgold_update(adgold_t *adgold) { - adgold_t *adgold = (adgold_t *)p; - int16_t* adgold_buffer = malloc(sizeof(int16_t) * len * 2); - if (adgold_buffer == NULL) fatal("adgold_buffer = NULL"); + for (; adgold->pos < sound_pos_global; adgold->pos++) { + adgold->mma_buffer[0][adgold->pos] = adgold->mma_buffer[1][adgold->pos] = 0; - int c; + if (adgold->adgold_mma_regs[0][9] & 0x20) + adgold->mma_buffer[0][adgold->pos] += adgold->adgold_mma_out[0] / 2; + if (adgold->adgold_mma_regs[0][9] & 0x40) + adgold->mma_buffer[1][adgold->pos] += adgold->adgold_mma_out[0] / 2; - opl3_update(&adgold->opl); - adgold_update(adgold); + if (adgold->adgold_mma_regs[1][9] & 0x20) + adgold->mma_buffer[0][adgold->pos] += adgold->adgold_mma_out[1] / 2; + if (adgold->adgold_mma_regs[1][9] & 0x40) + adgold->mma_buffer[1][adgold->pos] += adgold->adgold_mma_out[1] / 2; + } +} - for (c = 0; c < len * 2; c += 2) - { - adgold_buffer[c] = ((adgold->opl.buffer[c] * adgold->fm_vol_l) >> 7) / 2; - adgold_buffer[c] += ((adgold->mma_buffer[0][c >> 1] * adgold->samp_vol_l) >> 7) / 4; - adgold_buffer[c+1] = ((adgold->opl.buffer[c+1] * adgold->fm_vol_r) >> 7) / 2; - adgold_buffer[c+1] += ((adgold->mma_buffer[1][c >> 1] * adgold->samp_vol_r) >> 7) / 4; - } +void +adgold_mma_poll(adgold_t *adgold, int channel) +{ + int16_t dat; - if (adgold->surround_enabled) - ym7128_apply(&adgold->ym7128, adgold_buffer, len); + adgold_update(adgold); - switch (adgold->adgold_38x_regs[0x8] & 6) - { - case 0: - for (c = 0; c < len * 2; c++) - adgold_buffer[c] = 0; + if (adgold->adgold_mma_fifo_start[channel] != adgold->adgold_mma_fifo_end[channel]) { + switch (adgold->adgold_mma_regs[channel][0xc] & 0x60) { + case 0x00: /*8-bit*/ + dat = adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_start[channel]] * 256; + adgold->adgold_mma_out[channel] = dat; + adgold->adgold_mma_fifo_start[channel] = (adgold->adgold_mma_fifo_start[channel] + 1) & 255; break; - case 2: /*Left channel only*/ - for (c = 0; c < len * 2; c += 2) - adgold_buffer[c+1] = adgold_buffer[c]; - break; - case 4: /*Right channel only*/ - for (c = 0; c < len * 2; c += 2) - adgold_buffer[c] = adgold_buffer[c+1]; - break; - case 6: /*Left and right channels*/ + + case 0x40: /*12-bit sensible format*/ + if (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) < 2) + return; + + dat = adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_start[channel]] & 0xf0; + adgold->adgold_mma_fifo_start[channel] = (adgold->adgold_mma_fifo_start[channel] + 1) & 255; + dat |= (adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_start[channel]] << 8); + adgold->adgold_mma_fifo_start[channel] = (adgold->adgold_mma_fifo_start[channel] + 1) & 255; + adgold->adgold_mma_out[channel] = dat; break; } - switch (adgold->adgold_38x_regs[0x8] & 0x18) - { - case 0x00: /*Forced mono*/ - for (c = 0; c < len * 2; c += 2) - adgold_buffer[c] = adgold_buffer[c+1] = ((int32_t)adgold_buffer[c] + (int32_t)adgold_buffer[c+1]) / 2; - break; - case 0x08: /*Linear stereo*/ - break; - case 0x10: /*Pseudo stereo*/ - /*Filter left channel, leave right channel unchanged*/ - /*Filter cutoff is largely a guess*/ - for (c = 0; c < len * 2; c += 2) - adgold_buffer[c] += adgold_pseudo_stereo_iir(adgold_buffer[c]); - break; - case 0x18: /*Spatial stereo*/ - /*Quite probably wrong, I only have the diagram in the TDA8425 datasheet - and a very vague understanding of how op-amps work to go on*/ - for (c = 0; c < len * 2; c += 2) - { - int16_t l = adgold_buffer[c]; - int16_t r = adgold_buffer[c+1]; + if (adgold->adgold_mma_regs[channel][0xc] & 1) { + adgold_getsamp_dma(adgold, channel); + } + if (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) < adgold->adgold_mma_intpos[channel] && !(adgold->adgold_mma_status & 0x01)) { + adgold->adgold_mma_status |= 1 << channel; + adgold_update_irq_status(adgold); + } + } + if (adgold->adgold_mma_fifo_start[channel] == adgold->adgold_mma_fifo_end[channel]) { + adgold->adgold_mma_enable[channel] = 0; + } +} - adgold_buffer[c] += (r / 3) + ((l * 2) / 3); - adgold_buffer[c+1] += (l / 3) + ((r * 2) / 3); +void +adgold_timer_poll(void *p) +{ + adgold_t *adgold = (adgold_t *) p; + + timer_advance_u64(&adgold->adgold_mma_timer_count, (uint64_t) ((double) TIMER_USEC * 1.88964)); + + if (adgold->adgold_midi_ctrl & 0x3f) { + if ((adgold->adgold_midi_ctrl & 0x3f) != 0x3f) { + if (adgold->uart_out) + adgold->adgold_mma_status |= 0x08; + if (adgold->adgold_midi_ctrl & 0x10) + adgold->adgold_mma_status |= 0x80; + } + adgold_update_irq_status(adgold); + } + + if (adgold->adgold_mma_regs[0][8] & 0x01) /*Timer 0*/ + { + adgold->adgold_mma.timer0_count--; + if (!adgold->adgold_mma.timer0_count) { + adgold->adgold_mma.timer0_count = adgold->adgold_mma.timer0_latch; + adgold->adgold_mma_status |= 0x10; + adgold_update_irq_status(adgold); + } + } + if (adgold->adgold_mma_regs[0][8] & 0x08) /*Base timer*/ + { + adgold->adgold_mma.timerbase_count--; + if (!adgold->adgold_mma.timerbase_count) { + adgold->adgold_mma.timerbase_count = adgold->adgold_mma.timerbase_latch; + if (adgold->adgold_mma_regs[0][8] & 0x02) /*Timer 1*/ + { + adgold->adgold_mma.timer1_count--; + if (!adgold->adgold_mma.timer1_count) { + adgold->adgold_mma.timer1_count = adgold->adgold_mma.timer1_latch; + adgold->adgold_mma_status |= 0x20; + adgold_update_irq_status(adgold); } - break; + } + if (adgold->adgold_mma_regs[0][8] & 0x04) /*Timer 2*/ + { + adgold->adgold_mma.timer2_count--; + if (!adgold->adgold_mma.timer2_count) { + adgold->adgold_mma.timer2_count = adgold->adgold_mma.timer2_latch; + adgold->adgold_mma_status |= 0x40; + adgold_update_irq_status(adgold); + } + } } + } - for (c = 0; c < len * 2; c += 2) - { - int32_t temp, lowpass, highpass; - - /*Output is deliberately halved to avoid clipping*/ - temp = ((int32_t)adgold_buffer[c] * adgold->vol_l) >> 17; - lowpass = adgold_lowpass_iir(0, temp); - highpass = adgold_highpass_iir(0, temp); - if (adgold->bass > 6) - temp += (lowpass * bass_attenuation[adgold->bass]) >> 14; - else if (adgold->bass < 6) - temp = highpass + ((temp * bass_cut[adgold->bass]) >> 14); - if (adgold->treble > 6) - temp += (highpass * treble_attenuation[adgold->treble]) >> 14; - else if (adgold->treble < 6) - temp = lowpass + ((temp * treble_cut[adgold->treble]) >> 14); - if (temp < -32768) - temp = -32768; - if (temp > 32767) - temp = 32767; - buffer[c] += temp; - - temp = ((int32_t)adgold_buffer[c+1] * adgold->vol_r) >> 17; - lowpass = adgold_lowpass_iir(1, temp); - highpass = adgold_highpass_iir(1, temp); - if (adgold->bass > 6) - temp += (lowpass * bass_attenuation[adgold->bass]) >> 14; - else if (adgold->bass < 6) - temp = highpass + ((temp * bass_cut[adgold->bass]) >> 14); - if (adgold->treble > 6) - temp += (highpass * treble_attenuation[adgold->treble]) >> 14; - else if (adgold->treble < 6) - temp = lowpass + ((temp * treble_cut[adgold->treble]) >> 14); - if (temp < -32768) - temp = -32768; - if (temp > 32767) - temp = 32767; - buffer[c+1] += temp; + if (adgold->adgold_mma_enable[0]) { + adgold->adgold_mma.voice_count[0]--; + if (!adgold->adgold_mma.voice_count[0]) { + adgold->adgold_mma.voice_count[0] = adgold->adgold_mma.voice_latch[0]; + adgold_mma_poll(adgold, 0); } + } + if (adgold->adgold_mma_enable[1]) { + adgold->adgold_mma.voice_count[1]--; + if (!adgold->adgold_mma.voice_count[1]) { + adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1]; + adgold_mma_poll(adgold, 1); + } + } +} - adgold->opl.pos = 0; - adgold->pos = 0; +static void +adgold_get_buffer(int32_t *buffer, int len, void *p) +{ + adgold_t *adgold = (adgold_t *) p; + int16_t *adgold_buffer = malloc(sizeof(int16_t) * len * 2); + if (adgold_buffer == NULL) + fatal("adgold_buffer = NULL"); - free(adgold_buffer); + int c; + + opl3_update(&adgold->opl); + adgold_update(adgold); + + for (c = 0; c < len * 2; c += 2) { + adgold_buffer[c] = ((adgold->opl.buffer[c] * adgold->fm_vol_l) >> 7) / 2; + adgold_buffer[c] += ((adgold->mma_buffer[0][c >> 1] * adgold->samp_vol_l) >> 7) / 4; + adgold_buffer[c + 1] = ((adgold->opl.buffer[c + 1] * adgold->fm_vol_r) >> 7) / 2; + adgold_buffer[c + 1] += ((adgold->mma_buffer[1][c >> 1] * adgold->samp_vol_r) >> 7) / 4; + } + + if (adgold->surround_enabled) + ym7128_apply(&adgold->ym7128, adgold_buffer, len); + + switch (adgold->adgold_38x_regs[0x8] & 6) { + case 0: + for (c = 0; c < len * 2; c++) + adgold_buffer[c] = 0; + break; + case 2: /*Left channel only*/ + for (c = 0; c < len * 2; c += 2) + adgold_buffer[c + 1] = adgold_buffer[c]; + break; + case 4: /*Right channel only*/ + for (c = 0; c < len * 2; c += 2) + adgold_buffer[c] = adgold_buffer[c + 1]; + break; + case 6: /*Left and right channels*/ + break; + } + + switch (adgold->adgold_38x_regs[0x8] & 0x18) { + case 0x00: /*Forced mono*/ + for (c = 0; c < len * 2; c += 2) + adgold_buffer[c] = adgold_buffer[c + 1] = ((int32_t) adgold_buffer[c] + (int32_t) adgold_buffer[c + 1]) / 2; + break; + case 0x08: /*Linear stereo*/ + break; + case 0x10: /*Pseudo stereo*/ + /*Filter left channel, leave right channel unchanged*/ + /*Filter cutoff is largely a guess*/ + for (c = 0; c < len * 2; c += 2) + adgold_buffer[c] += adgold_pseudo_stereo_iir(adgold_buffer[c]); + break; + case 0x18: /*Spatial stereo*/ + /*Quite probably wrong, I only have the diagram in the TDA8425 datasheet + and a very vague understanding of how op-amps work to go on*/ + for (c = 0; c < len * 2; c += 2) { + int16_t l = adgold_buffer[c]; + int16_t r = adgold_buffer[c + 1]; + + adgold_buffer[c] += (r / 3) + ((l * 2) / 3); + adgold_buffer[c + 1] += (l / 3) + ((r * 2) / 3); + } + break; + } + + for (c = 0; c < len * 2; c += 2) { + int32_t temp, lowpass, highpass; + + /*Output is deliberately halved to avoid clipping*/ + temp = ((int32_t) adgold_buffer[c] * adgold->vol_l) >> 17; + lowpass = adgold_lowpass_iir(0, temp); + highpass = adgold_highpass_iir(0, temp); + if (adgold->bass > 6) + temp += (lowpass * bass_attenuation[adgold->bass]) >> 14; + else if (adgold->bass < 6) + temp = highpass + ((temp * bass_cut[adgold->bass]) >> 14); + if (adgold->treble > 6) + temp += (highpass * treble_attenuation[adgold->treble]) >> 14; + else if (adgold->treble < 6) + temp = lowpass + ((temp * treble_cut[adgold->treble]) >> 14); + if (temp < -32768) + temp = -32768; + if (temp > 32767) + temp = 32767; + buffer[c] += temp; + + temp = ((int32_t) adgold_buffer[c + 1] * adgold->vol_r) >> 17; + lowpass = adgold_lowpass_iir(1, temp); + highpass = adgold_highpass_iir(1, temp); + if (adgold->bass > 6) + temp += (lowpass * bass_attenuation[adgold->bass]) >> 14; + else if (adgold->bass < 6) + temp = highpass + ((temp * bass_cut[adgold->bass]) >> 14); + if (adgold->treble > 6) + temp += (highpass * treble_attenuation[adgold->treble]) >> 14; + else if (adgold->treble < 6) + temp = lowpass + ((temp * treble_cut[adgold->treble]) >> 14); + if (temp < -32768) + temp = -32768; + if (temp > 32767) + temp = 32767; + buffer[c + 1] += temp; + } + + adgold->opl.pos = 0; + adgold->pos = 0; + + free(adgold_buffer); } static void adgold_filter_cd_audio(int channel, double *buffer, void *p) { - adgold_t *adgold = (adgold_t *)p; - double c; - int aux = channel ? adgold->aux_vol_r : adgold->aux_vol_l; - int vol = channel ? adgold->vol_r : adgold->vol_l; + adgold_t *adgold = (adgold_t *) p; + double c; + int aux = channel ? adgold->aux_vol_r : adgold->aux_vol_l; + int vol = channel ? adgold->vol_r : adgold->vol_l; - c = ((((*buffer) * aux) / 4096.0) * vol) / 4096.0; + c = ((((*buffer) * aux) / 4096.0) * vol) / 4096.0; *buffer = c; } - -static void adgold_input_msg(void *p, uint8_t *msg, uint32_t len) +static void +adgold_input_msg(void *p, uint8_t *msg, uint32_t len) { - adgold_t *adgold = (adgold_t *)p; - uint8_t i; + adgold_t *adgold = (adgold_t *) p; + uint8_t i; - if (adgold->sysex) - return; + if (adgold->sysex) + return; - if (adgold->uart_in) { - adgold->adgold_mma_status |= 0x04; + if (adgold->uart_in) { + adgold->adgold_mma_status |= 0x04; - for (i=0; i < len; i++) { - adgold->midi_queue[adgold->midi_w++] = msg[i]; - adgold->midi_w &= 0x0f; - } - - adgold_update_irq_status(adgold); - } -} - -static int adgold_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort) -{ - adgold_t *adgold = (adgold_t *)p; - uint32_t i; - - if (abort) { - adgold->sysex = 0; - return 0; - } - adgold->sysex = 1; - for (i=0;imidi_r == adgold->midi_w) - return (len-i); - adgold->midi_queue[adgold->midi_w++] = buffer[i]; - adgold->midi_w &= 0x0f; - } - adgold->sysex = 0; - return 0; -} - - -void *adgold_init(const device_t *info) -{ - FILE *f; - int c; - double out; - adgold_t *adgold = malloc(sizeof(adgold_t)); - memset(adgold, 0, sizeof(adgold_t)); - - adgold->surround_enabled = device_get_config_int("surround"); - - adgold->gameport_enabled = device_get_config_int("gameport"); - - opl3_init(&adgold->opl); - if (adgold->surround_enabled) - ym7128_init(&adgold->ym7128); - - out = 65536.0; /*Main volume control ranges from +6 dB to -64 dB in 2 dB steps, then remaining settings are -80 dB (effectively 0)*/ - for (c = 0x3f; c >= 0x1c; c--) - { - attenuation[c] = (int)out; - out /= 1.25963; /*2 dB steps*/ - } - for (; c >= 0; c--) - attenuation[c] = 0; - - adgold->adgold_eeprom[0x00] = 0x00; - adgold->adgold_eeprom[0x01] = 0x00; - adgold->adgold_eeprom[0x02] = 0x7f; - adgold->adgold_eeprom[0x03] = 0x7f; - adgold->adgold_eeprom[0x04] = 0xf8; /* vol_l */ - adgold->adgold_eeprom[0x05] = 0xf8; /* vol_r */ - adgold->adgold_eeprom[0x06] = 0xf6; /* bass */ - adgold->adgold_eeprom[0x07] = 0xf6; /* treble */ - adgold->adgold_eeprom[0x08] = 0xce; - adgold->adgold_eeprom[0x09] = 0xff; /* fm_vol_l */ - adgold->adgold_eeprom[0x0a] = 0xff; /* fm_vol_r */ - adgold->adgold_eeprom[0x0b] = 0xff; /* samp_vol_l */ - adgold->adgold_eeprom[0x0c] = 0xff; /* samp_vol_r */ - adgold->adgold_eeprom[0x0d] = 0xff; /* aux_vol_l */ - adgold->adgold_eeprom[0x0e] = 0xff; /* aux_vol_r */ - adgold->adgold_eeprom[0x0f] = 0xff; - adgold->adgold_eeprom[0x10] = 0xff; - adgold->adgold_eeprom[0x11] = 0x20; - adgold->adgold_eeprom[0x12] = 0x00; - adgold->adgold_eeprom[0x13] = 0x0b; /* IRQ 1, DMA1 */ - adgold->adgold_eeprom[0x14] = 0x00; /* DMA2 */ - adgold->adgold_eeprom[0x15] = 0x71; /* Port */ - adgold->adgold_eeprom[0x16] = 0x00; - adgold->adgold_eeprom[0x17] = 0x68; - adgold->adgold_eeprom[0x18] = 0x00; /* Surround */ - adgold->adgold_eeprom[0x19] = 0x00; - - f = nvr_fopen("adgold.bin", "rb"); - if (f) - { - if (fread(adgold->adgold_eeprom, 1, 0x1a, f) != 0x1a) - fatal("adgold_init(): Error reading data\n"); - fclose(f); + for (i = 0; i < len; i++) { + adgold->midi_queue[adgold->midi_w++] = msg[i]; + adgold->midi_w &= 0x0f; } - adgold->adgold_status = 0xf; - adgold->adgold_38x_addr = 0; - adgold->adgold_eeprom[0x13] = 3 | (1 << 3); /*IRQ 7, DMA 1*/ -// adgold->adgold_eeprom[0x14] = 3 << 4; /*DMA 3 - Double check this */ - adgold->adgold_eeprom[0x14] = 0x00; /*DMA ?*/ - adgold->adgold_eeprom[0x15] = 0x388 / 8; /*Present at 388-38f*/ - memcpy(adgold->adgold_38x_regs, adgold->adgold_eeprom, 0x19); - adgold->vol_l = attenuation[adgold->adgold_eeprom[0x04] & 0x3f]; - adgold->vol_r = attenuation[adgold->adgold_eeprom[0x05] & 0x3f]; - adgold->bass = adgold->adgold_eeprom[0x06] & 0xf; - adgold->treble = adgold->adgold_eeprom[0x07] & 0xf; - adgold->fm_vol_l = (int)(int8_t)(adgold->adgold_eeprom[0x09] - 128); - adgold->fm_vol_r = (int)(int8_t)(adgold->adgold_eeprom[0x0a] - 128); - adgold->samp_vol_l = (int)(int8_t)(adgold->adgold_eeprom[0x0b] - 128); - adgold->samp_vol_r = (int)(int8_t)(adgold->adgold_eeprom[0x0c] - 128); - adgold->aux_vol_l = (int)(int8_t)(adgold->adgold_eeprom[0x0d] - 128); - adgold->aux_vol_r = (int)(int8_t)(adgold->adgold_eeprom[0x0e] - 128); + adgold_update_irq_status(adgold); + } +} - adgold->adgold_mma_enable[0] = 0; - adgold->adgold_mma_fifo_start[0] = adgold->adgold_mma_fifo_end[0] = 0; +static int +adgold_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort) +{ + adgold_t *adgold = (adgold_t *) p; + uint32_t i; - /*388/389 are handled by adlib_init*/ - io_sethandler(0x0388, 0x0008, adgold_read, NULL, NULL, adgold_write, NULL, NULL, adgold); + if (abort) { + adgold->sysex = 0; + return 0; + } + adgold->sysex = 1; + for (i = 0; i < len; i++) { + if (adgold->midi_r == adgold->midi_w) + return (len - i); + adgold->midi_queue[adgold->midi_w++] = buffer[i]; + adgold->midi_w &= 0x0f; + } + adgold->sysex = 0; + return 0; +} - if (adgold->gameport_enabled) +void * +adgold_init(const device_t *info) +{ + FILE *f; + int c; + double out; + adgold_t *adgold = malloc(sizeof(adgold_t)); + memset(adgold, 0, sizeof(adgold_t)); + + adgold->surround_enabled = device_get_config_int("surround"); + + adgold->gameport_enabled = device_get_config_int("gameport"); + + opl3_init(&adgold->opl); + if (adgold->surround_enabled) + ym7128_init(&adgold->ym7128); + + out = 65536.0; /*Main volume control ranges from +6 dB to -64 dB in 2 dB steps, then remaining settings are -80 dB (effectively 0)*/ + for (c = 0x3f; c >= 0x1c; c--) { + attenuation[c] = (int) out; + out /= 1.25963; /*2 dB steps*/ + } + for (; c >= 0; c--) + attenuation[c] = 0; + + adgold->adgold_eeprom[0x00] = 0x00; + adgold->adgold_eeprom[0x01] = 0x00; + adgold->adgold_eeprom[0x02] = 0x7f; + adgold->adgold_eeprom[0x03] = 0x7f; + adgold->adgold_eeprom[0x04] = 0xf8; /* vol_l */ + adgold->adgold_eeprom[0x05] = 0xf8; /* vol_r */ + adgold->adgold_eeprom[0x06] = 0xf6; /* bass */ + adgold->adgold_eeprom[0x07] = 0xf6; /* treble */ + adgold->adgold_eeprom[0x08] = 0xce; + adgold->adgold_eeprom[0x09] = 0xff; /* fm_vol_l */ + adgold->adgold_eeprom[0x0a] = 0xff; /* fm_vol_r */ + adgold->adgold_eeprom[0x0b] = 0xff; /* samp_vol_l */ + adgold->adgold_eeprom[0x0c] = 0xff; /* samp_vol_r */ + adgold->adgold_eeprom[0x0d] = 0xff; /* aux_vol_l */ + adgold->adgold_eeprom[0x0e] = 0xff; /* aux_vol_r */ + adgold->adgold_eeprom[0x0f] = 0xff; + adgold->adgold_eeprom[0x10] = 0xff; + adgold->adgold_eeprom[0x11] = 0x20; + adgold->adgold_eeprom[0x12] = 0x00; + adgold->adgold_eeprom[0x13] = 0x0b; /* IRQ 1, DMA1 */ + adgold->adgold_eeprom[0x14] = 0x00; /* DMA2 */ + adgold->adgold_eeprom[0x15] = 0x71; /* Port */ + adgold->adgold_eeprom[0x16] = 0x00; + adgold->adgold_eeprom[0x17] = 0x68; + adgold->adgold_eeprom[0x18] = 0x00; /* Surround */ + adgold->adgold_eeprom[0x19] = 0x00; + + f = nvr_fopen("adgold.bin", "rb"); + if (f) { + if (fread(adgold->adgold_eeprom, 1, 0x1a, f) != 0x1a) + fatal("adgold_init(): Error reading data\n"); + fclose(f); + } + + adgold->adgold_status = 0xf; + adgold->adgold_38x_addr = 0; + adgold->adgold_eeprom[0x13] = 3 | (1 << 3); /*IRQ 7, DMA 1*/ + // adgold->adgold_eeprom[0x14] = 3 << 4; /*DMA 3 - Double check this */ + adgold->adgold_eeprom[0x14] = 0x00; /*DMA ?*/ + adgold->adgold_eeprom[0x15] = 0x388 / 8; /*Present at 388-38f*/ + memcpy(adgold->adgold_38x_regs, adgold->adgold_eeprom, 0x19); + adgold->vol_l = attenuation[adgold->adgold_eeprom[0x04] & 0x3f]; + adgold->vol_r = attenuation[adgold->adgold_eeprom[0x05] & 0x3f]; + adgold->bass = adgold->adgold_eeprom[0x06] & 0xf; + adgold->treble = adgold->adgold_eeprom[0x07] & 0xf; + adgold->fm_vol_l = (int) (int8_t) (adgold->adgold_eeprom[0x09] - 128); + adgold->fm_vol_r = (int) (int8_t) (adgold->adgold_eeprom[0x0a] - 128); + adgold->samp_vol_l = (int) (int8_t) (adgold->adgold_eeprom[0x0b] - 128); + adgold->samp_vol_r = (int) (int8_t) (adgold->adgold_eeprom[0x0c] - 128); + adgold->aux_vol_l = (int) (int8_t) (adgold->adgold_eeprom[0x0d] - 128); + adgold->aux_vol_r = (int) (int8_t) (adgold->adgold_eeprom[0x0e] - 128); + + adgold->adgold_mma_enable[0] = 0; + adgold->adgold_mma_fifo_start[0] = adgold->adgold_mma_fifo_end[0] = 0; + + /*388/389 are handled by adlib_init*/ + io_sethandler(0x0388, 0x0008, adgold_read, NULL, NULL, adgold_write, NULL, NULL, adgold); + + if (adgold->gameport_enabled) gameport_remap(gameport_add(&gameport_201_device), 0x201); - timer_add(&adgold->adgold_mma_timer_count, adgold_timer_poll, adgold, 1); + timer_add(&adgold->adgold_mma_timer_count, adgold_timer_poll, adgold, 1); - sound_add_handler(adgold_get_buffer, adgold); - sound_set_cd_audio_filter(adgold_filter_cd_audio, adgold); + sound_add_handler(adgold_get_buffer, adgold); + sound_set_cd_audio_filter(adgold_filter_cd_audio, adgold); - if (device_get_config_int("receive_input")) - midi_in_handler(1, adgold_input_msg, adgold_input_sysex, adgold); + if (device_get_config_int("receive_input")) + midi_in_handler(1, adgold_input_msg, adgold_input_sysex, adgold); - return adgold; + return adgold; } -void adgold_close(void *p) +void +adgold_close(void *p) { - FILE *f; - adgold_t *adgold = (adgold_t *)p; + FILE *f; + adgold_t *adgold = (adgold_t *) p; - f = nvr_fopen("adgold.bin", "wb"); - if (f) - { - fwrite(adgold->adgold_eeprom, 0x1a, 1, f); - fclose(f); - } + f = nvr_fopen("adgold.bin", "wb"); + if (f) { + fwrite(adgold->adgold_eeprom, 0x1a, 1, f); + fclose(f); + } - free(adgold); + free(adgold); } -static const device_config_t adgold_config[] = -{ - { - "gameport", "Enable Game port", CONFIG_BINARY, "", 1 - }, - { - "surround", "Surround module", CONFIG_BINARY, "", 1 - }, - { - "receive_input", "Receive input (MIDI)", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 - } +static const device_config_t adgold_config[] = { +// clang-format off + { "gameport", "Enable Game port", CONFIG_BINARY, "", 1 }, + { "surround", "Surround module", CONFIG_BINARY, "", 1 }, + { "receive_input", "Receive input (MIDI)", CONFIG_BINARY, "", 1 }, + { "", "", -1 } +// clang-format on }; -const device_t adgold_device = -{ - "AdLib Gold", - "adlibgold", - DEVICE_ISA, 0, - adgold_init, - adgold_close, - NULL, - { NULL }, - NULL, - NULL, - adgold_config +const device_t adgold_device = { + "AdLib Gold", + "adlibgold", + DEVICE_ISA, + 0, + adgold_init, + adgold_close, + NULL, + { NULL }, + NULL, + NULL, + adgold_config }; diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 63f632ea7..23f1fa40c 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -1,178 +1,174 @@ /* - * 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 (ES1371) emulation. + * Ensoniq AudioPCI (ES1371) emulation. * * * - * Authors: Sarah Walker, - * RichardG, - * Miran Grca, + * Authors: Sarah Walker, + * RichardG, + * Miran Grca, * - * Copyright 2008-2021 Sarah Walker. - * Copyright 2021 RichardG. - * Copyright 2021 Miran Grca. + * Copyright 2008-2021 Sarah Walker. + * Copyright 2021 RichardG. + * Copyright 2021 Miran Grca. */ -#include +#include #include +#include #include #include -#include #define _USE_MATH_DEFINES #include #define HAVE_STDARG_H + #include <86box/86box.h> #include <86box/device.h> #include <86box/gameport.h> #include <86box/io.h> -#include <86box/nmi.h> #include <86box/mem.h> -#include <86box/pci.h> -#include <86box/timer.h> -#include <86box/sound.h> #include <86box/midi.h> +#include <86box/nmi.h> +#include <86box/pci.h> #include <86box/snd_ac97.h> +#include <86box/sound.h> +#include <86box/timer.h> - -#define N 16 +#define N 16 #define ES1371_NCoef 91 - static float low_fir_es1371_coef[ES1371_NCoef]; - typedef struct { - uint8_t pci_command, pci_serr; + uint8_t pci_command, pci_serr; - uint32_t base_addr; + uint32_t base_addr; - uint8_t int_line; + uint8_t int_line; - uint16_t pmcsr; + uint16_t pmcsr; - uint32_t int_ctrl, int_status, - legacy_ctrl; - void * gameport; + uint32_t int_ctrl, int_status, + legacy_ctrl; + void *gameport; - int mem_page; + int mem_page; - uint32_t si_cr; + uint32_t si_cr; - uint32_t sr_cir; - uint16_t sr_ram[128]; + uint32_t sr_cir; + uint16_t sr_ram[128]; - uint8_t uart_data, uart_ctrl, - uart_status, uart_res; - uint32_t uart_fifo[8]; - uint8_t read_fifo_pos, write_fifo_pos; + uint8_t uart_data, uart_ctrl, + uart_status, uart_res; + uint32_t uart_fifo[8]; + uint8_t read_fifo_pos, write_fifo_pos; - ac97_codec_t * codec; - uint32_t codec_ctrl; + ac97_codec_t *codec; + uint32_t codec_ctrl; struct { - uint32_t addr, addr_latch; - uint16_t count, size; + uint32_t addr, addr_latch; + uint16_t count, size; - uint16_t samp_ct; - int curr_samp_ct; + uint16_t samp_ct; + int curr_samp_ct; - pc_timer_t timer; - uint64_t latch; + pc_timer_t timer; + uint64_t latch; - uint32_t vf, ac; + uint32_t vf, ac; - int16_t buffer_l[64], buffer_r[64]; - int buffer_pos, buffer_pos_end; + int16_t buffer_l[64], buffer_r[64]; + int buffer_pos, buffer_pos_end; - int filtered_l[32], filtered_r[32]; - int f_pos; + int filtered_l[32], filtered_r[32]; + int f_pos; - int16_t out_l, out_r; + int16_t out_l, out_r; - int32_t vol_l, vol_r; + int32_t vol_l, vol_r; } dac[2], adc; - int64_t dac_latch, dac_time; + int64_t dac_latch, dac_time; - int master_vol_l, master_vol_r, - pcm_vol_l, pcm_vol_r, - cd_vol_l, cd_vol_r; + int master_vol_l, master_vol_r, + pcm_vol_l, pcm_vol_r, + cd_vol_l, cd_vol_r; - int card; + int card; - int pos; - int16_t buffer[SOUNDBUFLEN * 2]; + int pos; + int16_t buffer[SOUNDBUFLEN * 2]; - int type; + int type; } es1371_t; +#define LEGACY_SB_ADDR (1 << 29) +#define LEGACY_SSCAPE_ADDR_SHIFT 27 +#define LEGACY_CODEC_ADDR_SHIFT 25 +#define LEGACY_FORCE_IRQ (1 << 24) +#define LEGACY_CAPTURE_SLAVE_DMA (1 << 23) +#define LEGACY_CAPTURE_SLAVE_PIC (1 << 22) +#define LEGACY_CAPTURE_MASTER_DMA (1 << 21) +#define LEGACY_CAPTURE_MASTER_PIC (1 << 20) +#define LEGACY_CAPTURE_ADLIB (1 << 19) +#define LEGACY_CAPTURE_SB (1 << 18) +#define LEGACY_CAPTURE_CODEC (1 << 17) +#define LEGACY_CAPTURE_SSCAPE (1 << 16) +#define LEGACY_EVENT_SSCAPE (0 << 8) +#define LEGACY_EVENT_CODEC (1 << 8) +#define LEGACY_EVENT_SB (2 << 8) +#define LEGACY_EVENT_ADLIB (3 << 8) +#define LEGACY_EVENT_MASTER_PIC (4 << 8) +#define LEGACY_EVENT_MASTER_DMA (5 << 8) +#define LEGACY_EVENT_SLAVE_PIC (6 << 8) +#define LEGACY_EVENT_SLAVE_DMA (7 << 8) +#define LEGACY_EVENT_MASK (7 << 8) +#define LEGACY_EVENT_ADDR_SHIFT 3 +#define LEGACY_EVENT_ADDR_MASK (0x1f << 3) +#define LEGACY_EVENT_TYPE_RW (1 << 2) +#define LEGACY_INT (1 << 0) -#define LEGACY_SB_ADDR (1<<29) -#define LEGACY_SSCAPE_ADDR_SHIFT 27 -#define LEGACY_CODEC_ADDR_SHIFT 25 -#define LEGACY_FORCE_IRQ (1<<24) -#define LEGACY_CAPTURE_SLAVE_DMA (1<<23) -#define LEGACY_CAPTURE_SLAVE_PIC (1<<22) -#define LEGACY_CAPTURE_MASTER_DMA (1<<21) -#define LEGACY_CAPTURE_MASTER_PIC (1<<20) -#define LEGACY_CAPTURE_ADLIB (1<<19) -#define LEGACY_CAPTURE_SB (1<<18) -#define LEGACY_CAPTURE_CODEC (1<<17) -#define LEGACY_CAPTURE_SSCAPE (1<<16) -#define LEGACY_EVENT_SSCAPE (0<<8) -#define LEGACY_EVENT_CODEC (1<<8) -#define LEGACY_EVENT_SB (2<<8) -#define LEGACY_EVENT_ADLIB (3<<8) -#define LEGACY_EVENT_MASTER_PIC (4<<8) -#define LEGACY_EVENT_MASTER_DMA (5<<8) -#define LEGACY_EVENT_SLAVE_PIC (6<<8) -#define LEGACY_EVENT_SLAVE_DMA (7<<8) -#define LEGACY_EVENT_MASK (7<<8) -#define LEGACY_EVENT_ADDR_SHIFT 3 -#define LEGACY_EVENT_ADDR_MASK (0x1f<<3) -#define LEGACY_EVENT_TYPE_RW (1<<2) -#define LEGACY_INT (1<<0) +#define SRC_RAM_WE (1 << 24) -#define SRC_RAM_WE (1<<24) +#define CODEC_READ (1 << 23) +#define CODEC_READY (1 << 31) -#define CODEC_READ (1<<23) -#define CODEC_READY (1<<31) +#define INT_DAC1_EN (1 << 6) +#define INT_DAC2_EN (1 << 5) +#define INT_UART_EN (1 << 3) -#define INT_DAC1_EN (1<<6) -#define INT_DAC2_EN (1<<5) -#define INT_UART_EN (1<<3) +#define SI_P2_PAUSE (1 << 12) +#define SI_P1_PAUSE (1 << 11) +#define SI_P2_INTR_EN (1 << 9) +#define SI_P1_INTR_EN (1 << 8) -#define SI_P2_PAUSE (1<<12) -#define SI_P1_PAUSE (1<<11) -#define SI_P2_INTR_EN (1<<9) -#define SI_P1_INTR_EN (1<<8) +#define INT_STATUS_INTR (1 << 31) +#define INT_STATUS_UART (1 << 3) +#define INT_STATUS_DAC1 (1 << 2) +#define INT_STATUS_DAC2 (1 << 1) -#define INT_STATUS_INTR (1<<31) -#define INT_STATUS_UART (1<<3) -#define INT_STATUS_DAC1 (1<<2) -#define INT_STATUS_DAC2 (1<<1) +#define UART_CTRL_RXINTEN (1 << 7) +#define UART_CTRL_TXINTEN (3 << 5) -#define UART_CTRL_RXINTEN (1<<7) -#define UART_CTRL_TXINTEN (3<<5) +#define UART_STATUS_RXINT (1 << 7) +#define UART_STATUS_TXINT (1 << 2) +#define UART_STATUS_TXRDY (1 << 1) +#define UART_STATUS_RXRDY (1 << 0) -#define UART_STATUS_RXINT (1<<7) -#define UART_STATUS_TXINT (1<<2) -#define UART_STATUS_TXRDY (1<<1) -#define UART_STATUS_RXRDY (1<<0) - -#define UART_FIFO_BYTE_VALID 0x00000100 - -#define FORMAT_MONO_8 0 -#define FORMAT_STEREO_8 1 -#define FORMAT_MONO_16 2 -#define FORMAT_STEREO_16 3 +#define UART_FIFO_BYTE_VALID 0x00000100 +#define FORMAT_MONO_8 0 +#define FORMAT_STEREO_8 1 +#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); @@ -180,145 +176,135 @@ static void update_legacy(es1371_t *dev, uint32_t old_legacy_ctrl); #ifdef ENABLE_AUDIOPCI_LOG int audiopci_do_log = ENABLE_AUDIOPCI_LOG; - static void audiopci_log(const char *fmt, ...) { va_list ap; if (audiopci_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define audiopci_log(fmt, ...) +# define audiopci_log(fmt, ...) #endif - static void es1371_update_irqs(es1371_t *dev) { int irq = 0; if ((dev->int_status & INT_STATUS_DAC1) && (dev->si_cr & SI_P1_INTR_EN)) - irq = 1; + irq = 1; if ((dev->int_status & INT_STATUS_DAC2) && (dev->si_cr & SI_P2_INTR_EN)) - irq = 1; + irq = 1; dev->int_status &= ~INT_STATUS_UART; if ((dev->uart_status & UART_STATUS_TXINT) || (dev->uart_status & UART_STATUS_RXINT)) { - dev->int_status |= INT_STATUS_UART; - irq = 1; + dev->int_status |= INT_STATUS_UART; + irq = 1; } if (irq) - dev->int_status |= INT_STATUS_INTR; + dev->int_status |= INT_STATUS_INTR; else - dev->int_status &= ~INT_STATUS_INTR; + dev->int_status &= ~INT_STATUS_INTR; if (dev->legacy_ctrl & LEGACY_FORCE_IRQ) - irq = 1; + irq = 1; if (irq) - pci_set_irq(dev->card, PCI_INTA); + pci_set_irq(dev->card, PCI_INTA); else - pci_clear_irq(dev->card, PCI_INTA); + pci_clear_irq(dev->card, PCI_INTA); } - static void es1371_update_tx_irq(es1371_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; + dev->uart_status |= UART_STATUS_TXINT; es1371_update_irqs(dev); } - static void es1371_set_tx_irq(es1371_t *dev, int set) { dev->uart_status &= ~UART_STATUS_TXRDY; if (set) - dev->uart_status |= UART_STATUS_TXRDY; + dev->uart_status |= UART_STATUS_TXRDY; es1371_update_tx_irq(dev); } - static void es1371_update_rx_irq(es1371_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; + dev->uart_status |= UART_STATUS_RXINT; es1371_update_irqs(dev); } - static void es1371_set_rx_irq(es1371_t *dev, int set) { dev->uart_status &= ~UART_STATUS_RXRDY; if (set) - dev->uart_status |= UART_STATUS_RXRDY; + dev->uart_status |= UART_STATUS_RXRDY; es1371_update_rx_irq(dev); } - static void es1371_scan_fifo(es1371_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; + 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); + es1371_set_rx_irq(dev, 1); } else - es1371_set_rx_irq(dev, 0); + es1371_set_rx_irq(dev, 0); } - static void es1371_write_fifo(es1371_t *dev, uint8_t val) { if (dev->write_fifo_pos < 8) { - dev->uart_fifo[dev->write_fifo_pos] = val | UART_FIFO_BYTE_VALID; - dev->write_fifo_pos = (dev->write_fifo_pos + 1) & 7; + dev->uart_fifo[dev->write_fifo_pos] = val | UART_FIFO_BYTE_VALID; + dev->write_fifo_pos = (dev->write_fifo_pos + 1) & 7; } } - static void es1371_reset_fifo(es1371_t *dev) { int i; for (i = 0; i < 8; i++) - dev->uart_fifo[i] = 0x00000000; + dev->uart_fifo[i] = 0x00000000; dev->read_fifo_pos = dev->write_fifo_pos = 0; es1371_set_rx_irq(dev, 0); } - static void es1371_reset(void *p) { es1371_t *dev = (es1371_t *) p; - int i; + int i; nmi = 0; @@ -364,17 +350,17 @@ es1371_reset(void *p) /* DAC1 Channel Sample Count Register, Address 24H Addressable as word, longword */ - dev->dac[0].samp_ct = 0x00000000; + dev->dac[0].samp_ct = 0x00000000; dev->dac[0].curr_samp_ct = 0x00000000; /* DAC2 Channel Sample Count Register, Address 28H Addressable as word, longword */ - dev->dac[1].samp_ct = 0x00000000; + dev->dac[1].samp_ct = 0x00000000; dev->dac[1].curr_samp_ct = 0x00000000; /* ADC Channel Sample Count Register, Address 2CH Addressable as word, longword */ - dev->adc.samp_ct = 0x00000000; + dev->adc.samp_ct = 0x00000000; dev->adc.curr_samp_ct = 0x00000000; /* DAC1 Frame Register 1, Address 30H, Memory Page 1100b @@ -383,7 +369,7 @@ es1371_reset(void *p) /* DAC1 Frame Register 2, Address 34H, Memory Page 1100b Addressable as longword only */ - dev->dac[0].size = 0x00000000; + dev->dac[0].size = 0x00000000; dev->dac[0].count = 0x00000000; /* DAC2 Frame Register 1, Address 38H, Memory Page 1100b @@ -392,7 +378,7 @@ es1371_reset(void *p) /* DAC2 Frame Register 2, Address 3CH, Memory Page 1100b Addressable as longword only */ - dev->dac[1].size = 0x00000000; + dev->dac[1].size = 0x00000000; dev->dac[1].count = 0x00000000; /* ADC Frame Register 1, Address 30H, Memory Page 1101b @@ -401,13 +387,13 @@ es1371_reset(void *p) /* ADC Frame Register 2, Address 34H, Memory Page 1101b Addressable as longword only */ - dev->adc.size = 0x00000000; + dev->adc.size = 0x00000000; dev->adc.count = 0x00000000; /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b Addressable as longword only */ for (i = 0; i < 8; i++) - dev->uart_fifo[i] = 0xffff0000; + dev->uart_fifo[i] = 0xffff0000; /* Reset the UART TX. */ es1371_set_tx_irq(dev, 0); @@ -419,890 +405,892 @@ es1371_reset(void *p) es1371_update_irqs(dev); } - static uint32_t es1371_read_frame_reg(es1371_t *dev, int frame, int page) { uint32_t ret = 0xffffffff; switch (frame) { - case 0x30: - switch (page) { - /* DAC1 Frame Register 1, Address 30H, Memory Page 1100b - Addressable as longword only */ - case 0xc: - ret = dev->dac[0].addr_latch; - break; - /* ADC Frame Register 1, Address 30H, Memory Page 1101b - Addressable as longword only */ - case 0xd: - ret = dev->adc.addr_latch; - break; - /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b - Addressable as longword only */ - case 0xe: case 0xf: - audiopci_log("[30:%02X] ret = dev->uart_fifo[%02X] = %08X\n", page, - ((page & 0x01) << 2) + ((frame >> 2) & 0x03), - dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]); - ret = dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]; - break; - } - break; - case 0x34: - switch (page) { - /* DAC1 Frame Register 2, Address 34H, Memory Page 1100b - Addressable as longword only */ - case 0xc: - ret = dev->dac[0].size | (dev->dac[0].count << 16); - break; - /* ADC Frame Register 2, Address 34H, Memory Page 1101b - Addressable as longword only */ - case 0xd: - ret = dev->adc.size | (dev->adc.count << 16); - break; - /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b - Addressable as longword only */ - case 0xe: case 0xf: - audiopci_log("[34:%02X] ret = dev->uart_fifo[%02X] = %08X\n", page, - ((page & 0x01) << 2) + ((frame >> 2) & 0x03), - dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]); - ret = dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]; - break; - } - break; - case 0x38: - switch (page) { - /* DAC2 Frame Register 1, Address 38H, Memory Page 1100b - Addressable as longword only */ - case 0xc: - ret = dev->dac[1].addr_latch; - break; - /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b - Addressable as longword only */ - case 0xe: case 0xf: - audiopci_log("[38:%02X] ret = dev->uart_fifo[%02X] = %08X\n", page, - ((page & 0x01) << 2) + ((frame >> 2) & 0x03), - dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]); - ret = dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]; - break; - } - break; - case 0x3c: - switch (page) { - /* DAC2 Frame Register 2, Address 3CH, Memory Page 1100b - Addressable as longword only */ - case 0xc: - ret = dev->dac[1].size | (dev->dac[1].count << 16); - break; - /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b - Addressable as longword only */ - case 0xe: case 0xf: - audiopci_log("[3C:%02X] ret = dev->uart_fifo[%02X] = %08X\n", page, - ((page & 0x01) << 2) + ((frame >> 2) & 0x03), - dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]); - ret = dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]; - break; - } - break; + case 0x30: + switch (page) { + /* DAC1 Frame Register 1, Address 30H, Memory Page 1100b + Addressable as longword only */ + case 0xc: + ret = dev->dac[0].addr_latch; + break; + /* ADC Frame Register 1, Address 30H, Memory Page 1101b + Addressable as longword only */ + case 0xd: + ret = dev->adc.addr_latch; + break; + /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b + Addressable as longword only */ + case 0xe: + case 0xf: + audiopci_log("[30:%02X] ret = dev->uart_fifo[%02X] = %08X\n", page, + ((page & 0x01) << 2) + ((frame >> 2) & 0x03), + dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]); + ret = dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]; + break; + } + break; + case 0x34: + switch (page) { + /* DAC1 Frame Register 2, Address 34H, Memory Page 1100b + Addressable as longword only */ + case 0xc: + ret = dev->dac[0].size | (dev->dac[0].count << 16); + break; + /* ADC Frame Register 2, Address 34H, Memory Page 1101b + Addressable as longword only */ + case 0xd: + ret = dev->adc.size | (dev->adc.count << 16); + break; + /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b + Addressable as longword only */ + case 0xe: + case 0xf: + audiopci_log("[34:%02X] ret = dev->uart_fifo[%02X] = %08X\n", page, + ((page & 0x01) << 2) + ((frame >> 2) & 0x03), + dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]); + ret = dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]; + break; + } + break; + case 0x38: + switch (page) { + /* DAC2 Frame Register 1, Address 38H, Memory Page 1100b + Addressable as longword only */ + case 0xc: + ret = dev->dac[1].addr_latch; + break; + /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b + Addressable as longword only */ + case 0xe: + case 0xf: + audiopci_log("[38:%02X] ret = dev->uart_fifo[%02X] = %08X\n", page, + ((page & 0x01) << 2) + ((frame >> 2) & 0x03), + dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]); + ret = dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]; + break; + } + break; + case 0x3c: + switch (page) { + /* DAC2 Frame Register 2, Address 3CH, Memory Page 1100b + Addressable as longword only */ + case 0xc: + ret = dev->dac[1].size | (dev->dac[1].count << 16); + break; + /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b + Addressable as longword only */ + case 0xe: + case 0xf: + audiopci_log("[3C:%02X] ret = dev->uart_fifo[%02X] = %08X\n", page, + ((page & 0x01) << 2) + ((frame >> 2) & 0x03), + dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]); + ret = dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]; + break; + } + break; } - if (page == 0x0e || page == 0x0f) { - audiopci_log("Read frame = %02x, page = %02x, uart fifo valid = %02x, temp = %03x\n", frame, page, dev->valid, ret); - } + if (page == 0x0e || page == 0x0f) { + audiopci_log("Read frame = %02x, page = %02x, uart fifo valid = %02x, temp = %03x\n", frame, page, dev->valid, ret); + } return ret; } - static void es1371_write_frame_reg(es1371_t *dev, int frame, int page, uint32_t val) { switch (frame) { - case 0x30: - switch (page) { - /* DAC1 Frame Register 1, Address 30H, Memory Page 1100b - Addressable as longword only */ - case 0xc: - dev->dac[0].addr_latch = val; - break; - /* ADC Frame Register 1, Address 30H, Memory Page 1101b - Addressable as longword only */ - case 0xd: - dev->adc.addr_latch = val; - break; - /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b - Addressable as longword only */ - case 0xe: case 0xf: - audiopci_log("[30:%02X] dev->uart_fifo[%02X] = %08X\n", page, - ((page & 0x01) << 2) + ((frame >> 2) & 0x03), val); - dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)] = val; - break; - } - break; - case 0x34: - switch (page) { - /* DAC1 Frame Register 2, Address 34H, Memory Page 1100b - Addressable as longword only */ - case 0xc: - dev->dac[0].size = val & 0xffff; - dev->dac[0].count = val >> 16; - break; - /* ADC Frame Register 2, Address 34H, Memory Page 1101b - Addressable as longword only */ - case 0xd: - dev->adc.size = val & 0xffff; - dev->adc.count = val >> 16; - break; - /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b - Addressable as longword only */ - case 0xe: case 0xf: - audiopci_log("[34:%02X] dev->uart_fifo[%02X] = %08X\n", page, - ((page & 0x01) << 2) + ((frame >> 2) & 0x03), val); - dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)] = val; - break; - } - break; - case 0x38: - switch (page) { - /* DAC2 Frame Register 1, Address 38H, Memory Page 1100b - Addressable as longword only */ - case 0xc: - dev->dac[1].addr_latch = val; - break; - /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b - Addressable as longword only */ - case 0xe: case 0xf: - audiopci_log("[38:%02X] dev->uart_fifo[%02X] = %08X\n", page, - ((page & 0x01) << 2) + ((frame >> 2) & 0x03), val); - dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)] = val; - break; - } - break; - case 0x3c: - switch (page) { - /* DAC2 Frame Register 2, Address 3CH, Memory Page 1100b - Addressable as longword only */ - case 0xc: - dev->dac[1].size = val & 0xffff; - dev->dac[1].count = val >> 16; - break; - /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b - Addressable as longword only */ - case 0xe: case 0xf: - audiopci_log("[3C:%02X] dev->uart_fifo[%02X] = %08X\n", page, - ((page & 0x01) << 2) + ((frame >> 2) & 0x03), val); - dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)] = val; - break; - } - break; + case 0x30: + switch (page) { + /* DAC1 Frame Register 1, Address 30H, Memory Page 1100b + Addressable as longword only */ + case 0xc: + dev->dac[0].addr_latch = val; + break; + /* ADC Frame Register 1, Address 30H, Memory Page 1101b + Addressable as longword only */ + case 0xd: + dev->adc.addr_latch = val; + break; + /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b + Addressable as longword only */ + case 0xe: + case 0xf: + audiopci_log("[30:%02X] dev->uart_fifo[%02X] = %08X\n", page, + ((page & 0x01) << 2) + ((frame >> 2) & 0x03), val); + dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)] = val; + break; + } + break; + case 0x34: + switch (page) { + /* DAC1 Frame Register 2, Address 34H, Memory Page 1100b + Addressable as longword only */ + case 0xc: + dev->dac[0].size = val & 0xffff; + dev->dac[0].count = val >> 16; + break; + /* ADC Frame Register 2, Address 34H, Memory Page 1101b + Addressable as longword only */ + case 0xd: + dev->adc.size = val & 0xffff; + dev->adc.count = val >> 16; + break; + /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b + Addressable as longword only */ + case 0xe: + case 0xf: + audiopci_log("[34:%02X] dev->uart_fifo[%02X] = %08X\n", page, + ((page & 0x01) << 2) + ((frame >> 2) & 0x03), val); + dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)] = val; + break; + } + break; + case 0x38: + switch (page) { + /* DAC2 Frame Register 1, Address 38H, Memory Page 1100b + Addressable as longword only */ + case 0xc: + dev->dac[1].addr_latch = val; + break; + /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b + Addressable as longword only */ + case 0xe: + case 0xf: + audiopci_log("[38:%02X] dev->uart_fifo[%02X] = %08X\n", page, + ((page & 0x01) << 2) + ((frame >> 2) & 0x03), val); + dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)] = val; + break; + } + break; + case 0x3c: + switch (page) { + /* DAC2 Frame Register 2, Address 3CH, Memory Page 1100b + Addressable as longword only */ + case 0xc: + dev->dac[1].size = val & 0xffff; + dev->dac[1].count = val >> 16; + break; + /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b + Addressable as longword only */ + case 0xe: + case 0xf: + audiopci_log("[3C:%02X] dev->uart_fifo[%02X] = %08X\n", page, + ((page & 0x01) << 2) + ((frame >> 2) & 0x03), val); + dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)] = val; + break; + } + break; } if (page == 0x0e || page == 0x0f) { - audiopci_log("Write frame = %02x, page = %02x, uart fifo = %08x, val = %02x\n", frame, page, dev->uart_fifo, val); + audiopci_log("Write frame = %02x, page = %02x, uart fifo = %08x, val = %02x\n", frame, page, dev->uart_fifo, val); } } - static uint8_t es1371_inb(uint16_t port, void *p) { es1371_t *dev = (es1371_t *) p; - uint8_t ret = 0xff; + uint8_t ret = 0xff; switch (port & 0x3f) { - /* Interrupt/Chip Select Control Register, Address 00H - Addressable as byte, word, longword */ - case 0x00: - ret = dev->int_ctrl & 0xff; - break; - case 0x01: - ret = (dev->int_ctrl >> 8) & 0xff; - break; - case 0x02: - ret = (dev->int_ctrl >> 16) & 0x0f; - break; - case 0x03: - ret = ((dev->int_ctrl >> 24) & 0x03) | 0xfc; - break; + /* Interrupt/Chip Select Control Register, Address 00H + Addressable as byte, word, longword */ + case 0x00: + ret = dev->int_ctrl & 0xff; + break; + case 0x01: + ret = (dev->int_ctrl >> 8) & 0xff; + break; + case 0x02: + ret = (dev->int_ctrl >> 16) & 0x0f; + break; + case 0x03: + ret = ((dev->int_ctrl >> 24) & 0x03) | 0xfc; + break; - /* Interrupt/Chip Select Status Register, Address 04H - Addressable as longword only, but PCem implements byte access, which - must be for a reason */ - case 0x04: - ret = dev->int_status & 0xff; - audiopci_log("[R] STATUS 0- 7 = %02X\n", ret); - break; - case 0x05: - ret = (dev->int_status >> 8) & 0xff; - audiopci_log("[R] STATUS 8-15 = %02X\n", ret); - break; - case 0x06: - ret = (dev->int_status >> 16) & 0x0f; - audiopci_log("[R] STATUS 16-23 = %02X\n", ret); - break; - case 0x07: - ret = ((dev->int_status >> 24) & 0x03) | 0xfc; - audiopci_log("[R] STATUS 24-31 = %02X\n", ret); - break; + /* Interrupt/Chip Select Status Register, Address 04H + Addressable as longword only, but PCem implements byte access, which + must be for a reason */ + case 0x04: + ret = dev->int_status & 0xff; + audiopci_log("[R] STATUS 0- 7 = %02X\n", ret); + break; + case 0x05: + ret = (dev->int_status >> 8) & 0xff; + audiopci_log("[R] STATUS 8-15 = %02X\n", ret); + break; + case 0x06: + ret = (dev->int_status >> 16) & 0x0f; + audiopci_log("[R] STATUS 16-23 = %02X\n", ret); + break; + case 0x07: + ret = ((dev->int_status >> 24) & 0x03) | 0xfc; + audiopci_log("[R] STATUS 24-31 = %02X\n", ret); + break; - /* UART Data Register, Address 08H - Addressable as byte only */ - case 0x08: - ret = dev->uart_data; - es1371_set_rx_irq(dev, 0); - audiopci_log("[R] UART DATA = %02X\n", ret); - break; + /* UART Data Register, Address 08H + Addressable as byte only */ + case 0x08: + ret = dev->uart_data; + es1371_set_rx_irq(dev, 0); + audiopci_log("[R] UART DATA = %02X\n", ret); + break; - /* UART Status Register, Address 09H - Addressable as byte only */ - case 0x09: - ret = dev->uart_status & 0x87; - audiopci_log("ES1371 UART Status = %02x\n", dev->uart_status); - break; + /* UART Status Register, Address 09H + Addressable as byte only */ + case 0x09: + ret = dev->uart_status & 0x87; + audiopci_log("ES1371 UART Status = %02x\n", dev->uart_status); + break; - /* UART Reserved Register, Address 0AH - Addressable as byte only */ - case 0x0a: - ret = dev->uart_res & 0x01; - audiopci_log("[R] UART RES = %02X\n", ret); - break; + /* UART Reserved Register, Address 0AH + Addressable as byte only */ + case 0x0a: + ret = dev->uart_res & 0x01; + audiopci_log("[R] UART RES = %02X\n", ret); + break; - /* Memory Page Register, Address 0CH - Addressable as byte, word, longword */ - case 0x0c: - ret = dev->mem_page; - break; - case 0x0d ... 0x0e: - ret = 0x00; - break; + /* Memory Page Register, Address 0CH + Addressable as byte, word, longword */ + case 0x0c: + ret = dev->mem_page; + break; + case 0x0d ... 0x0e: + ret = 0x00; + break; - /* Legacy Control/Status Register, Address 18H - Addressable as byte, word, longword */ - case 0x18: - ret = dev->legacy_ctrl & 0xfd; - break; - case 0x19: - ret = ((dev->legacy_ctrl >> 8) & 0x07) | 0xf8; - break; - case 0x1a: - ret = dev->legacy_ctrl >> 16; - break; - case 0x1b: - ret = dev->legacy_ctrl >> 24; - break; + /* Legacy Control/Status Register, Address 18H + Addressable as byte, word, longword */ + case 0x18: + ret = dev->legacy_ctrl & 0xfd; + break; + case 0x19: + ret = ((dev->legacy_ctrl >> 8) & 0x07) | 0xf8; + break; + case 0x1a: + ret = dev->legacy_ctrl >> 16; + break; + case 0x1b: + ret = dev->legacy_ctrl >> 24; + break; - /* Serial Interface Control Register, Address 20H - Addressable as byte, word, longword */ - case 0x20: - ret = dev->si_cr & 0xff; - break; - case 0x21: - ret = dev->si_cr >> 8; - break; - case 0x22: - ret = (dev->si_cr >> 16) | 0x80; - break; - case 0x23: - ret = 0xff; - break; + /* Serial Interface Control Register, Address 20H + Addressable as byte, word, longword */ + case 0x20: + ret = dev->si_cr & 0xff; + break; + case 0x21: + ret = dev->si_cr >> 8; + break; + case 0x22: + ret = (dev->si_cr >> 16) | 0x80; + break; + case 0x23: + ret = 0xff; + break; - default: - audiopci_log("Bad es1371_inb: port=%04x\n", port); + default: + audiopci_log("Bad es1371_inb: port=%04x\n", port); } audiopci_log("es1371_inb: port=%04x ret=%02x\n", port, ret); return ret; } - static uint16_t es1371_inw(uint16_t port, void *p) { es1371_t *dev = (es1371_t *) p; - uint16_t ret = 0xffff; + uint16_t ret = 0xffff; switch (port & 0x3e) { - /* Interrupt/Chip Select Control Register, Address 00H - Addressable as byte, word, longword */ - case 0x00: - ret = dev->int_ctrl & 0xffff; - break; - case 0x02: - ret = ((dev->int_ctrl >> 16) & 0x030f) | 0xfc00; - break; + /* Interrupt/Chip Select Control Register, Address 00H + Addressable as byte, word, longword */ + case 0x00: + ret = dev->int_ctrl & 0xffff; + break; + case 0x02: + ret = ((dev->int_ctrl >> 16) & 0x030f) | 0xfc00; + break; - /* Memory Page Register, Address 0CH - Addressable as byte, word, longword */ - case 0x0c: - ret = dev->mem_page; - break; - case 0x0e: - ret = 0x0000; - break; + /* Memory Page Register, Address 0CH + Addressable as byte, word, longword */ + case 0x0c: + ret = dev->mem_page; + break; + case 0x0e: + ret = 0x0000; + break; - /* Legacy Control/Status Register, Address 18H - Addressable as byte, word, longword */ - case 0x18: - ret = (dev->legacy_ctrl & 0x07fd) | 0xf800; - break; - case 0x1a: - ret = dev->legacy_ctrl >> 16; - break; + /* Legacy Control/Status Register, Address 18H + Addressable as byte, word, longword */ + case 0x18: + ret = (dev->legacy_ctrl & 0x07fd) | 0xf800; + break; + case 0x1a: + ret = dev->legacy_ctrl >> 16; + break; - /* Serial Interface Control Register, Address 20H - Addressable as byte, word, longword */ - case 0x20: - ret = dev->si_cr & 0xffff; - break; - case 0x22: - ret = (dev->si_cr >> 16) | 0xff80; - break; + /* Serial Interface Control Register, Address 20H + Addressable as byte, word, longword */ + case 0x20: + ret = dev->si_cr & 0xffff; + break; + case 0x22: + ret = (dev->si_cr >> 16) | 0xff80; + break; - /* DAC1 Channel Sample Count Register, Address 24H - Addressable as word, longword */ - case 0x24: - ret = dev->dac[0].samp_ct; - break; - case 0x26: - ret = dev->dac[0].curr_samp_ct; - break; + /* DAC1 Channel Sample Count Register, Address 24H + Addressable as word, longword */ + case 0x24: + ret = dev->dac[0].samp_ct; + break; + case 0x26: + ret = dev->dac[0].curr_samp_ct; + break; - /* DAC2 Channel Sample Count Register, Address 28H - Addressable as word, longword */ - case 0x28: - ret = dev->dac[1].samp_ct; - break; - case 0x2a: - ret = dev->dac[1].curr_samp_ct; - break; + /* DAC2 Channel Sample Count Register, Address 28H + Addressable as word, longword */ + case 0x28: + ret = dev->dac[1].samp_ct; + break; + case 0x2a: + ret = dev->dac[1].curr_samp_ct; + break; - /* ADC Channel Sample Count Register, Address 2CH - Addressable as word, longword */ - case 0x2c: - ret = dev->adc.samp_ct; - break; - case 0x2e: - ret = dev->adc.curr_samp_ct; - break; + /* ADC Channel Sample Count Register, Address 2CH + Addressable as word, longword */ + case 0x2c: + ret = dev->adc.samp_ct; + break; + case 0x2e: + ret = dev->adc.curr_samp_ct; + break; - case 0x30: case 0x34: case 0x38: case 0x3c: - ret = es1371_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; - break; + case 0x30: + case 0x34: + case 0x38: + case 0x3c: + ret = es1371_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; + break; } - audiopci_log("es1371_inw: port=%04x ret=%04x\n", port, ret); + audiopci_log("es1371_inw: port=%04x ret=%04x\n", port, ret); return ret; } - static uint32_t es1371_inl(uint16_t port, void *p) { es1371_t *dev = (es1371_t *) p; - uint32_t ret = 0xffffffff; + uint32_t ret = 0xffffffff; switch (port & 0x3c) { - /* Interrupt/Chip Select Control Register, Address 00H - Addressable as byte, word, longword */ - case 0x00: - ret = (dev->int_ctrl & 0x030fffff) | 0xfc000000; - break; + /* Interrupt/Chip Select Control Register, Address 00H + Addressable as byte, word, longword */ + case 0x00: + ret = (dev->int_ctrl & 0x030fffff) | 0xfc000000; + break; - /* Interrupt/Chip Select Status Register, Address 04H - Addressable as longword only */ - case 0x04: - ret = dev->int_status; - audiopci_log("[R] STATUS = %08X\n", ret); - break; + /* Interrupt/Chip Select Status Register, Address 04H + Addressable as longword only */ + case 0x04: + ret = dev->int_status; + audiopci_log("[R] STATUS = %08X\n", ret); + break; - /* Memory Page Register, Address 0CH - Addressable as byte, word, longword */ - case 0x0c: - ret = dev->mem_page; - break; + /* Memory Page Register, Address 0CH + Addressable as byte, word, longword */ + case 0x0c: + ret = dev->mem_page; + break; - /* Sample Rate Converter Interface Register, Address 10H - Addressable as longword only */ - case 0x10: - ret = dev->sr_cir & ~0xffff; - ret |= dev->sr_ram[dev->sr_cir >> 25]; - break; + /* Sample Rate Converter Interface Register, Address 10H + Addressable as longword only */ + case 0x10: + ret = dev->sr_cir & ~0xffff; + ret |= dev->sr_ram[dev->sr_cir >> 25]; + break; - /* CODEC Read Register, Address 14H - Addressable as longword only */ - case 0x14: - ret = dev->codec_ctrl | CODEC_READY; - break; + /* CODEC Read Register, Address 14H + Addressable as longword only */ + case 0x14: + ret = dev->codec_ctrl | CODEC_READY; + break; - /* Legacy Control/Status Register, Address 18H - Addressable as byte, word, longword */ - case 0x18: - ret = (dev->legacy_ctrl & 0xffff07fd) | 0x0000f800; - break; + /* Legacy Control/Status Register, Address 18H + Addressable as byte, word, longword */ + case 0x18: + ret = (dev->legacy_ctrl & 0xffff07fd) | 0x0000f800; + break; - /* Serial Interface Control Register, Address 20H - Addressable as byte, word, longword */ - case 0x20: - ret = dev->si_cr | 0xff800000; - break; + /* Serial Interface Control Register, Address 20H + Addressable as byte, word, longword */ + case 0x20: + ret = dev->si_cr | 0xff800000; + break; - /* DAC1 Channel Sample Count Register, Address 24H - Addressable as word, longword */ - case 0x24: - ret = dev->dac[0].samp_ct | (((uint32_t) dev->dac[0].curr_samp_ct) << 16); - break; + /* DAC1 Channel Sample Count Register, Address 24H + Addressable as word, longword */ + case 0x24: + ret = dev->dac[0].samp_ct | (((uint32_t) dev->dac[0].curr_samp_ct) << 16); + break; - /* DAC2 Channel Sample Count Register, Address 28H - Addressable as word, longword */ - case 0x28: - ret = dev->dac[1].samp_ct | (((uint32_t) dev->dac[1].curr_samp_ct) << 16); - break; + /* DAC2 Channel Sample Count Register, Address 28H + Addressable as word, longword */ + case 0x28: + ret = dev->dac[1].samp_ct | (((uint32_t) dev->dac[1].curr_samp_ct) << 16); + break; - /* ADC Channel Sample Count Register, Address 2CH - Addressable as word, longword */ - case 0x2c: - ret = dev->adc.samp_ct | (((uint32_t) dev->adc.curr_samp_ct) << 16); - break; + /* ADC Channel Sample Count Register, Address 2CH + Addressable as word, longword */ + case 0x2c: + ret = dev->adc.samp_ct | (((uint32_t) dev->adc.curr_samp_ct) << 16); + break; - case 0x30: case 0x34: case 0x38: case 0x3c: - ret = es1371_read_frame_reg(dev, port & 0x3c, dev->mem_page); - break; + case 0x30: + case 0x34: + case 0x38: + case 0x3c: + ret = es1371_read_frame_reg(dev, port & 0x3c, dev->mem_page); + break; } audiopci_log("es1371_inl: port=%04x ret=%08x\n", port, ret); return ret; } - static void es1371_outb(uint16_t port, uint8_t val, void *p) { - es1371_t *dev = (es1371_t *)p; - uint32_t old_legacy_ctrl; + es1371_t *dev = (es1371_t *) p; + uint32_t old_legacy_ctrl; audiopci_log("es1371_outb: port=%04x val=%02x\n", port, val); switch (port & 0x3f) { - /* Interrupt/Chip Select Control Register, Address 00H - Addressable as byte, word, longword */ - case 0x00: - 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); - } - 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->int_ctrl = (dev->int_ctrl & 0xffffff00) | val; - break; - case 0x01: - dev->int_ctrl = (dev->int_ctrl & 0xffff00ff) | (val << 8); - break; - case 0x02: - dev->int_ctrl = (dev->int_ctrl & 0xff00ffff) | (val << 16); - break; - case 0x03: - dev->int_ctrl = (dev->int_ctrl & 0x00ffffff) | (val << 24); - gameport_remap(dev->gameport, 0x200 | ((val & 0x03) << 3)); - break; + /* Interrupt/Chip Select Control Register, Address 00H + Addressable as byte, word, longword */ + case 0x00: + 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); + } + 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->int_ctrl = (dev->int_ctrl & 0xffffff00) | val; + break; + case 0x01: + dev->int_ctrl = (dev->int_ctrl & 0xffff00ff) | (val << 8); + break; + case 0x02: + dev->int_ctrl = (dev->int_ctrl & 0xff00ffff) | (val << 16); + break; + case 0x03: + dev->int_ctrl = (dev->int_ctrl & 0x00ffffff) | (val << 24); + gameport_remap(dev->gameport, 0x200 | ((val & 0x03) << 3)); + break; - /* UART Data Register, Address 08H - Addressable as byte only */ - case 0x08: - audiopci_log("MIDI data = %02x\n", val); - /* TX does not use FIFO. */ - midi_raw_out_byte(val); - es1371_set_tx_irq(dev, 1); - break; + /* UART Data Register, Address 08H + Addressable as byte only */ + case 0x08: + audiopci_log("MIDI data = %02x\n", val); + /* TX does not use FIFO. */ + midi_raw_out_byte(val); + es1371_set_tx_irq(dev, 1); + break; - /* UART Control Register, Address 09H - Addressable as byte only */ - case 0x09: - audiopci_log("[W] UART CTRL = %02X\n", val); - dev->uart_ctrl = val & 0xe3; + /* UART Control Register, Address 09H + Addressable as byte only */ + case 0x09: + audiopci_log("[W] UART CTRL = %02X\n", val); + dev->uart_ctrl = val & 0xe3; - if ((val & 0x03) == 0x03) { - /* Reset TX */ - es1371_set_tx_irq(dev, 1); + if ((val & 0x03) == 0x03) { + /* Reset TX */ + es1371_set_tx_irq(dev, 1); - /* Software reset */ - es1371_reset_fifo(dev); - } else { - es1371_set_tx_irq(dev, 1); + /* Software reset */ + es1371_reset_fifo(dev); + } else { + es1371_set_tx_irq(dev, 1); - es1371_update_tx_irq(dev); - es1371_update_rx_irq(dev); - } - break; + es1371_update_tx_irq(dev); + es1371_update_rx_irq(dev); + } + break; - /* UART Reserved Register, Address 0AH - Addressable as byte only */ - case 0x0a: - audiopci_log("[W] UART RES = %02X\n", val); - dev->uart_res = val & 0x01; - break; + /* UART Reserved Register, Address 0AH + Addressable as byte only */ + case 0x0a: + audiopci_log("[W] UART RES = %02X\n", val); + dev->uart_res = val & 0x01; + break; - /* Memory Page Register, Address 0CH - Addressable as byte, word, longword */ - case 0x0c: - dev->mem_page = val & 0xf; - break; - case 0x0d ... 0x0f: - break; + /* Memory Page Register, Address 0CH + Addressable as byte, word, longword */ + case 0x0c: + dev->mem_page = val & 0xf; + break; + case 0x0d ... 0x0f: + break; - /* Legacy Control/Status Register, Address 18H - Addressable as byte, word, longword */ - case 0x18: - dev->legacy_ctrl |= LEGACY_INT; - break; - case 0x1a: - old_legacy_ctrl = dev->legacy_ctrl; - dev->legacy_ctrl = (dev->legacy_ctrl & 0xff00ffff) | (val << 16); - update_legacy(dev, old_legacy_ctrl); - break; - case 0x1b: - old_legacy_ctrl = dev->legacy_ctrl; - dev->legacy_ctrl = (dev->legacy_ctrl & 0x00ffffff) | (val << 24); - es1371_update_irqs(dev); - update_legacy(dev, old_legacy_ctrl); - break; + /* Legacy Control/Status Register, Address 18H + Addressable as byte, word, longword */ + case 0x18: + dev->legacy_ctrl |= LEGACY_INT; + break; + case 0x1a: + old_legacy_ctrl = dev->legacy_ctrl; + dev->legacy_ctrl = (dev->legacy_ctrl & 0xff00ffff) | (val << 16); + update_legacy(dev, old_legacy_ctrl); + break; + case 0x1b: + old_legacy_ctrl = dev->legacy_ctrl; + dev->legacy_ctrl = (dev->legacy_ctrl & 0x00ffffff) | (val << 24); + es1371_update_irqs(dev); + update_legacy(dev, old_legacy_ctrl); + break; - /* Serial Interface Control Register, Address 20H - Addressable as byte, word, longword */ - case 0x20: - dev->si_cr = (dev->si_cr & 0xffffff00) | val; - break; - case 0x21: - dev->si_cr = (dev->si_cr & 0xffff00ff) | (val << 8); - if (!(dev->si_cr & SI_P1_INTR_EN)) - dev->int_status &= ~INT_STATUS_DAC1; - if (!(dev->si_cr & SI_P2_INTR_EN)) - dev->int_status &= ~INT_STATUS_DAC2; - es1371_update_irqs(dev); - break; - case 0x22: - dev->si_cr = (dev->si_cr & 0xff80ffff) | ((val & 0x7f) << 16); - break; + /* Serial Interface Control Register, Address 20H + Addressable as byte, word, longword */ + case 0x20: + dev->si_cr = (dev->si_cr & 0xffffff00) | val; + break; + case 0x21: + dev->si_cr = (dev->si_cr & 0xffff00ff) | (val << 8); + if (!(dev->si_cr & SI_P1_INTR_EN)) + dev->int_status &= ~INT_STATUS_DAC1; + if (!(dev->si_cr & SI_P2_INTR_EN)) + dev->int_status &= ~INT_STATUS_DAC2; + es1371_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); + default: + audiopci_log("Bad es1371_outb: port=%04x val=%02x\n", port, val); } } - static void es1371_outw(uint16_t port, uint16_t val, void *p) { - es1371_t *dev = (es1371_t *)p; - uint32_t old_legacy_ctrl; + es1371_t *dev = (es1371_t *) p; + uint32_t old_legacy_ctrl; switch (port & 0x3f) { - /* Interrupt/Chip Select Control Register, Address 00H - Addressable as byte, word, longword */ - case 0x00: - 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); - } - 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->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)); - break; + /* Interrupt/Chip Select Control Register, Address 00H + Addressable as byte, word, longword */ + case 0x00: + 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); + } + 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->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)); + break; - /* Memory Page Register, Address 0CH - Addressable as byte, word, longword */ - case 0x0c: - dev->mem_page = val & 0xf; - break; - case 0x0e: - break; + /* Memory Page Register, Address 0CH + Addressable as byte, word, longword */ + case 0x0c: + dev->mem_page = val & 0xf; + break; + case 0x0e: + break; - /* Legacy Control/Status Register, Address 18H - Addressable as byte, word, longword */ - case 0x18: - dev->legacy_ctrl |= LEGACY_INT; - break; - case 0x1a: - old_legacy_ctrl = dev->legacy_ctrl; - dev->legacy_ctrl = (dev->legacy_ctrl & 0x0000ffff) | (val << 16); - es1371_update_irqs(dev); - update_legacy(dev, old_legacy_ctrl); - break; + /* Legacy Control/Status Register, Address 18H + Addressable as byte, word, longword */ + case 0x18: + dev->legacy_ctrl |= LEGACY_INT; + break; + case 0x1a: + old_legacy_ctrl = dev->legacy_ctrl; + dev->legacy_ctrl = (dev->legacy_ctrl & 0x0000ffff) | (val << 16); + es1371_update_irqs(dev); + update_legacy(dev, old_legacy_ctrl); + break; - /* Serial Interface Control Register, Address 20H - Addressable as byte, word, longword */ - case 0x20: - dev->si_cr = (dev->si_cr & 0xffff0000) | val; - if (!(dev->si_cr & SI_P1_INTR_EN)) - dev->int_status &= ~INT_STATUS_DAC1; - if (!(dev->si_cr & SI_P2_INTR_EN)) - dev->int_status &= ~INT_STATUS_DAC2; - es1371_update_irqs(dev); - break; - case 0x22: - dev->si_cr = (dev->si_cr & 0xff80ffff) | ((val & 0x007f) << 16); - break; + /* Serial Interface Control Register, Address 20H + Addressable as byte, word, longword */ + case 0x20: + dev->si_cr = (dev->si_cr & 0xffff0000) | val; + if (!(dev->si_cr & SI_P1_INTR_EN)) + dev->int_status &= ~INT_STATUS_DAC1; + if (!(dev->si_cr & SI_P2_INTR_EN)) + dev->int_status &= ~INT_STATUS_DAC2; + es1371_update_irqs(dev); + break; + case 0x22: + dev->si_cr = (dev->si_cr & 0xff80ffff) | ((val & 0x007f) << 16); + break; - /* DAC1 Channel Sample Count Register, Address 24H - Addressable as word, longword */ - case 0x24: - dev->dac[0].samp_ct = val; - break; + /* DAC1 Channel Sample Count Register, Address 24H + Addressable as word, longword */ + case 0x24: + dev->dac[0].samp_ct = val; + break; - /* DAC2 Channel Sample Count Register, Address 28H - Addressable as word, longword */ - case 0x28: - dev->dac[1].samp_ct = val; - break; + /* DAC2 Channel Sample Count Register, Address 28H + Addressable as word, longword */ + case 0x28: + dev->dac[1].samp_ct = val; + break; - /* ADC Channel Sample Count Register, Address 2CH - Addressable as word, longword */ - case 0x2c: - dev->adc.samp_ct = val; - break; + /* ADC Channel Sample Count Register, Address 2CH + Addressable as word, longword */ + case 0x2c: + dev->adc.samp_ct = val; + break; } } - static void es1371_outl(uint16_t port, uint32_t val, void *p) { - es1371_t *dev = (es1371_t *)p; - uint32_t old_legacy_ctrl; + es1371_t *dev = (es1371_t *) p; + uint32_t old_legacy_ctrl; audiopci_log("es1371_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: - 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); - } - 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->int_ctrl = val; - gameport_remap(dev->gameport, 0x200 | ((val & 0x03000000) >> 21)); - break; + /* Interrupt/Chip Select Control Register, Address 00H + Addressable as byte, word, longword */ + case 0x00: + 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); + } + 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->int_ctrl = val; + gameport_remap(dev->gameport, 0x200 | ((val & 0x03000000) >> 21)); + break; - /* Interrupt/Chip Select Status Register, Address 04H - Addressable as longword only */ - case 0x04: - audiopci_log("[W] STATUS = %08X\n", val); - break; + /* Interrupt/Chip Select Status Register, Address 04H + Addressable as longword only */ + case 0x04: + audiopci_log("[W] STATUS = %08X\n", val); + break; - /* Memory Page Register, Address 0CH - Addressable as byte, word, longword */ - case 0x0c: - dev->mem_page = val & 0xf; - break; + /* Memory Page Register, Address 0CH + Addressable as byte, word, longword */ + case 0x0c: + dev->mem_page = val & 0xf; + break; - /* Sample Rate Converter Interface Register, Address 10H - Addressable as longword only */ - case 0x10: - 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; - switch (dev->sr_cir >> 25) { - case 0x71: - dev->dac[0].vf = (dev->dac[0].vf & ~0x1f8000) | ((val & 0xfc00) << 5); - dev->dac[0].ac = (dev->dac[0].ac & ~0x7f8000) | ((val & 0x00ff) << 15); - dev->dac[0].f_pos = 0; - break; - case 0x72: - dev->dac[0].ac = (dev->dac[0].ac & ~0x7fff) | (val & 0x7fff); - break; - case 0x73: - dev->dac[0].vf = (dev->dac[0].vf & ~0x7fff) | (val & 0x7fff); - break; + /* Sample Rate Converter Interface Register, Address 10H + Addressable as longword only */ + case 0x10: + 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; + switch (dev->sr_cir >> 25) { + case 0x71: + dev->dac[0].vf = (dev->dac[0].vf & ~0x1f8000) | ((val & 0xfc00) << 5); + dev->dac[0].ac = (dev->dac[0].ac & ~0x7f8000) | ((val & 0x00ff) << 15); + dev->dac[0].f_pos = 0; + break; + case 0x72: + dev->dac[0].ac = (dev->dac[0].ac & ~0x7fff) | (val & 0x7fff); + break; + case 0x73: + dev->dac[0].vf = (dev->dac[0].vf & ~0x7fff) | (val & 0x7fff); + break; - case 0x75: - dev->dac[1].vf = (dev->dac[1].vf & ~0x1f8000) | ((val & 0xfc00) << 5); - dev->dac[1].ac = (dev->dac[1].ac & ~0x7f8000) | ((val & 0x00ff) << 15); - dev->dac[1].f_pos = 0; - break; - case 0x76: - dev->dac[1].ac = (dev->dac[1].ac & ~0x7fff) | (val & 0x7fff); - break; - case 0x77: - dev->dac[1].vf = (dev->dac[1].vf & ~0x7fff) | (val & 0x7fff); - break; + case 0x75: + dev->dac[1].vf = (dev->dac[1].vf & ~0x1f8000) | ((val & 0xfc00) << 5); + dev->dac[1].ac = (dev->dac[1].ac & ~0x7f8000) | ((val & 0x00ff) << 15); + dev->dac[1].f_pos = 0; + break; + case 0x76: + dev->dac[1].ac = (dev->dac[1].ac & ~0x7fff) | (val & 0x7fff); + break; + case 0x77: + dev->dac[1].vf = (dev->dac[1].vf & ~0x7fff) | (val & 0x7fff); + break; - case 0x7c: - dev->dac[0].vol_l = (int32_t)(int16_t)(val & 0xffff); - break; - case 0x7d: - dev->dac[0].vol_r = (int32_t)(int16_t)(val & 0xffff); - break; - case 0x7e: - dev->dac[1].vol_l = (int32_t)(int16_t)(val & 0xffff); - break; - case 0x7f: - dev->dac[1].vol_r = (int32_t)(int16_t)(val & 0xffff); - break; - } - } - break; + case 0x7c: + dev->dac[0].vol_l = (int32_t) (int16_t) (val & 0xffff); + break; + case 0x7d: + dev->dac[0].vol_r = (int32_t) (int16_t) (val & 0xffff); + break; + case 0x7e: + dev->dac[1].vol_l = (int32_t) (int16_t) (val & 0xffff); + break; + case 0x7f: + dev->dac[1].vol_r = (int32_t) (int16_t) (val & 0xffff); + break; + } + } + break; - /* CODEC Write Register, Address 14H - Addressable as longword only */ - case 0x14: - if (val & CODEC_READ) { - dev->codec_ctrl &= 0x00ff0000; - dev->codec_ctrl |= ac97_codec_readw(dev->codec, val >> 16); - } else { - dev->codec_ctrl = val & 0x00ffffff; - ac97_codec_writew(dev->codec, val >> 16, val); + /* CODEC Write Register, Address 14H + Addressable as longword only */ + case 0x14: + if (val & CODEC_READ) { + dev->codec_ctrl &= 0x00ff0000; + dev->codec_ctrl |= ac97_codec_readw(dev->codec, val >> 16); + } else { + dev->codec_ctrl = val & 0x00ffffff; + ac97_codec_writew(dev->codec, val >> 16, val); - ac97_codec_getattn(dev->codec, 0x02, &dev->master_vol_l, &dev->master_vol_r); - ac97_codec_getattn(dev->codec, 0x18, &dev->pcm_vol_l, &dev->pcm_vol_r); - ac97_codec_getattn(dev->codec, 0x12, &dev->cd_vol_l, &dev->cd_vol_r); - } - break; + ac97_codec_getattn(dev->codec, 0x02, &dev->master_vol_l, &dev->master_vol_r); + ac97_codec_getattn(dev->codec, 0x18, &dev->pcm_vol_l, &dev->pcm_vol_r); + ac97_codec_getattn(dev->codec, 0x12, &dev->cd_vol_l, &dev->cd_vol_r); + } + break; - /* Legacy Control/Status Register, Address 18H - Addressable as byte, word, longword */ - case 0x18: - old_legacy_ctrl = dev->legacy_ctrl; - dev->legacy_ctrl = (dev->legacy_ctrl & 0x0000ffff) | (val & 0xffff0000); - dev->legacy_ctrl |= LEGACY_INT; - es1371_update_irqs(dev); - update_legacy(dev, old_legacy_ctrl); - break; + /* Legacy Control/Status Register, Address 18H + Addressable as byte, word, longword */ + case 0x18: + old_legacy_ctrl = dev->legacy_ctrl; + dev->legacy_ctrl = (dev->legacy_ctrl & 0x0000ffff) | (val & 0xffff0000); + dev->legacy_ctrl |= LEGACY_INT; + es1371_update_irqs(dev); + update_legacy(dev, old_legacy_ctrl); + break; - /* Serial Interface Control Register, Address 20H - Addressable as byte, word, longword */ - case 0x20: - dev->si_cr = (val & 0x007fffff) | 0xff800000; - if (!(dev->si_cr & SI_P1_INTR_EN)) - dev->int_status &= ~INT_STATUS_DAC1; - if (!(dev->si_cr & SI_P2_INTR_EN)) - dev->int_status &= ~INT_STATUS_DAC2; - es1371_update_irqs(dev); - break; + /* Serial Interface Control Register, Address 20H + Addressable as byte, word, longword */ + case 0x20: + dev->si_cr = (val & 0x007fffff) | 0xff800000; + if (!(dev->si_cr & SI_P1_INTR_EN)) + dev->int_status &= ~INT_STATUS_DAC1; + if (!(dev->si_cr & SI_P2_INTR_EN)) + dev->int_status &= ~INT_STATUS_DAC2; + es1371_update_irqs(dev); + break; - /* DAC1 Channel Sample Count Register, Address 24H - Addressable as word, longword */ - case 0x24: - dev->dac[0].samp_ct = val & 0xffff; - break; + /* DAC1 Channel Sample Count Register, Address 24H + Addressable as word, longword */ + case 0x24: + dev->dac[0].samp_ct = val & 0xffff; + break; - /* DAC2 Channel Sample Count Register, Address 28H - Addressable as word, longword */ - case 0x28: - dev->dac[1].samp_ct = val & 0xffff; - break; + /* DAC2 Channel Sample Count Register, Address 28H + Addressable as word, longword */ + case 0x28: + dev->dac[1].samp_ct = val & 0xffff; + break; - /* ADC Channel Sample Count Register, Address 2CH - Addressable as word, longword */ - case 0x2c: - dev->adc.samp_ct = val & 0xffff; - break; + /* ADC Channel Sample Count Register, Address 2CH + Addressable as word, longword */ + case 0x2c: + dev->adc.samp_ct = val & 0xffff; + break; - case 0x30: case 0x34: case 0x38: case 0x3c: - es1371_write_frame_reg(dev, port & 0x3c, dev->mem_page, val); - break; + case 0x30: + case 0x34: + case 0x38: + case 0x3c: + es1371_write_frame_reg(dev, port & 0x3c, dev->mem_page, val); + break; } } - static void capture_event(es1371_t *dev, int type, int rw, uint16_t port) { dev->legacy_ctrl &= ~(LEGACY_EVENT_MASK | LEGACY_EVENT_ADDR_MASK); dev->legacy_ctrl |= type; if (rw) - dev->legacy_ctrl |= LEGACY_EVENT_TYPE_RW; + dev->legacy_ctrl |= LEGACY_EVENT_TYPE_RW; else - dev->legacy_ctrl &= ~LEGACY_EVENT_TYPE_RW; + dev->legacy_ctrl &= ~LEGACY_EVENT_TYPE_RW; dev->legacy_ctrl |= ((port << LEGACY_EVENT_ADDR_SHIFT) & LEGACY_EVENT_ADDR_MASK); dev->legacy_ctrl &= ~LEGACY_INT; nmi = 1; } - static void capture_write_sscape(uint16_t port, uint8_t val, void *p) { capture_event(p, LEGACY_EVENT_SSCAPE, 1, port); } - static void capture_write_codec(uint16_t port, uint8_t val, void *p) { capture_event(p, LEGACY_EVENT_CODEC, 1, port); } - static void capture_write_sb(uint16_t port, uint8_t val, void *p) { capture_event(p, LEGACY_EVENT_SB, 1, port); } - static void capture_write_adlib(uint16_t port, uint8_t val, void *p) { capture_event(p, LEGACY_EVENT_ADLIB, 1, port); } - static void capture_write_master_pic(uint16_t port, uint8_t val, void *p) { capture_event(p, LEGACY_EVENT_MASTER_PIC, 1, port); } - static void capture_write_master_dma(uint16_t port, uint8_t val, void *p) { capture_event(p, LEGACY_EVENT_MASTER_DMA, 1, port); } - static void capture_write_slave_pic(uint16_t port, uint8_t val, void *p) { capture_event(p, LEGACY_EVENT_SLAVE_PIC, 1, port); } - static void capture_write_slave_dma(uint16_t port, uint8_t val, void *p) { capture_event(p, LEGACY_EVENT_SLAVE_DMA, 1, port); } - static uint8_t capture_read_sscape(uint16_t port, void *p) { @@ -1310,7 +1298,6 @@ capture_read_sscape(uint16_t port, void *p) return 0xff; } - static uint8_t capture_read_codec(uint16_t port, void *p) { @@ -1318,7 +1305,6 @@ capture_read_codec(uint16_t port, void *p) return 0xff; } - static uint8_t capture_read_sb(uint16_t port, void *p) { @@ -1326,7 +1312,6 @@ capture_read_sb(uint16_t port, void *p) return 0xff; } - static uint8_t capture_read_adlib(uint16_t port, void *p) { @@ -1334,7 +1319,6 @@ capture_read_adlib(uint16_t port, void *p) return 0xff; } - static uint8_t capture_read_master_pic(uint16_t port, void *p) { @@ -1342,7 +1326,6 @@ capture_read_master_pic(uint16_t port, void *p) return 0xff; } - static uint8_t capture_read_master_dma(uint16_t port, void *p) { @@ -1350,7 +1333,6 @@ capture_read_master_dma(uint16_t port, void *p) return 0xff; } - static uint8_t capture_read_slave_pic(uint16_t port, void *p) { @@ -1358,7 +1340,6 @@ capture_read_slave_pic(uint16_t port, void *p) return 0xff; } - static uint8_t capture_read_slave_dma(uint16_t port, void *p) { @@ -1366,430 +1347,448 @@ capture_read_slave_dma(uint16_t port, void *p) return 0xff; } - static void update_legacy(es1371_t *dev, uint32_t old_legacy_ctrl) { if (old_legacy_ctrl & LEGACY_CAPTURE_SSCAPE) { - switch ((old_legacy_ctrl >> LEGACY_SSCAPE_ADDR_SHIFT) & 3) { - case 0: - io_removehandler(0x0320, 0x0008, - capture_read_sscape, NULL, NULL, - capture_write_sscape, NULL, NULL, dev); - break; - case 1: - io_removehandler(0x0330, 0x0008, - capture_read_sscape, NULL, NULL, - capture_write_sscape, NULL, NULL, dev); - break; - case 2: - io_removehandler(0x0340, 0x0008, - capture_read_sscape, NULL ,NULL, - capture_write_sscape, NULL, NULL, dev); - break; - case 3: - io_removehandler(0x0350, 0x0008, - capture_read_sscape, NULL, NULL, - capture_write_sscape, NULL, NULL, dev); - break; - } + switch ((old_legacy_ctrl >> LEGACY_SSCAPE_ADDR_SHIFT) & 3) { + case 0: + io_removehandler(0x0320, 0x0008, + capture_read_sscape, NULL, NULL, + capture_write_sscape, NULL, NULL, dev); + break; + case 1: + io_removehandler(0x0330, 0x0008, + capture_read_sscape, NULL, NULL, + capture_write_sscape, NULL, NULL, dev); + break; + case 2: + io_removehandler(0x0340, 0x0008, + capture_read_sscape, NULL, NULL, + capture_write_sscape, NULL, NULL, dev); + break; + case 3: + io_removehandler(0x0350, 0x0008, + capture_read_sscape, NULL, NULL, + capture_write_sscape, NULL, NULL, dev); + break; + } } if (old_legacy_ctrl & LEGACY_CAPTURE_CODEC) { - switch ((old_legacy_ctrl >> LEGACY_CODEC_ADDR_SHIFT) & 3) { - case 0: - io_removehandler(0x0530, 0x0008, - capture_read_codec, NULL, NULL, - capture_write_codec, NULL, NULL, dev); - break; - case 2: - io_removehandler(0x0e80, 0x0008, - capture_read_codec, NULL, NULL, - capture_write_codec,NULL,NULL, dev); - break; - case 3: - io_removehandler(0x0f40, 0x0008, - capture_read_codec, NULL, NULL, - capture_write_codec, NULL, NULL, dev); - break; - } + switch ((old_legacy_ctrl >> LEGACY_CODEC_ADDR_SHIFT) & 3) { + case 0: + io_removehandler(0x0530, 0x0008, + capture_read_codec, NULL, NULL, + capture_write_codec, NULL, NULL, dev); + break; + case 2: + io_removehandler(0x0e80, 0x0008, + capture_read_codec, NULL, NULL, + capture_write_codec, NULL, NULL, dev); + break; + case 3: + io_removehandler(0x0f40, 0x0008, + capture_read_codec, NULL, NULL, + capture_write_codec, NULL, NULL, dev); + break; + } } if (old_legacy_ctrl & LEGACY_CAPTURE_SB) { - if (!(old_legacy_ctrl & LEGACY_SB_ADDR)) { - io_removehandler(0x0220, 0x0010, - capture_read_sb, NULL, NULL, - capture_write_sb, NULL, NULL, dev); - } else { - io_removehandler(0x0240, 0x0010, - capture_read_sb, NULL, NULL, - capture_write_sb, NULL, NULL, dev); - } + if (!(old_legacy_ctrl & LEGACY_SB_ADDR)) { + io_removehandler(0x0220, 0x0010, + capture_read_sb, NULL, NULL, + capture_write_sb, NULL, NULL, dev); + } else { + io_removehandler(0x0240, 0x0010, + capture_read_sb, NULL, NULL, + capture_write_sb, NULL, NULL, dev); + } } if (old_legacy_ctrl & LEGACY_CAPTURE_ADLIB) { - io_removehandler(0x0388, 0x0004, - capture_read_adlib, NULL, NULL, - capture_write_adlib, NULL, NULL, dev); + io_removehandler(0x0388, 0x0004, + capture_read_adlib, NULL, NULL, + capture_write_adlib, NULL, NULL, dev); } if (old_legacy_ctrl & LEGACY_CAPTURE_MASTER_PIC) { - io_removehandler(0x0020, 0x0002, - capture_read_master_pic, NULL, NULL, - capture_write_master_pic,NULL,NULL, dev); + io_removehandler(0x0020, 0x0002, + capture_read_master_pic, NULL, NULL, + capture_write_master_pic, NULL, NULL, dev); } if (old_legacy_ctrl & LEGACY_CAPTURE_MASTER_DMA) { - io_removehandler(0x0000, 0x0010, - capture_read_master_dma, NULL, NULL, - capture_write_master_dma, NULL, NULL, dev); + io_removehandler(0x0000, 0x0010, + capture_read_master_dma, NULL, NULL, + capture_write_master_dma, NULL, NULL, dev); } if (old_legacy_ctrl & LEGACY_CAPTURE_SLAVE_PIC) { - io_removehandler(0x00a0, 0x0002, - capture_read_slave_pic, NULL, NULL, - capture_write_slave_pic, NULL, NULL, dev); + io_removehandler(0x00a0, 0x0002, + capture_read_slave_pic, NULL, NULL, + capture_write_slave_pic, NULL, NULL, dev); } if (old_legacy_ctrl & LEGACY_CAPTURE_SLAVE_DMA) { - io_removehandler(0x00c0, 0x0020, - capture_read_slave_dma, NULL, NULL, - capture_write_slave_dma, NULL, NULL, dev); + io_removehandler(0x00c0, 0x0020, + capture_read_slave_dma, NULL, NULL, + capture_write_slave_dma, NULL, NULL, dev); } if (dev->legacy_ctrl & LEGACY_CAPTURE_SSCAPE) { - switch ((dev->legacy_ctrl >> LEGACY_SSCAPE_ADDR_SHIFT) & 3) { - case 0: - io_sethandler(0x0320, 0x0008, - capture_read_sscape, NULL, NULL, - capture_write_sscape, NULL, NULL, dev); - break; - case 1: - io_sethandler(0x0330, 0x0008, - capture_read_sscape, NULL, NULL, - capture_write_sscape, NULL, NULL, dev); - break; - case 2: - io_sethandler(0x0340, 0x0008, - capture_read_sscape, NULL, NULL, - capture_write_sscape, NULL, NULL, dev); - break; - case 3: - io_sethandler(0x0350, 0x0008, - capture_read_sscape, NULL, NULL, - capture_write_sscape, NULL, NULL, dev); - break; - } + switch ((dev->legacy_ctrl >> LEGACY_SSCAPE_ADDR_SHIFT) & 3) { + case 0: + io_sethandler(0x0320, 0x0008, + capture_read_sscape, NULL, NULL, + capture_write_sscape, NULL, NULL, dev); + break; + case 1: + io_sethandler(0x0330, 0x0008, + capture_read_sscape, NULL, NULL, + capture_write_sscape, NULL, NULL, dev); + break; + case 2: + io_sethandler(0x0340, 0x0008, + capture_read_sscape, NULL, NULL, + capture_write_sscape, NULL, NULL, dev); + break; + case 3: + io_sethandler(0x0350, 0x0008, + capture_read_sscape, NULL, NULL, + capture_write_sscape, NULL, NULL, dev); + break; + } } if (dev->legacy_ctrl & LEGACY_CAPTURE_CODEC) { - switch ((dev->legacy_ctrl >> LEGACY_CODEC_ADDR_SHIFT) & 3) { - case 0: - io_sethandler(0x0530, 0x0008, - capture_read_codec, NULL, NULL, - capture_write_codec, NULL, NULL, dev); - break; - case 2: - io_sethandler(0x0e80, 0x0008, - capture_read_codec, NULL, NULL, - capture_write_codec, NULL, NULL, dev); - break; - case 3: - io_sethandler(0x0f40, 0x0008, - capture_read_codec, NULL, NULL, - capture_write_codec, NULL, NULL, dev); - break; - } + switch ((dev->legacy_ctrl >> LEGACY_CODEC_ADDR_SHIFT) & 3) { + case 0: + io_sethandler(0x0530, 0x0008, + capture_read_codec, NULL, NULL, + capture_write_codec, NULL, NULL, dev); + break; + case 2: + io_sethandler(0x0e80, 0x0008, + capture_read_codec, NULL, NULL, + capture_write_codec, NULL, NULL, dev); + break; + case 3: + io_sethandler(0x0f40, 0x0008, + capture_read_codec, NULL, NULL, + capture_write_codec, NULL, NULL, dev); + break; + } } if (dev->legacy_ctrl & LEGACY_CAPTURE_SB) { - if (!(dev->legacy_ctrl & LEGACY_SB_ADDR)) { - io_sethandler(0x0220, 0x0010, - capture_read_sb, NULL, NULL, - capture_write_sb, NULL, NULL, dev); - } else { - io_sethandler(0x0240, 0x0010, - capture_read_sb, NULL, NULL, - capture_write_sb, NULL, NULL, dev); - } + if (!(dev->legacy_ctrl & LEGACY_SB_ADDR)) { + io_sethandler(0x0220, 0x0010, + capture_read_sb, NULL, NULL, + capture_write_sb, NULL, NULL, dev); + } else { + io_sethandler(0x0240, 0x0010, + capture_read_sb, NULL, NULL, + capture_write_sb, NULL, NULL, dev); + } } if (dev->legacy_ctrl & LEGACY_CAPTURE_ADLIB) { - io_sethandler(0x0388, 0x0004, - capture_read_adlib, NULL, NULL, - capture_write_adlib, NULL, NULL, dev); + io_sethandler(0x0388, 0x0004, + capture_read_adlib, NULL, NULL, + capture_write_adlib, NULL, NULL, dev); } if (dev->legacy_ctrl & LEGACY_CAPTURE_MASTER_PIC) { - io_sethandler(0x0020, 0x0002, - capture_read_master_pic, NULL, NULL, - capture_write_master_pic, NULL, NULL, dev); + io_sethandler(0x0020, 0x0002, + capture_read_master_pic, NULL, NULL, + capture_write_master_pic, NULL, NULL, dev); } if (dev->legacy_ctrl & LEGACY_CAPTURE_MASTER_DMA) { - io_sethandler(0x0000, 0x0010, - capture_read_master_dma, NULL, NULL, - capture_write_master_dma, NULL, NULL, dev); + io_sethandler(0x0000, 0x0010, + capture_read_master_dma, NULL, NULL, + capture_write_master_dma, NULL, NULL, dev); } if (dev->legacy_ctrl & LEGACY_CAPTURE_SLAVE_PIC) { - io_sethandler(0x00a0, 0x0002, - capture_read_slave_pic, NULL, NULL, - capture_write_slave_pic, NULL, NULL, dev); + io_sethandler(0x00a0, 0x0002, + capture_read_slave_pic, NULL, NULL, + capture_write_slave_pic, NULL, NULL, dev); } if (dev->legacy_ctrl & LEGACY_CAPTURE_SLAVE_DMA) { - io_sethandler(0x00c0, 0x0020, - capture_read_slave_dma, NULL, NULL, - capture_write_slave_dma, NULL, NULL, dev); + io_sethandler(0x00c0, 0x0020, + capture_read_slave_dma, NULL, NULL, + capture_write_slave_dma, NULL, NULL, dev); } } - static uint8_t es1371_pci_read(int func, int addr, void *p) { - es1371_t *dev = (es1371_t *)p; + es1371_t *dev = (es1371_t *) p; if (func > 0) - return 0xff; + return 0xff; if ((addr > 0x3f) && ((addr < 0xdc) || (addr > 0xe1))) - return 0x00; + return 0x00; switch (addr) { - case 0x00: return 0x74; /* Ensoniq */ - case 0x01: return 0x12; + case 0x00: + return 0x74; /* Ensoniq */ + case 0x01: + return 0x12; - case 0x02: return 0x71; /* ES1371 */ - case 0x03: return 0x13; + case 0x02: + return 0x71; /* ES1371 */ + case 0x03: + return 0x13; - case 0x04: return dev->pci_command; - case 0x05: return dev->pci_serr; + case 0x04: + return dev->pci_command; + case 0x05: + return dev->pci_serr; - case 0x06: return 0x10; /* Supports ACPI */ - case 0x07: return 0x00; + case 0x06: + return 0x10; /* Supports ACPI */ + case 0x07: + return 0x00; - case 0x08: return 0x08; /* Revision ID - 0x02 (datasheet, VMware) has issues with the 2001 Creative WDM driver */ - case 0x09: return 0x00; /* Multimedia audio device */ - case 0x0a: return 0x01; - case 0x0b: return 0x04; + case 0x08: + return 0x08; /* Revision ID - 0x02 (datasheet, VMware) has issues with the 2001 Creative WDM driver */ + case 0x09: + return 0x00; /* Multimedia audio device */ + case 0x0a: + return 0x01; + case 0x0b: + return 0x04; - case 0x10: 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 0x10: + 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 0x74; /* Subsystem vendor ID */ - case 0x2d: return 0x12; - case 0x2e: return 0x71; - case 0x2f: return 0x13; + case 0x2c: + return 0x74; /* Subsystem vendor ID */ + case 0x2d: + return 0x12; + case 0x2e: + return 0x71; + case 0x2f: + return 0x13; - case 0x34: return 0xdc; /* Capabilites pointer */ + case 0x34: + return 0xdc; /* Capabilites pointer */ - case 0x3c: return dev->int_line; - case 0x3d: return 0x01; /* INTA */ + case 0x3c: + return dev->int_line; + case 0x3d: + return 0x01; /* INTA */ - case 0x3e: return 0xc; /* Minimum grant */ - case 0x3f: return 0x80; /* Maximum latency */ + case 0x3e: + return 0xc; /* Minimum grant */ + case 0x3f: + return 0x80; /* Maximum latency */ - 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 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; + case 0xe0: + return dev->pmcsr & 0xff; + case 0xe1: + return dev->pmcsr >> 8; } return 0x00; } - static void es1371_io_set(es1371_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); + io_handler(set, dev->base_addr, 0x0040, + es1371_inb, es1371_inw, es1371_inl, + es1371_outb, es1371_outw, es1371_outl, dev); } } - static void es1371_pci_write(int func, int addr, uint8_t val, void *p) { - es1371_t *dev = (es1371_t *)p; + es1371_t *dev = (es1371_t *) p; if (func) - return; + return; switch (addr) { - case 0x04: - es1371_io_set(dev, 0); - dev->pci_command = val & 0x05; - es1371_io_set(dev, 1); - break; - case 0x05: - dev->pci_serr = val & 1; - break; + case 0x04: + es1371_io_set(dev, 0); + dev->pci_command = val & 0x05; + es1371_io_set(dev, 1); + break; + case 0x05: + dev->pci_serr = val & 1; + break; - case 0x10: - es1371_io_set(dev, 0); - dev->base_addr = (dev->base_addr & 0xffffff00) | (val & 0xc0); - es1371_io_set(dev, 1); - break; - case 0x11: - es1371_io_set(dev, 0); - dev->base_addr = (dev->base_addr & 0xffff00c0) | (val << 8); - es1371_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 0x10: + es1371_io_set(dev, 0); + dev->base_addr = (dev->base_addr & 0xffffff00) | (val & 0xc0); + es1371_io_set(dev, 1); + break; + case 0x11: + es1371_io_set(dev, 0); + dev->base_addr = (dev->base_addr & 0xffff00c0) | (val << 8); + es1371_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 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; + case 0xe0: + dev->pmcsr = (dev->pmcsr & 0xff00) | (val & 0x03); + break; + case 0xe1: + dev->pmcsr = (dev->pmcsr & 0x00ff) | ((val & 0x01) << 8); + break; } } - static void es1371_fetch(es1371_t *dev, int dac_nr) { if (dev->si_cr & (dac_nr ? SI_P2_PAUSE : SI_P1_PAUSE)) - return; + return; int format = dac_nr ? ((dev->si_cr >> 2) & 3) : (dev->si_cr & 3); - int pos = dev->dac[dac_nr].buffer_pos & 63; + int pos = dev->dac[dac_nr].buffer_pos & 63; int c; switch (format) { - case FORMAT_MONO_8: - for (c = 0; c < 32; c += 4) { - dev->dac[dac_nr].buffer_l[(pos+c) & 63] = dev->dac[dac_nr].buffer_r[(pos+c) & 63] = - (mem_readb_phys(dev->dac[dac_nr].addr) ^ 0x80) << 8; - dev->dac[dac_nr].buffer_l[(pos+c+1) & 63] = dev->dac[dac_nr].buffer_r[(pos+c+1) & 63] = - (mem_readb_phys(dev->dac[dac_nr].addr+1) ^ 0x80) << 8; - dev->dac[dac_nr].buffer_l[(pos+c+2) & 63] = dev->dac[dac_nr].buffer_r[(pos+c+2) & 63] = - (mem_readb_phys(dev->dac[dac_nr].addr+2) ^ 0x80) << 8; - dev->dac[dac_nr].buffer_l[(pos+c+3) & 63] = dev->dac[dac_nr].buffer_r[(pos+c+3) & 63] = - (mem_readb_phys(dev->dac[dac_nr].addr+3) ^ 0x80) << 8; - dev->dac[dac_nr].addr += 4; + case FORMAT_MONO_8: + for (c = 0; c < 32; c += 4) { + dev->dac[dac_nr].buffer_l[(pos + c) & 63] = dev->dac[dac_nr].buffer_r[(pos + c) & 63] = (mem_readb_phys(dev->dac[dac_nr].addr) ^ 0x80) << 8; + dev->dac[dac_nr].buffer_l[(pos + c + 1) & 63] = dev->dac[dac_nr].buffer_r[(pos + c + 1) & 63] = (mem_readb_phys(dev->dac[dac_nr].addr + 1) ^ 0x80) << 8; + dev->dac[dac_nr].buffer_l[(pos + c + 2) & 63] = dev->dac[dac_nr].buffer_r[(pos + c + 2) & 63] = (mem_readb_phys(dev->dac[dac_nr].addr + 2) ^ 0x80) << 8; + dev->dac[dac_nr].buffer_l[(pos + c + 3) & 63] = dev->dac[dac_nr].buffer_r[(pos + c + 3) & 63] = (mem_readb_phys(dev->dac[dac_nr].addr + 3) ^ 0x80) << 8; + dev->dac[dac_nr].addr += 4; - dev->dac[dac_nr].buffer_pos_end += 4; - dev->dac[dac_nr].count++; + dev->dac[dac_nr].buffer_pos_end += 4; + dev->dac[dac_nr].count++; - if (dev->dac[dac_nr].count > dev->dac[dac_nr].size) { - dev->dac[dac_nr].count = 0; - dev->dac[dac_nr].addr = dev->dac[dac_nr].addr_latch; - break; - } - } - break; + if (dev->dac[dac_nr].count > dev->dac[dac_nr].size) { + dev->dac[dac_nr].count = 0; + dev->dac[dac_nr].addr = dev->dac[dac_nr].addr_latch; + break; + } + } + break; - case FORMAT_STEREO_8: - for (c = 0; c < 16; c += 2) { - dev->dac[dac_nr].buffer_l[(pos+c) & 63] = (mem_readb_phys(dev->dac[dac_nr].addr) ^ 0x80) << 8; - dev->dac[dac_nr].buffer_r[(pos+c) & 63] = (mem_readb_phys(dev->dac[dac_nr].addr + 1) ^ 0x80) << 8; - dev->dac[dac_nr].buffer_l[(pos+c+1) & 63] = (mem_readb_phys(dev->dac[dac_nr].addr + 2) ^ 0x80) << 8; - dev->dac[dac_nr].buffer_r[(pos+c+1) & 63] = (mem_readb_phys(dev->dac[dac_nr].addr + 3) ^ 0x80) << 8; - dev->dac[dac_nr].addr += 4; + case FORMAT_STEREO_8: + for (c = 0; c < 16; c += 2) { + dev->dac[dac_nr].buffer_l[(pos + c) & 63] = (mem_readb_phys(dev->dac[dac_nr].addr) ^ 0x80) << 8; + dev->dac[dac_nr].buffer_r[(pos + c) & 63] = (mem_readb_phys(dev->dac[dac_nr].addr + 1) ^ 0x80) << 8; + dev->dac[dac_nr].buffer_l[(pos + c + 1) & 63] = (mem_readb_phys(dev->dac[dac_nr].addr + 2) ^ 0x80) << 8; + dev->dac[dac_nr].buffer_r[(pos + c + 1) & 63] = (mem_readb_phys(dev->dac[dac_nr].addr + 3) ^ 0x80) << 8; + dev->dac[dac_nr].addr += 4; - dev->dac[dac_nr].buffer_pos_end += 2; - dev->dac[dac_nr].count++; + dev->dac[dac_nr].buffer_pos_end += 2; + dev->dac[dac_nr].count++; - if (dev->dac[dac_nr].count > dev->dac[dac_nr].size) { - dev->dac[dac_nr].count = 0; - dev->dac[dac_nr].addr = dev->dac[dac_nr].addr_latch; - break; - } - } - break; + if (dev->dac[dac_nr].count > dev->dac[dac_nr].size) { + dev->dac[dac_nr].count = 0; + dev->dac[dac_nr].addr = dev->dac[dac_nr].addr_latch; + break; + } + } + break; - case FORMAT_MONO_16: - for (c = 0; c < 16; c += 2) { - dev->dac[dac_nr].buffer_l[(pos+c) & 63] = dev->dac[dac_nr].buffer_r[(pos+c) & 63] = - mem_readw_phys(dev->dac[dac_nr].addr); - dev->dac[dac_nr].buffer_l[(pos+c+1) & 63] = dev->dac[dac_nr].buffer_r[(pos+c+1) & 63] = - mem_readw_phys(dev->dac[dac_nr].addr + 2); - dev->dac[dac_nr].addr += 4; + case FORMAT_MONO_16: + for (c = 0; c < 16; c += 2) { + dev->dac[dac_nr].buffer_l[(pos + c) & 63] = dev->dac[dac_nr].buffer_r[(pos + c) & 63] = mem_readw_phys(dev->dac[dac_nr].addr); + dev->dac[dac_nr].buffer_l[(pos + c + 1) & 63] = dev->dac[dac_nr].buffer_r[(pos + c + 1) & 63] = mem_readw_phys(dev->dac[dac_nr].addr + 2); + dev->dac[dac_nr].addr += 4; - dev->dac[dac_nr].buffer_pos_end += 2; - dev->dac[dac_nr].count++; + dev->dac[dac_nr].buffer_pos_end += 2; + dev->dac[dac_nr].count++; - if (dev->dac[dac_nr].count > dev->dac[dac_nr].size) { - dev->dac[dac_nr].count = 0; - dev->dac[dac_nr].addr = dev->dac[dac_nr].addr_latch; - break; - } - } - break; + if (dev->dac[dac_nr].count > dev->dac[dac_nr].size) { + dev->dac[dac_nr].count = 0; + dev->dac[dac_nr].addr = dev->dac[dac_nr].addr_latch; + break; + } + } + break; - case FORMAT_STEREO_16: - for (c = 0; c < 4; c++) { - dev->dac[dac_nr].buffer_l[(pos+c) & 63] = mem_readw_phys(dev->dac[dac_nr].addr); - dev->dac[dac_nr].buffer_r[(pos+c) & 63] = mem_readw_phys(dev->dac[dac_nr].addr + 2); - dev->dac[dac_nr].addr += 4; + case FORMAT_STEREO_16: + for (c = 0; c < 4; c++) { + dev->dac[dac_nr].buffer_l[(pos + c) & 63] = mem_readw_phys(dev->dac[dac_nr].addr); + dev->dac[dac_nr].buffer_r[(pos + c) & 63] = mem_readw_phys(dev->dac[dac_nr].addr + 2); + dev->dac[dac_nr].addr += 4; - dev->dac[dac_nr].buffer_pos_end++; - dev->dac[dac_nr].count++; + dev->dac[dac_nr].buffer_pos_end++; + dev->dac[dac_nr].count++; - if (dev->dac[dac_nr].count > dev->dac[dac_nr].size) { - dev->dac[dac_nr].count = 0; - dev->dac[dac_nr].addr = dev->dac[dac_nr].addr_latch; - break; - } - } - break; + if (dev->dac[dac_nr].count > dev->dac[dac_nr].size) { + dev->dac[dac_nr].count = 0; + dev->dac[dac_nr].addr = dev->dac[dac_nr].addr_latch; + break; + } + } + break; } } - static inline float low_fir_es1371(int dac_nr, int i, float NewSample) { - static float x[2][2][128]; //input samples - static int x_pos[2] = {0, 0}; - float out = 0.0; - int read_pos, n_coef; - int pos = x_pos[dac_nr]; + static float x[2][2][128]; // input samples + static int x_pos[2] = { 0, 0 }; + float out = 0.0; + int read_pos, n_coef; + int pos = x_pos[dac_nr]; x[dac_nr][i][pos] = NewSample; /* Since only 1/16th of input samples are non-zero, only filter those that are valid.*/ read_pos = (pos + 15) & (127 & ~15); - n_coef = (16 - pos) & 15; + n_coef = (16 - pos) & 15; while (n_coef < ES1371_NCoef) { - out += low_fir_es1371_coef[n_coef] * x[dac_nr][i][read_pos]; - read_pos = (read_pos + 16) & (127 & ~15); - n_coef += 16; + out += low_fir_es1371_coef[n_coef] * x[dac_nr][i][read_pos]; + read_pos = (read_pos + 16) & (127 & ~15); + n_coef += 16; } if (i == 1) { - x_pos[dac_nr] = (x_pos[dac_nr] + 1) & 127; - if (x_pos[dac_nr] > 127) - x_pos[dac_nr] = 0; + x_pos[dac_nr] = (x_pos[dac_nr] + 1) & 127; + if (x_pos[dac_nr] > 127) + x_pos[dac_nr] = 0; } return out; } - static void es1371_next_sample_filtered(es1371_t *dev, int dac_nr, int out_idx) { @@ -1797,23 +1796,22 @@ es1371_next_sample_filtered(es1371_t *dev, int dac_nr, int out_idx) int c; if ((dev->dac[dac_nr].buffer_pos - dev->dac[dac_nr].buffer_pos_end) >= 0) - es1371_fetch(dev, dac_nr); + es1371_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]; - dev->dac[dac_nr].filtered_l[out_idx] = (int)low_fir_es1371(dac_nr, 0, (float)out_l); - dev->dac[dac_nr].filtered_r[out_idx] = (int)low_fir_es1371(dac_nr, 1, (float)out_r); + dev->dac[dac_nr].filtered_l[out_idx] = (int) low_fir_es1371(dac_nr, 0, (float) out_l); + dev->dac[dac_nr].filtered_r[out_idx] = (int) low_fir_es1371(dac_nr, 1, (float) out_r); for (c = 1; c < 16; c++) { - dev->dac[dac_nr].filtered_l[out_idx+c] = (int)low_fir_es1371(dac_nr, 0, 0); - dev->dac[dac_nr].filtered_r[out_idx+c] = (int)low_fir_es1371(dac_nr, 1, 0); + dev->dac[dac_nr].filtered_l[out_idx + c] = (int) low_fir_es1371(dac_nr, 0, 0); + dev->dac[dac_nr].filtered_r[out_idx + c] = (int) low_fir_es1371(dac_nr, 1, 0); } dev->dac[dac_nr].buffer_pos++; } - static void es1371_update(es1371_t *dev) { @@ -1831,26 +1829,25 @@ es1371_update(es1371_t *dev) r = (((r * dev->pcm_vol_r) >> 15) * dev->master_vol_r) >> 15; if (l < -32768) - l = -32768; + l = -32768; else if (l > 32767) - l = 32767; + l = 32767; if (r < -32768) - r = -32768; + r = -32768; else if (r > 32767) - r = 32767; + r = 32767; - for (; dev->pos < sound_pos_global; dev->pos++) { - dev->buffer[dev->pos*2] = l; - dev->buffer[dev->pos*2 + 1] = r; + for (; dev->pos < sound_pos_global; dev->pos++) { + dev->buffer[dev->pos * 2] = l; + dev->buffer[dev->pos * 2 + 1] = r; } } - static void es1371_poll(void *p) { - es1371_t *dev = (es1371_t *)p; - int frac, idx, samp1_l, samp1_r, samp2_l, samp2_r; + es1371_t *dev = (es1371_t *) p; + int frac, idx, samp1_l, samp1_r, samp2_l, samp2_r; timer_advance_u64(&dev->dac[1].timer, dev->dac[1].latch); @@ -1859,152 +1856,146 @@ es1371_poll(void *p) es1371_update(dev); if (dev->int_ctrl & INT_DAC1_EN) { - frac = dev->dac[0].ac & 0x7fff; - idx = dev->dac[0].ac >> 15; - samp1_l = dev->dac[0].filtered_l[idx]; - samp1_r = dev->dac[0].filtered_r[idx]; - samp2_l = dev->dac[0].filtered_l[(idx + 1) & 31]; - samp2_r = dev->dac[0].filtered_r[(idx + 1) & 31]; + frac = dev->dac[0].ac & 0x7fff; + idx = dev->dac[0].ac >> 15; + samp1_l = dev->dac[0].filtered_l[idx]; + samp1_r = dev->dac[0].filtered_r[idx]; + samp2_l = dev->dac[0].filtered_l[(idx + 1) & 31]; + samp2_r = dev->dac[0].filtered_r[(idx + 1) & 31]; - dev->dac[0].out_l = ((samp1_l * (0x8000 - frac)) + (samp2_l * frac)) >> 15; - dev->dac[0].out_r = ((samp1_r * (0x8000 - frac)) + (samp2_r * frac)) >> 15; - 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); - dev->dac[0].f_pos = (dev->dac[0].f_pos + 1) & 1; + dev->dac[0].out_l = ((samp1_l * (0x8000 - frac)) + (samp2_l * frac)) >> 15; + dev->dac[0].out_r = ((samp1_r * (0x8000 - frac)) + (samp2_r * frac)) >> 15; + 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); + dev->dac[0].f_pos = (dev->dac[0].f_pos + 1) & 1; - dev->dac[0].curr_samp_ct--; - if (dev->dac[0].curr_samp_ct < 0) { - dev->int_status |= INT_STATUS_DAC1; - es1371_update_irqs(dev); - dev->dac[0].curr_samp_ct = dev->dac[0].samp_ct; - } - } + dev->dac[0].curr_samp_ct--; + if (dev->dac[0].curr_samp_ct < 0) { + dev->int_status |= INT_STATUS_DAC1; + es1371_update_irqs(dev); + dev->dac[0].curr_samp_ct = dev->dac[0].samp_ct; + } + } } if (dev->int_ctrl & INT_DAC2_EN) { - frac = dev->dac[1].ac & 0x7fff; - idx = dev->dac[1].ac >> 15; - samp1_l = dev->dac[1].filtered_l[idx]; - samp1_r = dev->dac[1].filtered_r[idx]; - samp2_l = dev->dac[1].filtered_l[(idx + 1) & 31]; - samp2_r = dev->dac[1].filtered_r[(idx + 1) & 31]; + frac = dev->dac[1].ac & 0x7fff; + idx = dev->dac[1].ac >> 15; + samp1_l = dev->dac[1].filtered_l[idx]; + samp1_r = dev->dac[1].filtered_r[idx]; + samp2_l = dev->dac[1].filtered_l[(idx + 1) & 31]; + samp2_r = dev->dac[1].filtered_r[(idx + 1) & 31]; - dev->dac[1].out_l = ((samp1_l * (0x8000 - frac)) + (samp2_l * frac)) >> 15; - dev->dac[1].out_r = ((samp1_r * (0x8000 - frac)) + (samp2_r * frac)) >> 15; - 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); - dev->dac[1].f_pos = (dev->dac[1].f_pos + 1) & 1; + dev->dac[1].out_l = ((samp1_l * (0x8000 - frac)) + (samp2_l * frac)) >> 15; + dev->dac[1].out_r = ((samp1_r * (0x8000 - frac)) + (samp2_r * frac)) >> 15; + 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); + dev->dac[1].f_pos = (dev->dac[1].f_pos + 1) & 1; - dev->dac[1].curr_samp_ct--; - if (dev->dac[1].curr_samp_ct < 0) { - dev->int_status |= INT_STATUS_DAC2; - es1371_update_irqs(dev); - dev->dac[1].curr_samp_ct = dev->dac[1].samp_ct; - } - } + dev->dac[1].curr_samp_ct--; + if (dev->dac[1].curr_samp_ct < 0) { + dev->int_status |= INT_STATUS_DAC2; + es1371_update_irqs(dev); + dev->dac[1].curr_samp_ct = dev->dac[1].samp_ct; + } + } } } - static void es1371_get_buffer(int32_t *buffer, int len, void *p) { - es1371_t *dev = (es1371_t *)p; - int c; + es1371_t *dev = (es1371_t *) p; + int c; es1371_update(dev); for (c = 0; c < len * 2; c++) - buffer[c] += (dev->buffer[c] / 2); + buffer[c] += (dev->buffer[c] / 2); dev->pos = 0; } - static void es1371_filter_cd_audio(int channel, double *buffer, void *p) { - es1371_t *dev = (es1371_t *)p; - double c; - int cd = channel ? dev->cd_vol_r : dev->cd_vol_l; - int master = channel ? dev->master_vol_r : dev->master_vol_l; + es1371_t *dev = (es1371_t *) p; + double c; + int cd = channel ? dev->cd_vol_r : dev->cd_vol_l; + int master = channel ? dev->master_vol_r : dev->master_vol_l; - c = ((((*buffer) * cd) / 65536.0) * master) / 65536.0; + c = ((((*buffer) * cd) / 65536.0) * master) / 65536.0; *buffer = c; } - -static inline -double sinc(double x) +static inline double +sinc(double x) { return sin(M_PI * x) / (M_PI * x); } - static void generate_es1371_filter(void) { /* Cutoff frequency = 1 / 32 */ float fC = 1.0 / 32.0; float gain; - int n; + int n; for (n = 0; n < ES1371_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))); - /* Sinc filter */ - double h = sinc(2.0 * fC * ((double)n - ((double)(ES1371_NCoef-1) / 2.0))); + /* 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))); + /* Sinc filter */ + double h = sinc(2.0 * fC * ((double) n - ((double) (ES1371_NCoef - 1) / 2.0))); - /* Create windowed-sinc filter */ - low_fir_es1371_coef[n] = w * h; + /* Create windowed-sinc filter */ + low_fir_es1371_coef[n] = w * h; } low_fir_es1371_coef[(ES1371_NCoef - 1) / 2] = 1.0; gain = 0.0; for (n = 0; n < ES1371_NCoef; n++) - gain += low_fir_es1371_coef[n] / (float)N; + gain += low_fir_es1371_coef[n] / (float) N; gain /= 0.95; /* Normalise filter, to produce unity gain */ for (n = 0; n < ES1371_NCoef; n++) - low_fir_es1371_coef[n] /= gain; + low_fir_es1371_coef[n] /= gain; } - static void es1371_input_msg(void *p, uint8_t *msg, uint32_t len) { - es1371_t *dev = (es1371_t *)p; - uint8_t i; + es1371_t *dev = (es1371_t *) p; + uint8_t i; for (i = 0; i < len; i++) - es1371_write_fifo(dev, msg[i]); + es1371_write_fifo(dev, msg[i]); } - static int es1371_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort) { - es1371_t *dev = (es1371_t *)p; - uint32_t i = -1; + es1371_t *dev = (es1371_t *) p; + uint32_t i = -1; audiopci_log("Abort = %i\n", abort); if (dev->uart_status & UART_STATUS_RXRDY) - abort = 1; + abort = 1; if (!abort) { - for (i = 0; i < len; i++) { - es1371_write_fifo(dev, buffer[i]); - if (dev->uart_status & UART_STATUS_RXRDY) - break; - } + for (i = 0; i < len; i++) { + es1371_write_fifo(dev, buffer[i]); + if (dev->uart_status & UART_STATUS_RXRDY) + break; + } } /* The last sent position is in i. Return 7 - i. */ @@ -2012,7 +2003,6 @@ es1371_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort) return 7 - i; } - static void * es1371_init(const device_t *info) { @@ -2020,7 +2010,7 @@ es1371_init(const device_t *info) memset(dev, 0x00, sizeof(es1371_t)); if (device_get_config_int("receive_input")) - midi_in_handler(1, es1371_input_msg, es1371_input_sysex, dev); + midi_in_handler(1, es1371_input_msg, es1371_input_sysex, dev); sound_add_handler(es1371_get_buffer, dev); sound_set_cd_audio_filter(es1371_filter_cd_audio, dev); @@ -2034,19 +2024,18 @@ es1371_init(const device_t *info) generate_es1371_filter(); - ac97_codec = &dev->codec; + ac97_codec = &dev->codec; ac97_codec_count = 1; - ac97_codec_id = 0; + ac97_codec_id = 0; /* Let the machine decide the codec on onboard implementations. */ if (!info->local) - device_add(ac97_codec_get(device_get_config_int("codec"))); + device_add(ac97_codec_get(device_get_config_int("codec"))); es1371_reset(dev); return dev; } - static void es1371_close(void *p) { @@ -2055,53 +2044,50 @@ es1371_close(void *p) free(dev); } - static void es1371_speed_changed(void *p) { - es1371_t *dev = (es1371_t *)p; + es1371_t *dev = (es1371_t *) p; - dev->dac[1].latch = (uint64_t)((double)TIMER_USEC * (1000000.0 / 48000.0)); + dev->dac[1].latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / 48000.0)); } - -static const device_config_t es1371_config[] = -{ +static const device_config_t es1371_config[] = { +// clang-format off { - .name = "codec", - .description = "CODEC", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "Asahi Kasei AK4540", - .value = AC97_CODEC_AK4540 - }, { - .description = "Crystal CS4297", - .value = AC97_CODEC_CS4297 - }, { - .description = "Crystal CS4297A", - .value = AC97_CODEC_CS4297A - }, { - .description = "SigmaTel STAC9708", - .value = AC97_CODEC_STAC9708 - }, { - .description = "SigmaTel STAC9721", - .value = AC97_CODEC_STAC9721 - } - }, - .default_int = AC97_CODEC_CS4297A + .name = "codec", + .description = "CODEC", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "Asahi Kasei AK4540", + .value = AC97_CODEC_AK4540 + }, { + .description = "Crystal CS4297", + .value = AC97_CODEC_CS4297 + }, { + .description = "Crystal CS4297A", + .value = AC97_CODEC_CS4297A + }, { + .description = "SigmaTel STAC9708", + .value = AC97_CODEC_STAC9708 + }, { + .description = "SigmaTel STAC9721", + .value = AC97_CODEC_STAC9721 + } }, - { - "receive_input", "Receive input (MIDI)", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 + .default_int = AC97_CODEC_CS4297A + }, + { + "receive_input", "Receive input (MIDI)", CONFIG_BINARY, "", 1 + }, + { + "", "", -1 } +// clang-format on }; - -const device_t es1371_device = -{ +const device_t es1371_device = { "Ensoniq AudioPCI (ES1371)", "es1371", DEVICE_PCI, @@ -2115,8 +2101,7 @@ const device_t es1371_device = es1371_config }; -const device_t es1371_onboard_device = -{ +const device_t es1371_onboard_device = { "Ensoniq AudioPCI (ES1371) (On-Board)", "es1371_onboard", DEVICE_PCI, diff --git a/src/sound/snd_azt2316a.c b/src/sound/snd_azt2316a.c index b6e882013..6a842e029 100644 --- a/src/sound/snd_azt2316a.c +++ b/src/sound/snd_azt2316a.c @@ -130,22 +130,23 @@ * are probably due to this. */ -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include #define HAVE_STDARG_H + #include <86box/86box.h> -#include <86box/io.h> -#include <86box/timer.h> -#include <86box/pic.h> -#include <86box/nvr.h> #include <86box/device.h> -#include <86box/sound.h> +#include <86box/io.h> #include <86box/midi.h> +#include <86box/timer.h> +#include <86box/nvr.h> +#include <86box/pic.h> +#include <86box/sound.h> #include <86box/snd_ad1848.h> #include <86box/snd_azt2316a.h> #include <86box/snd_sb.h> @@ -161,1328 +162,1292 @@ /*e80, 11, 1 - 530=22*/ /*f40, 11, 1 - 530=22*/ +static int azt2316a_wss_dma[4] = { 0, 0, 1, 3 }; +static int azt2316a_wss_irq[8] = { 5, 7, 9, 10, 11, 12, 14, 15 }; /* W95 only uses 7-10, others may be wrong */ +// static uint16_t azt2316a_wss_addr[4] = {0x530, 0x604, 0xe80, 0xf40}; -static int azt2316a_wss_dma[4] = {0, 0, 1, 3}; -static int azt2316a_wss_irq[8] = {5, 7, 9, 10, 11, 12, 14, 15}; /* W95 only uses 7-10, others may be wrong */ -//static uint16_t azt2316a_wss_addr[4] = {0x530, 0x604, 0xe80, 0xf40}; +typedef struct azt2316a_t { + int type; + int wss_interrupt_after_config; -typedef struct azt2316a_t -{ - int type; - int wss_interrupt_after_config; + uint8_t wss_config; - uint8_t wss_config; + uint16_t cur_addr, cur_wss_addr, cur_mpu401_addr; - uint16_t cur_addr, cur_wss_addr, cur_mpu401_addr; + int cur_irq, cur_dma; + int cur_wss_enabled, cur_wss_irq, cur_wss_dma; + int cur_mpu401_irq; + int cur_mpu401_enabled; - int cur_irq, cur_dma; - int cur_wss_enabled, cur_wss_irq, cur_wss_dma; - int cur_mpu401_irq; - int cur_mpu401_enabled; + uint32_t config_word; + uint32_t config_word_unlocked; - uint32_t config_word; - uint32_t config_word_unlocked; + uint8_t cur_mode; - uint8_t cur_mode; + ad1848_t ad1848; + mpu_t *mpu; - ad1848_t ad1848; - mpu_t *mpu; - - sb_t *sb; + sb_t *sb; } azt2316a_t; static uint8_t azt2316a_wss_read(uint16_t addr, void *p) { - azt2316a_t *azt2316a = (azt2316a_t *)p; - uint8_t temp; + azt2316a_t *azt2316a = (azt2316a_t *) p; + uint8_t temp; - /* TODO: when windows is initializing, writing 0x48, 0x58 and 0x60 to - 0x530 makes reading from 0x533 return 0x44, but writing 0x50 - makes this return 0x04. Why? */ - if (addr & 1) - temp = 4 | (azt2316a->wss_config & 0x40); - else - temp = 4 | (azt2316a->wss_config & 0xC0); + /* TODO: when windows is initializing, writing 0x48, 0x58 and 0x60 to + 0x530 makes reading from 0x533 return 0x44, but writing 0x50 + makes this return 0x04. Why? */ + if (addr & 1) + temp = 4 | (azt2316a->wss_config & 0x40); + else + temp = 4 | (azt2316a->wss_config & 0xC0); - return temp; + return temp; } static void azt2316a_wss_write(uint16_t addr, uint8_t val, void *p) { - azt2316a_t *azt2316a = (azt2316a_t *)p; - int interrupt = 0; + azt2316a_t *azt2316a = (azt2316a_t *) p; + int interrupt = 0; - if (azt2316a->wss_interrupt_after_config) { - if ((azt2316a->wss_config & 0x40) && !(val & 0x40)) { // TODO: is this the right edge? - interrupt = 1; - } - } + if (azt2316a->wss_interrupt_after_config) { + if ((azt2316a->wss_config & 0x40) && !(val & 0x40)) { // TODO: is this the right edge? + interrupt = 1; + } + } - azt2316a->wss_config = val; - azt2316a->cur_wss_dma = azt2316a_wss_dma[val & 3]; - azt2316a->cur_wss_irq = azt2316a_wss_irq[(val >> 3) & 7]; - ad1848_setdma(&azt2316a->ad1848, azt2316a_wss_dma[val & 3]); - ad1848_setirq(&azt2316a->ad1848, azt2316a_wss_irq[(val >> 3) & 7]); + azt2316a->wss_config = val; + azt2316a->cur_wss_dma = azt2316a_wss_dma[val & 3]; + azt2316a->cur_wss_irq = azt2316a_wss_irq[(val >> 3) & 7]; + ad1848_setdma(&azt2316a->ad1848, azt2316a_wss_dma[val & 3]); + ad1848_setirq(&azt2316a->ad1848, azt2316a_wss_irq[(val >> 3) & 7]); - if (interrupt) - picint(1 << azt2316a->cur_wss_irq); + if (interrupt) + picint(1 << azt2316a->cur_wss_irq); } /* generate a config word based on current settings */ static void azt1605_create_config_word(void *p) { - azt2316a_t *azt2316a = (azt2316a_t *)p; - uint32_t temp = 0; + azt2316a_t *azt2316a = (azt2316a_t *) p; + uint32_t temp = 0; - /* not implemented / hardcoded */ - uint8_t game_enable = 1; - uint8_t cd_type = 0; /* TODO: see if the cd-rom was originally connected there on the real machines emulated by 86Box (Packard Bell Legend 100CD, Itautec Infoway Multimidia, etc) */ - uint8_t cd_dma8 = -1; - uint8_t cd_irq = 0; + /* not implemented / hardcoded */ + uint8_t game_enable = 1; + uint8_t cd_type = 0; /* TODO: see if the cd-rom was originally connected there on the real machines emulated by 86Box (Packard Bell Legend 100CD, Itautec Infoway Multimidia, etc) */ + uint8_t cd_dma8 = -1; + uint8_t cd_irq = 0; - switch (azt2316a->cur_addr) { - case 0x220: - /* do nothing - temp += 0 << 0; */ - break; - case 0x240: - temp += 1 << 0; - break; -/* - case 0x260: // TODO: INVALID? - temp += 2 << 0; - break; - case 0x280: // TODO: INVALID? - temp += 3 << 0; - break; -*/ - } + switch (azt2316a->cur_addr) { + case 0x220: + /* do nothing + temp += 0 << 0; */ + break; + case 0x240: + temp += 1 << 0; + break; + /* + case 0x260: // TODO: INVALID? + temp += 2 << 0; + break; + case 0x280: // TODO: INVALID? + temp += 3 << 0; + break; + */ + } - switch (azt2316a->cur_irq) { - case 9: - temp += 1 << 8; - break; - case 3: - temp += 1 << 9; - break; - case 5: - temp += 1 << 10; - break; - case 7: - temp += 1 << 11; - break; - } + switch (azt2316a->cur_irq) { + case 9: + temp += 1 << 8; + break; + case 3: + temp += 1 << 9; + break; + case 5: + temp += 1 << 10; + break; + case 7: + temp += 1 << 11; + break; + } - switch (azt2316a->cur_wss_addr) { - case 0x530: - /* do nothing - temp += 0 << 16; */ - break; - case 0x604: - temp += 1 << 16; - break; - case 0xE80: - temp += 2 << 16; - break; - case 0xF40: - temp += 3 << 16; - break; - } + switch (azt2316a->cur_wss_addr) { + case 0x530: + /* do nothing + temp += 0 << 16; */ + break; + case 0x604: + temp += 1 << 16; + break; + case 0xE80: + temp += 2 << 16; + break; + case 0xF40: + temp += 3 << 16; + break; + } - if (azt2316a->cur_wss_enabled) - temp += 1 << 18; + if (azt2316a->cur_wss_enabled) + temp += 1 << 18; - if (game_enable) - temp += 1 << 4; + if (game_enable) + temp += 1 << 4; - switch (azt2316a->cur_mpu401_addr) { - case 0x300: - /* do nothing - temp += 0 << 2; */ - break; - case 0x330: - temp += 1 << 2; - break; - } + switch (azt2316a->cur_mpu401_addr) { + case 0x300: + /* do nothing + temp += 0 << 2; */ + break; + case 0x330: + temp += 1 << 2; + break; + } - if (azt2316a->cur_mpu401_enabled) - temp += 1 << 3; + if (azt2316a->cur_mpu401_enabled) + temp += 1 << 3; - switch (cd_type) { - case 0: /* disabled - do nothing - temp += 0 << 5; */ - break; - case 1: // panasonic - temp += 1 << 5; - break; - case 2: // mitsumi/sony/aztech - temp += 2 << 5; - break; - case 3: // all enabled - temp += 3 << 5; - break; - case 4: // unused - temp += 4 << 5; - break; - case 5: // unused - temp += 5 << 5; - break; - case 6: // unused - temp += 6 << 5; - break; - case 7: // unused - temp += 7 << 5; - break; - } + switch (cd_type) { + case 0: /* disabled + do nothing + temp += 0 << 5; */ + break; + case 1: // panasonic + temp += 1 << 5; + break; + case 2: // mitsumi/sony/aztech + temp += 2 << 5; + break; + case 3: // all enabled + temp += 3 << 5; + break; + case 4: // unused + temp += 4 << 5; + break; + case 5: // unused + temp += 5 << 5; + break; + case 6: // unused + temp += 6 << 5; + break; + case 7: // unused + temp += 7 << 5; + break; + } - switch (cd_dma8) { - case 0xFF: /* -1 - do nothing - temp += 0 << 22;*/ - break; - case 0: - temp += 1 << 22; - break; - case 1: - temp += 2 << 22; - break; - case 3: - temp += 3 << 22; - break; - } + switch (cd_dma8) { + case 0xFF: /* -1 + do nothing + temp += 0 << 22;*/ + break; + case 0: + temp += 1 << 22; + break; + case 1: + temp += 2 << 22; + break; + case 3: + temp += 3 << 22; + break; + } - switch (azt2316a->cur_mpu401_irq) { - case 9: - temp += 1 << 12; - break; - case 3: - temp += 1 << 13; - break; - case 5: - temp += 1 << 14; - break; - case 7: - temp += 1 << 15; - break; - } + switch (azt2316a->cur_mpu401_irq) { + case 9: + temp += 1 << 12; + break; + case 3: + temp += 1 << 13; + break; + case 5: + temp += 1 << 14; + break; + case 7: + temp += 1 << 15; + break; + } - switch (cd_irq) { - case 0: // disabled - // do nothing - break; - case 11: - temp += 1 << 19; - break; - case 12: - temp += 1 << 20; - break; - case 15: - temp += 1 << 21; - break; - } + switch (cd_irq) { + case 0: // disabled + // do nothing + break; + case 11: + temp += 1 << 19; + break; + case 12: + temp += 1 << 20; + break; + case 15: + temp += 1 << 21; + break; + } - azt2316a->config_word = temp; + azt2316a->config_word = temp; } static void azt2316a_create_config_word(void *p) { - azt2316a_t *azt2316a = (azt2316a_t *)p; - uint32_t temp = 0; + azt2316a_t *azt2316a = (azt2316a_t *) p; + uint32_t temp = 0; - /* not implemented / hardcoded */ - uint8_t game_enable = 1; - uint16_t cd_addr = 0x310; - uint8_t cd_type = 0; /* TODO: see if the cd-rom was originally connected there on the real machines emulated by 86Box (Packard Bell Legend 100CD, Itautec Infoway Multimidia, etc) */ - uint8_t cd_dma8 = -1; - uint8_t cd_dma16 = -1; - uint8_t cd_irq = 15; + /* not implemented / hardcoded */ + uint8_t game_enable = 1; + uint16_t cd_addr = 0x310; + uint8_t cd_type = 0; /* TODO: see if the cd-rom was originally connected there on the real machines emulated by 86Box (Packard Bell Legend 100CD, Itautec Infoway Multimidia, etc) */ + uint8_t cd_dma8 = -1; + uint8_t cd_dma16 = -1; + uint8_t cd_irq = 15; - if (azt2316a->type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { - azt1605_create_config_word(p); - return; - } + if (azt2316a->type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { + azt1605_create_config_word(p); + return; + } - switch (azt2316a->cur_addr) { - case 0x220: - /* do nothing - temp += 0 << 0; */ - break; - case 0x240: - temp += 1 << 0; - break; -/* - case 0x260: // TODO: INVALID? - temp += 2 << 0; - break; - case 0x280: // TODO: INVALID? - temp += 3 << 0; - break; -*/ - } + switch (azt2316a->cur_addr) { + case 0x220: + /* do nothing + temp += 0 << 0; */ + break; + case 0x240: + temp += 1 << 0; + break; + /* + case 0x260: // TODO: INVALID? + temp += 2 << 0; + break; + case 0x280: // TODO: INVALID? + temp += 3 << 0; + break; + */ + } - switch (azt2316a->cur_irq) { - case 9: - temp += 1 << 2; - break; - case 5: - temp += 1 << 3; - break; - case 7: - temp += 1 << 4; - break; - case 10: - temp += 1 << 5; - break; - } + switch (azt2316a->cur_irq) { + case 9: + temp += 1 << 2; + break; + case 5: + temp += 1 << 3; + break; + case 7: + temp += 1 << 4; + break; + case 10: + temp += 1 << 5; + break; + } - switch (azt2316a->cur_dma) { -/* - // TODO: INVALID? - case 0xFF: // -1 - // do nothing - //temp += 0 << 6; - break; -*/ - case 0: - temp += 1 << 6; - break; - case 1: - temp += 2 << 6; - break; - case 3: - temp += 3 << 6; - break; - } + switch (azt2316a->cur_dma) { + /* + // TODO: INVALID? + case 0xFF: // -1 + // do nothing + //temp += 0 << 6; + break; + */ + case 0: + temp += 1 << 6; + break; + case 1: + temp += 2 << 6; + break; + case 3: + temp += 3 << 6; + break; + } - switch (azt2316a->cur_wss_addr) - { - case 0x530: - // do nothing - //temp += 0 << 8; - break; - case 0x604: - temp += 1 << 8; - break; - case 0xE80: - temp += 2 << 8; - break; - case 0xF40: - temp += 3 << 8; - break; - } - if (azt2316a->cur_wss_enabled) - temp += 1 << 10; - if (game_enable) - temp += 1 << 11; - switch (azt2316a->cur_mpu401_addr) - { - case 0x300: - // do nothing - //temp += 0 << 12; - break; - case 0x330: - temp += 1 << 12; - break; - } + switch (azt2316a->cur_wss_addr) { + case 0x530: + // do nothing + // temp += 0 << 8; + break; + case 0x604: + temp += 1 << 8; + break; + case 0xE80: + temp += 2 << 8; + break; + case 0xF40: + temp += 3 << 8; + break; + } + if (azt2316a->cur_wss_enabled) + temp += 1 << 10; + if (game_enable) + temp += 1 << 11; + switch (azt2316a->cur_mpu401_addr) { + case 0x300: + // do nothing + // temp += 0 << 12; + break; + case 0x330: + temp += 1 << 12; + break; + } - if (azt2316a->cur_mpu401_enabled) - temp += 1 << 13; + if (azt2316a->cur_mpu401_enabled) + temp += 1 << 13; - switch (cd_addr) { - case 0x310: - // do nothing - //temp += 0 << 14; - break; - case 0x320: - temp += 1 << 14; - break; - case 0x340: - temp += 2 << 14; - break; - case 0x350: - temp += 3 << 14; - break; - } - switch (cd_type) { - case 0: /* disabled - do nothing - temp += 0 << 16; */ - break; - case 1: /* panasonic */ - temp += 1 << 16; - break; - case 2: /* sony */ - temp += 2 << 16; - break; - case 3: /* mitsumi */ - temp += 3 << 16; - break; - case 4: /* aztech */ - temp += 4 << 16; - break; - case 5: /* unused */ - temp += 5 << 16; - break; - case 6: /* unused */ - temp += 6 << 16; - break; - case 7: /* unused */ - temp += 7 << 16; - break; - } + switch (cd_addr) { + case 0x310: + // do nothing + // temp += 0 << 14; + break; + case 0x320: + temp += 1 << 14; + break; + case 0x340: + temp += 2 << 14; + break; + case 0x350: + temp += 3 << 14; + break; + } + switch (cd_type) { + case 0: /* disabled + do nothing + temp += 0 << 16; */ + break; + case 1: /* panasonic */ + temp += 1 << 16; + break; + case 2: /* sony */ + temp += 2 << 16; + break; + case 3: /* mitsumi */ + temp += 3 << 16; + break; + case 4: /* aztech */ + temp += 4 << 16; + break; + case 5: /* unused */ + temp += 5 << 16; + break; + case 6: /* unused */ + temp += 6 << 16; + break; + case 7: /* unused */ + temp += 7 << 16; + break; + } - switch (cd_dma8) { - case 0xFF: /* -1 - do nothing - temp += 0 << 20; */ - break; - case 0: - temp += 1 << 20; - break; -/* - case 1: // TODO: INVALID? - temp += 2 << 20; - break; -*/ - case 3: - temp += 3 << 20; - break; - } + switch (cd_dma8) { + case 0xFF: /* -1 + do nothing + temp += 0 << 20; */ + break; + case 0: + temp += 1 << 20; + break; + /* + case 1: // TODO: INVALID? + temp += 2 << 20; + break; + */ + case 3: + temp += 3 << 20; + break; + } - switch (cd_dma16) { - case 0xFF: /* -1 - do nothing - temp += 0 << 22; */ - break; - case 5: - temp += 1 << 22; - break; - case 6: - temp += 2 << 22; - break; - case 7: - temp += 3 << 22; - break; - } + switch (cd_dma16) { + case 0xFF: /* -1 + do nothing + temp += 0 << 22; */ + break; + case 5: + temp += 1 << 22; + break; + case 6: + temp += 2 << 22; + break; + case 7: + temp += 3 << 22; + break; + } - switch (azt2316a->cur_mpu401_irq) { - case 9: - temp += 1 << 24; - break; - case 5: - temp += 1 << 25; - break; - case 7: - temp += 1 << 26; - break; - case 10: - temp += 1 << 27; - break; - } + switch (azt2316a->cur_mpu401_irq) { + case 9: + temp += 1 << 24; + break; + case 5: + temp += 1 << 25; + break; + case 7: + temp += 1 << 26; + break; + case 10: + temp += 1 << 27; + break; + } - switch (cd_irq) { - case 5: - temp += 1 << 28; - break; - case 11: - temp += 1 << 29; - break; - case 12: - temp += 1 << 30; - break; - case 15: - temp += 1 << 31; - break; - } + switch (cd_irq) { + case 5: + temp += 1 << 28; + break; + case 11: + temp += 1 << 29; + break; + case 12: + temp += 1 << 30; + break; + case 15: + temp += 1 << 31; + break; + } - azt2316a->config_word = temp; + azt2316a->config_word = temp; } static uint8_t azt2316a_config_read(uint16_t addr, void *p) { - azt2316a_t *azt2316a = (azt2316a_t *)p; - uint8_t temp = 0; + azt2316a_t *azt2316a = (azt2316a_t *) p; + uint8_t temp = 0; - /* Some WSS config here + config change enable bit - (setting bit 7 and writing back) */ + /* Some WSS config here + config change enable bit + (setting bit 7 and writing back) */ - if (addr == (azt2316a->cur_addr + 0x404)) { - /* TODO: what is the real meaning of the read value? - I got a mention of bit 0x10 for WSS from disassembling the source - code of the driver, and when playing with the I/O ports on real - hardware after doing some configuration, but didn't dig into it. - Bit 0x08 seems to be a busy flag and generates a timeout - (continuous re-reading when initializing windows 98) */ - temp = azt2316a->cur_mode ? 0x07 : 0x0F; - if (azt2316a->config_word_unlocked) { - temp |= 0x80; - } - } else { - // Rest of config. These are documented in the Linux driver. - switch (addr & 0x3) - { - case 0: - temp = azt2316a->config_word & 0xFF; - break; - case 1: - temp = (azt2316a->config_word >> 8); - break; - case 2: - temp = (azt2316a->config_word >> 16); - break; - case 3: - temp = (azt2316a->config_word >> 24); - break; - } + if (addr == (azt2316a->cur_addr + 0x404)) { + /* TODO: what is the real meaning of the read value? + I got a mention of bit 0x10 for WSS from disassembling the source + code of the driver, and when playing with the I/O ports on real + hardware after doing some configuration, but didn't dig into it. + Bit 0x08 seems to be a busy flag and generates a timeout + (continuous re-reading when initializing windows 98) */ + temp = azt2316a->cur_mode ? 0x07 : 0x0F; + if (azt2316a->config_word_unlocked) { + temp |= 0x80; } + } else { + // Rest of config. These are documented in the Linux driver. + switch (addr & 0x3) { + case 0: + temp = azt2316a->config_word & 0xFF; + break; + case 1: + temp = (azt2316a->config_word >> 8); + break; + case 2: + temp = (azt2316a->config_word >> 16); + break; + case 3: + temp = (azt2316a->config_word >> 24); + break; + } + } - return temp; + return temp; } - static void azt1605_config_write(uint16_t addr, uint8_t val, void *p) { - azt2316a_t *azt2316a = (azt2316a_t *)p; - uint8_t temp; + azt2316a_t *azt2316a = (azt2316a_t *) p; + uint8_t temp; - if (addr == (azt2316a->cur_addr + 0x404)) { - if (val & 0x80) - azt2316a->config_word_unlocked = 1; - else - azt2316a->config_word_unlocked = 0; - } else if (azt2316a->config_word_unlocked) { - if (val == 0xFF) { /* TODO: check if this still happens on eeprom.sys after having more complete emulation! */ - return; - } - switch (addr & 3) { - case 0: - azt2316a->config_word = (azt2316a->config_word & 0xFFFFFF00) | val; - - temp = val & 3; - if (temp == 0) - azt2316a->cur_addr = 0x220; - else if (temp == 1) - azt2316a->cur_addr = 0x240; -/* - else if (temp == 2) - azt2316a->cur_addr = 0x260; // TODO: INVALID - else if (temp == 3) - azt2316a->cur_addr = 0x280; // TODO: INVALID -*/ - if (val & 0x4) - azt2316a->cur_mpu401_addr = 0x330; - else - azt2316a->cur_mpu401_addr = 0x300; - - if (val & 0x8) - azt2316a->cur_mpu401_enabled = 1; - else - azt2316a->cur_mpu401_enabled = 0; - break; - case 1: - azt2316a->config_word = (azt2316a->config_word & 0xFFFF00FF) | (val << 8); - - if (val & 0x1) - azt2316a->cur_irq = 9; - else if (val & 0x2) - azt2316a->cur_irq = 3; - else if (val & 0x4) - azt2316a->cur_irq = 5; - else if (val & 0x8) - azt2316a->cur_irq = 7; - /* else undefined? */ - - if (val & 0x10) - azt2316a->cur_mpu401_irq = 9; - else if (val & 0x20) - azt2316a->cur_mpu401_irq = 3; - else if (val & 0x40) - azt2316a->cur_mpu401_irq = 5; - else if (val & 0x80) - azt2316a->cur_mpu401_irq = 7; - /* else undefined? */ - break; - case 2: - azt2316a->config_word = (azt2316a->config_word & 0xFF00FFFF) | (val << 16); - - io_removehandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, NULL, azt2316a); - io_removehandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &azt2316a->ad1848); - - temp = val & 0x3; - if (temp == 0) - azt2316a->cur_wss_addr = 0x530; - else if (temp == 1) - azt2316a->cur_wss_addr = 0x604; - else if (temp == 2) - azt2316a->cur_wss_addr = 0xE80; - else if (temp == 3) - azt2316a->cur_wss_addr = 0xF40; - - io_sethandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, NULL, azt2316a); - io_sethandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &azt2316a->ad1848); - - /* no actual effect */ - if (val & 0x4) - azt2316a->cur_wss_enabled = 1; - else - azt2316a->cur_wss_enabled = 0; - break; - case 3: - break; - } - /* update sbprov2 configs */ - sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr); - sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq); - sb_dsp_setdma8(&azt2316a->sb->dsp, azt2316a->cur_dma); - - mpu401_change_addr(azt2316a->mpu, azt2316a->cur_mpu401_addr); - mpu401_setirq(azt2316a->mpu, azt2316a->cur_mpu401_irq); + if (addr == (azt2316a->cur_addr + 0x404)) { + if (val & 0x80) + azt2316a->config_word_unlocked = 1; + else + azt2316a->config_word_unlocked = 0; + } else if (azt2316a->config_word_unlocked) { + if (val == 0xFF) { /* TODO: check if this still happens on eeprom.sys after having more complete emulation! */ + return; } + switch (addr & 3) { + case 0: + azt2316a->config_word = (azt2316a->config_word & 0xFFFFFF00) | val; + + temp = val & 3; + if (temp == 0) + azt2316a->cur_addr = 0x220; + else if (temp == 1) + azt2316a->cur_addr = 0x240; + /* + else if (temp == 2) + azt2316a->cur_addr = 0x260; // TODO: INVALID + else if (temp == 3) + azt2316a->cur_addr = 0x280; // TODO: INVALID + */ + if (val & 0x4) + azt2316a->cur_mpu401_addr = 0x330; + else + azt2316a->cur_mpu401_addr = 0x300; + + if (val & 0x8) + azt2316a->cur_mpu401_enabled = 1; + else + azt2316a->cur_mpu401_enabled = 0; + break; + case 1: + azt2316a->config_word = (azt2316a->config_word & 0xFFFF00FF) | (val << 8); + + if (val & 0x1) + azt2316a->cur_irq = 9; + else if (val & 0x2) + azt2316a->cur_irq = 3; + else if (val & 0x4) + azt2316a->cur_irq = 5; + else if (val & 0x8) + azt2316a->cur_irq = 7; + /* else undefined? */ + + if (val & 0x10) + azt2316a->cur_mpu401_irq = 9; + else if (val & 0x20) + azt2316a->cur_mpu401_irq = 3; + else if (val & 0x40) + azt2316a->cur_mpu401_irq = 5; + else if (val & 0x80) + azt2316a->cur_mpu401_irq = 7; + /* else undefined? */ + break; + case 2: + azt2316a->config_word = (azt2316a->config_word & 0xFF00FFFF) | (val << 16); + + io_removehandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, NULL, azt2316a); + io_removehandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &azt2316a->ad1848); + + temp = val & 0x3; + if (temp == 0) + azt2316a->cur_wss_addr = 0x530; + else if (temp == 1) + azt2316a->cur_wss_addr = 0x604; + else if (temp == 2) + azt2316a->cur_wss_addr = 0xE80; + else if (temp == 3) + azt2316a->cur_wss_addr = 0xF40; + + io_sethandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, NULL, azt2316a); + io_sethandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &azt2316a->ad1848); + + /* no actual effect */ + if (val & 0x4) + azt2316a->cur_wss_enabled = 1; + else + azt2316a->cur_wss_enabled = 0; + break; + case 3: + break; + } + /* update sbprov2 configs */ + sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr); + sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq); + sb_dsp_setdma8(&azt2316a->sb->dsp, azt2316a->cur_dma); + + mpu401_change_addr(azt2316a->mpu, azt2316a->cur_mpu401_addr); + mpu401_setirq(azt2316a->mpu, azt2316a->cur_mpu401_irq); + } } static void azt2316a_config_write(uint16_t addr, uint8_t val, void *p) { - azt2316a_t *azt2316a = (azt2316a_t *)p; - uint8_t temp; + azt2316a_t *azt2316a = (azt2316a_t *) p; + uint8_t temp; - if (azt2316a->type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { - azt1605_config_write(addr, val, azt2316a); - return; - } + if (azt2316a->type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { + azt1605_config_write(addr, val, azt2316a); + return; + } - if (addr == (azt2316a->cur_addr + 0x404)) { - if (val & 0x80) - azt2316a->config_word_unlocked = 1; + if (addr == (azt2316a->cur_addr + 0x404)) { + if (val & 0x80) + azt2316a->config_word_unlocked = 1; + else + azt2316a->config_word_unlocked = 0; + } else if (azt2316a->config_word_unlocked) { + if (val == 0xFF) // TODO: check if this still happens on eeprom.sys after having more complete emulation! + return; + switch (addr & 3) { + case 0: + azt2316a->config_word = (azt2316a->config_word & 0xFFFFFF00) | val; + temp = val & 3; + + if (temp == 0) + azt2316a->cur_addr = 0x220; + else if (temp == 1) + azt2316a->cur_addr = 0x240; + + if (val & 0x4) + azt2316a->cur_irq = 9; + else if (val & 0x8) + azt2316a->cur_irq = 5; + else if (val & 0x10) + azt2316a->cur_irq = 7; + else if (val & 0x20) + azt2316a->cur_irq = 10; + + temp = (val >> 6) & 3; + if (temp == 1) + azt2316a->cur_dma = 0; + else if (temp == 2) + azt2316a->cur_dma = 1; + else if (temp == 3) + azt2316a->cur_dma = 3; + break; + case 1: + azt2316a->config_word = (azt2316a->config_word & 0xFFFF00FF) | (val << 8); + + io_removehandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, NULL, azt2316a); + io_removehandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &azt2316a->ad1848); + + temp = val & 0x3; + if (temp == 0) + azt2316a->cur_wss_addr = 0x530; + else if (temp == 1) + azt2316a->cur_wss_addr = 0x604; + else if (temp == 2) + azt2316a->cur_wss_addr = 0xE80; + else if (temp == 3) + azt2316a->cur_wss_addr = 0xF40; + + io_sethandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, NULL, azt2316a); + io_sethandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &azt2316a->ad1848); + + /* no actual effect */ + if (val & 0x4) + azt2316a->cur_wss_enabled = 1; else - azt2316a->config_word_unlocked = 0; - } else if (azt2316a->config_word_unlocked) { - if (val == 0xFF) // TODO: check if this still happens on eeprom.sys after having more complete emulation! - return; - switch (addr & 3) { - case 0: - azt2316a->config_word = (azt2316a->config_word & 0xFFFFFF00) | val; - temp = val & 3; + azt2316a->cur_wss_enabled = 0; - if (temp == 0) - azt2316a->cur_addr = 0x220; - else if (temp == 1) - azt2316a->cur_addr = 0x240; + if (val & 0x10) + azt2316a->cur_mpu401_addr = 0x330; + else + azt2316a->cur_mpu401_addr = 0x300; - if (val & 0x4) - azt2316a->cur_irq = 9; - else if (val & 0x8) - azt2316a->cur_irq = 5; - else if (val & 0x10) - azt2316a->cur_irq = 7; - else if (val & 0x20) - azt2316a->cur_irq = 10; + if (val & 0x20) + azt2316a->cur_mpu401_enabled = 1; + else + azt2316a->cur_mpu401_enabled = 0; + break; + case 2: + azt2316a->config_word = (azt2316a->config_word & 0xFF00FFFF) | (val << 16); + break; + case 3: + azt2316a->config_word = (azt2316a->config_word & 0x00FFFFFF) | (val << 24); - temp = (val >> 6) & 3; - if (temp == 1) - azt2316a->cur_dma = 0; - else if (temp == 2) - azt2316a->cur_dma = 1; - else if (temp == 3) - azt2316a->cur_dma = 3; - break; - case 1: - azt2316a->config_word = (azt2316a->config_word & 0xFFFF00FF) | (val << 8); - - io_removehandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, NULL, azt2316a); - io_removehandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &azt2316a->ad1848); - - temp = val & 0x3; - if (temp == 0) - azt2316a->cur_wss_addr = 0x530; - else if (temp == 1) - azt2316a->cur_wss_addr = 0x604; - else if (temp == 2) - azt2316a->cur_wss_addr = 0xE80; - else if (temp == 3) - azt2316a->cur_wss_addr = 0xF40; - - io_sethandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, NULL, azt2316a); - io_sethandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &azt2316a->ad1848); - - /* no actual effect */ - if (val & 0x4) - azt2316a->cur_wss_enabled = 1; - else - azt2316a->cur_wss_enabled = 0; - - if (val & 0x10) - azt2316a->cur_mpu401_addr = 0x330; - else - azt2316a->cur_mpu401_addr = 0x300; - - if (val & 0x20) - azt2316a->cur_mpu401_enabled = 1; - else - azt2316a->cur_mpu401_enabled = 0; - break; - case 2: - azt2316a->config_word = (azt2316a->config_word & 0xFF00FFFF) | (val << 16); - break; - case 3: - azt2316a->config_word = (azt2316a->config_word & 0x00FFFFFF) | (val << 24); - - if (val & 0x1) - azt2316a->cur_mpu401_irq = 9; - else if (val & 0x2) - azt2316a->cur_mpu401_irq = 5; - else if (val & 0x4) - azt2316a->cur_mpu401_irq = 7; - else if (val & 0x8) - azt2316a->cur_mpu401_irq = 10; - /* else undefined? */ - break; - } - /* update sbprov2 configs */ - sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr); - sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq); - sb_dsp_setdma8(&azt2316a->sb->dsp, azt2316a->cur_dma); - - mpu401_change_addr(azt2316a->mpu, azt2316a->cur_mpu401_addr); - mpu401_setirq(azt2316a->mpu, azt2316a->cur_mpu401_irq); + if (val & 0x1) + azt2316a->cur_mpu401_irq = 9; + else if (val & 0x2) + azt2316a->cur_mpu401_irq = 5; + else if (val & 0x4) + azt2316a->cur_mpu401_irq = 7; + else if (val & 0x8) + azt2316a->cur_mpu401_irq = 10; + /* else undefined? */ + break; } + /* update sbprov2 configs */ + sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr); + sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq); + sb_dsp_setdma8(&azt2316a->sb->dsp, azt2316a->cur_dma); + + mpu401_change_addr(azt2316a->mpu, azt2316a->cur_mpu401_addr); + mpu401_setirq(azt2316a->mpu, azt2316a->cur_mpu401_irq); + } } /* How it behaves when one or another is activated may affect games auto-detecting (and will also use more of the limited system resources!) */ void azt2316a_enable_wss(uint8_t enable, void *p) { - azt2316a_t *azt2316a = (azt2316a_t *)p; + azt2316a_t *azt2316a = (azt2316a_t *) p; - if (enable) - azt2316a->cur_mode = 1; - else - azt2316a->cur_mode = 0; + if (enable) + azt2316a->cur_mode = 1; + else + azt2316a->cur_mode = 0; } static void azt2316a_get_buffer(int32_t *buffer, int len, void *p) { - azt2316a_t *azt2316a = (azt2316a_t *)p; - int c; + azt2316a_t *azt2316a = (azt2316a_t *) p; + int c; - /* wss part */ - ad1848_update(&azt2316a->ad1848); - for (c = 0; c < len * 2; c++) - buffer[c] += (azt2316a->ad1848.buffer[c] / 2); + /* wss part */ + ad1848_update(&azt2316a->ad1848); + for (c = 0; c < len * 2; c++) + buffer[c] += (azt2316a->ad1848.buffer[c] / 2); - azt2316a->ad1848.pos = 0; + azt2316a->ad1848.pos = 0; - /* sbprov2 part */ - sb_get_buffer_sbpro(buffer, len, azt2316a->sb); + /* sbprov2 part */ + sb_get_buffer_sbpro(buffer, len, azt2316a->sb); } static void * azt_init(const device_t *info) { - FILE *f; - char *fn = NULL; - int i; - int loaded_from_eeprom = 0; - uint16_t addr_setting; - uint8_t read_eeprom[AZTECH_EEPROM_SIZE]; - azt2316a_t *azt2316a = malloc(sizeof(azt2316a_t)); - memset(azt2316a, 0, sizeof(azt2316a_t)); + FILE *f; + char *fn = NULL; + int i; + int loaded_from_eeprom = 0; + uint16_t addr_setting; + uint8_t read_eeprom[AZTECH_EEPROM_SIZE]; + azt2316a_t *azt2316a = malloc(sizeof(azt2316a_t)); + memset(azt2316a, 0, sizeof(azt2316a_t)); - azt2316a->type = info->local; + azt2316a->type = info->local; - if (azt2316a->type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { - fn = "azt1605.nvr"; - } else if (azt2316a->type == SB_SUBTYPE_CLONE_AZT2316A_0X11) { - fn = "azt2316a.nvr"; - } + if (azt2316a->type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { + fn = "azt1605.nvr"; + } else if (azt2316a->type == SB_SUBTYPE_CLONE_AZT2316A_0X11) { + fn = "azt2316a.nvr"; + } - /* config */ - f = nvr_fopen(fn, "rb"); - if (f) { - uint8_t checksum = 0x7f; - uint8_t saved_checksum; - size_t res; + /* config */ + f = nvr_fopen(fn, "rb"); + if (f) { + uint8_t checksum = 0x7f; + uint8_t saved_checksum; + size_t res; - res = fread(read_eeprom, AZTECH_EEPROM_SIZE, 1, f); - for (i = 0; i < AZTECH_EEPROM_SIZE; i++) - checksum += read_eeprom[i]; + res = fread(read_eeprom, AZTECH_EEPROM_SIZE, 1, f); + for (i = 0; i < AZTECH_EEPROM_SIZE; i++) + checksum += read_eeprom[i]; - res = fread(&saved_checksum, sizeof(saved_checksum), 1, f); - (void)res; + res = fread(&saved_checksum, sizeof(saved_checksum), 1, f); + (void) res; - fclose(f); + fclose(f); - if (checksum == saved_checksum) - loaded_from_eeprom = 1; + if (checksum == saved_checksum) + loaded_from_eeprom = 1; + } + + if (!loaded_from_eeprom) { + if (azt2316a->type == SB_SUBTYPE_CLONE_AZT2316A_0X11) { + read_eeprom[0] = 0x00; + read_eeprom[1] = 0x00; + read_eeprom[2] = 0x00; + read_eeprom[3] = 0x00; + read_eeprom[4] = 0x00; + read_eeprom[5] = 0x00; + read_eeprom[6] = 0x00; + read_eeprom[7] = 0x00; + read_eeprom[8] = 0x00; + read_eeprom[9] = 0x00; + read_eeprom[10] = 0x00; + read_eeprom[11] = 0x88; + read_eeprom[12] = 0xbc; + read_eeprom[13] = 0x00; + read_eeprom[14] = 0x01; + read_eeprom[15] = 0x00; + } else if (azt2316a->type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { + read_eeprom[0] = 0x80; + read_eeprom[1] = 0x80; + read_eeprom[2] = 0x9F; + read_eeprom[3] = 0x13; + read_eeprom[4] = 0x16; + read_eeprom[5] = 0x13; + read_eeprom[6] = 0x00; + read_eeprom[7] = 0x00; + read_eeprom[8] = 0x16; + read_eeprom[9] = 0x0B; + read_eeprom[10] = 0x06; + read_eeprom[11] = 0x01; + read_eeprom[12] = 0x1C; + read_eeprom[13] = 0x14; + read_eeprom[14] = 0x04; + read_eeprom[15] = 0x1C; + } + } + + if (azt2316a->type == SB_SUBTYPE_CLONE_AZT2316A_0X11) { + azt2316a->config_word = read_eeprom[11] | (read_eeprom[12] << 8) | (read_eeprom[13] << 16) | (read_eeprom[14] << 24); + + switch (azt2316a->config_word & (3 << 0)) { + case 0: + azt2316a->cur_addr = 0x220; + break; + case 1: + azt2316a->cur_addr = 0x240; + break; + default: + fatal("AZT2316A: invalid sb addr in config word %08X\n", azt2316a->config_word); } - if (!loaded_from_eeprom) { - if (azt2316a->type == SB_SUBTYPE_CLONE_AZT2316A_0X11) { - read_eeprom[0] = 0x00; - read_eeprom[1] = 0x00; - read_eeprom[2] = 0x00; - read_eeprom[3] = 0x00; - read_eeprom[4] = 0x00; - read_eeprom[5] = 0x00; - read_eeprom[6] = 0x00; - read_eeprom[7] = 0x00; - read_eeprom[8] = 0x00; - read_eeprom[9] = 0x00; - read_eeprom[10] = 0x00; - read_eeprom[11] = 0x88; - read_eeprom[12] = 0xbc; - read_eeprom[13] = 0x00; - read_eeprom[14] = 0x01; - read_eeprom[15] = 0x00; - } else if (azt2316a->type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { - read_eeprom[0] = 0x80; - read_eeprom[1] = 0x80; - read_eeprom[2] = 0x9F; - read_eeprom[3] = 0x13; - read_eeprom[4] = 0x16; - read_eeprom[5] = 0x13; - read_eeprom[6] = 0x00; - read_eeprom[7] = 0x00; - read_eeprom[8] = 0x16; - read_eeprom[9] = 0x0B; - read_eeprom[10] = 0x06; - read_eeprom[11] = 0x01; - read_eeprom[12] = 0x1C; - read_eeprom[13] = 0x14; - read_eeprom[14] = 0x04; - read_eeprom[15] = 0x1C; - } - } + if (azt2316a->config_word & (1 << 2)) + azt2316a->cur_irq = 9; + else if (azt2316a->config_word & (1 << 3)) + azt2316a->cur_irq = 5; + else if (azt2316a->config_word & (1 << 4)) + azt2316a->cur_irq = 7; + else if (azt2316a->config_word & (1 << 5)) + azt2316a->cur_irq = 10; + else + fatal("AZT2316A: invalid sb irq in config word %08X\n", azt2316a->config_word); - if (azt2316a->type == SB_SUBTYPE_CLONE_AZT2316A_0X11) { - azt2316a->config_word = read_eeprom[11] | (read_eeprom[12] << 8) | (read_eeprom[13] << 16) | (read_eeprom[14] << 24); - - switch (azt2316a->config_word & (3 << 0)) { - case 0: - azt2316a->cur_addr = 0x220; - break; - case 1: - azt2316a->cur_addr = 0x240; - break; - default: - fatal("AZT2316A: invalid sb addr in config word %08X\n", azt2316a->config_word); - } - - if (azt2316a->config_word & (1 << 2)) - azt2316a->cur_irq = 9; - else if (azt2316a->config_word & (1 << 3)) - azt2316a->cur_irq = 5; - else if (azt2316a->config_word & (1 << 4)) - azt2316a->cur_irq = 7; - else if (azt2316a->config_word & (1 << 5)) - azt2316a->cur_irq = 10; - else - fatal("AZT2316A: invalid sb irq in config word %08X\n", azt2316a->config_word); - - switch (azt2316a->config_word & (3 << 6)) { - case 1 << 6: - azt2316a->cur_dma = 0; - break; - case 2 << 6: - azt2316a->cur_dma = 1; - break; - case 3 << 6: - azt2316a->cur_dma = 3; - break; - default: - fatal("AZT2316A: invalid sb dma in config word %08X\n", azt2316a->config_word); - } - - switch (azt2316a->config_word & (3 << 8)) { - case 0: - azt2316a->cur_wss_addr = 0x530; - break; - case 1 << 8: - azt2316a->cur_wss_addr = 0x604; - break; - case 2 << 8: - azt2316a->cur_wss_addr = 0xE80; - break; - case 3 << 8: - azt2316a->cur_wss_addr = 0xF40; - break; - default: - fatal("AZT2316A: invalid wss addr in config word %08X\n", azt2316a->config_word); - } - - if (azt2316a->config_word & (1 << 10)) - azt2316a->cur_wss_enabled = 1; - else - azt2316a->cur_wss_enabled = 0; - - if (azt2316a->config_word & (1 << 12)) - azt2316a->cur_mpu401_addr = 0x330; - else - azt2316a->cur_mpu401_addr = 0x300; - - if (azt2316a->config_word & (1 << 13)) - azt2316a->cur_mpu401_enabled = 1; - else - azt2316a->cur_mpu401_enabled = 0; - - if (azt2316a->config_word & (1 << 24)) - azt2316a->cur_mpu401_irq = 9; - else if (azt2316a->config_word & (1 << 25)) - azt2316a->cur_mpu401_irq = 5; - else if (azt2316a->config_word & (1 << 26)) - azt2316a->cur_mpu401_irq = 7; - else if (azt2316a->config_word & (1 << 27)) - azt2316a->cur_mpu401_irq = 10; - else - fatal("AZT2316A: invalid mpu401 irq in config word %08X\n", azt2316a->config_word); - - /* these are not present on the EEPROM */ - azt2316a->cur_wss_irq = device_get_config_int("wss_irq"); - azt2316a->cur_wss_dma = device_get_config_int("wss_dma"); - azt2316a->cur_mode = 0; - } else if (azt2316a->type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { - azt2316a->config_word = read_eeprom[12] + (read_eeprom[13] << 8) + (read_eeprom[14] << 16); - - switch (azt2316a->config_word & (3 << 0)) { - case 0: - azt2316a->cur_addr = 0x220; - break; - case 1: - azt2316a->cur_addr = 0x240; - break; - default: - fatal("AZT1605: invalid sb addr in config word %08X\n", azt2316a->config_word); - } - - if (azt2316a->config_word & (1 << 2)) - azt2316a->cur_mpu401_addr = 0x330; - else - azt2316a->cur_mpu401_addr = 0x300; - - if (azt2316a->config_word & (1 << 3)) - azt2316a->cur_mpu401_enabled = 1; - else - azt2316a->cur_mpu401_enabled = 0; - - if (azt2316a->config_word & (1 << 8)) - azt2316a->cur_irq = 9; - else if (azt2316a->config_word & (1 << 9)) - azt2316a->cur_irq = 3; - else if (azt2316a->config_word & (1 << 10)) - azt2316a->cur_irq = 5; - else if (azt2316a->config_word & (1 << 11)) - azt2316a->cur_irq = 7; - else - fatal("AZT1605: invalid sb irq in config word %08X\n", azt2316a->config_word); - - if (azt2316a->config_word & (1 << 12)) - azt2316a->cur_mpu401_irq = 9; - else if (azt2316a->config_word & (1 << 13)) - azt2316a->cur_mpu401_irq = 3; - else if (azt2316a->config_word & (1 << 14)) - azt2316a->cur_mpu401_irq = 5; - else if (azt2316a->config_word & (1 << 15)) - azt2316a->cur_mpu401_irq = 7; - else - fatal("AZT1605: invalid mpu401 irq in config word %08X\n", azt2316a->config_word); - - switch (azt2316a->config_word & (3 << 16)) { - case 0: - azt2316a->cur_wss_addr = 0x530; - break; - case 1 << 16: - azt2316a->cur_wss_addr = 0x604; - break; - case 2 << 16: - azt2316a->cur_wss_addr = 0xE80; - break; - case 3 << 16: - azt2316a->cur_wss_addr = 0xF40; - break; - default: - fatal("AZT1605: invalid wss addr in config word %08X\n", azt2316a->config_word); - } - - if (azt2316a->config_word & (1 << 18)) - azt2316a->cur_wss_enabled = 1; - else - azt2316a->cur_wss_enabled = 0; - - // these are not present on the EEPROM - azt2316a->cur_dma = device_get_config_int("sb_dma8"); // TODO: investigate TSR to make this work with it - there is no software configurable DMA8? - azt2316a->cur_wss_irq = device_get_config_int("wss_irq"); - azt2316a->cur_wss_dma = device_get_config_int("wss_dma"); - azt2316a->cur_mode = 0; - } - - addr_setting = device_get_config_hex16("addr"); - if (addr_setting) - azt2316a->cur_addr = addr_setting; - - azt2316a->wss_interrupt_after_config = device_get_config_int("wss_interrupt_after_config"); - - /* wss part */ - ad1848_init(&azt2316a->ad1848, device_get_config_int("codec")); - - ad1848_setirq(&azt2316a->ad1848, azt2316a->cur_wss_irq); - ad1848_setdma(&azt2316a->ad1848, azt2316a->cur_wss_dma); - - io_sethandler(azt2316a->cur_addr + 0x0400, 0x0040, azt2316a_config_read, NULL, NULL, azt2316a_config_write, NULL, NULL, azt2316a); - io_sethandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, NULL, azt2316a); - io_sethandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &azt2316a->ad1848); - - /* sbprov2 part */ - /*sbpro port mappings. 220h or 240h. - 2x0 to 2x3 -> FM chip (18 voices) - 2x4 to 2x5 -> Mixer interface - 2x6, 2xA, 2xC, 2xE -> DSP chip - 2x8, 2x9, 388 and 389 FM chip (9 voices).*/ - azt2316a->sb = malloc(sizeof(sb_t)); - memset(azt2316a->sb, 0, sizeof(sb_t)); - - azt2316a->sb->opl_enabled = device_get_config_int("opl"); - - for (i = 0; i < AZTECH_EEPROM_SIZE; i++) - azt2316a->sb->dsp.azt_eeprom[i] = read_eeprom[i]; - - if (azt2316a->sb->opl_enabled) - opl3_init(&azt2316a->sb->opl); - - sb_dsp_init(&azt2316a->sb->dsp, SBPRO2, azt2316a->type, azt2316a); - sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr); - sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq); - sb_dsp_setdma8(&azt2316a->sb->dsp, azt2316a->cur_dma); - sb_ct1345_mixer_reset(azt2316a->sb); - /* DSP I/O handler is activated in sb_dsp_setaddr */ - if (azt2316a->sb->opl_enabled) { - io_sethandler(azt2316a->cur_addr+0, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &azt2316a->sb->opl); - io_sethandler(azt2316a->cur_addr+8, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &azt2316a->sb->opl); - io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &azt2316a->sb->opl); + switch (azt2316a->config_word & (3 << 6)) { + case 1 << 6: + azt2316a->cur_dma = 0; + break; + case 2 << 6: + azt2316a->cur_dma = 1; + break; + case 3 << 6: + azt2316a->cur_dma = 3; + break; + default: + fatal("AZT2316A: invalid sb dma in config word %08X\n", azt2316a->config_word); } - io_sethandler(azt2316a->cur_addr+4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, azt2316a->sb); + switch (azt2316a->config_word & (3 << 8)) { + case 0: + azt2316a->cur_wss_addr = 0x530; + break; + case 1 << 8: + azt2316a->cur_wss_addr = 0x604; + break; + case 2 << 8: + azt2316a->cur_wss_addr = 0xE80; + break; + case 3 << 8: + azt2316a->cur_wss_addr = 0xF40; + break; + default: + fatal("AZT2316A: invalid wss addr in config word %08X\n", azt2316a->config_word); + } - azt2316a_create_config_word(azt2316a); - sound_add_handler(azt2316a_get_buffer, azt2316a); - sound_set_cd_audio_filter(sbpro_filter_cd_audio, azt2316a->sb); + if (azt2316a->config_word & (1 << 10)) + azt2316a->cur_wss_enabled = 1; + else + azt2316a->cur_wss_enabled = 0; - if (azt2316a->cur_mpu401_enabled) { - azt2316a->mpu = (mpu_t *) malloc(sizeof(mpu_t)); - memset(azt2316a->mpu, 0, sizeof(mpu_t)); - mpu401_init(azt2316a->mpu, azt2316a->cur_mpu401_addr, azt2316a->cur_mpu401_irq, M_UART, device_get_config_int("receive_input401")); - } else - azt2316a->mpu = NULL; + if (azt2316a->config_word & (1 << 12)) + azt2316a->cur_mpu401_addr = 0x330; + else + azt2316a->cur_mpu401_addr = 0x300; - if (device_get_config_int("receive_input")) - midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &azt2316a->sb->dsp); + if (azt2316a->config_word & (1 << 13)) + azt2316a->cur_mpu401_enabled = 1; + else + azt2316a->cur_mpu401_enabled = 0; - return azt2316a; + if (azt2316a->config_word & (1 << 24)) + azt2316a->cur_mpu401_irq = 9; + else if (azt2316a->config_word & (1 << 25)) + azt2316a->cur_mpu401_irq = 5; + else if (azt2316a->config_word & (1 << 26)) + azt2316a->cur_mpu401_irq = 7; + else if (azt2316a->config_word & (1 << 27)) + azt2316a->cur_mpu401_irq = 10; + else + fatal("AZT2316A: invalid mpu401 irq in config word %08X\n", azt2316a->config_word); + + /* these are not present on the EEPROM */ + azt2316a->cur_wss_irq = device_get_config_int("wss_irq"); + azt2316a->cur_wss_dma = device_get_config_int("wss_dma"); + azt2316a->cur_mode = 0; + } else if (azt2316a->type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { + azt2316a->config_word = read_eeprom[12] + (read_eeprom[13] << 8) + (read_eeprom[14] << 16); + + switch (azt2316a->config_word & (3 << 0)) { + case 0: + azt2316a->cur_addr = 0x220; + break; + case 1: + azt2316a->cur_addr = 0x240; + break; + default: + fatal("AZT1605: invalid sb addr in config word %08X\n", azt2316a->config_word); + } + + if (azt2316a->config_word & (1 << 2)) + azt2316a->cur_mpu401_addr = 0x330; + else + azt2316a->cur_mpu401_addr = 0x300; + + if (azt2316a->config_word & (1 << 3)) + azt2316a->cur_mpu401_enabled = 1; + else + azt2316a->cur_mpu401_enabled = 0; + + if (azt2316a->config_word & (1 << 8)) + azt2316a->cur_irq = 9; + else if (azt2316a->config_word & (1 << 9)) + azt2316a->cur_irq = 3; + else if (azt2316a->config_word & (1 << 10)) + azt2316a->cur_irq = 5; + else if (azt2316a->config_word & (1 << 11)) + azt2316a->cur_irq = 7; + else + fatal("AZT1605: invalid sb irq in config word %08X\n", azt2316a->config_word); + + if (azt2316a->config_word & (1 << 12)) + azt2316a->cur_mpu401_irq = 9; + else if (azt2316a->config_word & (1 << 13)) + azt2316a->cur_mpu401_irq = 3; + else if (azt2316a->config_word & (1 << 14)) + azt2316a->cur_mpu401_irq = 5; + else if (azt2316a->config_word & (1 << 15)) + azt2316a->cur_mpu401_irq = 7; + else + fatal("AZT1605: invalid mpu401 irq in config word %08X\n", azt2316a->config_word); + + switch (azt2316a->config_word & (3 << 16)) { + case 0: + azt2316a->cur_wss_addr = 0x530; + break; + case 1 << 16: + azt2316a->cur_wss_addr = 0x604; + break; + case 2 << 16: + azt2316a->cur_wss_addr = 0xE80; + break; + case 3 << 16: + azt2316a->cur_wss_addr = 0xF40; + break; + default: + fatal("AZT1605: invalid wss addr in config word %08X\n", azt2316a->config_word); + } + + if (azt2316a->config_word & (1 << 18)) + azt2316a->cur_wss_enabled = 1; + else + azt2316a->cur_wss_enabled = 0; + + // these are not present on the EEPROM + azt2316a->cur_dma = device_get_config_int("sb_dma8"); // TODO: investigate TSR to make this work with it - there is no software configurable DMA8? + azt2316a->cur_wss_irq = device_get_config_int("wss_irq"); + azt2316a->cur_wss_dma = device_get_config_int("wss_dma"); + azt2316a->cur_mode = 0; + } + + addr_setting = device_get_config_hex16("addr"); + if (addr_setting) + azt2316a->cur_addr = addr_setting; + + azt2316a->wss_interrupt_after_config = device_get_config_int("wss_interrupt_after_config"); + + /* wss part */ + ad1848_init(&azt2316a->ad1848, device_get_config_int("codec")); + + ad1848_setirq(&azt2316a->ad1848, azt2316a->cur_wss_irq); + ad1848_setdma(&azt2316a->ad1848, azt2316a->cur_wss_dma); + + io_sethandler(azt2316a->cur_addr + 0x0400, 0x0040, azt2316a_config_read, NULL, NULL, azt2316a_config_write, NULL, NULL, azt2316a); + io_sethandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, NULL, azt2316a); + io_sethandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &azt2316a->ad1848); + + /* sbprov2 part */ + /*sbpro port mappings. 220h or 240h. + 2x0 to 2x3 -> FM chip (18 voices) + 2x4 to 2x5 -> Mixer interface + 2x6, 2xA, 2xC, 2xE -> DSP chip + 2x8, 2x9, 388 and 389 FM chip (9 voices).*/ + azt2316a->sb = malloc(sizeof(sb_t)); + memset(azt2316a->sb, 0, sizeof(sb_t)); + + azt2316a->sb->opl_enabled = device_get_config_int("opl"); + + for (i = 0; i < AZTECH_EEPROM_SIZE; i++) + azt2316a->sb->dsp.azt_eeprom[i] = read_eeprom[i]; + + if (azt2316a->sb->opl_enabled) + opl3_init(&azt2316a->sb->opl); + + sb_dsp_init(&azt2316a->sb->dsp, SBPRO2, azt2316a->type, azt2316a); + sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr); + sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq); + sb_dsp_setdma8(&azt2316a->sb->dsp, azt2316a->cur_dma); + sb_ct1345_mixer_reset(azt2316a->sb); + /* DSP I/O handler is activated in sb_dsp_setaddr */ + if (azt2316a->sb->opl_enabled) { + io_sethandler(azt2316a->cur_addr + 0, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &azt2316a->sb->opl); + io_sethandler(azt2316a->cur_addr + 8, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &azt2316a->sb->opl); + io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &azt2316a->sb->opl); + } + + io_sethandler(azt2316a->cur_addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, azt2316a->sb); + + azt2316a_create_config_word(azt2316a); + sound_add_handler(azt2316a_get_buffer, azt2316a); + sound_set_cd_audio_filter(sbpro_filter_cd_audio, azt2316a->sb); + + if (azt2316a->cur_mpu401_enabled) { + azt2316a->mpu = (mpu_t *) malloc(sizeof(mpu_t)); + memset(azt2316a->mpu, 0, sizeof(mpu_t)); + mpu401_init(azt2316a->mpu, azt2316a->cur_mpu401_addr, azt2316a->cur_mpu401_irq, M_UART, device_get_config_int("receive_input401")); + } else + azt2316a->mpu = NULL; + + if (device_get_config_int("receive_input")) + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &azt2316a->sb->dsp); + + return azt2316a; } static void azt_close(void *p) { - azt2316a_t *azt2316a = (azt2316a_t *)p; - char *fn = NULL; - FILE *f; - uint8_t checksum = 0x7f; - int i; + azt2316a_t *azt2316a = (azt2316a_t *) p; + char *fn = NULL; + FILE *f; + uint8_t checksum = 0x7f; + int i; - if (azt2316a->type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { - fn = "azt1605.nvr"; - } else if (azt2316a->type == SB_SUBTYPE_CLONE_AZT2316A_0X11) { - fn = "azt2316a.nvr"; - } + if (azt2316a->type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { + fn = "azt1605.nvr"; + } else if (azt2316a->type == SB_SUBTYPE_CLONE_AZT2316A_0X11) { + fn = "azt2316a.nvr"; + } - /* always save to eeprom (recover from bad values) */ - f = nvr_fopen(fn, "wb"); - if (f) { - for (i = 0; i < AZTECH_EEPROM_SIZE; i++) - checksum += azt2316a->sb->dsp.azt_eeprom[i]; - fwrite(azt2316a->sb->dsp.azt_eeprom, AZTECH_EEPROM_SIZE, 1, f); + /* always save to eeprom (recover from bad values) */ + f = nvr_fopen(fn, "wb"); + if (f) { + for (i = 0; i < AZTECH_EEPROM_SIZE; i++) + checksum += azt2316a->sb->dsp.azt_eeprom[i]; + fwrite(azt2316a->sb->dsp.azt_eeprom, AZTECH_EEPROM_SIZE, 1, f); - // TODO: confirm any models saving mixer settings to EEPROM and implement reading back - // TODO: should remember to save wss duplex setting if 86Box has voice recording implemented in the future? Also, default azt2316a->wss_config - // TODO: azt2316a->cur_mode is not saved to EEPROM? - fwrite(&checksum, sizeof(checksum), 1, f); + // TODO: confirm any models saving mixer settings to EEPROM and implement reading back + // TODO: should remember to save wss duplex setting if 86Box has voice recording implemented in the future? Also, default azt2316a->wss_config + // TODO: azt2316a->cur_mode is not saved to EEPROM? + fwrite(&checksum, sizeof(checksum), 1, f); - fclose(f); - } + fclose(f); + } - sb_close(azt2316a->sb); + sb_close(azt2316a->sb); - free(azt2316a); + free(azt2316a); } static void azt_speed_changed(void *p) { - azt2316a_t *azt2316a = (azt2316a_t *)p; + azt2316a_t *azt2316a = (azt2316a_t *) p; - ad1848_speed_changed(&azt2316a->ad1848); - sb_speed_changed(azt2316a->sb); + ad1848_speed_changed(&azt2316a->ad1848); + sb_speed_changed(azt2316a->sb); } -static const device_config_t azt1605_config[] = -{ - { - .name = "codec", - .description = "CODEC", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "CS4248", - .value = AD1848_TYPE_CS4248 - }, - { - .description = "CS4231", - .value = AD1848_TYPE_CS4231 - }, - }, - .default_int = AD1848_TYPE_CS4248 +static const device_config_t azt1605_config[] = { + // clang-format off + { + .name = "codec", + .description = "CODEC", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "CS4248", + .value = AD1848_TYPE_CS4248 + }, + { + .description = "CS4231", + .value = AD1848_TYPE_CS4231 + }, }, + .default_int = AD1848_TYPE_CS4248 + }, + { + .name = "wss_interrupt_after_config", + .description = "Raise CODEC interrupt on CODEC setup (needed by some drivers)", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + "addr", "SB Address", CONFIG_HEX16, "", 0, "", { 0 }, { - .name = "wss_interrupt_after_config", - .description = "Raise CODEC interrupt on CODEC setup (needed by some drivers)", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - "addr", "SB Address", CONFIG_HEX16, "", 0, "", { 0 }, - { - { - "0x220", 0x220 - }, - { - "0x240", 0x240 - }, - { - "Use EEPROM setting", 0 - }, - { - "" - } - } - }, - { - .name = "sb_dma8", - .description = "SB low DMA", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "DMA 0", - .value = 0 - }, - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 3", - .value = 3 - }, - { - .description = "" - } - }, - .default_int = 1 - }, - { - .name = "wss_irq", - .description = "WSS IRQ", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "IRQ 11", - .value = 11 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "" - } - }, - .default_int = 10 - }, - { - .name = "wss_dma", - .description = "WSS DMA", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "DMA 0", - .value = 0 - }, - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 3", - .value = 3 - }, - { - .description = "" - } - }, - .default_int = 0 - }, - { - "opl", "Enable OPL", CONFIG_BINARY, "", 1 - }, - { - "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 - }, - { - "receive_input401", "Receive input (MPU-401)", CONFIG_BINARY, "", 0 - }, - { - "", "", -1 + { "0x220", 0x220 }, + { "0x240", 0x240 }, + { "Use EEPROM setting", 0 }, + { "" } } -}; - -static const device_config_t azt2316a_config[] = -{ + }, + { + .name = "sb_dma8", + .description = "SB low DMA", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "DMA 0", + .value = 0 + }, + { + .description = "DMA 1", + .value = 1 + }, + { + .description = "DMA 3", + .value = 3 + }, + { + .description = "" + } + }, + .default_int = 1 + }, + { + .name = "wss_irq", + .description = "WSS IRQ", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "IRQ 11", + .value = 11 + }, + { + .description = "IRQ 10", + .value = 10 + }, + { + .description = "IRQ 7", + .value = 7 + }, + { + .description = "" + } + }, + .default_int = 10 + }, { - .name = "codec", - .description = "CODEC", - .type = CONFIG_SELECTION, - .selection = + .name = "wss_dma", + .description = "WSS DMA", + .type = CONFIG_SELECTION, + .selection = { { - { - .description = "CS4248", - .value = AD1848_TYPE_CS4248 - }, - { - .description = "CS4231", - .value = AD1848_TYPE_CS4231 - }, + .description = "DMA 0", + .value = 0 }, - .default_int = AD1848_TYPE_CS4248 - }, - { - .name = "wss_interrupt_after_config", - .description = "Raise CODEC interrupt on CODEC setup (needed by some drivers)", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - "addr", "SB Address", CONFIG_HEX16, "", 0, "", { 0 }, { - { - "0x220", 0x220 - }, - { - "0x240", 0x240 - }, - { - "Use EEPROM setting", 0 - }, - { - "" - } + .description = "DMA 1", + .value = 1 + }, + { + .description = "DMA 3", + .value = 3 + }, + { + .description = "" } + }, + .default_int = 0 }, + { "opl", "Enable OPL", CONFIG_BINARY, "", 1 }, + { "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 }, + { "receive_input401", "Receive input (MPU-401)", CONFIG_BINARY, "", 0 }, + { "", "", -1 } + // clang-format on +}; + +static const device_config_t azt2316a_config[] = { + // clang-format off + { + .name = "codec", + .description = "CODEC", + .type = CONFIG_SELECTION, + .selection = { - .name = "wss_irq", - .description = "WSS IRQ", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "IRQ 11", - .value = 11 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "" - } - }, - .default_int = 10 + { + .description = "CS4248", + .value = AD1848_TYPE_CS4248 + }, + { + .description = "CS4231", + .value = AD1848_TYPE_CS4231 + }, }, + .default_int = AD1848_TYPE_CS4248 + }, + { + .name = "wss_interrupt_after_config", + .description = "Raise CODEC interrupt on CODEC setup (needed by some drivers)", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + "addr", "SB Address", CONFIG_HEX16, "", 0, "", { 0 }, { - .name = "wss_dma", - .description = "WSS DMA", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "DMA 0", - .value = 0 - }, - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 3", - .value = 3 - }, - { - .description = "" - } - }, - .default_int = 0 - }, - { - "opl", "Enable OPL", CONFIG_BINARY, "", 1 - }, - { - "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 - }, - { - "receive_input401", "Receive input (MPU-401)", CONFIG_BINARY, "", 0 - }, - { - "", "", -1 + { "0x220", 0x220 }, + { "0x240", 0x240 }, + { "Use EEPROM setting", 0 }, + { "" } } + }, + { + .name = "wss_irq", + .description = "WSS IRQ", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "IRQ 11", + .value = 11 + }, + { + .description = "IRQ 10", + .value = 10 + }, + { + .description = "IRQ 7", + .value = 7 + }, + { + .description = "" + } + }, + .default_int = 10 + }, + { + .name = "wss_dma", + .description = "WSS DMA", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "DMA 0", + .value = 0 + }, + { + .description = "DMA 1", + .value = 1 + }, + { + .description = "DMA 3", + .value = 3 + }, + { + .description = "" + } + }, + .default_int = 0 + }, + { "opl", "Enable OPL", CONFIG_BINARY, "", 1 }, + { "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 }, + { "receive_input401", "Receive input (MPU-401)", CONFIG_BINARY, "", 0 }, + { "", "", -1 } + // clang-format on }; -const device_t azt2316a_device = -{ - "Aztech Sound Galaxy Pro 16 AB (Washington)", - "azt2316a", - DEVICE_ISA | DEVICE_AT, - SB_SUBTYPE_CLONE_AZT2316A_0X11, - azt_init, azt_close, NULL, { NULL }, - azt_speed_changed, - NULL, - azt2316a_config +const device_t azt2316a_device = { + "Aztech Sound Galaxy Pro 16 AB (Washington)", + "azt2316a", + DEVICE_ISA | DEVICE_AT, + SB_SUBTYPE_CLONE_AZT2316A_0X11, + azt_init, + azt_close, + NULL, + { NULL }, + azt_speed_changed, + NULL, + azt2316a_config }; -const device_t azt1605_device = -{ - "Aztech Sound Galaxy Nova 16 Extra (Clinton)", - "azt1605", - DEVICE_ISA | DEVICE_AT, - SB_SUBTYPE_CLONE_AZT1605_0X0C, - azt_init, azt_close, NULL, { NULL }, - azt_speed_changed, - NULL, - azt1605_config +const device_t azt1605_device = { + "Aztech Sound Galaxy Nova 16 Extra (Clinton)", + "azt1605", + DEVICE_ISA | DEVICE_AT, + SB_SUBTYPE_CLONE_AZT1605_0X0C, + azt_init, + azt_close, + NULL, + { NULL }, + azt_speed_changed, + NULL, + azt1605_config }; diff --git a/src/sound/snd_cms.c b/src/sound/snd_cms.c index 69481dd17..308af6351 100644 --- a/src/sound/snd_cms.c +++ b/src/sound/snd_cms.c @@ -1,215 +1,221 @@ #include #include #include -#include #include +#include #include #define HAVE_STDARG_H #include <86box/86box.h> -#include <86box/io.h> #include <86box/device.h> -#include <86box/sound.h> +#include <86box/io.h> #include <86box/snd_cms.h> +#include <86box/sound.h> - -void cms_update(cms_t *cms) +void +cms_update(cms_t *cms) { - for (; cms->pos < sound_pos_global; cms->pos++) - { - int c, d; - int16_t out_l = 0, out_r = 0; + for (; cms->pos < sound_pos_global; cms->pos++) { + int c, d; + int16_t out_l = 0, out_r = 0; - for (c = 0; c < 4; c++) - { - switch (cms->noisetype[c >> 1][c & 1]) - { - case 0: cms->noisefreq[c >> 1][c & 1] = MASTER_CLOCK/256; break; - case 1: cms->noisefreq[c >> 1][c & 1] = MASTER_CLOCK/512; break; - case 2: cms->noisefreq[c >> 1][c & 1] = MASTER_CLOCK/1024; break; - case 3: cms->noisefreq[c >> 1][c & 1] = cms->freq[c >> 1][(c & 1) * 3]; break; - } - } - for (c = 0; c < 2; c ++) - { - if (cms->regs[c][0x1C] & 1) - { - for (d = 0; d < 6; d++) - { - if (cms->regs[c][0x14] & (1 << d)) - { - if (cms->stat[c][d]) out_l += (cms->vol[c][d][0] * 90); - if (cms->stat[c][d]) out_r += (cms->vol[c][d][1] * 90); - cms->count[c][d] += cms->freq[c][d]; - if (cms->count[c][d] >= 24000) - { - cms->count[c][d] -= 24000; - cms->stat[c][d] ^= 1; - } - } - else if (cms->regs[c][0x15] & (1 << d)) - { - if (cms->noise[c][d / 3] & 1) out_l += (cms->vol[c][d][0] * 90); - if (cms->noise[c][d / 3] & 1) out_r += (cms->vol[c][d][0] * 90); - } - } - for (d = 0; d < 2; d++) - { - cms->noisecount[c][d] += cms->noisefreq[c][d]; - while (cms->noisecount[c][d] >= 24000) - { - cms->noisecount[c][d] -= 24000; - cms->noise[c][d] <<= 1; - if (!(((cms->noise[c][d] & 0x4000) >> 8) ^ (cms->noise[c][d] & 0x40))) - cms->noise[c][d] |= 1; - } - } - } - } - cms->buffer[(cms->pos << 1)] = out_l; - cms->buffer[(cms->pos << 1) + 1] = out_r; - } -} - -void cms_get_buffer(int32_t *buffer, int len, void *p) -{ - cms_t *cms = (cms_t *)p; - - int c; - - cms_update(cms); - - for (c = 0; c < len * 2; c++) - buffer[c] += cms->buffer[c]; - - cms->pos = 0; -} - -void cms_write(uint16_t addr, uint8_t val, void *p) -{ - cms_t *cms = (cms_t *)p; - int voice; - int chip = (addr & 2) >> 1; - - switch (addr & 0xf) - { + for (c = 0; c < 4; c++) { + switch (cms->noisetype[c >> 1][c & 1]) { + case 0: + cms->noisefreq[c >> 1][c & 1] = MASTER_CLOCK / 256; + break; case 1: - cms->addrs[0] = val & 31; - break; + cms->noisefreq[c >> 1][c & 1] = MASTER_CLOCK / 512; + break; + case 2: + cms->noisefreq[c >> 1][c & 1] = MASTER_CLOCK / 1024; + break; case 3: - cms->addrs[1] = val & 31; - break; - - case 0: case 2: - cms_update(cms); - cms->regs[chip][cms->addrs[chip] & 31] = val; - switch (cms->addrs[chip] & 31) - { - case 0x00: case 0x01: case 0x02: /*Volume*/ - case 0x03: case 0x04: case 0x05: - voice = cms->addrs[chip] & 7; - cms->vol[chip][voice][0] = val & 0xf; - cms->vol[chip][voice][1] = val >> 4; - break; - case 0x08: case 0x09: case 0x0A: /*Frequency*/ - case 0x0B: case 0x0C: case 0x0D: - voice = cms->addrs[chip] & 7; - cms->latch[chip][voice] = (cms->latch[chip][voice] & 0x700) | val; - cms->freq[chip][voice] = (MASTER_CLOCK/512 << (cms->latch[chip][voice] >> 8)) / (511 - (cms->latch[chip][voice] & 255)); - break; - case 0x10: case 0x11: case 0x12: /*Octave*/ - voice = (cms->addrs[chip] & 3) << 1; - cms->latch[chip][voice] = (cms->latch[chip][voice] & 0xFF) | ((val & 7) << 8); - cms->latch[chip][voice + 1] = (cms->latch[chip][voice + 1] & 0xFF) | ((val & 0x70) << 4); - cms->freq[chip][voice] = (MASTER_CLOCK/512 << (cms->latch[chip][voice] >> 8)) / (511 - (cms->latch[chip][voice] & 255)); - cms->freq[chip][voice + 1] = (MASTER_CLOCK/512 << (cms->latch[chip][voice + 1] >> 8)) / (511 - (cms->latch[chip][voice + 1] & 255)); - break; - case 0x16: /*Noise*/ - cms->noisetype[chip][0] = val & 3; - cms->noisetype[chip][1] = (val >> 4) & 3; - break; - } - break; - case 0x6: case 0x7: - cms->latched_data = val; - break; + cms->noisefreq[c >> 1][c & 1] = cms->freq[c >> 1][(c & 1) * 3]; + break; + } } -} - -uint8_t cms_read(uint16_t addr, void *p) -{ - cms_t *cms = (cms_t *)p; - - switch (addr & 0xf) - { - case 0x1: - return cms->addrs[0]; - case 0x3: - return cms->addrs[1]; - case 0x4: - return 0x7f; - case 0xa: case 0xb: - return cms->latched_data; - } - return 0xff; -} - -void *cms_init(const device_t *info) -{ - cms_t *cms = malloc(sizeof(cms_t)); - memset(cms, 0, sizeof(cms_t)); - - uint16_t addr = device_get_config_hex16("base"); - io_sethandler(addr, 0x0010, cms_read, NULL, NULL, cms_write, NULL, NULL, cms); - sound_add_handler(cms_get_buffer, cms); - return cms; -} - -void cms_close(void *p) -{ - cms_t *cms = (cms_t *)p; - - free(cms); -} - -static const device_config_t cms_config[] = -{ - { - "base", "Address", CONFIG_HEX16, "", 0x220, "", { 0 }, - { - { - "0x210", 0x210 - }, - { - "0x220", 0x220 - }, - { - "0x230", 0x230 - }, - { - "0x240", 0x240 - }, - { - "0x250", 0x250 - }, - { - "0x260", 0x260 - }, - { - "" + for (c = 0; c < 2; c++) { + if (cms->regs[c][0x1C] & 1) { + for (d = 0; d < 6; d++) { + if (cms->regs[c][0x14] & (1 << d)) { + if (cms->stat[c][d]) + out_l += (cms->vol[c][d][0] * 90); + if (cms->stat[c][d]) + out_r += (cms->vol[c][d][1] * 90); + cms->count[c][d] += cms->freq[c][d]; + if (cms->count[c][d] >= 24000) { + cms->count[c][d] -= 24000; + cms->stat[c][d] ^= 1; } + } else if (cms->regs[c][0x15] & (1 << d)) { + if (cms->noise[c][d / 3] & 1) + out_l += (cms->vol[c][d][0] * 90); + if (cms->noise[c][d / 3] & 1) + out_r += (cms->vol[c][d][0] * 90); + } } - }, - { - "", "", -1 + for (d = 0; d < 2; d++) { + cms->noisecount[c][d] += cms->noisefreq[c][d]; + while (cms->noisecount[c][d] >= 24000) { + cms->noisecount[c][d] -= 24000; + cms->noise[c][d] <<= 1; + if (!(((cms->noise[c][d] & 0x4000) >> 8) ^ (cms->noise[c][d] & 0x40))) + cms->noise[c][d] |= 1; + } + } + } } + cms->buffer[(cms->pos << 1)] = out_l; + cms->buffer[(cms->pos << 1) + 1] = out_r; + } +} + +void +cms_get_buffer(int32_t *buffer, int len, void *p) +{ + cms_t *cms = (cms_t *) p; + + int c; + + cms_update(cms); + + for (c = 0; c < len * 2; c++) + buffer[c] += cms->buffer[c]; + + cms->pos = 0; +} + +void +cms_write(uint16_t addr, uint8_t val, void *p) +{ + cms_t *cms = (cms_t *) p; + int voice; + int chip = (addr & 2) >> 1; + + switch (addr & 0xf) { + case 1: + cms->addrs[0] = val & 31; + break; + case 3: + cms->addrs[1] = val & 31; + break; + + case 0: + case 2: + cms_update(cms); + cms->regs[chip][cms->addrs[chip] & 31] = val; + switch (cms->addrs[chip] & 31) { + case 0x00: + case 0x01: + case 0x02: /*Volume*/ + case 0x03: + case 0x04: + case 0x05: + voice = cms->addrs[chip] & 7; + cms->vol[chip][voice][0] = val & 0xf; + cms->vol[chip][voice][1] = val >> 4; + break; + case 0x08: + case 0x09: + case 0x0A: /*Frequency*/ + case 0x0B: + case 0x0C: + case 0x0D: + voice = cms->addrs[chip] & 7; + cms->latch[chip][voice] = (cms->latch[chip][voice] & 0x700) | val; + cms->freq[chip][voice] = (MASTER_CLOCK / 512 << (cms->latch[chip][voice] >> 8)) / (511 - (cms->latch[chip][voice] & 255)); + break; + case 0x10: + case 0x11: + case 0x12: /*Octave*/ + voice = (cms->addrs[chip] & 3) << 1; + cms->latch[chip][voice] = (cms->latch[chip][voice] & 0xFF) | ((val & 7) << 8); + cms->latch[chip][voice + 1] = (cms->latch[chip][voice + 1] & 0xFF) | ((val & 0x70) << 4); + cms->freq[chip][voice] = (MASTER_CLOCK / 512 << (cms->latch[chip][voice] >> 8)) / (511 - (cms->latch[chip][voice] & 255)); + cms->freq[chip][voice + 1] = (MASTER_CLOCK / 512 << (cms->latch[chip][voice + 1] >> 8)) / (511 - (cms->latch[chip][voice + 1] & 255)); + break; + case 0x16: /*Noise*/ + cms->noisetype[chip][0] = val & 3; + cms->noisetype[chip][1] = (val >> 4) & 3; + break; + } + break; + case 0x6: + case 0x7: + cms->latched_data = val; + break; + } +} + +uint8_t +cms_read(uint16_t addr, void *p) +{ + cms_t *cms = (cms_t *) p; + + switch (addr & 0xf) { + case 0x1: + return cms->addrs[0]; + case 0x3: + return cms->addrs[1]; + case 0x4: + return 0x7f; + case 0xa: + case 0xb: + return cms->latched_data; + } + return 0xff; +} + +void * +cms_init(const device_t *info) +{ + cms_t *cms = malloc(sizeof(cms_t)); + memset(cms, 0, sizeof(cms_t)); + + uint16_t addr = device_get_config_hex16("base"); + io_sethandler(addr, 0x0010, cms_read, NULL, NULL, cms_write, NULL, NULL, cms); + sound_add_handler(cms_get_buffer, cms); + return cms; +} + +void +cms_close(void *p) +{ + cms_t *cms = (cms_t *) p; + + free(cms); +} + +static const device_config_t cms_config[] = { + // clang-format off + { + "base", "Address", CONFIG_HEX16, "", 0x220, "", { 0 }, + { + { "0x210", 0x210 }, + { "0x220", 0x220 }, + { "0x230", 0x230 }, + { "0x240", 0x240 }, + { "0x250", 0x250 }, + { "0x260", 0x260 }, + { "" } + } + }, + { + "", "", -1 + } + // clang-format on }; -const device_t cms_device = -{ - "Creative Music System / Game Blaster", - "cms", - DEVICE_ISA, 0, - cms_init, cms_close, NULL, - { NULL }, NULL, NULL, - cms_config +const device_t cms_device = { + "Creative Music System / Game Blaster", + "cms", + DEVICE_ISA, + 0, + cms_init, + cms_close, + NULL, + { NULL }, + NULL, + NULL, + cms_config }; diff --git a/src/sound/snd_cs423x.c b/src/sound/snd_cs423x.c index 575b41148..34d4fb21d 100644 --- a/src/sound/snd_cs423x.c +++ b/src/sound/snd_cs423x.c @@ -1,43 +1,43 @@ /* - * 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. * - * Crystal CS423x (SBPro/WSS compatible sound chips) emulation. + * Crystal CS423x (SBPro/WSS compatible sound chips) emulation. * * * - * Authors: RichardG, + * Authors: RichardG, * - * Copyright 2021-2022 RichardG. + * Copyright 2021-2022 RichardG. */ -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include + #include <86box/86box.h> -#include <86box/io.h> -#include <86box/timer.h> -#include <86box/pic.h> -#include <86box/dma.h> #include <86box/device.h> +#include <86box/dma.h> #include <86box/gameport.h> #include <86box/i2c.h> +#include <86box/io.h> #include <86box/isapnp.h> -#include <86box/sound.h> #include <86box/midi.h> +#include <86box/timer.h> +#include <86box/nvr.h> +#include <86box/pic.h> +#include <86box/sound.h> #include <86box/snd_ad1848.h> #include <86box/snd_opl.h> #include <86box/snd_sb.h> -#include <86box/nvr.h> - -#define CRYSTAL_NOEEPROM 0x100 +#define CRYSTAL_NOEEPROM 0x100 enum { CRYSTAL_CS4235 = 0xdd, @@ -52,12 +52,12 @@ enum { CRYSTAL_SLAM_BYTE2 = 3 }; - static const uint8_t slam_init_key[32] = { 0x96, 0x35, 0x9A, 0xCD, 0xE6, 0xF3, 0x79, 0xBC, - 0x5E, 0xAF, 0x57, 0x2B, 0x15, 0x8A, 0xC5, 0xE2, - 0xF1, 0xF8, 0x7C, 0x3E, 0x9F, 0x4F, 0x27, 0x13, - 0x09, 0x84, 0x42, 0xA1, 0xD0, 0x68, 0x34, 0x1A }; -static const uint8_t cs4236b_eeprom[] = { + 0x5E, 0xAF, 0x57, 0x2B, 0x15, 0x8A, 0xC5, 0xE2, + 0xF1, 0xF8, 0x7C, 0x3E, 0x9F, 0x4F, 0x27, 0x13, + 0x09, 0x84, 0x42, 0xA1, 0xD0, 0x68, 0x34, 0x1A }; +static const uint8_t cs4236b_eeprom[] = { + // clang-format off /* Chip configuration */ 0x55, 0xbb, /* magic */ 0x00, 0x00, /* length */ @@ -77,617 +77,605 @@ static const uint8_t cs4236b_eeprom[] = { 0x82, 0x0e, 0x00, 'C', 'r', 'y', 's', 't', 'a', 'l', ' ', 'C', 'o', 'd', 'e' ,'c', 0x00, /* ANSI identifier */ 0x15, 0x0e, 0x63, 0x00, 0x00, 0x00, /* logical device CSC0000 */ - 0x82, 0x07, 0x00, 'W', 'S', 'S', '/', 'S', 'B', 0x00, /* ANSI identifier */ - 0x31, 0x00, /* start dependent functions, preferred */ - 0x2a, 0x02, 0x28, /* DMA 1, type A, no count by word, count by byte, not bus master, 8-bit only */ - 0x2a, 0x09, 0x28, /* DMA 0/3, type A, no count by word, count by byte, not bus master, 8-bit only */ - 0x22, 0x20, 0x00, /* IRQ 5 */ - 0x47, 0x01, 0x34, 0x05, 0x34, 0x05, 0x04, 0x04, /* I/O 0x534, decodes 16-bit, 4-byte alignment, 4 addresses */ - 0x47, 0x01, 0x88, 0x03, 0x88, 0x03, 0x08, 0x04, /* I/O 0x388, decodes 16-bit, 8-byte alignment, 4 addresses */ - 0x47, 0x01, 0x20, 0x02, 0x20, 0x02, 0x20, 0x10, /* I/O 0x220, decodes 16-bit, 32-byte alignment, 16 addresses */ - 0x31, 0x01, /* start dependent functions, acceptable */ - 0x2a, 0x0a, 0x28, /* DMA 1/3, type A, no count by word, count by byte, not bus master, 8-bit only */ - 0x2a, 0x0b, 0x28, /* DMA 0/1/3, type A, no count by word, count by byte, not bus master, 8-bit only */ - 0x22, 0xa0, 0x9a, /* IRQ 5/7/9/11/12/15 */ - 0x47, 0x01, 0x34, 0x05, 0xfc, 0x0f, 0x04, 0x04, /* I/O 0x534-0xFFC, decodes 16-bit, 4-byte alignment, 4 addresses */ - 0x47, 0x01, 0x88, 0x03, 0x88, 0x03, 0x08, 0x04, /* I/O 0x388, decodes 16-bit, 8-byte alignment, 4 addresses */ - 0x47, 0x01, 0x20, 0x02, 0x60, 0x02, 0x20, 0x10, /* I/O 0x220-0x260, decodes 16-bit, 32-byte alignment, 16 addresses */ - 0x31, 0x02, /* start dependent functions, sub-optimal */ - 0x2a, 0x0b, 0x28, /* DMA 0/1/3, type A, no count by word, count by byte, not bus master, 8-bit only */ - 0x22, 0xa0, 0x9a, /* IRQ 5/7/9/11/12/15 */ - 0x47, 0x01, 0x34, 0x05, 0xfc, 0x0f, 0x04, 0x04, /* I/O 0x534-0xFFC, decodes 16-bit, 4-byte alignment, 4 addresses */ - 0x47, 0x01, 0x88, 0x03, 0xf8, 0x03, 0x08, 0x04, /* I/O 0x388-0x3F8, decodes 16-bit, 8-byte alignment, 4 addresses */ - 0x47, 0x01, 0x20, 0x02, 0x00, 0x03, 0x20, 0x10, /* I/O 0x220-0x300, decodes 16-bit, 32-byte alignment, 16 addresses */ - 0x38, /* end dependent functions */ + 0x82, 0x07, 0x00, 'W', 'S', 'S', '/', 'S', 'B', 0x00, /* ANSI identifier */ + 0x31, 0x00, /* start dependent functions, preferred */ + 0x2a, 0x02, 0x28, /* DMA 1, type A, no count by word, count by byte, not bus master, 8-bit only */ + 0x2a, 0x09, 0x28, /* DMA 0/3, type A, no count by word, count by byte, not bus master, 8-bit only */ + 0x22, 0x20, 0x00, /* IRQ 5 */ + 0x47, 0x01, 0x34, 0x05, 0x34, 0x05, 0x04, 0x04, /* I/O 0x534, decodes 16-bit, 4-byte alignment, 4 addresses */ + 0x47, 0x01, 0x88, 0x03, 0x88, 0x03, 0x08, 0x04, /* I/O 0x388, decodes 16-bit, 8-byte alignment, 4 addresses */ + 0x47, 0x01, 0x20, 0x02, 0x20, 0x02, 0x20, 0x10, /* I/O 0x220, decodes 16-bit, 32-byte alignment, 16 addresses */ + 0x31, 0x01, /* start dependent functions, acceptable */ + 0x2a, 0x0a, 0x28, /* DMA 1/3, type A, no count by word, count by byte, not bus master, 8-bit only */ + 0x2a, 0x0b, 0x28, /* DMA 0/1/3, type A, no count by word, count by byte, not bus master, 8-bit only */ + 0x22, 0xa0, 0x9a, /* IRQ 5/7/9/11/12/15 */ + 0x47, 0x01, 0x34, 0x05, 0xfc, 0x0f, 0x04, 0x04, /* I/O 0x534-0xFFC, decodes 16-bit, 4-byte alignment, 4 addresses */ + 0x47, 0x01, 0x88, 0x03, 0x88, 0x03, 0x08, 0x04, /* I/O 0x388, decodes 16-bit, 8-byte alignment, 4 addresses */ + 0x47, 0x01, 0x20, 0x02, 0x60, 0x02, 0x20, 0x10, /* I/O 0x220-0x260, decodes 16-bit, 32-byte alignment, 16 addresses */ + 0x31, 0x02, /* start dependent functions, sub-optimal */ + 0x2a, 0x0b, 0x28, /* DMA 0/1/3, type A, no count by word, count by byte, not bus master, 8-bit only */ + 0x22, 0xa0, 0x9a, /* IRQ 5/7/9/11/12/15 */ + 0x47, 0x01, 0x34, 0x05, 0xfc, 0x0f, 0x04, 0x04, /* I/O 0x534-0xFFC, decodes 16-bit, 4-byte alignment, 4 addresses */ + 0x47, 0x01, 0x88, 0x03, 0xf8, 0x03, 0x08, 0x04, /* I/O 0x388-0x3F8, decodes 16-bit, 8-byte alignment, 4 addresses */ + 0x47, 0x01, 0x20, 0x02, 0x00, 0x03, 0x20, 0x10, /* I/O 0x220-0x300, decodes 16-bit, 32-byte alignment, 16 addresses */ + 0x38, /* end dependent functions */ 0x15, 0x0e, 0x63, 0x00, 0x01, 0x00, /* logical device CSC0001 */ - 0x82, 0x05, 0x00, 'G', 'A', 'M', 'E', 0x00, /* ANSI identifier */ - 0x31, 0x00, /* start dependent functions, preferred */ - 0x47, 0x01, 0x00, 0x02, 0x00, 0x02, 0x08, 0x08, /* I/O 0x200, decodes 16-bit, 8-byte alignment, 8 addresses */ - 0x31, 0x01, /* start dependent functions, acceptable */ - 0x47, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x08, /* I/O 0x208, decodes 16-bit, 8-byte alignment, 8 addresses */ - 0x38, /* end dependent functions */ + 0x82, 0x05, 0x00, 'G', 'A', 'M', 'E', 0x00, /* ANSI identifier */ + 0x31, 0x00, /* start dependent functions, preferred */ + 0x47, 0x01, 0x00, 0x02, 0x00, 0x02, 0x08, 0x08, /* I/O 0x200, decodes 16-bit, 8-byte alignment, 8 addresses */ + 0x31, 0x01, /* start dependent functions, acceptable */ + 0x47, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x08, /* I/O 0x208, decodes 16-bit, 8-byte alignment, 8 addresses */ + 0x38, /* end dependent functions */ 0x15, 0x0e, 0x63, 0x00, 0x10, 0x00, /* logical device CSC0010 */ - 0x82, 0x05, 0x00, 'C', 'T', 'R', 'L', 0x00, /* ANSI identifier */ - 0x47, 0x01, 0x20, 0x01, 0xf8, 0x0f, 0x08, 0x08, /* I/O 0x120-0xFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ + 0x82, 0x05, 0x00, 'C', 'T', 'R', 'L', 0x00, /* ANSI identifier */ + 0x47, 0x01, 0x20, 0x01, 0xf8, 0x0f, 0x08, 0x08, /* I/O 0x120-0xFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ 0x15, 0x0e, 0x63, 0x00, 0x03, 0x00, /* logical device CSC0003 */ - 0x82, 0x04, 0x00, 'M', 'P', 'U', 0x00, /* ANSI identifier */ - 0x31, 0x00, /* start dependent functions, preferred */ - 0x22, 0x00, 0x02, /* IRQ 9 */ - 0x47, 0x01, 0x30, 0x03, 0x30, 0x03, 0x08, 0x02, /* I/O 0x330, decodes 16-bit, 8-byte alignment, 2 addresses */ - 0x31, 0x01, /* start dependent functions, acceptable */ - 0x22, 0x00, 0x9a, /* IRQ 9/11/12/15 */ - 0x47, 0x01, 0x30, 0x03, 0x60, 0x03, 0x08, 0x02, /* I/O 0x330-0x360, decodes 16-bit, 8-byte alignment, 2 addresses */ - 0x31, 0x02, /* start dependent functions, sub-optimal */ - 0x47, 0x01, 0x30, 0x03, 0xe0, 0x03, 0x08, 0x02, /* I/O 0x330-0x3E0, decodes 16-bit, 8-byte alignment, 2 addresses */ - 0x38, /* end dependent functions */ + 0x82, 0x04, 0x00, 'M', 'P', 'U', 0x00, /* ANSI identifier */ + 0x31, 0x00, /* start dependent functions, preferred */ + 0x22, 0x00, 0x02, /* IRQ 9 */ + 0x47, 0x01, 0x30, 0x03, 0x30, 0x03, 0x08, 0x02, /* I/O 0x330, decodes 16-bit, 8-byte alignment, 2 addresses */ + 0x31, 0x01, /* start dependent functions, acceptable */ + 0x22, 0x00, 0x9a, /* IRQ 9/11/12/15 */ + 0x47, 0x01, 0x30, 0x03, 0x60, 0x03, 0x08, 0x02, /* I/O 0x330-0x360, decodes 16-bit, 8-byte alignment, 2 addresses */ + 0x31, 0x02, /* start dependent functions, sub-optimal */ + 0x47, 0x01, 0x30, 0x03, 0xe0, 0x03, 0x08, 0x02, /* I/O 0x330-0x3E0, decodes 16-bit, 8-byte alignment, 2 addresses */ + 0x38, /* end dependent functions */ 0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */ + // clang-format on }; +typedef struct cs423x_t { + void *pnp_card; + ad1848_t ad1848; + sb_t *sb; + void *gameport; + void *i2c, *eeprom; -typedef struct cs423x_t -{ - void *pnp_card; - ad1848_t ad1848; - sb_t *sb; - void *gameport; - void *i2c, *eeprom; + uint16_t wss_base, opl_base, sb_base, ctrl_base, ram_addr, eeprom_size : 11, pnp_offset; + uint8_t type, ad1848_type, regs[8], indirect_regs[16], + eeprom_data[2048], ram_data[65536], ram_dl : 2, opl_wss : 1; + char *nvr_path; - uint16_t wss_base, opl_base, sb_base, ctrl_base, ram_addr, eeprom_size: 11, pnp_offset; - uint8_t type, ad1848_type, regs[8], indirect_regs[16], - eeprom_data[2048], ram_data[65536], ram_dl: 2, opl_wss: 1; - char *nvr_path; - - uint8_t pnp_enable: 1, key_pos: 5, slam_enable: 1, slam_state: 2, slam_ld, slam_reg; + uint8_t pnp_enable : 1, key_pos : 5, slam_enable : 1, slam_state : 2, slam_ld, slam_reg; isapnp_device_config_t *slam_config; } cs423x_t; - -static void cs423x_slam_enable(cs423x_t *dev, uint8_t enable); -static void cs423x_pnp_enable(cs423x_t *dev, uint8_t update_rom, uint8_t update_hwconfig); -static void cs423x_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv); - +static void cs423x_slam_enable(cs423x_t *dev, uint8_t enable); +static void cs423x_pnp_enable(cs423x_t *dev, uint8_t update_rom, uint8_t update_hwconfig); +static void cs423x_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv); static void cs423x_nvram(cs423x_t *dev, uint8_t save) { FILE *f = nvr_fopen(dev->nvr_path, save ? "wb" : "rb"); if (f) { - if (save) - fwrite(dev->eeprom_data, sizeof(dev->eeprom_data), 1, f); - else - fread(dev->eeprom_data, sizeof(dev->eeprom_data), 1, f); - fclose(f); + if (save) + fwrite(dev->eeprom_data, sizeof(dev->eeprom_data), 1, f); + else + fread(dev->eeprom_data, sizeof(dev->eeprom_data), 1, f); + fclose(f); } } - static uint8_t cs423x_read(uint16_t addr, void *priv) { cs423x_t *dev = (cs423x_t *) priv; - uint8_t reg = addr & 7; - uint8_t ret = dev->regs[reg]; + uint8_t reg = addr & 7; + uint8_t ret = dev->regs[reg]; switch (reg) { - case 1: /* EEPROM Interface */ - ret &= ~0x04; - if ((dev->regs[1] & 0x04) && i2c_gpio_get_sda(dev->i2c)) - ret |= 0x04; - break; + case 1: /* EEPROM Interface */ + ret &= ~0x04; + if ((dev->regs[1] & 0x04) && i2c_gpio_get_sda(dev->i2c)) + ret |= 0x04; + break; - case 4: /* Control Indirect Data Register */ - ret = dev->indirect_regs[dev->regs[3]]; - break; + case 4: /* Control Indirect Data Register */ + ret = dev->indirect_regs[dev->regs[3]]; + break; - case 5: /* Control/RAM Access */ - /* Reading RAM is undocumented; the Windows drivers do so. */ - if (dev->ram_dl == 3) - ret = dev->ram_data[dev->ram_addr++]; - break; + case 5: /* Control/RAM Access */ + /* Reading RAM is undocumented; the Windows drivers do so. */ + if (dev->ram_dl == 3) + ret = dev->ram_data[dev->ram_addr++]; + break; - case 7: /* Global Status */ - /* Context switching: take active context and interrupt flag, then clear interrupt flag. */ - ret &= 0xc0; - dev->regs[7] &= 0x80; + case 7: /* Global Status */ + /* Context switching: take active context and interrupt flag, then clear interrupt flag. */ + ret &= 0xc0; + dev->regs[7] &= 0x80; - if (dev->sb->mpu->state.irq_pending) /* MPU interrupt */ - ret |= 0x08; - if (dev->ad1848.status & 0x01) /* WSS interrupt */ - ret |= 0x10; - if (dev->sb->dsp.sb_irq8 || dev->sb->dsp.sb_irq16 || dev->sb->dsp.sb_irq401) /* SBPro interrupt */ - ret |= 0x20; + if (dev->sb->mpu->state.irq_pending) /* MPU interrupt */ + ret |= 0x08; + if (dev->ad1848.status & 0x01) /* WSS interrupt */ + ret |= 0x10; + if (dev->sb->dsp.sb_irq8 || dev->sb->dsp.sb_irq16 || dev->sb->dsp.sb_irq401) /* SBPro interrupt */ + ret |= 0x20; - break; + break; } return ret; } - static void cs423x_write(uint16_t addr, uint8_t val, void *priv) { cs423x_t *dev = (cs423x_t *) priv; - uint8_t reg = addr & 0x07; + uint8_t reg = addr & 0x07; switch (reg) { - case 1: /* EEPROM Interface */ - if (val & 0x04) - i2c_gpio_set(dev->i2c, val & 0x01, val & 0x02); - break; + case 1: /* EEPROM Interface */ + if (val & 0x04) + i2c_gpio_set(dev->i2c, val & 0x01, val & 0x02); + break; - case 3: /* Control Indirect Access Register */ - val &= 0x0f; - break; + case 3: /* Control Indirect Access Register */ + val &= 0x0f; + break; - case 4: /* Control Indirect Data Register */ - switch (dev->regs[3] & 0x0f) { - case 0: /* WSS Master Control */ - if (val & 0x80) - ad1848_init(&dev->ad1848, dev->ad1848_type); - val = 0x00; - break; + case 4: /* Control Indirect Data Register */ + switch (dev->regs[3] & 0x0f) { + case 0: /* WSS Master Control */ + if (val & 0x80) + ad1848_init(&dev->ad1848, dev->ad1848_type); + val = 0x00; + break; - case 1: /* Version / Chip ID */ - case 7: /* Reserved */ - case 9 ... 15: /* unspecified */ - return; + case 1: /* Version / Chip ID */ + case 7: /* Reserved */ + case 9 ... 15: /* unspecified */ + return; - case 2: /* 3D Space and {Center|Volume} */ - case 6: /* Upper Channel Status */ - if (dev->type < CRYSTAL_CS4237B) - return; - break; + case 2: /* 3D Space and {Center|Volume} */ + case 6: /* Upper Channel Status */ + if (dev->type < CRYSTAL_CS4237B) + return; + break; - case 3: /* 3D Enable */ - if (dev->type < CRYSTAL_CS4237B) - return; - val &= 0xe0; - break; + case 3: /* 3D Enable */ + if (dev->type < CRYSTAL_CS4237B) + return; + val &= 0xe0; + break; - case 4: /* Consumer Serial Port Enable */ - if (dev->type < CRYSTAL_CS4237B) - return; - val &= 0xf0; - break; + case 4: /* Consumer Serial Port Enable */ + if (dev->type < CRYSTAL_CS4237B) + return; + val &= 0xf0; + break; - case 5: /* Lower Channel Status */ - if (dev->type < CRYSTAL_CS4237B) - return; - val &= 0xfe; - break; + case 5: /* Lower Channel Status */ + if (dev->type < CRYSTAL_CS4237B) + return; + val &= 0xfe; + break; - case 8: /* CS9236 Wavetable Control */ - val &= 0x0f; - cs423x_pnp_enable(dev, 0, 0); + case 8: /* CS9236 Wavetable Control */ + val &= 0x0f; + cs423x_pnp_enable(dev, 0, 0); - /* Update WTEN state on the WSS codec. */ - dev->ad1848.wten = !!(val & 0x08); - ad1848_updatevolmask(&dev->ad1848); - break; - } - dev->indirect_regs[dev->regs[3]] = val; - break; + /* Update WTEN state on the WSS codec. */ + dev->ad1848.wten = !!(val & 0x08); + ad1848_updatevolmask(&dev->ad1848); + break; + } + dev->indirect_regs[dev->regs[3]] = val; + break; - case 5: /* Control/RAM Access */ - switch (dev->ram_dl) { - case 0: /* commands */ - switch (val) { - case 0x55: /* Disable PnP Key */ - dev->pnp_enable = 0; - /* fall-through */ + case 5: /* Control/RAM Access */ + switch (dev->ram_dl) { + case 0: /* commands */ + switch (val) { + case 0x55: /* Disable PnP Key */ + dev->pnp_enable = 0; + /* fall-through */ - case 0x5a: /* Update Hardware Configuration Data */ - cs423x_pnp_enable(dev, 0, 1); - break; + case 0x5a: /* Update Hardware Configuration Data */ + cs423x_pnp_enable(dev, 0, 1); + break; - case 0x56: /* Disable Crystal Key */ - cs423x_slam_enable(dev, 0); - break; + case 0x56: /* Disable Crystal Key */ + cs423x_slam_enable(dev, 0); + break; - case 0x57: /* Jump to ROM */ - break; + case 0x57: /* Jump to ROM */ + break; - case 0xaa: /* Download RAM */ - dev->ram_dl = 1; - break; - } - break; + case 0xaa: /* Download RAM */ + dev->ram_dl = 1; + break; + } + break; - case 1: /* low address byte */ - dev->ram_addr = val; - dev->ram_dl++; - break; + case 1: /* low address byte */ + dev->ram_addr = val; + dev->ram_dl++; + break; - case 2: /* high address byte */ - dev->ram_addr |= (val << 8); - dev->ram_dl++; - break; + case 2: /* high address byte */ + dev->ram_addr |= (val << 8); + dev->ram_dl++; + break; - case 3: /* data */ - dev->ram_data[dev->ram_addr++] = val; - break; - } - break; + case 3: /* data */ + dev->ram_data[dev->ram_addr++] = val; + break; + } + break; - case 6: /* RAM Access End */ - /* TriGem Delhi-III BIOS writes undocumented value 0x40 instead of 0x00. */ - if ((val == 0x00) || (val == 0x40)) { - dev->ram_dl = 0; + case 6: /* RAM Access End */ + /* TriGem Delhi-III BIOS writes undocumented value 0x40 instead of 0x00. */ + if ((val == 0x00) || (val == 0x40)) { + dev->ram_dl = 0; - /* Update PnP state and resource data. */ - cs423x_pnp_enable(dev, 1, 0); - } - break; + /* Update PnP state and resource data. */ + cs423x_pnp_enable(dev, 1, 0); + } + break; - case 7: /* Global Status */ - return; + case 7: /* Global Status */ + return; } dev->regs[reg] = val; } - static void cs423x_slam_write(uint16_t addr, uint8_t val, void *priv) { cs423x_t *dev = (cs423x_t *) priv; - uint8_t idx; + uint8_t idx; switch (dev->slam_state) { - case CRYSTAL_SLAM_NONE: - /* Not in SLAM: read and compare Crystal key. */ - if (val == slam_init_key[dev->key_pos]) { - dev->key_pos++; - /* Was the key successfully written? */ - if (!dev->key_pos) { - /* Discard any pending logical device configuration, just to be safe. */ - if (dev->slam_config) { - free(dev->slam_config); - dev->slam_config = NULL; - } + case CRYSTAL_SLAM_NONE: + /* Not in SLAM: read and compare Crystal key. */ + if (val == slam_init_key[dev->key_pos]) { + dev->key_pos++; + /* Was the key successfully written? */ + if (!dev->key_pos) { + /* Discard any pending logical device configuration, just to be safe. */ + if (dev->slam_config) { + free(dev->slam_config); + dev->slam_config = NULL; + } - /* Enter SLAM. */ - dev->slam_state = CRYSTAL_SLAM_INDEX; - } - } else { - dev->key_pos = 0; - } - break; + /* Enter SLAM. */ + dev->slam_state = CRYSTAL_SLAM_INDEX; + } + } else { + dev->key_pos = 0; + } + break; - case CRYSTAL_SLAM_INDEX: - /* Intercept the Activate Audio Device command. */ - if (val == 0x79) { - /* Apply the last logical device's configuration. */ - if (dev->slam_config) { - cs423x_pnp_config_changed(dev->slam_ld, dev->slam_config, dev); - free(dev->slam_config); - dev->slam_config = NULL; - } + case CRYSTAL_SLAM_INDEX: + /* Intercept the Activate Audio Device command. */ + if (val == 0x79) { + /* Apply the last logical device's configuration. */ + if (dev->slam_config) { + cs423x_pnp_config_changed(dev->slam_ld, dev->slam_config, dev); + free(dev->slam_config); + dev->slam_config = NULL; + } - /* Exit out of SLAM. */ - dev->slam_state = CRYSTAL_SLAM_NONE; - break; - } + /* Exit out of SLAM. */ + dev->slam_state = CRYSTAL_SLAM_NONE; + break; + } - /* Write register index. */ - dev->slam_reg = val; - dev->slam_state = CRYSTAL_SLAM_BYTE1; - break; + /* Write register index. */ + dev->slam_reg = val; + dev->slam_state = CRYSTAL_SLAM_BYTE1; + break; - case CRYSTAL_SLAM_BYTE1: - case CRYSTAL_SLAM_BYTE2: - /* Write register value: two bytes for I/O ports, single byte otherwise. */ - switch (dev->slam_reg) { - case 0x06: /* Card Select Number */ - isapnp_set_csn(dev->pnp_card, val); - break; + case CRYSTAL_SLAM_BYTE1: + case CRYSTAL_SLAM_BYTE2: + /* Write register value: two bytes for I/O ports, single byte otherwise. */ + switch (dev->slam_reg) { + case 0x06: /* Card Select Number */ + isapnp_set_csn(dev->pnp_card, val); + break; - case 0x15: /* Logical Device ID */ - /* Apply the previous logical device's configuration, and reuse its config structure. */ - if (dev->slam_config) - cs423x_pnp_config_changed(dev->slam_ld, dev->slam_config, dev); - else - dev->slam_config = (isapnp_device_config_t *) malloc(sizeof(isapnp_device_config_t)); + case 0x15: /* Logical Device ID */ + /* Apply the previous logical device's configuration, and reuse its config structure. */ + if (dev->slam_config) + cs423x_pnp_config_changed(dev->slam_ld, dev->slam_config, dev); + else + dev->slam_config = (isapnp_device_config_t *) malloc(sizeof(isapnp_device_config_t)); - /* Start new logical device. */ - memset(dev->slam_config, 0, sizeof(isapnp_device_config_t)); - dev->slam_ld = val; - break; + /* Start new logical device. */ + memset(dev->slam_config, 0, sizeof(isapnp_device_config_t)); + dev->slam_ld = val; + break; - case 0x47: /* I/O Port Base Address 0 */ - case 0x48: /* I/O Port Base Address 1 */ - case 0x42: /* I/O Port Base Address 2 */ - idx = (dev->slam_reg == 0x42) ? 2 : (dev->slam_reg - 0x47); - if (dev->slam_state == CRYSTAL_SLAM_BYTE1) { - /* Set high byte, or ignore it if no logical device is selected. */ - if (dev->slam_config) - dev->slam_config->io[idx].base = val << 8; + case 0x47: /* I/O Port Base Address 0 */ + case 0x48: /* I/O Port Base Address 1 */ + case 0x42: /* I/O Port Base Address 2 */ + idx = (dev->slam_reg == 0x42) ? 2 : (dev->slam_reg - 0x47); + if (dev->slam_state == CRYSTAL_SLAM_BYTE1) { + /* Set high byte, or ignore it if no logical device is selected. */ + if (dev->slam_config) + dev->slam_config->io[idx].base = val << 8; - /* Prepare for the second (low byte) write. */ - dev->slam_state = CRYSTAL_SLAM_BYTE2; - return; - } else if (dev->slam_config) { - /* Set low byte, or ignore it if no logical device is selected. */ - dev->slam_config->io[idx].base |= val; - } - break; + /* Prepare for the second (low byte) write. */ + dev->slam_state = CRYSTAL_SLAM_BYTE2; + return; + } else if (dev->slam_config) { + /* Set low byte, or ignore it if no logical device is selected. */ + dev->slam_config->io[idx].base |= val; + } + break; - case 0x22: /* Interrupt Select 0 */ - case 0x27: /* Interrupt Select 1 */ - /* Stop if no logical device is selected. */ - if (!dev->slam_config) - break; + case 0x22: /* Interrupt Select 0 */ + case 0x27: /* Interrupt Select 1 */ + /* Stop if no logical device is selected. */ + if (!dev->slam_config) + break; - /* Set IRQ value. */ - idx = (dev->slam_reg == 0x22) ? 0 : 1; - dev->slam_config->irq[idx].irq = val & 15; - break; + /* Set IRQ value. */ + idx = (dev->slam_reg == 0x22) ? 0 : 1; + dev->slam_config->irq[idx].irq = val & 15; + break; - case 0x2a: /* DMA Select 0 */ - case 0x25: /* DMA Select 1 */ - /* Stop if no logical device is selected. */ - if (!dev->slam_config) - break; + case 0x2a: /* DMA Select 0 */ + case 0x25: /* DMA Select 1 */ + /* Stop if no logical device is selected. */ + if (!dev->slam_config) + break; - /* Set DMA value. */ - idx = (dev->slam_reg == 0x2a) ? 0 : 1; - dev->slam_config->dma[idx].dma = val & 7; - break; + /* Set DMA value. */ + idx = (dev->slam_reg == 0x2a) ? 0 : 1; + dev->slam_config->dma[idx].dma = val & 7; + break; - case 0x33: /* Activate Device */ - /* Stop if no logical device is selected. */ - if (!dev->slam_config) - break; + case 0x33: /* Activate Device */ + /* Stop if no logical device is selected. */ + if (!dev->slam_config) + break; - /* Activate or deactivate the device. */ - dev->slam_config->activate = val & 0x01; - break; - } + /* Activate or deactivate the device. */ + dev->slam_config->activate = val & 0x01; + break; + } - /* Prepare for the next register, unless a two-byte read returns above. */ - dev->slam_state = CRYSTAL_SLAM_INDEX; - break; + /* Prepare for the next register, unless a two-byte read returns above. */ + dev->slam_state = CRYSTAL_SLAM_INDEX; + break; } } - static void cs423x_slam_enable(cs423x_t *dev, uint8_t enable) { /* Disable SLAM. */ if (dev->slam_enable) { - dev->slam_state = CRYSTAL_SLAM_NONE; - dev->slam_enable = 0; - io_removehandler(0x279, 1, NULL, NULL, NULL, cs423x_slam_write, NULL, NULL, dev); + dev->slam_state = CRYSTAL_SLAM_NONE; + dev->slam_enable = 0; + io_removehandler(0x279, 1, NULL, NULL, NULL, cs423x_slam_write, NULL, NULL, dev); } /* Enable SLAM if the CKD bit is not set. */ if (enable && !(dev->ram_data[0x4002] & 0x10)) { - dev->slam_enable = 1; - io_sethandler(0x279, 1, NULL, NULL, NULL, cs423x_slam_write, NULL, NULL, dev); + dev->slam_enable = 1; + io_sethandler(0x279, 1, NULL, NULL, NULL, cs423x_slam_write, NULL, NULL, dev); } } - static void cs423x_ctxswitch_write(uint16_t addr, uint8_t val, void *priv) { - cs423x_t *dev = (cs423x_t *) priv; - uint8_t ctx = (dev->regs[7] & 0x80), - enable_opl = (dev->ad1848.xregs[4] & 0x10) && !(dev->indirect_regs[2] & 0x85); + cs423x_t *dev = (cs423x_t *) priv; + uint8_t ctx = (dev->regs[7] & 0x80), + enable_opl = (dev->ad1848.xregs[4] & 0x10) && !(dev->indirect_regs[2] & 0x85); /* Check if a context switch (WSS=1 <-> SBPro=0) occurred through the address being written. */ if ((dev->regs[7] & 0x80) ? ((addr & 0xfff0) == dev->sb_base) : ((addr & 0xfffc) == dev->wss_base)) { - /* Flip context bit. */ - dev->regs[7] ^= 0x80; - ctx ^= 0x80; + /* Flip context bit. */ + dev->regs[7] ^= 0x80; + ctx ^= 0x80; - /* Update CD audio filter. - FIXME: not thread-safe: filter function TOCTTOU in sound_cd_thread! */ - sound_set_cd_audio_filter(NULL, NULL); - if (ctx) /* WSS */ - sound_set_cd_audio_filter(ad1848_filter_cd_audio, &dev->ad1848); - else /* SBPro */ - sound_set_cd_audio_filter(sbpro_filter_cd_audio, dev->sb); + /* Update CD audio filter. + FIXME: not thread-safe: filter function TOCTTOU in sound_cd_thread! */ + sound_set_cd_audio_filter(NULL, NULL); + if (ctx) /* WSS */ + sound_set_cd_audio_filter(ad1848_filter_cd_audio, &dev->ad1848); + else /* SBPro */ + sound_set_cd_audio_filter(sbpro_filter_cd_audio, dev->sb); - /* Fire a context switch interrupt if enabled. */ - if ((dev->regs[0] & 0x20) && (dev->ad1848.irq > 0)) { - dev->regs[7] |= 0x40; /* set interrupt flag */ - picint(1 << dev->ad1848.irq); /* control device shares IRQ with WSS and SBPro */ - } + /* Fire a context switch interrupt if enabled. */ + if ((dev->regs[0] & 0x20) && (dev->ad1848.irq > 0)) { + dev->regs[7] |= 0x40; /* set interrupt flag */ + picint(1 << dev->ad1848.irq); /* control device shares IRQ with WSS and SBPro */ + } } /* Update OPL ownership and state regardless of context switch, to trap writes to other registers which may disable the OPL. */ dev->sb->opl_enabled = !ctx && enable_opl; - dev->opl_wss = ctx && enable_opl; + dev->opl_wss = ctx && enable_opl; } - static void cs423x_get_buffer(int32_t *buffer, int len, void *priv) { cs423x_t *dev = (cs423x_t *) priv; - int c, opl_wss = dev->opl_wss; + int c, opl_wss = dev->opl_wss; /* Output audio from the WSS codec, and also the OPL if we're in charge of it. */ ad1848_update(&dev->ad1848); if (opl_wss) - opl3_update(&dev->sb->opl); + opl3_update(&dev->sb->opl); /* Don't output anything if the analog section is powered down. */ if (!(dev->indirect_regs[2] & 0xa4)) { - for (c = 0; c < len * 2; c += 2) { - if (opl_wss) { - buffer[c] += (dev->sb->opl.buffer[c] * dev->ad1848.fm_vol_l) >> 16; - buffer[c + 1] += (dev->sb->opl.buffer[c + 1] * dev->ad1848.fm_vol_r) >> 16; - } + for (c = 0; c < len * 2; c += 2) { + if (opl_wss) { + buffer[c] += (dev->sb->opl.buffer[c] * dev->ad1848.fm_vol_l) >> 16; + buffer[c + 1] += (dev->sb->opl.buffer[c + 1] * dev->ad1848.fm_vol_r) >> 16; + } - buffer[c] += dev->ad1848.buffer[c] / 2; - buffer[c + 1] += dev->ad1848.buffer[c + 1] / 2; - } + buffer[c] += dev->ad1848.buffer[c] / 2; + buffer[c + 1] += dev->ad1848.buffer[c + 1] / 2; + } } dev->ad1848.pos = 0; if (opl_wss) - dev->sb->opl.pos = 0; + dev->sb->opl.pos = 0; } - static void cs423x_pnp_enable(cs423x_t *dev, uint8_t update_rom, uint8_t update_hwconfig) { if (dev->pnp_card) { - /* Update PnP resource data if requested. */ - if (update_rom) - isapnp_update_card_rom(dev->pnp_card, &dev->ram_data[dev->pnp_offset], 384); + /* Update PnP resource data if requested. */ + if (update_rom) + isapnp_update_card_rom(dev->pnp_card, &dev->ram_data[dev->pnp_offset], 384); - /* Disable PnP key if the PKD bit is set, or if it was disabled by command 0x55. */ - /* But wait! The TriGem Delhi-III BIOS sends command 0x55, and its behavior doesn't - line up with real hardware (still listed in the POST summary and seen by software). - Disable the PnP key disabling mechanism until someone figures something out. */ - //isapnp_enable_card(dev->pnp_card, ((dev->ram_data[0x4002] & 0x20) || !dev->pnp_enable) ? ISAPNP_CARD_NO_KEY : ISAPNP_CARD_ENABLE); - if ((dev->ram_data[0x4002] & 0x20) || !dev->pnp_enable) - pclog("CS423x: Attempted to disable PnP key\n"); + /* Disable PnP key if the PKD bit is set, or if it was disabled by command 0x55. */ + /* But wait! The TriGem Delhi-III BIOS sends command 0x55, and its behavior doesn't + line up with real hardware (still listed in the POST summary and seen by software). + Disable the PnP key disabling mechanism until someone figures something out. */ + // isapnp_enable_card(dev->pnp_card, ((dev->ram_data[0x4002] & 0x20) || !dev->pnp_enable) ? ISAPNP_CARD_NO_KEY : ISAPNP_CARD_ENABLE); + if ((dev->ram_data[0x4002] & 0x20) || !dev->pnp_enable) + pclog("CS423x: Attempted to disable PnP key\n"); } /* Update some register bits based on the config data in RAM if requested. */ if (update_hwconfig) { - /* Update WTEN. */ - if (dev->ram_data[0x4003] & 0x08) { - dev->indirect_regs[8] |= 0x08; - dev->ad1848.wten = 1; - } else { - dev->indirect_regs[8] &= ~0x08; - dev->ad1848.wten = 0; - } + /* Update WTEN. */ + if (dev->ram_data[0x4003] & 0x08) { + dev->indirect_regs[8] |= 0x08; + dev->ad1848.wten = 1; + } else { + dev->indirect_regs[8] &= ~0x08; + dev->ad1848.wten = 0; + } - /* Update SPS. */ - if (dev->type != CRYSTAL_CS4235) { - if (dev->ram_data[0x4003] & 0x04) - dev->indirect_regs[8] |= 0x04; - else - dev->indirect_regs[8] &= ~0x04; - } + /* Update SPS. */ + if (dev->type != CRYSTAL_CS4235) { + if (dev->ram_data[0x4003] & 0x04) + dev->indirect_regs[8] |= 0x04; + else + dev->indirect_regs[8] &= ~0x04; + } - /* Update IFM. */ - if (dev->ram_data[0x4003] & 0x80) - dev->ad1848.xregs[4] |= 0x10; - else - dev->ad1848.xregs[4] &= ~0x10; + /* Update IFM. */ + if (dev->ram_data[0x4003] & 0x80) + dev->ad1848.xregs[4] |= 0x10; + else + dev->ad1848.xregs[4] &= ~0x10; - /* Inform WSS codec of the changes. */ - ad1848_updatevolmask(&dev->ad1848); + /* Inform WSS codec of the changes. */ + ad1848_updatevolmask(&dev->ad1848); } } - static void cs423x_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) { cs423x_t *dev = (cs423x_t *) priv; switch (ld) { - case 0: /* WSS, OPL3 and SBPro */ - if (dev->wss_base) { - io_removehandler(dev->wss_base, 4, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &dev->ad1848); - io_removehandler(dev->wss_base, 4, NULL, NULL, NULL, cs423x_ctxswitch_write, NULL, NULL, dev); - dev->wss_base = 0; - } + case 0: /* WSS, OPL3 and SBPro */ + if (dev->wss_base) { + io_removehandler(dev->wss_base, 4, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &dev->ad1848); + io_removehandler(dev->wss_base, 4, NULL, NULL, NULL, cs423x_ctxswitch_write, NULL, NULL, dev); + dev->wss_base = 0; + } - if (dev->opl_base) { - io_removehandler(dev->opl_base, 4, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &dev->sb->opl); - dev->opl_base = 0; - } + if (dev->opl_base) { + io_removehandler(dev->opl_base, 4, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &dev->sb->opl); + dev->opl_base = 0; + } - if (dev->sb_base) { - sb_dsp_setaddr(&dev->sb->dsp, 0); - io_removehandler(dev->sb_base, 4, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &dev->sb->opl); - io_removehandler(dev->sb_base + 8, 2, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &dev->sb->opl); - io_removehandler(dev->sb_base + 4, 2, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, dev->sb); - io_removehandler(dev->sb_base, 16, NULL, NULL, NULL, cs423x_ctxswitch_write, NULL, NULL, dev); - dev->sb_base = 0; - } + if (dev->sb_base) { + sb_dsp_setaddr(&dev->sb->dsp, 0); + io_removehandler(dev->sb_base, 4, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &dev->sb->opl); + io_removehandler(dev->sb_base + 8, 2, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &dev->sb->opl); + io_removehandler(dev->sb_base + 4, 2, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, dev->sb); + io_removehandler(dev->sb_base, 16, NULL, NULL, NULL, cs423x_ctxswitch_write, NULL, NULL, dev); + dev->sb_base = 0; + } - ad1848_setirq(&dev->ad1848, 0); - sb_dsp_setirq(&dev->sb->dsp, 0); + ad1848_setirq(&dev->ad1848, 0); + sb_dsp_setirq(&dev->sb->dsp, 0); - ad1848_setdma(&dev->ad1848, 0); - sb_dsp_setdma8(&dev->sb->dsp, 0); + ad1848_setdma(&dev->ad1848, 0); + sb_dsp_setdma8(&dev->sb->dsp, 0); - if (config->activate) { - if (config->io[0].base != ISAPNP_IO_DISABLED) { - dev->wss_base = config->io[0].base; - io_sethandler(dev->wss_base, 4, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &dev->ad1848); - io_sethandler(dev->wss_base, 4, NULL, NULL, NULL, cs423x_ctxswitch_write, NULL, NULL, dev); - } + if (config->activate) { + if (config->io[0].base != ISAPNP_IO_DISABLED) { + dev->wss_base = config->io[0].base; + io_sethandler(dev->wss_base, 4, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &dev->ad1848); + io_sethandler(dev->wss_base, 4, NULL, NULL, NULL, cs423x_ctxswitch_write, NULL, NULL, dev); + } - if (config->io[1].base != ISAPNP_IO_DISABLED) { - dev->opl_base = config->io[1].base; - io_sethandler(dev->opl_base, 4, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &dev->sb->opl); - } + if (config->io[1].base != ISAPNP_IO_DISABLED) { + dev->opl_base = config->io[1].base; + io_sethandler(dev->opl_base, 4, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &dev->sb->opl); + } - if (config->io[2].base != ISAPNP_IO_DISABLED) { - dev->sb_base = config->io[2].base; - sb_dsp_setaddr(&dev->sb->dsp, dev->sb_base); - io_sethandler(dev->sb_base, 4, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &dev->sb->opl); - io_sethandler(dev->sb_base + 8, 2, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &dev->sb->opl); - io_sethandler(dev->sb_base + 4, 2, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, dev->sb); - io_sethandler(dev->sb_base, 16, NULL, NULL, NULL, cs423x_ctxswitch_write, NULL, NULL, dev); - } + if (config->io[2].base != ISAPNP_IO_DISABLED) { + dev->sb_base = config->io[2].base; + sb_dsp_setaddr(&dev->sb->dsp, dev->sb_base); + io_sethandler(dev->sb_base, 4, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &dev->sb->opl); + io_sethandler(dev->sb_base + 8, 2, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &dev->sb->opl); + io_sethandler(dev->sb_base + 4, 2, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, dev->sb); + io_sethandler(dev->sb_base, 16, NULL, NULL, NULL, cs423x_ctxswitch_write, NULL, NULL, dev); + } - if (config->irq[0].irq != ISAPNP_IRQ_DISABLED) { - ad1848_setirq(&dev->ad1848, config->irq[0].irq); - sb_dsp_setirq(&dev->sb->dsp, config->irq[0].irq); - } + if (config->irq[0].irq != ISAPNP_IRQ_DISABLED) { + ad1848_setirq(&dev->ad1848, config->irq[0].irq); + sb_dsp_setirq(&dev->sb->dsp, config->irq[0].irq); + } - if (config->dma[0].dma != ISAPNP_DMA_DISABLED) { - ad1848_setdma(&dev->ad1848, config->dma[0].dma); - sb_dsp_setdma8(&dev->sb->dsp, config->dma[0].dma); - } - } - break; + if (config->dma[0].dma != ISAPNP_DMA_DISABLED) { + ad1848_setdma(&dev->ad1848, config->dma[0].dma); + sb_dsp_setdma8(&dev->sb->dsp, config->dma[0].dma); + } + } + break; - case 1: /* Game Port */ - if (dev->gameport) - gameport_remap(dev->gameport, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0); - break; + case 1: /* Game Port */ + if (dev->gameport) + gameport_remap(dev->gameport, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0); + break; - case 2: /* Control Registers */ - if (dev->ctrl_base) { - io_removehandler(dev->ctrl_base, 8, cs423x_read, NULL, NULL, cs423x_write, NULL, NULL, dev); - dev->ctrl_base = 0; - } + case 2: /* Control Registers */ + if (dev->ctrl_base) { + io_removehandler(dev->ctrl_base, 8, cs423x_read, NULL, NULL, cs423x_write, NULL, NULL, dev); + dev->ctrl_base = 0; + } - if (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) { - dev->ctrl_base = config->io[0].base; - io_sethandler(dev->ctrl_base, 8, cs423x_read, NULL, NULL, cs423x_write, NULL, NULL, dev); - } + if (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) { + dev->ctrl_base = config->io[0].base; + io_sethandler(dev->ctrl_base, 8, cs423x_read, NULL, NULL, cs423x_write, NULL, NULL, dev); + } - break; + break; - case 3: /* MPU-401 */ - mpu401_change_addr(dev->sb->mpu, 0); - mpu401_setirq(dev->sb->mpu, 0); + case 3: /* MPU-401 */ + mpu401_change_addr(dev->sb->mpu, 0); + mpu401_setirq(dev->sb->mpu, 0); - if (config->activate) { - if (config->io[0].base != ISAPNP_IO_DISABLED) - mpu401_change_addr(dev->sb->mpu, config->io[0].base); + if (config->activate) { + if (config->io[0].base != ISAPNP_IO_DISABLED) + mpu401_change_addr(dev->sb->mpu, config->io[0].base); - if (config->irq[0].irq != ISAPNP_IRQ_DISABLED) - mpu401_setirq(dev->sb->mpu, config->irq[0].irq); - } + if (config->irq[0].irq != ISAPNP_IRQ_DISABLED) + mpu401_setirq(dev->sb->mpu, config->irq[0].irq); + } - break; + break; } } - static void cs423x_reset(void *priv) { @@ -697,11 +685,11 @@ cs423x_reset(void *priv) memset(dev->ram_data, 0, sizeof(dev->ram_data)); if (dev->eeprom) { - /* Load EEPROM data to RAM. */ - memcpy(&dev->ram_data[0x4000], &dev->eeprom_data[4], MIN(384, ((dev->eeprom_data[2] << 8) | dev->eeprom_data[3]) - 4)); + /* Load EEPROM data to RAM. */ + memcpy(&dev->ram_data[0x4000], &dev->eeprom_data[4], MIN(384, ((dev->eeprom_data[2] << 8) | dev->eeprom_data[3]) - 4)); - /* Save EEPROM contents to file. */ - cs423x_nvram(dev, 1); + /* Save EEPROM contents to file. */ + cs423x_nvram(dev, 1); } /* Reset registers. */ @@ -710,7 +698,7 @@ cs423x_reset(void *priv) memset(dev->indirect_regs, 0, sizeof(dev->indirect_regs)); dev->indirect_regs[1] = dev->type; if (dev->type == CRYSTAL_CS4238B) - dev->indirect_regs[2] = 0x20; + dev->indirect_regs[2] = 0x20; /* Reset WSS codec. */ ad1848_init(&dev->ad1848, dev->ad1848_type); @@ -719,13 +707,12 @@ cs423x_reset(void *priv) dev->pnp_enable = 1; cs423x_pnp_enable(dev, 1, 1); if (dev->pnp_card && dev->sb) - isapnp_reset_card(dev->pnp_card); + isapnp_reset_card(dev->pnp_card); /* Reset SLAM. */ cs423x_slam_enable(dev, 1); } - static void * cs423x_init(const device_t *info) { @@ -735,58 +722,58 @@ cs423x_init(const device_t *info) /* Initialize model-specific data. */ dev->type = info->local & 0xff; switch (dev->type) { - case CRYSTAL_CS4235: - case CRYSTAL_CS4236B: - case CRYSTAL_CS4237B: - case CRYSTAL_CS4238B: - /* Same WSS codec and EEPROM structure. */ - dev->ad1848_type = AD1848_TYPE_CS4236; - dev->pnp_offset = 0x4013; + case CRYSTAL_CS4235: + case CRYSTAL_CS4236B: + case CRYSTAL_CS4237B: + case CRYSTAL_CS4238B: + /* Same WSS codec and EEPROM structure. */ + dev->ad1848_type = AD1848_TYPE_CS4236; + dev->pnp_offset = 0x4013; - /* Different Chip Version and ID registers, which shouldn't be reset by ad1848_init */ - dev->ad1848.xregs[25] = dev->type; + /* Different Chip Version and ID registers, which shouldn't be reset by ad1848_init */ + dev->ad1848.xregs[25] = dev->type; - if (!(info->local & CRYSTAL_NOEEPROM)) { - /* Load EEPROM contents from template. */ - memcpy(dev->eeprom_data, cs4236b_eeprom, sizeof(cs4236b_eeprom)); + if (!(info->local & CRYSTAL_NOEEPROM)) { + /* Load EEPROM contents from template. */ + memcpy(dev->eeprom_data, cs4236b_eeprom, sizeof(cs4236b_eeprom)); - /* Set content size. */ - dev->eeprom_data[2] = sizeof(cs4236b_eeprom) >> 8; - dev->eeprom_data[3] = sizeof(cs4236b_eeprom) & 0xff; + /* Set content size. */ + dev->eeprom_data[2] = sizeof(cs4236b_eeprom) >> 8; + dev->eeprom_data[3] = sizeof(cs4236b_eeprom) & 0xff; - /* Set PnP card ID and EEPROM file name. */ - switch (dev->type) { - case CRYSTAL_CS4235: - dev->eeprom_data[8] = 0x05; - dev->eeprom_data[16] = 0x08; - dev->eeprom_data[26] = 0x25; - dev->nvr_path = "cs4235.nvr"; - break; + /* Set PnP card ID and EEPROM file name. */ + switch (dev->type) { + case CRYSTAL_CS4235: + dev->eeprom_data[8] = 0x05; + dev->eeprom_data[16] = 0x08; + dev->eeprom_data[26] = 0x25; + dev->nvr_path = "cs4235.nvr"; + break; - case CRYSTAL_CS4236B: - dev->nvr_path = "cs4236b.nvr"; - break; + case CRYSTAL_CS4236B: + dev->nvr_path = "cs4236b.nvr"; + break; - case CRYSTAL_CS4237B: - dev->eeprom_data[26] = 0x37; - dev->nvr_path = "cs4237b.nvr"; - break; + case CRYSTAL_CS4237B: + dev->eeprom_data[26] = 0x37; + dev->nvr_path = "cs4237b.nvr"; + break; - case CRYSTAL_CS4238B: - dev->eeprom_data[26] = 0x38; - dev->nvr_path = "cs4238b.nvr"; - break; - } + case CRYSTAL_CS4238B: + dev->eeprom_data[26] = 0x38; + dev->nvr_path = "cs4238b.nvr"; + break; + } - /* Load EEPROM contents from file if present. */ - cs423x_nvram(dev, 0); - } + /* Load EEPROM contents from file if present. */ + cs423x_nvram(dev, 0); + } - /* Initialize game port. The '7B and '8B game port only responds to 6 I/O ports; the remaining - 2 ports are reserved on those chips, and probably connected to the Digital Assist feature. */ - dev->gameport = gameport_add(((dev->type == CRYSTAL_CS4235) || (dev->type == CRYSTAL_CS4236B)) ? &gameport_pnp_device : &gameport_pnp_6io_device); + /* Initialize game port. The '7B and '8B game port only responds to 6 I/O ports; the remaining + 2 ports are reserved on those chips, and probably connected to the Digital Assist feature. */ + dev->gameport = gameport_add(((dev->type == CRYSTAL_CS4235) || (dev->type == CRYSTAL_CS4236B)) ? &gameport_pnp_device : &gameport_pnp_6io_device); - break; + break; } /* Initialize I2C bus for the EEPROM. */ @@ -794,7 +781,7 @@ cs423x_init(const device_t *info) /* Initialize I2C EEPROM if the contents are valid. */ if ((dev->eeprom_data[0] == 0x55) && (dev->eeprom_data[1] == 0xbb)) - dev->eeprom = i2c_eeprom_init(i2c_gpio_get_bus(dev->i2c), 0x50, dev->eeprom_data, sizeof(dev->eeprom_data), 1); + dev->eeprom = i2c_eeprom_init(i2c_gpio_get_bus(dev->i2c), 0x50, dev->eeprom_data, sizeof(dev->eeprom_data), 1); /* Initialize ISAPnP. */ dev->pnp_card = isapnp_add_card(NULL, 0, cs423x_pnp_config_changed, NULL, NULL, NULL, dev); @@ -808,14 +795,13 @@ cs423x_init(const device_t *info) sound_add_handler(cs423x_get_buffer, dev); /* Add Control/RAM backdoor handlers for CS4235. */ - dev->ad1848.cram_priv = dev; - dev->ad1848.cram_read = cs423x_read; + dev->ad1848.cram_priv = dev; + dev->ad1848.cram_read = cs423x_read; dev->ad1848.cram_write = cs423x_write; return dev; } - static void cs423x_close(void *priv) { @@ -823,8 +809,8 @@ cs423x_close(void *priv) /* Save EEPROM contents to file. */ if (dev->eeprom) { - cs423x_nvram(dev, 1); - i2c_eeprom_close(dev->eeprom); + cs423x_nvram(dev, 1); + i2c_eeprom_close(dev->eeprom); } i2c_gpio_close(dev->i2c); @@ -832,7 +818,6 @@ cs423x_close(void *priv) free(dev); } - static void cs423x_speed_changed(void *priv) { @@ -841,66 +826,70 @@ cs423x_speed_changed(void *priv) ad1848_speed_changed(&dev->ad1848); } - -const device_t cs4235_device = -{ +const device_t cs4235_device = { "Crystal CS4235", "cs4235", DEVICE_ISA | DEVICE_AT, CRYSTAL_CS4235, - cs423x_init, cs423x_close, cs423x_reset, + cs423x_init, + cs423x_close, + cs423x_reset, { NULL }, cs423x_speed_changed, NULL, NULL }; -const device_t cs4235_onboard_device = -{ +const device_t cs4235_onboard_device = { "Crystal CS4235 (On-Board)", "cs4235_onboard", DEVICE_ISA | DEVICE_AT, CRYSTAL_CS4235 | CRYSTAL_NOEEPROM, - cs423x_init, cs423x_close, cs423x_reset, + cs423x_init, + cs423x_close, + cs423x_reset, { NULL }, cs423x_speed_changed, NULL, NULL }; -const device_t cs4236b_device = -{ +const device_t cs4236b_device = { "Crystal CS4236B", "cs4236b", DEVICE_ISA | DEVICE_AT, CRYSTAL_CS4236B, - cs423x_init, cs423x_close, cs423x_reset, + cs423x_init, + cs423x_close, + cs423x_reset, { NULL }, cs423x_speed_changed, NULL, NULL }; -const device_t cs4237b_device = -{ +const device_t cs4237b_device = { "Crystal CS4237B", "cs4237b", DEVICE_ISA | DEVICE_AT, CRYSTAL_CS4237B, - cs423x_init, cs423x_close, cs423x_reset, + cs423x_init, + cs423x_close, + cs423x_reset, { NULL }, cs423x_speed_changed, NULL, NULL }; -const device_t cs4238b_device = -{ +const device_t cs4238b_device = { "Crystal CS4238B", "cs4238b", DEVICE_ISA | DEVICE_AT, CRYSTAL_CS4238B, - cs423x_init, cs423x_close, cs423x_reset, + cs423x_init, + cs423x_close, + cs423x_reset, { NULL }, cs423x_speed_changed, NULL, diff --git a/src/sound/snd_emu8k.c b/src/sound/snd_emu8k.c index a83a41cb1..33e80fb31 100644 --- a/src/sound/snd_emu8k.c +++ b/src/sound/snd_emu8k.c @@ -1,120 +1,120 @@ #include #include -#include #include -#include +#include #include +#include #include #define _USE_MATH_DEFINES #include #define HAVE_STDARG_H + #include <86box/86box.h> #include <86box/device.h> #include <86box/io.h> #include <86box/mem.h> #include <86box/rom.h> -#include <86box/timer.h> #include <86box/sound.h> #include <86box/snd_emu8k.h> - +#include <86box/timer.h> #if !defined FILTER_INITIAL && !defined FILTER_MOOG && !defined FILTER_CONSTANT //#define FILTER_INITIAL -#define FILTER_MOOG +# define FILTER_MOOG //#define FILTER_CONSTANT #endif #if !defined RESAMPLER_LINEAR && !defined RESAMPLER_CUBIC //#define RESAMPLER_LINEAR -#define RESAMPLER_CUBIC +# define RESAMPLER_CUBIC #endif //#define EMU8K_DEBUG_REGISTERS -char *PORT_NAMES[][8] = -{ - /* Data 0 ( 0x620/0x622) */ - { "AWE_CPF", - "AWE_PTRX", - "AWE_CVCF", - "AWE_VTFT", - "Unk-620-4", - "Unk-620-5", - "AWE_PSST", - "AWE_CSL", - }, - /* Data 1 0xA20 */ - { "AWE_CCCA", - 0, - /* - "AWE_HWCF4" - "AWE_HWCF5" - "AWE_HWCF6" - "AWE_HWCF7" - "AWE_SMALR" - "AWE_SMARR" - "AWE_SMALW" - "AWE_SMARW" - "AWE_SMLD" - "AWE_SMRD" - "AWE_WC" - "AWE_HWCF1" - "AWE_HWCF2" - "AWE_HWCF3" - */ - 0,//"AWE_INIT1", - 0,//"AWE_INIT3", - "AWE_ENVVOL", - "AWE_DCYSUSV", - "AWE_ENVVAL", - "AWE_DCYSUS", - }, - /* Data 2 0xA22 */ - { "AWE_CCCA", - 0, - 0,//"AWE_INIT2", - 0,//"AWE_INIT4", - "AWE_ATKHLDV", - "AWE_LFO1VAL", - "AWE_ATKHLD", - "AWE_LFO2VAL", - }, - /* Data 3 0xE20 */ - { "AWE_IP", - "AWE_IFATN", - "AWE_PEFE", - "AWE_FMMOD", - "AWE_TREMFRQ", - "AWE_FM2FRQ2", - 0, - 0, - }, +char *PORT_NAMES[][8] = { + /* Data 0 ( 0x620/0x622) */ + { + "AWE_CPF", + "AWE_PTRX", + "AWE_CVCF", + "AWE_VTFT", + "Unk-620-4", + "Unk-620-5", + "AWE_PSST", + "AWE_CSL", + }, + /* Data 1 0xA20 */ + { + "AWE_CCCA", + 0, + /* + "AWE_HWCF4" + "AWE_HWCF5" + "AWE_HWCF6" + "AWE_HWCF7" + "AWE_SMALR" + "AWE_SMARR" + "AWE_SMALW" + "AWE_SMARW" + "AWE_SMLD" + "AWE_SMRD" + "AWE_WC" + "AWE_HWCF1" + "AWE_HWCF2" + "AWE_HWCF3" + */ + 0, //"AWE_INIT1", + 0, //"AWE_INIT3", + "AWE_ENVVOL", + "AWE_DCYSUSV", + "AWE_ENVVAL", + "AWE_DCYSUS", + }, + /* Data 2 0xA22 */ + { + "AWE_CCCA", + 0, + 0, //"AWE_INIT2", + 0, //"AWE_INIT4", + "AWE_ATKHLDV", + "AWE_LFO1VAL", + "AWE_ATKHLD", + "AWE_LFO2VAL", + }, + /* Data 3 0xE20 */ + { + "AWE_IP", + "AWE_IFATN", + "AWE_PEFE", + "AWE_FMMOD", + "AWE_TREMFRQ", + "AWE_FM2FRQ2", + 0, + 0, + }, }; -enum -{ - ENV_STOPPED = 0, - ENV_DELAY = 1, - ENV_ATTACK = 2, - ENV_HOLD = 3, - //ENV_DECAY = 4, - ENV_SUSTAIN = 5, - //ENV_RELEASE = 6, - ENV_RAMP_DOWN = 7, - ENV_RAMP_UP = 8 +enum { + ENV_STOPPED = 0, + ENV_DELAY = 1, + ENV_ATTACK = 2, + ENV_HOLD = 3, + // ENV_DECAY = 4, + ENV_SUSTAIN = 5, + // ENV_RELEASE = 6, + ENV_RAMP_DOWN = 7, + ENV_RAMP_UP = 8 }; - static int random_helper = 0; -int dmareadbit = 0; -int dmawritebit = 0; - +int dmareadbit = 0; +int dmawritebit = 0; /* cubic and linear tables resolution. Note: higher than 10 does not improve the result. */ #define CUBIC_RESOLUTION_LOG 10 -#define CUBIC_RESOLUTION (1<> 15 to move back to +/-1 range). */ static double chortable[65536]; -static const int REV_BUFSIZE_STEP=242; - +static const int REV_BUFSIZE_STEP = 242; /* These lines come from the awe32faq, describing the NRPN control for the initial filter * where it describes a linear increment filter instead of an octave-incremented one. @@ -211,2196 +211,2078 @@ Coeff Low Fc(Hz)Low Q(dB)High Fc(kHz)High Q(dB)DC Attenuation(dB) * 15 100 28 7.0 18 -11.0 * * Attenuation as above, codified in amplitude.*/ -static int32_t filter_atten[16] = -{ +static int32_t filter_atten[16] = { 65536, 61869, 57079, 53269, 49145, 44820, 40877, 34792, 32845, 30653, 28607, - 26392, 24630, 22463, 20487, 18470 + 26392, 24630, 22463, 20487, 18470 }; /*Coefficients for the filters for a defined Q and cutoff.*/ static int32_t filt_coeffs[16][256][3]; -#define READ16_SWITCH(addr, var) switch ((addr) & 2) \ - { \ - case 0: ret = (var) & 0xffff; break; \ - case 2: ret = ((var) >> 16) & 0xffff; break; \ - } +#define READ16_SWITCH(addr, var) \ + switch ((addr) &2) { \ + case 0: \ + ret = (var) &0xffff; \ + break; \ + case 2: \ + ret = ((var) >> 16) & 0xffff; \ + break; \ + } -#define WRITE16_SWITCH(addr, var, val) switch ((addr) & 2) \ - { \ - case 0: var = (var & 0xffff0000) | (val); break; \ - case 2: var = (var & 0x0000ffff) | ((val) << 16); break; \ - } +#define WRITE16_SWITCH(addr, var, val) \ + switch ((addr) &2) { \ + case 0: \ + var = (var & 0xffff0000) | (val); \ + break; \ + case 2: \ + var = (var & 0x0000ffff) | ((val) << 16); \ + break; \ + } #ifdef EMU8K_DEBUG_REGISTERS -uint32_t dw_value = 0; -uint32_t last_read = 0; -uint32_t last_write = 0; +uint32_t dw_value = 0; +uint32_t last_read = 0; +uint32_t last_write = 0; uint32_t rep_count_r = 0; uint32_t rep_count_w = 0; -# define READ16(addr, var) READ16_SWITCH(addr, var) \ - { \ - const char *name=0; \ - switch(addr&0xF02) \ - { \ - case 0x600: case 0x602: \ - name = PORT_NAMES[0][emu8k->cur_reg]; \ - break; \ - case 0xA00: \ - name = PORT_NAMES[1][emu8k->cur_reg]; \ - break; \ - case 0xA02: \ - name = PORT_NAMES[2][emu8k->cur_reg]; \ - break; \ - } \ - if (name == 0) \ - { \ - /*emu8k_log("EMU8K READ %04X-%02X(%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice, emu8k->cur_voice,ret);*/ \ - } \ - else \ - { \ - emu8k_log("EMU8K READ %s(%d) (%d): %04X\n",name, (addr&0x2), emu8k->cur_voice, ret); \ - }\ - } -# define WRITE16(addr, var, val) WRITE16_SWITCH(addr, var, val) \ - { \ - const char *name=0; \ - switch(addr&0xF02) \ - { \ - case 0x600: case 0x602: \ - name = PORT_NAMES[0][emu8k->cur_reg]; \ - break; \ - case 0xA00: \ - name = PORT_NAMES[1][emu8k->cur_reg]; \ - break; \ - case 0xA02: \ - name = PORT_NAMES[2][emu8k->cur_reg]; \ - break; \ - } \ - if (name == 0) \ - { \ - /*emu8k_log("EMU8K WRITE %04X-%02X(%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice,emu8k->cur_voice, val);*/ \ - } \ - else \ - { \ - emu8k_log("EMU8K WRITE %s(%d) (%d): %04X\n",name, (addr&0x2), emu8k->cur_voice,val); \ - }\ - } +# define READ16(addr, var) \ + READ16_SWITCH(addr, var) \ + { \ + const char *name = 0; \ + switch (addr & 0xF02) { \ + case 0x600: \ + case 0x602: \ + name = PORT_NAMES[0][emu8k->cur_reg]; \ + break; \ + case 0xA00: \ + name = PORT_NAMES[1][emu8k->cur_reg]; \ + break; \ + case 0xA02: \ + name = PORT_NAMES[2][emu8k->cur_reg]; \ + break; \ + } \ + if (name == 0) { \ + /*emu8k_log("EMU8K READ %04X-%02X(%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice, emu8k->cur_voice,ret);*/ \ + } else { \ + emu8k_log("EMU8K READ %s(%d) (%d): %04X\n", name, (addr & 0x2), emu8k->cur_voice, ret); \ + } \ + } +# define WRITE16(addr, var, val) \ + WRITE16_SWITCH(addr, var, val) \ + { \ + const char *name = 0; \ + switch (addr & 0xF02) { \ + case 0x600: \ + case 0x602: \ + name = PORT_NAMES[0][emu8k->cur_reg]; \ + break; \ + case 0xA00: \ + name = PORT_NAMES[1][emu8k->cur_reg]; \ + break; \ + case 0xA02: \ + name = PORT_NAMES[2][emu8k->cur_reg]; \ + break; \ + } \ + if (name == 0) { \ + /*emu8k_log("EMU8K WRITE %04X-%02X(%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice,emu8k->cur_voice, val);*/ \ + } else { \ + emu8k_log("EMU8K WRITE %s(%d) (%d): %04X\n", name, (addr & 0x2), emu8k->cur_voice, val); \ + } \ + } #else -# define READ16(addr, var) READ16_SWITCH(addr, var) -# define WRITE16(addr, var, val) WRITE16_SWITCH(addr, var, val) -#endif //EMU8K_DEBUG_REGISTERS - +# define READ16(addr, var) READ16_SWITCH(addr, var) +# define WRITE16(addr, var, val) WRITE16_SWITCH(addr, var, val) +#endif // EMU8K_DEBUG_REGISTERS #ifdef ENABLE_EMU8K_LOG int emu8k_do_log = ENABLE_EMU8K_LOG; - static void emu8k_log(const char *fmt, ...) { va_list ap; if (emu8k_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define emu8k_log(fmt, ...) +# define emu8k_log(fmt, ...) #endif - -static inline int16_t EMU8K_READ(emu8k_t *emu8k, uint32_t addr) +static inline int16_t +EMU8K_READ(emu8k_t *emu8k, uint32_t addr) { - const register emu8k_mem_pointers_t addrmem = {{addr}}; - return emu8k->ram_pointers[addrmem.hb_address][addrmem.lw_address]; + const register emu8k_mem_pointers_t addrmem = { { addr } }; + return emu8k->ram_pointers[addrmem.hb_address][addrmem.lw_address]; } #if NOTUSED -static inline int16_t EMU8K_READ_INTERP_LINEAR(emu8k_t *emu8k, uint32_t int_addr, uint16_t fract) +static inline int16_t +EMU8K_READ_INTERP_LINEAR(emu8k_t *emu8k, uint32_t int_addr, uint16_t fract) { - /* The interpolation in AWE32 used a so-called patented 3-point interpolation - * ( I guess some sort of spline having one point before and one point after). - * Also, it has the consequence that the playback is delayed by one sample. - * I simulate the "one sample later" than the address with addr+1 and addr+2 - * instead of +0 and +1 */ - int16_t dat1 = EMU8K_READ(emu8k, int_addr+1); - int32_t dat2 = EMU8K_READ(emu8k, int_addr+2); - dat1 += ((dat2-(int32_t)dat1)* fract) >> 16; - return dat1; + /* The interpolation in AWE32 used a so-called patented 3-point interpolation + * ( I guess some sort of spline having one point before and one point after). + * Also, it has the consequence that the playback is delayed by one sample. + * I simulate the "one sample later" than the address with addr+1 and addr+2 + * instead of +0 and +1 */ + int16_t dat1 = EMU8K_READ(emu8k, int_addr + 1); + int32_t dat2 = EMU8K_READ(emu8k, int_addr + 2); + dat1 += ((dat2 - (int32_t) dat1) * fract) >> 16; + return dat1; } #endif -static inline int32_t EMU8K_READ_INTERP_CUBIC(emu8k_t *emu8k, uint32_t int_addr, uint16_t fract) +static inline int32_t +EMU8K_READ_INTERP_CUBIC(emu8k_t *emu8k, uint32_t int_addr, uint16_t fract) { - /*Since there are four floats in the table for each fraction, the position is 16byte aligned. */ - fract >>= 16-CUBIC_RESOLUTION_LOG; - fract <<=2; + /*Since there are four floats in the table for each fraction, the position is 16byte aligned. */ + fract >>= 16 - CUBIC_RESOLUTION_LOG; + fract <<= 2; - /* TODO: I still have to verify how this works, but I think that - * the card could use two oscillators (usually 31 and 32) where it would - * be writing the OPL3 output, and to which, chorus and reverb could be applied to get - * those effects for OPL3 sounds.*/ -// if ((addr & EMU8K_FM_MEM_ADDRESS) == EMU8K_FM_MEM_ADDRESS) {} + /* TODO: I still have to verify how this works, but I think that + * the card could use two oscillators (usually 31 and 32) where it would + * be writing the OPL3 output, and to which, chorus and reverb could be applied to get + * those effects for OPL3 sounds.*/ + // if ((addr & EMU8K_FM_MEM_ADDRESS) == EMU8K_FM_MEM_ADDRESS) {} - /* This is cubic interpolation. - * Not the same than 3-point interpolation, but a better approximation than linear - * interpolation. - * Also, it takes into account the "Note that the actual audio location is the point - * 1 word higher than this value due to interpolation offset". - * That's why the pointers are 0, 1, 2, 3 and not -1, 0, 1, 2 */ - int32_t dat2 = EMU8K_READ(emu8k, int_addr+1); - const float *table = &cubic_table[fract]; - const int32_t dat1 = EMU8K_READ(emu8k, int_addr); - const int32_t dat3 = EMU8K_READ(emu8k, int_addr+2); - const int32_t dat4 = EMU8K_READ(emu8k, int_addr+3); - /* Note: I've ended using float for the table values to avoid some cases of integer overflow. */ - dat2 = dat1*table[0] + dat2*table[1] + dat3*table[2] + dat4*table[3]; - return dat2; + /* This is cubic interpolation. + * Not the same than 3-point interpolation, but a better approximation than linear + * interpolation. + * Also, it takes into account the "Note that the actual audio location is the point + * 1 word higher than this value due to interpolation offset". + * That's why the pointers are 0, 1, 2, 3 and not -1, 0, 1, 2 */ + int32_t dat2 = EMU8K_READ(emu8k, int_addr + 1); + const float *table = &cubic_table[fract]; + const int32_t dat1 = EMU8K_READ(emu8k, int_addr); + const int32_t dat3 = EMU8K_READ(emu8k, int_addr + 2); + const int32_t dat4 = EMU8K_READ(emu8k, int_addr + 3); + /* Note: I've ended using float for the table values to avoid some cases of integer overflow. */ + dat2 = dat1 * table[0] + dat2 * table[1] + dat3 * table[2] + dat4 * table[3]; + return dat2; } -static inline void EMU8K_WRITE(emu8k_t *emu8k, uint32_t addr, uint16_t val) +static inline void +EMU8K_WRITE(emu8k_t *emu8k, uint32_t addr, uint16_t val) { - addr &= EMU8K_MEM_ADDRESS_MASK; - if ( !emu8k->ram || addr < EMU8K_RAM_MEM_START || addr >= EMU8K_FM_MEM_ADDRESS ) - return; + addr &= EMU8K_MEM_ADDRESS_MASK; + if (!emu8k->ram || addr < EMU8K_RAM_MEM_START || addr >= EMU8K_FM_MEM_ADDRESS) + return; - /* It looks like if an application writes to a memory part outside of the available - * amount on the card, it wraps, and opencubicplayer uses that to detect the amount - * of memory, as opposed to simply check at the address that it has just tried to write. */ - while (addr >= emu8k->ram_end_addr) - addr -= emu8k->ram_end_addr - EMU8K_RAM_MEM_START; + /* It looks like if an application writes to a memory part outside of the available + * amount on the card, it wraps, and opencubicplayer uses that to detect the amount + * of memory, as opposed to simply check at the address that it has just tried to write. */ + while (addr >= emu8k->ram_end_addr) + addr -= emu8k->ram_end_addr - EMU8K_RAM_MEM_START; - emu8k->ram[addr - EMU8K_RAM_MEM_START] = val; + emu8k->ram[addr - EMU8K_RAM_MEM_START] = val; } -uint16_t emu8k_inw(uint16_t addr, void *p) +uint16_t +emu8k_inw(uint16_t addr, void *p) { - emu8k_t *emu8k = (emu8k_t *)p; - uint16_t ret = 0xffff; + emu8k_t *emu8k = (emu8k_t *) p; + uint16_t ret = 0xffff; #ifdef EMU8K_DEBUG_REGISTERS - if (addr == 0xE22) - { - emu8k_log("EMU8K READ POINTER: %d\n", - ((0x80 | ((random_helper + 1) & 0x1F)) << 8) | (emu8k->cur_reg << 5) | emu8k->cur_voice); + if (addr == 0xE22) { + emu8k_log("EMU8K READ POINTER: %d\n", + ((0x80 | ((random_helper + 1) & 0x1F)) << 8) | (emu8k->cur_reg << 5) | emu8k->cur_voice); + } else if ((addr & 0xF00) == 0x600) { + /* These are automatically reported by READ16 */ + if (rep_count_r > 1) { + emu8k_log("EMU8K ...... for %d times\n", rep_count_r); + rep_count_r = 0; } - else if ((addr&0xF00) == 0x600) - { - /* These are automatically reported by READ16 */ - if (rep_count_r>1) - { - emu8k_log("EMU8K ...... for %d times\n", rep_count_r); - rep_count_r=0; + last_read = 0; + } else if ((addr & 0xF00) == 0xA00 && emu8k->cur_reg == 0) { + /* These are automatically reported by READ16 */ + if (rep_count_r > 1) { + emu8k_log("EMU8K ...... for %d times\n", rep_count_r); + rep_count_r = 0; + } + last_read = 0; + } else if ((addr & 0xF00) == 0xA00 && emu8k->cur_reg == 1) { + uint32_t tmpz = ((addr & 0xF00) << 16) | (emu8k->cur_reg << 5); + if (tmpz != last_read) { + if (rep_count_r > 1) { + emu8k_log("EMU8K ...... for %d times\n", rep_count_r); + rep_count_r = 0; + } + last_read = tmpz; + emu8k_log("EMU8K READ RAM I/O or configuration or clock \n"); + } + // emu8k_log("EMU8K READ %04X-%02X(%d/%d)\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice); + } else if ((addr & 0xF00) == 0xA00 && (emu8k->cur_reg == 2 || emu8k->cur_reg == 3)) { + uint32_t tmpz = ((addr & 0xF00) << 16); + if (tmpz != last_read) { + if (rep_count_r > 1) { + emu8k_log("EMU8K ...... for %d times\n", rep_count_r); + rep_count_r = 0; + } + last_read = tmpz; + emu8k_log("EMU8K READ INIT \n"); + } + // emu8k_log("EMU8K READ %04X-%02X(%d/%d)\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice); + } else { + uint32_t tmpz = (addr << 16) | (emu8k->cur_reg << 5) | emu8k->cur_voice; + if (tmpz != last_read) { + char *name = 0; + uint16_t val = 0xBAAD; + if (addr == 0xA20) { + name = PORT_NAMES[1][emu8k->cur_reg]; + switch (emu8k->cur_reg) { + case 2: + val = emu8k->init1[emu8k->cur_voice]; + break; + case 3: + val = emu8k->init3[emu8k->cur_voice]; + break; + case 4: + val = emu8k->voice[emu8k->cur_voice].envvol; + break; + case 5: + val = emu8k->voice[emu8k->cur_voice].dcysusv; + break; + case 6: + val = emu8k->voice[emu8k->cur_voice].envval; + break; + case 7: + val = emu8k->voice[emu8k->cur_voice].dcysus; + break; } - last_read=0; - } - else if ((addr&0xF00) == 0xA00 && emu8k->cur_reg == 0) - { - /* These are automatically reported by READ16 */ - if (rep_count_r>1) - { - emu8k_log("EMU8K ...... for %d times\n", rep_count_r); - rep_count_r=0; + } else if (addr == 0xA22) { + name = PORT_NAMES[2][emu8k->cur_reg]; + switch (emu8k->cur_reg) { + case 2: + val = emu8k->init2[emu8k->cur_voice]; + break; + case 3: + val = emu8k->init4[emu8k->cur_voice]; + break; + case 4: + val = emu8k->voice[emu8k->cur_voice].atkhldv; + break; + case 5: + val = emu8k->voice[emu8k->cur_voice].lfo1val; + break; + case 6: + val = emu8k->voice[emu8k->cur_voice].atkhld; + break; + case 7: + val = emu8k->voice[emu8k->cur_voice].lfo2val; + break; } - last_read=0; - } - else if ((addr&0xF00) == 0xA00 && emu8k->cur_reg == 1) - { - uint32_t tmpz = ((addr&0xF00) << 16)|(emu8k->cur_reg<<5); - if (tmpz != last_read) - { - if (rep_count_r>1) - { - emu8k_log("EMU8K ...... for %d times\n", rep_count_r); - rep_count_r=0; - } - last_read=tmpz; - emu8k_log("EMU8K READ RAM I/O or configuration or clock \n"); + } else if (addr == 0xE20) { + name = PORT_NAMES[3][emu8k->cur_reg]; + switch (emu8k->cur_reg) { + case 0: + val = emu8k->voice[emu8k->cur_voice].ip; + break; + case 1: + val = emu8k->voice[emu8k->cur_voice].ifatn; + break; + case 2: + val = emu8k->voice[emu8k->cur_voice].pefe; + break; + case 3: + val = emu8k->voice[emu8k->cur_voice].fmmod; + break; + case 4: + val = emu8k->voice[emu8k->cur_voice].tremfrq; + break; + case 5: + val = emu8k->voice[emu8k->cur_voice].fm2frq2; + break; + case 6: + val = 0xffff; + break; + case 7: + val = 0x1c | ((emu8k->id & 0x0002) ? 0xff02 : 0); + break; } - //emu8k_log("EMU8K READ %04X-%02X(%d/%d)\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice); - } - else if ((addr&0xF00) == 0xA00 && (emu8k->cur_reg == 2 || emu8k->cur_reg == 3)) - { - uint32_t tmpz = ((addr&0xF00) << 16); - if (tmpz != last_read) - { - if (rep_count_r>1) - { - emu8k_log("EMU8K ...... for %d times\n", rep_count_r); - rep_count_r=0; - } - last_read=tmpz; - emu8k_log("EMU8K READ INIT \n"); - } - //emu8k_log("EMU8K READ %04X-%02X(%d/%d)\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice); - } - else - { - uint32_t tmpz = (addr << 16)|(emu8k->cur_reg<<5)| emu8k->cur_voice; - if (tmpz != last_read) - { - char* name = 0; - uint16_t val = 0xBAAD; - if (addr == 0xA20) - { - name = PORT_NAMES[1][emu8k->cur_reg]; - switch (emu8k->cur_reg) - { - case 2: val = emu8k->init1[emu8k->cur_voice]; break; - case 3: val = emu8k->init3[emu8k->cur_voice]; break; - case 4: val = emu8k->voice[emu8k->cur_voice].envvol; break; - case 5: val = emu8k->voice[emu8k->cur_voice].dcysusv; break; - case 6: val = emu8k->voice[emu8k->cur_voice].envval; break; - case 7: val = emu8k->voice[emu8k->cur_voice].dcysus; break; - } - } - else if (addr == 0xA22) - { - name = PORT_NAMES[2][emu8k->cur_reg]; - switch (emu8k->cur_reg) - { - case 2: val = emu8k->init2[emu8k->cur_voice]; break; - case 3: val = emu8k->init4[emu8k->cur_voice]; break; - case 4: val = emu8k->voice[emu8k->cur_voice].atkhldv; break; - case 5: val = emu8k->voice[emu8k->cur_voice].lfo1val; break; - case 6: val = emu8k->voice[emu8k->cur_voice].atkhld; break; - case 7: val = emu8k->voice[emu8k->cur_voice].lfo2val; break; - } - } - else if (addr == 0xE20) - { - name = PORT_NAMES[3][emu8k->cur_reg]; - switch (emu8k->cur_reg) - { - case 0: val = emu8k->voice[emu8k->cur_voice].ip; break; - case 1: val = emu8k->voice[emu8k->cur_voice].ifatn; break; - case 2: val = emu8k->voice[emu8k->cur_voice].pefe; break; - case 3: val = emu8k->voice[emu8k->cur_voice].fmmod; break; - case 4: val = emu8k->voice[emu8k->cur_voice].tremfrq; break; - case 5: val = emu8k->voice[emu8k->cur_voice].fm2frq2;break; - case 6: val = 0xffff; break; - case 7: val = 0x1c | ((emu8k->id & 0x0002) ? 0xff02 : 0); break; - } - } - if (rep_count_r>1) - { - emu8k_log("EMU8K ...... for %d times\n", rep_count_r); - } - if (name == 0) - { - emu8k_log("EMU8K READ %04X-%02X(%d/%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice,val); - } - else - { - emu8k_log("EMU8K READ %s (%d): %04X\n",name,emu8k->cur_voice, val); - } + } + if (rep_count_r > 1) { + emu8k_log("EMU8K ...... for %d times\n", rep_count_r); + } + if (name == 0) { + emu8k_log("EMU8K READ %04X-%02X(%d/%d): %04X\n", addr, (emu8k->cur_reg) << 5 | emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice, val); + } else { + emu8k_log("EMU8K READ %s (%d): %04X\n", name, emu8k->cur_voice, val); + } - rep_count_r=0; - last_read=tmpz; - } - rep_count_r++; + rep_count_r = 0; + last_read = tmpz; } + rep_count_r++; + } #endif // EMU8K_DEBUG_REGISTERS + switch (addr & 0xF02) { + case 0x600: + case 0x602: /*Data0. also known as BLASTER+0x400 and EMU+0x000 */ + switch (emu8k->cur_reg) { + case 0: + READ16(addr, emu8k->voice[emu8k->cur_voice].cpf); + return ret; - switch (addr & 0xF02) - { - case 0x600: case 0x602: /*Data0. also known as BLASTER+0x400 and EMU+0x000 */ - switch (emu8k->cur_reg) - { - case 0: - READ16(addr, emu8k->voice[emu8k->cur_voice].cpf); - return ret; + case 1: + READ16(addr, emu8k->voice[emu8k->cur_voice].ptrx); + return ret; - case 1: - READ16(addr, emu8k->voice[emu8k->cur_voice].ptrx); - return ret; + case 2: + READ16(addr, emu8k->voice[emu8k->cur_voice].cvcf); + return ret; - case 2: - READ16(addr, emu8k->voice[emu8k->cur_voice].cvcf); - return ret; + case 3: + READ16(addr, emu8k->voice[emu8k->cur_voice].vtft); + return ret; - case 3: - READ16(addr, emu8k->voice[emu8k->cur_voice].vtft); - return ret; + case 4: + READ16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_4); + return ret; - case 4: - READ16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_4); - return ret; + case 5: + READ16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_5); + return ret; - case 5: - READ16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_5); - return ret; + case 6: + READ16(addr, emu8k->voice[emu8k->cur_voice].psst); + return ret; - case 6: - READ16(addr, emu8k->voice[emu8k->cur_voice].psst); - return ret; + case 7: + READ16(addr, emu8k->voice[emu8k->cur_voice].csl); + return ret; + } + break; - case 7: - READ16(addr, emu8k->voice[emu8k->cur_voice].csl); - return ret; - } - break; + case 0xA00: /*Data1. also known as BLASTER+0x800 and EMU+0x400 */ + switch (emu8k->cur_reg) { + case 0: + READ16(addr, emu8k->voice[emu8k->cur_voice].ccca); + return ret; - case 0xA00: /*Data1. also known as BLASTER+0x800 and EMU+0x400 */ - switch (emu8k->cur_reg) - { - case 0: - READ16(addr, emu8k->voice[emu8k->cur_voice].ccca); - return ret; + case 1: + switch (emu8k->cur_voice) { + case 9: + READ16(addr, emu8k->hwcf4); + return ret; + case 10: + READ16(addr, emu8k->hwcf5); + return ret; + /* Actually, these two might be command words rather than registers, or some LFO position/buffer reset.*/ + case 13: + READ16(addr, emu8k->hwcf6); + return ret; + case 14: + READ16(addr, emu8k->hwcf7); + return ret; - case 1: - switch (emu8k->cur_voice) - { - case 9: - READ16(addr, emu8k->hwcf4); - return ret; - case 10: - READ16(addr, emu8k->hwcf5); - return ret; - /* Actually, these two might be command words rather than registers, or some LFO position/buffer reset.*/ - case 13: - READ16(addr, emu8k->hwcf6); - return ret; - case 14: - READ16(addr, emu8k->hwcf7); - return ret; + case 20: + READ16(addr, emu8k->smalr); + return ret; + case 21: + READ16(addr, emu8k->smarr); + return ret; + case 22: + READ16(addr, emu8k->smalw); + return ret; + case 23: + READ16(addr, emu8k->smarw); + return ret; - case 20: - READ16(addr, emu8k->smalr); - return ret; - case 21: - READ16(addr, emu8k->smarr); - return ret; - case 22: - READ16(addr, emu8k->smalw); - return ret; - case 23: - READ16(addr, emu8k->smarw); - return ret; + case 26: + { + uint16_t val = emu8k->smld_buffer; + emu8k->smld_buffer = EMU8K_READ(emu8k, emu8k->smalr); + emu8k->smalr = (emu8k->smalr + 1) & EMU8K_MEM_ADDRESS_MASK; + return val; + } - case 26: - { - uint16_t val = emu8k->smld_buffer; - emu8k->smld_buffer = EMU8K_READ(emu8k, emu8k->smalr); - emu8k->smalr = (emu8k->smalr+1) & EMU8K_MEM_ADDRESS_MASK; - return val; - } + /*The EMU8000 PGM describes the return values of these registers as 'a VLSI error'*/ + case 29: /*Configuration Word 1*/ + return (emu8k->hwcf1 & 0xfe) | (emu8k->hwcf3 & 0x01); + case 30: /*Configuration Word 2*/ + return ((emu8k->hwcf2 >> 4) & 0x0e) | (emu8k->hwcf1 & 0x01) | ((emu8k->hwcf3 & 0x02) ? 0x10 : 0) | ((emu8k->hwcf3 & 0x04) ? 0x40 : 0) + | ((emu8k->hwcf3 & 0x08) ? 0x20 : 0) | ((emu8k->hwcf3 & 0x10) ? 0x80 : 0); + case 31: /*Configuration Word 3*/ + return emu8k->hwcf2 & 0x1f; + } + break; - /*The EMU8000 PGM describes the return values of these registers as 'a VLSI error'*/ - case 29: /*Configuration Word 1*/ - return (emu8k->hwcf1 & 0xfe) | (emu8k->hwcf3 & 0x01); - case 30: /*Configuration Word 2*/ - return ((emu8k->hwcf2 >> 4) & 0x0e) | (emu8k->hwcf1 & 0x01) | ((emu8k->hwcf3 & 0x02) ? 0x10 : 0) | ((emu8k->hwcf3 & 0x04) ? 0x40 : 0) - | ((emu8k->hwcf3 & 0x08) ? 0x20 : 0) | ((emu8k->hwcf3 & 0x10) ? 0x80 : 0); - case 31: /*Configuration Word 3*/ - return emu8k->hwcf2 & 0x1f; - } - break; + case 2: + return emu8k->init1[emu8k->cur_voice]; - case 2: - return emu8k->init1[emu8k->cur_voice]; + case 3: + return emu8k->init3[emu8k->cur_voice]; - case 3: - return emu8k->init3[emu8k->cur_voice]; + case 4: + return emu8k->voice[emu8k->cur_voice].envvol; - case 4: - return emu8k->voice[emu8k->cur_voice].envvol; + case 5: + return emu8k->voice[emu8k->cur_voice].dcysusv; - case 5: - return emu8k->voice[emu8k->cur_voice].dcysusv; + case 6: + return emu8k->voice[emu8k->cur_voice].envval; - case 6: - return emu8k->voice[emu8k->cur_voice].envval; + case 7: + return emu8k->voice[emu8k->cur_voice].dcysus; + } + break; - case 7: - return emu8k->voice[emu8k->cur_voice].dcysus; - } - break; + case 0xA02: /*Data2. also known as BLASTER+0x802 and EMU+0x402 */ + switch (emu8k->cur_reg) { + case 0: + READ16(addr, emu8k->voice[emu8k->cur_voice].ccca); + return ret; - case 0xA02: /*Data2. also known as BLASTER+0x802 and EMU+0x402 */ - switch (emu8k->cur_reg) - { - case 0: - READ16(addr, emu8k->voice[emu8k->cur_voice].ccca); - return ret; + case 1: + switch (emu8k->cur_voice) { + case 9: + READ16(addr, emu8k->hwcf4); + return ret; + case 10: + READ16(addr, emu8k->hwcf5); + return ret; + /* Actually, these two might be command words rather than registers, or some LFO position/buffer reset. */ + case 13: + READ16(addr, emu8k->hwcf6); + return ret; + case 14: + READ16(addr, emu8k->hwcf7); + return ret; - case 1: - switch (emu8k->cur_voice) - { - case 9: - READ16(addr, emu8k->hwcf4); - return ret; - case 10: - READ16(addr, emu8k->hwcf5); - return ret; - /* Actually, these two might be command words rather than registers, or some LFO position/buffer reset. */ - case 13: - READ16(addr, emu8k->hwcf6); - return ret; - case 14: - READ16(addr, emu8k->hwcf7); - return ret; + /* Simulating empty/full bits by unsetting it once read. */ + case 20: + READ16(addr, emu8k->smalr | dmareadbit); + /* xor with itself to set to zero faster. */ + dmareadbit ^= dmareadbit; + return ret; + case 21: + READ16(addr, emu8k->smarr | dmareadbit); + /* xor with itself to set to zero faster.*/ + dmareadbit ^= dmareadbit; + return ret; + case 22: + READ16(addr, emu8k->smalw | dmawritebit); + /*xor with itself to set to zero faster.*/ + dmawritebit ^= dmawritebit; + return ret; + case 23: + READ16(addr, emu8k->smarw | dmawritebit); + /*xor with itself to set to zero faster.*/ + dmawritebit ^= dmawritebit; + return ret; - /* Simulating empty/full bits by unsetting it once read. */ - case 20: - READ16(addr, emu8k->smalr|dmareadbit); - /* xor with itself to set to zero faster. */ - dmareadbit^=dmareadbit; - return ret; - case 21: - READ16(addr, emu8k->smarr|dmareadbit); - /* xor with itself to set to zero faster.*/ - dmareadbit^=dmareadbit; - return ret; - case 22: - READ16(addr, emu8k->smalw|dmawritebit); - /*xor with itself to set to zero faster.*/ - dmawritebit^=dmawritebit; - return ret; - case 23: - READ16(addr, emu8k->smarw|dmawritebit); - /*xor with itself to set to zero faster.*/ - dmawritebit^=dmawritebit; - return ret; + case 26: + { + uint16_t val = emu8k->smrd_buffer; + emu8k->smrd_buffer = EMU8K_READ(emu8k, emu8k->smarr); + emu8k->smarr = (emu8k->smarr + 1) & EMU8K_MEM_ADDRESS_MASK; + return val; + } + /*TODO: We need to improve the precision of this clock, since + it is used by programs to wait. Not critical, but should help reduce + the amount of calls and wait time */ + case 27: /*Sample Counter ( 44Khz clock) */ + return emu8k->wc; + } + break; - case 26: - { - uint16_t val = emu8k->smrd_buffer; - emu8k->smrd_buffer = EMU8K_READ(emu8k, emu8k->smarr); - emu8k->smarr = (emu8k->smarr+1) & EMU8K_MEM_ADDRESS_MASK; - return val; - } - /*TODO: We need to improve the precision of this clock, since - it is used by programs to wait. Not critical, but should help reduce - the amount of calls and wait time */ - case 27: /*Sample Counter ( 44Khz clock) */ - return emu8k->wc; - } - break; + case 2: + return emu8k->init2[emu8k->cur_voice]; - case 2: - return emu8k->init2[emu8k->cur_voice]; + case 3: + return emu8k->init4[emu8k->cur_voice]; - case 3: - return emu8k->init4[emu8k->cur_voice]; + case 4: + return emu8k->voice[emu8k->cur_voice].atkhldv; - case 4: - return emu8k->voice[emu8k->cur_voice].atkhldv; + case 5: + return emu8k->voice[emu8k->cur_voice].lfo1val; - case 5: - return emu8k->voice[emu8k->cur_voice].lfo1val; + case 6: + return emu8k->voice[emu8k->cur_voice].atkhld; - case 6: - return emu8k->voice[emu8k->cur_voice].atkhld; + case 7: + return emu8k->voice[emu8k->cur_voice].lfo2val; + } + break; - case 7: - return emu8k->voice[emu8k->cur_voice].lfo2val; - } - break; + case 0xE00: /*Data3. also known as BLASTER+0xC00 and EMU+0x800 */ + switch (emu8k->cur_reg) { + case 0: + return emu8k->voice[emu8k->cur_voice].ip; - case 0xE00: /*Data3. also known as BLASTER+0xC00 and EMU+0x800 */ - switch (emu8k->cur_reg) - { - case 0: - return emu8k->voice[emu8k->cur_voice].ip; + case 1: + return emu8k->voice[emu8k->cur_voice].ifatn; - case 1: - return emu8k->voice[emu8k->cur_voice].ifatn; + case 2: + return emu8k->voice[emu8k->cur_voice].pefe; - case 2: - return emu8k->voice[emu8k->cur_voice].pefe; + case 3: + return emu8k->voice[emu8k->cur_voice].fmmod; - case 3: - return emu8k->voice[emu8k->cur_voice].fmmod; + case 4: + return emu8k->voice[emu8k->cur_voice].tremfrq; - case 4: - return emu8k->voice[emu8k->cur_voice].tremfrq; + case 5: + return emu8k->voice[emu8k->cur_voice].fm2frq2; - case 5: - return emu8k->voice[emu8k->cur_voice].fm2frq2; + case 6: + return 0xffff; - case 6: - return 0xffff; + case 7: /*ID?*/ + return 0x1c | ((emu8k->id & 0x0002) ? 0xff02 : 0); + } + break; - case 7: /*ID?*/ - return 0x1c | ((emu8k->id & 0x0002) ? 0xff02 : 0); - } - break; - - case 0xE02: /* Pointer. also known as BLASTER+0xC02 and EMU+0x802 */ - /* LS five bits = channel number, next 3 bits = register number - * and MS 8 bits = VLSI test register. - * Impulse tracker tests the non variability of the LS byte that it has set, and the variability - * of the MS byte to determine that it really is an AWE32. - * cubic player has a similar code, where it waits until value & 0x1000 is nonzero, and then waits again until it changes to zero.*/ - random_helper = (random_helper + 1) & 0x1F; - return ((0x80 | random_helper) << 8) | (emu8k->cur_reg << 5) | emu8k->cur_voice; - } - emu8k_log("EMU8K READ : Unknown register read: %04X-%02X(%d/%d) \n", addr, (emu8k->cur_reg << 5) | emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice); - return 0xffff; + case 0xE02: /* Pointer. also known as BLASTER+0xC02 and EMU+0x802 */ + /* LS five bits = channel number, next 3 bits = register number + * and MS 8 bits = VLSI test register. + * Impulse tracker tests the non variability of the LS byte that it has set, and the variability + * of the MS byte to determine that it really is an AWE32. + * cubic player has a similar code, where it waits until value & 0x1000 is nonzero, and then waits again until it changes to zero.*/ + random_helper = (random_helper + 1) & 0x1F; + return ((0x80 | random_helper) << 8) | (emu8k->cur_reg << 5) | emu8k->cur_voice; + } + emu8k_log("EMU8K READ : Unknown register read: %04X-%02X(%d/%d) \n", addr, (emu8k->cur_reg << 5) | emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice); + return 0xffff; } -void emu8k_outw(uint16_t addr, uint16_t val, void *p) +void +emu8k_outw(uint16_t addr, uint16_t val, void *p) { - emu8k_t *emu8k = (emu8k_t *)p; + emu8k_t *emu8k = (emu8k_t *) p; - /*TODO: I would like to not call this here, but i found it was needed or else cubic player would not finish opening (take a looot more of time than usual). - * Basically, being here means that the audio is generated in the emulation thread, instead of the audio thread.*/ - emu8k_update(emu8k); + /*TODO: I would like to not call this here, but i found it was needed or else cubic player would not finish opening (take a looot more of time than usual). + * Basically, being here means that the audio is generated in the emulation thread, instead of the audio thread.*/ + emu8k_update(emu8k); #ifdef EMU8K_DEBUG_REGISTERS - if (addr == 0xE22) - { - //emu8k_log("EMU8K WRITE POINTER: %d\n", val); + if (addr == 0xE22) { + // emu8k_log("EMU8K WRITE POINTER: %d\n", val); + } else if ((addr & 0xF00) == 0x600) { + /* These are automatically reported by WRITE16 */ + if (rep_count_w > 1) { + emu8k_log("EMU8K ...... for %d times\n", rep_count_w); + rep_count_w = 0; } - else if ((addr&0xF00) == 0x600) - { - /* These are automatically reported by WRITE16 */ - if (rep_count_w>1) - { - emu8k_log("EMU8K ...... for %d times\n", rep_count_w); - rep_count_w=0; - } - last_write=0; + last_write = 0; + } else if ((addr & 0xF00) == 0xA00 && emu8k->cur_reg == 0) { + /* These are automatically reported by WRITE16 */ + if (rep_count_w > 1) { + emu8k_log("EMU8K ...... for %d times\n", rep_count_w); + rep_count_w = 0; } - else if ((addr&0xF00) == 0xA00 && emu8k->cur_reg == 0) - { - /* These are automatically reported by WRITE16 */ - if (rep_count_w>1) - { - emu8k_log("EMU8K ...... for %d times\n", rep_count_w); - rep_count_w=0; - } - last_write=0; + last_write = 0; + } else if ((addr & 0xF00) == 0xA00 && emu8k->cur_reg == 1) { + uint32_t tmpz = ((addr & 0xF00) << 16) | (emu8k->cur_reg << 5); + if (tmpz != last_write) { + if (rep_count_w > 1) { + emu8k_log("EMU8K ...... for %d times\n", rep_count_w); + rep_count_w = 0; + } + last_write = tmpz; + emu8k_log("EMU8K WRITE RAM I/O or configuration \n"); } - else if ((addr&0xF00) == 0xA00 && emu8k->cur_reg == 1) - { - uint32_t tmpz = ((addr&0xF00) << 16)|(emu8k->cur_reg<<5); - if (tmpz != last_write) - { - if (rep_count_w>1) - { - emu8k_log("EMU8K ...... for %d times\n", rep_count_w); - rep_count_w=0; - } - last_write=tmpz; - emu8k_log("EMU8K WRITE RAM I/O or configuration \n"); - } - //emu8k_log("EMU8K WRITE %04X-%02X(%d/%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice,emu8k->cur_reg,emu8k->cur_voice, val); + // emu8k_log("EMU8K WRITE %04X-%02X(%d/%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice,emu8k->cur_reg,emu8k->cur_voice, val); + } else if ((addr & 0xF00) == 0xA00 && (emu8k->cur_reg == 2 || emu8k->cur_reg == 3)) { + uint32_t tmpz = ((addr & 0xF00) << 16); + if (tmpz != last_write) { + if (rep_count_w > 1) { + emu8k_log("EMU8K ...... for %d times\n", rep_count_w); + rep_count_w = 0; + } + last_write = tmpz; + emu8k_log("EMU8K WRITE INIT \n"); } - else if ((addr&0xF00) == 0xA00 && (emu8k->cur_reg == 2 || emu8k->cur_reg == 3)) - { - uint32_t tmpz = ((addr&0xF00) << 16); - if (tmpz != last_write) - { - if (rep_count_w>1) - { - emu8k_log("EMU8K ...... for %d times\n", rep_count_w); - rep_count_w=0; - } - last_write=tmpz; - emu8k_log("EMU8K WRITE INIT \n"); - } - //emu8k_log("EMU8K WRITE %04X-%02X(%d/%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice,emu8k->cur_reg,emu8k->cur_voice, val); + // emu8k_log("EMU8K WRITE %04X-%02X(%d/%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice,emu8k->cur_reg,emu8k->cur_voice, val); + } else if (addr != 0xE22) { + uint32_t tmpz = (addr << 16) | (emu8k->cur_reg << 5) | emu8k->cur_voice; + // if (tmpz != last_write) + if (1) { + char *name = 0; + if (addr == 0xA20) { + name = PORT_NAMES[1][emu8k->cur_reg]; + } else if (addr == 0xA22) { + name = PORT_NAMES[2][emu8k->cur_reg]; + } else if (addr == 0xE20) { + name = PORT_NAMES[3][emu8k->cur_reg]; + } + + if (rep_count_w > 1) { + emu8k_log("EMU8K ...... for %d times\n", rep_count_w); + } + if (name == 0) { + emu8k_log("EMU8K WRITE %04X-%02X(%d/%d): %04X\n", addr, (emu8k->cur_reg) << 5 | emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice, val); + } else { + emu8k_log("EMU8K WRITE %s (%d): %04X\n", name, emu8k->cur_voice, val); + } + + rep_count_w = 0; + last_write = tmpz; } - else if (addr != 0xE22) - { - uint32_t tmpz = (addr << 16)|(emu8k->cur_reg<<5)| emu8k->cur_voice; - //if (tmpz != last_write) - if(1) - { - char* name = 0; - if (addr == 0xA20) - { - name = PORT_NAMES[1][emu8k->cur_reg]; - } - else if (addr == 0xA22) - { - name = PORT_NAMES[2][emu8k->cur_reg]; - } - else if (addr == 0xE20) - { - name = PORT_NAMES[3][emu8k->cur_reg]; - } + rep_count_w++; + } +#endif // EMU8K_DEBUG_REGISTERS - if (rep_count_w>1) - { - emu8k_log("EMU8K ...... for %d times\n", rep_count_w); - } - if (name == 0) - { - emu8k_log("EMU8K WRITE %04X-%02X(%d/%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice,emu8k->cur_reg,emu8k->cur_voice, val); - } - else - { - emu8k_log("EMU8K WRITE %s (%d): %04X\n",name,emu8k->cur_voice, val); - } + switch (addr & 0xF02) { + case 0x600: + case 0x602: /*Data0. also known as BLASTER+0x400 and EMU+0x000 */ + switch (emu8k->cur_reg) { + case 0: + /* The docs says that this value is constantly updating, and it should have no actual effect. Actions should be done over ptrx */ + WRITE16(addr, emu8k->voice[emu8k->cur_voice].cpf, val); + return; - rep_count_w=0; - last_write=tmpz; - } - rep_count_w++; - } -#endif //EMU8K_DEBUG_REGISTERS + case 1: + WRITE16(addr, emu8k->voice[emu8k->cur_voice].ptrx, val); + return; + case 2: + /* The docs says that this value is constantly updating, and it should have no actual effect. Actions should be done over vtft */ + WRITE16(addr, emu8k->voice[emu8k->cur_voice].cvcf, val); + return; - switch (addr & 0xF02) - { - case 0x600: case 0x602: /*Data0. also known as BLASTER+0x400 and EMU+0x000 */ - switch (emu8k->cur_reg) - { - case 0: - /* The docs says that this value is constantly updating, and it should have no actual effect. Actions should be done over ptrx */ - WRITE16(addr, emu8k->voice[emu8k->cur_voice].cpf, val); - return; + case 3: + WRITE16(addr, emu8k->voice[emu8k->cur_voice].vtft, val); + return; - case 1: - WRITE16(addr, emu8k->voice[emu8k->cur_voice].ptrx, val); - return; + case 4: + WRITE16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_4, val); + return; - case 2: - /* The docs says that this value is constantly updating, and it should have no actual effect. Actions should be done over vtft */ - WRITE16(addr, emu8k->voice[emu8k->cur_voice].cvcf, val); - return; + case 5: + WRITE16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_5, val); + return; - case 3: - WRITE16(addr, emu8k->voice[emu8k->cur_voice].vtft, val); - return; - - case 4: - WRITE16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_4, val); - return; - - case 5: - WRITE16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_5, val); - return; - - case 6: - { - emu8k_voice_t *emu_voice = &emu8k->voice[emu8k->cur_voice]; - WRITE16(addr, emu_voice->psst, val); - /* TODO: Should we update only on MSB update, or this could be used as some sort of hack by applications? */ - emu_voice->loop_start.int_address = emu_voice->psst & EMU8K_MEM_ADDRESS_MASK; - if (addr & 2) - { - emu_voice->vol_l = emu_voice->psst_pan; - emu_voice->vol_r = 255 - (emu_voice->psst_pan); - } - } - return; - - case 7: - WRITE16(addr, emu8k->voice[emu8k->cur_voice].csl, val); + case 6: + { + emu8k_voice_t *emu_voice = &emu8k->voice[emu8k->cur_voice]; + WRITE16(addr, emu_voice->psst, val); /* TODO: Should we update only on MSB update, or this could be used as some sort of hack by applications? */ - emu8k->voice[emu8k->cur_voice].loop_end.int_address = emu8k->voice[emu8k->cur_voice].csl & EMU8K_MEM_ADDRESS_MASK; - return; - } - break; - - case 0xA00: /*Data1. also known as BLASTER+0x800 and EMU+0x400 */ - switch (emu8k->cur_reg) - { - case 0: - WRITE16(addr, emu8k->voice[emu8k->cur_voice].ccca, val); - /* TODO: Should we update only on MSB update, or this could be used as some sort of hack by applications? */ - emu8k->voice[emu8k->cur_voice].addr.int_address = emu8k->voice[emu8k->cur_voice].ccca & EMU8K_MEM_ADDRESS_MASK; - return; - - case 1: - switch (emu8k->cur_voice) - { - case 9: - WRITE16(addr, emu8k->hwcf4, val); - return; - case 10: - WRITE16(addr, emu8k->hwcf5, val); - return; - /* Actually, these two might be command words rather than registers, or some LFO position/buffer reset. */ - case 13: - WRITE16(addr, emu8k->hwcf6, val); - return; - case 14: - WRITE16(addr, emu8k->hwcf7, val); - return; - - case 20: - WRITE16(addr, emu8k->smalr, val); - return; - case 21: - WRITE16(addr, emu8k->smarr, val); - return; - case 22: - WRITE16(addr, emu8k->smalw, val); - return; - case 23: - WRITE16(addr, emu8k->smarw, val); - return; - - case 26: - EMU8K_WRITE(emu8k, emu8k->smalw, val); - emu8k->smalw = (emu8k->smalw+1) & EMU8K_MEM_ADDRESS_MASK; - return; - - case 29: - emu8k->hwcf1 = val; - return; - case 30: - emu8k->hwcf2 = val; - return; - case 31: - emu8k->hwcf3 = val; - return; + emu_voice->loop_start.int_address = emu_voice->psst & EMU8K_MEM_ADDRESS_MASK; + if (addr & 2) { + emu_voice->vol_l = emu_voice->psst_pan; + emu_voice->vol_r = 255 - (emu_voice->psst_pan); } - break; + } + return; - case 2: - emu8k->init1[emu8k->cur_voice] = val; - /* Skip if in first/second initialization step */ - if (emu8k->init1[0] != 0x03FF) - { - switch(emu8k->cur_voice) + case 7: + WRITE16(addr, emu8k->voice[emu8k->cur_voice].csl, val); + /* TODO: Should we update only on MSB update, or this could be used as some sort of hack by applications? */ + emu8k->voice[emu8k->cur_voice].loop_end.int_address = emu8k->voice[emu8k->cur_voice].csl & EMU8K_MEM_ADDRESS_MASK; + return; + } + break; + + case 0xA00: /*Data1. also known as BLASTER+0x800 and EMU+0x400 */ + switch (emu8k->cur_reg) { + case 0: + WRITE16(addr, emu8k->voice[emu8k->cur_voice].ccca, val); + /* TODO: Should we update only on MSB update, or this could be used as some sort of hack by applications? */ + emu8k->voice[emu8k->cur_voice].addr.int_address = emu8k->voice[emu8k->cur_voice].ccca & EMU8K_MEM_ADDRESS_MASK; + return; + + case 1: + switch (emu8k->cur_voice) { + case 9: + WRITE16(addr, emu8k->hwcf4, val); + return; + case 10: + WRITE16(addr, emu8k->hwcf5, val); + return; + /* Actually, these two might be command words rather than registers, or some LFO position/buffer reset. */ + case 13: + WRITE16(addr, emu8k->hwcf6, val); + return; + case 14: + WRITE16(addr, emu8k->hwcf7, val); + return; + + case 20: + WRITE16(addr, emu8k->smalr, val); + return; + case 21: + WRITE16(addr, emu8k->smarr, val); + return; + case 22: + WRITE16(addr, emu8k->smalw, val); + return; + case 23: + WRITE16(addr, emu8k->smarw, val); + return; + + case 26: + EMU8K_WRITE(emu8k, emu8k->smalw, val); + emu8k->smalw = (emu8k->smalw + 1) & EMU8K_MEM_ADDRESS_MASK; + return; + + case 29: + emu8k->hwcf1 = val; + return; + case 30: + emu8k->hwcf2 = val; + return; + case 31: + emu8k->hwcf3 = val; + return; + } + break; + + case 2: + emu8k->init1[emu8k->cur_voice] = val; + /* Skip if in first/second initialization step */ + if (emu8k->init1[0] != 0x03FF) { + switch (emu8k->cur_voice) { + case 0x3: + emu8k->reverb_engine.out_mix = val & 0xFF; + break; + case 0x5: { - case 0x3: emu8k->reverb_engine.out_mix = val&0xFF; - break; - case 0x5: - { - int c; - for (c=0;c<8;c++) - { - emu8k->reverb_engine.allpass[c].feedback=(val&0xFF)/((float)0xFF); - } - } - break; - case 0x7: emu8k->reverb_engine.link_return_type = (val==0x8474)? 1:0; - break; - case 0xF: emu8k->reverb_engine.reflections[0].output_gain = ((val&0xF0)>>4)/15.0; - break; - case 0x17: emu8k->reverb_engine.reflections[1].output_gain = ((val&0xF0)>>4)/15.0; - break; - case 0x1F: emu8k->reverb_engine.reflections[2].output_gain = ((val&0xF0)>>4)/15.0; - break; - case 0x9: emu8k->reverb_engine.reflections[0].feedback = (val&0xF)/15.0; - break; - case 0xB: //emu8k->reverb_engine.reflections[0].feedback_r = (val&0xF)/15.0; - break; - case 0x11:emu8k->reverb_engine.reflections[1].feedback = (val&0xF)/15.0; - break; - case 0x13: //emu8k->reverb_engine.reflections[1].feedback_r = (val&0xF)/15.0; - break; - case 0x19: emu8k->reverb_engine.reflections[2].feedback = (val&0xF)/15.0; - break; - case 0x1B: //emu8k->reverb_engine.reflections[2].feedback_r = (val&0xF)/15.0; - break; + int c; + for (c = 0; c < 8; c++) { + emu8k->reverb_engine.allpass[c].feedback = (val & 0xFF) / ((float) 0xFF); + } } + break; + case 0x7: + emu8k->reverb_engine.link_return_type = (val == 0x8474) ? 1 : 0; + break; + case 0xF: + emu8k->reverb_engine.reflections[0].output_gain = ((val & 0xF0) >> 4) / 15.0; + break; + case 0x17: + emu8k->reverb_engine.reflections[1].output_gain = ((val & 0xF0) >> 4) / 15.0; + break; + case 0x1F: + emu8k->reverb_engine.reflections[2].output_gain = ((val & 0xF0) >> 4) / 15.0; + break; + case 0x9: + emu8k->reverb_engine.reflections[0].feedback = (val & 0xF) / 15.0; + break; + case 0xB: // emu8k->reverb_engine.reflections[0].feedback_r = (val&0xF)/15.0; + break; + case 0x11: + emu8k->reverb_engine.reflections[1].feedback = (val & 0xF) / 15.0; + break; + case 0x13: // emu8k->reverb_engine.reflections[1].feedback_r = (val&0xF)/15.0; + break; + case 0x19: + emu8k->reverb_engine.reflections[2].feedback = (val & 0xF) / 15.0; + break; + case 0x1B: // emu8k->reverb_engine.reflections[2].feedback_r = (val&0xF)/15.0; + break; } - return; + } + return; - case 3: - emu8k->init3[emu8k->cur_voice] = val; - /* Skip if in first/second initialization step */ - if (emu8k->init1[0] != 0x03FF) - { - switch(emu8k->cur_voice) - { - case 9: - emu8k->chorus_engine.feedback = (val&0xFF); - break; - case 12: - /* Limiting this to a sane value given our buffer. */ - emu8k->chorus_engine.delay_samples_central = (val&0x1FFF); - break; + case 3: + emu8k->init3[emu8k->cur_voice] = val; + /* Skip if in first/second initialization step */ + if (emu8k->init1[0] != 0x03FF) { + switch (emu8k->cur_voice) { + case 9: + emu8k->chorus_engine.feedback = (val & 0xFF); + break; + case 12: + /* Limiting this to a sane value given our buffer. */ + emu8k->chorus_engine.delay_samples_central = (val & 0x1FFF); + break; - case 1: emu8k->reverb_engine.refl_in_amp = val&0xFF; - break; - case 3: //emu8k->reverb_engine.refl_in_amp_r = val&0xFF; - break; - } + case 1: + emu8k->reverb_engine.refl_in_amp = val & 0xFF; + break; + case 3: // emu8k->reverb_engine.refl_in_amp_r = val&0xFF; + break; } - return; + } + return; - case 4: - emu8k->voice[emu8k->cur_voice].envvol = val; - emu8k->voice[emu8k->cur_voice].vol_envelope.delay_samples = ENVVOL_TO_EMU_SAMPLES(val); - return; + case 4: + emu8k->voice[emu8k->cur_voice].envvol = val; + emu8k->voice[emu8k->cur_voice].vol_envelope.delay_samples = ENVVOL_TO_EMU_SAMPLES(val); + return; - case 5: - { - emu8k->voice[emu8k->cur_voice].dcysusv = val; - emu8k_envelope_t * const vol_env = &emu8k->voice[emu8k->cur_voice].vol_envelope; - int old_on=emu8k->voice[emu8k->cur_voice].env_engine_on; - emu8k->voice[emu8k->cur_voice].env_engine_on = DCYSUSV_GENERATOR_ENGINE_ON(val); + case 5: + { + emu8k->voice[emu8k->cur_voice].dcysusv = val; + emu8k_envelope_t *const vol_env = &emu8k->voice[emu8k->cur_voice].vol_envelope; + int old_on = emu8k->voice[emu8k->cur_voice].env_engine_on; + emu8k->voice[emu8k->cur_voice].env_engine_on = DCYSUSV_GENERATOR_ENGINE_ON(val); - if (emu8k->voice[emu8k->cur_voice].env_engine_on && - old_on != emu8k->voice[emu8k->cur_voice].env_engine_on) - { - if (emu8k->hwcf3 != 0x04) - { - /* This is a hack for some programs like Doom or cubic player 1.7 that don't initialize - the hwcfg and init registers (doom does not init the card at all. only tests the cfg registers) */ - emu8k->hwcf3 = 0x04; - } + if (emu8k->voice[emu8k->cur_voice].env_engine_on && old_on != emu8k->voice[emu8k->cur_voice].env_engine_on) { + if (emu8k->hwcf3 != 0x04) { + /* This is a hack for some programs like Doom or cubic player 1.7 that don't initialize + the hwcfg and init registers (doom does not init the card at all. only tests the cfg registers) */ + emu8k->hwcf3 = 0x04; + } - //reset lfos. - emu8k->voice[emu8k->cur_voice].lfo1_count.addr = 0; - emu8k->voice[emu8k->cur_voice].lfo2_count.addr = 0; - // Trigger envelopes - if (ATKHLDV_TRIGGER(emu8k->voice[emu8k->cur_voice].atkhldv)) - { - vol_env->value_amp_hz = 0; - if (vol_env->delay_samples) - { - vol_env->state = ENV_DELAY; - } - else if (vol_env->attack_amount_amp_hz == 0) - { - vol_env->state = ENV_STOPPED; - } - else - { - vol_env->state = ENV_ATTACK; - /* TODO: Verify if "never attack" means eternal mute, - * or it means skip attack, go to hold". - if (vol_env->attack_amount == 0) - { - vol_env->value = (1 << 21); - vol_env->state = ENV_HOLD; - }*/ - } - } - - if (ATKHLD_TRIGGER(emu8k->voice[emu8k->cur_voice].atkhld)) - { - emu8k_envelope_t* const mod_env = &emu8k->voice[emu8k->cur_voice].mod_envelope; - mod_env->value_amp_hz = 0; - mod_env->value_db_oct = 0; - if (mod_env->delay_samples) - { - mod_env->state = ENV_DELAY; - } - else if (mod_env->attack_amount_amp_hz == 0) - { - mod_env->state = ENV_STOPPED; - } - else - { - mod_env->state = ENV_ATTACK; - /* TODO: Verify if "never attack" means eternal start, - * or it means skip attack, go to hold". - if (mod_env->attack_amount == 0) - { - mod_env->value = (1 << 21); - mod_env->state = ENV_HOLD; - }*/ - } - } + // reset lfos. + emu8k->voice[emu8k->cur_voice].lfo1_count.addr = 0; + emu8k->voice[emu8k->cur_voice].lfo2_count.addr = 0; + // Trigger envelopes + if (ATKHLDV_TRIGGER(emu8k->voice[emu8k->cur_voice].atkhldv)) { + vol_env->value_amp_hz = 0; + if (vol_env->delay_samples) { + vol_env->state = ENV_DELAY; + } else if (vol_env->attack_amount_amp_hz == 0) { + vol_env->state = ENV_STOPPED; + } else { + vol_env->state = ENV_ATTACK; + /* TODO: Verify if "never attack" means eternal mute, + * or it means skip attack, go to hold". + if (vol_env->attack_amount == 0) + { + vol_env->value = (1 << 21); + vol_env->state = ENV_HOLD; + }*/ } + } - - /* Converting the input in dBs to envelope value range. */ - vol_env->sustain_value_db_oct = DCYSUSV_SUS_TO_ENV_RANGE(DCYSUSV_SUSVALUE_GET(val)); - vol_env->ramp_amount_db_oct = env_decay_to_dbs_or_oct[DCYSUSV_DECAYRELEASE_GET(val)]; - if (DCYSUSV_IS_RELEASE(val)) - { - if (vol_env->state == ENV_DELAY || vol_env->state == ENV_ATTACK || vol_env->state == ENV_HOLD) - { - vol_env->value_db_oct = env_vol_amplitude_to_db[vol_env->value_amp_hz >> 5] << 5; - if (vol_env->value_db_oct > (1 << 21)) - vol_env->value_db_oct = 1 << 21; - } - - vol_env->state = (vol_env->value_db_oct >= vol_env->sustain_value_db_oct) ? ENV_RAMP_DOWN : ENV_RAMP_UP; + if (ATKHLD_TRIGGER(emu8k->voice[emu8k->cur_voice].atkhld)) { + emu8k_envelope_t *const mod_env = &emu8k->voice[emu8k->cur_voice].mod_envelope; + mod_env->value_amp_hz = 0; + mod_env->value_db_oct = 0; + if (mod_env->delay_samples) { + mod_env->state = ENV_DELAY; + } else if (mod_env->attack_amount_amp_hz == 0) { + mod_env->state = ENV_STOPPED; + } else { + mod_env->state = ENV_ATTACK; + /* TODO: Verify if "never attack" means eternal start, + * or it means skip attack, go to hold". + if (mod_env->attack_amount == 0) + { + mod_env->value = (1 << 21); + mod_env->state = ENV_HOLD; + }*/ } + } } - return; - case 6: - emu8k->voice[emu8k->cur_voice].envval = val; - emu8k->voice[emu8k->cur_voice].mod_envelope.delay_samples = ENVVAL_TO_EMU_SAMPLES(val); - return; + /* Converting the input in dBs to envelope value range. */ + vol_env->sustain_value_db_oct = DCYSUSV_SUS_TO_ENV_RANGE(DCYSUSV_SUSVALUE_GET(val)); + vol_env->ramp_amount_db_oct = env_decay_to_dbs_or_oct[DCYSUSV_DECAYRELEASE_GET(val)]; + if (DCYSUSV_IS_RELEASE(val)) { + if (vol_env->state == ENV_DELAY || vol_env->state == ENV_ATTACK || vol_env->state == ENV_HOLD) { + vol_env->value_db_oct = env_vol_amplitude_to_db[vol_env->value_amp_hz >> 5] << 5; + if (vol_env->value_db_oct > (1 << 21)) + vol_env->value_db_oct = 1 << 21; + } - case 7: - { - //TODO: Look for a bug on delay (first trigger it works, next trigger it doesn't) - emu8k->voice[emu8k->cur_voice].dcysus = val; - emu8k_envelope_t* const mod_env = &emu8k->voice[emu8k->cur_voice].mod_envelope; - /* Converting the input in octaves to envelope value range. */ - mod_env->sustain_value_db_oct = DCYSUS_SUS_TO_ENV_RANGE(DCYSUS_SUSVALUE_GET(val)); - mod_env->ramp_amount_db_oct = env_decay_to_dbs_or_oct[DCYSUS_DECAYRELEASE_GET(val)]; - if (DCYSUS_IS_RELEASE(val)) - { - if (mod_env->state == ENV_DELAY || mod_env->state == ENV_ATTACK || mod_env->state == ENV_HOLD) - { - mod_env->value_db_oct = env_mod_hertz_to_octave[mod_env->value_amp_hz >> 9] << 9; - if (mod_env->value_db_oct >= (1 << 21)) - mod_env->value_db_oct = (1 << 21)-1; - } - - mod_env->state = (mod_env->value_db_oct >= mod_env->sustain_value_db_oct) ? ENV_RAMP_DOWN : ENV_RAMP_UP; - } + vol_env->state = (vol_env->value_db_oct >= vol_env->sustain_value_db_oct) ? ENV_RAMP_DOWN : ENV_RAMP_UP; } - return; - } - break; + } + return; - case 0xA02: /*Data2. also known as BLASTER+0x802 and EMU+0x402 */ - switch (emu8k->cur_reg) - { - case 0: - { - emu8k_voice_t *emu_voice = &emu8k->voice[emu8k->cur_voice]; - WRITE16(addr, emu_voice->ccca, val); - emu_voice->addr.int_address = emu_voice->ccca & EMU8K_MEM_ADDRESS_MASK; - uint32_t paramq = CCCA_FILTQ_GET(emu_voice->ccca); - emu_voice->filt_att = filter_atten[paramq]; - emu_voice->filterq_idx = paramq; + case 6: + emu8k->voice[emu8k->cur_voice].envval = val; + emu8k->voice[emu8k->cur_voice].mod_envelope.delay_samples = ENVVAL_TO_EMU_SAMPLES(val); + return; + + case 7: + { + // TODO: Look for a bug on delay (first trigger it works, next trigger it doesn't) + emu8k->voice[emu8k->cur_voice].dcysus = val; + emu8k_envelope_t *const mod_env = &emu8k->voice[emu8k->cur_voice].mod_envelope; + /* Converting the input in octaves to envelope value range. */ + mod_env->sustain_value_db_oct = DCYSUS_SUS_TO_ENV_RANGE(DCYSUS_SUSVALUE_GET(val)); + mod_env->ramp_amount_db_oct = env_decay_to_dbs_or_oct[DCYSUS_DECAYRELEASE_GET(val)]; + if (DCYSUS_IS_RELEASE(val)) { + if (mod_env->state == ENV_DELAY || mod_env->state == ENV_ATTACK || mod_env->state == ENV_HOLD) { + mod_env->value_db_oct = env_mod_hertz_to_octave[mod_env->value_amp_hz >> 9] << 9; + if (mod_env->value_db_oct >= (1 << 21)) + mod_env->value_db_oct = (1 << 21) - 1; + } + + mod_env->state = (mod_env->value_db_oct >= mod_env->sustain_value_db_oct) ? ENV_RAMP_DOWN : ENV_RAMP_UP; } - return; + } + return; + } + break; - case 1: - switch (emu8k->cur_voice) - { - case 9: - WRITE16(addr, emu8k->hwcf4, val); - /* Skip if in first/second initialization step */ - if (emu8k->init1[0] != 0x03FF) - { - /*(1/256th of a 44Khz sample) */ - /* clip the value to a reasonable value given our buffer */ - int32_t tmp = emu8k->hwcf4&0x1FFFFF; - emu8k->chorus_engine.delay_offset_samples_right = ((double)tmp)/256.0; - } - return; - case 10: - WRITE16(addr, emu8k->hwcf5, val); - /* Skip if in first/second initialization step */ - if (emu8k->init1[0] != 0x03FF) - { - /* The scale of this value is unknown. I've taken it as milliHz. - * Another interpretation could be periods. (and so, Hz = 1/period)*/ - double osc_speed = emu8k->hwcf5;//*1.316; -#if 1 // milliHz - /*milliHz to lfotable samples.*/ - osc_speed *= 65.536/44100.0; -#elif 0 //periods - /* 44.1Khz ticks to lfotable samples.*/ - osc_speed = 65.536/osc_speed; + case 0xA02: /*Data2. also known as BLASTER+0x802 and EMU+0x402 */ + switch (emu8k->cur_reg) { + case 0: + { + emu8k_voice_t *emu_voice = &emu8k->voice[emu8k->cur_voice]; + WRITE16(addr, emu_voice->ccca, val); + emu_voice->addr.int_address = emu_voice->ccca & EMU8K_MEM_ADDRESS_MASK; + uint32_t paramq = CCCA_FILTQ_GET(emu_voice->ccca); + emu_voice->filt_att = filter_atten[paramq]; + emu_voice->filterq_idx = paramq; + } + return; + + case 1: + switch (emu8k->cur_voice) { + case 9: + WRITE16(addr, emu8k->hwcf4, val); + /* Skip if in first/second initialization step */ + if (emu8k->init1[0] != 0x03FF) { + /*(1/256th of a 44Khz sample) */ + /* clip the value to a reasonable value given our buffer */ + int32_t tmp = emu8k->hwcf4 & 0x1FFFFF; + emu8k->chorus_engine.delay_offset_samples_right = ((double) tmp) / 256.0; + } + return; + case 10: + WRITE16(addr, emu8k->hwcf5, val); + /* Skip if in first/second initialization step */ + if (emu8k->init1[0] != 0x03FF) { + /* The scale of this value is unknown. I've taken it as milliHz. + * Another interpretation could be periods. (and so, Hz = 1/period)*/ + double osc_speed = emu8k->hwcf5; //*1.316; +#if 1 // milliHz + /*milliHz to lfotable samples.*/ + osc_speed *= 65.536 / 44100.0; +#elif 0 // periods + /* 44.1Khz ticks to lfotable samples.*/ + osc_speed = 65.536 / osc_speed; #endif - /*left shift 32bits for 32.32 fixed.point*/ - osc_speed *= 65536.0*65536.0; - emu8k->chorus_engine.lfo_inc.addr = (uint64_t)osc_speed; + /*left shift 32bits for 32.32 fixed.point*/ + osc_speed *= 65536.0 * 65536.0; + emu8k->chorus_engine.lfo_inc.addr = (uint64_t) osc_speed; + } + return; + /* Actually, these two might be command words rather than registers, or some LFO position/buffer reset.*/ + case 13: + WRITE16(addr, emu8k->hwcf6, val); + return; + case 14: + WRITE16(addr, emu8k->hwcf7, val); + return; + + case 20: /*Top 8 bits are for Empty (MT) bit or non-addressable.*/ + WRITE16(addr, emu8k->smalr, val & 0xFF); + dmareadbit = 0x8000; + return; + case 21: /*Top 8 bits are for Empty (MT) bit or non-addressable.*/ + WRITE16(addr, emu8k->smarr, val & 0xFF); + dmareadbit = 0x8000; + return; + case 22: /*Top 8 bits are for full bit or non-addressable.*/ + WRITE16(addr, emu8k->smalw, val & 0xFF); + return; + case 23: /*Top 8 bits are for full bit or non-addressable.*/ + WRITE16(addr, emu8k->smarw, val & 0xFF); + return; + + case 26: + dmawritebit = 0x8000; + EMU8K_WRITE(emu8k, emu8k->smarw, val); + emu8k->smarw++; + return; + } + break; + + case 2: + emu8k->init2[emu8k->cur_voice] = val; + /* Skip if in first/second initialization step */ + if (emu8k->init1[0] != 0x03FF) { + switch (emu8k->cur_voice) { + case 0x14: + { + int multip = ((val & 0xF00) >> 8) + 18; + emu8k->reverb_engine.reflections[5].bufsize = multip * REV_BUFSIZE_STEP; + emu8k->reverb_engine.tailL.bufsize = (multip + 1) * REV_BUFSIZE_STEP; + if (emu8k->reverb_engine.link_return_type == 0) { + emu8k->reverb_engine.tailR.bufsize = (multip + 1) * REV_BUFSIZE_STEP; + } } - return; - /* Actually, these two might be command words rather than registers, or some LFO position/buffer reset.*/ - case 13: - WRITE16(addr, emu8k->hwcf6, val); - return; - case 14: - WRITE16(addr, emu8k->hwcf7, val); - return; + break; + case 0x16: + if (emu8k->reverb_engine.link_return_type == 1) { + int multip = ((val & 0xF00) >> 8) + 18; + emu8k->reverb_engine.tailR.bufsize = (multip + 1) * REV_BUFSIZE_STEP; + } + break; + case 0x7: + emu8k->reverb_engine.reflections[3].output_gain = ((val & 0xF0) >> 4) / 15.0; + break; + case 0xf: + emu8k->reverb_engine.reflections[4].output_gain = ((val & 0xF0) >> 4) / 15.0; + break; + case 0x17: + emu8k->reverb_engine.reflections[5].output_gain = ((val & 0xF0) >> 4) / 15.0; + break; + case 0x1d: + { + int c; + for (c = 0; c < 6; c++) { + emu8k->reverb_engine.reflections[c].damp1 = (val & 0xFF) / 255.0; + emu8k->reverb_engine.reflections[c].damp2 = (0xFF - (val & 0xFF)) / 255.0; + emu8k->reverb_engine.reflections[c].filterstore = 0; + } + emu8k->reverb_engine.damper.damp1 = (val & 0xFF) / 255.0; + emu8k->reverb_engine.damper.damp2 = (0xFF - (val & 0xFF)) / 255.0; + emu8k->reverb_engine.damper.filterstore = 0; + } + break; + case 0x1f: /* filter r */ + break; + case 0x1: + emu8k->reverb_engine.reflections[3].feedback = (val & 0xF) / 15.0; + break; + case 0x3: // emu8k->reverb_engine.reflections[3].feedback_r = (val&0xF)/15.0; + break; + case 0x9: + emu8k->reverb_engine.reflections[4].feedback = (val & 0xF) / 15.0; + break; + case 0xb: // emu8k->reverb_engine.reflections[4].feedback_r = (val&0xF)/15.0; + break; + case 0x11: + emu8k->reverb_engine.reflections[5].feedback = (val & 0xF) / 15.0; + break; + case 0x13: // emu8k->reverb_engine.reflections[5].feedback_r = (val&0xF)/15.0; + break; + } + } + return; - case 20: /*Top 8 bits are for Empty (MT) bit or non-addressable.*/ - WRITE16(addr, emu8k->smalr, val&0xFF); - dmareadbit=0x8000; - return; - case 21: /*Top 8 bits are for Empty (MT) bit or non-addressable.*/ - WRITE16(addr, emu8k->smarr, val&0xFF); - dmareadbit=0x8000; - return; - case 22: /*Top 8 bits are for full bit or non-addressable.*/ - WRITE16(addr, emu8k->smalw, val&0xFF); - return; - case 23: /*Top 8 bits are for full bit or non-addressable.*/ - WRITE16(addr, emu8k->smarw, val&0xFF); - return; + case 3: + emu8k->init4[emu8k->cur_voice] = val; + /* Skip if in first/second initialization step */ + if (emu8k->init1[0] != 0x03FF) { + switch (emu8k->cur_voice) { + case 0x3: + { + int32_t samples = ((val & 0xFF) * emu8k->chorus_engine.delay_samples_central) >> 8; + emu8k->chorus_engine.lfodepth_multip = samples; + } + break; - case 26: - dmawritebit=0x8000; - EMU8K_WRITE(emu8k, emu8k->smarw, val); - emu8k->smarw++; - return; + case 0x1F: + emu8k->reverb_engine.link_return_amp = val & 0xFF; + break; + } + } + return; + + case 4: + { + emu8k->voice[emu8k->cur_voice].atkhldv = val; + emu8k_envelope_t *const vol_env = &emu8k->voice[emu8k->cur_voice].vol_envelope; + vol_env->attack_samples = env_attack_to_samples[ATKHLDV_ATTACK(val)]; + if (vol_env->attack_samples == 0) { + vol_env->attack_amount_amp_hz = 0; + } else { + /* Linear amplitude increase each sample. */ + vol_env->attack_amount_amp_hz = (1 << 21) / vol_env->attack_samples; + } + vol_env->hold_samples = ATKHLDV_HOLD_TO_EMU_SAMPLES(val); + if (ATKHLDV_TRIGGER(val) && emu8k->voice[emu8k->cur_voice].env_engine_on) { + /*TODO: I assume that "envelope trigger" is the same as new note + * (since changing the IP can be done when modulating pitch too) */ + emu8k->voice[emu8k->cur_voice].lfo1_count.addr = 0; + emu8k->voice[emu8k->cur_voice].lfo2_count.addr = 0; + + vol_env->value_amp_hz = 0; + if (vol_env->delay_samples) { + vol_env->state = ENV_DELAY; + } else if (vol_env->attack_amount_amp_hz == 0) { + vol_env->state = ENV_STOPPED; + } else { + vol_env->state = ENV_ATTACK; + /* TODO: Verify if "never attack" means eternal mute, + * or it means skip attack, go to hold". + if (vol_env->attack_amount == 0) + { + vol_env->value = (1 << 21); + vol_env->state = ENV_HOLD; + }*/ + } + } + } + return; + + case 5: + emu8k->voice[emu8k->cur_voice].lfo1val = val; + /* TODO: verify if this is set once, or set every time. */ + emu8k->voice[emu8k->cur_voice].lfo1_delay_samples = LFOxVAL_TO_EMU_SAMPLES(val); + return; + + case 6: + { + emu8k->voice[emu8k->cur_voice].atkhld = val; + emu8k_envelope_t *const mod_env = &emu8k->voice[emu8k->cur_voice].mod_envelope; + mod_env->attack_samples = env_attack_to_samples[ATKHLD_ATTACK(val)]; + if (mod_env->attack_samples == 0) { + mod_env->attack_amount_amp_hz = 0; + } else { + /* Linear amplitude increase each sample. */ + mod_env->attack_amount_amp_hz = (1 << 21) / mod_env->attack_samples; + } + mod_env->hold_samples = ATKHLD_HOLD_TO_EMU_SAMPLES(val); + if (ATKHLD_TRIGGER(val) && emu8k->voice[emu8k->cur_voice].env_engine_on) { + mod_env->value_amp_hz = 0; + mod_env->value_db_oct = 0; + if (mod_env->delay_samples) { + mod_env->state = ENV_DELAY; + } else if (mod_env->attack_amount_amp_hz == 0) { + mod_env->state = ENV_STOPPED; + } else { + mod_env->state = ENV_ATTACK; + /* TODO: Verify if "never attack" means eternal start, + * or it means skip attack, go to hold". + if (mod_env->attack_amount == 0) + { + mod_env->value = (1 << 21); + mod_env->state = ENV_HOLD; + }*/ + } + } + } + return; + + case 7: + emu8k->voice[emu8k->cur_voice].lfo2val = val; + emu8k->voice[emu8k->cur_voice].lfo2_delay_samples = LFOxVAL_TO_EMU_SAMPLES(val); + + return; + } + break; + + case 0xE00: /*Data3. also known as BLASTER+0xC00 and EMU+0x800 */ + switch (emu8k->cur_reg) { + case 0: + emu8k->voice[emu8k->cur_voice].ip = val; + emu8k->voice[emu8k->cur_voice].ptrx_pit_target = freqtable[val] >> 18; + return; + + case 1: + { + emu8k_voice_t *const the_voice = &emu8k->voice[emu8k->cur_voice]; + if ((val & 0xFF) == 0 && the_voice->cvcf_curr_volume == 0 && the_voice->vtft_vol_target == 0 + && the_voice->dcysusv == 0x80 && the_voice->ip == 0) { + // Patch to avoid some clicking noises with Impulse tracker or other software that sets + // different values to 0 to set noteoff, but here, 0 means no attenuation = full volume. + return; + } + the_voice->ifatn = val; + the_voice->initial_att = (((int32_t) the_voice->ifatn_attenuation << 21) / 0xFF); + the_voice->vtft_vol_target = attentable[the_voice->ifatn_attenuation]; + + the_voice->initial_filter = (((int32_t) the_voice->ifatn_init_filter << 21) / 0xFF); + if (the_voice->ifatn_init_filter == 0xFF) { + the_voice->vtft_filter_target = 0xFFFF; + } else { + the_voice->vtft_filter_target = the_voice->initial_filter >> 5; + } + } + return; + + case 2: + { + emu8k_voice_t *const the_voice = &emu8k->voice[emu8k->cur_voice]; + the_voice->pefe = val; + + int divider = (the_voice->pefe_modenv_filter_height < 0) ? 0x80 : 0x7F; + the_voice->fixed_modenv_filter_height = ((int32_t) the_voice->pefe_modenv_filter_height) * 0x4000 / divider; + + divider = (the_voice->pefe_modenv_pitch_height < 0) ? 0x80 : 0x7F; + the_voice->fixed_modenv_pitch_height = ((int32_t) the_voice->pefe_modenv_pitch_height) * 0x4000 / divider; + } + return; + + case 3: + { + emu8k_voice_t *const the_voice = &emu8k->voice[emu8k->cur_voice]; + the_voice->fmmod = val; + + int divider = (the_voice->fmmod_lfo1_filt_mod < 0) ? 0x80 : 0x7F; + the_voice->fixed_lfo1_filt_mod = ((int32_t) the_voice->fmmod_lfo1_filt_mod) * 0x4000 / divider; + + divider = (the_voice->fmmod_lfo1_vibrato < 0) ? 0x80 : 0x7F; + the_voice->fixed_lfo1_vibrato = ((int32_t) the_voice->fmmod_lfo1_vibrato) * 0x4000 / divider; + } + return; + + case 4: + { + emu8k_voice_t *const the_voice = &emu8k->voice[emu8k->cur_voice]; + the_voice->tremfrq = val; + the_voice->lfo1_speed = lfofreqtospeed[the_voice->tremfrq_lfo1_freq]; + + int divider = (the_voice->tremfrq_lfo1_tremolo < 0) ? 0x80 : 0x7F; + the_voice->fixed_lfo1_tremolo = ((int32_t) the_voice->tremfrq_lfo1_tremolo) * 0x4000 / divider; + } + return; + + case 5: + { + emu8k_voice_t *const the_voice = &emu8k->voice[emu8k->cur_voice]; + the_voice->fm2frq2 = val; + the_voice->lfo2_speed = lfofreqtospeed[the_voice->fm2frq2_lfo2_freq]; + + int divider = (the_voice->fm2frq2_lfo2_vibrato < 0) ? 0x80 : 0x7F; + the_voice->fixed_lfo2_vibrato = ((int32_t) the_voice->fm2frq2_lfo2_vibrato) * 0x4000 / divider; + } + return; + + case 7: /*ID? I believe that this allows applications to know if the emu is in use by another application */ + emu8k->id = val; + return; + } + break; + + case 0xE02: /* Pointer. also known as BLASTER+0xC02 and EMU+0x802 */ + emu8k->cur_voice = (val & 31); + emu8k->cur_reg = ((val >> 5) & 7); + return; + } + emu8k_log("EMU8K WRITE: Unknown register write: %04X-%02X(%d/%d): %04X \n", addr, (emu8k->cur_reg) << 5 | emu8k->cur_voice, + emu8k->cur_reg, emu8k->cur_voice, val); +} + +uint8_t +emu8k_inb(uint16_t addr, void *p) +{ + /* Reading a single byte is a feature that at least Impulse tracker uses, + * but only on detection code and not for odd addresses.*/ + if (addr & 1) + return emu8k_inw(addr & ~1, p) >> 1; + return emu8k_inw(addr, p) & 0xff; +} + +void +emu8k_outb(uint16_t addr, uint8_t val, void *p) +{ + /* TODO: AWE32 docs says that you cannot write in bytes, but if + * an app were to use this implementation, the content of the LS Byte would be lost.*/ + if (addr & 1) + emu8k_outw(addr & ~1, val << 8, p); + else + emu8k_outw(addr, val, p); +} + +/* TODO: This is not a correct emulation, just a workalike implementation. */ +void +emu8k_work_chorus(int32_t *inbuf, int32_t *outbuf, emu8k_chorus_eng_t *engine, int count) +{ + int pos; + for (pos = 0; pos < count; pos++) { + double lfo_inter1 = chortable[engine->lfo_pos.int_address]; + // double lfo_inter2 = chortable[(engine->lfo_pos.int_address+1)&0xFFFF]; + + double offset_lfo = lfo_inter1; //= lfo_inter1 + ((lfo_inter2-lfo_inter1)*engine->lfo_pos.fract_address/65536.0); + offset_lfo *= engine->lfodepth_multip; + + /* Work left */ + double readdouble = (double) engine->write - (double) engine->delay_samples_central - offset_lfo; + int read = (int32_t) floor(readdouble); + int fraction_part = (readdouble - (double) read) * 65536.0; + int next_value = read + 1; + if (read < 0) { + read += EMU8K_LFOCHORUS_SIZE; + if (next_value < 0) + next_value += EMU8K_LFOCHORUS_SIZE; + } else if (next_value >= EMU8K_LFOCHORUS_SIZE) { + next_value -= EMU8K_LFOCHORUS_SIZE; + if (read >= EMU8K_LFOCHORUS_SIZE) + read -= EMU8K_LFOCHORUS_SIZE; + } + int32_t dat1 = engine->chorus_left_buffer[read]; + int32_t dat2 = engine->chorus_left_buffer[next_value]; + dat1 += ((dat2 - dat1) * fraction_part) >> 16; + + engine->chorus_left_buffer[engine->write] = *inbuf + ((dat1 * engine->feedback) >> 8); + + /* Work right */ + readdouble = (double) engine->write - (double) engine->delay_samples_central - engine->delay_offset_samples_right - offset_lfo; + read = (int32_t) floor(readdouble); + next_value = read + 1; + if (read < 0) { + read += EMU8K_LFOCHORUS_SIZE; + if (next_value < 0) + next_value += EMU8K_LFOCHORUS_SIZE; + } else if (next_value >= EMU8K_LFOCHORUS_SIZE) { + next_value -= EMU8K_LFOCHORUS_SIZE; + if (read >= EMU8K_LFOCHORUS_SIZE) + read -= EMU8K_LFOCHORUS_SIZE; + } + int32_t dat3 = engine->chorus_right_buffer[read]; + int32_t dat4 = engine->chorus_right_buffer[next_value]; + dat3 += ((dat4 - dat3) * fraction_part) >> 16; + + engine->chorus_right_buffer[engine->write] = *inbuf + ((dat3 * engine->feedback) >> 8); + + ++engine->write; + engine->write %= EMU8K_LFOCHORUS_SIZE; + engine->lfo_pos.addr += engine->lfo_inc.addr; + engine->lfo_pos.int_address &= 0xFFFF; + + (*outbuf++) += dat1; + (*outbuf++) += dat3; + inbuf++; + } +} + +int32_t +emu8k_reverb_comb_work(emu8k_reverb_combfilter_t *comb, int32_t in) +{ + + int32_t bufin; + /* get echo */ + int32_t output = comb->reflection[comb->read_pos]; + /* apply lowpass */ + comb->filterstore = (output * comb->damp2) + (comb->filterstore * comb->damp1); + /* appply feedback */ + bufin = in - (comb->filterstore * comb->feedback); + /* store new value in delayed buffer */ + comb->reflection[comb->read_pos] = bufin; + + if (++comb->read_pos >= comb->bufsize) + comb->read_pos = 0; + + return output * comb->output_gain; +} + +int32_t +emu8k_reverb_diffuser_work(emu8k_reverb_combfilter_t *comb, int32_t in) +{ + + int32_t bufout = comb->reflection[comb->read_pos]; + /*diffuse*/ + int32_t bufin = -in + (bufout * comb->feedback); + int32_t output = bufout - (bufin * comb->feedback); + /* store new value in delayed buffer */ + comb->reflection[comb->read_pos] = bufin; + + if (++comb->read_pos >= comb->bufsize) + comb->read_pos = 0; + + return output; +} + +int32_t +emu8k_reverb_tail_work(emu8k_reverb_combfilter_t *comb, emu8k_reverb_combfilter_t *allpasses, int32_t in) +{ + int32_t output = comb->reflection[comb->read_pos]; + /* store new value in delayed buffer */ + comb->reflection[comb->read_pos] = in; + + // output = emu8k_reverb_allpass_work(&allpasses[0],output); + output = emu8k_reverb_diffuser_work(&allpasses[1], output); + output = emu8k_reverb_diffuser_work(&allpasses[2], output); + // output = emu8k_reverb_allpass_work(&allpasses[3],output); + + if (++comb->read_pos >= comb->bufsize) + comb->read_pos = 0; + + return output; +} +int32_t +emu8k_reverb_damper_work(emu8k_reverb_combfilter_t *comb, int32_t in) +{ + /* apply lowpass */ + comb->filterstore = (in * comb->damp2) + (comb->filterstore * comb->damp1); + return comb->filterstore; +} + +/* TODO: This is not a correct emulation, just a workalike implementation. */ +void +emu8k_work_reverb(int32_t *inbuf, int32_t *outbuf, emu8k_reverb_eng_t *engine, int count) +{ + int pos; + if (engine->link_return_type) { + for (pos = 0; pos < count; pos++) { + int32_t dat1, dat2, in, in2; + in = emu8k_reverb_damper_work(&engine->damper, inbuf[pos]); + in2 = (in * engine->refl_in_amp) >> 8; + dat2 = emu8k_reverb_comb_work(&engine->reflections[0], in2); + dat2 += emu8k_reverb_comb_work(&engine->reflections[1], in2); + dat1 = emu8k_reverb_comb_work(&engine->reflections[2], in2); + dat2 += emu8k_reverb_comb_work(&engine->reflections[3], in2); + dat1 += emu8k_reverb_comb_work(&engine->reflections[4], in2); + dat2 += emu8k_reverb_comb_work(&engine->reflections[5], in2); + + dat1 += (emu8k_reverb_tail_work(&engine->tailL, &engine->allpass[0], in + dat1) * engine->link_return_amp) >> 8; + dat2 += (emu8k_reverb_tail_work(&engine->tailR, &engine->allpass[4], in + dat2) * engine->link_return_amp) >> 8; + + (*outbuf++) += (dat1 * engine->out_mix) >> 8; + (*outbuf++) += (dat2 * engine->out_mix) >> 8; + } + } else { + for (pos = 0; pos < count; pos++) { + int32_t dat1, dat2, in, in2; + in = emu8k_reverb_damper_work(&engine->damper, inbuf[pos]); + in2 = (in * engine->refl_in_amp) >> 8; + dat1 = emu8k_reverb_comb_work(&engine->reflections[0], in2); + dat1 += emu8k_reverb_comb_work(&engine->reflections[1], in2); + dat1 += emu8k_reverb_comb_work(&engine->reflections[2], in2); + dat1 += emu8k_reverb_comb_work(&engine->reflections[3], in2); + dat1 += emu8k_reverb_comb_work(&engine->reflections[4], in2); + dat1 += emu8k_reverb_comb_work(&engine->reflections[5], in2); + dat2 = dat1; + + dat1 += (emu8k_reverb_tail_work(&engine->tailL, &engine->allpass[0], in + dat1) * engine->link_return_amp) >> 8; + dat2 += (emu8k_reverb_tail_work(&engine->tailR, &engine->allpass[4], in + dat2) * engine->link_return_amp) >> 8; + + (*outbuf++) += (dat1 * engine->out_mix) >> 8; + (*outbuf++) += (dat2 * engine->out_mix) >> 8; + } + } +} +void +emu8k_work_eq(int32_t *inoutbuf, int count) +{ + // TODO: Work EQ over buf +} + +int32_t +emu8k_vol_slide(emu8k_slide_t *slide, int32_t target) +{ + if (slide->last < target) { + slide->last += 0x400; + if (slide->last > target) + slide->last = target; + } else if (slide->last > target) { + slide->last -= 0x400; + if (slide->last < target) + slide->last = target; + } + return slide->last; +} + +// int32_t old_pitch[32]={0}; +// int32_t old_cut[32]={0}; +// int32_t old_vol[32]={0}; +void +emu8k_update(emu8k_t *emu8k) +{ + int new_pos = (sound_pos_global * 44100) / 48000; + if (emu8k->pos >= new_pos) + return; + + int32_t *buf; + emu8k_voice_t *emu_voice; + int pos; + int c; + + /* Clean the buffers since we will accumulate into them. */ + buf = &emu8k->buffer[emu8k->pos * 2]; + memset(buf, 0, 2 * (new_pos - emu8k->pos) * sizeof(emu8k->buffer[0])); + memset(&emu8k->chorus_in_buffer[emu8k->pos], 0, (new_pos - emu8k->pos) * sizeof(emu8k->chorus_in_buffer[0])); + memset(&emu8k->reverb_in_buffer[emu8k->pos], 0, (new_pos - emu8k->pos) * sizeof(emu8k->reverb_in_buffer[0])); + + /* Voices section */ + for (c = 0; c < 32; c++) { + emu_voice = &emu8k->voice[c]; + buf = &emu8k->buffer[emu8k->pos * 2]; + + for (pos = emu8k->pos; pos < new_pos; pos++) { + int32_t dat; + + if (emu_voice->cvcf_curr_volume) { + /* Waveform oscillator */ +#ifdef RESAMPLER_LINEAR + dat = EMU8K_READ_INTERP_LINEAR(emu8k, emu_voice->addr.int_address, + emu_voice->addr.fract_address); + +#elif defined RESAMPLER_CUBIC + dat = EMU8K_READ_INTERP_CUBIC(emu8k, emu_voice->addr.int_address, + emu_voice->addr.fract_address); +#endif + + /* Filter section */ + if (emu_voice->filterq_idx || emu_voice->cvcf_curr_filt_ctoff != 0xFFFF) { + int cutoff = emu_voice->cvcf_curr_filt_ctoff >> 8; + const int64_t coef0 = filt_coeffs[emu_voice->filterq_idx][cutoff][0]; + const int64_t coef1 = filt_coeffs[emu_voice->filterq_idx][cutoff][1]; + const int64_t coef2 = filt_coeffs[emu_voice->filterq_idx][cutoff][2]; +/* clip at twice the range */ +#define ClipBuffer(buf) (buf < -16777216) ? -16777216 : (buf > 16777216) ? 16777216 \ + : buf + +#ifdef FILTER_INITIAL +# define NOOP(x) (void) x; + NOOP(coef1) + /* Apply expected attenuation. (FILTER_MOOG does it implicitly, but this one doesn't). + * Work in 24bits. */ + dat = (dat * emu_voice->filt_att) >> 8; + + int64_t vhp = ((-emu_voice->filt_buffer[0] * coef2) >> 24) - emu_voice->filt_buffer[1] - dat; + emu_voice->filt_buffer[1] += (emu_voice->filt_buffer[0] * coef0) >> 24; + emu_voice->filt_buffer[0] += (vhp * coef0) >> 24; + dat = (int32_t) (emu_voice->filt_buffer[1] >> 8); + if (dat > 32767) { + dat = 32767; + } else if (dat < -32768) { + dat = -32768; + } + +#elif defined FILTER_MOOG + + /*move to 24bits*/ + dat <<= 8; + + dat -= (coef2 * emu_voice->filt_buffer[4]) >> 24; /*feedback*/ + int64_t t1 = emu_voice->filt_buffer[1]; + emu_voice->filt_buffer[1] = ((dat + emu_voice->filt_buffer[0]) * coef0 - emu_voice->filt_buffer[1] * coef1) >> 24; + emu_voice->filt_buffer[1] = ClipBuffer(emu_voice->filt_buffer[1]); + + int64_t t2 = emu_voice->filt_buffer[2]; + emu_voice->filt_buffer[2] = ((emu_voice->filt_buffer[1] + t1) * coef0 - emu_voice->filt_buffer[2] * coef1) >> 24; + emu_voice->filt_buffer[2] = ClipBuffer(emu_voice->filt_buffer[2]); + + int64_t t3 = emu_voice->filt_buffer[3]; + emu_voice->filt_buffer[3] = ((emu_voice->filt_buffer[2] + t2) * coef0 - emu_voice->filt_buffer[3] * coef1) >> 24; + emu_voice->filt_buffer[3] = ClipBuffer(emu_voice->filt_buffer[3]); + + emu_voice->filt_buffer[4] = ((emu_voice->filt_buffer[3] + t3) * coef0 - emu_voice->filt_buffer[4] * coef1) >> 24; + emu_voice->filt_buffer[4] = ClipBuffer(emu_voice->filt_buffer[4]); + + emu_voice->filt_buffer[0] = ClipBuffer(dat); + + dat = (int32_t) (emu_voice->filt_buffer[4] >> 8); + if (dat > 32767) { + dat = 32767; + } else if (dat < -32768) { + dat = -32768; + } + +#elif defined FILTER_CONSTANT + + /* Apply expected attenuation. (FILTER_MOOG does it implicitly, but this one is constant gain). + * Also stay at 24bits.*/ + dat = (dat * emu_voice->filt_att) >> 8; + + emu_voice->filt_buffer[0] = (coef1 * emu_voice->filt_buffer[0] + + coef0 * (dat + ((coef2 * (emu_voice->filt_buffer[0] - emu_voice->filt_buffer[1])) >> 24))) + >> 24; + emu_voice->filt_buffer[1] = (coef1 * emu_voice->filt_buffer[1] + + coef0 * emu_voice->filt_buffer[0]) + >> 24; + + emu_voice->filt_buffer[0] = ClipBuffer(emu_voice->filt_buffer[0]); + emu_voice->filt_buffer[1] = ClipBuffer(emu_voice->filt_buffer[1]); + + dat = (int32_t) (emu_voice->filt_buffer[1] >> 8); + if (dat > 32767) { + dat = 32767; + } else if (dat < -32768) { + dat = -32768; + } + +#endif + } + if ((emu8k->hwcf3 & 0x04) && !CCCA_DMA_ACTIVE(emu_voice->ccca)) { + /*volume and pan*/ + dat = (dat * emu_voice->cvcf_curr_volume) >> 16; + + (*buf++) += (dat * emu_voice->vol_l) >> 8; + (*buf++) += (dat * emu_voice->vol_r) >> 8; + + /* Effects section */ + if (emu_voice->ptrx_revb_send > 0) { + emu8k->reverb_in_buffer[pos] += (dat * emu_voice->ptrx_revb_send) >> 8; + } + if (emu_voice->csl_chor_send > 0) { + emu8k->chorus_in_buffer[pos] += (dat * emu_voice->csl_chor_send) >> 8; + } + } + } + + if (emu_voice->env_engine_on) { + int32_t attenuation = emu_voice->initial_att; + int32_t filtercut = emu_voice->initial_filter; + int32_t currentpitch = emu_voice->ip; + /* run envelopes */ + emu8k_envelope_t *volenv = &emu_voice->vol_envelope; + switch (volenv->state) { + case ENV_DELAY: + volenv->delay_samples--; + if (volenv->delay_samples <= 0) { + volenv->state = ENV_ATTACK; + volenv->delay_samples = 0; + } + attenuation = 0x1FFFFF; + break; + + case ENV_ATTACK: + /* Attack amount is in linear amplitude */ + volenv->value_amp_hz += volenv->attack_amount_amp_hz; + if (volenv->value_amp_hz >= (1 << 21)) { + volenv->value_amp_hz = 1 << 21; + volenv->value_db_oct = 0; + if (volenv->hold_samples) { + volenv->state = ENV_HOLD; + } else { + /* RAMP_UP since db value is inverted and it is 0 at this point. */ + volenv->state = ENV_RAMP_UP; + } + } + attenuation += env_vol_amplitude_to_db[volenv->value_amp_hz >> 5] << 5; + break; + + case ENV_HOLD: + volenv->hold_samples--; + if (volenv->hold_samples <= 0) { + volenv->state = ENV_RAMP_UP; + } + attenuation += volenv->value_db_oct; + break; + + case ENV_RAMP_DOWN: + /* Decay/release amount is in fraction of dBs and is always positive */ + volenv->value_db_oct -= volenv->ramp_amount_db_oct; + if (volenv->value_db_oct <= volenv->sustain_value_db_oct) { + volenv->value_db_oct = volenv->sustain_value_db_oct; + volenv->state = ENV_SUSTAIN; + } + attenuation += volenv->value_db_oct; + break; + + case ENV_RAMP_UP: + /* Decay/release amount is in fraction of dBs and is always positive */ + volenv->value_db_oct += volenv->ramp_amount_db_oct; + if (volenv->value_db_oct >= volenv->sustain_value_db_oct) { + volenv->value_db_oct = volenv->sustain_value_db_oct; + volenv->state = ENV_SUSTAIN; + } + attenuation += volenv->value_db_oct; + break; + + case ENV_SUSTAIN: + attenuation += volenv->value_db_oct; + break; + + case ENV_STOPPED: + attenuation = 0x1FFFFF; + break; + } + + emu8k_envelope_t *modenv = &emu_voice->mod_envelope; + switch (modenv->state) { + case ENV_DELAY: + modenv->delay_samples--; + if (modenv->delay_samples <= 0) { + modenv->state = ENV_ATTACK; + modenv->delay_samples = 0; } break; - case 2: - emu8k->init2[emu8k->cur_voice] = val; - /* Skip if in first/second initialization step */ - if (emu8k->init1[0] != 0x03FF) - { - switch(emu8k->cur_voice) - { - case 0x14: - { - int multip = ((val&0xF00)>>8)+18; - emu8k->reverb_engine.reflections[5].bufsize = multip*REV_BUFSIZE_STEP; - emu8k->reverb_engine.tailL.bufsize = (multip+1)*REV_BUFSIZE_STEP; - if ( emu8k->reverb_engine.link_return_type == 0) - { - emu8k->reverb_engine.tailR.bufsize = (multip+1)*REV_BUFSIZE_STEP; - } - } - break; - case 0x16: - if ( emu8k->reverb_engine.link_return_type == 1) - { - int multip = ((val&0xF00)>>8)+18; - emu8k->reverb_engine.tailR.bufsize = (multip+1)*REV_BUFSIZE_STEP; - } - break; - case 0x7: emu8k->reverb_engine.reflections[3].output_gain = ((val&0xF0)>>4)/15.0; - break; - case 0xf: emu8k->reverb_engine.reflections[4].output_gain = ((val&0xF0)>>4)/15.0; - break; - case 0x17: emu8k->reverb_engine.reflections[5].output_gain = ((val&0xF0)>>4)/15.0; - break; - case 0x1d: - { - int c; - for (c=0;c<6;c++) - { - emu8k->reverb_engine.reflections[c].damp1=(val&0xFF)/255.0; - emu8k->reverb_engine.reflections[c].damp2=(0xFF-(val&0xFF))/255.0; - emu8k->reverb_engine.reflections[c].filterstore=0; - } - emu8k->reverb_engine.damper.damp1=(val&0xFF)/255.0; - emu8k->reverb_engine.damper.damp2=(0xFF-(val&0xFF))/255.0; - emu8k->reverb_engine.damper.filterstore=0; - } - break; - case 0x1f: /* filter r */ - break; - case 0x1: emu8k->reverb_engine.reflections[3].feedback = (val&0xF)/15.0; - break; - case 0x3: //emu8k->reverb_engine.reflections[3].feedback_r = (val&0xF)/15.0; - break; - case 0x9: emu8k->reverb_engine.reflections[4].feedback = (val&0xF)/15.0; - break; - case 0xb: //emu8k->reverb_engine.reflections[4].feedback_r = (val&0xF)/15.0; - break; - case 0x11: emu8k->reverb_engine.reflections[5].feedback = (val&0xF)/15.0; - break; - case 0x13: //emu8k->reverb_engine.reflections[5].feedback_r = (val&0xF)/15.0; - break; - } + case ENV_ATTACK: + /* Attack amount is in linear amplitude */ + modenv->value_amp_hz += modenv->attack_amount_amp_hz; + modenv->value_db_oct = env_mod_hertz_to_octave[modenv->value_amp_hz >> 5] << 5; + if (modenv->value_amp_hz >= (1 << 21)) { + modenv->value_amp_hz = 1 << 21; + modenv->value_db_oct = 1 << 21; + if (modenv->hold_samples) { + modenv->state = ENV_HOLD; + } else { + modenv->state = ENV_RAMP_DOWN; + } } - return; + break; - case 3: - emu8k->init4[emu8k->cur_voice] = val; - /* Skip if in first/second initialization step */ - if (emu8k->init1[0] != 0x03FF) - { - switch(emu8k->cur_voice) - { - case 0x3: - { - int32_t samples = ((val&0xFF)*emu8k->chorus_engine.delay_samples_central) >> 8; - emu8k->chorus_engine.lfodepth_multip = samples; - - } - break; - - case 0x1F: - emu8k->reverb_engine.link_return_amp = val&0xFF; - break; - } + case ENV_HOLD: + modenv->hold_samples--; + if (modenv->hold_samples <= 0) { + modenv->state = ENV_RAMP_UP; } - return ; + break; - case 4: - { - emu8k->voice[emu8k->cur_voice].atkhldv = val; - emu8k_envelope_t* const vol_env = &emu8k->voice[emu8k->cur_voice].vol_envelope; - vol_env->attack_samples = env_attack_to_samples[ATKHLDV_ATTACK(val)]; - if (vol_env->attack_samples == 0) - { - vol_env->attack_amount_amp_hz = 0; - } - else - { - /* Linear amplitude increase each sample. */ - vol_env->attack_amount_amp_hz = (1<<21) / vol_env->attack_samples; - } - vol_env->hold_samples = ATKHLDV_HOLD_TO_EMU_SAMPLES(val); - if (ATKHLDV_TRIGGER(val) && emu8k->voice[emu8k->cur_voice].env_engine_on) - { - /*TODO: I assume that "envelope trigger" is the same as new note - * (since changing the IP can be done when modulating pitch too) */ - emu8k->voice[emu8k->cur_voice].lfo1_count.addr = 0; - emu8k->voice[emu8k->cur_voice].lfo2_count.addr = 0; - - vol_env->value_amp_hz = 0; - if (vol_env->delay_samples) - { - vol_env->state = ENV_DELAY; - } - else if (vol_env->attack_amount_amp_hz == 0) - { - vol_env->state = ENV_STOPPED; - } - else - { - vol_env->state = ENV_ATTACK; - /* TODO: Verify if "never attack" means eternal mute, - * or it means skip attack, go to hold". - if (vol_env->attack_amount == 0) - { - vol_env->value = (1 << 21); - vol_env->state = ENV_HOLD; - }*/ - } - } + case ENV_RAMP_DOWN: + /* Decay/release amount is in fraction of octave and is always positive */ + modenv->value_db_oct -= modenv->ramp_amount_db_oct; + if (modenv->value_db_oct <= modenv->sustain_value_db_oct) { + modenv->value_db_oct = modenv->sustain_value_db_oct; + modenv->state = ENV_SUSTAIN; } - return; + break; - case 5: - emu8k->voice[emu8k->cur_voice].lfo1val = val; - /* TODO: verify if this is set once, or set every time. */ - emu8k->voice[emu8k->cur_voice].lfo1_delay_samples = LFOxVAL_TO_EMU_SAMPLES(val); - return; - - case 6: - { - emu8k->voice[emu8k->cur_voice].atkhld = val; - emu8k_envelope_t* const mod_env = &emu8k->voice[emu8k->cur_voice].mod_envelope; - mod_env->attack_samples = env_attack_to_samples[ATKHLD_ATTACK(val)]; - if (mod_env->attack_samples == 0) - { - mod_env->attack_amount_amp_hz = 0; - } - else - { - /* Linear amplitude increase each sample. */ - mod_env->attack_amount_amp_hz = (1<<21) / mod_env->attack_samples; - } - mod_env->hold_samples = ATKHLD_HOLD_TO_EMU_SAMPLES(val); - if (ATKHLD_TRIGGER(val) && emu8k->voice[emu8k->cur_voice].env_engine_on) - { - mod_env->value_amp_hz = 0; - mod_env->value_db_oct = 0; - if (mod_env->delay_samples) - { - mod_env->state = ENV_DELAY; - } - else if (mod_env->attack_amount_amp_hz == 0) - { - mod_env->state = ENV_STOPPED; - } - else - { - mod_env->state = ENV_ATTACK; - /* TODO: Verify if "never attack" means eternal start, - * or it means skip attack, go to hold". - if (mod_env->attack_amount == 0) - { - mod_env->value = (1 << 21); - mod_env->state = ENV_HOLD; - }*/ - } - } + case ENV_RAMP_UP: + /* Decay/release amount is in fraction of octave and is always positive */ + modenv->value_db_oct += modenv->ramp_amount_db_oct; + if (modenv->value_db_oct >= modenv->sustain_value_db_oct) { + modenv->value_db_oct = modenv->sustain_value_db_oct; + modenv->state = ENV_SUSTAIN; } - return; - - case 7: - emu8k->voice[emu8k->cur_voice].lfo2val = val; - emu8k->voice[emu8k->cur_voice].lfo2_delay_samples = LFOxVAL_TO_EMU_SAMPLES(val); - - return; + break; } - break; - case 0xE00: /*Data3. also known as BLASTER+0xC00 and EMU+0x800 */ - switch (emu8k->cur_reg) - { - case 0: - emu8k->voice[emu8k->cur_voice].ip = val; - emu8k->voice[emu8k->cur_voice].ptrx_pit_target = freqtable[val] >> 18; - return; - - case 1: - { - emu8k_voice_t * const the_voice = &emu8k->voice[emu8k->cur_voice]; - if ((val&0xFF) == 0 && the_voice->cvcf_curr_volume == 0 && the_voice->vtft_vol_target == 0 - && the_voice->dcysusv == 0x80 && the_voice->ip == 0) - { - // Patch to avoid some clicking noises with Impulse tracker or other software that sets - // different values to 0 to set noteoff, but here, 0 means no attenuation = full volume. - return; - } - the_voice->ifatn = val; - the_voice->initial_att = (((int32_t)the_voice->ifatn_attenuation <<21)/0xFF); - the_voice->vtft_vol_target = attentable[the_voice->ifatn_attenuation]; - - the_voice->initial_filter = (((int32_t)the_voice->ifatn_init_filter <<21)/0xFF); - if (the_voice->ifatn_init_filter==0xFF) - { - the_voice->vtft_filter_target = 0xFFFF; - } - else - { - the_voice->vtft_filter_target = the_voice->initial_filter >> 5; - } - } - return; - - case 2: - { - emu8k_voice_t * const the_voice = &emu8k->voice[emu8k->cur_voice]; - the_voice->pefe = val; - - int divider = (the_voice->pefe_modenv_filter_height < 0) ? 0x80 : 0x7F; - the_voice->fixed_modenv_filter_height = ((int32_t)the_voice->pefe_modenv_filter_height)*0x4000/divider; - - divider = (the_voice->pefe_modenv_pitch_height < 0) ? 0x80 : 0x7F; - the_voice->fixed_modenv_pitch_height = ((int32_t)the_voice->pefe_modenv_pitch_height)*0x4000/divider; - } - return; - - case 3: - { - emu8k_voice_t * const the_voice = &emu8k->voice[emu8k->cur_voice]; - the_voice->fmmod = val; - - int divider = (the_voice->fmmod_lfo1_filt_mod < 0) ? 0x80 : 0x7F; - the_voice->fixed_lfo1_filt_mod = ((int32_t)the_voice->fmmod_lfo1_filt_mod)*0x4000/divider; - - divider = (the_voice->fmmod_lfo1_vibrato < 0) ? 0x80 : 0x7F; - the_voice->fixed_lfo1_vibrato = ((int32_t)the_voice->fmmod_lfo1_vibrato)*0x4000/divider; - } - return; - - case 4: - { - emu8k_voice_t * const the_voice = &emu8k->voice[emu8k->cur_voice]; - the_voice->tremfrq = val; - the_voice->lfo1_speed = lfofreqtospeed[the_voice->tremfrq_lfo1_freq]; - - int divider = (the_voice->tremfrq_lfo1_tremolo < 0) ? 0x80 : 0x7F; - the_voice->fixed_lfo1_tremolo = ((int32_t)the_voice->tremfrq_lfo1_tremolo)*0x4000/divider; - } - return; - - case 5: - { - emu8k_voice_t * const the_voice = &emu8k->voice[emu8k->cur_voice]; - the_voice->fm2frq2 = val; - the_voice->lfo2_speed = lfofreqtospeed[the_voice->fm2frq2_lfo2_freq]; - - int divider = (the_voice->fm2frq2_lfo2_vibrato < 0) ? 0x80 : 0x7F; - the_voice->fixed_lfo2_vibrato = ((int32_t)the_voice->fm2frq2_lfo2_vibrato)*0x4000/divider; - } - return; - - case 7: /*ID? I believe that this allows applications to know if the emu is in use by another application */ - emu8k->id = val; - return; + /* run lfos */ + if (emu_voice->lfo1_delay_samples) { + emu_voice->lfo1_delay_samples--; + } else { + emu_voice->lfo1_count.addr += emu_voice->lfo1_speed; + emu_voice->lfo1_count.int_address &= 0xFFFF; } - break; - - case 0xE02: /* Pointer. also known as BLASTER+0xC02 and EMU+0x802 */ - emu8k->cur_voice = (val & 31); - emu8k->cur_reg = ((val >> 5) & 7); - return; - } - emu8k_log("EMU8K WRITE: Unknown register write: %04X-%02X(%d/%d): %04X \n", addr, (emu8k->cur_reg)<<5|emu8k->cur_voice, - emu8k->cur_reg,emu8k->cur_voice, val); - -} - -uint8_t emu8k_inb(uint16_t addr, void *p) -{ - /* Reading a single byte is a feature that at least Impulse tracker uses, - * but only on detection code and not for odd addresses.*/ - if (addr & 1) - return emu8k_inw(addr & ~1, p) >> 1; - return emu8k_inw(addr, p) & 0xff; -} - -void emu8k_outb(uint16_t addr, uint8_t val, void *p) -{ - /* TODO: AWE32 docs says that you cannot write in bytes, but if - * an app were to use this implementation, the content of the LS Byte would be lost.*/ - if (addr & 1) - emu8k_outw(addr & ~1, val << 8, p); - else - emu8k_outw(addr, val, p); -} - -/* TODO: This is not a correct emulation, just a workalike implementation. */ -void emu8k_work_chorus(int32_t *inbuf, int32_t *outbuf, emu8k_chorus_eng_t *engine, int count) -{ - int pos; - for (pos = 0; pos < count; pos++) - { - double lfo_inter1 = chortable[engine->lfo_pos.int_address]; - // double lfo_inter2 = chortable[(engine->lfo_pos.int_address+1)&0xFFFF]; - - double offset_lfo =lfo_inter1; //= lfo_inter1 + ((lfo_inter2-lfo_inter1)*engine->lfo_pos.fract_address/65536.0); - offset_lfo *= engine->lfodepth_multip; - - /* Work left */ - double readdouble = (double)engine->write - (double)engine->delay_samples_central - offset_lfo; - int read = (int32_t)floor(readdouble); - int fraction_part = (readdouble - (double)read)*65536.0; - int next_value = read + 1; - if(read < 0) - { - read += EMU8K_LFOCHORUS_SIZE; - if(next_value < 0) next_value += EMU8K_LFOCHORUS_SIZE; + if (emu_voice->lfo2_delay_samples) { + emu_voice->lfo2_delay_samples--; + } else { + emu_voice->lfo2_count.addr += emu_voice->lfo2_speed; + emu_voice->lfo2_count.int_address &= 0xFFFF; } - else if(next_value >= EMU8K_LFOCHORUS_SIZE) - { - next_value -= EMU8K_LFOCHORUS_SIZE; - if(read >= EMU8K_LFOCHORUS_SIZE) read -= EMU8K_LFOCHORUS_SIZE; + + if (emu_voice->fixed_modenv_pitch_height) { + /* modenv range 1<<21, pitch height range 1<<14 desired range 0x1000 (+/-one octave) */ + currentpitch += ((modenv->value_db_oct >> 9) * emu_voice->fixed_modenv_pitch_height) >> 14; } - int32_t dat1 = engine->chorus_left_buffer[read]; - int32_t dat2 = engine->chorus_left_buffer[next_value]; - dat1 += ((dat2-dat1)* fraction_part) >> 16; - engine->chorus_left_buffer[engine->write] = *inbuf + ((dat1 * engine->feedback)>>8); - - - /* Work right */ - readdouble = (double)engine->write - (double)engine->delay_samples_central - engine->delay_offset_samples_right - offset_lfo; - read = (int32_t)floor(readdouble); - next_value = read + 1; - if(read < 0) - { - read += EMU8K_LFOCHORUS_SIZE; - if(next_value < 0) next_value += EMU8K_LFOCHORUS_SIZE; + if (emu_voice->fixed_lfo1_vibrato) { + /* table range 1<<15, pitch mod range 1<<14 desired range 0x1000 (+/-one octave) */ + int32_t lfo1_vibrato = (lfotable[emu_voice->lfo1_count.int_address] * emu_voice->fixed_lfo1_vibrato) >> 17; + currentpitch += lfo1_vibrato; } - else if(next_value >= EMU8K_LFOCHORUS_SIZE) - { - next_value -= EMU8K_LFOCHORUS_SIZE; - if(read >= EMU8K_LFOCHORUS_SIZE) read -= EMU8K_LFOCHORUS_SIZE; + if (emu_voice->fixed_lfo2_vibrato) { + /* table range 1<<15, pitch mod range 1<<14 desired range 0x1000 (+/-one octave) */ + int32_t lfo2_vibrato = (lfotable[emu_voice->lfo2_count.int_address] * emu_voice->fixed_lfo2_vibrato) >> 17; + currentpitch += lfo2_vibrato; } - int32_t dat3 = engine->chorus_right_buffer[read]; - int32_t dat4 = engine->chorus_right_buffer[next_value]; - dat3 += ((dat4-dat3)* fraction_part) >> 16; - engine->chorus_right_buffer[engine->write] = *inbuf + ((dat3 * engine->feedback)>>8); + if (emu_voice->fixed_modenv_filter_height) { + /* modenv range 1<<21, pitch height range 1<<14 desired range 0x200000 (+/-full filter range) */ + filtercut += ((modenv->value_db_oct >> 9) * emu_voice->fixed_modenv_filter_height) >> 5; + } - ++engine->write; - engine->write %= EMU8K_LFOCHORUS_SIZE; - engine->lfo_pos.addr +=engine->lfo_inc.addr; - engine->lfo_pos.int_address &= 0xFFFF; + if (emu_voice->fixed_lfo1_filt_mod) { + /* table range 1<<15, pitch mod range 1<<14 desired range 0x100000 (+/-three octaves) */ + int32_t lfo1_filtmod = (lfotable[emu_voice->lfo1_count.int_address] * emu_voice->fixed_lfo1_filt_mod) >> 9; + filtercut += lfo1_filtmod; + } - (*outbuf++) += dat1; - (*outbuf++) += dat3; - inbuf++; + if (emu_voice->fixed_lfo1_tremolo) { + /* table range 1<<15, pitch mod range 1<<14 desired range 0x40000 (+/-12dBs). */ + int32_t lfo1_tremolo = (lfotable[emu_voice->lfo1_count.int_address] * emu_voice->fixed_lfo1_tremolo) >> 11; + attenuation += lfo1_tremolo; + } + + if (currentpitch > 0xFFFF) + currentpitch = 0xFFFF; + if (currentpitch < 0) + currentpitch = 0; + if (attenuation > 0x1FFFFF) + attenuation = 0x1FFFFF; + if (attenuation < 0) + attenuation = 0; + if (filtercut > 0x1FFFFF) + filtercut = 0x1FFFFF; + if (filtercut < 0) + filtercut = 0; + + emu_voice->vtft_vol_target = env_vol_db_to_vol_target[attenuation >> 5]; + emu_voice->vtft_filter_target = filtercut >> 5; + emu_voice->ptrx_pit_target = freqtable[currentpitch] >> 18; + } + /* + I've recopilated these sentences to get an idea of how to loop + + - Set its PSST register and its CLS register to zero to cause no loops to occur. + -Setting the Loop Start Offset and the Loop End Offset to the same value, will cause the oscillator to loop the entire memory. + + -Setting the PlayPosition greater than the Loop End Offset, will cause the oscillator to play in reverse, back to the Loop End Offset. + It's pretty neat, but appears to be uncontrollable (the rate at which the samples are played in reverse). + + -Note that due to interpolator offset, the actual loop point is one greater than the start address + -Note that due to interpolator offset, the actual loop point will end at an address one greater than the loop address + -Note that the actual audio location is the point 1 word higher than this value due to interpolation offset + -In programs that use the awe, they generally set the loop address as "loopaddress -1" to compensate for the above. + (Note: I am already using address+1 in the interpolators so these things are already as they should.) + */ + emu_voice->addr.addr += ((uint64_t) emu_voice->cpf_curr_pitch) << 18; + if (emu_voice->addr.addr >= emu_voice->loop_end.addr) { + emu_voice->addr.int_address -= (emu_voice->loop_end.int_address - emu_voice->loop_start.int_address); + emu_voice->addr.int_address &= EMU8K_MEM_ADDRESS_MASK; + } + + /* TODO: How and when are the target and current values updated */ + emu_voice->cpf_curr_pitch = emu_voice->ptrx_pit_target; + emu_voice->cvcf_curr_volume = emu8k_vol_slide(&emu_voice->volumeslide, emu_voice->vtft_vol_target); + emu_voice->cvcf_curr_filt_ctoff = emu_voice->vtft_filter_target; } -} - -int32_t emu8k_reverb_comb_work(emu8k_reverb_combfilter_t* comb, int32_t in) -{ - - int32_t bufin; - /* get echo */ - int32_t output = comb->reflection[comb->read_pos]; - /* apply lowpass */ - comb->filterstore = (output*comb->damp2) + (comb->filterstore*comb->damp1); - /* appply feedback */ - bufin = in - (comb->filterstore*comb->feedback); - /* store new value in delayed buffer */ - comb->reflection[comb->read_pos] = bufin; - - if(++comb->read_pos>=comb->bufsize) comb->read_pos = 0; - - return output*comb->output_gain; -} - -int32_t emu8k_reverb_diffuser_work(emu8k_reverb_combfilter_t* comb, int32_t in) -{ - - int32_t bufout = comb->reflection[comb->read_pos]; - /*diffuse*/ - int32_t bufin = -in + (bufout*comb->feedback); - int32_t output = bufout - (bufin*comb->feedback); - /* store new value in delayed buffer */ - comb->reflection[comb->read_pos] = bufin; - - if(++comb->read_pos>=comb->bufsize) comb->read_pos = 0; - - return output; -} - -int32_t emu8k_reverb_tail_work(emu8k_reverb_combfilter_t* comb, emu8k_reverb_combfilter_t* allpasses, int32_t in) -{ - int32_t output = comb->reflection[comb->read_pos]; - /* store new value in delayed buffer */ - comb->reflection[comb->read_pos] = in; - - //output = emu8k_reverb_allpass_work(&allpasses[0],output); - output = emu8k_reverb_diffuser_work(&allpasses[1],output); - output = emu8k_reverb_diffuser_work(&allpasses[2],output); - //output = emu8k_reverb_allpass_work(&allpasses[3],output); - - if(++comb->read_pos>=comb->bufsize) comb->read_pos = 0; - - return output; -} -int32_t emu8k_reverb_damper_work(emu8k_reverb_combfilter_t* comb, int32_t in) -{ - /* apply lowpass */ - comb->filterstore = (in*comb->damp2) + (comb->filterstore*comb->damp1); - return comb->filterstore; -} - -/* TODO: This is not a correct emulation, just a workalike implementation. */ -void emu8k_work_reverb(int32_t *inbuf, int32_t *outbuf, emu8k_reverb_eng_t *engine, int count) -{ - int pos; - if (engine->link_return_type) - { - for (pos = 0; pos < count; pos++) - { - int32_t dat1, dat2, in, in2; - in = emu8k_reverb_damper_work(&engine->damper, inbuf[pos]); - in2 = (in * engine->refl_in_amp) >> 8; - dat2 = emu8k_reverb_comb_work(&engine->reflections[0], in2); - dat2 += emu8k_reverb_comb_work(&engine->reflections[1], in2); - dat1 = emu8k_reverb_comb_work(&engine->reflections[2], in2); - dat2 += emu8k_reverb_comb_work(&engine->reflections[3], in2); - dat1 += emu8k_reverb_comb_work(&engine->reflections[4], in2); - dat2 += emu8k_reverb_comb_work(&engine->reflections[5], in2); - - dat1 += (emu8k_reverb_tail_work(&engine->tailL,&engine->allpass[0], in+dat1)*engine->link_return_amp) >> 8; - dat2 += (emu8k_reverb_tail_work(&engine->tailR,&engine->allpass[4], in+dat2)*engine->link_return_amp) >> 8; - - (*outbuf++) += (dat1 * engine->out_mix) >> 8; - (*outbuf++) += (dat2 * engine->out_mix) >> 8; - } - } - else - { - for (pos = 0; pos < count; pos++) - { - int32_t dat1, dat2, in, in2; - in = emu8k_reverb_damper_work(&engine->damper, inbuf[pos]); - in2 = (in * engine->refl_in_amp) >> 8; - dat1 = emu8k_reverb_comb_work(&engine->reflections[0], in2); - dat1 += emu8k_reverb_comb_work(&engine->reflections[1], in2); - dat1 += emu8k_reverb_comb_work(&engine->reflections[2], in2); - dat1 += emu8k_reverb_comb_work(&engine->reflections[3], in2); - dat1 += emu8k_reverb_comb_work(&engine->reflections[4], in2); - dat1 += emu8k_reverb_comb_work(&engine->reflections[5], in2); - dat2 = dat1; - - dat1 += (emu8k_reverb_tail_work(&engine->tailL,&engine->allpass[0], in+dat1)*engine->link_return_amp) >> 8; - dat2 += (emu8k_reverb_tail_work(&engine->tailR,&engine->allpass[4], in+dat2)*engine->link_return_amp) >> 8; - - (*outbuf++) += (dat1 * engine->out_mix) >> 8; - (*outbuf++) += (dat2 * engine->out_mix) >> 8; - } - } -} -void emu8k_work_eq(int32_t *inoutbuf, int count) -{ - // TODO: Work EQ over buf -} - - -int32_t emu8k_vol_slide(emu8k_slide_t* slide, int32_t target) -{ - if (slide->last < target) - { - slide->last+=0x400; - if (slide->last > target) slide->last = target; - } - else if (slide->last > target) - { - slide->last-=0x400; - if (slide->last < target) slide->last = target; - } - return slide->last; -} - -//int32_t old_pitch[32]={0}; -//int32_t old_cut[32]={0}; -//int32_t old_vol[32]={0}; -void emu8k_update(emu8k_t *emu8k) -{ - int new_pos = (sound_pos_global * 44100) / 48000; - if (emu8k->pos >= new_pos) - return; - - int32_t *buf; - emu8k_voice_t* emu_voice; - int pos; - int c; - - /* Clean the buffers since we will accumulate into them. */ - buf = &emu8k->buffer[emu8k->pos*2]; - memset(buf, 0, 2*(new_pos-emu8k->pos)*sizeof(emu8k->buffer[0])); - memset(&emu8k->chorus_in_buffer[emu8k->pos], 0, (new_pos-emu8k->pos)*sizeof(emu8k->chorus_in_buffer[0])); - memset(&emu8k->reverb_in_buffer[emu8k->pos], 0, (new_pos-emu8k->pos)*sizeof(emu8k->reverb_in_buffer[0])); - - /* Voices section */ - for (c = 0; c < 32; c++) - { - emu_voice = &emu8k->voice[c]; - buf = &emu8k->buffer[emu8k->pos*2]; - - for (pos = emu8k->pos; pos < new_pos; pos++) - { - int32_t dat; - - if (emu_voice->cvcf_curr_volume) - { - /* Waveform oscillator */ - #ifdef RESAMPLER_LINEAR - dat = EMU8K_READ_INTERP_LINEAR(emu8k, emu_voice->addr.int_address, - emu_voice->addr.fract_address); - - #elif defined RESAMPLER_CUBIC - dat = EMU8K_READ_INTERP_CUBIC(emu8k, emu_voice->addr.int_address, - emu_voice->addr.fract_address); - #endif - - /* Filter section */ - if (emu_voice->filterq_idx || emu_voice->cvcf_curr_filt_ctoff != 0xFFFF ) - { - int cutoff = emu_voice->cvcf_curr_filt_ctoff >> 8; - const int64_t coef0 = filt_coeffs[emu_voice->filterq_idx][cutoff][0]; - const int64_t coef1 = filt_coeffs[emu_voice->filterq_idx][cutoff][1]; - const int64_t coef2 = filt_coeffs[emu_voice->filterq_idx][cutoff][2]; - /* clip at twice the range */ - #define ClipBuffer(buf) (buf < -16777216) ? -16777216 : (buf > 16777216) ? 16777216 : buf - - #ifdef FILTER_INITIAL - #define NOOP(x) (void)x; - NOOP(coef1) - /* Apply expected attenuation. (FILTER_MOOG does it implicitly, but this one doesn't). - * Work in 24bits. */ - dat = (dat * emu_voice->filt_att) >> 8; - - int64_t vhp = ((-emu_voice->filt_buffer[0] * coef2) >> 24) - emu_voice->filt_buffer[1] - dat; - emu_voice->filt_buffer[1] += (emu_voice->filt_buffer[0] * coef0) >> 24; - emu_voice->filt_buffer[0] += (vhp * coef0) >> 24; - dat = (int32_t)(emu_voice->filt_buffer[1] >> 8); - if (dat > 32767) { dat = 32767; } - else if (dat < -32768) { dat = -32768; } - - #elif defined FILTER_MOOG - - /*move to 24bits*/ - dat <<= 8; - - dat -= (coef2 * emu_voice->filt_buffer[4]) >> 24; /*feedback*/ - int64_t t1 = emu_voice->filt_buffer[1]; - emu_voice->filt_buffer[1] = ((dat + emu_voice->filt_buffer[0]) * coef0 - emu_voice->filt_buffer[1] * coef1) >> 24; - emu_voice->filt_buffer[1] = ClipBuffer(emu_voice->filt_buffer[1]); - - int64_t t2 = emu_voice->filt_buffer[2]; - emu_voice->filt_buffer[2] = ((emu_voice->filt_buffer[1] + t1) * coef0 - emu_voice->filt_buffer[2] * coef1) >> 24; - emu_voice->filt_buffer[2] = ClipBuffer(emu_voice->filt_buffer[2]); - - int64_t t3 = emu_voice->filt_buffer[3]; - emu_voice->filt_buffer[3] = ((emu_voice->filt_buffer[2] + t2) * coef0 - emu_voice->filt_buffer[3] * coef1) >> 24; - emu_voice->filt_buffer[3] = ClipBuffer(emu_voice->filt_buffer[3]); - - emu_voice->filt_buffer[4] = ((emu_voice->filt_buffer[3] + t3) * coef0 - emu_voice->filt_buffer[4] * coef1) >> 24; - emu_voice->filt_buffer[4] = ClipBuffer(emu_voice->filt_buffer[4]); - - emu_voice->filt_buffer[0] = ClipBuffer(dat); - - dat = (int32_t)(emu_voice->filt_buffer[4] >> 8); - if (dat > 32767) { dat = 32767; } - else if (dat < -32768) { dat = -32768; } - - #elif defined FILTER_CONSTANT - - /* Apply expected attenuation. (FILTER_MOOG does it implicitly, but this one is constant gain). - * Also stay at 24bits.*/ - dat = (dat * emu_voice->filt_att) >> 8; - - emu_voice->filt_buffer[0] = (coef1 * emu_voice->filt_buffer[0] - + coef0 * (dat + - ((coef2 * (emu_voice->filt_buffer[0] - emu_voice->filt_buffer[1]))>>24)) - ) >> 24; - emu_voice->filt_buffer[1] = (coef1 * emu_voice->filt_buffer[1] - + coef0 * emu_voice->filt_buffer[0]) >> 24; - - emu_voice->filt_buffer[0] = ClipBuffer(emu_voice->filt_buffer[0]); - emu_voice->filt_buffer[1] = ClipBuffer(emu_voice->filt_buffer[1]); - - dat = (int32_t)(emu_voice->filt_buffer[1] >> 8); - if (dat > 32767) { dat = 32767; } - else if (dat < -32768) { dat = -32768; } - - #endif - - } - if (( emu8k->hwcf3 & 0x04) && !CCCA_DMA_ACTIVE(emu_voice->ccca)) - { - /*volume and pan*/ - dat = (dat * emu_voice->cvcf_curr_volume) >> 16; - - (*buf++) += (dat * emu_voice->vol_l) >> 8; - (*buf++) += (dat * emu_voice->vol_r) >> 8; - - /* Effects section */ - if (emu_voice->ptrx_revb_send > 0) - { - emu8k->reverb_in_buffer[pos]+=(dat*emu_voice->ptrx_revb_send) >> 8; - } - if (emu_voice->csl_chor_send > 0) - { - emu8k->chorus_in_buffer[pos]+=(dat*emu_voice->csl_chor_send) >> 8; - } - } - } - - if ( emu_voice->env_engine_on) - { - int32_t attenuation = emu_voice->initial_att; - int32_t filtercut = emu_voice->initial_filter; - int32_t currentpitch = emu_voice->ip; - /* run envelopes */ - emu8k_envelope_t *volenv = &emu_voice->vol_envelope; - switch (volenv->state) - { - case ENV_DELAY: - volenv->delay_samples--; - if (volenv->delay_samples <=0) - { - volenv->state=ENV_ATTACK; - volenv->delay_samples=0; - } - attenuation = 0x1FFFFF; - break; - - case ENV_ATTACK: - /* Attack amount is in linear amplitude */ - volenv->value_amp_hz += volenv->attack_amount_amp_hz; - if (volenv->value_amp_hz >= (1 << 21)) - { - volenv->value_amp_hz = 1 << 21; - volenv->value_db_oct = 0; - if (volenv->hold_samples) - { - volenv->state = ENV_HOLD; - } - else - { - /* RAMP_UP since db value is inverted and it is 0 at this point. */ - volenv->state = ENV_RAMP_UP; - } - } - attenuation += env_vol_amplitude_to_db[volenv->value_amp_hz >> 5] << 5; - break; - - case ENV_HOLD: - volenv->hold_samples--; - if (volenv->hold_samples <=0) - { - volenv->state=ENV_RAMP_UP; - } - attenuation += volenv->value_db_oct; - break; - - case ENV_RAMP_DOWN: - /* Decay/release amount is in fraction of dBs and is always positive */ - volenv->value_db_oct -= volenv->ramp_amount_db_oct; - if (volenv->value_db_oct <= volenv->sustain_value_db_oct) - { - volenv->value_db_oct = volenv->sustain_value_db_oct; - volenv->state = ENV_SUSTAIN; - } - attenuation += volenv->value_db_oct; - break; - - case ENV_RAMP_UP: - /* Decay/release amount is in fraction of dBs and is always positive */ - volenv->value_db_oct += volenv->ramp_amount_db_oct; - if (volenv->value_db_oct >= volenv->sustain_value_db_oct) - { - volenv->value_db_oct = volenv->sustain_value_db_oct; - volenv->state = ENV_SUSTAIN; - } - attenuation += volenv->value_db_oct; - break; - - case ENV_SUSTAIN: - attenuation += volenv->value_db_oct; - break; - - case ENV_STOPPED: - attenuation = 0x1FFFFF; - break; - } - - emu8k_envelope_t *modenv = &emu_voice->mod_envelope; - switch (modenv->state) - { - case ENV_DELAY: - modenv->delay_samples--; - if (modenv->delay_samples <=0) - { - modenv->state=ENV_ATTACK; - modenv->delay_samples=0; - } - break; - - case ENV_ATTACK: - /* Attack amount is in linear amplitude */ - modenv->value_amp_hz += modenv->attack_amount_amp_hz; - modenv->value_db_oct = env_mod_hertz_to_octave[modenv->value_amp_hz >> 5] << 5; - if (modenv->value_amp_hz >= (1 << 21)) - { - modenv->value_amp_hz = 1 << 21; - modenv->value_db_oct = 1 << 21; - if (modenv->hold_samples) - { - modenv->state = ENV_HOLD; - } - else - { - modenv->state = ENV_RAMP_DOWN; - } - } - break; - - case ENV_HOLD: - modenv->hold_samples--; - if (modenv->hold_samples <=0) - { - modenv->state=ENV_RAMP_UP; - } - break; - - case ENV_RAMP_DOWN: - /* Decay/release amount is in fraction of octave and is always positive */ - modenv->value_db_oct -= modenv->ramp_amount_db_oct; - if (modenv->value_db_oct <= modenv->sustain_value_db_oct) - { - modenv->value_db_oct = modenv->sustain_value_db_oct; - modenv->state = ENV_SUSTAIN; - } - break; - - case ENV_RAMP_UP: - /* Decay/release amount is in fraction of octave and is always positive */ - modenv->value_db_oct += modenv->ramp_amount_db_oct; - if (modenv->value_db_oct >= modenv->sustain_value_db_oct) - { - modenv->value_db_oct = modenv->sustain_value_db_oct; - modenv->state = ENV_SUSTAIN; - } - break; - } - - /* run lfos */ - if (emu_voice->lfo1_delay_samples) - { - emu_voice->lfo1_delay_samples--; - } - else - { - emu_voice->lfo1_count.addr += emu_voice->lfo1_speed; - emu_voice->lfo1_count.int_address &= 0xFFFF; - } - if (emu_voice->lfo2_delay_samples) - { - emu_voice->lfo2_delay_samples--; - } - else - { - emu_voice->lfo2_count.addr += emu_voice->lfo2_speed; - emu_voice->lfo2_count.int_address &= 0xFFFF; - } - - - if (emu_voice->fixed_modenv_pitch_height) - { - /* modenv range 1<<21, pitch height range 1<<14 desired range 0x1000 (+/-one octave) */ - currentpitch += ((modenv->value_db_oct>>9)*emu_voice->fixed_modenv_pitch_height) >> 14; - } - - if (emu_voice->fixed_lfo1_vibrato) - { - /* table range 1<<15, pitch mod range 1<<14 desired range 0x1000 (+/-one octave) */ - int32_t lfo1_vibrato = (lfotable[emu_voice->lfo1_count.int_address]*emu_voice->fixed_lfo1_vibrato) >> 17; - currentpitch += lfo1_vibrato; - } - if (emu_voice->fixed_lfo2_vibrato) - { - /* table range 1<<15, pitch mod range 1<<14 desired range 0x1000 (+/-one octave) */ - int32_t lfo2_vibrato = (lfotable[emu_voice->lfo2_count.int_address]*emu_voice->fixed_lfo2_vibrato) >> 17; - currentpitch += lfo2_vibrato; - } - - if (emu_voice->fixed_modenv_filter_height) - { - /* modenv range 1<<21, pitch height range 1<<14 desired range 0x200000 (+/-full filter range) */ - filtercut += ((modenv->value_db_oct>>9)*emu_voice->fixed_modenv_filter_height) >> 5; - } - - if (emu_voice->fixed_lfo1_filt_mod) - { - /* table range 1<<15, pitch mod range 1<<14 desired range 0x100000 (+/-three octaves) */ - int32_t lfo1_filtmod = (lfotable[emu_voice->lfo1_count.int_address]*emu_voice->fixed_lfo1_filt_mod) >> 9; - filtercut += lfo1_filtmod; - } - - if (emu_voice->fixed_lfo1_tremolo) - { - /* table range 1<<15, pitch mod range 1<<14 desired range 0x40000 (+/-12dBs). */ - int32_t lfo1_tremolo = (lfotable[emu_voice->lfo1_count.int_address]*emu_voice->fixed_lfo1_tremolo) >> 11; - attenuation += lfo1_tremolo; - } - - if (currentpitch > 0xFFFF) currentpitch = 0xFFFF; - if (currentpitch < 0) currentpitch = 0; - if (attenuation > 0x1FFFFF) attenuation = 0x1FFFFF; - if (attenuation < 0) attenuation = 0; - if (filtercut > 0x1FFFFF) filtercut = 0x1FFFFF; - if (filtercut < 0) filtercut = 0; - - emu_voice->vtft_vol_target = env_vol_db_to_vol_target[attenuation >> 5]; - emu_voice->vtft_filter_target = filtercut >> 5; - emu_voice->ptrx_pit_target = freqtable[currentpitch]>>18; - - } -/* -I've recopilated these sentences to get an idea of how to loop - -- Set its PSST register and its CLS register to zero to cause no loops to occur. --Setting the Loop Start Offset and the Loop End Offset to the same value, will cause the oscillator to loop the entire memory. - --Setting the PlayPosition greater than the Loop End Offset, will cause the oscillator to play in reverse, back to the Loop End Offset. - It's pretty neat, but appears to be uncontrollable (the rate at which the samples are played in reverse). - --Note that due to interpolator offset, the actual loop point is one greater than the start address --Note that due to interpolator offset, the actual loop point will end at an address one greater than the loop address --Note that the actual audio location is the point 1 word higher than this value due to interpolation offset --In programs that use the awe, they generally set the loop address as "loopaddress -1" to compensate for the above. -(Note: I am already using address+1 in the interpolators so these things are already as they should.) -*/ - emu_voice->addr.addr += ((uint64_t)emu_voice->cpf_curr_pitch) << 18; - if (emu_voice->addr.addr >= emu_voice->loop_end.addr) - { - emu_voice->addr.int_address -= (emu_voice->loop_end.int_address - emu_voice->loop_start.int_address); - emu_voice->addr.int_address &= EMU8K_MEM_ADDRESS_MASK; - } - - /* TODO: How and when are the target and current values updated */ - emu_voice->cpf_curr_pitch = emu_voice->ptrx_pit_target; - emu_voice->cvcf_curr_volume = emu8k_vol_slide(&emu_voice->volumeslide,emu_voice->vtft_vol_target); - emu_voice->cvcf_curr_filt_ctoff = emu_voice->vtft_filter_target; - } - - /* Update EMU voice registers. */ - emu_voice->ccca = (((uint32_t)emu_voice->ccca_qcontrol) << 24) | emu_voice->addr.int_address; - emu_voice->cpf_curr_frac_addr = emu_voice->addr.fract_address; - - //if ( emu_voice->cvcf_curr_volume != old_vol[c]) { - // pclog("EMUVOL (%d):%d\n", c, emu_voice->cvcf_curr_volume); - // old_vol[c]=emu_voice->cvcf_curr_volume; - //} - //pclog("EMUFILT :%d\n", emu_voice->cvcf_curr_filt_ctoff); - } - - - buf = &emu8k->buffer[emu8k->pos*2]; - emu8k_work_reverb(&emu8k->reverb_in_buffer[emu8k->pos], buf, &emu8k->reverb_engine, new_pos-emu8k->pos); - emu8k_work_chorus(&emu8k->chorus_in_buffer[emu8k->pos], buf, &emu8k->chorus_engine, new_pos-emu8k->pos); - emu8k_work_eq(buf, new_pos-emu8k->pos); - - // Clip signal - for (pos = emu8k->pos; pos < new_pos; pos++) - { - if (buf[0] < -32768) - buf[0] = -32768; - else if (buf[0] > 32767) - buf[0] = 32767; - - if (buf[1] < -32768) - buf[1] = -32768; - else if (buf[1] > 32767) - buf[1] = 32767; - - buf += 2; - } - - /* Update EMU clock. */ - emu8k->wc += (new_pos - emu8k->pos); - - emu8k->pos = new_pos; + /* Update EMU voice registers. */ + emu_voice->ccca = (((uint32_t) emu_voice->ccca_qcontrol) << 24) | emu_voice->addr.int_address; + emu_voice->cpf_curr_frac_addr = emu_voice->addr.fract_address; + + // if ( emu_voice->cvcf_curr_volume != old_vol[c]) { + // pclog("EMUVOL (%d):%d\n", c, emu_voice->cvcf_curr_volume); + // old_vol[c]=emu_voice->cvcf_curr_volume; + // } + // pclog("EMUFILT :%d\n", emu_voice->cvcf_curr_filt_ctoff); + } + + buf = &emu8k->buffer[emu8k->pos * 2]; + emu8k_work_reverb(&emu8k->reverb_in_buffer[emu8k->pos], buf, &emu8k->reverb_engine, new_pos - emu8k->pos); + emu8k_work_chorus(&emu8k->chorus_in_buffer[emu8k->pos], buf, &emu8k->chorus_engine, new_pos - emu8k->pos); + emu8k_work_eq(buf, new_pos - emu8k->pos); + + // Clip signal + for (pos = emu8k->pos; pos < new_pos; pos++) { + if (buf[0] < -32768) + buf[0] = -32768; + else if (buf[0] > 32767) + buf[0] = 32767; + + if (buf[1] < -32768) + buf[1] = -32768; + else if (buf[1] > 32767) + buf[1] = 32767; + + buf += 2; + } + + /* Update EMU clock. */ + emu8k->wc += (new_pos - emu8k->pos); + + emu8k->pos = new_pos; } void emu8k_change_addr(emu8k_t *emu8k, uint16_t emu_addr) { - if (emu8k->addr) { - io_removehandler(emu8k->addr, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); - io_removehandler(emu8k->addr+0x400, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); - io_removehandler(emu8k->addr+0x800, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); - emu8k->addr = 0; - } - if (emu_addr) { - emu8k->addr = emu_addr; - io_sethandler(emu8k->addr, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); - io_sethandler(emu8k->addr+0x400, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); - io_sethandler(emu8k->addr+0x800, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); - } + if (emu8k->addr) { + io_removehandler(emu8k->addr, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); + io_removehandler(emu8k->addr + 0x400, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); + io_removehandler(emu8k->addr + 0x800, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); + emu8k->addr = 0; + } + if (emu_addr) { + emu8k->addr = emu_addr; + io_sethandler(emu8k->addr, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); + io_sethandler(emu8k->addr + 0x400, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); + io_sethandler(emu8k->addr + 0x800, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); + } } /* onboard_ram in kilobytes */ -void emu8k_init(emu8k_t *emu8k, uint16_t emu_addr, int onboard_ram) +void +emu8k_init(emu8k_t *emu8k, uint16_t emu_addr, int onboard_ram) { - uint32_t const BLOCK_SIZE_WORDS = 0x10000; - FILE *f; - int c; - double out; + uint32_t const BLOCK_SIZE_WORDS = 0x10000; + FILE *f; + int c; + double out; - f = rom_fopen("roms/sound/awe32.raw", "rb"); - if (!f) - fatal("AWE32.RAW not found\n"); + f = rom_fopen("roms/sound/awe32.raw", "rb"); + if (!f) + fatal("AWE32.RAW not found\n"); - emu8k->rom = malloc(1024 * 1024); - if (fread(emu8k->rom, 1, 1048576, f) != 1048576) - fatal("emu8k_init(): Error reading data\n"); - fclose(f); - /*AWE-DUMP creates ROM images offset by 2 bytes, so if we detect this - then correct it*/ - if (emu8k->rom[3] == 0x314d && emu8k->rom[4] == 0x474d) - { - memmove(&emu8k->rom[0], &emu8k->rom[1], (1024 * 1024) - 2); - emu8k->rom[0x7ffff] = 0; + emu8k->rom = malloc(1024 * 1024); + if (fread(emu8k->rom, 1, 1048576, f) != 1048576) + fatal("emu8k_init(): Error reading data\n"); + fclose(f); + /*AWE-DUMP creates ROM images offset by 2 bytes, so if we detect this + then correct it*/ + if (emu8k->rom[3] == 0x314d && emu8k->rom[4] == 0x474d) { + memmove(&emu8k->rom[0], &emu8k->rom[1], (1024 * 1024) - 2); + emu8k->rom[0x7ffff] = 0; + } + + emu8k->empty = malloc(2 * BLOCK_SIZE_WORDS); + memset(emu8k->empty, 0, 2 * BLOCK_SIZE_WORDS); + + int j = 0; + for (; j < 0x8; j++) { + emu8k->ram_pointers[j] = emu8k->rom + (j * BLOCK_SIZE_WORDS); + } + for (; j < 0x20; j++) { + emu8k->ram_pointers[j] = emu8k->empty; + } + + if (onboard_ram) { + /*Clip to 28MB, since that's the max that we can address. */ + if (onboard_ram > 0x7000) + onboard_ram = 0x7000; + emu8k->ram = malloc(onboard_ram * 1024); + memset(emu8k->ram, 0, onboard_ram * 1024); + const int i_end = onboard_ram >> 7; + int i = 0; + for (; i < i_end; i++, j++) { + emu8k->ram_pointers[j] = emu8k->ram + (i * BLOCK_SIZE_WORDS); } + emu8k->ram_end_addr = EMU8K_RAM_MEM_START + (onboard_ram << 9); + } else { + emu8k->ram = 0; + emu8k->ram_end_addr = EMU8K_RAM_MEM_START; + } + for (; j < 0x100; j++) { + emu8k->ram_pointers[j] = emu8k->empty; + } - emu8k->empty = malloc(2*BLOCK_SIZE_WORDS); - memset(emu8k->empty, 0, 2*BLOCK_SIZE_WORDS); + emu8k_change_addr(emu8k, emu_addr); - int j=0; - for (;j<0x8;j++) - { - emu8k->ram_pointers[j]=emu8k->rom+(j*BLOCK_SIZE_WORDS); - } - for (;j<0x20;j++) - { - emu8k->ram_pointers[j]=emu8k->empty; - } + /*Create frequency table. (Convert initial pitch register value to a linear speed change) + * The input is encoded such as 0xe000 is center note (no pitch shift) + * and from then on , changing up or down 0x1000 (4096) increments/decrements an octave. + * Note that this is in reference to the 44.1Khz clock that the channels play at. + * The 65536 * 65536 is in order to left-shift the 32bit value to a 64bit value as a 32.32 fixed point. + */ + for (c = 0; c < 0x10000; c++) { + freqtable[c] = (uint64_t) (exp2((double) (c - 0xe000) / 4096.0) * 65536.0 * 65536.0); + } + /* Shortcut: minimum pitch equals stopped. I don't really know if this is true, but it's better + * since some programs set the pitch to 0 for unused channels. */ + freqtable[0] = 0; - if (onboard_ram) - { - /*Clip to 28MB, since that's the max that we can address. */ - if (onboard_ram > 0x7000) onboard_ram = 0x7000; - emu8k->ram = malloc(onboard_ram * 1024); - memset(emu8k->ram, 0, onboard_ram * 1024); - const int i_end=onboard_ram>>7; - int i=0; - for(;iram_pointers[j]=emu8k->ram+(i*BLOCK_SIZE_WORDS); - } - emu8k->ram_end_addr = EMU8K_RAM_MEM_START + (onboard_ram<<9); - } + /* starting at 65535 because it is used for "volume target" register conversion. */ + out = 65535.0; + for (c = 0; c < 256; c++) { + attentable[c] = (int32_t) out; + out /= sqrt(1.09018); /*0.375 dB steps*/ + } + /* Shortcut: max attenuation is silent, not -96dB. */ + attentable[255] = 0; + + /* Note: these two tables have "db" inverted: 0 dB is max volume, 65535 "db" (-96.32dBFS) is silence. + * Important: Using 65535 as max output value because this is intended to be used with the volume target register! */ + out = 65535.0; + for (c = 0; c < 0x10000; c++) { + // double db = -(c*6.0205999/65535.0)*16.0; + // out = powf(10.f,db/20.f) * 65536.0; + env_vol_db_to_vol_target[c] = (int32_t) out; + /* calculated from the 65536th root of 65536 */ + out /= 1.00016923970; + } + /* Shortcut: max attenuation is silent, not -96dB. */ + env_vol_db_to_vol_target[0x10000 - 1] = 0; + /* One more position to accept max value being 65536. */ + env_vol_db_to_vol_target[0x10000] = 0; + + for (c = 1; c < 0x10000; c++) { + out = -680.32142884264 * 20.0 * log10(((double) c) / 65535.0); + env_vol_amplitude_to_db[c] = (int32_t) out; + } + /*Shortcut: max attenuation is silent, not -96dB.*/ + env_vol_amplitude_to_db[0] = 65535; + /* One more position to accept max value being 65536. */ + env_vol_amplitude_to_db[0x10000] = 0; + + for (c = 1; c < 0x10000; c++) { + out = log2((((double) c) / 0x10000) + 1.0) * 65536.0; + env_mod_hertz_to_octave[c] = (int32_t) out; + } + /*No hertz change, no octave change. */ + env_mod_hertz_to_octave[0] = 0; + /* One more position to accept max value being 65536. */ + env_mod_hertz_to_octave[0x10000] = 65536; + + /* This formula comes from vince vu/judge dredd's awe32p10 and corresponds to what the freebsd/linux AWE32 driver has. */ + float millis; + for (c = 0; c < 128; c++) { + if (c == 0) + millis = 0; /* This means never attack. */ + else if (c < 32) + millis = 11878.0 / c; else - { - emu8k->ram = 0; - emu8k->ram_end_addr = EMU8K_RAM_MEM_START; - } - for (;j < 0x100;j++) - { - emu8k->ram_pointers[j]=emu8k->empty; + millis = 360 * exp((c - 32) / (16.0 / log(1.0 / 2.0))); - } + env_attack_to_samples[c] = 44.1 * millis; + /* This is an alternate formula with linear increments, but probably incorrect: + * millis = (256+4096*(0x7F-c)) */ + } - emu8k_change_addr(emu8k, emu_addr); + /* The LFOs use a triangular waveform starting at zero and going 1/-1/1/-1. + * This table is stored in signed 16bits precision, with a period of 65536 samples */ + for (c = 0; c < 65536; c++) { + int d = (c + 16384) & 65535; + if (d >= 32768) + lfotable[c] = 32768 + ((32768 - d) * 2); + else + lfotable[c] = (d * 2) - 32768; + } + /* The 65536 * 65536 is in order to left-shift the 32bit value to a 64bit value as a 32.32 fixed point. */ + out = 0.01; + for (c = 0; c < 256; c++) { + lfofreqtospeed[c] = (uint64_t) (out * 65536.0 / 44100.0 * 65536.0 * 65536.0); + out += 0.042; + } - /*Create frequency table. (Convert initial pitch register value to a linear speed change) - * The input is encoded such as 0xe000 is center note (no pitch shift) - * and from then on , changing up or down 0x1000 (4096) increments/decrements an octave. - * Note that this is in reference to the 44.1Khz clock that the channels play at. - * The 65536 * 65536 is in order to left-shift the 32bit value to a 64bit value as a 32.32 fixed point. - */ - for (c = 0; c < 0x10000; c++) - { - freqtable[c] = (uint64_t)(exp2((double)(c - 0xe000) / 4096.0) * 65536.0 * 65536.0); - } - /* Shortcut: minimum pitch equals stopped. I don't really know if this is true, but it's better - * since some programs set the pitch to 0 for unused channels. */ - freqtable[0] = 0; + for (c = 0; c < 65536; c++) { + chortable[c] = sin(c * M_PI / 32768.0); + } - /* starting at 65535 because it is used for "volume target" register conversion. */ - out = 65535.0; - for (c = 0; c < 256; c++) - { - attentable[c] = (int32_t)out; - out /= sqrt(1.09018); /*0.375 dB steps*/ - } - /* Shortcut: max attenuation is silent, not -96dB. */ - attentable[255]=0; - - /* Note: these two tables have "db" inverted: 0 dB is max volume, 65535 "db" (-96.32dBFS) is silence. - * Important: Using 65535 as max output value because this is intended to be used with the volume target register! */ - out = 65535.0; - for (c = 0; c < 0x10000; c++) - { - //double db = -(c*6.0205999/65535.0)*16.0; - //out = powf(10.f,db/20.f) * 65536.0; - env_vol_db_to_vol_target[c] = (int32_t)out; - /* calculated from the 65536th root of 65536 */ - out /= 1.00016923970; - } - /* Shortcut: max attenuation is silent, not -96dB. */ - env_vol_db_to_vol_target[0x10000-1]=0; - /* One more position to accept max value being 65536. */ - env_vol_db_to_vol_target[0x10000]=0; - - for (c = 1; c < 0x10000; c++) - { - out = -680.32142884264* 20.0 * log10(((double)c)/65535.0); - env_vol_amplitude_to_db[c] = (int32_t)out; - } - /*Shortcut: max attenuation is silent, not -96dB.*/ - env_vol_amplitude_to_db[0]=65535; - /* One more position to accept max value being 65536. */ - env_vol_amplitude_to_db[0x10000]=0; - - - for (c = 1; c < 0x10000; c++) - { - out = log2((((double)c)/0x10000)+1.0) *65536.0; - env_mod_hertz_to_octave[c] = (int32_t)out; - } - /*No hertz change, no octave change. */ - env_mod_hertz_to_octave[0]=0; - /* One more position to accept max value being 65536. */ - env_mod_hertz_to_octave[0x10000]=65536; - - - /* This formula comes from vince vu/judge dredd's awe32p10 and corresponds to what the freebsd/linux AWE32 driver has. */ - float millis; - for (c=0;c<128;c++) - { - if (c==0) - millis = 0; /* This means never attack. */ - else if (c < 32) - millis = 11878.0/c; - else - millis = 360*exp((c - 32) / (16.0/log(1.0/2.0))); - - env_attack_to_samples[c] = 44.1*millis; - /* This is an alternate formula with linear increments, but probably incorrect: - * millis = (256+4096*(0x7F-c)) */ - } - - /* The LFOs use a triangular waveform starting at zero and going 1/-1/1/-1. - * This table is stored in signed 16bits precision, with a period of 65536 samples */ - for (c = 0; c < 65536; c++) - { - int d = (c + 16384) & 65535; - if (d >= 32768) - lfotable[c] = 32768 + ((32768 - d)*2); - else - lfotable[c] = (d*2) - 32768; - } - /* The 65536 * 65536 is in order to left-shift the 32bit value to a 64bit value as a 32.32 fixed point. */ - out = 0.01; - for (c = 0; c < 256; c++) - { - lfofreqtospeed[c] = (uint64_t)(out *65536.0/44100.0 * 65536.0 * 65536.0); - out += 0.042; - } - - for (c = 0; c < 65536; c++) - { - chortable[c] = sin(c*M_PI/32768.0); - } - - - /* Filter coefficients tables. Note: Values are multiplied by *16777216 to left shift 24 bits. (i.e. 8.24 fixed point) */ - int qidx; - for (qidx = 0; qidx < 16; qidx++) - { - out = 125.0; /* Start at 125Hz */ - for (c = 0; c < 256; c++) - { + /* Filter coefficients tables. Note: Values are multiplied by *16777216 to left shift 24 bits. (i.e. 8.24 fixed point) */ + int qidx; + for (qidx = 0; qidx < 16; qidx++) { + out = 125.0; /* Start at 125Hz */ + for (c = 0; c < 256; c++) { #ifdef FILTER_INITIAL - float w0 = sin(2.0*M_PI*out / 44100.0); - /* The value 102.5f has been selected a bit randomly. Pretends to reach 0.2929 at w0 = 1.0 */ - float q = (qidx / 102.5f) * (1.0 + 1.0 / w0); - /* Limit max value. Else it would be 470. */ - if (q > 200) q=200; - filt_coeffs[qidx][c][0] = (int32_t)(w0 * 16777216.0); - filt_coeffs[qidx][c][1] = 16777216.0; - filt_coeffs[qidx][c][2] = (int32_t)((1.0f / (0.7071f + q)) * 16777216.0); + float w0 = sin(2.0 * M_PI * out / 44100.0); + /* The value 102.5f has been selected a bit randomly. Pretends to reach 0.2929 at w0 = 1.0 */ + float q = (qidx / 102.5f) * (1.0 + 1.0 / w0); + /* Limit max value. Else it would be 470. */ + if (q > 200) + q = 200; + filt_coeffs[qidx][c][0] = (int32_t) (w0 * 16777216.0); + filt_coeffs[qidx][c][1] = 16777216.0; + filt_coeffs[qidx][c][2] = (int32_t) ((1.0f / (0.7071f + q)) * 16777216.0); #elif defined FILTER_MOOG - float w0 = sin(2.0*M_PI*out / 44100.0); - float q_factor = 1.0f - w0; - float p = w0 + 0.8f * w0 * q_factor; - float f = p + p - 1.0f; - float resonance = (1.0-pow(2.0,-qidx*24.0/90.0))*0.8; - float q = resonance * (1.0f + 0.5f * q_factor * (w0 + 5.6f * q_factor * q_factor)); - filt_coeffs[qidx][c][0] = (int32_t)(p * 16777216.0); - filt_coeffs[qidx][c][1] = (int32_t)(f * 16777216.0); - filt_coeffs[qidx][c][2] = (int32_t)(q * 16777216.0); + float w0 = sin(2.0 * M_PI * out / 44100.0); + float q_factor = 1.0f - w0; + float p = w0 + 0.8f * w0 * q_factor; + float f = p + p - 1.0f; + float resonance = (1.0 - pow(2.0, -qidx * 24.0 / 90.0)) * 0.8; + float q = resonance * (1.0f + 0.5f * q_factor * (w0 + 5.6f * q_factor * q_factor)); + filt_coeffs[qidx][c][0] = (int32_t) (p * 16777216.0); + filt_coeffs[qidx][c][1] = (int32_t) (f * 16777216.0); + filt_coeffs[qidx][c][2] = (int32_t) (q * 16777216.0); #elif defined FILTER_CONSTANT - float q = (1.0-pow(2.0,-qidx*24.0/90.0))*0.8; - float coef0 = sin(2.0*M_PI*out / 44100.0); - float coef1 = 1.0 - coef0; - float coef2 = q * (1.0 + 1.0 / coef1); - filt_coeffs[qidx][c][0] = (int32_t)(coef0 * 16777216.0); - filt_coeffs[qidx][c][1] = (int32_t)(coef1 * 16777216.0); - filt_coeffs[qidx][c][2] = (int32_t)(coef2 * 16777216.0); -#endif //FILTER_TYPE - /* 42.66 divisions per octave (the doc says quarter seminotes which is 48, but then it would be almost an octave less) */ - out *= 1.016378315; - /* 42 divisions. This moves the max frequency to 8.5Khz.*/ - //out *= 1.0166404394; - /* This is a linear increment method, that corresponds to the NRPN table, but contradicts the EMU8KPRM doc: */ - //out = 100.0 + (c+1.0)*31.25; //31.25Hz steps */ - } + float q = (1.0 - pow(2.0, -qidx * 24.0 / 90.0)) * 0.8; + float coef0 = sin(2.0 * M_PI * out / 44100.0); + float coef1 = 1.0 - coef0; + float coef2 = q * (1.0 + 1.0 / coef1); + filt_coeffs[qidx][c][0] = (int32_t) (coef0 * 16777216.0); + filt_coeffs[qidx][c][1] = (int32_t) (coef1 * 16777216.0); + filt_coeffs[qidx][c][2] = (int32_t) (coef2 * 16777216.0); +#endif // FILTER_TYPE + /* 42.66 divisions per octave (the doc says quarter seminotes which is 48, but then it would be almost an octave less) */ + out *= 1.016378315; + /* 42 divisions. This moves the max frequency to 8.5Khz.*/ + // out *= 1.0166404394; + /* This is a linear increment method, that corresponds to the NRPN table, but contradicts the EMU8KPRM doc: */ + // out = 100.0 + (c+1.0)*31.25; //31.25Hz steps */ } - /* NOTE! read_pos and buffer content is implicitly initialized to zero by the sb_t structure memset on sb_awe32_init() */ - emu8k->reverb_engine.reflections[0].bufsize=2*REV_BUFSIZE_STEP; - emu8k->reverb_engine.reflections[1].bufsize=4*REV_BUFSIZE_STEP; - emu8k->reverb_engine.reflections[2].bufsize=8*REV_BUFSIZE_STEP; - emu8k->reverb_engine.reflections[3].bufsize=13*REV_BUFSIZE_STEP; - emu8k->reverb_engine.reflections[4].bufsize=19*REV_BUFSIZE_STEP; - emu8k->reverb_engine.reflections[5].bufsize=26*REV_BUFSIZE_STEP; + } + /* NOTE! read_pos and buffer content is implicitly initialized to zero by the sb_t structure memset on sb_awe32_init() */ + emu8k->reverb_engine.reflections[0].bufsize = 2 * REV_BUFSIZE_STEP; + emu8k->reverb_engine.reflections[1].bufsize = 4 * REV_BUFSIZE_STEP; + emu8k->reverb_engine.reflections[2].bufsize = 8 * REV_BUFSIZE_STEP; + emu8k->reverb_engine.reflections[3].bufsize = 13 * REV_BUFSIZE_STEP; + emu8k->reverb_engine.reflections[4].bufsize = 19 * REV_BUFSIZE_STEP; + emu8k->reverb_engine.reflections[5].bufsize = 26 * REV_BUFSIZE_STEP; - /*This is a bit random.*/ - for (c=0;c<4;c++) - { - emu8k->reverb_engine.allpass[3-c].feedback=0.5; - emu8k->reverb_engine.allpass[3-c].bufsize=(4*c)*REV_BUFSIZE_STEP+55; - emu8k->reverb_engine.allpass[7-c].feedback=0.5; - emu8k->reverb_engine.allpass[7-c].bufsize=(4*c)*REV_BUFSIZE_STEP+55; - } + /*This is a bit random.*/ + for (c = 0; c < 4; c++) { + emu8k->reverb_engine.allpass[3 - c].feedback = 0.5; + emu8k->reverb_engine.allpass[3 - c].bufsize = (4 * c) * REV_BUFSIZE_STEP + 55; + emu8k->reverb_engine.allpass[7 - c].feedback = 0.5; + emu8k->reverb_engine.allpass[7 - c].bufsize = (4 * c) * REV_BUFSIZE_STEP + 55; + } - - - /* Cubic Resampling ( 4point cubic spline) */ - double const resdouble = 1.0/(double)CUBIC_RESOLUTION; - for (c = 0; c < CUBIC_RESOLUTION; c++) - { - double x = (double)c * resdouble; - /* Cubic resolution is made of four table, but I've put them all in one table to optimize memory access. */ - cubic_table[c*4] = (-0.5 * x * x * x + x * x - 0.5 * x) ; - cubic_table[c*4+1] = ( 1.5 * x * x * x - 2.5 * x * x + 1.0) ; - cubic_table[c*4+2] = (-1.5 * x * x * x + 2.0 * x * x + 0.5 * x) ; - cubic_table[c*4+3] = ( 0.5 * x * x * x - 0.5 * x * x) ; - } - /* Even when the documentation says that this has to be written by applications to initialize the card, - * several applications and drivers ( aweman on windows, linux oss driver..) read it to detect an AWE card. */ - emu8k->hwcf1 = 0x59; - emu8k->hwcf2 = 0x20; - /* Initial state is muted. 0x04 is unmuted. */ - emu8k->hwcf3 = 0x00; + /* Cubic Resampling ( 4point cubic spline) */ + double const resdouble = 1.0 / (double) CUBIC_RESOLUTION; + for (c = 0; c < CUBIC_RESOLUTION; c++) { + double x = (double) c * resdouble; + /* Cubic resolution is made of four table, but I've put them all in one table to optimize memory access. */ + cubic_table[c * 4] = (-0.5 * x * x * x + x * x - 0.5 * x); + cubic_table[c * 4 + 1] = (1.5 * x * x * x - 2.5 * x * x + 1.0); + cubic_table[c * 4 + 2] = (-1.5 * x * x * x + 2.0 * x * x + 0.5 * x); + cubic_table[c * 4 + 3] = (0.5 * x * x * x - 0.5 * x * x); + } + /* Even when the documentation says that this has to be written by applications to initialize the card, + * several applications and drivers ( aweman on windows, linux oss driver..) read it to detect an AWE card. */ + emu8k->hwcf1 = 0x59; + emu8k->hwcf2 = 0x20; + /* Initial state is muted. 0x04 is unmuted. */ + emu8k->hwcf3 = 0x00; } -void emu8k_close(emu8k_t *emu8k) +void +emu8k_close(emu8k_t *emu8k) { - free(emu8k->rom); - free(emu8k->ram); + free(emu8k->rom); + free(emu8k->ram); } diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index 9c18b964e..95c006612 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -1,1326 +1,1253 @@ #include #include #include -#include #include +#include #include #define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/io.h> -#include <86box/nmi.h> -#include <86box/pic.h> -#include <86box/dma.h> -#include <86box/timer.h> -#include <86box/device.h> -#include <86box/sound.h> -#include <86box/midi.h> -#include <86box/snd_ad1848.h> #include -enum -{ - MIDI_INT_RECEIVE = 0x01, - MIDI_INT_TRANSMIT = 0x02, - MIDI_INT_MASTER = 0x80 +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/dma.h> +#include <86box/io.h> +#include <86box/midi.h> +#include <86box/nmi.h> +#include <86box/pic.h> +#include <86box/sound.h> +#include <86box/timer.h> +#include <86box/snd_ad1848.h> + +enum { + MIDI_INT_RECEIVE = 0x01, + MIDI_INT_TRANSMIT = 0x02, + MIDI_INT_MASTER = 0x80 }; -enum -{ - MIDI_CTRL_TRANSMIT_MASK = 0x60, - MIDI_CTRL_TRANSMIT = 0x20, - MIDI_CTRL_RECEIVE = 0x80 +enum { + MIDI_CTRL_TRANSMIT_MASK = 0x60, + MIDI_CTRL_TRANSMIT = 0x20, + MIDI_CTRL_RECEIVE = 0x80 }; -enum -{ - GUS_INT_MIDI_TRANSMIT = 0x01, - GUS_INT_MIDI_RECEIVE = 0x02 +enum { + GUS_INT_MIDI_TRANSMIT = 0x01, + GUS_INT_MIDI_RECEIVE = 0x02 }; -enum -{ - GUS_TIMER_CTRL_AUTO = 0x01 +enum { + GUS_TIMER_CTRL_AUTO = 0x01 }; -enum -{ - GUS_CLASSIC = 0, - GUS_MAX = 1, +enum { + GUS_CLASSIC = 0, + GUS_MAX = 1, }; -typedef struct gus_t -{ - int reset; +typedef struct gus_t { + int reset; - int global; - uint32_t addr,dmaaddr; - int voice; - uint32_t start[32],end[32],cur[32]; - uint32_t startx[32],endx[32],curx[32]; - int rstart[32],rend[32]; - int rcur[32]; - uint16_t freq[32]; - uint16_t rfreq[32]; - uint8_t ctrl[32]; - uint8_t rctrl[32]; - int curvol[32]; - int pan_l[32], pan_r[32]; - int t1on,t2on; - uint8_t tctrl; - uint16_t t1,t2,t1l,t2l; - uint8_t irqstatus,irqstatus2; - uint8_t adcommand; - int waveirqs[32],rampirqs[32]; - int voices; - uint8_t dmactrl; + int global; + uint32_t addr, dmaaddr; + int voice; + uint32_t start[32], end[32], cur[32]; + uint32_t startx[32], endx[32], curx[32]; + int rstart[32], rend[32]; + int rcur[32]; + uint16_t freq[32]; + uint16_t rfreq[32]; + uint8_t ctrl[32]; + uint8_t rctrl[32]; + int curvol[32]; + int pan_l[32], pan_r[32]; + int t1on, t2on; + uint8_t tctrl; + uint16_t t1, t2, t1l, t2l; + uint8_t irqstatus, irqstatus2; + uint8_t adcommand; + int waveirqs[32], rampirqs[32]; + int voices; + uint8_t dmactrl; - int32_t out_l, out_r; + int32_t out_l, out_r; - int16_t buffer[2][SOUNDBUFLEN]; - int pos; + int16_t buffer[2][SOUNDBUFLEN]; + int pos; - pc_timer_t samp_timer; - uint64_t samp_latch; + pc_timer_t samp_timer; + uint64_t samp_latch; - uint8_t *ram; - uint32_t gus_end_ram; + uint8_t *ram; + uint32_t gus_end_ram; - int irqnext; + int irqnext; - pc_timer_t timer_1, timer_2; + pc_timer_t timer_1, timer_2; - int irq, dma, irq_midi; - uint16_t base; - int latch_enable; + int irq, dma, irq_midi; + uint16_t base; + int latch_enable; - uint8_t sb_2xa, sb_2xc, sb_2xe; - uint8_t sb_ctrl; - int sb_nmi; + uint8_t sb_2xa, sb_2xc, sb_2xe; + uint8_t sb_ctrl; + int sb_nmi; - uint8_t reg_ctrl; + uint8_t reg_ctrl; - uint8_t ad_status, ad_data; - uint8_t ad_timer_ctrl; + uint8_t ad_status, ad_data; + uint8_t ad_timer_ctrl; - uint8_t midi_ctrl, midi_status, midi_queue[64], midi_data; - int midi_r, midi_w; - int uart_in, uart_out, sysex; + uint8_t midi_ctrl, midi_status, midi_queue[64], midi_data; + int midi_r, midi_w; + int uart_in, uart_out, sysex; - uint8_t gp1, gp2; - uint16_t gp1_addr, gp2_addr; + uint8_t gp1, gp2; + uint16_t gp1_addr, gp2_addr; - uint8_t usrr; + uint8_t usrr; - uint8_t max_ctrl; + uint8_t max_ctrl; #if defined(DEV_BRANCH) && defined(USE_GUSMAX) - ad1848_t ad1848; + ad1848_t ad1848; #endif } gus_t; -static int gus_gf1_irqs[8] = {-1, 2, 5, 3, 7, 11, 12, 15}; -static int gus_midi_irqs[8] = {-1, 2, 5, 3, 7, 11, 12, 15}; -static int gus_dmas[8] = {-1, 1, 3, 5, 6, 7, -1, -1}; +static int gus_gf1_irqs[8] = { -1, 2, 5, 3, 7, 11, 12, 15 }; +static int gus_midi_irqs[8] = { -1, 2, 5, 3, 7, 11, 12, 15 }; +static int gus_dmas[8] = { -1, 1, 3, 5, 6, 7, -1, -1 }; -int gusfreqs[]= -{ - 44100,41160,38587,36317,34300,32494,30870,29400,28063,26843,25725,24696, - 23746,22866,22050,21289,20580,19916,19293 +int gusfreqs[] = { + 44100, 41160, 38587, 36317, 34300, 32494, 30870, 29400, 28063, 26843, 25725, 24696, + 23746, 22866, 22050, 21289, 20580, 19916, 19293 }; double vol16bit[4096]; -void gus_update_int_status(gus_t *gus) +void +gus_update_int_status(gus_t *gus) { - int c; - int irq_pending = 0; - int midi_irq_pending = 0; + int c; + int irq_pending = 0; + int midi_irq_pending = 0; - gus->irqstatus&=~0x60; - gus->irqstatus2=0xE0; - for (c=0;c<32;c++) - { - if (gus->waveirqs[c]) - { - gus->irqstatus2=0x60|c; - if (gus->rampirqs[c]) - gus->irqstatus2 |= 0x80; - gus->irqstatus|=0x20; - irq_pending = 1; - break; - } - if (gus->rampirqs[c]) - { - gus->irqstatus2=0xA0|c; - gus->irqstatus|=0x40; - irq_pending = 1; - break; - } + gus->irqstatus &= ~0x60; + gus->irqstatus2 = 0xE0; + for (c = 0; c < 32; c++) { + if (gus->waveirqs[c]) { + gus->irqstatus2 = 0x60 | c; + if (gus->rampirqs[c]) + gus->irqstatus2 |= 0x80; + gus->irqstatus |= 0x20; + irq_pending = 1; + break; } - if ((gus->tctrl & 4) && (gus->irqstatus & 0x04)) - irq_pending = 1; /*Timer 1 interrupt pending*/ - if ((gus->tctrl & 8) && (gus->irqstatus & 0x08)) - irq_pending = 1; /*Timer 2 interrupt pending*/ - if ((gus->irqstatus & 0x80) && (gus->dmactrl & 0x20)) - irq_pending = 1; /*DMA TC interrupt pending*/ - - midi_irq_pending = gus->midi_status & MIDI_INT_MASTER; - - if (gus->irq == gus->irq_midi && gus->irq != -1) - { - if (irq_pending || midi_irq_pending) - picintlevel(1 << gus->irq); - else - picintc(1 << gus->irq); + if (gus->rampirqs[c]) { + gus->irqstatus2 = 0xA0 | c; + gus->irqstatus |= 0x40; + irq_pending = 1; + break; } + } + if ((gus->tctrl & 4) && (gus->irqstatus & 0x04)) + irq_pending = 1; /*Timer 1 interrupt pending*/ + if ((gus->tctrl & 8) && (gus->irqstatus & 0x08)) + irq_pending = 1; /*Timer 2 interrupt pending*/ + if ((gus->irqstatus & 0x80) && (gus->dmactrl & 0x20)) + irq_pending = 1; /*DMA TC interrupt pending*/ + + midi_irq_pending = gus->midi_status & MIDI_INT_MASTER; + + if (gus->irq == gus->irq_midi && gus->irq != -1) { + if (irq_pending || midi_irq_pending) + picintlevel(1 << gus->irq); else - { - if (gus->irq != -1) - { - if (irq_pending) - picintlevel(1 << gus->irq); - else - picintc(1 << gus->irq); - } - if (gus->irq_midi != -1) - { - if (midi_irq_pending) - picintlevel(1 << gus->irq_midi); - else - picintc(1 << gus->irq_midi); - } + picintc(1 << gus->irq); + } else { + if (gus->irq != -1) { + if (irq_pending) + picintlevel(1 << gus->irq); + else + picintc(1 << gus->irq); } + if (gus->irq_midi != -1) { + if (midi_irq_pending) + picintlevel(1 << gus->irq_midi); + else + picintc(1 << gus->irq_midi); + } + } } -void gus_midi_update_int_status(gus_t *gus) +void +gus_midi_update_int_status(gus_t *gus) { - gus->midi_status &= ~MIDI_INT_MASTER; - if ((gus->midi_ctrl & MIDI_CTRL_TRANSMIT_MASK) == MIDI_CTRL_TRANSMIT && (gus->midi_status & MIDI_INT_TRANSMIT)) - { - gus->midi_status |= MIDI_INT_MASTER; - gus->irqstatus |= GUS_INT_MIDI_TRANSMIT; - } - else - gus->irqstatus &= ~GUS_INT_MIDI_TRANSMIT; + gus->midi_status &= ~MIDI_INT_MASTER; + if ((gus->midi_ctrl & MIDI_CTRL_TRANSMIT_MASK) == MIDI_CTRL_TRANSMIT && (gus->midi_status & MIDI_INT_TRANSMIT)) { + gus->midi_status |= MIDI_INT_MASTER; + gus->irqstatus |= GUS_INT_MIDI_TRANSMIT; + } else + gus->irqstatus &= ~GUS_INT_MIDI_TRANSMIT; - if ((gus->midi_ctrl & MIDI_CTRL_RECEIVE) && (gus->midi_status & MIDI_INT_RECEIVE)) - { - gus->midi_status |= MIDI_INT_MASTER; - gus->irqstatus |= GUS_INT_MIDI_RECEIVE; - } - else - gus->irqstatus &= ~GUS_INT_MIDI_RECEIVE; + if ((gus->midi_ctrl & MIDI_CTRL_RECEIVE) && (gus->midi_status & MIDI_INT_RECEIVE)) { + gus->midi_status |= MIDI_INT_MASTER; + gus->irqstatus |= GUS_INT_MIDI_RECEIVE; + } else + gus->irqstatus &= ~GUS_INT_MIDI_RECEIVE; + gus_update_int_status(gus); +} + +void +writegus(uint16_t addr, uint8_t val, void *p) +{ + gus_t *gus = (gus_t *) p; + int c, d; + int old; + uint16_t port; +#if defined(DEV_BRANCH) && defined(USE_GUSMAX) + uint16_t csioport; +#endif + + if ((addr == 0x388) || (addr == 0x389)) + port = addr; + else + port = addr & 0xf0f; + + switch (port) { + case 0x300: /*MIDI control*/ + old = gus->midi_ctrl; + gus->midi_ctrl = val; + gus->uart_out = 1; + + if ((val & 3) == 3) { /*Master reset*/ + gus->uart_in = 0; + gus->midi_status = 0; + gus->midi_r = 0; + gus->midi_w = 0; + } else if ((old & 3) == 3) { + gus->midi_status |= MIDI_INT_TRANSMIT; + } else if (gus->midi_ctrl & MIDI_CTRL_RECEIVE) { + gus->uart_in = 1; + } + gus_midi_update_int_status(gus); + break; + case 0x301: /*MIDI data*/ + gus->midi_data = val; + if (gus->uart_out) { + midi_raw_out_byte(val); + } + if (gus->latch_enable & 0x20) { + gus->midi_status |= MIDI_INT_RECEIVE; + } else + gus->midi_status |= MIDI_INT_TRANSMIT; + break; + case 0x302: /*Voice select*/ + gus->voice = val & 31; + break; + case 0x303: /*Global select*/ + gus->global = val; + break; + case 0x304: /*Global low*/ + switch (gus->global) { + case 0: /*Voice control*/ + gus->ctrl[gus->voice] = val; + break; + case 1: /*Frequency control*/ + gus->freq[gus->voice] = (gus->freq[gus->voice] & 0xFF00) | val; + break; + case 2: /*Start addr high*/ + gus->startx[gus->voice] = (gus->startx[gus->voice] & 0xF807F) | (val << 7); + gus->start[gus->voice] = (gus->start[gus->voice] & 0x1F00FFFF) | (val << 16); + break; + case 3: /*Start addr low*/ + gus->start[gus->voice] = (gus->start[gus->voice] & 0x1FFFFF00) | val; + break; + case 4: /*End addr high*/ + gus->endx[gus->voice] = (gus->endx[gus->voice] & 0xF807F) | (val << 7); + gus->end[gus->voice] = (gus->end[gus->voice] & 0x1F00FFFF) | (val << 16); + break; + case 5: /*End addr low*/ + gus->end[gus->voice] = (gus->end[gus->voice] & 0x1FFFFF00) | val; + break; + + case 6: /*Ramp frequency*/ + gus->rfreq[gus->voice] = (int) ((double) ((val & 63) * 512) / (double) (1 << (3 * (val >> 6)))); + break; + + case 9: /*Current volume*/ + gus->curvol[gus->voice] = gus->rcur[gus->voice] = (gus->rcur[gus->voice] & ~(0xff << 6)) | (val << 6); + break; + + case 0xA: /*Current addr high*/ + gus->cur[gus->voice] = (gus->cur[gus->voice] & 0x1F00FFFF) | (val << 16); + gus->curx[gus->voice] = (gus->curx[gus->voice] & 0xF807F00) | ((val << 7) << 8); + break; + case 0xB: /*Current addr low*/ + gus->cur[gus->voice] = (gus->cur[gus->voice] & 0x1FFFFF00) | val; + break; + + case 0x42: /*DMA address low*/ + gus->dmaaddr = (gus->dmaaddr & 0xFF000) | (val << 4); + break; + + case 0x43: /*Address low*/ + gus->addr = (gus->addr & 0xFFF00) | val; + break; + case 0x45: /*Timer control*/ + gus->tctrl = val; + gus_update_int_status(gus); + break; + } + break; + case 0x305: /*Global high*/ + switch (gus->global) { + case 0: /*Voice control*/ + gus->ctrl[gus->voice] = val & 0x7f; + + old = gus->waveirqs[gus->voice]; + gus->waveirqs[gus->voice] = ((val & 0xa0) == 0xa0) ? 1 : 0; + if (gus->waveirqs[gus->voice] != old) + gus_update_int_status(gus); + break; + case 1: /*Frequency control*/ + gus->freq[gus->voice] = (gus->freq[gus->voice] & 0xFF) | (val << 8); + break; + case 2: /*Start addr high*/ + gus->startx[gus->voice] = (gus->startx[gus->voice] & 0x07FFF) | (val << 15); + gus->start[gus->voice] = (gus->start[gus->voice] & 0x00FFFFFF) | ((val & 0x1F) << 24); + break; + case 3: /*Start addr low*/ + gus->startx[gus->voice] = (gus->startx[gus->voice] & 0xFFF80) | (val & 0x7F); + gus->start[gus->voice] = (gus->start[gus->voice] & 0x1FFF00FF) | (val << 8); + break; + case 4: /*End addr high*/ + gus->endx[gus->voice] = (gus->endx[gus->voice] & 0x07FFF) | (val << 15); + gus->end[gus->voice] = (gus->end[gus->voice] & 0x00FFFFFF) | ((val & 0x1F) << 24); + break; + case 5: /*End addr low*/ + gus->endx[gus->voice] = (gus->endx[gus->voice] & 0xFFF80) | (val & 0x7F); + gus->end[gus->voice] = (gus->end[gus->voice] & 0x1FFF00FF) | (val << 8); + break; + + case 6: /*Ramp frequency*/ + gus->rfreq[gus->voice] = (int) ((double) ((val & 63) * (1 << 10)) / (double) (1 << (3 * (val >> 6)))); + break; + case 7: /*Ramp start*/ + gus->rstart[gus->voice] = val << 14; + break; + case 8: /*Ramp end*/ + gus->rend[gus->voice] = val << 14; + break; + case 9: /*Current volume*/ + gus->curvol[gus->voice] = gus->rcur[gus->voice] = (gus->rcur[gus->voice] & ~(0xff << 14)) | (val << 14); + break; + + case 0xA: /*Current addr high*/ + gus->cur[gus->voice] = (gus->cur[gus->voice] & 0x00FFFFFF) | ((val & 0x1F) << 24); + gus->curx[gus->voice] = (gus->curx[gus->voice] & 0x07FFF00) | ((val << 15) << 8); + break; + case 0xB: /*Current addr low*/ + gus->cur[gus->voice] = (gus->cur[gus->voice] & 0x1FFF00FF) | (val << 8); + gus->curx[gus->voice] = (gus->curx[gus->voice] & 0xFFF8000) | ((val & 0x7F) << 8); + break; + case 0xC: /*Pan*/ + gus->pan_l[gus->voice] = 15 - (val & 0xf); + gus->pan_r[gus->voice] = (val & 0xf); + break; + case 0xD: /*Ramp control*/ + old = gus->rampirqs[gus->voice]; + gus->rctrl[gus->voice] = val & 0x7F; + gus->rampirqs[gus->voice] = ((val & 0xa0) == 0xa0) ? 1 : 0; + if (gus->rampirqs[gus->voice] != old) + gus_update_int_status(gus); + break; + + case 0xE: + gus->voices = (val & 63) + 1; + if (gus->voices > 32) + gus->voices = 32; + if (gus->voices < 14) + gus->voices = 14; + gus->global = val; + if (gus->voices < 14) + gus->samp_latch = (uint64_t) (TIMER_USEC * (1000000.0 / 44100.0)); + else + gus->samp_latch = (uint64_t) (TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); + break; + + case 0x41: /*DMA*/ + if (val & 1 && gus->dma != -1) { + if (val & 2) { + c = 0; + while (c < 65536) { + int dma_result; + if (val & 0x04) { + uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | ((gus->dmaaddr & 0x1ffff) << 1); + d = gus->ram[gus_addr] | (gus->ram[gus_addr + 1] << 8); + if (val & 0x80) + d ^= 0x8080; + dma_result = dma_channel_write(gus->dma, d); + if (dma_result == DMA_NODATA) + break; + } else { + d = gus->ram[gus->dmaaddr]; + if (val & 0x80) + d ^= 0x80; + dma_result = dma_channel_write(gus->dma, d); + if (dma_result == DMA_NODATA) + break; + } + gus->dmaaddr++; + gus->dmaaddr &= 0xFFFFF; + c++; + if (dma_result & DMA_OVER) + break; + } + gus->dmactrl = val & ~0x40; + gus->irqnext = 1; + } else { + c = 0; + while (c < 65536) { + d = dma_channel_read(gus->dma); + if (d == DMA_NODATA) + break; + if (val & 0x04) { + uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | ((gus->dmaaddr & 0x1ffff) << 1); + if (val & 0x80) + d ^= 0x8080; + gus->ram[gus_addr] = d & 0xff; + gus->ram[gus_addr + 1] = (d >> 8) & 0xff; + } else { + if (val & 0x80) + d ^= 0x80; + gus->ram[gus->dmaaddr] = d; + } + gus->dmaaddr++; + gus->dmaaddr &= 0xFFFFF; + c++; + if (d & DMA_OVER) + break; + } + gus->dmactrl = val & ~0x40; + gus->irqnext = 1; + } + } + break; + + case 0x42: /*DMA address low*/ + gus->dmaaddr = (gus->dmaaddr & 0xFF0) | (val << 12); + break; + + case 0x43: /*Address low*/ + gus->addr = (gus->addr & 0xF00FF) | (val << 8); + break; + case 0x44: /*Address high*/ + gus->addr = (gus->addr & 0xFFFF) | ((val << 16) & 0xF0000); + break; + case 0x45: /*Timer control*/ + if (!(val & 4)) + gus->irqstatus &= ~4; + if (!(val & 8)) + gus->irqstatus &= ~8; + if (!(val & 0x20)) { + gus->ad_status &= ~0x18; + nmi = 0; + } + if (!(val & 0x02)) { + gus->ad_status &= ~0x01; + nmi = 0; + } + gus->tctrl = val; + gus->sb_ctrl = val; + gus_update_int_status(gus); + break; + case 0x46: /*Timer 1*/ + gus->t1 = gus->t1l = val; + gus->t1on = 1; + break; + case 0x47: /*Timer 2*/ + gus->t2 = gus->t2l = val; + gus->t2on = 1; + break; + + case 0x4c: /*Reset*/ + gus->reset = val; + break; + } + break; + case 0x307: /*DRAM access*/ + if (gus->addr < gus->gus_end_ram) + gus->ram[gus->addr] = val; + gus->addr &= 0xFFFFF; + break; + case 0x208: + case 0x388: + gus->adcommand = val; + break; + + case 0x389: + if ((gus->tctrl & GUS_TIMER_CTRL_AUTO) || gus->adcommand != 4) { + gus->ad_data = val; + gus->ad_status |= 0x01; + if (gus->sb_ctrl & 0x02) { + if (gus->sb_nmi) + nmi = 1; + else if (gus->irq != -1) + picint(1 << gus->irq); + } + } else if (!(gus->tctrl & GUS_TIMER_CTRL_AUTO) && gus->adcommand == 4) { + if (val & 0x80) { + gus->ad_status &= ~0x60; + } else { + gus->ad_timer_ctrl = val; + + if (val & 0x01) + gus->t1on = 1; + else + gus->t1 = gus->t1l; + + if (val & 0x02) + gus->t2on = 1; + else + gus->t2 = gus->t2l; + } + } + break; + + case 0x200: + gus->latch_enable = val; + break; + + case 0x20b: + switch (gus->reg_ctrl & 0x07) { + case 0: + if (gus->latch_enable & 0x40) { + gus->irq = gus_gf1_irqs[val & 7]; + + if (val & 0x40) { + if (gus->irq == -1) + gus->irq = gus->irq_midi = gus_gf1_irqs[(val >> 3) & 7]; + else + gus->irq_midi = gus->irq; + } else + gus->irq_midi = gus_midi_irqs[(val >> 3) & 7]; +#if defined(DEV_BRANCH) && defined(USE_GUSMAX) + ad1848_setirq(&gus->ad1848, gus->irq); +#endif + + gus->sb_nmi = val & 0x80; + } else { + gus->dma = gus_dmas[val & 7]; +#if defined(DEV_BRANCH) && defined(USE_GUSMAX) + ad1848_setdma(&gus->ad1848, gus->dma); +#endif + } + break; + case 1: + gus->gp1 = val; + break; + case 2: + gus->gp2 = val; + break; + case 3: + gus->gp1_addr = val; + break; + case 4: + gus->gp2_addr = val; + break; + case 5: + gus->usrr = 0; + break; + case 6: + break; + } + break; + + case 0x206: + gus->ad_status |= 0x08; + if (gus->sb_ctrl & 0x20) { + if (gus->sb_nmi) + nmi = 1; + else if (gus->irq != -1) + picint(1 << gus->irq); + } + break; + case 0x20a: + gus->sb_2xa = val; + break; + case 0x20c: + gus->ad_status |= 0x10; + if (gus->sb_ctrl & 0x20) { + if (gus->sb_nmi) + nmi = 1; + else if (gus->irq != -1) + picint(1 << gus->irq); + } + /*FALLTHROUGH*/ + case 0x20d: + gus->sb_2xc = val; + break; + case 0x20e: + gus->sb_2xe = val; + break; + case 0x20f: + gus->reg_ctrl = val; + break; + case 0x306: + case 0x706: + if (gus->dma >= 4) + val |= 0x30; + gus->max_ctrl = (val >> 6) & 1; +#if defined(DEV_BRANCH) && defined(USE_GUSMAX) + if (val & 0x40) { + if ((val & 0xF) != ((addr >> 4) & 0xF)) { + csioport = 0x30c | ((addr >> 4) & 0xf); + io_removehandler(csioport, 4, + ad1848_read, NULL, NULL, + ad1848_write, NULL, NULL, &gus->ad1848); + csioport = 0x30c | ((val & 0xf) << 4); + io_sethandler(csioport, 4, + ad1848_read, NULL, NULL, + ad1848_write, NULL, NULL, &gus->ad1848); + } + } +#endif + break; + } +} + +uint8_t +readgus(uint16_t addr, void *p) +{ + gus_t *gus = (gus_t *) p; + uint8_t val = 0xff; + uint16_t port; + + if ((addr == 0x388) || (addr == 0x389)) + port = addr; + else + port = addr & 0xf0f; + + switch (port) { + case 0x300: /*MIDI status*/ + val = gus->midi_status; + break; + + case 0x301: /*MIDI data*/ + val = 0; + if (gus->uart_in) { + if ((gus->midi_data == 0xaa) && (gus->midi_ctrl & MIDI_CTRL_RECEIVE)) /*Handle master reset*/ + val = gus->midi_data; + else { + val = gus->midi_queue[gus->midi_r]; + if (gus->midi_r != gus->midi_w) { + gus->midi_r++; + gus->midi_r &= 63; + } + } + gus->midi_status &= ~MIDI_INT_RECEIVE; + gus_midi_update_int_status(gus); + } + break; + + case 0x200: + return 0; + + case 0x206: /*IRQ status*/ + val = gus->irqstatus & ~0x10; + if (gus->ad_status & 0x19) + val |= 0x10; + return val; + + case 0x20F: + if (gus->max_ctrl) + val = 0x02; + else + val = 0x00; + break; + + case 0x302: + return gus->voice; + + case 0x303: + return gus->global; + + case 0x304: /*Global low*/ + switch (gus->global) { + case 0x82: /*Start addr high*/ + return gus->start[gus->voice] >> 16; + case 0x83: /*Start addr low*/ + return gus->start[gus->voice] & 0xFF; + + case 0x89: /*Current volume*/ + return gus->rcur[gus->voice] >> 6; + case 0x8A: /*Current addr high*/ + return gus->cur[gus->voice] >> 16; + case 0x8B: /*Current addr low*/ + return gus->cur[gus->voice] & 0xFF; + + case 0x8F: /*IRQ status*/ + val = gus->irqstatus2; + gus->rampirqs[gus->irqstatus2 & 0x1F] = 0; + gus->waveirqs[gus->irqstatus2 & 0x1F] = 0; + gus_update_int_status(gus); + return val; + + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x07: + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + val = 0xff; + break; + } + break; + case 0x305: /*Global high*/ + switch (gus->global) { + case 0x80: /*Voice control*/ + return gus->ctrl[gus->voice] | (gus->waveirqs[gus->voice] ? 0x80 : 0); + + case 0x82: /*Start addr high*/ + return gus->start[gus->voice] >> 24; + case 0x83: /*Start addr low*/ + return gus->start[gus->voice] >> 8; + + case 0x89: /*Current volume*/ + return gus->rcur[gus->voice] >> 14; + + case 0x8A: /*Current addr high*/ + return gus->cur[gus->voice] >> 24; + case 0x8B: /*Current addr low*/ + return gus->cur[gus->voice] >> 8; + + case 0x8C: /*Pan*/ + return gus->pan_r[gus->voice]; + + case 0x8D: + return gus->rctrl[gus->voice] | (gus->rampirqs[gus->voice] ? 0x80 : 0); + + case 0x8F: /*IRQ status*/ + val = gus->irqstatus2; + gus->rampirqs[gus->irqstatus2 & 0x1F] = 0; + gus->waveirqs[gus->irqstatus2 & 0x1F] = 0; + gus_update_int_status(gus); + return val; + + case 0x41: /*DMA control*/ + val = gus->dmactrl | ((gus->irqstatus & 0x80) ? 0x40 : 0); + gus->irqstatus &= ~0x80; + return val; + case 0x45: /*Timer control*/ + return gus->tctrl; + case 0x49: /*Sampling control*/ + return 0; + + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x07: + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + val = 0xff; + break; + } + break; + case 0x306: + case 0x706: + if (gus->max_ctrl) + val = 0x0a; /* GUS MAX */ + else + val = 0xff; /*Pre 3.7 - no mixer*/ + break; + + break; + case 0x307: /*DRAM access*/ + val = gus->ram[gus->addr]; + gus->addr &= 0xFFFFF; + if (gus->addr < gus->gus_end_ram) + val = gus->ram[gus->addr]; + else + val = 0; + return val; + case 0x309: + return 0; + + case 0x20b: + switch (gus->reg_ctrl & 0x07) { + case 1: + val = gus->gp1; + break; + case 2: + val = gus->gp2; + break; + case 3: + val = gus->gp1_addr; + break; + case 4: + val = gus->gp2_addr; + break; + } + break; + + case 0x20c: + val = gus->sb_2xc; + if (gus->reg_ctrl & 0x20) + gus->sb_2xc &= 0x80; + break; + case 0x20e: + return gus->sb_2xe; + + case 0x208: + case 0x388: + if (gus->tctrl & GUS_TIMER_CTRL_AUTO) + val = gus->sb_2xa; + else { + val = gus->ad_status & ~(gus->ad_timer_ctrl & 0x60); + if (val & 0x60) + val |= 0x80; + } + break; + + case 0x209: + gus->ad_status &= ~0x01; + nmi = 0; + /*FALLTHROUGH*/ + case 0x389: + val = gus->ad_data; + break; + + case 0x20A: + val = gus->adcommand; + break; + } + return val; +} + +void +gus_poll_timer_1(void *p) +{ + gus_t *gus = (gus_t *) p; + + timer_advance_u64(&gus->timer_1, (uint64_t) (TIMER_USEC * 80)); + if (gus->t1on) { + gus->t1++; + if (gus->t1 > 0xFF) { + gus->t1 = gus->t1l; + gus->ad_status |= 0x40; + if (gus->tctrl & 4) { + gus->ad_status |= 0x04; + gus->irqstatus |= 0x04; + } + } + } + if (gus->irqnext) { + gus->irqnext = 0; + gus->irqstatus |= 0x80; + } + + gus_midi_update_int_status(gus); + gus_update_int_status(gus); +} + +void +gus_poll_timer_2(void *p) +{ + gus_t *gus = (gus_t *) p; + + timer_advance_u64(&gus->timer_2, (uint64_t) (TIMER_USEC * 320)); + if (gus->t2on) { + gus->t2++; + if (gus->t2 > 0xFF) { + gus->t2 = gus->t2l; + gus->ad_status |= 0x20; + if (gus->tctrl & 8) { + gus->ad_status |= 0x02; + gus->irqstatus |= 0x08; + } + } + } + if (gus->irqnext) { + gus->irqnext = 0; + gus->irqstatus |= 0x80; + } + gus_update_int_status(gus); +} + +static void +gus_update(gus_t *gus) +{ + for (; gus->pos < sound_pos_global; gus->pos++) { + if (gus->out_l < -32768) + gus->buffer[0][gus->pos] = -32768; + else if (gus->out_l > 32767) + gus->buffer[0][gus->pos] = 32767; + else + gus->buffer[0][gus->pos] = gus->out_l; + if (gus->out_r < -32768) + gus->buffer[1][gus->pos] = -32768; + else if (gus->out_r > 32767) + gus->buffer[1][gus->pos] = 32767; + else + gus->buffer[1][gus->pos] = gus->out_r; + } +} + +void +gus_poll_wave(void *p) +{ + gus_t *gus = (gus_t *) p; + uint32_t addr; + int d; + int16_t v; + int32_t vl; + int update_irqs = 0; + + gus_update(gus); + + timer_advance_u64(&gus->samp_timer, gus->samp_latch); + + gus->out_l = gus->out_r = 0; + + if ((gus->reset & 3) != 3) + return; + for (d = 0; d < 32; d++) { + if (!(gus->ctrl[d] & 3)) { + if (gus->ctrl[d] & 4) { + addr = gus->cur[d] >> 9; + addr = (addr & 0xC0000) | ((addr << 1) & 0x3FFFE); + if (!(gus->freq[d] >> 10)) /*Interpolate*/ + { + vl = (int16_t) (int8_t) ((gus->ram[(addr + 1) & 0xFFFFF] ^ 0x80) - 0x80) * (511 - (gus->cur[d] & 511)); + vl += (int16_t) (int8_t) ((gus->ram[(addr + 3) & 0xFFFFF] ^ 0x80) - 0x80) * (gus->cur[d] & 511); + v = vl >> 9; + } else + v = (int16_t) (int8_t) ((gus->ram[(addr + 1) & 0xFFFFF] ^ 0x80) - 0x80); + } else { + if (!(gus->freq[d] >> 10)) /*Interpolate*/ + { + vl = ((int8_t) ((gus->ram[(gus->cur[d] >> 9) & 0xFFFFF] ^ 0x80) - 0x80)) * (511 - (gus->cur[d] & 511)); + vl += ((int8_t) ((gus->ram[((gus->cur[d] >> 9) + 1) & 0xFFFFF] ^ 0x80) - 0x80)) * (gus->cur[d] & 511); + v = vl >> 9; + } else + v = (int16_t) (int8_t) ((gus->ram[(gus->cur[d] >> 9) & 0xFFFFF] ^ 0x80) - 0x80); + } + + if ((gus->rcur[d] >> 14) > 4095) + v = (int16_t) (float) (v) *24.0 * vol16bit[4095]; + else + v = (int16_t) (float) (v) *24.0 * vol16bit[(gus->rcur[d] >> 10) & 4095]; + + gus->out_l += (v * gus->pan_l[d]) / 7; + gus->out_r += (v * gus->pan_r[d]) / 7; + + if (gus->ctrl[d] & 0x40) { + gus->cur[d] -= (gus->freq[d] >> 1); + if (gus->cur[d] <= gus->start[d]) { + int diff = gus->start[d] - gus->cur[d]; + + if (gus->ctrl[d] & 8) { + if (gus->ctrl[d] & 0x10) + gus->ctrl[d] ^= 0x40; + gus->cur[d] = (gus->ctrl[d] & 0x40) ? (gus->end[d] - diff) : (gus->start[d] + diff); + } else if (!(gus->rctrl[d] & 4)) { + gus->ctrl[d] |= 1; + gus->cur[d] = (gus->ctrl[d] & 0x40) ? gus->end[d] : gus->start[d]; + } + + if ((gus->ctrl[d] & 0x20) && !gus->waveirqs[d]) { + gus->waveirqs[d] = 1; + update_irqs = 1; + } + } + } else { + gus->cur[d] += (gus->freq[d] >> 1); + + if (gus->cur[d] >= gus->end[d]) { + int diff = gus->cur[d] - gus->end[d]; + + if (gus->ctrl[d] & 8) { + if (gus->ctrl[d] & 0x10) + gus->ctrl[d] ^= 0x40; + gus->cur[d] = (gus->ctrl[d] & 0x40) ? (gus->end[d] - diff) : (gus->start[d] + diff); + } else if (!(gus->rctrl[d] & 4)) { + gus->ctrl[d] |= 1; + gus->cur[d] = (gus->ctrl[d] & 0x40) ? gus->end[d] : gus->start[d]; + } + + if ((gus->ctrl[d] & 0x20) && !gus->waveirqs[d]) { + gus->waveirqs[d] = 1; + update_irqs = 1; + } + } + } + } + if (!(gus->rctrl[d] & 3)) { + if (gus->rctrl[d] & 0x40) { + gus->rcur[d] -= gus->rfreq[d]; + if (gus->rcur[d] <= gus->rstart[d]) { + int diff = gus->rstart[d] - gus->rcur[d]; + if (!(gus->rctrl[d] & 8)) { + gus->rctrl[d] |= 1; + gus->rcur[d] = (gus->rctrl[d] & 0x40) ? gus->rstart[d] : gus->rend[d]; + } else { + if (gus->rctrl[d] & 0x10) + gus->rctrl[d] ^= 0x40; + gus->rcur[d] = (gus->rctrl[d] & 0x40) ? (gus->rend[d] - diff) : (gus->rstart[d] + diff); + } + + if ((gus->rctrl[d] & 0x20) && !gus->rampirqs[d]) { + gus->rampirqs[d] = 1; + update_irqs = 1; + } + } + } else { + gus->rcur[d] += gus->rfreq[d]; + if (gus->rcur[d] >= gus->rend[d]) { + int diff = gus->rcur[d] - gus->rend[d]; + if (!(gus->rctrl[d] & 8)) { + gus->rctrl[d] |= 1; + gus->rcur[d] = (gus->rctrl[d] & 0x40) ? gus->rstart[d] : gus->rend[d]; + } else { + if (gus->rctrl[d] & 0x10) + gus->rctrl[d] ^= 0x40; + gus->rcur[d] = (gus->rctrl[d] & 0x40) ? (gus->rend[d] - diff) : (gus->rstart[d] + diff); + } + + if ((gus->rctrl[d] & 0x20) && !gus->rampirqs[d]) { + gus->rampirqs[d] = 1; + update_irqs = 1; + } + } + } + } + } + + if (update_irqs) gus_update_int_status(gus); } -void writegus(uint16_t addr, uint8_t val, void *p) +static void +gus_get_buffer(int32_t *buffer, int len, void *p) { - gus_t *gus = (gus_t *)p; - int c, d; - int old; - uint16_t port; -#if defined(DEV_BRANCH) && defined(USE_GUSMAX) - uint16_t csioport; -#endif - - if ((addr == 0x388) || (addr == 0x389)) - port = addr; - else - port = addr & 0xf0f; - - switch (port) - { - case 0x300: /*MIDI control*/ - old = gus->midi_ctrl; - gus->midi_ctrl = val; - gus->uart_out = 1; - - if ((val & 3) == 3) { /*Master reset*/ - gus->uart_in = 0; - gus->midi_status = 0; - gus->midi_r = 0; - gus->midi_w = 0; - } else if ((old & 3) == 3) { - gus->midi_status |= MIDI_INT_TRANSMIT; - } else if (gus->midi_ctrl & MIDI_CTRL_RECEIVE) { - gus->uart_in = 1; - } - gus_midi_update_int_status(gus); - break; - case 0x301: /*MIDI data*/ - gus->midi_data = val; - if (gus->uart_out) { - midi_raw_out_byte(val); - } - if (gus->latch_enable & 0x20) { - gus->midi_status |= MIDI_INT_RECEIVE; - } else - gus->midi_status |= MIDI_INT_TRANSMIT; - break; - case 0x302: /*Voice select*/ - gus->voice=val&31; - break; - case 0x303: /*Global select*/ - gus->global=val; - break; - case 0x304: /*Global low*/ - switch (gus->global) - { - case 0: /*Voice control*/ - gus->ctrl[gus->voice]=val; - break; - case 1: /*Frequency control*/ - gus->freq[gus->voice]=(gus->freq[gus->voice]&0xFF00)|val; - break; - case 2: /*Start addr high*/ - gus->startx[gus->voice]=(gus->startx[gus->voice]&0xF807F)|(val<<7); - gus->start[gus->voice]=(gus->start[gus->voice]&0x1F00FFFF)|(val<<16); - break; - case 3: /*Start addr low*/ - gus->start[gus->voice]=(gus->start[gus->voice]&0x1FFFFF00)|val; - break; - case 4: /*End addr high*/ - gus->endx[gus->voice]=(gus->endx[gus->voice]&0xF807F)|(val<<7); - gus->end[gus->voice]=(gus->end[gus->voice]&0x1F00FFFF)|(val<<16); - break; - case 5: /*End addr low*/ - gus->end[gus->voice]=(gus->end[gus->voice]&0x1FFFFF00)|val; - break; - - case 6: /*Ramp frequency*/ - gus->rfreq[gus->voice] = (int)( (double)((val & 63)*512)/(double)(1 << (3*(val >> 6)))); - break; - - case 9: /*Current volume*/ - gus->curvol[gus->voice] = gus->rcur[gus->voice] = (gus->rcur[gus->voice] & ~(0xff << 6)) | (val << 6); - break; - - case 0xA: /*Current addr high*/ - gus->cur[gus->voice]=(gus->cur[gus->voice]&0x1F00FFFF)|(val<<16); -gus->curx[gus->voice]=(gus->curx[gus->voice]&0xF807F00)|((val<<7)<<8); - break; - case 0xB: /*Current addr low*/ - gus->cur[gus->voice]=(gus->cur[gus->voice]&0x1FFFFF00)|val; - break; - - case 0x42: /*DMA address low*/ - gus->dmaaddr=(gus->dmaaddr&0xFF000)|(val<<4); - break; - - case 0x43: /*Address low*/ - gus->addr=(gus->addr&0xFFF00)|val; - break; - case 0x45: /*Timer control*/ - gus->tctrl=val; - gus_update_int_status(gus); - break; - } - break; - case 0x305: /*Global high*/ - switch (gus->global) - { - case 0: /*Voice control*/ - gus->ctrl[gus->voice] = val & 0x7f; - - old = gus->waveirqs[gus->voice]; - gus->waveirqs[gus->voice] = ((val & 0xa0) == 0xa0) ? 1 : 0; - if (gus->waveirqs[gus->voice] != old) - gus_update_int_status(gus); - break; - case 1: /*Frequency control*/ - gus->freq[gus->voice]=(gus->freq[gus->voice]&0xFF)|(val<<8); - break; - case 2: /*Start addr high*/ - gus->startx[gus->voice]=(gus->startx[gus->voice]&0x07FFF)|(val<<15); - gus->start[gus->voice]=(gus->start[gus->voice]&0x00FFFFFF)|((val&0x1F)<<24); - break; - case 3: /*Start addr low*/ - gus->startx[gus->voice]=(gus->startx[gus->voice]&0xFFF80)|(val&0x7F); - gus->start[gus->voice]=(gus->start[gus->voice]&0x1FFF00FF)|(val<<8); - break; - case 4: /*End addr high*/ - gus->endx[gus->voice]=(gus->endx[gus->voice]&0x07FFF)|(val<<15); - gus->end[gus->voice]=(gus->end[gus->voice]&0x00FFFFFF)|((val&0x1F)<<24); - break; - case 5: /*End addr low*/ - gus->endx[gus->voice]=(gus->endx[gus->voice]&0xFFF80)|(val&0x7F); - gus->end[gus->voice]=(gus->end[gus->voice]&0x1FFF00FF)|(val<<8); - break; - - case 6: /*Ramp frequency*/ - gus->rfreq[gus->voice] = (int)( (double)((val & 63) * (1 << 10))/(double)(1 << (3 * (val >> 6)))); - break; - case 7: /*Ramp start*/ - gus->rstart[gus->voice] = val << 14; - break; - case 8: /*Ramp end*/ - gus->rend[gus->voice] = val << 14; - break; - case 9: /*Current volume*/ - gus->curvol[gus->voice] = gus->rcur[gus->voice] = (gus->rcur[gus->voice] & ~(0xff << 14)) | (val << 14); - break; - - case 0xA: /*Current addr high*/ - gus->cur[gus->voice]=(gus->cur[gus->voice]&0x00FFFFFF)|((val&0x1F)<<24); - gus->curx[gus->voice]=(gus->curx[gus->voice]&0x07FFF00)|((val<<15)<<8); - break; - case 0xB: /*Current addr low*/ - gus->cur[gus->voice]=(gus->cur[gus->voice]&0x1FFF00FF)|(val<<8); -gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); - break; - case 0xC: /*Pan*/ - gus->pan_l[gus->voice] = 15 - (val & 0xf); - gus->pan_r[gus->voice] = (val & 0xf); - break; - case 0xD: /*Ramp control*/ - old = gus->rampirqs[gus->voice]; - gus->rctrl[gus->voice] = val & 0x7F; - gus->rampirqs[gus->voice] = ((val & 0xa0) == 0xa0) ? 1 : 0; - if (gus->rampirqs[gus->voice] != old) - gus_update_int_status(gus); - break; - - case 0xE: - gus->voices=(val&63)+1; - if (gus->voices>32) gus->voices=32; - if (gus->voices<14) gus->voices=14; - gus->global=val; - if (gus->voices < 14) - gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / 44100.0)); - else - gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); - break; - - case 0x41: /*DMA*/ - if (val&1 && gus->dma != -1) - { - if (val & 2) - { - c=0; - while (c<65536) - { - int dma_result; - if (val & 0x04) - { - uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | ((gus->dmaaddr & 0x1ffff) << 1); - d = gus->ram[gus_addr] | (gus->ram[gus_addr + 1] << 8); - if (val & 0x80) - d ^= 0x8080; - dma_result = dma_channel_write(gus->dma, d); - if (dma_result == DMA_NODATA) - break; - } - else - { - d = gus->ram[gus->dmaaddr]; - if (val & 0x80) - d ^= 0x80; - dma_result = dma_channel_write(gus->dma, d); - if (dma_result == DMA_NODATA) - break; - } - gus->dmaaddr++; - gus->dmaaddr &= 0xFFFFF; - c++; - if (dma_result & DMA_OVER) - break; - } - gus->dmactrl=val&~0x40; - gus->irqnext=1; - } - else - { - c=0; - while (c<65536) - { - d = dma_channel_read(gus->dma); - if (d == DMA_NODATA) - break; - if (val & 0x04) - { - uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | ((gus->dmaaddr & 0x1ffff) << 1); - if (val & 0x80) - d ^= 0x8080; - gus->ram[gus_addr] = d & 0xff; - gus->ram[gus_addr +1] = (d >> 8) & 0xff; - } - else - { - if (val & 0x80) - d ^= 0x80; - gus->ram[gus->dmaaddr] = d; - } - gus->dmaaddr++; - gus->dmaaddr &= 0xFFFFF; - c++; - if (d & DMA_OVER) - break; - } - gus->dmactrl=val&~0x40; - gus->irqnext=1; - } - } - break; - - case 0x42: /*DMA address low*/ - gus->dmaaddr=(gus->dmaaddr&0xFF0)|(val<<12); - break; - - case 0x43: /*Address low*/ - gus->addr=(gus->addr&0xF00FF)|(val<<8); - break; - case 0x44: /*Address high*/ - gus->addr=(gus->addr&0xFFFF)|((val<<16)&0xF0000); - break; - case 0x45: /*Timer control*/ - if (!(val&4)) gus->irqstatus&=~4; - if (!(val&8)) gus->irqstatus&=~8; - if (!(val & 0x20)) - { - gus->ad_status &= ~0x18; - nmi = 0; - } - if (!(val & 0x02)) - { - gus->ad_status &= ~0x01; - nmi = 0; - } - gus->tctrl=val; - gus->sb_ctrl = val; - gus_update_int_status(gus); - break; - case 0x46: /*Timer 1*/ - gus->t1 = gus->t1l = val; - gus->t1on = 1; - break; - case 0x47: /*Timer 2*/ - gus->t2 = gus->t2l = val; - gus->t2on = 1; - break; - - case 0x4c: /*Reset*/ - gus->reset = val; - break; - } - break; - case 0x307: /*DRAM access*/ - if (gus->addr < gus->gus_end_ram) - gus->ram[gus->addr]=val; - gus->addr&=0xFFFFF; - break; - case 0x208: case 0x388: - gus->adcommand = val; - break; - - case 0x389: - if ((gus->tctrl & GUS_TIMER_CTRL_AUTO) || gus->adcommand != 4) - { - gus->ad_data = val; - gus->ad_status |= 0x01; - if (gus->sb_ctrl & 0x02) - { - if (gus->sb_nmi) - nmi = 1; - else if (gus->irq != -1) - picint(1 << gus->irq); - } - } - else if (!(gus->tctrl & GUS_TIMER_CTRL_AUTO) && gus->adcommand == 4) - { - if (val & 0x80) - { - gus->ad_status &= ~0x60; - } - else - { - gus->ad_timer_ctrl = val; - - if (val & 0x01) - gus->t1on = 1; - else - gus->t1 = gus->t1l; - - if (val & 0x02) - gus->t2on = 1; - else - gus->t2 = gus->t2l; - } - } - break; - - case 0x200: - gus->latch_enable = val; - break; - - case 0x20b: - switch (gus->reg_ctrl & 0x07) - { - case 0: - if (gus->latch_enable & 0x40) { - gus->irq = gus_gf1_irqs[val & 7]; - - if (val & 0x40) - { - if (gus->irq == -1) - gus->irq = gus->irq_midi = gus_gf1_irqs[(val >> 3) & 7]; - else - gus->irq_midi = gus->irq; - } - else - gus->irq_midi = gus_midi_irqs[(val >> 3) & 7]; -#if defined(DEV_BRANCH) && defined(USE_GUSMAX) - ad1848_setirq(&gus->ad1848, gus->irq); -#endif - - gus->sb_nmi = val & 0x80; - } else { - gus->dma = gus_dmas[val & 7]; -#if defined(DEV_BRANCH) && defined(USE_GUSMAX) - ad1848_setdma(&gus->ad1848, gus->dma); -#endif - } - break; - case 1: - gus->gp1 = val; - break; - case 2: - gus->gp2 = val; - break; - case 3: - gus->gp1_addr = val; - break; - case 4: - gus->gp2_addr = val; - break; - case 5: - gus->usrr = 0; - break; - case 6: - break; - } - break; - - case 0x206: - gus->ad_status |= 0x08; - if (gus->sb_ctrl & 0x20) - { - if (gus->sb_nmi) - nmi = 1; - else if (gus->irq != -1) - picint(1 << gus->irq); - } - break; - case 0x20a: - gus->sb_2xa = val; - break; - case 0x20c: - gus->ad_status |= 0x10; - if (gus->sb_ctrl & 0x20) - { - if (gus->sb_nmi) - nmi = 1; - else if (gus->irq != -1) - picint(1 << gus->irq); - } - /*FALLTHROUGH*/ - case 0x20d: - gus->sb_2xc = val; - break; - case 0x20e: - gus->sb_2xe = val; - break; - case 0x20f: - gus->reg_ctrl = val; - break; - case 0x306: case 0x706: - if (gus->dma >= 4) - val |= 0x30; - gus->max_ctrl = (val >> 6) & 1; -#if defined(DEV_BRANCH) && defined(USE_GUSMAX) - if (val & 0x40) { - if ((val & 0xF) != ((addr >> 4) & 0xF)) { - csioport = 0x30c | ((addr >> 4) & 0xf); - io_removehandler(csioport, 4, - ad1848_read,NULL,NULL, - ad1848_write,NULL,NULL,&gus->ad1848); - csioport = 0x30c | ((val & 0xf) << 4); - io_sethandler(csioport, 4, - ad1848_read,NULL,NULL, - ad1848_write,NULL,NULL, &gus->ad1848); - } - } -#endif - break; - } -} - - -uint8_t readgus(uint16_t addr, void *p) -{ - gus_t *gus = (gus_t *)p; - uint8_t val = 0xff; - uint16_t port; - - if ((addr == 0x388) || (addr == 0x389)) - port = addr; - else - port = addr & 0xf0f; - - switch (port) - { - case 0x300: /*MIDI status*/ - val = gus->midi_status; - break; - - case 0x301: /*MIDI data*/ - val = 0; - if (gus->uart_in) { - if ((gus->midi_data == 0xaa) && (gus->midi_ctrl & MIDI_CTRL_RECEIVE)) /*Handle master reset*/ - val = gus->midi_data; - else { - val = gus->midi_queue[gus->midi_r]; - if (gus->midi_r != gus->midi_w) { - gus->midi_r++; - gus->midi_r &= 63; - } - } - gus->midi_status &= ~MIDI_INT_RECEIVE; - gus_midi_update_int_status(gus); - } - break; - - case 0x200: - return 0; - - case 0x206: /*IRQ status*/ - val = gus->irqstatus & ~0x10; - if (gus->ad_status & 0x19) - val |= 0x10; - return val; - - case 0x20F: - if (gus->max_ctrl) - val = 0x02; - else - val = 0x00; - break; - - case 0x302: - return gus->voice; - - case 0x303: - return gus->global; - - case 0x304: /*Global low*/ - switch (gus->global) - { - case 0x82: /*Start addr high*/ - return gus->start[gus->voice]>>16; - case 0x83: /*Start addr low*/ - return gus->start[gus->voice]&0xFF; - - case 0x89: /*Current volume*/ - return gus->rcur[gus->voice]>>6; - case 0x8A: /*Current addr high*/ - return gus->cur[gus->voice]>>16; - case 0x8B: /*Current addr low*/ - return gus->cur[gus->voice]&0xFF; - - case 0x8F: /*IRQ status*/ - val=gus->irqstatus2; - gus->rampirqs[gus->irqstatus2&0x1F]=0; - gus->waveirqs[gus->irqstatus2&0x1F]=0; - gus_update_int_status(gus); - return val; - - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x04: case 0x05: case 0x06: case 0x07: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0c: case 0x0d: case 0x0e: case 0x0f: - val = 0xff; - break; - } - break; - case 0x305: /*Global high*/ - switch (gus->global) - { - case 0x80: /*Voice control*/ - return gus->ctrl[gus->voice]|(gus->waveirqs[gus->voice]?0x80:0); - - case 0x82: /*Start addr high*/ - return gus->start[gus->voice]>>24; - case 0x83: /*Start addr low*/ - return gus->start[gus->voice]>>8; - - case 0x89: /*Current volume*/ - return gus->rcur[gus->voice]>>14; - - case 0x8A: /*Current addr high*/ - return gus->cur[gus->voice]>>24; - case 0x8B: /*Current addr low*/ - return gus->cur[gus->voice]>>8; - - case 0x8C: /*Pan*/ - return gus->pan_r[gus->voice]; - - case 0x8D: - return gus->rctrl[gus->voice]|(gus->rampirqs[gus->voice]?0x80:0); - - case 0x8F: /*IRQ status*/ - val=gus->irqstatus2; - gus->rampirqs[gus->irqstatus2&0x1F]=0; - gus->waveirqs[gus->irqstatus2&0x1F]=0; - gus_update_int_status(gus); - return val; - - case 0x41: /*DMA control*/ - val=gus->dmactrl|((gus->irqstatus&0x80)?0x40:0); - gus->irqstatus&=~0x80; - return val; - case 0x45: /*Timer control*/ - return gus->tctrl; - case 0x49: /*Sampling control*/ - return 0; - - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x04: case 0x05: case 0x06: case 0x07: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0c: case 0x0d: case 0x0e: case 0x0f: - val = 0xff; - break; - } - break; - case 0x306: case 0x706: - if (gus->max_ctrl) - val = 0x0a; /* GUS MAX */ - else - val = 0xff; /*Pre 3.7 - no mixer*/ - break; - - break; - case 0x307: /*DRAM access*/ - val=gus->ram[gus->addr]; - gus->addr&=0xFFFFF; - if (gus->addr < gus->gus_end_ram) - val = gus->ram[gus->addr]; - else - val = 0; - return val; - case 0x309: return 0; - - case 0x20b: - switch (gus->reg_ctrl & 0x07) - { - case 1: - val = gus->gp1; - break; - case 2: - val = gus->gp2; - break; - case 3: - val = gus->gp1_addr; - break; - case 4: - val = gus->gp2_addr; - break; - } - break; - - case 0x20c: - val = gus->sb_2xc; - if (gus->reg_ctrl & 0x20) - gus->sb_2xc &= 0x80; - break; - case 0x20e: - return gus->sb_2xe; - - case 0x208: case 0x388: - if (gus->tctrl & GUS_TIMER_CTRL_AUTO) - val = gus->sb_2xa; - else - { - val = gus->ad_status & ~(gus->ad_timer_ctrl & 0x60); - if (val & 0x60) - val |= 0x80; - } - break; - - case 0x209: - gus->ad_status &= ~0x01; - nmi = 0; - /*FALLTHROUGH*/ - case 0x389: - val = gus->ad_data; - break; - - case 0x20A: - val = gus->adcommand; - break; - - } - return val; -} - -void gus_poll_timer_1(void *p) -{ - gus_t *gus = (gus_t *)p; - - timer_advance_u64(&gus->timer_1, (uint64_t)(TIMER_USEC * 80)); - if (gus->t1on) - { - gus->t1++; - if (gus->t1 > 0xFF) - { - gus->t1=gus->t1l; - gus->ad_status |= 0x40; - if (gus->tctrl&4) - { - gus->ad_status |= 0x04; - gus->irqstatus |= 0x04; - } - } - } - if (gus->irqnext) - { - gus->irqnext=0; - gus->irqstatus|=0x80; - } - - gus_midi_update_int_status(gus); - gus_update_int_status(gus); -} - -void gus_poll_timer_2(void *p) -{ - gus_t *gus = (gus_t *)p; - - timer_advance_u64(&gus->timer_2, (uint64_t)(TIMER_USEC * 320)); - if (gus->t2on) - { - gus->t2++; - if (gus->t2 > 0xFF) - { - gus->t2=gus->t2l; - gus->ad_status |= 0x20; - if (gus->tctrl&8) - { - gus->ad_status |= 0x02; - gus->irqstatus |= 0x08; - } - } - } - if (gus->irqnext) - { - gus->irqnext=0; - gus->irqstatus|=0x80; - } - gus_update_int_status(gus); -} - -static void gus_update(gus_t *gus) -{ - for (; gus->pos < sound_pos_global; gus->pos++) - { - if (gus->out_l < -32768) - gus->buffer[0][gus->pos] = -32768; - else if (gus->out_l > 32767) - gus->buffer[0][gus->pos] = 32767; - else - gus->buffer[0][gus->pos] = gus->out_l; - if (gus->out_r < -32768) - gus->buffer[1][gus->pos] = -32768; - else if (gus->out_r > 32767) - gus->buffer[1][gus->pos] = 32767; - else - gus->buffer[1][gus->pos] = gus->out_r; - } -} - -void gus_poll_wave(void *p) -{ - gus_t *gus = (gus_t *)p; - uint32_t addr; - int d; - int16_t v; - int32_t vl; - int update_irqs = 0; - - gus_update(gus); - - timer_advance_u64(&gus->samp_timer, gus->samp_latch); - - gus->out_l = gus->out_r = 0; - - if ((gus->reset & 3) != 3) - return; - for (d=0;d<32;d++) - { - if (!(gus->ctrl[d] & 3)) - { - if (gus->ctrl[d] & 4) - { - addr = gus->cur[d] >> 9; - addr = (addr & 0xC0000) | ((addr << 1) & 0x3FFFE); - if (!(gus->freq[d] >> 10)) /*Interpolate*/ - { - vl = (int16_t)(int8_t)((gus->ram[(addr + 1) & 0xFFFFF] ^ 0x80) - 0x80) * (511 - (gus->cur[d] & 511)); - vl += (int16_t)(int8_t)((gus->ram[(addr + 3) & 0xFFFFF] ^ 0x80) - 0x80) * (gus->cur[d] & 511); - v = vl >> 9; - } - else - v = (int16_t)(int8_t)((gus->ram[(addr + 1) & 0xFFFFF] ^ 0x80) - 0x80); - } - else - { - if (!(gus->freq[d] >> 10)) /*Interpolate*/ - { - vl = ((int8_t)((gus->ram[(gus->cur[d] >> 9) & 0xFFFFF] ^ 0x80) - 0x80)) * (511 - (gus->cur[d] & 511)); - vl += ((int8_t)((gus->ram[((gus->cur[d] >> 9) + 1) & 0xFFFFF] ^ 0x80) - 0x80)) * (gus->cur[d] & 511); - v = vl >> 9; - } - else - v = (int16_t)(int8_t)((gus->ram[(gus->cur[d] >> 9) & 0xFFFFF] ^ 0x80) - 0x80); - } - - if ((gus->rcur[d] >> 14) > 4095) v = (int16_t)(float)(v) * 24.0 * vol16bit[4095]; - else v = (int16_t)(float)(v) * 24.0 * vol16bit[(gus->rcur[d]>>10) & 4095]; - - gus->out_l += (v * gus->pan_l[d]) / 7; - gus->out_r += (v * gus->pan_r[d]) / 7; - - if (gus->ctrl[d]&0x40) - { - gus->cur[d] -= (gus->freq[d] >> 1); - if (gus->cur[d] <= gus->start[d]) - { - int diff = gus->start[d] - gus->cur[d]; - - if (gus->ctrl[d]&8) - { - if (gus->ctrl[d]&0x10) gus->ctrl[d]^=0x40; - gus->cur[d] = (gus->ctrl[d] & 0x40) ? (gus->end[d] - diff) : (gus->start[d] + diff); - } - else if (!(gus->rctrl[d]&4)) - { - gus->ctrl[d] |= 1; - gus->cur[d] = (gus->ctrl[d] & 0x40) ? gus->end[d] : gus->start[d]; - } - - if ((gus->ctrl[d] & 0x20) && !gus->waveirqs[d]) - { - gus->waveirqs[d] = 1; - update_irqs = 1; - } - } - } - else - { - gus->cur[d] += (gus->freq[d] >> 1); - - if (gus->cur[d] >= gus->end[d]) - { - int diff = gus->cur[d] - gus->end[d]; - - if (gus->ctrl[d]&8) - { - if (gus->ctrl[d]&0x10) gus->ctrl[d]^=0x40; - gus->cur[d] = (gus->ctrl[d] & 0x40) ? (gus->end[d] - diff) : (gus->start[d] + diff); - } - else if (!(gus->rctrl[d]&4)) - { - gus->ctrl[d] |= 1; - gus->cur[d] = (gus->ctrl[d] & 0x40) ? gus->end[d] : gus->start[d]; - } - - if ((gus->ctrl[d] & 0x20) && !gus->waveirqs[d]) - { - gus->waveirqs[d] = 1; - update_irqs = 1; - } - } - } - } - if (!(gus->rctrl[d] & 3)) - { - if (gus->rctrl[d] & 0x40) - { - gus->rcur[d] -= gus->rfreq[d]; - if (gus->rcur[d] <= gus->rstart[d]) - { - int diff = gus->rstart[d] - gus->rcur[d]; - if (!(gus->rctrl[d] & 8)) - { - gus->rctrl[d] |= 1; - gus->rcur[d] = (gus->rctrl[d] & 0x40) ? gus->rstart[d] : gus->rend[d]; - } - else - { - if (gus->rctrl[d] & 0x10) gus->rctrl[d] ^= 0x40; - gus->rcur[d] = (gus->rctrl[d] & 0x40) ? (gus->rend[d] - diff) : (gus->rstart[d] + diff); - } - - if ((gus->rctrl[d] & 0x20) && !gus->rampirqs[d]) - { - gus->rampirqs[d] = 1; - update_irqs = 1; - } - } - } - else - { - gus->rcur[d] += gus->rfreq[d]; - if (gus->rcur[d] >= gus->rend[d]) - { - int diff = gus->rcur[d] - gus->rend[d]; - if (!(gus->rctrl[d] & 8)) - { - gus->rctrl[d] |= 1; - gus->rcur[d] = (gus->rctrl[d] & 0x40) ? gus->rstart[d] : gus->rend[d]; - } - else - { - if (gus->rctrl[d] & 0x10) gus->rctrl[d] ^= 0x40; - gus->rcur[d] = (gus->rctrl[d] & 0x40) ? (gus->rend[d] - diff) : (gus->rstart[d] + diff); - } - - if ((gus->rctrl[d] & 0x20) && !gus->rampirqs[d]) - { - gus->rampirqs[d] = 1; - update_irqs = 1; - } - } - } - } - } - - if (update_irqs) - gus_update_int_status(gus); -} - -static void gus_get_buffer(int32_t *buffer, int len, void *p) -{ - gus_t *gus = (gus_t *)p; - int c; - -#if defined(DEV_BRANCH) && defined(USE_GUSMAX) - if (gus->max_ctrl) - ad1848_update(&gus->ad1848); -#endif - gus_update(gus); - - for (c = 0; c < len * 2; c++) - { -#if defined(DEV_BRANCH) && defined(USE_GUSMAX) - if (gus->max_ctrl) - buffer[c] += (int32_t)(gus->ad1848.buffer[c] / 2); -#endif - buffer[c] += (int32_t)gus->buffer[c & 1][c >> 1]; - } + gus_t *gus = (gus_t *) p; + int c; #if defined(DEV_BRANCH) && defined(USE_GUSMAX) if (gus->max_ctrl) - gus->ad1848.pos = 0; + ad1848_update(&gus->ad1848); #endif - gus->pos = 0; -} - -static void gus_input_msg(void *p, uint8_t *msg, uint32_t len) -{ - gus_t *gus = (gus_t *)p; - uint8_t i; - - if (gus->sysex) - return; - - if (gus->uart_in) { - gus->midi_status |= MIDI_INT_RECEIVE; - - for (i=0; i < len; i++) { - gus->midi_queue[gus->midi_w++] = msg[i]; - gus->midi_w &= 63; - } - - gus_midi_update_int_status(gus); - } -} - -static int gus_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort) -{ - gus_t *gus = (gus_t *)p; - uint32_t i; - - if (abort) { - gus->sysex = 0; - return 0; - } - gus->sysex = 1; - for (i=0;imidi_r == gus->midi_w) - return (len-i); - gus->midi_queue[gus->midi_w++] = buffer[i]; - gus->midi_w &= 63; - } - gus->sysex = 0; - return 0; -} - -void *gus_init(const device_t *info) -{ - int c; - double out = 1.0; - uint8_t gus_ram = device_get_config_int("gus_ram"); - gus_t *gus = malloc(sizeof(gus_t)); - memset(gus, 0, sizeof(gus_t)); - - gus->gus_end_ram = 1 << (18 + gus_ram); - gus->ram = (uint8_t *)malloc(gus->gus_end_ram); - memset(gus->ram, 0x00, (gus->gus_end_ram)); - - for (c=0;c<32;c++) - { - gus->ctrl[c]=1; - gus->rctrl[c]=1; - gus->rfreq[c]=63*512; - } - - for (c=4095;c>=0;c--) { - vol16bit[c]=out; - out/=1.002709201; /* 0.0235 dB Steps */ - } - - gus->voices=14; - - gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / 44100.0)); - - gus->t1l = gus->t2l = 0xff; - - gus->uart_out = 1; - - gus->base = device_get_config_hex16("base"); - - io_sethandler(gus->base, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL, gus); - io_sethandler(0x0100+gus->base, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL, gus); - io_sethandler(0x0506+gus->base, 0x0001, readgus, NULL, NULL, writegus, NULL, NULL, gus); - io_sethandler(0x0388, 0x0002, readgus, NULL, NULL, writegus, NULL, NULL, gus); - -#if defined(DEV_BRANCH) && defined(USE_GUSMAX) - ad1848_init(&gus->ad1848, AD1848_TYPE_CS4231); - ad1848_setirq(&gus->ad1848, 5); - ad1848_setdma(&gus->ad1848, 3); - io_sethandler(0x10C+gus->base, 4, - ad1848_read,NULL,NULL, ad1848_write,NULL,NULL, &gus->ad1848); -#endif - - timer_add(&gus->samp_timer, gus_poll_wave, gus, 1); - timer_add(&gus->timer_1, gus_poll_timer_1, gus, 1); - timer_add(&gus->timer_2, gus_poll_timer_2, gus, 1); - - sound_add_handler(gus_get_buffer, gus); - - if (device_get_config_int("receive_input")) - midi_in_handler(1, gus_input_msg, gus_input_sysex, gus); - - return gus; -} - -void gus_close(void *p) -{ - gus_t *gus = (gus_t *)p; - - free(gus->ram); - free(gus); -} - -void gus_speed_changed(void *p) -{ - gus_t *gus = (gus_t *)p; - - if (gus->voices < 14) - gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / 44100.0)); - else - gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); + gus_update(gus); + for (c = 0; c < len * 2; c++) { #if defined(DEV_BRANCH) && defined(USE_GUSMAX) if (gus->max_ctrl) - ad1848_speed_changed(&gus->ad1848); + buffer[c] += (int32_t) (gus->ad1848.buffer[c] / 2); +#endif + buffer[c] += (int32_t) gus->buffer[c & 1][c >> 1]; + } + +#if defined(DEV_BRANCH) && defined(USE_GUSMAX) + if (gus->max_ctrl) + gus->ad1848.pos = 0; +#endif + gus->pos = 0; +} + +static void +gus_input_msg(void *p, uint8_t *msg, uint32_t len) +{ + gus_t *gus = (gus_t *) p; + uint8_t i; + + if (gus->sysex) + return; + + if (gus->uart_in) { + gus->midi_status |= MIDI_INT_RECEIVE; + + for (i = 0; i < len; i++) { + gus->midi_queue[gus->midi_w++] = msg[i]; + gus->midi_w &= 63; + } + + gus_midi_update_int_status(gus); + } +} + +static int +gus_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort) +{ + gus_t *gus = (gus_t *) p; + uint32_t i; + + if (abort) { + gus->sysex = 0; + return 0; + } + gus->sysex = 1; + for (i = 0; i < len; i++) { + if (gus->midi_r == gus->midi_w) + return (len - i); + gus->midi_queue[gus->midi_w++] = buffer[i]; + gus->midi_w &= 63; + } + gus->sysex = 0; + return 0; +} + +void * +gus_init(const device_t *info) +{ + int c; + double out = 1.0; + uint8_t gus_ram = device_get_config_int("gus_ram"); + gus_t *gus = malloc(sizeof(gus_t)); + memset(gus, 0, sizeof(gus_t)); + + gus->gus_end_ram = 1 << (18 + gus_ram); + gus->ram = (uint8_t *) malloc(gus->gus_end_ram); + memset(gus->ram, 0x00, (gus->gus_end_ram)); + + for (c = 0; c < 32; c++) { + gus->ctrl[c] = 1; + gus->rctrl[c] = 1; + gus->rfreq[c] = 63 * 512; + } + + for (c = 4095; c >= 0; c--) { + vol16bit[c] = out; + out /= 1.002709201; /* 0.0235 dB Steps */ + } + + gus->voices = 14; + + gus->samp_latch = (uint64_t) (TIMER_USEC * (1000000.0 / 44100.0)); + + gus->t1l = gus->t2l = 0xff; + + gus->uart_out = 1; + + gus->base = device_get_config_hex16("base"); + + io_sethandler(gus->base, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL, gus); + io_sethandler(0x0100 + gus->base, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL, gus); + io_sethandler(0x0506 + gus->base, 0x0001, readgus, NULL, NULL, writegus, NULL, NULL, gus); + io_sethandler(0x0388, 0x0002, readgus, NULL, NULL, writegus, NULL, NULL, gus); + +#if defined(DEV_BRANCH) && defined(USE_GUSMAX) + ad1848_init(&gus->ad1848, AD1848_TYPE_CS4231); + ad1848_setirq(&gus->ad1848, 5); + ad1848_setdma(&gus->ad1848, 3); + io_sethandler(0x10C + gus->base, 4, + ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &gus->ad1848); +#endif + + timer_add(&gus->samp_timer, gus_poll_wave, gus, 1); + timer_add(&gus->timer_1, gus_poll_timer_1, gus, 1); + timer_add(&gus->timer_2, gus_poll_timer_2, gus, 1); + + sound_add_handler(gus_get_buffer, gus); + + if (device_get_config_int("receive_input")) + midi_in_handler(1, gus_input_msg, gus_input_sysex, gus); + + return gus; +} + +void +gus_close(void *p) +{ + gus_t *gus = (gus_t *) p; + + free(gus->ram); + free(gus); +} + +void +gus_speed_changed(void *p) +{ + gus_t *gus = (gus_t *) p; + + if (gus->voices < 14) + gus->samp_latch = (uint64_t) (TIMER_USEC * (1000000.0 / 44100.0)); + else + gus->samp_latch = (uint64_t) (TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); + +#if defined(DEV_BRANCH) && defined(USE_GUSMAX) + if (gus->max_ctrl) + ad1848_speed_changed(&gus->ad1848); #endif } static const device_config_t gus_config[] = { - { - "type", "GUS type", CONFIG_SELECTION, "", 0, "", { 0 }, - { - { - "Classic", GUS_CLASSIC - }, + // clang-format off + { + "type", "GUS type", CONFIG_SELECTION, "", 0, "", { 0 }, + { + { "Classic", GUS_CLASSIC }, #if defined(DEV_BRANCH) && defined(USE_GUSMAX) - { - "MAX", GUS_MAX - }, + { "MAX", GUS_MAX }, #endif - { - NULL - } - }, - }, - { - "base", "Address", CONFIG_HEX16, "", 0x220, "", { 0 }, - { - { - "210H", 0x210 - }, - { - "220H", 0x220 - }, - { - "230H", 0x230 - }, - { - "240H", 0x240 - }, - { - "250H", 0x250 - }, - { - "260H", 0x260 - }, - }, - }, - { - "gus_ram", "Onboard RAM", CONFIG_SELECTION, "", 0, "", { 0 }, - { - { - "256 KB", 0 - }, - { - "512 KB", 1 - }, - { - "1 MB", 2 - }, - { - NULL - } - } - }, - { - "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 - } + { NULL } + }, + }, + { + "base", "Address", CONFIG_HEX16, "", 0x220, "", { 0 }, + { + { "210H", 0x210 }, + { "220H", 0x220 }, + { "230H", 0x230 }, + { "240H", 0x240 }, + { "250H", 0x250 }, + { "260H", 0x260 }, + }, + }, + { + "gus_ram", "Onboard RAM", CONFIG_SELECTION, "", 0, "", { 0 }, + { + { "256 KB", 0 }, + { "512 KB", 1 }, + { "1 MB", 2 }, + { NULL } + } + }, + { "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 }, + { "", "", -1 } +// clang-format off }; -const device_t gus_device = -{ - "Gravis UltraSound", - "gus", - DEVICE_ISA | DEVICE_AT, - 0, - gus_init, gus_close, NULL, - { NULL }, - gus_speed_changed, - NULL, - gus_config +const device_t gus_device = { + "Gravis UltraSound", + "gus", + DEVICE_ISA | DEVICE_AT, + 0, + gus_init, + gus_close, + NULL, + { NULL }, + gus_speed_changed, + NULL, + gus_config }; diff --git a/src/sound/snd_lpt_dac.c b/src/sound/snd_lpt_dac.c index a743ff7e2..e4869f397 100644 --- a/src/sound/snd_lpt_dac.c +++ b/src/sound/snd_lpt_dac.c @@ -1,129 +1,131 @@ -#include #include -#include +#include #include +#include #include -#include <86box/86box.h> + #include "cpu.h" -#include <86box/machine.h> -#include <86box/lpt.h> -#include <86box/timer.h> -#include <86box/sound.h> +#include <86box/86box.h> #include <86box/filters.h> +#include <86box/lpt.h> +#include <86box/machine.h> +#include <86box/sound.h> +#include <86box/timer.h> -typedef struct lpt_dac_t -{ - void *lpt; +typedef struct lpt_dac_t { + void *lpt; - uint8_t dac_val_l, dac_val_r; + uint8_t dac_val_l, dac_val_r; - int is_stereo; - int channel; + int is_stereo; + int channel; - int16_t buffer[2][SOUNDBUFLEN]; - int pos; + int16_t buffer[2][SOUNDBUFLEN]; + int pos; } lpt_dac_t; -static void dac_update(lpt_dac_t *lpt_dac) +static void +dac_update(lpt_dac_t *lpt_dac) { - for (; lpt_dac->pos < sound_pos_global; lpt_dac->pos++) - { - lpt_dac->buffer[0][lpt_dac->pos] = (int8_t)(lpt_dac->dac_val_l ^ 0x80) * 0x40; - lpt_dac->buffer[1][lpt_dac->pos] = (int8_t)(lpt_dac->dac_val_r ^ 0x80) * 0x40; - } + for (; lpt_dac->pos < sound_pos_global; lpt_dac->pos++) { + lpt_dac->buffer[0][lpt_dac->pos] = (int8_t) (lpt_dac->dac_val_l ^ 0x80) * 0x40; + lpt_dac->buffer[1][lpt_dac->pos] = (int8_t) (lpt_dac->dac_val_r ^ 0x80) * 0x40; + } } - -static void dac_write_data(uint8_t val, void *p) +static void +dac_write_data(uint8_t val, void *p) { - lpt_dac_t *lpt_dac = (lpt_dac_t *)p; + lpt_dac_t *lpt_dac = (lpt_dac_t *) p; - if (lpt_dac->is_stereo) - { - if (lpt_dac->channel) - lpt_dac->dac_val_r = val; - else - lpt_dac->dac_val_l = val; - } + if (lpt_dac->is_stereo) { + if (lpt_dac->channel) + lpt_dac->dac_val_r = val; else - lpt_dac->dac_val_l = lpt_dac->dac_val_r = val; - dac_update(lpt_dac); + lpt_dac->dac_val_l = val; + } else + lpt_dac->dac_val_l = lpt_dac->dac_val_r = val; + dac_update(lpt_dac); } -static void dac_write_ctrl(uint8_t val, void *p) +static void +dac_write_ctrl(uint8_t val, void *p) { - lpt_dac_t *lpt_dac = (lpt_dac_t *)p; + lpt_dac_t *lpt_dac = (lpt_dac_t *) p; - if (lpt_dac->is_stereo) - lpt_dac->channel = val & 0x01; + if (lpt_dac->is_stereo) + lpt_dac->channel = val & 0x01; } -static uint8_t dac_read_status(void *p) +static uint8_t +dac_read_status(void *p) { - return 0x0f; + return 0x0f; } - -static void dac_get_buffer(int32_t *buffer, int len, void *p) +static void +dac_get_buffer(int32_t *buffer, int len, void *p) { - lpt_dac_t *lpt_dac = (lpt_dac_t *)p; - int c; + lpt_dac_t *lpt_dac = (lpt_dac_t *) p; + int c; - dac_update(lpt_dac); + dac_update(lpt_dac); - for (c = 0; c < len; c++) - { - buffer[c*2] += dac_iir(0, lpt_dac->buffer[0][c]); - buffer[c*2 + 1] += dac_iir(1, lpt_dac->buffer[1][c]); - } - lpt_dac->pos = 0; + for (c = 0; c < len; c++) { + buffer[c * 2] += dac_iir(0, lpt_dac->buffer[0][c]); + buffer[c * 2 + 1] += dac_iir(1, lpt_dac->buffer[1][c]); + } + lpt_dac->pos = 0; } -static void *dac_init(void *lpt) +static void * +dac_init(void *lpt) { - lpt_dac_t *lpt_dac = malloc(sizeof(lpt_dac_t)); - memset(lpt_dac, 0, sizeof(lpt_dac_t)); + lpt_dac_t *lpt_dac = malloc(sizeof(lpt_dac_t)); + memset(lpt_dac, 0, sizeof(lpt_dac_t)); - lpt_dac->lpt = lpt; + lpt_dac->lpt = lpt; - sound_add_handler(dac_get_buffer, lpt_dac); + sound_add_handler(dac_get_buffer, lpt_dac); - return lpt_dac; -} -static void *dac_stereo_init(void *lpt) -{ - lpt_dac_t *lpt_dac = dac_init(lpt); - - lpt_dac->is_stereo = 1; - - return lpt_dac; -} -static void dac_close(void *p) -{ - lpt_dac_t *lpt_dac = (lpt_dac_t *)p; - - free(lpt_dac); + return lpt_dac; } -const lpt_device_t lpt_dac_device = +static void * +dac_stereo_init(void *lpt) { - "LPT DAC / Covox Speech Thing", - dac_init, - dac_close, - dac_write_data, - dac_write_ctrl, - NULL, - dac_read_status, - NULL + lpt_dac_t *lpt_dac = dac_init(lpt); + + lpt_dac->is_stereo = 1; + + return lpt_dac; +} +static void +dac_close(void *p) +{ + lpt_dac_t *lpt_dac = (lpt_dac_t *) p; + + free(lpt_dac); +} + +const lpt_device_t lpt_dac_device = { + "LPT DAC / Covox Speech Thing", + dac_init, + dac_close, + dac_write_data, + dac_write_ctrl, + NULL, + dac_read_status, + NULL }; -const lpt_device_t lpt_dac_stereo_device = -{ - "Stereo LPT DAC", - dac_stereo_init, - dac_close, - dac_write_data, - dac_write_ctrl, - NULL, - dac_read_status, - NULL + +const lpt_device_t lpt_dac_stereo_device = { + "Stereo LPT DAC", + dac_stereo_init, + dac_close, + dac_write_data, + dac_write_ctrl, + NULL, + dac_read_status, + NULL }; diff --git a/src/sound/snd_lpt_dss.c b/src/sound/snd_lpt_dss.c index e534c76d2..131349141 100644 --- a/src/sound/snd_lpt_dss.c +++ b/src/sound/snd_lpt_dss.c @@ -1,141 +1,143 @@ -#include #include -#include +#include #include +#include #include -#include <86box/86box.h> + #include "cpu.h" -#include <86box/machine.h> -#include <86box/timer.h> -#include <86box/lpt.h> -#include <86box/sound.h> +#include <86box/86box.h> #include <86box/filters.h> +#include <86box/lpt.h> +#include <86box/machine.h> +#include <86box/sound.h> +#include <86box/timer.h> -typedef struct dss_t -{ - void *lpt; +typedef struct dss_t { + void *lpt; - uint8_t fifo[16]; - int read_idx, write_idx; + uint8_t fifo[16]; + int read_idx, write_idx; - uint8_t dac_val, - status; + uint8_t dac_val, + status; - pc_timer_t timer; + pc_timer_t timer; - int16_t buffer[SOUNDBUFLEN]; - int pos; + int16_t buffer[SOUNDBUFLEN]; + int pos; } dss_t; -static void dss_update(dss_t *dss) +static void +dss_update(dss_t *dss) { - for (; dss->pos < sound_pos_global; dss->pos++) - dss->buffer[dss->pos] = (int8_t)(dss->dac_val ^ 0x80) * 0x40; + for (; dss->pos < sound_pos_global; dss->pos++) + dss->buffer[dss->pos] = (int8_t) (dss->dac_val ^ 0x80) * 0x40; } - -static void dss_update_status(dss_t *dss) +static void +dss_update_status(dss_t *dss) { - uint8_t old = dss->status; + uint8_t old = dss->status; - dss->status &= ~0x40; + dss->status &= ~0x40; - if ((dss->write_idx - dss->read_idx) >= 16) - dss->status |= 0x40; + if ((dss->write_idx - dss->read_idx) >= 16) + dss->status |= 0x40; - if ((old & 0x40) && !(dss->status & 0x40)) - lpt_irq(dss->lpt, 1); + if ((old & 0x40) && !(dss->status & 0x40)) + lpt_irq(dss->lpt, 1); } - -static void dss_write_data(uint8_t val, void *p) +static void +dss_write_data(uint8_t val, void *p) { - dss_t *dss = (dss_t *)p; + dss_t *dss = (dss_t *) p; - if ((dss->write_idx - dss->read_idx) < 16) - { - dss->fifo[dss->write_idx & 15] = val; - dss->write_idx++; - dss_update_status(dss); - } + if ((dss->write_idx - dss->read_idx) < 16) { + dss->fifo[dss->write_idx & 15] = val; + dss->write_idx++; + dss_update_status(dss); + } } -static void dss_write_ctrl(uint8_t val, void *p) +static void +dss_write_ctrl(uint8_t val, void *p) { } -static uint8_t dss_read_status(void *p) +static uint8_t +dss_read_status(void *p) { - dss_t *dss = (dss_t *)p; + dss_t *dss = (dss_t *) p; - return dss->status | 0x0f; + return dss->status | 0x0f; } - -static void dss_get_buffer(int32_t *buffer, int len, void *p) +static void +dss_get_buffer(int32_t *buffer, int len, void *p) { - dss_t *dss = (dss_t *)p; - int c; - int16_t val; - float fval; + dss_t *dss = (dss_t *) p; + int c; + int16_t val; + float fval; - dss_update(dss); + dss_update(dss); - for (c = 0; c < len*2; c += 2) - { - fval = dss_iir((float)dss->buffer[c >> 1]); - val = (float) fval; + for (c = 0; c < len * 2; c += 2) { + fval = dss_iir((float) dss->buffer[c >> 1]); + val = (float) fval; - buffer[c] += val; - buffer[c+1] += val; - } + buffer[c] += val; + buffer[c + 1] += val; + } - dss->pos = 0; + dss->pos = 0; } -static void dss_callback(void *p) +static void +dss_callback(void *p) { - dss_t *dss = (dss_t *)p; + dss_t *dss = (dss_t *) p; - dss_update(dss); + dss_update(dss); - if ((dss->write_idx - dss->read_idx) > 0) - { - dss->dac_val = dss->fifo[dss->read_idx & 15]; - dss->read_idx++; - dss_update_status(dss); - } + if ((dss->write_idx - dss->read_idx) > 0) { + dss->dac_val = dss->fifo[dss->read_idx & 15]; + dss->read_idx++; + dss_update_status(dss); + } - timer_advance_u64(&dss->timer, (TIMER_USEC * (1000000.0 / 7000.0))); + timer_advance_u64(&dss->timer, (TIMER_USEC * (1000000.0 / 7000.0))); } -static void *dss_init(void *lpt) +static void * +dss_init(void *lpt) { - dss_t *dss = malloc(sizeof(dss_t)); - memset(dss, 0, sizeof(dss_t)); + dss_t *dss = malloc(sizeof(dss_t)); + memset(dss, 0, sizeof(dss_t)); - dss->lpt = lpt; + dss->lpt = lpt; - sound_add_handler(dss_get_buffer, dss); - timer_add(&dss->timer, dss_callback, dss, 1); + sound_add_handler(dss_get_buffer, dss); + timer_add(&dss->timer, dss_callback, dss, 1); - return dss; + return dss; } -static void dss_close(void *p) +static void +dss_close(void *p) { - dss_t *dss = (dss_t *)p; + dss_t *dss = (dss_t *) p; - free(dss); + free(dss); } -const lpt_device_t dss_device = -{ - "Disney Sound Source", - dss_init, - dss_close, - dss_write_data, - dss_write_ctrl, - NULL, - dss_read_status, - NULL +const lpt_device_t dss_device = { + "Disney Sound Source", + dss_init, + dss_close, + dss_write_data, + dss_write_ctrl, + NULL, + dss_read_status, + NULL }; diff --git a/src/sound/snd_mpu401.c b/src/sound/snd_mpu401.c index 0922ab21c..fe686c875 100644 --- a/src/sound/snd_mpu401.c +++ b/src/sound/snd_mpu401.c @@ -1,85 +1,78 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 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. * - * Roland MPU-401 emulation. + * Roland MPU-401 emulation. * * * - * Authors: Sarah Walker, - * DOSBox Team, - * Miran Grca, - * TheCollector1995, + * Authors: Sarah Walker, + * DOSBox Team, + * Miran Grca, + * TheCollector1995, * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2008-2020 DOSBox Team. - * Copyright 2016-2020 Miran Grca. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2008-2020 DOSBox Team. + * Copyright 2016-2020 Miran Grca. */ #include #include #include -#include #include -#include +#include #include #define HAVE_STDARG_H + #include <86box/86box.h> #include <86box/device.h> -#include <86box/plat.h> #include <86box/io.h> #include <86box/machine.h> #include <86box/mca.h> -#include <86box/pic.h> -#include <86box/timer.h> -#include <86box/sound.h> -#include <86box/snd_mpu401.h> #include <86box/midi.h> +#include <86box/pic.h> +#include <86box/plat.h> +#include <86box/timer.h> +#include <86box/snd_mpu401.h> +#include <86box/sound.h> - -static uint32_t MPUClockBase[8] = {48,72,96,120,144,168,192}; -static uint8_t cth_data[16] = {0,0,0,0,1,0,0,0,1,0,1,0,1,1,1,0}; - +static uint32_t MPUClockBase[8] = { 48, 72, 96, 120, 144, 168, 192 }; +static uint8_t cth_data[16] = { 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0 }; enum { STATUS_OUTPUT_NOT_READY = 0x40, STATUS_INPUT_NOT_READY = 0x80 }; - int mpu401_standalone_enable = 0; - static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val); static void MPU401_IntelligentOut(mpu_t *mpu, uint8_t track); static void MPU401_EOIHandler(void *priv); static void MPU401_EOIHandlerDispatch(void *p); static void MPU401_NotesOff(mpu_t *mpu, int i); - #ifdef ENABLE_MPU401_LOG int mpu401_do_log = ENABLE_MPU401_LOG; - static void mpu401_log(const char *fmt, ...) { va_list ap; if (mpu401_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define mpu401_log(fmt, ...) +# define mpu401_log(fmt, ...) #endif - static void MPU401_ReCalcClock(mpu_t *mpu) { @@ -87,179 +80,169 @@ MPU401_ReCalcClock(mpu_t *mpu) int32_t freq; if (mpu->clock.timebase < 72) { - maxtempo = 240; - mintempo = 32; + maxtempo = 240; + mintempo = 32; } else if (mpu->clock.timebase < 120) { - maxtempo = 240; - mintempo = 16; + maxtempo = 240; + mintempo = 16; } else if (mpu->clock.timebase < 168) { - maxtempo = 208; - mintempo = 8; + maxtempo = 208; + mintempo = 8; } else { - maxtempo = 179; - mintempo = 8; + maxtempo = 179; + mintempo = 8; } - mpu->clock.freq = ((uint32_t)(mpu->clock.tempo * 2 * mpu->clock.tempo_rel)) >> 6; - mpu->clock.freq = mpu->clock.timebase * (mpu->clock.freq < (mintempo * 2) ? mintempo : - ((mpu->clock.freq / 2) < maxtempo ? (mpu->clock.freq / 2) : maxtempo)); + mpu->clock.freq = ((uint32_t) (mpu->clock.tempo * 2 * mpu->clock.tempo_rel)) >> 6; + mpu->clock.freq = mpu->clock.timebase * (mpu->clock.freq < (mintempo * 2) ? mintempo : ((mpu->clock.freq / 2) < maxtempo ? (mpu->clock.freq / 2) : maxtempo)); if (mpu->state.sync_in) { - freq = (int32_t)((float)(mpu->clock.freq) * mpu->clock.freq_mod); - if ((freq > (mpu->clock.timebase * mintempo)) && (freq < (mpu->clock.timebase * maxtempo))) - mpu->clock.freq = freq; + freq = (int32_t) ((float) (mpu->clock.freq) * mpu->clock.freq_mod); + if ((freq > (mpu->clock.timebase * mintempo)) && (freq < (mpu->clock.timebase * maxtempo))) + mpu->clock.freq = freq; } } - static void MPU401_StartClock(mpu_t *mpu) { if (mpu->clock.active) - return; + return; if (!(mpu->state.clock_to_host || mpu->state.playing || (mpu->state.rec == M_RECON))) - return; + return; mpu->clock.active = 1; timer_set_delay_u64(&mpu->mpu401_event_callback, (MPU401_TIMECONSTANT / mpu->clock.freq) * 1000 * TIMER_USEC); } - static void MPU401_StopClock(mpu_t *mpu) { if (mpu->state.clock_to_host || mpu->state.playing || (mpu->state.rec == M_RECON)) - return; + return; mpu->clock.active = 0; timer_disable(&mpu->mpu401_event_callback); } - static void MPU401_RunClock(mpu_t *mpu) { if (!mpu->clock.active) { - timer_disable(&mpu->mpu401_event_callback); - return; + timer_disable(&mpu->mpu401_event_callback); + return; } timer_set_delay_u64(&mpu->mpu401_event_callback, (MPU401_TIMECONSTANT / mpu->clock.freq) * 1000 * TIMER_USEC); - mpu401_log("Next event after %i us (time constant: %i)\n", (uint64_t) ((MPU401_TIMECONSTANT/mpu->clock.freq) * 1000 * TIMER_USEC), (int) MPU401_TIMECONSTANT); + mpu401_log("Next event after %i us (time constant: %i)\n", (uint64_t) ((MPU401_TIMECONSTANT / mpu->clock.freq) * 1000 * TIMER_USEC), (int) MPU401_TIMECONSTANT); } - static void MPU401_QueueByteEx(mpu_t *mpu, uint8_t data, int irq) { if (mpu->state.block_ack) { - mpu->state.block_ack = 0; - return; + mpu->state.block_ack = 0; + return; } if (mpu->queue_used == 0) { - if (mpu->ext_irq_update) - mpu->ext_irq_update(mpu->priv, 1); - else { - mpu->state.irq_pending = 1; - picint(1 << mpu->irq); - } + if (mpu->ext_irq_update) + mpu->ext_irq_update(mpu->priv, 1); + else { + mpu->state.irq_pending = 1; + picint(1 << mpu->irq); + } } if (mpu->queue_used < MPU401_QUEUE) { - int pos = mpu->queue_used+mpu->queue_pos; + int pos = mpu->queue_used + mpu->queue_pos; - if (mpu->queue_pos >= MPU401_QUEUE) - mpu->queue_pos -= MPU401_QUEUE; - if (pos>=MPU401_QUEUE) - pos-=MPU401_QUEUE; + if (mpu->queue_pos >= MPU401_QUEUE) + mpu->queue_pos -= MPU401_QUEUE; + if (pos >= MPU401_QUEUE) + pos -= MPU401_QUEUE; - mpu->queue_used++; - mpu->queue[pos] = data; + mpu->queue_used++; + mpu->queue[pos] = data; } } - static void MPU401_QueueByte(mpu_t *mpu, uint8_t data) { MPU401_QueueByteEx(mpu, data, 1); } - static int MPU401_IRQPending(mpu_t *mpu) { int irq_pending; if (mpu->ext_irq_pending) - irq_pending = mpu->ext_irq_pending(mpu->priv); + irq_pending = mpu->ext_irq_pending(mpu->priv); else - irq_pending = mpu->state.irq_pending; + irq_pending = mpu->state.irq_pending; return irq_pending; } - static void MPU401_RecQueueBuffer(mpu_t *mpu, uint8_t *buf, uint32_t len, int block) { uint32_t cnt = 0; - int pos; + int pos; while (cnt < len) { - if (mpu->rec_queue_used < MPU401_INPUT_QUEUE) { - pos = mpu->rec_queue_used + mpu->rec_queue_pos; - if (pos >= MPU401_INPUT_QUEUE) - pos -= MPU401_INPUT_QUEUE; - mpu->rec_queue[pos] = buf[cnt]; - mpu->rec_queue_used++; - if ((!mpu->state.sysex_in_finished) && (buf[cnt] == MSG_EOX)) { - /* finish sysex */ - mpu->state.sysex_in_finished = 1; - break; - } - cnt++; - } + if (mpu->rec_queue_used < MPU401_INPUT_QUEUE) { + pos = mpu->rec_queue_used + mpu->rec_queue_pos; + if (pos >= MPU401_INPUT_QUEUE) + pos -= MPU401_INPUT_QUEUE; + mpu->rec_queue[pos] = buf[cnt]; + mpu->rec_queue_used++; + if ((!mpu->state.sysex_in_finished) && (buf[cnt] == MSG_EOX)) { + /* finish sysex */ + mpu->state.sysex_in_finished = 1; + break; + } + cnt++; + } } if (mpu->queue_used == 0) { - if (mpu->state.rec_copy || MPU401_IRQPending(mpu)) { - if (MPU401_IRQPending(mpu)) { - if (mpu->ext_irq_update) - mpu->ext_irq_update(mpu->priv, 0); - else { - mpu->state.irq_pending = 0; - picintc(1 << mpu->irq); - } - } - return; - } - mpu->state.rec_copy = 1; - if (mpu->rec_queue_pos >= MPU401_INPUT_QUEUE) - mpu->rec_queue_pos -= MPU401_INPUT_QUEUE; - MPU401_QueueByte(mpu, mpu->rec_queue[mpu->rec_queue_pos]); - mpu->rec_queue_used--; - mpu->rec_queue_pos++; + if (mpu->state.rec_copy || MPU401_IRQPending(mpu)) { + if (MPU401_IRQPending(mpu)) { + if (mpu->ext_irq_update) + mpu->ext_irq_update(mpu->priv, 0); + else { + mpu->state.irq_pending = 0; + picintc(1 << mpu->irq); + } + } + return; + } + mpu->state.rec_copy = 1; + if (mpu->rec_queue_pos >= MPU401_INPUT_QUEUE) + mpu->rec_queue_pos -= MPU401_INPUT_QUEUE; + MPU401_QueueByte(mpu, mpu->rec_queue[mpu->rec_queue_pos]); + mpu->rec_queue_used--; + mpu->rec_queue_pos++; } } - static void MPU401_ClrQueue(mpu_t *mpu) { - mpu->queue_used = 0; - mpu->queue_pos = 0; - mpu->rec_queue_used = 0; - mpu->rec_queue_pos = 0; + mpu->queue_used = 0; + mpu->queue_pos = 0; + mpu->rec_queue_used = 0; + mpu->rec_queue_pos = 0; mpu->state.sysex_in_finished = 1; if (mpu->ext_irq_update) - mpu->ext_irq_update(mpu->priv, 0); + mpu->ext_irq_update(mpu->priv, 0); else { - mpu->state.irq_pending = 0; - picintc(1 << mpu->irq); + mpu->state.irq_pending = 0; + picintc(1 << mpu->irq); } } - static void MPU401_Reset(mpu_t *mpu) { @@ -267,101 +250,100 @@ MPU401_Reset(mpu_t *mpu) #ifdef DOSBOX_CODE if (mpu->mode == M_INTELLIGENT) { - if (mpu->ext_irq_update) - mpu->ext_irq_update(mpu->priv, 0); - else { - mpu->state.irq_pending = 0; - picintc(1 << mpu->irq); - } + if (mpu->ext_irq_update) + mpu->ext_irq_update(mpu->priv, 0); + else { + mpu->state.irq_pending = 0; + picintc(1 << mpu->irq); + } } #else if (mpu->ext_irq_update) - mpu->ext_irq_update(mpu->priv, 0); + mpu->ext_irq_update(mpu->priv, 0); else { - mpu->state.irq_pending = 0; - picintc(1 << mpu->irq); + mpu->state.irq_pending = 0; + picintc(1 << mpu->irq); } #endif - mpu->mode = M_INTELLIGENT; - mpu->midi_thru = 0; - mpu->state.rec = M_RECOFF; + mpu->mode = M_INTELLIGENT; + mpu->midi_thru = 0; + mpu->state.rec = M_RECOFF; mpu->state.eoi_scheduled = 0; - mpu->state.wsd = 0; - mpu->state.wsm = 0; - mpu->state.conductor = 0; - mpu->state.cond_req = 0; - mpu->state.cond_set = 0; - mpu->state.playing = 0; - mpu->state.run_irq = 0; - mpu->state.cmask = 0xff; + mpu->state.wsd = 0; + mpu->state.wsm = 0; + mpu->state.conductor = 0; + mpu->state.cond_req = 0; + mpu->state.cond_set = 0; + mpu->state.playing = 0; + mpu->state.run_irq = 0; + mpu->state.cmask = 0xff; mpu->state.amask = mpu->state.tmask = 0; - mpu->state.midi_mask = 0xffff; - mpu->state.command_byte = 0; - mpu->state.block_ack = 0; + mpu->state.midi_mask = 0xffff; + mpu->state.command_byte = 0; + mpu->state.block_ack = 0; mpu->clock.tempo = mpu->clock.old_tempo = 100; mpu->clock.timebase = mpu->clock.old_timebase = 120; mpu->clock.tempo_rel = mpu->clock.old_tempo_rel = 0x40; - mpu->clock.freq_mod = 1.0; - mpu->clock.tempo_grad = 0; + mpu->clock.freq_mod = 1.0; + mpu->clock.tempo_grad = 0; MPU401_StopClock(mpu); MPU401_ReCalcClock(mpu); for (i = 0; i < 4; i++) - mpu->clock.cth_rate[i] = 60; + mpu->clock.cth_rate[i] = 60; - mpu->clock.cth_counter = 0; - mpu->clock.midimetro = 12; - mpu->clock.metromeas = 8; + mpu->clock.cth_counter = 0; + mpu->clock.midimetro = 12; + mpu->clock.metromeas = 8; mpu->filter.rec_measure_end = 1; - mpu->filter.rt_out = 1; - mpu->filter.rt_affection = 1; + mpu->filter.rt_out = 1; + mpu->filter.rt_affection = 1; mpu->filter.allnotesoff_out = 1; - mpu->filter.all_thru = 1; - mpu->filter.midi_thru = 1; + mpu->filter.all_thru = 1; + mpu->filter.midi_thru = 1; mpu->filter.commonmsgs_thru = 1; /* Reset channel reference and input tables. */ for (i = 0; i < 4; i++) { - mpu->chanref[i].on = 1; - mpu->chanref[i].chan = i; - mpu->ch_toref[i] = i; + mpu->chanref[i].on = 1; + mpu->chanref[i].chan = i; + mpu->ch_toref[i] = i; } for (i = 0; i < 16; i++) { - mpu->inputref[i].on = 1; - mpu->inputref[i].chan = i; - if (i > 3) - mpu->ch_toref[i] = 4; /* Dummy reftable. */ + mpu->inputref[i].on = 1; + mpu->inputref[i].chan = i; + if (i > 3) + mpu->ch_toref[i] = 4; /* Dummy reftable. */ } MPU401_ClrQueue(mpu); mpu->state.data_onoff = -1; - mpu->state.req_mask = 0; - mpu->condbuf.counter = 0; - mpu->condbuf.type = T_OVERFLOW; + mpu->state.req_mask = 0; + mpu->condbuf.counter = 0; + mpu->condbuf.type = T_OVERFLOW; for (i = 0; i < 8; i++) { - mpu->playbuf[i].type = T_OVERFLOW; - mpu->playbuf[i].counter = 0; + mpu->playbuf[i].type = T_OVERFLOW; + mpu->playbuf[i].counter = 0; } /* Clear MIDI buffers, terminate notes. */ midi_clear_buffer(); for (i = 0xb0; i <= 0xbf; i++) { - midi_raw_out_byte(i); - midi_raw_out_byte(0x7b); - midi_raw_out_byte(0); + midi_raw_out_byte(i); + midi_raw_out_byte(0x7b); + midi_raw_out_byte(0); } } - static void MPU401_ResetDone(void *priv) { - mpu_t *mpu = (mpu_t *)priv; + mpu_t *mpu = (mpu_t *) priv; mpu401_log("MPU-401 reset callback\n"); @@ -370,680 +352,712 @@ MPU401_ResetDone(void *priv) mpu->state.reset = 0; if (mpu->state.cmd_pending) { - MPU401_WriteCommand(mpu, mpu->state.cmd_pending - 1); - mpu->state.cmd_pending = 0; + MPU401_WriteCommand(mpu, mpu->state.cmd_pending - 1); + mpu->state.cmd_pending = 0; } } - static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val) { uint8_t i, j, was_uart, recmsg[3]; if (mpu->state.reset) - mpu->state.cmd_pending = val + 1; + mpu->state.cmd_pending = val + 1; /* The only command recognized in UART mode is 0xFF: Reset and return to Intelligent mode. */ if ((val != 0xff) && (mpu->mode == M_UART)) - return; + return; /* In Intelligent mode, UART-only variants of the MPU-401 only support commands 0x3F and 0xFF. */ if (!mpu->intelligent && (val != 0x3f) && (val != 0xff)) - return; + return; /* Hack: Enable midi through after the first mpu401 command is written. */ mpu->midi_thru = 1; if (val <= 0x2f) { /* Sequencer state */ - int send_prchg = 0; - if ((val & 0xf) < 0xc) { - switch (val & 3) { /* MIDI realtime messages */ - case 1: - mpu->state.last_rtcmd = 0xfc; - if (mpu->filter.rt_out) - midi_raw_out_rt_byte(0xfc); - mpu->clock.meas_old = mpu->clock.measure_counter; - mpu->clock.cth_old = mpu->clock.cth_counter; - break; - case 2: - mpu->state.last_rtcmd = 0xfa; - if (mpu->filter.rt_out) - midi_raw_out_rt_byte(0xfb); - mpu->clock.measure_counter = mpu->clock.meas_old = 0; - mpu->clock.cth_counter = mpu->clock.cth_old = 0; - break; - case 3: - mpu->state.last_rtcmd = 0xfc; - if (mpu->filter.rt_out) - midi_raw_out_rt_byte(0xfa); - mpu->clock.measure_counter = mpu->clock.meas_old; - mpu->clock.cth_counter = mpu->clock.cth_old; - break; - } - switch (val & 0xc) { /* Playing */ - case 0x4: /* Stop */ - mpu->state.playing = 0; - MPU401_StopClock(mpu); - for (i = 0; i < 16; i++) - MPU401_NotesOff(mpu, i); - mpu->filter.prchg_mask = 0; - break; - case 0x8: /* Start */ - mpu->state.playing = 1; - MPU401_StartClock(mpu); - break; - } - switch (val & 0x30) { /* Recording */ - case 0: /* check if it waited for MIDI RT command */ - if (((val & 3) < 2) || !mpu->filter.rt_affection || (mpu->state.rec != M_RECSTB)) - break; - mpu->state.rec = M_RECON; - MPU401_StartClock(mpu); - if (mpu->filter.prchg_mask) - send_prchg = 1; - break; - case 0x10: /* Stop */ - mpu->state.rec = M_RECOFF; - MPU401_StopClock(mpu); - MPU401_QueueByte(mpu, MSG_MPU_ACK); - MPU401_QueueByte(mpu, mpu->clock.rec_counter); - MPU401_QueueByte(mpu, MSG_MPU_END); - mpu->filter.prchg_mask = 0; - mpu->clock.rec_counter = 0; - return; - case 0x20: /* Start */ - if (!(mpu->state.rec == M_RECON)) { - mpu->clock.rec_counter = 0; - mpu->state.rec = M_RECSTB; - } - if ((mpu->state.last_rtcmd == 0xfa) || (mpu->state.last_rtcmd == 0xfb)) { - mpu->clock.rec_counter = 0; - mpu->state.rec = M_RECON; - if (mpu->filter.prchg_mask) - send_prchg = 1; - MPU401_StartClock(mpu); - } - break; - } - } - MPU401_QueueByte(mpu, MSG_MPU_ACK); - /* record counter hack: needed by Prism, but sent only on cmd 0x20/0x26 (or breaks Ballade) */ - uint8_t rec_cnt = mpu->clock.rec_counter; - if (((val == 0x20) || (val == 0x26)) && (mpu->state.rec == M_RECON)) - MPU401_RecQueueBuffer(mpu, &rec_cnt, 1, 0); + int send_prchg = 0; + if ((val & 0xf) < 0xc) { + switch (val & 3) { /* MIDI realtime messages */ + case 1: + mpu->state.last_rtcmd = 0xfc; + if (mpu->filter.rt_out) + midi_raw_out_rt_byte(0xfc); + mpu->clock.meas_old = mpu->clock.measure_counter; + mpu->clock.cth_old = mpu->clock.cth_counter; + break; + case 2: + mpu->state.last_rtcmd = 0xfa; + if (mpu->filter.rt_out) + midi_raw_out_rt_byte(0xfb); + mpu->clock.measure_counter = mpu->clock.meas_old = 0; + mpu->clock.cth_counter = mpu->clock.cth_old = 0; + break; + case 3: + mpu->state.last_rtcmd = 0xfc; + if (mpu->filter.rt_out) + midi_raw_out_rt_byte(0xfa); + mpu->clock.measure_counter = mpu->clock.meas_old; + mpu->clock.cth_counter = mpu->clock.cth_old; + break; + } + switch (val & 0xc) { /* Playing */ + case 0x4: /* Stop */ + mpu->state.playing = 0; + MPU401_StopClock(mpu); + for (i = 0; i < 16; i++) + MPU401_NotesOff(mpu, i); + mpu->filter.prchg_mask = 0; + break; + case 0x8: /* Start */ + mpu->state.playing = 1; + MPU401_StartClock(mpu); + break; + } + switch (val & 0x30) { /* Recording */ + case 0: /* check if it waited for MIDI RT command */ + if (((val & 3) < 2) || !mpu->filter.rt_affection || (mpu->state.rec != M_RECSTB)) + break; + mpu->state.rec = M_RECON; + MPU401_StartClock(mpu); + if (mpu->filter.prchg_mask) + send_prchg = 1; + break; + case 0x10: /* Stop */ + mpu->state.rec = M_RECOFF; + MPU401_StopClock(mpu); + MPU401_QueueByte(mpu, MSG_MPU_ACK); + MPU401_QueueByte(mpu, mpu->clock.rec_counter); + MPU401_QueueByte(mpu, MSG_MPU_END); + mpu->filter.prchg_mask = 0; + mpu->clock.rec_counter = 0; + return; + case 0x20: /* Start */ + if (!(mpu->state.rec == M_RECON)) { + mpu->clock.rec_counter = 0; + mpu->state.rec = M_RECSTB; + } + if ((mpu->state.last_rtcmd == 0xfa) || (mpu->state.last_rtcmd == 0xfb)) { + mpu->clock.rec_counter = 0; + mpu->state.rec = M_RECON; + if (mpu->filter.prchg_mask) + send_prchg = 1; + MPU401_StartClock(mpu); + } + break; + } + } + MPU401_QueueByte(mpu, MSG_MPU_ACK); + /* record counter hack: needed by Prism, but sent only on cmd 0x20/0x26 (or breaks Ballade) */ + uint8_t rec_cnt = mpu->clock.rec_counter; + if (((val == 0x20) || (val == 0x26)) && (mpu->state.rec == M_RECON)) + MPU401_RecQueueBuffer(mpu, &rec_cnt, 1, 0); - if (send_prchg) { - for (i = 0; i < 16; i++) { - if (mpu->filter.prchg_mask & (1 << i)) { - recmsg[0] = mpu->clock.rec_counter; - recmsg[1] = 0xc0 | i; - recmsg[2] = mpu->filter.prchg_buf[i]; - MPU401_RecQueueBuffer(mpu, recmsg, 3, 0); - mpu->filter.prchg_mask &= ~(1 << i); - } - } - } - } else if ((val >= 0xa0) && (val <= 0xa7)) /* Request play counter */ - MPU401_QueueByte(mpu, mpu->playbuf[val & 7].counter); - else if ((val >= 0xd0) && (val <= 0xd7)) { /* Send data */ - mpu->state.old_track = mpu->state.track; - mpu->state.track= val & 7; - mpu->state.wsd = 1; - mpu->state.wsm = 0; - mpu->state.wsd_start = 1; + if (send_prchg) { + for (i = 0; i < 16; i++) { + if (mpu->filter.prchg_mask & (1 << i)) { + recmsg[0] = mpu->clock.rec_counter; + recmsg[1] = 0xc0 | i; + recmsg[2] = mpu->filter.prchg_buf[i]; + MPU401_RecQueueBuffer(mpu, recmsg, 3, 0); + mpu->filter.prchg_mask &= ~(1 << i); + } + } + } + } else if ((val >= 0xa0) && (val <= 0xa7)) /* Request play counter */ + MPU401_QueueByte(mpu, mpu->playbuf[val & 7].counter); + else if ((val >= 0xd0) && (val <= 0xd7)) { /* Send data */ + mpu->state.old_track = mpu->state.track; + mpu->state.track = val & 7; + mpu->state.wsd = 1; + mpu->state.wsm = 0; + mpu->state.wsd_start = 1; } else if ((val < 0x80) && (val >= 0x40)) { /* Set reference table channel */ - mpu->chanref[(val >> 4) - 4].on = 1; - mpu->chanref[(val >> 4) - 4].chan = val & 0x0f; - mpu->chanref[(val >> 4) - 4].trmask = 0; - for (i = 0; i < 4; i++) - mpu->chanref[(val >> 4) - 4].key[i] = 0; - for (i = 0; i < 16; i++) { - if (mpu->ch_toref[i] == ((val >> 4) - 4)) - mpu->ch_toref[i] = 4; - } - mpu->ch_toref[val & 0x0f] = (val >> 4) - 4; - } else switch (val) { - case 0x30: /* Configuration 0x30 - 0x39 */ - mpu->filter.allnotesoff_out = 0; - break; - case 0x32: - mpu->filter.rt_out = 0; - break; - case 0x33: - mpu->filter.all_thru = 0; - mpu->filter.commonmsgs_thru = 0; - mpu->filter.midi_thru = 0; - for (i = 0; i < 16; i++) { - mpu->inputref[i].on = 0; - for (j = 0; j < 4; j++) - mpu->inputref[i].key[j] = 0; - } - break; - case 0x34: - mpu->filter.timing_in_stop = 1; - break; - case 0x35: - mpu->filter.modemsgs_in = 1; - break; - case 0x37: - mpu->filter.sysex_thru = 1; - break; - case 0x38: - mpu->filter.commonmsgs_in = 1; - break; - case 0x39: - mpu->filter.rt_in = 1; - break; - case 0x3f: /* UART mode */ - mpu401_log("MPU-401: Set UART mode %X\n",val); - MPU401_QueueByte(mpu, MSG_MPU_ACK); - mpu->mode = M_UART; - return; - case 0x80: /* Internal clock */ - if (mpu->clock.active && mpu->state.sync_in) { - timer_set_delay_u64(&mpu->mpu401_event_callback, (MPU401_TIMECONSTANT / mpu->clock.freq) * 1000 * TIMER_USEC); - mpu->clock.freq_mod = 1.0; - } - mpu->state.sync_in = 0; - break; - case 0x81: /* Sync to tape signal */ - case 0x82: /* Sync to MIDI */ - mpu->clock.ticks_in = 0; - mpu->state.sync_in = 1; - break; - case 0x86: case 0x87: /* Bender */ - mpu->filter.bender_in = !!(val & 1); - break; - case 0x88: case 0x89: /* MIDI through */ - mpu->filter.midi_thru = !!(val & 1); - for (i = 0; i < 16; i++) { - mpu->inputref[i].on = mpu->filter.midi_thru; - if (!(val & 1)) { - for (j = 0; j < 4; j++) - mpu->inputref[i].key[j] = 0; - } - } - break; - case 0x8a: case 0x8b: /* Data in stop */ - mpu->filter.data_in_stop = !!(val & 1); - break; - case 0x8c: case 0x8d: /* Send measure end */ - mpu->filter.rec_measure_end = !!(val & 1); - break; - case 0x8e: case 0x8f: /* Conductor */ - mpu->state.cond_set = !!(val & 1); - break; - case 0x90: case 0x91: /* Realtime affection */ - mpu->filter.rt_affection = !!(val & 1); - break; - case 0x94: /* Clock to host */ - mpu->state.clock_to_host = 0; - MPU401_StopClock(mpu); - break; - case 0x95: - mpu->state.clock_to_host = 1; - MPU401_StartClock(mpu); - break; - case 0x96: case 0x97: /* Sysex input allow */ - mpu->filter.sysex_in = !!(val & 1); - if (val & 1) - mpu->filter.sysex_thru = 0; - break; - case 0x98: case 0x99: case 0x9a: case 0x9b: /* Reference tables on/off */ - case 0x9c: case 0x9d: case 0x9e: case 0x9f: - mpu->chanref[(val - 0x98) / 2].on = !!(val & 1); - break; - /* Commands 0xa# returning data */ - case 0xab: /* Request and clear recording counter */ - MPU401_QueueByte(mpu, MSG_MPU_ACK); - MPU401_QueueByte(mpu, 0); - return; - case 0xac: /* Request version */ - MPU401_QueueByte(mpu, MSG_MPU_ACK); - MPU401_QueueByte(mpu, MPU401_VERSION); - return; - case 0xad: /* Request revision */ - MPU401_QueueByte(mpu, MSG_MPU_ACK); - MPU401_QueueByte(mpu, MPU401_REVISION); - return; - case 0xaf: /* Request tempo */ - MPU401_QueueByte(mpu, MSG_MPU_ACK); - MPU401_QueueByte(mpu, mpu->clock.tempo); - return; - case 0xb1: /* Reset relative tempo */ - mpu->clock.old_tempo_rel = mpu->clock.tempo_rel; - mpu->clock.tempo_rel = 0x40; - break; - case 0xb8: /* Clear play counters */ - mpu->state.last_rtcmd = 0; - for (i = 0; i < 8; i++) { - mpu->playbuf[i].counter = 0; - mpu->playbuf[i].type = T_OVERFLOW; - } - mpu->condbuf.counter = 0; - mpu->condbuf.type = T_OVERFLOW; - mpu->state.amask = mpu->state.tmask; - mpu->state.conductor = mpu->state.cond_set; - mpu->clock.cth_counter = mpu->clock.cth_old = 0; - mpu->clock.measure_counter = mpu->clock.meas_old = 0; - break; - case 0xb9: /* Clear play map */ - for (i = 0; i < 16; i++) - MPU401_NotesOff(mpu, i); - for (i = 0; i < 8; i++) { - mpu->playbuf[i].counter = 0; - mpu->playbuf[i].type = T_OVERFLOW; - } - mpu->state.last_rtcmd = 0; - mpu->clock.cth_counter = mpu->clock.cth_old = 0; - mpu->clock.measure_counter = mpu->clock.meas_old = 0; - break; - case 0xba: /* Clear record counter */ - mpu->clock.rec_counter = 0; - break; - case 0xc2: case 0xc3: case 0xc4: /* Internal timebase */ - case 0xc5: case 0xc6: case 0xc7: case 0xc8: - mpu->clock.timebase = MPUClockBase[val-0xc2]; - MPU401_ReCalcClock(mpu); - break; - case 0xdf: /* Send system message */ - mpu->state.wsd = 0; - mpu->state.wsm = 1; - mpu->state.wsd_start = 1; - break; - /* Commands with data byte */ - case 0xe0: case 0xe1: case 0xe2: case 0xe4: case 0xe6: - case 0xe7: case 0xec: case 0xed: case 0xee: case 0xef: - mpu->state.command_byte = val; - break; - case 0xff: /* Reset MPU-401 */ - mpu401_log("MPU-401: Reset %X\n", val); - timer_set_delay_u64(&mpu->mpu401_reset_callback, MPU401_RESETBUSY * 33LL * TIMER_USEC); - mpu->state.reset = 1; - was_uart = (mpu->mode == M_UART); - MPU401_Reset(mpu); - if (was_uart) - return; - break; + mpu->chanref[(val >> 4) - 4].on = 1; + mpu->chanref[(val >> 4) - 4].chan = val & 0x0f; + mpu->chanref[(val >> 4) - 4].trmask = 0; + for (i = 0; i < 4; i++) + mpu->chanref[(val >> 4) - 4].key[i] = 0; + for (i = 0; i < 16; i++) { + if (mpu->ch_toref[i] == ((val >> 4) - 4)) + mpu->ch_toref[i] = 4; + } + mpu->ch_toref[val & 0x0f] = (val >> 4) - 4; + } else + switch (val) { + case 0x30: /* Configuration 0x30 - 0x39 */ + mpu->filter.allnotesoff_out = 0; + break; + case 0x32: + mpu->filter.rt_out = 0; + break; + case 0x33: + mpu->filter.all_thru = 0; + mpu->filter.commonmsgs_thru = 0; + mpu->filter.midi_thru = 0; + for (i = 0; i < 16; i++) { + mpu->inputref[i].on = 0; + for (j = 0; j < 4; j++) + mpu->inputref[i].key[j] = 0; + } + break; + case 0x34: + mpu->filter.timing_in_stop = 1; + break; + case 0x35: + mpu->filter.modemsgs_in = 1; + break; + case 0x37: + mpu->filter.sysex_thru = 1; + break; + case 0x38: + mpu->filter.commonmsgs_in = 1; + break; + case 0x39: + mpu->filter.rt_in = 1; + break; + case 0x3f: /* UART mode */ + mpu401_log("MPU-401: Set UART mode %X\n", val); + MPU401_QueueByte(mpu, MSG_MPU_ACK); + mpu->mode = M_UART; + return; + case 0x80: /* Internal clock */ + if (mpu->clock.active && mpu->state.sync_in) { + timer_set_delay_u64(&mpu->mpu401_event_callback, (MPU401_TIMECONSTANT / mpu->clock.freq) * 1000 * TIMER_USEC); + mpu->clock.freq_mod = 1.0; + } + mpu->state.sync_in = 0; + break; + case 0x81: /* Sync to tape signal */ + case 0x82: /* Sync to MIDI */ + mpu->clock.ticks_in = 0; + mpu->state.sync_in = 1; + break; + case 0x86: + case 0x87: /* Bender */ + mpu->filter.bender_in = !!(val & 1); + break; + case 0x88: + case 0x89: /* MIDI through */ + mpu->filter.midi_thru = !!(val & 1); + for (i = 0; i < 16; i++) { + mpu->inputref[i].on = mpu->filter.midi_thru; + if (!(val & 1)) { + for (j = 0; j < 4; j++) + mpu->inputref[i].key[j] = 0; + } + } + break; + case 0x8a: + case 0x8b: /* Data in stop */ + mpu->filter.data_in_stop = !!(val & 1); + break; + case 0x8c: + case 0x8d: /* Send measure end */ + mpu->filter.rec_measure_end = !!(val & 1); + break; + case 0x8e: + case 0x8f: /* Conductor */ + mpu->state.cond_set = !!(val & 1); + break; + case 0x90: + case 0x91: /* Realtime affection */ + mpu->filter.rt_affection = !!(val & 1); + break; + case 0x94: /* Clock to host */ + mpu->state.clock_to_host = 0; + MPU401_StopClock(mpu); + break; + case 0x95: + mpu->state.clock_to_host = 1; + MPU401_StartClock(mpu); + break; + case 0x96: + case 0x97: /* Sysex input allow */ + mpu->filter.sysex_in = !!(val & 1); + if (val & 1) + mpu->filter.sysex_thru = 0; + break; + case 0x98: + case 0x99: + case 0x9a: + case 0x9b: /* Reference tables on/off */ + case 0x9c: + case 0x9d: + case 0x9e: + case 0x9f: + mpu->chanref[(val - 0x98) / 2].on = !!(val & 1); + break; + /* Commands 0xa# returning data */ + case 0xab: /* Request and clear recording counter */ + MPU401_QueueByte(mpu, MSG_MPU_ACK); + MPU401_QueueByte(mpu, 0); + return; + case 0xac: /* Request version */ + MPU401_QueueByte(mpu, MSG_MPU_ACK); + MPU401_QueueByte(mpu, MPU401_VERSION); + return; + case 0xad: /* Request revision */ + MPU401_QueueByte(mpu, MSG_MPU_ACK); + MPU401_QueueByte(mpu, MPU401_REVISION); + return; + case 0xaf: /* Request tempo */ + MPU401_QueueByte(mpu, MSG_MPU_ACK); + MPU401_QueueByte(mpu, mpu->clock.tempo); + return; + case 0xb1: /* Reset relative tempo */ + mpu->clock.old_tempo_rel = mpu->clock.tempo_rel; + mpu->clock.tempo_rel = 0x40; + break; + case 0xb8: /* Clear play counters */ + mpu->state.last_rtcmd = 0; + for (i = 0; i < 8; i++) { + mpu->playbuf[i].counter = 0; + mpu->playbuf[i].type = T_OVERFLOW; + } + mpu->condbuf.counter = 0; + mpu->condbuf.type = T_OVERFLOW; + mpu->state.amask = mpu->state.tmask; + mpu->state.conductor = mpu->state.cond_set; + mpu->clock.cth_counter = mpu->clock.cth_old = 0; + mpu->clock.measure_counter = mpu->clock.meas_old = 0; + break; + case 0xb9: /* Clear play map */ + for (i = 0; i < 16; i++) + MPU401_NotesOff(mpu, i); + for (i = 0; i < 8; i++) { + mpu->playbuf[i].counter = 0; + mpu->playbuf[i].type = T_OVERFLOW; + } + mpu->state.last_rtcmd = 0; + mpu->clock.cth_counter = mpu->clock.cth_old = 0; + mpu->clock.measure_counter = mpu->clock.meas_old = 0; + break; + case 0xba: /* Clear record counter */ + mpu->clock.rec_counter = 0; + break; + case 0xc2: + case 0xc3: + case 0xc4: /* Internal timebase */ + case 0xc5: + case 0xc6: + case 0xc7: + case 0xc8: + mpu->clock.timebase = MPUClockBase[val - 0xc2]; + MPU401_ReCalcClock(mpu); + break; + case 0xdf: /* Send system message */ + mpu->state.wsd = 0; + mpu->state.wsm = 1; + mpu->state.wsd_start = 1; + break; + /* Commands with data byte */ + case 0xe0: + case 0xe1: + case 0xe2: + case 0xe4: + case 0xe6: + case 0xe7: + case 0xec: + case 0xed: + case 0xee: + case 0xef: + mpu->state.command_byte = val; + break; + case 0xff: /* Reset MPU-401 */ + mpu401_log("MPU-401: Reset %X\n", val); + timer_set_delay_u64(&mpu->mpu401_reset_callback, MPU401_RESETBUSY * 33LL * TIMER_USEC); + mpu->state.reset = 1; + was_uart = (mpu->mode == M_UART); + MPU401_Reset(mpu); + if (was_uart) + return; + break; - /* default: - mpu401_log("MPU-401:Unhandled command %X",val); */ - } + /* default: + mpu401_log("MPU-401:Unhandled command %X",val); */ + } MPU401_QueueByte(mpu, MSG_MPU_ACK); } - static void MPU401_WriteData(mpu_t *mpu, uint8_t val) { static int length, cnt; - uint8_t i; + uint8_t i; #ifdef DOSBOX_CODE if (mpu->mode == M_UART) { - midi_raw_out_byte(val); - return; + midi_raw_out_byte(val); + return; } if (!mpu->intelligent) { - mpu->state.command_byte = 0; - return; + mpu->state.command_byte = 0; + return; } #else if (!mpu->intelligent || (mpu->mode == M_UART)) { - midi_raw_out_byte(val); - return; + midi_raw_out_byte(val); + return; } #endif - switch (mpu->state.command_byte) { /* 0xe# command data */ - case 0x00: - break; - case 0xe0: /* Set tempo */ - mpu->state.command_byte = 0; - if (mpu->clock.tempo < 8) - mpu->clock.tempo = 8; - else if (mpu->clock.tempo > 250) - mpu->clock.tempo = 250; - else - mpu->clock.tempo = val; - MPU401_ReCalcClock(mpu); - return; - case 0xe1: /* Set relative tempo */ - mpu->state.command_byte = 0; - mpu->clock.old_tempo_rel = mpu->clock.tempo_rel; - mpu->clock.tempo_rel = val; - MPU401_ReCalcClock(mpu); - return; - case 0xe2: /* Set gradation for relative tempo */ - mpu->clock.tempo_grad = val; - MPU401_ReCalcClock(mpu); - return; - case 0xe4: /* Set MIDI clocks for metronome ticks */ - mpu->state.command_byte = 0; - mpu->clock.midimetro = val; - return; - case 0xe6: /* Set metronome ticks per measure */ - mpu->state.command_byte = 0; - mpu->clock.metromeas = val; - return; - case 0xe7: /* Set internal clock to host interval */ - mpu->state.command_byte = 0; - if (!val) - val = 64; - for (i = 0; i < 4; i++) - mpu->clock.cth_rate[i] = (val >> 2) + cth_data[(val & 3) * 4 + i]; - mpu->clock.cth_mode = 0; - return; - case 0xec: /* Set active track mask */ - mpu->state.command_byte = 0; - mpu->state.tmask = val; - return; - case 0xed: /* Set play counter mask */ - mpu->state.command_byte = 0; - mpu->state.cmask = val; - return; - case 0xee: /* Set 1-8 MIDI channel mask */ - mpu->state.command_byte = 0; - mpu->state.midi_mask &= 0xff00; - mpu->state.midi_mask |= val; - return; - case 0xef: /* Set 9-16 MIDI channel mask */ - mpu->state.command_byte = 0; - mpu->state.midi_mask &= 0x00ff; - mpu->state.midi_mask |= ((uint16_t) val) << 8; - return; + switch (mpu->state.command_byte) { /* 0xe# command data */ + case 0x00: + break; + case 0xe0: /* Set tempo */ + mpu->state.command_byte = 0; + if (mpu->clock.tempo < 8) + mpu->clock.tempo = 8; + else if (mpu->clock.tempo > 250) + mpu->clock.tempo = 250; + else + mpu->clock.tempo = val; + MPU401_ReCalcClock(mpu); + return; + case 0xe1: /* Set relative tempo */ + mpu->state.command_byte = 0; + mpu->clock.old_tempo_rel = mpu->clock.tempo_rel; + mpu->clock.tempo_rel = val; + MPU401_ReCalcClock(mpu); + return; + case 0xe2: /* Set gradation for relative tempo */ + mpu->clock.tempo_grad = val; + MPU401_ReCalcClock(mpu); + return; + case 0xe4: /* Set MIDI clocks for metronome ticks */ + mpu->state.command_byte = 0; + mpu->clock.midimetro = val; + return; + case 0xe6: /* Set metronome ticks per measure */ + mpu->state.command_byte = 0; + mpu->clock.metromeas = val; + return; + case 0xe7: /* Set internal clock to host interval */ + mpu->state.command_byte = 0; + if (!val) + val = 64; + for (i = 0; i < 4; i++) + mpu->clock.cth_rate[i] = (val >> 2) + cth_data[(val & 3) * 4 + i]; + mpu->clock.cth_mode = 0; + return; + case 0xec: /* Set active track mask */ + mpu->state.command_byte = 0; + mpu->state.tmask = val; + return; + case 0xed: /* Set play counter mask */ + mpu->state.command_byte = 0; + mpu->state.cmask = val; + return; + case 0xee: /* Set 1-8 MIDI channel mask */ + mpu->state.command_byte = 0; + mpu->state.midi_mask &= 0xff00; + mpu->state.midi_mask |= val; + return; + case 0xef: /* Set 9-16 MIDI channel mask */ + mpu->state.command_byte = 0; + mpu->state.midi_mask &= 0x00ff; + mpu->state.midi_mask |= ((uint16_t) val) << 8; + return; - default: - mpu->state.command_byte = 0; - return; + default: + mpu->state.command_byte = 0; + return; } if (mpu->state.wsd && !mpu->state.track_req && !mpu->state.cond_req) { - /* Directly send MIDI message */ - if (mpu->state.wsd_start) { - mpu->state.wsd_start = 0; - cnt = 0; - switch (val & 0xf0) { - case 0xc0: case 0xd0: - length = mpu->playbuf[mpu->state.track].length = 2; - mpu->playbuf[mpu->state.track].type = T_MIDI_NORM; - break; - case 0x80: case 0x90: case 0xa0: case 0xb0:case 0xe0: - length = mpu->playbuf[mpu->state.track].length = 3; - mpu->playbuf[mpu->state.track].type = T_MIDI_NORM; - break; + /* Directly send MIDI message */ + if (mpu->state.wsd_start) { + mpu->state.wsd_start = 0; + cnt = 0; + switch (val & 0xf0) { + case 0xc0: + case 0xd0: + length = mpu->playbuf[mpu->state.track].length = 2; + mpu->playbuf[mpu->state.track].type = T_MIDI_NORM; + break; + case 0x80: + case 0x90: + case 0xa0: + case 0xb0: + case 0xe0: + length = mpu->playbuf[mpu->state.track].length = 3; + mpu->playbuf[mpu->state.track].type = T_MIDI_NORM; + break; - case 0xf0: - /* mpu401_log("MPU-401:Illegal WSD byte\n"); */ - mpu->state.wsd = 0; - mpu->state.track = mpu->state.old_track; - return; + case 0xf0: + /* mpu401_log("MPU-401:Illegal WSD byte\n"); */ + mpu->state.wsd = 0; + mpu->state.track = mpu->state.old_track; + return; - default: /* MIDI with running status */ - cnt++; - length = mpu->playbuf[mpu->state.track].length; - mpu->playbuf[mpu->state.track].type = T_MIDI_NORM; - } - } + default: /* MIDI with running status */ + cnt++; + length = mpu->playbuf[mpu->state.track].length; + mpu->playbuf[mpu->state.track].type = T_MIDI_NORM; + } + } - if (cnt < length) { - mpu->playbuf[mpu->state.track].value[cnt] = val; - cnt++; - } + if (cnt < length) { + mpu->playbuf[mpu->state.track].value[cnt] = val; + cnt++; + } - if (cnt == length) { - MPU401_IntelligentOut(mpu, mpu->state.track); - mpu->state.wsd = 0; - mpu->state.track = mpu->state.old_track; - } + if (cnt == length) { + MPU401_IntelligentOut(mpu, mpu->state.track); + mpu->state.wsd = 0; + mpu->state.track = mpu->state.old_track; + } - return; + return; } - if (mpu->state.wsm && !mpu->state.track_req && !mpu->state.cond_req) { /* Send system message */ - if (mpu->state.wsd_start) { - mpu->state.wsd_start = 0; - cnt = 0; - switch (val) { - case 0xf2: - length = 3; - break; + if (mpu->state.wsm && !mpu->state.track_req && !mpu->state.cond_req) { /* Send system message */ + if (mpu->state.wsd_start) { + mpu->state.wsd_start = 0; + cnt = 0; + switch (val) { + case 0xf2: + length = 3; + break; - case 0xf3: - length = 2; - break; + case 0xf3: + length = 2; + break; - case 0xf6: - length = 1; - break; + case 0xf6: + length = 1; + break; - case 0xf0: - length = 0; - break; + case 0xf0: + length = 0; + break; - default: - mpu->state.wsm = 0; - return; - } - } else if (val & 0x80) { - midi_raw_out_byte(MSG_EOX); - mpu->state.wsm = 0; - return; - } + default: + mpu->state.wsm = 0; + return; + } + } else if (val & 0x80) { + midi_raw_out_byte(MSG_EOX); + mpu->state.wsm = 0; + return; + } - if (!length || (cnt < length)) { - midi_raw_out_byte(val); - cnt++; - } + if (!length || (cnt < length)) { + midi_raw_out_byte(val); + cnt++; + } - if (cnt == length) - mpu->state.wsm = 0; + if (cnt == length) + mpu->state.wsm = 0; - return; + return; } if (mpu->state.cond_req) { - /* Command */ - switch (mpu->state.data_onoff) { - case -1: - return; - case 0: /* Timing byte */ - mpu->condbuf.length = 0; - if (val < 0xf0) - mpu->state.data_onoff++; - else { - mpu->state.cond_req = 0; - mpu->state.data_onoff = -1; - MPU401_EOIHandlerDispatch(mpu); - break; - } - mpu->state.send_now = !val ? 1 : 0; - mpu->condbuf.counter = val; - break; - case 1: /* Command byte #1 */ - mpu->condbuf.type = T_COMMAND; - if ((val == 0xf8) || (val == 0xf9) || (val == 0xfc)) - mpu->condbuf.type = T_OVERFLOW; - mpu->condbuf.value[mpu->condbuf.length] = val; - mpu->condbuf.length++; - if ((val & 0xf0) != 0xe0) { /*no cmd data byte*/ - MPU401_EOIHandler(mpu); - mpu->state.data_onoff = -1; - mpu->state.cond_req = 0; - } else - mpu->state.data_onoff++; - break; + /* Command */ + switch (mpu->state.data_onoff) { + case -1: + return; + case 0: /* Timing byte */ + mpu->condbuf.length = 0; + if (val < 0xf0) + mpu->state.data_onoff++; + else { + mpu->state.cond_req = 0; + mpu->state.data_onoff = -1; + MPU401_EOIHandlerDispatch(mpu); + break; + } + mpu->state.send_now = !val ? 1 : 0; + mpu->condbuf.counter = val; + break; + case 1: /* Command byte #1 */ + mpu->condbuf.type = T_COMMAND; + if ((val == 0xf8) || (val == 0xf9) || (val == 0xfc)) + mpu->condbuf.type = T_OVERFLOW; + mpu->condbuf.value[mpu->condbuf.length] = val; + mpu->condbuf.length++; + if ((val & 0xf0) != 0xe0) { /*no cmd data byte*/ + MPU401_EOIHandler(mpu); + mpu->state.data_onoff = -1; + mpu->state.cond_req = 0; + } else + mpu->state.data_onoff++; + break; - case 2:/* Command byte #2 */ - mpu->condbuf.value[mpu->condbuf.length]=val; - mpu->condbuf.length++; - MPU401_EOIHandler(mpu); - mpu->state.data_onoff = -1; - mpu->state.cond_req = 0; - break; - } - return; + case 2: /* Command byte #2 */ + mpu->condbuf.value[mpu->condbuf.length] = val; + mpu->condbuf.length++; + MPU401_EOIHandler(mpu); + mpu->state.data_onoff = -1; + mpu->state.cond_req = 0; + break; + } + return; } switch (mpu->state.data_onoff) { - /* Data */ - case -1: - break; - case 0: /* Timing byte */ - if (val < 0xf0) - mpu->state.data_onoff++; - else { - mpu->state.data_onoff = -1; - MPU401_EOIHandlerDispatch(mpu); - mpu->state.track_req = 0; - return; - } - mpu->state.send_now = !val ? 1 : 0; - mpu->playbuf[mpu->state.track].counter = val; - break; - case 1: /* MIDI */ - cnt = 0; - mpu->state.data_onoff++; - switch (val & 0xf0) { - case 0xc0: case 0xd0: /* MIDI Message */ - length = mpu->playbuf[mpu->state.track].length = 2; - mpu->playbuf[mpu->state.track].type = T_MIDI_NORM; - break; - case 0x80: case 0x90: case 0xa0: case 0xb0: case 0xe0: - length = mpu->playbuf[mpu->state.track].length = 3; - mpu->playbuf[mpu->state.track].type = T_MIDI_NORM; - break; - case 0xf0: /* System message or mark */ - mpu->playbuf[mpu->state.track].sys_val = val; - if (val > 0xf7) { - mpu->playbuf[mpu->state.track].type = T_MARK; - if (val == 0xf9) - mpu->clock.measure_counter = 0; - } else { - /* mpu401_log("MPU-401:Illegal message"); */ - mpu->playbuf[mpu->state.track].type = T_OVERFLOW; - } - mpu->state.data_onoff = -1; - MPU401_EOIHandler(mpu); - mpu->state.track_req = 0; - return; - default: /* MIDI with running status */ - cnt++; - length = mpu->playbuf[mpu->state.track].length; - mpu->playbuf[mpu->state.track].type = T_MIDI_NORM; - break; - } - break; - case 2: - if (cnt < length) { - mpu->playbuf[mpu->state.track].value[cnt] = val; - cnt++; - } - if (cnt == length) { - mpu->state.data_onoff = -1; - mpu->state.track_req = 0; - MPU401_EOIHandler(mpu); - } - break; + /* Data */ + case -1: + break; + case 0: /* Timing byte */ + if (val < 0xf0) + mpu->state.data_onoff++; + else { + mpu->state.data_onoff = -1; + MPU401_EOIHandlerDispatch(mpu); + mpu->state.track_req = 0; + return; + } + mpu->state.send_now = !val ? 1 : 0; + mpu->playbuf[mpu->state.track].counter = val; + break; + case 1: /* MIDI */ + cnt = 0; + mpu->state.data_onoff++; + switch (val & 0xf0) { + case 0xc0: + case 0xd0: /* MIDI Message */ + length = mpu->playbuf[mpu->state.track].length = 2; + mpu->playbuf[mpu->state.track].type = T_MIDI_NORM; + break; + case 0x80: + case 0x90: + case 0xa0: + case 0xb0: + case 0xe0: + length = mpu->playbuf[mpu->state.track].length = 3; + mpu->playbuf[mpu->state.track].type = T_MIDI_NORM; + break; + case 0xf0: /* System message or mark */ + mpu->playbuf[mpu->state.track].sys_val = val; + if (val > 0xf7) { + mpu->playbuf[mpu->state.track].type = T_MARK; + if (val == 0xf9) + mpu->clock.measure_counter = 0; + } else { + /* mpu401_log("MPU-401:Illegal message"); */ + mpu->playbuf[mpu->state.track].type = T_OVERFLOW; + } + mpu->state.data_onoff = -1; + MPU401_EOIHandler(mpu); + mpu->state.track_req = 0; + return; + default: /* MIDI with running status */ + cnt++; + length = mpu->playbuf[mpu->state.track].length; + mpu->playbuf[mpu->state.track].type = T_MIDI_NORM; + break; + } + break; + case 2: + if (cnt < length) { + mpu->playbuf[mpu->state.track].value[cnt] = val; + cnt++; + } + if (cnt == length) { + mpu->state.data_onoff = -1; + mpu->state.track_req = 0; + MPU401_EOIHandler(mpu); + } + break; } - return; + return; } - static void MPU401_IntelligentOut(mpu_t *mpu, uint8_t track) { uint8_t chan, chrefnum, key, msg; - int send, retrigger; + int send, retrigger; uint8_t i; switch (mpu->playbuf[track].type) { - case T_OVERFLOW: - break; + case T_OVERFLOW: + break; - case T_MARK: - if (mpu->playbuf[track].sys_val == 0xfc) { - midi_raw_out_rt_byte(mpu->playbuf[track].sys_val); - mpu->state.amask&=~(1<playbuf[track].sys_val == 0xfc) { + midi_raw_out_rt_byte(mpu->playbuf[track].sys_val); + mpu->state.amask &= ~(1 << track); + } + break; - case T_MIDI_NORM: - chan = mpu->playbuf[track].value[0] & 0xf; - key = mpu->playbuf[track].value[1] & 0x7f; - chrefnum = mpu->ch_toref[chan]; - send = 1; - retrigger = 0; - switch (msg = mpu->playbuf[track].value[0] & 0xf0) { - case 0x80: /* note off */ - if (mpu->inputref[chan].on && (mpu->inputref[chan].M_GETKEY)) - send = 0; - if (mpu->chanref[chrefnum].on && (!(mpu->chanref[chrefnum].M_GETKEY))) - send = 0; - mpu->chanref[chrefnum].M_DELKEY; - break; - case 0x90: /* note on */ - if (mpu->inputref[chan].on && (mpu->inputref[chan].M_GETKEY)) - retrigger = 1; - if (mpu->chanref[chrefnum].on && (!(mpu->chanref[chrefnum].M_GETKEY))) - retrigger = 1; - mpu->chanref[chrefnum].M_SETKEY; - break; - case 0xb0: - if (mpu->playbuf[track].value[1] == 123) { /* All notes off */ - MPU401_NotesOff(mpu, mpu->playbuf[track].value[0] & 0xf); - return; - } - break; - } - if (retrigger) { - midi_raw_out_byte(0x80 | chan); - midi_raw_out_byte(key); - midi_raw_out_byte(0); - } - if (send) { - for (i = 0; i < mpu->playbuf[track].length; i++) - midi_raw_out_byte(mpu->playbuf[track].value[i]); - } - break; + case T_MIDI_NORM: + chan = mpu->playbuf[track].value[0] & 0xf; + key = mpu->playbuf[track].value[1] & 0x7f; + chrefnum = mpu->ch_toref[chan]; + send = 1; + retrigger = 0; + switch (msg = mpu->playbuf[track].value[0] & 0xf0) { + case 0x80: /* note off */ + if (mpu->inputref[chan].on && (mpu->inputref[chan].M_GETKEY)) + send = 0; + if (mpu->chanref[chrefnum].on && (!(mpu->chanref[chrefnum].M_GETKEY))) + send = 0; + mpu->chanref[chrefnum].M_DELKEY; + break; + case 0x90: /* note on */ + if (mpu->inputref[chan].on && (mpu->inputref[chan].M_GETKEY)) + retrigger = 1; + if (mpu->chanref[chrefnum].on && (!(mpu->chanref[chrefnum].M_GETKEY))) + retrigger = 1; + mpu->chanref[chrefnum].M_SETKEY; + break; + case 0xb0: + if (mpu->playbuf[track].value[1] == 123) { /* All notes off */ + MPU401_NotesOff(mpu, mpu->playbuf[track].value[0] & 0xf); + return; + } + break; + } + if (retrigger) { + midi_raw_out_byte(0x80 | chan); + midi_raw_out_byte(key); + midi_raw_out_byte(0); + } + if (send) { + for (i = 0; i < mpu->playbuf[track].length; i++) + midi_raw_out_byte(mpu->playbuf[track].value[i]); + } + break; - default: - break; + default: + break; } } - static void UpdateTrack(mpu_t *mpu, uint8_t track) { MPU401_IntelligentOut(mpu, track); - if (mpu->state.amask&(1<playbuf[track].type = T_OVERFLOW; - mpu->playbuf[track].counter = 0xf0; - mpu->state.req_mask |= (1 << track); + if (mpu->state.amask & (1 << track)) { + mpu->playbuf[track].type = T_OVERFLOW; + mpu->playbuf[track].counter = 0xf0; + mpu->state.req_mask |= (1 << track); } else { - if ((mpu->state.amask == 0) && !mpu->state.conductor) - mpu->state.req_mask |= (1 << 12); + if ((mpu->state.amask == 0) && !mpu->state.conductor) + mpu->state.req_mask |= (1 << 12); } } - #if 0 static void UpdateConductor(mpu_t *mpu) { if (mpu->condbuf.value[0] == 0xfc) { - mpu->condbuf.value[0] = 0; - mpu->state.conductor = 0; - mpu->state.req_mask &= ~(1 << 9); - if (mpu->state.amask == 0) - mpu->state.req_mask |= (1 << 12); - return; + mpu->condbuf.value[0] = 0; + mpu->state.conductor = 0; + mpu->state.req_mask &= ~(1 << 9); + if (mpu->state.amask == 0) + mpu->state.req_mask |= (1 << 12); + return; } mpu->condbuf.vlength = 0; @@ -1052,12 +1066,11 @@ UpdateConductor(mpu_t *mpu) } #endif - /* Updates counters and requests new data on "End of Input" */ static void MPU401_EOIHandler(void *priv) { - mpu_t *mpu = (mpu_t *)priv; + mpu_t *mpu = (mpu_t *) priv; uint8_t i; mpu401_log("MPU-401 end of input callback\n"); @@ -1065,81 +1078,78 @@ MPU401_EOIHandler(void *priv) timer_disable(&mpu->mpu401_eoi_callback); mpu->state.eoi_scheduled = 0; if (mpu->state.send_now) { - mpu->state.send_now = 0; - if (mpu->state.cond_req) { - mpu->condbuf.counter = 0xf0; - mpu->state.req_mask |= (1 << 9); - } else UpdateTrack(mpu, mpu->state.track); + mpu->state.send_now = 0; + if (mpu->state.cond_req) { + mpu->condbuf.counter = 0xf0; + mpu->state.req_mask |= (1 << 9); + } else + UpdateTrack(mpu, mpu->state.track); } if (mpu->state.rec_copy || !mpu->state.sysex_in_finished) - return; + return; if (mpu->ext_irq_update) - mpu->ext_irq_update(mpu->priv, 0); + mpu->ext_irq_update(mpu->priv, 0); else { - mpu->state.irq_pending = 0; - picintc(1 << mpu->irq); + mpu->state.irq_pending = 0; + picintc(1 << mpu->irq); } if (!(mpu->state.req_mask && mpu->clock.active)) - return; + return; i = 0; do { - if (mpu->state.req_mask & (1 << i)) { - MPU401_QueueByte(mpu, 0xf0 + i); - mpu->state.req_mask &= ~(1 << i); - break; - } + if (mpu->state.req_mask & (1 << i)) { + MPU401_QueueByte(mpu, 0xf0 + i); + mpu->state.req_mask &= ~(1 << i); + break; + } } while ((i++) < 16); } - static void MPU401_EOIHandlerDispatch(void *priv) { - mpu_t *mpu = (mpu_t *)priv; + mpu_t *mpu = (mpu_t *) priv; mpu401_log("EOI handler dispatch\n"); if (mpu->state.send_now) { - mpu->state.eoi_scheduled = 1; - timer_advance_u64(&mpu->mpu401_eoi_callback, 60LL * TIMER_USEC); /* Possibly a bit longer */ + mpu->state.eoi_scheduled = 1; + timer_advance_u64(&mpu->mpu401_eoi_callback, 60LL * TIMER_USEC); /* Possibly a bit longer */ } else if (!mpu->state.eoi_scheduled) - MPU401_EOIHandler(mpu); + MPU401_EOIHandler(mpu); } - static void imf_write(uint16_t addr, uint8_t val, void *priv) { mpu401_log("IMF:Wr %4X,%X\n", addr, val); } - void MPU401_ReadRaiseIRQ(mpu_t *mpu) { /* Clear IRQ. */ if (mpu->ext_irq_update) - mpu->ext_irq_update(mpu->priv, 0); + mpu->ext_irq_update(mpu->priv, 0); else { - mpu->state.irq_pending = 0; - picintc(1 << mpu->irq); + mpu->state.irq_pending = 0; + picintc(1 << mpu->irq); } if (mpu->queue_used) { - /* Bytes remaining in queue, raise IRQ again. */ - if (mpu->ext_irq_update) - mpu->ext_irq_update(mpu->priv, 1); - else { - mpu->state.irq_pending = 1; - picint(1 << mpu->irq); - } + /* Bytes remaining in queue, raise IRQ again. */ + if (mpu->ext_irq_update) + mpu->ext_irq_update(mpu->priv, 1); + else { + mpu->state.irq_pending = 1; + picint(1 << mpu->irq); + } } } - uint8_t MPU401_ReadData(mpu_t *mpu) { @@ -1148,239 +1158,231 @@ MPU401_ReadData(mpu_t *mpu) ret = MSG_MPU_ACK; if (mpu->queue_used) { - if (mpu->queue_pos >= MPU401_QUEUE) - mpu->queue_pos -= MPU401_QUEUE; - ret = mpu->queue[mpu->queue_pos]; - mpu->queue_pos++; - mpu->queue_used--; + if (mpu->queue_pos >= MPU401_QUEUE) + mpu->queue_pos -= MPU401_QUEUE; + ret = mpu->queue[mpu->queue_pos]; + mpu->queue_pos++; + mpu->queue_used--; } /* Shouldn't this check mpu->mode? */ #ifdef DOSBOX_CODE if (mpu->mode == M_UART) { - MPU401_ReadRaiseIRQ(mpu); - return ret; + MPU401_ReadRaiseIRQ(mpu); + return ret; } #else if (!mpu->intelligent || (mpu->mode == M_UART)) { - MPU401_ReadRaiseIRQ(mpu); - return ret; + MPU401_ReadRaiseIRQ(mpu); + return ret; } #endif if (mpu->state.rec_copy && !mpu->rec_queue_used) { - mpu->state.rec_copy = 0; - MPU401_EOIHandler(mpu); - return ret; + mpu->state.rec_copy = 0; + MPU401_EOIHandler(mpu); + return ret; } /* Copy from recording buffer. */ if (!mpu->queue_used && mpu->rec_queue_used) { - mpu->state.rec_copy = 1; - if (mpu->rec_queue_pos >= MPU401_INPUT_QUEUE) - mpu->rec_queue_pos -= MPU401_INPUT_QUEUE; - MPU401_QueueByte(mpu, mpu->rec_queue[mpu->rec_queue_pos]); - mpu->rec_queue_pos++; - mpu->rec_queue_used--; + mpu->state.rec_copy = 1; + if (mpu->rec_queue_pos >= MPU401_INPUT_QUEUE) + mpu->rec_queue_pos -= MPU401_INPUT_QUEUE; + MPU401_QueueByte(mpu, mpu->rec_queue[mpu->rec_queue_pos]); + mpu->rec_queue_pos++; + mpu->rec_queue_used--; } MPU401_ReadRaiseIRQ(mpu); if ((ret >= 0xf0) && (ret <= 0xf7)) { - /* MIDI data request */ - mpu->state.track = ret & 7; - mpu->state.data_onoff = 0; - mpu->state.cond_req = 0; - mpu->state.track_req = 1; + /* MIDI data request */ + mpu->state.track = ret & 7; + mpu->state.data_onoff = 0; + mpu->state.cond_req = 0; + mpu->state.track_req = 1; } if (ret == MSG_MPU_COMMAND_REQ) { - mpu->state.data_onoff = 0; - mpu->state.cond_req = 1; - if (mpu->condbuf.type != T_OVERFLOW) { - mpu->state.block_ack = 1; - MPU401_WriteCommand(mpu, mpu->condbuf.value[0]); - if (mpu->state.command_byte) - MPU401_WriteData(mpu, mpu->condbuf.value[1]); - mpu->condbuf.type = T_OVERFLOW; - } + mpu->state.data_onoff = 0; + mpu->state.cond_req = 1; + if (mpu->condbuf.type != T_OVERFLOW) { + mpu->state.block_ack = 1; + MPU401_WriteCommand(mpu, mpu->condbuf.value[0]); + if (mpu->state.command_byte) + MPU401_WriteData(mpu, mpu->condbuf.value[1]); + mpu->condbuf.type = T_OVERFLOW; + } } if ((ret == MSG_MPU_END) || (ret == MSG_MPU_CLOCK) || (ret == MSG_MPU_ACK) || (ret == MSG_MPU_OVERFLOW)) - MPU401_EOIHandlerDispatch(mpu); + MPU401_EOIHandlerDispatch(mpu); return ret; } - static void mpu401_write(uint16_t addr, uint8_t val, void *priv) { - mpu_t *mpu = (mpu_t *)priv; + mpu_t *mpu = (mpu_t *) priv; /* mpu401_log("MPU401 Write Port %04X, val %x\n", addr, val); */ switch (addr & 1) { - case 0: /*Data*/ - MPU401_WriteData(mpu, val); - mpu401_log("Write Data (0x330) %X\n", val); - break; + case 0: /*Data*/ + MPU401_WriteData(mpu, val); + mpu401_log("Write Data (0x330) %X\n", val); + break; - case 1: /*Command*/ - MPU401_WriteCommand(mpu, val); - mpu401_log("Write Command (0x331) %x\n", val); - break; + case 1: /*Command*/ + MPU401_WriteCommand(mpu, val); + mpu401_log("Write Command (0x331) %x\n", val); + break; } } - static uint8_t mpu401_read(uint16_t addr, void *priv) { - mpu_t *mpu = (mpu_t *)priv; + mpu_t *mpu = (mpu_t *) priv; uint8_t ret = 0; switch (addr & 1) { - case 0: /* Read Data */ - ret = MPU401_ReadData(mpu); - mpu401_log("Read Data (0x330) %X\n", ret); - break; + case 0: /* Read Data */ + ret = MPU401_ReadData(mpu); + mpu401_log("Read Data (0x330) %X\n", ret); + break; - case 1: /* Read Status */ - if (mpu->state.cmd_pending) - ret = STATUS_OUTPUT_NOT_READY; - if (!mpu->queue_used) - ret = STATUS_INPUT_NOT_READY; - ret |= 0x3f; + case 1: /* Read Status */ + if (mpu->state.cmd_pending) + ret = STATUS_OUTPUT_NOT_READY; + if (!mpu->queue_used) + ret = STATUS_INPUT_NOT_READY; + ret |= 0x3f; - mpu401_log("Read Status (0x331) %x\n", ret); - break; + mpu401_log("Read Status (0x331) %x\n", ret); + break; } /* mpu401_log("MPU401 Read Port %04X, ret %x\n", addr, ret); */ - return(ret); + return (ret); } - static void MPU401_Event(void *priv) { - mpu_t *mpu = (mpu_t *)priv; + mpu_t *mpu = (mpu_t *) priv; uint8_t i; - int max_meascnt; + int max_meascnt; mpu401_log("MPU-401 event callback\n"); #ifdef DOSBOX_CODE if (mpu->mode == M_UART) { - timer_disable(&mpu->mpu401_event_callback); - return; + timer_disable(&mpu->mpu401_event_callback); + return; } #else if (!mpu->intelligent || (mpu->mode == M_UART)) { - timer_disable(&mpu->mpu401_event_callback); - return; + timer_disable(&mpu->mpu401_event_callback); + return; } #endif if (MPU401_IRQPending(mpu)) - goto next_event; + goto next_event; if (mpu->state.playing) { - for (i = 0; i < 8; i++) { - /* Decrease counters. */ - if (mpu->state.amask & (1 << i)) { - mpu->playbuf[i].counter--; - if (mpu->playbuf[i].counter <= 0) - UpdateTrack(mpu, i); - } - } + for (i = 0; i < 8; i++) { + /* Decrease counters. */ + if (mpu->state.amask & (1 << i)) { + mpu->playbuf[i].counter--; + if (mpu->playbuf[i].counter <= 0) + UpdateTrack(mpu, i); + } + } - if (mpu->state.conductor) { - mpu->condbuf.counter--; - if (mpu->condbuf.counter <= 0) { - mpu->condbuf.counter = 0xf0; - mpu->state.req_mask |= (1 << 9); - } - } + if (mpu->state.conductor) { + mpu->condbuf.counter--; + if (mpu->condbuf.counter <= 0) { + mpu->condbuf.counter = 0xf0; + mpu->state.req_mask |= (1 << 9); + } + } } if (mpu->state.clock_to_host) { - mpu->clock.cth_counter++; - if (mpu->clock.cth_counter >= mpu->clock.cth_rate[mpu->clock.cth_mode]) { - mpu->clock.cth_counter = 0; - mpu->clock.cth_mode++; - mpu->clock.cth_mode %= 4; - mpu->state.req_mask |= (1 << 13); - } + mpu->clock.cth_counter++; + if (mpu->clock.cth_counter >= mpu->clock.cth_rate[mpu->clock.cth_mode]) { + mpu->clock.cth_counter = 0; + mpu->clock.cth_mode++; + mpu->clock.cth_mode %= 4; + mpu->state.req_mask |= (1 << 13); + } } if (mpu->state.rec == M_RECON) { - /* Recording. */ - mpu->clock.rec_counter++; - if (mpu->clock.rec_counter>=240) { - mpu->clock.rec_counter=0; - mpu->state.req_mask|=(1<<8); - } + /* Recording. */ + mpu->clock.rec_counter++; + if (mpu->clock.rec_counter >= 240) { + mpu->clock.rec_counter = 0; + mpu->state.req_mask |= (1 << 8); + } } if (mpu->state.playing || (mpu->state.rec == M_RECON)) { - max_meascnt = (mpu->clock.timebase * mpu->clock.midimetro * mpu->clock.metromeas) / 24; - if (max_meascnt != 0) { - /* Measure end. */ - if (++mpu->clock.measure_counter >= max_meascnt) { - if (mpu->filter.rt_out) - midi_raw_out_rt_byte(0xf8); - mpu->clock.measure_counter = 0; - if (mpu->filter.rec_measure_end && (mpu->state.rec == M_RECON)) - mpu->state.req_mask |= (1 << 12); - } - } + max_meascnt = (mpu->clock.timebase * mpu->clock.midimetro * mpu->clock.metromeas) / 24; + if (max_meascnt != 0) { + /* Measure end. */ + if (++mpu->clock.measure_counter >= max_meascnt) { + if (mpu->filter.rt_out) + midi_raw_out_rt_byte(0xf8); + mpu->clock.measure_counter = 0; + if (mpu->filter.rec_measure_end && (mpu->state.rec == M_RECON)) + mpu->state.req_mask |= (1 << 12); + } + } } if (MPU401_IRQPending(mpu) && mpu->state.req_mask) - MPU401_EOIHandler(mpu); + MPU401_EOIHandler(mpu); next_event: MPU401_RunClock(mpu); if (mpu->state.sync_in) - mpu->clock.ticks_in++; + mpu->clock.ticks_in++; } - static void MPU401_NotesOff(mpu_t *mpu, int i) { - int j; + int j; uint8_t key; - if (mpu->filter.allnotesoff_out && !(mpu->inputref[i].on && - (mpu->inputref[i].key[0] | mpu->inputref[i].key[1] | - mpu->inputref[i].key[2] | mpu->inputref[i].key[3]))) { - for (j=0;j<4;j++) - mpu->chanref[mpu->ch_toref[i]].key[j]=0; - midi_raw_out_byte(0xb0 | i); - midi_raw_out_byte(123); - midi_raw_out_byte(0); + if (mpu->filter.allnotesoff_out && !(mpu->inputref[i].on && (mpu->inputref[i].key[0] | mpu->inputref[i].key[1] | mpu->inputref[i].key[2] | mpu->inputref[i].key[3]))) { + for (j = 0; j < 4; j++) + mpu->chanref[mpu->ch_toref[i]].key[j] = 0; + midi_raw_out_byte(0xb0 | i); + midi_raw_out_byte(123); + midi_raw_out_byte(0); } else if (mpu->chanref[mpu->ch_toref[i]].on) { - for (key = 0; key < 128; key++) { - if ((mpu->chanref[mpu->ch_toref[i]].M_GETKEY) && - !(mpu->inputref[i].on && (mpu->inputref[i].M_GETKEY))) { - midi_raw_out_byte(0x80|i); - midi_raw_out_byte(key); - midi_raw_out_byte(0); - } - mpu->chanref[mpu->ch_toref[i]].M_DELKEY; - } + for (key = 0; key < 128; key++) { + if ((mpu->chanref[mpu->ch_toref[i]].M_GETKEY) && !(mpu->inputref[i].on && (mpu->inputref[i].M_GETKEY))) { + midi_raw_out_byte(0x80 | i); + midi_raw_out_byte(key); + midi_raw_out_byte(0); + } + mpu->chanref[mpu->ch_toref[i]].M_DELKEY; + } } } - /*Input handler for SysEx */ int MPU401_InputSysex(void *p, uint8_t *buffer, uint32_t len, int abort) { - mpu_t *mpu = (mpu_t *)p; - int i; + mpu_t *mpu = (mpu_t *) p; + int i; uint8_t val_ff = 0xff; mpu401_log("MPU401 Input Sysex\n"); @@ -1390,63 +1392,62 @@ MPU401_InputSysex(void *p, uint8_t *buffer, uint32_t len, int abort) #else if (!mpu->intelligent || mpu->mode == M_UART) { #endif - /* UART mode input. */ - for (i = 0; i < len; i++) - MPU401_QueueByte(mpu, buffer[i]); - return 0; + /* UART mode input. */ + for (i = 0; i < len; i++) + MPU401_QueueByte(mpu, buffer[i]); + return 0; } if (mpu->filter.sysex_in) { - if (abort) { - mpu->state.sysex_in_finished=1; - mpu->rec_queue_used=0;/*reset also the input queue*/ - return 0; - } - if (mpu->state.sysex_in_finished) { - if (mpu->rec_queue_used>=MPU401_INPUT_QUEUE) - return len; - MPU401_RecQueueBuffer(mpu, &val_ff, 1, 1); - mpu->state.sysex_in_finished=0; - mpu->clock.rec_counter=0; - } - if (mpu->rec_queue_used>=MPU401_INPUT_QUEUE) - return len; - int available = MPU401_INPUT_QUEUE - mpu->rec_queue_used; + if (abort) { + mpu->state.sysex_in_finished = 1; + mpu->rec_queue_used = 0; /*reset also the input queue*/ + return 0; + } + if (mpu->state.sysex_in_finished) { + if (mpu->rec_queue_used >= MPU401_INPUT_QUEUE) + return len; + MPU401_RecQueueBuffer(mpu, &val_ff, 1, 1); + mpu->state.sysex_in_finished = 0; + mpu->clock.rec_counter = 0; + } + if (mpu->rec_queue_used >= MPU401_INPUT_QUEUE) + return len; + int available = MPU401_INPUT_QUEUE - mpu->rec_queue_used; - if (available >= len) { - MPU401_RecQueueBuffer(mpu, buffer, len, 1); - return 0; - } else { - MPU401_RecQueueBuffer(mpu,buffer, available, 1); - if (mpu->state.sysex_in_finished) - return 0; - return (len - available); - } + if (available >= len) { + MPU401_RecQueueBuffer(mpu, buffer, len, 1); + return 0; + } else { + MPU401_RecQueueBuffer(mpu, buffer, available, 1); + if (mpu->state.sysex_in_finished) + return 0; + return (len - available); + } } else if (mpu->filter.sysex_thru && mpu->midi_thru) { - midi_raw_out_byte(0xf0); - for (i = 0; i < len; i++) - midi_raw_out_byte(*(buffer+i)); + midi_raw_out_byte(0xf0); + for (i = 0; i < len; i++) + midi_raw_out_byte(*(buffer + i)); } return 0; } - /*Input handler for MIDI*/ void MPU401_InputMsg(void *p, uint8_t *msg, uint32_t len) { - mpu_t *mpu = (mpu_t *)p; - int i, tick; + mpu_t *mpu = (mpu_t *) p; + int i, tick; static uint8_t old_msg = 0; - uint8_t key; - uint8_t recdata[2], recmsg[4]; - int send = 1, send_thru = 0; - int retrigger_thru = 0, chan, chrefnum; + uint8_t key; + uint8_t recdata[2], recmsg[4]; + int send = 1, send_thru = 0; + int retrigger_thru = 0, chan, chrefnum; /* Abort if sysex transfer is in progress. */ if (!mpu->state.sysex_in_finished) { - mpu401_log("SYSEX in progress\n"); - return; + mpu401_log("SYSEX in progress\n"); + return; } mpu401_log("MPU401 Input Msg\n"); @@ -1456,202 +1457,202 @@ MPU401_InputMsg(void *p, uint8_t *msg, uint32_t len) #else if (mpu->intelligent && (mpu->mode == M_INTELLIGENT)) { #endif - if (msg[0] < 0x80) { - /* Expand running status */ - msg[2] = msg[1]; - msg[1] = msg[0]; - msg[0] = old_msg; - } - old_msg = msg[0]; - chan = msg[0] & 0xf; - chrefnum = mpu->ch_toref[chan]; - key = msg[1] & 0x7f; - if (msg[0] < 0xf0) { - /* If non-system msg. */ - if (!(mpu->state.midi_mask & (1 << chan)) && mpu->filter.all_thru) - send_thru = 1; - else if (mpu->filter.midi_thru) - send_thru = 1; - switch (msg[0] & 0xf0) { - case 0x80: /* Note off. */ - if (send_thru) { - if (mpu->chanref[chrefnum].on && (mpu->chanref[chrefnum].M_GETKEY)) - send_thru = 0; - if (!mpu->filter.midi_thru) - break; - if (!(mpu->inputref[chan].M_GETKEY)) - send_thru = 0; - mpu->inputref[chan].M_DELKEY; - } - break; - case 0x90: /* Note on. */ - if (send_thru) { - if (mpu->chanref[chrefnum].on && (mpu->chanref[chrefnum].M_GETKEY)) - retrigger_thru = 1; - if (!mpu->filter.midi_thru) - break; - if (mpu->inputref[chan].M_GETKEY) - retrigger_thru = 1; - mpu->inputref[chan].M_SETKEY; - } - break; - case 0xb0: - if (msg[1] >= 120) { - send_thru = 0; - if (msg[1] == 123) { - /* All notes off. */ - for (key = 0; key < 128; key++) { - if (!(mpu->chanref[chrefnum].on && (mpu->chanref[chrefnum].M_GETKEY))) { - if (mpu->inputref[chan].on && mpu->inputref[chan].M_GETKEY) { - midi_raw_out_byte(0x80 | chan); - midi_raw_out_byte(key); - midi_raw_out_byte(0); - } - mpu->inputref[chan].M_DELKEY; - } - } - } - break; - } - } - } - if ((msg[0] >= 0xf0) || (mpu->state.midi_mask & (1 << chan))) { - switch (msg[0] & 0xf0) { - case 0xa0: /* Aftertouch. */ - if (!mpu->filter.bender_in) - send = 0; - break; - case 0xb0: /* Control change. */ - if (!mpu->filter.bender_in && (msg[1] < 64)) - send = 0; - if (msg[1] >= 120) { - if (mpu->filter.modemsgs_in) - send = 1; - } - break; - case 0xc0: /* Program change. */ - if ((mpu->state.rec != M_RECON) && !mpu->filter.data_in_stop) { - mpu->filter.prchg_buf[chan] = msg[1]; - mpu->filter.prchg_mask |= 1 << chan; - } - break; - case 0xd0: /* Ch pressure. */ - case 0xe0: /* Pitch wheel. */ - if (!mpu->filter.bender_in) - send = 0; - break; - case 0xf0: /* System message. */ - if (msg[0] == 0xf8) { - send = 0; - if (mpu->clock.active && mpu->state.sync_in) { - send = 0; /* Don't pass to host in this mode? */ - tick = mpu->clock.timebase / 24; - if (mpu->clock.ticks_in != tick) { - if (!mpu->clock.ticks_in || (mpu->clock.ticks_in > (tick * 2))) - mpu->clock.freq_mod *= 2.0; - else { - if (ABS(mpu->clock.ticks_in-tick) == 1) - mpu->clock.freq_mod /= mpu->clock.ticks_in / (float) (tick * 2); - else - mpu->clock.freq_mod /= mpu->clock.ticks_in / (float) (tick); - } - MPU401_ReCalcClock(mpu); - } - mpu->clock.ticks_in = 0; - } - } else if (msg[0] > 0xf8) { /* Realtime. */ - if (!(mpu->filter.rt_in && (msg[0] <= 0xfc) && (msg[0] >= 0xfa))) { - recdata[0] = 0xff; - recdata[1] = msg[0]; - MPU401_RecQueueBuffer(mpu, recdata, 2, 1); - send = 0; - } - } else { /* Common or system. */ - send = 0; - if ((msg[0] == 0xf2) || (msg[0] == 0xf3) || (msg[0] == 0xf6)) { - if (mpu->filter.commonmsgs_in) - send = 1; - if (mpu->filter.commonmsgs_thru) - for (i = 0; i < len; i++) - midi_raw_out_byte(msg[i]); - } - } - if (send) { - recmsg[0] = 0xff; - recmsg[1] = msg[0]; - recmsg[2] = msg[1]; - recmsg[3] = msg[2]; - MPU401_RecQueueBuffer(mpu, recmsg, len + 1, 1); - } - if (mpu->filter.rt_affection) { - switch(msg[0]) { - case 0xf2: case 0xf3: - mpu->state.block_ack = 1; - MPU401_WriteCommand(mpu, 0xb8); /* Clear play counters. */ - break; - case 0xfa: - mpu->state.block_ack = 1; - MPU401_WriteCommand(mpu, 0xa); /* Start, play. */ - if (mpu->filter.rt_out) - midi_raw_out_rt_byte(msg[0]); - break; - case 0xfb: - mpu->state.block_ack = 1; - MPU401_WriteCommand(mpu, 0xb); /* Continue, play. */ - if (mpu->filter.rt_out) - midi_raw_out_rt_byte(msg[0]); - break; - case 0xfc: - mpu->state.block_ack = 1; - MPU401_WriteCommand(mpu, 0xd) ;/* Stop: Play, rec, midi */ - if (mpu->filter.rt_out) - midi_raw_out_rt_byte(msg[0]); - break; - } - return; - } - } - } - if (send_thru && mpu->midi_thru) { - if (retrigger_thru) { - midi_raw_out_byte(0x80 | (msg[0] & 0xf)); - midi_raw_out_byte(msg[1]); - midi_raw_out_byte(msg[2]); - } - for (i = 0; i < len; i++) - midi_raw_out_byte(msg[i]); - } - if (send) { - if (mpu->state.rec == M_RECON) { - recmsg[0] = mpu->clock.rec_counter; - recmsg[1] = msg[0]; - recmsg[2] = msg[1]; - recmsg[3] = msg[2]; - MPU401_RecQueueBuffer(mpu, recmsg, len + 1, 1); - mpu->clock.rec_counter = 0; - } - else if (mpu->filter.data_in_stop) { - if (mpu->filter.timing_in_stop) { - recmsg[0] = 0; - recmsg[1] = msg[0]; - recmsg[2] = msg[1]; - recmsg[3] = msg[2]; - MPU401_RecQueueBuffer(mpu, recmsg, len + 1, 1); - } else { - recmsg[0] = msg[0]; - recmsg[1] = msg[1]; - recmsg[2] = msg[2]; - recmsg[3] = 0; - MPU401_RecQueueBuffer(mpu, recmsg, len, 1); - } - } - } - return; + if (msg[0] < 0x80) { + /* Expand running status */ + msg[2] = msg[1]; + msg[1] = msg[0]; + msg[0] = old_msg; + } + old_msg = msg[0]; + chan = msg[0] & 0xf; + chrefnum = mpu->ch_toref[chan]; + key = msg[1] & 0x7f; + if (msg[0] < 0xf0) { + /* If non-system msg. */ + if (!(mpu->state.midi_mask & (1 << chan)) && mpu->filter.all_thru) + send_thru = 1; + else if (mpu->filter.midi_thru) + send_thru = 1; + switch (msg[0] & 0xf0) { + case 0x80: /* Note off. */ + if (send_thru) { + if (mpu->chanref[chrefnum].on && (mpu->chanref[chrefnum].M_GETKEY)) + send_thru = 0; + if (!mpu->filter.midi_thru) + break; + if (!(mpu->inputref[chan].M_GETKEY)) + send_thru = 0; + mpu->inputref[chan].M_DELKEY; + } + break; + case 0x90: /* Note on. */ + if (send_thru) { + if (mpu->chanref[chrefnum].on && (mpu->chanref[chrefnum].M_GETKEY)) + retrigger_thru = 1; + if (!mpu->filter.midi_thru) + break; + if (mpu->inputref[chan].M_GETKEY) + retrigger_thru = 1; + mpu->inputref[chan].M_SETKEY; + } + break; + case 0xb0: + if (msg[1] >= 120) { + send_thru = 0; + if (msg[1] == 123) { + /* All notes off. */ + for (key = 0; key < 128; key++) { + if (!(mpu->chanref[chrefnum].on && (mpu->chanref[chrefnum].M_GETKEY))) { + if (mpu->inputref[chan].on && mpu->inputref[chan].M_GETKEY) { + midi_raw_out_byte(0x80 | chan); + midi_raw_out_byte(key); + midi_raw_out_byte(0); + } + mpu->inputref[chan].M_DELKEY; + } + } + } + break; + } + } + } + if ((msg[0] >= 0xf0) || (mpu->state.midi_mask & (1 << chan))) { + switch (msg[0] & 0xf0) { + case 0xa0: /* Aftertouch. */ + if (!mpu->filter.bender_in) + send = 0; + break; + case 0xb0: /* Control change. */ + if (!mpu->filter.bender_in && (msg[1] < 64)) + send = 0; + if (msg[1] >= 120) { + if (mpu->filter.modemsgs_in) + send = 1; + } + break; + case 0xc0: /* Program change. */ + if ((mpu->state.rec != M_RECON) && !mpu->filter.data_in_stop) { + mpu->filter.prchg_buf[chan] = msg[1]; + mpu->filter.prchg_mask |= 1 << chan; + } + break; + case 0xd0: /* Ch pressure. */ + case 0xe0: /* Pitch wheel. */ + if (!mpu->filter.bender_in) + send = 0; + break; + case 0xf0: /* System message. */ + if (msg[0] == 0xf8) { + send = 0; + if (mpu->clock.active && mpu->state.sync_in) { + send = 0; /* Don't pass to host in this mode? */ + tick = mpu->clock.timebase / 24; + if (mpu->clock.ticks_in != tick) { + if (!mpu->clock.ticks_in || (mpu->clock.ticks_in > (tick * 2))) + mpu->clock.freq_mod *= 2.0; + else { + if (ABS(mpu->clock.ticks_in - tick) == 1) + mpu->clock.freq_mod /= mpu->clock.ticks_in / (float) (tick * 2); + else + mpu->clock.freq_mod /= mpu->clock.ticks_in / (float) (tick); + } + MPU401_ReCalcClock(mpu); + } + mpu->clock.ticks_in = 0; + } + } else if (msg[0] > 0xf8) { /* Realtime. */ + if (!(mpu->filter.rt_in && (msg[0] <= 0xfc) && (msg[0] >= 0xfa))) { + recdata[0] = 0xff; + recdata[1] = msg[0]; + MPU401_RecQueueBuffer(mpu, recdata, 2, 1); + send = 0; + } + } else { /* Common or system. */ + send = 0; + if ((msg[0] == 0xf2) || (msg[0] == 0xf3) || (msg[0] == 0xf6)) { + if (mpu->filter.commonmsgs_in) + send = 1; + if (mpu->filter.commonmsgs_thru) + for (i = 0; i < len; i++) + midi_raw_out_byte(msg[i]); + } + } + if (send) { + recmsg[0] = 0xff; + recmsg[1] = msg[0]; + recmsg[2] = msg[1]; + recmsg[3] = msg[2]; + MPU401_RecQueueBuffer(mpu, recmsg, len + 1, 1); + } + if (mpu->filter.rt_affection) { + switch (msg[0]) { + case 0xf2: + case 0xf3: + mpu->state.block_ack = 1; + MPU401_WriteCommand(mpu, 0xb8); /* Clear play counters. */ + break; + case 0xfa: + mpu->state.block_ack = 1; + MPU401_WriteCommand(mpu, 0xa); /* Start, play. */ + if (mpu->filter.rt_out) + midi_raw_out_rt_byte(msg[0]); + break; + case 0xfb: + mpu->state.block_ack = 1; + MPU401_WriteCommand(mpu, 0xb); /* Continue, play. */ + if (mpu->filter.rt_out) + midi_raw_out_rt_byte(msg[0]); + break; + case 0xfc: + mpu->state.block_ack = 1; + MPU401_WriteCommand(mpu, 0xd); /* Stop: Play, rec, midi */ + if (mpu->filter.rt_out) + midi_raw_out_rt_byte(msg[0]); + break; + } + return; + } + } + } + if (send_thru && mpu->midi_thru) { + if (retrigger_thru) { + midi_raw_out_byte(0x80 | (msg[0] & 0xf)); + midi_raw_out_byte(msg[1]); + midi_raw_out_byte(msg[2]); + } + for (i = 0; i < len; i++) + midi_raw_out_byte(msg[i]); + } + if (send) { + if (mpu->state.rec == M_RECON) { + recmsg[0] = mpu->clock.rec_counter; + recmsg[1] = msg[0]; + recmsg[2] = msg[1]; + recmsg[3] = msg[2]; + MPU401_RecQueueBuffer(mpu, recmsg, len + 1, 1); + mpu->clock.rec_counter = 0; + } else if (mpu->filter.data_in_stop) { + if (mpu->filter.timing_in_stop) { + recmsg[0] = 0; + recmsg[1] = msg[0]; + recmsg[2] = msg[1]; + recmsg[3] = msg[2]; + MPU401_RecQueueBuffer(mpu, recmsg, len + 1, 1); + } else { + recmsg[0] = msg[0]; + recmsg[1] = msg[1]; + recmsg[2] = msg[2]; + recmsg[3] = 0; + MPU401_RecQueueBuffer(mpu, recmsg, len, 1); + } + } + } + return; } /* UART mode input. */ for (i = 0; i < len; i++) - MPU401_QueueByte(mpu, msg[i]); + MPU401_QueueByte(mpu, msg[i]); } void @@ -1664,39 +1665,38 @@ void mpu401_change_addr(mpu_t *mpu, uint16_t addr) { if (mpu == NULL) - return; + return; if (mpu->addr) - io_removehandler(mpu->addr, 2, - mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); + io_removehandler(mpu->addr, 2, + mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); mpu->addr = addr; if (mpu->addr) - io_sethandler(mpu->addr, 2, - mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); + io_sethandler(mpu->addr, 2, + mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); } - void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode, int receive_input) { - mpu->status = STATUS_INPUT_NOT_READY; - mpu->irq = irq; + mpu->status = STATUS_INPUT_NOT_READY; + mpu->irq = irq; mpu->queue_used = 0; - mpu->queue_pos = 0; - mpu->mode = M_UART; - mpu->addr = addr; + mpu->queue_pos = 0; + mpu->mode = M_UART; + mpu->addr = addr; /* Expalantion: - MPU-401 starting in intelligent mode = Full MPU-401 intelligent mode capability; - MPU-401 starting in UART mode = Reduced MPU-401 intelligent mode capability seen on the Sound Blaster 16/AWE32, - only supporting commands 3F (set UART mode) and FF (reset). */ + MPU-401 starting in intelligent mode = Full MPU-401 intelligent mode capability; + MPU-401 starting in UART mode = Reduced MPU-401 intelligent mode capability seen on the Sound Blaster 16/AWE32, + only supporting commands 3F (set UART mode) and FF (reset). */ mpu->intelligent = (mode == M_INTELLIGENT) ? 1 : 0; mpu401_log("Starting as %s (mode is %s)\n", mpu->intelligent ? "INTELLIGENT" : "UART", (mode == M_INTELLIGENT) ? "INTELLIGENT" : "UART"); if (mpu->addr) - io_sethandler(mpu->addr, 2, - mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); + io_sethandler(mpu->addr, 2, + mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); io_sethandler(0x2A20, 16, - NULL, NULL, NULL, imf_write, NULL, NULL, mpu); + NULL, NULL, NULL, imf_write, NULL, NULL, mpu); timer_add(&mpu->mpu401_event_callback, MPU401_Event, mpu, 0); timer_add(&mpu->mpu401_eoi_callback, MPU401_EOIHandler, mpu, 0); timer_add(&mpu->mpu401_reset_callback, MPU401_ResetDone, mpu, 0); @@ -1704,40 +1704,37 @@ mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode, int receive_input) MPU401_Reset(mpu); if (receive_input) - midi_in_handler(1, MPU401_InputMsg, MPU401_InputSysex, mpu); + midi_in_handler(1, MPU401_InputMsg, MPU401_InputSysex, mpu); } - void mpu401_device_add(void) { if (!mpu401_standalone_enable) - return; + return; if (machine_has_bus(machine, MACHINE_BUS_MCA)) - device_add(&mpu401_mca_device); + device_add(&mpu401_mca_device); else - device_add(&mpu401_device); + device_add(&mpu401_device); } - static uint8_t mpu401_mca_read(int port, void *p) { - mpu_t *mpu = (mpu_t *)p; + mpu_t *mpu = (mpu_t *) p; return mpu->pos_regs[port & 7]; } - static void mpu401_mca_write(int port, uint8_t val, void *p) { - mpu_t *mpu = (mpu_t *)p; + mpu_t *mpu = (mpu_t *) p; uint16_t addr; if (port < 0x102) - return; + return; addr = (mpu->pos_regs[2] & 2) ? 0x0330 : 0x1330; @@ -1746,38 +1743,35 @@ mpu401_mca_write(int port, uint8_t val, void *p) mpu->pos_regs[port] = val; if (port == 2) { - io_removehandler(addr, 2, - mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); + io_removehandler(addr, 2, + mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); - addr = (mpu->pos_regs[2] & 2) ? 0x1330 : 0x0330; + addr = (mpu->pos_regs[2] & 2) ? 0x1330 : 0x0330; - io_sethandler(addr, 2, - mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); + io_sethandler(addr, 2, + mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); } } - static uint8_t mpu401_mca_feedb(void *p) { return 1; } - void mpu401_irq_attach(mpu_t *mpu, void (*ext_irq_update)(void *priv, int set), int (*ext_irq_pending)(void *priv), void *priv) { - mpu->ext_irq_update = ext_irq_update; + mpu->ext_irq_update = ext_irq_update; mpu->ext_irq_pending = ext_irq_pending; - mpu->priv = priv; + mpu->priv = priv; } - static void * mpu401_standalone_init(const device_t *info) { - mpu_t *mpu; - int irq; + mpu_t *mpu; + int irq; uint16_t base; mpu = malloc(sizeof(mpu_t)); @@ -1786,125 +1780,90 @@ mpu401_standalone_init(const device_t *info) mpu401_log("mpu_init\n"); if (info->flags & DEVICE_MCA) { - mca_add(mpu401_mca_read, mpu401_mca_write, mpu401_mca_feedb, NULL, mpu); - mpu->pos_regs[0] = 0x0F; - mpu->pos_regs[1] = 0x6C; - base = 0; /* Tell mpu401_init() that this is the MCA variant. */ - irq = 2; /* According to @6c0f.adf, the IRQ is fixed to 2. */ + mca_add(mpu401_mca_read, mpu401_mca_write, mpu401_mca_feedb, NULL, mpu); + mpu->pos_regs[0] = 0x0F; + mpu->pos_regs[1] = 0x6C; + base = 0; /* Tell mpu401_init() that this is the MCA variant. */ + irq = 2; /* According to @6c0f.adf, the IRQ is fixed to 2. */ } else { - base = device_get_config_hex16("base"); - irq = device_get_config_int("irq"); + base = device_get_config_hex16("base"); + irq = device_get_config_int("irq"); } mpu401_init(mpu, base, irq, M_INTELLIGENT, device_get_config_int("receive_input")); - return(mpu); + return (mpu); } - static void mpu401_standalone_close(void *priv) { - mpu_t *mpu = (mpu_t *)priv; + mpu_t *mpu = (mpu_t *) priv; free(mpu); } - -static const device_config_t mpu401_standalone_config[] = -{ +static const device_config_t mpu401_standalone_config[] = { + // clang-format off + { + "base", "MPU-401 Address", CONFIG_HEX16, "", 0x330, "", { 0 }, { - "base", "MPU-401 Address", CONFIG_HEX16, "", 0x330, "", { 0 }, - { - { - "0x220", 0x220 - }, - { - "0x230", 0x230 - }, - { - "0x240", 0x240 - }, - { - "0x250", 0x250 - }, - { - "0x300", 0x300 - }, - { - "0x320", 0x320 - }, - { - "0x330", 0x330 - }, - { - "0x340", 0x340 - }, - { - "0x350", 0x350 - }, - { - "" - } - } - }, - { - "irq", "MPU-401 IRQ", CONFIG_SELECTION, "", 2, "", { 0 }, - { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 6", 6 - }, - { - "IRQ 7", 7 - }, - { - "" - } - } - }, - { - .name = "receive_input", - .description = "Receive input", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - "", "", -1 + { "0x220", 0x220 }, + { "0x230", 0x230 }, + { "0x240", 0x240 }, + { "0x250", 0x250 }, + { "0x300", 0x300 }, + { "0x320", 0x320 }, + { "0x330", 0x330 }, + { "0x340", 0x340 }, + { "0x350", 0x350 }, + { "" } } + }, + { + "irq", "MPU-401 IRQ", CONFIG_SELECTION, "", 2, "", { 0 }, + { + { "IRQ 2", 2 }, + { "IRQ 3", 3 }, + { "IRQ 4", 4 }, + { "IRQ 5", 5 }, + { "IRQ 6", 6 }, + { "IRQ 7", 7 }, + { "" } + } + }, + { + .name = "receive_input", + .description = "Receive input", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { "", "", -1 } + // clang-format on }; - -static const device_config_t mpu401_standalone_mca_config[] = -{ - { - .name = "receive_input", - .description = "Receive input", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - "", "", -1 - } +static const device_config_t mpu401_standalone_mca_config[] = { + // clang-format off + { + .name = "receive_input", + .description = "Receive input", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + "", "", -1 + } + // clang-format on }; - const device_t mpu401_device = { "Roland MPU-IPC-T", "mpu401", - DEVICE_ISA, 0, - mpu401_standalone_init, mpu401_standalone_close, NULL, + DEVICE_ISA, + 0, + mpu401_standalone_init, + mpu401_standalone_close, + NULL, { NULL }, NULL, NULL, @@ -1914,8 +1873,11 @@ const device_t mpu401_device = { const device_t mpu401_mca_device = { "Roland MPU-IMC", "mpu401_mca", - DEVICE_MCA, 0, - mpu401_standalone_init, mpu401_standalone_close, NULL, + DEVICE_MCA, + 0, + mpu401_standalone_init, + mpu401_standalone_close, + NULL, { NULL }, NULL, NULL, diff --git a/src/sound/snd_opl.c b/src/sound/snd_opl.c index 6e6afe7b5..6cba7b3e8 100644 --- a/src/sound/snd_opl.c +++ b/src/sound/snd_opl.c @@ -1,22 +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. + * 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. * - * Interface to the actual OPL emulator. + * Interface to the actual OPL emulator. * - * TODO: Finish re-working this into a device_t, which requires a - * poll-like function for "update" so the sound card can call - * that and get a buffer-full of sample data. + * TODO: Finish re-working this into a device_t, which requires a + * poll-like function for "update" so the sound card can call + * that and get a buffer-full of sample data. * - * Authors: Fred N. van Kempen, - * Miran Grca, + * Authors: Fred N. van Kempen, + * Miran Grca, * - * Copyright 2017-2020 Fred N. van Kempen. - * Copyright 2016-2020 Miran Grca. + * Copyright 2017-2020 Fred N. van Kempen. + * Copyright 2016-2020 Miran Grca. */ #include #include @@ -25,57 +25,54 @@ #include #include #define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/timer.h> + #include "cpu.h" +#include <86box/86box.h> #include <86box/io.h> +#include <86box/timer.h> #include <86box/sound.h> #include <86box/snd_opl.h> #include <86box/snd_opl_nuked.h> - enum { FLAG_CYCLES = 0x02, - FLAG_OPL3 = 0x01 + FLAG_OPL3 = 0x01 }; enum { - STAT_TMR_OVER = 0x60, + STAT_TMR_OVER = 0x60, STAT_TMR1_OVER = 0x40, STAT_TMR2_OVER = 0x20, - STAT_TMR_ANY = 0x80 + STAT_TMR_ANY = 0x80 }; enum { - CTRL_RESET = 0x80, - CTRL_TMR_MASK = 0x60, - CTRL_TMR1_MASK = 0x40, - CTRL_TMR2_MASK = 0x20, + CTRL_RESET = 0x80, + CTRL_TMR_MASK = 0x60, + CTRL_TMR1_MASK = 0x40, + CTRL_TMR2_MASK = 0x20, CTRL_TMR2_START = 0x02, CTRL_TMR1_START = 0x01 }; - #ifdef ENABLE_OPL_LOG int opl_do_log = ENABLE_OPL_LOG; - static void opl_log(const char *fmt, ...) { va_list ap; if (opl_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define opl_log(fmt, ...) +# define opl_log(fmt, ...) #endif - static void timer_tick(opl_t *dev, int tmr) { @@ -84,121 +81,114 @@ timer_tick(opl_t *dev, int tmr) opl_log("Ticking timer %i, count now %02X...\n", tmr, dev->timer_cur_count[tmr]); if (dev->timer_cur_count[tmr] == 0x00) { - dev->status |= ((STAT_TMR1_OVER >> tmr) & ~dev->timer_ctrl); - dev->timer_cur_count[tmr] = dev->timer_count[tmr]; + dev->status |= ((STAT_TMR1_OVER >> tmr) & ~dev->timer_ctrl); + dev->timer_cur_count[tmr] = dev->timer_count[tmr]; - opl_log("Count wrapped around to zero, reloading timer %i (%02X), status = %02X...\n", tmr, (STAT_TMR1_OVER >> tmr), dev->status); + opl_log("Count wrapped around to zero, reloading timer %i (%02X), status = %02X...\n", tmr, (STAT_TMR1_OVER >> tmr), dev->status); } timer_on_auto(&dev->timers[tmr], (tmr == 1) ? 320.0 : 80.0); } - static void timer_control(opl_t *dev, int tmr, int start) { timer_on_auto(&dev->timers[tmr], 0.0); if (start) { - opl_log("Loading timer %i count: %02X = %02X\n", tmr, dev->timer_cur_count[tmr], dev->timer_count[tmr]); - dev->timer_cur_count[tmr] = dev->timer_count[tmr]; - if (dev->flags & FLAG_OPL3) - timer_tick(dev, tmr); /* Per the YMF 262 datasheet, OPL3 starts counting immediately, unlike OPL2. */ - else - timer_on_auto(&dev->timers[tmr], (tmr == 1) ? 320.0 : 80.0); + opl_log("Loading timer %i count: %02X = %02X\n", tmr, dev->timer_cur_count[tmr], dev->timer_count[tmr]); + dev->timer_cur_count[tmr] = dev->timer_count[tmr]; + if (dev->flags & FLAG_OPL3) + timer_tick(dev, tmr); /* Per the YMF 262 datasheet, OPL3 starts counting immediately, unlike OPL2. */ + else + timer_on_auto(&dev->timers[tmr], (tmr == 1) ? 320.0 : 80.0); } else { - opl_log("Timer %i stopped\n", tmr); - if (tmr == 1) { - dev->status &= ~STAT_TMR2_OVER; - } else - dev->status &= ~STAT_TMR1_OVER; - } + opl_log("Timer %i stopped\n", tmr); + if (tmr == 1) { + dev->status &= ~STAT_TMR2_OVER; + } else + dev->status &= ~STAT_TMR1_OVER; + } } - static void timer_1(void *priv) { - opl_t *dev = (opl_t *)priv; + opl_t *dev = (opl_t *) priv; timer_tick(dev, 0); } - static void timer_2(void *priv) { - opl_t *dev = (opl_t *)priv; + opl_t *dev = (opl_t *) priv; timer_tick(dev, 1); } - static uint8_t opl_read(opl_t *dev, uint16_t port) { uint8_t ret = 0xff; if ((port & 0x0003) == 0x0000) { - ret = dev->status; - if (dev->status & STAT_TMR_OVER) - ret |= STAT_TMR_ANY; + ret = dev->status; + if (dev->status & STAT_TMR_OVER) + ret |= STAT_TMR_ANY; } - opl_log("OPL statret = %02x, status = %02x\n", ret, dev->status); + opl_log("OPL statret = %02x, status = %02x\n", ret, dev->status); return ret; } - static void opl_write(opl_t *dev, uint16_t port, uint8_t val) { if ((port & 0x0001) == 0x0001) { - nuked_write_reg_buffered(dev->opl, dev->port, val); + nuked_write_reg_buffered(dev->opl, dev->port, val); - switch (dev->port) { - case 0x02: /* Timer 1 */ - dev->timer_count[0] = val; - opl_log("Timer 0 count now: %i\n", dev->timer_count[0]); - break; + switch (dev->port) { + case 0x02: /* Timer 1 */ + dev->timer_count[0] = val; + opl_log("Timer 0 count now: %i\n", dev->timer_count[0]); + break; - case 0x03: /* Timer 2 */ - dev->timer_count[1] = val; - opl_log("Timer 1 count now: %i\n", dev->timer_count[1]); - break; + case 0x03: /* Timer 2 */ + dev->timer_count[1] = val; + opl_log("Timer 1 count now: %i\n", dev->timer_count[1]); + break; - case 0x04: /* Timer control */ - if (val & CTRL_RESET) { - opl_log("Resetting timer status...\n"); - dev->status &= ~STAT_TMR_OVER; - } else { - dev->timer_ctrl = val; - timer_control(dev, 0, val & CTRL_TMR1_START); - timer_control(dev, 1, val & CTRL_TMR2_START); - opl_log("Status mask now %02X (val = %02X)\n", (val & ~CTRL_TMR_MASK) & CTRL_TMR_MASK, val); - } - break; - } + case 0x04: /* Timer control */ + if (val & CTRL_RESET) { + opl_log("Resetting timer status...\n"); + dev->status &= ~STAT_TMR_OVER; + } else { + dev->timer_ctrl = val; + timer_control(dev, 0, val & CTRL_TMR1_START); + timer_control(dev, 1, val & CTRL_TMR2_START); + opl_log("Status mask now %02X (val = %02X)\n", (val & ~CTRL_TMR_MASK) & CTRL_TMR_MASK, val); + } + break; + } } else { - dev->port = nuked_write_addr(dev->opl, port, val) & 0x01ff; + dev->port = nuked_write_addr(dev->opl, port, val) & 0x01ff; - if (!(dev->flags & FLAG_OPL3)) - dev->port &= 0x00ff; + if (!(dev->flags & FLAG_OPL3)) + dev->port &= 0x00ff; } } - void opl_set_do_cycles(opl_t *dev, int8_t do_cycles) { if (do_cycles) - dev->flags |= FLAG_CYCLES; + dev->flags |= FLAG_CYCLES; else - dev->flags &= ~FLAG_CYCLES; + dev->flags &= ~FLAG_CYCLES; } - static void opl_init(opl_t *dev, int is_opl3) { @@ -206,9 +196,9 @@ opl_init(opl_t *dev, int is_opl3) dev->flags = FLAG_CYCLES; if (is_opl3) - dev->flags |= FLAG_OPL3; + dev->flags |= FLAG_OPL3; else - dev->status = 0x06; + dev->status = 0x06; /* Create a NukedOPL object. */ dev->opl = nuked_init(48000); @@ -217,115 +207,106 @@ opl_init(opl_t *dev, int is_opl3) timer_add(&dev->timers[1], timer_2, dev, 0); } - void opl_close(opl_t *dev) { /* Release the NukedOPL object. */ if (dev->opl) { - nuked_close(dev->opl); - dev->opl = NULL; + nuked_close(dev->opl); + dev->opl = NULL; } } - uint8_t opl2_read(uint16_t port, void *priv) { - opl_t *dev = (opl_t *)priv; + opl_t *dev = (opl_t *) priv; if (dev->flags & FLAG_CYCLES) - cycles -= ((int) (isa_timing * 8)); + cycles -= ((int) (isa_timing * 8)); opl2_update(dev); - opl_log("OPL2 port read = %04x\n", port); + opl_log("OPL2 port read = %04x\n", port); - return(opl_read(dev, port)); + return (opl_read(dev, port)); } - void opl2_write(uint16_t port, uint8_t val, void *priv) { - opl_t *dev = (opl_t *)priv; + opl_t *dev = (opl_t *) priv; opl2_update(dev); - opl_log("OPL2 port write = %04x\n", port); + opl_log("OPL2 port write = %04x\n", port); opl_write(dev, port, val); } - void opl2_init(opl_t *dev) { opl_init(dev, 0); } - void opl2_update(opl_t *dev) { if (dev->pos >= sound_pos_global) { - return; - } + return; + } nuked_generate_stream(dev->opl, - &dev->buffer[dev->pos * 2], - sound_pos_global - dev->pos); + &dev->buffer[dev->pos * 2], + sound_pos_global - dev->pos); for (; dev->pos < sound_pos_global; dev->pos++) { - dev->buffer[dev->pos * 2] /= 2; - dev->buffer[(dev->pos * 2) + 1] = dev->buffer[dev->pos * 2]; + dev->buffer[dev->pos * 2] /= 2; + dev->buffer[(dev->pos * 2) + 1] = dev->buffer[dev->pos * 2]; } } - uint8_t opl3_read(uint16_t port, void *priv) { - opl_t *dev = (opl_t *)priv; + opl_t *dev = (opl_t *) priv; if (dev->flags & FLAG_CYCLES) - cycles -= ((int)(isa_timing * 8)); + cycles -= ((int) (isa_timing * 8)); opl3_update(dev); - return(opl_read(dev, port)); + return (opl_read(dev, port)); } - void opl3_write(uint16_t port, uint8_t val, void *priv) { - opl_t *dev = (opl_t *)priv; + opl_t *dev = (opl_t *) priv; opl3_update(dev); opl_write(dev, port, val); } - void opl3_init(opl_t *dev) { opl_init(dev, 1); } - /* API to sound interface. */ void opl3_update(opl_t *dev) { if (dev->pos >= sound_pos_global) - return; + return; nuked_generate_stream(dev->opl, - &dev->buffer[dev->pos * 2], - sound_pos_global - dev->pos); + &dev->buffer[dev->pos * 2], + sound_pos_global - dev->pos); for (; dev->pos < sound_pos_global; dev->pos++) { - dev->buffer[dev->pos * 2] /= 2; - dev->buffer[(dev->pos * 2) + 1] /= 2; + dev->buffer[dev->pos * 2] /= 2; + dev->buffer[(dev->pos * 2) + 1] /= 2; } } diff --git a/src/sound/snd_opl_nuked.c b/src/sound/snd_opl_nuked.c index 2ac17c75e..347316e4e 100644 --- a/src/sound/snd_opl_nuked.c +++ b/src/sound/snd_opl_nuked.c @@ -1,61 +1,60 @@ /* - * 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. * - * Nuked OPL3 emulator. + * Nuked OPL3 emulator. * - * Thanks: - * MAME Development Team(Jarek Burczynski, Tatsuyuki Satoh): - * Feedback and Rhythm part calculation information. - * forums.submarine.org.uk(carbon14, opl3): - * Tremolo and phase generator calculation information. - * OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): - * OPL2 ROMs. - * siliconpr0n.org(John McMaster, digshadow): - * YMF262 and VRC VII decaps and die shots. + * Thanks: + * MAME Development Team(Jarek Burczynski, Tatsuyuki Satoh): + * Feedback and Rhythm part calculation information. + * forums.submarine.org.uk(carbon14, opl3): + * Tremolo and phase generator calculation information. + * OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): + * OPL2 ROMs. + * siliconpr0n.org(John McMaster, digshadow): + * YMF262 and VRC VII decaps and die shots. * - * Version: 1.8.0 + * Version: 1.8.0 * - * Translation from C++ into C done by Miran Grca. + * Translation from C++ into C done by Miran Grca. * - * **TODO** The OPL3 is a stereo chip, and, thus, always generates - * a two-sample stream of data, for the L and R channels, - * in that order. The OPL2, however, is mono. What should - * we generate for that? + * **TODO** The OPL3 is a stereo chip, and, thus, always generates + * a two-sample stream of data, for the L and R channels, + * in that order. The OPL2, however, is mono. What should + * we generate for that? * - * Version: @(#)snd_opl_nuked.c 1.0.5 2020/07/16 + * Version: @(#)snd_opl_nuked.c 1.0.5 2020/07/16 * - * Authors: Fred N. van Kempen, - * Miran Grca, - * Alexey Khokholov (Nuke.YKT) + * Authors: Fred N. van Kempen, + * Miran Grca, + * Alexey Khokholov (Nuke.YKT) * - * Copyright 2017-2020 Fred N. van Kempen. - * Copyright 2016-2020 Miran Grca. - * Copyright 2013-2018 Alexey Khokholov (Nuke.YKT) + * Copyright 2017-2020 Fred N. van Kempen. + * Copyright 2016-2020 Miran Grca. + * Copyright 2013-2018 Alexey Khokholov (Nuke.YKT) */ #include #include #include #include + #include <86box/86box.h> -#include <86box/timer.h> -#include <86box/sound.h> #include <86box/snd_opl_nuked.h> +#include <86box/sound.h> +#include <86box/timer.h> - -#define WRBUF_SIZE 1024 -#define WRBUF_DELAY 1 -#define RSM_FRAC 10 - +#define WRBUF_SIZE 1024 +#define WRBUF_DELAY 1 +#define RSM_FRAC 10 // Channel types enum { - ch_2op = 0, - ch_4op = 1, + ch_2op = 0, + ch_4op = 1, ch_4op2 = 2, ch_drum = 3 }; @@ -67,111 +66,109 @@ enum { }; enum envelope_gen_num { - envelope_gen_num_attack = 0, - envelope_gen_num_decay = 1, + envelope_gen_num_attack = 0, + envelope_gen_num_decay = 1, envelope_gen_num_sustain = 2, envelope_gen_num_release = 3 }; - struct chan; struct chip; typedef struct slot { - struct chan *chan; - struct chip *dev; - int16_t out; - int16_t fbmod; - int16_t *mod; - int16_t prout; - int16_t eg_rout; - int16_t eg_out; - uint8_t eg_inc; - uint8_t eg_gen; - uint8_t eg_rate; - uint8_t eg_ksl; - uint8_t *trem; - uint8_t reg_vib; - uint8_t reg_type; - uint8_t reg_ksr; - uint8_t reg_mult; - uint8_t reg_ksl; - uint8_t reg_tl; - uint8_t reg_ar; - uint8_t reg_dr; - uint8_t reg_sl; - uint8_t reg_rr; - uint8_t reg_wf; - uint8_t key; - uint32_t pg_reset; - uint32_t pg_phase; - uint16_t pg_phase_out; - uint8_t slot_num; + struct chan *chan; + struct chip *dev; + int16_t out; + int16_t fbmod; + int16_t *mod; + int16_t prout; + int16_t eg_rout; + int16_t eg_out; + uint8_t eg_inc; + uint8_t eg_gen; + uint8_t eg_rate; + uint8_t eg_ksl; + uint8_t *trem; + uint8_t reg_vib; + uint8_t reg_type; + uint8_t reg_ksr; + uint8_t reg_mult; + uint8_t reg_ksl; + uint8_t reg_tl; + uint8_t reg_ar; + uint8_t reg_dr; + uint8_t reg_sl; + uint8_t reg_rr; + uint8_t reg_wf; + uint8_t key; + uint32_t pg_reset; + uint32_t pg_phase; + uint16_t pg_phase_out; + uint8_t slot_num; } slot_t; typedef struct chan { - slot_t *slots[2]; - struct chan *pair; - struct chip *dev; - int16_t *out[4]; - uint8_t chtype; - uint16_t f_num; - uint8_t block; - uint8_t fb; - uint8_t con; - uint8_t alg; - uint8_t ksv; - uint16_t cha, - chb; - uint8_t ch_num; + slot_t *slots[2]; + struct chan *pair; + struct chip *dev; + int16_t *out[4]; + uint8_t chtype; + uint16_t f_num; + uint8_t block; + uint8_t fb; + uint8_t con; + uint8_t alg; + uint8_t ksv; + uint16_t cha, + chb; + uint8_t ch_num; } chan_t; typedef struct wrbuf { - uint64_t time; - uint16_t reg; - uint8_t data; + uint64_t time; + uint16_t reg; + uint8_t data; } wrbuf_t; typedef struct chip { - chan_t chan[18]; - slot_t slot[36]; - uint16_t timer; - uint64_t eg_timer; - uint8_t eg_timerrem; - uint8_t eg_state; - uint8_t eg_add; - uint8_t newm; - uint8_t nts; - uint8_t rhy; - uint8_t vibpos; - uint8_t vibshift; - uint8_t tremolo; - uint8_t tremolopos; - uint8_t tremoloshift; - uint32_t noise; - int16_t zeromod; - int32_t mixbuff[2]; - uint8_t rm_hh_bit2; - uint8_t rm_hh_bit3; - uint8_t rm_hh_bit7; - uint8_t rm_hh_bit8; - uint8_t rm_tc_bit3; - uint8_t rm_tc_bit5; + chan_t chan[18]; + slot_t slot[36]; + uint16_t timer; + uint64_t eg_timer; + uint8_t eg_timerrem; + uint8_t eg_state; + uint8_t eg_add; + uint8_t newm; + uint8_t nts; + uint8_t rhy; + uint8_t vibpos; + uint8_t vibshift; + uint8_t tremolo; + uint8_t tremolopos; + uint8_t tremoloshift; + uint32_t noise; + int16_t zeromod; + int32_t mixbuff[2]; + uint8_t rm_hh_bit2; + uint8_t rm_hh_bit3; + uint8_t rm_hh_bit7; + uint8_t rm_hh_bit8; + uint8_t rm_tc_bit3; + uint8_t rm_tc_bit5; - //OPL3L - int32_t rateratio; - int32_t samplecnt; - int32_t oldsamples[2]; - int32_t samples[2]; + // OPL3L + int32_t rateratio; + int32_t samplecnt; + int32_t oldsamples[2]; + int32_t samples[2]; - uint64_t wrbuf_samplecnt; - uint32_t wrbuf_cur; - uint32_t wrbuf_last; - uint64_t wrbuf_lasttime; - wrbuf_t wrbuf[WRBUF_SIZE]; + uint64_t wrbuf_samplecnt; + uint32_t wrbuf_cur; + uint32_t wrbuf_last; + uint64_t wrbuf_lasttime; + wrbuf_t wrbuf[WRBUF_SIZE]; } nuked_t; - // logsin table static const uint16_t logsinrom[256] = { 0x859, 0x6c3, 0x607, 0x58b, 0x52e, 0x4e4, 0x4a6, 0x471, @@ -262,10 +259,10 @@ static const uint8_t kslshift[4] = { // envelope generator constants static const uint8_t eg_incstep[4][4] = { - { 0, 0, 0, 0 }, - { 1, 0, 0, 0 }, - { 1, 0, 1, 0 }, - { 1, 1, 1, 0 } + {0, 0, 0, 0}, + { 1, 0, 0, 0}, + { 1, 0, 1, 0}, + { 1, 1, 1, 0} }; // address decoding @@ -279,20 +276,18 @@ static const uint8_t ch_slot[18] = { }; // Envelope generator -typedef int16_t(*env_sinfunc)(uint16_t phase, uint16_t envelope); -typedef void(*env_genfunc)(slot_t *slot); - +typedef int16_t (*env_sinfunc)(uint16_t phase, uint16_t envelope); +typedef void (*env_genfunc)(slot_t *slot); static int16_t env_calc_exp(uint32_t level) { if (level > 0x1fff) - level = 0x1fff; + level = 0x1fff; - return((exprom[level & 0xff] << 1) >> (level >> 8)); + return ((exprom[level & 0xff] << 1) >> (level >> 8)); } - static int16_t env_calc_sin0(uint16_t phase, uint16_t env) { @@ -302,17 +297,16 @@ env_calc_sin0(uint16_t phase, uint16_t env) phase &= 0x3ff; if (phase & 0x0200) - neg = 0xffff; + neg = 0xffff; if (phase & 0x0100) - out = logsinrom[(phase & 0xff) ^ 0xff]; + out = logsinrom[(phase & 0xff) ^ 0xff]; else - out = logsinrom[phase & 0xff]; + out = logsinrom[phase & 0xff]; - return(env_calc_exp(out + (env << 3)) ^ neg); + return (env_calc_exp(out + (env << 3)) ^ neg); } - static int16_t env_calc_sin1(uint16_t phase, uint16_t env) { @@ -321,16 +315,15 @@ env_calc_sin1(uint16_t phase, uint16_t env) phase &= 0x3ff; if (phase & 0x0200) - out = 0x1000; + out = 0x1000; else if (phase & 0x0100) - out = logsinrom[(phase & 0xff) ^ 0xff]; + out = logsinrom[(phase & 0xff) ^ 0xff]; else - out = logsinrom[phase & 0xff]; + out = logsinrom[phase & 0xff]; - return(env_calc_exp(out + (env << 3))); + return (env_calc_exp(out + (env << 3))); } - static int16_t env_calc_sin2(uint16_t phase, uint16_t env) { @@ -339,14 +332,13 @@ env_calc_sin2(uint16_t phase, uint16_t env) phase &= 0x03ff; if (phase & 0x0100) - out = logsinrom[(phase & 0xff) ^ 0xff]; + out = logsinrom[(phase & 0xff) ^ 0xff]; else - out = logsinrom[phase & 0xff]; + out = logsinrom[phase & 0xff]; - return(env_calc_exp(out + (env << 3))); + return (env_calc_exp(out + (env << 3))); } - static int16_t env_calc_sin3(uint16_t phase, uint16_t env) { @@ -355,14 +347,13 @@ env_calc_sin3(uint16_t phase, uint16_t env) phase &= 0x03ff; if (phase & 0x0100) - out = 0x1000; + out = 0x1000; else - out = logsinrom[phase & 0xff]; + out = logsinrom[phase & 0xff]; - return(env_calc_exp(out + (env << 3))); + return (env_calc_exp(out + (env << 3))); } - static int16_t env_calc_sin4(uint16_t phase, uint16_t env) { @@ -372,19 +363,18 @@ env_calc_sin4(uint16_t phase, uint16_t env) phase &= 0x03ff; if ((phase & 0x0300) == 0x0100) - neg = 0xffff; + neg = 0xffff; if (phase & 0x0200) - out = 0x1000; + out = 0x1000; else if (phase & 0x80) - out = logsinrom[((phase ^ 0xff) << 1) & 0xff]; + out = logsinrom[((phase ^ 0xff) << 1) & 0xff]; else - out = logsinrom[(phase << 1) & 0xff]; + out = logsinrom[(phase << 1) & 0xff]; - return(env_calc_exp(out + (env << 3)) ^ neg); + return (env_calc_exp(out + (env << 3)) ^ neg); } - static int16_t env_calc_sin5(uint16_t phase, uint16_t env) { @@ -393,16 +383,15 @@ env_calc_sin5(uint16_t phase, uint16_t env) phase &= 0x03ff; if (phase & 0x0200) - out = 0x1000; + out = 0x1000; else if (phase & 0x80) - out = logsinrom[((phase ^ 0xff) << 1) & 0xff]; + out = logsinrom[((phase ^ 0xff) << 1) & 0xff]; else - out = logsinrom[(phase << 1) & 0xff]; + out = logsinrom[(phase << 1) & 0xff]; - return(env_calc_exp(out + (env << 3))); + return (env_calc_exp(out + (env << 3))); } - static int16_t env_calc_sin6(uint16_t phase, uint16_t env) { @@ -411,12 +400,11 @@ env_calc_sin6(uint16_t phase, uint16_t env) phase &= 0x03ff; if (phase & 0x0200) - neg = 0xffff; + neg = 0xffff; - return(env_calc_exp(env << 3) ^ neg); + return (env_calc_exp(env << 3) ^ neg); } - static int16_t env_calc_sin7(uint16_t phase, uint16_t env) { @@ -426,16 +414,15 @@ env_calc_sin7(uint16_t phase, uint16_t env) phase &= 0x03ff; if (phase & 0x0200) { - neg = 0xffff; - phase = (phase & 0x01ff) ^ 0x01ff; + neg = 0xffff; + phase = (phase & 0x01ff) ^ 0x01ff; } out = phase << 3; - return(env_calc_exp(out + (env << 3)) ^ neg); + return (env_calc_exp(out + (env << 3)) ^ neg); } - static const env_sinfunc env_sin[8] = { env_calc_sin0, env_calc_sin1, @@ -447,233 +434,225 @@ static const env_sinfunc env_sin[8] = { env_calc_sin7 }; - static void env_update_ksl(slot_t *slot) { - int16_t ksl = (kslrom[slot->chan->f_num >> 6] << 2) - - ((0x08 - slot->chan->block) << 5); + int16_t ksl = (kslrom[slot->chan->f_num >> 6] << 2) - ((0x08 - slot->chan->block) << 5); if (ksl < 0) - ksl = 0; + ksl = 0; - slot->eg_ksl = (uint8_t)ksl; + slot->eg_ksl = (uint8_t) ksl; } - static void env_calc(slot_t *slot) { - uint8_t nonzero; - uint8_t rate; - uint8_t rate_hi; - uint8_t rate_lo; - uint8_t reg_rate = 0; - uint8_t ks; - uint8_t eg_shift, shift; + uint8_t nonzero; + uint8_t rate; + uint8_t rate_hi; + uint8_t rate_lo; + uint8_t reg_rate = 0; + uint8_t ks; + uint8_t eg_shift, shift; uint16_t eg_rout; - int16_t eg_inc; - uint8_t eg_off; - uint8_t reset = 0; + int16_t eg_inc; + uint8_t eg_off; + uint8_t reset = 0; - slot->eg_out = slot->eg_rout + (slot->reg_tl << 2) + - (slot->eg_ksl >> kslshift[slot->reg_ksl]) + *slot->trem; + slot->eg_out = slot->eg_rout + (slot->reg_tl << 2) + (slot->eg_ksl >> kslshift[slot->reg_ksl]) + *slot->trem; if (slot->key && slot->eg_gen == envelope_gen_num_release) { - reset = 1; - reg_rate = slot->reg_ar; - } else switch (slot->eg_gen) { - case envelope_gen_num_attack: - reg_rate = slot->reg_ar; - break; + reset = 1; + reg_rate = slot->reg_ar; + } else + switch (slot->eg_gen) { + case envelope_gen_num_attack: + reg_rate = slot->reg_ar; + break; - case envelope_gen_num_decay: - reg_rate = slot->reg_dr; - break; + case envelope_gen_num_decay: + reg_rate = slot->reg_dr; + break; - case envelope_gen_num_sustain: - if (! slot->reg_type) - reg_rate = slot->reg_rr; - break; + case envelope_gen_num_sustain: + if (!slot->reg_type) + reg_rate = slot->reg_rr; + break; - case envelope_gen_num_release: - reg_rate = slot->reg_rr; - break; - } + case envelope_gen_num_release: + reg_rate = slot->reg_rr; + break; + } slot->pg_reset = reset; - ks = slot->chan->ksv >> ((slot->reg_ksr ^ 1) << 1); - nonzero = (reg_rate != 0); - rate = ks + (reg_rate << 2); - rate_hi = rate >> 2; - rate_lo = rate & 0x03; + ks = slot->chan->ksv >> ((slot->reg_ksr ^ 1) << 1); + nonzero = (reg_rate != 0); + rate = ks + (reg_rate << 2); + rate_hi = rate >> 2; + rate_lo = rate & 0x03; if (rate_hi & 0x10) - rate_hi = 0x0f; + rate_hi = 0x0f; eg_shift = rate_hi + slot->dev->eg_add; - shift = 0; + shift = 0; if (nonzero) { - if (rate_hi < 12) { - if (slot->dev->eg_state) switch (eg_shift) { - case 12: - shift = 1; - break; + if (rate_hi < 12) { + if (slot->dev->eg_state) + switch (eg_shift) { + case 12: + shift = 1; + break; - case 13: - shift = (rate_lo >> 1) & 0x01; - break; + case 13: + shift = (rate_lo >> 1) & 0x01; + break; - case 14: - shift = rate_lo & 0x01; - break; + case 14: + shift = rate_lo & 0x01; + break; - default: - break; - } - } else { - shift = (rate_hi & 0x03) + eg_incstep[rate_lo][slot->dev->timer & 0x03]; - if (shift & 0x04) - shift = 0x03; - if (! shift) - shift = slot->dev->eg_state; - } + default: + break; + } + } else { + shift = (rate_hi & 0x03) + eg_incstep[rate_lo][slot->dev->timer & 0x03]; + if (shift & 0x04) + shift = 0x03; + if (!shift) + shift = slot->dev->eg_state; + } } eg_rout = slot->eg_rout; - eg_inc = 0; - eg_off = 0; + eg_inc = 0; + eg_off = 0; // Instant attack if (reset && rate_hi == 0x0f) - eg_rout = 0x00; + eg_rout = 0x00; // Envelope off if ((slot->eg_rout & 0x1f8) == 0x1f8) - eg_off = 1; + eg_off = 1; if (slot->eg_gen != envelope_gen_num_attack && !reset && eg_off) - eg_rout = 0x1ff; + eg_rout = 0x1ff; switch (slot->eg_gen) { - case envelope_gen_num_attack: - if (! slot->eg_rout) - slot->eg_gen = envelope_gen_num_decay; - else if (slot->key && shift > 0 && rate_hi != 0x0f) - eg_inc = ((~slot->eg_rout) << shift) >> 4; - break; + case envelope_gen_num_attack: + if (!slot->eg_rout) + slot->eg_gen = envelope_gen_num_decay; + else if (slot->key && shift > 0 && rate_hi != 0x0f) + eg_inc = ((~slot->eg_rout) << shift) >> 4; + break; - case envelope_gen_num_decay: - if ((slot->eg_rout >> 4) == slot->reg_sl) - slot->eg_gen = envelope_gen_num_sustain; - else if (!eg_off && !reset && shift > 0) - eg_inc = 1 << (shift - 1); - break; + case envelope_gen_num_decay: + if ((slot->eg_rout >> 4) == slot->reg_sl) + slot->eg_gen = envelope_gen_num_sustain; + else if (!eg_off && !reset && shift > 0) + eg_inc = 1 << (shift - 1); + break; - case envelope_gen_num_sustain: - case envelope_gen_num_release: - if (!eg_off && !reset && shift > 0) - eg_inc = 1 << (shift - 1); - break; + case envelope_gen_num_sustain: + case envelope_gen_num_release: + if (!eg_off && !reset && shift > 0) + eg_inc = 1 << (shift - 1); + break; } slot->eg_rout = (eg_rout + eg_inc) & 0x1ff; // Key off if (reset) - slot->eg_gen = envelope_gen_num_attack; + slot->eg_gen = envelope_gen_num_attack; - if (! slot->key) - slot->eg_gen = envelope_gen_num_release; + if (!slot->key) + slot->eg_gen = envelope_gen_num_release; } - static void env_key_on(slot_t *slot, uint8_t type) { slot->key |= type; } - static void env_key_off(slot_t *slot, uint8_t type) { slot->key &= ~type; } - static void phase_generate(slot_t *slot) { uint16_t f_num; uint32_t basefreq; - uint8_t rm_xor, n_bit; + uint8_t rm_xor, n_bit; uint32_t noise; uint16_t phase; - int8_t range; - uint8_t vibpos; + int8_t range; + uint8_t vibpos; nuked_t *dev; - dev = slot->dev; + dev = slot->dev; f_num = slot->chan->f_num; if (slot->reg_vib) { - range = (f_num >> 7) & 7; - vibpos = dev->vibpos; + range = (f_num >> 7) & 7; + vibpos = dev->vibpos; - if (! (vibpos & 3)) - range = 0; - else if (vibpos & 1) - range >>= 1; - range >>= dev->vibshift; + if (!(vibpos & 3)) + range = 0; + else if (vibpos & 1) + range >>= 1; + range >>= dev->vibshift; - if (vibpos & 4) - range = -range; - f_num += range; + if (vibpos & 4) + range = -range; + f_num += range; } basefreq = (f_num << slot->chan->block) >> 1; - phase = (uint16_t)(slot->pg_phase >> 9); + phase = (uint16_t) (slot->pg_phase >> 9); if (slot->pg_reset) - slot->pg_phase = 0; + slot->pg_phase = 0; slot->pg_phase += (basefreq * mt[slot->reg_mult]) >> 1; // Rhythm mode - noise = dev->noise; + noise = dev->noise; slot->pg_phase_out = phase; - if (slot->slot_num == 13) { // hh - dev->rm_hh_bit2 = (phase >> 2) & 1; - dev->rm_hh_bit3 = (phase >> 3) & 1; - dev->rm_hh_bit7 = (phase >> 7) & 1; - dev->rm_hh_bit8 = (phase >> 8) & 1; + if (slot->slot_num == 13) { // hh + dev->rm_hh_bit2 = (phase >> 2) & 1; + dev->rm_hh_bit3 = (phase >> 3) & 1; + dev->rm_hh_bit7 = (phase >> 7) & 1; + dev->rm_hh_bit8 = (phase >> 8) & 1; } - if (slot->slot_num == 17 && (dev->rhy & 0x20)) { // tc - dev->rm_tc_bit3 = (phase >> 3) & 1; - dev->rm_tc_bit5 = (phase >> 5) & 1; + if (slot->slot_num == 17 && (dev->rhy & 0x20)) { // tc + dev->rm_tc_bit3 = (phase >> 3) & 1; + dev->rm_tc_bit5 = (phase >> 5) & 1; } if (dev->rhy & 0x20) { - rm_xor = (dev->rm_hh_bit2 ^ dev->rm_hh_bit7) | - (dev->rm_hh_bit3 ^ dev->rm_tc_bit5) | - (dev->rm_tc_bit3 ^ dev->rm_tc_bit5); + rm_xor = (dev->rm_hh_bit2 ^ dev->rm_hh_bit7) | (dev->rm_hh_bit3 ^ dev->rm_tc_bit5) | (dev->rm_tc_bit3 ^ dev->rm_tc_bit5); - switch (slot->slot_num) { - case 13: // hh - slot->pg_phase_out = rm_xor << 9; - if (rm_xor ^ (noise & 1)) - slot->pg_phase_out |= 0xd0; - else - slot->pg_phase_out |= 0x34; - break; + switch (slot->slot_num) { + case 13: // hh + slot->pg_phase_out = rm_xor << 9; + if (rm_xor ^ (noise & 1)) + slot->pg_phase_out |= 0xd0; + else + slot->pg_phase_out |= 0x34; + break; - case 16: // sd - slot->pg_phase_out = (dev->rm_hh_bit8 << 9) | - ((dev->rm_hh_bit8 ^ (noise & 1)) << 8); - break; + case 16: // sd + slot->pg_phase_out = (dev->rm_hh_bit8 << 9) | ((dev->rm_hh_bit8 ^ (noise & 1)) << 8); + break; - case 17: // tc - slot->pg_phase_out = (rm_xor << 9) | 0x80; - break; + case 17: // tc + slot->pg_phase_out = (rm_xor << 9) | 0x80; + break; - default: - break; - } + default: + break; + } } n_bit = ((noise >> 14) ^ noise) & 0x01; @@ -681,32 +660,29 @@ phase_generate(slot_t *slot) dev->noise = (noise >> 1) | (n_bit << 22); } - static void slot_write_20(slot_t *slot, uint8_t data) { if ((data >> 7) & 0x01) - slot->trem = &slot->dev->tremolo; + slot->trem = &slot->dev->tremolo; else - slot->trem = (uint8_t*)&slot->dev->zeromod; + slot->trem = (uint8_t *) &slot->dev->zeromod; - slot->reg_vib = (data >> 6) & 0x01; + slot->reg_vib = (data >> 6) & 0x01; slot->reg_type = (data >> 5) & 0x01; - slot->reg_ksr = (data >> 4) & 0x01; + slot->reg_ksr = (data >> 4) & 0x01; slot->reg_mult = data & 0x0f; } - static void slot_write_40(slot_t *slot, uint8_t data) { slot->reg_ksl = (data >> 6) & 0x03; - slot->reg_tl = data & 0x3f; + slot->reg_tl = data & 0x3f; env_update_ksl(slot); } - static void slot_write_60(slot_t *slot, uint8_t data) { @@ -714,149 +690,144 @@ slot_write_60(slot_t *slot, uint8_t data) slot->reg_dr = data & 0x0f; } - static void slot_write_80(slot_t *slot, uint8_t data) { slot->reg_sl = (data >> 4) & 0x0f; if (slot->reg_sl == 0x0f) - slot->reg_sl = 0x1f; + slot->reg_sl = 0x1f; slot->reg_rr = data & 0x0f; } - static void slot_write_e0(slot_t *slot, uint8_t data) { slot->reg_wf = data & 0x07; if (slot->dev->newm == 0x00) - slot->reg_wf &= 0x03; + slot->reg_wf &= 0x03; } - static void slot_generate(slot_t *slot) { slot->out = env_sin[slot->reg_wf](slot->pg_phase_out + *slot->mod, - slot->eg_out); + slot->eg_out); } - static void slot_calc_fb(slot_t *slot) { if (slot->chan->fb != 0x00) - slot->fbmod = (slot->prout + slot->out) >> (0x09 - slot->chan->fb); + slot->fbmod = (slot->prout + slot->out) >> (0x09 - slot->chan->fb); else - slot->fbmod = 0; + slot->fbmod = 0; slot->prout = slot->out; } - static void channel_setup_alg(chan_t *ch) { if (ch->chtype == ch_drum) { - if (ch->ch_num == 7 || ch->ch_num == 8) { - ch->slots[0]->mod = &ch->dev->zeromod; - ch->slots[1]->mod = &ch->dev->zeromod; - return; - } + if (ch->ch_num == 7 || ch->ch_num == 8) { + ch->slots[0]->mod = &ch->dev->zeromod; + ch->slots[1]->mod = &ch->dev->zeromod; + return; + } - switch (ch->alg & 0x01) { - case 0x00: - ch->slots[0]->mod = &ch->slots[0]->fbmod; - ch->slots[1]->mod = &ch->slots[0]->out; - break; + switch (ch->alg & 0x01) { + case 0x00: + ch->slots[0]->mod = &ch->slots[0]->fbmod; + ch->slots[1]->mod = &ch->slots[0]->out; + break; - case 0x01: - ch->slots[0]->mod = &ch->slots[0]->fbmod; - ch->slots[1]->mod = &ch->dev->zeromod; - break; - } - return; + case 0x01: + ch->slots[0]->mod = &ch->slots[0]->fbmod; + ch->slots[1]->mod = &ch->dev->zeromod; + break; + } + return; } if (ch->alg & 0x08) - return; + return; if (ch->alg & 0x04) { - ch->pair->out[0] = &ch->dev->zeromod; - ch->pair->out[1] = &ch->dev->zeromod; - ch->pair->out[2] = &ch->dev->zeromod; - ch->pair->out[3] = &ch->dev->zeromod; + ch->pair->out[0] = &ch->dev->zeromod; + ch->pair->out[1] = &ch->dev->zeromod; + ch->pair->out[2] = &ch->dev->zeromod; + ch->pair->out[3] = &ch->dev->zeromod; - switch (ch->alg & 0x03) { - case 0x00: - ch->pair->slots[0]->mod = &ch->pair->slots[0]->fbmod; - ch->pair->slots[1]->mod = &ch->pair->slots[0]->out; - ch->slots[0]->mod = &ch->pair->slots[1]->out; - ch->slots[1]->mod = &ch->slots[0]->out; - ch->out[0] = &ch->slots[1]->out; - ch->out[1] = &ch->dev->zeromod; - ch->out[2] = &ch->dev->zeromod; - ch->out[3] = &ch->dev->zeromod; - break; + switch (ch->alg & 0x03) { + case 0x00: + ch->pair->slots[0]->mod = &ch->pair->slots[0]->fbmod; + ch->pair->slots[1]->mod = &ch->pair->slots[0]->out; + ch->slots[0]->mod = &ch->pair->slots[1]->out; + ch->slots[1]->mod = &ch->slots[0]->out; + ch->out[0] = &ch->slots[1]->out; + ch->out[1] = &ch->dev->zeromod; + ch->out[2] = &ch->dev->zeromod; + ch->out[3] = &ch->dev->zeromod; + break; - case 0x01: - ch->pair->slots[0]->mod = &ch->pair->slots[0]->fbmod; - ch->pair->slots[1]->mod = &ch->pair->slots[0]->out; - ch->slots[0]->mod = &ch->dev->zeromod; - ch->slots[1]->mod = &ch->slots[0]->out; - ch->out[0] = &ch->pair->slots[1]->out; - ch->out[1] = &ch->slots[1]->out; - ch->out[2] = &ch->dev->zeromod; - ch->out[3] = &ch->dev->zeromod; - break; + case 0x01: + ch->pair->slots[0]->mod = &ch->pair->slots[0]->fbmod; + ch->pair->slots[1]->mod = &ch->pair->slots[0]->out; + ch->slots[0]->mod = &ch->dev->zeromod; + ch->slots[1]->mod = &ch->slots[0]->out; + ch->out[0] = &ch->pair->slots[1]->out; + ch->out[1] = &ch->slots[1]->out; + ch->out[2] = &ch->dev->zeromod; + ch->out[3] = &ch->dev->zeromod; + break; - case 0x02: - ch->pair->slots[0]->mod = &ch->pair->slots[0]->fbmod; - ch->pair->slots[1]->mod = &ch->dev->zeromod; - ch->slots[0]->mod = &ch->pair->slots[1]->out; - ch->slots[1]->mod = &ch->slots[0]->out; - ch->out[0] = &ch->pair->slots[0]->out; - ch->out[1] = &ch->slots[1]->out; - ch->out[2] = &ch->dev->zeromod; - ch->out[3] = &ch->dev->zeromod; - break; + case 0x02: + ch->pair->slots[0]->mod = &ch->pair->slots[0]->fbmod; + ch->pair->slots[1]->mod = &ch->dev->zeromod; + ch->slots[0]->mod = &ch->pair->slots[1]->out; + ch->slots[1]->mod = &ch->slots[0]->out; + ch->out[0] = &ch->pair->slots[0]->out; + ch->out[1] = &ch->slots[1]->out; + ch->out[2] = &ch->dev->zeromod; + ch->out[3] = &ch->dev->zeromod; + break; - case 0x03: - ch->pair->slots[0]->mod = &ch->pair->slots[0]->fbmod; - ch->pair->slots[1]->mod = &ch->dev->zeromod; - ch->slots[0]->mod = &ch->pair->slots[1]->out; - ch->slots[1]->mod = &ch->dev->zeromod; - ch->out[0] = &ch->pair->slots[0]->out; - ch->out[1] = &ch->slots[0]->out; - ch->out[2] = &ch->slots[1]->out; - ch->out[3] = &ch->dev->zeromod; - break; - } - } else switch (ch->alg & 0x01) { - case 0x00: - ch->slots[0]->mod = &ch->slots[0]->fbmod; - ch->slots[1]->mod = &ch->slots[0]->out; - ch->out[0] = &ch->slots[1]->out; - ch->out[1] = &ch->dev->zeromod; - ch->out[2] = &ch->dev->zeromod; - ch->out[3] = &ch->dev->zeromod; - break; + case 0x03: + ch->pair->slots[0]->mod = &ch->pair->slots[0]->fbmod; + ch->pair->slots[1]->mod = &ch->dev->zeromod; + ch->slots[0]->mod = &ch->pair->slots[1]->out; + ch->slots[1]->mod = &ch->dev->zeromod; + ch->out[0] = &ch->pair->slots[0]->out; + ch->out[1] = &ch->slots[0]->out; + ch->out[2] = &ch->slots[1]->out; + ch->out[3] = &ch->dev->zeromod; + break; + } + } else + switch (ch->alg & 0x01) { + case 0x00: + ch->slots[0]->mod = &ch->slots[0]->fbmod; + ch->slots[1]->mod = &ch->slots[0]->out; + ch->out[0] = &ch->slots[1]->out; + ch->out[1] = &ch->dev->zeromod; + ch->out[2] = &ch->dev->zeromod; + ch->out[3] = &ch->dev->zeromod; + break; - case 0x01: - ch->slots[0]->mod = &ch->slots[0]->fbmod; - ch->slots[1]->mod = &ch->dev->zeromod; - ch->out[0] = &ch->slots[0]->out; - ch->out[1] = &ch->slots[1]->out; - ch->out[2] = &ch->dev->zeromod; - ch->out[3] = &ch->dev->zeromod; - break; - } + case 0x01: + ch->slots[0]->mod = &ch->slots[0]->fbmod; + ch->slots[1]->mod = &ch->dev->zeromod; + ch->out[0] = &ch->slots[0]->out; + ch->out[1] = &ch->slots[1]->out; + ch->out[2] = &ch->dev->zeromod; + ch->out[3] = &ch->dev->zeromod; + break; + } } - static void channel_update_rhythm(nuked_t *dev, uint8_t data) { @@ -865,188 +836,182 @@ channel_update_rhythm(nuked_t *dev, uint8_t data) dev->rhy = data & 0x3f; if (dev->rhy & 0x20) { - ch6 = &dev->chan[6]; - ch7 = &dev->chan[7]; - ch8 = &dev->chan[8]; - ch6->out[0] = &ch6->slots[1]->out; - ch6->out[1] = &ch6->slots[1]->out; - ch6->out[2] = &dev->zeromod; - ch6->out[3] = &dev->zeromod; - ch7->out[0] = &ch7->slots[0]->out; - ch7->out[1] = &ch7->slots[0]->out; - ch7->out[2] = &ch7->slots[1]->out; - ch7->out[3] = &ch7->slots[1]->out; - ch8->out[0] = &ch8->slots[0]->out; - ch8->out[1] = &ch8->slots[0]->out; - ch8->out[2] = &ch8->slots[1]->out; - ch8->out[3] = &ch8->slots[1]->out; + ch6 = &dev->chan[6]; + ch7 = &dev->chan[7]; + ch8 = &dev->chan[8]; + ch6->out[0] = &ch6->slots[1]->out; + ch6->out[1] = &ch6->slots[1]->out; + ch6->out[2] = &dev->zeromod; + ch6->out[3] = &dev->zeromod; + ch7->out[0] = &ch7->slots[0]->out; + ch7->out[1] = &ch7->slots[0]->out; + ch7->out[2] = &ch7->slots[1]->out; + ch7->out[3] = &ch7->slots[1]->out; + ch8->out[0] = &ch8->slots[0]->out; + ch8->out[1] = &ch8->slots[0]->out; + ch8->out[2] = &ch8->slots[1]->out; + ch8->out[3] = &ch8->slots[1]->out; - for (chnum = 6; chnum < 9; chnum++) - dev->chan[chnum].chtype = ch_drum; + for (chnum = 6; chnum < 9; chnum++) + dev->chan[chnum].chtype = ch_drum; - channel_setup_alg(ch6); - channel_setup_alg(ch7); - channel_setup_alg(ch8); + channel_setup_alg(ch6); + channel_setup_alg(ch7); + channel_setup_alg(ch8); - // hh - if (dev->rhy & 0x01) - env_key_on(ch7->slots[0], egk_drum); - else - env_key_off(ch7->slots[0], egk_drum); + // hh + if (dev->rhy & 0x01) + env_key_on(ch7->slots[0], egk_drum); + else + env_key_off(ch7->slots[0], egk_drum); - // tc - if (dev->rhy & 0x02) - env_key_on(ch8->slots[1], egk_drum); - else - env_key_off(ch8->slots[1], egk_drum); + // tc + if (dev->rhy & 0x02) + env_key_on(ch8->slots[1], egk_drum); + else + env_key_off(ch8->slots[1], egk_drum); - // tom - if (dev->rhy & 0x04) - env_key_on(ch8->slots[0], egk_drum); - else - env_key_off(ch8->slots[0], egk_drum); + // tom + if (dev->rhy & 0x04) + env_key_on(ch8->slots[0], egk_drum); + else + env_key_off(ch8->slots[0], egk_drum); - // sd - if (dev->rhy & 0x08) - env_key_on(ch7->slots[1], egk_drum); - else - env_key_off(ch7->slots[1], egk_drum); + // sd + if (dev->rhy & 0x08) + env_key_on(ch7->slots[1], egk_drum); + else + env_key_off(ch7->slots[1], egk_drum); - // bd - if (dev->rhy & 0x10) { - env_key_on(ch6->slots[0], egk_drum); - env_key_on(ch6->slots[1], egk_drum); - } else { - env_key_off(ch6->slots[0], egk_drum); - env_key_off(ch6->slots[1], egk_drum); - } + // bd + if (dev->rhy & 0x10) { + env_key_on(ch6->slots[0], egk_drum); + env_key_on(ch6->slots[1], egk_drum); + } else { + env_key_off(ch6->slots[0], egk_drum); + env_key_off(ch6->slots[1], egk_drum); + } } else { - for (chnum = 6; chnum < 9; chnum++) { - dev->chan[chnum].chtype = ch_2op; + for (chnum = 6; chnum < 9; chnum++) { + dev->chan[chnum].chtype = ch_2op; - channel_setup_alg(&dev->chan[chnum]); - env_key_off(dev->chan[chnum].slots[0], egk_drum); - env_key_off(dev->chan[chnum].slots[1], egk_drum); - } + channel_setup_alg(&dev->chan[chnum]); + env_key_off(dev->chan[chnum].slots[0], egk_drum); + env_key_off(dev->chan[chnum].slots[1], egk_drum); + } } } - static void channel_write_a0(chan_t *ch, uint8_t data) { if (ch->dev->newm && ch->chtype == ch_4op2) - return; + return; ch->f_num = (ch->f_num & 0x300) | data; - ch->ksv = (ch->block << 1) | ((ch->f_num >> (0x09 - ch->dev->nts)) & 0x01); + ch->ksv = (ch->block << 1) | ((ch->f_num >> (0x09 - ch->dev->nts)) & 0x01); env_update_ksl(ch->slots[0]); env_update_ksl(ch->slots[1]); if (ch->dev->newm && ch->chtype == ch_4op) { - ch->pair->f_num = ch->f_num; - ch->pair->ksv = ch->ksv; + ch->pair->f_num = ch->f_num; + ch->pair->ksv = ch->ksv; - env_update_ksl(ch->pair->slots[0]); - env_update_ksl(ch->pair->slots[1]); + env_update_ksl(ch->pair->slots[0]); + env_update_ksl(ch->pair->slots[1]); } } - static void channel_write_b0(chan_t *ch, uint8_t data) { if (ch->dev->newm && ch->chtype == ch_4op2) - return; + return; ch->f_num = (ch->f_num & 0xff) | ((data & 0x03) << 8); ch->block = (data >> 2) & 0x07; - ch->ksv = (ch->block << 1) | ((ch->f_num >> (0x09 - ch->dev->nts)) & 0x01); + ch->ksv = (ch->block << 1) | ((ch->f_num >> (0x09 - ch->dev->nts)) & 0x01); env_update_ksl(ch->slots[0]); env_update_ksl(ch->slots[1]); if (ch->dev->newm && ch->chtype == ch_4op) { - ch->pair->f_num = ch->f_num; - ch->pair->block = ch->block; - ch->pair->ksv = ch->ksv; + ch->pair->f_num = ch->f_num; + ch->pair->block = ch->block; + ch->pair->ksv = ch->ksv; - env_update_ksl(ch->pair->slots[0]); - env_update_ksl(ch->pair->slots[1]); + env_update_ksl(ch->pair->slots[0]); + env_update_ksl(ch->pair->slots[1]); } } - static void channel_write_c0(chan_t *ch, uint8_t data) { - ch->fb = (data & 0x0e) >> 1; + ch->fb = (data & 0x0e) >> 1; ch->con = data & 0x01; ch->alg = ch->con; if (ch->dev->newm) { - if (ch->chtype == ch_4op) { - ch->pair->alg = 0x04 | (ch->con << 1) | ch->pair->con; - ch->alg = 0x08; - channel_setup_alg(ch->pair); - } else if (ch->chtype == ch_4op2) { - ch->alg = 0x04 | (ch->pair->con << 1) | ch->con; - ch->pair->alg = 0x08; - channel_setup_alg(ch); - } else - channel_setup_alg(ch); + if (ch->chtype == ch_4op) { + ch->pair->alg = 0x04 | (ch->con << 1) | ch->pair->con; + ch->alg = 0x08; + channel_setup_alg(ch->pair); + } else if (ch->chtype == ch_4op2) { + ch->alg = 0x04 | (ch->pair->con << 1) | ch->con; + ch->pair->alg = 0x08; + channel_setup_alg(ch); + } else + channel_setup_alg(ch); } else - channel_setup_alg(ch); + channel_setup_alg(ch); if (ch->dev->newm) { - ch->cha = ((data >> 4) & 0x01) ? ~0 : 0; - ch->chb = ((data >> 5) & 0x01) ? ~0 : 0; + ch->cha = ((data >> 4) & 0x01) ? ~0 : 0; + ch->chb = ((data >> 5) & 0x01) ? ~0 : 0; } else - ch->cha = ch->chb = (uint16_t)~0; + ch->cha = ch->chb = (uint16_t) ~0; } - static void channel_key_on(chan_t *ch) { if (ch->dev->newm) { - if (ch->chtype == ch_4op) { - env_key_on(ch->slots[0], egk_norm); - env_key_on(ch->slots[1], egk_norm); - env_key_on(ch->pair->slots[0], egk_norm); - env_key_on(ch->pair->slots[1], egk_norm); - } else if (ch->chtype == ch_2op || ch->chtype == ch_drum) { - env_key_on(ch->slots[0], egk_norm); - env_key_on(ch->slots[1], egk_norm); - } + if (ch->chtype == ch_4op) { + env_key_on(ch->slots[0], egk_norm); + env_key_on(ch->slots[1], egk_norm); + env_key_on(ch->pair->slots[0], egk_norm); + env_key_on(ch->pair->slots[1], egk_norm); + } else if (ch->chtype == ch_2op || ch->chtype == ch_drum) { + env_key_on(ch->slots[0], egk_norm); + env_key_on(ch->slots[1], egk_norm); + } } else { - env_key_on(ch->slots[0], egk_norm); - env_key_on(ch->slots[1], egk_norm); + env_key_on(ch->slots[0], egk_norm); + env_key_on(ch->slots[1], egk_norm); } } - static void channel_key_off(chan_t *ch) { if (ch->dev->newm) { - if (ch->chtype == ch_4op) { - env_key_off(ch->slots[0], egk_norm); - env_key_off(ch->slots[1], egk_norm); - env_key_off(ch->pair->slots[0], egk_norm); - env_key_off(ch->pair->slots[1], egk_norm); - } else if (ch->chtype == ch_2op || ch->chtype == ch_drum) { - env_key_off(ch->slots[0], egk_norm); - env_key_off(ch->slots[1], egk_norm); - } + if (ch->chtype == ch_4op) { + env_key_off(ch->slots[0], egk_norm); + env_key_off(ch->slots[1], egk_norm); + env_key_off(ch->pair->slots[0], egk_norm); + env_key_off(ch->pair->slots[1], egk_norm); + } else if (ch->chtype == ch_2op || ch->chtype == ch_drum) { + env_key_off(ch->slots[0], egk_norm); + env_key_off(ch->slots[1], egk_norm); + } } else { - env_key_off(ch->slots[0], egk_norm); - env_key_off(ch->slots[1], egk_norm); + env_key_off(ch->slots[0], egk_norm); + env_key_off(ch->slots[1], egk_norm); } } - static void channel_set_4op(nuked_t *dev, uint8_t data) { @@ -1054,349 +1019,345 @@ channel_set_4op(nuked_t *dev, uint8_t data) uint8_t bit; for (bit = 0; bit < 6; bit++) { - chnum = bit; + chnum = bit; - if (bit >= 3) - chnum += 9 - 3; + if (bit >= 3) + chnum += 9 - 3; - if ((data >> bit) & 0x01) { - dev->chan[chnum].chtype = ch_4op; - dev->chan[chnum + 3].chtype = ch_4op2; - } else { - dev->chan[chnum].chtype = ch_2op; - dev->chan[chnum + 3].chtype = ch_2op; - } + if ((data >> bit) & 0x01) { + dev->chan[chnum].chtype = ch_4op; + dev->chan[chnum + 3].chtype = ch_4op2; + } else { + dev->chan[chnum].chtype = ch_2op; + dev->chan[chnum + 3].chtype = ch_2op; + } } } - uint16_t nuked_write_addr(void *priv, uint16_t port, uint8_t val) { - nuked_t *dev = (nuked_t *)priv; + nuked_t *dev = (nuked_t *) priv; uint16_t addr; addr = val; if ((port & 0x0002) && ((addr == 0x0005) || dev->newm)) - addr |= 0x0100; + addr |= 0x0100; - return(addr); + return (addr); } - void nuked_write_reg(void *priv, uint16_t reg, uint8_t val) { - nuked_t *dev = (nuked_t *)priv; - uint8_t high = (reg >> 8) & 0x01; - uint8_t regm = reg & 0xff; + nuked_t *dev = (nuked_t *) priv; + uint8_t high = (reg >> 8) & 0x01; + uint8_t regm = reg & 0xff; switch (regm & 0xf0) { - case 0x00: - if (high) switch (regm & 0x0f) { - case 0x04: - channel_set_4op(dev, val); - break; + case 0x00: + if (high) + switch (regm & 0x0f) { + case 0x04: + channel_set_4op(dev, val); + break; - case 0x05: - dev->newm = val & 0x01; - break; - } else switch (regm & 0x0f) { - case 0x08: - dev->nts = (val >> 6) & 0x01; - break; - } - break; + case 0x05: + dev->newm = val & 0x01; + break; + } + else + switch (regm & 0x0f) { + case 0x08: + dev->nts = (val >> 6) & 0x01; + break; + } + break; - case 0x20: - case 0x30: - if (ad_slot[regm & 0x1f] >= 0) - slot_write_20(&dev->slot[18 * high + ad_slot[regm & 0x1f]], val); - break; + case 0x20: + case 0x30: + if (ad_slot[regm & 0x1f] >= 0) + slot_write_20(&dev->slot[18 * high + ad_slot[regm & 0x1f]], val); + break; - case 0x40: - case 0x50: - if (ad_slot[regm & 0x1f] >= 0) - slot_write_40(&dev->slot[18 * high + ad_slot[regm & 0x1f]], val); - break; + case 0x40: + case 0x50: + if (ad_slot[regm & 0x1f] >= 0) + slot_write_40(&dev->slot[18 * high + ad_slot[regm & 0x1f]], val); + break; - case 0x60: - case 0x70: - if (ad_slot[regm & 0x1f] >= 0) - slot_write_60(&dev->slot[18 * high + ad_slot[regm & 0x1f]], val); - break; + case 0x60: + case 0x70: + if (ad_slot[regm & 0x1f] >= 0) + slot_write_60(&dev->slot[18 * high + ad_slot[regm & 0x1f]], val); + break; - case 0x80: - case 0x90: - if (ad_slot[regm & 0x1f] >= 0) - slot_write_80(&dev->slot[18 * high + ad_slot[regm & 0x1f]], val); - break; + case 0x80: + case 0x90: + if (ad_slot[regm & 0x1f] >= 0) + slot_write_80(&dev->slot[18 * high + ad_slot[regm & 0x1f]], val); + break; - case 0xa0: - if ((regm & 0x0f) < 9) - channel_write_a0(&dev->chan[9 * high + (regm & 0x0f)], val); - break; + case 0xa0: + if ((regm & 0x0f) < 9) + channel_write_a0(&dev->chan[9 * high + (regm & 0x0f)], val); + break; - case 0xb0: - if (regm == 0xbd && !high) { - dev->tremoloshift = (((val >> 7) ^ 1) << 1) + 2; - dev->vibshift = ((val >> 6) & 0x01) ^ 1; - channel_update_rhythm(dev, val); - } else if ((regm & 0x0f) < 9) { - channel_write_b0(&dev->chan[9 * high + (regm & 0x0f)], val); + case 0xb0: + if (regm == 0xbd && !high) { + dev->tremoloshift = (((val >> 7) ^ 1) << 1) + 2; + dev->vibshift = ((val >> 6) & 0x01) ^ 1; + channel_update_rhythm(dev, val); + } else if ((regm & 0x0f) < 9) { + channel_write_b0(&dev->chan[9 * high + (regm & 0x0f)], val); - if (val & 0x20) - channel_key_on(&dev->chan[9 * high + (regm & 0x0f)]); - else - channel_key_off(&dev->chan[9 * high + (regm & 0x0f)]); - } - break; + if (val & 0x20) + channel_key_on(&dev->chan[9 * high + (regm & 0x0f)]); + else + channel_key_off(&dev->chan[9 * high + (regm & 0x0f)]); + } + break; - case 0xc0: - if ((regm & 0x0f) < 9) - channel_write_c0(&dev->chan[9 * high + (regm & 0x0f)], val); - break; - - case 0xe0: - case 0xf0: - if (ad_slot[regm & 0x1f] >= 0) - slot_write_e0(&dev->slot[18 * high + ad_slot[regm & 0x1f]], val); - break; + case 0xc0: + if ((regm & 0x0f) < 9) + channel_write_c0(&dev->chan[9 * high + (regm & 0x0f)], val); + break; + case 0xe0: + case 0xf0: + if (ad_slot[regm & 0x1f] >= 0) + slot_write_e0(&dev->slot[18 * high + ad_slot[regm & 0x1f]], val); + break; } } - void nuked_write_reg_buffered(void *priv, uint16_t reg, uint8_t val) { - nuked_t *dev = (nuked_t *)priv; + nuked_t *dev = (nuked_t *) priv; uint64_t time1, time2; if (dev->wrbuf[dev->wrbuf_last].reg & 0x0200) { - nuked_write_reg(dev, dev->wrbuf[dev->wrbuf_last].reg & 0x01ff, - dev->wrbuf[dev->wrbuf_last].data); + nuked_write_reg(dev, dev->wrbuf[dev->wrbuf_last].reg & 0x01ff, + dev->wrbuf[dev->wrbuf_last].data); - dev->wrbuf_cur = (dev->wrbuf_last + 1) % WRBUF_SIZE; - dev->wrbuf_samplecnt = dev->wrbuf[dev->wrbuf_last].time; + dev->wrbuf_cur = (dev->wrbuf_last + 1) % WRBUF_SIZE; + dev->wrbuf_samplecnt = dev->wrbuf[dev->wrbuf_last].time; } - dev->wrbuf[dev->wrbuf_last].reg = reg | 0x0200; + dev->wrbuf[dev->wrbuf_last].reg = reg | 0x0200; dev->wrbuf[dev->wrbuf_last].data = val; - time1 = dev->wrbuf_lasttime + WRBUF_DELAY; - time2 = dev->wrbuf_samplecnt; + time1 = dev->wrbuf_lasttime + WRBUF_DELAY; + time2 = dev->wrbuf_samplecnt; if (time1 < time2) - time1 = time2; + time1 = time2; dev->wrbuf[dev->wrbuf_last].time = time1; - dev->wrbuf_lasttime = time1; - dev->wrbuf_last = (dev->wrbuf_last + 1) % WRBUF_SIZE; + dev->wrbuf_lasttime = time1; + dev->wrbuf_last = (dev->wrbuf_last + 1) % WRBUF_SIZE; } - void nuked_generate(void *priv, int32_t *bufp) { - nuked_t *dev = (nuked_t *)priv; - int16_t accm, shift = 0; - uint8_t i, j; + nuked_t *dev = (nuked_t *) priv; + int16_t accm, shift = 0; + uint8_t i, j; bufp[1] = dev->mixbuff[1]; for (i = 0; i < 15; i++) { - slot_calc_fb(&dev->slot[i]); - env_calc(&dev->slot[i]); - phase_generate(&dev->slot[i]); - slot_generate(&dev->slot[i]); + slot_calc_fb(&dev->slot[i]); + env_calc(&dev->slot[i]); + phase_generate(&dev->slot[i]); + slot_generate(&dev->slot[i]); } dev->mixbuff[0] = 0; for (i = 0; i < 18; i++) { - accm = 0; + accm = 0; - for (j = 0; j < 4; j++) - accm += *dev->chan[i].out[j]; + for (j = 0; j < 4; j++) + accm += *dev->chan[i].out[j]; - dev->mixbuff[0] += (int16_t)(accm & dev->chan[i].cha); + dev->mixbuff[0] += (int16_t) (accm & dev->chan[i].cha); } for (i = 15; i < 18; i++) { - slot_calc_fb(&dev->slot[i]); - env_calc(&dev->slot[i]); - phase_generate(&dev->slot[i]); - slot_generate(&dev->slot[i]); + slot_calc_fb(&dev->slot[i]); + env_calc(&dev->slot[i]); + phase_generate(&dev->slot[i]); + slot_generate(&dev->slot[i]); } bufp[0] = dev->mixbuff[0]; for (i = 18; i < 33; i++) { - slot_calc_fb(&dev->slot[i]); - env_calc(&dev->slot[i]); - phase_generate(&dev->slot[i]); - slot_generate(&dev->slot[i]); + slot_calc_fb(&dev->slot[i]); + env_calc(&dev->slot[i]); + phase_generate(&dev->slot[i]); + slot_generate(&dev->slot[i]); } dev->mixbuff[1] = 0; for (i = 0; i < 18; i++) { - accm = 0; + accm = 0; - for (j = 0; j < 4; j++) - accm += *dev->chan[i].out[j]; + for (j = 0; j < 4; j++) + accm += *dev->chan[i].out[j]; - dev->mixbuff[1] += (int16_t)(accm & dev->chan[i].chb); + dev->mixbuff[1] += (int16_t) (accm & dev->chan[i].chb); } for (i = 33; i < 36; i++) { - slot_calc_fb(&dev->slot[i]); - env_calc(&dev->slot[i]); - phase_generate(&dev->slot[i]); - slot_generate(&dev->slot[i]); + slot_calc_fb(&dev->slot[i]); + env_calc(&dev->slot[i]); + phase_generate(&dev->slot[i]); + slot_generate(&dev->slot[i]); } if ((dev->timer & 0x3f) == 0x3f) - dev->tremolopos = (dev->tremolopos + 1) % 210; + dev->tremolopos = (dev->tremolopos + 1) % 210; if (dev->tremolopos < 105) - dev->tremolo = dev->tremolopos >> dev->tremoloshift; + dev->tremolo = dev->tremolopos >> dev->tremoloshift; else - dev->tremolo = (210 - dev->tremolopos) >> dev->tremoloshift; + dev->tremolo = (210 - dev->tremolopos) >> dev->tremoloshift; if ((dev->timer & 0x03ff) == 0x03ff) - dev->vibpos = (dev->vibpos + 1) & 7; + dev->vibpos = (dev->vibpos + 1) & 7; dev->timer++; dev->eg_add = 0; if (dev->eg_timer) { - while (shift < 36 && ((dev->eg_timer >> shift) & 1) == 0) - shift++; + while (shift < 36 && ((dev->eg_timer >> shift) & 1) == 0) + shift++; - if (shift > 12) - dev->eg_add = 0; - else - dev->eg_add = shift + 1; + if (shift > 12) + dev->eg_add = 0; + else + dev->eg_add = shift + 1; } if (dev->eg_timerrem || dev->eg_state) { - if (dev->eg_timer == 0xfffffffff) { - dev->eg_timer = 0; - dev->eg_timerrem = 1; - } else { - dev->eg_timer++; - dev->eg_timerrem = 0; - } + if (dev->eg_timer == 0xfffffffff) { + dev->eg_timer = 0; + dev->eg_timerrem = 1; + } else { + dev->eg_timer++; + dev->eg_timerrem = 0; + } } dev->eg_state ^= 1; while (dev->wrbuf[dev->wrbuf_cur].time <= dev->wrbuf_samplecnt) { - if (! (dev->wrbuf[dev->wrbuf_cur].reg & 0x200)) - break; + if (!(dev->wrbuf[dev->wrbuf_cur].reg & 0x200)) + break; - dev->wrbuf[dev->wrbuf_cur].reg &= 0x01ff; + dev->wrbuf[dev->wrbuf_cur].reg &= 0x01ff; - nuked_write_reg(dev, dev->wrbuf[dev->wrbuf_cur].reg, - dev->wrbuf[dev->wrbuf_cur].data); + nuked_write_reg(dev, dev->wrbuf[dev->wrbuf_cur].reg, + dev->wrbuf[dev->wrbuf_cur].data); - dev->wrbuf_cur = (dev->wrbuf_cur + 1) % WRBUF_SIZE; + dev->wrbuf_cur = (dev->wrbuf_cur + 1) % WRBUF_SIZE; } dev->wrbuf_samplecnt++; } - void nuked_generate_resampled(void *priv, int32_t *bufp) { - nuked_t *dev = (nuked_t *)priv; + nuked_t *dev = (nuked_t *) priv; while (dev->samplecnt >= dev->rateratio) { - dev->oldsamples[0] = dev->samples[0]; - dev->oldsamples[1] = dev->samples[1]; - nuked_generate(dev, dev->samples); - dev->samplecnt -= dev->rateratio; + dev->oldsamples[0] = dev->samples[0]; + dev->oldsamples[1] = dev->samples[1]; + nuked_generate(dev, dev->samples); + dev->samplecnt -= dev->rateratio; } - bufp[0] = (int32_t)((dev->oldsamples[0] * (dev->rateratio - dev->samplecnt) - + dev->samples[0] * dev->samplecnt) / dev->rateratio); - bufp[1] = (int32_t)((dev->oldsamples[1] * (dev->rateratio - dev->samplecnt) - + dev->samples[1] * dev->samplecnt) / dev->rateratio); + bufp[0] = (int32_t) ((dev->oldsamples[0] * (dev->rateratio - dev->samplecnt) + + dev->samples[0] * dev->samplecnt) + / dev->rateratio); + bufp[1] = (int32_t) ((dev->oldsamples[1] * (dev->rateratio - dev->samplecnt) + + dev->samples[1] * dev->samplecnt) + / dev->rateratio); dev->samplecnt += 1 << RSM_FRAC; } - void nuked_generate_stream(void *priv, int32_t *sndptr, uint32_t num) { - nuked_t *dev = (nuked_t *)priv; + nuked_t *dev = (nuked_t *) priv; uint32_t i; for (i = 0; i < num; i++) { - nuked_generate_resampled(dev, sndptr); - sndptr += 2; + nuked_generate_resampled(dev, sndptr); + sndptr += 2; } } - void * nuked_init(uint32_t samplerate) { nuked_t *dev; - uint8_t i; + uint8_t i; - dev = (nuked_t *)malloc(sizeof(nuked_t)); + dev = (nuked_t *) malloc(sizeof(nuked_t)); memset(dev, 0x00, sizeof(nuked_t)); for (i = 0; i < 36; i++) { - dev->slot[i].dev = dev; - dev->slot[i].mod = &dev->zeromod; - dev->slot[i].eg_rout = 0x01ff; - dev->slot[i].eg_out = 0x01ff; - dev->slot[i].eg_gen = envelope_gen_num_release; - dev->slot[i].trem = (uint8_t*)&dev->zeromod; - dev->slot[i].slot_num = i; + dev->slot[i].dev = dev; + dev->slot[i].mod = &dev->zeromod; + dev->slot[i].eg_rout = 0x01ff; + dev->slot[i].eg_out = 0x01ff; + dev->slot[i].eg_gen = envelope_gen_num_release; + dev->slot[i].trem = (uint8_t *) &dev->zeromod; + dev->slot[i].slot_num = i; } for (i = 0; i < 18; i++) { - dev->chan[i].slots[0] = &dev->slot[ch_slot[i]]; - dev->chan[i].slots[1] = &dev->slot[ch_slot[i] + 3]; - dev->slot[ch_slot[i]].chan = &dev->chan[i]; - dev->slot[ch_slot[i] + 3].chan = &dev->chan[i]; + dev->chan[i].slots[0] = &dev->slot[ch_slot[i]]; + dev->chan[i].slots[1] = &dev->slot[ch_slot[i] + 3]; + dev->slot[ch_slot[i]].chan = &dev->chan[i]; + dev->slot[ch_slot[i] + 3].chan = &dev->chan[i]; - if ((i % 9) < 3) - dev->chan[i].pair = &dev->chan[i + 3]; - else if ((i % 9) < 6) - dev->chan[i].pair = &dev->chan[i - 3]; + if ((i % 9) < 3) + dev->chan[i].pair = &dev->chan[i + 3]; + else if ((i % 9) < 6) + dev->chan[i].pair = &dev->chan[i - 3]; - dev->chan[i].dev = dev; - dev->chan[i].out[0] = &dev->zeromod; - dev->chan[i].out[1] = &dev->zeromod; - dev->chan[i].out[2] = &dev->zeromod; - dev->chan[i].out[3] = &dev->zeromod; - dev->chan[i].chtype = ch_2op; - dev->chan[i].cha = 0xffff; - dev->chan[i].chb = 0xffff; - dev->chan[i].ch_num = i; + dev->chan[i].dev = dev; + dev->chan[i].out[0] = &dev->zeromod; + dev->chan[i].out[1] = &dev->zeromod; + dev->chan[i].out[2] = &dev->zeromod; + dev->chan[i].out[3] = &dev->zeromod; + dev->chan[i].chtype = ch_2op; + dev->chan[i].cha = 0xffff; + dev->chan[i].chb = 0xffff; + dev->chan[i].ch_num = i; - channel_setup_alg(&dev->chan[i]); + channel_setup_alg(&dev->chan[i]); } - dev->noise = 1; - dev->rateratio = (samplerate << RSM_FRAC) / 49716; + dev->noise = 1; + dev->rateratio = (samplerate << RSM_FRAC) / 49716; dev->tremoloshift = 4; - dev->vibshift = 1; + dev->vibshift = 1; - return(dev); + return (dev); } - void nuked_close(void *priv) { - nuked_t *dev = (nuked_t *)priv; + nuked_t *dev = (nuked_t *) priv; free(dev); } diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index c99bd5248..df983d4ad 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -1,26 +1,26 @@ #include #include #include -#include #include +#include #include #define HAVE_STDARG_H -#include <86box/86box.h> + #include "cpu.h" +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/dma.h> +#include <86box/filters.h> #include <86box/io.h> #include <86box/pic.h> #include <86box/timer.h> #include <86box/pit.h> -#include <86box/dma.h> -#include <86box/device.h> -#include <86box/sound.h> -#include <86box/filters.h> #include <86box/snd_mpu401.h> +#include <86box/sound.h> #include <86box/snd_opl.h> #include <86box/snd_sb.h> #include <86box/snd_sb_dsp.h> - /* Original PAS uses 2 x OPL2 PIT - sample rate/count @@ -94,675 +94,662 @@ 3 = PAS16 */ -typedef struct pas16_t -{ - uint16_t base; +typedef struct pas16_t { + uint16_t base; - int irq, dma; + int irq, dma; - uint8_t audiofilt; + uint8_t audiofilt; - uint8_t audio_mixer; + uint8_t audio_mixer; - uint8_t compat, compat_base; + uint8_t compat, compat_base; - uint8_t enhancedscsi; + uint8_t enhancedscsi; - uint8_t io_conf_1, io_conf_2, io_conf_3, io_conf_4; + uint8_t io_conf_1, io_conf_2, io_conf_3, io_conf_4; - uint8_t irq_stat, irq_ena; + uint8_t irq_stat, irq_ena; - uint8_t pcm_ctrl; - uint16_t pcm_dat; + uint8_t pcm_ctrl; + uint16_t pcm_dat; - uint16_t pcm_dat_l, pcm_dat_r; + uint16_t pcm_dat_l, pcm_dat_r; - uint8_t sb_irqdma; + uint8_t sb_irqdma; - int stereo_lr; + int stereo_lr; - uint8_t sys_conf_1, sys_conf_2, sys_conf_3, sys_conf_4; + uint8_t sys_conf_1, sys_conf_2, sys_conf_3, sys_conf_4; - struct - { - uint32_t l[3]; - int64_t c[3]; - pc_timer_t timer[3]; - uint8_t m[3]; - uint8_t ctrl, ctrls[2]; - int wp, rm[3], wm[3]; - uint16_t rl[3]; - int thit[3]; - int delay[3]; - int rereadlatch[3]; - int64_t enable[3]; - } pit; + struct + { + uint32_t l[3]; + int64_t c[3]; + pc_timer_t timer[3]; + uint8_t m[3]; + uint8_t ctrl, ctrls[2]; + int wp, rm[3], wm[3]; + uint16_t rl[3]; + int thit[3]; + int delay[3]; + int rereadlatch[3]; + int64_t enable[3]; + } pit; - opl_t opl; - sb_dsp_t dsp; + opl_t opl; + sb_dsp_t dsp; - int16_t pcm_buffer[2][SOUNDBUFLEN]; + int16_t pcm_buffer[2][SOUNDBUFLEN]; - int pos; + int pos; } pas16_t; static uint8_t pas16_pit_in(uint16_t port, void *priv); -static void pas16_pit_out(uint16_t port, uint8_t val, void *priv); -static void pas16_update(pas16_t *pas16); +static void pas16_pit_out(uint16_t port, uint8_t val, void *priv); +static void pas16_update(pas16_t *pas16); -static int pas16_dmas[8] = {4, 1, 2, 3, 0, 5, 6, 7}; -static int pas16_irqs[16] = {0, 2, 3, 4, 5, 6, 7, 10, 11, 12, 14, 15, 0, 0, 0, 0}; -static int pas16_sb_irqs[8] = {0, 2, 3, 5, 7, 10, 11, 12}; -static int pas16_sb_dmas[8] = {0, 1, 2, 3}; +static int pas16_dmas[8] = { 4, 1, 2, 3, 0, 5, 6, 7 }; +static int pas16_irqs[16] = { 0, 2, 3, 4, 5, 6, 7, 10, 11, 12, 14, 15, 0, 0, 0, 0 }; +static int pas16_sb_irqs[8] = { 0, 2, 3, 5, 7, 10, 11, 12 }; +static int pas16_sb_dmas[8] = { 0, 1, 2, 3 }; -enum -{ - PAS16_INT_SAMP = 0x04, - PAS16_INT_PCM = 0x08 +enum { + PAS16_INT_SAMP = 0x04, + PAS16_INT_PCM = 0x08 }; -enum -{ - PAS16_PCM_MONO = 0x20, - PAS16_PCM_ENA = 0x40 +enum { + PAS16_PCM_MONO = 0x20, + PAS16_PCM_ENA = 0x40 }; -enum -{ - PAS16_SC2_16BIT = 0x04, - PAS16_SC2_MSBINV = 0x10 +enum { + PAS16_SC2_16BIT = 0x04, + PAS16_SC2_MSBINV = 0x10 }; -enum -{ - PAS16_FILT_MUTE = 0x20 +enum { + PAS16_FILT_MUTE = 0x20 }; - #ifdef ENABLE_PAS16_LOG int pas16_do_log = ENABLE_PAS16_LOG; - static void pas16_log(const char *fmt, ...) { va_list ap; if (pas16_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define pas16_log(fmt, ...) +# define pas16_log(fmt, ...) #endif - -static uint8_t pas16_in(uint16_t port, void *p) +static uint8_t +pas16_in(uint16_t port, void *p) { - pas16_t *pas16 = (pas16_t *)p; - uint8_t temp = 0xff; - switch ((port - pas16->base) + 0x388) - { - case 0x388: case 0x389: case 0x38a: case 0x38b: - temp = opl3_read((port - pas16->base) + 0x388, &pas16->opl); - break; + pas16_t *pas16 = (pas16_t *) p; + uint8_t temp = 0xff; + switch ((port - pas16->base) + 0x388) { + case 0x388: + case 0x389: + case 0x38a: + case 0x38b: + temp = opl3_read((port - pas16->base) + 0x388, &pas16->opl); + break; - case 0xb88: - temp = pas16->audio_mixer; - break; + case 0xb88: + temp = pas16->audio_mixer; + break; - case 0xb89: - temp = pas16->irq_stat; - break; + case 0xb89: + temp = pas16->irq_stat; + break; - case 0xb8a: - temp = pas16->audiofilt; - break; + case 0xb8a: + temp = pas16->audiofilt; + break; - case 0xb8b: - temp = (pas16->irq_ena & ~0xe0) | 0x20; - break; + case 0xb8b: + temp = (pas16->irq_ena & ~0xe0) | 0x20; + break; - case 0xf8a: - temp = pas16->pcm_ctrl; - break; + case 0xf8a: + temp = pas16->pcm_ctrl; + break; - case 0x1388: case 0x1389: case 0x138a: case 0x138b: - temp = pas16_pit_in(port, pas16); - break; + case 0x1388: + case 0x1389: + case 0x138a: + case 0x138b: + temp = pas16_pit_in(port, pas16); + break; - case 0x2789: /*Board revision*/ - temp = 0; - break; + case 0x2789: /*Board revision*/ + temp = 0; + break; - case 0x7f89: - temp = pas16->enhancedscsi & ~1; - break; + case 0x7f89: + temp = pas16->enhancedscsi & ~1; + break; - case 0x8388: - temp = pas16->sys_conf_1; - break; - case 0x8389: - temp = pas16->sys_conf_2; - break; - case 0x838b: - temp = pas16->sys_conf_3; - break; - case 0x838c: - temp = pas16->sys_conf_4; - break; + case 0x8388: + temp = pas16->sys_conf_1; + break; + case 0x8389: + temp = pas16->sys_conf_2; + break; + case 0x838b: + temp = pas16->sys_conf_3; + break; + case 0x838c: + temp = pas16->sys_conf_4; + break; - case 0xef8b: - temp = 0x0c; - break; + case 0xef8b: + temp = 0x0c; + break; - case 0xf388: - temp = pas16->io_conf_1; - break; - case 0xf389: - temp = pas16->io_conf_2; - break; - case 0xf38b: - temp = pas16->io_conf_3; - break; - case 0xf38c: - temp = pas16->io_conf_4; - break; + case 0xf388: + temp = pas16->io_conf_1; + break; + case 0xf389: + temp = pas16->io_conf_2; + break; + case 0xf38b: + temp = pas16->io_conf_3; + break; + case 0xf38c: + temp = pas16->io_conf_4; + break; - case 0xf788: - temp = pas16->compat; - break; - case 0xf789: - temp = pas16->compat_base; - break; + case 0xf788: + temp = pas16->compat; + break; + case 0xf789: + temp = pas16->compat_base; + break; - case 0xfb8a: - temp = pas16->sb_irqdma; - break; + case 0xfb8a: + temp = pas16->sb_irqdma; + break; - case 0xff88: /*Board model*/ - temp = 4; /*PAS16*/ - break; - case 0xff8b: /*Master mode read*/ - temp = 0x20 | 0x10 | 0x01; /*AT bus, XT/AT timing*/ - break; - } - pas16_log("pas16_in : port %04X return %02X %04X:%04X\n", port, temp, CS,cpu_state.pc); - return temp; + case 0xff88: /*Board model*/ + temp = 4; /*PAS16*/ + break; + case 0xff8b: /*Master mode read*/ + temp = 0x20 | 0x10 | 0x01; /*AT bus, XT/AT timing*/ + break; + } + pas16_log("pas16_in : port %04X return %02X %04X:%04X\n", port, temp, CS, cpu_state.pc); + return temp; } -static void pas16_out(uint16_t port, uint8_t val, void *p) +static void +pas16_out(uint16_t port, uint8_t val, void *p) { - pas16_t *pas16 = (pas16_t *)p; - pas16_log("pas16_out : port %04X val %02X %04X:%04X\n", port, val, CS,cpu_state.pc); - switch ((port - pas16->base) + 0x388) - { - case 0x388: case 0x389: case 0x38a: case 0x38b: - opl3_write((port - pas16->base) + 0x388, val, &pas16->opl); - break; + pas16_t *pas16 = (pas16_t *) p; + pas16_log("pas16_out : port %04X val %02X %04X:%04X\n", port, val, CS, cpu_state.pc); + switch ((port - pas16->base) + 0x388) { + case 0x388: + case 0x389: + case 0x38a: + case 0x38b: + opl3_write((port - pas16->base) + 0x388, val, &pas16->opl); + break; - case 0xb88: - pas16->audio_mixer = val; - break; + case 0xb88: + pas16->audio_mixer = val; + break; - case 0xb89: - pas16->irq_stat &= ~val; - break; + case 0xb89: + pas16->irq_stat &= ~val; + break; - case 0xb8a: - pas16_update(pas16); - pas16->audiofilt = val; - break; + case 0xb8a: + pas16_update(pas16); + pas16->audiofilt = val; + break; - case 0xb8b: - pas16->irq_ena = val; - break; + case 0xb8b: + pas16->irq_ena = val; + break; - case 0xf88: - pas16_update(pas16); - pas16->pcm_dat = (pas16->pcm_dat & 0xff00) | val; - break; - case 0xf89: - pas16_update(pas16); - pas16->pcm_dat = (pas16->pcm_dat & 0x00ff) | (val << 8); - break; - case 0xf8a: - if ((val & PAS16_PCM_ENA) && !(pas16->pcm_ctrl & PAS16_PCM_ENA)) /*Guess*/ - pas16->stereo_lr = 0; - pas16->pcm_ctrl = val; - break; + case 0xf88: + pas16_update(pas16); + pas16->pcm_dat = (pas16->pcm_dat & 0xff00) | val; + break; + case 0xf89: + pas16_update(pas16); + pas16->pcm_dat = (pas16->pcm_dat & 0x00ff) | (val << 8); + break; + case 0xf8a: + if ((val & PAS16_PCM_ENA) && !(pas16->pcm_ctrl & PAS16_PCM_ENA)) /*Guess*/ + pas16->stereo_lr = 0; + pas16->pcm_ctrl = val; + break; - case 0x1388: case 0x1389: case 0x138a: case 0x138b: - pas16_pit_out(port, val, pas16); - break; + case 0x1388: + case 0x1389: + case 0x138a: + case 0x138b: + pas16_pit_out(port, val, pas16); + break; - case 0x7f89: - pas16->enhancedscsi = val; - break; + case 0x7f89: + pas16->enhancedscsi = val; + break; - case 0x8388: - pas16->sys_conf_1 = val; - break; - case 0x8389: - pas16->sys_conf_2 = val; - break; - case 0x838a: - pas16->sys_conf_3 = val; - break; - case 0x838b: - pas16->sys_conf_4 = val; - break; + case 0x8388: + pas16->sys_conf_1 = val; + break; + case 0x8389: + pas16->sys_conf_2 = val; + break; + case 0x838a: + pas16->sys_conf_3 = val; + break; + case 0x838b: + pas16->sys_conf_4 = val; + break; - case 0xf388: - pas16->io_conf_1 = val; - break; - case 0xf389: - pas16->io_conf_2 = val; - pas16->dma = pas16_dmas[val & 0x7]; - pas16_log("pas16_out : set PAS DMA %i\n", pas16->dma); - break; - case 0xf38a: - pas16->io_conf_3 = val; - pas16->irq = pas16_irqs[val & 0xf]; - pas16_log("pas16_out : set PAS IRQ %i\n", pas16->irq); - break; - case 0xf38b: - pas16->io_conf_4 = val; - break; + case 0xf388: + pas16->io_conf_1 = val; + break; + case 0xf389: + pas16->io_conf_2 = val; + pas16->dma = pas16_dmas[val & 0x7]; + pas16_log("pas16_out : set PAS DMA %i\n", pas16->dma); + break; + case 0xf38a: + pas16->io_conf_3 = val; + pas16->irq = pas16_irqs[val & 0xf]; + pas16_log("pas16_out : set PAS IRQ %i\n", pas16->irq); + break; + case 0xf38b: + pas16->io_conf_4 = val; + break; - case 0xf788: - pas16->compat = val; - if (pas16->compat & 0x02) - sb_dsp_setaddr(&pas16->dsp, ((pas16->compat_base & 0xf) << 4) | 0x200); - else - sb_dsp_setaddr(&pas16->dsp, 0); - break; - case 0xf789: - pas16->compat_base = val; - if (pas16->compat & 0x02) - sb_dsp_setaddr(&pas16->dsp, ((pas16->compat_base & 0xf) << 4) | 0x200); - break; + case 0xf788: + pas16->compat = val; + if (pas16->compat & 0x02) + sb_dsp_setaddr(&pas16->dsp, ((pas16->compat_base & 0xf) << 4) | 0x200); + else + sb_dsp_setaddr(&pas16->dsp, 0); + break; + case 0xf789: + pas16->compat_base = val; + if (pas16->compat & 0x02) + sb_dsp_setaddr(&pas16->dsp, ((pas16->compat_base & 0xf) << 4) | 0x200); + break; - case 0xfb8a: - pas16->sb_irqdma = val; - sb_dsp_setirq(&pas16->dsp, pas16_sb_irqs[(val >> 3) & 7]); - sb_dsp_setdma8(&pas16->dsp, pas16_sb_dmas[(val >> 6) & 3]); - pas16_log("pas16_out : set SB IRQ %i DMA %i\n", pas16_sb_irqs[(val >> 3) & 7], pas16_sb_dmas[(val >> 6) & 3]); - break; + case 0xfb8a: + pas16->sb_irqdma = val; + sb_dsp_setirq(&pas16->dsp, pas16_sb_irqs[(val >> 3) & 7]); + sb_dsp_setdma8(&pas16->dsp, pas16_sb_dmas[(val >> 6) & 3]); + pas16_log("pas16_out : set SB IRQ %i DMA %i\n", pas16_sb_irqs[(val >> 3) & 7], pas16_sb_dmas[(val >> 6) & 3]); + break; - default: - pas16_log("pas16_out : unknown %04X\n", port); - } - if (cpu_state.pc == 0x80048CF3) - { - if (output) - fatal("here\n"); - output = 3; - } + default: + pas16_log("pas16_out : unknown %04X\n", port); + } + if (cpu_state.pc == 0x80048CF3) { + if (output) + fatal("here\n"); + output = 3; + } } -static void pas16_pit_out(uint16_t port, uint8_t val, void *p) +static void +pas16_pit_out(uint16_t port, uint8_t val, void *p) { - pas16_t *pas16 = (pas16_t *)p; - int t; - switch (port & 3) - { - case 3: /*CTRL*/ - if ((val & 0xC0) == 0xC0) - { - if (!(val & 0x20)) - { - if (val & 2) pas16->pit.rl[0] = timer_get_remaining_u64(&pas16->pit.timer[0]) / PITCONST;; - if (val & 4) pas16->pit.rl[1] = pas16->pit.c[1]; - if (val & 8) pas16->pit.rl[2] = pas16->pit.c[2]; - } - return; + pas16_t *pas16 = (pas16_t *) p; + int t; + switch (port & 3) { + case 3: /*CTRL*/ + if ((val & 0xC0) == 0xC0) { + if (!(val & 0x20)) { + if (val & 2) + pas16->pit.rl[0] = timer_get_remaining_u64(&pas16->pit.timer[0]) / PITCONST; + ; + if (val & 4) + pas16->pit.rl[1] = pas16->pit.c[1]; + if (val & 8) + pas16->pit.rl[2] = pas16->pit.c[2]; } - t = val >> 6; - pas16->pit.ctrls[t] = pas16->pit.ctrl = val; - if (t == 3) - { - printf("Bad PIT reg select\n"); - return; + return; + } + t = val >> 6; + pas16->pit.ctrls[t] = pas16->pit.ctrl = val; + if (t == 3) { + printf("Bad PIT reg select\n"); + return; + } + if (!(pas16->pit.ctrl & 0x30)) { + if (!t) + pas16->pit.rl[t] = timer_get_remaining_u64(&pas16->pit.timer[t]) / PITCONST; + else { + pas16->pit.rl[t] = pas16->pit.c[t]; + if (pas16->pit.c[t] < 0) + pas16->pit.rl[t] = 0; } - if (!(pas16->pit.ctrl & 0x30)) - { - if (!t) - pas16->pit.rl[t] = timer_get_remaining_u64(&pas16->pit.timer[t]) / PITCONST; - else - { - pas16->pit.rl[t] = pas16->pit.c[t]; - if (pas16->pit.c[t] < 0) - pas16->pit.rl[t] = 0; - } - pas16->pit.ctrl |= 0x30; - pas16->pit.rereadlatch[t] = 0; - pas16->pit.rm[t] = 3; + pas16->pit.ctrl |= 0x30; + pas16->pit.rereadlatch[t] = 0; + pas16->pit.rm[t] = 3; + } else { + pas16->pit.rm[t] = pas16->pit.wm[t] = (pas16->pit.ctrl >> 4) & 3; + pas16->pit.m[t] = (val >> 1) & 7; + if (pas16->pit.m[t] > 5) + pas16->pit.m[t] &= 3; + if (!pas16->pit.rm[t]) { + pas16->pit.rm[t] = 3; + if (!t) + pas16->pit.rl[t] = timer_get_remaining_u64(&pas16->pit.timer[t]) / PITCONST; + else + pas16->pit.rl[t] = pas16->pit.c[t]; } - else - { - pas16->pit.rm[t] = pas16->pit.wm[t] = (pas16->pit.ctrl >> 4) & 3; - pas16->pit.m[t] = (val >> 1) & 7; - if (pas16->pit.m[t] > 5) - pas16->pit.m[t] &= 3; - if (!pas16->pit.rm[t]) - { - pas16->pit.rm[t] = 3; - if (!t) - pas16->pit.rl[t] = timer_get_remaining_u64(&pas16->pit.timer[t]) / PITCONST; - else - pas16->pit.rl[t] = pas16->pit.c[t]; - } - pas16->pit.rereadlatch[t] = 1; - } - pas16->pit.wp = 0; - pas16->pit.thit[t] = 0; - break; - case 0: case 1: case 2: /*Timers*/ - t = port & 3; - switch (pas16->pit.wm[t]) - { - case 1: - pas16->pit.l[t] = val; - pas16->pit.thit[t] = 0; - pas16->pit.c[t] = pas16->pit.l[t]; - if (!t) - timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); - pas16->pit.enable[t] = 1; - break; - case 2: - pas16->pit.l[t] = val << 8; - pas16->pit.thit[t] = 0; - pas16->pit.c[t] = pas16->pit.l[t]; - if (!t) - timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); - pas16->pit.enable[t] = 1; - break; - case 0: - pas16->pit.l[t] &= 0xFF; - pas16->pit.l[t] |= (val << 8); - pas16->pit.c[t] = pas16->pit.l[t]; - if (!t) - timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); - pas16->pit.thit[t] = 0; - pas16->pit.wm[t] = 3; - pas16->pit.enable[t] = 1; - break; - case 3: - pas16->pit.l[t] &= 0xFF00; - pas16->pit.l[t] |= val; - pas16->pit.wm[t] = 0; - break; - } - if (!pas16->pit.l[t]) - { - pas16->pit.l[t] |= 0x10000; - pas16->pit.c[t] = pas16->pit.l[t]; - if (!t) - timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); - } - break; - } + pas16->pit.rereadlatch[t] = 1; + } + pas16->pit.wp = 0; + pas16->pit.thit[t] = 0; + break; + case 0: + case 1: + case 2: /*Timers*/ + t = port & 3; + switch (pas16->pit.wm[t]) { + case 1: + pas16->pit.l[t] = val; + pas16->pit.thit[t] = 0; + pas16->pit.c[t] = pas16->pit.l[t]; + if (!t) + timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); + pas16->pit.enable[t] = 1; + break; + case 2: + pas16->pit.l[t] = val << 8; + pas16->pit.thit[t] = 0; + pas16->pit.c[t] = pas16->pit.l[t]; + if (!t) + timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); + pas16->pit.enable[t] = 1; + break; + case 0: + pas16->pit.l[t] &= 0xFF; + pas16->pit.l[t] |= (val << 8); + pas16->pit.c[t] = pas16->pit.l[t]; + if (!t) + timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); + pas16->pit.thit[t] = 0; + pas16->pit.wm[t] = 3; + pas16->pit.enable[t] = 1; + break; + case 3: + pas16->pit.l[t] &= 0xFF00; + pas16->pit.l[t] |= val; + pas16->pit.wm[t] = 0; + break; + } + if (!pas16->pit.l[t]) { + pas16->pit.l[t] |= 0x10000; + pas16->pit.c[t] = pas16->pit.l[t]; + if (!t) + timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); + } + break; + } } -static uint8_t pas16_pit_in(uint16_t port, void *p) +static uint8_t +pas16_pit_in(uint16_t port, void *p) { - pas16_t *pas16 = (pas16_t *)p; - uint8_t temp = 0xff; - int t = port & 3; - switch (port & 3) - { - case 0: case 1: case 2: /*Timers*/ - if (pas16->pit.rereadlatch[t]) - { - pas16->pit.rereadlatch[t] = 0; - if (!t) - { - pas16->pit.rl[t] = timer_get_remaining_u64(&pas16->pit.timer[t]) / PITCONST; - if ((timer_get_remaining_u64(&pas16->pit.timer[t]) / PITCONST) > 65536) - pas16->pit.rl[t] = 0xFFFF; - } - else - { - pas16->pit.rl[t] = pas16->pit.c[t]; - if (pas16->pit.c[t] > 65536) - pas16->pit.rl[t] = 0xFFFF; - } + pas16_t *pas16 = (pas16_t *) p; + uint8_t temp = 0xff; + int t = port & 3; + switch (port & 3) { + case 0: + case 1: + case 2: /*Timers*/ + if (pas16->pit.rereadlatch[t]) { + pas16->pit.rereadlatch[t] = 0; + if (!t) { + pas16->pit.rl[t] = timer_get_remaining_u64(&pas16->pit.timer[t]) / PITCONST; + if ((timer_get_remaining_u64(&pas16->pit.timer[t]) / PITCONST) > 65536) + pas16->pit.rl[t] = 0xFFFF; + } else { + pas16->pit.rl[t] = pas16->pit.c[t]; + if (pas16->pit.c[t] > 65536) + pas16->pit.rl[t] = 0xFFFF; } - switch (pas16->pit.rm[t]) - { - case 0: - temp = pas16->pit.rl[t] >> 8; - pas16->pit.rm[t] = 3; - pas16->pit.rereadlatch[t] = 1; - break; - case 1: - temp = (pas16->pit.rl[t]) & 0xFF; - pas16->pit.rereadlatch[t] = 1; - break; - case 2: - temp = (pas16->pit.rl[t]) >> 8; - pas16->pit.rereadlatch[t] = 1; - break; - case 3: - temp = (pas16->pit.rl[t]) & 0xFF; - if (pas16->pit.m[t] & 0x80) pas16->pit.m[t] &= 7; - else pas16->pit.rm[t] = 0; - break; - } - break; - case 3: /*Control*/ - temp = pas16->pit.ctrl; - break; - } - return temp; + } + switch (pas16->pit.rm[t]) { + case 0: + temp = pas16->pit.rl[t] >> 8; + pas16->pit.rm[t] = 3; + pas16->pit.rereadlatch[t] = 1; + break; + case 1: + temp = (pas16->pit.rl[t]) & 0xFF; + pas16->pit.rereadlatch[t] = 1; + break; + case 2: + temp = (pas16->pit.rl[t]) >> 8; + pas16->pit.rereadlatch[t] = 1; + break; + case 3: + temp = (pas16->pit.rl[t]) & 0xFF; + if (pas16->pit.m[t] & 0x80) + pas16->pit.m[t] &= 7; + else + pas16->pit.rm[t] = 0; + break; + } + break; + case 3: /*Control*/ + temp = pas16->pit.ctrl; + break; + } + return temp; } -static uint8_t pas16_readdma(pas16_t *pas16) +static uint8_t +pas16_readdma(pas16_t *pas16) { - return dma_channel_read(pas16->dma); + return dma_channel_read(pas16->dma); } -static void pas16_pcm_poll(void *p) +static void +pas16_pcm_poll(void *p) { - pas16_t *pas16 = (pas16_t *)p; + pas16_t *pas16 = (pas16_t *) p; - pas16_update(pas16); - if (pas16->pit.m[0] & 2) - { - if (pas16->pit.l[0]) - timer_advance_u64(&pas16->pit.timer[0], pas16->pit.l[0] * PITCONST); - else - timer_advance_u64(&pas16->pit.timer[0], 0x10000 * PITCONST); - } + pas16_update(pas16); + if (pas16->pit.m[0] & 2) { + if (pas16->pit.l[0]) + timer_advance_u64(&pas16->pit.timer[0], pas16->pit.l[0] * PITCONST); else - { - pas16->pit.enable[0] = 0; - } + timer_advance_u64(&pas16->pit.timer[0], 0x10000 * PITCONST); + } else { + pas16->pit.enable[0] = 0; + } - pas16->irq_stat |= PAS16_INT_SAMP; - if (pas16->irq_ena & PAS16_INT_SAMP) + pas16->irq_stat |= PAS16_INT_SAMP; + if (pas16->irq_ena & PAS16_INT_SAMP) + picint(1 << pas16->irq); + + /*Update sample rate counter*/ + if (pas16->pit.enable[1]) { + if (pas16->pcm_ctrl & PAS16_PCM_ENA) { + uint16_t temp; + + if (pas16->sys_conf_2 & PAS16_SC2_16BIT) { + temp = pas16_readdma(pas16) << 8; + temp |= pas16_readdma(pas16); + } else + temp = (pas16_readdma(pas16) ^ 0x80) << 8; + + if (pas16->sys_conf_2 & PAS16_SC2_MSBINV) + temp ^= 0x8000; + if (pas16->pcm_ctrl & PAS16_PCM_MONO) + pas16->pcm_dat_l = pas16->pcm_dat_r = temp; + else { + if (pas16->stereo_lr) + pas16->pcm_dat_r = temp; + else + pas16->pcm_dat_l = temp; + + pas16->stereo_lr = !pas16->stereo_lr; + } + } + if (pas16->sys_conf_2 & PAS16_SC2_16BIT) + pas16->pit.c[1] -= 2; + else + pas16->pit.c[1]--; + if (pas16->pit.c[1] == 0) { + if (pas16->pit.m[1] & 2) { + if (pas16->pit.l[1]) + pas16->pit.c[1] += pas16->pit.l[1]; + else + pas16->pit.c[1] += 0x10000; + } else { + pas16->pit.c[1] = -1; + pas16->pit.enable[1] = 0; + } + + pas16->irq_stat |= PAS16_INT_PCM; + if (pas16->irq_ena & PAS16_INT_PCM) { + pas16_log("pas16_pcm_poll : cause IRQ %i %02X\n", pas16->irq, 1 << pas16->irq); picint(1 << pas16->irq); - - /*Update sample rate counter*/ - if (pas16->pit.enable[1]) - { - if (pas16->pcm_ctrl & PAS16_PCM_ENA) - { - uint16_t temp; - - if (pas16->sys_conf_2 & PAS16_SC2_16BIT) - { - temp = pas16_readdma(pas16) << 8; - temp |= pas16_readdma(pas16); - } - else - temp = (pas16_readdma(pas16) ^ 0x80) << 8; - - if (pas16->sys_conf_2 & PAS16_SC2_MSBINV) - temp ^= 0x8000; - if (pas16->pcm_ctrl & PAS16_PCM_MONO) - pas16->pcm_dat_l = pas16->pcm_dat_r = temp; - else - { - if (pas16->stereo_lr) - pas16->pcm_dat_r = temp; - else - pas16->pcm_dat_l = temp; - - pas16->stereo_lr = !pas16->stereo_lr; - } - } - if (pas16->sys_conf_2 & PAS16_SC2_16BIT) - pas16->pit.c[1] -= 2; - else - pas16->pit.c[1]--; - if (pas16->pit.c[1] == 0) - { - if (pas16->pit.m[1] & 2) - { - if (pas16->pit.l[1]) - pas16->pit.c[1] += pas16->pit.l[1]; - else - pas16->pit.c[1] += 0x10000; - } - else - { - pas16->pit.c[1] = -1; - pas16->pit.enable[1] = 0; - } - - pas16->irq_stat |= PAS16_INT_PCM; - if (pas16->irq_ena & PAS16_INT_PCM) - { - pas16_log("pas16_pcm_poll : cause IRQ %i %02X\n", pas16->irq, 1 << pas16->irq); - picint(1 << pas16->irq); - } - } + } } + } } -static void pas16_out_base(uint16_t port, uint8_t val, void *p) +static void +pas16_out_base(uint16_t port, uint8_t val, void *p) { - pas16_t *pas16 = (pas16_t *)p; + pas16_t *pas16 = (pas16_t *) p; - io_removehandler((pas16->base - 0x388) + 0x0388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x0788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x0b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x0f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x1388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x1788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x2788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x7f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0x8388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xbf88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xe388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xe788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xeb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xef88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xf388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xf788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xfb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_removehandler((pas16->base - 0x388) + 0xff88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler((pas16->base - 0x388) + 0x0388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler((pas16->base - 0x388) + 0x0788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler((pas16->base - 0x388) + 0x0b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler((pas16->base - 0x388) + 0x0f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler((pas16->base - 0x388) + 0x1388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler((pas16->base - 0x388) + 0x1788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler((pas16->base - 0x388) + 0x2788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler((pas16->base - 0x388) + 0x7f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler((pas16->base - 0x388) + 0x8388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler((pas16->base - 0x388) + 0xbf88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler((pas16->base - 0x388) + 0xe388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler((pas16->base - 0x388) + 0xe788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler((pas16->base - 0x388) + 0xeb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler((pas16->base - 0x388) + 0xef88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler((pas16->base - 0x388) + 0xf388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler((pas16->base - 0x388) + 0xf788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler((pas16->base - 0x388) + 0xfb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_removehandler((pas16->base - 0x388) + 0xff88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - pas16->base = val << 2; - pas16_log("pas16_write_base : PAS16 base now at %04X\n", pas16->base); + pas16->base = val << 2; + pas16_log("pas16_write_base : PAS16 base now at %04X\n", pas16->base); - io_sethandler((pas16->base - 0x388) + 0x0388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x0788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x0b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x0f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x1388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x1788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x2788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x7f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0x8388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xbf88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xe388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xe788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xeb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xef88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xf388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xf788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xfb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); - io_sethandler((pas16->base - 0x388) + 0xff88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler((pas16->base - 0x388) + 0x0388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler((pas16->base - 0x388) + 0x0788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler((pas16->base - 0x388) + 0x0b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler((pas16->base - 0x388) + 0x0f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler((pas16->base - 0x388) + 0x1388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler((pas16->base - 0x388) + 0x1788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler((pas16->base - 0x388) + 0x2788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler((pas16->base - 0x388) + 0x7f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler((pas16->base - 0x388) + 0x8388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler((pas16->base - 0x388) + 0xbf88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler((pas16->base - 0x388) + 0xe388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler((pas16->base - 0x388) + 0xe788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler((pas16->base - 0x388) + 0xeb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler((pas16->base - 0x388) + 0xef88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler((pas16->base - 0x388) + 0xf388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler((pas16->base - 0x388) + 0xf788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler((pas16->base - 0x388) + 0xfb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); + io_sethandler((pas16->base - 0x388) + 0xff88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); } - -static void pas16_update(pas16_t *pas16) +static void +pas16_update(pas16_t *pas16) { - if (!(pas16->audiofilt & PAS16_FILT_MUTE)) - { - for (; pas16->pos < sound_pos_global; pas16->pos++) - { - pas16->pcm_buffer[0][pas16->pos] = 0; - pas16->pcm_buffer[1][pas16->pos] = 0; - } + if (!(pas16->audiofilt & PAS16_FILT_MUTE)) { + for (; pas16->pos < sound_pos_global; pas16->pos++) { + pas16->pcm_buffer[0][pas16->pos] = 0; + pas16->pcm_buffer[1][pas16->pos] = 0; } - else - { - for (; pas16->pos < sound_pos_global; pas16->pos++) - { - pas16->pcm_buffer[0][pas16->pos] = (int16_t)pas16->pcm_dat_l; - pas16->pcm_buffer[1][pas16->pos] = (int16_t)pas16->pcm_dat_r; - } + } else { + for (; pas16->pos < sound_pos_global; pas16->pos++) { + pas16->pcm_buffer[0][pas16->pos] = (int16_t) pas16->pcm_dat_l; + pas16->pcm_buffer[1][pas16->pos] = (int16_t) pas16->pcm_dat_r; } + } } -void pas16_get_buffer(int32_t *buffer, int len, void *p) +void +pas16_get_buffer(int32_t *buffer, int len, void *p) { - pas16_t *pas16 = (pas16_t *)p; - int c; + pas16_t *pas16 = (pas16_t *) p; + int c; - opl3_update(&pas16->opl); - sb_dsp_update(&pas16->dsp); - pas16_update(pas16); - for (c = 0; c < len * 2; c++) - { - buffer[c] += pas16->opl.buffer[c]; - buffer[c] += (int16_t)(sb_iir(c & 1, (float)pas16->dsp.buffer[c]) / 1.3) / 2; - buffer[c] += (pas16->pcm_buffer[c & 1][c >> 1] / 2); - } + opl3_update(&pas16->opl); + sb_dsp_update(&pas16->dsp); + pas16_update(pas16); + for (c = 0; c < len * 2; c++) { + buffer[c] += pas16->opl.buffer[c]; + buffer[c] += (int16_t) (sb_iir(c & 1, (float) pas16->dsp.buffer[c]) / 1.3) / 2; + buffer[c] += (pas16->pcm_buffer[c & 1][c >> 1] / 2); + } - pas16->pos = 0; - pas16->opl.pos = 0; - pas16->dsp.pos = 0; + pas16->pos = 0; + pas16->opl.pos = 0; + pas16->dsp.pos = 0; } - -static void *pas16_init(const device_t *info) +static void * +pas16_init(const device_t *info) { - pas16_t *pas16 = malloc(sizeof(pas16_t)); - memset(pas16, 0, sizeof(pas16_t)); + pas16_t *pas16 = malloc(sizeof(pas16_t)); + memset(pas16, 0, sizeof(pas16_t)); - opl3_init(&pas16->opl); - sb_dsp_init(&pas16->dsp, SB2, SB_SUBTYPE_DEFAULT, pas16); + opl3_init(&pas16->opl); + sb_dsp_init(&pas16->dsp, SB2, SB_SUBTYPE_DEFAULT, pas16); - io_sethandler(0x9a01, 0x0001, NULL, NULL, NULL, pas16_out_base, NULL, NULL, pas16); + io_sethandler(0x9a01, 0x0001, NULL, NULL, NULL, pas16_out_base, NULL, NULL, pas16); - timer_add(&pas16->pit.timer[0], pas16_pcm_poll, pas16, 0); + timer_add(&pas16->pit.timer[0], pas16_pcm_poll, pas16, 0); - sound_add_handler(pas16_get_buffer, pas16); + sound_add_handler(pas16_get_buffer, pas16); - return pas16; + return pas16; } -static void pas16_close(void *p) +static void +pas16_close(void *p) { - pas16_t *pas16 = (pas16_t *)p; + pas16_t *pas16 = (pas16_t *) p; - free(pas16); + free(pas16); } -const device_t pas16_device = -{ - "Pro Audio Spectrum 16", - "pas16", - DEVICE_ISA | DEVICE_NOT_WORKING, - 0, - pas16_init, pas16_close, NULL, - { NULL }, NULL, NULL, - NULL +const device_t pas16_device = { + "Pro Audio Spectrum 16", + "pas16", + DEVICE_ISA | DEVICE_NOT_WORKING, + 0, + pas16_init, + pas16_close, + NULL, + { NULL }, + NULL, + NULL, + NULL }; diff --git a/src/sound/snd_ps1.c b/src/sound/snd_ps1.c index b26e6c65e..ff778dfbf 100644 --- a/src/sound/snd_ps1.c +++ b/src/sound/snd_ps1.c @@ -1,34 +1,33 @@ #include #include #include -#include #include +#include #include #define HAVE_STDARG_H + #include <86box/86box.h> +#include <86box/device.h> #include <86box/io.h> #include <86box/pic.h> -#include <86box/timer.h> -#include <86box/device.h> #include <86box/sound.h> #include <86box/snd_sn76489.h> - +#include <86box/timer.h> typedef struct { - sn76489_t sn76489; - uint8_t status, ctrl; - uint64_t timer_latch; + sn76489_t sn76489; + uint8_t status, ctrl; + uint64_t timer_latch; pc_timer_t timer_count; - int timer_enable; - uint8_t fifo[2048]; - int fifo_read_idx, fifo_write_idx; - int fifo_threshold; - uint8_t dac_val; - int16_t buffer[SOUNDBUFLEN]; - int pos; + int timer_enable; + uint8_t fifo[2048]; + int fifo_read_idx, fifo_write_idx; + int fifo_threshold; + uint8_t dac_val; + int16_t buffer[SOUNDBUFLEN]; + int pos; } ps1snd_t; - static void ps1snd_update_irq_status(ps1snd_t *snd) { @@ -38,96 +37,92 @@ ps1snd_update_irq_status(ps1snd_t *snd) picintc(1 << 7); } - static uint8_t ps1snd_read(uint16_t port, void *priv) { - ps1snd_t *ps1snd = (ps1snd_t *)priv; - uint8_t ret = 0xff; + ps1snd_t *ps1snd = (ps1snd_t *) priv; + uint8_t ret = 0xff; switch (port & 7) { - case 0: /* ADC data */ - ps1snd->status &= ~0x10; - ps1snd_update_irq_status(ps1snd); - ret = 0; - break; + case 0: /* ADC data */ + ps1snd->status &= ~0x10; + ps1snd_update_irq_status(ps1snd); + ret = 0; + break; - case 2: /* status */ - ret = ps1snd->status; - ret |= (ps1snd->ctrl & 0x01); - if ((ps1snd->fifo_write_idx - ps1snd->fifo_read_idx) >= 2048) - ret |= 0x08; /* FIFO full */ - if (ps1snd->fifo_read_idx == ps1snd->fifo_write_idx) - ret |= 0x04; /* FIFO empty */ - break; + case 2: /* status */ + ret = ps1snd->status; + ret |= (ps1snd->ctrl & 0x01); + if ((ps1snd->fifo_write_idx - ps1snd->fifo_read_idx) >= 2048) + ret |= 0x08; /* FIFO full */ + if (ps1snd->fifo_read_idx == ps1snd->fifo_write_idx) + ret |= 0x04; /* FIFO empty */ + break; - case 3: /* FIFO timer */ - /* - * The PS/1 Technical Reference says this should return - * thecurrent value, but the PS/1 BIOS and Stunt Island - * expect it not to change. - */ - ret = ps1snd->timer_latch; - break; + case 3: /* FIFO timer */ + /* + * The PS/1 Technical Reference says this should return + * thecurrent value, but the PS/1 BIOS and Stunt Island + * expect it not to change. + */ + ret = ps1snd->timer_latch; + break; - case 4: - case 5: - case 6: - case 7: - ret = 0; + case 4: + case 5: + case 6: + case 7: + ret = 0; } - return(ret); + return (ret); } - static void ps1snd_write(uint16_t port, uint8_t val, void *priv) { - ps1snd_t *ps1snd = (ps1snd_t *)priv; + ps1snd_t *ps1snd = (ps1snd_t *) priv; switch (port & 7) { - case 0: /* DAC output */ - if ((ps1snd->fifo_write_idx - ps1snd->fifo_read_idx) < 2048) { - ps1snd->fifo[ps1snd->fifo_write_idx & 2047] = val; - ps1snd->fifo_write_idx++; - } - break; + case 0: /* DAC output */ + if ((ps1snd->fifo_write_idx - ps1snd->fifo_read_idx) < 2048) { + ps1snd->fifo[ps1snd->fifo_write_idx & 2047] = val; + ps1snd->fifo_write_idx++; + } + break; - case 2: /* control */ - ps1snd->ctrl = val; - if (! (val & 0x02)) - ps1snd->status &= ~0x02; - ps1snd_update_irq_status(ps1snd); - break; + case 2: /* control */ + ps1snd->ctrl = val; + if (!(val & 0x02)) + ps1snd->status &= ~0x02; + ps1snd_update_irq_status(ps1snd); + break; - case 3: /* timer reload value */ - ps1snd->timer_latch = val; - if (val) - timer_set_delay_u64(&ps1snd->timer_count, ((0xff-val) * TIMER_USEC)); - else - timer_disable(&ps1snd->timer_count); - break; + case 3: /* timer reload value */ + ps1snd->timer_latch = val; + if (val) + timer_set_delay_u64(&ps1snd->timer_count, ((0xff - val) * TIMER_USEC)); + else + timer_disable(&ps1snd->timer_count); + break; - case 4: /* almost empty */ - ps1snd->fifo_threshold = val * 4; - break; + case 4: /* almost empty */ + ps1snd->fifo_threshold = val * 4; + break; } } - static void ps1snd_update(ps1snd_t *ps1snd) { for (; ps1snd->pos < sound_pos_global; ps1snd->pos++) - ps1snd->buffer[ps1snd->pos] = (int8_t)(ps1snd->dac_val ^ 0x80) * 0x20; + ps1snd->buffer[ps1snd->pos] = (int8_t) (ps1snd->dac_val ^ 0x80) * 0x20; } - static void ps1snd_callback(void *priv) { - ps1snd_t *ps1snd = (ps1snd_t *)priv; + ps1snd_t *ps1snd = (ps1snd_t *) priv; ps1snd_update(ps1snd); @@ -145,12 +140,11 @@ ps1snd_callback(void *priv) timer_advance_u64(&ps1snd->timer_count, ps1snd->timer_latch * TIMER_USEC); } - static void ps1snd_get_buffer(int32_t *buffer, int len, void *priv) { - ps1snd_t *ps1snd = (ps1snd_t *)priv; - int c; + ps1snd_t *ps1snd = (ps1snd_t *) priv; + int c; ps1snd_update(ps1snd); @@ -160,7 +154,6 @@ ps1snd_get_buffer(int32_t *buffer, int len, void *priv) ps1snd->pos = 0; } - static void * ps1snd_init(const device_t *info) { @@ -169,31 +162,37 @@ ps1snd_init(const device_t *info) sn76489_init(&ps1snd->sn76489, 0x0205, 0x0001, SN76496, 4000000); - io_sethandler(0x0200, 1, ps1snd_read,NULL,NULL, ps1snd_write,NULL,NULL, ps1snd); - io_sethandler(0x0202, 6, ps1snd_read,NULL,NULL, ps1snd_write,NULL,NULL, ps1snd); + io_sethandler(0x0200, 1, + ps1snd_read, NULL, NULL, + ps1snd_write, NULL, NULL, + ps1snd); + io_sethandler(0x0202, 6, + ps1snd_read, NULL, NULL, + ps1snd_write, NULL, NULL, + ps1snd); timer_add(&ps1snd->timer_count, ps1snd_callback, ps1snd, 0); sound_add_handler(ps1snd_get_buffer, ps1snd); - return(ps1snd); + return (ps1snd); } - static void ps1snd_close(void *priv) { - ps1snd_t *ps1snd = (ps1snd_t *)priv; + ps1snd_t *ps1snd = (ps1snd_t *) priv; free(ps1snd); } - const device_t ps1snd_device = { "IBM PS/1 Audio Card", "ps1snd", - 0, 0, - ps1snd_init, ps1snd_close, + 0, + 0, + ps1snd_init, + ps1snd_close, NULL, { NULL }, NULL, diff --git a/src/sound/snd_pssj.c b/src/sound/snd_pssj.c index e7bdcf85c..9bf1c47f5 100644 --- a/src/sound/snd_pssj.c +++ b/src/sound/snd_pssj.c @@ -1,55 +1,55 @@ -#include #include -#include +#include #include +#include #include + #include <86box/86box.h> -#include <86box/io.h> -#include <86box/dma.h> -#include <86box/pic.h> -#include <86box/timer.h> #include <86box/device.h> +#include <86box/dma.h> +#include <86box/io.h> +#include <86box/pic.h> #include <86box/sound.h> #include <86box/snd_sn76489.h> +#include <86box/timer.h> - -typedef struct pssj_t -{ +typedef struct pssj_t { sn76489_t sn76489; - uint8_t ctrl; - uint8_t wave; - uint8_t dac_val; + uint8_t ctrl; + uint8_t wave; + uint8_t dac_val; uint16_t freq; - int amplitude; + int amplitude; - int irq; + int irq; pc_timer_t timer_count; - int enable; + int enable; int wave_pos; int pulse_width; int16_t buffer[SOUNDBUFLEN]; - int pos; + int pos; } pssj_t; -static void pssj_update_irq(pssj_t *pssj) +static void +pssj_update_irq(pssj_t *pssj) { if (pssj->irq && (pssj->ctrl & 0x10) && (pssj->ctrl & 0x08)) picint(1 << 7); } -static void pssj_write(uint16_t port, uint8_t val, void *p) +static void +pssj_write(uint16_t port, uint8_t val, void *p) { - pssj_t *pssj = (pssj_t *)p; + pssj_t *pssj = (pssj_t *) p; - switch (port & 3) - { + switch (port & 3) { case 0: pssj->ctrl = val; if (!pssj->enable && ((val & 4) && (pssj->ctrl & 3))) - timer_set_delay_u64(&pssj->timer_count, (TIMER_USEC * (1000000.0 / 3579545.0) * (double)(pssj->freq ? pssj->freq : 0x400))); + timer_set_delay_u64(&pssj->timer_count, (TIMER_USEC * (1000000.0 / 3579545.0) * (double) (pssj->freq ? pssj->freq : 0x400))); pssj->enable = (val & 4) && (pssj->ctrl & 3); if (!pssj->enable) timer_disable(&pssj->timer_count); @@ -59,10 +59,9 @@ static void pssj_write(uint16_t port, uint8_t val, void *p) pssj_update_irq(pssj); break; case 1: - switch (pssj->ctrl & 3) - { + switch (pssj->ctrl & 3) { case 1: /*Sound channel*/ - pssj->wave = val; + pssj->wave = val; pssj->pulse_width = val & 7; break; case 3: /*Direct DAC*/ @@ -74,22 +73,21 @@ static void pssj_write(uint16_t port, uint8_t val, void *p) pssj->freq = (pssj->freq & 0xf00) | val; break; case 3: - pssj->freq = (pssj->freq & 0x0ff) | ((val & 0xf) << 8); + pssj->freq = (pssj->freq & 0x0ff) | ((val & 0xf) << 8); pssj->amplitude = val >> 4; break; } } -static uint8_t pssj_read(uint16_t port, void *p) +static uint8_t +pssj_read(uint16_t port, void *p) { - pssj_t *pssj = (pssj_t *)p; + pssj_t *pssj = (pssj_t *) p; - switch (port & 3) - { + switch (port & 3) { case 0: return (pssj->ctrl & ~0x88) | (pssj->irq ? 8 : 0); case 1: - switch (pssj->ctrl & 3) - { + switch (pssj->ctrl & 3) { case 0: /*Joystick*/ return 0; case 1: /*Sound channel*/ @@ -111,47 +109,39 @@ static uint8_t pssj_read(uint16_t port, void *p) return 0xff; } -static void pssj_update(pssj_t *pssj) +static void +pssj_update(pssj_t *pssj) { for (; pssj->pos < sound_pos_global; pssj->pos++) - pssj->buffer[pssj->pos] = (((int8_t)(pssj->dac_val ^ 0x80) * 0x20) * pssj->amplitude) / 15; + pssj->buffer[pssj->pos] = (((int8_t) (pssj->dac_val ^ 0x80) * 0x20) * pssj->amplitude) / 15; } -static void pssj_callback(void *p) +static void +pssj_callback(void *p) { - pssj_t *pssj = (pssj_t *)p; - int data; + pssj_t *pssj = (pssj_t *) p; + int data; pssj_update(pssj); - if (pssj->ctrl & 2) - { - if ((pssj->ctrl & 3) == 3) - { + if (pssj->ctrl & 2) { + if ((pssj->ctrl & 3) == 3) { data = dma_channel_read(1); - if (data != DMA_NODATA) - { + if (data != DMA_NODATA) { pssj->dac_val = data & 0xff; } - } - else - { + } else { data = dma_channel_write(1, 0x80); } - if ((data & DMA_OVER) && data != DMA_NODATA) - { - if (pssj->ctrl & 0x08) - { + if ((data & DMA_OVER) && data != DMA_NODATA) { + if (pssj->ctrl & 0x08) { pssj->irq = 1; pssj_update_irq(pssj); } } - } - else - { - switch (pssj->wave & 0xc0) - { + } else { + switch (pssj->wave & 0xc0) { case 0x00: /*Pulse*/ pssj->dac_val = (pssj->wave_pos > (pssj->pulse_width << 1)) ? 0xff : 0; break; @@ -171,13 +161,14 @@ static void pssj_callback(void *p) pssj->wave_pos = (pssj->wave_pos + 1) & 31; } - timer_advance_u64(&pssj->timer_count, (TIMER_USEC * (1000000.0 / 3579545.0) * (double)(pssj->freq ? pssj->freq : 0x400))); + timer_advance_u64(&pssj->timer_count, (TIMER_USEC * (1000000.0 / 3579545.0) * (double) (pssj->freq ? pssj->freq : 0x400))); } -static void pssj_get_buffer(int32_t *buffer, int len, void *p) +static void +pssj_get_buffer(int32_t *buffer, int len, void *p) { - pssj_t *pssj = (pssj_t *)p; - int c; + pssj_t *pssj = (pssj_t *) p; + int c; pssj_update(pssj); @@ -187,7 +178,8 @@ static void pssj_get_buffer(int32_t *buffer, int len, void *p) pssj->pos = 0; } -void *pssj_init(const device_t *info) +void * +pssj_init(const device_t *info) { pssj_t *pssj = malloc(sizeof(pssj_t)); memset(pssj, 0, sizeof(pssj_t)); @@ -201,7 +193,8 @@ void *pssj_init(const device_t *info) return pssj; } -void *pssj_1e0_init(const device_t *info) +void * +pssj_1e0_init(const device_t *info) { pssj_t *pssj = malloc(sizeof(pssj_t)); memset(pssj, 0, sizeof(pssj_t)); @@ -216,7 +209,8 @@ void *pssj_1e0_init(const device_t *info) } #if defined(DEV_BRANCH) && defined(USE_TANDY_ISA) -void *pssj_isa_init(const device_t *info) +void * +pssj_isa_init(const device_t *info) { pssj_t *pssj = malloc(sizeof(pssj_t)); memset(pssj, 0, sizeof(pssj_t)); @@ -233,41 +227,32 @@ void *pssj_isa_init(const device_t *info) } #endif -void pssj_close(void *p) +void +pssj_close(void *p) { - pssj_t *pssj = (pssj_t *)p; + pssj_t *pssj = (pssj_t *) p; free(pssj); } #if defined(DEV_BRANCH) && defined(USE_TANDY_ISA) -static const device_config_t pssj_isa_config[] = -{ +static const device_config_t pssj_isa_config[] = { +// clang-format off { "base", "Address", CONFIG_HEX16, "", 0x2C0, "", { 0 }, { - { - "0xC0", 0xC0 - }, - { - "0x1E0", 0x1E0 - }, - { - "0x2C0", 0x2C0 - }, - { - "" - } + { "0x0C0", 0x0C0 }, + { "0x1E0", 0x1E0 }, + { "0x2C0", 0x2C0 }, + { "" } } }, - { - "", "", -1 - } + { "", "", -1 } +// clang-format on }; #endif -const device_t pssj_device = -{ +const device_t pssj_device = { "Tandy PSSJ", "pssj", 0, @@ -280,8 +265,7 @@ const device_t pssj_device = NULL }; -const device_t pssj_1e0_device = -{ +const device_t pssj_1e0_device = { "Tandy PSSJ (port 1e0h)", "pssj_1e0", 0, @@ -295,8 +279,7 @@ const device_t pssj_1e0_device = }; #if defined(DEV_BRANCH) && defined(USE_TANDY_ISA) -const device_t pssj_isa_device = -{ +const device_t pssj_isa_device = { "Tandy PSSJ Clone", "pssj_isa", DEVICE_ISA, diff --git a/src/sound/snd_resid.cc b/src/sound/snd_resid.cc index 5ca5f6804..173039098 100644 --- a/src/sound/snd_resid.cc +++ b/src/sound/snd_resid.cc @@ -1,112 +1,114 @@ -#include -#include #include +#include #include +#include + #include "resid-fp/sid.h" #include <86box/plat.h> #include <86box/snd_resid.h> - -typedef struct psid_t -{ - /* resid sid implementation */ - SIDFP *sid; - int16_t last_sample; +typedef struct psid_t { + /* resid sid implementation */ + SIDFP *sid; + int16_t last_sample; } psid_t; - psid_t *psid; - -void *sid_init(void) +void * +sid_init(void) { -// psid_t *psid; - int c; - sampling_method method=SAMPLE_INTERPOLATE; - float cycles_per_sec = 14318180.0 / 16.0; - - psid = new psid_t; -// psid = (psid_t *)malloc(sizeof(sound_t)); - psid->sid = new SIDFP; - - psid->sid->set_chip_model(MOS8580FP); - - psid->sid->set_voice_nonlinearity(1.0f); - psid->sid->get_filter().set_distortion_properties(0.f, 0.f, 0.f); - psid->sid->get_filter().set_type4_properties(6.55f, 20.0f); + // psid_t *psid; + int c; + sampling_method method = SAMPLE_INTERPOLATE; + float cycles_per_sec = 14318180.0 / 16.0; - psid->sid->enable_filter(true); - psid->sid->enable_external_filter(true); + psid = new psid_t; + // psid = (psid_t *)malloc(sizeof(sound_t)); + psid->sid = new SIDFP; - psid->sid->reset(); - - for (c=0;c<32;c++) - psid->sid->write(c,0); - - if (!psid->sid->set_sampling_parameters((float)cycles_per_sec, method, - (float)48000, 0.9*48000.0/2.0)) - { - // printf("reSID failed!\n"); - } + psid->sid->set_chip_model(MOS8580FP); - psid->sid->set_chip_model(MOS6581FP); - psid->sid->set_voice_nonlinearity(0.96f); - psid->sid->get_filter().set_distortion_properties(3.7e-3f, 2048.f, 1.2e-4f); + psid->sid->set_voice_nonlinearity(1.0f); + psid->sid->get_filter().set_distortion_properties(0.f, 0.f, 0.f); + psid->sid->get_filter().set_type4_properties(6.55f, 20.0f); - psid->sid->input(0); - psid->sid->get_filter().set_type3_properties(1.33e6f, 2.2e9f, 1.0056f, 7e3f); + psid->sid->enable_filter(true); + psid->sid->enable_external_filter(true); - return (void *)psid; + psid->sid->reset(); + + for (c = 0; c < 32; c++) + psid->sid->write(c, 0); + + if (!psid->sid->set_sampling_parameters((float) cycles_per_sec, method, + (float) 48000, 0.9 * 48000.0 / 2.0)) { + // printf("reSID failed!\n"); + } + + psid->sid->set_chip_model(MOS6581FP); + psid->sid->set_voice_nonlinearity(0.96f); + psid->sid->get_filter().set_distortion_properties(3.7e-3f, 2048.f, 1.2e-4f); + + psid->sid->input(0); + psid->sid->get_filter().set_type3_properties(1.33e6f, 2.2e9f, 1.0056f, 7e3f); + + return (void *) psid; } -void sid_close(UNUSED(void *p)) +void +sid_close(UNUSED(void *p)) { -// psid_t *psid = (psid_t *)p; - delete psid->sid; -// free(psid); + // psid_t *psid = (psid_t *)p; + delete psid->sid; + // free(psid); } -void sid_reset(UNUSED(void *p)) +void +sid_reset(UNUSED(void *p)) { -// psid_t *psid = (psid_t *)p; - int c; - - psid->sid->reset(); + // psid_t *psid = (psid_t *)p; + int c; - for (c = 0; c < 32; c++) - psid->sid->write(c, 0); + psid->sid->reset(); + + for (c = 0; c < 32; c++) + psid->sid->write(c, 0); } - -uint8_t sid_read(uint16_t addr, UNUSED(void *p)) +uint8_t +sid_read(uint16_t addr, UNUSED(void *p)) { -// psid_t *psid = (psid_t *)p; - - return psid->sid->read(addr & 0x1f); -// return 0xFF; + // psid_t *psid = (psid_t *)p; + + return psid->sid->read(addr & 0x1f); + // return 0xFF; } -void sid_write(uint16_t addr, uint8_t val, UNUSED(void *p)) +void +sid_write(uint16_t addr, uint8_t val, UNUSED(void *p)) { -// psid_t *psid = (psid_t *)p; - - psid->sid->write(addr & 0x1f,val); + // psid_t *psid = (psid_t *)p; + + psid->sid->write(addr & 0x1f, val); } -#define CLOCK_DELTA(n) (int)(((14318180.0 * n) / 16.0) / 48000.0) +#define CLOCK_DELTA(n) (int) (((14318180.0 * n) / 16.0) / 48000.0) -static void fillbuf2(int& count, int16_t *buf, int len) +static void +fillbuf2(int &count, int16_t *buf, int len) { - int c; - c = psid->sid->clock(count, buf, len, 1); - if (!c) - *buf = psid->last_sample; - psid->last_sample = *buf; + int c; + c = psid->sid->clock(count, buf, len, 1); + if (!c) + *buf = psid->last_sample; + psid->last_sample = *buf; } -void sid_fillbuf(int16_t *buf, int len, UNUSED(void *p)) +void +sid_fillbuf(int16_t *buf, int len, UNUSED(void *p)) { -// psid_t *psid = (psid_t *)p; - int x = CLOCK_DELTA(len); - - fillbuf2(x, buf, len); + // psid_t *psid = (psid_t *)p; + int x = CLOCK_DELTA(len); + + fillbuf2(x, buf, len); } diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 56e34bbb9..fcf59788d 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -1,456 +1,448 @@ /* - * 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. * - * Sound Blaster emulation. + * Sound Blaster emulation. * * * - * Authors: Sarah Walker, - * Miran Grca, - * TheCollector1995, + * Authors: Sarah Walker, + * Miran Grca, + * TheCollector1995, * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. */ #include #include #include -#include #include +#include #include #define HAVE_STDARG_H + #include <86box/86box.h> +#include <86box/device.h> +#include <86box/filters.h> +#include <86box/gameport.h> +#include <86box/hdc.h> +#include <86box/isapnp.h> +#include <86box/hdc_ide.h> #include <86box/io.h> -#include <86box/timer.h> #include <86box/mca.h> #include <86box/mem.h> -#include <86box/rom.h> -#include <86box/device.h> -#include <86box/gameport.h> -#include <86box/pic.h> -#include <86box/sound.h> #include <86box/midi.h> -#include <86box/filters.h> -#include <86box/isapnp.h> +#include <86box/pic.h> +#include <86box/rom.h> +#include <86box/sound.h> +#include <86box/timer.h> #include <86box/snd_sb.h> -#include <86box/hdc.h> -#include <86box/hdc_ide.h> - /* 0 to 7 -> -14dB to 0dB i 2dB steps. 8 to 15 -> 0 to +14dB in 2dB steps. - Note that for positive dB values, this is not amplitude, it is amplitude-1. */ -static const double sb_bass_treble_4bits[]= { + Note that for positive dB values, this is not amplitude, it is amplitude - 1. */ +static const double sb_bass_treble_4bits[] = { 0.199526231, 0.25, 0.316227766, 0.398107170, 0.5, 0.63095734, 0.794328234, 1, 0, 0.25892541, 0.584893192, 1, 1.511886431, 2.16227766, 3, 4.011872336 }; /* Attenuation tables for the mixer. Max volume = 32767 in order to give 6dB of * headroom and avoid integer overflow */ -static const double sb_att_2dbstep_5bits[]= -{ +// clang-format off +static const double sb_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 const double sb_att_4dbstep_3bits[]= -{ +static const double sb_att_4dbstep_3bits[] = { 164.0, 2067.0, 3276.0, 5193.0, 8230.0, 13045.0, 20675.0, 32767.0 }; -static const double sb_att_7dbstep_2bits[]= -{ +static const double sb_att_7dbstep_2bits[] = { 164.0, 6537.0, 14637.0, 32767.0 }; +// clang-format on - -static const uint16_t sb_mcv_addr[8] = {0x200, 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x270}; -static const int sb_pro_mcv_irqs[4] = {7, 5, 3, 3}; - +static const uint16_t sb_mcv_addr[8] = { 0x200, 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x270 }; +static const int sb_pro_mcv_irqs[4] = { 7, 5, 3, 3 }; /* Each card in the SB16 family has a million variants, and it shows in the large variety of device IDs for the PnP models. This ROM was reconstructed in a best-effort basis around a pnpdump output log found in a forum. */ static uint8_t sb_16_pnp_rom[] = { + // clang-format off 0x0e, 0x8c, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, /* CTL0024, dummy checksum (filled in by isapnp_add_card) */ 0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */ 0x82, 0x11, 0x00, 'C', 'r', 'e', 'a', 't', 'i', 'v', 'e', ' ', 'S', 'B', '1', '6', ' ', 'P', 'n', 'P', /* ANSI identifier */ 0x16, 0x0e, 0x8c, 0x00, 0x31, 0x00, 0x65, /* logical device CTL0031, supports vendor-specific registers 0x39/0x3A/0x3D/0x3F */ - 0x82, 0x05, 0x00, 'A', 'u', 'd', 'i', 'o', /* ANSI identifier */ - 0x31, 0x00, /* start dependent functions, preferred */ - 0x22, 0x20, 0x00, /* IRQ 5 */ - 0x2a, 0x02, 0x08, /* DMA 1, compatibility, no count by word, count by byte, not bus master, 8-bit only */ - 0x2a, 0x20, 0x12, /* DMA 5, compatibility, count by word, no count by byte, not bus master, 16-bit only */ - 0x47, 0x01, 0x20, 0x02, 0x20, 0x02, 0x01, 0x10, /* I/O 0x220, decodes 16-bit, 1-byte alignment, 16 addresses */ - 0x47, 0x01, 0x30, 0x03, 0x30, 0x03, 0x01, 0x02, /* I/O 0x330, decodes 16-bit, 1-byte alignment, 2 addresses */ - 0x47, 0x01, 0x88, 0x03, 0x88, 0x03, 0x01, 0x04, /* I/O 0x388, decodes 16-bit, 1-byte alignment, 4 addresses */ - 0x31, 0x01, /* start dependent functions, acceptable */ - 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ - 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ - 0x2a, 0xe0, 0x12, /* DMA 5/6/7, compatibility, count by word, no count by byte, not bus master, 16-bit only */ - 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ - 0x47, 0x01, 0x00, 0x03, 0x30, 0x03, 0x30, 0x02, /* I/O 0x300-0x330, decodes 16-bit, 48-byte alignment, 2 addresses */ - 0x47, 0x01, 0x88, 0x03, 0x88, 0x03, 0x01, 0x04, /* I/O 0x388, decodes 16-bit, 1-byte alignment, 4 addresses */ - 0x31, 0x01, /* start dependent functions, acceptable */ - 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ - 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ - 0x2a, 0xe0, 0x12, /* DMA 5/6/7, compatibility, count by word, no count by byte, not bus master, 16-bit only */ - 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ - 0x47, 0x01, 0x00, 0x03, 0x30, 0x03, 0x30, 0x02, /* I/O 0x300-0x330, decodes 16-bit, 48-byte alignment, 2 addresses */ - 0x31, 0x02, /* start dependent functions, functional */ - 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ - 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ - 0x2a, 0xe0, 0x12, /* DMA 5/6/7, compatibility, count by word, no count by byte, not bus master, 16-bit only */ - 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ - 0x31, 0x02, /* start dependent functions, functional */ - 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ - 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ - 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ - 0x47, 0x01, 0x00, 0x03, 0x30, 0x03, 0x30, 0x02, /* I/O 0x300-0x330, decodes 16-bit, 48-byte alignment, 2 addresses */ - 0x47, 0x01, 0x88, 0x03, 0x88, 0x03, 0x01, 0x04, /* I/O 0x388, decodes 16-bit, 1-byte alignment, 4 addresses */ - 0x31, 0x02, /* start dependent functions, functional */ - 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ - 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ - 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ - 0x47, 0x01, 0x00, 0x03, 0x30, 0x03, 0x30, 0x02, /* I/O 0x300-0x330, decodes 16-bit, 48-byte alignment, 2 addresses */ - 0x31, 0x02, /* start dependent functions, functional */ - 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ - 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ - 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ - 0x38, /* end dependent functions */ + 0x82, 0x05, 0x00, 'A', 'u', 'd', 'i', 'o', /* ANSI identifier */ + 0x31, 0x00, /* start dependent functions, preferred */ + 0x22, 0x20, 0x00, /* IRQ 5 */ + 0x2a, 0x02, 0x08, /* DMA 1, compatibility, no count by word, count by byte, not bus master, 8-bit only */ + 0x2a, 0x20, 0x12, /* DMA 5, compatibility, count by word, no count by byte, not bus master, 16-bit only */ + 0x47, 0x01, 0x20, 0x02, 0x20, 0x02, 0x01, 0x10, /* I/O 0x220, decodes 16-bit, 1-byte alignment, 16 addresses */ + 0x47, 0x01, 0x30, 0x03, 0x30, 0x03, 0x01, 0x02, /* I/O 0x330, decodes 16-bit, 1-byte alignment, 2 addresses */ + 0x47, 0x01, 0x88, 0x03, 0x88, 0x03, 0x01, 0x04, /* I/O 0x388, decodes 16-bit, 1-byte alignment, 4 addresses */ + 0x31, 0x01, /* start dependent functions, acceptable */ + 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ + 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ + 0x2a, 0xe0, 0x12, /* DMA 5/6/7, compatibility, count by word, no count by byte, not bus master, 16-bit only */ + 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ + 0x47, 0x01, 0x00, 0x03, 0x30, 0x03, 0x30, 0x02, /* I/O 0x300-0x330, decodes 16-bit, 48-byte alignment, 2 addresses */ + 0x47, 0x01, 0x88, 0x03, 0x88, 0x03, 0x01, 0x04, /* I/O 0x388, decodes 16-bit, 1-byte alignment, 4 addresses */ + 0x31, 0x01, /* start dependent functions, acceptable */ + 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ + 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ + 0x2a, 0xe0, 0x12, /* DMA 5/6/7, compatibility, count by word, no count by byte, not bus master, 16-bit only */ + 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ + 0x47, 0x01, 0x00, 0x03, 0x30, 0x03, 0x30, 0x02, /* I/O 0x300-0x330, decodes 16-bit, 48-byte alignment, 2 addresses */ + 0x31, 0x02, /* start dependent functions, functional */ + 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ + 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ + 0x2a, 0xe0, 0x12, /* DMA 5/6/7, compatibility, count by word, no count by byte, not bus master, 16-bit only */ + 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ + 0x31, 0x02, /* start dependent functions, functional */ + 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ + 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ + 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ + 0x47, 0x01, 0x00, 0x03, 0x30, 0x03, 0x30, 0x02, /* I/O 0x300-0x330, decodes 16-bit, 48-byte alignment, 2 addresses */ + 0x47, 0x01, 0x88, 0x03, 0x88, 0x03, 0x01, 0x04, /* I/O 0x388, decodes 16-bit, 1-byte alignment, 4 addresses */ + 0x31, 0x02, /* start dependent functions, functional */ + 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ + 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ + 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ + 0x47, 0x01, 0x00, 0x03, 0x30, 0x03, 0x30, 0x02, /* I/O 0x300-0x330, decodes 16-bit, 48-byte alignment, 2 addresses */ + 0x31, 0x02, /* start dependent functions, functional */ + 0x22, 0xa0, 0x04, /* IRQ 5/7/10 */ + 0x2a, 0x0b, 0x08, /* DMA 0/1/3, compatibility, no count by word, count by byte, not bus master, 8-bit only */ + 0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */ + 0x38, /* end dependent functions */ 0x16, 0x0e, 0x8c, 0x20, 0x11, 0x00, 0x5a, /* logical device CTL2011, supports vendor-specific registers 0x39/0x3B/0x3C/0x3E */ - 0x1c, 0x41, 0xd0, 0x06, 0x00, /* compatible device PNP0600 */ - 0x82, 0x03, 0x00, 'I', 'D', 'E', /* ANSI identifier */ - 0x31, 0x00, /* start dependent functions, preferred */ - 0x22, 0x00, 0x04, /* IRQ 10 */ - 0x47, 0x01, 0x68, 0x01, 0x68, 0x01, 0x01, 0x08, /* I/O 0x168, decodes 16-bit, 1-byte alignment, 8 addresses */ - 0x47, 0x01, 0x6e, 0x03, 0x6e, 0x03, 0x01, 0x02, /* I/O 0x36E, decodes 16-bit, 1-byte alignment, 2 addresses */ - 0x31, 0x01, /* start dependent functions, acceptable */ - 0x22, 0x00, 0x08, /* IRQ 11 */ - 0x47, 0x01, 0xe8, 0x01, 0xe8, 0x01, 0x01, 0x08, /* I/O 0x1E8, decodes 16-bit, 1-byte alignment, 8 addresses */ - 0x47, 0x01, 0xee, 0x03, 0xee, 0x03, 0x01, 0x02, /* I/O 0x3EE, decodes 16-bit, 1-byte alignment, 2 addresses */ - 0x31, 0x01, /* start dependent functions, acceptable */ - 0x22, 0x00, 0x8c, /* IRQ 10/11/15 */ - 0x47, 0x01, 0x00, 0x01, 0xf8, 0x01, 0x08, 0x08, /* I/O 0x100-0x1F8, decodes 16-bit, 8-byte alignment, 8 addresses */ - 0x47, 0x01, 0x00, 0x03, 0xfe, 0x03, 0x02, 0x02, /* I/O 0x300-0x3FE, decodes 16-bit, 2-byte alignment, 2 addresses */ - 0x31, 0x02, /* start dependent functions, functional */ - 0x22, 0x00, 0x80, /* IRQ 15 */ - 0x47, 0x01, 0x70, 0x01, 0x70, 0x01, 0x01, 0x08, /* I/O 0x170, decodes 16-bit, 1-byte alignment, 8 addresses */ - 0x47, 0x01, 0x76, 0x03, 0x76, 0x03, 0x01, 0x02, /* I/O 0x376, decodes 16-bit, 1-byte alignment, 1 addresses */ - 0x38, /* end dependent functions */ + 0x1c, 0x41, 0xd0, 0x06, 0x00, /* compatible device PNP0600 */ + 0x82, 0x03, 0x00, 'I', 'D', 'E', /* ANSI identifier */ + 0x31, 0x00, /* start dependent functions, preferred */ + 0x22, 0x00, 0x04, /* IRQ 10 */ + 0x47, 0x01, 0x68, 0x01, 0x68, 0x01, 0x01, 0x08, /* I/O 0x168, decodes 16-bit, 1-byte alignment, 8 addresses */ + 0x47, 0x01, 0x6e, 0x03, 0x6e, 0x03, 0x01, 0x02, /* I/O 0x36E, decodes 16-bit, 1-byte alignment, 2 addresses */ + 0x31, 0x01, /* start dependent functions, acceptable */ + 0x22, 0x00, 0x08, /* IRQ 11 */ + 0x47, 0x01, 0xe8, 0x01, 0xe8, 0x01, 0x01, 0x08, /* I/O 0x1E8, decodes 16-bit, 1-byte alignment, 8 addresses */ + 0x47, 0x01, 0xee, 0x03, 0xee, 0x03, 0x01, 0x02, /* I/O 0x3EE, decodes 16-bit, 1-byte alignment, 2 addresses */ + 0x31, 0x01, /* start dependent functions, acceptable */ + 0x22, 0x00, 0x8c, /* IRQ 10/11/15 */ + 0x47, 0x01, 0x00, 0x01, 0xf8, 0x01, 0x08, 0x08, /* I/O 0x100-0x1F8, decodes 16-bit, 8-byte alignment, 8 addresses */ + 0x47, 0x01, 0x00, 0x03, 0xfe, 0x03, 0x02, 0x02, /* I/O 0x300-0x3FE, decodes 16-bit, 2-byte alignment, 2 addresses */ + 0x31, 0x02, /* start dependent functions, functional */ + 0x22, 0x00, 0x80, /* IRQ 15 */ + 0x47, 0x01, 0x70, 0x01, 0x70, 0x01, 0x01, 0x08, /* I/O 0x170, decodes 16-bit, 1-byte alignment, 8 addresses */ + 0x47, 0x01, 0x76, 0x03, 0x76, 0x03, 0x01, 0x02, /* I/O 0x376, decodes 16-bit, 1-byte alignment, 1 addresses */ + 0x38, /* end dependent functions */ 0x16, 0x41, 0xd0, 0xff, 0xff, 0x00, 0xda, /* logical device PNPFFFF, supports vendor-specific registers 0x38/0x39/0x3B/0x3C/0x3E */ - 0x82, 0x08, 0x00, 'R', 'e', 's', 'e', 'r', 'v', 'e', 'd', /* ANSI identifier */ - 0x47, 0x01, 0x00, 0x01, 0xf8, 0x03, 0x08, 0x01, /* I/O 0x100-0x3F8, decodes 16-bit, 8-byte alignment, 1 address */ + 0x82, 0x08, 0x00, 'R', 'e', 's', 'e', 'r', 'v', 'e', 'd', /* ANSI identifier */ + 0x47, 0x01, 0x00, 0x01, 0xf8, 0x03, 0x08, 0x01, /* I/O 0x100-0x3F8, decodes 16-bit, 8-byte alignment, 1 address */ 0x15, 0x0e, 0x8c, 0x70, 0x01, 0x00, /* logical device CTL7001 */ - 0x1c, 0x41, 0xd0, 0xb0, 0x2f, /* compatible device PNPB02F */ - 0x82, 0x04, 0x00, 'G', 'a', 'm', 'e', /* ANSI identifier */ - 0x47, 0x01, 0x00, 0x02, 0x00, 0x02, 0x01, 0x08, /* I/O 0x200, decodes 16-bit, 1-byte alignment, 8 addresses */ + 0x1c, 0x41, 0xd0, 0xb0, 0x2f, /* compatible device PNPB02F */ + 0x82, 0x04, 0x00, 'G', 'a', 'm', 'e', /* ANSI identifier */ + 0x47, 0x01, 0x00, 0x02, 0x00, 0x02, 0x01, 0x08, /* I/O 0x200, decodes 16-bit, 1-byte alignment, 8 addresses */ 0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */ + // clang-format on }; - #ifdef ENABLE_SB_LOG int sb_do_log = ENABLE_SB_LOG; - static void sb_log(const char *fmt, ...) { va_list ap; if (sb_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define sb_log(fmt, ...) +# define sb_log(fmt, ...) #endif - /* SB 1, 1.5, MCV, and 2 do not have a mixer, so signal is hardwired. */ static void sb_get_buffer_sb2(int32_t *buffer, int len, void *p) { - sb_t *sb = (sb_t *) p; + sb_t *sb = (sb_t *) p; sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; - int c; - double out_mono = 0.0, out_l = 0.0, out_r = 0.0; + int c; + double out_mono = 0.0, out_l = 0.0, out_r = 0.0; if (sb->opl_enabled) - opl2_update(&sb->opl); + opl2_update(&sb->opl); sb_dsp_update(&sb->dsp); if (sb->cms_enabled) - cms_update(&sb->cms); + cms_update(&sb->cms); for (c = 0; c < len * 2; c += 2) { - out_mono = 0.0; - out_l = 0.0; - out_r = 0.0; + out_mono = 0.0; + out_l = 0.0; + out_r = 0.0; - if (sb->opl_enabled) - out_mono = ((double) sb->opl.buffer[c]) * 0.7171630859375; + if (sb->opl_enabled) + out_mono = ((double) sb->opl.buffer[c]) * 0.7171630859375; - if (sb->cms_enabled) { - out_l += sb->cms.buffer[c]; - out_r += sb->cms.buffer[c + 1]; - } - out_l += out_mono; - out_r += out_mono; + if (sb->cms_enabled) { + out_l += sb->cms.buffer[c]; + out_r += sb->cms.buffer[c + 1]; + } + out_l += out_mono; + out_r += out_mono; - if (((sb->opl_enabled) || (sb->cms_enabled)) && sb->mixer_enabled) { - out_l *= mixer->fm; - out_r *= mixer->fm; - } + if (((sb->opl_enabled) || (sb->cms_enabled)) && sb->mixer_enabled) { + out_l *= mixer->fm; + out_r *= mixer->fm; + } - /* TODO: Recording: I assume it has direct mic and line in like SB2. - It is unclear from the docs if it has a filter, but it probably does. */ - /* TODO: Recording: Mic and line In with AGC. */ - if (sb->mixer_enabled) - out_mono = (sb_iir(0, 0, (double) sb->dsp.buffer[c]) * mixer->voice) / 3.9; - else - out_mono = (((sb_iir(0, 0, (double) sb->dsp.buffer[c]) / 1.3) * 65536.0) / 3.0) / 65536.0; - out_l += out_mono; - out_r += out_mono; + /* TODO: Recording: I assume it has direct mic and line in like SB2. + It is unclear from the docs if it has a filter, but it probably does. */ + /* TODO: Recording: Mic and line In with AGC. */ + if (sb->mixer_enabled) + out_mono = (sb_iir(0, 0, (double) sb->dsp.buffer[c]) * mixer->voice) / 3.9; + else + out_mono = (((sb_iir(0, 0, (double) sb->dsp.buffer[c]) / 1.3) * 65536.0) / 3.0) / 65536.0; + out_l += out_mono; + out_r += out_mono; - if (sb->mixer_enabled) { - out_l *= mixer->master; - out_r *= mixer->master; - } + if (sb->mixer_enabled) { + out_l *= mixer->master; + out_r *= mixer->master; + } - buffer[c] += (int32_t) out_l; - buffer[c + 1] += (int32_t) out_r; + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; } sb->pos = 0; if (sb->opl_enabled) - sb->opl.pos = 0; + sb->opl.pos = 0; sb->dsp.pos = 0; if (sb->cms_enabled) - sb->cms.pos = 0; + sb->cms.pos = 0; } - static void sb2_filter_cd_audio(int channel, double *buffer, void *p) { - sb_t *sb = (sb_t *)p; + sb_t *sb = (sb_t *) p; sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; - double c; + double c; if (sb->mixer_enabled) { - c = ((sb_iir(1, 0, *buffer) / 1.3) * mixer->cd) / 3.0; - *buffer = c * mixer->master; + c = ((sb_iir(1, 0, *buffer) / 1.3) * mixer->cd) / 3.0; + *buffer = c * mixer->master; } else { - c = (((sb_iir(1, 0, ((double) *buffer)) / 1.3) * 65536) / 3.0) / 65536.0; - *buffer = c; + c = (((sb_iir(1, 0, ((double) *buffer)) / 1.3) * 65536) / 3.0) / 65536.0; + *buffer = c; } } - void sb_get_buffer_sbpro(int32_t *buffer, int len, void *p) { - sb_t *sb = (sb_t *)p; + sb_t *sb = (sb_t *) p; sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; - int c; - double out_l = 0.0, out_r = 0.0; + int c; + double out_l = 0.0, out_r = 0.0; if (sb->opl_enabled) { - if (sb->dsp.sb_type == SBPRO) { - opl2_update(&sb->opl); - opl2_update(&sb->opl2); - } else - opl3_update(&sb->opl); + if (sb->dsp.sb_type == SBPRO) { + opl2_update(&sb->opl); + opl2_update(&sb->opl2); + } else + opl3_update(&sb->opl); } sb_dsp_update(&sb->dsp); for (c = 0; c < len * 2; c += 2) { - out_l = 0.0, out_r = 0.0; + out_l = 0.0, out_r = 0.0; - if (sb->opl_enabled) { - if (sb->dsp.sb_type == SBPRO) { - /* Two chips for LEFT and RIGHT channels. - Each chip stores data into the LEFT channel only (no sample alternating.) */ - out_l = (((double) sb->opl.buffer [c ]) * mixer->fm_l) * 0.7171630859375; - out_r = (((double) sb->opl2.buffer[c ]) * mixer->fm_r) * 0.7171630859375; - } else { - out_l = (((double) sb->opl.buffer[c ]) * mixer->fm_l) * 0.7171630859375; - out_r = (((double) sb->opl.buffer[c + 1]) * mixer->fm_r) * 0.7171630859375; - } - } + if (sb->opl_enabled) { + if (sb->dsp.sb_type == SBPRO) { + /* Two chips for LEFT and RIGHT channels. + Each chip stores data into the LEFT channel only (no sample alternating.) */ + out_l = (((double) sb->opl.buffer[c]) * mixer->fm_l) * 0.7171630859375; + out_r = (((double) sb->opl2.buffer[c]) * mixer->fm_r) * 0.7171630859375; + } else { + out_l = (((double) sb->opl.buffer[c]) * mixer->fm_l) * 0.7171630859375; + out_r = (((double) sb->opl.buffer[c + 1]) * mixer->fm_r) * 0.7171630859375; + } + } - /* TODO: Implement the stereo switch on the mixer instead of on the dsp? */ - if (mixer->output_filter) { - out_l += (sb_iir(0, 0, (double) sb->dsp.buffer[c]) * mixer->voice_l) / 3.9; - out_r += (sb_iir(0, 1, (double) sb->dsp.buffer[c + 1]) * mixer->voice_r) / 3.9; - } else { - out_l += (sb->dsp.buffer[c] * mixer->voice_l) / 3.0; - out_r += (sb->dsp.buffer[c + 1] * mixer->voice_r) / 3.0; - } - /* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */ + /* TODO: Implement the stereo switch on the mixer instead of on the dsp? */ + if (mixer->output_filter) { + out_l += (sb_iir(0, 0, (double) sb->dsp.buffer[c]) * mixer->voice_l) / 3.9; + out_r += (sb_iir(0, 1, (double) sb->dsp.buffer[c + 1]) * mixer->voice_r) / 3.9; + } else { + out_l += (sb->dsp.buffer[c] * mixer->voice_l) / 3.0; + out_r += (sb->dsp.buffer[c + 1] * mixer->voice_r) / 3.0; + } - out_l *= mixer->master_l; - out_r *= mixer->master_r; + /* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */ + out_l *= mixer->master_l; + out_r *= mixer->master_r; - buffer[c] += (int32_t) out_l; - buffer[c + 1] += (int32_t) out_r; + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; } sb->pos = 0; if (sb->opl_enabled) { - sb->opl.pos = 0; - if (sb->dsp.sb_type != SBPRO) - sb->opl2.pos = 0; + sb->opl.pos = 0; + if (sb->dsp.sb_type != SBPRO) + sb->opl2.pos = 0; } sb->dsp.pos = 0; } - void sbpro_filter_cd_audio(int channel, double *buffer, void *p) { - sb_t *sb = (sb_t *)p; + sb_t *sb = (sb_t *) p; sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; - double c; - double cd = channel ? mixer->cd_r : mixer->cd_l; - double master = channel ? mixer->master_r : mixer->master_l; + double c; + double cd = channel ? mixer->cd_r : mixer->cd_l; + double master = channel ? mixer->master_r : mixer->master_l; if (mixer->output_filter) - c = (sb_iir(1, channel, *buffer) * cd) / 3.9; + c = (sb_iir(1, channel, *buffer) * cd) / 3.9; else - c = (*buffer * cd) / 3.0; + c = (*buffer * cd) / 3.0; *buffer = c * master; } - static void sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *p) { - sb_t *sb = (sb_t *)p; + sb_t *sb = (sb_t *) p; sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - int c, dsp_rec_pos = sb->dsp.record_pos_write; - int c_emu8k, c_record; - int32_t in_l, in_r; - double out_l = 0.0, out_r = 0.0; - double bass_treble; + int c, dsp_rec_pos = sb->dsp.record_pos_write; + int c_emu8k, c_record; + int32_t in_l, in_r; + double out_l = 0.0, out_r = 0.0; + double bass_treble; if (sb->opl_enabled) - opl3_update(&sb->opl); + opl3_update(&sb->opl); if (sb->dsp.sb_type > SB16) - emu8k_update(&sb->emu8k); + emu8k_update(&sb->emu8k); sb_dsp_update(&sb->dsp); for (c = 0; c < len * 2; c += 2) { - out_l = 0.0, out_r = 0.0; + out_l = 0.0, out_r = 0.0; - if (sb->dsp.sb_type > SB16) - c_emu8k = ((((c / 2) * 44100) / 48000) * 2); + if (sb->dsp.sb_type > SB16) + c_emu8k = ((((c / 2) * 44100) / 48000) * 2); - if (sb->opl_enabled) { - out_l = ((double) sb->opl.buffer[c ]) * mixer->fm_l * 0.7171630859375; - out_r = ((double) sb->opl.buffer[c + 1]) * mixer->fm_r * 0.7171630859375; - } + if (sb->opl_enabled) { + out_l = ((double) sb->opl.buffer[c]) * mixer->fm_l * 0.7171630859375; + out_r = ((double) sb->opl.buffer[c + 1]) * mixer->fm_r * 0.7171630859375; + } - if (sb->dsp.sb_type > SB16) { - out_l += (((double) sb->emu8k.buffer[c_emu8k]) * mixer->fm_l); - out_r += (((double) sb->emu8k.buffer[c_emu8k + 1]) * mixer->fm_r); - } + if (sb->dsp.sb_type > SB16) { + out_l += (((double) sb->emu8k.buffer[c_emu8k]) * mixer->fm_l); + out_r += (((double) sb->emu8k.buffer[c_emu8k + 1]) * mixer->fm_r); + } - /* TODO: Multi-recording mic with agc/+20db, CD, and line in with channel inversion */ - in_l = (mixer->input_selector_left & INPUT_MIDI_L) ? ((int32_t) out_l) : - 0 + (mixer->input_selector_left & INPUT_MIDI_R) ? ((int32_t) out_r) : 0; - in_r = (mixer->input_selector_right & INPUT_MIDI_L) ? ((int32_t) out_l) : - 0 + (mixer->input_selector_right & INPUT_MIDI_R) ? ((int32_t) out_r) : 0; + /* TODO: Multi-recording mic with agc/+20db, CD, and line in with channel inversion */ + in_l = (mixer->input_selector_left & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_left & INPUT_MIDI_R) ? ((int32_t) out_r) + : 0; + in_r = (mixer->input_selector_right & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_right & INPUT_MIDI_R) ? ((int32_t) out_r) + : 0; - /* We divide by 3 to get the volume down to normal. */ - out_l += (low_fir_sb16(0, 0, (double) sb->dsp.buffer[c]) * mixer->voice_l) / 3.0; - out_r += (low_fir_sb16(0, 1, (double) sb->dsp.buffer[c + 1]) * mixer->voice_r) / 3.0; + /* We divide by 3 to get the volume down to normal. */ + out_l += (low_fir_sb16(0, 0, (double) sb->dsp.buffer[c]) * mixer->voice_l) / 3.0; + out_r += (low_fir_sb16(0, 1, (double) sb->dsp.buffer[c + 1]) * mixer->voice_r) / 3.0; - out_l *= mixer->master_l; - out_r *= mixer->master_r; + out_l *= mixer->master_l; + out_r *= mixer->master_r; - /* This is not exactly how one does bass/treble controls, but the end result is like it. - A better implementation would reduce the CPU usage. */ - if (mixer->bass_l != 8) { - bass_treble = sb_bass_treble_4bits[mixer->bass_l]; + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (mixer->bass_l != 8) { + bass_treble = sb_bass_treble_4bits[mixer->bass_l]; - if (mixer->bass_l > 8) - out_l += (low_iir(0, 0, out_l) * bass_treble); - else if (mixer->bass_l < 8) - out_l = ((out_l) * bass_treble + low_cut_iir(0, 0, out_l) * (1.0 - bass_treble)); - } + if (mixer->bass_l > 8) + out_l += (low_iir(0, 0, out_l) * bass_treble); + else if (mixer->bass_l < 8) + out_l = ((out_l) *bass_treble + low_cut_iir(0, 0, out_l) * (1.0 - bass_treble)); + } - if (mixer->bass_r != 8) { - bass_treble = sb_bass_treble_4bits[mixer->bass_r]; + if (mixer->bass_r != 8) { + bass_treble = sb_bass_treble_4bits[mixer->bass_r]; - if (mixer->bass_r > 8) - out_r += (low_iir(0, 1, out_r) * bass_treble); - else if (mixer->bass_r < 8) - out_r = ((out_r) * bass_treble + low_cut_iir(0, 1, out_r) * (1.0 - bass_treble)); - } + if (mixer->bass_r > 8) + out_r += (low_iir(0, 1, out_r) * bass_treble); + else if (mixer->bass_r < 8) + out_r = ((out_r) *bass_treble + low_cut_iir(0, 1, out_r) * (1.0 - bass_treble)); + } - if (mixer->treble_l != 8) { - bass_treble = sb_bass_treble_4bits[mixer->treble_l]; + if (mixer->treble_l != 8) { + bass_treble = sb_bass_treble_4bits[mixer->treble_l]; - if (mixer->treble_l > 8) - out_l += (high_iir(0, 0, out_l) * bass_treble); - else if (mixer->treble_l < 8) - out_l = ((out_l) * bass_treble + high_cut_iir(0, 0, out_l) * (1.0 - bass_treble)); - } + if (mixer->treble_l > 8) + out_l += (high_iir(0, 0, out_l) * bass_treble); + else if (mixer->treble_l < 8) + out_l = ((out_l) *bass_treble + high_cut_iir(0, 0, out_l) * (1.0 - bass_treble)); + } - if (mixer->treble_r != 8) { - bass_treble = sb_bass_treble_4bits[mixer->treble_r]; + if (mixer->treble_r != 8) { + bass_treble = sb_bass_treble_4bits[mixer->treble_r]; - if (mixer->treble_r > 8) - out_r += (high_iir(0, 1, out_r) * bass_treble); - else if (mixer->treble_r < 8) - out_r = ((out_l) * bass_treble + high_cut_iir(0, 1, out_r) * (1.0 - bass_treble)); - } + if (mixer->treble_r > 8) + out_r += (high_iir(0, 1, out_r) * bass_treble); + else if (mixer->treble_r < 8) + out_r = ((out_l) *bass_treble + high_cut_iir(0, 1, out_r) * (1.0 - bass_treble)); + } - if (sb->dsp.sb_enable_i) { - c_record = dsp_rec_pos + ((c * sb->dsp.sb_freq) / 48000); - in_l <<= mixer->input_gain_L; - in_r <<= mixer->input_gain_R; + if (sb->dsp.sb_enable_i) { + c_record = dsp_rec_pos + ((c * sb->dsp.sb_freq) / 48000); + in_l <<= mixer->input_gain_L; + in_r <<= mixer->input_gain_R; - /* Clip signal */ - if (in_l < -32768) - in_l = -32768; - else if (in_l > 32767) - in_l = 32767; + /* Clip signal */ + if (in_l < -32768) + in_l = -32768; + else if (in_l > 32767) + in_l = 32767; - if (in_r < -32768) - in_r = -32768; - else if (in_r > 32767) - in_r = 32767; + if (in_r < -32768) + in_r = -32768; + else if (in_r > 32767) + in_r = 32767; - sb->dsp.record_buffer[c_record & 0xffff] = in_l; - sb->dsp.record_buffer[(c_record+1) & 0xffff] = in_r; - } + sb->dsp.record_buffer[c_record & 0xffff] = in_l; + sb->dsp.record_buffer[(c_record + 1) & 0xffff] = in_r; + } - buffer[c] += (int32_t) (out_l * mixer->output_gain_L); - buffer[c + 1] += (int32_t) (out_r * mixer->output_gain_R); + buffer[c] += (int32_t) (out_l * mixer->output_gain_L); + buffer[c + 1] += (int32_t) (out_r * mixer->output_gain_R); } sb->dsp.record_pos_write += ((len * sb->dsp.sb_freq) / 24000); @@ -459,562 +451,603 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *p) sb->pos = 0; if (sb->opl_enabled) - sb->opl.pos = 0; + sb->opl.pos = 0; sb->dsp.pos = 0; if (sb->dsp.sb_type > SB16) - sb->emu8k.pos = 0; + sb->emu8k.pos = 0; } - static void sb16_awe32_filter_cd_audio(int channel, double *buffer, void *p) { - sb_t *sb = (sb_t *)p; + sb_t *sb = (sb_t *) p; sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - double c; - double cd = channel ? mixer->cd_r : mixer->cd_l /* / 3.0 */; - double master = channel ? mixer->master_r : mixer->master_l; - int32_t bass = channel ? mixer->bass_r : mixer->bass_l; - int32_t treble = channel ? mixer->treble_r : mixer->treble_l; - double bass_treble; - double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L); + double c; + double cd = channel ? mixer->cd_r : mixer->cd_l /* / 3.0 */; + double master = channel ? mixer->master_r : mixer->master_l; + int32_t bass = channel ? mixer->bass_r : mixer->bass_l; + int32_t treble = channel ? mixer->treble_r : mixer->treble_l; + double bass_treble; + double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L); - c = (low_fir_sb16(1, channel, *buffer) * cd) / 3.0; + c = (low_fir_sb16(1, channel, *buffer) * cd) / 3.0; c *= master; /* This is not exactly how one does bass/treble controls, but the end result is like it. A better implementation would reduce the CPU usage. */ if (bass != 8) { - bass_treble = sb_bass_treble_4bits[bass]; + bass_treble = sb_bass_treble_4bits[bass]; - if (bass > 8) - c += (low_iir(1, channel, c) * bass_treble); - else if (bass < 8) - c = (c * bass_treble + low_cut_iir(1, channel, c) * (1.0 - bass_treble)); + if (bass > 8) + c += (low_iir(1, channel, c) * bass_treble); + else if (bass < 8) + c = (c * bass_treble + low_cut_iir(1, channel, c) * (1.0 - bass_treble)); } if (treble != 8) { - bass_treble = sb_bass_treble_4bits[treble]; + bass_treble = sb_bass_treble_4bits[treble]; - if (treble > 8) - c += (high_iir(1, channel, c) * bass_treble); - else if (treble < 8) - c = (c * bass_treble + high_cut_iir(1, channel, c) * (1.0 - bass_treble)); + if (treble > 8) + c += (high_iir(1, channel, c) * bass_treble); + else if (treble < 8) + c = (c * bass_treble + high_cut_iir(1, channel, c) * (1.0 - bass_treble)); } *buffer = c * output_gain; } - void sb_ct1335_mixer_write(uint16_t addr, uint8_t val, void *p) { - sb_t *sb = (sb_t *)p; + sb_t *sb = (sb_t *) p; sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; if (!(addr & 1)) { - mixer->index = val; - mixer->regs[0x01] = val; + mixer->index = val; + mixer->regs[0x01] = val; } else { - if (mixer->index == 0) { - /* Reset */ - mixer->regs[0x02] = mixer->regs[0x06] = 0x08; - mixer->regs[0x08] = 0x00; - /* Changed default from -46dB to 0dB*/ - mixer->regs[0x0a] = 0x06; - } else { - mixer->regs[mixer->index] = val; - switch (mixer->index) { - case 0x00: case 0x02: case 0x06: case 0x08: case 0x0a: - break; + if (mixer->index == 0) { + /* Reset */ + mixer->regs[0x02] = mixer->regs[0x06] = 0x08; + mixer->regs[0x08] = 0x00; + /* Changed default from -46dB to 0dB*/ + mixer->regs[0x0a] = 0x06; + } else { + mixer->regs[mixer->index] = val; + switch (mixer->index) { + case 0x00: + case 0x02: + case 0x06: + case 0x08: + case 0x0a: + break; - default: - sb_log("sb_ct1335: Unknown register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); - break; - } - } + default: + sb_log("sb_ct1335: Unknown register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + break; + } + } - mixer->master = sb_att_4dbstep_3bits[(mixer->regs[0x02] >> 1) & 0x7] / 32768.0; - mixer->fm = sb_att_4dbstep_3bits[(mixer->regs[0x06] >> 1) & 0x7] / 32768.0; - mixer->cd = sb_att_4dbstep_3bits[(mixer->regs[0x08] >> 1) & 0x7] / 32768.0; - mixer->voice = sb_att_7dbstep_2bits[(mixer->regs[0x0a] >> 1) & 0x3] / 32768.0; + mixer->master = sb_att_4dbstep_3bits[(mixer->regs[0x02] >> 1) & 0x7] / 32768.0; + mixer->fm = sb_att_4dbstep_3bits[(mixer->regs[0x06] >> 1) & 0x7] / 32768.0; + mixer->cd = sb_att_4dbstep_3bits[(mixer->regs[0x08] >> 1) & 0x7] / 32768.0; + mixer->voice = sb_att_7dbstep_2bits[(mixer->regs[0x0a] >> 1) & 0x3] / 32768.0; } } - uint8_t sb_ct1335_mixer_read(uint16_t addr, void *p) { - sb_t *sb = (sb_t *)p; + sb_t *sb = (sb_t *) p; sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; if (!(addr & 1)) - return mixer->index; + return mixer->index; switch (mixer->index) { - case 0x00: case 0x02: case 0x06: case 0x08: case 0x0A: - return mixer->regs[mixer->index]; - default: - sb_log("sb_ct1335: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); - break; + case 0x00: + case 0x02: + case 0x06: + case 0x08: + case 0x0A: + return mixer->regs[mixer->index]; + default: + sb_log("sb_ct1335: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + break; } return 0xff; } - void -sb_ct1335_mixer_reset(sb_t* sb) +sb_ct1335_mixer_reset(sb_t *sb) { sb_ct1335_mixer_write(0x254, 0, sb); sb_ct1335_mixer_write(0x255, 0, sb); } - void sb_ct1345_mixer_write(uint16_t addr, uint8_t val, void *p) { - sb_t *sb = (sb_t *)p; + sb_t *sb = (sb_t *) p; sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; if (!(addr & 1)) { - mixer->index = val; - mixer->regs[0x01] = val; + mixer->index = val; + mixer->regs[0x01] = val; } else { - if (mixer->index == 0) { - /* Reset */ - mixer->regs[0x0a] = mixer->regs[0x0c] = 0x00; - mixer->regs[0x0e] = 0x00; - /* Changed default from -11dB to 0dB */ - mixer->regs[0x04] = mixer->regs[0x22] = 0xee; - mixer->regs[0x26] = mixer->regs[0x28] = 0xee; - mixer->regs[0x2e] = 0x00; - sb_dsp_set_stereo(&sb->dsp, mixer->regs[0x0e] & 2); - } else { - mixer->regs[mixer->index] = val; + if (mixer->index == 0) { + /* Reset */ + mixer->regs[0x0a] = mixer->regs[0x0c] = 0x00; + mixer->regs[0x0e] = 0x00; + /* Changed default from -11dB to 0dB */ + mixer->regs[0x04] = mixer->regs[0x22] = 0xee; + mixer->regs[0x26] = mixer->regs[0x28] = 0xee; + mixer->regs[0x2e] = 0x00; + sb_dsp_set_stereo(&sb->dsp, mixer->regs[0x0e] & 2); + } else { + mixer->regs[mixer->index] = val; - switch (mixer->index) { - /* Compatibility: chain registers 0x02 and 0x22 as well as 0x06 and 0x26 */ - case 0x02: case 0x06: case 0x08: - mixer->regs[mixer->index + 0x20] = ((val & 0xe) << 4) | (val&0xe); - break; + switch (mixer->index) { + /* Compatibility: chain registers 0x02 and 0x22 as well as 0x06 and 0x26 */ + case 0x02: + case 0x06: + case 0x08: + mixer->regs[mixer->index + 0x20] = ((val & 0xe) << 4) | (val & 0xe); + break; - case 0x22: case 0x26: case 0x28: - mixer->regs[mixer->index - 0x20] = (val & 0xe); - break; + case 0x22: + case 0x26: + case 0x28: + mixer->regs[mixer->index - 0x20] = (val & 0xe); + break; - /* More compatibility: - SoundBlaster Pro selects register 020h for 030h, 022h for 032h, - 026h for 036h, and 028h for 038h. */ - case 0x30: case 0x32: case 0x36: case 0x38: - mixer->regs[mixer->index - 0x10] = (val & 0xee); - break; + /* More compatibility: + SoundBlaster Pro selects register 020h for 030h, 022h for 032h, + 026h for 036h, and 028h for 038h. */ + case 0x30: + case 0x32: + case 0x36: + case 0x38: + mixer->regs[mixer->index - 0x10] = (val & 0xee); + break; - case 0x00: case 0x04: case 0x0a: case 0x0c: case 0x0e: - case 0x2e: - break; + case 0x00: + case 0x04: + case 0x0a: + case 0x0c: + case 0x0e: + case 0x2e: + break; - default: - sb_log("sb_ct1345: Unknown register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); - break; - } - } + default: + sb_log("sb_ct1345: Unknown register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + break; + } + } - mixer->voice_l = sb_att_4dbstep_3bits[(mixer->regs[0x04] >> 5) & 0x7] / 32768.0; - mixer->voice_r = sb_att_4dbstep_3bits[(mixer->regs[0x04] >> 1) & 0x7] / 32768.0; - mixer->master_l = sb_att_4dbstep_3bits[(mixer->regs[0x22] >> 5) & 0x7] / 32768.0; - mixer->master_r = sb_att_4dbstep_3bits[(mixer->regs[0x22] >> 1) & 0x7] / 32768.0; - mixer->fm_l = sb_att_4dbstep_3bits[(mixer->regs[0x26] >> 5) & 0x7] / 32768.0; - mixer->fm_r = sb_att_4dbstep_3bits[(mixer->regs[0x26] >> 1) & 0x7] / 32768.0; - mixer->cd_l = sb_att_4dbstep_3bits[(mixer->regs[0x28] >> 5) & 0x7] / 32768.0; - mixer->cd_r = sb_att_4dbstep_3bits[(mixer->regs[0x28] >> 1) & 0x7] / 32768.0; - mixer->line_l = sb_att_4dbstep_3bits[(mixer->regs[0x2e] >> 5) & 0x7] / 32768.0; - mixer->line_r = sb_att_4dbstep_3bits[(mixer->regs[0x2e] >> 1) & 0x7] / 32768.0; + mixer->voice_l = sb_att_4dbstep_3bits[(mixer->regs[0x04] >> 5) & 0x7] / 32768.0; + mixer->voice_r = sb_att_4dbstep_3bits[(mixer->regs[0x04] >> 1) & 0x7] / 32768.0; + mixer->master_l = sb_att_4dbstep_3bits[(mixer->regs[0x22] >> 5) & 0x7] / 32768.0; + mixer->master_r = sb_att_4dbstep_3bits[(mixer->regs[0x22] >> 1) & 0x7] / 32768.0; + mixer->fm_l = sb_att_4dbstep_3bits[(mixer->regs[0x26] >> 5) & 0x7] / 32768.0; + mixer->fm_r = sb_att_4dbstep_3bits[(mixer->regs[0x26] >> 1) & 0x7] / 32768.0; + mixer->cd_l = sb_att_4dbstep_3bits[(mixer->regs[0x28] >> 5) & 0x7] / 32768.0; + mixer->cd_r = sb_att_4dbstep_3bits[(mixer->regs[0x28] >> 1) & 0x7] / 32768.0; + mixer->line_l = sb_att_4dbstep_3bits[(mixer->regs[0x2e] >> 5) & 0x7] / 32768.0; + mixer->line_r = sb_att_4dbstep_3bits[(mixer->regs[0x2e] >> 1) & 0x7] / 32768.0; - mixer->mic = sb_att_7dbstep_2bits[(mixer->regs[0x0a] >> 1) & 0x3] / 32768.0; + mixer->mic = sb_att_7dbstep_2bits[(mixer->regs[0x0a] >> 1) & 0x3] / 32768.0; - mixer->output_filter = !(mixer->regs[0xe] & 0x20); - mixer->input_filter = !(mixer->regs[0xc] & 0x20); - mixer->in_filter_freq = ((mixer->regs[0xc] & 0x8) == 0) ? 3200 : 8800; - mixer->stereo = mixer->regs[0xe] & 2; - if (mixer->index == 0xe) - sb_dsp_set_stereo(&sb->dsp, val & 2); + mixer->output_filter = !(mixer->regs[0xe] & 0x20); + mixer->input_filter = !(mixer->regs[0xc] & 0x20); + mixer->in_filter_freq = ((mixer->regs[0xc] & 0x8) == 0) ? 3200 : 8800; + mixer->stereo = mixer->regs[0xe] & 2; + if (mixer->index == 0xe) + sb_dsp_set_stereo(&sb->dsp, val & 2); - switch ((mixer->regs[0xc] & 6)) { - case 2: - mixer->input_selector = INPUT_CD_L | INPUT_CD_R; - break; - case 6: - mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; - break; - default: - mixer->input_selector = INPUT_MIC; - break; - } + switch ((mixer->regs[0xc] & 6)) { + case 2: + mixer->input_selector = INPUT_CD_L | INPUT_CD_R; + break; + case 6: + mixer->input_selector = INPUT_LINE_L | INPUT_LINE_R; + break; + default: + mixer->input_selector = INPUT_MIC; + break; + } - /* TODO: pcspeaker volume? Or is it not worth? */ + /* TODO: pcspeaker volume? Or is it not worth? */ } } - uint8_t sb_ct1345_mixer_read(uint16_t addr, void *p) { - sb_t *sb = (sb_t *)p; + sb_t *sb = (sb_t *) p; sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; if (!(addr & 1)) - return mixer->index; + return mixer->index; switch (mixer->index) { - case 0x00: case 0x04: case 0x0a: case 0x0c: case 0x0e: - case 0x22: case 0x26: case 0x28: case 0x2e: case 0x02: case 0x06: - case 0x30: case 0x32: case 0x36: case 0x38: - return mixer->regs[mixer->index]; + case 0x00: + case 0x04: + case 0x0a: + case 0x0c: + case 0x0e: + case 0x22: + case 0x26: + case 0x28: + case 0x2e: + case 0x02: + case 0x06: + case 0x30: + case 0x32: + case 0x36: + case 0x38: + return mixer->regs[mixer->index]; - default: - sb_log("sb_ct1345: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); - break; + default: + sb_log("sb_ct1345: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + break; } return 0xff; } - void -sb_ct1345_mixer_reset(sb_t* sb) +sb_ct1345_mixer_reset(sb_t *sb) { sb_ct1345_mixer_write(4, 0, sb); sb_ct1345_mixer_write(5, 0, sb); } - static void sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p) { - sb_t *sb = (sb_t *) p; + sb_t *sb = (sb_t *) p; sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; if (!(addr & 1)) - mixer->index = val; + mixer->index = val; else { - /* DESCRIPTION: - Contains previously selected register value. Mixer Data Register value. - NOTES: - SoundBlaster 16 sets bit 7 if previous mixer index invalid. - Status bytes initially 080h on startup for all but level bytes (SB16). */ + /* DESCRIPTION: + Contains previously selected register value. Mixer Data Register value. + NOTES: + SoundBlaster 16 sets bit 7 if previous mixer index invalid. + Status bytes initially 080h on startup for all but level bytes (SB16). */ - if (mixer->index == 0) { - /* Reset: Changed defaults from -14dB to 0dB */ + if (mixer->index == 0) { + /* Reset: Changed defaults from -14dB to 0dB */ - mixer->regs[0x30] = mixer->regs[0x31] = 0xf8; - mixer->regs[0x32] = mixer->regs[0x33] = 0xf8; - mixer->regs[0x34] = mixer->regs[0x35] = 0xf8; - mixer->regs[0x36] = mixer->regs[0x37] = 0xf8; - mixer->regs[0x38] = mixer->regs[0x39] = 0x00; + mixer->regs[0x30] = mixer->regs[0x31] = 0xf8; + mixer->regs[0x32] = mixer->regs[0x33] = 0xf8; + mixer->regs[0x34] = mixer->regs[0x35] = 0xf8; + mixer->regs[0x36] = mixer->regs[0x37] = 0xf8; + mixer->regs[0x38] = mixer->regs[0x39] = 0x00; - mixer->regs[0x3a] = mixer->regs[0x3b] = 0x00; + mixer->regs[0x3a] = mixer->regs[0x3b] = 0x00; - mixer->regs[0x3c] = (OUTPUT_MIC | OUTPUT_CD_R | OUTPUT_CD_L | OUTPUT_LINE_R | OUTPUT_LINE_L); - mixer->regs[0x3d] = (INPUT_MIC | INPUT_CD_L | INPUT_LINE_L | INPUT_MIDI_L); - mixer->regs[0x3e] = (INPUT_MIC | INPUT_CD_R | INPUT_LINE_R | INPUT_MIDI_R); + mixer->regs[0x3c] = (OUTPUT_MIC | OUTPUT_CD_R | OUTPUT_CD_L | OUTPUT_LINE_R | OUTPUT_LINE_L); + mixer->regs[0x3d] = (INPUT_MIC | INPUT_CD_L | INPUT_LINE_L | INPUT_MIDI_L); + mixer->regs[0x3e] = (INPUT_MIC | INPUT_CD_R | INPUT_LINE_R | INPUT_MIDI_R); - mixer->regs[0x3f] = mixer->regs[0x40] = 0x00; - mixer->regs[0x41] = mixer->regs[0x42] = 0x00; + mixer->regs[0x3f] = mixer->regs[0x40] = 0x00; + mixer->regs[0x41] = mixer->regs[0x42] = 0x00; - mixer->regs[0x44] = mixer->regs[0x45] = 0x80; - mixer->regs[0x46] = mixer->regs[0x47] = 0x80; + mixer->regs[0x44] = mixer->regs[0x45] = 0x80; + mixer->regs[0x46] = mixer->regs[0x47] = 0x80; - mixer->regs[0x43] = 0x00; + mixer->regs[0x43] = 0x00; - mixer->regs[0x83] = 0xff; - sb->dsp.sb_irqm8 = 0; - sb->dsp.sb_irqm16 = 0; - sb->dsp.sb_irqm401 = 0; - } else - mixer->regs[mixer->index] = val; + mixer->regs[0x83] = 0xff; + sb->dsp.sb_irqm8 = 0; + sb->dsp.sb_irqm16 = 0; + sb->dsp.sb_irqm401 = 0; + } else + mixer->regs[mixer->index] = val; - switch (mixer->index) { - /* SB1/2 compatibility? */ - case 0x02: - mixer->regs[0x30] = ((mixer->regs[0x02] & 0xf) << 4) | 0x8; - mixer->regs[0x31] = ((mixer->regs[0x02] & 0xf) << 4) | 0x8; - break; - case 0x06: - mixer->regs[0x34] = ((mixer->regs[0x06] & 0xf) << 4) | 0x8; - mixer->regs[0x35] = ((mixer->regs[0x06] & 0xf) << 4) | 0x8; - break; - case 0x08: - mixer->regs[0x36] = ((mixer->regs[0x08] & 0xf) << 4) | 0x8; - mixer->regs[0x37] = ((mixer->regs[0x08] & 0xf) << 4) | 0x8; - break; - /* SBPro compatibility. Copy values to sb16 registers. */ - case 0x22: - mixer->regs[0x30] = (mixer->regs[0x22] & 0xf0) | 0x8; - mixer->regs[0x31] = ((mixer->regs[0x22] & 0xf) << 4) | 0x8; - break; - case 0x04: - mixer->regs[0x32] = (mixer->regs[0x04] & 0xf0) | 0x8; - mixer->regs[0x33] = ((mixer->regs[0x04] & 0xf) << 4) | 0x8; - break; - case 0x26: - mixer->regs[0x34] = (mixer->regs[0x26] & 0xf0) | 0x8; - mixer->regs[0x35] = ((mixer->regs[0x26] & 0xf) << 4) | 0x8; - break; - case 0x28: - mixer->regs[0x36] = (mixer->regs[0x28] & 0xf0) | 0x8; - mixer->regs[0x37] = ((mixer->regs[0x28] & 0xf) << 4) | 0x8; - break; - case 0x0A: - mixer->regs[0x3a] = (mixer->regs[0x0a] << 5) | 0x18; - break; - case 0x2e: - mixer->regs[0x38] = (mixer->regs[0x2e] & 0xf0) | 0x8; - mixer->regs[0x39] = ((mixer->regs[0x2e] & 0xf) << 4) | 0x8; - break; + switch (mixer->index) { + /* SB1/2 compatibility? */ + case 0x02: + mixer->regs[0x30] = ((mixer->regs[0x02] & 0xf) << 4) | 0x8; + mixer->regs[0x31] = ((mixer->regs[0x02] & 0xf) << 4) | 0x8; + break; + case 0x06: + mixer->regs[0x34] = ((mixer->regs[0x06] & 0xf) << 4) | 0x8; + mixer->regs[0x35] = ((mixer->regs[0x06] & 0xf) << 4) | 0x8; + break; + case 0x08: + mixer->regs[0x36] = ((mixer->regs[0x08] & 0xf) << 4) | 0x8; + mixer->regs[0x37] = ((mixer->regs[0x08] & 0xf) << 4) | 0x8; + break; + /* SBPro compatibility. Copy values to sb16 registers. */ + case 0x22: + mixer->regs[0x30] = (mixer->regs[0x22] & 0xf0) | 0x8; + mixer->regs[0x31] = ((mixer->regs[0x22] & 0xf) << 4) | 0x8; + break; + case 0x04: + mixer->regs[0x32] = (mixer->regs[0x04] & 0xf0) | 0x8; + mixer->regs[0x33] = ((mixer->regs[0x04] & 0xf) << 4) | 0x8; + break; + case 0x26: + mixer->regs[0x34] = (mixer->regs[0x26] & 0xf0) | 0x8; + mixer->regs[0x35] = ((mixer->regs[0x26] & 0xf) << 4) | 0x8; + break; + case 0x28: + mixer->regs[0x36] = (mixer->regs[0x28] & 0xf0) | 0x8; + mixer->regs[0x37] = ((mixer->regs[0x28] & 0xf) << 4) | 0x8; + break; + case 0x0A: + mixer->regs[0x3a] = (mixer->regs[0x0a] << 5) | 0x18; + break; + case 0x2e: + mixer->regs[0x38] = (mixer->regs[0x2e] & 0xf0) | 0x8; + mixer->regs[0x39] = ((mixer->regs[0x2e] & 0xf) << 4) | 0x8; + break; - /* (DSP 4.xx feature): - The Interrupt Setup register, addressed as register 80h on the Mixer register map, - is used to configure or determine the Interrupt request line. - The DMA setup register, addressed as register 81h on the Mixer register map, is - used to configure or determine the DMA channels. + /* (DSP 4.xx feature): + The Interrupt Setup register, addressed as register 80h on the Mixer register map, + is used to configure or determine the Interrupt request line. + The DMA setup register, addressed as register 81h on the Mixer register map, is + used to configure or determine the DMA channels. - Note: Registers 80h and 81h are Read-only for PnP boards. */ - case 0x80: - if (val & 0x01) - sb_dsp_setirq(&sb->dsp, 2); - if (val & 0x02) - sb_dsp_setirq(&sb->dsp, 5); - if (val & 0x04) - sb_dsp_setirq(&sb->dsp, 7); - if (val & 0x08) - sb_dsp_setirq(&sb->dsp, 10); - break; + Note: Registers 80h and 81h are Read-only for PnP boards. */ + case 0x80: + if (val & 0x01) + sb_dsp_setirq(&sb->dsp, 2); + if (val & 0x02) + sb_dsp_setirq(&sb->dsp, 5); + if (val & 0x04) + sb_dsp_setirq(&sb->dsp, 7); + if (val & 0x08) + sb_dsp_setirq(&sb->dsp, 10); + break; - case 0x81: - /* The documentation is confusing. sounds as if multple dma8 channels could - be set. */ - if (val & 0x01) - sb_dsp_setdma8(&sb->dsp, 0); - if (val & 0x02) - sb_dsp_setdma8(&sb->dsp, 1); - if (val & 0x08) - sb_dsp_setdma8(&sb->dsp, 3); - if (val & 0x20) - sb_dsp_setdma16(&sb->dsp, 5); - if (val & 0x40) - sb_dsp_setdma16(&sb->dsp, 6); - if (val & 0x80) - sb_dsp_setdma16(&sb->dsp, 7); - break; + case 0x81: + /* The documentation is confusing. sounds as if multple dma8 channels could + be set. */ + if (val & 0x01) + sb_dsp_setdma8(&sb->dsp, 0); + if (val & 0x02) + sb_dsp_setdma8(&sb->dsp, 1); + if (val & 0x08) + sb_dsp_setdma8(&sb->dsp, 3); + if (val & 0x20) + sb_dsp_setdma16(&sb->dsp, 5); + if (val & 0x40) + sb_dsp_setdma16(&sb->dsp, 6); + if (val & 0x80) + sb_dsp_setdma16(&sb->dsp, 7); + break; - case 0x83: - /* Interrupt mask. */ - sb_update_mask(&sb->dsp, !(val & 0x01), !(val & 0x02), !(val & 0x04)); - break; + case 0x83: + /* Interrupt mask. */ + sb_update_mask(&sb->dsp, !(val & 0x01), !(val & 0x02), !(val & 0x04)); + break; - case 0x84: - /* MPU Control register, per the Linux source code. */ - if (sb->mpu != NULL) { - if ((val & 0x06) == 0x00) - mpu401_change_addr(sb->mpu, 0x330); - else if ((val & 0x06) == 0x04) - mpu401_change_addr(sb->mpu, 0x300); - else if ((val & 0x06) == 0x02) - mpu401_change_addr(sb->mpu, 0); - } - break; - } + case 0x84: + /* MPU Control register, per the Linux source code. */ + if (sb->mpu != NULL) { + if ((val & 0x06) == 0x00) + mpu401_change_addr(sb->mpu, 0x330); + else if ((val & 0x06) == 0x04) + mpu401_change_addr(sb->mpu, 0x300); + else if ((val & 0x06) == 0x02) + mpu401_change_addr(sb->mpu, 0); + } + break; + } - mixer->output_selector = mixer->regs[0x3c]; - mixer->input_selector_left = mixer->regs[0x3d]; - mixer->input_selector_right = mixer->regs[0x3e]; + mixer->output_selector = mixer->regs[0x3c]; + mixer->input_selector_left = mixer->regs[0x3d]; + mixer->input_selector_right = mixer->regs[0x3e]; - mixer->master_l = sb_att_2dbstep_5bits[mixer->regs[0x30] >> 3] / 32768.0; - mixer->master_r = sb_att_2dbstep_5bits[mixer->regs[0x31] >> 3] / 32768.0; - mixer->voice_l = sb_att_2dbstep_5bits[mixer->regs[0x32] >> 3] / 32768.0; - mixer->voice_r = sb_att_2dbstep_5bits[mixer->regs[0x33] >> 3] / 32768.0; - mixer->fm_l = sb_att_2dbstep_5bits[mixer->regs[0x34] >> 3] / 32768.0; - mixer->fm_r = sb_att_2dbstep_5bits[mixer->regs[0x35] >> 3] / 32768.0; - mixer->cd_l = (mixer->output_selector & OUTPUT_CD_L) ? (sb_att_2dbstep_5bits[mixer->regs[0x36] >> 3] / 32768.0): 0.0; - mixer->cd_r = (mixer->output_selector & OUTPUT_CD_R) ? (sb_att_2dbstep_5bits[mixer->regs[0x37] >> 3] / 32768.0) : 0.0; - mixer->line_l = (mixer->output_selector & OUTPUT_LINE_L) ? (sb_att_2dbstep_5bits[mixer->regs[0x38] >> 3] / 32768.0) : 0.0; - mixer->line_r = (mixer->output_selector & OUTPUT_LINE_R) ? (sb_att_2dbstep_5bits[mixer->regs[0x39] >> 3] / 32768.0) : 0.0; + mixer->master_l = sb_att_2dbstep_5bits[mixer->regs[0x30] >> 3] / 32768.0; + mixer->master_r = sb_att_2dbstep_5bits[mixer->regs[0x31] >> 3] / 32768.0; + mixer->voice_l = sb_att_2dbstep_5bits[mixer->regs[0x32] >> 3] / 32768.0; + mixer->voice_r = sb_att_2dbstep_5bits[mixer->regs[0x33] >> 3] / 32768.0; + mixer->fm_l = sb_att_2dbstep_5bits[mixer->regs[0x34] >> 3] / 32768.0; + mixer->fm_r = sb_att_2dbstep_5bits[mixer->regs[0x35] >> 3] / 32768.0; + mixer->cd_l = (mixer->output_selector & OUTPUT_CD_L) ? (sb_att_2dbstep_5bits[mixer->regs[0x36] >> 3] / 32768.0) : 0.0; + mixer->cd_r = (mixer->output_selector & OUTPUT_CD_R) ? (sb_att_2dbstep_5bits[mixer->regs[0x37] >> 3] / 32768.0) : 0.0; + mixer->line_l = (mixer->output_selector & OUTPUT_LINE_L) ? (sb_att_2dbstep_5bits[mixer->regs[0x38] >> 3] / 32768.0) : 0.0; + mixer->line_r = (mixer->output_selector & OUTPUT_LINE_R) ? (sb_att_2dbstep_5bits[mixer->regs[0x39] >> 3] / 32768.0) : 0.0; - mixer->mic = sb_att_2dbstep_5bits[mixer->regs[0x3a] >> 3] / 32768.0; - mixer->speaker = sb_att_2dbstep_5bits[mixer->regs[0x3b] * 3 + 22] / 32768.0; + mixer->mic = sb_att_2dbstep_5bits[mixer->regs[0x3a] >> 3] / 32768.0; + mixer->speaker = sb_att_2dbstep_5bits[mixer->regs[0x3b] * 3 + 22] / 32768.0; - mixer->input_gain_L = (mixer->regs[0x3f] >> 6); - mixer->input_gain_R = (mixer->regs[0x40] >> 6); - mixer->output_gain_L = (double) (1 << (mixer->regs[0x41] >> 6)); - mixer->output_gain_R = (double) (1 << (mixer->regs[0x42] >> 6)); + mixer->input_gain_L = (mixer->regs[0x3f] >> 6); + mixer->input_gain_R = (mixer->regs[0x40] >> 6); + mixer->output_gain_L = (double) (1 << (mixer->regs[0x41] >> 6)); + mixer->output_gain_R = (double) (1 << (mixer->regs[0x42] >> 6)); - mixer->bass_l = mixer->regs[0x46] >> 4; - mixer->bass_r = mixer->regs[0x47] >> 4; - mixer->treble_l = mixer->regs[0x44] >> 4; - mixer->treble_r = mixer->regs[0x45] >> 4; + mixer->bass_l = mixer->regs[0x46] >> 4; + mixer->bass_r = mixer->regs[0x47] >> 4; + mixer->treble_l = mixer->regs[0x44] >> 4; + mixer->treble_r = mixer->regs[0x45] >> 4; - /* TODO: PC Speaker volume, with "output_selector" check? or better not? */ - sb_log("sb_ct1745: Received register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + /* TODO: PC Speaker volume, with "output_selector" check? or better not? */ + sb_log("sb_ct1745: Received register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); } } - static uint8_t sb_ct1745_mixer_read(uint16_t addr, void *p) { - sb_t *sb = (sb_t *) p; + sb_t *sb = (sb_t *) p; sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - uint8_t temp, ret = 0xff; + uint8_t temp, ret = 0xff; if (!(addr & 1)) - ret = mixer->index; + ret = mixer->index; sb_log("sb_ct1745: received register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); if ((mixer->index >= 0x30) && (mixer->index <= 0x47)) - ret = mixer->regs[mixer->index]; - else switch (mixer->index) { - case 0x00: - ret = mixer->regs[mixer->index]; - break; + ret = mixer->regs[mixer->index]; + else + switch (mixer->index) { + case 0x00: + ret = mixer->regs[mixer->index]; + break; - /*SB Pro compatibility*/ - case 0x04: - ret = ((mixer->regs[0x33] >> 4) & 0x0f) | (mixer->regs[0x32] & 0xf0); - break; - case 0x0a: - ret = (mixer->regs[0x3a] >> 5); - break; - case 0x02: - ret = ((mixer->regs[0x30] >> 4) & 0x0f); - break; - case 0x06: - ret = ((mixer->regs[0x34] >> 4) & 0x0f); - break; - case 0x08: - ret = ((mixer->regs[0x36] >> 4) & 0x0f); - break; - case 0x0e: - ret = 0x02; - break; - case 0x22: - ret = ((mixer->regs[0x31] >> 4) & 0x0f) | (mixer->regs[0x30] & 0xf0); - break; - case 0x26: - ret = ((mixer->regs[0x35] >> 4) & 0x0f) | (mixer->regs[0x34] & 0xf0); - break; - case 0x28: - ret = ((mixer->regs[0x37] >> 4) & 0x0f) | (mixer->regs[0x36] & 0xf0); - break; - case 0x2e: - ret = ((mixer->regs[0x39] >> 4) & 0x0f) | (mixer->regs[0x38] & 0xf0); - break; + /*SB Pro compatibility*/ + case 0x04: + ret = ((mixer->regs[0x33] >> 4) & 0x0f) | (mixer->regs[0x32] & 0xf0); + break; + case 0x0a: + ret = (mixer->regs[0x3a] >> 5); + break; + case 0x02: + ret = ((mixer->regs[0x30] >> 4) & 0x0f); + break; + case 0x06: + ret = ((mixer->regs[0x34] >> 4) & 0x0f); + break; + case 0x08: + ret = ((mixer->regs[0x36] >> 4) & 0x0f); + break; + case 0x0e: + ret = 0x02; + break; + case 0x22: + ret = ((mixer->regs[0x31] >> 4) & 0x0f) | (mixer->regs[0x30] & 0xf0); + break; + case 0x26: + ret = ((mixer->regs[0x35] >> 4) & 0x0f) | (mixer->regs[0x34] & 0xf0); + break; + case 0x28: + ret = ((mixer->regs[0x37] >> 4) & 0x0f) | (mixer->regs[0x36] & 0xf0); + break; + case 0x2e: + ret = ((mixer->regs[0x39] >> 4) & 0x0f) | (mixer->regs[0x38] & 0xf0); + break; - case 0x48: - /* Undocumented. The Creative Windows Mixer calls this after calling 3C (input selector), - even when writing. - Also, the version I have (5.17), does not use the MIDI.L/R input selectors, it uses - the volume to mute (Affecting the output, obviously). */ - ret = mixer->regs[mixer->index]; - break; + case 0x48: + /* Undocumented. The Creative Windows Mixer calls this after calling 3C (input selector), + even when writing. + Also, the version I have (5.17), does not use the MIDI.L/R input selectors, it uses + the volume to mute (Affecting the output, obviously). */ + ret = mixer->regs[mixer->index]; + break; - case 0x80: - /* TODO: Unaffected by mixer reset or soft reboot. - Enabling multiple bits enables multiple IRQs. */ + case 0x80: + /* TODO: Unaffected by mixer reset or soft reboot. + Enabling multiple bits enables multiple IRQs. */ - switch (sb->dsp.sb_irqnum) { - case 2: ret = 1; break; - case 5: ret = 2; break; - case 7: ret = 4; break; - case 10: ret = 8; break; - } - break; + switch (sb->dsp.sb_irqnum) { + case 2: + ret = 1; + break; + case 5: + ret = 2; + break; + case 7: + ret = 4; + break; + case 10: + ret = 8; + break; + } + break; - case 0x81: - /* TODO: Unaffected by mixer reset or soft reboot. - Enabling multiple 8 or 16-bit DMA bits enables multiple DMA channels. - Disabling all 8-bit DMA channel bits disables 8-bit DMA requests, - including translated 16-bit DMA requests. - Disabling all 16-bit DMA channel bits enables translation of 16-bit DMA - requests to 8-bit ones, using the selected 8-bit DMA channel. */ + case 0x81: + /* TODO: Unaffected by mixer reset or soft reboot. + Enabling multiple 8 or 16-bit DMA bits enables multiple DMA channels. + Disabling all 8-bit DMA channel bits disables 8-bit DMA requests, + including translated 16-bit DMA requests. + Disabling all 16-bit DMA channel bits enables translation of 16-bit DMA + requests to 8-bit ones, using the selected 8-bit DMA channel. */ - ret = 0; - switch (sb->dsp.sb_8_dmanum) { - case 0: ret |= 1; break; - case 1: ret |= 2; break; - case 3: ret |= 8; break; - } - switch (sb->dsp.sb_16_dmanum) { - case 5: ret |= 0x20; break; - case 6: ret |= 0x40; break; - case 7: ret |= 0x80; break; - } - break; + ret = 0; + switch (sb->dsp.sb_8_dmanum) { + case 0: + ret |= 1; + break; + case 1: + ret |= 2; + break; + case 3: + ret |= 8; + break; + } + switch (sb->dsp.sb_16_dmanum) { + case 5: + ret |= 0x20; + break; + case 6: + ret |= 0x40; + break; + case 7: + ret |= 0x80; + break; + } + break; - case 0x82: - /* The Interrupt status register, addressed as register 82h on the Mixer register map, - is used by the ISR to determine whether the interrupt is meant for it or for some other ISR, - in which case it should chain to the previous routine. */ - /* 0 = none, 1 = digital 8bit or SBMIDI, 2 = digital 16bit, 4 = MPU-401 */ - /* 0x02000 DSP v4.04, 0x4000 DSP v4.05, 0x8000 DSP v4.12. - I haven't seen this making any difference, but I'm keeping it for now. */ - /* If QEMU is any indication, then the values are actually 0x20, 0x40, and 0x80. */ - temp = ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) | - ((sb->dsp.sb_irq401) ? 4 : 0) | 0x40; - ret = temp; - break; + case 0x82: + /* The Interrupt status register, addressed as register 82h on the Mixer register map, + is used by the ISR to determine whether the interrupt is meant for it or for some other ISR, + in which case it should chain to the previous routine. */ + /* 0 = none, 1 = digital 8bit or SBMIDI, 2 = digital 16bit, 4 = MPU-401 */ + /* 0x02000 DSP v4.04, 0x4000 DSP v4.05, 0x8000 DSP v4.12. + I haven't seen this making any difference, but I'm keeping it for now. */ + /* If QEMU is any indication, then the values are actually 0x20, 0x40, and 0x80. */ + temp = ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) | ((sb->dsp.sb_irq401) ? 4 : 0) | 0x40; + ret = temp; + break; - case 0x83: - /* Interrupt mask. */ - ret = mixer->regs[mixer->index]; - break; + case 0x83: + /* Interrupt mask. */ + ret = mixer->regs[mixer->index]; + break; - case 0x84: - /* MPU Control. */ - if (sb->mpu == NULL) - ret = 0x02; - else { - if (sb->mpu->addr == 0x330) - ret = 0x00; - else if (sb->mpu->addr == 0x300) - ret = 0x04; - else if (sb->mpu->addr == 0) - ret = 0x02; - else - ret = 0x06; /* Should never happen. */ - } - break; + case 0x84: + /* MPU Control. */ + if (sb->mpu == NULL) + ret = 0x02; + else { + if (sb->mpu->addr == 0x330) + ret = 0x00; + else if (sb->mpu->addr == 0x300) + ret = 0x04; + else if (sb->mpu->addr == 0) + ret = 0x02; + else + ret = 0x06; /* Should never happen. */ + } + break; - case 0x90: - /* 3D Enhancement switch. */ - ret = mixer->regs[mixer->index]; - break; + case 0x90: + /* 3D Enhancement switch. */ + ret = mixer->regs[mixer->index]; + break; - /* TODO: creative drivers read and write on 0xFE and 0xFF. not sure what they are supposed to be. */ - case 0xfd: - ret = 16; - break; + /* TODO: creative drivers read and write on 0xFE and 0xFF. not sure what they are supposed to be. */ + case 0xfd: + ret = 16; + break; - case 0xfe: - ret = 6; - break; + case 0xfe: + ret = 6; + break; - default: - sb_log("sb_ct1745: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); - break; - } + default: + sb_log("sb_ct1745: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + break; + } sb_log("CT1745: read REG%02X: %02X\n", mixer->index, ret); return ret; } - static void -sb_ct1745_mixer_reset(sb_t* sb) +sb_ct1745_mixer_reset(sb_t *sb) { sb_ct1745_mixer_write(4, 0, sb); sb_ct1745_mixer_write(5, 0, sb); @@ -1023,35 +1056,37 @@ sb_ct1745_mixer_reset(sb_t* sb) sb->mixer_sb16.regs[0xfe] = 6; } - uint8_t sb_mcv_read(int port, void *p) { - sb_t *sb = (sb_t *)p; + sb_t *sb = (sb_t *) p; sb_log("sb_mcv_read: port=%04x\n", port); return sb->pos_regs[port & 7]; } - void sb_mcv_write(int port, uint8_t val, void *p) { uint16_t addr; - sb_t *sb = (sb_t *)p; + sb_t *sb = (sb_t *) p; if (port < 0x102) - return; + return; sb_log("sb_mcv_write: port=%04x val=%02x\n", port, val); addr = sb_mcv_addr[sb->pos_regs[4] & 7]; if (sb->opl_enabled) { - io_removehandler(addr + 8, 0x0002, opl2_read, NULL, NULL, - opl2_write, NULL, NULL, &sb->opl); - io_removehandler(0x0388, 0x0002, opl2_read, NULL, NULL, - opl2_write, NULL, NULL, &sb->opl); + io_removehandler(addr + 8, 0x0002, + opl2_read, NULL, NULL, + opl2_write, NULL, NULL, + &sb->opl); + io_removehandler(0x0388, 0x0002, + opl2_read, NULL, NULL, + opl2_write, NULL, NULL, + &sb->opl); } /* DSP I/O handler is activated in sb_dsp_setaddr */ sb_dsp_setaddr(&sb->dsp, 0); @@ -1059,33 +1094,35 @@ sb_mcv_write(int port, uint8_t val, void *p) sb->pos_regs[port & 7] = val; if (sb->pos_regs[2] & 1) { - addr = sb_mcv_addr[sb->pos_regs[4] & 7]; + addr = sb_mcv_addr[sb->pos_regs[4] & 7]; - if (sb->opl_enabled) { - io_sethandler(addr + 8, 0x0002, opl2_read, NULL, NULL, - opl2_write, NULL, NULL, &sb->opl); - io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, - opl2_write, NULL, NULL, &sb->opl); - } - /* DSP I/O handler is activated in sb_dsp_setaddr */ - sb_dsp_setaddr(&sb->dsp, addr); + if (sb->opl_enabled) { + io_sethandler(addr + 8, 0x0002, + opl2_read, NULL, NULL, + opl2_write, NULL, NULL, + &sb->opl); + io_sethandler(0x0388, 0x0002, + opl2_read, NULL, NULL, + opl2_write, NULL, NULL, + &sb->opl); + } + /* DSP I/O handler is activated in sb_dsp_setaddr */ + sb_dsp_setaddr(&sb->dsp, addr); } } - uint8_t sb_mcv_feedb(void *p) { - sb_t *sb = (sb_t *)p; + sb_t *sb = (sb_t *) p; return (sb->pos_regs[2] & 1); } - static uint8_t sb_pro_mcv_read(int port, void *p) { - sb_t *sb = (sb_t *)p; + sb_t *sb = (sb_t *) p; uint8_t ret = sb->pos_regs[port & 7]; sb_log("sb_pro_mcv_read: port=%04x ret=%02x\n", port, ret); @@ -1093,178 +1130,204 @@ sb_pro_mcv_read(int port, void *p) return ret; } - static void sb_pro_mcv_write(int port, uint8_t val, void *p) { uint16_t addr; - sb_t *sb = (sb_t *)p; + sb_t *sb = (sb_t *) p; if (port < 0x102) - return; + return; sb_log("sb_pro_mcv_write: port=%04x val=%02x\n", port, val); addr = (sb->pos_regs[2] & 0x20) ? 0x220 : 0x240; - io_removehandler(addr, 0x0004, opl3_read, NULL, NULL, - opl3_write, NULL, NULL, &sb->opl); - io_removehandler(addr + 8, 0x0002, opl3_read, NULL, NULL, - opl3_write, NULL, NULL, &sb->opl); - io_removehandler(0x0388, 0x0004, opl3_read, NULL, NULL, - opl3_write, NULL, NULL, &sb->opl); - io_removehandler(addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, - sb_ct1345_mixer_write, NULL, NULL, sb); + io_removehandler(addr, 0x0004, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); + io_removehandler(addr + 8, 0x0002, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); + io_removehandler(0x0388, 0x0004, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); + io_removehandler(addr + 4, 0x0002, + sb_ct1345_mixer_read, NULL, NULL, + sb_ct1345_mixer_write, NULL, NULL, + sb); /* DSP I/O handler is activated in sb_dsp_setaddr */ sb_dsp_setaddr(&sb->dsp, 0); sb->pos_regs[port & 7] = val; if (sb->pos_regs[2] & 1) { - addr = (sb->pos_regs[2] & 0x20) ? 0x220 : 0x240; + addr = (sb->pos_regs[2] & 0x20) ? 0x220 : 0x240; - io_sethandler(addr, 0x0004, opl3_read, NULL, NULL, - opl3_write, NULL, NULL, &sb->opl); - io_sethandler(addr + 8, 0x0002, opl3_read, NULL, NULL, - opl3_write, NULL, NULL, &sb->opl); - io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, - opl3_write, NULL, NULL, &sb->opl); - io_sethandler(addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, - sb_ct1345_mixer_write, NULL, NULL, sb); - /* DSP I/O handler is activated in sb_dsp_setaddr */ - sb_dsp_setaddr(&sb->dsp, addr); + io_sethandler(addr, 0x0004, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); + io_sethandler(addr + 8, 0x0002, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); + io_sethandler(0x0388, 0x0004, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, &sb->opl); + io_sethandler(addr + 4, 0x0002, + sb_ct1345_mixer_read, NULL, NULL, + sb_ct1345_mixer_write, NULL, NULL, + sb); + /* DSP I/O handler is activated in sb_dsp_setaddr */ + sb_dsp_setaddr(&sb->dsp, addr); } sb_dsp_setirq(&sb->dsp, sb_pro_mcv_irqs[(sb->pos_regs[5] >> 4) & 3]); sb_dsp_setdma8(&sb->dsp, sb->pos_regs[4] & 3); } - static void sb_16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) { - sb_t *sb = (sb_t *) priv; + sb_t *sb = (sb_t *) priv; uint16_t addr = sb->dsp.sb_addr; - uint8_t val; + uint8_t val; switch (ld) { - case 0: /* Audio */ - io_removehandler(addr, 0x0004, opl3_read, NULL, NULL, - opl3_write, NULL, NULL, &sb->opl); - io_removehandler(addr + 8, 0x0002, opl3_read, NULL, NULL, - opl3_write, NULL, NULL, &sb->opl); - io_removehandler(addr + 4, 0x0002, sb_ct1745_mixer_read, NULL, NULL, - sb_ct1745_mixer_write, NULL, NULL, sb); + case 0: /* Audio */ + io_removehandler(addr, 0x0004, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); + io_removehandler(addr + 8, 0x0002, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); + io_removehandler(addr + 4, 0x0002, + sb_ct1745_mixer_read, NULL, NULL, + sb_ct1745_mixer_write, NULL, NULL, + sb); - addr = sb->opl_pnp_addr; - if (addr) { - sb->opl_pnp_addr = 0; - io_removehandler(addr, 0x0004, opl3_read, NULL, NULL, - opl3_write, NULL, NULL, &sb->opl); - } + addr = sb->opl_pnp_addr; + if (addr) { + sb->opl_pnp_addr = 0; + io_removehandler(addr, 0x0004, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); + } - sb_dsp_setaddr(&sb->dsp, 0); - sb_dsp_setirq(&sb->dsp, 0); - sb_dsp_setdma8(&sb->dsp, ISAPNP_DMA_DISABLED); - sb_dsp_setdma16(&sb->dsp, ISAPNP_DMA_DISABLED); + sb_dsp_setaddr(&sb->dsp, 0); + sb_dsp_setirq(&sb->dsp, 0); + sb_dsp_setdma8(&sb->dsp, ISAPNP_DMA_DISABLED); + sb_dsp_setdma16(&sb->dsp, ISAPNP_DMA_DISABLED); - mpu401_change_addr(sb->mpu, 0); + mpu401_change_addr(sb->mpu, 0); - if (config->activate) { - addr = config->io[0].base; - if (addr != ISAPNP_IO_DISABLED) { - io_sethandler(addr, 0x0004, opl3_read, NULL, NULL, - opl3_write, NULL, NULL, &sb->opl); - io_sethandler(addr + 8, 0x0002, opl3_read, NULL, NULL, - opl3_write, NULL, NULL, &sb->opl); - io_sethandler(addr + 4, 0x0002, sb_ct1745_mixer_read, NULL, NULL, - sb_ct1745_mixer_write, NULL, NULL, sb); + if (config->activate) { + addr = config->io[0].base; + if (addr != ISAPNP_IO_DISABLED) { + io_sethandler(addr, 0x0004, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); + io_sethandler(addr + 8, 0x0002, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); + io_sethandler(addr + 4, 0x0002, + sb_ct1745_mixer_read, NULL, NULL, + sb_ct1745_mixer_write, NULL, NULL, + sb); - sb_dsp_setaddr(&sb->dsp, addr); - } + sb_dsp_setaddr(&sb->dsp, addr); + } - addr = config->io[1].base; - if (addr != ISAPNP_IO_DISABLED) - mpu401_change_addr(sb->mpu, addr); + addr = config->io[1].base; + if (addr != ISAPNP_IO_DISABLED) + mpu401_change_addr(sb->mpu, addr); - addr = config->io[2].base; - if (addr != ISAPNP_IO_DISABLED) { - sb->opl_pnp_addr = addr; - io_sethandler(addr, 0x0004, opl3_read, NULL, NULL, - opl3_write, NULL, NULL, &sb->opl); - } + addr = config->io[2].base; + if (addr != ISAPNP_IO_DISABLED) { + sb->opl_pnp_addr = addr; + io_sethandler(addr, 0x0004, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); + } - val = config->irq[0].irq; - if (val != ISAPNP_IRQ_DISABLED) - sb_dsp_setirq(&sb->dsp, val); + val = config->irq[0].irq; + if (val != ISAPNP_IRQ_DISABLED) + sb_dsp_setirq(&sb->dsp, val); - val = config->dma[0].dma; - if (val != ISAPNP_DMA_DISABLED) - sb_dsp_setdma8(&sb->dsp, val); + val = config->dma[0].dma; + if (val != ISAPNP_DMA_DISABLED) + sb_dsp_setdma8(&sb->dsp, val); - val = config->dma[1].dma; - if (val != ISAPNP_DMA_DISABLED) - sb_dsp_setdma16(&sb->dsp, val); - } + val = config->dma[1].dma; + if (val != ISAPNP_DMA_DISABLED) + sb_dsp_setdma16(&sb->dsp, val); + } - break; + break; - case 1: /* IDE */ - ide_pnp_config_changed(0, config, (void *) 2); - break; + case 1: /* IDE */ + ide_pnp_config_changed(0, config, (void *) 2); + break; - case 2: /* Reserved (16) / WaveTable (32+) */ - if (sb->dsp.sb_type > SB16) - emu8k_change_addr(&sb->emu8k, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0); - break; + case 2: /* Reserved (16) / WaveTable (32+) */ + if (sb->dsp.sb_type > SB16) + emu8k_change_addr(&sb->emu8k, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0); + break; - case 3: /* Game */ - gameport_remap(sb->gameport, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0); - break; + case 3: /* Game */ + gameport_remap(sb->gameport, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0); + break; - case 4: /* StereoEnhance (32) */ - break; + case 4: /* StereoEnhance (32) */ + break; } } - static void sb_awe32_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) { sb_t *sb = (sb_t *) priv; switch (ld) { - case 0: /* Audio */ - case 1: /* IDE */ - sb_16_pnp_config_changed(ld, config, sb); - break; + case 0: /* Audio */ + case 1: /* IDE */ + sb_16_pnp_config_changed(ld, config, sb); + break; - case 2: /* Game */ - case 3: /* WaveTable */ - sb_16_pnp_config_changed(ld ^ 1, config, sb); - break; + case 2: /* Game */ + case 3: /* WaveTable */ + sb_16_pnp_config_changed(ld ^ 1, config, sb); + break; } } - static void sb_awe64_gold_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) { sb_t *sb = (sb_t *) priv; switch (ld) { - case 0: /* Audio */ - case 2: /* WaveTable */ - sb_16_pnp_config_changed(ld, config, sb); - break; + case 0: /* Audio */ + case 2: /* WaveTable */ + sb_16_pnp_config_changed(ld, config, sb); + break; - case 1: /* Game */ - sb_16_pnp_config_changed(3, config, sb); - break; + case 1: /* Game */ + sb_16_pnp_config_changed(3, config, sb); + break; } } - void * sb_1_init(const device_t *info) { @@ -1272,13 +1335,13 @@ sb_1_init(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)); uint16_t addr = device_get_config_hex16("base"); memset(sb, 0, sizeof(sb_t)); sb->opl_enabled = device_get_config_int("opl"); if (sb->opl_enabled) - opl2_init(&sb->opl); + opl2_init(&sb->opl); sb_dsp_init(&sb->dsp, SB1, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); @@ -1286,27 +1349,33 @@ sb_1_init(const device_t *info) sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); /* DSP I/O handler is activated in sb_dsp_setaddr */ if (sb->opl_enabled) { - io_sethandler(addr + 8, 0x0002, opl2_read, NULL, NULL, - opl2_write, NULL, NULL, &sb->opl); - io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, - opl2_write, NULL, NULL, &sb->opl); + io_sethandler(addr + 8, 0x0002, + opl2_read, NULL, NULL, + opl2_write, NULL, NULL, + &sb->opl); + io_sethandler(0x0388, 0x0002, + opl2_read, NULL, NULL, + opl2_write, NULL, NULL, + &sb->opl); } sb->cms_enabled = 1; memset(&sb->cms, 0, sizeof(cms_t)); - io_sethandler(addr, 0x0004, cms_read, NULL, NULL, cms_write, NULL, NULL, &sb->cms); + io_sethandler(addr, 0x0004, + cms_read, NULL, NULL, + cms_write, NULL, NULL, + &sb->cms); sb->mixer_enabled = 0; sound_add_handler(sb_get_buffer_sb2, sb); sound_set_cd_audio_filter(sb2_filter_cd_audio, sb); if (device_get_config_int("receive_input")) - midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); return sb; } - void * sb_15_init(const device_t *info) { @@ -1314,13 +1383,13 @@ sb_15_init(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)); uint16_t addr = device_get_config_hex16("base"); memset(sb, 0, sizeof(sb_t)); sb->opl_enabled = device_get_config_int("opl"); if (sb->opl_enabled) - opl2_init(&sb->opl); + opl2_init(&sb->opl); sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); @@ -1328,16 +1397,23 @@ sb_15_init(const device_t *info) sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); /* DSP I/O handler is activated in sb_dsp_setaddr */ if (sb->opl_enabled) { - io_sethandler(addr + 8, 0x0002, opl2_read, NULL, NULL, - opl2_write, NULL, NULL, &sb->opl); - io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, - opl2_write, NULL, NULL, &sb->opl); + io_sethandler(addr + 8, 0x0002, + opl2_read, NULL, NULL, + opl2_write, NULL, NULL, + &sb->opl); + io_sethandler(0x0388, 0x0002, + opl2_read, NULL, NULL, + opl2_write, NULL, NULL, + &sb->opl); } sb->cms_enabled = device_get_config_int("cms"); if (sb->cms_enabled) { - memset(&sb->cms, 0, sizeof(cms_t)); - io_sethandler(addr, 0x0004, cms_read, NULL, NULL, cms_write, NULL, NULL, &sb->cms); + memset(&sb->cms, 0, sizeof(cms_t)); + io_sethandler(addr, 0x0004, + cms_read, NULL, NULL, + cms_write, NULL, NULL, + &sb->cms); } sb->mixer_enabled = 0; @@ -1345,12 +1421,11 @@ sb_15_init(const device_t *info) sound_set_cd_audio_filter(sb2_filter_cd_audio, sb); if (device_get_config_int("receive_input")) - midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); return sb; } - void * sb_mcv_init(const device_t *info) { @@ -1362,7 +1437,7 @@ sb_mcv_init(const device_t *info) sb->opl_enabled = device_get_config_int("opl"); if (sb->opl_enabled) - opl2_init(&sb->opl); + opl2_init(&sb->opl); sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, 0); @@ -1379,12 +1454,11 @@ sb_mcv_init(const device_t *info) sb->pos_regs[1] = 0x50; if (device_get_config_int("receive_input")) - midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); return sb; } - void * sb_2_init(const device_t *info) { @@ -1400,79 +1474,87 @@ sb_2_init(const device_t *info) This mirror may also exist on SB 1.5 & MCV, however I am unable to test this. It shouldn't exist on SB 1.0 as the CMS chips are always present there. Syndicate requires this mirror for music to play.*/ - sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_hex16("base"); + sb_t *sb = malloc(sizeof(sb_t)); + uint16_t addr = device_get_config_hex16("base"); uint16_t mixer_addr = device_get_config_int("mixaddr"); memset(sb, 0, sizeof(sb_t)); sb->opl_enabled = device_get_config_int("opl"); if (sb->opl_enabled) - opl2_init(&sb->opl); + opl2_init(&sb->opl); sb_dsp_init(&sb->dsp, SB2, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); if (mixer_addr > 0x000) - sb_ct1335_mixer_reset(sb); + sb_ct1335_mixer_reset(sb); sb->cms_enabled = device_get_config_int("cms"); /* DSP I/O handler is activated in sb_dsp_setaddr */ if (sb->opl_enabled) { - if (!sb->cms_enabled) { - io_sethandler(addr, 0x0002, opl2_read, NULL, NULL, - opl2_write, NULL, NULL, &sb->opl); - } - io_sethandler(addr + 8, 0x0002, opl2_read, NULL, NULL, - opl2_write, NULL, NULL, &sb->opl); - io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, - opl2_write, NULL, NULL, &sb->opl); + if (!sb->cms_enabled) { + io_sethandler(addr, 0x0002, + opl2_read, NULL, NULL, + opl2_write, NULL, NULL, + &sb->opl); + } + io_sethandler(addr + 8, 0x0002, + opl2_read, NULL, NULL, + opl2_write, NULL, NULL, + &sb->opl); + io_sethandler(0x0388, 0x0002, + opl2_read, NULL, NULL, + opl2_write, NULL, NULL, + &sb->opl); } if (sb->cms_enabled) { - memset(&sb->cms, 0, sizeof(cms_t)); - io_sethandler(addr, 0x0004, cms_read, NULL, NULL, cms_write, NULL, NULL, &sb->cms); + memset(&sb->cms, 0, sizeof(cms_t)); + io_sethandler(addr, 0x0004, + cms_read, NULL, NULL, + cms_write, NULL, NULL, + &sb->cms); } if (mixer_addr > 0x000) { - sb->mixer_enabled = 1; - io_sethandler(mixer_addr + 4, 0x0002, sb_ct1335_mixer_read, NULL, NULL, - sb_ct1335_mixer_write, NULL, NULL, sb); + sb->mixer_enabled = 1; + io_sethandler(mixer_addr + 4, 0x0002, + sb_ct1335_mixer_read, NULL, NULL, + sb_ct1335_mixer_write, NULL, NULL, + sb); } else - sb->mixer_enabled = 0; + sb->mixer_enabled = 0; sound_add_handler(sb_get_buffer_sb2, sb); sound_set_cd_audio_filter(sb2_filter_cd_audio, sb); if (device_get_config_int("receive_input")) - midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); return sb; } - static uint8_t sb_pro_v1_opl_read(uint16_t port, void *priv) { - sb_t *sb = (sb_t *)priv; + sb_t *sb = (sb_t *) priv; cycles -= ((int) (isa_timing * 8)); - (void)opl2_read(port, &sb->opl2); // read, but ignore - return(opl2_read(port, &sb->opl)); + (void) opl2_read(port, &sb->opl2); // read, but ignore + return (opl2_read(port, &sb->opl)); } - static void sb_pro_v1_opl_write(uint16_t port, uint8_t val, void *priv) { - sb_t *sb = (sb_t *)priv; + sb_t *sb = (sb_t *) priv; opl2_write(port, val, &sb->opl); opl2_write(port, val, &sb->opl2); } - static void * sb_pro_v1_init(const device_t *info) { @@ -1482,16 +1564,16 @@ sb_pro_v1_init(const device_t *info) 2x6, 2xA, 2xC, 2xE -> DSP chip 2x8, 2x9, 388 and 389 FM chip (9 voices) 2x0+10 to 2x0+13 CDROM interface. */ - sb_t *sb = malloc(sizeof(sb_t)); + sb_t *sb = malloc(sizeof(sb_t)); uint16_t addr = device_get_config_hex16("base"); memset(sb, 0, sizeof(sb_t)); sb->opl_enabled = device_get_config_int("opl"); if (sb->opl_enabled) { - opl2_init(&sb->opl); - opl_set_do_cycles(&sb->opl, 0); - opl2_init(&sb->opl2); - opl_set_do_cycles(&sb->opl2, 0); + opl2_init(&sb->opl); + opl_set_do_cycles(&sb->opl, 0); + opl2_init(&sb->opl2); + opl_set_do_cycles(&sb->opl2, 0); } sb_dsp_init(&sb->dsp, SBPRO, SB_SUBTYPE_DEFAULT, sb); @@ -1501,29 +1583,38 @@ sb_pro_v1_init(const device_t *info) sb_ct1345_mixer_reset(sb); /* DSP I/O handler is activated in sb_dsp_setaddr */ if (sb->opl_enabled) { - io_sethandler(addr, 0x0002, opl2_read, NULL, NULL, - opl2_write, NULL, NULL, &sb->opl); - io_sethandler(addr + 2, 0x0002, opl2_read, NULL, NULL, - opl2_write, NULL, NULL, &sb->opl2); - io_sethandler(addr + 8, 0x0002, sb_pro_v1_opl_read, NULL, NULL, - sb_pro_v1_opl_write, NULL, NULL, sb); - io_sethandler(0x0388, 0x0002, sb_pro_v1_opl_read, NULL, NULL, - sb_pro_v1_opl_write, NULL, NULL, sb); + io_sethandler(addr, 0x0002, + opl2_read, NULL, NULL, + opl2_write, NULL, NULL, + &sb->opl); + io_sethandler(addr + 2, 0x0002, + opl2_read, NULL, NULL, + opl2_write, NULL, NULL, + &sb->opl2); + io_sethandler(addr + 8, 0x0002, + sb_pro_v1_opl_read, NULL, NULL, + sb_pro_v1_opl_write, NULL, NULL, + sb); + io_sethandler(0x0388, 0x0002, + sb_pro_v1_opl_read, NULL, NULL, + sb_pro_v1_opl_write, NULL, NULL, + sb); } sb->mixer_enabled = 1; - io_sethandler(addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, - sb_ct1345_mixer_write, NULL, NULL, sb); + io_sethandler(addr + 4, 0x0002, + sb_ct1345_mixer_read, NULL, NULL, + sb_ct1345_mixer_write, NULL, NULL, + sb); sound_add_handler(sb_get_buffer_sbpro, sb); sound_set_cd_audio_filter(sbpro_filter_cd_audio, sb); if (device_get_config_int("receive_input")) - midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); return sb; } - static void * sb_pro_v2_init(const device_t *info) { @@ -1533,13 +1624,13 @@ sb_pro_v2_init(const device_t *info) 2x6, 2xA, 2xC, 2xE -> DSP chip 2x8, 2x9, 388 and 389 FM chip (9 voices) 2x0+10 to 2x0+13 CDROM interface. */ - sb_t *sb = malloc(sizeof(sb_t)); + sb_t *sb = malloc(sizeof(sb_t)); uint16_t addr = device_get_config_hex16("base"); memset(sb, 0, sizeof(sb_t)); sb->opl_enabled = device_get_config_int("opl"); if (sb->opl_enabled) - opl3_init(&sb->opl); + opl3_init(&sb->opl); sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); @@ -1548,27 +1639,34 @@ sb_pro_v2_init(const device_t *info) sb_ct1345_mixer_reset(sb); /* DSP I/O handler is activated in sb_dsp_setaddr */ if (sb->opl_enabled) { - io_sethandler(addr, 0x0004, opl3_read, NULL, NULL, - opl3_write, NULL, NULL, &sb->opl); - io_sethandler(addr + 8, 0x0002, opl3_read, NULL, NULL, - opl3_write, NULL, NULL, &sb->opl); - io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, - opl3_write, NULL, NULL, &sb->opl); + io_sethandler(addr, 0x0004, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); + io_sethandler(addr + 8, 0x0002, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); + io_sethandler(0x0388, 0x0004, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); } sb->mixer_enabled = 1; - io_sethandler(addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, - sb_ct1345_mixer_write, NULL, NULL, sb); + io_sethandler(addr + 4, 0x0002, + sb_ct1345_mixer_read, NULL, NULL, + sb_ct1345_mixer_write, NULL, NULL, + sb); sound_add_handler(sb_get_buffer_sbpro, sb); sound_set_cd_audio_filter(sbpro_filter_cd_audio, sb); if (device_get_config_int("receive_input")) - midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); return sb; } - static void * sb_pro_mcv_init(const device_t *info) { @@ -1596,12 +1694,11 @@ sb_pro_mcv_init(const device_t *info) sb->pos_regs[1] = 0x51; if (device_get_config_int("receive_input")) - midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); return sb; } - static void * sb_pro_compat_init(const device_t *info) { @@ -1624,19 +1721,18 @@ sb_pro_compat_init(const device_t *info) return sb; } - static void * sb_16_init(const device_t *info) { - sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_hex16("base"); + sb_t *sb = malloc(sizeof(sb_t)); + uint16_t addr = device_get_config_hex16("base"); uint16_t mpu_addr = device_get_config_hex16("base401"); memset(sb, 0x00, sizeof(sb_t)); sb->opl_enabled = device_get_config_int("opl"); if (sb->opl_enabled) - opl3_init(&sb->opl); + opl3_init(&sb->opl); sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); @@ -1646,35 +1742,42 @@ sb_16_init(const device_t *info) sb_ct1745_mixer_reset(sb); if (sb->opl_enabled) { - io_sethandler(addr, 0x0004, opl3_read, NULL, NULL, - opl3_write, NULL, NULL, &sb->opl); - io_sethandler(addr + 8, 0x0002, opl3_read, NULL, NULL, - opl3_write, NULL, NULL, &sb->opl); - io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, - opl3_write, NULL, NULL, &sb->opl); + io_sethandler(addr, 0x0004, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); + io_sethandler(addr + 8, 0x0002, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); + io_sethandler(0x0388, 0x0004, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); } sb->mixer_enabled = 1; - io_sethandler(addr + 4, 0x0002, sb_ct1745_mixer_read, NULL, NULL, - sb_ct1745_mixer_write, NULL, NULL, sb); + io_sethandler(addr + 4, 0x0002, + sb_ct1745_mixer_read, NULL, NULL, + sb_ct1745_mixer_write, NULL, NULL, + sb); sound_add_handler(sb_get_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (mpu_addr) { - sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); - memset(sb->mpu, 0, sizeof(mpu_t)); - mpu401_init(sb->mpu, device_get_config_hex16("base401"), device_get_config_int("irq"), M_UART, device_get_config_int("receive_input401")); + sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); + memset(sb->mpu, 0, sizeof(mpu_t)); + mpu401_init(sb->mpu, device_get_config_hex16("base401"), device_get_config_int("irq"), M_UART, device_get_config_int("receive_input401")); } else - sb->mpu = NULL; + sb->mpu = NULL; sb_dsp_set_mpu(&sb->dsp, sb->mpu); if (device_get_config_int("receive_input")) - midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); return sb; } - static void * sb_16_pnp_init(const device_t *info) { @@ -1697,7 +1800,7 @@ sb_16_pnp_init(const device_t *info) sb_dsp_set_mpu(&sb->dsp, sb->mpu); if (device_get_config_int("receive_input")) - midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); sb->gameport = gameport_add(&gameport_pnp_device); @@ -1708,63 +1811,56 @@ sb_16_pnp_init(const device_t *info) return sb; } - static int sb_awe32_available() { return rom_present("roms/sound/awe32.raw"); } - static int sb_32_pnp_available() { return sb_awe32_available() && rom_present("roms/sound/CT3600 PnP.BIN"); } - static int sb_awe32_pnp_available() { return sb_awe32_available() && rom_present("roms/sound/CT3980 PnP.BIN"); } - static int sb_awe64_value_available() { return sb_awe32_available() && rom_present("roms/sound/CT4520 PnP.BIN"); } - static int sb_awe64_available() { return sb_awe32_available() && rom_present("roms/sound/CT4520 PnP.BIN"); } - static int sb_awe64_gold_available() { return sb_awe32_available() && rom_present("roms/sound/CT4540 PnP.BIN"); } - static void * sb_awe32_init(const device_t *info) { - sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_hex16("base"); - uint16_t mpu_addr = device_get_config_hex16("base401"); - uint16_t emu_addr = device_get_config_hex16("emu_base"); - int onboard_ram = device_get_config_int("onboard_ram"); + sb_t *sb = malloc(sizeof(sb_t)); + uint16_t addr = device_get_config_hex16("base"); + uint16_t mpu_addr = device_get_config_hex16("base401"); + uint16_t emu_addr = device_get_config_hex16("emu_base"); + int onboard_ram = device_get_config_int("onboard_ram"); memset(sb, 0x00, sizeof(sb_t)); sb->opl_enabled = device_get_config_int("opl"); if (sb->opl_enabled) - opl3_init(&sb->opl); + opl3_init(&sb->opl); sb_dsp_init(&sb->dsp, SBAWE32, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); @@ -1774,42 +1870,49 @@ sb_awe32_init(const device_t *info) sb_ct1745_mixer_reset(sb); if (sb->opl_enabled) { - io_sethandler(addr, 0x0004, opl3_read, NULL, NULL, - opl3_write, NULL, NULL, &sb->opl); - io_sethandler(addr + 8, 0x0002, opl3_read, NULL, NULL, - opl3_write, NULL, NULL, &sb->opl); - io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, - opl3_write, NULL, NULL, &sb->opl); + io_sethandler(addr, 0x0004, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); + io_sethandler(addr + 8, 0x0002, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); + io_sethandler(0x0388, 0x0004, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); } sb->mixer_enabled = 1; - io_sethandler(addr + 4, 0x0002, sb_ct1745_mixer_read, NULL, NULL, - sb_ct1745_mixer_write, NULL, NULL, sb); + io_sethandler(addr + 4, 0x0002, + sb_ct1745_mixer_read, NULL, NULL, + sb_ct1745_mixer_write, NULL, NULL, + sb); sound_add_handler(sb_get_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); if (mpu_addr) { - sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); - memset(sb->mpu, 0, sizeof(mpu_t)); - mpu401_init(sb->mpu, device_get_config_hex16("base401"), device_get_config_int("irq"), M_UART, device_get_config_int("receive_input401")); + sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); + memset(sb->mpu, 0, sizeof(mpu_t)); + mpu401_init(sb->mpu, device_get_config_hex16("base401"), device_get_config_int("irq"), M_UART, device_get_config_int("receive_input401")); } else - sb->mpu = NULL; + sb->mpu = NULL; sb_dsp_set_mpu(&sb->dsp, sb->mpu); emu8k_init(&sb->emu8k, emu_addr, onboard_ram); if (device_get_config_int("receive_input")) - midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); return sb; } - static void * sb_awe32_pnp_init(const device_t *info) { - sb_t *sb = malloc(sizeof(sb_t)); - int onboard_ram = device_get_config_int("onboard_ram"); + sb_t *sb = malloc(sizeof(sb_t)); + int onboard_ram = device_get_config_int("onboard_ram"); memset(sb, 0x00, sizeof(sb_t)); @@ -1831,1120 +1934,685 @@ sb_awe32_pnp_init(const device_t *info) emu8k_init(&sb->emu8k, 0, onboard_ram); if (device_get_config_int("receive_input")) - midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); sb->gameport = gameport_add(&gameport_pnp_device); if ((info->local != 2) && (info->local != 3) && (info->local != 4)) - device_add(&ide_ter_pnp_device); + device_add(&ide_ter_pnp_device); char *pnp_rom_file = NULL; switch (info->local) { - case 0: - pnp_rom_file = "roms/sound/CT3600 PnP.BIN"; - break; + case 0: + pnp_rom_file = "roms/sound/CT3600 PnP.BIN"; + break; - case 1: - pnp_rom_file = "roms/sound/CT3980 PnP.BIN"; - break; + case 1: + pnp_rom_file = "roms/sound/CT3980 PnP.BIN"; + break; - case 2: case 3: - pnp_rom_file = "roms/sound/CT4520 PnP.BIN"; - break; + case 2: + case 3: + pnp_rom_file = "roms/sound/CT4520 PnP.BIN"; + break; - case 4: - pnp_rom_file = "roms/sound/CT4540 PnP.BIN"; - break; + case 4: + pnp_rom_file = "roms/sound/CT4540 PnP.BIN"; + break; } uint8_t *pnp_rom = NULL; if (pnp_rom_file) { - FILE *f = rom_fopen(pnp_rom_file, "rb"); - if (f) { - if (fread(sb->pnp_rom, 1, 512, f) == 512) - pnp_rom = sb->pnp_rom; - fclose(f); - } + FILE *f = rom_fopen(pnp_rom_file, "rb"); + if (f) { + if (fread(sb->pnp_rom, 1, 512, f) == 512) + pnp_rom = sb->pnp_rom; + fclose(f); + } } switch (info->local) { - case 0: - isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_16_pnp_config_changed, NULL, NULL, NULL, sb); - break; + case 0: + isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_16_pnp_config_changed, NULL, NULL, NULL, sb); + break; - case 1: - isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_awe32_pnp_config_changed, NULL, NULL, NULL, sb); - break; + case 1: + isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_awe32_pnp_config_changed, NULL, NULL, NULL, sb); + break; - case 2: case 3: case 4: - isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_awe64_gold_pnp_config_changed, NULL, NULL, NULL, sb); - break; + case 2: + case 3: + case 4: + isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_awe64_gold_pnp_config_changed, NULL, NULL, NULL, sb); + break; } return sb; } - void sb_close(void *p) { - sb_t *sb = (sb_t *)p; + sb_t *sb = (sb_t *) p; sb_dsp_close(&sb->dsp); free(sb); } - static void sb_awe32_close(void *p) { - sb_t *sb = (sb_t *)p; + sb_t *sb = (sb_t *) p; emu8k_close(&sb->emu8k); sb_close(sb); } - void sb_speed_changed(void *p) { - sb_t *sb = (sb_t *)p; + sb_t *sb = (sb_t *) p; sb_dsp_speed_changed(&sb->dsp); } - -static const device_config_t sb_config[] = -{ +// clang-format off +static const device_config_t sb_config[] = { + { "base", "Address", CONFIG_HEX16, "", 0x220, "", { 0 }, { - "base", "Address", CONFIG_HEX16, "", 0x220, "", { 0 }, - { - { - "0x210", 0x210 - }, - { - "0x220", 0x220 - }, - { - "0x230", 0x230 - }, - { - "0x240", 0x240 - }, - { - "0x250", 0x250 - }, - { - "0x260", 0x260 - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 7, "", { 0 }, - { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "" - } - } - }, - { - "dma", "DMA", CONFIG_SELECTION, "", 1, "", { 0 }, - { - { - "DMA 1", 1 - }, - { - "DMA 3", 3 - }, - { - "" - } - } - }, - { - "opl", "Enable OPL", CONFIG_BINARY, "", 1 - }, - { - "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 + { "0x210", 0x210 }, + { "0x220", 0x220 }, + { "0x230", 0x230 }, + { "0x240", 0x240 }, + { "0x250", 0x250 }, + { "0x260", 0x260 }, + { "" } } -}; - - -static const device_config_t sb15_config[] = -{ + }, + { "irq", "IRQ", CONFIG_SELECTION, "", 7, "", { 0 }, { - "base", "Address", CONFIG_HEX16, "", 0x220, "", { 0 }, - { - { - "0x210", 0x210 - }, - { - "0x220", 0x220 - }, - { - "0x230", 0x230 - }, - { - "0x240", 0x240 - }, - { - "0x250", 0x250 - }, - { - "0x260", 0x260 - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 7, "", { 0 }, - { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "" - } - } - }, - { - "dma", "DMA", CONFIG_SELECTION, "", 1, "", { 0 }, - { - { - "DMA 1", 1 - }, - { - "DMA 3", 3 - }, - { - "" - } - } - }, - { - "opl", "Enable OPL", CONFIG_BINARY, "", 1 - }, - { - "cms", "Enable CMS", CONFIG_BINARY, "", 0 - }, - { - "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 + { "IRQ 2", 2 }, + { "IRQ 3", 3 }, + { "IRQ 5", 5 }, + { "IRQ 7", 7 }, + { "" } } -}; - - -static const device_config_t sb2_config[] = -{ + }, + { "dma", "DMA", CONFIG_SELECTION, "", 1, "", { 0 }, { - "base", "Address", CONFIG_HEX16, "", 0x220, "", { 0 }, - { - { - "0x220", 0x220 - }, - { - "0x240", 0x240 - }, - { - "0x260", 0x260 - }, - { - "" - } - } - }, - { - "mixaddr", "Mixer", CONFIG_HEX16, "", 0, "", { 0 }, - { - { - "Disabled", 0 - }, - { - "0x220", 0x220 - }, - { - "0x240", 0x240 - }, - { - "0x250", 0x250 - }, - { - "0x260", 0x260 - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, - { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "" - } - } - }, - { - "dma", "DMA", CONFIG_SELECTION, "", 1, "", { 0 }, - { - { - "DMA 1", 1 - }, - { - "DMA 3", 3 - }, - { - "" - } - } - }, - { - "opl", "Enable OPL", CONFIG_BINARY, "", 1 - }, - { - "cms", "Enable CMS", CONFIG_BINARY, "", 0 - }, - { - "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 + { "DMA 1", 1 }, + { "DMA 3", 3 }, + { "" } } + }, + { "opl", "Enable OPL", CONFIG_BINARY, "", 1 }, + { "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 }, + { "", "", -1 } }; -static const device_config_t sb_mcv_config[] = -{ +static const device_config_t sb15_config[] = { + { "base", "Address", CONFIG_HEX16, "", 0x220, "", { 0 }, { - "irq", "IRQ", CONFIG_SELECTION, "", 7, "", { 0 }, - { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "" - } - } - }, - { - "dma", "DMA", CONFIG_SELECTION, "", 1, "", { 0 }, - { - { - "DMA 1", 1 - }, - { - "DMA 3", 3 - }, - { - "" - } - } - }, - { - "opl", "Enable OPL", CONFIG_BINARY, "", 1 - }, - { - "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 + { "0x210", 0x210 }, + { "0x220", 0x220 }, + { "0x230", 0x230 }, + { "0x240", 0x240 }, + { "0x250", 0x250 }, + { "0x260", 0x260 }, + { "" } } -}; - -static const device_config_t sb_pro_config[] = -{ + }, + { "irq", "IRQ", CONFIG_SELECTION, "", 7, "", { 0 }, { - "base", "Address", CONFIG_HEX16, "", 0x220, "", { 0 }, - { - { - "0x220", 0x220 - }, - { - "0x240", 0x240 - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 7, "", { 0 }, - { - { - "IRQ 2", 2 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "IRQ 10", 10 - }, - { - "" - } - } - }, - { - "dma", "DMA", CONFIG_SELECTION, "", 1, "", { 0 }, - { - { - "DMA 0", 0 - }, - { - "DMA 1", 1 - }, - { - "DMA 3", 3 - }, - { - "" - } - } - }, - { - "opl", "Enable OPL", CONFIG_BINARY, "", 1 - }, - { - "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 + { "IRQ 2", 2 }, + { "IRQ 3", 3 }, + { "IRQ 5", 5 }, + { "IRQ 7", 7 }, + { "" } } -}; - -static const device_config_t sb_16_config[] = -{ + }, + { "dma", "DMA", CONFIG_SELECTION, "", 1, "", { 0 }, { - "base", "Address", CONFIG_HEX16, "", 0x220, "", { 0 }, - { - { - "0x220", 0x220 - }, - { - "0x240", 0x240 - }, - { - "0x260", 0x260 - }, - { - "0x280", 0x280 - }, - { - "" - } - } - }, - { - "base401", "MPU-401 Address", CONFIG_HEX16, "", 0x330, "", { 0 }, - { - { - "Disabled", 0 - }, - { - "0x300", 0x300 - }, - { - "0x330", 0x330 - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, - { - { - "IRQ 2", 2 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "IRQ 10", 10 - }, - { - "" - } - } - }, - { - "dma", "Low DMA channel", CONFIG_SELECTION, "", 1, "", { 0 }, - { - { - "DMA 0", 0 - }, - { - "DMA 1", 1 - }, - { - "DMA 3", 3 - }, - { - "" - } - } - }, - { - "dma16", "High DMA channel", CONFIG_SELECTION, "", 5, "", { 0 }, - { - { - "DMA 5", 5 - }, - { - "DMA 6", 6 - }, - { - "DMA 7", 7 - }, - { - "" - } - } - }, - { - "opl", "Enable OPL", CONFIG_BINARY, "", 1 - }, - { - "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 - }, - { - "receive_input401", "Receive input (MPU-401)", CONFIG_BINARY, "", 0 - }, - { - "", "", -1 + { "DMA 1", 1 }, + { "DMA 3", 3 }, + { "" } } + }, + { "opl", "Enable OPL", CONFIG_BINARY, "", 1 }, + { "cms", "Enable CMS", CONFIG_BINARY, "", 0 }, + { "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 }, + { "", "", -1 } }; -static const device_config_t sb_16_pnp_config[] = -{ +static const device_config_t sb2_config[] = { + { "base", "Address", CONFIG_HEX16, "", 0x220, "", { 0 }, { - "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 - }, - { - "receive_input401", "Receive input (MPU-401)", CONFIG_BINARY, "", 0 - }, - { - "", "", -1 + { "0x220", 0x220 }, + { "0x240", 0x240 }, + { "0x260", 0x260 }, + { "" } } -}; - -static const device_config_t sb_32_pnp_config[] = -{ + }, + { "mixaddr", "Mixer", CONFIG_HEX16, "", 0, "", { 0 }, { - "onboard_ram", "Onboard RAM", CONFIG_SELECTION, "", 0, "", { 0 }, - { - { - "None", 0 - }, - { - "512 KB", 512 - }, - { - "2 MB", 2048 - }, - { - "8 MB", 8192 - }, - { - "28 MB", 28*1024 - }, - { - "" - } - } - }, - { - "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 - }, - { - "receive_input401", "Receive input (MPU-401)", CONFIG_BINARY, "", 0 - }, - { - "", "", -1 + { "Disabled", 0 }, + { "0x220", 0x220 }, + { "0x240", 0x240 }, + { "0x250", 0x250 }, + { "0x260", 0x260 }, + { "" } } -}; - -static const device_config_t sb_awe32_config[] = -{ + }, + { "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, { - "base", "Address", CONFIG_HEX16, "", 0x220, "", { 0 }, - { - { - "0x220", 0x220 - }, - { - "0x240", 0x240 - }, - { - "0x260", 0x260 - }, - { - "0x280", 0x280 - }, - { - "" - } - } - }, - { - "emu_base", "EMU8000 Address", CONFIG_HEX16, "", 0x620, "", { 0 }, - { - { - "0x620", 0x620 - }, - { - "0x640", 0x640 - }, - { - "0x660", 0x660 - }, - { - "0x680", 0x680 - }, - { - .description = "" - } - } - }, - { - "base401", "MPU-401 Address", CONFIG_HEX16, "", 0x330, "", { 0 }, - { - { - "Disabled", 0 - }, - { - "0x300", 0x300 - }, - { - "0x330", 0x330 - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, - { - { - "IRQ 2", 2 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "IRQ 10", 10 - }, - { - "" - } - } - }, - { - "dma", "Low DMA channel", CONFIG_SELECTION, "", 1, "", { 0 }, - { - { - "DMA 0", 0 - }, - { - "DMA 1", 1 - }, - { - "DMA 3", 3 - }, - { - "" - } - } - }, - { - "dma16", "High DMA channel", CONFIG_SELECTION, "", 5, "", { 0 }, - { - { - "DMA 5", 5 - }, - { - "DMA 6", 6 - }, - { - "DMA 7", 7 - }, - { - "" - } - } - }, - { - "onboard_ram", "Onboard RAM", CONFIG_SELECTION, "", 512, "", { 0 }, - { - { - "None", 0 - }, - { - "512 KB", 512 - }, - { - "2 MB", 2048 - }, - { - "8 MB", 8192 - }, - { - "28 MB", 28*1024 - }, - { - "" - } - } - }, - { - "opl", "Enable OPL", CONFIG_BINARY, "", 1 - }, - { - "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 - }, - { - "receive_input401", "Receive input (MPU-401)", CONFIG_BINARY, "", 0 - }, - { - "", "", -1 + { "IRQ 2", 2 }, + { "IRQ 3", 3 }, + { "IRQ 5", 5 }, + { "IRQ 7", 7 }, + { "" } } -}; - -static const device_config_t sb_awe32_pnp_config[] = -{ + }, + { "dma", "DMA", CONFIG_SELECTION, "", 1, "", { 0 }, { - "onboard_ram", "Onboard RAM", CONFIG_SELECTION, "", 512, "", { 0 }, - { - { - "None", 0 - }, - { - "512 KB", 512 - }, - { - "2 MB", 2048 - }, - { - "8 MB", 8192 - }, - { - "28 MB", 28*1024 - }, - { - "" - } - } - }, - { - "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 - }, - { - "receive_input401", "Receive input (MPU-401)", CONFIG_BINARY, "", 0 - }, - { - "", "", -1 + { "DMA 1", 1 }, + { "DMA 3", 3 }, + { "" } } + }, + { "opl", "Enable OPL", CONFIG_BINARY, "", 1 }, + { "cms", "Enable CMS", CONFIG_BINARY, "", 0 }, + { "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 }, + { "", "", -1 } }; -static const device_config_t sb_awe64_value_config[] = -{ +static const device_config_t sb_mcv_config[] = { + { "irq", "IRQ", CONFIG_SELECTION, "", 7, "", { 0 }, { - "onboard_ram", "Onboard RAM", CONFIG_SELECTION, "", 512, "", { 0 }, - { - { - "512 KB", 512 - }, - { - "1 MB", 1024 - }, - { - "2 MB", 2048 - }, - { - "4 MB", 4096 - }, - { - "8 MB", 8192 - }, - { - "12 MB", 12288 - }, - { - "16 MB", 16384 - }, - { - "20 MB", 20480 - }, - { - "24 MB", 24576 - }, - { - "28 MB", 28672 - }, - { - "" - } - } - }, - { - "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 - }, - { - "receive_input401", "Receive input (MPU-401)", CONFIG_BINARY, "", 0 - }, - { - "", "", -1 + { "IRQ 2", 2 }, + { "IRQ 3", 3 }, + { "IRQ 5", 5 }, + { "IRQ 7", 7 }, + { "" } } -}; - -static const device_config_t sb_awe64_config[] = -{ + }, + { "dma", "DMA", CONFIG_SELECTION, "", 1, "", { 0 }, { - "onboard_ram", "Onboard RAM", CONFIG_SELECTION, "", 1024, "", { 0 }, - { - { - "1 MB", 1024 - }, - { - "2 MB", 2048 - }, - { - "4 MB", 4096 - }, - { - "8 MB", 8192 - }, - { - "12 MB", 12288 - }, - { - "16 MB", 16384 - }, - { - "20 MB", 20480 - }, - { - "24 MB", 24576 - }, - { - "28 MB", 28672 - }, - { - "" - } - } - }, - { - "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 - }, - { - "receive_input401", "Receive input (MPU-401)", CONFIG_BINARY, "", 0 - }, - { - "", "", -1 + { "DMA 1", 1 }, + { "DMA 3", 3 }, + { "" } } + }, + { "opl", "Enable OPL", CONFIG_BINARY, "", 1 }, + { "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 }, + { "", "", -1 } }; -static const device_config_t sb_awe64_gold_config[] = -{ +static const device_config_t sb_pro_config[] = { + { "base", "Address", CONFIG_HEX16, "", 0x220, "", { 0 }, { - "onboard_ram", "Onboard RAM", CONFIG_SELECTION, "", 4096, "", { 0 }, - { - { - "4 MB", 4096 - }, - { - "8 MB", 8192 - }, - { - "12 MB", 12288 - }, - { - "16 MB", 16384 - }, - { - "20 MB", 20480 - }, - { - "24 MB", 24576 - }, - { - "28 MB", 28672 - }, - { - "" - } - } - }, - { - "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 - }, - { - "receive_input401", "Receive input (MPU-401)", CONFIG_BINARY, "", 0 - }, - { - "", "", -1 + { "0x220", 0x220 }, + { "0x240", 0x240 }, + { "" } } + }, + { "irq", "IRQ", CONFIG_SELECTION, "", 7, "", { 0 }, + { + { "IRQ 2", 2 }, + { "IRQ 5", 5 }, + { "IRQ 7", 7 }, + { "IRQ 10", 10 }, + { "" } + } + }, + { "dma", "DMA", CONFIG_SELECTION, "", 1, "", { 0 }, + { + { "DMA 0", 0 }, + { "DMA 1", 1 }, + { "DMA 3", 3 }, + { "" } + } + }, + { "opl", "Enable OPL", CONFIG_BINARY, "", 1 }, + { "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 }, + { "", "", -1 } }; -const device_t sb_1_device = -{ - "Sound Blaster v1.0", - "sb", - DEVICE_ISA, - 0, - sb_1_init, sb_close, NULL, { NULL }, - sb_speed_changed, - NULL, - sb_config +static const device_config_t sb_16_config[] = { + { "base", "Address", CONFIG_HEX16, "", 0x220, "", { 0 }, + { + { "0x220", 0x220 }, + { "0x240", 0x240 }, + { "0x260", 0x260 }, + { "0x280", 0x280 }, + { "" } + } + }, + { "base401", "MPU-401 Address", CONFIG_HEX16, "", 0x330, "", { 0 }, + { + { "Disabled", 0 }, + { "0x300", 0x300 }, + { "0x330", 0x330 }, + { "" } + } + }, + { "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, + { + { "IRQ 2", 2 }, + { "IRQ 5", 5 }, + { "IRQ 7", 7 }, + { "IRQ 10", 10 }, + { "" } + } + }, + { "dma", "Low DMA channel", CONFIG_SELECTION, "", 1, "", { 0 }, + { + { "DMA 0", 0 }, + { "DMA 1", 1 }, + { "DMA 3", 3 }, + { "" } + } + }, + { "dma16", "High DMA channel", CONFIG_SELECTION, "", 5, "", { 0 }, + { + { "DMA 5", 5 }, + { "DMA 6", 6 }, + { "DMA 7", 7 }, + { "" } + } + }, + { "opl", "Enable OPL", CONFIG_BINARY, "", 1 }, + { "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 }, + { "receive_input401", "Receive input (MPU-401)", CONFIG_BINARY, "", 0 }, + { "", "", -1 } }; -const device_t sb_15_device = -{ - "Sound Blaster v1.5", - "sb1.5", - DEVICE_ISA, - 0, - sb_15_init, sb_close, NULL, { NULL }, - sb_speed_changed, - NULL, - sb15_config +static const device_config_t sb_16_pnp_config[] = { + { "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 }, + { "receive_input401", "Receive input (MPU-401)", CONFIG_BINARY, "", 0 }, + { "", "", -1 } }; -const device_t sb_mcv_device = -{ - "Sound Blaster MCV", - "sbmcv", - DEVICE_MCA, - 0, - sb_mcv_init, sb_close, NULL, { NULL }, - sb_speed_changed, - NULL, - sb_mcv_config +static const device_config_t sb_32_pnp_config[] = { + { "onboard_ram", "Onboard RAM", CONFIG_SELECTION, "", 0, "", { 0 }, + { + { "None", 0 }, + { "512 KB", 512 }, + { "2 MB", 2048 }, + { "8 MB", 8192 }, + { "28 MB", 28672 }, + { "" } + } + }, + { "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 }, + { "receive_input401", "Receive input (MPU-401)", CONFIG_BINARY, "", 0 }, + { "", "", -1 } }; -const device_t sb_2_device = -{ - "Sound Blaster v2.0", - "sb2.0", - DEVICE_ISA, - 0, - sb_2_init, sb_close, NULL, { NULL }, - sb_speed_changed, - NULL, - sb2_config +static const device_config_t sb_awe32_config[] = { + { "base", "Address", CONFIG_HEX16, "", 0x220, "", { 0 }, + { + { "0x220", 0x220 }, + { "0x240", 0x240 }, + { "0x260", 0x260 }, + { "0x280", 0x280 }, + { "" } + } + }, + { "emu_base", "EMU8000 Address", CONFIG_HEX16, "", 0x620, "", { 0 }, + { + { "0x620", 0x620 }, + { "0x640", 0x640 }, + { "0x660", 0x660 }, + { "0x680", 0x680 }, + { .description = ""} + } + }, + { "base401", "MPU-401 Address", CONFIG_HEX16, "", 0x330, "", { 0 }, + { + { "Disabled", 0 }, + { "0x300", 0x300 }, + { "0x330", 0x330 }, + { "" } + } + }, + { "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, + { + { "IRQ 2", 2 }, + { "IRQ 5", 5 }, + { "IRQ 7", 7 }, + { "IRQ 10", 10 }, + { "" } + } + }, + { "dma", "Low DMA channel", CONFIG_SELECTION, "", 1, "", { 0 }, + { + { "DMA 0", 0 }, + { "DMA 1", 1 }, + { "DMA 3", 3 }, + { "" } + } + }, + { "dma16", "High DMA channel", CONFIG_SELECTION, "", 5, "", { 0 }, + { + { "DMA 5", 5 }, + { "DMA 6", 6 }, + { "DMA 7", 7 }, + { "" } + } + }, + { "onboard_ram", "Onboard RAM", CONFIG_SELECTION, "", 512, "", { 0 }, + { + { "None", 0 }, + { "512 KB", 512 }, + { "2 MB", 2048 }, + { "8 MB", 8192 }, + { "28 MB", 28672 }, + { "" } + } + }, + { "opl", "Enable OPL", CONFIG_BINARY, "", 1 }, + { "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 }, + { "receive_input401", "Receive input (MPU-401)", CONFIG_BINARY, "", 0 }, + { "", "", -1 } }; -const device_t sb_pro_v1_device = -{ - "Sound Blaster Pro v1", - "sbprov1", - DEVICE_ISA, - 0, - sb_pro_v1_init, sb_close, NULL, { NULL }, - sb_speed_changed, - NULL, - sb_pro_config +static const device_config_t sb_awe32_pnp_config[] = { + { "onboard_ram", "Onboard RAM", CONFIG_SELECTION, "", 512, "", { 0 }, + { + { "None", 0 }, + { "512 KB", 512 }, + { "2 MB", 2048 }, + { "8 MB", 8192 }, + { "28 MB", 28672 }, + { "" } + } + }, + { "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 }, + { "receive_input401", "Receive input (MPU-401)", CONFIG_BINARY, "", 0 }, + { "", "", -1 } }; -const device_t sb_pro_v2_device = -{ - "Sound Blaster Pro v2", - "sbprov2", - DEVICE_ISA, - 0, - sb_pro_v2_init, sb_close, NULL, { NULL }, - sb_speed_changed, - NULL, - sb_pro_config +static const device_config_t sb_awe64_value_config[] = { + { "onboard_ram", "Onboard RAM", CONFIG_SELECTION, "", 512, "", { 0 }, + { + { "512 KB", 512 }, + { "1 MB", 1024 }, + { "2 MB", 2048 }, + { "4 MB", 4096 }, + { "8 MB", 8192 }, + { "12 MB", 12288 }, + { "16 MB", 16384 }, + { "20 MB", 20480 }, + { "24 MB", 24576 }, + { "28 MB", 28672 }, + { "" } + } + }, + { "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 }, + { "receive_input401", "Receive input (MPU-401)", CONFIG_BINARY, "", 0 }, + { "", "", -1 } }; -const device_t sb_pro_mcv_device = -{ - "Sound Blaster Pro MCV", - "sbpromcv", - DEVICE_MCA, - 0, - sb_pro_mcv_init, sb_close, NULL, { NULL }, - sb_speed_changed, - NULL, - NULL +static const device_config_t sb_awe64_config[] = { + { "onboard_ram", "Onboard RAM", CONFIG_SELECTION, "", 1024, "", { 0 }, + { + { "1 MB", 1024 }, + { "2 MB", 2048 }, + { "4 MB", 4096 }, + { "8 MB", 8192 }, + { "12 MB", 12288 }, + { "16 MB", 16384 }, + { "20 MB", 20480 }, + { "24 MB", 24576 }, + { "28 MB", 28672 }, + { "" } + } + }, + { "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 }, + { "receive_input401", "Receive input (MPU-401)", CONFIG_BINARY, "", 0 }, + { "", "", -1 } }; -const device_t sb_pro_compat_device = -{ - "Sound Blaster Pro (Compatibility)", - "sbpro_compat", - DEVICE_ISA | DEVICE_AT, - 0, - sb_pro_compat_init, sb_close, NULL, { NULL }, - sb_speed_changed, - NULL, - NULL +static const device_config_t sb_awe64_gold_config[] = { + { "onboard_ram", "Onboard RAM", CONFIG_SELECTION, "", 4096, "", { 0 }, + { + { "4 MB", 4096 }, + { "8 MB", 8192 }, + { "12 MB", 12288 }, + { "16 MB", 16384 }, + { "20 MB", 20480 }, + { "24 MB", 24576 }, + { "28 MB", 28672 }, + { "" } + } + }, + { "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 }, + { "receive_input401", "Receive input (MPU-401)", CONFIG_BINARY, "", 0 }, + { "", "", -1 } +}; +// clang-format on + +const device_t sb_1_device = { + "Sound Blaster v1.0", + "sb", + DEVICE_ISA, + 0, + sb_1_init, + sb_close, + NULL, + { NULL }, + sb_speed_changed, + NULL, + sb_config }; -const device_t sb_16_device = -{ - "Sound Blaster 16", - "sb16", - DEVICE_ISA | DEVICE_AT, - 0, - sb_16_init, sb_close, NULL, { NULL }, - sb_speed_changed, - NULL, - sb_16_config +const device_t sb_15_device = { + "Sound Blaster v1.5", + "sb1.5", + DEVICE_ISA, + 0, + sb_15_init, + sb_close, + NULL, + { NULL }, + sb_speed_changed, + NULL, + sb15_config }; -const device_t sb_16_pnp_device = -{ - "Sound Blaster 16 PnP", - "sb16_pnp", - DEVICE_ISA | DEVICE_AT, - 0, - sb_16_pnp_init, sb_close, NULL, { NULL }, - sb_speed_changed, - NULL, - sb_16_pnp_config +const device_t sb_mcv_device = { + "Sound Blaster MCV", + "sbmcv", + DEVICE_MCA, + 0, + sb_mcv_init, + sb_close, + NULL, + { NULL }, + sb_speed_changed, + NULL, + sb_mcv_config }; -const device_t sb_32_pnp_device = -{ - "Sound Blaster 32 PnP", - "sb32_pnp", - DEVICE_ISA | DEVICE_AT, - 0, - sb_awe32_pnp_init, sb_awe32_close, NULL, - { sb_32_pnp_available }, - sb_speed_changed, - NULL, - sb_32_pnp_config +const device_t sb_2_device = { + "Sound Blaster v2.0", + "sb2.0", + DEVICE_ISA, + 0, + sb_2_init, + sb_close, + NULL, + { NULL }, + sb_speed_changed, + NULL, + sb2_config }; - -const device_t sb_awe32_device = -{ - "Sound Blaster AWE32", - "sbawe32", - DEVICE_ISA | DEVICE_AT, - 0, - sb_awe32_init, sb_awe32_close, NULL, - { sb_awe32_available }, - sb_speed_changed, - NULL, - sb_awe32_config +const device_t sb_pro_v1_device = { + "Sound Blaster Pro v1", + "sbprov1", + DEVICE_ISA, + 0, + sb_pro_v1_init, + sb_close, + NULL, + { NULL }, + sb_speed_changed, + NULL, + sb_pro_config }; -const device_t sb_awe32_pnp_device = -{ - "Sound Blaster AWE32 PnP", - "sbawe32_pnp", - DEVICE_ISA | DEVICE_AT, - 1, - sb_awe32_pnp_init, sb_awe32_close, NULL, - { sb_awe32_pnp_available }, - sb_speed_changed, - NULL, - sb_awe32_pnp_config +const device_t sb_pro_v2_device = { + "Sound Blaster Pro v2", + "sbprov2", + DEVICE_ISA, + 0, + sb_pro_v2_init, + sb_close, + NULL, + { NULL }, + sb_speed_changed, + NULL, + sb_pro_config }; -const device_t sb_awe64_value_device = -{ - "Sound Blaster AWE64 Value", - "sbawe64_value", - DEVICE_ISA | DEVICE_AT, - 2, - sb_awe32_pnp_init, sb_awe32_close, NULL, - { sb_awe64_value_available }, - sb_speed_changed, - NULL, - sb_awe64_value_config +const device_t sb_pro_mcv_device = { + "Sound Blaster Pro MCV", + "sbpromcv", + DEVICE_MCA, + 0, + sb_pro_mcv_init, + sb_close, + NULL, + { NULL }, + sb_speed_changed, + NULL, + NULL }; -const device_t sb_awe64_device = -{ - "Sound Blaster AWE64", - "sbawe64", - DEVICE_ISA | DEVICE_AT, - 3, - sb_awe32_pnp_init, sb_awe32_close, NULL, - { sb_awe64_available }, - sb_speed_changed, - NULL, - sb_awe64_config +const device_t sb_pro_compat_device = { + "Sound Blaster Pro (Compatibility)", + "sbpro_compat", + DEVICE_ISA | DEVICE_AT, + 0, + sb_pro_compat_init, + sb_close, + NULL, + { NULL }, + sb_speed_changed, + NULL, + NULL }; -const device_t sb_awe64_gold_device = -{ - "Sound Blaster AWE64 Gold", - "sbawe64_gold", - DEVICE_ISA | DEVICE_AT, - 4, - sb_awe32_pnp_init, sb_awe32_close, NULL, - { sb_awe64_gold_available }, - sb_speed_changed, - NULL, - sb_awe64_gold_config +const device_t sb_16_device = { + "Sound Blaster 16", + "sb16", + DEVICE_ISA | DEVICE_AT, + 0, + sb_16_init, + sb_close, + NULL, + { NULL }, + sb_speed_changed, + NULL, + sb_16_config +}; + +const device_t sb_16_pnp_device = { + "Sound Blaster 16 PnP", + "sb16_pnp", + DEVICE_ISA | DEVICE_AT, + 0, + sb_16_pnp_init, + sb_close, + NULL, + { NULL }, + sb_speed_changed, + NULL, + sb_16_pnp_config +}; + +const device_t sb_32_pnp_device = { + "Sound Blaster 32 PnP", + "sb32_pnp", + DEVICE_ISA | DEVICE_AT, + 0, + sb_awe32_pnp_init, + sb_awe32_close, + NULL, + { sb_32_pnp_available }, + sb_speed_changed, + NULL, + sb_32_pnp_config +}; + +const device_t sb_awe32_device = { + "Sound Blaster AWE32", + "sbawe32", + DEVICE_ISA | DEVICE_AT, + 0, + sb_awe32_init, + sb_awe32_close, + NULL, + { sb_awe32_available }, + sb_speed_changed, + NULL, + sb_awe32_config +}; + +const device_t sb_awe32_pnp_device = { + "Sound Blaster AWE32 PnP", + "sbawe32_pnp", + DEVICE_ISA | DEVICE_AT, + 1, + sb_awe32_pnp_init, + sb_awe32_close, + NULL, + { sb_awe32_pnp_available }, + sb_speed_changed, + NULL, + sb_awe32_pnp_config +}; + +const device_t sb_awe64_value_device = { + "Sound Blaster AWE64 Value", + "sbawe64_value", + DEVICE_ISA | DEVICE_AT, + 2, + sb_awe32_pnp_init, + sb_awe32_close, + NULL, + { sb_awe64_value_available }, + sb_speed_changed, + NULL, + sb_awe64_value_config +}; + +const device_t sb_awe64_device = { + "Sound Blaster AWE64", + "sbawe64", + DEVICE_ISA | DEVICE_AT, + 3, + sb_awe32_pnp_init, + sb_awe32_close, + NULL, + { sb_awe64_available }, + sb_speed_changed, + NULL, + sb_awe64_config +}; + +const device_t sb_awe64_gold_device = { + "Sound Blaster AWE64 Gold", + "sbawe64_gold", + DEVICE_ISA | DEVICE_AT, + 4, + sb_awe32_pnp_init, + sb_awe32_close, + NULL, + { sb_awe64_gold_available }, + sb_speed_changed, + NULL, + sb_awe64_gold_config }; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 17f7ae979..59f384e2a 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -9,27 +9,26 @@ #include #include #include -#include #include +#include #include #define HAVE_STDARG_H + #include <86box/86box.h> -#include <86box/io.h> -#include <86box/pic.h> -#include <86box/dma.h> -#include <86box/timer.h> #include <86box/device.h> +#include <86box/dma.h> #include <86box/filters.h> -#include <86box/sound.h> +#include <86box/io.h> #include <86box/midi.h> -#include <86box/sound.h> +#include <86box/pic.h> #include <86box/snd_azt2316a.h> +#include <86box/sound.h> +#include <86box/timer.h> #include <86box/snd_sb.h> - -#define ADPCM_4 1 -#define ADPCM_26 2 -#define ADPCM_2 3 +#define ADPCM_4 1 +#define ADPCM_26 2 +#define ADPCM_2 3 /*The recording safety margin is intended for uneven "len" calls to the get_buffer mixer calls on sound_sb*/ #define SB_DSP_REC_SAFEFTY_MARGIN 4096 @@ -38,66 +37,63 @@ void pollsb(void *p); void sb_poll_i(void *p); static int sbe2dat[4][9] = { - { 0x01, -0x02, -0x04, 0x08, -0x10, 0x20, 0x40, -0x80, -106 }, - { -0x01, 0x02, -0x04, 0x08, 0x10, -0x20, 0x40, -0x80, 165 }, - { -0x01, 0x02, 0x04, -0x08, 0x10, -0x20, -0x40, 0x80, -151 }, - { 0x01, -0x02, 0x04, -0x08, -0x10, 0x20, -0x40, 0x80, 90 } + {0x01, -0x02, -0x04, 0x08, -0x10, 0x20, 0x40, -0x80, -106}, + { -0x01, 0x02, -0x04, 0x08, 0x10, -0x20, 0x40, -0x80, 165 }, + { -0x01, 0x02, 0x04, -0x08, 0x10, -0x20, -0x40, 0x80, -151}, + { 0x01, -0x02, 0x04, -0x08, -0x10, 0x20, -0x40, 0x80, 90 } }; -static int sb_commands[256]= -{ - -1, 2,-1, 0, 1, 2,-1, 0, 1,-1,-1,-1,-1,-1, 2, 1, - 1,-1,-1,-1, 2,-1, 2, 2,-1,-1,-1,-1, 0,-1,-1, 0, - 0,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1, 0,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - 1, 2, 2,-1,-1,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1, 2, 2, 2, 2,-1,-1,-1,-1,-1, 0,-1, 0, - 2, 2,-1,-1,-1,-1,-1,-1, 2, 2,-1,-1,-1,-1,-1,-1, - 0,-1,-1,-1,-1,-1,-1,-1, 0,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 0, 0,-1, 0, 0, 0, 0,-1, 0, 0, 0,-1,-1,-1,-1,-1, - 1, 0, 1, 0, 1,-1,-1, 0, 0,-1,-1,-1,-1,-1,-1,-1, - -1,-1, 0, 0,-1,-1,-1,-1,-1, 1, 2,-1,-1,-1,-1, 0 +static int sb_commands[256] = { + -1, 2, -1, 0, 1, 2, -1, 0, 1, -1, -1, -1, -1, -1, 2, 1, + 1, -1, -1, -1, 2, -1, 2, 2, -1, -1, -1, -1, 0, -1, -1, 0, + 0, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 2, 2, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 2, 2, 2, 2, -1, -1, -1, -1, -1, 0, -1, 0, + 2, 2, -1, -1, -1, -1, -1, -1, 2, 2, -1, -1, -1, -1, -1, -1, + 0, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, -1, -1, -1, -1, -1, + 1, 0, 1, 0, 1, -1, -1, 0, 0, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 0, 0, -1, -1, -1, -1, -1, 1, 2, -1, -1, -1, -1, 0 }; - -char sb16_copyright[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992."; -uint16_t sb_dsp_versions[] = {0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405, 0x40d, 0x410}; - +char sb16_copyright[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992."; +uint16_t sb_dsp_versions[] = { 0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405, 0x40d, 0x410 }; /*These tables were 'borrowed' from DOSBox*/ int8_t scaleMap4[64] = { - 0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7, - 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15, - 2, 6, 10, 14, 18, 22, 26, 30, -2, -6, -10, -14, -18, -22, -26, -30, + 0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7, + 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15, + 2, 6, 10, 14, 18, 22, 26, 30, -2, -6, -10, -14, -18, -22, -26, -30, 4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60 }; uint8_t adjustMap4[64] = { - 0, 0, 0, 0, 0, 16, 16, 16, - 0, 0, 0, 0, 0, 16, 16, 16, + 0, 0, 0, 0, 0, 16, 16, 16, + 0, 0, 0, 0, 0, 16, 16, 16, 240, 0, 0, 0, 0, 16, 16, 16, 240, 0, 0, 0, 0, 16, 16, 16, 240, 0, 0, 0, 0, 16, 16, 16, 240, 0, 0, 0, 0, 16, 16, 16, - 240, 0, 0, 0, 0, 0, 0, 0, - 240, 0, 0, 0, 0, 0, 0, 0 + 240, 0, 0, 0, 0, 0, 0, 0, + 240, 0, 0, 0, 0, 0, 0, 0 }; int8_t scaleMap26[40] = { - 0, 1, 2, 3, 0, -1, -2, -3, - 1, 3, 5, 7, -1, -3, -5, -7, - 2, 6, 10, 14, -2, -6, -10, -14, + 0, 1, 2, 3, 0, -1, -2, -3, + 1, 3, 5, 7, -1, -3, -5, -7, + 2, 6, 10, 14, -2, -6, -10, -14, 4, 12, 20, 28, -4, -12, -20, -28, 5, 15, 25, 35, -5, -15, -25, -35 }; uint8_t adjustMap26[40] = { - 0, 0, 0, 8, 0, 0, 0, 8, + 0, 0, 0, 8, 0, 0, 0, 8, 248, 0, 0, 8, 248, 0, 0, 8, 248, 0, 0, 8, 248, 0, 0, 8, 248, 0, 0, 8, 248, 0, 0, 8, @@ -105,13 +101,13 @@ uint8_t adjustMap26[40] = { }; int8_t scaleMap2[24] = { - 0, 1, 0, -1, 1, 3, -1, -3, - 2, 6, -2, -6, 4, 12, -4, -12, + 0, 1, 0, -1, 1, 3, -1, -3, + 2, 6, -2, -6, 4, 12, -4, -12, 8, 24, -8, -24, 6, 48, -16, -48 }; uint8_t adjustMap2[24] = { - 0, 4, 0, 4, + 0, 4, 0, 4, 252, 4, 252, 4, 252, 4, 252, 4, 252, 4, 252, 4, 252, 4, 252, 4, 252, 0, 252, 0 @@ -119,27 +115,24 @@ uint8_t adjustMap2[24] = { double low_fir_sb16_coef[2][SB16_NCoef]; - #ifdef ENABLE_SB_DSP_LOG int sb_dsp_do_log = ENABLE_SB_DSP_LOG; - static void sb_dsp_log(const char *fmt, ...) { va_list ap; if (sb_dsp_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define sb_dsp_log(fmt, ...) +# define sb_dsp_log(fmt, ...) #endif - static __inline double sinc(double x) { @@ -150,95 +143,90 @@ static void recalc_sb16_filter(int c, int playback_freq) { /* Cutoff frequency = playback / 2 */ - int n; + int n; double w, h; double fC = ((double) playback_freq) / 96000.0; double gain; for (n = 0; n < SB16_NCoef; n++) { - /* Blackman window */ - w = 0.42 - (0.5 * cos((2.0*n*M_PI)/(double)(SB16_NCoef-1))) + (0.08 * cos((4.0*n*M_PI)/(double)(SB16_NCoef-1))); - /* Sinc filter */ - h = sinc(2.0 * fC * ((double)n - ((double)(SB16_NCoef-1) / 2.0))); + /* Blackman window */ + w = 0.42 - (0.5 * cos((2.0 * n * M_PI) / (double) (SB16_NCoef - 1))) + (0.08 * cos((4.0 * n * M_PI) / (double) (SB16_NCoef - 1))); + /* Sinc filter */ + h = sinc(2.0 * fC * ((double) n - ((double) (SB16_NCoef - 1) / 2.0))); - /* Create windowed-sinc filter */ - low_fir_sb16_coef[c][n] = w * h; + /* Create windowed-sinc filter */ + low_fir_sb16_coef[c][n] = w * h; } low_fir_sb16_coef[c][(SB16_NCoef - 1) / 2] = 1.0; gain = 0.0; for (n = 0; n < SB16_NCoef; n++) - gain += low_fir_sb16_coef[c][n]; + gain += low_fir_sb16_coef[c][n]; /* Normalise filter, to produce unity gain */ for (n = 0; n < SB16_NCoef; n++) - low_fir_sb16_coef[c][n] /= gain; + low_fir_sb16_coef[c][n] /= gain; } - void sb_update_mask(sb_dsp_t *dsp, int irqm8, int irqm16, int irqm401) { int clear = 0; if (!dsp->sb_irqm8 && irqm8) - clear |= 1; + clear |= 1; dsp->sb_irqm8 = irqm8; if (!dsp->sb_irqm16 && irqm16) - clear |= 1; + clear |= 1; dsp->sb_irqm16 = irqm16; if (!dsp->sb_irqm401 && irqm401) - clear |= 1; + clear |= 1; dsp->sb_irqm401 = irqm401; if (clear) - picintc(1 << dsp->sb_irqnum); + picintc(1 << dsp->sb_irqnum); } - void sb_update_status(sb_dsp_t *dsp, int bit, int set) { int masked = 0; switch (bit) { - case 0: - default: - dsp->sb_irq8 = set; - masked = dsp->sb_irqm8; - break; - case 1: - dsp->sb_irq16 = set; - masked = dsp->sb_irqm16; - break; - case 2: - dsp->sb_irq401 = set; - masked = dsp->sb_irqm401; - break; + case 0: + default: + dsp->sb_irq8 = set; + masked = dsp->sb_irqm8; + break; + case 1: + dsp->sb_irq16 = set; + masked = dsp->sb_irqm16; + break; + case 2: + dsp->sb_irq401 = set; + masked = dsp->sb_irqm401; + break; } if (set && !masked) - picint(1 << dsp->sb_irqnum); + picint(1 << dsp->sb_irqnum); else if (!set) - picintc(1 << dsp->sb_irqnum); + picintc(1 << dsp->sb_irqnum); } - void sb_irq(sb_dsp_t *dsp, int irq8) { sb_update_status(dsp, !irq8, 1); } - void sb_irqc(sb_dsp_t *dsp, int irq8) { sb_update_status(dsp, !irq8, 0); } - static void sb_dsp_irq_update(void *priv, int set) { @@ -247,7 +235,6 @@ sb_dsp_irq_update(void *priv, int set) sb_update_status(dsp, 2, set); } - static int sb_dsp_irq_pending(void *priv) { @@ -256,17 +243,15 @@ sb_dsp_irq_pending(void *priv) return dsp->sb_irq401; } - void sb_dsp_set_mpu(sb_dsp_t *dsp, mpu_t *mpu) { dsp->mpu = mpu; if (mpu != NULL) - mpu401_irq_attach(mpu, sb_dsp_irq_update, sb_dsp_irq_pending, dsp); + mpu401_irq_attach(mpu, sb_dsp_irq_update, sb_dsp_irq_pending, dsp); } - void sb_dsp_reset(sb_dsp_t *dsp) { @@ -277,23 +262,23 @@ sb_dsp_reset(sb_dsp_t *dsp) dsp->sb_command = 0; - dsp->sb_8_length = 0xffff; + dsp->sb_8_length = 0xffff; dsp->sb_8_autolen = 0xffff; - dsp->sb_irq8 = 0; - dsp->sb_irq16 = 0; - dsp->sb_irq401 = 0; + dsp->sb_irq8 = 0; + dsp->sb_irq16 = 0; + dsp->sb_irq401 = 0; dsp->sb_16_pause = 0; dsp->sb_read_wp = dsp->sb_read_rp = 0; - dsp->sb_data_stat = -1; - dsp->sb_speaker = 0; - dsp->sb_pausetime = -1LL; - dsp->sbe2 = 0xAA; - dsp->sbe2count = 0; + dsp->sb_data_stat = -1; + dsp->sb_speaker = 0; + dsp->sb_pausetime = -1LL; + dsp->sbe2 = 0xAA; + dsp->sbe2count = 0; dsp->sbreset = 0; - dsp->record_pos_read = 0; + dsp->record_pos_read = 0; dsp->record_pos_write = SB_DSP_REC_SAFEFTY_MARGIN; picintc(1 << dsp->sb_irqnum); @@ -301,7 +286,6 @@ sb_dsp_reset(sb_dsp_t *dsp) dsp->asp_data_len = 0; } - void sb_doreset(sb_dsp_t *dsp) { @@ -309,42 +293,39 @@ sb_doreset(sb_dsp_t *dsp) sb_dsp_reset(dsp); - if (IS_AZTECH(dsp)) { - sb_commands[8] = 1; - sb_commands[9] = 1; + sb_commands[8] = 1; + sb_commands[9] = 1; } else { - if (dsp->sb_type >= SB16) - sb_commands[8] = 1; - else - sb_commands[8] = -1; + if (dsp->sb_type >= SB16) + sb_commands[8] = 1; + else + sb_commands[8] = -1; } - dsp->sb_asp_mode = 0; + dsp->sb_asp_mode = 0; dsp->sb_asp_ram_index = 0; for (c = 0; c < 256; c++) - dsp->sb_asp_regs[c] = 0; + dsp->sb_asp_regs[c] = 0; dsp->sb_asp_regs[5] = 0x01; dsp->sb_asp_regs[9] = 0xf8; } - void sb_dsp_speed_changed(sb_dsp_t *dsp) { if (dsp->sb_timeo < 256) - dsp->sblatcho = TIMER_USEC * (256 - dsp->sb_timeo); + dsp->sblatcho = TIMER_USEC * (256 - dsp->sb_timeo); else - dsp->sblatcho = (uint64_t)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timeo - 256))); + dsp->sblatcho = (uint64_t) (TIMER_USEC * (1000000.0f / (float) (dsp->sb_timeo - 256))); if (dsp->sb_timei < 256) - dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_timei); + dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_timei); else - dsp->sblatchi = (uint64_t)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timei - 256))); + dsp->sblatchi = (uint64_t) (TIMER_USEC * (1000000.0f / (float) (dsp->sb_timei - 256))); } - void sb_add_data(sb_dsp_t *dsp, uint8_t v) { @@ -352,92 +333,87 @@ sb_add_data(sb_dsp_t *dsp, uint8_t v) dsp->sb_read_wp &= 0xff; } - void sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) { dsp->sb_pausetime = -1; if (dma8) { - dsp->sb_8_length = len; - dsp->sb_8_format = format; - dsp->sb_8_autoinit = autoinit; - dsp->sb_8_pause = 0; - dsp->sb_8_enable = 1; + dsp->sb_8_length = len; + dsp->sb_8_format = format; + dsp->sb_8_autoinit = autoinit; + dsp->sb_8_pause = 0; + dsp->sb_8_enable = 1; - if (dsp->sb_16_enable && dsp->sb_16_output) - dsp->sb_16_enable = 0; - dsp->sb_8_output = 1; - if (!timer_is_enabled(&dsp->output_timer)) - timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); - dsp->sbleftright = 0; - dsp->sbdacpos = 0; + if (dsp->sb_16_enable && dsp->sb_16_output) + dsp->sb_16_enable = 0; + dsp->sb_8_output = 1; + if (!timer_is_enabled(&dsp->output_timer)) + timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); + dsp->sbleftright = 0; + dsp->sbdacpos = 0; } else { - dsp->sb_16_length = len; - dsp->sb_16_format = format; - dsp->sb_16_autoinit = autoinit; - dsp->sb_16_pause = 0; - dsp->sb_16_enable = 1; - if (dsp->sb_8_enable && dsp->sb_8_output) dsp->sb_8_enable = 0; - dsp->sb_16_output = 1; - if (!timer_is_enabled(&dsp->output_timer)) - timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); + dsp->sb_16_length = len; + dsp->sb_16_format = format; + dsp->sb_16_autoinit = autoinit; + dsp->sb_16_pause = 0; + dsp->sb_16_enable = 1; + if (dsp->sb_8_enable && dsp->sb_8_output) + dsp->sb_8_enable = 0; + dsp->sb_16_output = 1; + if (!timer_is_enabled(&dsp->output_timer)) + timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); } } - void sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) { if (dma8) { - dsp->sb_8_length = len; - dsp->sb_8_format = format; - dsp->sb_8_autoinit = autoinit; - dsp->sb_8_pause = 0; - dsp->sb_8_enable = 1; - if (dsp->sb_16_enable && !dsp->sb_16_output) - dsp->sb_16_enable = 0; - dsp->sb_8_output = 0; - if (!timer_is_enabled(&dsp->input_timer)) - timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); + dsp->sb_8_length = len; + dsp->sb_8_format = format; + dsp->sb_8_autoinit = autoinit; + dsp->sb_8_pause = 0; + dsp->sb_8_enable = 1; + if (dsp->sb_16_enable && !dsp->sb_16_output) + dsp->sb_16_enable = 0; + dsp->sb_8_output = 0; + if (!timer_is_enabled(&dsp->input_timer)) + timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); } else { - dsp->sb_16_length = len; - dsp->sb_16_format = format; - dsp->sb_16_autoinit = autoinit; - dsp->sb_16_pause = 0; - dsp->sb_16_enable = 1; - if (dsp->sb_8_enable && !dsp->sb_8_output) - dsp->sb_8_enable = 0; - dsp->sb_16_output = 0; - if (!timer_is_enabled(&dsp->input_timer)) - timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); + dsp->sb_16_length = len; + dsp->sb_16_format = format; + dsp->sb_16_autoinit = autoinit; + dsp->sb_16_pause = 0; + dsp->sb_16_enable = 1; + if (dsp->sb_8_enable && !dsp->sb_8_output) + dsp->sb_8_enable = 0; + dsp->sb_16_output = 0; + if (!timer_is_enabled(&dsp->input_timer)) + timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); } - memset(dsp->record_buffer,0,sizeof(dsp->record_buffer)); + memset(dsp->record_buffer, 0, sizeof(dsp->record_buffer)); } - int sb_8_read_dma(sb_dsp_t *dsp) { return dma_channel_read(dsp->sb_8_dmanum); } - void sb_8_write_dma(sb_dsp_t *dsp, uint8_t val) { dma_channel_write(dsp->sb_8_dmanum, val); } - int sb_16_read_dma(sb_dsp_t *dsp) { return dma_channel_read(dsp->sb_16_dmanum); } - int sb_16_write_dma(sb_dsp_t *dsp, uint16_t val) { @@ -446,21 +422,18 @@ sb_16_write_dma(sb_dsp_t *dsp, uint16_t val) return (ret == DMA_NODATA); } - void sb_dsp_setirq(sb_dsp_t *dsp, int irq) { dsp->sb_irqnum = irq; } - void sb_dsp_setdma8(sb_dsp_t *dsp, int dma) { dsp->sb_8_dmanum = dma; } - void sb_dsp_setdma16(sb_dsp_t *dsp, int dma) { @@ -474,627 +447,647 @@ sb_exec_command(sb_dsp_t *dsp) sb_dsp_log("sb_exec_command : SB command %02X\n", dsp->sb_command); - /* Update 8051 ram with the current DSP command. See https://github.com/joncampbell123/dosbox-x/issues/1044 */ if (dsp->sb_type >= SB16) - dsp->sb_8051_ram[0x20] = dsp->sb_command; + dsp->sb_8051_ram[0x20] = dsp->sb_command; switch (dsp->sb_command) { - case 0x01: /* ???? */ - if (dsp->sb_type >= SB16) - dsp->asp_data_len = dsp->sb_data[0] + (dsp->sb_data[1] << 8) + 1; - break; - case 0x03: /* ASP status */ - if (dsp->sb_type >= SB16) - sb_add_data(dsp, 0); - break; - case 0x10: /* 8-bit direct mode */ - sb_dsp_update(dsp); - dsp->sbdat = dsp->sbdatl = dsp->sbdatr = (dsp->sb_data[0] ^ 0x80) << 8; - break; - case 0x14: /* 8-bit single cycle DMA output */ - sb_start_dma(dsp, 1, 0, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - break; - case 0x17: /* 2-bit ADPCM output with reference */ - dsp->sbref = sb_8_read_dma(dsp); - dsp->sbstep = 0; - /* Fall through */ - case 0x16: /* 2-bit ADPCM output */ - sb_start_dma(dsp, 1, 0, ADPCM_2, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - dsp->sbdat2 = sb_8_read_dma(dsp); - dsp->sb_8_length--; - if (dsp->sb_command == 0x17) - dsp->sb_8_length--; - break; - case 0x1C: /* 8-bit autoinit DMA output */ - if (dsp->sb_type >= SB15) - sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen); - break; - case 0x1F: /* 2-bit ADPCM autoinit output */ - if (dsp->sb_type >= SB15) { - sb_start_dma(dsp, 1, 1, ADPCM_2, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - dsp->sbdat2 = sb_8_read_dma(dsp); - dsp->sb_8_length--; - } - break; - case 0x20: /* 8-bit direct input */ - sb_add_data(dsp, (dsp->record_buffer[dsp->record_pos_read]>>8) ^0x80); - /* Due to the current implementation, I need to emulate a samplerate, even if this - mode does not imply such samplerate. Position is increased in sb_poll_i(). */ - if (!timer_is_enabled(&dsp->input_timer)) { - dsp->sb_timei = 256 - 22; - dsp->sblatchi = TIMER_USEC * 22; - temp = 1000000 / 22; - dsp->sb_freq = temp; - timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); - } - break; - case 0x24: /* 8-bit single cycle DMA input */ - sb_start_dma_i(dsp, 1, 0, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - break; - case 0x28: /* Direct ADC, 8-bit (Burst) */ - break; - case 0x2C: /* 8-bit autoinit DMA input */ - if (dsp->sb_type >= SB15) - sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - break; - case 0x30: /* MIDI Polling mode input */ - sb_dsp_log("MIDI polling mode input\n"); - dsp->midi_in_poll = 1; - dsp->uart_irq = 0; - break; - case 0x31: /* MIDI Interrupt mode input */ - sb_dsp_log("MIDI interrupt mode input\n"); - dsp->midi_in_poll = 0; - dsp->uart_irq = 1; - break; - case 0x32: /* MIDI Read Timestamp Poll */ - break; - case 0x33: /* MIDI Read Timestamp Interrupt */ - break; - case 0x34: /* MIDI In poll */ - if (dsp->sb_type < SB2) - break; - sb_dsp_log("MIDI poll in\n"); - dsp->midi_in_poll = 1; - dsp->uart_midi = 1; - dsp->uart_irq = 0; - break; - case 0x35: /* MIDI In irq */ - if (dsp->sb_type < SB2) - break; - sb_dsp_log("MIDI irq in\n"); - dsp->midi_in_poll = 0; - dsp->uart_midi = 1; - dsp->uart_irq = 1; - break; - case 0x36: case 0x37: /* MIDI timestamps */ - break; - case 0x38: /* Write to SB MIDI Output (Raw) */ - dsp->onebyte_midi = 1; - break; - case 0x40: /* Set time constant */ - dsp->sb_timei = dsp->sb_timeo = dsp->sb_data[0]; - dsp->sblatcho = dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_data[0]); - temp = 256 - dsp->sb_data[0]; - temp = 1000000 / temp; - sb_dsp_log("Sample rate - %ihz (%i)\n",temp, dsp->sblatcho); - if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16)) - recalc_sb16_filter(0, temp); - dsp->sb_freq = temp; - break; - case 0x41: /* Set output sampling rate */ - case 0x42: /* Set input sampling rate */ - if (dsp->sb_type >= SB16) { - dsp->sblatcho = (uint64_t)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_data[1] + (dsp->sb_data[0] << 8)))); - sb_dsp_log("Sample rate - %ihz (%i)\n",dsp->sb_data[1]+(dsp->sb_data[0]<<8), dsp->sblatcho); - temp = dsp->sb_freq; - dsp->sb_freq = dsp->sb_data[1] + (dsp->sb_data[0] << 8); - dsp->sb_timeo = 256LL + dsp->sb_freq; - dsp->sblatchi = dsp->sblatcho; - dsp->sb_timei = dsp->sb_timeo; - if (dsp->sb_freq != temp && dsp->sb_type >= SB16) - recalc_sb16_filter(0, dsp->sb_freq); - dsp->sb_8051_ram[0x13] = dsp->sb_freq & 0xff; - dsp->sb_8051_ram[0x14] = (dsp->sb_freq >> 8) & 0xff; - } - break; - case 0x45: /* Continue Auto-Initialize DMA, 8-bit */ - break; - case 0x47: /* Continue Auto-Initialize DMA, 16-bit */ - break; - case 0x48: /* Set DSP block transfer size */ - dsp->sb_8_autolen = dsp->sb_data[0] + (dsp->sb_data[1] << 8); - break; - case 0x75: /* 4-bit ADPCM output with reference */ - dsp->sbref = sb_8_read_dma(dsp); - dsp->sbstep = 0; - /* Fall through */ - case 0x74: /* 4-bit ADPCM output */ - sb_start_dma(dsp, 1, 0, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - dsp->sbdat2 = sb_8_read_dma(dsp); - dsp->sb_8_length--; - if (dsp->sb_command == 0x75) - dsp->sb_8_length--; - break; - case 0x77: /* 2.6-bit ADPCM output with reference */ - dsp->sbref = sb_8_read_dma(dsp); - dsp->sbstep = 0; - /* Fall through */ - case 0x76: /* 2.6-bit ADPCM output */ - sb_start_dma(dsp, 1, 0, ADPCM_26, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - dsp->sbdat2 = sb_8_read_dma(dsp); - dsp->sb_8_length--; - if (dsp->sb_command == 0x77) - dsp->sb_8_length--; - break; - case 0x7D: /* 4-bit ADPCM autoinit output */ - if (dsp->sb_type >= SB15) { - sb_start_dma(dsp, 1, 1, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - dsp->sbdat2 = sb_8_read_dma(dsp); - dsp->sb_8_length--; - } - break; - case 0x7F: /* 2.6-bit ADPCM autoinit output */ - if (dsp->sb_type >= SB15) { - sb_start_dma(dsp, 1, 1, ADPCM_26, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); - dsp->sbdat2 = sb_8_read_dma(dsp); - dsp->sb_8_length--; - } - break; - case 0x80: /* Pause DAC */ - dsp->sb_pausetime = dsp->sb_data[0] + (dsp->sb_data[1] << 8); - if (!timer_is_enabled(&dsp->output_timer)) - timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); - break; - case 0x90: /* High speed 8-bit autoinit DMA output */ - if (dsp->sb_type >= SB2) - sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen); - break; - case 0x91: /* High speed 8-bit single cycle DMA output */ - if (dsp->sb_type >= SB2) - sb_start_dma(dsp, 1, 0, 0, dsp->sb_8_autolen); - break; - case 0x98: /* High speed 8-bit autoinit DMA input */ - if (dsp->sb_type >= SB2) - sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_8_autolen); - break; - case 0x99: /* High speed 8-bit single cycle DMA input */ - if (dsp->sb_type >= SB2) - sb_start_dma_i(dsp, 1, 0, 0, dsp->sb_8_autolen); - break; - case 0xA0: /* Set input mode to mono */ - case 0xA8: /* Set input mode to stereo */ - if ((dsp->sb_type < SB2) || (dsp->sb_type > SBPRO2)) - break; - /* TODO: Implement. 3.xx-only command. */ - break; - case 0xB0: case 0xB1: case 0xB2: case 0xB3: - case 0xB4: case 0xB5: case 0xB6: case 0xB7: /* 16-bit DMA output */ - if (dsp->sb_type >= SB16) { - sb_start_dma(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); - dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); - } - break; - case 0xB8: case 0xB9: case 0xBA: case 0xBB: - case 0xBC: case 0xBD: case 0xBE: case 0xBF: /* 16-bit DMA input */ - if (dsp->sb_type >= SB16) { - sb_start_dma_i(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); - dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); - } - break; - case 0xC0: case 0xC1: case 0xC2: case 0xC3: - case 0xC4: case 0xC5: case 0xC6: case 0xC7: /* 8-bit DMA output */ - if (dsp->sb_type >= SB16) { - sb_start_dma(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); - dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); - } - break; - case 0xC8: case 0xC9: case 0xCA: case 0xCB: - case 0xCC: case 0xCD: case 0xCE: case 0xCF: /* 8-bit DMA input */ - if (dsp->sb_type >= SB16) { - sb_start_dma_i(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); - dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); - } - break; - case 0xD0: /* Pause 8-bit DMA */ - dsp->sb_8_pause = 1; - break; - case 0xD1: /* Speaker on */ - if (dsp->sb_type < SB15) - dsp->sb_8_pause = 1; - else if (dsp->sb_type < SB16) - dsp->muted = 0; - dsp->sb_speaker = 1; - break; - case 0xD3: /* Speaker off */ - if (dsp->sb_type < SB15 ) - dsp->sb_8_pause = 1; - else if (dsp->sb_type < SB16) - dsp->muted = 1; - dsp->sb_speaker = 0; - break; - case 0xD4: /* Continue 8-bit DMA */ - dsp->sb_8_pause = 0; - break; - case 0xD5: /* Pause 16-bit DMA */ - if (dsp->sb_type >= SB16) - dsp->sb_16_pause = 1; - break; - case 0xD6: /* Continue 16-bit DMA */ - if (dsp->sb_type >= SB16) - dsp->sb_16_pause = 0; - break; - case 0xD8: /* Get speaker status */ - sb_add_data(dsp, dsp->sb_speaker ? 0xff : 0); - break; - case 0xD9: /* Exit 16-bit auto-init mode */ - if (dsp->sb_type >= SB16) - dsp->sb_16_autoinit = 0; - break; - case 0xDA: /* Exit 8-bit auto-init mode */ - dsp->sb_8_autoinit = 0; - break; - case 0xE0: /* DSP identification */ - sb_add_data(dsp, ~dsp->sb_data[0]); - break; - case 0xE1: /* Get DSP version */ - if (IS_AZTECH(dsp)) { - if (dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11) { - sb_add_data(dsp, 0x3); - sb_add_data(dsp, 0x1); - } else if (dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) { - sb_add_data(dsp, 0x2); - sb_add_data(dsp, 0x1); - } - break; - } - sb_add_data(dsp, sb_dsp_versions[dsp->sb_type] >> 8); - sb_add_data(dsp, sb_dsp_versions[dsp->sb_type] & 0xff); - break; - case 0xE2: /* Stupid ID/protection */ - for (c = 0; c < 8; c++) { - if (dsp->sb_data[0] & (1 << c)) - dsp->sbe2 += sbe2dat[dsp->sbe2count & 3][c]; - } - dsp->sbe2 += sbe2dat[dsp->sbe2count & 3][8]; - dsp->sbe2count++; - sb_8_write_dma(dsp, dsp->sbe2); - break; - case 0xE3: /* DSP copyright */ - if (dsp->sb_type >= SB16) { - c = 0; - while (sb16_copyright[c]) - sb_add_data(dsp, sb16_copyright[c++]); - sb_add_data(dsp, 0); - } - break; - case 0xE4: /* Write test register */ - dsp->sb_test = dsp->sb_data[0]; - break; - case 0xE8: /* Read test register */ - sb_add_data(dsp, dsp->sb_test); - break; - case 0xF2: /* Trigger 8-bit IRQ */ - sb_dsp_log("Trigger IRQ\n"); - sb_irq(dsp, 1); - break; - case 0xF3: /* Trigger 16-bit IRQ */ - sb_dsp_log("Trigger IRQ\n"); - sb_irq(dsp, 0); - break; - case 0xE7: /* ???? */ - break; - case 0x07: case 0xFF: /* No, that's not how you program auto-init DMA */ - break; - case 0x08: /* ASP get version / AZTECH type/EEPROM access */ - if (IS_AZTECH(dsp)) { - if ((dsp->sb_data[0] == 0x05 || dsp->sb_data[0] == 0x55)&& dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11) - sb_add_data(dsp, 0x11); /* AZTECH get type, WASHINGTON/latest - according to devkit. E.g.: The one in the Itautec Infoway Multimidia */ - else if ((dsp->sb_data[0] == 0x05 || dsp->sb_data[0] == 0x55) && dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) - sb_add_data(dsp, 0x0C); /* AZTECH get type, CLINTON - according to devkit. E.g.: The one in the Packard Bell Legend 100CD */ - else if (dsp->sb_data[0] == 0x08) { - /* EEPROM address to write followed by byte */ - if (dsp->sb_data[1] < 0 || dsp->sb_data[1] >= AZTECH_EEPROM_SIZE) - fatal("AZT EEPROM: out of bounds write to %02X\n", dsp->sb_data[1]); - sb_dsp_log("EEPROM write = %02x\n", dsp->sb_data[2]); - dsp->azt_eeprom[dsp->sb_data[1]] = dsp->sb_data[2]; - break; - } else if (dsp->sb_data[0] == 0x07) { - /* EEPROM address to read */ - if (dsp->sb_data[1] < 0 || dsp->sb_data[1] >= AZTECH_EEPROM_SIZE) - fatal("AZT EEPROM: out of bounds read to %02X\n", dsp->sb_data[1]); - sb_dsp_log("EEPROM read = %02x\n", dsp->azt_eeprom[dsp->sb_data[1]]); - sb_add_data(dsp, dsp->azt_eeprom[dsp->sb_data[1]]); - break; - } else - sb_dsp_log("AZT2316A: UNKNOWN 0x08 COMMAND: %02X\n", dsp->sb_data[0]); /* 0x08 (when shutting down, driver tries to read 1 byte of response), 0x55, 0x0D, 0x08D seen */ - break; - } - if (dsp->sb_type == SBAWE64) /* AWE64 has no ASP or a socket for it */ - sb_add_data(dsp, 0xFF); - else if (dsp->sb_type >= SB16) - sb_add_data(dsp, 0x18); - break; - case 0x0E: /* ASP set register */ - if (dsp->sb_type >= SB16) { - dsp->sb_asp_regs[dsp->sb_data[0]] = dsp->sb_data[1]; + case 0x01: /* ???? */ + if (dsp->sb_type >= SB16) + dsp->asp_data_len = dsp->sb_data[0] + (dsp->sb_data[1] << 8) + 1; + break; + case 0x03: /* ASP status */ + if (dsp->sb_type >= SB16) + sb_add_data(dsp, 0); + break; + case 0x10: /* 8-bit direct mode */ + sb_dsp_update(dsp); + dsp->sbdat = dsp->sbdatl = dsp->sbdatr = (dsp->sb_data[0] ^ 0x80) << 8; + break; + case 0x14: /* 8-bit single cycle DMA output */ + sb_start_dma(dsp, 1, 0, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + break; + case 0x17: /* 2-bit ADPCM output with reference */ + dsp->sbref = sb_8_read_dma(dsp); + dsp->sbstep = 0; + /* Fall through */ + case 0x16: /* 2-bit ADPCM output */ + sb_start_dma(dsp, 1, 0, ADPCM_2, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + dsp->sbdat2 = sb_8_read_dma(dsp); + dsp->sb_8_length--; + if (dsp->sb_command == 0x17) + dsp->sb_8_length--; + break; + case 0x1C: /* 8-bit autoinit DMA output */ + if (dsp->sb_type >= SB15) + sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen); + break; + case 0x1F: /* 2-bit ADPCM autoinit output */ + if (dsp->sb_type >= SB15) { + sb_start_dma(dsp, 1, 1, ADPCM_2, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + dsp->sbdat2 = sb_8_read_dma(dsp); + dsp->sb_8_length--; + } + break; + case 0x20: /* 8-bit direct input */ + sb_add_data(dsp, (dsp->record_buffer[dsp->record_pos_read] >> 8) ^ 0x80); + /* Due to the current implementation, I need to emulate a samplerate, even if this + mode does not imply such samplerate. Position is increased in sb_poll_i(). */ + if (!timer_is_enabled(&dsp->input_timer)) { + dsp->sb_timei = 256 - 22; + dsp->sblatchi = TIMER_USEC * 22; + temp = 1000000 / 22; + dsp->sb_freq = temp; + timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); + } + break; + case 0x24: /* 8-bit single cycle DMA input */ + sb_start_dma_i(dsp, 1, 0, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + break; + case 0x28: /* Direct ADC, 8-bit (Burst) */ + break; + case 0x2C: /* 8-bit autoinit DMA input */ + if (dsp->sb_type >= SB15) + sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + break; + case 0x30: /* MIDI Polling mode input */ + sb_dsp_log("MIDI polling mode input\n"); + dsp->midi_in_poll = 1; + dsp->uart_irq = 0; + break; + case 0x31: /* MIDI Interrupt mode input */ + sb_dsp_log("MIDI interrupt mode input\n"); + dsp->midi_in_poll = 0; + dsp->uart_irq = 1; + break; + case 0x32: /* MIDI Read Timestamp Poll */ + break; + case 0x33: /* MIDI Read Timestamp Interrupt */ + break; + case 0x34: /* MIDI In poll */ + if (dsp->sb_type < SB2) + break; + sb_dsp_log("MIDI poll in\n"); + dsp->midi_in_poll = 1; + dsp->uart_midi = 1; + dsp->uart_irq = 0; + break; + case 0x35: /* MIDI In irq */ + if (dsp->sb_type < SB2) + break; + sb_dsp_log("MIDI irq in\n"); + dsp->midi_in_poll = 0; + dsp->uart_midi = 1; + dsp->uart_irq = 1; + break; + case 0x36: + case 0x37: /* MIDI timestamps */ + break; + case 0x38: /* Write to SB MIDI Output (Raw) */ + dsp->onebyte_midi = 1; + break; + case 0x40: /* Set time constant */ + dsp->sb_timei = dsp->sb_timeo = dsp->sb_data[0]; + dsp->sblatcho = dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_data[0]); + temp = 256 - dsp->sb_data[0]; + temp = 1000000 / temp; + sb_dsp_log("Sample rate - %ihz (%i)\n", temp, dsp->sblatcho); + if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16)) + recalc_sb16_filter(0, temp); + dsp->sb_freq = temp; + break; + case 0x41: /* Set output sampling rate */ + case 0x42: /* Set input sampling rate */ + if (dsp->sb_type >= SB16) { + dsp->sblatcho = (uint64_t) (TIMER_USEC * (1000000.0f / (float) (dsp->sb_data[1] + (dsp->sb_data[0] << 8)))); + sb_dsp_log("Sample rate - %ihz (%i)\n", dsp->sb_data[1] + (dsp->sb_data[0] << 8), dsp->sblatcho); + temp = dsp->sb_freq; + dsp->sb_freq = dsp->sb_data[1] + (dsp->sb_data[0] << 8); + dsp->sb_timeo = 256LL + dsp->sb_freq; + dsp->sblatchi = dsp->sblatcho; + dsp->sb_timei = dsp->sb_timeo; + if (dsp->sb_freq != temp && dsp->sb_type >= SB16) + recalc_sb16_filter(0, dsp->sb_freq); + dsp->sb_8051_ram[0x13] = dsp->sb_freq & 0xff; + dsp->sb_8051_ram[0x14] = (dsp->sb_freq >> 8) & 0xff; + } + break; + case 0x45: /* Continue Auto-Initialize DMA, 8-bit */ + break; + case 0x47: /* Continue Auto-Initialize DMA, 16-bit */ + break; + case 0x48: /* Set DSP block transfer size */ + dsp->sb_8_autolen = dsp->sb_data[0] + (dsp->sb_data[1] << 8); + break; + case 0x75: /* 4-bit ADPCM output with reference */ + dsp->sbref = sb_8_read_dma(dsp); + dsp->sbstep = 0; + /* Fall through */ + case 0x74: /* 4-bit ADPCM output */ + sb_start_dma(dsp, 1, 0, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + dsp->sbdat2 = sb_8_read_dma(dsp); + dsp->sb_8_length--; + if (dsp->sb_command == 0x75) + dsp->sb_8_length--; + break; + case 0x77: /* 2.6-bit ADPCM output with reference */ + dsp->sbref = sb_8_read_dma(dsp); + dsp->sbstep = 0; + /* Fall through */ + case 0x76: /* 2.6-bit ADPCM output */ + sb_start_dma(dsp, 1, 0, ADPCM_26, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + dsp->sbdat2 = sb_8_read_dma(dsp); + dsp->sb_8_length--; + if (dsp->sb_command == 0x77) + dsp->sb_8_length--; + break; + case 0x7D: /* 4-bit ADPCM autoinit output */ + if (dsp->sb_type >= SB15) { + sb_start_dma(dsp, 1, 1, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + dsp->sbdat2 = sb_8_read_dma(dsp); + dsp->sb_8_length--; + } + break; + case 0x7F: /* 2.6-bit ADPCM autoinit output */ + if (dsp->sb_type >= SB15) { + sb_start_dma(dsp, 1, 1, ADPCM_26, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); + dsp->sbdat2 = sb_8_read_dma(dsp); + dsp->sb_8_length--; + } + break; + case 0x80: /* Pause DAC */ + dsp->sb_pausetime = dsp->sb_data[0] + (dsp->sb_data[1] << 8); + if (!timer_is_enabled(&dsp->output_timer)) + timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); + break; + case 0x90: /* High speed 8-bit autoinit DMA output */ + if (dsp->sb_type >= SB2) + sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen); + break; + case 0x91: /* High speed 8-bit single cycle DMA output */ + if (dsp->sb_type >= SB2) + sb_start_dma(dsp, 1, 0, 0, dsp->sb_8_autolen); + break; + case 0x98: /* High speed 8-bit autoinit DMA input */ + if (dsp->sb_type >= SB2) + sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_8_autolen); + break; + case 0x99: /* High speed 8-bit single cycle DMA input */ + if (dsp->sb_type >= SB2) + sb_start_dma_i(dsp, 1, 0, 0, dsp->sb_8_autolen); + break; + case 0xA0: /* Set input mode to mono */ + case 0xA8: /* Set input mode to stereo */ + if ((dsp->sb_type < SB2) || (dsp->sb_type > SBPRO2)) + break; + /* TODO: Implement. 3.xx-only command. */ + break; + case 0xB0: + case 0xB1: + case 0xB2: + case 0xB3: + case 0xB4: + case 0xB5: + case 0xB6: + case 0xB7: /* 16-bit DMA output */ + if (dsp->sb_type >= SB16) { + sb_start_dma(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); + dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); + } + break; + case 0xB8: + case 0xB9: + case 0xBA: + case 0xBB: + case 0xBC: + case 0xBD: + case 0xBE: + case 0xBF: /* 16-bit DMA input */ + if (dsp->sb_type >= SB16) { + sb_start_dma_i(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); + dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); + } + break; + case 0xC0: + case 0xC1: + case 0xC2: + case 0xC3: + case 0xC4: + case 0xC5: + case 0xC6: + case 0xC7: /* 8-bit DMA output */ + if (dsp->sb_type >= SB16) { + sb_start_dma(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); + dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); + } + break; + case 0xC8: + case 0xC9: + case 0xCA: + case 0xCB: + case 0xCC: + case 0xCD: + case 0xCE: + case 0xCF: /* 8-bit DMA input */ + if (dsp->sb_type >= SB16) { + sb_start_dma_i(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); + dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); + } + break; + case 0xD0: /* Pause 8-bit DMA */ + dsp->sb_8_pause = 1; + break; + case 0xD1: /* Speaker on */ + if (dsp->sb_type < SB15) + dsp->sb_8_pause = 1; + else if (dsp->sb_type < SB16) + dsp->muted = 0; + dsp->sb_speaker = 1; + break; + case 0xD3: /* Speaker off */ + if (dsp->sb_type < SB15) + dsp->sb_8_pause = 1; + else if (dsp->sb_type < SB16) + dsp->muted = 1; + dsp->sb_speaker = 0; + break; + case 0xD4: /* Continue 8-bit DMA */ + dsp->sb_8_pause = 0; + break; + case 0xD5: /* Pause 16-bit DMA */ + if (dsp->sb_type >= SB16) + dsp->sb_16_pause = 1; + break; + case 0xD6: /* Continue 16-bit DMA */ + if (dsp->sb_type >= SB16) + dsp->sb_16_pause = 0; + break; + case 0xD8: /* Get speaker status */ + sb_add_data(dsp, dsp->sb_speaker ? 0xff : 0); + break; + case 0xD9: /* Exit 16-bit auto-init mode */ + if (dsp->sb_type >= SB16) + dsp->sb_16_autoinit = 0; + break; + case 0xDA: /* Exit 8-bit auto-init mode */ + dsp->sb_8_autoinit = 0; + break; + case 0xE0: /* DSP identification */ + sb_add_data(dsp, ~dsp->sb_data[0]); + break; + case 0xE1: /* Get DSP version */ + if (IS_AZTECH(dsp)) { + if (dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11) { + sb_add_data(dsp, 0x3); + sb_add_data(dsp, 0x1); + } else if (dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) { + sb_add_data(dsp, 0x2); + sb_add_data(dsp, 0x1); + } + break; + } + sb_add_data(dsp, sb_dsp_versions[dsp->sb_type] >> 8); + sb_add_data(dsp, sb_dsp_versions[dsp->sb_type] & 0xff); + break; + case 0xE2: /* Stupid ID/protection */ + for (c = 0; c < 8; c++) { + if (dsp->sb_data[0] & (1 << c)) + dsp->sbe2 += sbe2dat[dsp->sbe2count & 3][c]; + } + dsp->sbe2 += sbe2dat[dsp->sbe2count & 3][8]; + dsp->sbe2count++; + sb_8_write_dma(dsp, dsp->sbe2); + break; + case 0xE3: /* DSP copyright */ + if (dsp->sb_type >= SB16) { + c = 0; + while (sb16_copyright[c]) + sb_add_data(dsp, sb16_copyright[c++]); + sb_add_data(dsp, 0); + } + break; + case 0xE4: /* Write test register */ + dsp->sb_test = dsp->sb_data[0]; + break; + case 0xE8: /* Read test register */ + sb_add_data(dsp, dsp->sb_test); + break; + case 0xF2: /* Trigger 8-bit IRQ */ + sb_dsp_log("Trigger IRQ\n"); + sb_irq(dsp, 1); + break; + case 0xF3: /* Trigger 16-bit IRQ */ + sb_dsp_log("Trigger IRQ\n"); + sb_irq(dsp, 0); + break; + case 0xE7: /* ???? */ + break; + case 0x07: + case 0xFF: /* No, that's not how you program auto-init DMA */ + break; + case 0x08: /* ASP get version / AZTECH type/EEPROM access */ + if (IS_AZTECH(dsp)) { + if ((dsp->sb_data[0] == 0x05 || dsp->sb_data[0] == 0x55) && dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11) + sb_add_data(dsp, 0x11); /* AZTECH get type, WASHINGTON/latest - according to devkit. E.g.: The one in the Itautec Infoway Multimidia */ + else if ((dsp->sb_data[0] == 0x05 || dsp->sb_data[0] == 0x55) && dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) + sb_add_data(dsp, 0x0C); /* AZTECH get type, CLINTON - according to devkit. E.g.: The one in the Packard Bell Legend 100CD */ + else if (dsp->sb_data[0] == 0x08) { + /* EEPROM address to write followed by byte */ + if (dsp->sb_data[1] < 0 || dsp->sb_data[1] >= AZTECH_EEPROM_SIZE) + fatal("AZT EEPROM: out of bounds write to %02X\n", dsp->sb_data[1]); + sb_dsp_log("EEPROM write = %02x\n", dsp->sb_data[2]); + dsp->azt_eeprom[dsp->sb_data[1]] = dsp->sb_data[2]; + break; + } else if (dsp->sb_data[0] == 0x07) { + /* EEPROM address to read */ + if (dsp->sb_data[1] < 0 || dsp->sb_data[1] >= AZTECH_EEPROM_SIZE) + fatal("AZT EEPROM: out of bounds read to %02X\n", dsp->sb_data[1]); + sb_dsp_log("EEPROM read = %02x\n", dsp->azt_eeprom[dsp->sb_data[1]]); + sb_add_data(dsp, dsp->azt_eeprom[dsp->sb_data[1]]); + break; + } else + sb_dsp_log("AZT2316A: UNKNOWN 0x08 COMMAND: %02X\n", dsp->sb_data[0]); /* 0x08 (when shutting down, driver tries to read 1 byte of response), 0x55, 0x0D, 0x08D seen */ + break; + } + if (dsp->sb_type == SBAWE64) /* AWE64 has no ASP or a socket for it */ + sb_add_data(dsp, 0xFF); + else if (dsp->sb_type >= SB16) + sb_add_data(dsp, 0x18); + break; + case 0x0E: /* ASP set register */ + if (dsp->sb_type >= SB16) { + dsp->sb_asp_regs[dsp->sb_data[0]] = dsp->sb_data[1]; - if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory write */ - if (dsp->sb_asp_mode & 8) - dsp->sb_asp_ram_index = 0; + if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory write */ + if (dsp->sb_asp_mode & 8) + dsp->sb_asp_ram_index = 0; - dsp->sb_asp_ram[dsp->sb_asp_ram_index] = dsp->sb_data[1]; + dsp->sb_asp_ram[dsp->sb_asp_ram_index] = dsp->sb_data[1]; - if (dsp->sb_asp_mode & 2) { - dsp->sb_asp_ram_index++; - if (dsp->sb_asp_ram_index >= 2048) - dsp->sb_asp_ram_index = 0; - } - } - sb_dsp_log("SB16 ASP write reg %02X, val %02X\n", dsp->sb_data[0], dsp->sb_data[1]); - } - break; - case 0x0F: /* ASP get register */ - if (dsp->sb_type >= SB16) { - if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory read */ - if (dsp->sb_asp_mode & 8) - dsp->sb_asp_ram_index = 0; + if (dsp->sb_asp_mode & 2) { + dsp->sb_asp_ram_index++; + if (dsp->sb_asp_ram_index >= 2048) + dsp->sb_asp_ram_index = 0; + } + } + sb_dsp_log("SB16 ASP write reg %02X, val %02X\n", dsp->sb_data[0], dsp->sb_data[1]); + } + break; + case 0x0F: /* ASP get register */ + if (dsp->sb_type >= SB16) { + if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory read */ + if (dsp->sb_asp_mode & 8) + dsp->sb_asp_ram_index = 0; - dsp->sb_asp_regs[0x83] = dsp->sb_asp_ram[dsp->sb_asp_ram_index]; + dsp->sb_asp_regs[0x83] = dsp->sb_asp_ram[dsp->sb_asp_ram_index]; - if (dsp->sb_asp_mode & 1) { - dsp->sb_asp_ram_index++; - if (dsp->sb_asp_ram_index >= 2048) - dsp->sb_asp_ram_index = 0; - } - } else if (dsp->sb_data[0] == 0x83) { - dsp->sb_asp_regs[0x83] = 0x18; - } - sb_add_data(dsp, dsp->sb_asp_regs[dsp->sb_data[0]]); - sb_dsp_log("SB16 ASP read reg %02X, val %02X\n", dsp->sb_data[0], dsp->sb_asp_regs[dsp->sb_data[0]]); - } - break; - case 0xF8: - if (dsp->sb_type < SB16) - sb_add_data(dsp, 0); - break; - case 0xF9: /* SB16 8051 RAM read */ - if (dsp->sb_type >= SB16) - sb_add_data(dsp, dsp->sb_8051_ram[dsp->sb_data[0]]); - break; - case 0xFA: /* SB16 8051 RAM write */ - if (dsp->sb_type >= SB16) - dsp->sb_8051_ram[dsp->sb_data[0]] = dsp->sb_data[1]; - break; - case 0x04: /* ASP set mode register */ - if (dsp->sb_type >= SB16) { - dsp->sb_asp_mode = dsp->sb_data[0]; - if (dsp->sb_asp_mode & 4) - dsp->sb_asp_ram_index = 0; - sb_dsp_log("SB16 ASP set mode %02X\n", dsp->sb_asp_mode); - } /* else DSP Status (Obsolete) */ - break; - case 0x05: /* ASP set codec parameter */ - if (dsp->sb_type >= SB16) - sb_dsp_log("SB16 ASP unknown codec params %02X, %02X\n", dsp->sb_data[0], dsp->sb_data[1]); - break; + if (dsp->sb_asp_mode & 1) { + dsp->sb_asp_ram_index++; + if (dsp->sb_asp_ram_index >= 2048) + dsp->sb_asp_ram_index = 0; + } + } else if (dsp->sb_data[0] == 0x83) { + dsp->sb_asp_regs[0x83] = 0x18; + } + sb_add_data(dsp, dsp->sb_asp_regs[dsp->sb_data[0]]); + sb_dsp_log("SB16 ASP read reg %02X, val %02X\n", dsp->sb_data[0], dsp->sb_asp_regs[dsp->sb_data[0]]); + } + break; + case 0xF8: + if (dsp->sb_type < SB16) + sb_add_data(dsp, 0); + break; + case 0xF9: /* SB16 8051 RAM read */ + if (dsp->sb_type >= SB16) + sb_add_data(dsp, dsp->sb_8051_ram[dsp->sb_data[0]]); + break; + case 0xFA: /* SB16 8051 RAM write */ + if (dsp->sb_type >= SB16) + dsp->sb_8051_ram[dsp->sb_data[0]] = dsp->sb_data[1]; + break; + case 0x04: /* ASP set mode register */ + if (dsp->sb_type >= SB16) { + dsp->sb_asp_mode = dsp->sb_data[0]; + if (dsp->sb_asp_mode & 4) + dsp->sb_asp_ram_index = 0; + sb_dsp_log("SB16 ASP set mode %02X\n", dsp->sb_asp_mode); + } /* else DSP Status (Obsolete) */ + break; + case 0x05: /* ASP set codec parameter */ + if (dsp->sb_type >= SB16) + sb_dsp_log("SB16 ASP unknown codec params %02X, %02X\n", dsp->sb_data[0], dsp->sb_data[1]); + break; - case 0x09: /* AZTECH mode set */ - if (IS_AZTECH(dsp)) { - if (dsp->sb_data[0] == 0x00) { - sb_dsp_log("AZT2316A: WSS MODE!\n"); - azt2316a_enable_wss(1, dsp->parent); - } else if (dsp->sb_data[0] == 0x01) { - sb_dsp_log("AZT2316A: SB8PROV2 MODE!\n"); - azt2316a_enable_wss(0, dsp->parent); - } else - sb_dsp_log("AZT2316A: UNKNOWN MODE! = %02x\n", dsp->sb_data[0]); // sequences 0x02->0xFF, 0x04->0xFF seen - } - break; + case 0x09: /* AZTECH mode set */ + if (IS_AZTECH(dsp)) { + if (dsp->sb_data[0] == 0x00) { + sb_dsp_log("AZT2316A: WSS MODE!\n"); + azt2316a_enable_wss(1, dsp->parent); + } else if (dsp->sb_data[0] == 0x01) { + sb_dsp_log("AZT2316A: SB8PROV2 MODE!\n"); + azt2316a_enable_wss(0, dsp->parent); + } else + sb_dsp_log("AZT2316A: UNKNOWN MODE! = %02x\n", dsp->sb_data[0]); // sequences 0x02->0xFF, 0x04->0xFF seen + } + break; - /* TODO: Some more data about the DSP registeres - * http://the.earth.li/~tfm/oldpage/sb_dsp.html - * http://www.synchrondata.com/pheaven/www/area19.htm - * http://www.dcee.net/Files/Programm/Sound/ - * 0E3h DSP Copyright SBPro2??? - * 0F0h Sine Generator SB - * 0F1h DSP Auxiliary Status (Obsolete) SB-Pro2 - * 0F2h IRQ Request, 8-bit SB - * 0F3h IRQ Request, 16-bit SB16 - * 0FBh DSP Status SB16 - * 0FCh DSP Auxiliary Status SB16 - * 0FDh DSP Command Status SB16 - */ + /* TODO: Some more data about the DSP registeres + * http://the.earth.li/~tfm/oldpage/sb_dsp.html + * http://www.synchrondata.com/pheaven/www/area19.htm + * http://www.dcee.net/Files/Programm/Sound/ + * 0E3h DSP Copyright SBPro2??? + * 0F0h Sine Generator SB + * 0F1h DSP Auxiliary Status (Obsolete) SB-Pro2 + * 0F2h IRQ Request, 8-bit SB + * 0F3h IRQ Request, 16-bit SB16 + * 0FBh DSP Status SB16 + * 0FCh DSP Auxiliary Status SB16 + * 0FDh DSP Command Status SB16 + */ } - /* Update 8051 ram with the last DSP command. See https://github.com/joncampbell123/dosbox-x/issues/1044 */ if (dsp->sb_type >= SB16) - dsp->sb_8051_ram[0x30] = dsp->sb_command; + dsp->sb_8051_ram[0x30] = dsp->sb_command; } - void sb_write(uint16_t a, uint8_t v, void *priv) { sb_dsp_t *dsp = (sb_dsp_t *) priv; switch (a & 0xF) { - case 6: /* Reset */ - if (!dsp->uart_midi) { - if (!(v & 1) && (dsp->sbreset & 1)) { - sb_dsp_reset(dsp); - sb_add_data(dsp, 0xAA); - } - dsp->sbreset = v; - } - dsp->uart_midi = 0; - dsp->uart_irq = 0; - dsp->onebyte_midi = 0; - return; - case 0xC: /* Command/data write */ - if (dsp->uart_midi || dsp->onebyte_midi ) { - midi_raw_out_byte(v); - dsp->onebyte_midi = 0; - return; - } - timer_set_delay_u64(&dsp->wb_timer, TIMER_USEC * 1); - if (dsp->asp_data_len) { - sb_dsp_log("ASP data %i\n", dsp->asp_data_len); - dsp->asp_data_len--; - if (!dsp->asp_data_len) - sb_add_data(dsp, 0); - return; - } - if (dsp->sb_data_stat == -1) { - dsp->sb_command = v; - if (v == 0x01) - sb_add_data(dsp, 0); - dsp->sb_data_stat++; - } else { - dsp->sb_data[dsp->sb_data_stat++] = v; - if (IS_AZTECH(dsp)) { - /* variable length commands */ - if (dsp->sb_command == 0x08 && dsp->sb_data_stat == 1 && dsp->sb_data[0] == 0x08) - sb_commands[dsp->sb_command] = 3; - else if (dsp->sb_command == 0x08 && dsp->sb_data_stat == 1 && dsp->sb_data[0] == 0x07) - sb_commands[dsp->sb_command] = 2; - } - } - if (dsp->sb_data_stat == sb_commands[dsp->sb_command] || sb_commands[dsp->sb_command] == -1) { - sb_exec_command(dsp); - dsp->sb_data_stat = -1; - if (IS_AZTECH(dsp)) { - /* variable length commands */ - if (dsp->sb_command == 0x08) - sb_commands[dsp->sb_command] = 1; - } - } - break; + case 6: /* Reset */ + if (!dsp->uart_midi) { + if (!(v & 1) && (dsp->sbreset & 1)) { + sb_dsp_reset(dsp); + sb_add_data(dsp, 0xAA); + } + dsp->sbreset = v; + } + dsp->uart_midi = 0; + dsp->uart_irq = 0; + dsp->onebyte_midi = 0; + return; + case 0xC: /* Command/data write */ + if (dsp->uart_midi || dsp->onebyte_midi) { + midi_raw_out_byte(v); + dsp->onebyte_midi = 0; + return; + } + timer_set_delay_u64(&dsp->wb_timer, TIMER_USEC * 1); + if (dsp->asp_data_len) { + sb_dsp_log("ASP data %i\n", dsp->asp_data_len); + dsp->asp_data_len--; + if (!dsp->asp_data_len) + sb_add_data(dsp, 0); + return; + } + if (dsp->sb_data_stat == -1) { + dsp->sb_command = v; + if (v == 0x01) + sb_add_data(dsp, 0); + dsp->sb_data_stat++; + } else { + dsp->sb_data[dsp->sb_data_stat++] = v; + if (IS_AZTECH(dsp)) { + /* variable length commands */ + if (dsp->sb_command == 0x08 && dsp->sb_data_stat == 1 && dsp->sb_data[0] == 0x08) + sb_commands[dsp->sb_command] = 3; + else if (dsp->sb_command == 0x08 && dsp->sb_data_stat == 1 && dsp->sb_data[0] == 0x07) + sb_commands[dsp->sb_command] = 2; + } + } + if (dsp->sb_data_stat == sb_commands[dsp->sb_command] || sb_commands[dsp->sb_command] == -1) { + sb_exec_command(dsp); + dsp->sb_data_stat = -1; + if (IS_AZTECH(dsp)) { + /* variable length commands */ + if (dsp->sb_command == 0x08) + sb_commands[dsp->sb_command] = 1; + } + } + break; } } - uint8_t sb_read(uint16_t a, void *priv) { sb_dsp_t *dsp = (sb_dsp_t *) priv; - uint8_t ret = 0x00; + uint8_t ret = 0x00; switch (a & 0xf) { - case 0xA: /* Read data */ - if (dsp->mpu && dsp->uart_midi) { - ret = MPU401_ReadData(dsp->mpu); - } else { - dsp->sbreaddat = dsp->sb_read_data[dsp->sb_read_rp]; - if (dsp->sb_read_rp != dsp->sb_read_wp) { - dsp->sb_read_rp++; - dsp->sb_read_rp &= 0xff; - } - return dsp->sbreaddat; - } - break; - case 0xC: /* Write data ready */ - if (dsp->sb_8_enable || dsp->sb_type >= SB16) - dsp->busy_count = (dsp->busy_count + 1) & 3; - else - dsp->busy_count = 0; - if (dsp->wb_full || (dsp->busy_count & 2)) { - dsp->wb_full = timer_is_enabled(&dsp->wb_timer); - if (IS_AZTECH(dsp)) { - sb_dsp_log("SB Write Data Aztech read 0x80\n"); - return 0x80; - } else { - sb_dsp_log("SB Write Data Creative read 0xff\n"); - return 0xff; - } - } - if (IS_AZTECH(dsp)) { - sb_dsp_log("SB Write Data Aztech read 0x00\n"); - ret = 0x00; - } else { - sb_dsp_log("SB Write Data Creative read 0x7f\n"); - ret = 0x7f; - } - break; - case 0xE: /* Read data ready */ - picintc(1 << dsp->sb_irqnum); - dsp->sb_irq8 = dsp->sb_irq16 = 0; - /* Only bit 7 is defined but aztech diagnostics fail if the others are set. Keep the original behavior to not interfere with what's already working. */ - if (IS_AZTECH(dsp)) { - sb_dsp_log("SB Read Data Aztech read %02X, Read RP = %d, Read WP = %d\n",(dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80, dsp->sb_read_rp, dsp->sb_read_wp); - ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80; - } else { - sb_dsp_log("SB Read Data Creative read %02X\n",(dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff); - ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff; - } - break; - case 0xF: /* 16-bit ack */ - dsp->sb_irq16 = 0; - if (!dsp->sb_irq8) - picintc(1 << dsp->sb_irqnum); - sb_dsp_log("SB 16-bit ACK read 0xFF\n"); - ret = 0xff; - break; - } + case 0xA: /* Read data */ + if (dsp->mpu && dsp->uart_midi) { + ret = MPU401_ReadData(dsp->mpu); + } else { + dsp->sbreaddat = dsp->sb_read_data[dsp->sb_read_rp]; + if (dsp->sb_read_rp != dsp->sb_read_wp) { + dsp->sb_read_rp++; + dsp->sb_read_rp &= 0xff; + } + return dsp->sbreaddat; + } + break; + case 0xC: /* Write data ready */ + if (dsp->sb_8_enable || dsp->sb_type >= SB16) + dsp->busy_count = (dsp->busy_count + 1) & 3; + else + dsp->busy_count = 0; + if (dsp->wb_full || (dsp->busy_count & 2)) { + dsp->wb_full = timer_is_enabled(&dsp->wb_timer); + if (IS_AZTECH(dsp)) { + sb_dsp_log("SB Write Data Aztech read 0x80\n"); + return 0x80; + } else { + sb_dsp_log("SB Write Data Creative read 0xff\n"); + return 0xff; + } + } + if (IS_AZTECH(dsp)) { + sb_dsp_log("SB Write Data Aztech read 0x00\n"); + ret = 0x00; + } else { + sb_dsp_log("SB Write Data Creative read 0x7f\n"); + ret = 0x7f; + } + break; + case 0xE: /* Read data ready */ + picintc(1 << dsp->sb_irqnum); + dsp->sb_irq8 = dsp->sb_irq16 = 0; + /* Only bit 7 is defined but aztech diagnostics fail if the others are set. Keep the original behavior to not interfere with what's already working. */ + if (IS_AZTECH(dsp)) { + sb_dsp_log("SB Read Data Aztech read %02X, Read RP = %d, Read WP = %d\n", (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80, dsp->sb_read_rp, dsp->sb_read_wp); + ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80; + } else { + sb_dsp_log("SB Read Data Creative read %02X\n", (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff); + ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff; + } + break; + case 0xF: /* 16-bit ack */ + dsp->sb_irq16 = 0; + if (!dsp->sb_irq8) + picintc(1 << dsp->sb_irqnum); + sb_dsp_log("SB 16-bit ACK read 0xFF\n"); + ret = 0xff; + break; + } - return ret; + return ret; } - void sb_dsp_input_msg(void *p, uint8_t *msg, uint32_t len) { sb_dsp_t *dsp = (sb_dsp_t *) p; - uint8_t i = 0; + uint8_t i = 0; sb_dsp_log("MIDI in sysex = %d, uart irq = %d, msg = %d\n", dsp->midi_in_sysex, dsp->uart_irq, len); if (!dsp->uart_irq && !dsp->midi_in_poll && (dsp->mpu != NULL)) { - MPU401_InputMsg(dsp->mpu, msg, len); - return; + MPU401_InputMsg(dsp->mpu, msg, len); + return; } if (dsp->midi_in_sysex) - return; + return; if (dsp->uart_irq) { - for (i = 0; i < len; i++) - sb_add_data(dsp, msg[i]); - sb_irq(dsp, 1); + for (i = 0; i < len; i++) + sb_add_data(dsp, msg[i]); + sb_irq(dsp, 1); } else if (dsp->midi_in_poll) { - for (i = 0; i < len; i++) - sb_add_data(dsp, msg[i]); + for (i = 0; i < len; i++) + sb_add_data(dsp, msg[i]); } } - int sb_dsp_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort) { sb_dsp_t *dsp = (sb_dsp_t *) p; - uint32_t i; + uint32_t i; if (!dsp->uart_irq && !dsp->midi_in_poll && (dsp->mpu != NULL)) - return MPU401_InputSysex(dsp->mpu, buffer, len, abort); + return MPU401_InputSysex(dsp->mpu, buffer, len, abort); if (abort) { - dsp->midi_in_sysex = 0; - return 0; + dsp->midi_in_sysex = 0; + return 0; } dsp->midi_in_sysex = 1; for (i = 0; i < len; i++) { - if (dsp->sb_read_rp == dsp->sb_read_wp) { - sb_dsp_log("Length sysex SB = %d\n", len - i); - return (len - i); - } + if (dsp->sb_read_rp == dsp->sb_read_wp) { + sb_dsp_log("Length sysex SB = %d\n", len - i); + return (len - i); + } - sb_add_data(dsp, buffer[i]); + sb_add_data(dsp, buffer[i]); } dsp->midi_in_sysex = 0; @@ -1102,19 +1095,18 @@ sb_dsp_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort) return 0; } - void sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) { - dsp->sb_type = type; + dsp->sb_type = type; dsp->sb_subtype = subtype; - dsp->parent = parent; + dsp->parent = parent; /* Default values. Use sb_dsp_setxxx() methods to change. */ - dsp->sb_irqnum = 7; - dsp->sb_8_dmanum = 1; + dsp->sb_irqnum = 7; + dsp->sb_8_dmanum = 1; dsp->sb_16_dmanum = 5; - dsp->mpu = NULL; + dsp->mpu = NULL; sb_doreset(dsp); @@ -1124,7 +1116,7 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) /* Initialise SB16 filter to same cutoff as 8-bit SBs (3.2 kHz). This will be recalculated when a set frequency command is sent. */ - recalc_sb16_filter(0, 3200*2); + recalc_sb16_filter(0, 3200 * 2); recalc_sb16_filter(1, 44100); /* Initialize SB16 8051 RAM and ASP internal RAM */ @@ -1136,404 +1128,399 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) memset(dsp->sb_asp_ram, 0xff, sizeof(dsp->sb_asp_ram)); } - void sb_dsp_setaddr(sb_dsp_t *dsp, uint16_t addr) { sb_dsp_log("sb_dsp_setaddr : %04X\n", addr); if (dsp->sb_addr != 0) { - io_removehandler(dsp->sb_addr + 6, 0x0002, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp); - io_removehandler(dsp->sb_addr + 0xa, 0x0006, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp); + io_removehandler(dsp->sb_addr + 6, 0x0002, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp); + io_removehandler(dsp->sb_addr + 0xa, 0x0006, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp); } dsp->sb_addr = addr; if (dsp->sb_addr != 0) { - io_sethandler(dsp->sb_addr + 6, 0x0002, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp); - io_sethandler(dsp->sb_addr + 0xa, 0x0006, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp); + io_sethandler(dsp->sb_addr + 6, 0x0002, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp); + io_sethandler(dsp->sb_addr + 0xa, 0x0006, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp); } } - void sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo) { dsp->stereo = stereo; } - void pollsb(void *p) { sb_dsp_t *dsp = (sb_dsp_t *) p; - int tempi, ref; - int data[2]; + int tempi, ref; + int data[2]; timer_advance_u64(&dsp->output_timer, dsp->sblatcho); if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && dsp->sb_8_output) { - sb_dsp_update(dsp); + sb_dsp_update(dsp); - switch (dsp->sb_8_format) { - case 0x00: /* Mono unsigned */ - data[0] = sb_8_read_dma(dsp); - /* Needed to prevent clicking in Worms, which programs the DSP to - auto-init DMA but programs the DMA controller to single cycle */ - if (data[0] == DMA_NODATA) - break; - dsp->sbdat = (data[0] ^ 0x80) << 8; - if ((dsp->sb_type >= SBPRO) && (dsp->sb_type < SB16) && dsp->stereo) { - sb_dsp_log("pollsb: Mono unsigned, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); - if (dsp->sbleftright) - dsp->sbdatl = dsp->sbdat; - else - dsp->sbdatr = dsp->sbdat; - dsp->sbleftright = !dsp->sbleftright; - } else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; - dsp->sb_8_length--; - break; - case 0x10: /* Mono signed */ - data[0] = sb_8_read_dma(dsp); - if (data[0] == DMA_NODATA) - break; - dsp->sbdat = data[0] << 8; - if ((dsp->sb_type >= SBPRO) && (dsp->sb_type < SB16) && dsp->stereo) { - sb_dsp_log("pollsb: Mono signed, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", data[0], dsp->sbdat); - if (dsp->sbleftright) - dsp->sbdatl = dsp->sbdat; - else - dsp->sbdatr = dsp->sbdat; - dsp->sbleftright = !dsp->sbleftright; - } else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; - dsp->sb_8_length--; - break; - case 0x20: /* Stereo unsigned */ - data[0] = sb_8_read_dma(dsp); - data[1] = sb_8_read_dma(dsp); - if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) - break; - dsp->sbdatl = (data[0] ^ 0x80) << 8; - dsp->sbdatr = (data[1] ^ 0x80) << 8; - dsp->sb_8_length -= 2; - break; - case 0x30: /* Stereo signed */ - data[0] = sb_8_read_dma(dsp); - data[1] = sb_8_read_dma(dsp); - if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) - break; - dsp->sbdatl = data[0] << 8; - dsp->sbdatr = data[1] << 8; - dsp->sb_8_length -= 2; - break; + switch (dsp->sb_8_format) { + case 0x00: /* Mono unsigned */ + data[0] = sb_8_read_dma(dsp); + /* Needed to prevent clicking in Worms, which programs the DSP to + auto-init DMA but programs the DMA controller to single cycle */ + if (data[0] == DMA_NODATA) + break; + dsp->sbdat = (data[0] ^ 0x80) << 8; + if ((dsp->sb_type >= SBPRO) && (dsp->sb_type < SB16) && dsp->stereo) { + sb_dsp_log("pollsb: Mono unsigned, dsp->stereo, %s channel, %04X\n", + dsp->sbleftright ? "left" : "right", dsp->sbdat); + if (dsp->sbleftright) + dsp->sbdatl = dsp->sbdat; + else + dsp->sbdatr = dsp->sbdat; + dsp->sbleftright = !dsp->sbleftright; + } else + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + dsp->sb_8_length--; + break; + case 0x10: /* Mono signed */ + data[0] = sb_8_read_dma(dsp); + if (data[0] == DMA_NODATA) + break; + dsp->sbdat = data[0] << 8; + if ((dsp->sb_type >= SBPRO) && (dsp->sb_type < SB16) && dsp->stereo) { + sb_dsp_log("pollsb: Mono signed, dsp->stereo, %s channel, %04X\n", + dsp->sbleftright ? "left" : "right", data[0], dsp->sbdat); + if (dsp->sbleftright) + dsp->sbdatl = dsp->sbdat; + else + dsp->sbdatr = dsp->sbdat; + dsp->sbleftright = !dsp->sbleftright; + } else + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + dsp->sb_8_length--; + break; + case 0x20: /* Stereo unsigned */ + data[0] = sb_8_read_dma(dsp); + data[1] = sb_8_read_dma(dsp); + if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) + break; + dsp->sbdatl = (data[0] ^ 0x80) << 8; + dsp->sbdatr = (data[1] ^ 0x80) << 8; + dsp->sb_8_length -= 2; + break; + case 0x30: /* Stereo signed */ + data[0] = sb_8_read_dma(dsp); + data[1] = sb_8_read_dma(dsp); + if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) + break; + dsp->sbdatl = data[0] << 8; + dsp->sbdatr = data[1] << 8; + dsp->sb_8_length -= 2; + break; - case ADPCM_4: - if (dsp->sbdacpos) - tempi = (dsp->sbdat2 & 0xF) + dsp->sbstep; - else - tempi = (dsp->sbdat2 >> 4) + dsp->sbstep; - if (tempi < 0) - tempi = 0; - if (tempi > 63) - tempi = 63; + case ADPCM_4: + if (dsp->sbdacpos) + tempi = (dsp->sbdat2 & 0xF) + dsp->sbstep; + else + tempi = (dsp->sbdat2 >> 4) + dsp->sbstep; + if (tempi < 0) + tempi = 0; + if (tempi > 63) + tempi = 63; - ref = dsp->sbref + scaleMap4[tempi]; - if (ref > 0xff) - dsp->sbref = 0xff; - else if (ref < 0x00) - dsp->sbref = 0x00; - else - dsp->sbref = ref; + ref = dsp->sbref + scaleMap4[tempi]; + if (ref > 0xff) + dsp->sbref = 0xff; + else if (ref < 0x00) + dsp->sbref = 0x00; + else + dsp->sbref = ref; - dsp->sbstep = (dsp->sbstep + adjustMap4[tempi]) & 0xff; - dsp->sbdat = (dsp->sbref ^ 0x80) << 8; + dsp->sbstep = (dsp->sbstep + adjustMap4[tempi]) & 0xff; + dsp->sbdat = (dsp->sbref ^ 0x80) << 8; - dsp->sbdacpos++; + dsp->sbdacpos++; - if (dsp->sbdacpos >= 2) { - dsp->sbdacpos = 0; - dsp->sbdat2 = sb_8_read_dma(dsp); - dsp->sb_8_length--; - } + if (dsp->sbdacpos >= 2) { + dsp->sbdacpos = 0; + dsp->sbdat2 = sb_8_read_dma(dsp); + dsp->sb_8_length--; + } - if ((dsp->sb_type >= SBPRO) && (dsp->sb_type < SB16) && dsp->stereo) { - sb_dsp_log("pollsb: ADPCM 4, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); - if (dsp->sbleftright) - dsp->sbdatl = dsp->sbdat; - else - dsp->sbdatr = dsp->sbdat; - dsp->sbleftright = !dsp->sbleftright; - } else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; - break; + if ((dsp->sb_type >= SBPRO) && (dsp->sb_type < SB16) && dsp->stereo) { + sb_dsp_log("pollsb: ADPCM 4, dsp->stereo, %s channel, %04X\n", + dsp->sbleftright ? "left" : "right", dsp->sbdat); + if (dsp->sbleftright) + dsp->sbdatl = dsp->sbdat; + else + dsp->sbdatr = dsp->sbdat; + dsp->sbleftright = !dsp->sbleftright; + } else + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + break; - case ADPCM_26: - if (!dsp->sbdacpos) - tempi = (dsp->sbdat2 >> 5) + dsp->sbstep; - else if (dsp->sbdacpos == 1) - tempi = ((dsp->sbdat2 >> 2) & 7) + dsp->sbstep; - else - tempi = ((dsp->sbdat2 << 1) & 7) + dsp->sbstep; + case ADPCM_26: + if (!dsp->sbdacpos) + tempi = (dsp->sbdat2 >> 5) + dsp->sbstep; + else if (dsp->sbdacpos == 1) + tempi = ((dsp->sbdat2 >> 2) & 7) + dsp->sbstep; + else + tempi = ((dsp->sbdat2 << 1) & 7) + dsp->sbstep; - if (tempi < 0) - tempi = 0; - if (tempi > 39) - tempi = 39; + if (tempi < 0) + tempi = 0; + if (tempi > 39) + tempi = 39; - ref = dsp->sbref + scaleMap26[tempi]; - if (ref > 0xff) - dsp->sbref = 0xff; - else if (ref < 0x00) - dsp->sbref = 0x00; - else - dsp->sbref = ref; - dsp->sbstep = (dsp->sbstep + adjustMap26[tempi]) & 0xff; + ref = dsp->sbref + scaleMap26[tempi]; + if (ref > 0xff) + dsp->sbref = 0xff; + else if (ref < 0x00) + dsp->sbref = 0x00; + else + dsp->sbref = ref; + dsp->sbstep = (dsp->sbstep + adjustMap26[tempi]) & 0xff; - dsp->sbdat = (dsp->sbref ^ 0x80) << 8; + dsp->sbdat = (dsp->sbref ^ 0x80) << 8; - dsp->sbdacpos++; - if (dsp->sbdacpos >= 3) { - dsp->sbdacpos = 0; - dsp->sbdat2 = sb_8_read_dma(dsp); - dsp->sb_8_length--; - } + dsp->sbdacpos++; + if (dsp->sbdacpos >= 3) { + dsp->sbdacpos = 0; + dsp->sbdat2 = sb_8_read_dma(dsp); + dsp->sb_8_length--; + } - if ((dsp->sb_type >= SBPRO) && (dsp->sb_type < SB16) && dsp->stereo) { - sb_dsp_log("pollsb: ADPCM 26, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); - if (dsp->sbleftright) - dsp->sbdatl = dsp->sbdat; - else - dsp->sbdatr = dsp->sbdat; - dsp->sbleftright = !dsp->sbleftright; - } else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; - break; + if ((dsp->sb_type >= SBPRO) && (dsp->sb_type < SB16) && dsp->stereo) { + sb_dsp_log("pollsb: ADPCM 26, dsp->stereo, %s channel, %04X\n", + dsp->sbleftright ? "left" : "right", dsp->sbdat); + if (dsp->sbleftright) + dsp->sbdatl = dsp->sbdat; + else + dsp->sbdatr = dsp->sbdat; + dsp->sbleftright = !dsp->sbleftright; + } else + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + break; - case ADPCM_2: - tempi = ((dsp->sbdat2 >> ((3 - dsp->sbdacpos) * 2)) & 3) + dsp->sbstep; - if (tempi < 0) - tempi = 0; - if (tempi > 23) - tempi = 23; + case ADPCM_2: + tempi = ((dsp->sbdat2 >> ((3 - dsp->sbdacpos) * 2)) & 3) + dsp->sbstep; + if (tempi < 0) + tempi = 0; + if (tempi > 23) + tempi = 23; - ref = dsp->sbref + scaleMap2[tempi]; - if (ref > 0xff) - dsp->sbref = 0xff; - else if (ref < 0x00) - dsp->sbref = 0x00; - else - dsp->sbref = ref; - dsp->sbstep = (dsp->sbstep + adjustMap2[tempi]) & 0xff; + ref = dsp->sbref + scaleMap2[tempi]; + if (ref > 0xff) + dsp->sbref = 0xff; + else if (ref < 0x00) + dsp->sbref = 0x00; + else + dsp->sbref = ref; + dsp->sbstep = (dsp->sbstep + adjustMap2[tempi]) & 0xff; - dsp->sbdat = (dsp->sbref ^ 0x80) << 8; + dsp->sbdat = (dsp->sbref ^ 0x80) << 8; - dsp->sbdacpos++; - if (dsp->sbdacpos >= 4) { - dsp->sbdacpos = 0; - dsp->sbdat2 = sb_8_read_dma(dsp); - } + dsp->sbdacpos++; + if (dsp->sbdacpos >= 4) { + dsp->sbdacpos = 0; + dsp->sbdat2 = sb_8_read_dma(dsp); + } - if ((dsp->sb_type >= SBPRO) && (dsp->sb_type < SB16) && dsp->stereo) { - sb_dsp_log("pollsb: ADPCM 2, dsp->stereo, %s channel, %04X\n", - dsp->sbleftright ? "left" : "right", dsp->sbdat); - if (dsp->sbleftright) - dsp->sbdatl = dsp->sbdat; - else - dsp->sbdatr = dsp->sbdat; - dsp->sbleftright = !dsp->sbleftright; - } else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; - break; - } + if ((dsp->sb_type >= SBPRO) && (dsp->sb_type < SB16) && dsp->stereo) { + sb_dsp_log("pollsb: ADPCM 2, dsp->stereo, %s channel, %04X\n", + dsp->sbleftright ? "left" : "right", dsp->sbdat); + if (dsp->sbleftright) + dsp->sbdatl = dsp->sbdat; + else + dsp->sbdatr = dsp->sbdat; + dsp->sbleftright = !dsp->sbleftright; + } else + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + break; + } - if (dsp->sb_8_length < 0) { - if (dsp->sb_8_autoinit) - dsp->sb_8_length = dsp->sb_8_autolen; - else { - dsp->sb_8_enable = 0; - timer_disable(&dsp->output_timer); - } - sb_irq(dsp, 1); - } + if (dsp->sb_8_length < 0) { + if (dsp->sb_8_autoinit) + dsp->sb_8_length = dsp->sb_8_autolen; + else { + dsp->sb_8_enable = 0; + timer_disable(&dsp->output_timer); + } + sb_irq(dsp, 1); + } } if (dsp->sb_16_enable && !dsp->sb_16_pause && (dsp->sb_pausetime < 0LL) && dsp->sb_16_output) { - sb_dsp_update(dsp); + sb_dsp_update(dsp); - switch (dsp->sb_16_format) { - case 0x00: /* Mono unsigned */ - data[0] = sb_16_read_dma(dsp); - if (data[0] == DMA_NODATA) - break; - dsp->sbdatl = dsp->sbdatr = data[0] ^ 0x8000; - dsp->sb_16_length--; - break; - case 0x10: /* Mono signed */ - data[0] = sb_16_read_dma(dsp); - if (data[0] == DMA_NODATA) - break; - dsp->sbdatl = dsp->sbdatr = data[0]; - dsp->sb_16_length--; - break; - case 0x20: /* Stereo unsigned */ - data[0] = sb_16_read_dma(dsp); - data[1] = sb_16_read_dma(dsp); - if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) - break; - dsp->sbdatl = data[0] ^ 0x8000; - dsp->sbdatr = data[1] ^ 0x8000; - dsp->sb_16_length -= 2; - break; - case 0x30: /* Stereo signed */ - data[0] = sb_16_read_dma(dsp); - data[1] = sb_16_read_dma(dsp); - if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) - break; - dsp->sbdatl = data[0]; - dsp->sbdatr = data[1]; - dsp->sb_16_length -= 2; - break; - } + switch (dsp->sb_16_format) { + case 0x00: /* Mono unsigned */ + data[0] = sb_16_read_dma(dsp); + if (data[0] == DMA_NODATA) + break; + dsp->sbdatl = dsp->sbdatr = data[0] ^ 0x8000; + dsp->sb_16_length--; + break; + case 0x10: /* Mono signed */ + data[0] = sb_16_read_dma(dsp); + if (data[0] == DMA_NODATA) + break; + dsp->sbdatl = dsp->sbdatr = data[0]; + dsp->sb_16_length--; + break; + case 0x20: /* Stereo unsigned */ + data[0] = sb_16_read_dma(dsp); + data[1] = sb_16_read_dma(dsp); + if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) + break; + dsp->sbdatl = data[0] ^ 0x8000; + dsp->sbdatr = data[1] ^ 0x8000; + dsp->sb_16_length -= 2; + break; + case 0x30: /* Stereo signed */ + data[0] = sb_16_read_dma(dsp); + data[1] = sb_16_read_dma(dsp); + if ((data[0] == DMA_NODATA) || (data[1] == DMA_NODATA)) + break; + dsp->sbdatl = data[0]; + dsp->sbdatr = data[1]; + dsp->sb_16_length -= 2; + break; + } - if (dsp->sb_16_length < 0) { - sb_dsp_log("16DMA over %i\n", dsp->sb_16_autoinit); - if (dsp->sb_16_autoinit) - dsp->sb_16_length = dsp->sb_16_autolen; - else { - dsp->sb_16_enable = 0; - timer_disable(&dsp->output_timer); - } - sb_irq(dsp, 0); - } + if (dsp->sb_16_length < 0) { + sb_dsp_log("16DMA over %i\n", dsp->sb_16_autoinit); + if (dsp->sb_16_autoinit) + dsp->sb_16_length = dsp->sb_16_autolen; + else { + dsp->sb_16_enable = 0; + timer_disable(&dsp->output_timer); + } + sb_irq(dsp, 0); + } } if (dsp->sb_pausetime > -1) { - dsp->sb_pausetime--; - if (dsp->sb_pausetime < 0) { - sb_irq(dsp, 1); - if (!dsp->sb_8_enable) - timer_disable(&dsp->output_timer); - sb_dsp_log("SB pause over\n"); - } + dsp->sb_pausetime--; + if (dsp->sb_pausetime < 0) { + sb_irq(dsp, 1); + if (!dsp->sb_8_enable) + timer_disable(&dsp->output_timer); + sb_dsp_log("SB pause over\n"); + } } } - void sb_poll_i(void *p) { - sb_dsp_t *dsp = (sb_dsp_t *) p; - int processed = 0; + sb_dsp_t *dsp = (sb_dsp_t *) p; + int processed = 0; timer_advance_u64(&dsp->input_timer, dsp->sblatchi); if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && !dsp->sb_8_output) { - switch (dsp->sb_8_format) { - case 0x00: /* Mono unsigned As the manual says, only the left channel is recorded */ - sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read]>>8) ^0x80); - dsp->sb_8_length--; - dsp->record_pos_read += 2; - dsp->record_pos_read &= 0xFFFF; - break; - case 0x10: /* Mono signed As the manual says, only the left channel is recorded */ - sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read]>>8)); - dsp->sb_8_length--; - dsp->record_pos_read += 2; - dsp->record_pos_read &= 0xFFFF; - break; - case 0x20: /* Stereo unsigned */ - sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read]>>8)^0x80); - sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read+1]>>8)^0x80); - dsp->sb_8_length -= 2; - dsp->record_pos_read += 2; - dsp->record_pos_read &= 0xFFFF; - break; - case 0x30: /* Stereo signed */ - sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read]>>8)); - sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read+1]>>8)); - dsp->sb_8_length -= 2; - dsp->record_pos_read += 2; - dsp->record_pos_read &= 0xFFFF; - break; - } + switch (dsp->sb_8_format) { + case 0x00: /* Mono unsigned As the manual says, only the left channel is recorded */ + sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read] >> 8) ^ 0x80); + dsp->sb_8_length--; + dsp->record_pos_read += 2; + dsp->record_pos_read &= 0xFFFF; + break; + case 0x10: /* Mono signed As the manual says, only the left channel is recorded */ + sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read] >> 8)); + dsp->sb_8_length--; + dsp->record_pos_read += 2; + dsp->record_pos_read &= 0xFFFF; + break; + case 0x20: /* Stereo unsigned */ + sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read] >> 8) ^ 0x80); + sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read + 1] >> 8) ^ 0x80); + dsp->sb_8_length -= 2; + dsp->record_pos_read += 2; + dsp->record_pos_read &= 0xFFFF; + break; + case 0x30: /* Stereo signed */ + sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read] >> 8)); + sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read + 1] >> 8)); + dsp->sb_8_length -= 2; + dsp->record_pos_read += 2; + dsp->record_pos_read &= 0xFFFF; + break; + } - if (dsp->sb_8_length < 0) { - if (dsp->sb_8_autoinit) - dsp->sb_8_length = dsp->sb_8_autolen; - else { - dsp->sb_8_enable = 0; - timer_disable(&dsp->input_timer); - } - sb_irq(dsp, 1); - } - processed = 1; + if (dsp->sb_8_length < 0) { + if (dsp->sb_8_autoinit) + dsp->sb_8_length = dsp->sb_8_autolen; + else { + dsp->sb_8_enable = 0; + timer_disable(&dsp->input_timer); + } + sb_irq(dsp, 1); + } + processed = 1; } if (dsp->sb_16_enable && !dsp->sb_16_pause && (dsp->sb_pausetime < 0LL) && !dsp->sb_16_output) { - switch (dsp->sb_16_format) { - case 0x00: /* Unsigned mono. As the manual says, only the left channel is recorded */ - if (sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read]^0x8000)) - return; - dsp->sb_16_length--; - dsp->record_pos_read += 2; - dsp->record_pos_read &= 0xFFFF; - break; - case 0x10: /* Signed mono. As the manual says, only the left channel is recorded */ - if (sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read])) - return; - dsp->sb_16_length--; - dsp->record_pos_read += 2; - dsp->record_pos_read &= 0xFFFF; - break; - case 0x20: /* Unsigned stereo */ - if (sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read]^0x8000)) - return; - sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read+1]^0x8000); - dsp->sb_16_length -= 2; - dsp->record_pos_read += 2; - dsp->record_pos_read &= 0xFFFF; - break; - case 0x30: /* Signed stereo */ - if (sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read])) - return; - sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read+1]); - dsp->sb_16_length -= 2; - dsp->record_pos_read += 2; - dsp->record_pos_read &= 0xFFFF; - break; - } + switch (dsp->sb_16_format) { + case 0x00: /* Unsigned mono. As the manual says, only the left channel is recorded */ + if (sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read] ^ 0x8000)) + return; + dsp->sb_16_length--; + dsp->record_pos_read += 2; + dsp->record_pos_read &= 0xFFFF; + break; + case 0x10: /* Signed mono. As the manual says, only the left channel is recorded */ + if (sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read])) + return; + dsp->sb_16_length--; + dsp->record_pos_read += 2; + dsp->record_pos_read &= 0xFFFF; + break; + case 0x20: /* Unsigned stereo */ + if (sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read] ^ 0x8000)) + return; + sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read + 1] ^ 0x8000); + dsp->sb_16_length -= 2; + dsp->record_pos_read += 2; + dsp->record_pos_read &= 0xFFFF; + break; + case 0x30: /* Signed stereo */ + if (sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read])) + return; + sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read + 1]); + dsp->sb_16_length -= 2; + dsp->record_pos_read += 2; + dsp->record_pos_read &= 0xFFFF; + break; + } - if (dsp->sb_16_length < 0) { - if (dsp->sb_16_autoinit) - dsp->sb_16_length = dsp->sb_16_autolen; - else { - dsp->sb_16_enable = 0; - timer_disable(&dsp->input_timer); - } - sb_irq(dsp, 0); - } - processed = 1; + if (dsp->sb_16_length < 0) { + if (dsp->sb_16_autoinit) + dsp->sb_16_length = dsp->sb_16_autolen; + else { + dsp->sb_16_enable = 0; + timer_disable(&dsp->input_timer); + } + sb_irq(dsp, 0); + } + processed = 1; } /* Assume this is direct mode */ if (!processed) { - dsp->record_pos_read += 2; - dsp->record_pos_read &= 0xFFFF; + dsp->record_pos_read += 2; + dsp->record_pos_read &= 0xFFFF; } } - -void sb_dsp_update(sb_dsp_t *dsp) +void +sb_dsp_update(sb_dsp_t *dsp) { if (dsp->muted) { - dsp->sbdatl = 0; - dsp->sbdatr = 0; + dsp->sbdatl = 0; + dsp->sbdatr = 0; } for (; dsp->pos < sound_pos_global; dsp->pos++) { - dsp->buffer[dsp->pos*2] = dsp->sbdatl; - dsp->buffer[dsp->pos*2 + 1] = dsp->sbdatr; + dsp->buffer[dsp->pos * 2] = dsp->sbdatl; + dsp->buffer[dsp->pos * 2 + 1] = dsp->sbdatr; } } - void sb_dsp_close(sb_dsp_t *dsp) { diff --git a/src/sound/snd_sn76489.c b/src/sound/snd_sn76489.c index a1cc66a40..96b152b18 100644 --- a/src/sound/snd_sn76489.c +++ b/src/sound/snd_sn76489.c @@ -1,311 +1,303 @@ -#include #include -#include +#include #include -#include +#include #include +#include + #include <86box/86box.h> -#include <86box/io.h> #include <86box/device.h> +#include <86box/io.h> #include <86box/sound.h> #include <86box/snd_sn76489.h> - int sn76489_mute; - -static float volslog[16]= -{ - 0.00000f,0.59715f,0.75180f,0.94650f, - 1.19145f,1.50000f,1.88835f,2.37735f, - 2.99295f,3.76785f,4.74345f,5.97165f, - 7.51785f,9.46440f,11.9194f,15.0000f +static float volslog[16] = { + 0.00000f, 0.59715f, 0.75180f, 0.94650f, + 1.19145f, 1.50000f, 1.88835f, 2.37735f, + 2.99295f, 3.76785f, 4.74345f, 5.97165f, + 7.51785f, 9.46440f, 11.9194f, 15.0000f }; -void sn76489_update(sn76489_t *sn76489) +void +sn76489_update(sn76489_t *sn76489) { - for (; sn76489->pos < sound_pos_global; sn76489->pos++) - { - int c; - int16_t result = 0; + for (; sn76489->pos < sound_pos_global; sn76489->pos++) { + int c; + int16_t result = 0; - for (c = 1; c < 4; c++) - { - if (sn76489->latch[c] > 256) result += (int16_t) (volslog[sn76489->vol[c]] * sn76489->stat[c]); - else result += (int16_t) (volslog[sn76489->vol[c]] * 127); + for (c = 1; c < 4; c++) { + if (sn76489->latch[c] > 256) + result += (int16_t) (volslog[sn76489->vol[c]] * sn76489->stat[c]); + else + result += (int16_t) (volslog[sn76489->vol[c]] * 127); - sn76489->count[c] -= (256 * sn76489->psgconst); - while ((int)sn76489->count[c] < 0) - { - sn76489->count[c] += sn76489->latch[c]; - sn76489->stat[c] = -sn76489->stat[c]; - } - } - result += (((sn76489->shift & 1) ^ 1) * 127 * volslog[sn76489->vol[0]] * 2); - - sn76489->count[0] -= (512 * sn76489->psgconst); - while ((int)sn76489->count[0] < 0 && sn76489->latch[0]) - { - sn76489->count[0] += (sn76489->latch[0] * 4); - if (!(sn76489->noise & 4)) - { - if (sn76489->shift & 1) - sn76489->shift |= 0x8000; - sn76489->shift >>= 1; - } - else - { - if ((sn76489->shift & 1) ^ ((sn76489->shift >> 1) & 1)) - sn76489->shift |= 0x8000; - sn76489->shift >>= 1; - } - } - - sn76489->buffer[sn76489->pos] = result; + sn76489->count[c] -= (256 * sn76489->psgconst); + while ((int) sn76489->count[c] < 0) { + sn76489->count[c] += sn76489->latch[c]; + sn76489->stat[c] = -sn76489->stat[c]; + } } -} + result += (((sn76489->shift & 1) ^ 1) * 127 * volslog[sn76489->vol[0]] * 2); -void sn76489_get_buffer(int32_t *buffer, int len, void *p) -{ - sn76489_t *sn76489 = (sn76489_t *)p; - - int c; - - sn76489_update(sn76489); - - if (!sn76489_mute) - { - for (c = 0; c < len * 2; c++) - buffer[c] += sn76489->buffer[c >> 1]; + sn76489->count[0] -= (512 * sn76489->psgconst); + while ((int) sn76489->count[0] < 0 && sn76489->latch[0]) { + sn76489->count[0] += (sn76489->latch[0] * 4); + if (!(sn76489->noise & 4)) { + if (sn76489->shift & 1) + sn76489->shift |= 0x8000; + sn76489->shift >>= 1; + } else { + if ((sn76489->shift & 1) ^ ((sn76489->shift >> 1) & 1)) + sn76489->shift |= 0x8000; + sn76489->shift >>= 1; + } } - sn76489->pos = 0; + sn76489->buffer[sn76489->pos] = result; + } } -void sn76489_write(uint16_t addr, uint8_t data, void *p) +void +sn76489_get_buffer(int32_t *buffer, int len, void *p) { - sn76489_t *sn76489 = (sn76489_t *)p; - int freq; + sn76489_t *sn76489 = (sn76489_t *) p; - sn76489_update(sn76489); + int c; - if (data & 0x80) - { - sn76489->firstdat = data; - switch (data & 0x70) - { - case 0: - sn76489->freqlo[3] = data & 0xf; - sn76489->latch[3] = (sn76489->freqlo[3] | (sn76489->freqhi[3] << 4)) << 6; - if (sn76489->extra_divide) - sn76489->latch[3] &= 0x3ff; - if (!sn76489->latch[3]) - sn76489->latch[3] = (sn76489->extra_divide ? 2048 : 1024) << 6; - sn76489->lasttone = 3; - break; - case 0x10: - data &= 0xf; - sn76489->vol[3] = 0xf - data; - break; - case 0x20: - sn76489->freqlo[2] = data & 0xf; - sn76489->latch[2] = (sn76489->freqlo[2] | (sn76489->freqhi[2] << 4)) << 6; - if (sn76489->extra_divide) - sn76489->latch[2] &= 0x3ff; - if (!sn76489->latch[2]) - sn76489->latch[2] = (sn76489->extra_divide ? 2048 : 1024) << 6; - sn76489->lasttone = 2; - break; - case 0x30: - data &= 0xf; - sn76489->vol[2] = 0xf - data; - break; - case 0x40: - sn76489->freqlo[1] = data & 0xf; - sn76489->latch[1] = (sn76489->freqlo[1] | (sn76489->freqhi[1] << 4)) << 6; - if (sn76489->extra_divide) - sn76489->latch[1] &= 0x3ff; - if (!sn76489->latch[1]) - sn76489->latch[1] = (sn76489->extra_divide ? 2048 : 1024) << 6; - sn76489->lasttone = 1; - break; - case 0x50: - data &= 0xf; - sn76489->vol[1] = 0xf - data; - break; - case 0x60: - if ((data & 4) != (sn76489->noise & 4) || sn76489->type == SN76496) - sn76489->shift = 0x4000; - sn76489->noise = data & 0xf; - if ((data & 3) == 3) sn76489->latch[0] = sn76489->latch[1]; - else sn76489->latch[0] = 0x400 << (data & 3); - if (sn76489->extra_divide) - sn76489->latch[0] &= 0x3ff; - if (!sn76489->latch[0]) - sn76489->latch[0] = (sn76489->extra_divide ? 2048 : 1024) << 6; - break; - case 0x70: - data &= 0xf; - sn76489->vol[0] = 0xf - data; - break; - } + sn76489_update(sn76489); + + if (!sn76489_mute) { + for (c = 0; c < len * 2; c++) + buffer[c] += sn76489->buffer[c >> 1]; + } + + sn76489->pos = 0; +} + +void +sn76489_write(uint16_t addr, uint8_t data, void *p) +{ + sn76489_t *sn76489 = (sn76489_t *) p; + int freq; + + sn76489_update(sn76489); + + if (data & 0x80) { + sn76489->firstdat = data; + switch (data & 0x70) { + case 0: + sn76489->freqlo[3] = data & 0xf; + sn76489->latch[3] = (sn76489->freqlo[3] | (sn76489->freqhi[3] << 4)) << 6; + if (sn76489->extra_divide) + sn76489->latch[3] &= 0x3ff; + if (!sn76489->latch[3]) + sn76489->latch[3] = (sn76489->extra_divide ? 2048 : 1024) << 6; + sn76489->lasttone = 3; + break; + case 0x10: + data &= 0xf; + sn76489->vol[3] = 0xf - data; + break; + case 0x20: + sn76489->freqlo[2] = data & 0xf; + sn76489->latch[2] = (sn76489->freqlo[2] | (sn76489->freqhi[2] << 4)) << 6; + if (sn76489->extra_divide) + sn76489->latch[2] &= 0x3ff; + if (!sn76489->latch[2]) + sn76489->latch[2] = (sn76489->extra_divide ? 2048 : 1024) << 6; + sn76489->lasttone = 2; + break; + case 0x30: + data &= 0xf; + sn76489->vol[2] = 0xf - data; + break; + case 0x40: + sn76489->freqlo[1] = data & 0xf; + sn76489->latch[1] = (sn76489->freqlo[1] | (sn76489->freqhi[1] << 4)) << 6; + if (sn76489->extra_divide) + sn76489->latch[1] &= 0x3ff; + if (!sn76489->latch[1]) + sn76489->latch[1] = (sn76489->extra_divide ? 2048 : 1024) << 6; + sn76489->lasttone = 1; + break; + case 0x50: + data &= 0xf; + sn76489->vol[1] = 0xf - data; + break; + case 0x60: + if ((data & 4) != (sn76489->noise & 4) || sn76489->type == SN76496) + sn76489->shift = 0x4000; + sn76489->noise = data & 0xf; + if ((data & 3) == 3) + sn76489->latch[0] = sn76489->latch[1]; + else + sn76489->latch[0] = 0x400 << (data & 3); + if (sn76489->extra_divide) + sn76489->latch[0] &= 0x3ff; + if (!sn76489->latch[0]) + sn76489->latch[0] = (sn76489->extra_divide ? 2048 : 1024) << 6; + break; + case 0x70: + data &= 0xf; + sn76489->vol[0] = 0xf - data; + break; } - else - { - if ((sn76489->firstdat & 0x70) == 0x60 && (sn76489->type == SN76496)) - { - if ((data & 4) != (sn76489->noise & 4) || sn76489->type == SN76496) - sn76489->shift = 0x4000; - sn76489->noise = data & 0xf; - if ((data & 3) == 3) sn76489->latch[0] = sn76489->latch[1]; - else sn76489->latch[0] = 0x400 << (data & 3); - if (!sn76489->latch[0]) - sn76489->latch[0] = 1024 << 6; - } - else if ((sn76489->firstdat & 0x70) != 0x60) - { - sn76489->freqhi[sn76489->lasttone] = data & 0x7F; - freq = sn76489->freqlo[sn76489->lasttone] | (sn76489->freqhi[sn76489->lasttone] << 4); - if (sn76489->extra_divide) - freq &= 0x3ff; - if (!freq) - freq = sn76489->extra_divide ? 2048 : 1024; - if ((sn76489->noise & 3) == 3 && sn76489->lasttone == 1) - sn76489->latch[0] = freq << 6; - sn76489->latch[sn76489->lasttone] = freq << 6; - } + } else { + if ((sn76489->firstdat & 0x70) == 0x60 && (sn76489->type == SN76496)) { + if ((data & 4) != (sn76489->noise & 4) || sn76489->type == SN76496) + sn76489->shift = 0x4000; + sn76489->noise = data & 0xf; + if ((data & 3) == 3) + sn76489->latch[0] = sn76489->latch[1]; + else + sn76489->latch[0] = 0x400 << (data & 3); + if (!sn76489->latch[0]) + sn76489->latch[0] = 1024 << 6; + } else if ((sn76489->firstdat & 0x70) != 0x60) { + sn76489->freqhi[sn76489->lasttone] = data & 0x7F; + freq = sn76489->freqlo[sn76489->lasttone] | (sn76489->freqhi[sn76489->lasttone] << 4); + if (sn76489->extra_divide) + freq &= 0x3ff; + if (!freq) + freq = sn76489->extra_divide ? 2048 : 1024; + if ((sn76489->noise & 3) == 3 && sn76489->lasttone == 1) + sn76489->latch[0] = freq << 6; + sn76489->latch[sn76489->lasttone] = freq << 6; } + } } -void sn74689_set_extra_divide(sn76489_t *sn76489, int enable) +void +sn74689_set_extra_divide(sn76489_t *sn76489, int enable) { - sn76489->extra_divide = enable; + sn76489->extra_divide = enable; } -void sn76489_init(sn76489_t *sn76489, uint16_t base, uint16_t size, int type, int freq) +void +sn76489_init(sn76489_t *sn76489, uint16_t base, uint16_t size, int type, int freq) { - sound_add_handler(sn76489_get_buffer, sn76489); + sound_add_handler(sn76489_get_buffer, sn76489); - sn76489->latch[0] = sn76489->latch[1] = sn76489->latch[2] = sn76489->latch[3] = 0x3FF << 6; - sn76489->vol[0] = 0; - sn76489->vol[1] = sn76489->vol[2] = sn76489->vol[3] = 8; - sn76489->stat[0] = sn76489->stat[1] = sn76489->stat[2] = sn76489->stat[3] = 127; - srand(time(NULL)); - sn76489->count[0] = 0; - sn76489->count[1] = (rand()&0x3FF)<<6; - sn76489->count[2] = (rand()&0x3FF)<<6; - sn76489->count[3] = (rand()&0x3FF)<<6; - sn76489->noise = 3; - sn76489->shift = 0x4000; - sn76489->type = type; - sn76489->psgconst = (((double)freq / 64.0) / 48000.0); + sn76489->latch[0] = sn76489->latch[1] = sn76489->latch[2] = sn76489->latch[3] = 0x3FF << 6; + sn76489->vol[0] = 0; + sn76489->vol[1] = sn76489->vol[2] = sn76489->vol[3] = 8; + sn76489->stat[0] = sn76489->stat[1] = sn76489->stat[2] = sn76489->stat[3] = 127; + srand(time(NULL)); + sn76489->count[0] = 0; + sn76489->count[1] = (rand() & 0x3FF) << 6; + sn76489->count[2] = (rand() & 0x3FF) << 6; + sn76489->count[3] = (rand() & 0x3FF) << 6; + sn76489->noise = 3; + sn76489->shift = 0x4000; + sn76489->type = type; + sn76489->psgconst = (((double) freq / 64.0) / 48000.0); - sn76489_mute = 0; + sn76489_mute = 0; - io_sethandler(base, size, NULL, NULL, NULL, sn76489_write, NULL, NULL, sn76489); + io_sethandler(base, size, NULL, NULL, NULL, sn76489_write, NULL, NULL, sn76489); } -void *sn76489_device_init(const device_t *info) +void * +sn76489_device_init(const device_t *info) { - sn76489_t *sn76489 = malloc(sizeof(sn76489_t)); - memset(sn76489, 0, sizeof(sn76489_t)); + sn76489_t *sn76489 = malloc(sizeof(sn76489_t)); + memset(sn76489, 0, sizeof(sn76489_t)); - sn76489_init(sn76489, 0x00c0, 0x0008, SN76496, 3579545); + sn76489_init(sn76489, 0x00c0, 0x0008, SN76496, 3579545); - return sn76489; + return sn76489; } -void *ncr8496_device_init(const device_t *info) +void * +ncr8496_device_init(const device_t *info) { - sn76489_t *sn76489 = malloc(sizeof(sn76489_t)); - memset(sn76489, 0, sizeof(sn76489_t)); + sn76489_t *sn76489 = malloc(sizeof(sn76489_t)); + memset(sn76489, 0, sizeof(sn76489_t)); - sn76489_init(sn76489, 0x00c0, 0x0008, NCR8496, 3579545); + sn76489_init(sn76489, 0x00c0, 0x0008, NCR8496, 3579545); - return sn76489; + return sn76489; } #if defined(DEV_BRANCH) && defined(USE_TANDY_ISA) -void *tndy_device_init(const device_t *info) +void * +tndy_device_init(const device_t *info) { - sn76489_t *sn76489 = malloc(sizeof(sn76489_t)); - memset(sn76489, 0, sizeof(sn76489_t)); + sn76489_t *sn76489 = malloc(sizeof(sn76489_t)); + memset(sn76489, 0, sizeof(sn76489_t)); - uint16_t addr = device_get_config_hex16("base"); + uint16_t addr = device_get_config_hex16("base"); - sn76489_init(sn76489, addr, 0x0008, SN76496, 3579545); + sn76489_init(sn76489, addr, 0x0008, SN76496, 3579545); - return sn76489; + return sn76489; } #endif -void sn76489_device_close(void *p) +void +sn76489_device_close(void *p) { - sn76489_t *sn76489 = (sn76489_t *)p; + sn76489_t *sn76489 = (sn76489_t *) p; - free(sn76489); + free(sn76489); } #if defined(DEV_BRANCH) && defined(USE_TANDY_ISA) -static const device_config_t tndy_config[] = -{ +static const device_config_t tndy_config[] = { +// clang-format off + { + "base", "Address", CONFIG_HEX16, "", 0x0C0, "", { 0 }, { - "base", "Address", CONFIG_HEX16, "", 0x0C0, "", { 0 }, - { - { - "0x0C0", 0x0C0 - }, - { - "0x1E0", 0x1E0 - }, - { - "0x2C0", 0x2C0 - }, - { - "" - } - } - }, - { - "", "", -1 + { "0x0C0", 0x0C0 }, + { "0x1E0", 0x1E0 }, + { "0x2C0", 0x2C0 }, + { "" } } + }, + { "", "", -1 } +// clang-format on }; #endif -const device_t sn76489_device = -{ - "TI SN74689 PSG", - "sn76489", - 0, - 0, - sn76489_device_init, - sn76489_device_close, - NULL, { NULL }, NULL, - NULL +const device_t sn76489_device = { + "TI SN74689 PSG", + "sn76489", + 0, + 0, + sn76489_device_init, + sn76489_device_close, + NULL, + { NULL }, + NULL, + NULL }; -const device_t ncr8496_device = -{ - "NCR8496 PSG", - "ncr8496", - 0, - 0, - ncr8496_device_init, - sn76489_device_close, - NULL, { NULL }, NULL, - NULL +const device_t ncr8496_device = { + "NCR8496 PSG", + "ncr8496", + 0, + 0, + ncr8496_device_init, + sn76489_device_close, + NULL, + { NULL }, + NULL, + NULL }; #if defined(DEV_BRANCH) && defined(USE_TANDY_ISA) -const device_t tndy_device = -{ - "TNDY", - "tndy", - DEVICE_ISA, - 0, - tndy_device_init, - sn76489_device_close, - NULL, { NULL }, NULL, - NULL, - tndy_config +const device_t tndy_device = { + "TNDY", + "tndy", + DEVICE_ISA, + 0, + tndy_device_init, + sn76489_device_close, + NULL, + { NULL }, + NULL, + NULL, + tndy_config }; #endif diff --git a/src/sound/snd_speaker.c b/src/sound/snd_speaker.c index 027febf40..34d32c110 100644 --- a/src/sound/snd_speaker.c +++ b/src/sound/snd_speaker.c @@ -1,89 +1,85 @@ /* - * 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. * - * Emulation of the PC speaker. + * Emulation of the PC speaker. * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Sarah Walker, + * Miran Grca, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. */ -#include #include +#include #include #include + #include <86box/86box.h> #include <86box/timer.h> #include <86box/pit.h> -#include <86box/sound.h> #include <86box/snd_speaker.h> - +#include <86box/sound.h> int speaker_mute = 0, speaker_gated = 0; int speaker_enable = 0, was_speaker_enable = 0; int gated, speakval, speakon; - static int32_t speaker_buffer[SOUNDBUFLEN]; -static int speaker_pos = 0; - -static uint8_t speaker_mode = 0; -static double speaker_count = 65535.0; +static int speaker_pos = 0; +static uint8_t speaker_mode = 0; +static double speaker_count = 65535.0; void speaker_set_count(uint8_t new_m, int new_count) { - speaker_mode = new_m; + speaker_mode = new_m; speaker_count = (double) new_count; } - void speaker_update(void) { int32_t val; - double amplitude; + double amplitude; amplitude = ((speaker_count / 64.0) * 10240.0) - 5120.0; if (amplitude > 5120.0) - amplitude = 5120.0; + amplitude = 5120.0; if (speaker_pos < sound_pos_global) { - for (; speaker_pos < sound_pos_global; speaker_pos++) { - if (speaker_gated && was_speaker_enable) { - if ((speaker_mode == 0) || (speaker_mode == 4)) - val = (int32_t) amplitude; - else if (speaker_count < 64.0) - val = 0xa00; - else - val = speakon ? 0x1400 : 0; - } else { - if (speaker_mode == 1) - val = was_speaker_enable ? (int32_t) amplitude : 0; - else - val = was_speaker_enable ? 0x1400 : 0; - } + for (; speaker_pos < sound_pos_global; speaker_pos++) { + if (speaker_gated && was_speaker_enable) { + if ((speaker_mode == 0) || (speaker_mode == 4)) + val = (int32_t) amplitude; + else if (speaker_count < 64.0) + val = 0xa00; + else + val = speakon ? 0x1400 : 0; + } else { + if (speaker_mode == 1) + val = was_speaker_enable ? (int32_t) amplitude : 0; + else + val = was_speaker_enable ? 0x1400 : 0; + } - if (!speaker_enable) - was_speaker_enable = 0; + if (!speaker_enable) + was_speaker_enable = 0; - speaker_buffer[speaker_pos] = val; - } + speaker_buffer[speaker_pos] = val; + } } } - void speaker_get_buffer(int32_t *buffer, int len, void *p) { @@ -92,17 +88,16 @@ speaker_get_buffer(int32_t *buffer, int len, void *p) speaker_update(); if (!speaker_mute) { - for (c = 0; c < len * 2; c += 2) { - val = speaker_buffer[c >> 1]; - buffer[c] += val; - buffer[c + 1] += val; - } + for (c = 0; c < len * 2; c += 2) { + val = speaker_buffer[c >> 1]; + buffer[c] += val; + buffer[c + 1] += val; + } } speaker_pos = 0; } - void speaker_init(void) { diff --git a/src/sound/snd_ssi2001.c b/src/sound/snd_ssi2001.c index c44471467..cfbdf8d49 100644 --- a/src/sound/snd_ssi2001.c +++ b/src/sound/snd_ssi2001.c @@ -1,126 +1,122 @@ #include #include #include -#include #include +#include #include #define HAVE_STDARG_H + #include <86box/86box.h> -#include <86box/io.h> #include <86box/device.h> #include <86box/gameport.h> -#include <86box/sound.h> +#include <86box/io.h> #include <86box/snd_resid.h> +#include <86box/sound.h> - -typedef struct ssi2001_t -{ - void *psid; - int16_t buffer[SOUNDBUFLEN * 2]; - int pos; - int gameport_enabled; +typedef struct ssi2001_t { + void *psid; + int16_t buffer[SOUNDBUFLEN * 2]; + int pos; + int gameport_enabled; } ssi2001_t; -static void ssi2001_update(ssi2001_t *ssi2001) +static void +ssi2001_update(ssi2001_t *ssi2001) { - if (ssi2001->pos >= sound_pos_global) - return; + if (ssi2001->pos >= sound_pos_global) + return; - sid_fillbuf(&ssi2001->buffer[ssi2001->pos], sound_pos_global - ssi2001->pos, ssi2001->psid); - ssi2001->pos = sound_pos_global; + sid_fillbuf(&ssi2001->buffer[ssi2001->pos], sound_pos_global - ssi2001->pos, ssi2001->psid); + ssi2001->pos = sound_pos_global; } -static void ssi2001_get_buffer(int32_t *buffer, int len, void *p) +static void +ssi2001_get_buffer(int32_t *buffer, int len, void *p) { - ssi2001_t *ssi2001 = (ssi2001_t *)p; - int c; + ssi2001_t *ssi2001 = (ssi2001_t *) p; + int c; - ssi2001_update(ssi2001); + ssi2001_update(ssi2001); - for (c = 0; c < len * 2; c++) - buffer[c] += ssi2001->buffer[c >> 1] / 2; + for (c = 0; c < len * 2; c++) + buffer[c] += ssi2001->buffer[c >> 1] / 2; - ssi2001->pos = 0; + ssi2001->pos = 0; } -static uint8_t ssi2001_read(uint16_t addr, void *p) +static uint8_t +ssi2001_read(uint16_t addr, void *p) { - ssi2001_t *ssi2001 = (ssi2001_t *)p; + ssi2001_t *ssi2001 = (ssi2001_t *) p; - ssi2001_update(ssi2001); + ssi2001_update(ssi2001); - return sid_read(addr, p); + return sid_read(addr, p); } -static void ssi2001_write(uint16_t addr, uint8_t val, void *p) +static void +ssi2001_write(uint16_t addr, uint8_t val, void *p) { - ssi2001_t *ssi2001 = (ssi2001_t *)p; + ssi2001_t *ssi2001 = (ssi2001_t *) p; - ssi2001_update(ssi2001); - sid_write(addr, val, p); + ssi2001_update(ssi2001); + sid_write(addr, val, p); } -void *ssi2001_init(const device_t *info) +void * +ssi2001_init(const device_t *info) { - ssi2001_t *ssi2001 = malloc(sizeof(ssi2001_t)); - memset(ssi2001, 0, sizeof(ssi2001_t)); + ssi2001_t *ssi2001 = malloc(sizeof(ssi2001_t)); + memset(ssi2001, 0, sizeof(ssi2001_t)); - ssi2001->psid = sid_init(); - sid_reset(ssi2001->psid); - uint16_t addr = device_get_config_hex16("base"); - ssi2001->gameport_enabled = device_get_config_int("gameport"); - io_sethandler(addr, 0x0020, ssi2001_read, NULL, NULL, ssi2001_write, NULL, NULL, ssi2001); - if (ssi2001->gameport_enabled) + ssi2001->psid = sid_init(); + sid_reset(ssi2001->psid); + uint16_t addr = device_get_config_hex16("base"); + ssi2001->gameport_enabled = device_get_config_int("gameport"); + io_sethandler(addr, 0x0020, ssi2001_read, NULL, NULL, ssi2001_write, NULL, NULL, ssi2001); + if (ssi2001->gameport_enabled) gameport_remap(gameport_add(&gameport_201_device), 0x201); - sound_add_handler(ssi2001_get_buffer, ssi2001); - return ssi2001; + sound_add_handler(ssi2001_get_buffer, ssi2001); + return ssi2001; } -void ssi2001_close(void *p) +void +ssi2001_close(void *p) { - ssi2001_t *ssi2001 = (ssi2001_t *)p; + ssi2001_t *ssi2001 = (ssi2001_t *) p; - sid_close(ssi2001->psid); + sid_close(ssi2001->psid); - free(ssi2001); + free(ssi2001); } -static const device_config_t ssi2001_config[] = -{ +static const device_config_t ssi2001_config[] = { +// clang-format off + { "base", "Address", CONFIG_HEX16, "", 0x280, "", { 0 }, { - "base", "Address", CONFIG_HEX16, "", 0x280, "", { 0 }, - { - { - "0x280", 0x280 - }, - { - "0x2A0", 0x2A0 - }, - { - "0x2C0", 0x2C0 - }, - { - "0x2E0", 0x2E0 - }, - { - "" - } - } - }, - { - "gameport", "Enable Game port", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 + { "0x280", 0x280 }, + { "0x2A0", 0x2A0 }, + { "0x2C0", 0x2C0 }, + { "0x2E0", 0x2E0 }, + { "" } } + }, + { "gameport", "Enable Game port", CONFIG_BINARY, "", 1 }, + { "", "", -1 } +// clang-format off }; const device_t ssi2001_device = { - "Innovation SSI-2001", - "ssi2001", - DEVICE_ISA, 0, - ssi2001_init, ssi2001_close, NULL, - { NULL }, NULL, NULL, - ssi2001_config + "Innovation SSI-2001", + "ssi2001", + DEVICE_ISA, + 0, + ssi2001_init, + ssi2001_close, + NULL, + { NULL }, + NULL, + NULL, + ssi2001_config }; diff --git a/src/sound/snd_wss.c b/src/sound/snd_wss.c index b3e06cf94..7428d22d6 100644 --- a/src/sound/snd_wss.c +++ b/src/sound/snd_wss.c @@ -1,39 +1,39 @@ /* - * 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. * - * Windows Sound System emulation. + * Windows Sound System emulation. * * * - * Authors: Sarah Walker, - * TheCollector1995, + * Authors: Sarah Walker, + * TheCollector1995, * - * Copyright 2012-2018 Sarah Walker. - * Copyright 2018 TheCollector1995. + * Copyright 2012-2018 Sarah Walker. + * Copyright 2018 TheCollector1995. */ -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include + #include <86box/86box.h> +#include <86box/device.h> +#include <86box/dma.h> #include <86box/io.h> -#include <86box/timer.h> #include <86box/mca.h> #include <86box/pic.h> -#include <86box/dma.h> -#include <86box/device.h> #include <86box/sound.h> +#include <86box/timer.h> #include <86box/snd_ad1848.h> #include <86box/snd_opl.h> - /* 530, 11, 3 - 530=23 * 530, 11, 1 - 530=22 * 530, 11, 0 - 530=21 @@ -45,29 +45,26 @@ * f40, 11, 1 - 530=22 */ - -static const int wss_dma[4] = {0, 0, 1, 3}; -static const int wss_irq[8] = {5, 7, 9, 10, 11, 12, 14, 15}; /* W95 only uses 7-9, others may be wrong */ - +static const int wss_dma[4] = { 0, 0, 1, 3 }; +static const int wss_irq[8] = { 5, 7, 9, 10, 11, 12, 14, 15 }; /* W95 only uses 7-9, others may be wrong */ typedef struct wss_t { - uint8_t config; + uint8_t config; - ad1848_t ad1848; - opl_t opl; + ad1848_t ad1848; + opl_t opl; - int opl_enabled; - uint8_t pos_regs[8]; + int opl_enabled; + uint8_t pos_regs[8]; } wss_t; - uint8_t -wss_read(uint16_t addr, void *priv) { +wss_read(uint16_t addr, void *priv) +{ wss_t *wss = (wss_t *) priv; return 4 | (wss->config & 0x40); } - void wss_write(uint16_t addr, uint8_t val, void *priv) { @@ -78,36 +75,34 @@ wss_write(uint16_t addr, uint8_t val, void *priv) ad1848_setirq(&wss->ad1848, wss_irq[(val >> 3) & 7]); } - static void wss_get_buffer(int32_t *buffer, int len, void *priv) { wss_t *wss = (wss_t *) priv; - int c; + int c; opl3_update(&wss->opl); ad1848_update(&wss->ad1848); for (c = 0; c < len * 2; c++) { - buffer[c] += wss->opl.buffer[c]; - buffer[c] += wss->ad1848.buffer[c] / 2; + buffer[c] += wss->opl.buffer[c]; + buffer[c] += wss->ad1848.buffer[c] / 2; } - wss->opl.pos = 0; + wss->opl.pos = 0; wss->ad1848.pos = 0; } - void * wss_init(const device_t *info) { wss_t *wss = malloc(sizeof(wss_t)); memset(wss, 0, sizeof(wss_t)); - uint16_t addr = device_get_config_hex16("base"); + uint16_t addr = device_get_config_hex16("base"); wss->opl_enabled = device_get_config_int("opl"); if (wss->opl_enabled) - opl3_init(&wss->opl); + opl3_init(&wss->opl); ad1848_init(&wss->ad1848, AD1848_TYPE_DEFAULT); @@ -115,17 +110,25 @@ wss_init(const device_t *info) ad1848_setdma(&wss->ad1848, 3); if (wss->opl_enabled) - io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &wss->opl); + io_sethandler(0x0388, 0x0004, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &wss->opl); - io_sethandler(addr, 0x0004, wss_read, NULL, NULL, wss_write, NULL, NULL, wss); - io_sethandler(addr+4, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &wss->ad1848); + io_sethandler(addr, 0x0004, + wss_read, NULL, NULL, + wss_write, NULL, NULL, + wss); + io_sethandler(addr + 4, 0x0004, + ad1848_read, NULL, NULL, + ad1848_write, NULL, NULL, + &wss->ad1848); sound_add_handler(wss_get_buffer, wss); return wss; } - static uint8_t ncr_audio_mca_read(int port, void *priv) { @@ -133,38 +136,54 @@ ncr_audio_mca_read(int port, void *priv) return wss->pos_regs[port & 7]; } - static void ncr_audio_mca_write(int port, uint8_t val, void *priv) { - wss_t *wss = (wss_t *) priv; - uint16_t ports[4] = {0x530, 0xE80, 0xF40, 0x604}; + wss_t *wss = (wss_t *) priv; + uint16_t ports[4] = { 0x530, 0xE80, 0xF40, 0x604 }; uint16_t addr; if (port < 0x102) - return; + return; wss->opl_enabled = (wss->pos_regs[2] & 0x20) ? 1 : 0; - addr = ports[(wss->pos_regs[2] & 0x18) >> 3]; + addr = ports[(wss->pos_regs[2] & 0x18) >> 3]; - io_removehandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &wss->opl); - io_removehandler(addr, 0x0004, wss_read, NULL, NULL, wss_write, NULL, NULL, wss); - io_removehandler(addr+4, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &wss->ad1848); + io_removehandler(0x0388, 0x0004, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &wss->opl); + io_removehandler(addr, 0x0004, + wss_read, NULL, NULL, + wss_write, NULL, NULL, + wss); + io_removehandler(addr + 4, 0x0004, + ad1848_read, NULL, NULL, + ad1848_write, NULL, NULL, + &wss->ad1848); wss->pos_regs[port & 7] = val; if (wss->pos_regs[2] & 1) { - addr = ports[(wss->pos_regs[2] & 0x18) >> 3]; + addr = ports[(wss->pos_regs[2] & 0x18) >> 3]; - if (wss->opl_enabled) - io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &wss->opl); + if (wss->opl_enabled) + io_sethandler(0x0388, 0x0004, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &wss->opl); - io_sethandler(addr, 0x0004, wss_read, NULL, NULL, wss_write, NULL, NULL, wss); - io_sethandler(addr+4, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &wss->ad1848); + io_sethandler(addr, 0x0004, + wss_read, NULL, NULL, + wss_write, NULL, NULL, + wss); + io_sethandler(addr + 4, 0x0004, + ad1848_read, NULL, NULL, + ad1848_write, NULL, NULL, + &wss->ad1848); } } - static uint8_t ncr_audio_mca_feedb(void *priv) { @@ -172,7 +191,6 @@ ncr_audio_mca_feedb(void *priv) return (wss->pos_regs[2] & 1); } - void * ncr_audio_init(const device_t *info) { @@ -194,7 +212,6 @@ ncr_audio_init(const device_t *info) return wss; } - void wss_close(void *priv) { @@ -202,7 +219,6 @@ wss_close(void *priv) free(wss); } - void wss_speed_changed(void *priv) { @@ -210,55 +226,44 @@ wss_speed_changed(void *priv) ad1848_speed_changed(&wss->ad1848); } - static const device_config_t wss_config[] = { - { - "base", "Address", CONFIG_HEX16, "", 0x530, "", { 0 }, - { - { - "0x530", 0x530 - }, - { - "0x604", 0x604 - }, - { - "0xe80", 0xe80 - }, - { - "0xf40", 0xf40 - }, - { - "" - } - } +// clang-format off + { "base", "Address", CONFIG_HEX16, "", 0x530, "", { 0 }, + { + { "0x530", 0x530 }, + { "0x604", 0x604 }, + { "0xe80", 0xe80 }, + { "0xf40", 0xf40 }, + { "" } + } }, - { - "opl", "Enable OPL", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 - } + { "opl", "Enable OPL", CONFIG_BINARY, "", 1 }, + { "", "", -1 } +// clang-format on }; - -const device_t wss_device = -{ +const device_t wss_device = { "Windows Sound System", "wss", - DEVICE_ISA | DEVICE_AT, 0, - wss_init, wss_close, NULL, + DEVICE_ISA | DEVICE_AT, + 0, + wss_init, + wss_close, + NULL, { NULL }, wss_speed_changed, NULL, wss_config }; -const device_t ncr_business_audio_device = -{ +const device_t ncr_business_audio_device = { "NCR Business Audio", "ncraudio", - DEVICE_MCA, 0, - ncr_audio_init, wss_close, NULL, + DEVICE_MCA, + 0, + ncr_audio_init, + wss_close, + NULL, { NULL }, wss_speed_changed, NULL, diff --git a/src/sound/snd_ym7128.c b/src/sound/snd_ym7128.c index 7b89fedff..a6398628a 100644 --- a/src/sound/snd_ym7128.c +++ b/src/sound/snd_ym7128.c @@ -1,138 +1,153 @@ -#include #include +#include #include #include + #include <86box/86box.h> #include <86box/snd_ym7128.h> - static int attenuation[32]; static int tap_position[32]; - -void ym7128_init(ym7128_t *ym7128) +void +ym7128_init(ym7128_t *ym7128) { - int c; - double out = 65536.0; + int c; + double out = 65536.0; - for (c = 0; c < 32; c++) - tap_position[c] = c * (2400 / 31); + for (c = 0; c < 32; c++) + tap_position[c] = c * (2400 / 31); - for (c = 31; c >= 1; c--) - { - attenuation[c] = (int)out; - out /= 1.25963; /*2 dB steps*/ - } - attenuation[0] = 0; + for (c = 31; c >= 1; c--) { + attenuation[c] = (int) out; + out /= 1.25963; /*2 dB steps*/ + } + attenuation[0] = 0; } #define GET_ATTENUATION(val) (val & 0x20) ? -attenuation[val & 0x1f] : attenuation[val & 0x1f] -void ym7128_write(ym7128_t *ym7128, uint8_t val) +void +ym7128_write(ym7128_t *ym7128, uint8_t val) { - int new_dat = val & 1; - int new_sci = val & 2; - int new_a0 = val & 4; - if (!ym7128->sci && new_sci) - ym7128->dat = (ym7128->dat << 1) | new_dat; + int new_dat = val & 1; + int new_sci = val & 2; + int new_a0 = val & 4; + if (!ym7128->sci && new_sci) + ym7128->dat = (ym7128->dat << 1) | new_dat; - if (ym7128->a0 != new_a0) - { - if (!ym7128->a0) - ym7128->reg_sel = ym7128->dat & 0x1f; - else - { - switch (ym7128->reg_sel) - { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x04: case 0x05: case 0x06: case 0x07: - ym7128->gl[ym7128->reg_sel & 7] = GET_ATTENUATION(ym7128->dat); - break; - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0c: case 0x0d: case 0x0e: case 0x0f: - ym7128->gr[ym7128->reg_sel & 7] = GET_ATTENUATION(ym7128->dat); - break; + if (ym7128->a0 != new_a0) { + if (!ym7128->a0) + ym7128->reg_sel = ym7128->dat & 0x1f; + else { + switch (ym7128->reg_sel) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x07: + ym7128->gl[ym7128->reg_sel & 7] = GET_ATTENUATION(ym7128->dat); + break; + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + ym7128->gr[ym7128->reg_sel & 7] = GET_ATTENUATION(ym7128->dat); + break; - case 0x10: - ym7128->vm = GET_ATTENUATION(ym7128->dat); - break; - case 0x11: - ym7128->vc = GET_ATTENUATION(ym7128->dat); - break; - case 0x12: - ym7128->vl = GET_ATTENUATION(ym7128->dat); - break; - case 0x13: - ym7128->vr = GET_ATTENUATION(ym7128->dat); - break; + case 0x10: + ym7128->vm = GET_ATTENUATION(ym7128->dat); + break; + case 0x11: + ym7128->vc = GET_ATTENUATION(ym7128->dat); + break; + case 0x12: + ym7128->vl = GET_ATTENUATION(ym7128->dat); + break; + case 0x13: + ym7128->vr = GET_ATTENUATION(ym7128->dat); + break; - case 0x14: - ym7128->c0 = (ym7128->dat & 0x3f) << 6; - if (ym7128->dat & 0x20) - ym7128->c0 |= 0xfffff000; - break; - case 0x15: - ym7128->c1 = (ym7128->dat & 0x3f) << 6; - if (ym7128->dat & 0x20) - ym7128->c1 |= 0xfffff000; - break; + case 0x14: + ym7128->c0 = (ym7128->dat & 0x3f) << 6; + if (ym7128->dat & 0x20) + ym7128->c0 |= 0xfffff000; + break; + case 0x15: + ym7128->c1 = (ym7128->dat & 0x3f) << 6; + if (ym7128->dat & 0x20) + ym7128->c1 |= 0xfffff000; + break; - case 0x16: case 0x17: case 0x18: case 0x19: - case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: - ym7128->t[ym7128->reg_sel - 0x16] = tap_position[ym7128->dat & 0x1f]; - break; - } - ym7128->regs[ym7128->reg_sel] = ym7128->dat; - } - ym7128->dat = 0; + case 0x16: + case 0x17: + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + case 0x1c: + case 0x1d: + case 0x1e: + ym7128->t[ym7128->reg_sel - 0x16] = tap_position[ym7128->dat & 0x1f]; + break; + } + ym7128->regs[ym7128->reg_sel] = ym7128->dat; } + ym7128->dat = 0; + } - ym7128->sci = new_sci; - ym7128->a0 = new_a0; + ym7128->sci = new_sci; + ym7128->a0 = new_a0; } #define GET_DELAY_SAMPLE(ym7128, offset) (((ym7128->delay_pos - offset) < 0) ? ym7128->delay_buffer[(ym7128->delay_pos - offset) + 2400] : ym7128->delay_buffer[ym7128->delay_pos - offset]) -void ym7128_apply(ym7128_t *ym7128, int16_t *buffer, int len) +void +ym7128_apply(ym7128_t *ym7128, int16_t *buffer, int len) { - int c, d; + int c, d; - for (c = 0; c < len*2; c += 4) - { - /*YM7128 samples a mono stream at ~24 kHz, so downsample*/ - int32_t samp = ((int32_t)buffer[c] + (int32_t)buffer[c+1] + (int32_t)buffer[c+2] + (int32_t)buffer[c+3]) / 4; - int32_t filter_temp, filter_out; - int32_t samp_l = 0, samp_r = 0; + for (c = 0; c < len * 2; c += 4) { + /*YM7128 samples a mono stream at ~24 kHz, so downsample*/ + int32_t samp = ((int32_t) buffer[c] + (int32_t) buffer[c + 1] + (int32_t) buffer[c + 2] + (int32_t) buffer[c + 3]) / 4; + int32_t filter_temp, filter_out; + int32_t samp_l = 0, samp_r = 0; - filter_temp = GET_DELAY_SAMPLE(ym7128, ym7128->t[0]); - filter_out = ((filter_temp * ym7128->c0) >> 11) + ((ym7128->filter_dat * ym7128->c1) >> 11); - filter_out = (filter_out * ym7128->vc) >> 16; + filter_temp = GET_DELAY_SAMPLE(ym7128, ym7128->t[0]); + filter_out = ((filter_temp * ym7128->c0) >> 11) + ((ym7128->filter_dat * ym7128->c1) >> 11); + filter_out = (filter_out * ym7128->vc) >> 16; - samp = (samp * ym7128->vm) >> 16; - samp += filter_out; + samp = (samp * ym7128->vm) >> 16; + samp += filter_out; - ym7128->delay_buffer[ym7128->delay_pos] = samp; + ym7128->delay_buffer[ym7128->delay_pos] = samp; - for (d = 0; d < 8; d++) - { - samp_l += (GET_DELAY_SAMPLE(ym7128, ym7128->t[d+1]) * ym7128->gl[d]) >> 16; - samp_r += (GET_DELAY_SAMPLE(ym7128, ym7128->t[d+1]) * ym7128->gr[d]) >> 16; - } - - samp_l = (samp_l * ym7128->vl*2) >> 16; - samp_r = (samp_r * ym7128->vr*2) >> 16; - - buffer[c] += ((int32_t)samp_l + (int32_t)ym7128->prev_l) / 2; - buffer[c+1] += ((int32_t)samp_r + (int32_t)ym7128->prev_r) / 2; - buffer[c+2] += samp_l; - buffer[c+3] += samp_r; - - ym7128->delay_pos++; - if (ym7128->delay_pos >= 2400) - ym7128->delay_pos = 0; - - ym7128->filter_dat = filter_temp; - ym7128->prev_l = samp_l; - ym7128->prev_r = samp_r; + for (d = 0; d < 8; d++) { + samp_l += (GET_DELAY_SAMPLE(ym7128, ym7128->t[d + 1]) * ym7128->gl[d]) >> 16; + samp_r += (GET_DELAY_SAMPLE(ym7128, ym7128->t[d + 1]) * ym7128->gr[d]) >> 16; } + + samp_l = (samp_l * ym7128->vl * 2) >> 16; + samp_r = (samp_r * ym7128->vr * 2) >> 16; + + buffer[c] += ((int32_t) samp_l + (int32_t) ym7128->prev_l) / 2; + buffer[c + 1] += ((int32_t) samp_r + (int32_t) ym7128->prev_r) / 2; + buffer[c + 2] += samp_l; + buffer[c + 3] += samp_r; + + ym7128->delay_pos++; + if (ym7128->delay_pos >= 2400) + ym7128->delay_pos = 0; + + ym7128->filter_dat = filter_temp; + ym7128->prev_l = samp_l; + ym7128->prev_r = samp_r; + } } diff --git a/src/sound/sound.c b/src/sound/sound.c index 4beab94ba..a1a3353c6 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -1,221 +1,219 @@ /* - * 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. * - * Sound emulation core. + * Sound emulation core. * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Sarah Walker, + * Miran Grca, * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. */ #include #include #include #include -#include #include +#include #include #define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/timer.h> -#include <86box/cdrom.h> -#include <86box/hdc_ide.h> -#include <86box/plat.h> -#include <86box/machine.h> -#include <86box/sound.h> -#include <86box/midi.h> -#include <86box/snd_opl.h> -#include <86box/snd_mpu401.h> -#include <86box/snd_sb_dsp.h> -#include <86box/snd_azt2316a.h> -#include <86box/snd_ac97.h> -#include <86box/filters.h> +#include <86box/86box.h> +#include <86box/cdrom.h> +#include <86box/device.h> +#include <86box/filters.h> +#include <86box/hdc_ide.h> +#include <86box/machine.h> +#include <86box/midi.h> +#include <86box/plat.h> +#include <86box/snd_ac97.h> +#include <86box/snd_azt2316a.h> +#include <86box/timer.h> +#include <86box/snd_mpu401.h> +#include <86box/sound.h> +#include <86box/snd_opl.h> +#include <86box/snd_sb_dsp.h> typedef struct { - const device_t *device; + const device_t *device; } SOUND_CARD; typedef struct { - void (*get_buffer)(int32_t *buffer, int len, void *p); - void *priv; + void (*get_buffer)(int32_t *buffer, int len, void *p); + void *priv; } sound_handler_t; - int sound_card_current = 0; -int sound_pos_global = 0; -int sound_gain = 0; - +int sound_pos_global = 0; +int sound_gain = 0; static sound_handler_t sound_handlers[8]; -static thread_t *sound_cd_thread_h; -static event_t *sound_cd_event; -static event_t *sound_cd_start_event; -static int32_t *outbuffer; -static float *outbuffer_ex; -static int16_t *outbuffer_ex_int16; -static int sound_handlers_num; +static thread_t *sound_cd_thread_h; +static event_t *sound_cd_event; +static event_t *sound_cd_start_event; +static int32_t *outbuffer; +static float *outbuffer_ex; +static int16_t *outbuffer_ex_int16; +static int sound_handlers_num; static pc_timer_t sound_poll_timer; -static uint64_t sound_poll_latch; +static uint64_t sound_poll_latch; -static int16_t cd_buffer[CDROM_NUM][CD_BUFLEN * 2]; -static float cd_out_buffer[CD_BUFLEN * 2]; -static int16_t cd_out_buffer_int16[CD_BUFLEN * 2]; +static int16_t cd_buffer[CDROM_NUM][CD_BUFLEN * 2]; +static float cd_out_buffer[CD_BUFLEN * 2]; +static int16_t cd_out_buffer_int16[CD_BUFLEN * 2]; static unsigned int cd_vol_l, cd_vol_r; -static int cd_buf_update = CD_BUFLEN / SOUNDBUFLEN; -static volatile int cdaudioon = 0; -static int cd_thread_enable = 0; +static int cd_buf_update = CD_BUFLEN / SOUNDBUFLEN; +static volatile int cdaudioon = 0; +static int cd_thread_enable = 0; static void (*filter_cd_audio)(int channel, double *buffer, void *p) = NULL; -static void *filter_cd_audio_p = NULL; - +static void *filter_cd_audio_p = NULL; static const device_t sound_none_device = { - "None", - "none", - 0, 0, - NULL, NULL, NULL, - { NULL }, NULL, NULL, - NULL + "None", + "none", + 0, + 0, + NULL, + NULL, + NULL, + { NULL }, + NULL, + NULL, + NULL }; static const device_t sound_internal_device = { - "Internal", - "internal", - 0, 0, - NULL, NULL, NULL, - { NULL }, NULL, NULL, - NULL + "Internal", + "internal", + 0, + 0, + NULL, + NULL, + NULL, + { NULL }, + NULL, + NULL, + NULL }; - -static const SOUND_CARD sound_cards[] = -{ - { &sound_none_device }, - { &sound_internal_device }, - { &adlib_device }, - { &adgold_device }, - { &azt2316a_device }, - { &azt1605_device }, - { &cs4235_device }, - { &cs4236b_device }, - { &sb_1_device }, - { &sb_15_device }, - { &sb_2_device }, - { &sb_pro_v1_device }, - { &sb_pro_v2_device }, - { &sb_16_device }, - { &sb_16_pnp_device }, - { &sb_32_pnp_device }, - { &sb_awe32_device }, - { &sb_awe32_pnp_device }, - { &sb_awe64_value_device }, - { &sb_awe64_device }, - { &sb_awe64_gold_device }, +static const SOUND_CARD sound_cards[] = { + // clang-format off + { &sound_none_device }, + { &sound_internal_device }, + { &adlib_device }, + { &adgold_device }, + { &azt2316a_device }, + { &azt1605_device }, + { &cs4235_device }, + { &cs4236b_device }, + { &sb_1_device }, + { &sb_15_device }, + { &sb_2_device }, + { &sb_pro_v1_device }, + { &sb_pro_v2_device }, + { &sb_16_device }, + { &sb_16_pnp_device }, + { &sb_32_pnp_device }, + { &sb_awe32_device }, + { &sb_awe32_pnp_device }, + { &sb_awe64_value_device }, + { &sb_awe64_device }, + { &sb_awe64_gold_device }, #if defined(DEV_BRANCH) && defined(USE_PAS16) - { &pas16_device }, + { &pas16_device }, #endif #if defined(DEV_BRANCH) && defined(USE_TANDY_ISA) - { &pssj_isa_device }, - { &tndy_device }, + { &pssj_isa_device }, + { &tndy_device }, #endif - { &wss_device }, - { &adlib_mca_device }, - { &ncr_business_audio_device }, - { &sb_mcv_device }, - { &sb_pro_mcv_device }, - { &es1371_device }, - { &ad1881_device }, - { &cs4297a_device }, - { NULL } + { &wss_device }, + { &adlib_mca_device }, + { &ncr_business_audio_device }, + { &sb_mcv_device }, + { &sb_pro_mcv_device }, + { &es1371_device }, + { &ad1881_device }, + { &cs4297a_device }, + { NULL } + // clang-format on }; - #ifdef ENABLE_SOUND_LOG int sound_do_log = ENABLE_SOUND_LOG; - static void sound_log(const char *fmt, ...) { va_list ap; if (sound_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define sound_log(fmt, ...) +# define sound_log(fmt, ...) #endif - int sound_card_available(int card) { if (sound_cards[card].device) - return device_available(sound_cards[card].device); + return device_available(sound_cards[card].device); return 1; } - const device_t * sound_card_getdevice(int card) { return sound_cards[card].device; } - int sound_card_has_config(int card) { if (!sound_cards[card].device) - return 0; + return 0; return sound_cards[card].device->config ? 1 : 0; } - char * sound_card_get_internal_name(int card) { return device_get_internal_name(sound_cards[card].device); } - int sound_card_get_from_internal_name(char *s) { int c = 0; while (sound_cards[c].device != NULL) { - if (!strcmp((char *) sound_cards[c].device->internal_name, s)) - return c; - c++; + if (!strcmp((char *) sound_cards[c].device->internal_name, s)) + return c; + c++; } return 0; } - void sound_card_init(void) { if (sound_cards[sound_card_current].device) - device_add(sound_cards[sound_card_current].device); + device_add(sound_cards[sound_card_current].device); } - void sound_set_cd_volume(unsigned int vol_l, unsigned int vol_r) { @@ -223,168 +221,163 @@ sound_set_cd_volume(unsigned int vol_l, unsigned int vol_r) cd_vol_r = vol_r; } - static void sound_cd_clean_buffers(void) { if (sound_is_float) - memset(cd_out_buffer, 0, (CD_BUFLEN * 2) * sizeof(float)); + memset(cd_out_buffer, 0, (CD_BUFLEN * 2) * sizeof(float)); else - memset(cd_out_buffer_int16, 0, (CD_BUFLEN * 2) * sizeof(int16_t)); + memset(cd_out_buffer_int16, 0, (CD_BUFLEN * 2) * sizeof(int16_t)); } - static void sound_cd_thread(void *param) { uint32_t lba; - int c, r, i, pre, channel_select[2]; - double audio_vol_l, audio_vol_r; - double cd_buffer_temp[2] = {0.0, 0.0}; + int c, r, i, pre, channel_select[2]; + double audio_vol_l, audio_vol_r; + double cd_buffer_temp[2] = { 0.0, 0.0 }; thread_set_event(sound_cd_start_event); while (cdaudioon) { - thread_wait_event(sound_cd_event, -1); - thread_reset_event(sound_cd_event); + thread_wait_event(sound_cd_event, -1); + thread_reset_event(sound_cd_event); - if (!cdaudioon) - return; + if (!cdaudioon) + return; - sound_cd_clean_buffers(); + sound_cd_clean_buffers(); - for (i = 0; i < CDROM_NUM; i++) { - if ((cdrom[i].bus_type == CDROM_BUS_DISABLED) || - (cdrom[i].cd_status == CD_STATUS_EMPTY)) - continue; - lba = cdrom[i].seek_pos; - r = cdrom_audio_callback(&(cdrom[i]), cd_buffer[i], CD_BUFLEN * 2); - if (!cdrom[i].bus_type || !cdrom[i].sound_on || !r) - continue; - pre = cdrom_is_pre(&(cdrom[i]), lba); + for (i = 0; i < CDROM_NUM; i++) { + if ((cdrom[i].bus_type == CDROM_BUS_DISABLED) || (cdrom[i].cd_status == CD_STATUS_EMPTY)) + continue; + lba = cdrom[i].seek_pos; + r = cdrom_audio_callback(&(cdrom[i]), cd_buffer[i], CD_BUFLEN * 2); + if (!cdrom[i].bus_type || !cdrom[i].sound_on || !r) + continue; + pre = cdrom_is_pre(&(cdrom[i]), lba); - if (cdrom[i].get_volume) { - audio_vol_l = (float) (cdrom[i].get_volume(cdrom[i].priv, 0)); - audio_vol_r = (float) (cdrom[i].get_volume(cdrom[i].priv, 1)); - } else { - audio_vol_l = 255.0; - audio_vol_r = 255.0; - } + if (cdrom[i].get_volume) { + audio_vol_l = (float) (cdrom[i].get_volume(cdrom[i].priv, 0)); + audio_vol_r = (float) (cdrom[i].get_volume(cdrom[i].priv, 1)); + } else { + audio_vol_l = 255.0; + audio_vol_r = 255.0; + } - /* Calculate attenuation per the specification. */ - if (audio_vol_l >= 255.0) - audio_vol_l = 1.0; - else if (audio_vol_l > 0.0) - audio_vol_l = (48.0 + (20.0 * log(audio_vol_l / 256.0))) / 48.0; - else - audio_vol_l = 0.0; + /* Calculate attenuation per the specification. */ + if (audio_vol_l >= 255.0) + audio_vol_l = 1.0; + else if (audio_vol_l > 0.0) + audio_vol_l = (48.0 + (20.0 * log(audio_vol_l / 256.0))) / 48.0; + else + audio_vol_l = 0.0; - if (audio_vol_r >= 255.0) - audio_vol_r = 1.0; - else if (audio_vol_r > 0.0) - audio_vol_r = (48.0 + (20.0 * log(audio_vol_r / 256.0))) / 48.0; - else - audio_vol_r = 0.0; + if (audio_vol_r >= 255.0) + audio_vol_r = 1.0; + else if (audio_vol_r > 0.0) + audio_vol_r = (48.0 + (20.0 * log(audio_vol_r / 256.0))) / 48.0; + else + audio_vol_r = 0.0; - if (cdrom[i].get_channel) { - channel_select[0] = cdrom[i].get_channel(cdrom[i].priv, 0); - channel_select[1] = cdrom[i].get_channel(cdrom[i].priv, 1); - } else { - channel_select[0] = 1; - channel_select[1] = 2; - } + if (cdrom[i].get_channel) { + channel_select[0] = cdrom[i].get_channel(cdrom[i].priv, 0); + channel_select[1] = cdrom[i].get_channel(cdrom[i].priv, 1); + } else { + channel_select[0] = 1; + channel_select[1] = 2; + } - for (c = 0; c < CD_BUFLEN*2; c += 2) { - /*Apply ATAPI channel select*/ - cd_buffer_temp[0] = cd_buffer_temp[1] = 0.0; + for (c = 0; c < CD_BUFLEN * 2; c += 2) { + /*Apply ATAPI channel select*/ + cd_buffer_temp[0] = cd_buffer_temp[1] = 0.0; - if ((audio_vol_l != 0.0) && (channel_select[0] != 0)) { - if (channel_select[0] & 1) - cd_buffer_temp[0] += ((double) cd_buffer[i][c]); /* Channel 0 => Port 0 */ - if (channel_select[0] & 2) - cd_buffer_temp[0] += ((double) cd_buffer[i][c + 1]); /* Channel 1 => Port 0 */ + if ((audio_vol_l != 0.0) && (channel_select[0] != 0)) { + if (channel_select[0] & 1) + cd_buffer_temp[0] += ((double) cd_buffer[i][c]); /* Channel 0 => Port 0 */ + if (channel_select[0] & 2) + cd_buffer_temp[0] += ((double) cd_buffer[i][c + 1]); /* Channel 1 => Port 0 */ - cd_buffer_temp[0] *= audio_vol_l; /* Multiply Port 0 by Port 0 volume */ + cd_buffer_temp[0] *= audio_vol_l; /* Multiply Port 0 by Port 0 volume */ - if (pre) - cd_buffer_temp[0] = deemph_iir(0, cd_buffer_temp[0]); /* De-emphasize if necessary */ - } + if (pre) + cd_buffer_temp[0] = deemph_iir(0, cd_buffer_temp[0]); /* De-emphasize if necessary */ + } - if ((audio_vol_r != 0.0) && (channel_select[1] != 0)) { - if (channel_select[1] & 1) - cd_buffer_temp[1] += ((double) cd_buffer[i][c]); /* Channel 0 => Port 1 */ - if (channel_select[1] & 2) - cd_buffer_temp[1] += ((double) cd_buffer[i][c + 1]); /* Channel 1 => Port 1 */ + if ((audio_vol_r != 0.0) && (channel_select[1] != 0)) { + if (channel_select[1] & 1) + cd_buffer_temp[1] += ((double) cd_buffer[i][c]); /* Channel 0 => Port 1 */ + if (channel_select[1] & 2) + cd_buffer_temp[1] += ((double) cd_buffer[i][c + 1]); /* Channel 1 => Port 1 */ - cd_buffer_temp[1] *= audio_vol_r; /* Multiply Port 1 by Port 1 volume */ + cd_buffer_temp[1] *= audio_vol_r; /* Multiply Port 1 by Port 1 volume */ - if (pre) - cd_buffer_temp[1] = deemph_iir(1, cd_buffer_temp[1]); /* De-emphasize if necessary */ - } + if (pre) + cd_buffer_temp[1] = deemph_iir(1, cd_buffer_temp[1]); /* De-emphasize if necessary */ + } - /* Apply sound card CD volume and filters */ - if (filter_cd_audio != NULL) { - filter_cd_audio(0, &(cd_buffer_temp[0]), filter_cd_audio_p); - filter_cd_audio(1, &(cd_buffer_temp[1]), filter_cd_audio_p); - } + /* Apply sound card CD volume and filters */ + if (filter_cd_audio != NULL) { + filter_cd_audio(0, &(cd_buffer_temp[0]), filter_cd_audio_p); + filter_cd_audio(1, &(cd_buffer_temp[1]), filter_cd_audio_p); + } - if (sound_is_float) { - cd_out_buffer[c] += (float) (cd_buffer_temp[0] / 32768.0); - cd_out_buffer[c+1] += (float) (cd_buffer_temp[1] / 32768.0); - } else { - if (cd_buffer_temp[0] > 32767) - cd_buffer_temp[0] = 32767; - if (cd_buffer_temp[0] < -32768) - cd_buffer_temp[0] = -32768; - if (cd_buffer_temp[1] > 32767) - cd_buffer_temp[1] = 32767; - if (cd_buffer_temp[1] < -32768) - cd_buffer_temp[1] = -32768; + if (sound_is_float) { + cd_out_buffer[c] += (float) (cd_buffer_temp[0] / 32768.0); + cd_out_buffer[c + 1] += (float) (cd_buffer_temp[1] / 32768.0); + } else { + if (cd_buffer_temp[0] > 32767) + cd_buffer_temp[0] = 32767; + if (cd_buffer_temp[0] < -32768) + cd_buffer_temp[0] = -32768; + if (cd_buffer_temp[1] > 32767) + cd_buffer_temp[1] = 32767; + if (cd_buffer_temp[1] < -32768) + cd_buffer_temp[1] = -32768; - cd_out_buffer_int16[c] += (int16_t) cd_buffer_temp[0]; - cd_out_buffer_int16[c+1] += (int16_t) cd_buffer_temp[1]; - } - } - } + cd_out_buffer_int16[c] += (int16_t) cd_buffer_temp[0]; + cd_out_buffer_int16[c + 1] += (int16_t) cd_buffer_temp[1]; + } + } + } - if (sound_is_float) - givealbuffer_cd(cd_out_buffer); - else - givealbuffer_cd(cd_out_buffer_int16); + if (sound_is_float) + givealbuffer_cd(cd_out_buffer); + else + givealbuffer_cd(cd_out_buffer_int16); } } - static void sound_realloc_buffers(void) { if (outbuffer_ex != NULL) { - free(outbuffer_ex); - outbuffer_ex = NULL; + free(outbuffer_ex); + outbuffer_ex = NULL; } if (outbuffer_ex_int16 != NULL) { - free(outbuffer_ex_int16); - outbuffer_ex_int16 = NULL; + free(outbuffer_ex_int16); + outbuffer_ex_int16 = NULL; } if (sound_is_float) { outbuffer_ex = calloc(SOUNDBUFLEN * 2, sizeof(float)); - memset(outbuffer_ex, 0x00, SOUNDBUFLEN * 2 * sizeof(float)); + memset(outbuffer_ex, 0x00, SOUNDBUFLEN * 2 * sizeof(float)); } else { outbuffer_ex_int16 = calloc(SOUNDBUFLEN * 2, sizeof(int16_t)); - memset(outbuffer_ex_int16, 0x00, SOUNDBUFLEN * 2 * sizeof(int16_t)); + memset(outbuffer_ex_int16, 0x00, SOUNDBUFLEN * 2 * sizeof(int16_t)); } } - void sound_init(void) { - int i = 0; + int i = 0; int available_cdrom_drives = 0; - outbuffer_ex = NULL; + outbuffer_ex = NULL; outbuffer_ex_int16 = NULL; outbuffer = NULL; @@ -392,48 +385,45 @@ sound_init(void) memset(outbuffer, 0x00, SOUNDBUFLEN * 2 * sizeof(int32_t)); for (i = 0; i < CDROM_NUM; i++) { - if (cdrom[i].bus_type != CDROM_BUS_DISABLED) - available_cdrom_drives++; + if (cdrom[i].bus_type != CDROM_BUS_DISABLED) + available_cdrom_drives++; } if (available_cdrom_drives) { - cdaudioon = 1; + cdaudioon = 1; - sound_cd_start_event = thread_create_event(); + sound_cd_start_event = thread_create_event(); - sound_cd_event = thread_create_event(); - sound_cd_thread_h = thread_create(sound_cd_thread, NULL); + sound_cd_event = thread_create_event(); + sound_cd_thread_h = thread_create(sound_cd_thread, NULL); - sound_log("Waiting for CD start event...\n"); - thread_wait_event(sound_cd_start_event, -1); - thread_reset_event(sound_cd_start_event); - sound_log("Done!\n"); + sound_log("Waiting for CD start event...\n"); + thread_wait_event(sound_cd_start_event, -1); + thread_reset_event(sound_cd_start_event); + sound_log("Done!\n"); } else - cdaudioon = 0; + cdaudioon = 0; cd_thread_enable = available_cdrom_drives ? 1 : 0; } - void sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *p), void *p) { sound_handlers[sound_handlers_num].get_buffer = get_buffer; - sound_handlers[sound_handlers_num].priv = p; + sound_handlers[sound_handlers_num].priv = p; sound_handlers_num++; } - void sound_set_cd_audio_filter(void (*filter)(int channel, double *buffer, void *p), void *p) { if ((filter_cd_audio == NULL) || (filter == NULL)) { - filter_cd_audio = filter; - filter_cd_audio_p = p; + filter_cd_audio = filter; + filter_cd_audio_p = p; } } - void sound_poll(void *priv) { @@ -443,51 +433,49 @@ sound_poll(void *priv) sound_pos_global++; if (sound_pos_global == SOUNDBUFLEN) { - int c; + int c; - memset(outbuffer, 0x00, SOUNDBUFLEN * 2 * sizeof(int32_t)); + memset(outbuffer, 0x00, SOUNDBUFLEN * 2 * sizeof(int32_t)); - for (c = 0; c < sound_handlers_num; c++) - sound_handlers[c].get_buffer(outbuffer, SOUNDBUFLEN, sound_handlers[c].priv); + for (c = 0; c < sound_handlers_num; c++) + sound_handlers[c].get_buffer(outbuffer, SOUNDBUFLEN, sound_handlers[c].priv); - for (c = 0; c < SOUNDBUFLEN * 2; c++) { - if (sound_is_float) - outbuffer_ex[c] = ((float) outbuffer[c]) / 32768.0; - else { - if (outbuffer[c] > 32767) - outbuffer[c] = 32767; - if (outbuffer[c] < -32768) - outbuffer[c] = -32768; + for (c = 0; c < SOUNDBUFLEN * 2; c++) { + if (sound_is_float) + outbuffer_ex[c] = ((float) outbuffer[c]) / 32768.0; + else { + if (outbuffer[c] > 32767) + outbuffer[c] = 32767; + if (outbuffer[c] < -32768) + outbuffer[c] = -32768; - outbuffer_ex_int16[c] = outbuffer[c]; - } - } + outbuffer_ex_int16[c] = outbuffer[c]; + } + } - if (sound_is_float) - givealbuffer(outbuffer_ex); - else - givealbuffer(outbuffer_ex_int16); + if (sound_is_float) + givealbuffer(outbuffer_ex); + else + givealbuffer(outbuffer_ex_int16); - if (cd_thread_enable) { - cd_buf_update--; - if (!cd_buf_update) { - cd_buf_update = (48000 / SOUNDBUFLEN) / (CD_FREQ / CD_BUFLEN); - thread_set_event(sound_cd_event); - } - } + if (cd_thread_enable) { + cd_buf_update--; + if (!cd_buf_update) { + cd_buf_update = (48000 / SOUNDBUFLEN) / (CD_FREQ / CD_BUFLEN); + thread_set_event(sound_cd_event); + } + } - sound_pos_global = 0; + sound_pos_global = 0; } } - void sound_speed_changed(void) { - sound_poll_latch = (uint64_t)((double)TIMER_USEC * (1000000.0 / 48000.0)); + sound_poll_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / 48000.0)); } - void sound_reset(void) { @@ -503,13 +491,12 @@ sound_reset(void) sound_handlers_num = 0; memset(sound_handlers, 0x00, 8 * sizeof(sound_handler_t)); - filter_cd_audio = NULL; + filter_cd_audio = NULL; filter_cd_audio_p = NULL; sound_set_cd_volume(65535, 65535); } - void sound_card_reset(void) { @@ -519,70 +506,68 @@ sound_card_reset(void) sound_card_init(); if (mpu401_standalone_enable) - mpu401_device_add(); + mpu401_device_add(); if (GUS) - device_add(&gus_device); + device_add(&gus_device); if (GAMEBLASTER) - device_add(&cms_device); + device_add(&cms_device); if (SSI2001) - device_add(&ssi2001_device); + device_add(&ssi2001_device); } - void sound_cd_thread_end(void) { if (cdaudioon) { - cdaudioon = 0; + cdaudioon = 0; - sound_log("Waiting for CD Audio thread to terminate...\n"); - thread_set_event(sound_cd_event); - thread_wait(sound_cd_thread_h); - sound_log("CD Audio thread terminated...\n"); + sound_log("Waiting for CD Audio thread to terminate...\n"); + thread_set_event(sound_cd_event); + thread_wait(sound_cd_thread_h); + sound_log("CD Audio thread terminated...\n"); - if (sound_cd_event) { - thread_destroy_event(sound_cd_event); - sound_cd_event = NULL; - } + if (sound_cd_event) { + thread_destroy_event(sound_cd_event); + sound_cd_event = NULL; + } - sound_cd_thread_h = NULL; + sound_cd_thread_h = NULL; - if (sound_cd_start_event) { - thread_destroy_event(sound_cd_start_event); - sound_cd_event = NULL; - } + if (sound_cd_start_event) { + thread_destroy_event(sound_cd_start_event); + sound_cd_event = NULL; + } } } - void sound_cd_thread_reset(void) { - int i = 0; + int i = 0; int available_cdrom_drives = 0; for (i = 0; i < CDROM_NUM; i++) { - cdrom_stop(&(cdrom[i])); + cdrom_stop(&(cdrom[i])); - if (cdrom[i].bus_type != CDROM_BUS_DISABLED) - available_cdrom_drives++; + if (cdrom[i].bus_type != CDROM_BUS_DISABLED) + available_cdrom_drives++; } if (available_cdrom_drives && !cd_thread_enable) { - cdaudioon = 1; + cdaudioon = 1; - sound_cd_start_event = thread_create_event(); + sound_cd_start_event = thread_create_event(); - sound_cd_event = thread_create_event(); - sound_cd_thread_h = thread_create(sound_cd_thread, NULL); + sound_cd_event = thread_create_event(); + sound_cd_thread_h = thread_create(sound_cd_thread, NULL); - thread_wait_event(sound_cd_start_event, -1); - thread_reset_event(sound_cd_start_event); + thread_wait_event(sound_cd_start_event, -1); + thread_reset_event(sound_cd_start_event); } else if (!available_cdrom_drives && cd_thread_enable) - sound_cd_thread_end(); + sound_cd_thread_end(); cd_thread_enable = available_cdrom_drives ? 1 : 0; } diff --git a/src/sound/xaudio2.c b/src/sound/xaudio2.c index c82c45403..114aa16da 100644 --- a/src/sound/xaudio2.c +++ b/src/sound/xaudio2.c @@ -1,67 +1,85 @@ /* - * 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. * - * Interface to the XAudio2 audio processing library. + * Interface to the XAudio2 audio processing library. * * * - * Authors: Cacodemon345 + * Authors: Cacodemon345 * - * Copyright 2022 Cacodemon345. + * Copyright 2022 Cacodemon345. */ #include -#include #include -#include +#include #include +#include #include #if defined(_WIN32) && !defined(USE_FAUDIO) -#define COBJMACROS -#include +# define COBJMACROS +# include #else -#include -#include +# include +# include #endif #include <86box/86box.h> -#include <86box/sound.h> #include <86box/midi.h> #include <86box/plat_dynld.h> +#include <86box/sound.h> #if defined(_WIN32) && !defined(USE_FAUDIO) static void *xaudio2_handle = NULL; -static HRESULT (WINAPI *pXAudio2Create)(IXAudio2** ppXAudio2, uint32_t Flags, XAUDIO2_PROCESSOR XAudio2Processor); +static HRESULT(WINAPI *pXAudio2Create)(IXAudio2 **ppXAudio2, uint32_t Flags, XAUDIO2_PROCESSOR XAudio2Processor); static dllimp_t xaudio2_imports[] = { - { "XAudio2Create", &pXAudio2Create }, - { NULL, NULL }, + {"XAudio2Create", &pXAudio2Create}, + { NULL, NULL }, }; -#define XAudio2Create pXAudio2Create +# define XAudio2Create pXAudio2Create #endif -static int midi_freq = 44100; -static int midi_buf_size = 4410; -static int initialized = 0; -static IXAudio2 *xaudio2 = NULL; -static IXAudio2MasteringVoice *mastervoice = NULL; -static IXAudio2SourceVoice *srcvoice = NULL; -static IXAudio2SourceVoice *srcvoicemidi = NULL; -static IXAudio2SourceVoice *srcvoicecd = NULL; +static int midi_freq = 44100; +static int midi_buf_size = 4410; +static int initialized = 0; +static IXAudio2 *xaudio2 = NULL; +static IXAudio2MasteringVoice *mastervoice = NULL; +static IXAudio2SourceVoice *srcvoice = NULL; +static IXAudio2SourceVoice *srcvoicemidi = NULL; +static IXAudio2SourceVoice *srcvoicecd = NULL; -#define FREQ 48000 -#define BUFLEN SOUNDBUFLEN +#define FREQ 48000 +#define BUFLEN SOUNDBUFLEN -static void WINAPI OnVoiceProcessingPassStart(IXAudio2VoiceCallback *callback, uint32_t bytesRequired) {} -static void WINAPI OnVoiceProcessingPassEnd(IXAudio2VoiceCallback *callback) {} -static void WINAPI OnStreamEnd(IXAudio2VoiceCallback *callback) {} -static void WINAPI OnBufferStart(IXAudio2VoiceCallback *callback, void *pBufferContext) {} -static void WINAPI OnLoopEnd(IXAudio2VoiceCallback *callback, void *pBufferContext) {} -static void WINAPI OnVoiceError(IXAudio2VoiceCallback *callback, void *pBufferContext, HRESULT error) {} +static void WINAPI +OnVoiceProcessingPassStart(IXAudio2VoiceCallback *callback, uint32_t bytesRequired) +{ +} +static void WINAPI +OnVoiceProcessingPassEnd(IXAudio2VoiceCallback *callback) +{ +} +static void WINAPI +OnStreamEnd(IXAudio2VoiceCallback *callback) +{ +} +static void WINAPI +OnBufferStart(IXAudio2VoiceCallback *callback, void *pBufferContext) +{ +} +static void WINAPI +OnLoopEnd(IXAudio2VoiceCallback *callback, void *pBufferContext) +{ +} +static void WINAPI +OnVoiceError(IXAudio2VoiceCallback *callback, void *pBufferContext, HRESULT error) +{ +} static void WINAPI OnBufferEnd(IXAudio2VoiceCallback *callback, void *pBufferContext) @@ -74,15 +92,15 @@ static IXAudio2VoiceCallbackVtbl callbacksVtbl = #else static FAudioVoiceCallback callbacks = #endif -{ - .OnVoiceProcessingPassStart = OnVoiceProcessingPassStart, - .OnVoiceProcessingPassEnd = OnVoiceProcessingPassEnd, - .OnStreamEnd = OnStreamEnd, - .OnBufferStart = OnBufferStart, - .OnBufferEnd = OnBufferEnd, - .OnLoopEnd = OnLoopEnd, - .OnVoiceError = OnVoiceError -}; + { + .OnVoiceProcessingPassStart = OnVoiceProcessingPassStart, + .OnVoiceProcessingPassEnd = OnVoiceProcessingPassEnd, + .OnStreamEnd = OnStreamEnd, + .OnBufferStart = OnBufferStart, + .OnBufferEnd = OnBufferEnd, + .OnLoopEnd = OnLoopEnd, + .OnVoiceError = OnVoiceError + }; #if defined(_WIN32) && !defined(USE_FAUDIO) static IXAudio2VoiceCallback callbacks = { &callbacksVtbl }; @@ -93,25 +111,23 @@ inital() { #if defined(_WIN32) && !defined(USE_FAUDIO) if (xaudio2_handle == NULL) { - xaudio2_handle = dynld_module("xaudio2_9.dll", xaudio2_imports); + xaudio2_handle = dynld_module("xaudio2_9.dll", xaudio2_imports); } if (xaudio2_handle == NULL) { - xaudio2_handle = dynld_module("xaudio2_9redist.dll", xaudio2_imports); + xaudio2_handle = dynld_module("xaudio2_9redist.dll", xaudio2_imports); } if (xaudio2_handle == NULL) { - return; + return; } #endif - if (XAudio2Create(&xaudio2, 0, XAUDIO2_DEFAULT_PROCESSOR)) - { + if (XAudio2Create(&xaudio2, 0, XAUDIO2_DEFAULT_PROCESSOR)) { return; } - if (IXAudio2_CreateMasteringVoice(xaudio2, &mastervoice, 2, FREQ, 0, 0, NULL, 0)) - { + if (IXAudio2_CreateMasteringVoice(xaudio2, &mastervoice, 2, FREQ, 0, 0, NULL, 0)) { IXAudio2_Release(xaudio2); xaudio2 = NULL; return; @@ -120,33 +136,29 @@ inital() WAVEFORMATEX fmt; fmt.nChannels = 2; - if (sound_is_float) - { - fmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; + if (sound_is_float) { + fmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; fmt.wBitsPerSample = 32; - } - else - { - fmt.wFormatTag = WAVE_FORMAT_PCM; + } else { + fmt.wFormatTag = WAVE_FORMAT_PCM; fmt.wBitsPerSample = 16; } - fmt.nSamplesPerSec = FREQ; - fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; + fmt.nSamplesPerSec = FREQ; + fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; - fmt.cbSize = 0; + fmt.cbSize = 0; - if (IXAudio2_CreateSourceVoice(xaudio2, &srcvoice, &fmt, 0, 2.0f, &callbacks, NULL, NULL)) - { + if (IXAudio2_CreateSourceVoice(xaudio2, &srcvoice, &fmt, 0, 2.0f, &callbacks, NULL, NULL)) { IXAudio2MasteringVoice_DestroyVoice(mastervoice); IXAudio2_Release(xaudio2); - xaudio2 = NULL; + xaudio2 = NULL; mastervoice = NULL; return; } - fmt.nSamplesPerSec = CD_FREQ; - fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; + fmt.nSamplesPerSec = CD_FREQ; + fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; IXAudio2_CreateSourceVoice(xaudio2, &srcvoicecd, &fmt, 0, 2.0f, &callbacks, NULL, NULL); @@ -157,10 +169,9 @@ inital() char *mdn = midi_device_get_internal_name(midi_device_current); - if (strcmp(mdn, "none") && strcmp(mdn, SYSTEM_MIDI_INTERNAL_NAME)) - { - fmt.nSamplesPerSec = midi_freq; - fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; + if (strcmp(mdn, "none") && strcmp(mdn, SYSTEM_MIDI_INTERNAL_NAME)) { + fmt.nSamplesPerSec = midi_freq; + fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; IXAudio2_CreateSourceVoice(xaudio2, &srcvoicemidi, &fmt, 0, 2.0f, &callbacks, NULL, NULL); IXAudio2SourceVoice_Start(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW); @@ -172,14 +183,14 @@ inital() void closeal() { - if (!initialized) return; + if (!initialized) + return; initialized = 0; IXAudio2SourceVoice_Stop(srcvoice, 0, XAUDIO2_COMMIT_NOW); IXAudio2SourceVoice_FlushSourceBuffers(srcvoice); IXAudio2SourceVoice_Stop(srcvoicecd, 0, XAUDIO2_COMMIT_NOW); IXAudio2SourceVoice_FlushSourceBuffers(srcvoicecd); - if (srcvoicemidi) - { + if (srcvoicemidi) { IXAudio2SourceVoice_Stop(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW); IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemidi); IXAudio2SourceVoice_DestroyVoice(srcvoicemidi); @@ -189,8 +200,8 @@ closeal() IXAudio2MasteringVoice_DestroyVoice(mastervoice); IXAudio2_Release(xaudio2); srcvoice = srcvoicecd = srcvoicemidi = NULL; - mastervoice = NULL; - xaudio2 = NULL; + mastervoice = NULL; + xaudio2 = NULL; #if defined(_WIN32) && !defined(USE_FAUDIO) dynld_close(xaudio2_handle); @@ -199,31 +210,28 @@ closeal() } void -givealbuffer_common(void *buf, IXAudio2SourceVoice* sourcevoice, size_t buflen) +givealbuffer_common(void *buf, IXAudio2SourceVoice *sourcevoice, size_t buflen) { - if (!initialized) return; + if (!initialized) + return; - IXAudio2MasteringVoice_SetVolume(mastervoice, pow(10.0, (double)sound_gain / 20.0), XAUDIO2_COMMIT_NOW); - XAUDIO2_BUFFER buffer = {0}; - buffer.Flags = 0; - if (sound_is_float) - { + IXAudio2MasteringVoice_SetVolume(mastervoice, pow(10.0, (double) sound_gain / 20.0), XAUDIO2_COMMIT_NOW); + XAUDIO2_BUFFER buffer = { 0 }; + buffer.Flags = 0; + if (sound_is_float) { buffer.pAudioData = calloc(buflen, sizeof(float)); buffer.AudioBytes = (buflen) * sizeof(float); - } - else - { + } else { buffer.pAudioData = calloc(buflen, sizeof(int16_t)); buffer.AudioBytes = (buflen) * sizeof(int16_t); } - if (buffer.pAudioData == NULL) - { + if (buffer.pAudioData == NULL) { fatal("xaudio2: Out Of Memory!"); } - memcpy((void*)buffer.pAudioData, buf, buffer.AudioBytes); + memcpy((void *) buffer.pAudioData, buf, buffer.AudioBytes); buffer.PlayBegin = buffer.PlayLength = 0; - buffer.PlayLength = buflen >> 1; - buffer.pContext = (void*)buffer.pAudioData; + buffer.PlayLength = buflen >> 1; + buffer.pContext = (void *) buffer.pAudioData; IXAudio2SourceVoice_SubmitSourceBuffer(sourcevoice, &buffer, NULL); } @@ -236,37 +244,34 @@ givealbuffer(void *buf) void givealbuffer_cd(void *buf) { - if (srcvoicecd) givealbuffer_common(buf, srcvoicecd, CD_BUFLEN << 1); + if (srcvoicecd) + givealbuffer_common(buf, srcvoicecd, CD_BUFLEN << 1); } void al_set_midi(int freq, int buf_size) { - midi_freq = freq; + midi_freq = freq; midi_buf_size = buf_size; - if (initialized && srcvoicemidi) - { + if (initialized && srcvoicemidi) { IXAudio2SourceVoice_Stop(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW); IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemidi); IXAudio2SourceVoice_DestroyVoice(srcvoicemidi); srcvoicemidi = NULL; WAVEFORMATEX fmt; fmt.nChannels = 2; - if (sound_is_float) - { - fmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; + if (sound_is_float) { + fmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; fmt.wBitsPerSample = 32; - } - else - { - fmt.wFormatTag = WAVE_FORMAT_PCM; + } else { + fmt.wFormatTag = WAVE_FORMAT_PCM; fmt.wBitsPerSample = 16; } - fmt.nSamplesPerSec = midi_freq; - fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; + fmt.nSamplesPerSec = midi_freq; + fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; - fmt.cbSize = 0; + fmt.cbSize = 0; IXAudio2_CreateSourceVoice(xaudio2, &srcvoicemidi, &fmt, 0, 2.0f, &callbacks, NULL, NULL); IXAudio2SourceVoice_Start(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW); } From b061f42101be882252aed58a374485cddca3c6d2 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 25 Feb 2022 22:14:24 -0500 Subject: [PATCH 03/37] Update snd_pas16.c --- src/sound/snd_pas16.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index df983d4ad..12afc3740 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -399,11 +399,13 @@ pas16_out(uint16_t port, uint8_t val, void *p) default: pas16_log("pas16_out : unknown %04X\n", port); } +#if 0 if (cpu_state.pc == 0x80048CF3) { if (output) fatal("here\n"); output = 3; } +#endif } static void @@ -705,7 +707,7 @@ pas16_get_buffer(int32_t *buffer, int len, void *p) pas16_update(pas16); for (c = 0; c < len * 2; c++) { buffer[c] += pas16->opl.buffer[c]; - buffer[c] += (int16_t) (sb_iir(c & 1, (float) pas16->dsp.buffer[c]) / 1.3) / 2; + buffer[c] += (int16_t) (sb_iir(0, c & 1, (double) pas16->dsp.buffer[c]) / 1.3) / 2; buffer[c] += (pas16->pcm_buffer[c & 1][c >> 1] / 2); } From 81819727ad5b14b09596672b2c3a0a2b68fefb1f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 26 Feb 2022 13:56:50 +0600 Subject: [PATCH 04/37] qt: Port Win32 86F creation code to Qt --- src/qt/qt_newfloppydialog.cpp | 109 ++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 52 deletions(-) diff --git a/src/qt/qt_newfloppydialog.cpp b/src/qt/qt_newfloppydialog.cpp index 6c33c6003..a5ec8d695 100644 --- a/src/qt/qt_newfloppydialog.cpp +++ b/src/qt/qt_newfloppydialog.cpp @@ -236,6 +236,8 @@ void NewFloppyDialog::onCreate() { bool NewFloppyDialog::create86f(const QString& filename, const disk_size_t& disk_size, uint8_t rpm_mode) { + FILE *f; + uint32_t magic = 0x46423638; uint16_t version = 0x020C; uint16_t dflags = 0; @@ -259,74 +261,77 @@ bool NewFloppyDialog::create86f(const QString& filename, const disk_size_t& disk tflags |= (disk_size.rpm << 5); /* RPM. */ switch (disk_size.hole) { - case 0: - case 1: - default: - switch(rpm_mode) { - case 1: - array_size = 25250; - break; - case 2: - array_size = 25374; - break; - case 3: - array_size = 25750; - break; - default: - array_size = 25000; - break; - } - break; - case 2: - switch(rpm_mode) { - case 1: - array_size = 50500; - break; - case 2: - array_size = 50750; - break; - case 3: - array_size = 51000; - break; - default: - array_size = 50000; - break; - } - break; + case 0: + case 1: + default: + switch(rpm_mode) { + case 1: + array_size = 25250; + break; + case 2: + array_size = 25374; + break; + case 3: + array_size = 25750; + break; + default: + array_size = 25000; + break; + } + break; + case 2: + switch(rpm_mode) { + case 1: + array_size = 50500; + break; + case 2: + array_size = 50750; + break; + case 3: + array_size = 51000; + break; + default: + array_size = 50000; + break; + } + break; } - QByteArray bytes(array_size, 0); + empty = (unsigned char *) malloc(array_size); + memset(tarray, 0, 2048); + memset(empty, 0, array_size); - QFile file(filename); - if (! file.open(QIODevice::WriteOnly)) { - return false; - } - QDataStream stream(&file); - stream.setByteOrder(QDataStream::LittleEndian); + f = plat_fopen(filename.toUtf8().data(), "wb"); + if (!f) + return false; - stream << magic; - stream << version; - stream << dflags; + fwrite(&magic, 4, 1, f); + fwrite(&version, 2, 1, f); + fwrite(&dflags, 2, 1, f); track_size = array_size + 6; + track_base = 8 + ((disk_size.sides == 2) ? 2048 : 1024); if (disk_size.tracks <= 43) - shift = 1; + shift = 1; for (i = 0; i < (disk_size.tracks * disk_size.sides) << shift; i++) - tarray[i] = track_base + (i * track_size); + tarray[i] = track_base + (i * track_size); - stream.writeRawData(reinterpret_cast(tarray), (disk_size.sides == 2) ? 2048 : 1024); + fwrite(tarray, 1, (disk_size.sides == 2) ? 2048 : 1024, f); - int max = i < (disk_size.tracks * disk_size.sides) << shift; - for (i = 0; i < max; i++) { - stream << tflags; - stream << index_hole_pos; - stream.writeRawData(bytes, bytes.size()); + for (i = 0; i < (disk_size.tracks * disk_size.sides) << shift; i++) { + fwrite(&tflags, 2, 1, f); + fwrite(&index_hole_pos, 4, 1, f); + fwrite(empty, 1, array_size, f); } + free(empty); + + fclose(f); + return true; } From 6f672fb3bac0525545a50b3bb7493efff2afc151 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 26 Feb 2022 14:02:13 +0600 Subject: [PATCH 05/37] qt: Include necessary files --- src/qt/qt_newfloppydialog.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/qt/qt_newfloppydialog.cpp b/src/qt/qt_newfloppydialog.cpp index a5ec8d695..596927125 100644 --- a/src/qt/qt_newfloppydialog.cpp +++ b/src/qt/qt_newfloppydialog.cpp @@ -31,6 +31,9 @@ extern "C" { #include <86box/mo.h> } +#include +#include + #include #include #include From 62333560dc5c5be4a260f9be06972cb8e98bda25 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 26 Feb 2022 14:09:58 +0600 Subject: [PATCH 06/37] qt: Include plat.h --- src/qt/qt_newfloppydialog.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt/qt_newfloppydialog.cpp b/src/qt/qt_newfloppydialog.cpp index 596927125..694dc769e 100644 --- a/src/qt/qt_newfloppydialog.cpp +++ b/src/qt/qt_newfloppydialog.cpp @@ -25,6 +25,7 @@ #include "qt_util.hpp" extern "C" { +#include <86box/plat.h> #include <86box/random.h> #include <86box/scsi_device.h> #include <86box/zip.h> From f966909500a521e5d2b0acdc37165d9b33783bc6 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 26 Feb 2022 14:28:16 +0600 Subject: [PATCH 07/37] qt: Fix compile error --- src/qt/qt_newfloppydialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_newfloppydialog.cpp b/src/qt/qt_newfloppydialog.cpp index 694dc769e..6eb43c960 100644 --- a/src/qt/qt_newfloppydialog.cpp +++ b/src/qt/qt_newfloppydialog.cpp @@ -301,7 +301,7 @@ bool NewFloppyDialog::create86f(const QString& filename, const disk_size_t& disk break; } - empty = (unsigned char *) malloc(array_size); + auto empty = (unsigned char *) malloc(array_size); memset(tarray, 0, 2048); memset(empty, 0, array_size); From 801f81fbda507c4288c15bf5cea456ef7e1cf3e5 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 26 Feb 2022 23:31:28 -0500 Subject: [PATCH 08/37] clean up device_config_t formatting --- src/device/bugger.c | 2 +- src/device/isamem.c | 809 ++++++++++++------------------ src/device/isartc.c | 176 +++---- src/device/mouse.c | 22 +- src/device/mouse_bus.c | 169 ++----- src/device/mouse_ps2.c | 25 +- src/device/mouse_serial.c | 85 ++-- src/disk/hdc.c | 49 +- src/disk/hdc_ide.c | 116 ++--- src/disk/hdc_st506_xt.c | 268 ++++------ src/disk/hdc_xta.c | 62 +-- src/floppy/fdc.c | 3 - src/floppy/fdc_magitronic.c | 24 +- src/floppy/fdc_pii15xb.c | 32 +- src/game/gameport.c | 1 - src/lpt.c | 23 +- src/network/net_3c503.c | 136 ++--- src/network/net_dp8390.c | 13 +- src/network/net_ne2000.c | 246 +++------ src/network/net_pcnet.c | 187 +++---- src/network/net_wd8003.c | 466 ++++++----------- src/network/network.c | 42 +- src/network/pcap_if.c | 14 +- src/printer/prt_cpmap.c | 32 +- src/printer/prt_ps.c | 16 +- src/scsi/scsi_aha154x.c | 466 ++++++----------- src/scsi/scsi_buslogic.c | 132 ++--- src/scsi/scsi_ncr5380.c | 267 ++++------ src/scsi/scsi_ncr53c8xx.c | 28 +- src/scsi/scsi_pcscsi.c | 15 +- src/scsi/scsi_spock.c | 24 +- src/video/vid_ati28800.c | 80 ++- src/video/vid_ati_mach64.c | 104 ++-- src/video/vid_cga.c | 117 ++--- src/video/vid_cl54xx.c | 402 +++++++-------- src/video/vid_colorplus.c | 73 ++- src/video/vid_ega.c | 128 +++-- src/video/vid_et4000.c | 35 +- src/video/vid_et4000w32.c | 27 +- src/video/vid_genius.c | 2 +- src/video/vid_hercules.c | 36 +- src/video/vid_herculesplus.c | 36 +- src/video/vid_ht216.c | 85 ++-- src/video/vid_ibm_rgb528_ramdac.c | 13 +- src/video/vid_mda.c | 41 +- src/video/vid_mga.c | 53 +- src/video/vid_nga.c | 101 ++-- src/video/vid_oak_oti.c | 116 ++--- src/video/vid_ogc.c | 42 +- src/video/vid_paradise.c | 27 +- src/video/vid_rtg310x.c | 35 +- src/video/vid_s3.c | 173 +++---- src/video/vid_s3_virge.c | 134 ++--- src/video/vid_sigma.c | 97 ++-- src/video/vid_table.c | 413 +++++++-------- src/video/vid_tgui9440.c | 125 +++-- src/video/vid_tvga.c | 42 +- src/video/vid_vga.c | 12 +- src/video/vid_voodoo.c | 239 +++++---- src/video/vid_voodoo_banshee.c | 237 +++++---- src/video/vid_wy700.c | 4 +- 61 files changed, 2679 insertions(+), 4300 deletions(-) diff --git a/src/device/bugger.c b/src/device/bugger.c index 6f2b64e65..214f8acb8 100644 --- a/src/device/bugger.c +++ b/src/device/bugger.c @@ -351,7 +351,7 @@ static void bug_close(UNUSED(void *priv)) { io_removehandler(BUGGER_ADDR, BUGGER_ADDRLEN, - bug_read, NULL, NULL, bug_write, NULL, NULL, NULL); + bug_read, NULL, NULL, bug_write, NULL, NULL, NULL); } diff --git a/src/device/isamem.c b/src/device/isamem.c index 70ef32024..9b1ee7090 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -676,22 +676,20 @@ isamem_close(void *priv) free(dev); } - -static const device_config_t ibmxt_config[] = -{ - { - "size", "Memory Size", CONFIG_SPINNER, "", 128, "", - { 0, 512, 16 }, - { { 0 } } - }, - { - "start", "Start Address", CONFIG_SPINNER, "", 256, "", - { 0, 576, 64 }, - { { 0 } } - }, - { - "", "", -1 - } +static const device_config_t ibmxt_config[] = { +// clang-format off + { + "size", "Memory Size", CONFIG_SPINNER, "", 128, "", + { 0, 512, 16 }, + { { 0 } } + }, + { + "start", "Start Address", CONFIG_SPINNER, "", 256, "", + { 0, 576, 64 }, + { { 0 } } + }, + { "", "", -1 } +// clang-format on }; static const device_t ibmxt_device = { @@ -704,22 +702,20 @@ static const device_t ibmxt_device = { ibmxt_config }; - -static const device_config_t genericxt_config[] = -{ - { - "size", "Memory Size", CONFIG_SPINNER, "", 16, "", - { 0, 640, 16 }, - { { 0 } } - }, - { - "start", "Start Address", CONFIG_SPINNER, "", 0, "", - { 0, 624, 16 }, - { { 0 } } - }, - { - "", "", -1 - } +static const device_config_t genericxt_config[] = { +// clang-format off + { + "size", "Memory Size", CONFIG_SPINNER, "", 16, "", + { 0, 640, 16 }, + { { 0 } } + }, + { + "start", "Start Address", CONFIG_SPINNER, "", 0, "", + { 0, 624, 16 }, + { { 0 } } + }, + { "", "", -1 } +// clang-format on }; static const device_t genericxt_device = { @@ -733,21 +729,20 @@ static const device_t genericxt_device = { }; -static const device_config_t ibmat_config[] = -{ - { - "size", "Memory Size", CONFIG_SPINNER, "", 512, "", - { 0, 12288, 512 }, - { { 0 } } - }, - { - "start", "Start Address", CONFIG_SPINNER, "", 512, "", - { 0, 15872, 512 }, - { { 0 } } - }, - { - "", "", -1 - } +static const device_config_t ibmat_config[] = { +// clang-format off + { + "size", "Memory Size", CONFIG_SPINNER, "", 512, "", + { 0, 12288, 512 }, + { { 0 } } + }, + { + "start", "Start Address", CONFIG_SPINNER, "", 512, "", + { 0, 15872, 512 }, + { { 0 } } + }, + { "", "", -1 } +// clang-format on }; static const device_t ibmat_device = { @@ -761,21 +756,20 @@ static const device_t ibmat_device = { }; -static const device_config_t genericat_config[] = -{ - { - "size", "Memory Size", CONFIG_SPINNER, "", 512, "", - { 0, 16384, 512 }, - { { 0 } } - }, - { - "start", "Start Address", CONFIG_SPINNER, "", 512, "", - { 0, 15872, 128 }, - { { 0 } } - }, - { - "", "", -1 - } +static const device_config_t genericat_config[] = { +// clang-format off + { + "size", "Memory Size", CONFIG_SPINNER, "", 512, "", + { 0, 16384, 512 }, + { { 0 } } + }, + { + "start", "Start Address", CONFIG_SPINNER, "", 512, "", + { 0, 15872, 128 }, + { { 0 } } + }, + { "", "", -1 } +// clang-format on }; static const device_t genericat_device = { @@ -789,21 +783,20 @@ static const device_t genericat_device = { }; -static const device_config_t p5pak_config[] = -{ - { - "size", "Memory Size", CONFIG_SPINNER, "", 128, "", - { 0, 384, 64 }, - { { 0 } } - }, - { - "start", "Start Address", CONFIG_SPINNER, "", 512, "", - { 64, 576, 64 }, - { { 0 } } - }, - { - "", "", -1 - } +static const device_config_t p5pak_config[] = { +// clang-format off + { + "size", "Memory Size", CONFIG_SPINNER, "", 128, "", + { 0, 384, 64 }, + { { 0 } } + }, + { + "start", "Start Address", CONFIG_SPINNER, "", 512, "", + { 64, 576, 64 }, + { { 0 } } + }, + { "", "", -1 } +// clang-format on }; static const device_t p5pak_device = { @@ -817,21 +810,20 @@ static const device_t p5pak_device = { }; -static const device_config_t a6pak_config[] = -{ - { - "size", "Memory Size", CONFIG_SPINNER, "", 64, "", - { 0, 576, 64 }, - { { 0 } } - }, - { - "start", "Start Address", CONFIG_SPINNER, "", 256, "", - { 64, 512, 64 }, - { { 0 } } - }, - { - "", "", -1 - } +static const device_config_t a6pak_config[] = { +// clang-format off + { + "size", "Memory Size", CONFIG_SPINNER, "", 64, "", + { 0, 576, 64 }, + { { 0 } } + }, + { + "start", "Start Address", CONFIG_SPINNER, "", 256, "", + { 64, 512, 64 }, + { { 0 } } + }, + { "", "", -1 } +// clang-format on }; static const device_t a6pak_device = { @@ -845,40 +837,26 @@ static const device_t a6pak_device = { }; -static const device_config_t ems5150_config[] = -{ - { - "size", "Memory Size", CONFIG_SPINNER, "", 256, - "", - { 0, 2048, 64 }, - { { 0 } } - }, - { - "base", "Address", CONFIG_HEX16, "", 0, "", { 0 }, - { - { - "Disabled", 0 - }, - { - "Board 1", 0x0208 - }, - { - "Board 2", 0x020a - }, - { - "Board 3", 0x020c - }, - { - "Board 4", 0x020e - }, - { - "" - } - }, - }, - { - "", "", -1 - } +static const device_config_t ems5150_config[] = { +// clang-format off + { + "size", "Memory Size", CONFIG_SPINNER, "", 256, "", + { 0, 2048, 64 }, + { { 0 } } + }, + { + "base", "Address", CONFIG_HEX16, "", 0, "", { 0 }, + { + { "Disabled", 0x0000 }, + { "Board 1", 0x0208 }, + { "Board 2", 0x020a }, + { "Board 3", 0x020c }, + { "Board 4", 0x020e }, + { "" } + }, + }, + { "", "", -1 } +// clang-format on }; static const device_t ems5150_device = { @@ -891,98 +869,62 @@ static const device_t ems5150_device = { ems5150_config }; - -static const device_config_t ev159_config[] = -{ - { - "size", "Memory Size", CONFIG_SPINNER, "", 512, "", - { 0, 3072, 512 }, - { { 0 } } - }, - { - "start", "Start Address", CONFIG_SPINNER, "", 0, "", - { 0, 16128, 128 }, - { { 0 } } - }, - { - "length", "Contiguous Size", CONFIG_SPINNER, "", 0, "", - { 0, 16384, 128 }, - { { 0 } } - }, - { - "width", "I/O Width", CONFIG_SELECTION, "", 0, "", { 0 }, - { - { - "8-bit", 0 - }, - { - "16-bit", 1 - }, - { - "" - } - }, - }, - { - "speed", "Transfer Speed", CONFIG_SELECTION, "", 0, "", { 0 }, - { - { - "Standard (150ns)", 0 - }, - { - "High-Speed (120ns)", 1 - }, - { - "" - } - } - }, - { - "ems", "EMS mode", CONFIG_SELECTION, "", 0, "", { 0 }, - { - { - "Disabled", 0 - }, - { - "Enabled", 1 - }, - { - "" - } - }, - }, - { - "base", "Address", CONFIG_HEX16, "", 0x0258, "", { 0 }, - { - { - "208H", 0x0208 - }, - { - "218H", 0x0218 - }, - { - "258H", 0x0258 - }, - { - "268H", 0x0268 - }, - { - "2A8H", 0x02A8 - }, - { - "2B8H", 0x02B8 - }, - { - "2E8H", 0x02E8 - }, - { - "" - } - }, - }, - { - "", "", -1 - } +static const device_config_t ev159_config[] = { +// clang-format off + { + "size", "Memory Size", CONFIG_SPINNER, "", 512, "", + { 0, 3072, 512 }, + { { 0 } } + }, + { + "start", "Start Address", CONFIG_SPINNER, "", 0, "", + { 0, 16128, 128 }, + { { 0 } } + }, + { + "length", "Contiguous Size", CONFIG_SPINNER, "", 0, "", + { 0, 16384, 128 }, + { { 0 } } + }, + { + "width", "I/O Width", CONFIG_SELECTION, "", 0, "", { 0 }, + { + { "8-bit", 0 }, + { "16-bit", 1 }, + { "" } + }, + }, + { + "speed", "Transfer Speed", CONFIG_SELECTION, "", 0, "", { 0 }, + { + { "Standard (150ns)", 0 }, + { "High-Speed (120ns)", 1 }, + { "" } + } + }, + { + "ems", "EMS mode", CONFIG_SELECTION, "", 0, "", { 0 }, + { + { "Disabled", 0 }, + { "Enabled", 1 }, + { "" } + }, + }, + { + "base", "Address", CONFIG_HEX16, "", 0x0258, "", { 0 }, + { + { "208H", 0x0208 }, + { "218H", 0x0218 }, + { "258H", 0x0258 }, + { "268H", 0x0268 }, + { "2A8H", 0x02A8 }, + { "2B8H", 0x02B8 }, + { "2E8H", 0x02E8 }, + { "" } + }, + }, + { "", "", -1 } +// clang-format on }; static const device_t ev159_device = { @@ -995,84 +937,52 @@ static const device_t ev159_device = { ev159_config }; - #if defined(DEV_BRANCH) && defined(USE_ISAMEM_BRAT) -static const device_config_t brat_config[] = -{ - { - "base", "Address", CONFIG_HEX16, "", 0x0258, "", { 0 }, - { - { - "208H", 0x0208 - }, - { - "218H", 0x0218 - }, - { - "258H", 0x0258 - }, - { - "268H", 0x0268 - }, - { - "" - } - }, - }, - { - "frame", "Frame Address", CONFIG_HEX20, "", 0, "", { 0 }, - { - { - "Disabled", 0x00000 - }, - { - "D000H", 0xD0000 - }, - { - "E000H", 0xE0000 - }, - { - "" - } - }, - }, - { - "width", "I/O Width", CONFIG_SELECTION, "", 8, "", { 0 }, - { - { - "8-bit", 8 - }, - { - "16-bit", 16 - }, - { - "" - } - }, - }, - { - "speed", "Transfer Speed", CONFIG_SELECTION, "", 0, "", { 0 }, - { - { - "Standard", 0 - }, - { - "High-Speed", 1 - }, - { - "" - } - } - }, - { - "size", "Memory Size", CONFIG_SPINNER, "", 128, - "", - { 0, 8192, 512 }, - { { 0 } } - }, - { - "", "", -1 - } +static const device_config_t brat_config[] = { +// clang-format off + { + "base", "Address", CONFIG_HEX16, "", 0x0258, "", { 0 }, + { + { "208H", 0x0208 }, + { "218H", 0x0218 }, + { "258H", 0x0258 }, + { "268H", 0x0268 }, + { "" } + }, + }, + { + "frame", "Frame Address", CONFIG_HEX20, "", 0, "", { 0 }, + { + { "Disabled", 0x00000 }, + { "D000H", 0xD0000 }, + { "E000H", 0xE0000 }, + { "" } + }, + }, + { + "width", "I/O Width", CONFIG_SELECTION, "", 8, "", { 0 }, + { + { "8-bit", 8 }, + { "16-bit", 16 }, + { "" } + }, + }, + { + "speed", "Transfer Speed", CONFIG_SELECTION, "", 0, "", { 0 }, + { + { "Standard", 0 }, + { "High-Speed", 1 }, + { "" } + } + }, + { + "size", "Memory Size", CONFIG_SPINNER, "", 128, + "", + { 0, 8192, 512 }, + { { 0 } } + }, + { "", "", -1 } +// clang-format on }; static const device_t brat_device = { @@ -1086,96 +996,55 @@ static const device_t brat_device = { }; #endif - #if defined(DEV_BRANCH) && defined(USE_ISAMEM_RAMPAGE) -static const device_config_t rampage_config[] = -{ - { - "base", "Address", CONFIG_HEX16, "", 0x0258, "", { 0 }, - { - { - "208H", 0x0208 - }, - { - "218H", 0x0218 - }, - { - "258H", 0x0258 - }, - { - "268H", 0x0268 - }, - { - "2A8H", 0x02A8 - }, - { - "2B8H", 0x02B8 - }, - { - "2E8H", 0x02E8 - }, - { - "" - } - }, - }, - { - "frame", "Frame Address", CONFIG_HEX20, "", 0, "", { 0 }, - { - { - "Disabled", 0x00000 - }, - { - "C000H", 0xC0000 - }, - { - "D000H", 0xD0000 - }, - { - "E000H", 0xE0000 - }, - { - "" - } - }, - }, - { - "width", "I/O Width", CONFIG_SELECTION, "", 8, "", { 0 }, - { - { - "8-bit", 8 - }, - { - "16-bit", 16 - }, - { - "" - } - }, - }, - { - "speed", "Transfer Speed", CONFIG_SELECTION, "", 0, "", { 0 }, - { - { - "Standard", 0 - }, - { - "High-Speed", 1 - }, - { - "" - } - } - }, - { - "size", "Memory Size", CONFIG_SPINNER, "", 128, - "", - { 0, 8192, 128 }, - { { 0 } } - }, - { - "", "", -1 - } +static const device_config_t rampage_config[] = { +// clang-format off + { + "base", "Address", CONFIG_HEX16, "", 0x0258, "", { 0 }, + { + { "208H", 0x0208 }, + { "218H", 0x0218 }, + { "258H", 0x0258 }, + { "268H", 0x0268 }, + { "2A8H", 0x02A8 }, + { "2B8H", 0x02B8 }, + { "2E8H", 0x02E8 }, + { "" } + }, + }, + { + "frame", "Frame Address", CONFIG_HEX20, "", 0, "", { 0 }, + { + { "Disabled", 0x00000 }, + { "C000H", 0xC0000 }, + { "D000H", 0xD0000 }, + { "E000H", 0xE0000 }, + { "" } + }, + }, + { + "width", "I/O Width", CONFIG_SELECTION, "", 8, "", { 0 }, + { + { "8-bit", 8 }, + { "16-bit", 16 }, + { "" } + }, + }, + { + "speed", "Transfer Speed", CONFIG_SELECTION, "", 0, "", { 0 }, + { + { "Standard", 0 }, + { "High-Speed", 1 }, + { "" } + } + }, + { + "size", "Memory Size", CONFIG_SPINNER, "", 128, "", + { 0, 8192, 128 }, + { { 0 } } + }, + { "", "", -1 } +// clang-format on }; static const device_t rampage_device = { @@ -1191,94 +1060,54 @@ static const device_t rampage_device = { #if defined(DEV_BRANCH) && defined(USE_ISAMEM_IAB) -static const device_config_t iab_config[] = -{ - { - "base", "Address", CONFIG_HEX16, "", 0x0258, "", { 0 }, - { - { - "208H", 0x0208 - }, - { - "218H", 0x0218 - }, - { - "258H", 0x0258 - }, - { - "268H", 0x0268 - }, - { - "2A8H", 0x02A8 - }, - { - "2B8H", 0x02B8 - }, - { - "2E8H", 0x02E8 - }, - { - "" - } - }, - }, - { - "frame", "Frame Address", CONFIG_HEX20, "", 0, "", { 0 }, - { - { - "Disabled", 0x00000 - }, - { - "C000H", 0xC0000 - }, - { - "D000H", 0xD0000 - }, - { - "E000H", 0xE0000 - }, - { - "" - } - }, - }, - { - "width", "I/O Width", CONFIG_SELECTION, "", 8, "", { 0 }, - { - { - "8-bit", 8 - }, - { - "16-bit", 16 - }, - { - "" - } - }, - }, - { - "speed", "Transfer Speed", CONFIG_SELECTION, "", 0, "", { 0 }, - { - { - "Standard", 0 - }, - { - "High-Speed", 1 - }, - { - "" - } - } - }, - { - "size", "Memory Size", CONFIG_SPINNER, "", 128, - "", - { 0, 8192, 128 }, - { { 0 } } - }, - { - "", "", -1 - } +static const device_config_t iab_config[] = { +// clang-format off + { + "base", "Address", CONFIG_HEX16, "", 0x0258, "", { 0 }, + { + { "208H", 0x0208 }, + { "218H", 0x0218 }, + { "258H", 0x0258 }, + { "268H", 0x0268 }, + { "2A8H", 0x02A8 }, + { "2B8H", 0x02B8 }, + { "2E8H", 0x02E8 }, + { "" } + }, + }, + { + "frame", "Frame Address", CONFIG_HEX20, "", 0, "", { 0 }, + { + { "Disabled", 0x00000 }, + { "C000H", 0xC0000 }, + { "D000H", 0xD0000 }, + { "E000H", 0xE0000 }, + { "" } + }, + }, + { + "width", "I/O Width", CONFIG_SELECTION, "", 8, "", { 0 }, + { + { "8-bit", 8 }, + { "16-bit", 16 }, + { "" } + }, + }, + { + "speed", "Transfer Speed", CONFIG_SELECTION, "", 0, "", { 0 }, + { + { "Standard", 0 }, + { "High-Speed", 1 }, + { "" } + } + }, + { + "size", "Memory Size", CONFIG_SPINNER, "", 128, "", + { 0, 8192, 128 }, + { { 0 } } + }, + { "", "", -1 } +// clang-format on }; static const device_t iab_device = { @@ -1292,7 +1121,6 @@ static const device_t iab_device = { }; #endif - static const device_t isa_none_device = { "None", "none", @@ -1302,32 +1130,32 @@ static const device_t isa_none_device = { NULL }; - static const struct { const device_t *dev; } boards[] = { - { &isa_none_device }, - { &ibmxt_device }, - { &genericxt_device }, - { &ibmat_device }, - { &genericat_device }, - { &p5pak_device }, - { &a6pak_device }, - { &ems5150_device }, - { &ev159_device }, +// clang-format off + { &isa_none_device }, + { &ibmxt_device }, + { &genericxt_device }, + { &ibmat_device }, + { &genericat_device }, + { &p5pak_device }, + { &a6pak_device }, + { &ems5150_device }, + { &ev159_device }, #if defined(DEV_BRANCH) && defined(USE_ISAMEM_BRAT) - { &brat_device }, + { &brat_device }, #endif #if defined(DEV_BRANCH) && defined(USE_ISAMEM_RAMPAGE) - { &rampage_device }, + { &rampage_device }, #endif #if defined(DEV_BRANCH) && defined(USE_ISAMEM_IAB) - { &iab_device }, + { &iab_device }, #endif - { NULL } + { NULL } +// clang-format on }; - void isamem_reset(void) { @@ -1345,7 +1173,6 @@ isamem_reset(void) } } - const char * isamem_get_name(int board) { @@ -1354,15 +1181,12 @@ isamem_get_name(int board) return(boards[board].dev->name); } - const char * isamem_get_internal_name(int board) { return device_get_internal_name(boards[board].dev); } - - int isamem_get_from_internal_name(const char *s) { @@ -1378,7 +1202,6 @@ isamem_get_from_internal_name(const char *s) return(0); } - const device_t * isamem_get_device(int board) { diff --git a/src/device/isartc.c b/src/device/isartc.c index 57ccd957f..6acf01f0c 100644 --- a/src/device/isartc.c +++ b/src/device/isartc.c @@ -594,43 +594,27 @@ isartc_close(void *priv) static const device_config_t ev170_config[] = { - { - "base", "Address", CONFIG_HEX16, "", 0x02C0, "", { 0 }, - { - { - "240H", 0x0240 - }, - { - "2C0H", 0x02c0 - }, - { - "" - } - }, - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", -1, "", { 0 }, - { - { - "Disabled", -1 - }, - { - "IRQ2", 2 - }, - { - "IRQ5", 5 - }, - { - "IRQ7", 7 - }, - { - "" - } - }, - }, - { - "", "", -1 - } +// clang-format off + { + "base", "Address", CONFIG_HEX16, "", 0x02C0, "", { 0 }, + { + { "240H", 0x0240 }, + { "2C0H", 0x02c0 }, + { "" } + }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", -1, "", { 0 }, + { + { "Disabled", -1 }, + { "IRQ2", 2 }, + { "IRQ5", 5 }, + { "IRQ7", 7 }, + { "" } + }, + }, + { "", "", -1 } +// clang-format on }; static const device_t ev170_device = { @@ -645,23 +629,17 @@ static const device_t ev170_device = { static const device_config_t pii147_config[] = { - { - "base", "Address", CONFIG_HEX16, "", 0x0240, "", { 0 }, - { - { - "Clock 1", 0x0240 - }, - { - "Clock 2", 0x0340 - }, - { - "" - } - }, - }, - { - "", "", -1 - } +// clang-format off + { + "base", "Address", CONFIG_HEX16, "", 0x0240, "", { 0 }, + { + { "Clock 1", 0x0240 }, + { "Clock 2", 0x0340 }, + { "" } + }, + }, + { "", "", -1 } +// clang-format on }; static const device_t pii147_device = { @@ -676,29 +654,19 @@ static const device_t pii147_device = { static const device_config_t p5pak_config[] = { - { - "irq", "IRQ", CONFIG_SELECTION, "", -1, "", { 0 }, - { - { - "Disabled", -1 - }, - { - "IRQ2", 2 - }, - { - "IRQ3", 3 - }, - { - "IRQ5", 5 - }, - { - "" - } - }, - }, - { - "", "", -1 - } +// clang-format off + { + "irq", "IRQ", CONFIG_SELECTION, "", -1, "", { 0 }, + { + { "Disabled", -1 }, + { "IRQ2", 2 }, + { "IRQ3", 3 }, + { "IRQ5", 5 }, + { "" } + }, + }, + { "", "", -1 } +// clang-format on }; static const device_t p5pak_device = { @@ -713,29 +681,19 @@ static const device_t p5pak_device = { static const device_config_t a6pak_config[] = { - { - "irq", "IRQ", CONFIG_SELECTION, "", -1, "", { 0 }, - { - { - "Disabled", -1 - }, - { - "IRQ2", 2 - }, - { - "IRQ3", 3 - }, - { - "IRQ5", 5 - }, - { - "" - } - }, - }, - { - "", "", -1 - } +// clang-format off + { + "irq", "IRQ", CONFIG_SELECTION, "", -1, "", { 0 }, + { + { "Disabled", -1 }, + { "IRQ2", 2 }, + { "IRQ3", 3 }, + { "IRQ5", 5 }, + { "" } + }, + }, + { "", "", -1 } +// clang-format on }; static const device_t a6pak_device = { @@ -748,7 +706,6 @@ static const device_t a6pak_device = { a6pak_config }; - static const device_t isartc_none_device = { "None", "none", @@ -758,19 +715,19 @@ static const device_t isartc_none_device = { NULL }; - static const struct { const device_t *dev; } boards[] = { - { &isartc_none_device }, - { &ev170_device }, - { &pii147_device }, - { &p5pak_device }, - { &a6pak_device }, - { NULL }, +// clang-format off + { &isartc_none_device }, + { &ev170_device }, + { &pii147_device }, + { &p5pak_device }, + { &a6pak_device }, + { NULL }, +// clang-format on }; - void isartc_reset(void) { @@ -780,7 +737,6 @@ isartc_reset(void) device_add(boards[isartc_type].dev); } - char * isartc_get_internal_name(int board) { diff --git a/src/device/mouse.c b/src/device/mouse.c index 662d5e76e..295f0b8fb 100644 --- a/src/device/mouse.c +++ b/src/device/mouse.c @@ -61,18 +61,20 @@ static const device_t mouse_internal_device = { static mouse_t mouse_devices[] = { - { &mouse_none_device }, - { &mouse_internal_device }, - { &mouse_logibus_device }, - { &mouse_msinport_device }, +// clang-format off + { &mouse_none_device }, + { &mouse_internal_device }, + { &mouse_logibus_device }, + { &mouse_msinport_device }, #if 0 - { &mouse_genibus_device }, + { &mouse_genibus_device }, #endif - { &mouse_mssystems_device }, - { &mouse_msserial_device }, - { &mouse_ltserial_device }, - { &mouse_ps2_device }, - { NULL } + { &mouse_mssystems_device }, + { &mouse_msserial_device }, + { &mouse_ltserial_device }, + { &mouse_ps2_device }, + { NULL } +// clang-format on }; diff --git a/src/device/mouse_bus.c b/src/device/mouse_bus.c index d627db75f..de2183b4d 100644 --- a/src/device/mouse_bus.c +++ b/src/device/mouse_bus.c @@ -693,144 +693,77 @@ bm_init(const device_t *info) return dev; } - static const device_config_t lt_config[] = { +// clang-format off { - "base", "Address", CONFIG_HEX16, "", 0x23c, "", { 0 }, - { - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x238", 0x238 - }, - { - "0x23C", 0x23c - }, - { - "" - } - } + "base", "Address", CONFIG_HEX16, "", 0x23c, "", { 0 }, { + { "0x230", 0x230 }, + { "0x234", 0x234 }, + { "0x238", 0x238 }, + { "0x23C", 0x23c }, + { "" } + } }, { - "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "" - } - } + "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, { + { "IRQ 2", 2 }, + { "IRQ 3", 3 }, + { "IRQ 4", 4 }, + { "IRQ 5", 5 }, + { "" } + } }, { - "hz", "Hz", CONFIG_SELECTION, "", 45, "", { 0 }, { - { - "Non-timed (original)", 0 - }, - { - "30 Hz (JMP2 = 1)", 30 - }, - { - "45 Hz (JMP2 not populated)", 45 - }, - { - "60 Hz (JMP 2 = 2)", 60 - }, - { - "" - } - } + "hz", "Hz", CONFIG_SELECTION, "", 45, "", { 0 }, { + { "Non-timed (original)", 0 }, + { "30 Hz (JMP2 = 1)", 30 }, + { "45 Hz (JMP2 not populated)", 45 }, + { "60 Hz (JMP 2 = 2)", 60 }, + { "" } + } }, { - "buttons", "Buttons", CONFIG_SELECTION, "", 2, "", { 0 }, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "" - } - } + "buttons", "Buttons", CONFIG_SELECTION, "", 2, "", { 0 }, { + { "Two", 2 }, + { "Three", 3 }, + { "" } + } }, - { - "", "", -1 - } + { "", "", -1 } +// clang-format on }; - static const device_config_t ms_config[] = { +// clang-format off { - "base", "Address", CONFIG_HEX16, "", 0x23c, "", { 0 }, - { - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x238", 0x238 - }, - { - "0x23C", 0x23c - }, - { - "" - } - } + "base", "Address", CONFIG_HEX16, "", 0x23c, "", { 0 }, { + { "0x230", 0x230 }, + { "0x234", 0x234 }, + { "0x238", 0x238 }, + { "0x23C", 0x23c }, + { "" } + } }, { - "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "" - } - } + "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, { + { "IRQ 2", 2 }, + { "IRQ 3", 3 }, + { "IRQ 4", 4 }, + { "IRQ 5", 5 }, + { "" } + } }, { - "buttons", "Buttons", CONFIG_SELECTION, "", 2, "", { 0 }, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "" - } - } + "buttons", "Buttons", CONFIG_SELECTION, "", 2, "", { 0 }, { + { "Two", 2 }, + { "Three", 3 }, + { "" } + } }, - { - "", "", -1 - } + { "", "", -1 } +// clang-format on }; - const device_t mouse_logibus_device = { "Logitech/Microsoft Bus Mouse", "logibus", diff --git a/src/device/mouse_ps2.c b/src/device/mouse_ps2.c index 949875bbf..04653661b 100644 --- a/src/device/mouse_ps2.c +++ b/src/device/mouse_ps2.c @@ -331,28 +331,21 @@ ps2_close(void *priv) static const device_config_t ps2_config[] = { +// clang-format off { - "buttons", "Buttons", CONFIG_SELECTION, "", 2, "", { 0 }, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "Wheel", 4 - }, - { - "" - } - } + "buttons", "Buttons", CONFIG_SELECTION, "", 2, "", { 0 }, { + { "Two", 2 }, + { "Three", 3 }, + { "Wheel", 4 }, + { "" } + } }, { - "", "", -1 + "", "", -1 } +// clang-format on }; - const device_t mouse_ps2_device = { "Standard PS/2 Mouse", "ps2", diff --git a/src/device/mouse_serial.c b/src/device/mouse_serial.c index 432aa1711..32365fffe 100644 --- a/src/device/mouse_serial.c +++ b/src/device/mouse_serial.c @@ -830,74 +830,51 @@ sermouse_init(const device_t *info) static const device_config_t mssermouse_config[] = { +// clang-format off { - "port", "Serial Port", CONFIG_SELECTION, "", 0, "", { 0 }, { - { - "COM1", 0 - }, - { - "COM2", 1 - }, - { - "" - } - } + "port", "Serial Port", CONFIG_SELECTION, "", 0, "", { 0 }, { + { "COM1", 0 }, + { "COM2", 1 }, + { "COM3", 2 }, + { "COM4", 3 }, + { "" } + } }, { - "buttons", "Buttons", CONFIG_SELECTION, "", 2, "", { 0 }, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "Wheel", 4 - }, - { - "" - } - } + "buttons", "Buttons", CONFIG_SELECTION, "", 2, "", { 0 }, { + { "Two", 2 }, + { "Three", 3 }, + { "Wheel", 4 }, + { "" } + } }, - { - "", "", -1 - } + { "", "", -1 } +// clang-format on }; static const device_config_t ltsermouse_config[] = { +// clang-format off { - "port", "Serial Port", CONFIG_SELECTION, "", 0, "", { 0 }, { - { - "COM1", 0 - }, - { - "COM2", 1 - }, - { - "" - } - } + "port", "Serial Port", CONFIG_SELECTION, "", 0, "", { 0 }, { + { "COM1", 0 }, + { "COM2", 1 }, + { "COM3", 2 }, + { "COM4", 3 }, + { "" } + } }, { - "buttons", "Buttons", CONFIG_SELECTION, "", 2, "", { 0 }, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "" - } - } + "buttons", "Buttons", CONFIG_SELECTION, "", 2, "", { 0 }, { + { "Two", 2 }, + { "Three", 3 }, + { "" } + } }, - { - "", "", -1 - } + { "", "", -1 } +// clang-format on }; - const device_t mouse_mssystems_device = { "Mouse Systems Serial Mouse", "mssystems", diff --git a/src/disk/hdc.c b/src/disk/hdc.c index a6e09b732..10b9ea72a 100644 --- a/src/disk/hdc.c +++ b/src/disk/hdc.c @@ -92,35 +92,36 @@ static const device_t hdc_internal_device = { static const struct { +// clang-format off const device_t *device; } controllers[] = { - { &hdc_none_device }, - { &hdc_internal_device }, - { &st506_xt_xebec_device }, - { &st506_xt_dtc5150x_device }, - { &st506_xt_st11_m_device }, - { &st506_xt_wd1002a_wx1_device }, - { &st506_at_wd1003_device }, - { &st506_xt_st11_r_device }, - { &st506_xt_wd1002a_27x_device }, - { &esdi_at_wd1007vse1_device }, - { &ide_isa_device }, - { &ide_isa_2ch_device }, - { &xtide_at_device }, - { &xtide_at_386_device }, - { &xtide_at_ps2_device }, - { &xta_wdxt150_device }, - { &xtide_acculogic_device }, - { &xtide_device }, - { &esdi_ps2_device }, - { &ide_pci_device }, - { &ide_pci_2ch_device }, - { &ide_vlb_device }, - { &ide_vlb_2ch_device }, + { &hdc_none_device }, + { &hdc_internal_device }, + { &st506_xt_xebec_device }, + { &st506_xt_dtc5150x_device }, + { &st506_xt_st11_m_device }, + { &st506_xt_wd1002a_wx1_device }, + { &st506_at_wd1003_device }, + { &st506_xt_st11_r_device }, + { &st506_xt_wd1002a_27x_device }, + { &esdi_at_wd1007vse1_device }, + { &ide_isa_device }, + { &ide_isa_2ch_device }, + { &xtide_at_device }, + { &xtide_at_386_device }, + { &xtide_at_ps2_device }, + { &xta_wdxt150_device }, + { &xtide_acculogic_device }, + { &xtide_device }, + { &esdi_ps2_device }, + { &ide_pci_device }, + { &ide_pci_2ch_device }, + { &ide_vlb_device }, + { &ide_vlb_2ch_device }, { NULL } +// clang-format on }; - /* Initialize the 'hdc_current' value based on configured HDC name. */ void hdc_init(void) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index cc0eb7126..7350f6d84 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -3117,95 +3117,47 @@ const device_t ide_pci_2ch_device = { { NULL }, NULL, NULL, NULL }; -static const device_config_t ide_ter_config[] = -{ +// clang-format off +static const device_config_t ide_ter_config[] = { + { + "irq", "IRQ", CONFIG_SELECTION, "", 10, "", { 0 }, { - "irq", "IRQ", CONFIG_SELECTION, "", 10, "", { 0 }, - { - { - "Plug and Play", -1 - }, - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "IRQ 9", 9 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "IRQ 12", 12 - }, - { - "" - } - } - }, - { - "", "", -1 + { "Plug and Play", -1 }, + { "IRQ 2", 2 }, + { "IRQ 3", 3 }, + { "IRQ 4", 4 }, + { "IRQ 5", 5 }, + { "IRQ 7", 7 }, + { "IRQ 9", 9 }, + { "IRQ 10", 10 }, + { "IRQ 11", 11 }, + { "IRQ 12", 12 }, + { "" } } + }, + { "", "", -1 } }; -static const device_config_t ide_qua_config[] = -{ +static const device_config_t ide_qua_config[] = { + { + "irq", "IRQ", CONFIG_SELECTION, "", 11, "", { 0 }, { - "irq", "IRQ", CONFIG_SELECTION, "", 11, "", { 0 }, - { - { - "Plug and Play", -1 - }, - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "IRQ 9", 9 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "IRQ 12", 12 - }, - { - "" - } - } - }, - { - "", "", -1 + { "Plug and Play", -1 }, + { "IRQ 2", 2 }, + { "IRQ 3", 3 }, + { "IRQ 4", 4 }, + { "IRQ 5", 5 }, + { "IRQ 7", 7 }, + { "IRQ 9", 9 }, + { "IRQ 10", 10 }, + { "IRQ 11", 11 }, + { "IRQ 12", 12 }, + { "" } } + }, + { "", "", -1 } }; +// clang-format on const device_t ide_ter_device = { "Tertiary IDE Controller", diff --git a/src/disk/hdc_st506_xt.c b/src/disk/hdc_st506_xt.c index 814bd5c59..fd2ef2b9b 100644 --- a/src/disk/hdc_st506_xt.c +++ b/src/disk/hdc_st506_xt.c @@ -1614,223 +1614,127 @@ wd1002a_27x_available(void) return(rom_present(WD1002A_27X_BIOS_FILE)); } - +// clang-format off static const device_config_t dtc_config[] = { { - "bios_addr", "BIOS address", CONFIG_HEX20, "", 0xc8000, "", { 0 }, - { - { - "Disabled", 0x00000 - }, - { - "C800H", 0xc8000 - }, - { - "CA00H", 0xca000 - }, - { - "D800H", 0xd8000 - }, - { - "F400H", 0xf4000 - }, - { - "" - } - } + "bios_addr", "BIOS address", CONFIG_HEX20, "", 0xc8000, "", { 0 }, + { + { "Disabled", 0x00000 }, + { "C800H", 0xc8000 }, + { "CA00H", 0xca000 }, + { "D800H", 0xd8000 }, + { "F400H", 0xf4000 }, + { "" } + } }, - { - "", "", -1 - } + { "", "", -1 } }; static const device_config_t st11_config[] = { { - "base", "Address", CONFIG_HEX16, "", 0x0320, "", { 0 }, - { - { - "320H", 0x0320 - }, - { - "324H", 0x0324 - }, - { - "328H", 0x0328 - }, - { - "32CH", 0x032c - }, - { - "" - } - } + "base", "Address", CONFIG_HEX16, "", 0x0320, "", { 0 }, + { + { "320H", 0x0320 }, + { "324H", 0x0324 }, + { "328H", 0x0328 }, + { "32CH", 0x032c }, + { "" } + } }, { - "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, - { - { - "IRQ 2", 2 - }, - { - "IRQ 5", 5 - }, - { - "" - } - } + "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, + { + { "IRQ 2", 2 }, + { "IRQ 5", 5 }, + { "" } + } }, { - "bios_addr", "BIOS address", CONFIG_HEX20, "", 0xc8000, "", { 0 }, - { - { - "Disabled", 0x00000 - }, - { - "C800H", 0xc8000 - }, - { - "D000H", 0xd0000 - }, - { - "D800H", 0xd8000 - }, - { - "E000H", 0xe0000 - }, - { - "" - } - } + "bios_addr", "BIOS address", CONFIG_HEX20, "", 0xc8000, "", { 0 }, + { + { "Disabled", 0x00000 }, + { "C800H", 0xc8000 }, + { "D000H", 0xd0000 }, + { "D800H", 0xd8000 }, + { "E000H", 0xe0000 }, + { "" } + } }, { - "revision", "Board Revision", CONFIG_SELECTION, "", 19, "", { 0 }, - { - { - "Rev. 05 (v1.7)", 5 - }, - { - "Rev. 19 (v2.0)", 19 - }, - { - "" - } - } + "revision", "Board Revision", CONFIG_SELECTION, "", 19, "", { 0 }, + { + { "Rev. 05 (v1.7)", 5 }, + { "Rev. 19 (v2.0)", 19 }, + { "" } + } }, - { - "", "", -1 - } + { "", "", -1 } }; static const device_config_t wd_config[] = { { - "bios_addr", "BIOS address", CONFIG_HEX20, "", 0xc8000, "", { 0 }, - { - { - "Disabled", 0x00000 - }, - { - "C800H", 0xc8000 - }, - { - "" - } - } + "bios_addr", "BIOS address", CONFIG_HEX20, "", 0xc8000, "", { 0 }, + { + { "Disabled", 0x00000 }, + { "C800H", 0xc8000 }, + { "" } + } }, { - "base", "Address", CONFIG_HEX16, "", 0x0320, "", { 0 }, - { - { - "320H", 0x0320 - }, - { - "324H", 0x0324 - }, - { - "" - } - } + "base", "Address", CONFIG_HEX16, "", 0x0320, "", { 0 }, + { + { "320H", 0x0320 }, + { "324H", 0x0324 }, + { "" } + } }, { - "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, - { - { - "IRQ 2", 2 - }, - { - "IRQ 5", 5 - }, - { - "" - } - } + "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, + { + { "IRQ 2", 2 }, + { "IRQ 5", 5 }, + { "" } + } }, - { - "", "", -1 - } + { "", "", -1 } }; static const device_config_t wd_rll_config[] = { { - "bios_addr", "BIOS address", CONFIG_HEX20, "", 0xc8000, "", { 0 }, - { - { - "Disabled", 0x00000 - }, - { - "C800H", 0xc8000 - }, - { - "" - } - } + "bios_addr", "BIOS address", CONFIG_HEX20, "", 0xc8000, "", { 0 }, + { + { "Disabled", 0x00000 }, + { "C800H", 0xc8000 }, + { "" } + } }, { - "base", "Address", CONFIG_HEX16, "", 0x0320, "", { 0 }, - { - { - "320H", 0x0320 - }, - { - "324H", 0x0324 - }, - { - "" - } - } + "base", "Address", CONFIG_HEX16, "", 0x0320, "", { 0 }, + { + { "320H", 0x0320 }, + { "324H", 0x0324 }, + { "" } + } }, { - "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, - { - { - "IRQ 2", 2 - }, - { - "IRQ 5", 5 - }, - { - "" - } - } + "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, + { + { "IRQ 2", 2 }, + { "IRQ 5", 5 }, + { "" } + } }, { - "translate", "Translate 26 -> 17", CONFIG_SELECTION, "", 0, "", { 0 }, - { - { - "Off", 0 - }, - { - "On", 1 - }, - { - "" - } - } + "translate", "Translate 26 -> 17", CONFIG_SELECTION, "", 0, "", { 0 }, + { + { "Off", 0 }, + { "On", 1 }, + { "" } + } }, - { - "", "", -1 - } + { "", "", -1 } }; - +// clang-format on const device_t st506_xt_xebec_device = { "IBM PC Fixed Disk Adapter (MFM)", diff --git a/src/disk/hdc_xta.c b/src/disk/hdc_xta.c index 31c6ada0e..03a7c6fb2 100644 --- a/src/disk/hdc_xta.c +++ b/src/disk/hdc_xta.c @@ -1104,54 +1104,35 @@ xta_close(void *priv) static const device_config_t wdxt150_config[] = { +// clang-format off + { + "base", "Address", CONFIG_HEX16, "", 0x0320, "", { 0 }, /*W2*/ { - "base", "Address", CONFIG_HEX16, "", 0x0320, "", { 0 }, /*W2*/ - { - { - "320H", 0x0320 - }, - { - "324H", 0x0324 - }, - { - "" - } - }, + { "320H", 0x0320 }, + { "324H", 0x0324 }, + { "" } }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, /*W3*/ { - "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, /*W3*/ - { - { - "IRQ 5", 5 - }, - { - "IRQ 4", 4 - }, - { - "" - } - }, + { "IRQ 5", 5 }, + { "IRQ 4", 4 }, + { "" } }, + }, + { + "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0xc8000, "", { 0 }, /*W1*/ { - "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0xc8000, "", { 0 }, /*W1*/ - { - { - "C800H", 0xc8000 - }, - { - "CA00H", 0xca000 - }, - { - "" - } - }, + { "C800H", 0xc8000 }, + { "CA00H", 0xca000 }, + { "" } }, - { - "", "", -1 - } + }, + { "", "", -1 } +// clang-format off }; - const device_t xta_wdxt150_device = { "WDXT-150 XTA Fixed Disk Controller", "xta_wdxt150", @@ -1162,7 +1143,6 @@ const device_t xta_wdxt150_device = { wdxt150_config }; - const device_t xta_hd20_device = { "EuroPC HD20 Fixed Disk Controller", "xta_hd20", diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 21c114d90..485b8925c 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -2381,9 +2381,6 @@ fdc_3f1_enable(fdc_t *fdc, int enable) fdc->enable_3f1 = enable; } - - - const device_t fdc_xt_device = { "PC/XT Floppy Drive Controller", "fdc_xt", diff --git a/src/floppy/fdc_magitronic.c b/src/floppy/fdc_magitronic.c index e0845ae7d..58679a5aa 100644 --- a/src/floppy/fdc_magitronic.c +++ b/src/floppy/fdc_magitronic.c @@ -112,23 +112,17 @@ static int b215_available(void) } static const device_config_t b215_config[] = { +// clang-format off { - "bios_addr", "BIOS Address:", CONFIG_HEX20, "", 0xca000, "", { 0 }, - { - { - "CA00H", 0xca000 - }, - { - "CC00H", 0xcc000 - }, - { - "" - } - } + "bios_addr", "BIOS Address:", CONFIG_HEX20, "", 0xca000, "", { 0 }, + { + { "CA00H", 0xca000 }, + { "CC00H", 0xcc000 }, + { "" } + } }, - { - "", "", -1 - } + { "", "", -1 } +// clang-format on }; const device_t fdc_b215_device = { diff --git a/src/floppy/fdc_pii15xb.c b/src/floppy/fdc_pii15xb.c index 661520e02..6ac6786c9 100644 --- a/src/floppy/fdc_pii15xb.c +++ b/src/floppy/fdc_pii15xb.c @@ -122,29 +122,19 @@ static int pii_158_available(void) } static const device_config_t pii_config[] = { +// clang-format off { - "bios_addr", "BIOS Address:", CONFIG_HEX20, "", 0xce000, "", { 0 }, - { - { - "Disabled", 0 - }, - { - "CA00H", 0xca000 - }, - { - "CC00H", 0xcc000 - }, - { - "CE00H", 0xce000 - }, - { - "" - } - } + "bios_addr", "BIOS Address:", CONFIG_HEX20, "", 0xce000, "", { 0 }, + { + { "Disabled", 0 }, + { "CA00H", 0xca000 }, + { "CC00H", 0xcc000 }, + { "CE00H", 0xce000 }, + { "" } + } }, - { - "", "", -1 - } + { "", "", -1 } +// clang-format on }; const device_t fdc_pii151b_device = { diff --git a/src/game/gameport.c b/src/game/gameport.c index cbd4ec4ba..d224e7baa 100644 --- a/src/game/gameport.c +++ b/src/game/gameport.c @@ -438,7 +438,6 @@ gameport_close(void *priv) free(dev); } - const device_t gameport_device = { "Game port", "gameport", diff --git a/src/lpt.c b/src/lpt.c index e2cb6ad5e..fa8fa458f 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -21,19 +21,20 @@ static const struct { const char *internal_name; const lpt_device_t *device; } lpt_devices[] = { - {"none", NULL}, - {"dss", &dss_device}, - {"lpt_dac", &lpt_dac_device}, - {"lpt_dac_stereo", &lpt_dac_stereo_device}, - {"text_prt", &lpt_prt_text_device}, - {"dot_matrix", &lpt_prt_escp_device}, - {"postscript", &lpt_prt_ps_device}, - {"plip", &lpt_plip_device}, - {"dongle_savquest", &lpt_hasp_savquest_device}, - {"", NULL} +// clang-format off + {"none", NULL }, + {"dss", &dss_device }, + {"lpt_dac", &lpt_dac_device }, + {"lpt_dac_stereo", &lpt_dac_stereo_device }, + {"text_prt", &lpt_prt_text_device }, + {"dot_matrix", &lpt_prt_escp_device }, + {"postscript", &lpt_prt_ps_device }, + {"plip", &lpt_plip_device }, + {"dongle_savquest", &lpt_hasp_savquest_device }, + {"", NULL } +// clang-format on }; - char * lpt_device_get_name(int id) { diff --git a/src/network/net_3c503.c b/src/network/net_3c503.c index acbc1ec04..7700c8039 100644 --- a/src/network/net_3c503.c +++ b/src/network/net_3c503.c @@ -636,111 +636,61 @@ threec503_nic_close(void *priv) } -static const device_config_t threec503_config[] = -{ +static const device_config_t threec503_config[] = { +// clang-format off { - "base", "Address", CONFIG_HEX16, "", 0x300, "", { 0 }, - { - { - "0x250", 0x250 - }, - { - "0x280", 0x280 - }, - { - "0x2a0", 0x2a0 - }, - { - "0x2e0", 0x2e0 - }, - { - "0x300", 0x300 - }, - { - "0x310", 0x310 - }, - { - "0x330", 0x330 - }, - { - "0x350", 0x350 - }, - { - "", 0 - } - }, + "base", "Address", CONFIG_HEX16, "", 0x300, "", { 0 }, + { + { "0x250", 0x250 }, + { "0x280", 0x280 }, + { "0x2a0", 0x2a0 }, + { "0x2e0", 0x2e0 }, + { "0x300", 0x300 }, + { "0x310", 0x310 }, + { "0x330", 0x330 }, + { "0x350", 0x350 }, + { "", 0 } + }, }, { - "irq", "IRQ", CONFIG_SELECTION, "", 3, "", { 0 }, - { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "", 0 - } - }, + "irq", "IRQ", CONFIG_SELECTION, "", 3, "", { 0 }, + { + { "IRQ 2", 2 }, + { "IRQ 3", 3 }, + { "IRQ 4", 4 }, + { "IRQ 5", 5 }, + { "", 0 } + }, }, { - "dma", "DMA", CONFIG_SELECTION, "", 3, "", { 0 }, - { - { - "DMA 1", 1 - }, - { - "DMA 2", 2 - }, - { - "DMA 3", 3 - }, - { - "", 0 - } - }, + "dma", "DMA", CONFIG_SELECTION, "", 3, "", { 0 }, + { + { "DMA 1", 1 }, + { "DMA 2", 2 }, + { "DMA 3", 3 }, + { "", 0 } + }, }, { - "mac", "MAC Address", CONFIG_MAC, "", -1, "", { 0 }, - { - { - "", 0 - } - }, + "mac", "MAC Address", CONFIG_MAC, "", -1, "", { 0 }, + { + { "", 0 } + }, }, { - "bios_addr", "BIOS address", CONFIG_HEX20, "", 0xCC000, "", { 0 }, - { - { - "DC00", 0xDC000 - }, - { - "D800", 0xD8000 - }, - { - "C800", 0xC8000 - }, - { - "CC00", 0xCC000 - }, - { - "", 0 - } - }, + "bios_addr", "BIOS address", CONFIG_HEX20, "", 0xCC000, "", { 0 }, + { + { "DC00", 0xDC000 }, + { "D800", 0xD8000 }, + { "C800", 0xC8000 }, + { "CC00", 0xCC000 }, + { "", 0 } + }, }, - { - "", "", -1 - } + { "", "", -1 } +// clang-format off }; - const device_t threec503_device = { "3Com EtherLink II", "3c503", diff --git a/src/network/net_dp8390.c b/src/network/net_dp8390.c index 28b6fd4bd..8e9b16f59 100644 --- a/src/network/net_dp8390.c +++ b/src/network/net_dp8390.c @@ -1111,11 +1111,10 @@ dp8390_close(void *priv) } -const device_t dp8390_device = -{ - "DP8390 Network Interface Controller", - "dp8390", - 0, 0, - dp8390_init, dp8390_close, - NULL, { NULL }, NULL, NULL +const device_t dp8390_device = { + "DP8390 Network Interface Controller", + "dp8390", + 0, 0, + dp8390_init, dp8390_close, + NULL, { NULL }, NULL, NULL }; diff --git a/src/network/net_ne2000.c b/src/network/net_ne2000.c index 1f75d21fc..a836d5d8a 100644 --- a/src/network/net_ne2000.c +++ b/src/network/net_ne2000.c @@ -1139,185 +1139,91 @@ nic_close(void *priv) free(dev); } - -static const device_config_t ne1000_config[] = -{ - { - "base", "Address", CONFIG_HEX16, "", 0x300, "", { 0 }, - { - { - "0x280", 0x280 - }, - { - "0x300", 0x300 - }, - { - "0x320", 0x320 - }, - { - "0x340", 0x340 - }, - { - "0x360", 0x360 - }, - { - "0x380", 0x380 - }, - { - "" - } - }, - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 3, "", { 0 }, - { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "" - } - }, - }, - { - "mac", "MAC Address", CONFIG_MAC, "", -1 - }, - { - "", "", -1 - } +// clang-format off +static const device_config_t ne1000_config[] = { + { + "base", "Address", CONFIG_HEX16, "", 0x300, "", { 0 }, + { + { "0x280", 0x280 }, + { "0x300", 0x300 }, + { "0x320", 0x320 }, + { "0x340", 0x340 }, + { "0x360", 0x360 }, + { "0x380", 0x380 }, + { "" } + }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 3, "", { 0 }, + { + { "IRQ 2", 2 }, + { "IRQ 3", 3 }, + { "IRQ 5", 5 }, + { "IRQ 7", 7 }, + { "IRQ 10", 10 }, + { "IRQ 11", 11 }, + { "" } + }, + }, + { "mac", "MAC Address", CONFIG_MAC, "", -1 }, + { "", "", -1 } }; -static const device_config_t ne2000_config[] = -{ - { - "base", "Address", CONFIG_HEX16, "", 0x300, "", { 0 }, - { - { - "0x280", 0x280 - }, - { - "0x300", 0x300 - }, - { - "0x320", 0x320 - }, - { - "0x340", 0x340 - }, - { - "0x360", 0x360 - }, - { - "0x380", 0x380 - }, - { - "" - } - }, - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 10, "", { 0 }, - { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "" - } - }, - }, - { - "mac", "MAC Address", CONFIG_MAC, "", -1 - }, - { - "bios_addr", "BIOS address", CONFIG_HEX20, "", 0, "", { 0 }, - { - { - "Disabled", 0x00000 - }, - { - "D000", 0xD0000 - }, - { - "D800", 0xD8000 - }, - { - "C800", 0xC8000 - }, - { - "" - } - }, - }, - { - "", "", -1 - } +static const device_config_t ne2000_config[] = { + { + "base", "Address", CONFIG_HEX16, "", 0x300, "", { 0 }, + { + { "0x280", 0x280 }, + { "0x300", 0x300 }, + { "0x320", 0x320 }, + { "0x340", 0x340 }, + { "0x360", 0x360 }, + { "0x380", 0x380 }, + { "" } + }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 10, "", { 0 }, + { + { "IRQ 2", 2 }, + { "IRQ 3", 3 }, + { "IRQ 5", 5 }, + { "IRQ 7", 7 }, + { "IRQ 10", 10 }, + { "IRQ 11", 11 }, + { "" } + }, + }, + { "mac", "MAC Address", CONFIG_MAC, "", -1 }, + { + "bios_addr", "BIOS address", CONFIG_HEX20, "", 0, "", { 0 }, + { + { "Disabled", 0x00000 }, + { "D000", 0xD0000 }, + { "D800", 0xD8000 }, + { "C800", 0xC8000 }, + { "" } + }, + }, + { "", "", -1 } }; -static const device_config_t rtl8019as_config[] = -{ - { - "mac", "MAC Address", CONFIG_MAC, "", -1 - }, - { - "", "", -1 - } +static const device_config_t rtl8019as_config[] = { + { "mac", "MAC Address", CONFIG_MAC, "", -1 }, + { "", "", -1 } }; -static const device_config_t rtl8029as_config[] = -{ - { - "bios", "Enable BIOS", CONFIG_BINARY, "", 0 - }, - { - "mac", "MAC Address", CONFIG_MAC, "", -1 - }, - { - "", "", -1 - } +static const device_config_t rtl8029as_config[] = { + { "bios", "Enable BIOS", CONFIG_BINARY, "", 0 }, + { "mac", "MAC Address", CONFIG_MAC, "", -1 }, + { "", "", -1 } }; -static const device_config_t mca_mac_config[] = -{ - { - "mac", "MAC Address", CONFIG_MAC, "", -1 - }, - { - "", "", -1 - } +static const device_config_t mca_mac_config[] = { + { "mac", "MAC Address", CONFIG_MAC, "", -1 }, + { "", "", -1 } }; - - +// clang-format on const device_t ne1000_device = { "Novell NE1000", diff --git a/src/network/net_pcnet.c b/src/network/net_pcnet.c index 6eee3d508..17049e2bf 100644 --- a/src/network/net_pcnet.c +++ b/src/network/net_pcnet.c @@ -3076,137 +3076,72 @@ pcnet_close(void *priv) } } - -static const device_config_t pcnet_pci_config[] = -{ - { - "mac", "MAC Address", CONFIG_MAC, "", -1 - }, - { - "", "", -1 - } +// clang-format off +static const device_config_t pcnet_pci_config[] = { + { "mac", "MAC Address", CONFIG_MAC, "", -1 }, + { "", "", -1 } }; - -static const device_config_t pcnet_isa_config[] = -{ - { - "base", "Address", CONFIG_HEX16, "", 0x300, "", { 0 }, - { - { - "0x300", 0x300 - }, - { - "0x320", 0x320 - }, - { - "0x340", 0x340 - }, - { - "0x360", 0x360 - }, - { - "" - } - }, - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 3, "", { 0 }, - { - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 9", 9 - }, - { - "" - } - }, - }, - { - "dma", "DMA channel", CONFIG_SELECTION, "", 5, "", { 0 }, - { - { - "DMA 3", 3 - }, - { - "DMA 5", 5 - }, - { - "DMA 6", 6 - }, - { - "DMA 7", 7 - }, - { - "" - } - }, - }, - { - "mac", "MAC Address", CONFIG_MAC, "", -1 - }, - { - "", "", -1 - } +static const device_config_t pcnet_isa_config[] = { + { + "base", "Address", CONFIG_HEX16, "", 0x300, "", { 0 }, + { + { "0x300", 0x300 }, + { "0x320", 0x320 }, + { "0x340", 0x340 }, + { "0x360", 0x360 }, + { "" } + }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 3, "", { 0 }, + { + { "IRQ 3", 3 }, + { "IRQ 4", 4 }, + { "IRQ 5", 5 }, + { "IRQ 9", 9 }, + { "" } + }, + }, + { + "dma", "DMA channel", CONFIG_SELECTION, "", 5, "", { 0 }, + { + { "DMA 3", 3 }, + { "DMA 5", 5 }, + { "DMA 6", 6 }, + { "DMA 7", 7 }, + { "" } + }, + }, + { "mac", "MAC Address", CONFIG_MAC, "", -1 }, + { "", "", -1 } }; -static const device_config_t pcnet_vlb_config[] = -{ - { - "base", "Address", CONFIG_HEX16, "", 0x300, "", { 0 }, - { - { - "0x300", 0x300 - }, - { - "0x320", 0x320 - }, - { - "0x340", 0x340 - }, - { - "0x360", 0x360 - }, - { - "" - } - }, - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 3, "", { 0 }, - { - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 9", 9 - }, - { - "" - } - }, - }, - { - "mac", "MAC Address", CONFIG_MAC, "", -1 - }, - { - "", "", -1 - } +static const device_config_t pcnet_vlb_config[] = { + { + "base", "Address", CONFIG_HEX16, "", 0x300, "", { 0 }, + { + { "0x300", 0x300 }, + { "0x320", 0x320 }, + { "0x340", 0x340 }, + { "0x360", 0x360 }, + { "" } + }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 3, "", { 0 }, + { + { "IRQ 3", 3 }, + { "IRQ 4", 4 }, + { "IRQ 5", 5 }, + { "IRQ 9", 9 }, + { "" } + }, + }, + { "mac", "MAC Address", CONFIG_MAC, "", -1 }, + { "", "", -1 } }; +// clang-format on const device_t pcnet_am79c960_device = { "AMD PCnet-ISA", diff --git a/src/network/net_wd8003.c b/src/network/net_wd8003.c index 3c6a5a059..90cbdea2e 100644 --- a/src/network/net_wd8003.c +++ b/src/network/net_wd8003.c @@ -735,335 +735,161 @@ wd_close(void *priv) free(dev); } - -static const device_config_t wd8003_config[] = -{ - { - "base", "Address", CONFIG_HEX16, "", 0x300, "", { 0 }, - { - { - "0x240", 0x240 - }, - { - "0x280", 0x280 - }, - { - "0x300", 0x300 - }, - { - "0x380", 0x380 - }, - { - "" - } - }, - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 3, "", { 0 }, - { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "" - } - }, - }, - { - "ram_addr", "RAM address", CONFIG_HEX20, "", 0xD0000, "", { 0 }, - { - { - "C800", 0xC8000 - }, - { - "CC00", 0xCC000 - }, - { - "D000", 0xD0000 - }, - { - "D400", 0xD4000 - }, - { - "D800", 0xD8000 - }, - { - "DC00", 0xDC000 - }, - { - "" - } - }, - }, - { - "mac", "MAC Address", CONFIG_MAC, "", -1 - }, - { - "", "", -1 - } +// clang-format off +static const device_config_t wd8003_config[] = { + { + "base", "Address", CONFIG_HEX16, "", 0x300, "", { 0 }, + { + { "0x240", 0x240 }, + { "0x280", 0x280 }, + { "0x300", 0x300 }, + { "0x380", 0x380 }, + { "" } + }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 3, "", { 0 }, + { + { "IRQ 2", 2 }, + { "IRQ 3", 3 }, + { "IRQ 5", 5 }, + { "IRQ 7", 7 }, + { "" } + }, + }, + { + "ram_addr", "RAM address", CONFIG_HEX20, "", 0xD0000, "", { 0 }, + { + { "C800", 0xC8000 }, + { "CC00", 0xCC000 }, + { "D000", 0xD0000 }, + { "D400", 0xD4000 }, + { "D800", 0xD8000 }, + { "DC00", 0xDC000 }, + { "" } + }, + }, + { "mac", "MAC Address", CONFIG_MAC, "", -1 }, + { "", "", -1 } }; -static const device_config_t wd8003eb_config[] = -{ - { - "base", "Address", CONFIG_HEX16, "", 0x280, "", { 0 }, - { - { - "0x200", 0x200 - }, - { - "0x220", 0x220 - }, - { - "0x240", 0x240 - }, - { - "0x260", 0x260 - }, - { - "0x280", 0x280 - }, - { - "0x2A0", 0x2A0 - }, - { - "0x2C0", 0x2C0 - }, - { - "0x300", 0x300 - }, - { - "0x340", 0x340 - }, - { - "0x380", 0x380 - }, - { - "" - } - }, - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 3, "", { 0 }, - { - { - "IRQ 2/9", 9 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 7", 7 - }, - { - "" - } - }, - }, - { - "ram_addr", "RAM address", CONFIG_HEX20, "", 0xD0000, "", { 0 }, - { - { - "C000", 0xC0000 - }, - { - "C400", 0xC4000 - }, - { - "C800", 0xC8000 - }, - { - "CC00", 0xCC000 - }, - { - "D000", 0xD0000 - }, - { - "D400", 0xD4000 - }, - { - "D800", 0xD8000 - }, - { - "DC00", 0xDC000 - }, - { - "" - } - }, - }, - { - "ram_size", "RAM size", CONFIG_SELECTION, "", 8192, "", { 0 }, - { - { - "8 kB", 8192 - }, - { - "32 kB", 32768 - }, - { - "" - } - }, - }, - { - "mac", "MAC Address", CONFIG_MAC, "", -1 - }, - { - "", "", -1 - } +static const device_config_t wd8003eb_config[] = { + { + "base", "Address", CONFIG_HEX16, "", 0x280, "", { 0 }, + { + { "0x200", 0x200 }, + { "0x220", 0x220 }, + { "0x240", 0x240 }, + { "0x260", 0x260 }, + { "0x280", 0x280 }, + { "0x2A0", 0x2A0 }, + { "0x2C0", 0x2C0 }, + { "0x300", 0x300 }, + { "0x340", 0x340 }, + { "0x380", 0x380 }, + { "" } + }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 3, "", { 0 }, + { + { "IRQ 2/9", 9 }, + { "IRQ 3", 3 }, + { "IRQ 4", 4 }, + { "IRQ 7", 7 }, + { "" } + }, + }, + { + "ram_addr", "RAM address", CONFIG_HEX20, "", 0xD0000, "", { 0 }, + { + { "C000", 0xC0000 }, + { "C400", 0xC4000 }, + { "C800", 0xC8000 }, + { "CC00", 0xCC000 }, + { "D000", 0xD0000 }, + { "D400", 0xD4000 }, + { "D800", 0xD8000 }, + { "DC00", 0xDC000 }, + { "" } + }, + }, + { + "ram_size", "RAM size", CONFIG_SELECTION, "", 8192, "", { 0 }, + { + { "8 kB", 8192 }, + { "32 kB", 32768 }, + { "" } + }, + }, + { "mac", "MAC Address", CONFIG_MAC, "", -1 }, + { "", "", -1 } }; /* WD8013EBT configuration and defaults set according to this site: http://www.stack.nl/~marcolz/network/wd80x3.html#WD8013EBT */ -static const device_config_t wd8013_config[] = -{ - { - "base", "Address", CONFIG_HEX16, "", 0x280, "", { 0 }, - { - { - "0x200", 0x200 - }, - { - "0x220", 0x220 - }, - { - "0x240", 0x240 - }, - { - "0x260", 0x260 - }, - { - "0x280", 0x280 - }, - { - "0x2A0", 0x2A0 - }, - { - "0x2C0", 0x2C0 - }, - { - "0x300", 0x300 - }, - { - "0x340", 0x340 - }, - { - "0x380", 0x380 - }, - { - "" - } - }, - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 3, "", { 0 }, - { - { - "IRQ 2/9", 9 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "IRQ 15", 15 - }, - { - "" - } - }, - }, - { - "ram_addr", "RAM address", CONFIG_HEX20, "", 0xD0000, "", { 0 }, - { - { - "C000", 0xC0000 - }, - { - "C400", 0xC4000 - }, - { - "C800", 0xC8000 - }, - { - "CC00", 0xCC000 - }, - { - "D000", 0xD0000 - }, - { - "D400", 0xD4000 - }, - { - "D800", 0xD8000 - }, - { - "DC00", 0xDC000 - }, - { - "" - } - }, - }, - { - "ram_size", "RAM size", CONFIG_SELECTION, "", 16384, "", { 0 }, - { - { - "16 kB", 16384 - }, - { - "64 kB", 65536 - }, - { - "" - } - }, - }, - { - "mac", "MAC Address", CONFIG_MAC, "", -1 - }, - { - "", "", -1 - } +static const device_config_t wd8013_config[] = { + { + "base", "Address", CONFIG_HEX16, "", 0x280, "", { 0 }, + { + { "0x200", 0x200 }, + { "0x220", 0x220 }, + { "0x240", 0x240 }, + { "0x260", 0x260 }, + { "0x280", 0x280 }, + { "0x2A0", 0x2A0 }, + { "0x2C0", 0x2C0 }, + { "0x300", 0x300 }, + { "0x340", 0x340 }, + { "0x380", 0x380 }, + { "" } + }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 3, "", { 0 }, + { + { "IRQ 2/9", 9 }, + { "IRQ 3", 3 }, + { "IRQ 4", 4 }, + { "IRQ 5", 5 }, + { "IRQ 7", 7 }, + { "IRQ 10", 10 }, + { "IRQ 11", 11 }, + { "IRQ 15", 15 }, + { "" } + }, + }, + { + "ram_addr", "RAM address", CONFIG_HEX20, "", 0xD0000, "", { 0 }, + { + { "C000", 0xC0000 }, + { "C400", 0xC4000 }, + { "C800", 0xC8000 }, + { "CC00", 0xCC000 }, + { "D000", 0xD0000 }, + { "D400", 0xD4000 }, + { "D800", 0xD8000 }, + { "DC00", 0xDC000 }, + { "" } + }, + }, + { + "ram_size", "RAM size", CONFIG_SELECTION, "", 16384, "", { 0 }, + { + { "16 kB", 16384 }, + { "64 kB", 65536 }, + { "" } + }, + }, + { "mac", "MAC Address", CONFIG_MAC, "", -1 }, + { "", "", -1 } }; -static const device_config_t mca_mac_config[] = -{ - { - "mac", "MAC Address", CONFIG_MAC, "", -1 - }, - { - "", "", -1 - } +static const device_config_t mca_mac_config[] = { + { "mac", "MAC Address", CONFIG_MAC, "", -1 }, + { "", "", -1 } }; - +// clang-format on const device_t wd8003e_device = { "Western Digital WD8003E", diff --git a/src/network/network.c b/src/network/network.c index 8caf11067..ea1ccdf46 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -81,26 +81,28 @@ static const device_t net_none_device = { static netcard_t net_cards[] = { - { &net_none_device, NULL }, - { &threec503_device, NULL }, - { &pcnet_am79c960_device, NULL }, - { &pcnet_am79c961_device, NULL }, - { &ne1000_device, NULL }, - { &ne2000_device, NULL }, - { &pcnet_am79c960_eb_device, NULL }, - { &rtl8019as_device, NULL }, - { &wd8003e_device, NULL }, - { &wd8003eb_device, NULL }, - { &wd8013ebt_device, NULL }, - { &plip_device, NULL }, - { ðernext_mc_device, NULL }, - { &wd8003eta_device, NULL }, - { &wd8003ea_device, NULL }, - { &pcnet_am79c973_device, NULL }, - { &pcnet_am79c970a_device, NULL }, - { &rtl8029as_device, NULL }, - { &pcnet_am79c960_vlb_device, NULL }, - { NULL, NULL } +// clang-format off + { &net_none_device, NULL }, + { &threec503_device, NULL }, + { &pcnet_am79c960_device, NULL }, + { &pcnet_am79c961_device, NULL }, + { &ne1000_device, NULL }, + { &ne2000_device, NULL }, + { &pcnet_am79c960_eb_device, NULL }, + { &rtl8019as_device, NULL }, + { &wd8003e_device, NULL }, + { &wd8003eb_device, NULL }, + { &wd8013ebt_device, NULL }, + { &plip_device, NULL }, + { ðernext_mc_device, NULL }, + { &wd8003eta_device, NULL }, + { &wd8003ea_device, NULL }, + { &pcnet_am79c973_device, NULL }, + { &pcnet_am79c970a_device, NULL }, + { &rtl8029as_device, NULL }, + { &pcnet_am79c960_vlb_device, NULL }, + { NULL, NULL } +// clang-format off }; diff --git a/src/network/pcap_if.c b/src/network/pcap_if.c index 53b3d8882..384b11746 100644 --- a/src/network/pcap_if.c +++ b/src/network/pcap_if.c @@ -69,12 +69,14 @@ static pcap_t *(*f_pcap_open_live)(const char *,int,int,int,char *); static int (*f_pcap_next_ex)(pcap_t*,struct pcap_pkthdr**,const unsigned char**); static void (*f_pcap_close)(pcap_t *); static dllimp_t pcap_imports[] = { - { "pcap_findalldevs", &f_pcap_findalldevs }, - { "pcap_freealldevs", &f_pcap_freealldevs }, - { "pcap_open_live", &f_pcap_open_live }, - { "pcap_next_ex", &f_pcap_next_ex }, - { "pcap_close", &f_pcap_close }, - { NULL, NULL }, +// clang-format off + { "pcap_findalldevs", &f_pcap_findalldevs }, + { "pcap_freealldevs", &f_pcap_freealldevs }, + { "pcap_open_live", &f_pcap_open_live }, + { "pcap_next_ex", &f_pcap_next_ex }, + { "pcap_close", &f_pcap_close }, + { NULL, NULL }, +// clang-format on }; diff --git a/src/printer/prt_cpmap.c b/src/printer/prt_cpmap.c index 605fe9fdc..2c1465878 100644 --- a/src/printer/prt_cpmap.c +++ b/src/printer/prt_cpmap.c @@ -553,21 +553,23 @@ static const struct { uint16_t code; const uint16_t *map; } maps[] = { - { 437, cp437Map }, - { 737, cp737Map }, - { 775, cp775Map }, - { 850, cp850Map }, - { 852, cp852Map }, - { 855, cp855Map }, - { 857, cp857Map }, - { 860, cp860Map }, - { 861, cp861Map }, - { 862, cp862Map }, - { 863, cp863Map }, - { 864, cp864Map }, - { 865, cp865Map }, - { 866, cp866Map }, - { -1, NULL } +// clang-format off + { 437, cp437Map }, + { 737, cp737Map }, + { 775, cp775Map }, + { 850, cp850Map }, + { 852, cp852Map }, + { 855, cp855Map }, + { 857, cp857Map }, + { 860, cp860Map }, + { 861, cp861Map }, + { 862, cp862Map }, + { 863, cp863Map }, + { 864, cp864Map }, + { 865, cp865Map }, + { 866, cp866Map }, + { -1, NULL } +// clang-format on }; diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index efb6d104f..fdc820a84 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -100,13 +100,15 @@ static int (GSDLLAPI *gsapi_init_with_args)(void *instance, int argc, char **ar static int (GSDLLAPI *gsapi_exit)(void *instance); static dllimp_t ghostscript_imports[] = { - { "gsapi_revision", &gsapi_revision }, - { "gsapi_new_instance", &gsapi_new_instance }, - { "gsapi_delete_instance", &gsapi_delete_instance }, - { "gsapi_set_arg_encoding", &gsapi_set_arg_encoding }, - { "gsapi_init_with_args", &gsapi_init_with_args }, - { "gsapi_exit", &gsapi_exit }, - { NULL, NULL } +// clang-format off + { "gsapi_revision", &gsapi_revision }, + { "gsapi_new_instance", &gsapi_new_instance }, + { "gsapi_delete_instance", &gsapi_delete_instance }, + { "gsapi_set_arg_encoding", &gsapi_set_arg_encoding }, + { "gsapi_init_with_args", &gsapi_init_with_args }, + { "gsapi_exit", &gsapi_exit }, + { NULL, NULL } +// clang-format on }; static void *ghostscript_handle = NULL; diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index 1c78473f9..ab94a57be 100644 --- a/src/scsi/scsi_aha154x.c +++ b/src/scsi/scsi_aha154x.c @@ -1138,366 +1138,186 @@ aha_init(const device_t *info) return(dev); } - +// clang-format off static const device_config_t aha_154xb_config[] = { + { + "base", "Address", CONFIG_HEX16, "", 0x334, "", { 0 }, { - "base", "Address", CONFIG_HEX16, "", 0x334, "", { 0 }, - { - { - "None", 0 - }, - { - "0x330", 0x330 - }, - { - "0x334", 0x334 - }, - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x130", 0x130 - }, - { - "0x134", 0x134 - }, - { - "" - } - }, + { "None", 0 }, + { "0x330", 0x330 }, + { "0x334", 0x334 }, + { "0x230", 0x230 }, + { "0x234", 0x234 }, + { "0x130", 0x130 }, + { "0x134", 0x134 }, + { "" } }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 11, "", { 0 }, { - "irq", "IRQ", CONFIG_SELECTION, "", 11, "", { 0 }, - { - { - "IRQ 9", 9 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "IRQ 12", 12 - }, - { - "IRQ 14", 14 - }, - { - "IRQ 15", 15 - }, - { - "" - } - }, + { "IRQ 9", 9 }, + { "IRQ 10", 10 }, + { "IRQ 11", 11 }, + { "IRQ 12", 12 }, + { "IRQ 14", 14 }, + { "IRQ 15", 15 }, + { "" } }, + }, + { + "dma", "DMA channel", CONFIG_SELECTION, "", 6, "", { 0 }, { - "dma", "DMA channel", CONFIG_SELECTION, "", 6, "", { 0 }, - { - { - "DMA 5", 5 - }, - { - "DMA 6", 6 - }, - { - "DMA 7", 7 - }, - { - "" - } - }, + { "DMA 5", 5 }, + { "DMA 6", 6 }, + { "DMA 7", 7 }, + { "" } }, + }, + { + "hostid", "Host ID", CONFIG_SELECTION, "", 7, "", { 0 }, { - "hostid", "Host ID", CONFIG_SELECTION, "", 7, "", { 0 }, - { - { - "0", 0 - }, - { - "1", 1 - }, - { - "2", 2 - }, - { - "3", 3 - }, - { - "4", 4 - }, - { - "5", 5 - }, - { - "6", 6 - }, - { - "7", 7 - }, - { - "" - } - }, + { "0", 0 }, + { "1", 1 }, + { "2", 2 }, + { "3", 3 }, + { "4", 4 }, + { "5", 5 }, + { "6", 6 }, + { "7", 7 }, + { "" } }, + }, + { + "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0, "", { 0 }, { - "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0, "", { 0 }, - { - { - "Disabled", 0 - }, - { - "C800H", 0xc8000 - }, - { - "D000H", 0xd0000 - }, - { - "D800H", 0xd8000 - }, - { - "DC00H", 0xdc000 - }, - { - "" - } - }, + { "Disabled", 0 }, + { "C800H", 0xc8000 }, + { "D000H", 0xd0000 }, + { "D800H", 0xd8000 }, + { "DC00H", 0xdc000 }, + { "" } }, - { - "", "", -1 - } + }, + { + "", "", -1 + } }; static const device_config_t aha_154x_config[] = { + { + "base", "Address", CONFIG_HEX16, "", 0x334, "", { 0 }, { - "base", "Address", CONFIG_HEX16, "", 0x334, "", { 0 }, - { - { - "None", 0 - }, - { - "0x330", 0x330 - }, - { - "0x334", 0x334 - }, - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x130", 0x130 - }, - { - "0x134", 0x134 - }, - { - "" - } - }, + { "None", 0 }, + { "0x330", 0x330 }, + { "0x334", 0x334 }, + { "0x230", 0x230 }, + { "0x234", 0x234 }, + { "0x130", 0x130 }, + { "0x134", 0x134 }, + { "" } }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 11, "", { 0 }, { - "irq", "IRQ", CONFIG_SELECTION, "", 11, "", { 0 }, - { - { - "IRQ 9", 9 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "IRQ 12", 12 - }, - { - "IRQ 14", 14 - }, - { - "IRQ 15", 15 - }, - { - "" - } - }, + { "IRQ 9", 9 }, + { "IRQ 10", 10 }, + { "IRQ 11", 11 }, + { "IRQ 12", 12 }, + { "IRQ 14", 14 }, + { "IRQ 15", 15 }, + { "" } }, + }, + { + "dma", "DMA channel", CONFIG_SELECTION, "", 6, "", { 0 }, { - "dma", "DMA channel", CONFIG_SELECTION, "", 6, "", { 0 }, - { - { - "DMA 5", 5 - }, - { - "DMA 6", 6 - }, - { - "DMA 7", 7 - }, - { - "" - } - }, + { "DMA 5", 5 }, + { "DMA 6", 6 }, + { "DMA 7", 7 }, + { "" } }, + }, + { + "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0, "", { 0 }, { - "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0, "", { 0 }, - { - { - "Disabled", 0 - }, - { - "C800H", 0xc8000 - }, - { - "D000H", 0xd0000 - }, - { - "D800H", 0xd8000 - }, - { - "DC00H", 0xdc000 - }, - { - "" - } - }, + { "Disabled", 0 }, + { "C800H", 0xc8000 }, + { "D000H", 0xd0000 }, + { "D800H", 0xd8000 }, + { "DC00H", 0xdc000 }, + { "" } + }, }, - { - "", "", -1 - } + { + "", "", -1 + } }; static const device_config_t aha_154xcf_config[] = { + { + "base", "Address", CONFIG_HEX16, "", 0x334, "", { 0 }, { - "base", "Address", CONFIG_HEX16, "", 0x334, "", { 0 }, - { - { - "None", 0 - }, - { - "0x330", 0x330 - }, - { - "0x334", 0x334 - }, - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x130", 0x130 - }, - { - "0x134", 0x134 - }, - { - "" - } - }, + { "None", 0 }, + { "0x330", 0x330 }, + { "0x334", 0x334 }, + { "0x230", 0x230 }, + { "0x234", 0x234 }, + { "0x130", 0x130 }, + { "0x134", 0x134 }, + { "" } }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 11, "", { 0 }, { - "irq", "IRQ", CONFIG_SELECTION, "", 11, "", { 0 }, - { - { - "IRQ 9", 9 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "IRQ 12", 12 - }, - { - "IRQ 14", 14 - }, - { - "IRQ 15", 15 - }, - { - "" - } - }, + { "IRQ 9", 9 }, + { "IRQ 10", 10 }, + { "IRQ 11", 11 }, + { "IRQ 12", 12 }, + { "IRQ 14", 14 }, + { "IRQ 15", 15 }, + { "" } }, + }, + { + "dma", "DMA channel", CONFIG_SELECTION, "", 6, "", { 0 }, { - "dma", "DMA channel", CONFIG_SELECTION, "", 6, "", { 0 }, - { - { - "DMA 5", 5 - }, - { - "DMA 6", 6 - }, - { - "DMA 7", 7 - }, - { - "" - } - }, + { "DMA 5", 5 }, + { "DMA 6", 6 }, + { "DMA 7", 7 }, + { "" } }, + }, + { + "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0, "", { 0 }, { - "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0, "", { 0 }, - { - { - "Disabled", 0 - }, - { - "C800H", 0xc8000 - }, - { - "CC00H", 0xcc000 - }, - { - "D000H", 0xd0000 - }, - { - "D400H", 0xd4000 - }, - { - "D800H", 0xd8000 - }, - { - "DC00H", 0xdc000 - }, - { - "" - } - }, + { "Disabled", 0 }, + { "C800H", 0xc8000 }, + { "CC00H", 0xcc000 }, + { "D000H", 0xd0000 }, + { "D400H", 0xd4000 }, + { "D800H", 0xd8000 }, + { "DC00H", 0xdc000 }, + { "" } }, - { + }, + { "fdc_addr", "FDC address", CONFIG_HEX16, "", 0, "", { 0 }, - { - { - "None", 0 - }, - { - "0x3f0", 0x3f0 - }, - { - "0x370", 0x370 - }, - { - "" - } - }, + { + { "None", 0 }, + { "0x3f0", 0x3f0 }, + { "0x370", 0x370 }, + { "" } }, - { - "", "", -1 - } + }, + { + "", "", -1 + } }; - +// clang-format on const device_t aha154xa_device = { "Adaptec AHA-154xA", diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index d6c0b69b5..84144383b 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -1802,111 +1802,59 @@ buslogic_init(const device_t *info) return(dev); } - +// clang-format off static const device_config_t BT_ISA_Config[] = { + { + "base", "Address", CONFIG_HEX16, "", 0x334, "", { 0 }, { - "base", "Address", CONFIG_HEX16, "", 0x334, "", { 0 }, - { - { - "0x330", 0x330 - }, - { - "0x334", 0x334 - }, - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x130", 0x130 - }, - { - "0x134", 0x134 - }, - { - "", 0 - } - }, + { "0x330", 0x330 }, + { "0x334", 0x334 }, + { "0x230", 0x230 }, + { "0x234", 0x234 }, + { "0x130", 0x130 }, + { "0x134", 0x134 }, + { "", 0 } }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 11, "", { 0 }, { - "irq", "IRQ", CONFIG_SELECTION, "", 11, "", { 0 }, - { - { - "IRQ 9", 9 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "IRQ 12", 12 - }, - { - "IRQ 14", 14 - }, - { - "IRQ 15", 15 - }, - { - "", 0 - } - }, + { "IRQ 9", 9 }, + { "IRQ 10", 10 }, + { "IRQ 11", 11 }, + { "IRQ 12", 12 }, + { "IRQ 14", 14 }, + { "IRQ 15", 15 }, + { "", 0 } }, + }, + { + "dma", "DMA channel", CONFIG_SELECTION, "", 6, "", { 0 }, { - "dma", "DMA channel", CONFIG_SELECTION, "", 6, "", { 0 }, - { - { - "DMA 5", 5 - }, - { - "DMA 6", 6 - }, - { - "DMA 7", 7 - }, - { - "", 0 - } - }, + { "DMA 5", 5 }, + { "DMA 6", 6 }, + { "DMA 7", 7 }, + { "", 0 } }, + }, + { + "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0, "", { 0 }, { - "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0, "", { 0 }, - { - { - "Disabled", 0 - }, - { - "C800H", 0xc8000 - }, - { - "D000H", 0xd0000 - }, - { - "D800H", 0xd8000 - }, - { - "", 0 - } - }, + { "Disabled", 0 }, + { "C800H", 0xc8000 }, + { "D000H", 0xd0000 }, + { "D800H", 0xd8000 }, + { "", 0 } }, - { - "", "", -1 - } + }, + { "", "", -1 } }; - static const device_config_t BT958D_Config[] = { - { - "bios", "Enable BIOS", CONFIG_BINARY, "", 0 - }, - { - "", "", -1 - } + { "bios", "Enable BIOS", CONFIG_BINARY, "", 0 }, + { "", "", -1 } }; +// clang-format on const device_t buslogic_542b_device = { "BusLogic BT-542B ISA", diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index 713e69f7b..394bb1907 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -1568,220 +1568,121 @@ t128_available(void) return(rom_present(T128_ROM)); } +// clang-format off static const device_config_t ncr5380_mmio_config[] = { + { + "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0xD8000, "", { 0 }, { - "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0xD8000, "", { 0 }, - { - { - "C800H", 0xc8000 - }, - { - "CC00H", 0xcc000 - }, - { - "D800H", 0xd8000 - }, - { - "DC00H", 0xdc000 - }, - { - "" - } - }, - + { "C800H", 0xc8000 }, + { "CC00H", 0xcc000 }, + { "D800H", 0xd8000 }, + { "DC00H", 0xdc000 }, + { "" } }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, { - "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, - { - { - "IRQ 3", 3 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "" - } - }, + { "IRQ 3", 3 }, + { "IRQ 5", 5 }, + { "IRQ 7", 7 }, + { "" } }, - { - "", "", -1 - } + }, + { "", "", -1 } }; static const device_config_t rancho_config[] = { + { + "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0xD8000, "", { 0 }, { - "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0xD8000, "", { 0 }, - { - { - "C800H", 0xc8000 - }, - { - "CC00H", 0xcc000 - }, - { - "D800H", 0xd8000 - }, - { - "DC00H", 0xdc000 - }, - { - "" - } - }, - + { "C800H", 0xc8000 }, + { "CC00H", 0xcc000 }, + { "D800H", 0xd8000 }, + { "DC00H", 0xdc000 }, + { "" } }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, { - "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, - { - { - "IRQ 3", 3 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "" - } - }, + { "IRQ 3", 3 }, + { "IRQ 5", 5 }, + { "IRQ 7", 7 }, + { "" } }, + }, + { + "bios_ver", "BIOS Version", CONFIG_SELECTION, "", 1, "", { 0 }, { - "bios_ver", "BIOS Version", CONFIG_SELECTION, "", 1, "", { 0 }, - { - { - "8.20R", 1 - }, - { - "8.10R", 0 - }, - { - "" - } - }, + { "8.20R", 1 }, + { "8.10R", 0 }, + { "" } }, - { - "", "", -1 - } + }, + { "", "", -1 } }; static const device_config_t t130b_config[] = { + { + "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0xD8000, "", { 0 }, { - "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0xD8000, "", { 0 }, - { - { - "Disabled", 0 - }, - { - "C800H", 0xc8000 - }, - { - "CC00H", 0xcc000 - }, - { - "D800H", 0xd8000 - }, - { - "DC00H", 0xdc000 - }, - { - "" - } - }, + { "Disabled", 0 }, + { "C800H", 0xc8000 }, + { "CC00H", 0xcc000 }, + { "D800H", 0xd8000 }, + { "DC00H", 0xdc000 }, + { "" } }, + }, + { + "base", "Address", CONFIG_HEX16, "", 0x0350, "", { 0 }, { - "base", "Address", CONFIG_HEX16, "", 0x0350, "", { 0 }, - { - { - "240H", 0x0240 - }, - { - "250H", 0x0250 - }, - { - "340H", 0x0340 - }, - { - "350H", 0x0350 - }, - { - "" - } - }, + { "240H", 0x0240 }, + { "250H", 0x0250 }, + { "340H", 0x0340 }, + { "350H", 0x0350 }, + { "" } }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, { - "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, - { - { - "IRQ 3", 3 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "" - } - }, + { "IRQ 3", 3 }, + { "IRQ 5", 5 }, + { "IRQ 7", 7 }, + { "" } }, - { - "", "", -1 - } + }, + { "", "", -1 } }; - static const device_config_t t128_config[] = { + { + "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0xD8000, "", { 0 }, { - "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0xD8000, "", { 0 }, - { - { - "C800H", 0xc8000 - }, - { - "CC00H", 0xcc000 - }, - { - "D800H", 0xd8000 - }, - { - "DC00H", 0xdc000 - }, - { - "" - } - }, + { "C800H", 0xc8000 }, + { "CC00H", 0xcc000 }, + { "D800H", 0xd8000 }, + { "DC00H", 0xdc000 }, + { "" } }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, { - "irq", "IRQ", CONFIG_SELECTION, "", 5, "", { 0 }, - { - { - "IRQ 3", 3 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "" - } - }, + { "IRQ 3", 3 }, + { "IRQ 5", 5 }, + { "IRQ 7", 7 }, + { "" } }, - { - "boot", "Enable Boot ROM", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 - } + }, + { + "boot", "Enable Boot ROM", CONFIG_BINARY, "", 1 + }, + { "", "", -1 } }; +// clang-format on const device_t scsi_lcs6821n_device = { diff --git a/src/scsi/scsi_ncr53c8xx.c b/src/scsi/scsi_ncr53c8xx.c index 919a4ef05..12439e4ee 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -2634,26 +2634,18 @@ ncr53c8xx_close(void *priv) } static const device_config_t ncr53c8xx_pci_config[] = { +// clang-format off + { + "bios", "BIOS", CONFIG_SELECTION, "", 1, "", { 0 }, { - "bios", "BIOS", CONFIG_SELECTION, "", 1, "", { 0 }, - { - { - "SDMS 4.x BIOS", 2 - }, - { - "SDMS 3.x BIOS", 1 - }, - { - "Disable BIOS", 0 - }, - { - "" - } - }, + { "SDMS 4.x BIOS", 2 }, + { "SDMS 3.x BIOS", 1 }, + { "Disable BIOS", 0 }, + { "" } }, - { - "", "", -1 - } + }, + { "", "", -1 } +// clang-format on }; diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index 41bbd65b9..aff95074e 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -2000,15 +2000,16 @@ esp_close(void *priv) static const device_config_t bios_enable_config[] = { - { - "bios", "Enable BIOS", CONFIG_BINARY, "", 0 - }, - { - "", "", -1 - } +// clang-format off + { + "bios", "Enable BIOS", CONFIG_BINARY, "", 0 + }, + { + "", "", -1 + } +// clang-format on }; - const device_t dc390_pci_device = { "Tekram DC-390 PCI", diff --git a/src/scsi/scsi_spock.c b/src/scsi/scsi_spock.c index 849b4c953..32ce2a812 100644 --- a/src/scsi/scsi_spock.c +++ b/src/scsi/scsi_spock.c @@ -1157,23 +1157,17 @@ spock_available(void) } static const device_config_t spock_rom_config[] = { +// clang-format off + { + "bios_ver", "BIOS Version", CONFIG_SELECTION, "", 1, "", { 0 }, { - "bios_ver", "BIOS Version", CONFIG_SELECTION, "", 1, "", { 0 }, - { - { - "1991 BIOS (>1GB)", 1 - }, - { - "1990 BIOS", 0 - }, - { - "" - } - }, + { "1991 BIOS (>1GB)", 1 }, + { "1990 BIOS", 0 }, + { "" } }, - { - "", "", -1 - } + }, + { "", "", -1 } +// clang-format on }; const device_t spock_device = diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index 2fac97885..26d2c9cfd 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -705,63 +705,47 @@ ati28800_force_redraw(void *priv) ati28800->svga.fullchange = changeframecount; } - -static const device_config_t ati28800_config[] = -{ +// clang-format off +static const device_config_t ati28800_config[] = { + { + "memory", "Memory size", CONFIG_SELECTION, "", 512, "", { 0 }, { - "memory", "Memory size", CONFIG_SELECTION, "", 512, "", { 0 }, - { - { - "256 kB", 256 - }, - { - "512 kB", 512 - }, - { - "1 MB", 1024 - }, - { - "" - } - } - }, - { - "", "", -1 + { "256 kB", 256 }, + { "512 kB", 512 }, + { "1 MB", 1024 }, + { "" } } + }, + { + "", "", -1 + } }; #if defined(DEV_BRANCH) && defined(USE_XL24) static const device_config_t ati28800_wonderxl_config[] = { + { + "memory", "Memory size", CONFIG_SELECTION, "", 512, "", { 0 }, { - "memory", "Memory size", CONFIG_SELECTION, "", 512, "", { 0 }, - { - { - "256 kB", 256 - }, - { - "512 kB", 512 - }, - { - "1 MB", 1024 - }, - { - "" - } - } - }, - { - "", "", -1 + { "256 kB", 256 }, + { "512 kB", 512 }, + { "1 MB", 1024 }, + { "" } } + }, + { + "", "", -1 + } }; #endif +// clang-format on const device_t ati28800_device = { "ATI 28800-5 (ATI VGA Charger)", "ati28800", DEVICE_ISA, - 0, + 0, ati28800_init, ati28800_close, NULL, { ati28800_available }, ati28800_speed_changed, @@ -774,12 +758,12 @@ const device_t ati28800k_device = "ATI Korean VGA", "ati28800k", DEVICE_ISA, - 0, + 0, ati28800k_init, ati28800_close, NULL, { ati28800k_available }, ati28800_speed_changed, ati28800_force_redraw, - ati28800_config + ati28800_config }; const device_t ati28800k_spc4620p_device = @@ -787,7 +771,7 @@ const device_t ati28800k_spc4620p_device = "ATI Korean VGA On-Board SPC-4620P", "ati28800k_spc4620p", DEVICE_ISA, - 1, + 1, ati28800k_init, ati28800_close, NULL, { NULL }, ati28800_speed_changed, @@ -799,7 +783,7 @@ const device_t ati28800k_spc6033p_device = "ATI Korean VGA On-Board SPC-6033P", "ati28800k_spc6033p", DEVICE_ISA, - 2, + 2, ati28800k_init, ati28800_close, NULL, { NULL }, ati28800_speed_changed, @@ -811,12 +795,12 @@ const device_t compaq_ati28800_device = "ATI 28800-5 (ATI VGA Wonder XL)", "compaq_ati28800", DEVICE_ISA, - VGAWONDERXL, + VGAWONDERXL, ati28800_init, ati28800_close, NULL, { compaq_ati28800_available }, ati28800_speed_changed, ati28800_force_redraw, - ati28800_config + ati28800_config }; #if defined(DEV_BRANCH) && defined(USE_XL24) @@ -825,11 +809,11 @@ const device_t ati28800_wonderxl24_device = "ATI-28800 (VGA Wonder XL24)", "ati28800w", DEVICE_ISA, - VGAWONDERXL24, + VGAWONDERXL24, ati28800_init, ati28800_close, NULL, { ati28800_wonderxl24_available }, ati28800_speed_changed, ati28800_force_redraw, - ati28800_wonderxl_config + ati28800_wonderxl_config }; #endif diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 1838ef5a7..032cb7e26 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -3441,75 +3441,65 @@ void mach64_force_redraw(void *p) mach64->svga.fullchange = changeframecount; } -static const device_config_t mach64gx_config[] = -{ +// clang-format off +static const device_config_t mach64gx_config[] = { + { + "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, { - "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, - { - { - "1 MB", 1 - }, - { - "2 MB", 2 - }, - { - "4 MB", 4 - }, - { - "" - } - } - }, - { - "", "", -1 + { "1 MB", 1 }, + { "2 MB", 2 }, + { "4 MB", 4 }, + { "" } } + }, + { + "", "", -1 + } }; -static const device_config_t mach64vt2_config[] = -{ +static const device_config_t mach64vt2_config[] = { + { + "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, { - "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, - { - { - "2 MB", 2 - }, - { - "4 MB", 4 - }, - { - "" - } - } - }, - { - "", "", -1 + { "2 MB", 2 }, + { "4 MB", 4 }, + { "" } } + }, + { + "", "", -1 + } }; +// clang-format on const device_t mach64gx_isa_device = { - "ATI Mach64GX ISA", - "mach64gx_isa", - DEVICE_AT | DEVICE_ISA, - 0, - mach64gx_init, mach64_close, NULL, - { mach64gx_isa_available }, - mach64_speed_changed, - mach64_force_redraw, - mach64gx_config + "ATI Mach64GX ISA", + "mach64gx_isa", + DEVICE_AT | DEVICE_ISA, + 0, + mach64gx_init, + mach64_close, + NULL, + { mach64gx_isa_available }, + mach64_speed_changed, + mach64_force_redraw, + mach64gx_config }; const device_t mach64gx_vlb_device = { - "ATI Mach64GX VLB", - "mach64gx_vlb", - DEVICE_VLB, - 0, - mach64gx_init, mach64_close, NULL, - { mach64gx_vlb_available }, - mach64_speed_changed, - mach64_force_redraw, - mach64gx_config + "ATI Mach64GX VLB", + "mach64gx_vlb", + DEVICE_VLB, + 0, + mach64gx_init, + mach64_close, + NULL, + { mach64gx_vlb_available }, + mach64_speed_changed, + mach64_force_redraw, + mach64gx_config }; const device_t mach64gx_pci_device = @@ -3517,7 +3507,7 @@ const device_t mach64gx_pci_device = "ATI Mach64GX PCI", "mach64gx_pci", DEVICE_PCI, - 0, + 0, mach64gx_init, mach64_close, NULL, { mach64gx_available }, mach64_speed_changed, @@ -3530,7 +3520,7 @@ const device_t mach64vt2_device = "ATI Mach64VT2", "mach64vt2", DEVICE_PCI, - 0, + 0, mach64vt2_init, mach64_close, NULL, { mach64vt2_available }, mach64_speed_changed, diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index e022e1a67..138d9d987 100644 --- a/src/video/vid_cga.c +++ b/src/video/vid_cga.c @@ -575,79 +575,54 @@ cga_speed_changed(void *p) cga_recalctimings(cga); } - -const device_config_t cga_config[] = -{ +// clang-format off +const device_config_t cga_config[] = { + { + "display_type", "Display type", CONFIG_SELECTION, "", CGA_RGB, "", { 0 }, { - "display_type", "Display type", CONFIG_SELECTION, "", CGA_RGB, "", { 0 }, - { - { - "RGB", CGA_RGB - }, - { - "Composite", CGA_COMPOSITE - }, - { - "" - } - } - }, - { - "composite_type", "Composite type", CONFIG_SELECTION, "", COMPOSITE_OLD, "", { 0 }, - { - { - "Old", COMPOSITE_OLD - }, - { - "New", COMPOSITE_NEW - }, - { - "" - } - } - }, - { - "rgb_type", "RGB type", CONFIG_SELECTION, "", 0, "", { 0 }, - { - { - "Color", 0 - }, - { - "Green Monochrome", 1 - }, - { - "Amber Monochrome", 2 - }, - { - "Gray Monochrome", 3 - }, - { - "Color (no brown)", 4 - }, - { - "" - } - } - }, - { - "snow_enabled", "Snow emulation", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 + { "RGB", CGA_RGB }, + { "Composite", CGA_COMPOSITE }, + { "" } } + }, + { + "composite_type", "Composite type", CONFIG_SELECTION, "", COMPOSITE_OLD, "", { 0 }, + { + { "Old", COMPOSITE_OLD }, + { "New", COMPOSITE_NEW }, + { "" } + } + }, + { + "rgb_type", "RGB type", CONFIG_SELECTION, "", 0, "", { 0 }, + { + { "Color", 0 }, + { "Green Monochrome", 1 }, + { "Amber Monochrome", 2 }, + { "Gray Monochrome", 3 }, + { "Color (no brown)", 4 }, + { "" } + } + }, + { + "snow_enabled", "Snow emulation", CONFIG_BINARY, "", 1 + }, + { + "", "", -1 + } }; +// clang-format on - -const device_t cga_device = -{ - "CGA", - "cga", - DEVICE_ISA, 0, - cga_standalone_init, - cga_close, - NULL, - { NULL }, - cga_speed_changed, - NULL, - cga_config +const device_t cga_device = { + "CGA", + "cga", + DEVICE_ISA, + 0, + cga_standalone_init, + cga_close, + NULL, + { NULL }, + cga_speed_changed, + NULL, + cga_config }; diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 99fb61980..8ee63fd18 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -4282,237 +4282,223 @@ gd54xx_force_redraw(void *p) gd54xx->svga.fullchange = changeframecount; } -static const device_config_t gd542x_config[] = -{ - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "512 KB", - .value = 512 - }, - { - .description = "1 MB", - .value = 1024 - }, - { - .description = "" - } - }, - .default_int = 512 +// clang-format off +static const device_config_t gd542x_config[] = { + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "512 KB", + .value = 512 + }, + { + .description = "1 MB", + .value = 1024 + }, + { + .description = "" + } }, - { - .type = -1 - } + .default_int = 512 + }, + { + .type = -1 + } }; -static const device_config_t gd5426_config[] = -{ - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "512 KB", - .value = 512 - }, - { - .description = "1 MB", - .value = 1024 - }, - { - .description = "2 MB", - .value = 2048 - }, - { - .description = "" - } - }, - .default_int = 2048 +static const device_config_t gd5426_config[] = { + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "512 KB", + .value = 512 + }, + { + .description = "1 MB", + .value = 1024 + }, + { + .description = "2 MB", + .value = 2048 + }, + { + .description = "" + } }, - { - .type = -1 - } + .default_int = 2048 + }, + { + .type = -1 + } }; -static const device_config_t gd5428_onboard_config[] = -{ - { - .name = "memory", - .description = "Onboard memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "512 KB", - .value = 512 - }, - { - .description = "1 MB", - .value = 1024 - }, - { - .description = "2 MB", - .value = 2048 - }, - { - .description = "" - } - }, - .default_int = 2048 +static const device_config_t gd5428_onboard_config[] = { + { + .name = "memory", + .description = "Onboard memory size", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "512 KB", + .value = 512 + }, + { + .description = "1 MB", + .value = 1024 + }, + { + .description = "2 MB", + .value = 2048 + }, + { + .description = "" + } }, - { - .type = -1 - } + .default_int = 2048 + }, + { + .type = -1 + } }; -static const device_config_t gd5429_config[] = -{ - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "" - } - }, - .default_int = 2 +static const device_config_t gd5429_config[] = { + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "1 MB", + .value = 1 + }, + { + .description = "2 MB", + .value = 2 + }, + { + .description = "" + } }, - { - .type = -1 - } + .default_int = 2 + }, + { + .type = -1 + } }; -static const device_config_t gd5440_onboard_config[] = -{ - { - .name = "memory", - .description = "Onboard memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "" - } - }, - .default_int = 2 +static const device_config_t gd5440_onboard_config[] = { + { + .name = "memory", + .description = "Onboard memory size", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "1 MB", + .value = 1 + }, + { + .description = "2 MB", + .value = 2 + }, + { + .description = "" + } }, - { - .type = -1 - } + .default_int = 2 + }, + { + .type = -1 + } }; -static const device_config_t gd5434_config[] = -{ - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 4 +static const device_config_t gd5434_config[] = { + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "1 MB", + .value = 1 + }, + { + .description = "2 MB", + .value = 2 + }, + { + .description = "4 MB", + .value = 4 + }, + { + .description = "" + } }, - { - .type = -1 - } + .default_int = 4 + }, + { + .type = -1 + } }; -static const device_config_t gd5434_onboard_config[] = -{ - { - .name = "memory", - .description = "Onboard memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 4 +static const device_config_t gd5434_onboard_config[] = { + { + .name = "memory", + .description = "Onboard memory size", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "1 MB", + .value = 1 + }, + { + .description = "2 MB", + .value = 2 + }, + { + .description = "4 MB", + .value = 4 + }, + { + .description = "" + } }, - { - .type = -1 - } + .default_int = 4 + }, + { + .type = -1 + } }; -static const device_config_t gd5480_config[] = -{ - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 4 +static const device_config_t gd5480_config[] = { + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "2 MB", + .value = 2 + }, + { + .description = "4 MB", + .value = 4 + }, + { + .description = "" + } }, - { - .type = -1 - } + .default_int = 4 + }, + { + .type = -1 + } }; +// clang-format on const device_t gd5401_isa_device = { diff --git a/src/video/vid_colorplus.c b/src/video/vid_colorplus.c index 3b51beb60..ee9d10eb3 100644 --- a/src/video/vid_colorplus.c +++ b/src/video/vid_colorplus.c @@ -427,53 +427,40 @@ void colorplus_speed_changed(void *p) cga_recalctimings(&colorplus->cga); } -static const device_config_t colorplus_config[] = -{ + +static const device_config_t colorplus_config[] = { +// clang-format off + { + "display_type", "Display type", CONFIG_SELECTION, "", CGA_RGB, "", { 0 }, { - "display_type", "Display type", CONFIG_SELECTION, "", CGA_RGB, "", { 0 }, - { - { - "RGB", CGA_RGB - }, - { - "Composite", CGA_COMPOSITE - }, - { - "" - } - } - }, - { - "composite_type", "Composite type", CONFIG_SELECTION, "", COMPOSITE_OLD, "", { 0 }, - { - { - "Old", COMPOSITE_OLD - }, - { - "New", COMPOSITE_NEW - }, - { - "" - } - } - }, - { - "snow_enabled", "Snow emulation", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 + { "RGB", CGA_RGB }, + { "Composite", CGA_COMPOSITE }, + { "" } } + }, + { + "composite_type", "Composite type", CONFIG_SELECTION, "", COMPOSITE_OLD, "", { 0 }, + { + { "Old", COMPOSITE_OLD }, + { "New", COMPOSITE_NEW }, + { "" } + } + }, + { "snow_enabled", "Snow emulation", CONFIG_BINARY, "", 1 }, + { "", "", -1 } +// clang-format on }; const device_t colorplus_device = { - "Colorplus", - "plantronics", - DEVICE_ISA, 0, - colorplus_standalone_init, - colorplus_close, - NULL, { NULL }, - colorplus_speed_changed, - NULL, - colorplus_config + "Colorplus", + "plantronics", + DEVICE_ISA, 0, + colorplus_standalone_init, + colorplus_close, + NULL, + { NULL }, + colorplus_speed_changed, + NULL, + colorplus_config }; diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index b6ed063e9..4969cdfed 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -1176,71 +1176,61 @@ ega_speed_changed(void *p) 0 = Switch closed (ON); 1 = Switch open (OFF). */ -static const device_config_t ega_config[] = -{ +static const device_config_t ega_config[] = { +// clang-format off + { + "memory", "Memory size", CONFIG_SELECTION, "", 256, "", { 0 }, { - "memory", "Memory size", CONFIG_SELECTION, "", 256, "", { 0 }, - { - { - "32 kB", 32 - }, - { - "64 kB", 64 - }, - { - "128 kB", 128 - }, - { - "256 kB", 256 - }, - { - "" - } - } - }, - { - .name = "monitor_type", - .description = "Monitor type", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Monochrome (5151/MDA) (white)", - .value = 0x0B | (DISPLAY_WHITE << 4) - }, - { - .description = "Monochrome (5151/MDA) (green)", - .value = 0x0B | (DISPLAY_GREEN << 4) - }, - { - .description = "Monochrome (5151/MDA) (amber)", - .value = 0x0B | (DISPLAY_AMBER << 4) - }, - { - .description = "Color 40x25 (5153/CGA)", - .value = 0x06 - }, - { - .description = "Color 80x25 (5153/CGA)", - .value = 0x07 - }, - { - .description = "Enhanced Color - Normal Mode (5154/ECD)", - .value = 0x08 - }, - { - .description = "Enhanced Color - Enhanced Mode (5154/ECD)", - .value = 0x09 - }, - { - .description = "" - } - }, - .default_int = 9 - }, - { - .type = -1 + { "32 kB", 32 }, + { "64 kB", 64 }, + { "128 kB", 128 }, + { "256 kB", 256 }, + { "" } } + }, + { + .name = "monitor_type", + .description = "Monitor type", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "Monochrome (5151/MDA) (white)", + .value = 0x0B | (DISPLAY_WHITE << 4) + }, + { + .description = "Monochrome (5151/MDA) (green)", + .value = 0x0B | (DISPLAY_GREEN << 4) + }, + { + .description = "Monochrome (5151/MDA) (amber)", + .value = 0x0B | (DISPLAY_AMBER << 4) + }, + { + .description = "Color 40x25 (5153/CGA)", + .value = 0x06 + }, + { + .description = "Color 80x25 (5153/CGA)", + .value = 0x07 + }, + { + .description = "Enhanced Color - Normal Mode (5154/ECD)", + .value = 0x08 + }, + { + .description = "Enhanced Color - Enhanced Mode (5154/ECD)", + .value = 0x09 + }, + { + .description = "" + } + }, + .default_int = 9 + }, + { + .type = -1 + } +// clang-format on }; @@ -1249,7 +1239,7 @@ const device_t ega_device = "EGA", "ega", DEVICE_ISA, - EGA_IBM, + EGA_IBM, ega_standalone_init, ega_close, NULL, { ega_standalone_available }, ega_speed_changed, @@ -1262,7 +1252,7 @@ const device_t cpqega_device = "Compaq EGA", "compaq_ega", DEVICE_ISA, - EGA_COMPAQ, + EGA_COMPAQ, ega_standalone_init, ega_close, NULL, { cpqega_standalone_available }, ega_speed_changed, @@ -1275,7 +1265,7 @@ const device_t sega_device = "SuperEGA", "superega", DEVICE_ISA, - EGA_SUPEREGA, + EGA_SUPEREGA, ega_standalone_init, ega_close, NULL, { sega_standalone_available }, ega_speed_changed, @@ -1288,7 +1278,7 @@ const device_t atiega_device = "ATI EGA Wonder 800+", "egawonder800", DEVICE_ISA, - EGA_ATI, + EGA_ATI, ega_standalone_init, ega_close, NULL, { atiega_standalone_available }, ega_speed_changed, @@ -1301,7 +1291,7 @@ const device_t iskra_ega_device = "Iskra EGA (Cyrillic ROM)", "iskra_ega", DEVICE_ISA, - EGA_ISKRA, + EGA_ISKRA, ega_standalone_init, ega_close, NULL, { iskra_ega_standalone_available }, ega_speed_changed, @@ -1314,7 +1304,7 @@ const device_t et2000_device = "Tseng Labs ET2000", "et2000", DEVICE_ISA, - EGA_TSENG, + EGA_TSENG, ega_standalone_init, ega_close, NULL, { et2000_standalone_available }, ega_speed_changed, diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 0254a8509..e443ae517 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -804,28 +804,19 @@ et4000_kasan_available(void) rom_present(KASAN_FONT_ROM_PATH); } -static const device_config_t et4000_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 1024, "", { 0 }, - { - { - "256 KB", 256 - }, - { - "512 KB", 512 - }, - { - "1 MB", 1024 - }, - { - "" - } - } - }, - { - "", "", -1 - } +static const device_config_t et4000_config[] = { +// clang-format off + { + "memory", "Memory size", CONFIG_SELECTION, "", 1024, "", { 0 }, + { + { "256 KB", 256 }, + { "512 KB", 512 }, + { "1 MB", 1024 }, + { "" } + } + }, + { "", "", -1 } +// clang-format on }; const device_t et4000_isa_device = { diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index dfc0c242e..ccae1d869 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -2191,25 +2191,18 @@ et4000w32p_force_redraw(void *p) } -static const device_config_t et4000w32p_config[] = -{ +static const device_config_t et4000w32p_config[] = { +// clang-format off + { + "memory", "Memory size", CONFIG_SELECTION, "", 2, "", { 0 }, { - "memory", "Memory size", CONFIG_SELECTION, "", 2, "", { 0 }, - { - { - "1 MB", 1 - }, - { - "2 MB", 2 - }, - { - "" - } - } - }, - { - "", "", -1 + { "1 MB", 1 }, + { "2 MB", 2 }, + { "" } } + }, + { "", "", -1 } +// clang-format on }; diff --git a/src/video/vid_genius.c b/src/video/vid_genius.c index 847730ac8..db89eebc0 100644 --- a/src/video/vid_genius.c +++ b/src/video/vid_genius.c @@ -797,6 +797,6 @@ const device_t genius_device = genius_init, genius_close, NULL, { genius_available }, genius_speed_changed, - NULL, + NULL, NULL }; diff --git a/src/video/vid_hercules.c b/src/video/vid_hercules.c index ce9cf0349..923f0d874 100644 --- a/src/video/vid_hercules.c +++ b/src/video/vid_hercules.c @@ -610,32 +610,20 @@ speed_changed(void *priv) static const device_config_t hercules_config[] = { +// clang-format off { - "rgb_type", "Display type", CONFIG_SELECTION, "", 0, "", { 0 }, - { - { - "Default", 0 - }, - { - "Green", 1 - }, - { - "Amber", 2 - }, - { - "Gray", 3 - }, - { - "" - } - } + "rgb_type", "Display type", CONFIG_SELECTION, "", 0, "", { 0 }, + { + { "Default", 0 }, + { "Green", 1 }, + { "Amber", 2 }, + { "Gray", 3 }, + { "" } + } }, - { - "blend", "Blend", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 - } + { "blend", "Blend", CONFIG_BINARY, "", 1 }, + { "", "", -1 } +// clang-format on }; const device_t hercules_device = { diff --git a/src/video/vid_herculesplus.c b/src/video/vid_herculesplus.c index 8c95c6734..21f8642ba 100644 --- a/src/video/vid_herculesplus.c +++ b/src/video/vid_herculesplus.c @@ -695,32 +695,20 @@ speed_changed(void *priv) static const device_config_t herculesplus_config[] = { +// clang-format off { - "rgb_type", "Display type", CONFIG_SELECTION, "", 0, "", { 0 }, - { - { - "Default", 0 - }, - { - "Green", 1 - }, - { - "Amber", 2 - }, - { - "Gray", 3 - }, - { - "" - } - } + "rgb_type", "Display type", CONFIG_SELECTION, "", 0, "", { 0 }, + { + { "Default", 0 }, + { "Green", 1 }, + { "Amber", 2 }, + { "Gray", 3 }, + { "" } + } }, - { - "blend", "Blend", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 - } + { "blend", "Blend", CONFIG_BINARY, "", 1 }, + { "", "", -1 } +// clang-format on }; const device_t herculesplus_device = { diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index c65cde149..58a3a1a73 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -1622,74 +1622,45 @@ ht216_force_redraw(void *p) } -static const device_config_t v7_vga_1024i_config[] = -{ +static const device_config_t v7_vga_1024i_config[] = { + { + "memory", "Memory size", CONFIG_SELECTION, "", 512, "", { 0 }, { - "memory", "Memory size", CONFIG_SELECTION, "", 512, "", { 0 }, - { - { - "256 kB", 256 - }, - { - "512 kB", 512 - }, - { - "" - } - } - }, - { - "", "", -1 + { "256 kB", 256 }, + { "512 kB", 512 }, + { "" } } + }, + { "", "", -1 } }; -static const device_config_t ht216_32_standalone_config[] = -{ +// clang-format off +static const device_config_t ht216_32_standalone_config[] = { + { + "monitor_type", "Monitor type", CONFIG_SELECTION, "", 0x18, "", { 0 }, { - "monitor_type", "Monitor type", CONFIG_SELECTION, "", 0x18, "", { 0 }, - { - { - "Mono Interlaced", 0x00 - }, - { - "Mono Non-Interlaced", 0x08 - }, - { - "Color Interlaced", 0x10 - }, - { - "Color Non-Interlaced", 0x18 - }, - { - "" - } - } - }, - { - "", "", -1 + { "Mono Interlaced", 0x00 }, + { "Mono Non-Interlaced", 0x08 }, + { "Color Interlaced", 0x10 }, + { "Color Non-Interlaced", 0x18 }, + { "" } } + }, + { "", "", -1 } }; -static const device_config_t radius_svga_multiview_config[] = -{ +static const device_config_t radius_svga_multiview_config[] = { + { + "extensions", "Extensions", CONFIG_SELECTION, "", 0x00, "", { 0 }, { - "extensions", "Extensions", CONFIG_SELECTION, "", 0x00, "", { 0 }, - { - { - "Extensions Enabled", 0x00 - }, - { - "Extensions Disabled", 0x02 - }, - { - "" - } - } - }, - { - "", "", -1 + { "Extensions Enabled", 0x00 }, + { "Extensions Disabled", 0x02 }, + { "" } } + }, + { "", "", -1 } }; +// clang-format on const device_t g2_gc205_device = { diff --git a/src/video/vid_ibm_rgb528_ramdac.c b/src/video/vid_ibm_rgb528_ramdac.c index 8dae60f23..4e736ee8e 100644 --- a/src/video/vid_ibm_rgb528_ramdac.c +++ b/src/video/vid_ibm_rgb528_ramdac.c @@ -954,11 +954,10 @@ ibm_rgb528_ramdac_close(void *priv) } -const device_t ibm_rgb528_ramdac_device = -{ - "IBM RGB528 RAMDAC", - "ibm_rgb528_ramdac", - 0, 0, - ibm_rgb528_ramdac_init, ibm_rgb528_ramdac_close, - NULL, { NULL }, NULL, NULL, NULL +const device_t ibm_rgb528_ramdac_device = { + "IBM RGB528 RAMDAC", + "ibm_rgb528_ramdac", + 0, 0, + ibm_rgb528_ramdac_init, ibm_rgb528_ramdac_close, + NULL, { NULL }, NULL, NULL, NULL }; diff --git a/src/video/vid_mda.c b/src/video/vid_mda.c index fed92c1f5..fba6257fa 100644 --- a/src/video/vid_mda.c +++ b/src/video/vid_mda.c @@ -327,36 +327,23 @@ void mda_speed_changed(void *p) mda_recalctimings(mda); } -static const device_config_t mda_config[] = -{ +static const device_config_t mda_config[] = { +// clang-format off + { + "rgb_type", "Display type", CONFIG_SELECTION, "", 0, "", { 0 }, { - "rgb_type", "Display type", CONFIG_SELECTION, "", 0, "", { 0 }, - { - { - "Default", 0 - }, - { - "Green", 1 - }, - { - "Amber", 2 - }, - { - "Gray", 3 - }, - { - "" - } - } - }, - { - "", "", -1 + { "Default", 0 }, + { "Green", 1 }, + { "Amber", 2 }, + { "Gray", 3 }, + { "" } } + }, + { "", "", -1 } +// clang-format on }; - -const device_t mda_device = -{ +const device_t mda_device = { "MDA", "mda", DEVICE_ISA, 0, @@ -364,5 +351,5 @@ const device_t mda_device = { NULL }, mda_speed_changed, NULL, - mda_config + mda_config }; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index f81baf596..836be2011 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5337,35 +5337,34 @@ mystique_force_redraw(void *p) } -static const device_config_t mystique_config[] = -{ +static const device_config_t mystique_config[] = { +// clang-format off { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "8 MB", - .value = 8 - }, - { - .description = "" - } - }, - .default_int = 8 + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "2 MB", + .value = 2 + }, + { + .description = "4 MB", + .value = 4 + }, + { + .description = "8 MB", + .value = 8 + }, + { + .description = "" + } + }, + .default_int = 8 }, - { - .type = -1 - } + { .type = -1 } +// clang-format on }; const device_t millennium_device = diff --git a/src/video/vid_nga.c b/src/video/vid_nga.c index 927a63c12..abacd10bb 100644 --- a/src/video/vid_nga.c +++ b/src/video/vid_nga.c @@ -599,76 +599,45 @@ nga_init(const device_t *info) } -const device_config_t nga_config[] = -{ +const device_config_t nga_config[] = { +// clang-format off + { + "rgb_type", "RGB type", CONFIG_SELECTION, "", 0, "", { 0 }, { - "rgb_type", "RGB type", CONFIG_SELECTION, "", 0, "", { 0 }, - { - { - "Color", 0 - }, - { - "Green Monochrome", 1 - }, - { - "Amber Monochrome", 2 - }, - { - "Gray Monochrome", 3 - }, - { - "Color (no brown)", 4 - }, - { - "" - } - } - }, - { - "snow_enabled", "Snow emulation", CONFIG_BINARY, "", 1 - }, - { - "memory", "Memory size", CONFIG_SELECTION, "", 64, "", { 0 }, - { - { - "32 KB", 32 - }, - { - "64 KB", 64 - }, - { - "" - } - } - }, - { - "charset", "Character set", CONFIG_SELECTION, "", 0, "", { 0 }, - { - { - "U.S. English", 0 - }, - { - "Scandinavian", 1 - }, - { - "Other languages", 2 - }, - { - "E.F. Hutton", 3 - }, - { - "" - } - } - }, - { - "", "", -1 + { "Color", 0 }, + { "Green Monochrome", 1 }, + { "Amber Monochrome", 2 }, + { "Gray Monochrome", 3 }, + { "Color (no brown)", 4 }, + { "" } } + }, + { + "snow_enabled", "Snow emulation", CONFIG_BINARY, "", 1 + }, + { + "memory", "Memory size", CONFIG_SELECTION, "", 64, "", { 0 }, + { + { "32 KB", 32 }, + { "64 KB", 64 }, + { "" } + } + }, + { + "charset", "Character set", CONFIG_SELECTION, "", 0, "", { 0 }, + { + { "U.S. English", 0 }, + { "Scandinavian", 1 }, + { "Other languages", 2 }, + { "E.F. Hutton", 3 }, + { "" } + } + }, + { "", "", -1 } +// clang-format on }; - -const device_t nga_device = -{ +const device_t nga_device = { "NCR NGA", "nga", DEVICE_ISA, 0, diff --git a/src/video/vid_oak_oti.c b/src/video/vid_oak_oti.c index 0902d33ee..956c07781 100644 --- a/src/video/vid_oak_oti.c +++ b/src/video/vid_oak_oti.c @@ -495,82 +495,52 @@ static int oti067_m300_available(void) { if (rom_present(BIOS_067_M300_15_PATH)) - return(rom_present(BIOS_067_M300_15_PATH)); - else - return(rom_present(BIOS_067_M300_08_PATH)); + return(rom_present(BIOS_067_M300_15_PATH)); + else + return(rom_present(BIOS_067_M300_08_PATH)); } -static const device_config_t oti067_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 512, "", { 0 }, - { - { - "256 kB", 256 - }, - { - "512 kB", 512 - }, - { - "" - } - } - }, - { - "", "", -1 - } +// clang-format off +static const device_config_t oti067_config[] = { + { + "memory", "Memory size", CONFIG_SELECTION, "", 512, "", { 0 }, + { + { "256 kB", 256 }, + { "512 kB", 512 }, + { "" } + } + }, + { "", "", -1 } }; - -static const device_config_t oti067_ama932j_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 256, "", { 0 }, - { - { - "256 kB", 256 - }, - { - "512 kB", 512 - }, - { - "" - } - } - }, - { - "", "", -1 - } +static const device_config_t oti067_ama932j_config[] = { + { + "memory", "Memory size", CONFIG_SELECTION, "", 256, "", { 0 }, + { + { "256 kB", 256 }, + { "512 kB", 512 }, + { "" } + } + }, + { "", "", -1 } }; - -static const device_config_t oti077_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 1024, "", { 0 }, - { - { - "256 kB", 256 - }, - { - "512 kB", 512 - }, - { - "1 MB", 1024 - }, - { - "" - } - } - }, - { - "", "", -1 - } +static const device_config_t oti077_config[] = { + { + "memory", "Memory size", CONFIG_SELECTION, "", 1024, "", { 0 }, + { + { "256 kB", 256 }, + { "512 kB", 512 }, + { "1 MB", 1024 }, + { "" } + } + }, + { "", "", -1 } }; +// clang-format on -const device_t oti037c_device = -{ +const device_t oti037c_device = { "Oak OTI-037C", "oti037c", DEVICE_ISA, @@ -581,8 +551,7 @@ const device_t oti037c_device = oti_force_redraw }; -const device_t oti067_device = -{ +const device_t oti067_device = { "Oak OTI-067", "oti067", DEVICE_ISA, @@ -594,8 +563,7 @@ const device_t oti067_device = oti067_config }; -const device_t oti067_m300_device = -{ +const device_t oti067_m300_device = { "Oak OTI-067 (Olivetti M300-08/15)", "oti067_m300", DEVICE_ISA, @@ -607,8 +575,7 @@ const device_t oti067_m300_device = oti067_config }; -const device_t oti067_ama932j_device = -{ +const device_t oti067_ama932j_device = { "Oak OTI-067 (AMA-932J)", "oti067_ama932j", DEVICE_ISA, @@ -620,8 +587,7 @@ const device_t oti067_ama932j_device = oti067_ama932j_config }; -const device_t oti077_device = -{ +const device_t oti077_device = { "Oak OTI-077", "oti077", DEVICE_ISA, diff --git a/src/video/vid_ogc.c b/src/video/vid_ogc.c index 8da375ef2..05ad26222 100644 --- a/src/video/vid_ogc.c +++ b/src/video/vid_ogc.c @@ -635,36 +635,22 @@ ogc_init(const device_t *info) return ogc; } - -const device_config_t ogc_m24_config[] = -{ +const device_config_t ogc_m24_config[] = { +// clang-format off + { + /* Olivetti / ATT compatible displays */ + "rgb_type", "RGB type", CONFIG_SELECTION, "", CGA_RGB, "", { 0 }, { - /* Olivetti / ATT compatible displays */ - "rgb_type", "RGB type", CONFIG_SELECTION, "", CGA_RGB, "", { 0 }, - { - { - "Color", 0 - }, - { - "Green Monochrome", 1 - }, - { - "Amber Monochrome", 2 - }, - { - "Gray Monochrome", 3 - }, - { - "" - } - } - }, - { - "snow_enabled", "Snow emulation", CONFIG_BINARY, "", 1, - }, - { - "", "", -1 + { "Color", 0 }, + { "Green Monochrome", 1 }, + { "Amber Monochrome", 2 }, + { "Gray Monochrome", 3 }, + { "" } } + }, + { "snow_enabled", "Snow emulation", CONFIG_BINARY, "", 1, }, + { "", "", -1 } +// clang-format on }; const device_t ogc_m24_device = diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index 1042440b6..3fc5f5de2 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -826,25 +826,18 @@ const device_t paradise_wd90c11_device = NULL }; -static const device_config_t paradise_wd90c30_config[] = -{ +static const device_config_t paradise_wd90c30_config[] = { +// clang-format off + { + "memory", "Memory size", CONFIG_SELECTION, "", 1024, "", { 0 }, { - "memory", "Memory size", CONFIG_SELECTION, "", 1024, "", { 0 }, - { - { - "512 kB", 512 - }, - { - "1 MB", 1024 - }, - { - "" - } - } - }, - { - "", "", -1 + { "512 kB", 512 }, + { "1 MB", 1024 }, + { "" } } + }, + { "", "", -1 } +// clang-format on }; const device_t paradise_wd90c30_device = diff --git a/src/video/vid_rtg310x.c b/src/video/vid_rtg310x.c index 18f577719..ec3275487 100644 --- a/src/video/vid_rtg310x.c +++ b/src/video/vid_rtg310x.c @@ -358,28 +358,19 @@ rtg_available(void) return rom_present(BIOS_ROM_PATH); } -static const device_config_t rtg_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 1024, "", { 0 }, - { - { - "256 KB", 256 - }, - { - "512 KB", 512 - }, - { - "1 MB", 1024 - }, - { - "" - } - } - }, - { - "", "", -1 - } +static const device_config_t rtg_config[] = { +// clang-format off + { + "memory", "Memory size", CONFIG_SELECTION, "", 1024, "", { 0 }, + { + { "256 KB", 256 }, + { "512 KB", 512 }, + { "1 MB", 1024 }, + { "" } + } + }, + { "", "", -1 } +// clang-format on }; const device_t realtek_rtg3106_device = { diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 08bfe4aa6..e77817782 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -7609,124 +7609,73 @@ static void s3_force_redraw(void *p) s3->svga.fullchange = changeframecount; } -static const device_config_t s3_orchid_86c911_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 1, "", { 0 }, - { - { - "512 KB", 0 - }, - { - "1 MB", 1 - }, - { - "" - } - } - }, - { - "", "", -1 - } +// clang-format off +static const device_config_t s3_orchid_86c911_config[] = { + { + "memory", "Memory size", CONFIG_SELECTION, "", 1, "", { 0 }, + { + { "512 KB", 0 }, + { "1 MB", 1 }, + { "" } + } + }, + { "", "", -1 } }; -static const device_config_t s3_9fx_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 2, "", { 0 }, - { - { - "1 MB", 1 - }, - { - "2 MB", 2 - }, - /*Trio64 also supports 4 MB, however the Number Nine BIOS does not*/ - { - "" - } - } - }, - { - "", "", -1 - } +static const device_config_t s3_9fx_config[] = { + { + "memory", "Memory size", CONFIG_SELECTION, "", 2, "", { 0 }, + { + { "1 MB", 1 }, + { "2 MB", 2 }, + /*Trio64 also supports 4 MB, however the Number Nine BIOS does not*/ + { "" } + } + }, + { "", "", -1 } }; -static const device_config_t s3_phoenix_trio32_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 2, "", { 0 }, - { - { - "512 KB", 0 - }, - { - "1 MB", 1 - }, - { - "2 MB", 2 - }, - { - "" - } - } - }, - { - "", "", -1 - } +static const device_config_t s3_phoenix_trio32_config[] = { + { + "memory", "Memory size", CONFIG_SELECTION, "", 2, "", { 0 }, + { + { "512 KB", 0 }, + { "1 MB", 1 }, + { "2 MB", 2 }, + { "" } + } + }, + { "", "", -1 } }; -static const device_config_t s3_standard_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, - { - { - "1 MB", 1 - }, - { - "2 MB", 2 - }, - { - "4 MB", 4 - }, - { - "" - } - } - }, - { - "", "", -1 - } +static const device_config_t s3_standard_config[] = { + { + "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, + { + { "1 MB", 1 }, + { "2 MB", 2 }, + { "4 MB", 4 }, + { "" } + } + }, + { "", "", -1 } }; -static const device_config_t s3_968_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, - { - { - "1 MB", 1 - }, - { - "2 MB", 2 - }, - { - "4 MB", 4 - }, - { - "8 MB", 8 - }, - { - "" - } - } - }, - { - "", "", -1 - } +static const device_config_t s3_968_config[] = { + { + "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, + { + { "1 MB", 1 }, + { "2 MB", 2 }, + { "4 MB", 4 }, + { "8 MB", 8 }, + { "" } + } + }, + { "", "", -1 } }; +// clang-format on const device_t s3_orchid_86c911_isa_device = { @@ -8384,7 +8333,7 @@ const device_t s3_elsa_winner2000_pro_x_964_pci_device = S3_ELSAWIN2KPROX_964, s3_init, s3_close, - s3_reset, + s3_reset, { s3_elsa_winner2000_pro_x_964_available }, s3_speed_changed, s3_force_redraw, @@ -8399,7 +8348,7 @@ const device_t s3_elsa_winner2000_pro_x_pci_device = S3_ELSAWIN2KPROX, s3_init, s3_close, - s3_reset, + s3_reset, { s3_elsa_winner2000_pro_x_available }, s3_speed_changed, s3_force_redraw, @@ -8414,7 +8363,7 @@ const device_t s3_trio64v2_dx_pci_device = S3_TRIO64V2_DX, s3_init, s3_close, - s3_reset, + s3_reset, { s3_trio64v2_dx_available }, s3_speed_changed, s3_force_redraw, @@ -8430,7 +8379,7 @@ const device_t s3_trio64v2_dx_onboard_pci_device = S3_TRIO64V2_DX_ONBOARD, s3_init, s3_close, - NULL, + NULL, { NULL }, s3_speed_changed, s3_force_redraw, diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 7f2a37253..4acaa0aa0 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -4216,102 +4216,60 @@ static void s3_virge_force_redraw(void *p) virge->svga.fullchange = changeframecount; } +// clang-format off static const device_config_t s3_virge_config[] = { + { + "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, { - "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, - { - { - "2 MB", 2 - }, - { - "4 MB", 4 - }, - { - "" - } - } - }, - { - "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 - }, - { - "dithering", "Dithering", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 + { "2 MB", 2 }, + { "4 MB", 4 }, + { "" } } + }, + { "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 }, + { "dithering", "Dithering", CONFIG_BINARY, "", 1 }, + { "", "", -1 } }; static const device_config_t s3_virge_stb_config[] = { + { + "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, { - "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, - { - { - "2 MB", 2 - }, - { - "4 MB", 4 - }, - { - "8 MB", 8 - }, - { - "" - } - } - }, - { - "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 - }, - { - "dithering", "Dithering", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 + { "2 MB", 2 }, + { "4 MB", 4 }, + { "8 MB", 8 }, + { "" } } + }, + { "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 }, + { "dithering", "Dithering", CONFIG_BINARY, "", 1 }, + { "", "", -1 } }; static const device_config_t s3_virge_357_config[] = { - { - "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 - }, - { - "dithering", "Dithering", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 - } + { "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 }, + { "dithering", "Dithering", CONFIG_BINARY, "", 1 }, + { "", "", -1 } }; static const device_config_t s3_trio3d2x_config[] = { + { + "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, { - "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, - { - { - "4 MB", 4 - }, - { - "8 MB", 8 - }, - { - "" - } - } - }, - { - "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 - }, - { - "dithering", "Dithering", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 + { "4 MB", 4 }, + { "8 MB", 8 }, + { "" } } + }, + { "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 }, + { "dithering", "Dithering", CONFIG_BINARY, "", 1 }, + { "", "", -1 } }; +// clang-format on const device_t s3_virge_325_pci_device = { @@ -4321,7 +4279,7 @@ const device_t s3_virge_325_pci_device = S3_VIRGE_325, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_325_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4336,7 +4294,7 @@ const device_t s3_diamond_stealth_2000_pci_device = S3_DIAMOND_STEALTH3D_2000, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_325_diamond_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4351,7 +4309,7 @@ const device_t s3_diamond_stealth_3000_pci_device = S3_DIAMOND_STEALTH3D_3000, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_988_diamond_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4366,7 +4324,7 @@ const device_t s3_stb_velocity_3d_pci_device = S3_STB_VELOCITY_3D, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_988_stb_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4381,7 +4339,7 @@ const device_t s3_virge_375_pci_device = S3_VIRGE_DX, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_375_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4396,7 +4354,7 @@ const device_t s3_diamond_stealth_2000pro_pci_device = S3_DIAMOND_STEALTH3D_2000PRO, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_375_diamond_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4411,7 +4369,7 @@ const device_t s3_virge_385_pci_device = S3_VIRGE_GX, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_385_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4426,7 +4384,7 @@ const device_t s3_virge_357_pci_device = S3_VIRGE_GX2, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_357_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4441,7 +4399,7 @@ const device_t s3_virge_357_agp_device = S3_VIRGE_GX2, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_357_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4456,7 +4414,7 @@ const device_t s3_diamond_stealth_4000_pci_device = S3_DIAMOND_STEALTH3D_4000, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_357_diamond_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4471,7 +4429,7 @@ const device_t s3_diamond_stealth_4000_agp_device = S3_DIAMOND_STEALTH3D_4000, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_357_diamond_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4486,7 +4444,7 @@ const device_t s3_trio3d2x_pci_device = S3_TRIO_3D2X, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_trio3d2x_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4501,7 +4459,7 @@ const device_t s3_trio3d2x_agp_device = S3_TRIO_3D2X, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_trio3d2x_available }, s3_virge_speed_changed, s3_virge_force_redraw, diff --git a/src/video/vid_sigma.c b/src/video/vid_sigma.c index e7b154ba4..3472e9f1a 100644 --- a/src/video/vid_sigma.c +++ b/src/video/vid_sigma.c @@ -881,78 +881,39 @@ sigma_speed_changed(void *p) } -device_config_t sigma_config[] = -{ +device_config_t sigma_config[] = { +// clang-format off { - "rgb_type", "RGB type", CONFIG_SELECTION, "", 0, "", { 0 }, - { - { - "Color", 0 - }, - { - "Green Monochrome", 1 - }, - { - "Amber Monochrome", 2 - }, - { - "Gray Monochrome", 3 - }, - { - "Color (no brown)", 4 - }, - { - "" - } - } + "rgb_type", "RGB type", CONFIG_SELECTION, "", 0, "", { 0 }, + { + { "Color", 0 }, + { "Green Monochrome", 1 }, + { "Amber Monochrome", 2 }, + { "Gray Monochrome", 3 }, + { "Color (no brown)", 4 }, + { "" } + } }, + { "enable_nmi", "Enable NMI for CGA emulation", CONFIG_BINARY, "", 1 }, { - "enable_nmi", "Enable NMI for CGA emulation", CONFIG_BINARY, "", 1 + "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0xc0000, "", { 0 }, + { + { "C000H", 0xc0000 }, + { "C800H", 0xc8000 }, + { "CC00H", 0xcc000 }, + { "D000H", 0xd0000 }, + { "D400H", 0xd4000 }, + { "D800H", 0xd8000 }, + { "DC00H", 0xdc000 }, + { "E000H", 0xe0000 }, + { "E400H", 0xe4000 }, + { "E800H", 0xe8000 }, + { "EC00H", 0xec000 }, + { "" } + }, }, - { - "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0xc0000, "", { 0 }, - { - { - "C000H", 0xc0000 - }, - { - "C800H", 0xc8000 - }, - { - "CC00H", 0xcc000 - }, - { - "D000H", 0xd0000 - }, - { - "D400H", 0xd4000 - }, - { - "D800H", 0xd8000 - }, - { - "DC00H", 0xdc000 - }, - { - "E000H", 0xe0000 - }, - { - "E400H", 0xe4000 - }, - { - "E800H", 0xe8000 - }, - { - "EC00H", 0xec000 - }, - { - "" - } - }, - }, - { - "", "", -1 - } + { "", "", -1 } +// clang-format on }; const device_t sigma_device = diff --git a/src/video/vid_table.c b/src/video/vid_table.c index f3797e730..ccd9c4071 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -1,20 +1,20 @@ /* - * 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. * - * Define all known video cards. + * Define all known video cards. * * * - * Authors: Miran Grca, - * Fred N. van Kempen, + * Authors: Miran Grca, + * Fred N. van Kempen, * - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. + * Copyright 2016-2020 Miran Grca. + * Copyright 2017-2020 Fred N. van Kempen. */ #include #include @@ -39,7 +39,7 @@ typedef struct { - const device_t *device; + const device_t *device; } VIDEO_CARD; @@ -51,193 +51,204 @@ static int was_reset = 0; static const device_t vid_none_device = { "None", "none", - 0, 0, - NULL, NULL, NULL, - { NULL }, NULL, NULL, + 0, + 0, + NULL, + NULL, + NULL, + { NULL }, + NULL, + NULL, NULL }; static const device_t vid_internal_device = { "Internal", "internal", - 0, 0, - NULL, NULL, NULL, - { NULL }, NULL, NULL, + 0, + 0, + NULL, + NULL, NULL, + { NULL }, + NULL, + NULL, NULL }; static const VIDEO_CARD video_cards[] = { - { &vid_none_device }, - { &vid_internal_device }, - { &atiega_device }, - { &mach64gx_isa_device }, - { &ati28800k_device }, - { &ati18800_vga88_device }, - { &ati28800_device }, - { &compaq_ati28800_device }, +// clang-format off + { &vid_none_device }, + { &vid_internal_device }, + { &atiega_device }, + { &mach64gx_isa_device }, + { &ati28800k_device }, + { &ati18800_vga88_device }, + { &ati28800_device }, + { &compaq_ati28800_device }, #if defined(DEV_BRANCH) && defined(USE_XL24) - { &ati28800_wonderxl24_device }, + { &ati28800_wonderxl24_device }, #endif - { &ati18800_device }, + { &ati18800_device }, #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) - { &ati18800_wonder_device }, + { &ati18800_wonder_device }, #endif - { &cga_device }, - { &sega_device }, - { &gd5401_isa_device }, - { &gd5402_isa_device }, - { &gd5420_isa_device }, - { &gd5422_isa_device }, - { &gd5426_isa_device }, - { &gd5426_diamond_speedstar_pro_a1_isa_device }, - { &gd5428_isa_device }, - { &gd5429_isa_device }, - { &gd5434_isa_device }, - { &gd5434_diamond_speedstar_64_a3_isa_device }, - { &compaq_cga_device }, - { &compaq_cga_2_device }, - { &cpqega_device }, - { &ega_device }, - { &g2_gc205_device }, - { &hercules_device }, - { &herculesplus_device }, - { &incolor_device }, - { &im1024_device }, - { &iskra_ega_device }, - { &et4000_kasan_isa_device }, - { &mda_device }, - { &genius_device }, - { &nga_device }, - { &ogc_device }, - { &oti037c_device }, - { &oti067_device }, - { &oti077_device }, - { ¶dise_pvga1a_device }, - { ¶dise_wd90c11_device }, - { ¶dise_wd90c30_device }, - { &colorplus_device }, - { &pgc_device }, - { &radius_svga_multiview_isa_device }, - { &realtek_rtg3106_device }, - { &s3_diamond_stealth_vram_isa_device }, - { &s3_orchid_86c911_isa_device }, - { &s3_ami_86c924_isa_device }, - { &s3_metheus_86c928_isa_device }, - { &s3_phoenix_86c801_isa_device }, - { &s3_spea_mirage_86c801_isa_device }, - { &sigma_device }, - { &tvga8900b_device }, - { &tvga8900d_device }, - { &tvga9000b_device }, - { &et4000k_isa_device }, - { &et2000_device }, - { &et4000_isa_device }, - { &et4000w32_device }, - { &et4000w32i_isa_device }, - { &vga_device }, - { &v7_vga_1024i_device }, - { &wy700_device }, - { &gd5428_mca_device }, - { &et4000_mca_device }, - { &radius_svga_multiview_mca_device }, - { &mach64gx_pci_device }, - { &mach64vt2_device }, - { &et4000w32p_videomagic_revb_pci_device }, - { &et4000w32p_revc_pci_device }, - { &et4000w32p_cardex_pci_device }, - { &et4000w32p_noncardex_pci_device }, - { &et4000w32p_pci_device }, - { &gd5430_pci_device, }, - { &gd5434_pci_device }, - { &gd5436_pci_device }, - { &gd5440_pci_device }, - { &gd5446_pci_device }, - { &gd5446_stb_pci_device }, - { &gd5480_pci_device }, - { &s3_spea_mercury_lite_86c928_pci_device }, - { &s3_diamond_stealth64_964_pci_device }, - { &s3_elsa_winner2000_pro_x_964_pci_device }, - { &s3_mirocrystal_20sv_964_pci_device }, - { &s3_bahamas64_pci_device }, - { &s3_phoenix_vision864_pci_device }, - { &s3_diamond_stealth_se_pci_device }, - { &s3_phoenix_trio32_pci_device }, - { &s3_diamond_stealth64_pci_device }, - { &s3_9fx_pci_device }, - { &s3_phoenix_trio64_pci_device }, - { &s3_elsa_winner2000_pro_x_pci_device }, - { &s3_mirovideo_40sv_ergo_968_pci_device }, - { &s3_9fx_771_pci_device }, - { &s3_phoenix_vision968_pci_device }, - { &s3_spea_mercury_p64v_pci_device }, - { &s3_9fx_531_pci_device }, - { &s3_phoenix_vision868_pci_device }, - { &s3_phoenix_trio64vplus_pci_device }, - { &s3_trio64v2_dx_pci_device }, - { &s3_virge_325_pci_device }, - { &s3_diamond_stealth_2000_pci_device }, - { &s3_diamond_stealth_3000_pci_device }, - { &s3_stb_velocity_3d_pci_device }, - { &s3_virge_375_pci_device }, - { &s3_diamond_stealth_2000pro_pci_device }, - { &s3_virge_385_pci_device }, - { &s3_virge_357_pci_device }, - { &s3_diamond_stealth_4000_pci_device }, - { &s3_trio3d2x_pci_device }, + { &cga_device }, + { &sega_device }, + { &gd5401_isa_device }, + { &gd5402_isa_device }, + { &gd5420_isa_device }, + { &gd5422_isa_device }, + { &gd5426_isa_device }, + { &gd5426_diamond_speedstar_pro_a1_isa_device }, + { &gd5428_isa_device }, + { &gd5429_isa_device }, + { &gd5434_isa_device }, + { &gd5434_diamond_speedstar_64_a3_isa_device }, + { &compaq_cga_device }, + { &compaq_cga_2_device }, + { &cpqega_device }, + { &ega_device }, + { &g2_gc205_device }, + { &hercules_device }, + { &herculesplus_device }, + { &incolor_device }, + { &im1024_device }, + { &iskra_ega_device }, + { &et4000_kasan_isa_device }, + { &mda_device }, + { &genius_device }, + { &nga_device }, + { &ogc_device }, + { &oti037c_device }, + { &oti067_device }, + { &oti077_device }, + { ¶dise_pvga1a_device }, + { ¶dise_wd90c11_device }, + { ¶dise_wd90c30_device }, + { &colorplus_device }, + { &pgc_device }, + { &radius_svga_multiview_isa_device }, + { &realtek_rtg3106_device }, + { &s3_diamond_stealth_vram_isa_device }, + { &s3_orchid_86c911_isa_device }, + { &s3_ami_86c924_isa_device }, + { &s3_metheus_86c928_isa_device }, + { &s3_phoenix_86c801_isa_device }, + { &s3_spea_mirage_86c801_isa_device }, + { &sigma_device }, + { &tvga8900b_device }, + { &tvga8900d_device }, + { &tvga9000b_device }, + { &et4000k_isa_device }, + { &et2000_device }, + { &et4000_isa_device }, + { &et4000w32_device }, + { &et4000w32i_isa_device }, + { &vga_device }, + { &v7_vga_1024i_device }, + { &wy700_device }, + { &gd5428_mca_device }, + { &et4000_mca_device }, + { &radius_svga_multiview_mca_device }, + { &mach64gx_pci_device }, + { &mach64vt2_device }, + { &et4000w32p_videomagic_revb_pci_device }, + { &et4000w32p_revc_pci_device }, + { &et4000w32p_cardex_pci_device }, + { &et4000w32p_noncardex_pci_device }, + { &et4000w32p_pci_device }, + { &gd5430_pci_device, }, + { &gd5434_pci_device }, + { &gd5436_pci_device }, + { &gd5440_pci_device }, + { &gd5446_pci_device }, + { &gd5446_stb_pci_device }, + { &gd5480_pci_device }, + { &s3_spea_mercury_lite_86c928_pci_device }, + { &s3_diamond_stealth64_964_pci_device }, + { &s3_elsa_winner2000_pro_x_964_pci_device }, + { &s3_mirocrystal_20sv_964_pci_device }, + { &s3_bahamas64_pci_device }, + { &s3_phoenix_vision864_pci_device }, + { &s3_diamond_stealth_se_pci_device }, + { &s3_phoenix_trio32_pci_device }, + { &s3_diamond_stealth64_pci_device }, + { &s3_9fx_pci_device }, + { &s3_phoenix_trio64_pci_device }, + { &s3_elsa_winner2000_pro_x_pci_device }, + { &s3_mirovideo_40sv_ergo_968_pci_device }, + { &s3_9fx_771_pci_device }, + { &s3_phoenix_vision968_pci_device }, + { &s3_spea_mercury_p64v_pci_device }, + { &s3_9fx_531_pci_device }, + { &s3_phoenix_vision868_pci_device }, + { &s3_phoenix_trio64vplus_pci_device }, + { &s3_trio64v2_dx_pci_device }, + { &s3_virge_325_pci_device }, + { &s3_diamond_stealth_2000_pci_device }, + { &s3_diamond_stealth_3000_pci_device }, + { &s3_stb_velocity_3d_pci_device }, + { &s3_virge_375_pci_device }, + { &s3_diamond_stealth_2000pro_pci_device }, + { &s3_virge_385_pci_device }, + { &s3_virge_357_pci_device }, + { &s3_diamond_stealth_4000_pci_device }, + { &s3_trio3d2x_pci_device }, #if defined(DEV_BRANCH) && defined(USE_MGA) - { &millennium_device }, - { &mystique_device }, - { &mystique_220_device }, + { &millennium_device }, + { &mystique_device }, + { &mystique_220_device }, #endif - { &tgui9440_pci_device }, - { &tgui9660_pci_device }, - { &tgui9680_pci_device }, - { &voodoo_banshee_device }, - { &creative_voodoo_banshee_device }, - { &voodoo_3_2000_device }, - { &voodoo_3_3000_device }, - { &mach64gx_vlb_device }, - { &et4000w32i_vlb_device }, - { &et4000w32p_videomagic_revb_vlb_device }, - { &et4000w32p_revc_vlb_device }, - { &et4000w32p_cardex_vlb_device }, - { &et4000w32p_vlb_device }, - { &et4000w32p_noncardex_vlb_device }, - { &gd5424_vlb_device }, - { &gd5426_vlb_device }, - { &gd5428_vlb_device }, - { &gd5428_diamond_speedstar_pro_b1_vlb_device }, - { &gd5429_vlb_device }, - { &gd5430_diamond_speedstar_pro_se_a8_vlb_device }, - { &gd5434_vlb_device }, - { &s3_metheus_86c928_vlb_device }, - { &s3_mirocrystal_8s_805_vlb_device }, - { &s3_mirocrystal_10sd_805_vlb_device }, - { &s3_phoenix_86c805_vlb_device }, - { &s3_spea_mirage_86c805_vlb_device }, - { &s3_diamond_stealth64_964_vlb_device }, - { &s3_mirocrystal_20sv_964_vlb_device }, - { &s3_mirocrystal_20sd_864_vlb_device }, - { &s3_bahamas64_vlb_device }, - { &s3_phoenix_vision864_vlb_device }, - { &s3_diamond_stealth_se_vlb_device }, - { &s3_phoenix_trio32_vlb_device }, - { &s3_diamond_stealth64_vlb_device }, - { &s3_9fx_vlb_device }, - { &s3_phoenix_trio64_vlb_device }, - { &s3_spea_mirage_p64_vlb_device }, - { &s3_phoenix_vision968_vlb_device }, - { &s3_phoenix_vision868_vlb_device }, - { &ht216_32_standalone_device }, - { &tgui9400cxi_device }, - { &tgui9440_vlb_device }, - { &s3_virge_357_agp_device }, - { &s3_diamond_stealth_4000_agp_device }, - { &s3_trio3d2x_agp_device }, - { &velocity_100_agp_device }, - { &voodoo_3_2000_agp_device }, - { &voodoo_3_3000_agp_device }, - { NULL } + { &tgui9440_pci_device }, + { &tgui9660_pci_device }, + { &tgui9680_pci_device }, + { &voodoo_banshee_device }, + { &creative_voodoo_banshee_device }, + { &voodoo_3_2000_device }, + { &voodoo_3_3000_device }, + { &mach64gx_vlb_device }, + { &et4000w32i_vlb_device }, + { &et4000w32p_videomagic_revb_vlb_device }, + { &et4000w32p_revc_vlb_device }, + { &et4000w32p_cardex_vlb_device }, + { &et4000w32p_vlb_device }, + { &et4000w32p_noncardex_vlb_device }, + { &gd5424_vlb_device }, + { &gd5426_vlb_device }, + { &gd5428_vlb_device }, + { &gd5428_diamond_speedstar_pro_b1_vlb_device }, + { &gd5429_vlb_device }, + { &gd5430_diamond_speedstar_pro_se_a8_vlb_device }, + { &gd5434_vlb_device }, + { &s3_metheus_86c928_vlb_device }, + { &s3_mirocrystal_8s_805_vlb_device }, + { &s3_mirocrystal_10sd_805_vlb_device }, + { &s3_phoenix_86c805_vlb_device }, + { &s3_spea_mirage_86c805_vlb_device }, + { &s3_diamond_stealth64_964_vlb_device }, + { &s3_mirocrystal_20sv_964_vlb_device }, + { &s3_mirocrystal_20sd_864_vlb_device }, + { &s3_bahamas64_vlb_device }, + { &s3_phoenix_vision864_vlb_device }, + { &s3_diamond_stealth_se_vlb_device }, + { &s3_phoenix_trio32_vlb_device }, + { &s3_diamond_stealth64_vlb_device }, + { &s3_9fx_vlb_device }, + { &s3_phoenix_trio64_vlb_device }, + { &s3_spea_mirage_p64_vlb_device }, + { &s3_phoenix_vision968_vlb_device }, + { &s3_phoenix_vision868_vlb_device }, + { &ht216_32_standalone_device }, + { &tgui9400cxi_device }, + { &tgui9440_vlb_device }, + { &s3_virge_357_agp_device }, + { &s3_diamond_stealth_4000_agp_device }, + { &s3_trio3d2x_agp_device }, + { &velocity_100_agp_device }, + { &voodoo_3_2000_agp_device }, + { &voodoo_3_3000_agp_device }, + { NULL } +// clang-format off }; @@ -251,9 +262,9 @@ vid_table_log(const char *fmt, ...) va_list ap; if (vid_table_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else @@ -274,8 +285,8 @@ video_prepare(void) { /* Reset (deallocate) the video font arrays. */ if (fontdatksc5601) { - free(fontdatksc5601); - fontdatksc5601 = NULL; + free(fontdatksc5601); + fontdatksc5601 = NULL; } /* Reset the CGA palette. */ @@ -295,8 +306,8 @@ void video_pre_reset(int card) { if ((card == VID_NONE) || \ - (card == VID_INTERNAL) || machine_has_flags(machine, MACHINE_VIDEO_ONLY)) - video_prepare(); + (card == VID_INTERNAL) || machine_has_flags(machine, MACHINE_VIDEO_ONLY)) + video_prepare(); } @@ -305,27 +316,27 @@ video_reset(int card) { /* This is needed to avoid duplicate resets. */ if ((video_get_type() != VIDEO_FLAG_TYPE_NONE) && was_reset) - return; + return; vid_table_log("VIDEO: reset (gfxcard=%d, internal=%d)\n", - card, machine_has_flags(machine, MACHINE_VIDEO) ? 1 : 0); + card, machine_has_flags(machine, MACHINE_VIDEO) ? 1 : 0); loadfont("roms/video/mda/mda.rom", 0); /* Do not initialize internal cards here. */ if (!(card == VID_NONE) && \ - !(card == VID_INTERNAL) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY)) { - vid_table_log("VIDEO: initializing '%s'\n", video_cards[card].name); + !(card == VID_INTERNAL) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY)) { + vid_table_log("VIDEO: initializing '%s'\n", video_cards[card].name); - video_prepare(); + video_prepare(); - /* Initialize the video card. */ - device_add(video_cards[card].device); + /* Initialize the video card. */ + device_add(video_cards[card].device); } /* Enable the Voodoo if configured. */ if (voodoo_enabled) - device_add(&voodoo_device); + device_add(&voodoo_device); was_reset = 1; } @@ -335,7 +346,7 @@ int video_card_available(int card) { if (video_cards[card].device) - return(device_available(video_cards[card].device)); + return(device_available(video_cards[card].device)); return(1); } @@ -370,9 +381,9 @@ video_get_video_from_internal_name(char *s) int c = 0; while (video_cards[c].device != NULL) { - if (!strcmp((char *) video_cards[c].device->internal_name, s)) - return(c); - c++; + if (!strcmp((char *) video_cards[c].device->internal_name, s)) + return(c); + c++; } return(0); diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index a59a479b3..d56bc2038 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -3171,64 +3171,61 @@ void tgui_force_redraw(void *p) tgui->svga.fullchange = changeframecount; } - -static const device_config_t tgui9440_config[] = -{ - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "" - } - }, - .default_int = 2 +// clang-format off +static const device_config_t tgui9440_config[] = { + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "1 MB", + .value = 1 + }, + { + .description = "2 MB", + .value = 2 + }, + { + .description = "" + } }, - { - .type = -1 - } + .default_int = 2 + }, + { + .type = -1 + } }; -static const device_config_t tgui96xx_config[] = -{ - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 4 +static const device_config_t tgui96xx_config[] = { + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "1 MB", + .value = 1 + }, + { + .description = "2 MB", + .value = 2 + }, + { + .description = "4 MB", + .value = 4 + }, + { + .description = "" + } }, - { - .type = -1 - } + .default_int = 4 + }, + { + .type = -1 + } }; +// clang-format on const device_t tgui9400cxi_device = { @@ -3238,7 +3235,7 @@ const device_t tgui9400cxi_device = TGUI_9400CXI, tgui_init, tgui_close, - NULL, + NULL, { tgui9400cxi_available }, tgui_speed_changed, tgui_force_redraw, @@ -3250,10 +3247,10 @@ const device_t tgui9440_vlb_device = "Trident TGUI 9440AGi VLB", "tgui9440_vlb", DEVICE_VLB, - TGUI_9440, + TGUI_9440, tgui_init, tgui_close, - NULL, + NULL, { tgui9440_available }, tgui_speed_changed, tgui_force_redraw, @@ -3265,10 +3262,10 @@ const device_t tgui9440_pci_device = "Trident TGUI 9440AGi PCI", "tgui9440_pci", DEVICE_PCI, - TGUI_9440, + TGUI_9440, tgui_init, tgui_close, - NULL, + NULL, { tgui9440_available }, tgui_speed_changed, tgui_force_redraw, @@ -3280,10 +3277,10 @@ const device_t tgui9440_onboard_pci_device = "Trident TGUI 9440AGi On-Board PCI", "tgui9440_onboard_pci", DEVICE_PCI, - TGUI_9440 | ONBOARD, + TGUI_9440 | ONBOARD, tgui_init, tgui_close, - NULL, + NULL, { NULL }, tgui_speed_changed, tgui_force_redraw, @@ -3295,10 +3292,10 @@ const device_t tgui9660_pci_device = "Trident TGUI 9660XGi PCI", "tgui9660_pci", DEVICE_PCI, - TGUI_9660, + TGUI_9660, tgui_init, tgui_close, - NULL, + NULL, { tgui96xx_available }, tgui_speed_changed, tgui_force_redraw, @@ -3310,10 +3307,10 @@ const device_t tgui9680_pci_device = "Trident TGUI 9680XGi PCI", "tgui9680_pci", DEVICE_PCI, - TGUI_9680, + TGUI_9680, tgui_init, tgui_close, - NULL, + NULL, { tgui96xx_available }, tgui_speed_changed, tgui_force_redraw, diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index 9f4cae6f4..dd68829ef 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -445,27 +445,19 @@ void tvga_force_redraw(void *p) static const device_config_t tvga_config[] = { +// clang-format off + { + "memory", "Memory size", CONFIG_SELECTION, "", 1024, "", { 0 }, { - "memory", "Memory size", CONFIG_SELECTION, "", 1024, "", { 0 }, - { - { - "256 kB", 256 - }, - { - "512 kB", 512 - }, - { - "1 MB", 1024 - }, - /*Chip supports 2mb, but drivers are buggy*/ - { - "" - } - } - }, - { - "", "", -1 + { "256 kB", 256 }, + { "512 kB", 512 }, + { "1 MB", 1024 }, + /*Chip supports 2mb, but drivers are buggy*/ + { "" } } + }, + { "", "", -1 } +// clang-format off }; const device_t tvga8900b_device = @@ -473,10 +465,10 @@ const device_t tvga8900b_device = "Trident TVGA 8900B", "tvga8900b", DEVICE_ISA, - TVGA8900B_ID, + TVGA8900B_ID, tvga_init, tvga_close, - NULL, + NULL, { tvga8900b_available }, tvga_speed_changed, tvga_force_redraw, @@ -488,10 +480,10 @@ const device_t tvga8900d_device = "Trident TVGA 8900D", "tvga8900d", DEVICE_ISA, - TVGA8900CLD_ID, + TVGA8900CLD_ID, tvga_init, tvga_close, - NULL, + NULL, { tvga8900d_available }, tvga_speed_changed, tvga_force_redraw, @@ -503,10 +495,10 @@ const device_t tvga9000b_device = "Trident TVGA 9000B", "tvga9000b", DEVICE_ISA, - TVGA9000B_ID, + TVGA9000B_ID, tvga_init, tvga_close, - NULL, + NULL, { tvga9000b_available }, tvga_speed_changed, tvga_force_redraw, diff --git a/src/video/vid_vga.c b/src/video/vid_vga.c index 90aff23e2..473dab58b 100644 --- a/src/video/vid_vga.c +++ b/src/video/vid_vga.c @@ -186,10 +186,10 @@ const device_t vga_device = "VGA", "vga", DEVICE_ISA, - 0, + 0, vga_init, vga_close, - NULL, + NULL, { vga_available }, vga_speed_changed, vga_force_redraw, @@ -201,10 +201,10 @@ const device_t ps1vga_device = "PS/1 VGA", "ps1vga", DEVICE_ISA, - 0, + 0, ps1vga_init, vga_close, - NULL, + NULL, { vga_available }, vga_speed_changed, vga_force_redraw, @@ -216,10 +216,10 @@ const device_t ps1vga_mca_device = "PS/1 VGA", "ps1vga_mca", DEVICE_MCA, - 0, + 0, ps1vga_init, vga_close, - NULL, + NULL, { vga_available }, vga_speed_changed, vga_force_redraw, diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index 43d389353..76e6c4009 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -1299,131 +1299,128 @@ void voodoo_close(void *p) free(voodoo_set); } -static const device_config_t voodoo_config[] = -{ - { - .name = "type", - .description = "Voodoo type", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Voodoo Graphics", - .value = VOODOO_1 - }, - { - .description = "Obsidian SB50 + Amethyst (2 TMUs)", - .value = VOODOO_SB50 - }, - { - .description = "Voodoo 2", - .value = VOODOO_2 - }, - { - .description = "" - } - }, - .default_int = 0 +static const device_config_t voodoo_config[] = { +// clang-format off + { + .name = "type", + .description = "Voodoo type", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "Voodoo Graphics", + .value = VOODOO_1 + }, + { + .description = "Obsidian SB50 + Amethyst (2 TMUs)", + .value = VOODOO_SB50 + }, + { + .description = "Voodoo 2", + .value = VOODOO_2 + }, + { + .description = "" + } }, - { - .name = "framebuffer_memory", - .description = "Framebuffer memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 2 + .default_int = 0 + }, + { + .name = "framebuffer_memory", + .description = "Framebuffer memory size", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "2 MB", + .value = 2 + }, + { + .description = "4 MB", + .value = 4 + }, + { + .description = "" + } }, - { - .name = "texture_memory", - .description = "Texture memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 2 + .default_int = 2 + }, + { + .name = "texture_memory", + .description = "Texture memory size", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "2 MB", + .value = 2 + }, + { + .description = "4 MB", + .value = 4 + }, + { + .description = "" + } }, - { - .name = "bilinear", - .description = "Bilinear filtering", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "dithersub", - .description = "Dither subtraction", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "dacfilter", - .description = "Screen Filter", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "render_threads", - .description = "Render threads", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1", - .value = 1 - }, - { - .description = "2", - .value = 2 - }, - { - .description = "4", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 2 - }, - { - .name = "sli", - .description = "SLI", - .type = CONFIG_BINARY, - .default_int = 0 + .default_int = 2 + }, + { + .name = "bilinear", + .description = "Bilinear filtering", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + .name = "dithersub", + .description = "Dither subtraction", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + .name = "dacfilter", + .description = "Screen Filter", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .name = "render_threads", + .description = "Render threads", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "1", + .value = 1 + }, + { + .description = "2", + .value = 2 + }, + { + .description = "4", + .value = 4 + }, + { + .description = "" + } }, + .default_int = 2 + }, + { + .name = "sli", + .description = "SLI", + .type = CONFIG_BINARY, + .default_int = 0 + }, #ifndef NO_CODEGEN - { - .name = "recompiler", - .description = "Recompiler", - .type = CONFIG_BINARY, - .default_int = 1 - }, + { + .name = "recompiler", + .description = "Recompiler", + .type = CONFIG_BINARY, + .default_int = 1 + }, #endif - { - .type = -1 - } + { + .type = -1 + } +// clang-format on }; const device_t voodoo_device = @@ -1431,10 +1428,10 @@ const device_t voodoo_device = "3DFX Voodoo Graphics", "voodoo", DEVICE_PCI, - 0, + 0, voodoo_init, voodoo_close, - NULL, + NULL, { NULL }, voodoo_speed_changed, voodoo_force_blit, diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 933f521a0..b314cc152 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -2600,139 +2600,138 @@ static void banshee_pci_write(int func, int addr, uint8_t val, void *p) } } +// clang-format off static const device_config_t banshee_sgram_config[] = { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "8 MB", - .value = 8 - }, - { - .description = "16 MB", - .value = 16 - }, - { - .description = "" - } - }, - .default_int = 16 + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "8 MB", + .value = 8 + }, + { + .description = "16 MB", + .value = 16 + }, + { + .description = "" + } }, - { - .name = "bilinear", - .description = "Bilinear filtering", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "dithersub", - .description = "Dither subtraction", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "dacfilter", - .description = "Screen Filter", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "render_threads", - .description = "Render threads", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1", - .value = 1 - }, - { - .description = "2", - .value = 2 - }, - { - .description = "4", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 2 + .default_int = 16 + }, + { + .name = "bilinear", + .description = "Bilinear filtering", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + .name = "dithersub", + .description = "Dither subtraction", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + .name = "dacfilter", + .description = "Screen Filter", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .name = "render_threads", + .description = "Render threads", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "1", + .value = 1 + }, + { + .description = "2", + .value = 2 + }, + { + .description = "4", + .value = 4 + }, + { + .description = "" + } }, + .default_int = 2 + }, #ifndef NO_CODEGEN - { - .name = "recompiler", - .description = "Recompiler", - .type = CONFIG_BINARY, - .default_int = 1 - }, + { + .name = "recompiler", + .description = "Recompiler", + .type = CONFIG_BINARY, + .default_int = 1 + }, #endif - { - .type = -1 - } + { + .type = -1 + } }; static const device_config_t banshee_sdram_config[] = { - { - .name = "bilinear", - .description = "Bilinear filtering", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "dithersub", - .description = "Dither subtraction", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "dacfilter", - .description = "Screen Filter", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "render_threads", - .description = "Render threads", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1", - .value = 1 - }, - { - .description = "2", - .value = 2 - }, - { - .description = "4", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 2 + { + .name = "bilinear", + .description = "Bilinear filtering", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + .name = "dithersub", + .description = "Dither subtraction", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + .name = "dacfilter", + .description = "Screen Filter", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .name = "render_threads", + .description = "Render threads", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "1", + .value = 1 + }, + { + .description = "2", + .value = 2 + }, + { + .description = "4", + .value = 4 + }, + { + .description = "" + } }, + .default_int = 2 + }, #ifndef NO_CODEGEN - { - .name = "recompiler", - .description = "Recompiler", - .type = CONFIG_BINARY, - .default_int = 1 - }, + { + .name = "recompiler", + .description = "Recompiler", + .type = CONFIG_BINARY, + .default_int = 1 + }, #endif - { - .type = -1 - } + { + .type = -1 + } }; +// clang-format on static void *banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int voodoo_type, int agp) { diff --git a/src/video/vid_wy700.c b/src/video/vid_wy700.c index 75a78b3c1..e0333bf17 100644 --- a/src/video/vid_wy700.c +++ b/src/video/vid_wy700.c @@ -1014,9 +1014,9 @@ const device_t wy700_device = DEVICE_ISA, 0, wy700_init, wy700_close, - NULL, + NULL, { NULL }, wy700_speed_changed, - NULL, + NULL, NULL }; From 06fc26ccab9283dc758f971b29fe9b7e3d97a862 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 27 Feb 2022 15:30:35 +0600 Subject: [PATCH 09/37] qt: Add Unix manager support (client-side interface) --- src/qt/CMakeLists.txt | 7 ++- src/qt/qt_main.cpp | 8 +++- src/qt/qt_platform.cpp | 1 + src/qt/qt_unixmanagerfilter.cpp | 79 +++++++++++++++++++++++++++++++++ src/qt/qt_unixmanagerfilter.hpp | 50 +++++++++++++++++++++ 5 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 src/qt/qt_unixmanagerfilter.cpp create mode 100644 src/qt/qt_unixmanagerfilter.hpp diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 94a7dadd9..cae9f1c81 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -20,7 +20,7 @@ if(QT_STATIC AND MINGW) endif() find_package(Threads REQUIRED) -find_package(Qt${QT_MAJOR} COMPONENTS Core Widgets OpenGL REQUIRED) +find_package(Qt${QT_MAJOR} COMPONENTS Core Widgets Network OpenGL REQUIRED) find_package(Qt${QT_MAJOR}LinguistTools REQUIRED) add_library(plat STATIC @@ -127,6 +127,9 @@ add_library(ui STATIC qt_util.hpp qt_util.cpp + qt_unixmanagerfilter.cpp + qt_unixmanagerfilter.hpp + ../qt_resources.qrc ) @@ -176,6 +179,7 @@ target_link_libraries( PRIVATE Qt${QT_MAJOR}::Widgets Qt${QT_MAJOR}::Gui + Qt${QT_MAJOR}::Network Threads::Threads ) @@ -185,6 +189,7 @@ target_link_libraries( Qt${QT_MAJOR}::Widgets Qt${QT_MAJOR}::Gui Qt${QT_MAJOR}::OpenGL + Qt${QT_MAJOR}::Network Threads::Threads ) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 46cf9a5dd..a8d9e2387 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -65,7 +65,7 @@ extern "C" #include "qt_settings.hpp" #include "cocoa_mouse.hpp" #include "qt_styleoverride.hpp" - +#include "qt_unixmanagerfilter.hpp" // Void Cast #define VC(x) const_cast(x) @@ -238,6 +238,11 @@ int main(int argc, char* argv[]) { } #endif + UnixManagerSocket socket; + if (qgetenv("86BOX_MANAGER_SOCKET").size()) + { + socket.connectToServer(qgetenv("86BOX_MANAGER_SOCKET")); + } pc_reset_hard_init(); /* Set the PAUSE mode depending on the renderer. */ @@ -272,5 +277,6 @@ int main(int argc, char* argv[]) { cpu_thread_run = 0; main_thread.join(); + socket.close(); return ret; } diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index e676a1b92..785f85619 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include diff --git a/src/qt/qt_unixmanagerfilter.cpp b/src/qt/qt_unixmanagerfilter.cpp new file mode 100644 index 000000000..88557dcf4 --- /dev/null +++ b/src/qt/qt_unixmanagerfilter.cpp @@ -0,0 +1,79 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Source file for Unix VM-managers (client-side) + * + * Authors: + * Teemu Korhonen + Cacodemon345 + * + * Copyright 2022 Teemu Korhonen + * Copyright 2022 Cacodemon345 + */ + +#include "qt_unixmanagerfilter.hpp" + +UnixManagerSocket::UnixManagerSocket(QObject* obj) + : QLocalSocket(obj) +{ + connect(this, &QLocalSocket::readyRead, this, &UnixManagerSocket::readyToRead); +} + +void UnixManagerSocket::readyToRead() +{ + if (canReadLine()) + { + QByteArray line = readLine(); + if (line.size()) + { + line.resize(line.size() - 2); + line.push_back((unsigned char)0); + if (line == "showsettings") + { + emit showsettings(); + } + else if (line == "pause") + { + emit pause(); + } + else if (line == "cad") + { + emit ctrlaltdel(); + } + else if (line == "reset") + { + emit resetVM(); + } + else if (line == "shutdownnoprompt") + { + emit force_shutdown(); + } + else if (line == "shutdown") + { + emit request_shutdown(); + } + } + } +} + +bool UnixManagerSocket::eventFilter(QObject *obj, QEvent *event) +{ + if (state() == QLocalSocket::ConnectedState) + { + if (event->type() == QEvent::WindowBlocked) + { + write(QByteArray{"1"}); + } + else if (event->type() == QEvent::WindowUnblocked) + { + write(QByteArray{"0"}); + } + } + + return QObject::eventFilter(obj, event); +} diff --git a/src/qt/qt_unixmanagerfilter.hpp b/src/qt/qt_unixmanagerfilter.hpp new file mode 100644 index 000000000..33b0f76a8 --- /dev/null +++ b/src/qt/qt_unixmanagerfilter.hpp @@ -0,0 +1,50 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Header file for Unix VM-managers (client-side) + * + * Authors: + * Teemu Korhonen + Cacodemon345 + * + * Copyright 2022 Teemu Korhonen + * Copyright 2022 Cacodemon345 + */ + +#ifndef QT_UNIXMANAGERFILTER_HPP +#define QT_UNIXMANAGERFILTER_HPP + +#include +#include +#include + +/* + * Filters messages from VM-manager and + * window blocked events to notify about open modal dialogs. + */ +class UnixManagerSocket : public QLocalSocket +{ + Q_OBJECT +public: + UnixManagerSocket(QObject* object = nullptr); +signals: + void pause(); + void ctrlaltdel(); + void showsettings(); + void resetVM(); + void request_shutdown(); + void force_shutdown(); + void dialogstatus(bool open); + +protected: + bool eventFilter(QObject *obj, QEvent *event) override; +protected slots: + void readyToRead(); +}; + +#endif From d2a9389ce7bca5f292e0b2e193774b99a3b742a2 Mon Sep 17 00:00:00 2001 From: ts-korhonen Date: Sun, 27 Feb 2022 14:56:51 +0200 Subject: [PATCH 10/37] qt: Initial OpenGL 3.0 renderer implementation --- src/qt/CMakeLists.txt | 7 + src/qt/qt_mainwindow.cpp | 110 ++++---- src/qt/qt_mainwindow.hpp | 17 +- src/qt/qt_mainwindow.ui | 19 ++ src/qt/qt_opengloptions.cpp | 207 +++++++++++++++ src/qt/qt_opengloptions.hpp | 103 ++++++++ src/qt/qt_opengloptionsdialog.cpp | 114 +++++++++ src/qt/qt_opengloptionsdialog.hpp | 48 ++++ src/qt/qt_opengloptionsdialog.ui | 280 +++++++++++++++++++++ src/qt/qt_openglrenderer.cpp | 406 ++++++++++++++++++++++++++++++ src/qt/qt_openglrenderer.hpp | 117 +++++++++ src/qt/qt_renderercommon.hpp | 33 ++- src/qt/qt_rendererstack.cpp | 248 ++++++++++-------- src/qt/qt_rendererstack.hpp | 54 ++-- src/qt/qt_softwarerenderer.cpp | 4 +- 15 files changed, 1558 insertions(+), 209 deletions(-) create mode 100644 src/qt/qt_opengloptions.cpp create mode 100644 src/qt/qt_opengloptions.hpp create mode 100644 src/qt/qt_opengloptionsdialog.cpp create mode 100644 src/qt/qt_opengloptionsdialog.hpp create mode 100644 src/qt/qt_opengloptionsdialog.ui create mode 100644 src/qt/qt_openglrenderer.cpp create mode 100644 src/qt/qt_openglrenderer.hpp diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 94a7dadd9..1d9c4187e 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -49,6 +49,13 @@ add_library(ui STATIC qt_softwarerenderer.hpp qt_hardwarerenderer.cpp qt_hardwarerenderer.hpp + qt_openglrenderer.cpp + qt_openglrenderer.hpp + qt_opengloptions.cpp + qt_opengloptions.hpp + qt_opengloptionsdialog.cpp + qt_opengloptionsdialog.hpp + qt_opengloptionsdialog.ui qt_settings.cpp qt_settings.hpp diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 2f1b6ca6a..e9e7548cf 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -202,7 +202,7 @@ MainWindow::MainWindow(QWidget *parent) : config_save(); if (QApplication::activeWindow() == this) { - ui->stackedWidget->current->setFocus(); + ui->stackedWidget->setFocusRenderer(); } }); @@ -236,30 +236,47 @@ MainWindow::MainWindow(QWidget *parent) : fprintf(stderr, "OpenGL renderers are unsupported on EGLFS.\n"); vid_api = 0; } + QActionGroup* actGroup = nullptr; - switch (vid_api) { - case 0: - ui->stackedWidget->switchRenderer(RendererStack::Renderer::Software); - ui->actionSoftware_Renderer->setChecked(true); - break; - case 1: - ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGL); - ui->actionHardware_Renderer_OpenGL->setChecked(true); - break; - case 2: - ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGLES); - ui->actionHardware_Renderer_OpenGL_ES->setChecked(true); - break; - case 3: - ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGL3); - ui->actionOpenGL_3_0_Core->setChecked(true); - break; - } + actGroup = new QActionGroup(this); actGroup->addAction(ui->actionSoftware_Renderer); actGroup->addAction(ui->actionHardware_Renderer_OpenGL); actGroup->addAction(ui->actionHardware_Renderer_OpenGL_ES); actGroup->addAction(ui->actionOpenGL_3_0_Core); + actGroup->setExclusive(true); + + connect(actGroup, &QActionGroup::triggered, [this](QAction* action) { + vid_api = action->property("vid_api").toInt(); + switch (vid_api) + { + case 0: + ui->stackedWidget->switchRenderer(RendererStack::Renderer::Software); + break; + case 1: + ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGL); + break; + case 2: + ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGLES); + break; + case 3: + ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGL3); + break; + } + }); + + connect(ui->stackedWidget, &RendererStack::rendererChanged, [this]() { + ui->actionRenderer_options->setVisible(ui->stackedWidget->hasOptions()); + }); + + /* Trigger initial renderer switch */ + for (auto action : actGroup->actions()) + if (action->property("vid_api").toInt() == vid_api) { + action->setChecked(true); + emit actGroup->triggered(action); + break; + } + switch (scale) { case 0: ui->action0_5x->setChecked(true); @@ -424,7 +441,7 @@ void MainWindow::closeEvent(QCloseEvent *event) { QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); questionbox.setCheckBox(chkbox); chkbox->setChecked(!confirm_exit); - bool confirm_exit_temp = false; + QObject::connect(chkbox, &QCheckBox::stateChanged, [](int state) { confirm_exit = (state == Qt::CheckState::Unchecked); }); @@ -497,7 +514,7 @@ void MainWindow::on_actionHard_Reset_triggered() { QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); questionbox.setCheckBox(chkbox); chkbox->setChecked(!confirm_reset); - bool confirm_exit_temp = false; + QObject::connect(chkbox, &QCheckBox::stateChanged, [](int state) { confirm_reset = (state == Qt::CheckState::Unchecked); }); @@ -1099,21 +1116,21 @@ void MainWindow::on_actionFullscreen_triggered() { QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); questionbox.setCheckBox(chkbox); chkbox->setChecked(!video_fullscreen_first); - bool confirm_exit_temp = false; + QObject::connect(chkbox, &QCheckBox::stateChanged, [](int state) { video_fullscreen_first = (state == Qt::CheckState::Unchecked); }); questionbox.exec(); config_save(); } + video_fullscreen = 1; setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); ui->menubar->hide(); ui->statusbar->hide(); ui->toolBar->hide(); showFullScreen(); - video_fullscreen = 1; } - ui->stackedWidget->rendererWindow->onResize(width(), height()); + ui->stackedWidget->onResize(width(), height()); } void MainWindow::getTitle_(wchar_t *title) @@ -1216,30 +1233,6 @@ QSize MainWindow::getRenderWidgetSize() return ui->stackedWidget->size(); } -void MainWindow::on_actionSoftware_Renderer_triggered() { - ui->stackedWidget->switchRenderer(RendererStack::Renderer::Software); - ui->actionHardware_Renderer_OpenGL->setChecked(false); - ui->actionHardware_Renderer_OpenGL_ES->setChecked(false); - ui->actionOpenGL_3_0_Core->setChecked(false); - vid_api = 0; -} - -void MainWindow::on_actionHardware_Renderer_OpenGL_triggered() { - ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGL); - ui->actionSoftware_Renderer->setChecked(false); - ui->actionHardware_Renderer_OpenGL_ES->setChecked(false); - ui->actionOpenGL_3_0_Core->setChecked(false); - vid_api = 1; -} - -void MainWindow::on_actionHardware_Renderer_OpenGL_ES_triggered() { - ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGLES); - ui->actionSoftware_Renderer->setChecked(false); - ui->actionHardware_Renderer_OpenGL->setChecked(false); - ui->actionOpenGL_3_0_Core->setChecked(false); - vid_api = 2; -} - void MainWindow::focusInEvent(QFocusEvent* event) { this->grabKeyboard(); @@ -1335,8 +1328,7 @@ static void update_fullscreen_scale_checkboxes(Ui::MainWindow* ui, QAction* sele if (video_fullscreen > 0) { auto widget = ui->stackedWidget->currentWidget(); - auto rc = ui->stackedWidget->rendererWindow; - rc->onResize(widget->width(), widget->height()); + ui->stackedWidget->onResize(widget->width(), widget->height()); } device_force_redraw(); @@ -1563,16 +1555,6 @@ void MainWindow::setSendKeyboardInput(bool enabled) send_keyboard_input = enabled; } -void MainWindow::on_actionOpenGL_3_0_Core_triggered() -{ - ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGL3); - ui->actionSoftware_Renderer->setChecked(false); - ui->actionHardware_Renderer_OpenGL->setChecked(false); - ui->actionHardware_Renderer_OpenGL_ES->setChecked(false); - ui->actionOpenGL_3_0_Core->setChecked(true); - vid_api = 3; -} - void MainWindow::on_actionPreferences_triggered() { ProgSettings progsettings(this); @@ -1618,3 +1600,11 @@ void MainWindow::changeEvent(QEvent* event) #endif QWidget::changeEvent(event); } + +void MainWindow::on_actionRenderer_options_triggered() +{ + auto dlg = ui->stackedWidget->getOptions(this); + + if (dlg) + dlg->exec(); +} diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index e6e7d3053..5b155079c 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -61,9 +61,6 @@ private slots: void on_actionHard_Reset_triggered(); void on_actionRight_CTRL_is_left_ALT_triggered(); void on_actionKeyboard_requires_capture_triggered(); - void on_actionHardware_Renderer_OpenGL_ES_triggered(); - void on_actionHardware_Renderer_OpenGL_triggered(); - void on_actionSoftware_Renderer_triggered(); void on_actionResizable_window_triggered(bool checked); void on_actionInverted_VGA_monitor_triggered(); void on_action0_5x_triggered(); @@ -96,19 +93,15 @@ private slots: void on_actionHide_status_bar_triggered(); void on_actionHide_tool_bar_triggered(); void on_actionUpdate_status_bar_icons_triggered(); + void on_actionTake_screenshot_triggered(); + void on_actionSound_gain_triggered(); + void on_actionPreferences_triggered(); + void on_actionEnable_Discord_integration_triggered(bool checked); + void on_actionRenderer_options_triggered(); void refreshMediaMenu(); void showMessage_(const QString& header, const QString& message); void getTitle_(wchar_t* title); - void on_actionTake_screenshot_triggered(); - - void on_actionSound_gain_triggered(); - - void on_actionOpenGL_3_0_Core_triggered(); - - void on_actionPreferences_triggered(); - - void on_actionEnable_Discord_integration_triggered(bool checked); protected: void keyPressEvent(QKeyEvent* event) override; diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index 98bb6ae2d..69197d015 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -154,6 +154,8 @@ + + @@ -341,6 +343,9 @@ &Qt (Software) + + 0 + @@ -349,6 +354,9 @@ Qt (&OpenGL) + + 1 + @@ -357,6 +365,9 @@ Qt (OpenGL &ES) + + 2 + @@ -626,6 +637,9 @@ Open&GL (3.0 Core) + + 3 + @@ -700,6 +714,11 @@ false + + + Renderer options... + + diff --git a/src/qt/qt_opengloptions.cpp b/src/qt/qt_opengloptions.cpp new file mode 100644 index 000000000..1f2460794 --- /dev/null +++ b/src/qt/qt_opengloptions.cpp @@ -0,0 +1,207 @@ +/* + * 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. + * + * OpenGL renderer options for Qt + * + * Authors: + * Teemu Korhonen + * + * Copyright 2022 Teemu Korhonen + */ + +#include +#include +#include + +#include + +#include "qt_opengloptions.hpp" + +extern "C" { +#include <86box/86box.h> +} + +/* Default vertex shader. */ +static const GLchar *vertex_shader = "#version 130\n\ +in vec2 VertexCoord;\n\ +in vec2 TexCoord;\n\ +out vec2 tex;\n\ +void main(){\n\ + gl_Position = vec4(VertexCoord, 0.0, 1.0);\n\ + tex = TexCoord;\n\ +}\n"; + +/* Default fragment shader. */ +static const GLchar *fragment_shader = "#version 130\n\ +in vec2 tex;\n\ +uniform sampler2D texsampler;\n\ +out vec4 color;\n\ +void main() {\n\ + color = texture(texsampler, tex);\n\ +}\n"; + +OpenGLOptions::OpenGLOptions(QObject *parent, bool loadConfig) + : QObject(parent) +{ + if (!loadConfig) + return; + + /* Initialize with config. */ + m_vsync = video_vsync != 0; + m_framerate = video_framerate; + + m_renderBehavior = video_framerate == -1 + ? RenderBehaviorType::SyncWithVideo + : RenderBehaviorType::TargetFramerate; + + m_filter = video_filter_method == 0 + ? FilterType::Nearest + : FilterType::Linear; + + QString shaderPath(video_shader); + + if (shaderPath.isEmpty()) + addDefaultShader(); + else + addShader(shaderPath); + + m_modified = ~ModifiedFlags {}; +} + +void +OpenGLOptions::save() +{ + video_vsync = m_vsync ? 1 : 0; + video_framerate = m_renderBehavior == RenderBehaviorType::SyncWithVideo ? -1 : m_framerate; + video_filter_method = m_filter == FilterType::Nearest ? 0 : 1; + + /* TODO: multiple shaders */ + auto path = m_shaders.first().path.toLocal8Bit(); + + if (!path.isEmpty()) + memcpy(video_shader, path.constData(), path.size()); + else + video_shader[0] = '\0'; +} + +bool +OpenGLOptions::isModified() +{ + /* Filter method is controlled externally */ + auto newfilter = video_filter_method == 0 + ? FilterType::Nearest + : FilterType::Linear; + + if (m_filter != newfilter) { + m_filter = newfilter; + m_modified.setFlag(ModifiedFlag::FilterModified); + } + + return m_modified != ModifiedFlags {}; +} + +OpenGLOptions::ModifiedFlags +OpenGLOptions::modified() +{ + ModifiedFlags temp {}; + std::swap(temp, m_modified); + return temp; +} + +void +OpenGLOptions::setRenderBehavior(RenderBehaviorType value) +{ + m_renderBehavior = value; + m_modified.setFlag(ModifiedFlag::RenderBehaviorModified); +} + +void +OpenGLOptions::setFrameRate(int value) +{ + m_framerate = value; + m_modified.setFlag(ModifiedFlag::FrameRateModified); +} + +void +OpenGLOptions::setVSync(bool value) +{ + m_vsync = value; + m_modified.setFlag(ModifiedFlag::VsyncModified); +} + +void +OpenGLOptions::setFilter(FilterType value) +{ + m_filter = value; + m_modified.setFlag(ModifiedFlag::FilterModified); +} + +void +OpenGLOptions::addShader(const QString &path) +{ + QFile shader_file(path); + + if (!shader_file.open(QIODevice::ReadOnly | QIODevice::Text)) { + throw std::runtime_error( + QString(tr("Error opening \"%1\": %2")) + .arg(path) + .arg(shader_file.errorString()) + .toStdString()); + } + + auto shader_text = QString(shader_file.readAll()); + + shader_file.close(); + + QRegularExpression version("^\\s*(#version\\s+\\w+)", QRegularExpression::MultilineOption); + + auto match = version.match(shader_text); + + QString version_line("#version 130"); + + if (match.hasMatch()) { + /* Extract existing version and remove it. */ + version_line = match.captured(1); + shader_text.remove(version); + } + + auto shader = new QOpenGLShaderProgram(this); + + auto throw_shader_error = [path, shader](const QString &what) { + throw std::runtime_error( + QString(what % ":\n\n %2") + .arg(path) + .arg(shader->log()) + .toStdString()); + }; + + if (!shader->addShaderFromSourceCode(QOpenGLShader::Vertex, version_line % "\n#define VERTEX\n" % shader_text)) + throw_shader_error(tr("Error compiling vertex shader in file \"%1\"")); + + if (!shader->addShaderFromSourceCode(QOpenGLShader::Fragment, version_line % "\n#define FRAGMENT\n" % shader_text)) + throw_shader_error(tr("Error compiling fragment shader in file \"%1\"")); + + if (!shader->link()) + throw_shader_error(tr("Error linking shader program in file \"%1\"")); + + m_shaders << OpenGLShaderPass(shader, path); + + m_modified.setFlag(ModifiedFlag::ShadersModified); +} + +void +OpenGLOptions::addDefaultShader() +{ + auto shader = new QOpenGLShaderProgram(this); + shader->addShaderFromSourceCode(QOpenGLShader::Vertex, vertex_shader); + shader->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment_shader); + shader->link(); + m_shaders << OpenGLShaderPass(shader, QString()); + + m_modified.setFlag(ModifiedFlag::ShadersModified); +} diff --git a/src/qt/qt_opengloptions.hpp b/src/qt/qt_opengloptions.hpp new file mode 100644 index 000000000..2cbb1f2b2 --- /dev/null +++ b/src/qt/qt_opengloptions.hpp @@ -0,0 +1,103 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Header for OpenGL renderer options + * + * Authors: + * Teemu Korhonen + * + * Copyright 2022 Teemu Korhonen + */ + +#ifndef QT_OPENGLOPTIONS_HPP +#define QT_OPENGLOPTIONS_HPP + +#include +#include +#include +#include + +struct OpenGLShaderPass { + OpenGLShaderPass(QOpenGLShaderProgram *shader, const QString &path) + : shader(shader) + , path(path) + , vertex_coord(shader->attributeLocation("VertexCoord")) + , tex_coord(shader->attributeLocation("TexCoord")) + , color(shader->attributeLocation("Color")) + , mvp_matrix(shader->uniformLocation("MVPMatrix")) + , input_size(shader->uniformLocation("InputSize")) + , output_size(shader->uniformLocation("OutputSize")) + , texture_size(shader->uniformLocation("TextureSize")) + , frame_count(shader->uniformLocation("FrameCount")) + { + } + + QOpenGLShaderProgram *shader; + const QString path; + const GLint vertex_coord; + const GLint tex_coord; + const GLint color; + const GLint mvp_matrix; + const GLint input_size; + const GLint output_size; + const GLint texture_size; + const GLint frame_count; +}; + +class OpenGLOptions : public QObject { + Q_OBJECT + +public: + enum ModifiedFlag { + RenderBehaviorModified = 0x01, + FrameRateModified = 0x02, + VsyncModified = 0x04, + FilterModified = 0x08, + ShadersModified = 0x10 + }; + Q_DECLARE_FLAGS(ModifiedFlags, ModifiedFlag) + + enum RenderBehaviorType { SyncWithVideo, + TargetFramerate }; + + enum FilterType { Nearest, + Linear }; + + OpenGLOptions(QObject *parent = nullptr, bool loadConfig = false); + + void save(); + bool isModified(); + ModifiedFlags modified(); + + RenderBehaviorType renderBehavior() const { return m_renderBehavior; } + int framerate() const { return m_framerate; } + bool vSync() const { return m_vsync; } + FilterType filter() const { return m_filter; } + + QList shaders() const { return m_shaders; }; + + void setRenderBehavior(RenderBehaviorType value); + void setFrameRate(int value); + void setVSync(bool value); + void setFilter(FilterType value); + + void addShader(const QString &path); + void addDefaultShader(); + +private: + RenderBehaviorType m_renderBehavior = SyncWithVideo; + int m_framerate = -1; + bool m_vsync = false; + FilterType m_filter = Nearest; + ModifiedFlags m_modified = {}; + QList m_shaders; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(OpenGLOptions::ModifiedFlags) + +#endif diff --git a/src/qt/qt_opengloptionsdialog.cpp b/src/qt/qt_opengloptionsdialog.cpp new file mode 100644 index 000000000..4503e0b90 --- /dev/null +++ b/src/qt/qt_opengloptionsdialog.cpp @@ -0,0 +1,114 @@ +/* + * 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. + * + * OpenGL renderer options dialog for Qt + * + * Authors: + * Teemu Korhonen + * + * Copyright 2022 Teemu Korhonen + */ + +#include +#include +#include + +#include + +#include "qt_opengloptionsdialog.hpp" +#include "qt_util.hpp" +#include "ui_qt_opengloptionsdialog.h" + +OpenGLOptionsDialog::OpenGLOptionsDialog(QWidget *parent, const OpenGLOptions &options) + : QDialog(parent) + , ui(new Ui::OpenGLOptionsDialog) +{ + ui->setupUi(this); + + if (options.renderBehavior() == OpenGLOptions::SyncWithVideo) + ui->syncWithVideo->setChecked(true); + else { + ui->syncToFramerate->setChecked(true); + ui->targetFps->setValue(options.framerate()); + } + + ui->vsync->setChecked(options.vSync()); + + if (!options.shaders().isEmpty()) { + auto path = options.shaders().first().path; + if (!path.isEmpty()) + ui->shader->setPlainText(path); + } +} + +OpenGLOptionsDialog::~OpenGLOptionsDialog() +{ + delete ui; +} + +void +OpenGLOptionsDialog::accept() +{ + auto options = new OpenGLOptions(); + + options->setRenderBehavior( + ui->syncWithVideo->isChecked() + ? OpenGLOptions::SyncWithVideo + : OpenGLOptions::TargetFramerate); + + options->setFrameRate(ui->targetFps->value()); + + options->setVSync(ui->vsync->isChecked()); + + auto shader = ui->shader->toPlainText(); + + try { + + if (!shader.isEmpty()) + options->addShader(shader); + else + options->addDefaultShader(); + + } catch (std::runtime_error &e) { + delete options; + + QMessageBox msgBox(this); + msgBox.setWindowTitle(tr("Shader error")); + msgBox.setText(tr("Could not load shaders.")); + msgBox.setInformativeText(tr("More information in details.")); + msgBox.setDetailedText(e.what()); + msgBox.setIcon(QMessageBox::Critical); + msgBox.setStandardButtons(QMessageBox::Close); + msgBox.setDefaultButton(QMessageBox::Close); + msgBox.setStyleSheet("QTextEdit { min-width: 45em; }"); + msgBox.exec(); + + return; + } + + options->save(); + + emit optionsChanged(options); + + QDialog::accept(); +} + +void +OpenGLOptionsDialog::on_addShader_clicked() +{ + auto shader = QFileDialog::getOpenFileName( + this, + QString(), + QString(), + tr("OpenGL Shaders") % util::DlgFilter({ "glsl" }, true)); + + if (shader.isNull()) + return; + + ui->shader->setPlainText(shader); +} diff --git a/src/qt/qt_opengloptionsdialog.hpp b/src/qt/qt_opengloptionsdialog.hpp new file mode 100644 index 000000000..833c58471 --- /dev/null +++ b/src/qt/qt_opengloptionsdialog.hpp @@ -0,0 +1,48 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Header for OpenGL renderer options dialog + * + * Authors: + * Teemu Korhonen + * + * Copyright 2022 Teemu Korhonen + */ + +#ifndef QT_OPENGLOPTIONSDIALOG_H +#define QT_OPENGLOPTIONSDIALOG_H + +#include + +#include "qt_opengloptions.hpp" + +namespace Ui { +class OpenGLOptionsDialog; +} + +class OpenGLOptionsDialog : public QDialog { + Q_OBJECT + +public: + explicit OpenGLOptionsDialog(QWidget *parent, const OpenGLOptions &options); + ~OpenGLOptionsDialog(); + +signals: + void optionsChanged(OpenGLOptions *options); + +public slots: + void accept() override; + +private: + Ui::OpenGLOptionsDialog *ui; + +private slots: + void on_addShader_clicked(); +}; + +#endif // QT_OPENGLOPTIONSDIALOG_H diff --git a/src/qt/qt_opengloptionsdialog.ui b/src/qt/qt_opengloptionsdialog.ui new file mode 100644 index 000000000..a6f86b6c2 --- /dev/null +++ b/src/qt/qt_opengloptionsdialog.ui @@ -0,0 +1,280 @@ + + + OpenGLOptionsDialog + + + + 0 + 0 + 400 + 320 + + + + OpenGL 3.0 renderer options + + + + + + Render behavior + + + + + + Use target framerate: + + + + + + + false + + + fps + + + 15 + + + 240 + + + 60 + + + + + + + VSync + + + + + + + <html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html> + + + Synchronize with video + + + true + + + + + + + false + + + 15 + + + 240 + + + 60 + + + Qt::Horizontal + + + false + + + QSlider::NoTicks + + + + + + + + + + Shaders + + + + + + Remove + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + true + + + No shader selected + + + + + + + Browse... + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + syncWithVideo + syncToFramerate + fpsSlider + targetFps + vsync + shader + addShader + removeShader + + + + + buttonBox + accepted() + OpenGLOptionsDialog + accept() + + + 257 + 310 + + + 157 + 274 + + + + + buttonBox + rejected() + OpenGLOptionsDialog + reject() + + + 325 + 310 + + + 286 + 274 + + + + + syncToFramerate + toggled(bool) + targetFps + setEnabled(bool) + + + 140 + 71 + + + 380 + 98 + + + + + syncToFramerate + toggled(bool) + fpsSlider + setEnabled(bool) + + + 158 + 66 + + + 168 + 87 + + + + + fpsSlider + valueChanged(int) + targetFps + setValue(int) + + + 252 + 90 + + + 308 + 89 + + + + + targetFps + valueChanged(int) + fpsSlider + setValue(int) + + + 364 + 93 + + + 134 + 93 + + + + + removeShader + clicked() + shader + clear() + + + 333 + 201 + + + 235 + 208 + + + + + diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp new file mode 100644 index 000000000..206cf0a69 --- /dev/null +++ b/src/qt/qt_openglrenderer.cpp @@ -0,0 +1,406 @@ +/* + * 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. + * + * OpenGL renderer for Qt + * + * Authors: + * Teemu Korhonen + * + * Copyright 2022 Teemu Korhonen + */ + +#include +#include +#include +#include + +#include + +#include "qt_opengloptionsdialog.hpp" +#include "qt_openglrenderer.hpp" + +OpenGLRenderer::OpenGLRenderer(QWidget *parent) + : QWindow(parent->windowHandle()) + , renderTimer(new QTimer(this)) +{ + renderTimer->setTimerType(Qt::PreciseTimer); + /* TODO: need's more accuracy, maybe target 1ms earlier and spin yield */ + connect(renderTimer, &QTimer::timeout, this, &OpenGLRenderer::render); + + buf_usage = std::vector(BUFFERCOUNT); + for (auto &flag : buf_usage) + flag.clear(); + + setSurfaceType(QWindow::OpenGLSurface); + + QSurfaceFormat format; + + format.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile); + format.setMajorVersion(3); + format.setMinorVersion(0); + + setFormat(format); + + context = new QOpenGLContext(this); + + context->setFormat(format); + + context->create(); + + parentWidget = parent; + + source.setRect(0, 0, INIT_WIDTH, INIT_HEIGHT); +} + +OpenGLRenderer::~OpenGLRenderer() +{ + finalize(); +} + +void +OpenGLRenderer::exposeEvent(QExposeEvent *event) +{ + Q_UNUSED(event); + + if (!isInitialized) + initialize(); +} + +void +OpenGLRenderer::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event); + + onResize(event->size().width(), event->size().height()); + + if (notReady()) + return; + + context->makeCurrent(this); + + glViewport( + destination.x(), + destination.y(), + destination.width(), + destination.height()); +} + +bool +OpenGLRenderer::event(QEvent *event) +{ + Q_UNUSED(event); + + bool res = false; + if (!eventDelegate(event, res)) + return QWindow::event(event); + return res; +} + +void +OpenGLRenderer::initialize() +{ + if (!context->makeCurrent(this) || !initializeOpenGLFunctions()) { + /* TODO: This could be done much better */ + QMessageBox::critical((QWidget *) qApp->findChild(), tr("Error initializing OpenGL"), tr("OpenGL functions could not be initialized. Falling back to software rendering.")); + context->doneCurrent(); + isFinalized = true; + isInitialized = true; + emit errorInitializing(); + return; + } + + setupExtensions(); + + setupBuffers(); + + /* Vertex, texture 2d coordinates and color (white) making a quad as triangle strip */ + const GLfloat surface[] = { + -1.f, 1.f, 0.f, 0.f, 1.f, 1.f, 1.f, 1.f, + 1.f, 1.f, 1.f, 0.f, 1.f, 1.f, 1.f, 1.f, + -1.f, -1.f, 0.f, 1.f, 1.f, 1.f, 1.f, 1.f, + 1.f, -1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f + }; + + glGenVertexArrays(1, &vertexArrayID); + + glBindVertexArray(vertexArrayID); + + glGenBuffers(1, &vertexBufferID); + glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID); + glBufferData(GL_ARRAY_BUFFER, sizeof(surface), surface, GL_STATIC_DRAW); + + glGenTextures(1, &textureID); + glBindTexture(GL_TEXTURE_2D, textureID); + + const GLfloat border_color[] = { 0.f, 0.f, 0.f, 1.f }; + + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, INIT_WIDTH, INIT_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); + + options = new OpenGLOptions(this, true); + + applyOptions(); + + glClearColor(0.f, 0.f, 0.f, 1.f); + + glViewport( + destination.x(), + destination.y(), + destination.width(), + destination.height()); + + isInitialized = true; + + emit initialized(); +} + +void +OpenGLRenderer::finalize() +{ + if (isFinalized) + return; + + context->makeCurrent(this); + + if (hasBufferStorage) + glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); + + glDeleteBuffers(1, &unpackBufferID); + glDeleteTextures(1, &textureID); + glDeleteBuffers(1, &vertexBufferID); + glDeleteVertexArrays(1, &vertexArrayID); + + if (!hasBufferStorage && unpackBuffer) + free(unpackBuffer); + + context->doneCurrent(); + + isFinalized = true; +} + +QDialog * +OpenGLRenderer::getOptions(QWidget *parent) +{ + auto dialog = new OpenGLOptionsDialog(parent, *options); + + connect(dialog, &OpenGLOptionsDialog::optionsChanged, this, &OpenGLRenderer::updateOptions); + + return dialog; +} + +void +OpenGLRenderer::setupExtensions() +{ + if (context->hasExtension("GL_ARB_buffer_storage")) { + hasBufferStorage = true; + + glBufferStorage = (PFNGLBUFFERSTORAGEPROC) context->getProcAddress("glBufferStorage"); + } + + if (context->hasExtension("GL_ARB_debug_output")) { + hasDebugOutput = true; + + glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC) context->getProcAddress("glDebugMessageControlARB"); + glDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC) context->getProcAddress("glDebugMessageInsertARB"); + glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC) context->getProcAddress("glDebugMessageCallbackARB"); + glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC) context->getProcAddress("glGetDebugMessageLogARB"); + } + + if (context->hasExtension("GL_ARB_sync")) { + hasSync = true; + + glFenceSync = (PFNGLFENCESYNCPROC) context->getProcAddress("glFenceSync"); + glIsSync = (PFNGLISSYNCPROC) context->getProcAddress("glIsSync"); + glDeleteSync = (PFNGLDELETESYNCPROC) context->getProcAddress("glDeleteSync"); + glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) context->getProcAddress("glClientWaitSync"); + glWaitSync = (PFNGLWAITSYNCPROC) context->getProcAddress("glWaitSync"); + glGetInteger64v = (PFNGLGETINTEGER64VPROC) context->getProcAddress("glGetInteger64v"); + glGetSynciv = (PFNGLGETSYNCIVPROC) context->getProcAddress("glGetSynciv"); + } +} + +void +OpenGLRenderer::setupBuffers() +{ + glGenBuffers(1, &unpackBufferID); + + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBufferID); + + if (hasBufferStorage) { + /* Create persistent buffer for pixel transfer. */ + glBufferStorage(GL_PIXEL_UNPACK_BUFFER, BUFFERBYTES * BUFFERCOUNT, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); + + unpackBuffer = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, BUFFERBYTES * BUFFERCOUNT, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); + } else { + /* Fallback; create our own buffer. */ + unpackBuffer = malloc(BUFFERBYTES * BUFFERCOUNT); + + glBufferData(GL_PIXEL_UNPACK_BUFFER, BUFFERBYTES * BUFFERCOUNT, NULL, GL_STREAM_DRAW); + } +} + +void +OpenGLRenderer::applyOptions() +{ + /* TODO: make something else; this was a bad idea. */ + + auto modified = options->modified(); + + if (modified.testFlag(OpenGLOptions::FrameRateModified) && options->framerate() > 0) { + int interval = (int) ceilf(1000.f / (float) options->framerate()); + renderTimer->setInterval(std::chrono::milliseconds(interval)); + } + + if (modified.testFlag(OpenGLOptions::RenderBehaviorModified)) { + if (options->renderBehavior() == OpenGLOptions::TargetFramerate) + renderTimer->start(); + else + renderTimer->stop(); + } + + if (modified.testFlag(OpenGLOptions::VsyncModified)) { + auto format = this->format(); + format.setSwapInterval(options->vSync() ? 1 : 0); + setFormat(format); + context->setFormat(format); + } + + if (modified.testFlag(OpenGLOptions::FilterModified)) { + GLint filter = options->filter() == OpenGLOptions::Linear ? GL_LINEAR : GL_NEAREST; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); + } +} + +void +OpenGLRenderer::applyShader(const OpenGLShaderPass &shader) +{ + if (!shader.shader->bind()) + return; + + if (shader.vertex_coord != -1) { + glEnableVertexAttribArray(shader.vertex_coord); + glVertexAttribPointer(shader.vertex_coord, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), 0); + } + + if (shader.tex_coord != -1) { + glEnableVertexAttribArray(shader.tex_coord); + glVertexAttribPointer(shader.tex_coord, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void *) (2 * sizeof(GLfloat))); + } + + if (shader.color != -1) { + glEnableVertexAttribArray(shader.color); + glVertexAttribPointer(shader.color, 4, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void *) (4 * sizeof(GLfloat))); + } + + if (shader.mvp_matrix != -1) { + static const GLfloat mvp[] = { + 1.f, 0.f, 0.f, 0.f, + 0.f, 1.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + 0.f, 0.f, 0.f, 1.f + }; + glUniformMatrix4fv(shader.mvp_matrix, 1, GL_FALSE, mvp); + } + + if (shader.output_size != -1) + glUniform2f(shader.output_size, destination.width(), destination.height()); + + if (shader.input_size != -1) + glUniform2f(shader.input_size, source.width(), source.height()); + + if (shader.texture_size != -1) + glUniform2f(shader.texture_size, source.width(), source.height()); + + if (shader.frame_count != -1) + glUniform1i(shader.frame_count, frameCounter); +} + +void +OpenGLRenderer::render() +{ + context->makeCurrent(this); + + if (options->isModified()) + applyOptions(); + + /* TODO: multiple shader passes */ + applyShader(options->shaders().first()); + + glClear(GL_COLOR_BUFFER_BIT); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + context->swapBuffers(this); + + frameCounter = (frameCounter + 1) & 1023; +} + +void +OpenGLRenderer::updateOptions(OpenGLOptions *newOptions) +{ + context->makeCurrent(this); + + glUseProgram(0); + + delete options; + + options = newOptions; + + options->setParent(this); + + applyOptions(); +} + +std::vector> +OpenGLRenderer::getBuffers() +{ + std::vector> buffers; + + if (notReady() || !unpackBuffer) + return buffers; + + /* Split the buffer area */ + for (int i = 0; i < BUFFERCOUNT; i++) { + buffers.push_back(std::make_tuple((uint8_t *) unpackBuffer + BUFFERBYTES * i, &buf_usage[i])); + } + + return buffers; +} + +void +OpenGLRenderer::onBlit(int buf_idx, int x, int y, int w, int h) +{ + if (notReady()) + return; + + context->makeCurrent(this); + + if (source.width() != w || source.height() != h) { + source.setRect(0, 0, w, h); + + /* Resize the texture */ + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, source.width(), source.height(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBufferID); + } + + glPixelStorei(GL_UNPACK_SKIP_PIXELS, BUFFERPIXELS * buf_idx + y * ROW_LENGTH + x); + glPixelStorei(GL_UNPACK_ROW_LENGTH, ROW_LENGTH); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); + + /* TODO: check if fence sync is implementable here and still has any benefit. */ + glFinish(); + + buf_usage[buf_idx].clear(); + + if (options->renderBehavior() == OpenGLOptions::SyncWithVideo) + render(); +} \ No newline at end of file diff --git a/src/qt/qt_openglrenderer.hpp b/src/qt/qt_openglrenderer.hpp new file mode 100644 index 000000000..1d8bc036d --- /dev/null +++ b/src/qt/qt_openglrenderer.hpp @@ -0,0 +1,117 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Header file for OpenGL renderer + * + * Authors: + * Teemu Korhonen + * + * Copyright 2022 Teemu Korhonen + */ + +#ifndef QT_OPENGLRENDERER_HPP +#define QT_OPENGLRENDERER_HPP + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "qt_opengloptions.hpp" +#include "qt_renderercommon.hpp" + +class OpenGLRenderer : public QWindow, protected QOpenGLFunctions_3_0, public RendererCommon { + Q_OBJECT + +public: + QOpenGLContext *context; + + OpenGLRenderer(QWidget *parent = nullptr); + ~OpenGLRenderer(); + + std::vector> getBuffers() override; + + void finalize() override final; + bool hasOptions() const override { return true; } + QDialog *getOptions(QWidget *parent) override; + +signals: + void initialized(); + void errorInitializing(); + +public slots: + void onBlit(int buf_idx, int x, int y, int w, int h); + +protected: + void exposeEvent(QExposeEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + bool event(QEvent *event) override; + +private: + static constexpr int INIT_WIDTH = 640; + static constexpr int INIT_HEIGHT = 400; + static constexpr int ROW_LENGTH = 2048; + static constexpr int BUFFERPIXELS = 4194304; + static constexpr int BUFFERBYTES = 16777216; /* Pixel is 4 bytes. */ + static constexpr int BUFFERCOUNT = 3; /* How many buffers to use for pixel transfer (2-3 is commonly recommended). */ + + OpenGLOptions *options; + QTimer *renderTimer; + + bool isInitialized = false; + bool isFinalized = false; + + GLuint unpackBufferID = 0; + GLuint vertexArrayID = 0; + GLuint vertexBufferID = 0; + GLuint textureID = 0; + int frameCounter = 0; + + void *unpackBuffer = nullptr; + + void initialize(); + void setupExtensions(); + void setupBuffers(); + void applyOptions(); + void applyShader(const OpenGLShaderPass &shader); + bool notReady() const { return !isInitialized || isFinalized; } + + /* GL_ARB_buffer_storage */ + bool hasBufferStorage = false; + PFNGLBUFFERSTORAGEPROC glBufferStorage = nullptr; + + /* GL_ARB_debug_output */ + bool hasDebugOutput = false; + PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB = nullptr; + PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB = nullptr; + PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB = nullptr; + PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLogARB = nullptr; + + /* GL_ARB_sync */ + bool hasSync = false; + PFNGLFENCESYNCPROC glFenceSync = nullptr; + PFNGLISSYNCPROC glIsSync = nullptr; + PFNGLDELETESYNCPROC glDeleteSync = nullptr; + PFNGLCLIENTWAITSYNCPROC glClientWaitSync = nullptr; + PFNGLWAITSYNCPROC glWaitSync = nullptr; + PFNGLGETINTEGER64VPROC glGetInteger64v = nullptr; + PFNGLGETSYNCIVPROC glGetSynciv = nullptr; + +private slots: + void render(); + void updateOptions(OpenGLOptions *newOptions); +}; + +#endif diff --git a/src/qt/qt_renderercommon.hpp b/src/qt/qt_renderercommon.hpp index f55f3ee03..1f94781e4 100644 --- a/src/qt/qt_renderercommon.hpp +++ b/src/qt/qt_renderercommon.hpp @@ -1,28 +1,37 @@ #pragma once -#include -#include +#include #include +#include +#include +#include -#include -#include #include #include +#include +#include class QWidget; -class RendererCommon -{ +class RendererCommon { public: RendererCommon(); - void onResize(int width, int height); - virtual std::vector> getBuffers() = 0; -protected: - bool eventDelegate(QEvent* event, bool& result); + void onResize(int width, int height); + virtual void finalize() { } - QRect source, destination; - QWidget* parentWidget{nullptr}; + virtual std::vector> getBuffers() = 0; + + /* Does renderer implement options dialog */ + virtual bool hasOptions() const { return false; } + /* Returns options dialog for renderer */ + virtual QDialog *getOptions(QWidget *parent) { return nullptr; } + +protected: + bool eventDelegate(QEvent *event, bool &result); + + QRect source, destination; + QWidget *parentWidget { nullptr }; std::vector buf_usage; }; diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 4788fa4df..be783864d 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -21,8 +21,9 @@ #include "qt_rendererstack.hpp" #include "ui_qt_rendererstack.h" -#include "qt_softwarerenderer.hpp" #include "qt_hardwarerenderer.hpp" +#include "qt_openglrenderer.hpp" +#include "qt_softwarerenderer.hpp" #include "qt_mainwindow.hpp" #include "qt_util.hpp" @@ -32,34 +33,33 @@ #include #ifdef __APPLE__ -#include +# include #endif -extern "C" -{ +extern "C" { #include <86box/mouse.h> #include <86box/plat.h> #include <86box/video.h> } -extern MainWindow* main_window; -RendererStack::RendererStack(QWidget *parent) : - QStackedWidget(parent), - ui(new Ui::RendererStack) +extern MainWindow *main_window; +RendererStack::RendererStack(QWidget *parent) + : QStackedWidget(parent) + , ui(new Ui::RendererStack) { ui->setupUi(this); #ifdef __unix__ -#ifdef WAYLAND +# ifdef WAYLAND if (QApplication::platformName().contains("wayland")) { wl_init(); } -#endif -#ifdef EVDEV_INPUT +# endif +# ifdef EVDEV_INPUT if (QApplication::platformName() == "eglfs") { evdev_init(); } -#endif +# endif if (QApplication::platformName() == "xcb") { extern void xinput2_init(); xinput2_init(); @@ -76,8 +76,7 @@ extern "C" void macos_poll_mouse(); void qt_mouse_capture(int on) { - if (!on) - { + if (!on) { mouse_capture = 0; QApplication::setOverrideCursor(Qt::ArrowCursor); #ifdef __APPLE__ @@ -93,162 +92,193 @@ qt_mouse_capture(int on) return; } -void RendererStack::mousePoll() +void +RendererStack::mousePoll() { #ifdef __APPLE__ return macos_poll_mouse(); #else /* !defined __APPLE__ */ - mouse_x = mousedata.deltax; - mouse_y = mousedata.deltay; - mouse_z = mousedata.deltaz; + mouse_x = mousedata.deltax; + mouse_y = mousedata.deltay; + mouse_z = mousedata.deltaz; mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0; - mouse_buttons = mousedata.mousebuttons; + mouse_buttons = mousedata.mousebuttons; -#ifdef __unix__ -#ifdef WAYLAND +# ifdef __unix__ +# ifdef WAYLAND if (QApplication::platformName().contains("wayland")) wl_mouse_poll(); -#endif +# endif -#ifdef EVDEV_INPUT - if (QApplication::platformName() == "eglfs") evdev_mouse_poll(); +# ifdef EVDEV_INPUT + if (QApplication::platformName() == "eglfs") + evdev_mouse_poll(); else -#endif - if (QApplication::platformName() == "xcb") - { +# endif + if (QApplication::platformName() == "xcb") { extern void xinput2_poll(); xinput2_poll(); } -#endif /* defined __unix__ */ -#endif /* !defined __APPLE__ */ - +# endif /* defined __unix__ */ +#endif /* !defined __APPLE__ */ } int ignoreNextMouseEvent = 1; -void RendererStack::mouseReleaseEvent(QMouseEvent *event) +void +RendererStack::mouseReleaseEvent(QMouseEvent *event) { - if (this->geometry().contains(event->pos()) && event->button() == Qt::LeftButton && !mouse_capture && (isMouseDown & 1)) - { + if (this->geometry().contains(event->pos()) && event->button() == Qt::LeftButton && !mouse_capture && (isMouseDown & 1)) { plat_mouse_capture(1); this->setCursor(Qt::BlankCursor); - if (!ignoreNextMouseEvent) ignoreNextMouseEvent++; // Avoid jumping cursor when moved. + if (!ignoreNextMouseEvent) + ignoreNextMouseEvent++; // Avoid jumping cursor when moved. isMouseDown &= ~1; return; } - if (mouse_capture && event->button() == Qt::MiddleButton && mouse_get_buttons() < 3) - { + if (mouse_capture && event->button() == Qt::MiddleButton && mouse_get_buttons() < 3) { plat_mouse_capture(0); this->setCursor(Qt::ArrowCursor); isMouseDown &= ~1; return; } - if (mouse_capture) - { + if (mouse_capture) { mousedata.mousebuttons &= ~event->button(); } isMouseDown &= ~1; } -void RendererStack::mousePressEvent(QMouseEvent *event) +void +RendererStack::mousePressEvent(QMouseEvent *event) { isMouseDown |= 1; - if (mouse_capture) - { + if (mouse_capture) { mousedata.mousebuttons |= event->button(); } event->accept(); } -void RendererStack::wheelEvent(QWheelEvent *event) +void +RendererStack::wheelEvent(QWheelEvent *event) { - if (mouse_capture) - { + if (mouse_capture) { mousedata.deltaz += event->pixelDelta().y(); } } -void RendererStack::mouseMoveEvent(QMouseEvent *event) +void +RendererStack::mouseMoveEvent(QMouseEvent *event) { - if (QApplication::platformName().contains("wayland")) - { + if (QApplication::platformName().contains("wayland")) { event->accept(); return; } - if (!mouse_capture) { event->ignore(); return; } + if (!mouse_capture) { + event->ignore(); + return; + } #ifdef __APPLE__ event->accept(); return; #else static QPoint oldPos = QCursor::pos(); - if (ignoreNextMouseEvent) { oldPos = event->pos(); ignoreNextMouseEvent--; event->accept(); return; } + if (ignoreNextMouseEvent) { + oldPos = event->pos(); + ignoreNextMouseEvent--; + event->accept(); + return; + } mousedata.deltax += event->pos().x() - oldPos.x(); mousedata.deltay += event->pos().y() - oldPos.y(); - if (QApplication::platformName() == "eglfs") - { - leaveEvent((QEvent*)event); + if (QApplication::platformName() == "eglfs") { + leaveEvent((QEvent *) event); ignoreNextMouseEvent--; } QCursor::setPos(mapToGlobal(QPoint(width() / 2, height() / 2))); ignoreNextMouseEvent = 2; - oldPos = event->pos(); + oldPos = event->pos(); #endif } -void RendererStack::leaveEvent(QEvent* event) +void +RendererStack::leaveEvent(QEvent *event) { - if (QApplication::platformName().contains("wayland")) - { + if (QApplication::platformName().contains("wayland")) { event->accept(); return; } - if (!mouse_capture) return; + if (!mouse_capture) + return; ignoreNextMouseEvent = 2; event->accept(); } -void RendererStack::switchRenderer(Renderer renderer) { +void +RendererStack::switchRenderer(Renderer renderer) +{ startblit(); if (current) { + rendererWindow->finalize(); removeWidget(current.get()); - } + disconnect(this, &RendererStack::blitToRenderer, nullptr, nullptr); + /* Create new renderer only after previous is destroyed! */ + connect(current.get(), &QObject::destroyed, [this, renderer](QObject *) { createRenderer(renderer); }); + + current.release()->deleteLater(); + } else { + createRenderer(renderer); + } +} + +void +RendererStack::createRenderer(Renderer renderer) +{ switch (renderer) { - case Renderer::Software: - { - auto sw = new SoftwareRenderer(this); - rendererWindow = sw; - connect(this, &RendererStack::blitToRenderer, sw, &SoftwareRenderer::onBlit, Qt::QueuedConnection); - current.reset(this->createWindowContainer(sw, this)); + case Renderer::Software: + { + auto sw = new SoftwareRenderer(this); + rendererWindow = sw; + connect(this, &RendererStack::blitToRenderer, sw, &SoftwareRenderer::onBlit, Qt::QueuedConnection); + current.reset(this->createWindowContainer(sw, this)); + } + break; + case Renderer::OpenGL: + { + this->createWinId(); + auto hw = new HardwareRenderer(this); + rendererWindow = hw; + connect(this, &RendererStack::blitToRenderer, hw, &HardwareRenderer::onBlit, Qt::QueuedConnection); + current.reset(this->createWindowContainer(hw, this)); + break; + } + case Renderer::OpenGLES: + { + this->createWinId(); + auto hw = new HardwareRenderer(this, HardwareRenderer::RenderType::OpenGLES); + rendererWindow = hw; + connect(this, &RendererStack::blitToRenderer, hw, &HardwareRenderer::onBlit, Qt::QueuedConnection); + current.reset(this->createWindowContainer(hw, this)); + break; + } + case Renderer::OpenGL3: + { + this->createWinId(); + auto hw = new OpenGLRenderer(this); + rendererWindow = hw; + connect(this, &RendererStack::blitToRenderer, hw, &OpenGLRenderer::onBlit, Qt::QueuedConnection); + connect(hw, &OpenGLRenderer::initialized, [=]() { + /* Buffers are awailable only after initialization. */ + imagebufs = rendererWindow->getBuffers(); + endblit(); + emit rendererChanged(); + }); + connect(hw, &OpenGLRenderer::errorInitializing, [=]() { + /* Renderer could initialize, fallback to software. */ + endblit(); + QTimer::singleShot(0, this, [this]() { switchRenderer(Renderer::Software); }); + }); + current.reset(this->createWindowContainer(hw, this)); + break; + } } - break; - case Renderer::OpenGL: - { - this->createWinId(); - auto hw = new HardwareRenderer(this); - rendererWindow = hw; - connect(this, &RendererStack::blitToRenderer, hw, &HardwareRenderer::onBlit, Qt::QueuedConnection); - current.reset(this->createWindowContainer(hw, this)); - break; - } - case Renderer::OpenGLES: - { - this->createWinId(); - auto hw = new HardwareRenderer(this, HardwareRenderer::RenderType::OpenGLES); - rendererWindow = hw; - connect(this, &RendererStack::blitToRenderer, hw, &HardwareRenderer::onBlit, Qt::QueuedConnection); - current.reset(this->createWindowContainer(hw, this)); - break; - } - case Renderer::OpenGL3: - { - this->createWinId(); - auto hw = new HardwareRenderer(this, HardwareRenderer::RenderType::OpenGL3); - rendererWindow = hw; - connect(this, &RendererStack::blitToRenderer, hw, &HardwareRenderer::onBlit, Qt::QueuedConnection); - current.reset(this->createWindowContainer(hw, this)); - break; - } - } - - imagebufs = std::move(rendererWindow->getBuffers()); current->setFocusPolicy(Qt::NoFocus); current->setFocusProxy(this); @@ -256,31 +286,35 @@ void RendererStack::switchRenderer(Renderer renderer) { this->setStyleSheet("background-color: black"); - endblit(); + currentBuf = 0; + + if (renderer != Renderer::OpenGL3) { + imagebufs = rendererWindow->getBuffers(); + endblit(); + emit rendererChanged(); + } } // called from blitter thread -void RendererStack::blit(int x, int y, int w, int h) +void +RendererStack::blit(int x, int y, int w, int h) { - if ((w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || std::get(imagebufs[currentBuf])->test_and_set()) - { + if ((w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || std::get(imagebufs[currentBuf])->test_and_set()) { video_blit_complete(); return; } sx = x; sy = y; sw = this->w = w; - sh = this->h = h; - uint8_t* imagebits = std::get(imagebufs[currentBuf]); - for (int y1 = y; y1 < (y + h); y1++) - { + sh = this->h = h; + uint8_t *imagebits = std::get(imagebufs[currentBuf]); + for (int y1 = y; y1 < (y + h); y1++) { auto scanline = imagebits + (y1 * (2048) * 4) + (x * 4); video_copy(scanline, &(buffer32->line[y1][x]), w * 4); } - if (screenshots) - { - video_screenshot((uint32_t *)imagebits, x, y, 2048); + if (screenshots) { + video_screenshot((uint32_t *) imagebits, x, y, 2048); } video_blit_complete(); emit blitToRenderer(currentBuf, sx, sy, sw, sh); diff --git a/src/qt/qt_rendererstack.hpp b/src/qt/qt_rendererstack.hpp index 9bff340f0..9133a4927 100644 --- a/src/qt/qt_rendererstack.hpp +++ b/src/qt/qt_rendererstack.hpp @@ -1,37 +1,41 @@ #ifndef QT_RENDERERCONTAINER_HPP #define QT_RENDERERCONTAINER_HPP -#include -#include +#include #include -#include -#include +#include +#include +#include + #include +#include #include +#include + +#include "qt_renderercommon.hpp" namespace Ui { class RendererStack; } class RendererCommon; -class RendererStack : public QStackedWidget -{ +class RendererStack : public QStackedWidget { Q_OBJECT public: explicit RendererStack(QWidget *parent = nullptr); ~RendererStack(); - void mousePressEvent(QMouseEvent* event) override; - void mouseReleaseEvent(QMouseEvent* event) override; - void mouseMoveEvent(QMouseEvent* event) override; + void mousePressEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; void wheelEvent(QWheelEvent *event) override; void leaveEvent(QEvent *event) override; - void keyPressEvent(QKeyEvent* event) override + void keyPressEvent(QKeyEvent *event) override { event->ignore(); } - void keyReleaseEvent(QKeyEvent* event) override + void keyReleaseEvent(QKeyEvent *event) override { event->ignore(); } @@ -44,15 +48,33 @@ public: }; void switchRenderer(Renderer renderer); - RendererCommon* rendererWindow{nullptr}; + /* Does current renderer implement options dialog */ + bool hasOptions() const { return rendererWindow ? rendererWindow->hasOptions() : false; } + /* Returns options dialog for current renderer */ + QDialog *getOptions(QWidget *parent) { return rendererWindow ? rendererWindow->getOptions(parent) : nullptr; } + + void setFocusRenderer() + { + if (current) + current->setFocus(); + } + void onResize(int width, int height) + { + if (rendererWindow) + rendererWindow->onResize(width, height); + } + signals: void blitToRenderer(int buf_idx, int x, int y, int w, int h); + void rendererChanged(); public slots: void blit(int x, int y, int w, int h); void mousePoll(); private: + void createRenderer(Renderer renderer); + Ui::RendererStack *ui; struct mouseinputdata { @@ -63,13 +85,13 @@ private: int x, y, w, h, sx, sy, sw, sh; - int currentBuf = 0; + int currentBuf = 0; int isMouseDown = 0; - std::vector> imagebufs; + std::vector> imagebufs; + + RendererCommon *rendererWindow { nullptr }; std::unique_ptr current; - - friend class MainWindow; }; #endif // QT_RENDERERCONTAINER_HPP diff --git a/src/qt/qt_softwarerenderer.cpp b/src/qt/qt_softwarerenderer.cpp index 3deeb1a9f..82d33a7cb 100644 --- a/src/qt/qt_softwarerenderer.cpp +++ b/src/qt/qt_softwarerenderer.cpp @@ -53,8 +53,8 @@ void SoftwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { cur_image = buf_idx; buf_usage[(buf_idx + 1) % 2].clear(); - - source.setRect(x, y, w, h), + + source.setRect(x, y, w, h); update(); } From 04a8265bd7257889a784c937332b69830b8290bd Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 27 Feb 2022 15:32:50 +0100 Subject: [PATCH 11/37] Added length checks to the t128 scsi dma read/write initialization (ncr_write), fixes crashes when length is below 0. --- src/scsi/scsi_ncr5380.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index 713e69f7b..ecc2e32ce 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -657,14 +657,16 @@ ncr_write(uint16_t port, uint8_t val, void *priv) /*a Write 6/10 has occurred, start the timer when the block count is loaded*/ ncr->dma_mode = DMA_SEND; if (ncr_dev->type == 3) { - memset(ncr_dev->t128.buffer, 0, MIN(512, dev->buffer_length)); + if (dev->buffer_length > 0) { + memset(ncr_dev->t128.buffer, 0, MIN(512, dev->buffer_length)); - ncr_log("DMA send timer start, enabled? = %i\n", timer_is_enabled(&ncr_dev->timer)); - ncr_dev->t128.block_count = dev->buffer_length >> 9; - ncr_dev->t128.block_loaded = 1; + ncr_log("DMA send timer start, enabled? = %i\n", timer_is_enabled(&ncr_dev->timer)); + ncr_dev->t128.block_count = dev->buffer_length >> 9; + ncr_dev->t128.block_loaded = 1; - ncr_dev->t128.host_pos = 0; - ncr_dev->t128.status |= 0x04; + ncr_dev->t128.host_pos = 0; + ncr_dev->t128.status |= 0x04; + } } else { if ((ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) { memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length)); @@ -680,19 +682,21 @@ ncr_write(uint16_t port, uint8_t val, void *priv) /*a Read 6/10 has occurred, start the timer when the block count is loaded*/ ncr->dma_mode = DMA_INITIATOR_RECEIVE; if (ncr_dev->type == 3) { - ncr_log("DMA receive timer start, enabled? = %i, cdb[0] = %02x\n", timer_is_enabled(&ncr_dev->timer), ncr->command[0]); - memset(ncr_dev->t128.buffer, 0, MIN(512, dev->buffer_length)); + ncr_log("DMA receive timer start, enabled? = %i, cdb[0] = %02x, buflen = %i\n", timer_is_enabled(&ncr_dev->timer), ncr->command[0], dev->buffer_length); + if (dev->buffer_length > 0) { + memset(ncr_dev->t128.buffer, 0, MIN(512, dev->buffer_length)); - ncr_dev->t128.block_count = dev->buffer_length >> 9; + ncr_dev->t128.block_count = dev->buffer_length >> 9; - if (dev->buffer_length < 512) - ncr_dev->t128.block_count = 1; + if (dev->buffer_length < 512) + ncr_dev->t128.block_count = 1; - ncr_dev->t128.block_loaded = 1; + ncr_dev->t128.block_loaded = 1; - ncr_dev->t128.host_pos = MIN(512, dev->buffer_length); - ncr_dev->t128.status |= 0x04; - timer_on_auto(&ncr_dev->timer, 0.02); + ncr_dev->t128.host_pos = MIN(512, dev->buffer_length); + ncr_dev->t128.status |= 0x04; + timer_on_auto(&ncr_dev->timer, 0.02); + } } else { if ((ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) { memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length)); From 1dcb712ef7cb9a238fe6462961036249ea8c6b69 Mon Sep 17 00:00:00 2001 From: ts-korhonen Date: Sun, 27 Feb 2022 16:45:57 +0200 Subject: [PATCH 12/37] qt: Remove QFlags from OpenGLOptions. Didn't work in ubuntu and was a bad design attempt to mimic win32 options change detection. --- src/qt/qt_opengloptions.cpp | 31 +++---------------------------- src/qt/qt_opengloptions.hpp | 21 ++------------------- src/qt/qt_openglrenderer.cpp | 36 +++++++++++++++++------------------- src/qt/qt_openglrenderer.hpp | 2 ++ 4 files changed, 24 insertions(+), 66 deletions(-) diff --git a/src/qt/qt_opengloptions.cpp b/src/qt/qt_opengloptions.cpp index 1f2460794..995fd8401 100644 --- a/src/qt/qt_opengloptions.cpp +++ b/src/qt/qt_opengloptions.cpp @@ -69,8 +69,6 @@ OpenGLOptions::OpenGLOptions(QObject *parent, bool loadConfig) addDefaultShader(); else addShader(shaderPath); - - m_modified = ~ModifiedFlags {}; } void @@ -89,56 +87,37 @@ OpenGLOptions::save() video_shader[0] = '\0'; } -bool -OpenGLOptions::isModified() +OpenGLOptions::FilterType +OpenGLOptions::filter() const { /* Filter method is controlled externally */ - auto newfilter = video_filter_method == 0 + return video_filter_method == 0 ? FilterType::Nearest : FilterType::Linear; - - if (m_filter != newfilter) { - m_filter = newfilter; - m_modified.setFlag(ModifiedFlag::FilterModified); - } - - return m_modified != ModifiedFlags {}; -} - -OpenGLOptions::ModifiedFlags -OpenGLOptions::modified() -{ - ModifiedFlags temp {}; - std::swap(temp, m_modified); - return temp; } void OpenGLOptions::setRenderBehavior(RenderBehaviorType value) { m_renderBehavior = value; - m_modified.setFlag(ModifiedFlag::RenderBehaviorModified); } void OpenGLOptions::setFrameRate(int value) { m_framerate = value; - m_modified.setFlag(ModifiedFlag::FrameRateModified); } void OpenGLOptions::setVSync(bool value) { m_vsync = value; - m_modified.setFlag(ModifiedFlag::VsyncModified); } void OpenGLOptions::setFilter(FilterType value) { m_filter = value; - m_modified.setFlag(ModifiedFlag::FilterModified); } void @@ -190,8 +169,6 @@ OpenGLOptions::addShader(const QString &path) throw_shader_error(tr("Error linking shader program in file \"%1\"")); m_shaders << OpenGLShaderPass(shader, path); - - m_modified.setFlag(ModifiedFlag::ShadersModified); } void @@ -202,6 +179,4 @@ OpenGLOptions::addDefaultShader() shader->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment_shader); shader->link(); m_shaders << OpenGLShaderPass(shader, QString()); - - m_modified.setFlag(ModifiedFlag::ShadersModified); } diff --git a/src/qt/qt_opengloptions.hpp b/src/qt/qt_opengloptions.hpp index 2cbb1f2b2..728b3c4fd 100644 --- a/src/qt/qt_opengloptions.hpp +++ b/src/qt/qt_opengloptions.hpp @@ -17,7 +17,6 @@ #ifndef QT_OPENGLOPTIONS_HPP #define QT_OPENGLOPTIONS_HPP -#include #include #include #include @@ -53,15 +52,6 @@ class OpenGLOptions : public QObject { Q_OBJECT public: - enum ModifiedFlag { - RenderBehaviorModified = 0x01, - FrameRateModified = 0x02, - VsyncModified = 0x04, - FilterModified = 0x08, - ShadersModified = 0x10 - }; - Q_DECLARE_FLAGS(ModifiedFlags, ModifiedFlag) - enum RenderBehaviorType { SyncWithVideo, TargetFramerate }; @@ -70,14 +60,10 @@ public: OpenGLOptions(QObject *parent = nullptr, bool loadConfig = false); - void save(); - bool isModified(); - ModifiedFlags modified(); - RenderBehaviorType renderBehavior() const { return m_renderBehavior; } int framerate() const { return m_framerate; } bool vSync() const { return m_vsync; } - FilterType filter() const { return m_filter; } + FilterType filter() const; QList shaders() const { return m_shaders; }; @@ -85,19 +71,16 @@ public: void setFrameRate(int value); void setVSync(bool value); void setFilter(FilterType value); - void addShader(const QString &path); void addDefaultShader(); + void save(); private: RenderBehaviorType m_renderBehavior = SyncWithVideo; int m_framerate = -1; bool m_vsync = false; FilterType m_filter = Nearest; - ModifiedFlags m_modified = {}; QList m_shaders; }; -Q_DECLARE_OPERATORS_FOR_FLAGS(OpenGLOptions::ModifiedFlags) - #endif diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index 206cf0a69..c864d88e5 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -250,34 +250,32 @@ OpenGLRenderer::setupBuffers() void OpenGLRenderer::applyOptions() { - /* TODO: make something else; this was a bad idea. */ + /* TODO: change detection in options */ - auto modified = options->modified(); - - if (modified.testFlag(OpenGLOptions::FrameRateModified) && options->framerate() > 0) { + if (options->framerate() > 0) { int interval = (int) ceilf(1000.f / (float) options->framerate()); renderTimer->setInterval(std::chrono::milliseconds(interval)); } - if (modified.testFlag(OpenGLOptions::RenderBehaviorModified)) { - if (options->renderBehavior() == OpenGLOptions::TargetFramerate) - renderTimer->start(); - else - renderTimer->stop(); - } + if (options->renderBehavior() == OpenGLOptions::TargetFramerate) + renderTimer->start(); + else + renderTimer->stop(); - if (modified.testFlag(OpenGLOptions::VsyncModified)) { - auto format = this->format(); - format.setSwapInterval(options->vSync() ? 1 : 0); + auto format = this->format(); + int interval = options->vSync() ? 1 : 0; + + if (format.swapInterval() != interval) { + format.setSwapInterval(interval); setFormat(format); context->setFormat(format); } - if (modified.testFlag(OpenGLOptions::FilterModified)) { - GLint filter = options->filter() == OpenGLOptions::Linear ? GL_LINEAR : GL_NEAREST; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); - } + GLint filter = options->filter() == OpenGLOptions::Linear ? GL_LINEAR : GL_NEAREST; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); + + currentFilter = options->filter(); } void @@ -329,7 +327,7 @@ OpenGLRenderer::render() { context->makeCurrent(this); - if (options->isModified()) + if (options->filter() != currentFilter) applyOptions(); /* TODO: multiple shader passes */ diff --git a/src/qt/qt_openglrenderer.hpp b/src/qt/qt_openglrenderer.hpp index 1d8bc036d..d22bcb82c 100644 --- a/src/qt/qt_openglrenderer.hpp +++ b/src/qt/qt_openglrenderer.hpp @@ -79,6 +79,8 @@ private: GLuint textureID = 0; int frameCounter = 0; + OpenGLOptions::FilterType currentFilter; + void *unpackBuffer = nullptr; void initialize(); From c9714c9bfca3c5e5169b13d9d9d5c92c39184a7e Mon Sep 17 00:00:00 2001 From: ts-korhonen Date: Sun, 27 Feb 2022 20:22:28 +0200 Subject: [PATCH 13/37] qt: Try to fix linux gcc 11 build --- src/qt/qt_opengloptions.cpp | 4 +-- src/qt/qt_opengloptions.hpp | 59 +++++++++++++++++++------------ src/qt/qt_opengloptionsdialog.cpp | 2 +- src/qt/qt_openglrenderer.cpp | 40 ++++++++++----------- 4 files changed, 59 insertions(+), 46 deletions(-) diff --git a/src/qt/qt_opengloptions.cpp b/src/qt/qt_opengloptions.cpp index 995fd8401..720d61ef7 100644 --- a/src/qt/qt_opengloptions.cpp +++ b/src/qt/qt_opengloptions.cpp @@ -72,14 +72,14 @@ OpenGLOptions::OpenGLOptions(QObject *parent, bool loadConfig) } void -OpenGLOptions::save() +OpenGLOptions::save() const { video_vsync = m_vsync ? 1 : 0; video_framerate = m_renderBehavior == RenderBehaviorType::SyncWithVideo ? -1 : m_framerate; video_filter_method = m_filter == FilterType::Nearest ? 0 : 1; /* TODO: multiple shaders */ - auto path = m_shaders.first().path.toLocal8Bit(); + auto path = m_shaders.first().path().toLocal8Bit(); if (!path.isEmpty()) memcpy(video_shader, path.constData(), path.size()); diff --git a/src/qt/qt_opengloptions.hpp b/src/qt/qt_opengloptions.hpp index 728b3c4fd..d28b388ba 100644 --- a/src/qt/qt_opengloptions.hpp +++ b/src/qt/qt_opengloptions.hpp @@ -21,31 +21,44 @@ #include #include -struct OpenGLShaderPass { +class OpenGLShaderPass { +public: OpenGLShaderPass(QOpenGLShaderProgram *shader, const QString &path) - : shader(shader) - , path(path) - , vertex_coord(shader->attributeLocation("VertexCoord")) - , tex_coord(shader->attributeLocation("TexCoord")) - , color(shader->attributeLocation("Color")) - , mvp_matrix(shader->uniformLocation("MVPMatrix")) - , input_size(shader->uniformLocation("InputSize")) - , output_size(shader->uniformLocation("OutputSize")) - , texture_size(shader->uniformLocation("TextureSize")) - , frame_count(shader->uniformLocation("FrameCount")) + : m_shader(shader) + , m_path(path) + , m_vertex_coord(shader->attributeLocation("VertexCoord")) + , m_tex_coord(shader->attributeLocation("TexCoord")) + , m_color(shader->attributeLocation("Color")) + , m_mvp_matrix(shader->uniformLocation("MVPMatrix")) + , m_input_size(shader->uniformLocation("InputSize")) + , m_output_size(shader->uniformLocation("OutputSize")) + , m_texture_size(shader->uniformLocation("TextureSize")) + , m_frame_count(shader->uniformLocation("FrameCount")) { } - QOpenGLShaderProgram *shader; - const QString path; - const GLint vertex_coord; - const GLint tex_coord; - const GLint color; - const GLint mvp_matrix; - const GLint input_size; - const GLint output_size; - const GLint texture_size; - const GLint frame_count; + bool bind() const { return m_shader->bind(); } + const QString &path() const { return m_path; } + const GLint &vertex_coord() const { return m_vertex_coord; } + const GLint &tex_coord() const { return m_tex_coord; } + const GLint &color() const { return m_color; } + const GLint &mvp_matrix() const { return m_mvp_matrix; } + const GLint &input_size() const { return m_input_size; } + const GLint &output_size() const { return m_output_size; } + const GLint &texture_size() const { return m_texture_size; } + const GLint &frame_count() const { return m_frame_count; } + +private: + QOpenGLShaderProgram *m_shader; + QString m_path; + GLint m_vertex_coord; + GLint m_tex_coord; + GLint m_color; + GLint m_mvp_matrix; + GLint m_input_size; + GLint m_output_size; + GLint m_texture_size; + GLint m_frame_count; }; class OpenGLOptions : public QObject { @@ -65,7 +78,7 @@ public: bool vSync() const { return m_vsync; } FilterType filter() const; - QList shaders() const { return m_shaders; }; + const QList &shaders() const { return m_shaders; }; void setRenderBehavior(RenderBehaviorType value); void setFrameRate(int value); @@ -73,7 +86,7 @@ public: void setFilter(FilterType value); void addShader(const QString &path); void addDefaultShader(); - void save(); + void save() const; private: RenderBehaviorType m_renderBehavior = SyncWithVideo; diff --git a/src/qt/qt_opengloptionsdialog.cpp b/src/qt/qt_opengloptionsdialog.cpp index 4503e0b90..424b6468b 100644 --- a/src/qt/qt_opengloptionsdialog.cpp +++ b/src/qt/qt_opengloptionsdialog.cpp @@ -40,7 +40,7 @@ OpenGLOptionsDialog::OpenGLOptionsDialog(QWidget *parent, const OpenGLOptions &o ui->vsync->setChecked(options.vSync()); if (!options.shaders().isEmpty()) { - auto path = options.shaders().first().path; + auto path = options.shaders().first().path(); if (!path.isEmpty()) ui->shader->setPlainText(path); } diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index c864d88e5..b7bf8628f 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -281,45 +281,45 @@ OpenGLRenderer::applyOptions() void OpenGLRenderer::applyShader(const OpenGLShaderPass &shader) { - if (!shader.shader->bind()) + if (!shader.bind()) return; - if (shader.vertex_coord != -1) { - glEnableVertexAttribArray(shader.vertex_coord); - glVertexAttribPointer(shader.vertex_coord, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), 0); + if (shader.vertex_coord() != -1) { + glEnableVertexAttribArray(shader.vertex_coord()); + glVertexAttribPointer(shader.vertex_coord(), 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), 0); } - if (shader.tex_coord != -1) { - glEnableVertexAttribArray(shader.tex_coord); - glVertexAttribPointer(shader.tex_coord, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void *) (2 * sizeof(GLfloat))); + if (shader.tex_coord() != -1) { + glEnableVertexAttribArray(shader.tex_coord()); + glVertexAttribPointer(shader.tex_coord(), 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void *) (2 * sizeof(GLfloat))); } - if (shader.color != -1) { - glEnableVertexAttribArray(shader.color); - glVertexAttribPointer(shader.color, 4, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void *) (4 * sizeof(GLfloat))); + if (shader.color() != -1) { + glEnableVertexAttribArray(shader.color()); + glVertexAttribPointer(shader.color(), 4, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void *) (4 * sizeof(GLfloat))); } - if (shader.mvp_matrix != -1) { + if (shader.mvp_matrix() != -1) { static const GLfloat mvp[] = { 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f }; - glUniformMatrix4fv(shader.mvp_matrix, 1, GL_FALSE, mvp); + glUniformMatrix4fv(shader.mvp_matrix(), 1, GL_FALSE, mvp); } - if (shader.output_size != -1) - glUniform2f(shader.output_size, destination.width(), destination.height()); + if (shader.output_size() != -1) + glUniform2f(shader.output_size(), destination.width(), destination.height()); - if (shader.input_size != -1) - glUniform2f(shader.input_size, source.width(), source.height()); + if (shader.input_size() != -1) + glUniform2f(shader.input_size(), source.width(), source.height()); - if (shader.texture_size != -1) - glUniform2f(shader.texture_size, source.width(), source.height()); + if (shader.texture_size() != -1) + glUniform2f(shader.texture_size(), source.width(), source.height()); - if (shader.frame_count != -1) - glUniform1i(shader.frame_count, frameCounter); + if (shader.frame_count() != -1) + glUniform1i(shader.frame_count(), frameCounter); } void From 08014dc5b56287a9d1c6b8bf631b995773461e72 Mon Sep 17 00:00:00 2001 From: ts-korhonen Date: Sun, 27 Feb 2022 20:55:59 +0200 Subject: [PATCH 14/37] qt: Change include for opengl extensions. Trying to fix macOS builds. --- src/qt/qt_openglrenderer.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_openglrenderer.hpp b/src/qt/qt_openglrenderer.hpp index d22bcb82c..e5d1304a8 100644 --- a/src/qt/qt_openglrenderer.hpp +++ b/src/qt/qt_openglrenderer.hpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include From 4ec8e80042b1cd2cae7953f27f281d82c47dd4f6 Mon Sep 17 00:00:00 2001 From: ts-korhonen Date: Sun, 27 Feb 2022 20:56:47 +0200 Subject: [PATCH 15/37] qt: Fix shader path copying to config. memcpy corrupted the path, use strcpy instead. --- src/qt/qt_opengloptions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_opengloptions.cpp b/src/qt/qt_opengloptions.cpp index 720d61ef7..72f649b53 100644 --- a/src/qt/qt_opengloptions.cpp +++ b/src/qt/qt_opengloptions.cpp @@ -82,7 +82,7 @@ OpenGLOptions::save() const auto path = m_shaders.first().path().toLocal8Bit(); if (!path.isEmpty()) - memcpy(video_shader, path.constData(), path.size()); + strcpy(video_shader, path.constData()); else video_shader[0] = '\0'; } From d3b00ff27b47b5b23b42f3fd7dcf196e759e2c36 Mon Sep 17 00:00:00 2001 From: ts-korhonen Date: Sun, 27 Feb 2022 21:57:14 +0200 Subject: [PATCH 16/37] qt: Disable OpenGL 3.0 renderer for macOS. Until it's figured out, macOS has dummy implementation to keep it building. --- src/qt/CMakeLists.txt | 20 ++++++++++++------- src/qt/qt_mainwindow.cpp | 3 +++ src/qt/qt_opengldummy.hpp | 40 +++++++++++++++++++++++++++++++++++++ src/qt/qt_rendererstack.cpp | 8 +++++++- 4 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 src/qt/qt_opengldummy.hpp diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 1d9c4187e..6749da29f 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -49,13 +49,6 @@ add_library(ui STATIC qt_softwarerenderer.hpp qt_hardwarerenderer.cpp qt_hardwarerenderer.hpp - qt_openglrenderer.cpp - qt_openglrenderer.hpp - qt_opengloptions.cpp - qt_opengloptions.hpp - qt_opengloptionsdialog.cpp - qt_opengloptionsdialog.hpp - qt_opengloptionsdialog.ui qt_settings.cpp qt_settings.hpp @@ -137,6 +130,19 @@ add_library(ui STATIC ../qt_resources.qrc ) +if(NOT APPLE) + target_sources(ui PRIVATE + qt_openglrenderer.cpp + qt_openglrenderer.hpp + qt_opengloptions.cpp + qt_opengloptions.hpp + qt_opengloptionsdialog.cpp + qt_opengloptionsdialog.hpp + qt_opengloptionsdialog.ui + ) +else() + target_sources(ui PRIVATE qt_opengldummy.hpp) +endif() if(WIN32) enable_language(RC) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index e9e7548cf..655fe5b58 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -231,6 +231,9 @@ MainWindow::MainWindow(QWidget *parent) : ui->actionHardware_Renderer_OpenGL_ES->setVisible(QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES); if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGLES && vid_api == 2) vid_api = 1; #endif +#ifdef Q_OS_MACOS + ui->actionOpenGL_3_0_Core->setVisible(false); +#endif if (QApplication::platformName().contains("eglfs") && vid_api >= 1) { fprintf(stderr, "OpenGL renderers are unsupported on EGLFS.\n"); diff --git a/src/qt/qt_opengldummy.hpp b/src/qt/qt_opengldummy.hpp new file mode 100644 index 000000000..6ff9a79b9 --- /dev/null +++ b/src/qt/qt_opengldummy.hpp @@ -0,0 +1,40 @@ +#ifndef QT_OPENGLDUMMY_HPP +#define QT_OPENGLDUMMY_HPP + +#include +#include +#include + +#include +#include +#include + +#include "qt_renderercommon.hpp" + +/* Dummy implementation of OpenGLRenderer so macOS builds. */ +class OpenGLRenderer : public QWindow, public RendererCommon { + Q_OBJECT +public: + OpenGLRenderer(QWidget *parent = nullptr) { emit errorInitializing(); } + virtual std::vector> getBuffers() { return std::vector>(); } + +signals: + void initialized(); + void errorInitializing(); + +public slots: + void onBlit(int buf_idx, int x, int y, int w, int h) { } + +protected: + void exposeEvent(QExposeEvent *event) override + { + if (!done) + emit errorInitializing(); + done = true; + } + +private: + bool done = false; +}; + +#endif \ No newline at end of file diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index be783864d..07762c5ef 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -22,15 +22,21 @@ #include "ui_qt_rendererstack.h" #include "qt_hardwarerenderer.hpp" -#include "qt_openglrenderer.hpp" #include "qt_softwarerenderer.hpp" +#ifndef Q_OS_MACOS +# include "qt_openglrenderer.hpp" +#else +# include "qt_opengldummy.hpp" +#endif + #include "qt_mainwindow.hpp" #include "qt_util.hpp" #include "evdev_mouse.hpp" #include +#include #ifdef __APPLE__ # include From ed22399f4bf55611d34aae54a7d661c84f4ec46f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 28 Feb 2022 12:16:43 +0600 Subject: [PATCH 17/37] qt: Actually make client-side Unix manager functional --- src/qt/qt_main.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index a8d9e2387..7ec4930d2 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -241,6 +241,16 @@ int main(int argc, char* argv[]) { UnixManagerSocket socket; if (qgetenv("86BOX_MANAGER_SOCKET").size()) { + QObject::connect(&socket, &UnixManagerSocket::showsettings, main_window, &MainWindow::showSettings); + QObject::connect(&socket, &UnixManagerSocket::pause, main_window, &MainWindow::togglePause); + QObject::connect(&socket, &UnixManagerSocket::reset, main_window, &MainWindow::hardReset); + QObject::connect(&socket, &UnixManagerSocket::request_shutdown, main_window, &MainWindow::close); + QObject::connect(&socket, &UnixManagerSocket::force_shutdown, [](){ + do_stop(); + emit main_window->close(); + }); + QObject::connect(&socket, &UnixManagerSocket::ctrlaltdel, [](){ pc_send_cad(); }); + main_window->installEventFilter(&socket); socket.connectToServer(qgetenv("86BOX_MANAGER_SOCKET")); } pc_reset_hard_init(); From 9af1d0cc5f1ec6b082aec3f3cf7d3093fd707293 Mon Sep 17 00:00:00 2001 From: ts-korhonen Date: Mon, 28 Feb 2022 08:43:14 +0200 Subject: [PATCH 18/37] Revert "qt: Disable OpenGL 3.0 renderer for macOS." This reverts commit d3b00ff27b47b5b23b42f3fd7dcf196e759e2c36. --- src/qt/CMakeLists.txt | 20 +++++++------------ src/qt/qt_mainwindow.cpp | 3 --- src/qt/qt_opengldummy.hpp | 40 ------------------------------------- src/qt/qt_rendererstack.cpp | 8 +------- 4 files changed, 8 insertions(+), 63 deletions(-) delete mode 100644 src/qt/qt_opengldummy.hpp diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 6749da29f..1d9c4187e 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -49,6 +49,13 @@ add_library(ui STATIC qt_softwarerenderer.hpp qt_hardwarerenderer.cpp qt_hardwarerenderer.hpp + qt_openglrenderer.cpp + qt_openglrenderer.hpp + qt_opengloptions.cpp + qt_opengloptions.hpp + qt_opengloptionsdialog.cpp + qt_opengloptionsdialog.hpp + qt_opengloptionsdialog.ui qt_settings.cpp qt_settings.hpp @@ -130,19 +137,6 @@ add_library(ui STATIC ../qt_resources.qrc ) -if(NOT APPLE) - target_sources(ui PRIVATE - qt_openglrenderer.cpp - qt_openglrenderer.hpp - qt_opengloptions.cpp - qt_opengloptions.hpp - qt_opengloptionsdialog.cpp - qt_opengloptionsdialog.hpp - qt_opengloptionsdialog.ui - ) -else() - target_sources(ui PRIVATE qt_opengldummy.hpp) -endif() if(WIN32) enable_language(RC) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 655fe5b58..e9e7548cf 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -231,9 +231,6 @@ MainWindow::MainWindow(QWidget *parent) : ui->actionHardware_Renderer_OpenGL_ES->setVisible(QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES); if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGLES && vid_api == 2) vid_api = 1; #endif -#ifdef Q_OS_MACOS - ui->actionOpenGL_3_0_Core->setVisible(false); -#endif if (QApplication::platformName().contains("eglfs") && vid_api >= 1) { fprintf(stderr, "OpenGL renderers are unsupported on EGLFS.\n"); diff --git a/src/qt/qt_opengldummy.hpp b/src/qt/qt_opengldummy.hpp deleted file mode 100644 index 6ff9a79b9..000000000 --- a/src/qt/qt_opengldummy.hpp +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef QT_OPENGLDUMMY_HPP -#define QT_OPENGLDUMMY_HPP - -#include -#include -#include - -#include -#include -#include - -#include "qt_renderercommon.hpp" - -/* Dummy implementation of OpenGLRenderer so macOS builds. */ -class OpenGLRenderer : public QWindow, public RendererCommon { - Q_OBJECT -public: - OpenGLRenderer(QWidget *parent = nullptr) { emit errorInitializing(); } - virtual std::vector> getBuffers() { return std::vector>(); } - -signals: - void initialized(); - void errorInitializing(); - -public slots: - void onBlit(int buf_idx, int x, int y, int w, int h) { } - -protected: - void exposeEvent(QExposeEvent *event) override - { - if (!done) - emit errorInitializing(); - done = true; - } - -private: - bool done = false; -}; - -#endif \ No newline at end of file diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 07762c5ef..be783864d 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -22,21 +22,15 @@ #include "ui_qt_rendererstack.h" #include "qt_hardwarerenderer.hpp" +#include "qt_openglrenderer.hpp" #include "qt_softwarerenderer.hpp" -#ifndef Q_OS_MACOS -# include "qt_openglrenderer.hpp" -#else -# include "qt_opengldummy.hpp" -#endif - #include "qt_mainwindow.hpp" #include "qt_util.hpp" #include "evdev_mouse.hpp" #include -#include #ifdef __APPLE__ # include From 08e199380819519fd7cf12f892031d484709d514 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 28 Feb 2022 12:43:24 +0600 Subject: [PATCH 19/37] qt: Fix building with Qt 5 --- src/qt/qt_unixmanagerfilter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_unixmanagerfilter.cpp b/src/qt/qt_unixmanagerfilter.cpp index 88557dcf4..d240e9d5f 100644 --- a/src/qt/qt_unixmanagerfilter.cpp +++ b/src/qt/qt_unixmanagerfilter.cpp @@ -32,7 +32,7 @@ void UnixManagerSocket::readyToRead() if (line.size()) { line.resize(line.size() - 2); - line.push_back((unsigned char)0); + line.push_back('\0'); if (line == "showsettings") { emit showsettings(); From b1bd408aeb70b52de779afc52f2f9d78a0b7d252 Mon Sep 17 00:00:00 2001 From: ts-korhonen Date: Mon, 28 Feb 2022 19:55:51 +0200 Subject: [PATCH 20/37] Revert "qt: Change include for opengl extensions." This reverts commit 08014dc5b56287a9d1c6b8bf631b995773461e72. --- src/qt/qt_openglrenderer.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_openglrenderer.hpp b/src/qt/qt_openglrenderer.hpp index e5d1304a8..d22bcb82c 100644 --- a/src/qt/qt_openglrenderer.hpp +++ b/src/qt/qt_openglrenderer.hpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include From 911c300123f2e2686f55735722489038d5f2f1b5 Mon Sep 17 00:00:00 2001 From: ts-korhonen Date: Mon, 28 Feb 2022 21:55:58 +0200 Subject: [PATCH 21/37] qt: add missing call to glBufferSubData --- src/qt/qt_openglrenderer.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index b7bf8628f..ff2cd7ac8 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -390,6 +390,9 @@ OpenGLRenderer::onBlit(int buf_idx, int x, int y, int w, int h) glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBufferID); } + if (!hasBufferStorage) + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, BUFFERBYTES * buf_idx, h * ROW_LENGTH * sizeof(uint32_t), (byte *) unpackBuffer + BUFFERBYTES * buf_idx); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, BUFFERPIXELS * buf_idx + y * ROW_LENGTH + x); glPixelStorei(GL_UNPACK_ROW_LENGTH, ROW_LENGTH); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); From 7af00696935545e336d2b86fbd5b440104e5a8d5 Mon Sep 17 00:00:00 2001 From: ts-korhonen Date: Mon, 28 Feb 2022 22:13:11 +0200 Subject: [PATCH 22/37] qt: QOpenGLFunctions_3_0 -> QOpenGLExtraFunctions --- src/qt/qt_openglrenderer.cpp | 31 ++++++++----------------------- src/qt/qt_openglrenderer.hpp | 31 +++++++++---------------------- 2 files changed, 17 insertions(+), 45 deletions(-) diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index ff2cd7ac8..4e1431874 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -104,9 +104,9 @@ OpenGLRenderer::event(QEvent *event) void OpenGLRenderer::initialize() { - if (!context->makeCurrent(this) || !initializeOpenGLFunctions()) { + if (!context->makeCurrent(this)) { /* TODO: This could be done much better */ - QMessageBox::critical((QWidget *) qApp->findChild(), tr("Error initializing OpenGL"), tr("OpenGL functions could not be initialized. Falling back to software rendering.")); + QMessageBox::critical((QWidget *) qApp->findChild(), tr("Error initializing OpenGL"), tr("Error setting OpenGL context. Falling back to software rendering.")); context->doneCurrent(); isFinalized = true; isInitialized = true; @@ -114,6 +114,8 @@ OpenGLRenderer::initialize() return; } + initializeOpenGLFunctions(); + setupExtensions(); setupBuffers(); @@ -199,32 +201,13 @@ OpenGLRenderer::getOptions(QWidget *parent) void OpenGLRenderer::setupExtensions() { +#ifndef Q_OS_MACOS if (context->hasExtension("GL_ARB_buffer_storage")) { hasBufferStorage = true; glBufferStorage = (PFNGLBUFFERSTORAGEPROC) context->getProcAddress("glBufferStorage"); } - - if (context->hasExtension("GL_ARB_debug_output")) { - hasDebugOutput = true; - - glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC) context->getProcAddress("glDebugMessageControlARB"); - glDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC) context->getProcAddress("glDebugMessageInsertARB"); - glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC) context->getProcAddress("glDebugMessageCallbackARB"); - glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC) context->getProcAddress("glGetDebugMessageLogARB"); - } - - if (context->hasExtension("GL_ARB_sync")) { - hasSync = true; - - glFenceSync = (PFNGLFENCESYNCPROC) context->getProcAddress("glFenceSync"); - glIsSync = (PFNGLISSYNCPROC) context->getProcAddress("glIsSync"); - glDeleteSync = (PFNGLDELETESYNCPROC) context->getProcAddress("glDeleteSync"); - glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) context->getProcAddress("glClientWaitSync"); - glWaitSync = (PFNGLWAITSYNCPROC) context->getProcAddress("glWaitSync"); - glGetInteger64v = (PFNGLGETINTEGER64VPROC) context->getProcAddress("glGetInteger64v"); - glGetSynciv = (PFNGLGETSYNCIVPROC) context->getProcAddress("glGetSynciv"); - } +#endif } void @@ -235,10 +218,12 @@ OpenGLRenderer::setupBuffers() glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBufferID); if (hasBufferStorage) { +#ifndef Q_OS_MACOS /* Create persistent buffer for pixel transfer. */ glBufferStorage(GL_PIXEL_UNPACK_BUFFER, BUFFERBYTES * BUFFERCOUNT, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); unpackBuffer = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, BUFFERBYTES * BUFFERCOUNT, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); +#endif } else { /* Fallback; create our own buffer. */ unpackBuffer = malloc(BUFFERBYTES * BUFFERCOUNT); diff --git a/src/qt/qt_openglrenderer.hpp b/src/qt/qt_openglrenderer.hpp index d22bcb82c..bbd0c1f01 100644 --- a/src/qt/qt_openglrenderer.hpp +++ b/src/qt/qt_openglrenderer.hpp @@ -18,12 +18,14 @@ #define QT_OPENGLRENDERER_HPP #include -#include +#include #include #include #include #include -#include +#ifndef Q_OS_MACOS +# include +#endif #include #include @@ -32,7 +34,7 @@ #include "qt_opengloptions.hpp" #include "qt_renderercommon.hpp" -class OpenGLRenderer : public QWindow, protected QOpenGLFunctions_3_0, public RendererCommon { +class OpenGLRenderer : public QWindow, protected QOpenGLExtraFunctions, public RendererCommon { Q_OBJECT public: @@ -91,25 +93,10 @@ private: bool notReady() const { return !isInitialized || isFinalized; } /* GL_ARB_buffer_storage */ - bool hasBufferStorage = false; - PFNGLBUFFERSTORAGEPROC glBufferStorage = nullptr; - - /* GL_ARB_debug_output */ - bool hasDebugOutput = false; - PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB = nullptr; - PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB = nullptr; - PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB = nullptr; - PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLogARB = nullptr; - - /* GL_ARB_sync */ - bool hasSync = false; - PFNGLFENCESYNCPROC glFenceSync = nullptr; - PFNGLISSYNCPROC glIsSync = nullptr; - PFNGLDELETESYNCPROC glDeleteSync = nullptr; - PFNGLCLIENTWAITSYNCPROC glClientWaitSync = nullptr; - PFNGLWAITSYNCPROC glWaitSync = nullptr; - PFNGLGETINTEGER64VPROC glGetInteger64v = nullptr; - PFNGLGETSYNCIVPROC glGetSynciv = nullptr; + bool hasBufferStorage = false; +#ifndef Q_OS_MACOS + PFNGLBUFFERSTORAGEPROC glBufferStorage = nullptr; +#endif private slots: void render(); From 16e98249c1086f5563d666014fb7e2036f2d996c Mon Sep 17 00:00:00 2001 From: ts-korhonen Date: Mon, 28 Feb 2022 22:29:06 +0200 Subject: [PATCH 23/37] qt: fix build error --- src/qt/qt_openglrenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index 4e1431874..077772a95 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -376,7 +376,7 @@ OpenGLRenderer::onBlit(int buf_idx, int x, int y, int w, int h) } if (!hasBufferStorage) - glBufferSubData(GL_PIXEL_UNPACK_BUFFER, BUFFERBYTES * buf_idx, h * ROW_LENGTH * sizeof(uint32_t), (byte *) unpackBuffer + BUFFERBYTES * buf_idx); + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, BUFFERBYTES * buf_idx, h * ROW_LENGTH * sizeof(uint32_t), (uint8_t *) unpackBuffer + BUFFERBYTES * buf_idx); glPixelStorei(GL_UNPACK_SKIP_PIXELS, BUFFERPIXELS * buf_idx + y * ROW_LENGTH + x); glPixelStorei(GL_UNPACK_ROW_LENGTH, ROW_LENGTH); From 5a6b8501cef9dffeaf684d8ea6745ace023bf69c Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 1 Mar 2022 12:12:07 +0600 Subject: [PATCH 24/37] qt: Fix building with Qt 6 --- src/qt/qt_openglrenderer.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_openglrenderer.hpp b/src/qt/qt_openglrenderer.hpp index bbd0c1f01..83490f293 100644 --- a/src/qt/qt_openglrenderer.hpp +++ b/src/qt/qt_openglrenderer.hpp @@ -23,7 +23,7 @@ #include #include #include -#ifndef Q_OS_MACOS +#if !defined Q_OS_MACOS && !(QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) # include #endif From ee69b022fc880145384e1b33717c415eecd04ee0 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 1 Mar 2022 13:31:19 +0600 Subject: [PATCH 25/37] qt: OpenGL ES 3.0 support --- src/qt/qt_mainwindow.cpp | 2 ++ src/qt/qt_opengloptions.cpp | 28 ++++++++++++++++++++++++++-- src/qt/qt_opengloptions.hpp | 1 + src/qt/qt_openglrenderer.cpp | 3 ++- src/qt/qt_openglrenderer.hpp | 2 +- 5 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index e9e7548cf..0c1d88fb8 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -231,6 +231,8 @@ MainWindow::MainWindow(QWidget *parent) : ui->actionHardware_Renderer_OpenGL_ES->setVisible(QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES); if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGLES && vid_api == 2) vid_api = 1; #endif + ui->actionHardware_Renderer_OpenGL->setVisible(QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGLES); + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES && vid_api == 1) vid_api = 0; if (QApplication::platformName().contains("eglfs") && vid_api >= 1) { fprintf(stderr, "OpenGL renderers are unsupported on EGLFS.\n"); diff --git a/src/qt/qt_opengloptions.cpp b/src/qt/qt_opengloptions.cpp index 72f649b53..26b8f05fe 100644 --- a/src/qt/qt_opengloptions.cpp +++ b/src/qt/qt_opengloptions.cpp @@ -45,6 +45,25 @@ void main() {\n\ color = texture(texsampler, tex);\n\ }\n"; +/* Default vertex shader (OpenGL ES 3). */ +static const GLchar *vertex_shader_es3 = "#version 300 es\n\ +in vec2 VertexCoord;\n\ +in vec2 TexCoord;\n\ +out vec2 tex;\n\ +void main(){\n\ + gl_Position = vec4(VertexCoord, 0.0, 1.0);\n\ + tex = TexCoord;\n\ +}\n"; + +/* Default fragment shader (OpenGL ES 3). */ +static const GLchar *fragment_shader_es3 = "#version 300 es\n\ +in vec2 tex;\n\ +uniform sampler2D texsampler;\n\ +out vec4 color;\n\ +void main() {\n\ + color = texture(texsampler, tex);\n\ +}\n"; + OpenGLOptions::OpenGLOptions(QObject *parent, bool loadConfig) : QObject(parent) { @@ -149,6 +168,11 @@ OpenGLOptions::addShader(const QString &path) shader_text.remove(version); } + if (QOpenGLContext::currentContext() && QOpenGLContext::currentContext()->isOpenGLES()) + { + /* Force #version 300 es (the default of #version 100 es is too old and too limited) */ + version_line = "#version 300 es"; + } auto shader = new QOpenGLShaderProgram(this); auto throw_shader_error = [path, shader](const QString &what) { @@ -175,8 +199,8 @@ void OpenGLOptions::addDefaultShader() { auto shader = new QOpenGLShaderProgram(this); - shader->addShaderFromSourceCode(QOpenGLShader::Vertex, vertex_shader); - shader->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment_shader); + shader->addShaderFromSourceCode(QOpenGLShader::Vertex, QOpenGLContext::currentContext() && QOpenGLContext::currentContext()->isOpenGLES() ? vertex_shader_es3 : vertex_shader); + shader->addShaderFromSourceCode(QOpenGLShader::Fragment, QOpenGLContext::currentContext() && QOpenGLContext::currentContext()->isOpenGLES() ? fragment_shader_es3 : fragment_shader); shader->link(); m_shaders << OpenGLShaderPass(shader, QString()); } diff --git a/src/qt/qt_opengloptions.hpp b/src/qt/qt_opengloptions.hpp index d28b388ba..45a11377a 100644 --- a/src/qt/qt_opengloptions.hpp +++ b/src/qt/qt_opengloptions.hpp @@ -19,6 +19,7 @@ #include #include +#include #include class OpenGLShaderPass { diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index 077772a95..b1a911841 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -43,6 +43,7 @@ OpenGLRenderer::OpenGLRenderer(QWidget *parent) format.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile); format.setMajorVersion(3); format.setMinorVersion(0); + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) format.setRenderableType(QSurfaceFormat::OpenGLES); setFormat(format); @@ -389,4 +390,4 @@ OpenGLRenderer::onBlit(int buf_idx, int x, int y, int w, int h) if (options->renderBehavior() == OpenGLOptions::SyncWithVideo) render(); -} \ No newline at end of file +} diff --git a/src/qt/qt_openglrenderer.hpp b/src/qt/qt_openglrenderer.hpp index bbd0c1f01..83490f293 100644 --- a/src/qt/qt_openglrenderer.hpp +++ b/src/qt/qt_openglrenderer.hpp @@ -23,7 +23,7 @@ #include #include #include -#ifndef Q_OS_MACOS +#if !defined Q_OS_MACOS && !(QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) # include #endif From e6f5018d51d002f28625d8c5aaa768006f3ffa22 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 1 Mar 2022 14:20:11 +0100 Subject: [PATCH 26/37] Added the Corel LS2000 53c400-based card. --- src/include/86box/scsi_ncr5380.h | 1 + src/scsi/scsi.c | 1 + src/scsi/scsi_ncr5380.c | 39 ++++++++++++++++++++++++++++---- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/include/86box/scsi_ncr5380.h b/src/include/86box/scsi_ncr5380.h index 380f379e6..6053e0275 100644 --- a/src/include/86box/scsi_ncr5380.h +++ b/src/include/86box/scsi_ncr5380.h @@ -28,6 +28,7 @@ extern const device_t scsi_lcs6821n_device; extern const device_t scsi_rt1000b_device; extern const device_t scsi_t128_device; extern const device_t scsi_t130b_device; +extern const device_t scsi_ls2000_device; #if defined(DEV_BRANCH) && defined(USE_SUMO) extern const device_t scsi_scsiat_device; #endif diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index 638c0bfaa..b898f9de8 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -77,6 +77,7 @@ static SCSI_CARD scsi_cards[] = { { &buslogic_542bh_device, }, { &buslogic_545s_device, }, { &buslogic_545c_device, }, + { &scsi_ls2000_device, }, { &scsi_lcs6821n_device, }, { &scsi_rt1000b_device, }, { &scsi_t128_device, }, diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index 60f4632e3..083efabe4 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -48,6 +48,7 @@ #define RT1000B_820R_ROM "roms/scsi/ncr5380/RTBIOS82.ROM" #define T130B_ROM "roms/scsi/ncr5380/trantor_t130b_bios_v2.14.bin" #define T128_ROM "roms/scsi/ncr5380/trantor_t128_bios_v1.12.bin" +#define COREL_LS2000_ROM "roms/scsi/ncr5380/Corel LS2000 - BIOS ROM - Ver 1.65.bin" #define NCR_CURDATA 0 /* current SCSI data (read only) */ @@ -712,7 +713,7 @@ ncr_write(uint16_t port, uint8_t val, void *priv) break; } - if (ncr->dma_mode == DMA_IDLE || ncr_dev->type == 0 || ncr_dev->type == 3) { + if (ncr->dma_mode == DMA_IDLE || ncr_dev->type == 0 || ncr_dev->type >= 3) { bus_host = get_bus_host(ncr); ncr_bus_update(priv, bus_host); } @@ -1079,9 +1080,9 @@ ncr_dma_send(ncr5380_t *ncr_dev, ncr_t *ncr, scsi_device_t *dev) } /* Data ready. */ - if (ncr_dev->type == 3) { + if (ncr_dev->type == 3) data = ncr_dev->t128.buffer[ncr_dev->t128.pos]; - } else + else data = ncr_dev->buffer[ncr_dev->buffer_pos]; bus = get_bus_host(ncr) & ~BUS_DATAMASK; bus |= BUS_SETDATA(data); @@ -1506,6 +1507,18 @@ ncr_init(const device_t *info) t128_write, NULL, NULL, ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); break; + + case 4: /* Corel LS2000 */ + ncr_dev->rom_addr = device_get_config_hex20("bios_addr"); + ncr_dev->irq = device_get_config_int("irq"); + rom_init(&ncr_dev->bios_rom, COREL_LS2000_ROM, + ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000, + memio_read, NULL, NULL, + memio_write, NULL, NULL, + ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); + break; } sprintf(temp, "%s: BIOS=%05X", ncr_dev->name, ncr_dev->rom_addr); @@ -1516,7 +1529,7 @@ ncr_init(const device_t *info) ncr_log("%s\n", temp); ncr_reset(ncr_dev, &ncr_dev->ncr); - if (ncr_dev->type < 3) { + if (ncr_dev->type < 3 || ncr_dev->type == 4) { ncr_dev->status_ctrl = STATUS_BUFFER_NOT_READY; ncr_dev->buffer_host_pos = 128; } else { @@ -1572,6 +1585,12 @@ t128_available(void) return(rom_present(T128_ROM)); } +static int +corel_ls2000_available(void) +{ + return(rom_present(COREL_LS2000_ROM)); +} + // clang-format off static const device_config_t ncr5380_mmio_config[] = { { @@ -1735,3 +1754,15 @@ const device_t scsi_t128_device = NULL, NULL, t128_config }; + +const device_t scsi_ls2000_device = +{ + "Corel LS2000", + "ls2000", + DEVICE_ISA, + 4, + ncr_init, ncr_close, NULL, + { corel_ls2000_available }, + NULL, NULL, + ncr5380_mmio_config +}; From 61239efa39ca75ef1c3c28f76e869be57daf1650 Mon Sep 17 00:00:00 2001 From: ts-korhonen Date: Tue, 1 Mar 2022 19:15:12 +0200 Subject: [PATCH 27/37] qt: fix linux arm32 build error --- src/qt/qt_openglrenderer.cpp | 4 ++-- src/qt/qt_openglrenderer.hpp | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index b1a911841..173e82448 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -202,7 +202,7 @@ OpenGLRenderer::getOptions(QWidget *parent) void OpenGLRenderer::setupExtensions() { -#ifndef Q_OS_MACOS +#ifndef NO_BUFFER_STORAGE if (context->hasExtension("GL_ARB_buffer_storage")) { hasBufferStorage = true; @@ -219,7 +219,7 @@ OpenGLRenderer::setupBuffers() glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBufferID); if (hasBufferStorage) { -#ifndef Q_OS_MACOS +#ifndef NO_BUFFER_STORAGE /* Create persistent buffer for pixel transfer. */ glBufferStorage(GL_PIXEL_UNPACK_BUFFER, BUFFERBYTES * BUFFERCOUNT, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); diff --git a/src/qt/qt_openglrenderer.hpp b/src/qt/qt_openglrenderer.hpp index 83490f293..47bc82c22 100644 --- a/src/qt/qt_openglrenderer.hpp +++ b/src/qt/qt_openglrenderer.hpp @@ -17,13 +17,17 @@ #ifndef QT_OPENGLRENDERER_HPP #define QT_OPENGLRENDERER_HPP +#if defined Q_OS_MACOS || __arm__ +# define NO_BUFFER_STORAGE +#endif + #include #include #include #include #include #include -#if !defined Q_OS_MACOS && !(QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +#if !defined NO_BUFFER_STORAGE && !(QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) # include #endif @@ -94,7 +98,7 @@ private: /* GL_ARB_buffer_storage */ bool hasBufferStorage = false; -#ifndef Q_OS_MACOS +#ifndef NO_BUFFER_STORAGE PFNGLBUFFERSTORAGEPROC glBufferStorage = nullptr; #endif From 109683300aee350d910d9f7bdd4e4e7624c2c59c Mon Sep 17 00:00:00 2001 From: ts-korhonen Date: Tue, 1 Mar 2022 22:20:19 +0200 Subject: [PATCH 28/37] qt: Add fallback to default shader on load --- src/qt/qt_opengloptions.cpp | 46 ++++++++++++------------------- src/qt/qt_opengloptionsdialog.cpp | 2 +- 2 files changed, 19 insertions(+), 29 deletions(-) diff --git a/src/qt/qt_opengloptions.cpp b/src/qt/qt_opengloptions.cpp index 26b8f05fe..3222d940c 100644 --- a/src/qt/qt_opengloptions.cpp +++ b/src/qt/qt_opengloptions.cpp @@ -27,7 +27,7 @@ extern "C" { } /* Default vertex shader. */ -static const GLchar *vertex_shader = "#version 130\n\ +static const GLchar *vertex_shader = "\ in vec2 VertexCoord;\n\ in vec2 TexCoord;\n\ out vec2 tex;\n\ @@ -37,26 +37,7 @@ void main(){\n\ }\n"; /* Default fragment shader. */ -static const GLchar *fragment_shader = "#version 130\n\ -in vec2 tex;\n\ -uniform sampler2D texsampler;\n\ -out vec4 color;\n\ -void main() {\n\ - color = texture(texsampler, tex);\n\ -}\n"; - -/* Default vertex shader (OpenGL ES 3). */ -static const GLchar *vertex_shader_es3 = "#version 300 es\n\ -in vec2 VertexCoord;\n\ -in vec2 TexCoord;\n\ -out vec2 tex;\n\ -void main(){\n\ - gl_Position = vec4(VertexCoord, 0.0, 1.0);\n\ - tex = TexCoord;\n\ -}\n"; - -/* Default fragment shader (OpenGL ES 3). */ -static const GLchar *fragment_shader_es3 = "#version 300 es\n\ +static const GLchar *fragment_shader = "\ in vec2 tex;\n\ uniform sampler2D texsampler;\n\ out vec4 color;\n\ @@ -84,10 +65,16 @@ OpenGLOptions::OpenGLOptions(QObject *parent, bool loadConfig) QString shaderPath(video_shader); - if (shaderPath.isEmpty()) + if (shaderPath.isEmpty()) { addDefaultShader(); - else - addShader(shaderPath); + } else { + try { + addShader(shaderPath); + } catch (const std::runtime_error &) { + /* Fallback to default shader */ + addDefaultShader(); + } + } } void @@ -168,8 +155,7 @@ OpenGLOptions::addShader(const QString &path) shader_text.remove(version); } - if (QOpenGLContext::currentContext() && QOpenGLContext::currentContext()->isOpenGLES()) - { + if (QOpenGLContext::currentContext() && QOpenGLContext::currentContext()->isOpenGLES()) { /* Force #version 300 es (the default of #version 100 es is too old and too limited) */ version_line = "#version 300 es"; } @@ -198,9 +184,13 @@ OpenGLOptions::addShader(const QString &path) void OpenGLOptions::addDefaultShader() { + QString version = QOpenGLContext::currentContext() && QOpenGLContext::currentContext()->isOpenGLES() + ? "#version 300 es\n" + : "#version 130\n"; + auto shader = new QOpenGLShaderProgram(this); - shader->addShaderFromSourceCode(QOpenGLShader::Vertex, QOpenGLContext::currentContext() && QOpenGLContext::currentContext()->isOpenGLES() ? vertex_shader_es3 : vertex_shader); - shader->addShaderFromSourceCode(QOpenGLShader::Fragment, QOpenGLContext::currentContext() && QOpenGLContext::currentContext()->isOpenGLES() ? fragment_shader_es3 : fragment_shader); + shader->addShaderFromSourceCode(QOpenGLShader::Vertex, version % vertex_shader); + shader->addShaderFromSourceCode(QOpenGLShader::Fragment, version % fragment_shader); shader->link(); m_shaders << OpenGLShaderPass(shader, QString()); } diff --git a/src/qt/qt_opengloptionsdialog.cpp b/src/qt/qt_opengloptionsdialog.cpp index 424b6468b..d996fbd3c 100644 --- a/src/qt/qt_opengloptionsdialog.cpp +++ b/src/qt/qt_opengloptionsdialog.cpp @@ -74,7 +74,7 @@ OpenGLOptionsDialog::accept() else options->addDefaultShader(); - } catch (std::runtime_error &e) { + } catch (const std::runtime_error &e) { delete options; QMessageBox msgBox(this); From f78a3f2c1029f1ca914f8b493a8e90b503cbff1b Mon Sep 17 00:00:00 2001 From: ts-korhonen Date: Tue, 1 Mar 2022 22:21:43 +0200 Subject: [PATCH 29/37] qt: try again to fix linux arm32 build error --- src/qt/qt_openglrenderer.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index 173e82448..f1e44f3a9 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -43,7 +44,8 @@ OpenGLRenderer::OpenGLRenderer(QWidget *parent) format.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile); format.setMajorVersion(3); format.setMinorVersion(0); - if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) format.setRenderableType(QSurfaceFormat::OpenGLES); + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) + format.setRenderableType(QSurfaceFormat::OpenGLES); setFormat(format); @@ -146,7 +148,7 @@ OpenGLRenderer::initialize() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, INIT_WIDTH, INIT_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, QOpenGLTexture::RGBA8_UNorm, INIT_WIDTH, INIT_HEIGHT, 0, QOpenGLTexture::BGRA, QOpenGLTexture::UInt32_RGBA8_Rev, NULL); options = new OpenGLOptions(this, true); @@ -372,7 +374,7 @@ OpenGLRenderer::onBlit(int buf_idx, int x, int y, int w, int h) /* Resize the texture */ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, source.width(), source.height(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, QOpenGLTexture::RGBA8_UNorm, source.width(), source.height(), 0, QOpenGLTexture::BGRA, QOpenGLTexture::UInt32_RGBA8_Rev, NULL); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBufferID); } @@ -381,7 +383,7 @@ OpenGLRenderer::onBlit(int buf_idx, int x, int y, int w, int h) glPixelStorei(GL_UNPACK_SKIP_PIXELS, BUFFERPIXELS * buf_idx + y * ROW_LENGTH + x); glPixelStorei(GL_UNPACK_ROW_LENGTH, ROW_LENGTH); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, QOpenGLTexture::BGRA, QOpenGLTexture::UInt32_RGBA8_Rev, NULL); /* TODO: check if fence sync is implementable here and still has any benefit. */ glFinish(); From c213f287b15d26a38335c96884c2497f9015973a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 2 Mar 2022 14:45:28 +0600 Subject: [PATCH 30/37] qt: Fix loading of shaders using GL_ARB_shading_language_420pack extension --- src/qt/qt_opengloptions.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_opengloptions.cpp b/src/qt/qt_opengloptions.cpp index 26b8f05fe..95f13f2df 100644 --- a/src/qt/qt_opengloptions.cpp +++ b/src/qt/qt_opengloptions.cpp @@ -183,10 +183,10 @@ OpenGLOptions::addShader(const QString &path) .toStdString()); }; - if (!shader->addShaderFromSourceCode(QOpenGLShader::Vertex, version_line % "\n#define VERTEX\n" % shader_text)) + if (!shader->addShaderFromSourceCode(QOpenGLShader::Vertex, version_line % "\n#extension GL_ARB_shading_language_420pack : enable\n" % "\n#define VERTEX\n" % shader_text)) throw_shader_error(tr("Error compiling vertex shader in file \"%1\"")); - if (!shader->addShaderFromSourceCode(QOpenGLShader::Fragment, version_line % "\n#define FRAGMENT\n" % shader_text)) + if (!shader->addShaderFromSourceCode(QOpenGLShader::Fragment, version_line % "\n#extension GL_ARB_shading_language_420pack : enable\n" "\n#define FRAGMENT\n" % shader_text)) throw_shader_error(tr("Error compiling fragment shader in file \"%1\"")); if (!shader->link()) From c1c0f68f81e6733c328978c180854b91379d2299 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 2 Mar 2022 14:48:33 +0600 Subject: [PATCH 31/37] qt: Make central widget expanding --- src/qt/qt_mainwindow.ui | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index 69197d015..60b77d290 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -15,7 +15,7 @@ - + 0 0 @@ -37,7 +37,14 @@ 0 - + + + + 0 + 0 + + + From ed954e4b2f59720fea71a2737e003899e3232585 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 2 Mar 2022 15:08:14 +0600 Subject: [PATCH 32/37] qt: Fix HiDPI scaling on OpenGL 3.0 renderer --- src/qt/qt_openglrenderer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index 173e82448..2ba45f081 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -87,8 +87,8 @@ OpenGLRenderer::resizeEvent(QResizeEvent *event) glViewport( destination.x(), destination.y(), - destination.width(), - destination.height()); + destination.width() * devicePixelRatio(), + destination.height() * devicePixelRatio()); } bool From 445ebb905f063c0488985b7ac948ad303ab1d885 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 2 Mar 2022 15:08:41 +0600 Subject: [PATCH 33/37] qt: More Settings UI inconsistency-with-Win32 fixes --- src/qt/qt_settingsmachine.ui | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/qt/qt_settingsmachine.ui b/src/qt/qt_settingsmachine.ui index fabb52fe9..30f375f7e 100644 --- a/src/qt/qt_settingsmachine.ui +++ b/src/qt/qt_settingsmachine.ui @@ -202,6 +202,12 @@ + + + 0 + 0 + + Time synchronization From 9da55289ed0c2579c86afef3e66292df59909a20 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 2 Mar 2022 15:14:17 +0600 Subject: [PATCH 34/37] qt: Fix building on AArch32 --- src/qt/qt_openglrenderer.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index 2ba45f081..eb5656d3b 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -372,7 +373,7 @@ OpenGLRenderer::onBlit(int buf_idx, int x, int y, int w, int h) /* Resize the texture */ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, source.width(), source.height(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, (GLenum)QOpenGLTexture::RGBA8_UNorm, source.width(), source.height(), 0, (GLenum)QOpenGLTexture::BGRA, (GLenum)QOpenGLTexture::UInt32_RGBA8_Rev, NULL); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBufferID); } @@ -381,7 +382,7 @@ OpenGLRenderer::onBlit(int buf_idx, int x, int y, int w, int h) glPixelStorei(GL_UNPACK_SKIP_PIXELS, BUFFERPIXELS * buf_idx + y * ROW_LENGTH + x); glPixelStorei(GL_UNPACK_ROW_LENGTH, ROW_LENGTH); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, (GLenum)QOpenGLTexture::BGRA, (GLenum)QOpenGLTexture::UInt32_RGBA8_Rev, NULL); /* TODO: check if fence sync is implementable here and still has any benefit. */ glFinish(); From c3c7864bd6344de8f03017e4536f1b043968a07d Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 2 Mar 2022 16:18:58 +0100 Subject: [PATCH 35/37] Added a legacy way to address some issues with the SVGA scrolling and such (such as Pinball Illusions on S3 cards, including the ViRGE). --- src/include/86box/vid_svga.h | 3 +- src/video/vid_s3.c | 207 ++++-- src/video/vid_s3_virge.c | 561 +++++++------- src/video/vid_svga.c | 13 +- src/video/vid_svga_render.c | 1353 +++++++++++++++++++++++----------- 5 files changed, 1373 insertions(+), 764 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 1e8cc2b91..1502fba2d 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -158,7 +158,8 @@ typedef struct svga_t /*Force CRTC to dword mode, regardless of CR14/CR17. Required for S3 enhanced mode*/ int force_dword_mode; - int force_byte_mode; + + int force_old_addr; int remap_required; uint32_t (*remap_func)(struct svga_t *svga, uint32_t in_addr); diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index e77817782..e8826f4e4 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -404,9 +404,9 @@ static void s3_pci_write(int func, int addr, uint8_t val, void *p); static __inline uint32_t dword_remap(svga_t *svga, uint32_t in_addr) { - if (svga->packed_chain4) + if (svga->packed_chain4 || svga->force_old_addr) return in_addr; - + return ((in_addr << 2) & 0x3fff0) | ((in_addr >> 14) & 0xc) | (in_addr & ~0x3fffc); @@ -414,9 +414,9 @@ dword_remap(svga_t *svga, uint32_t in_addr) static __inline uint32_t dword_remap_w(svga_t *svga, uint32_t in_addr) { - if (svga->packed_chain4) - return in_addr; - + if (svga->packed_chain4 || svga->force_old_addr) + return in_addr; + return ((in_addr << 2) & 0x1fff8) | ((in_addr >> 14) & 0x6) | (in_addr & ~0x1fffe); @@ -424,9 +424,9 @@ dword_remap_w(svga_t *svga, uint32_t in_addr) static __inline uint32_t dword_remap_l(svga_t *svga, uint32_t in_addr) { - if (svga->packed_chain4) - return in_addr; - + if (svga->packed_chain4 || svga->force_old_addr) + return in_addr; + return ((in_addr << 2) & 0xfffc) | ((in_addr >> 14) & 0x3) | (in_addr & ~0xffff); @@ -2552,6 +2552,7 @@ s3_out(uint16_t addr, uint8_t val, void *p) { case 0x31: s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4); + svga->force_dword_mode = !!(val & 0x08); break; case 0x32: if ((svga->crtc[0x31] & 0x30) && (svga->crtc[0x51] & 0x01) && (val & 0x40)) @@ -2971,7 +2972,6 @@ static void s3_recalctimings(svga_t *svga) } if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { - svga->fb_only = 1; switch (svga->bpp) { case 8: svga->render = svga_render_8bpp_highres; @@ -3154,7 +3154,6 @@ static void s3_recalctimings(svga_t *svga) break; } } else { - svga->fb_only = 0; if (!svga->scrblank && svga->attr_palette_enable) { if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { if ((svga->crtc[0x31] & 0x08) && ((svga->gdcreg[5] & 0x60) == 0x00)) { @@ -3208,7 +3207,6 @@ static void s3_trio64v_recalctimings(svga_t *svga) svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { - svga->fb_only = 1; switch (svga->bpp) { case 8: svga->render = svga_render_8bpp_highres; @@ -3229,13 +3227,10 @@ static void s3_trio64v_recalctimings(svga_t *svga) svga->render = svga_render_32bpp_highres; break; } - } else - svga->fb_only = 0; + } } else /*Streams mode*/ { - svga->fb_only = 1; - if (s3->streams.buffer_ctrl & 1) svga->ma_latch = s3->streams.pri_fb1 >> 2; else @@ -3379,7 +3374,12 @@ s3_updatemapping(s3_t *s3) mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size); } + if (s3->chip >= S3_TRIO64V) + svga->fb_only = 1; } else { + if (s3->chip >= S3_TRIO64V) + svga->fb_only = 0; + mem_mapping_disable(&s3->linear_mapping); } @@ -7140,6 +7140,8 @@ static void *s3_init(const device_t *info) s3->card_type = info->local; + svga->force_old_addr = 1; + switch(s3->card_type) { case S3_ORCHID_86C911: case S3_DIAMOND_STEALTH_VRAM: @@ -7401,8 +7403,6 @@ static void *s3_init(const device_t *info) return NULL; } - svga->packed_chain4 = 1; - if (s3->pci) s3->card = pci_add_card(PCI_ADD_VIDEO, s3_pci_read, s3_pci_write, s3); @@ -7609,73 +7609,124 @@ static void s3_force_redraw(void *p) s3->svga.fullchange = changeframecount; } -// clang-format off -static const device_config_t s3_orchid_86c911_config[] = { - { - "memory", "Memory size", CONFIG_SELECTION, "", 1, "", { 0 }, - { - { "512 KB", 0 }, - { "1 MB", 1 }, - { "" } - } - }, - { "", "", -1 } +static const device_config_t s3_orchid_86c911_config[] = +{ + { + "memory", "Memory size", CONFIG_SELECTION, "", 1, "", { 0 }, + { + { + "512 KB", 0 + }, + { + "1 MB", 1 + }, + { + "" + } + } + }, + { + "", "", -1 + } }; -static const device_config_t s3_9fx_config[] = { - { - "memory", "Memory size", CONFIG_SELECTION, "", 2, "", { 0 }, - { - { "1 MB", 1 }, - { "2 MB", 2 }, - /*Trio64 also supports 4 MB, however the Number Nine BIOS does not*/ - { "" } - } - }, - { "", "", -1 } +static const device_config_t s3_9fx_config[] = +{ + { + "memory", "Memory size", CONFIG_SELECTION, "", 2, "", { 0 }, + { + { + "1 MB", 1 + }, + { + "2 MB", 2 + }, + /*Trio64 also supports 4 MB, however the Number Nine BIOS does not*/ + { + "" + } + } + }, + { + "", "", -1 + } }; -static const device_config_t s3_phoenix_trio32_config[] = { - { - "memory", "Memory size", CONFIG_SELECTION, "", 2, "", { 0 }, - { - { "512 KB", 0 }, - { "1 MB", 1 }, - { "2 MB", 2 }, - { "" } - } - }, - { "", "", -1 } +static const device_config_t s3_phoenix_trio32_config[] = +{ + { + "memory", "Memory size", CONFIG_SELECTION, "", 2, "", { 0 }, + { + { + "512 KB", 0 + }, + { + "1 MB", 1 + }, + { + "2 MB", 2 + }, + { + "" + } + } + }, + { + "", "", -1 + } }; -static const device_config_t s3_standard_config[] = { - { - "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, - { - { "1 MB", 1 }, - { "2 MB", 2 }, - { "4 MB", 4 }, - { "" } - } - }, - { "", "", -1 } +static const device_config_t s3_standard_config[] = +{ + { + "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, + { + { + "1 MB", 1 + }, + { + "2 MB", 2 + }, + { + "4 MB", 4 + }, + { + "" + } + } + }, + { + "", "", -1 + } }; -static const device_config_t s3_968_config[] = { - { - "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, - { - { "1 MB", 1 }, - { "2 MB", 2 }, - { "4 MB", 4 }, - { "8 MB", 8 }, - { "" } - } - }, - { "", "", -1 } +static const device_config_t s3_968_config[] = +{ + { + "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, + { + { + "1 MB", 1 + }, + { + "2 MB", 2 + }, + { + "4 MB", 4 + }, + { + "8 MB", 8 + }, + { + "" + } + } + }, + { + "", "", -1 + } }; -// clang-format on const device_t s3_orchid_86c911_isa_device = { @@ -8333,7 +8384,7 @@ const device_t s3_elsa_winner2000_pro_x_964_pci_device = S3_ELSAWIN2KPROX_964, s3_init, s3_close, - s3_reset, + s3_reset, { s3_elsa_winner2000_pro_x_964_available }, s3_speed_changed, s3_force_redraw, @@ -8348,7 +8399,7 @@ const device_t s3_elsa_winner2000_pro_x_pci_device = S3_ELSAWIN2KPROX, s3_init, s3_close, - s3_reset, + s3_reset, { s3_elsa_winner2000_pro_x_available }, s3_speed_changed, s3_force_redraw, @@ -8363,7 +8414,7 @@ const device_t s3_trio64v2_dx_pci_device = S3_TRIO64V2_DX, s3_init, s3_close, - s3_reset, + s3_reset, { s3_trio64v2_dx_available }, s3_speed_changed, s3_force_redraw, @@ -8379,7 +8430,7 @@ const device_t s3_trio64v2_dx_onboard_pci_device = S3_TRIO64V2_DX_ONBOARD, s3_init, s3_close, - NULL, + NULL, { NULL }, s3_speed_changed, s3_force_redraw, diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 4acaa0aa0..6f46278da 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -117,10 +117,10 @@ typedef struct s3d_t { uint32_t cmd_set; int clip_l, clip_r, clip_t, clip_b; - + uint32_t dest_base; uint32_t dest_str; - + uint32_t z_base; uint32_t z_str; @@ -136,14 +136,14 @@ typedef struct s3d_t int32_t TdWdX, TdWdY; uint32_t tws; - + int32_t TdDdX, TdDdY; uint32_t tds; - + int16_t TdGdX, TdBdX, TdRdX, TdAdX; int16_t TdGdY, TdBdY, TdRdY, TdAdY; uint32_t tgs, tbs, trs, tas; - + uint32_t TdXdY12; uint32_t txend12; uint32_t TdXdY01; @@ -161,9 +161,9 @@ typedef struct virge_t mem_mapping_t linear_mapping; mem_mapping_t mmio_mapping; mem_mapping_t new_mmio_mapping; - + rom_t bios_rom; - + svga_t svga; uint8_t bank; @@ -195,7 +195,7 @@ typedef struct virge_t uint32_t hwc_fg_col, hwc_bg_col; int hwc_col_stack_pos; - + struct { uint32_t src_base; @@ -212,21 +212,21 @@ typedef struct virge_t int r_width, r_height; int rsrc_x, rsrc_y; int rdest_x, rdest_y; - + int lxend0, lxend1; int32_t ldx; uint32_t lxstart, lystart; int lycnt; int line_dir; - + int src_x, src_y; int dest_x, dest_y; int w, h; uint8_t rop; - + int data_left_count; uint32_t data_left; - + uint32_t pattern_8[8*8]; uint32_t pattern_16[8*8]; uint32_t pattern_24[8*8]; @@ -240,14 +240,14 @@ typedef struct virge_t uint32_t pycnt; uint32_t dest_l, dest_r; } s3d; - + s3d_t s3d_tri; s3d_t s3d_buffer[RB_SIZE]; int s3d_read_idx, s3d_write_idx; int s3d_busy; int render_idx; - + struct { uint32_t pri_ctrl; @@ -273,9 +273,9 @@ typedef struct virge_t uint32_t pri_size; uint32_t sec_start; uint32_t sec_size; - + int sdif; - + int pri_x, pri_y, pri_w, pri_h; int sec_x, sec_y, sec_w, sec_h; } streams; @@ -285,7 +285,7 @@ typedef struct virge_t uint32_t dma_ptr; uint64_t blitter_time; volatile int fifo_slot; - + pc_timer_t tri_timer; int virge_busy, local; @@ -297,7 +297,7 @@ typedef struct virge_t uint8_t serialport; void *i2c, *ddc; - + int waiting; } virge_t; @@ -324,29 +324,29 @@ enum { CMD_SET_AE = 1, CMD_SET_HC = (1 << 1), - + CMD_SET_FORMAT_MASK = (7 << 2), CMD_SET_FORMAT_8 = (0 << 2), CMD_SET_FORMAT_16 = (1 << 2), CMD_SET_FORMAT_24 = (2 << 2), - + CMD_SET_MS = (1 << 6), CMD_SET_IDS = (1 << 7), CMD_SET_MP = (1 << 8), CMD_SET_TP = (1 << 9), - + CMD_SET_ITA_MASK = (3 << 10), CMD_SET_ITA_BYTE = (0 << 10), CMD_SET_ITA_WORD = (1 << 10), CMD_SET_ITA_DWORD = (2 << 10), - + CMD_SET_ZUP = (1 << 23), - + CMD_SET_ZB_MODE = (3 << 24), CMD_SET_XP = (1 << 25), CMD_SET_YP = (1 << 26), - + CMD_SET_COMMAND_MASK = (15 << 27) }; @@ -440,7 +440,7 @@ static void render_thread(void *param) { virge_t *virge = (virge_t *)param; - + while (virge->render_thread_run) { thread_wait_event(virge->wake_render_thread, -1); thread_reset_event(virge->wake_render_thread); @@ -467,9 +467,9 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) uint8_t old; uint32_t cursoraddr; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; - + switch (addr) { case 0x3c5: @@ -495,7 +495,7 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) return; } break; - + case 0x3d4: svga->crtcreg = val; return; @@ -503,7 +503,7 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); + val = (svga->crtc[7] & ~0x10) | (val & 0x10); if ((svga->crtcreg >= 0x20) && (svga->crtcreg < 0x40) && (svga->crtcreg != 0x36) && (svga->crtcreg != 0x38) && (svga->crtcreg != 0x39) && ((svga->crtc[0x38] & 0xcc) != 0x48)) @@ -516,10 +516,10 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) return; old = svga->crtc[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; - + if (svga->crtcreg > 0x18) s3_virge_log("OUTB VGA reg = %02x, val = %02x\n", svga->crtcreg, val); - + switch (svga->crtcreg) { case 0x31: @@ -528,11 +528,11 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) case 0x32: s3_virge_update_irqs(virge); break; - + case 0x69: virge->ma_ext = val & 0x1f; break; - + case 0x35: virge->bank = (virge->bank & 0x70) | (val & 0xf); if (svga->chain4) @@ -555,12 +555,12 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) else svga->write_bank = svga->read_bank = virge->bank << 14; break; - + case 0x3a: if (val & 0x10) svga->gdcreg[5] |= 0x40; /*Horrible cheat*/ break; - + case 0x45: svga->hwcursor.ena = val & 1; break; @@ -573,7 +573,7 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) cursoraddr = (virge->memory_size == 8) ? 0x1fff : 0x0fff; svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & cursoraddr) * 1024) + (svga->hwcursor.yoff * 16); break; - + case 0x4a: switch (virge->hwc_col_stack_pos) { @@ -614,12 +614,12 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) svga->dpms = (svga->seqregs[0x0d] & 0x50) || (svga->crtc[0x56] & 0x06); old = ~val; /* force recalc */ break; - + case 0x5c: if ((val & 0xa0) == 0x80) i2c_gpio_set(virge->i2c, !!(val & 0x40), !!(val & 0x10)); break; - + case 0x67: switch (val >> 4) { @@ -630,7 +630,7 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) default: svga->bpp = 8; break; } break; - + case 0xaa: i2c_gpio_set(virge->i2c, !!(val & SERIAL_PORT_SCW), !!(val & SERIAL_PORT_SDW)); break; @@ -660,8 +660,8 @@ static uint8_t s3_virge_in(uint16_t addr, void *p) virge_t *virge = (virge_t *)p; svga_t *svga = &virge->svga; uint8_t ret; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; switch (addr) @@ -671,7 +671,7 @@ static uint8_t s3_virge_in(uint16_t addr, void *p) ret = 0xff; else ret = svga_in(addr, svga); - break; + break; case 0x3c5: if (svga->seqaddr >= 8) @@ -690,7 +690,7 @@ static uint8_t s3_virge_in(uint16_t addr, void *p) { case 0x2d: ret = virge->virge_id_high; break; /*Extended chip ID*/ case 0x2e: ret = virge->virge_id_low; break; /*New chip ID*/ - case 0x2f: ret = virge->virge_rev; break; + case 0x2f: ret = virge->virge_rev; break; case 0x30: ret = virge->virge_id; break; /*Chip ID*/ case 0x31: ret = (svga->crtc[0x31] & 0xcf) | ((virge->ma_ext & 3) << 4); break; case 0x33: ret = (svga->crtc[0x33] | 0x04); break; @@ -724,16 +724,16 @@ static uint8_t s3_virge_in(uint16_t addr, void *p) } else ret = svga->crtc[0xaa]; break; - + default: ret = svga->crtc[svga->crtcreg]; break; } break; - + default: ret = svga_in(addr, svga); - break; + break; } return ret; } @@ -741,7 +741,7 @@ static uint8_t s3_virge_in(uint16_t addr, void *p) static void s3_virge_recalctimings(svga_t *svga) { virge_t *virge = (virge_t *)svga->p; - + svga->hdisp = svga->hdisp_old; if (svga->crtc[0x5d] & 0x01) svga->htotal += 0x100; @@ -759,36 +759,36 @@ static void s3_virge_recalctimings(svga_t *svga) if (((svga->miscout >> 2) & 3) == 3) { int n = svga->seqregs[0x12] & 0x1f; int r = (svga->seqregs[0x12] >> 5); - - if (virge->chip == S3_VIRGEVX || virge->chip == S3_VIRGEDX) + + if (virge->chip == S3_VIRGEVX || virge->chip == S3_VIRGEDX) r &= 7; else if (virge->chip >= S3_VIRGEGX2) r &= 10; else r &= 3; - + int m = svga->seqregs[0x13] & 0x7f; double freq = (((double)m + 2) / (((double)n + 2) * (double)(1 << r))) * 14318184.0; svga->clock = (cpuclock * (float)(1ull << 32)) / freq; } - + if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ - { + { + svga->fb_only = 0; svga->ma_latch |= (virge->ma_ext << 16); if (svga->crtc[0x51] & 0x30) svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4; else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100; if (!svga->rowoffset) svga->rowoffset = 256; - + svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { - svga->fb_only = 1; switch (svga->bpp) { - case 8: - svga->render = svga_render_8bpp_highres; + case 8: + svga->render = svga_render_8bpp_highres; break; - case 15: + case 15: svga->render = svga_render_15bpp_highres; if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) { @@ -796,12 +796,12 @@ static void s3_virge_recalctimings(svga_t *svga) svga->hdisp >>= 1; } break; - case 16: + case 16: svga->render = svga_render_16bpp_highres; if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) { svga->htotal >>= 1; - svga->hdisp >>= 1; + svga->hdisp >>= 1; } break; case 24: @@ -809,28 +809,27 @@ static void s3_virge_recalctimings(svga_t *svga) if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) svga->rowoffset = (svga->rowoffset * 3) / 4; /*Hack*/ break; - case 32: + case 32: svga->render = svga_render_32bpp_highres; break; } - } else - svga->fb_only = 0; + } svga->vram_display_mask = (!(svga->crtc[0x31] & 0x08) && (svga->crtc[0x32] & 0x40)) ? 0x3ffff : virge->vram_mask; s3_virge_log("VGA mode\n"); } else /*Streams mode*/ { svga->fb_only = 1; - + if (virge->streams.buffer_ctrl & 1) svga->ma_latch = virge->streams.pri_fb1 >> 2; else svga->ma_latch = virge->streams.pri_fb0 >> 2; - + svga->hdisp = virge->streams.pri_w + 1; if (virge->streams.pri_h < svga->dispend) svga->dispend = virge->streams.pri_h; - + svga->overlay.x = virge->streams.sec_x - virge->streams.pri_x; svga->overlay.y = virge->streams.sec_y - virge->streams.pri_y; svga->overlay.ysize = virge->streams.sec_h; @@ -847,21 +846,21 @@ static void s3_virge_recalctimings(svga_t *svga) switch ((virge->streams.pri_ctrl >> 24) & 0x7) { case 0: /*RGB-8 (CLUT)*/ - svga->render = svga_render_8bpp_highres; + svga->render = svga_render_8bpp_highres; break; - case 3: /*KRGB-16 (1.5.5.5)*/ + case 3: /*KRGB-16 (1.5.5.5)*/ svga->htotal >>= 1; - svga->render = svga_render_15bpp_highres; + svga->render = svga_render_15bpp_highres; break; - case 5: /*RGB-16 (5.6.5)*/ + case 5: /*RGB-16 (5.6.5)*/ svga->htotal >>= 1; - svga->render = svga_render_16bpp_highres; + svga->render = svga_render_16bpp_highres; break; - case 6: /*RGB-24 (8.8.8)*/ - svga->render = svga_render_24bpp_highres; + case 6: /*RGB-24 (8.8.8)*/ + svga->render = svga_render_24bpp_highres; break; case 7: /*XRGB-32 (X.8.8.8)*/ - svga->render = svga_render_32bpp_highres; + svga->render = svga_render_32bpp_highres; break; } svga->vram_display_mask = virge->vram_mask; @@ -881,7 +880,7 @@ static void s3_virge_updatemapping(virge_t *virge) return; } - s3_virge_log("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); + s3_virge_log("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); /*Banked framebuffer*/ switch (svga->gdcreg[6] & 0xc) { /*VGA mapping*/ case 0x0: /*128k at A0000*/ @@ -901,7 +900,7 @@ static void s3_virge_updatemapping(virge_t *virge) svga->banked_mask = 0x7fff; break; } - + virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); s3_virge_log("Linear framebuffer %02X, linear base = %08x, display mask = %08x\n", svga->crtc[0x58] & 0x17, virge->linear_base, svga->vram_display_mask); @@ -937,13 +936,15 @@ static void s3_virge_updatemapping(virge_t *virge) } else { virge->linear_base &= 0xfc000000; } - + mem_mapping_set_addr(&virge->linear_mapping, virge->linear_base, virge->linear_size); } + svga->fb_only = 1; } else { mem_mapping_disable(&virge->linear_mapping); + svga->fb_only = 0; } - + s3_virge_log("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x38); /* Memory mapped I/O. */ @@ -983,8 +984,8 @@ s3_virge_mmio_fifo_write(uint32_t addr, uint8_t val, virge_t *virge) case 0x859c: virge->cmd_dma = val; break; - } - } + } + } } static void @@ -1003,7 +1004,7 @@ s3_virge_mmio_fifo_write_w(uint32_t addr, uint16_t val, virge_t *virge) static void s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge) -{ +{ if ((addr & 0xfffc) < 0x8000) { if (virge->s3d.cmd_set & CMD_SET_MS) s3_virge_bitblt(virge, 32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); @@ -1015,7 +1016,7 @@ s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge) case 0x8590: virge->cmd_dma_base = val; break; - + case 0x8594: virge->dma_ptr = val; break; @@ -1026,7 +1027,7 @@ s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge) case 0x859c: virge->cmd_dma = val; break; - + case 0xa000: case 0xa004: case 0xa008: case 0xa00c: case 0xa010: case 0xa014: case 0xa018: case 0xa01c: case 0xa020: case 0xa024: case 0xa028: case 0xa02c: @@ -1068,7 +1069,7 @@ s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge) virge->s3d.pattern_8[y*8 + x + 1] = val >> 8; virge->s3d.pattern_8[y*8 + x + 2] = val >> 16; virge->s3d.pattern_8[y*8 + x + 3] = val >> 24; - + x = (addr >> 1) & 6; y = (addr >> 4) & 7; virge->s3d.pattern_16[y*8 + x] = val & 0xffff; @@ -1194,7 +1195,7 @@ s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge) if (virge->s3d.cmd_set & CMD_SET_AE) s3_virge_bitblt(virge, -1, 0); break; - + case 0xb0f4: case 0xb4f4: virge->s3d_tri.fog_b = val & 0xff; virge->s3d_tri.fog_g = (val >> 8) & 0xff; @@ -1298,7 +1299,7 @@ s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge) virge->s3d_tri.tas = (val >> 16) & 0xffff; virge->s3d_tri.trs = val & 0xffff; break; - + case 0xb554: virge->s3d_tri.TdZdX = val; break; @@ -1361,7 +1362,7 @@ s3_virge_mmio_read(uint32_t addr, void *p) if (virge->fifo_slot) virge->fifo_slot--; return ret; - + case 0x83b0: case 0x83b1: case 0x83b2: case 0x83b3: case 0x83b4: case 0x83b5: case 0x83b6: case 0x83b7: case 0x83b8: case 0x83b9: case 0x83ba: case 0x83bb: @@ -1375,10 +1376,10 @@ s3_virge_mmio_read(uint32_t addr, void *p) case 0x83d8: case 0x83d9: case 0x83da: case 0x83db: case 0x83dc: case 0x83dd: case 0x83de: case 0x83df: return s3_virge_in(addr & 0x3ff, virge); - + case 0x859c: return virge->cmd_dma; - + case 0xff20: case 0xff21: ret = virge->serialport & ~(SERIAL_PORT_SCR | SERIAL_PORT_SDR); if ((virge->serialport & SERIAL_PORT_SCW) && i2c_gpio_get_scl(virge->i2c)) @@ -1394,9 +1395,9 @@ s3_virge_mmio_read_w(uint32_t addr, void *p) { virge_t *virge = (virge_t *)p; uint16_t ret = 0xffff; - + s3_virge_log("[%04X:%08X]: MMIO ReadW addr = %04x\n", CS, cpu_state.pc, addr & 0xfffe); - + switch (addr & 0xfffe) { case 0x8504: if (!virge->fifo_slot) @@ -1407,10 +1408,10 @@ s3_virge_mmio_read_w(uint32_t addr, void *p) ret |= 0x30; /*A bit of a workaround at the moment.*/ s3_virge_update_irqs(virge); return ret; - + case 0x859c: return virge->cmd_dma; - + default: return s3_virge_mmio_read(addr, virge) | (s3_virge_mmio_read(addr + 1, virge) << 8); @@ -1493,7 +1494,7 @@ s3_virge_mmio_read_l(uint32_t addr, void *p) break; case 0x81fc: ret = virge->streams.sec_size; - break; + break; case 0x8504: if (virge->s3d_busy || virge->fifo_slot) { @@ -1510,7 +1511,7 @@ s3_virge_mmio_read_l(uint32_t addr, void *p) virge->fifo_slot--; s3_virge_update_irqs(virge); break; - + case 0x8590: ret = virge->cmd_dma_base; break; @@ -1522,7 +1523,7 @@ s3_virge_mmio_read_l(uint32_t addr, void *p) case 0x859c: ret = virge->cmd_dma; break; - + case 0xa4d4: ret = virge->s3d.src_base; break; @@ -1568,11 +1569,11 @@ s3_virge_mmio_read_l(uint32_t addr, void *p) case 0xa50c: ret = (virge->s3d.rdest_x << 16) | virge->s3d.rdest_y; break; - + default: ret = s3_virge_mmio_read(addr, virge) | (s3_virge_mmio_read(addr + 1, virge) << 8) | - (s3_virge_mmio_read(addr + 2, virge) << 16) | + (s3_virge_mmio_read(addr + 2, virge) << 16) | (s3_virge_mmio_read(addr + 3, virge) << 24); break; } @@ -1626,7 +1627,7 @@ s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p) if ((addr & 0xfffe) == 0x83d4) { s3_virge_mmio_write(addr, val, virge); s3_virge_mmio_write(addr + 1, val >> 8, virge); - } + } } } @@ -1634,12 +1635,12 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) { virge_t *virge = (virge_t *)p; - svga_t *svga = &virge->svga; - + svga_t *svga = &virge->svga; + s3_virge_log("[%04X:%08X]: MMIO WriteL addr = %04x, val = %04x\n", CS, cpu_state.pc, addr & 0xfffc, val); if (((addr & 0xfffc) >= 0x8590) || ((addr & 0xfffc) < 0x8000)) if ((addr & 0xfffc) == 0xff20) - s3_virge_mmio_write(addr, val, virge); + s3_virge_mmio_write(addr, val, virge); else { s3_virge_mmio_fifo_write_l(addr, val, virge); } @@ -1734,38 +1735,38 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) case 0x81f0: virge->streams.pri_start = val; virge->streams.pri_x = (val >> 16) & 0x7ff; - virge->streams.pri_y = val & 0x7ff; + virge->streams.pri_y = val & 0x7ff; svga_recalctimings(svga); svga->fullchange = changeframecount; break; case 0x81f4: virge->streams.pri_size = val; virge->streams.pri_w = (val >> 16) & 0x7ff; - virge->streams.pri_h = val & 0x7ff; + virge->streams.pri_h = val & 0x7ff; svga_recalctimings(svga); svga->fullchange = changeframecount; break; case 0x81f8: virge->streams.sec_start = val; virge->streams.sec_x = (val >> 16) & 0x7ff; - virge->streams.sec_y = val & 0x7ff; + virge->streams.sec_y = val & 0x7ff; svga_recalctimings(svga); svga->fullchange = changeframecount; break; case 0x81fc: virge->streams.sec_size = val; virge->streams.sec_w = (val >> 16) & 0x7ff; - virge->streams.sec_h = val & 0x7ff; + virge->streams.sec_h = val & 0x7ff; svga_recalctimings(svga); svga->fullchange = changeframecount; break; - + case 0x8504: virge->subsys_stat &= ~(val & 0xff); virge->subsys_cntl = (val >> 8); s3_virge_update_irqs(virge); break; - + case 0x850c: virge->advfunc_cntl = val & 0xff; s3_virge_updatemapping(virge); @@ -1809,7 +1810,7 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) y > s3d_tri->clip_b)) \ update = 0; \ } - + #define MIX() \ { \ @@ -1861,7 +1862,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) uint32_t source = 0, dest = 0, pattern; uint32_t out = 0; int update; - + switch (virge->s3d.cmd_set & CMD_SET_FORMAT_MASK) { case CMD_SET_FORMAT_8: @@ -1892,7 +1893,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) } if (virge->s3d.cmd_set & CMD_SET_MP) pattern_data = mono_pattern; - + switch (virge->s3d.cmd_set & CMD_SET_ITA_MASK) { case CMD_SET_ITA_BYTE: @@ -1937,7 +1938,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) virge->s3d.h = virge->s3d.r_height; virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; virge->s3d.data_left_count = 0; - + s3_virge_log("BitBlt start src_x=%i,src_y=%i,dest_x=%i,dest_y=%i,w=%i,h=%i,rop=%02X,src_base=%x,dest_base=%x\n", virge->s3d.src_x, virge->s3d.src_y, @@ -1948,7 +1949,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) virge->s3d.rop, virge->s3d.src_base, virge->s3d.dest_base); - + if (virge->s3d.cmd_set & CMD_SET_IDS) return; } @@ -2019,7 +2020,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) WRITE(dest_addr, out); } - + virge->s3d.src_x += x_inc; virge->s3d.src_x &= 0x7ff; virge->s3d.dest_x += x_inc; @@ -2033,7 +2034,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) virge->s3d.src_y += y_inc; virge->s3d.dest_y += y_inc; virge->s3d.h--; - + switch (virge->s3d.cmd_set & (CMD_SET_MS | CMD_SET_IDS)) { case CMD_SET_IDS: @@ -2053,10 +2054,10 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) } } else - virge->s3d.w--; + virge->s3d.w--; } break; - + case CMD_SET_COMMAND_RECTFILL: /*No source, pattern = pat_fg_clr*/ if (count == -1) @@ -2068,7 +2069,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) virge->s3d.w = virge->s3d.r_width; virge->s3d.h = virge->s3d.r_height; virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; - + s3_virge_log("RctFll start %i,%i %i,%i %02X %08x\n", virge->s3d.dest_x, virge->s3d.dest_y, virge->s3d.w, @@ -2114,11 +2115,11 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) } } else - virge->s3d.w--; + virge->s3d.w--; count--; } break; - + case CMD_SET_COMMAND_LINE: if (count == -1) { @@ -2132,7 +2133,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) int x; int new_x; int first_pixel = 1; - + x = virge->s3d.dest_x >> 20; if (virge->s3d.h == virge->s3d.lycnt && @@ -2145,11 +2146,11 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) else new_x = (virge->s3d.dest_x + virge->s3d.ldx) >> 20; - + if ((virge->s3d.line_dir && x > new_x) || (!virge->s3d.line_dir && x < new_x)) goto skip_line; - + do { uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); @@ -2178,7 +2179,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) WRITE(dest_addr, out); } - + if (x < new_x) x++; else if (x > new_x) @@ -2224,7 +2225,7 @@ skip_line: WRITE(dest_addr, out); } - + x = (x + xdir) & 0x7ff; } while (x != (xend + xdir)); @@ -2273,21 +2274,21 @@ typedef struct s3d_state_t int32_t r, g, b, a, u, v, d, w; int32_t base_r, base_g, base_b, base_a, base_u, base_v, base_d, base_w; - + uint32_t base_z; uint32_t tbu, tbv; uint32_t cmd_set; int max_d; - + uint16_t *texture[10]; - + uint32_t tex_bdr_clr; - + int32_t x1, x2; int y; - + rgba_t dest_rgba; } s3d_state_t; @@ -2295,7 +2296,7 @@ typedef struct s3d_texture_state_t { int level; int texture_shift; - + int32_t u, v; } s3d_texture_state_t; @@ -2391,7 +2392,7 @@ static void tex_ARGB8888_nowrap(s3d_state_t *state, s3d_texture_state_t *texture static void tex_sample_normal(s3d_state_t *state) { s3d_texture_state_t texture_state; - + texture_state.level = state->max_d; texture_state.texture_shift = 18 + (9 - texture_state.level); texture_state.u = state->u + state->tbu; @@ -2429,12 +2430,12 @@ static void tex_sample_normal_filter(s3d_state_t *state) texture_state.u = state->u + state->tbu + tex_offset; texture_state.v = state->v + state->tbv + tex_offset; tex_read(state, &texture_state, &tex_samples[3]); - + d[0] = (256 - du) * (256 - dv); d[1] = du * (256 - dv); d[2] = (256 - du) * dv; d[3] = du * dv; - + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; @@ -2468,7 +2469,7 @@ static void tex_sample_mipmap_filter(s3d_state_t *state) texture_state.level = 0; texture_state.texture_shift = 18 + (9 - texture_state.level); tex_offset = 1 << texture_state.texture_shift; - + texture_state.u = state->u + state->tbu; texture_state.v = state->v + state->tbv; tex_read(state, &texture_state, &tex_samples[0]); @@ -2491,7 +2492,7 @@ static void tex_sample_mipmap_filter(s3d_state_t *state) d[1] = du * (256 - dv); d[2] = (256 - du) * dv; d[3] = du * dv; - + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; @@ -2505,9 +2506,9 @@ static void tex_sample_persp_normal(s3d_state_t *state) if (state->w) w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - + texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); + texture_state.texture_shift = 18 + (9 - texture_state.level); texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; @@ -2532,7 +2533,7 @@ static void tex_sample_persp_normal_filter(s3d_state_t *state) texture_state.level = state->max_d; texture_state.texture_shift = 18 + (9 - texture_state.level); tex_offset = 1 << texture_state.texture_shift; - + texture_state.u = u; texture_state.v = v; tex_read(state, &texture_state, &tex_samples[0]); @@ -2555,7 +2556,7 @@ static void tex_sample_persp_normal_filter(s3d_state_t *state) d[1] = du * (256 - dv); d[2] = (256 - du) * dv; d[3] = du * dv; - + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; @@ -2569,9 +2570,9 @@ static void tex_sample_persp_normal_375(s3d_state_t *state) if (state->w) w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - + texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); + texture_state.texture_shift = 18 + (9 - texture_state.level); texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; @@ -2592,7 +2593,7 @@ static void tex_sample_persp_normal_filter_375(s3d_state_t *state) u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; - + texture_state.level = state->max_d; texture_state.texture_shift = 18 + (9 - texture_state.level); tex_offset = 1 << texture_state.texture_shift; @@ -2619,7 +2620,7 @@ static void tex_sample_persp_normal_filter_375(s3d_state_t *state) d[1] = du * (256 - dv); d[2] = (256 - du) * dv; d[3] = du * dv; - + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; @@ -2634,7 +2635,7 @@ static void tex_sample_persp_mipmap(s3d_state_t *state) if (state->w) w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); if (texture_state.level < 0) texture_state.level = 0; @@ -2659,7 +2660,7 @@ static void tex_sample_persp_mipmap_filter(s3d_state_t *state) u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; - + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); if (texture_state.level < 0) texture_state.level = 0; @@ -2688,7 +2689,7 @@ static void tex_sample_persp_mipmap_filter(s3d_state_t *state) d[1] = du * (256 - dv); d[2] = (256 - du) * dv; d[3] = du * dv; - + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; @@ -2702,7 +2703,7 @@ static void tex_sample_persp_mipmap_375(s3d_state_t *state) if (state->w) w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); if (texture_state.level < 0) texture_state.level = 0; @@ -2727,13 +2728,13 @@ static void tex_sample_persp_mipmap_filter_375(s3d_state_t *state) u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; - + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); if (texture_state.level < 0) texture_state.level = 0; texture_state.texture_shift = 18 + (9 - texture_state.level); tex_offset = 1 << texture_state.texture_shift; - + texture_state.u = u; texture_state.v = v; tex_read(state, &texture_state, &tex_samples[0]); @@ -2756,7 +2757,7 @@ static void tex_sample_persp_mipmap_filter_375(s3d_state_t *state) d[1] = du * (256 - dv); d[2] = (256 - du) * dv; d[3] = du * dv; - + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; @@ -2780,7 +2781,7 @@ static void tex_sample_persp_mipmap_filter_375(s3d_state_t *state) b = ((b) < 0) ? 0 : 0xff; \ if ((a) & ~0xff) \ a = ((a) < 0) ? 0 : 0xff; - + #define CLAMP_RGB(r, g, b) do \ { \ if ((r) < 0) \ @@ -2845,11 +2846,11 @@ static void dest_pixel_lit_texture_reflection(s3d_state_t *state) static void dest_pixel_lit_texture_modulate(s3d_state_t *state) { int r = state->r >> 7, g = state->g >> 7, b = state->b >> 7, a = state->a >> 7; - + tex_sample(state); - + CLAMP_RGBA(r, g, b, a); - + state->dest_rgba.r = ((state->dest_rgba.r) * r) >> 8; state->dest_rgba.g = ((state->dest_rgba.g) * g) >> 8; state->dest_rgba.b = ((state->dest_rgba.b) * b) >> 8; @@ -2864,13 +2865,13 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 uint8_t *vram = (uint8_t *)svga->vram; int x_dir = s3d_tri->tlr ? 1 : -1; - + int use_z = !(s3d_tri->cmd_set & CMD_SET_ZB_MODE); int y_count = yc; - + int bpp = (s3d_tri->cmd_set >> 2) & 7; - + uint32_t dest_offset = 0, z_offset = 0; uint32_t src_col; @@ -2888,7 +2889,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 int update; uint16_t src_z = 0; - + if (s3d_tri->cmd_set & CMD_SET_HC) { if (state->y < s3d_tri->clip_t) @@ -2896,10 +2897,10 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 if (state->y > s3d_tri->clip_b) { int diff_y = state->y - s3d_tri->clip_b; - + if (diff_y > y_count) diff_y = y_count; - + state->base_u += (s3d_tri->TdUdY * diff_y); state->base_v += (s3d_tri->TdVdY * diff_y); state->base_z += (s3d_tri->TdZdY * diff_y); @@ -2922,7 +2923,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 dest_offset = s3d_tri->dest_base + (state->y * s3d_tri->dest_str); z_offset = s3d_tri->z_base + (state->y * s3d_tri->z_str); - + while (y_count > 0) { x = (state->x1 + ((1 << 20) - 1)) >> 20; @@ -2964,7 +2965,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 if (x < s3d_tri->clip_l) { int diff_x = s3d_tri->clip_l - x; - + z += (s3d_tri->TdZdX * diff_x); state->u += (s3d_tri->TdUdX * diff_x); state->v += (s3d_tri->TdVdX * diff_x); @@ -2974,7 +2975,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 state->a += (s3d_tri->TdAdX * diff_x); state->d += (s3d_tri->TdDdX * diff_x); state->w += (s3d_tri->TdWdX * diff_x); - + x = s3d_tri->clip_l; } } @@ -2989,7 +2990,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 if (x > s3d_tri->clip_r) { int diff_x = x - s3d_tri->clip_r; - + z += (s3d_tri->TdZdX * diff_x); state->u += (s3d_tri->TdUdX * diff_x); state->v += (s3d_tri->TdVdX * diff_x); @@ -2999,7 +3000,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 state->a += (s3d_tri->TdAdX * diff_x); state->d += (s3d_tri->TdDdX * diff_x); state->w += (s3d_tri->TdWdX * diff_x); - + x = s3d_tri->clip_r; } } @@ -3012,7 +3013,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 x &= 0xfff; xe &= 0xfff; - + while (x != xe) { update = 1; _x = x; _y = state->y; @@ -3104,7 +3105,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 switch (bpp) { - case 0: /*8 bpp*/ + case 0: /*8 bpp*/ /*Not implemented yet*/ break; case 1: /*16 bpp*/ @@ -3138,13 +3139,13 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 state->w += s3d_tri->TdWdX; dest_addr += x_offset; z_addr += xz_offset; - + x = (x + x_dir) & 0xfff; } } y_count--; - + tri_skip_line: state->x1 += dx1; state->x2 += dx2; @@ -3187,11 +3188,11 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) state.tbu = s3d_tri->tbu << 11; state.tbv = s3d_tri->tbv << 11; - + state.max_d = (s3d_tri->cmd_set >> 8) & 15; - + state.tex_bdr_clr = s3d_tri->tex_bdr_clr; - + state.cmd_set = s3d_tri->cmd_set; state.base_u = s3d_tri->tus; @@ -3203,7 +3204,7 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) state.base_a = (int32_t)s3d_tri->tas; state.base_d = s3d_tri->tds; state.base_w = s3d_tri->tws; - + tex_base = s3d_tri->tex_base; for (c = 9; c >= 0; c--) { @@ -3242,8 +3243,8 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) default: s3_virge_log("bad triangle type %x\n", (s3d_tri->cmd_set >> 27) & 0xf); return; - } - + } + switch (((s3d_tri->cmd_set >> 12) & 7) | ((s3d_tri->cmd_set & (1 << 29)) ? 8 : 0)) { case 0: case 1: @@ -3283,7 +3284,7 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter : tex_sample_persp_normal; break; } - + switch ((s3d_tri->cmd_set >> 5) & 7) { case 0: @@ -3307,9 +3308,9 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) tri(virge, s3d_tri, &state, s3d_tri->ty01, s3d_tri->TdXdY02, s3d_tri->TdXdY01); state.x2 = s3d_tri->txend12; tri(virge, s3d_tri, &state, s3d_tri->ty12, s3d_tri->TdXdY02, s3d_tri->TdXdY12); - + end_time = plat_timer_read(); - + virge->blitter_time += end_time - start_time; } @@ -3327,17 +3328,17 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine) svga->hwcursor_latch.addr += 16; switch (svga->bpp) - { + { case 15: fg = video_15to32[virge->hwc_fg_col & 0xffff]; bg = video_15to32[virge->hwc_bg_col & 0xffff]; break; - + case 16: fg = video_16to32[virge->hwc_fg_col & 0xffff]; bg = video_16to32[virge->hwc_bg_col & 0xffff]; break; - + case 24: case 32: fg = virge->hwc_fg_col; bg = virge->hwc_bg_col; @@ -3363,7 +3364,7 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine) if (dat[0] & 0x8000) buffer32->line[displine][offset + svga->x_add] = (dat[1] & 0x8000) ? fg : bg; } - + offset++; dat[0] <<= 1; dat[1] <<= 1; @@ -3381,7 +3382,7 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine) else if (dat[1] & 0x8000) buffer32->line[displine][offset + svga->x_add] ^= 0xffffff; } - + offset++; dat[0] <<= 1; dat[1] <<= 1; @@ -3630,7 +3631,7 @@ static void s3_virge_overlay_draw(svga_t *svga, int displine) int x; uint32_t *p; uint8_t *src = &svga->vram[svga->overlay_latch.addr]; - + p = &(buffer32->line[displine][offset + svga->x_add]); if ((offset + virge->streams.sec_w) > virge->streams.pri_w) @@ -3639,7 +3640,7 @@ static void s3_virge_overlay_draw(svga_t *svga, int displine) x_size = virge->streams.sec_w + 1; OVERLAY_SAMPLE(); - + for (x = 0; x < x_size; x++) { *p++ = r[x_read] | (g[x_read] << 8) | (b[x_read] << 16); @@ -3672,22 +3673,22 @@ static uint8_t s3_virge_pci_read(int func, int addr, void *p) switch (addr) { case 0x00: ret = 0x33; break; /*'S3'*/ case 0x01: ret = 0x53; break; - + case 0x02: ret = virge->virge_id_low; break; case 0x03: ret = virge->virge_id_high; break; case PCI_REG_COMMAND: ret = virge->pci_regs[PCI_REG_COMMAND] & 0x27; break; - + case 0x07: ret = virge->pci_regs[0x07] & 0x36; break; - + case 0x08: ret = virge->virge_rev; break; /*Revision ID*/ case 0x09: ret = 0; break; /*Programming interface*/ - + case 0x0a: ret = 0x00; break; /*Supports VGA interface*/ case 0x0b: ret = 0x03; break; case 0x0d: ret = virge->pci_regs[0x0d] & 0xf8; break; - + case 0x10: ret = 0x00; break;/*Linear frame buffer address*/ case 0x11: ret = 0x00; break; case 0x12: ret = 0x00; break; @@ -3706,12 +3707,12 @@ static uint8_t s3_virge_pci_read(int func, int addr, void *p) case 0x34: ret = (virge->chip >= S3_VIRGEGX2) ? 0xdc : 0x00; break; case 0x3c: ret = virge->pci_regs[0x3c]; break; - + case 0x3d: ret = PCI_INTA; break; /*INTA*/ - + case 0x3e: ret = 0x04; break; case 0x3f: ret = 0xff; break; - + case 0x80: ret = 0x02; break; /* AGP capability */ case 0x81: ret = 0x00; break; case 0x82: ret = 0x10; break; /* assumed AGP 1.0 */ @@ -3745,8 +3746,8 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x3d: case 0x3e: case 0x3f: - return; - + return; + case PCI_REG_COMMAND: if (val & PCI_COMMAND_IO) { @@ -3756,12 +3757,12 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) else io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); virge->pci_regs[PCI_REG_COMMAND] = val & 0x27; - s3_virge_updatemapping(virge); + s3_virge_updatemapping(virge); return; case 0x07: virge->pci_regs[0x07] = val & 0x3e; return; - case 0x0d: + case 0x0d: virge->pci_regs[0x0d] = val & 0xf8; return; @@ -3785,7 +3786,7 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) mem_mapping_disable(&virge->bios_rom.mapping); } return; - case 0x3c: + case 0x3c: virge->pci_regs[0x3c] = val; return; @@ -3833,7 +3834,7 @@ static void s3_virge_reset(void *priv) virge->pci_regs[0x06] = 0; virge->pci_regs[0x07] = 2; virge->pci_regs[0x32] = 0x0c; - virge->pci_regs[0x3d] = 1; + virge->pci_regs[0x3d] = 1; virge->pci_regs[0x3e] = 4; virge->pci_regs[0x3f] = 0xff; @@ -3887,7 +3888,7 @@ static void s3_virge_reset(void *priv) else virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); break; - } + } if (virge->local == S3_VIRGE_GX) virge->svga.crtc[0x36] |= (1 << 2); } @@ -3916,8 +3917,8 @@ static void *s3_virge_init(const device_t *info) virge->memory_size = 4; else virge->memory_size = device_get_config_int("memory"); - - + + switch(info->local) { case S3_VIRGE_325: bios_fn = ROM_VIRGE_325; @@ -3965,7 +3966,7 @@ static void *s3_virge_init(const device_t *info) rom_init(&virge->bios_rom, (char *) bios_fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); else rom_init(&virge->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - + mem_mapping_disable(&virge->bios_rom.mapping); mem_mapping_add(&virge->linear_mapping, 0, 0, svga_read_linear, @@ -4003,10 +4004,10 @@ static void *s3_virge_init(const device_t *info) virge->pci_regs[0x06] = 0; virge->pci_regs[0x07] = 2; virge->pci_regs[0x32] = 0x0c; - virge->pci_regs[0x3d] = 1; + virge->pci_regs[0x3d] = 1; virge->pci_regs[0x3e] = 4; virge->pci_regs[0x3f] = 0xff; - + virge->virge_rev = 0; virge->virge_id = 0xe1; virge->is_agp = !!(info->flags & DEVICE_AGP); @@ -4105,11 +4106,11 @@ static void *s3_virge_init(const device_t *info) else virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); break; - } + } if (info->local == S3_VIRGE_GX) virge->svga.crtc[0x36] |= (1 << 2); } - + virge->svga.crtc[0x37] = 1 | (7 << 5); virge->svga.crtc[0x53] = 8; @@ -4117,8 +4118,8 @@ static void *s3_virge_init(const device_t *info) virge->i2c = i2c_gpio_init("ddc_s3_virge"); virge->ddc = ddc_init(i2c_gpio_get_bus(virge->i2c)); - - virge->svga.packed_chain4 = 1; + + virge->svga.force_old_addr = 1; virge->wake_render_thread = thread_create_event(); virge->wake_main_thread = thread_create_event(); @@ -4127,9 +4128,9 @@ static void *s3_virge_init(const device_t *info) virge->render_thread = thread_create(render_thread, virge); timer_add(&virge->tri_timer, s3_virge_tri_timer, virge, 0); - + virge->local = info->local; - + return virge; } @@ -4148,7 +4149,7 @@ static void s3_virge_close(void *p) ddc_close(virge->ddc); i2c_gpio_close(virge->i2c); - + free(virge); } @@ -4205,7 +4206,7 @@ static int s3_trio3d2x_available(void) static void s3_virge_speed_changed(void *p) { virge_t *virge = (virge_t *)p; - + svga_recalctimings(&virge->svga); } @@ -4216,60 +4217,102 @@ static void s3_virge_force_redraw(void *p) virge->svga.fullchange = changeframecount; } -// clang-format off static const device_config_t s3_virge_config[] = { - { - "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, { - { "2 MB", 2 }, - { "4 MB", 4 }, - { "" } + "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, + { + { + "2 MB", 2 + }, + { + "4 MB", 4 + }, + { + "" + } + } + }, + { + "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 + }, + { + "dithering", "Dithering", CONFIG_BINARY, "", 1 + }, + { + "", "", -1 } - }, - { "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 }, - { "dithering", "Dithering", CONFIG_BINARY, "", 1 }, - { "", "", -1 } }; static const device_config_t s3_virge_stb_config[] = { - { - "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, { - { "2 MB", 2 }, - { "4 MB", 4 }, - { "8 MB", 8 }, - { "" } + "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, + { + { + "2 MB", 2 + }, + { + "4 MB", 4 + }, + { + "8 MB", 8 + }, + { + "" + } + } + }, + { + "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 + }, + { + "dithering", "Dithering", CONFIG_BINARY, "", 1 + }, + { + "", "", -1 } - }, - { "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 }, - { "dithering", "Dithering", CONFIG_BINARY, "", 1 }, - { "", "", -1 } }; static const device_config_t s3_virge_357_config[] = { - { "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 }, - { "dithering", "Dithering", CONFIG_BINARY, "", 1 }, - { "", "", -1 } + { + "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 + }, + { + "dithering", "Dithering", CONFIG_BINARY, "", 1 + }, + { + "", "", -1 + } }; static const device_config_t s3_trio3d2x_config[] = { - { - "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, { - { "4 MB", 4 }, - { "8 MB", 8 }, - { "" } + "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, + { + { + "4 MB", 4 + }, + { + "8 MB", 8 + }, + { + "" + } + } + }, + { + "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 + }, + { + "dithering", "Dithering", CONFIG_BINARY, "", 1 + }, + { + "", "", -1 } - }, - { "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 }, - { "dithering", "Dithering", CONFIG_BINARY, "", 1 }, - { "", "", -1 } }; -// clang-format on const device_t s3_virge_325_pci_device = { @@ -4279,7 +4322,7 @@ const device_t s3_virge_325_pci_device = S3_VIRGE_325, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_325_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4294,7 +4337,7 @@ const device_t s3_diamond_stealth_2000_pci_device = S3_DIAMOND_STEALTH3D_2000, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_325_diamond_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4309,7 +4352,7 @@ const device_t s3_diamond_stealth_3000_pci_device = S3_DIAMOND_STEALTH3D_3000, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_988_diamond_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4324,7 +4367,7 @@ const device_t s3_stb_velocity_3d_pci_device = S3_STB_VELOCITY_3D, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_988_stb_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4339,7 +4382,7 @@ const device_t s3_virge_375_pci_device = S3_VIRGE_DX, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_375_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4354,7 +4397,7 @@ const device_t s3_diamond_stealth_2000pro_pci_device = S3_DIAMOND_STEALTH3D_2000PRO, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_375_diamond_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4369,7 +4412,7 @@ const device_t s3_virge_385_pci_device = S3_VIRGE_GX, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_385_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4384,7 +4427,7 @@ const device_t s3_virge_357_pci_device = S3_VIRGE_GX2, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_357_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4399,7 +4442,7 @@ const device_t s3_virge_357_agp_device = S3_VIRGE_GX2, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_357_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4414,7 +4457,7 @@ const device_t s3_diamond_stealth_4000_pci_device = S3_DIAMOND_STEALTH3D_4000, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_357_diamond_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4429,7 +4472,7 @@ const device_t s3_diamond_stealth_4000_agp_device = S3_DIAMOND_STEALTH3D_4000, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_357_diamond_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4444,7 +4487,7 @@ const device_t s3_trio3d2x_pci_device = S3_TRIO_3D2X, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_trio3d2x_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4459,7 +4502,7 @@ const device_t s3_trio3d2x_agp_device = S3_TRIO_3D2X, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_trio3d2x_available }, s3_virge_speed_changed, s3_virge_force_redraw, diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 9640b5540..20c4d6dd6 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -179,7 +179,7 @@ svga_out(uint16_t addr, uint8_t val, void *p) svga->chain2_write = !(val & 4); svga->chain4 = val & 8; svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && - !svga->gdcreg[1]) && ((svga->chain4 && svga->packed_chain4) || svga->fb_only) && !(svga->adv_flags & FLAG_ADDR_BY8); + !svga->gdcreg[1]) && ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && !(svga->adv_flags & FLAG_ADDR_BY8); break; } break; @@ -264,7 +264,7 @@ svga_out(uint16_t addr, uint8_t val, void *p) } svga->gdcreg[svga->gdcaddr & 15] = val; svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && - !svga->gdcreg[1]) && ((svga->chain4 && svga->packed_chain4) || svga->fb_only); + !svga->gdcreg[1]) && ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only); if (((svga->gdcaddr & 15) == 5 && (val ^ o) & 0x70) || ((svga->gdcaddr & 15) == 6 && (val ^ o) & 1)) svga_recalctimings(svga); @@ -582,7 +582,8 @@ svga_recalctimings(svga_t *svga) if (svga->dispofftime < TIMER_USEC) svga->dispofftime = TIMER_USEC; - svga_recalc_remap_func(svga); + if (!svga->force_old_addr) + svga_recalc_remap_func(svga); /* Inform the user interface of any DPMS mode changes. */ if (svga->dpms) { @@ -1068,7 +1069,7 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) addr <<= 4; else if ((svga->adv_flags & FLAG_ADDR_BY8) && (svga->writemode < 4)) addr <<= 3; - else if (((svga->chain4 && svga->packed_chain4) || svga->fb_only) && (svga->writemode < 4)) { + else if (((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && (svga->writemode < 4)) { writemask2 = 1 << (addr & 3); addr &= ~3; } else if (svga->chain4 && (svga->writemode < 4)) { @@ -1256,7 +1257,7 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p) addr <<= 4; else if (svga->adv_flags & FLAG_ADDR_BY8) addr <<= 3; - else if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) { + else if ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) { addr &= svga->decode_mask; if (svga->translate_address) addr = svga->translate_address(addr, p); @@ -1266,7 +1267,7 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p) for (i = 0; i < count; i++) svga->latch.b[i] = svga->vram[latch_addr | i]; return svga->vram[addr & svga->vram_mask]; - } else if (svga->chain4) { + } else if (svga->chain4 && !svga->force_old_addr) { readplane = addr & 3; addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); } else if (svga->chain2_read) { diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index ddd3ad0eb..2d23231be 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -117,6 +117,7 @@ svga_render_text_40(svga_t *svga) uint8_t chr, attr, dat; uint32_t charaddr; int fg, bg; + uint32_t addr = 0; if ((svga->displine + svga->y_add) < 0) return; @@ -130,13 +131,19 @@ svga_render_text_40(svga_t *svga) xinc = (svga->seqregs[1] & 1) ? 16 : 18; for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { - uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; + if (!svga->force_old_addr) + addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); if (svga->crtc[0x17] & 0x80) { - chr = svga->vram[addr]; - attr = svga->vram[addr+1]; + if (svga->force_old_addr) { + chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; + attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + } else { + chr = svga->vram[addr]; + attr = svga->vram[addr+1]; + } } else chr = attr = 0; @@ -186,6 +193,7 @@ svga_render_text_80(svga_t *svga) uint8_t chr, attr, dat; uint32_t charaddr; int fg, bg; + uint32_t addr = 0; if ((svga->displine + svga->y_add) < 0) return; @@ -199,13 +207,19 @@ svga_render_text_80(svga_t *svga) xinc = (svga->seqregs[1] & 1) ? 8 : 9; for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { - uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; + if (!svga->force_old_addr) + addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); if (svga->crtc[0x17] & 0x80) { - chr = svga->vram[addr]; - attr = svga->vram[addr+1]; + if (svga->force_old_addr) { + chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; + attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + } else { + chr = svga->vram[addr]; + attr = svga->vram[addr+1]; + } } else chr = attr = 0; @@ -244,7 +258,7 @@ svga_render_text_80(svga_t *svga) } } - +/*Not available on most generic cards.*/ void svga_render_text_80_ksc5601(svga_t *svga) { @@ -373,6 +387,7 @@ svga_render_text_80_ksc5601(svga_t *svga) void svga_render_2bpp_lowres(svga_t *svga) { + int changed_offset; int x; uint8_t dat[2]; uint32_t addr, *p; @@ -381,41 +396,94 @@ svga_render_2bpp_lowres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - changed_addr = svga->remap_func(svga, svga->ma); + if (svga->force_old_addr) { + changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; + + if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { + addr = svga->ma; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { - addr = svga->remap_func(svga, svga->ma); + if (!(svga->crtc[0x17] & 0x40)) { + addr = (addr << 1) & svga->vram_mask; + addr &= ~7; - dat[0] = svga->vram[addr]; - dat[1] = svga->vram[addr | 0x1]; - if (svga->seqregs[1] & 4) - svga->ma += 2; - else - svga->ma += 4; + if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000)) + addr |= 4; - svga->ma &= svga->vram_mask; + if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000)) + addr |= 4; + } - if (svga->crtc[0x17] & 0x80) { - p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; - p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; - p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; - p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]]; - p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; - p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; - p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; - p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]]; - } else - memset(p, 0x00, 16 * sizeof(uint32_t)); + if (!(svga->crtc[0x17] & 0x01)) + addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); - p += 16; - } + if (!(svga->crtc[0x17] & 0x02)) + addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); + + dat[0] = svga->vram[addr]; + dat[1] = svga->vram[addr | 0x1]; + if (svga->seqregs[1] & 4) + svga->ma += 2; + else + svga->ma += 4; + svga->ma &= svga->vram_mask; + if (svga->crtc[0x17] & 0x80) { + p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; + p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; + p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; + p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]]; + p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; + p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; + p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; + p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]]; + } else + memset(p, 0x00, 16 * sizeof(uint32_t)); + p += 16; + } + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { + addr = svga->remap_func(svga, svga->ma); + + dat[0] = svga->vram[addr]; + dat[1] = svga->vram[addr | 0x1]; + if (svga->seqregs[1] & 4) + svga->ma += 2; + else + svga->ma += 4; + + svga->ma &= svga->vram_mask; + + if (svga->crtc[0x17] & 0x80) { + p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; + p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; + p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; + p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]]; + p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; + p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; + p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; + p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]]; + } else + memset(p, 0x00, 16 * sizeof(uint32_t)); + + p += 16; + } + } } } @@ -423,6 +491,7 @@ svga_render_2bpp_lowres(svga_t *svga) void svga_render_2bpp_highres(svga_t *svga) { + int changed_offset; int x; uint8_t dat[2]; uint32_t addr, *p; @@ -431,42 +500,95 @@ svga_render_2bpp_highres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - changed_addr = svga->remap_func(svga, svga->ma); + if (svga->force_old_addr) { + changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - addr = svga->remap_func(svga, svga->ma); + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + addr = svga->ma; - dat[0] = svga->vram[addr]; - dat[1] = svga->vram[addr | 0x1]; - if (svga->seqregs[1] & 4) - svga->ma += 2; - else - svga->ma += 4; + if (!(svga->crtc[0x17] & 0x40)) { + addr = (addr << 1) & svga->vram_mask; + addr &= ~7; - svga->ma &= svga->vram_mask; + if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000)) + addr |= 4; - if (svga->crtc[0x17] & 0x80) { - p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; - p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; - p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; - p[3] = svga->pallook[svga->egapal[dat[0] & 3]]; - p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; - p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; - p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; - p[7] = svga->pallook[svga->egapal[dat[1] & 3]]; - } else - memset(p, 0x00, 8 * sizeof(uint32_t)); + if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000)) + addr |= 4; + } - p += 8; + if (!(svga->crtc[0x17] & 0x01)) + addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); + + if (!(svga->crtc[0x17] & 0x02)) + addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); + + dat[0] = svga->vram[addr]; + dat[1] = svga->vram[addr | 0x1]; + if (svga->seqregs[1] & 4) + svga->ma += 2; + else + svga->ma += 4; + svga->ma &= svga->vram_mask; + if (svga->crtc[0x17] & 0x80) { + p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; + p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; + p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; + p[3] = svga->pallook[svga->egapal[dat[0] & 3]]; + p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; + p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; + p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; + p[7] = svga->pallook[svga->egapal[dat[1] & 3]]; + } else + memset(p, 0x00, 8 * sizeof(uint32_t)); + p += 8; + } + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + addr = svga->remap_func(svga, svga->ma); + + dat[0] = svga->vram[addr]; + dat[1] = svga->vram[addr | 0x1]; + if (svga->seqregs[1] & 4) + svga->ma += 2; + else + svga->ma += 4; + + svga->ma &= svga->vram_mask; + + if (svga->crtc[0x17] & 0x80) { + p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; + p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; + p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; + p[3] = svga->pallook[svga->egapal[dat[0] & 3]]; + p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; + p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; + p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; + p[7] = svga->pallook[svga->egapal[dat[1] & 3]]; + } else + memset(p, 0x00, 8 * sizeof(uint32_t)); + + p += 8; + } + } } - } } @@ -540,56 +662,120 @@ svga_render_4bpp_lowres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - changed_addr = svga->remap_func(svga, svga->ma); + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { + addr = svga->ma; + oddeven = 0; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { - addr = svga->remap_func(svga, svga->ma); - oddeven = 0; + if (!(svga->crtc[0x17] & 0x40)) { + addr = (addr << 1) & svga->vram_mask; - if (svga->seqregs[1] & 4) { - oddeven = (addr & 4) ? 1 : 0; - edat[0] = svga->vram[addr | oddeven]; - edat[2] = svga->vram[addr | oddeven | 0x2]; - edat[1] = edat[3] = 0; - svga->ma += 2; - } else { - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); - svga->ma += 4; + if (svga->seqregs[1] & 4) + oddeven = (addr & 4) ? 1 : 0; + + addr &= ~7; + + if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000)) + addr |= 4; + if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000)) + addr |= 4; + } + + if (!(svga->crtc[0x17] & 0x01)) + addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); + if (!(svga->crtc[0x17] & 0x02)) + addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); + + if (svga->seqregs[1] & 4) { + edat[0] = svga->vram[addr | oddeven]; + edat[2] = svga->vram[addr | oddeven | 0x2]; + edat[1] = edat[3] = 0; + svga->ma += 2; + } else { + *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); + svga->ma += 4; + } + svga->ma &= svga->vram_mask; + + if (svga->crtc[0x17] & 0x80) { + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[2] = p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + p[4] = p[5] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[6] = p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + p[8] = p[9] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[10] = p[11] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + p[12] = p[13] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[14] = p[15] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + } else + memset(p, 0x00, 16 * sizeof(uint32_t)); + + p += 16; } - svga->ma &= svga->vram_mask; + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); - if (svga->crtc[0x17] & 0x80) { - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[2] = p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[4] = p[5] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[6] = p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[8] = p[9] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[10] = p[11] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[12] = p[13] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[14] = p[15] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - } else - memset(p, 0x00, 16 * sizeof(uint32_t)); + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - p += 16; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { + addr = svga->remap_func(svga, svga->ma); + oddeven = 0; + + if (svga->seqregs[1] & 4) { + oddeven = (addr & 4) ? 1 : 0; + edat[0] = svga->vram[addr | oddeven]; + edat[2] = svga->vram[addr | oddeven | 0x2]; + edat[1] = edat[3] = 0; + svga->ma += 2; + } else { + *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); + svga->ma += 4; + } + svga->ma &= svga->vram_mask; + + if (svga->crtc[0x17] & 0x80) { + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[2] = p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + p[4] = p[5] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[6] = p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + p[8] = p[9] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[10] = p[11] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + p[12] = p[13] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[14] = p[15] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + } else + memset(p, 0x00, 16 * sizeof(uint32_t)); + + p += 16; + } + } } - } } void svga_render_4bpp_highres(svga_t *svga) { + int changed_offset; int x, oddeven; uint32_t addr, *p; uint8_t edat[4]; @@ -598,51 +784,116 @@ svga_render_4bpp_highres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; + + if (svga->force_old_addr) { + changed_offset = (svga->ma + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; - changed_addr = svga->remap_func(svga, svga->ma); + if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + addr = svga->ma; + oddeven = 0; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - addr = svga->remap_func(svga, svga->ma); - oddeven = 0; + if (!(svga->crtc[0x17] & 0x40)) { + addr = (addr << 1) & svga->vram_mask; - if (svga->seqregs[1] & 4) { - oddeven = (addr & 4) ? 1 : 0; - edat[0] = svga->vram[addr | oddeven]; - edat[2] = svga->vram[addr | oddeven | 0x2]; - edat[1] = edat[3] = 0; - svga->ma += 2; - } else { - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); - svga->ma += 4; + if (svga->seqregs[1] & 4) + oddeven = (addr & 4) ? 1 : 0; + + addr &= ~7; + + if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000)) + addr |= 4; + if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000)) + addr |= 4; + } + + if (!(svga->crtc[0x17] & 0x01)) + addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); + if (!(svga->crtc[0x17] & 0x02)) + addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); + + if (svga->seqregs[1] & 4) { + edat[0] = svga->vram[addr | oddeven]; + edat[2] = svga->vram[addr | oddeven | 0x2]; + edat[1] = edat[3] = 0; + svga->ma += 2; + } else { + *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); + svga->ma += 4; + } + svga->ma &= svga->vram_mask; + + if (svga->crtc[0x17] & 0x80) { + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + } else + memset(p, 0x00, 8 * sizeof(uint32_t)); + + p += 8; } - svga->ma &= svga->vram_mask; + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); - if (svga->crtc[0x17] & 0x80) { - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - } else - memset(p, 0x00, 8 * sizeof(uint32_t)); + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - p += 8; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + addr = svga->remap_func(svga, svga->ma); + oddeven = 0; + + if (svga->seqregs[1] & 4) { + oddeven = (addr & 4) ? 1 : 0; + edat[0] = svga->vram[addr | oddeven]; + edat[2] = svga->vram[addr | oddeven | 0x2]; + edat[1] = edat[3] = 0; + svga->ma += 2; + } else { + *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); + svga->ma += 4; + } + svga->ma &= svga->vram_mask; + + if (svga->crtc[0x17] & 0x80) { + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + } else + memset(p, 0x00, 8 * sizeof(uint32_t)); + + p += 8; + } + } } - } } @@ -657,19 +908,18 @@ svga_render_8bpp_lowres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; + + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - changed_addr = svga->remap_func(svga, svga->ma); + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + p[0] = p[1] = svga->map8[dat & 0xff]; p[2] = p[3] = svga->map8[(dat >> 8) & 0xff]; p[4] = p[5] = svga->map8[(dat >> 16) & 0xff]; @@ -678,21 +928,45 @@ svga_render_8bpp_lowres(svga_t *svga) svga->ma += 4; p += 8; } + svga->ma &= svga->vram_display_mask; + } } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - p[0] = p[1] = svga->map8[dat & 0xff]; - p[2] = p[3] = svga->map8[(dat >> 8) & 0xff]; - p[4] = p[5] = svga->map8[(dat >> 16) & 0xff]; - p[6] = p[7] = svga->map8[(dat >> 24) & 0xff]; + changed_addr = svga->remap_func(svga, svga->ma); - svga->ma += 4; - p += 8; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + p[0] = p[1] = svga->map8[dat & 0xff]; + p[2] = p[3] = svga->map8[(dat >> 8) & 0xff]; + p[4] = p[5] = svga->map8[(dat >> 16) & 0xff]; + p[6] = p[7] = svga->map8[(dat >> 24) & 0xff]; + + svga->ma += 4; + p += 8; + } + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + p[0] = p[1] = svga->map8[dat & 0xff]; + p[2] = p[3] = svga->map8[(dat >> 8) & 0xff]; + p[4] = p[5] = svga->map8[(dat >> 16) & 0xff]; + p[6] = p[7] = svga->map8[(dat >> 24) & 0xff]; + + svga->ma += 4; + p += 8; + } + } + svga->ma &= svga->vram_display_mask; } } - svga->ma &= svga->vram_display_mask; - } } @@ -707,17 +981,15 @@ svga_render_8bpp_highres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; + + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - changed_addr = svga->remap_func(svga, svga->ma); + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp/* + svga->scrollcache*/); x += 8) { dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); p[0] = svga->map8[dat & 0xff]; @@ -734,21 +1006,51 @@ svga_render_8bpp_highres(svga_t *svga) svga->ma += 8; p += 8; } + svga->ma &= svga->vram_display_mask; + } } else { - for (x = 0; x <= (svga->hdisp/* + svga->scrollcache*/); x += 4) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - p[0] = svga->map8[dat & 0xff]; - p[1] = svga->map8[(dat >> 8) & 0xff]; - p[2] = svga->map8[(dat >> 16) & 0xff]; - p[3] = svga->map8[(dat >> 24) & 0xff]; + changed_addr = svga->remap_func(svga, svga->ma); - svga->ma += 4; - p += 4; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp/* + svga->scrollcache*/); x += 8) { + dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + p[0] = svga->map8[dat & 0xff]; + p[1] = svga->map8[(dat >> 8) & 0xff]; + p[2] = svga->map8[(dat >> 16) & 0xff]; + p[3] = svga->map8[(dat >> 24) & 0xff]; + + dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + p[4] = svga->map8[dat & 0xff]; + p[5] = svga->map8[(dat >> 8) & 0xff]; + p[6] = svga->map8[(dat >> 16) & 0xff]; + p[7] = svga->map8[(dat >> 24) & 0xff]; + + svga->ma += 8; + p += 8; + } + } else { + for (x = 0; x <= (svga->hdisp/* + svga->scrollcache*/); x += 4) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + p[0] = svga->map8[dat & 0xff]; + p[1] = svga->map8[(dat >> 8) & 0xff]; + p[2] = svga->map8[(dat >> 16) & 0xff]; + p[3] = svga->map8[(dat >> 24) & 0xff]; + + svga->ma += 4; + p += 4; + } + } + svga->ma &= svga->vram_display_mask; } } - svga->ma &= svga->vram_display_mask; - } } void @@ -870,47 +1172,74 @@ svga_render_15bpp_lowres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; + + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - changed_addr = svga->remap_func(svga, svga->ma); + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { if (svga->crtc[0x17] & 0x80) { dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + p[(x << 1)] = p[(x << 1) + 1] = video_15to32[dat & 0xffff]; + p[(x << 1) + 2] = p[(x << 1) + 3] = video_15to32[dat >> 16]; dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + p[(x << 1) + 4] = p[(x << 1) + 5] = video_15to32[dat & 0xffff]; + p[(x << 1) + 6] = p[(x << 1) + 7] = video_15to32[dat >> 16]; } else memset(&(p[(x << 1)]), 0x00, 8 * sizeof(uint32_t)); } svga->ma += x << 1; + svga->ma &= svga->vram_display_mask; + } } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { - if (svga->crtc[0x17] & 0x80) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + changed_addr = svga->remap_func(svga, svga->ma); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; - } else - memset(&(p[x]), 0x00, 2 * sizeof(uint32_t)); - svga->ma += 4; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { + if (svga->crtc[0x17] & 0x80) { + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + } else + memset(&(p[(x << 1)]), 0x00, 8 * sizeof(uint32_t)); + } + svga->ma += x << 1; + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { + if (svga->crtc[0x17] & 0x80) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + } else + memset(&(p[x]), 0x00, 2 * sizeof(uint32_t)); + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; } } - svga->ma &= svga->vram_display_mask; - } } @@ -924,53 +1253,86 @@ svga_render_15bpp_highres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; + + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - changed_addr = svga->remap_func(svga, svga->ma); + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { if (svga->crtc[0x17] & 0x80) { dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + p[x] = video_15to32[dat & 0xffff]; + p[x + 1] = video_15to32[dat >> 16]; dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + p[x + 2] = video_15to32[dat & 0xffff]; + p[x + 3] = video_15to32[dat >> 16]; dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + p[x + 4] = video_15to32[dat & 0xffff]; + p[x + 5] = video_15to32[dat >> 16]; dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + p[x + 6] = video_15to32[dat & 0xffff]; + p[x + 7] = video_15to32[dat >> 16]; } else memset(&(p[x]), 0x00, 8 * sizeof(uint32_t)); } - svga->ma += x << 1; + svga->ma += x << 1; + svga->ma &= svga->vram_display_mask; + } } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { - if (svga->crtc[0x17] & 0x80) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + changed_addr = svga->remap_func(svga, svga->ma); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; - } else - memset(&(p[x]), 0x00, 2 * sizeof(uint32_t)); - svga->ma += 4; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + if (svga->crtc[0x17] & 0x80) { + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + } else + memset(&(p[x]), 0x00, 8 * sizeof(uint32_t)); + } + svga->ma += x << 1; + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { + if (svga->crtc[0x17] & 0x80) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + } else + memset(&(p[x]), 0x00, 2 * sizeof(uint32_t)); + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; } } - svga->ma &= svga->vram_display_mask; - } } @@ -1071,46 +1433,71 @@ svga_render_16bpp_lowres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - changed_addr = svga->remap_func(svga, svga->ma); + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { if (svga->crtc[0x17] & 0x80) { dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + p[(x << 1)] = p[(x << 1) + 1] = video_16to32[dat & 0xffff]; + p[(x << 1) + 2] = p[(x << 1) + 3] = video_16to32[dat >> 16]; dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + p[(x << 1) + 4] = p[(x << 1) + 5] = video_16to32[dat & 0xffff]; + p[(x << 1) + 6] = p[(x << 1) + 7] = video_16to32[dat >> 16]; } else memset(&(p[(x << 1)]), 0x00, 8 * sizeof(uint32_t)); } - svga->ma += x << 1; - } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { - if (svga->crtc[0x17] & 0x80) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; - } else - memset(&(p[x]), 0x00, 2 * sizeof(uint32_t)); + svga->ma += x << 1; + svga->ma &= svga->vram_display_mask; } - svga->ma += 4; + } else { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { + if (svga->crtc[0x17] & 0x80) { + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + } else + memset(&(p[(x << 1)]), 0x00, 8 * sizeof(uint32_t)); + } + svga->ma += x << 1; + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { + if (svga->crtc[0x17] & 0x80) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + } else + memset(&(p[x]), 0x00, 2 * sizeof(uint32_t)); + } + svga->ma += 4; + } + svga->ma &= svga->vram_display_mask; + } } - svga->ma &= svga->vram_display_mask; - } } @@ -1124,54 +1511,87 @@ svga_render_16bpp_highres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - - changed_addr = svga->remap_func(svga, svga->ma); - - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) + if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - if (svga->crtc[0x17] & 0x80) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + if (svga->crtc[0x17] & 0x80) { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + p[x] = video_16to32[dat & 0xffff]; + p[x + 1] = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + p[x + 2] = video_16to32[dat & 0xffff]; + p[x + 3] = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); + p[x + 4] = video_16to32[dat & 0xffff]; + p[x + 5] = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; - } else - memset(&(p[x]), 0x00, 8 * sizeof(uint32_t)); - } - svga->ma += x << 1; - } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { - if (svga->crtc[0x17] & 0x80) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; - } else - memset(&(p[x]), 0x00, 2 * sizeof(uint32_t)); - - svga->ma += 4; - } + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); + p[x + 6] = video_16to32[dat & 0xffff]; + p[x + 7] = video_16to32[dat >> 16]; + } else + memset(&(p[x]), 0x00, 8 * sizeof(uint32_t)); } + svga->ma += x << 1; svga->ma &= svga->vram_display_mask; - } + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + if (svga->crtc[0x17] & 0x80) { + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + } else + memset(&(p[x]), 0x00, 8 * sizeof(uint32_t)); + } + svga->ma += x << 1; + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { + if (svga->crtc[0x17] & 0x80) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + } else + memset(&(p[x]), 0x00, 2 * sizeof(uint32_t)); + + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; + } + } } @@ -1182,56 +1602,79 @@ svga_render_24bpp_lowres(svga_t *svga) uint32_t *p; uint32_t changed_addr, addr; uint32_t dat0, dat1, dat2; + uint32_t fg; if ((svga->displine + svga->y_add) < 0) return; + + if (svga->force_old_addr) { + if ((svga->displine + svga->y_add) < 0) + return; - changed_addr = svga->remap_func(svga, svga->ma); + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - if (svga->crtc[0x17] & 0x80) { - dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); - dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); - } else - dat0 = dat1 = dat2 = 0x00000000; - - p[0] = p[1] = dat0 & 0xffffff; - p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16); - p[6] = p[7] = dat2 >> 8; - - svga->ma += 12; + if (svga->crtc[0x17] & 0x80) + fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); + else + fg = 0x00000000; + svga->ma += 3; + svga->ma &= svga->vram_display_mask; + buffer32->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = + buffer32->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = fg; } - } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - if (svga->crtc[0x17] & 0x80) { - addr = svga->remap_func(svga, svga->ma); - dat0 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - addr = svga->remap_func(svga, svga->ma + 4); - dat1 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - addr = svga->remap_func(svga, svga->ma + 8); - dat2 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - } else - dat0 = dat1 = dat2 = 0x00000000; - - p[0] = p[1] = dat0 & 0xffffff; - p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16); - p[6] = p[7] = dat2 >> 8; - - svga->ma += 12; } - } - svga->ma &= svga->vram_display_mask; + } else { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + if (svga->crtc[0x17] & 0x80) { + dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); + } else + dat0 = dat1 = dat2 = 0x00000000; + + p[0] = p[1] = dat0 & 0xffffff; + p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8); + p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16); + p[6] = p[7] = dat2 >> 8; + + svga->ma += 12; + } + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { + if (svga->crtc[0x17] & 0x80) { + addr = svga->remap_func(svga, svga->ma); + dat0 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + addr = svga->remap_func(svga, svga->ma + 4); + dat1 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + addr = svga->remap_func(svga, svga->ma + 8); + dat2 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + } else + dat0 = dat1 = dat2 = 0x00000000; + + p[0] = p[1] = dat0 & 0xffffff; + p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8); + p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16); + p[6] = p[7] = dat2 >> 8; + + svga->ma += 12; + } + } + svga->ma &= svga->vram_display_mask; + } } } @@ -1243,57 +1686,88 @@ svga_render_24bpp_highres(svga_t *svga) uint32_t *p; uint32_t changed_addr, addr; uint32_t dat0, dat1, dat2; + uint32_t dat; if ((svga->displine + svga->y_add) < 0) return; + + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - changed_addr = svga->remap_func(svga, svga->ma); + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { if (svga->crtc[0x17] & 0x80) { - dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); - dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); + dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + p[x] = dat & 0xffffff; - *p++ = dat0 & 0xffffff; - *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); - *p++ = dat2 >> 8; + dat = *(uint32_t *)(&svga->vram[(svga->ma + 3) & svga->vram_display_mask]); + p[x + 1] = dat & 0xffffff; + + dat = *(uint32_t *)(&svga->vram[(svga->ma + 6) & svga->vram_display_mask]); + p[x + 2] = dat & 0xffffff; + + dat = *(uint32_t *)(&svga->vram[(svga->ma + 9) & svga->vram_display_mask]); + p[x + 3] = dat & 0xffffff; } else memset(&(p[x]), 0x0, 4 * sizeof(uint32_t)); svga->ma += 12; } + svga->ma &= svga->vram_display_mask; + } } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - if (svga->crtc[0x17] & 0x80) { - addr = svga->remap_func(svga, svga->ma); - dat0 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - addr = svga->remap_func(svga, svga->ma + 4); - dat1 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - addr = svga->remap_func(svga, svga->ma + 8); - dat2 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + changed_addr = svga->remap_func(svga, svga->ma); - *p++ = dat0 & 0xffffff; - *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); - *p++ = dat2 >> 8; - } else - memset(&(p[x]), 0x0, 4 * sizeof(uint32_t)); + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - svga->ma += 12; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { + if (svga->crtc[0x17] & 0x80) { + dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); + + *p++ = dat0 & 0xffffff; + *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); + *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); + *p++ = dat2 >> 8; + } else + memset(&(p[x]), 0x0, 4 * sizeof(uint32_t)); + + svga->ma += 12; + } + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { + if (svga->crtc[0x17] & 0x80) { + addr = svga->remap_func(svga, svga->ma); + dat0 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + addr = svga->remap_func(svga, svga->ma + 4); + dat1 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + addr = svga->remap_func(svga, svga->ma + 8); + dat2 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + *p++ = dat0 & 0xffffff; + *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); + *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); + *p++ = dat2 >> 8; + } else + memset(&(p[x]), 0x0, 4 * sizeof(uint32_t)); + + svga->ma += 12; + } } + svga->ma &= svga->vram_display_mask; + } } - svga->ma &= svga->vram_display_mask; - } } @@ -1307,40 +1781,59 @@ svga_render_32bpp_lowres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; + + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - changed_addr = svga->remap_func(svga, svga->ma); - - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { if (svga->crtc[0x17] & 0x80) - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + dat = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); else dat = 0x00000000; - *p++ = dat & 0xffffff; - *p++ = dat & 0xffffff; - } - svga->ma += (x * 4); - } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - if (svga->crtc[0x17] & 0x80) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - } else - dat = 0x00000000; - *p++ = dat & 0xffffff; - *p++ = dat & 0xffffff; svga->ma += 4; + svga->ma &= svga->vram_display_mask; + buffer32->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = + buffer32->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = dat; + } + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + if (svga->crtc[0x17] & 0x80) + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + else + dat = 0x00000000; + *p++ = dat & 0xffffff; + *p++ = dat & 0xffffff; + } + svga->ma += (x * 4); + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + if (svga->crtc[0x17] & 0x80) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + } else + dat = 0x00000000; + *p++ = dat & 0xffffff; + *p++ = dat & 0xffffff; + svga->ma += 4; + } + svga->ma &= svga->vram_display_mask; + } } - svga->ma &= svga->vram_display_mask; } - } } @@ -1354,39 +1847,59 @@ svga_render_32bpp_highres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; + + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - changed_addr = svga->remap_func(svga, svga->ma); - - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - if (svga->crtc[0x17] & 0x80) { + if (svga->crtc[0x17] & 0x80) dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - *p++ = dat & 0xffffff; - } else - memset(&(p[x]), 0x0, 1 * sizeof(uint32_t)); + else + dat = 0x00000000; + p[x] = dat & 0xffffff; + } + svga->ma += 4; + svga->ma &= svga->vram_display_mask; } - svga->ma += (x * 4); } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - if (svga->crtc[0x17] & 0x80) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - *p++ = dat & 0xffffff; - } else - memset(&(p[x]), 0x0, 1 * sizeof(uint32_t)); + changed_addr = svga->remap_func(svga, svga->ma); - svga->ma += 4; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + if (svga->crtc[0x17] & 0x80) { + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + *p++ = dat & 0xffffff; + } else + memset(&(p[x]), 0x0, 1 * sizeof(uint32_t)); + } + svga->ma += (x * 4); + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + if (svga->crtc[0x17] & 0x80) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + *p++ = dat & 0xffffff; + } else + memset(&(p[x]), 0x0, 1 * sizeof(uint32_t)); + + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; } } - svga->ma &= svga->vram_display_mask; - } } From c4f5c7e5e023cf7cc6e7c82950059d63e569a937 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 2 Mar 2022 16:37:19 +0100 Subject: [PATCH 36/37] Fix compile. --- src/include/86box/vid_svga_render_remap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/86box/vid_svga_render_remap.h b/src/include/86box/vid_svga_render_remap.h index 2602cc5c4..1077cbc69 100644 --- a/src/include/86box/vid_svga_render_remap.h +++ b/src/include/86box/vid_svga_render_remap.h @@ -104,7 +104,7 @@ void svga_recalc_remap_func(svga_t *svga) { int func_nr; - if (svga->fb_only || svga->force_byte_mode) + if (svga->fb_only) func_nr = 0; else { if (svga->force_dword_mode) From 7dc84e0f67ce25cdf20af7350275454ff79419e3 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 4 Mar 2022 01:17:38 +0600 Subject: [PATCH 37/37] qt: Fix HDD path relativization on Windows --- src/86box.c | 6 +++++- src/config.c | 5 ++++- src/disk/hdd_image.c | 4 ++++ src/include/86box/plat.h | 1 + src/qt/qt_platform.cpp | 12 +++++++++++- src/unix/unix.c | 10 ++++++++++ src/win/win.c | 5 +++++ 7 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/86box.c b/src/86box.c index 444fe1e81..17a1cca9c 100644 --- a/src/86box.c +++ b/src/86box.c @@ -710,7 +710,11 @@ usage: if (rom_path[0] != '\0') pclog("# ROM path: %s\n", rom_path); else - pclog("# ROM path: %sroms\\\n", exe_path); +#ifndef _WIN32 + pclog("# ROM path: %sroms/\n", exe_path); +#else + pclog("# ROM path: %sroms\\\n", exe_path); +#endif pclog("# Configuration file: %s\n#\n\n", cfg_path); /* * We are about to read the configuration file, which MAY diff --git a/src/config.c b/src/config.c index 658e3be01..ccd949278 100644 --- a/src/config.c +++ b/src/config.c @@ -1402,6 +1402,7 @@ load_hard_disks(void) } else { plat_append_filename(hdd[c].fn, usr_path, p); } + plat_path_normalize(hdd[c].fn); /* If disk is empty or invalid, mark it for deletion. */ if (! hdd_is_valid(c)) { @@ -2810,11 +2811,13 @@ save_hard_disks(void) } sprintf(temp, "hdd_%02i_fn", c+1); - if (hdd_is_valid(c) && (strlen(hdd[c].fn) != 0)) + if (hdd_is_valid(c) && (strlen(hdd[c].fn) != 0)) { + plat_path_normalize(hdd[c].fn); if (!strnicmp(hdd[c].fn, usr_path, strlen(usr_path))) config_set_string(cat, temp, &hdd[c].fn[strlen(usr_path)]); else config_set_string(cat, temp, hdd[c].fn); + } else config_delete_var(cat, temp); } diff --git a/src/disk/hdd_image.c b/src/disk/hdd_image.c index 5244bc638..f52be646c 100644 --- a/src/disk/hdd_image.c +++ b/src/disk/hdd_image.c @@ -252,6 +252,10 @@ hdd_image_load(int id) int vhd_error = 0; memset(empty_sector, 0, sizeof(empty_sector)); + if (fn) { + plat_path_normalize(fn); + } + hdd_images[id].base = 0; diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index b09207c14..ee04d0e12 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -111,6 +111,7 @@ extern char *plat_get_extension(char *s); extern void plat_append_filename(char *dest, const char *s1, const char *s2); extern void plat_put_backslash(char *s); extern void plat_path_slash(char *path); +extern void plat_path_normalize(char *path); extern int plat_path_abs(char *path); extern int plat_dir_check(char *path); extern int plat_dir_create(char *path); diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 785f85619..4ec31b842 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -235,15 +235,25 @@ plat_path_abs(char *path) #endif } +void +plat_path_normalize(char* path) +{ + while (*path++ != 0) + { + if (*path == '\\') *path = '/'; + } +} + void plat_path_slash(char *path) { auto len = strlen(path); - auto separator = QDir::separator().toLatin1(); + auto separator = '/'; if (path[len-1] != separator) { path[len] = separator; path[len+1] = 0; } + plat_path_normalize(path); } void diff --git a/src/unix/unix.c b/src/unix/unix.c index 9eb2b2c35..83f6b4a9b 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -282,12 +282,22 @@ plat_path_abs(char *path) return path[0] == '/'; } +void +plat_path_normalize(char* path) +{ + while (*path++ != 0) + { + if (*path == '\\') *path = '/'; + } +} + void plat_path_slash(char *path) { if ((path[strlen(path)-1] != '/')) { strcat(path, "/"); } + plat_path_normalize(path); } void diff --git a/src/win/win.c b/src/win/win.c index e54f4d243..1490a1ce1 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -731,6 +731,11 @@ plat_remove(char *path) } } +void +plat_path_normalize(char* path) +{ + /* No-op */ +} /* Make sure a path ends with a trailing (back)slash. */ void