mirror of
https://github.com/86Box/86Box.git
synced 2026-02-22 01:25:33 -07:00
Initial implementation of the Crystal CS4232 audio controller
This commit is contained in:
@@ -177,6 +177,7 @@ extern const device_t sb_awe64_ide_device;
|
||||
extern const device_t sb_awe64_gold_device;
|
||||
|
||||
/* Crystal CS423x */
|
||||
extern const device_t cs4232_onboard_device;
|
||||
extern const device_t cs4235_device;
|
||||
extern const device_t cs4235_onboard_device;
|
||||
extern const device_t cs4236_onboard_device;
|
||||
|
||||
@@ -88,6 +88,20 @@ static const uint8_t slam_init_key[32] = { 0x96, 0x35, 0x9A, 0xCD, 0xE6, 0xF3, 0
|
||||
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 cs4232_default[] = {
|
||||
// clang-format off
|
||||
/* Chip configuration */
|
||||
0x00, /* external decode length */
|
||||
0x48, /* reserved */
|
||||
0x75, 0xb9, 0xfc, /* IRQ routing */
|
||||
0x10, 0x03, /* DMA routing */
|
||||
|
||||
/* Default PnP data */
|
||||
0x0e, 0x63, 0x42, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00 /* hinted by documentation to be just the header */
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static const uint8_t cs4236_default[] = {
|
||||
// clang-format off
|
||||
/* Chip configuration */
|
||||
@@ -388,9 +402,17 @@ cs423x_write(uint16_t addr, uint8_t val, void *priv)
|
||||
|
||||
case 6: /* RAM Access End */
|
||||
/* TriGem Delhi-III BIOS writes undocumented value 0x40 instead of 0x00. */
|
||||
if ((val == 0x00) || (val == 0x40)) {
|
||||
/* Intel Atlantis, Holly, Monaco, Morrison and Thor BIOSes use several undocumented values */
|
||||
/* 0x25, 0x60, 0x69, 0x86, 0xE2, 0xFE and 0xFF were observed on these BIOSes */
|
||||
/* CS4232 likely accepts any written value to end RAM writes */
|
||||
if ((val == 0x00) || (val == 0x40) || (dev->type == CRYSTAL_CS4232)) {
|
||||
cs423x_log("CS423x: RAM end\n");
|
||||
dev->ram_dl = CRYSTAL_RAM_CMD;
|
||||
/* CS4232 resource data at 0x2090/2091 is written backwards */
|
||||
if (dev->type == CRYSTAL_CS4232) {
|
||||
dev->ram_data[0x2090] = 0x00;
|
||||
dev->ram_data[0x2091] = 0x48;
|
||||
}
|
||||
|
||||
/* Update PnP state and resource data. */
|
||||
dev->pnp_size = (dev->type >= CRYSTAL_CS4236) ? 384 : 256; /* we don't know the length */
|
||||
@@ -808,6 +830,10 @@ static void
|
||||
cs423x_load_defaults(cs423x_t *dev, uint8_t *dest)
|
||||
{
|
||||
switch (dev->type) {
|
||||
case CRYSTAL_CS4232:
|
||||
memcpy(dest, cs4232_default, sizeof(cs4232_default));
|
||||
dev->pnp_size = 9; /* header-only PnP ROM size */
|
||||
break;
|
||||
case CRYSTAL_CS4236:
|
||||
case CRYSTAL_CS4236B:
|
||||
case CRYSTAL_CS4237B:
|
||||
@@ -841,7 +867,11 @@ cs423x_reset(void *priv)
|
||||
memset(dev->ram_data, 0, sizeof(dev->ram_data));
|
||||
|
||||
/* Load default configuration data to RAM. */
|
||||
cs423x_load_defaults(dev, &dev->ram_data[0x4000]);
|
||||
/* CS4232 uses 0x2090 as the initial RAM location instead of 0x4000 */
|
||||
if (dev->type == CRYSTAL_CS4232)
|
||||
cs423x_load_defaults(dev, &dev->ram_data[0x2090]);
|
||||
else
|
||||
cs423x_load_defaults(dev, &dev->ram_data[0x4000]);
|
||||
|
||||
if (dev->eeprom) {
|
||||
/* Load EEPROM data to RAM if the magic bytes are present. */
|
||||
@@ -890,6 +920,7 @@ cs423x_init(const device_t *info)
|
||||
dev->type = info->local & 0xff;
|
||||
cs423x_log("CS423x: init(%02X)\n", dev->type);
|
||||
switch (dev->type) {
|
||||
case CRYSTAL_CS4232:
|
||||
case CRYSTAL_CS4236:
|
||||
case CRYSTAL_CS4236B:
|
||||
case CRYSTAL_CS4237B:
|
||||
@@ -897,13 +928,16 @@ cs423x_init(const device_t *info)
|
||||
case CRYSTAL_CS4235:
|
||||
case CRYSTAL_CS4239:
|
||||
/* Different WSS codec families. */
|
||||
dev->ad1848_type = (dev->type >= CRYSTAL_CS4235) ? AD1848_TYPE_CS4235 : ((dev->type >= CRYSTAL_CS4236B) ? AD1848_TYPE_CS4236B : AD1848_TYPE_CS4236);
|
||||
dev->ad1848_type = (dev->type >= CRYSTAL_CS4235) ? AD1848_TYPE_CS4235 : ((dev->type >= CRYSTAL_CS4236B) ? AD1848_TYPE_CS4236B : (dev->type >= CRYSTAL_CS4236) ? AD1848_TYPE_CS4236 : AD1848_TYPE_CS4232);
|
||||
|
||||
/* Different Chip Version and ID values (N/A on CS4236), which shouldn't be reset by ad1848_init. */
|
||||
dev->ad1848.xregs[25] = dev->type;
|
||||
|
||||
/* Same EEPROM structure. */
|
||||
dev->pnp_offset = 0x4013;
|
||||
/* Same EEPROM structure on CS4236+. CS4232 is different. */
|
||||
if (dev->type == CRYSTAL_CS4232)
|
||||
dev->pnp_offset = 0x2097;
|
||||
else
|
||||
dev->pnp_offset = 0x4013;
|
||||
|
||||
if (!(info->local & CRYSTAL_NOEEPROM)) {
|
||||
/* Start a new EEPROM with the default configuration data. */
|
||||
@@ -1056,6 +1090,20 @@ cs423x_speed_changed(void *priv)
|
||||
ad1848_speed_changed(&dev->ad1848);
|
||||
}
|
||||
|
||||
const device_t cs4232_onboard_device = {
|
||||
.name = "Crystal CS4232 (On-Board)",
|
||||
.internal_name = "cs4232_onboard",
|
||||
.flags = DEVICE_ISA16,
|
||||
.local = CRYSTAL_CS4232 | CRYSTAL_NOEEPROM,
|
||||
.init = cs423x_init,
|
||||
.close = cs423x_close,
|
||||
.reset = cs423x_reset,
|
||||
.available = cs423x_available,
|
||||
.speed_changed = cs423x_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t cs4235_device = {
|
||||
.name = "Crystal CS4235",
|
||||
.internal_name = "cs4235",
|
||||
|
||||
Reference in New Issue
Block a user