[Core/CD] added support for Wondermega & Wondermega M2/X'Eye specific fader hardware (fixes CD-DA issues and freeze when using Wondermega, Wondermega M2 or X'Eye BIOS)

This commit is contained in:
ekeeke 2018-08-30 18:37:12 +02:00
parent 2de69b3a5c
commit d539061d99
8 changed files with 72 additions and 9 deletions

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 MiB

After

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 MiB

After

Width:  |  Height:  |  Size: 3.5 MiB

View File

@ -214,7 +214,7 @@ void cdd_reset(void)
cdd.status = cdd.loaded ? CD_STOP : NO_DISC; cdd.status = cdd.loaded ? CD_STOP : NO_DISC;
/* reset CD-DA fader (full volume) */ /* reset CD-DA fader (full volume) */
cdd.volume = 0x400; cdd.fader[0] = cdd.fader[1] = 0x400;
/* clear CD-DA output */ /* clear CD-DA output */
cdd.audio[0] = cdd.audio[1] = 0; cdd.audio[0] = cdd.audio[1] = 0;
@ -229,7 +229,7 @@ int cdd_context_save(uint8 *state)
save_param(&cdd.index, sizeof(cdd.index)); save_param(&cdd.index, sizeof(cdd.index));
save_param(&cdd.lba, sizeof(cdd.lba)); save_param(&cdd.lba, sizeof(cdd.lba));
save_param(&cdd.scanOffset, sizeof(cdd.scanOffset)); save_param(&cdd.scanOffset, sizeof(cdd.scanOffset));
save_param(&cdd.volume, sizeof(cdd.volume)); save_param(&cdd.fader, sizeof(cdd.fader));
save_param(&cdd.status, sizeof(cdd.status)); save_param(&cdd.status, sizeof(cdd.status));
return bufferptr; return bufferptr;
@ -255,7 +255,7 @@ int cdd_context_load(uint8 *state)
load_param(&cdd.index, sizeof(cdd.index)); load_param(&cdd.index, sizeof(cdd.index));
load_param(&cdd.lba, sizeof(cdd.lba)); load_param(&cdd.lba, sizeof(cdd.lba));
load_param(&cdd.scanOffset, sizeof(cdd.scanOffset)); load_param(&cdd.scanOffset, sizeof(cdd.scanOffset));
load_param(&cdd.volume, sizeof(cdd.volume)); load_param(&cdd.fader, sizeof(cdd.fader));
load_param(&cdd.status, sizeof(cdd.status)); load_param(&cdd.status, sizeof(cdd.status));
/* adjust current LBA within track limit */ /* adjust current LBA within track limit */
@ -1287,10 +1287,10 @@ void cdd_read_audio(unsigned int samples)
int i, mul, l, r; int i, mul, l, r;
/* current CD-DA fader volume */ /* current CD-DA fader volume */
int curVol = cdd.volume; int curVol = cdd.fader[0];
/* CD-DA fader volume setup (0-1024) */ /* CD-DA fader volume setup (0-1024) */
int endVol = scd.regs[0x34>>1].w >> 4; int endVol = cdd.fader[1];
/* read samples from current block */ /* read samples from current block */
#if defined(USE_LIBCHDR) #if defined(USE_LIBCHDR)
@ -1476,7 +1476,7 @@ void cdd_read_audio(unsigned int samples)
} }
/* save current CD-DA fader volume */ /* save current CD-DA fader volume */
cdd.volume = curVol; cdd.fader[0] = curVol;
/* save last audio output for next frame */ /* save last audio output for next frame */
cdd.audio[0] = prev_l; cdd.audio[0] = prev_l;

View File

@ -64,6 +64,11 @@
#define NO_DISC 0x0B #define NO_DISC 0x0B
#define CD_END 0x0C #define CD_END 0x0C
/* CD-DA digital filter types */
#define CD_TYPE_DEFAULT 0x00
#define CD_TYPE_WONDERMEGA 0x01
#define CD_TYPE_WONDERMEGA_M2 0x02
/* CD track */ /* CD track */
typedef struct typedef struct
{ {
@ -103,11 +108,12 @@ typedef struct
{ {
uint32 cycles; uint32 cycles;
uint32 latency; uint32 latency;
int type;
int loaded; int loaded;
int index; int index;
int lba; int lba;
int scanOffset; int scanOffset;
int volume; uint16 fader[2];
uint8 status; uint8 status;
uint16 sectorSize; uint16 sectorSize;
toc_t toc; toc_t toc;

View File

@ -2,7 +2,7 @@
* Genesis Plus * Genesis Plus
* Mega CD / Sega CD hardware * Mega CD / Sega CD hardware
* *
* Copyright (C) 2012-2016 Eke-Eke (Genesis Plus GX) * Copyright (C) 2012-2018 Eke-Eke (Genesis Plus GX)
* *
* Redistribution and use of this code or any derivative works are permitted * Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met: * provided that the following conditions are met:
@ -1281,6 +1281,46 @@ static void scd_write_word(unsigned int address, unsigned int data)
return; return;
} }
case 0x34: /* CD Fader */
{
/* Wondermega hardware (CXD2554M digital filter) */
if (cdd.type == CD_TYPE_WONDERMEGA)
{
/* only MSB is latched by CXD2554M chip, LSB is ignored (8-bit digital filter) */
/* attenuator data is 7-bit only (bits 0-7) */
data = (data >> 8) & 0x7f;
/* scale CXD2554M volume (0-127) to full (LC7883KM compatible) volume range (0-1024) */
cdd.fader[1] = (1024 * data) / 127 ;
}
/* Wondermega M2 / X'Eye hardware (SM5841A digital filter) */
else if (cdd.type == CD_TYPE_WONDERMEGA_M2)
{
/* only MSB is latched by SM5841A chip, LSB is ignored (8-bit digital filter) */
data = data >> 8;
/* attenuator data is set only when command bit (bit 0) is cleared (other commands are ignored) */
if (data & 0x01) return;
/* attenuator data is 7-bit only (bits 8-1) and reverted (bit 1 = msb) */
/* bit reversing formula taken from http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits */
data = (((((data * 0x0802) & 0x22110) | ((data * 0x8020) & 0x88440)) * 0x10101) >> 16) & 0x7f;
/* convert & scale SM5841A attenuation (127-0) to full (LC7883KM compatible) volume range (0-1024) */
cdd.fader[1] = (1024 * (127 - data)) / 127 ;
}
/* default CD hardware (LC7883KM digital filter) */
else
{
/* get LC7883KM volume data (12-bit) */
cdd.fader[1] = data >> 4 ;
}
return;
}
case 0x4a: /* CDD command 9 (controlled by BIOS, word access only ?) */ case 0x4a: /* CDD command 9 (controlled by BIOS, word access only ?) */
{ {
scd.regs[0x4a>>1].w = 0; scd.regs[0x4a>>1].w = 0;

View File

@ -2,7 +2,7 @@
* Genesis Plus * Genesis Plus
* Mega CD / Sega CD hardware * Mega CD / Sega CD hardware
* *
* Copyright (C) 2012-2016 Eke-Eke (Genesis Plus GX) * Copyright (C) 2012-2018 Eke-Eke (Genesis Plus GX)
* *
* Redistribution and use of this code or any derivative works are permitted * Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met: * provided that the following conditions are met:

View File

@ -417,6 +417,23 @@ int load_bios(int system)
/* CD BOOTROM loaded ? */ /* CD BOOTROM loaded ? */
if (size > 0) if (size > 0)
{ {
/* auto-detect CD hardware model */
if (!memcmp (&scd.bootrom[0x120], "WONDER-MEGA BOOT", 16))
{
/* Wondermega CD hardware */
cdd.type = CD_TYPE_WONDERMEGA;
}
else if (!memcmp (&scd.bootrom[0x120], "WONDERMEGA2 BOOT", 16))
{
/* Wondermega M2 / X'Eye CD hardware */
cdd.type = CD_TYPE_WONDERMEGA_M2;
}
else
{
/* default CD hardware */
cdd.type = CD_TYPE_DEFAULT;
}
#ifdef LSB_FIRST #ifdef LSB_FIRST
/* Byteswap ROM to optimize 16-bit access */ /* Byteswap ROM to optimize 16-bit access */
int i; int i;