AD1848: Make CD audio input designated per-card

Fixes CD audio mixer not working for GUS MAX
This commit is contained in:
Alexander Babikov
2025-09-11 16:47:56 +05:00
parent cb96d4e1bc
commit a59eb526ed
6 changed files with 41 additions and 11 deletions

View File

@@ -32,6 +32,14 @@ enum {
AD1848_TYPE_CS4235 = 6
};
enum {
AD1848_AUX1 = 2,
AD1848_AUX2 = 4,
AD1848_OUT = 6,
AD1848_LINE_IN = 18,
AD1848_MONO = 26
};
typedef struct ad1848_t {
uint8_t type;
uint8_t index;
@@ -47,6 +55,7 @@ typedef struct ad1848_t {
int16_t out_l;
int16_t out_r;
int8_t cd_vol_reg;
double cd_vol_l;
double cd_vol_r;
int fm_vol_l;
@@ -86,6 +95,7 @@ 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_set_cd_audio_channel(void *priv, int channel);
extern void ad1848_filter_cd_audio(int channel, double *buffer, void *priv);
extern void ad1848_filter_aux2(void* priv, double* out_l, double* out_r);

View File

@@ -501,16 +501,16 @@ readonly_x:
if (updatefreq)
ad1848_updatefreq(ad1848);
temp = (ad1848->type < AD1848_TYPE_CS4231) ? 2 : ((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];
if (ad1848->cd_vol_reg > -1) {
if (ad1848->regs[ad1848->cd_vol_reg] & 0x80)
ad1848->cd_vol_l = 0;
else
ad1848->cd_vol_l = ad1848_vols_5bits_aux_gain[ad1848->regs[ad1848->cd_vol_reg] & 0x1f];
if (ad1848->regs[ad1848->cd_vol_reg + 1] & 0x80)
ad1848->cd_vol_r = 0;
else
ad1848->cd_vol_r = ad1848_vols_5bits_aux_gain[ad1848->regs[ad1848->cd_vol_reg + 1] & 0x1f];
}
readonly_i:
ad1848_log("AD1848: write(I%d, %02X)\n", ad1848->index, val);
@@ -746,6 +746,18 @@ ad1848_poll(void *priv)
}
}
void
ad1848_set_cd_audio_channel(void *priv, int channel)
{
ad1848_t *ad1848 = (ad1848_t *) priv;
const int max_channel = (ad1848->type >= AD1848_TYPE_CS4231) ? 31 : 15;
if (channel > max_channel)
channel = max_channel;
ad1848->cd_vol_reg = channel;
}
void
ad1848_filter_cd_audio(int channel, double *buffer, void *priv)
{
@@ -837,6 +849,8 @@ ad1848_init(ad1848_t *ad1848, uint8_t type)
ad1848->out_l = ad1848->out_r = 0;
ad1848->fm_vol_l = ad1848->fm_vol_r = 65536;
ad1848->cd_vol_l = ad1848->cd_vol_r = 65536;
ad1848->cd_vol_reg = -1;
ad1848_updatevolmask(ad1848);
if (type >= AD1848_TYPE_CS4235)
ad1848->fmt_mask = 0x50;

View File

@@ -1211,6 +1211,7 @@ azt_init(const device_t *info)
/* wss part */
ad1848_init(&azt2316a->ad1848, device_get_config_int("codec"));
ad1848_set_cd_audio_channel(&azt2316a->ad1848, (device_get_config_int("codec") == AD1848_TYPE_CS4248) ? AD1848_AUX1 : AD1848_LINE_IN);
ad1848_setirq(&azt2316a->ad1848, azt2316a->cur_wss_irq);
ad1848_setdma(&azt2316a->ad1848, azt2316a->cur_wss_dma);

View File

@@ -273,8 +273,10 @@ cs423x_write(uint16_t addr, uint8_t val, void *priv)
}
switch (dev->regs[3] & 0x0f) {
case 0: /* WSS Master Control */
if ((dev->type < CRYSTAL_CS4235) && (val & 0x80))
if ((dev->type < CRYSTAL_CS4235) && (val & 0x80)) {
ad1848_init(&dev->ad1848, dev->ad1848_type);
ad1848_set_cd_audio_channel(&dev->ad1848, AD1848_AUX2);
}
val = 0x00;
break;
@@ -865,6 +867,7 @@ cs423x_reset(void *priv)
/* Reset WSS codec. */
ad1848_init(&dev->ad1848, dev->ad1848_type);
ad1848_set_cd_audio_channel(&dev->ad1848, AD1848_AUX2);
/* Reset PnP resource data, state and logical devices. */
dev->pnp_enable = 1;

View File

@@ -1569,6 +1569,7 @@ gus_init(UNUSED(const device_t *info))
if (gus->type == GUS_MAX) {
ad1848_init(&gus->ad1848, AD1848_TYPE_CS4231);
ad1848_set_cd_audio_channel(&gus->ad1848, AD1848_AUX2);
ad1848_setirq(&gus->ad1848, 5);
ad1848_setdma(&gus->ad1848, 3);
io_sethandler(0x10C + gus->base, 4,

View File

@@ -380,6 +380,7 @@ optimc_init(const device_t *info)
else
ad1848_init(&optimc->ad1848, AD1848_TYPE_DEFAULT);
ad1848_set_cd_audio_channel(&optimc->ad1848, (info->local & 0x100) ? AD1848_LINE_IN : AD1848_AUX1);
ad1848_setirq(&optimc->ad1848, optimc->cur_wss_irq);
ad1848_setdma(&optimc->ad1848, optimc->cur_wss_dma);