diff --git a/src/include/86box/snd_ad1848.h b/src/include/86box/snd_ad1848.h index 99525807c..1ff5bc1d7 100644 --- a/src/include/86box/snd_ad1848.h +++ b/src/include/86box/snd_ad1848.h @@ -22,11 +22,12 @@ enum { AD1848_TYPE_DEFAULT = 0, AD1848_TYPE_CS4248 = 1, - AD1848_TYPE_CS4231 = 2, - AD1848_TYPE_CS4232 = 3, - AD1848_TYPE_CS4236 = 4, - AD1848_TYPE_CS4236B = 5, - AD1848_TYPE_CS4235 = 6 + AD1848_TYPE_OPTI930 = 2, + AD1848_TYPE_CS4231 = 3, + AD1848_TYPE_CS4232 = 4, + AD1848_TYPE_CS4236 = 5, + AD1848_TYPE_CS4236B = 6, + AD1848_TYPE_CS4235 = 7 }; enum { @@ -44,6 +45,7 @@ typedef struct ad1848_t { uint8_t regs[32]; uint8_t xregs[32]; uint8_t status; /* 16 original registers + 16 CS4231A extensions + 32 CS4236 extensions */ + uint8_t opti930_mode2; int count; uint8_t trd; diff --git a/src/sound/snd_ad1848.c b/src/sound/snd_ad1848.c index 8f120b157..44e328842 100644 --- a/src/sound/snd_ad1848.c +++ b/src/sound/snd_ad1848.c @@ -300,7 +300,7 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) switch (addr & 3) { case 0: /* Index */ - if ((ad1848->regs[12] & 0x40) && (ad1848->type >= AD1848_TYPE_CS4231)) + if (((ad1848->regs[12] & 0x40) && (ad1848->type >= AD1848_TYPE_CS4231)) || ((ad1848->type == AD1848_TYPE_OPTI930) && (ad1848->opti930_mode2))) 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? */ @@ -816,7 +816,7 @@ 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; + const int max_channel = (ad1848->type >= AD1848_TYPE_CS4231) ? 31 : (ad1848->type == AD1848_TYPE_OPTI930) ? 19 : 15; if (channel > max_channel) channel = max_channel; @@ -839,7 +839,7 @@ ad1848_filter_channel(void *priv, int channel, double *out_l, double *out_r) { const ad1848_t *ad1848 = (ad1848_t *) priv; - const int max_channel = (ad1848->type >= AD1848_TYPE_CS4231) ? 31 : 15; + const int max_channel = (ad1848->type >= AD1848_TYPE_CS4231) ? 31 : (ad1848->type == AD1848_TYPE_OPTI930) ? 19 : 15; if (channel > max_channel) channel = max_channel; @@ -880,7 +880,13 @@ ad1848_init(ad1848_t *ad1848, uint8_t type) ad1848->regs[13] = 0; ad1848->regs[14] = ad1848->regs[15] = 0; - if (type == AD1848_TYPE_CS4231) { + if (type == AD1848_TYPE_OPTI930) { + ad1848->regs[18] = ad1848->regs[19] = 0x88; /* LINE volume */ + ad1848->regs[20] = ad1848->regs[21] = 0x84; /* OPTi 930 MIC volume */ + ad1848->regs[22] = ad1848->regs[23] = 0x84; /* OPTi 930 master volume */ + ad1848->regs[24] = 0; + ad1848->regs[25] = 0; + } else if (type == AD1848_TYPE_CS4231) { ad1848->regs[16] = ad1848->regs[17] = 0; ad1848->regs[18] = ad1848->regs[19] = 0x88; ad1848->regs[22] = 0x80;