AC97 Codec: Rework with modem and proper multi-codec support

This commit is contained in:
RichardG867
2025-11-15 23:45:19 -03:00
parent 91c9cd4af2
commit 0a1464444a
3 changed files with 254 additions and 87 deletions

View File

@@ -8,9 +8,11 @@
*
* Definitions for AC'97 audio emulation.
*
*
*
* Authors: RichardG, <richardg867@gmail.com>
*
* Copyright 2021 RichardG.
* Copyright 2021-2025 RichardG.
*/
#ifndef SOUND_AC97_H
#define SOUND_AC97_H
@@ -19,23 +21,26 @@
/* 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_AUDIO (1 << 0) /* audio codec */
#define AC97_MODEM (1 << 1) /* modem codec */
#define AC97_MASTER_6B (1 << 2) /* register 02 bits [13,5] (ML5/MR5) */
#define AC97_AUXOUT (1 << 3) /* register 04 */
#define AC97_AUXOUT_6B (1 << 4) /* register 04 bits [13,5] (ML5/MR5) */
#define AC97_MONOOUT (1 << 5) /* register 06 */
#define AC97_MONOOUT_6B (1 << 6) /* register 06 bit 5 (MM5) */
#define AC97_PCBEEP (1 << 9) /* register 0A */
#define AC97_PCBEEP_GEN (1 << 10) /* register 0A bits [12:5] (F[7:0]) */
#define AC97_PHONE (1 << 11) /* register 0C */
#define AC97_VIDEO (1 << 12) /* register 14 */
#define AC97_AUXIN (1 << 13) /* 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_DSA (1 << 14) /* register 28 bits [5:4] (DSA[1:0]) */
#define AC97_LFE_6B (1 << 16) /* register 36 bit 13 (LFE5) */
#define AC97_CENTER_6B (1 << 17) /* register 36 bit 5 (CNT5) */
#define AC97_SURR_6B (1 << 18) /* register 38 bits [13,5] (LSR5/RSR5) */
#define AC97_GAIN_3B (1 << 19) /* registers [1C:1E] (audio) or [46:4A] (modem) bits [8,0] are always 0 (spec violation?) if this is set */
/* Reset bits (reset_flags), register 00. */
#define AC97_MICPCM (1 << 0)
@@ -89,6 +94,14 @@
#define AC97_PRK (1 << 13)
#define AC97_PRL (1 << 14)
/* Extended Modem ID bits, register 3C. */
#define AC97_LIN1 (1 << 0)
#define AC97_LIN2 (1 << 1)
#define AC97_HSET (1 << 2)
#define AC97_CID1 (1 << 3)
#define AC97_CID2 (1 << 4)
#define AC97_CIDR (1 << 7) /* special case: not part of register 3C, but rather 56 bit 13 */
/* Codec IDs. */
#define AC97_CODEC_AD1881 AC97_VENDOR_ID('A', 'D', 'S', 0x40)
#define AC97_CODEC_AK4540 AC97_VENDOR_ID('A', 'D', 'S', 0x40)
@@ -115,6 +128,8 @@ typedef struct ac97_codec_t {
uint8_t vendor_reg_page_max;
const ac97_vendor_reg_t *vendor_regs;
uint16_t *vendor_reg_pages;
uint16_t gpi;
uint16_t gpo;
} ac97_codec_t;
extern uint16_t ac97_codec_readw(ac97_codec_t *dev, uint8_t reg);
@@ -122,6 +137,8 @@ extern void ac97_codec_writew(ac97_codec_t *dev, uint8_t reg, uint16_
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 void ac97_codec_setgpi(void *priv, uint16_t gpi);
extern void ac97_codec_setgpo(void *priv, uint16_t gpo);
extern const device_t *ac97_codec_get(uint32_t id);
extern void ac97_via_set_slot(void *priv, int slot, int irq_pin);
@@ -133,11 +150,8 @@ extern void ac97_via_remap_audio_codec(void *priv, uint16_t new_io_base, uint
extern void ac97_via_remap_modem_codec(void *priv, uint16_t new_io_base, uint8_t enable);
extern ac97_codec_t **ac97_codec;
extern ac97_codec_t **ac97_modem_codec;
extern int ac97_codec_count;
extern int ac97_modem_codec_count;
extern int ac97_codec_id;
extern int ac97_modem_codec_id;
#ifdef EMU_DEVICE_H
extern const device_t ad1881_device;