AD1848: Plumbing for more CS423x chips

This commit is contained in:
RichardG867
2025-01-19 20:23:11 -03:00
parent 8652974205
commit 84853cb21f
2 changed files with 48 additions and 47 deletions

View File

@@ -16,7 +16,7 @@
*
* Copyright 2008-2020 Sarah Walker.
* Copyright 2018-2020 TheCollector1995.
* Copyright 2021 RichardG.
* Copyright 2021-2025 RichardG.
*/
#ifndef SOUND_AD1848_H
@@ -26,8 +26,10 @@ enum {
AD1848_TYPE_DEFAULT = 0,
AD1848_TYPE_CS4248 = 1,
AD1848_TYPE_CS4231 = 2,
AD1848_TYPE_CS4235 = 3,
AD1848_TYPE_CS4236 = 4
AD1848_TYPE_CS4232 = 3,
AD1848_TYPE_CS4236 = 4,
AD1848_TYPE_CS4236B = 5,
AD1848_TYPE_CS4235 = 6
};
typedef struct ad1848_t {

View File

@@ -16,7 +16,7 @@
*
* Copyright 2008-2020 Sarah Walker.
* Copyright 2018-2020 TheCollector1995.
* Copyright 2021-2022 RichardG.
* Copyright 2021-2025 RichardG.
*/
#include <math.h>
#include <stdint.h>
@@ -33,6 +33,7 @@
#include <86box/plat_fallthrough.h>
#define CS4231 0x80
#define CS4232 0x02
#define CS4236 0x03
static int ad1848_vols_7bits[128];
@@ -57,10 +58,10 @@ ad1848_setdma(ad1848_t *ad1848, int newdma)
void
ad1848_updatevolmask(ad1848_t *ad1848)
{
if ((ad1848->type >= AD1848_TYPE_CS4235) && ((ad1848->xregs[4] & 0x10) || ad1848->wten))
ad1848->wave_vol_mask = 0x3f;
else
if ((ad1848->type == AD1848_TYPE_CS4236B) && !(ad1848->xregs[4] & 0x10) && !ad1848->wten)
ad1848->wave_vol_mask = 0x7f;
else
ad1848->wave_vol_mask = 0x3f;
}
static double
@@ -106,8 +107,8 @@ ad1848_updatefreq(ad1848_t *ad1848)
{
double freq;
if (ad1848->type >= AD1848_TYPE_CS4235) {
if (ad1848->xregs[11] & 0x20) {
if (ad1848->type >= AD1848_TYPE_CS4232) {
if (ad1848->xregs[11] & 0x20) { /* CS4236B+ only */
freq = 16934400.0;
switch (ad1848->xregs[13]) {
default:
@@ -182,7 +183,7 @@ ad1848_read(uint16_t addr, void *priv)
case 18:
case 19:
if (ad1848->type >= AD1848_TYPE_CS4235) {
if (ad1848->type >= AD1848_TYPE_CS4236B) {
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 */
@@ -192,13 +193,13 @@ ad1848_read(uint16_t addr, void *priv)
case 20:
case 21:
/* Backdoor to the Control/RAM registers on CS4235. */
if ((ad1848->type == AD1848_TYPE_CS4235) && (ad1848->xregs[18] & 0x80))
/* 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->type >= AD1848_TYPE_CS4236B) && (ad1848->regs[23] & 0x08)) {
if ((ad1848->xindex & 0xfe) == 0x00) /* remapped line volume */
ret = ad1848->regs[18 + ad1848->xindex];
else
@@ -235,7 +236,7 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv)
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)
if (ad1848->type >= AD1848_TYPE_CS4236B)
ad1848->regs[23] &= ~0x08; /* clear XRAE */
ad1848->trd = val & 0x20;
ad1848->mce = val & 0x40;
@@ -244,7 +245,7 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv)
case 1:
switch (ad1848->index) {
case 10:
if (ad1848->type < AD1848_TYPE_CS4235)
if (ad1848->type < AD1848_TYPE_CS4232)
break;
fallthrough;
@@ -282,13 +283,13 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv)
case 17:
/* Enable additional data formats on modes 2 and 3 where supported. */
if ((ad1848->type == AD1848_TYPE_CS4231) || (ad1848->type == AD1848_TYPE_CS4236))
if ((ad1848->type == AD1848_TYPE_CS4231) || (ad1848->type == AD1848_TYPE_CS4236B))
ad1848->fmt_mask = (val & 0x40) ? 0xf0 : 0x70;
break;
case 18:
case 19:
if (ad1848->type >= AD1848_TYPE_CS4235) {
if (ad1848->type >= AD1848_TYPE_CS4236B) {
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;
@@ -332,8 +333,8 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv)
case 20:
case 21:
/* Backdoor to the Control/RAM registers on CS4235. */
if ((ad1848->type == AD1848_TYPE_CS4235) && (ad1848->xregs[18] & 0x80)) {
/* 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];
}
@@ -344,7 +345,7 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv)
break;
case 23:
if ((ad1848->type >= AD1848_TYPE_CS4235) && ((ad1848->regs[12] & 0x60) == 0x60)) {
if ((ad1848->type >= AD1848_TYPE_CS4236B) && ((ad1848->regs[12] & 0x60) == 0x60)) {
if (!(ad1848->regs[23] & 0x08)) { /* existing (not new) XRAE is clear */
ad1848->xindex = ((val & 0x04) << 2) | (val >> 4);
break;
@@ -401,7 +402,11 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv)
case 25:
return;
case 27:
if (ad1848->type != AD1848_TYPE_DEFAULT)
if ((ad1848->type != AD1848_TYPE_CS4232) && (ad1848->type != AD1848_TYPE_CS4236))
return;
break;
case 29:
if ((ad1848->type != AD1848_TYPE_CS4232) && (ad1848->type != AD1848_TYPE_CS4236))
return;
break;
@@ -456,17 +461,13 @@ ad1848_process_mulaw(uint8_t byte)
{
byte = ~byte;
int temp = (((byte & 0x0f) << 3) + 0x84);
int16_t dec;
temp <<= ((byte & 0x70) >> 4);
temp = (byte & 0x80) ? (0x84 - temp) : (temp - 0x84);
if (temp > 32767)
dec = 32767;
return 32767;
else if (temp < -32768)
dec = -32768;
else
dec = (int16_t) temp;
return dec;
return -32768;
return (int16_t) temp;
}
static int16_t
@@ -489,8 +490,7 @@ ad1848_process_alaw(uint8_t byte)
dec |= 0x108;
break;
}
dec = (byte & 0x80) ? dec : -dec;
return (int16_t) dec;
return (int16_t) ((byte & 0x80) ? dec : -dec);
}
static uint32_t
@@ -704,10 +704,7 @@ ad1848_init(ad1848_t *ad1848, uint8_t type)
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;
else
ad1848->regs[12] = 0xa;
ad1848->regs[12] = (type >= AD1848_TYPE_CS4248) ? 0x8a : 0xa;
ad1848->regs[13] = 0;
ad1848->regs[14] = ad1848->regs[15] = 0;
@@ -719,27 +716,29 @@ ad1848_init(ad1848_t *ad1848, uint8_t type)
ad1848->regs[25] = CS4231;
ad1848->regs[26] = 0x80;
ad1848->regs[29] = 0x80;
} else if (type >= AD1848_TYPE_CS4235) {
} else if (type >= AD1848_TYPE_CS4232) {
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[25] = (type == AD1848_TYPE_CS4232) ? CS4232 : 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;
if (type >= AD1848_TYPE_CS4236B) {
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);
@@ -747,7 +746,7 @@ 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_updatevolmask(ad1848);
if (type == AD1848_TYPE_CS4235)
if (type >= AD1848_TYPE_CS4235)
ad1848->fmt_mask = 0x50;
else
ad1848->fmt_mask = 0x70;