mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-11-13 06:15:07 +01:00
[Core/CD] added limited support for LC89513K extended registers (only when Wondermega M2, X'Eye, CDX or Multi-Mega BIOS is detected) and improved accuracy of Main-CPU & Sub-CPU access to CDC registers (fixes mcd-verificator CDC REGS tests)
This commit is contained in:
parent
b330eb85cf
commit
fcb6620202
@ -20,8 +20,10 @@ Genesis Plus GX 1.7.5 (xx/xx/xxxx) (Eke-Eke)
|
||||
* added configurable CD-DA and PCM outputs mixing volume
|
||||
* added setting to enable/disable CD access time simulation
|
||||
* added emulation of Word-RAM access limitations in 2M mode (fixes graphical issues in Marko's Magic Football)
|
||||
* added limited support for LC89513K extended registers when Wondermega M2, X'Eye, CDX or Multi-Mega BIOS is detected (fixes Krikzz's mcd-verificator CDC REGS tests)
|
||||
* improved Timer interrupt timings and CDD interrupt accuracy (fixes audio stutters during Popful Mail FMV)
|
||||
* improved CDC emulation (fixes random freezes during Jeopardy & ESPN Sunday Night NFL intro)
|
||||
* improved accuracy of Main-CPU & Sub-CPU access to CDC registers (verified on real hardware, cf. Krikzz's mcd-verificator)
|
||||
* improved emulation of mirrored memory areas
|
||||
* improved savestate format
|
||||
* improved Sub-CPU synchronization with Main-CPU (fixes "Soul Star")
|
||||
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 3.8 MiB After Width: | Height: | Size: 3.8 MiB |
Binary file not shown.
Before Width: | Height: | Size: 4.0 MiB After Width: | Height: | Size: 4.0 MiB |
189
core/cd_hw/cdc.c
189
core/cd_hw/cdc.c
@ -68,6 +68,18 @@
|
||||
void cdc_init(void)
|
||||
{
|
||||
memset(&cdc, 0, sizeof(cdc_t));
|
||||
|
||||
/* autodetect CDC configuration */
|
||||
if ((scd.type == CD_TYPE_WONDERMEGA_M2) || (scd.type == CD_TYPE_CDX))
|
||||
{
|
||||
/* LC89513K chip (Wondermega M2 / X'Eye / CDX / Multi-Mega) */
|
||||
cdc.ar_mask = 0x1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* LC8951 or LC89515 chip (default)*/
|
||||
cdc.ar_mask = 0x0f;
|
||||
}
|
||||
}
|
||||
|
||||
void cdc_reset(void)
|
||||
@ -140,7 +152,19 @@ int cdc_context_save(uint8 *state)
|
||||
tmp8 = 0;
|
||||
}
|
||||
|
||||
save_param(&cdc, sizeof(cdc));
|
||||
|
||||
save_param(&cdc.ifstat, sizeof(cdc.ifstat));
|
||||
save_param(&cdc.ifctrl, sizeof(cdc.ifctrl));
|
||||
save_param(&cdc.dbc, sizeof(cdc.dbc));
|
||||
save_param(&cdc.dac, sizeof(cdc.dac));
|
||||
save_param(&cdc.pt, sizeof(cdc.pt));
|
||||
save_param(&cdc.wa, sizeof(cdc.wa));
|
||||
save_param(&cdc.ctrl, sizeof(cdc.ctrl));
|
||||
save_param(&cdc.head, sizeof(cdc.head));
|
||||
save_param(&cdc.stat, sizeof(cdc.stat));
|
||||
save_param(&cdc.cycles, sizeof(cdc.cycles));
|
||||
save_param(&cdc.dma_w, sizeof(cdc.dma_w));
|
||||
save_param(&cdc.ram, sizeof(cdc.ram));
|
||||
save_param(&tmp8, 1);
|
||||
|
||||
return bufferptr;
|
||||
@ -151,7 +175,19 @@ int cdc_context_load(uint8 *state)
|
||||
uint8 tmp8;
|
||||
int bufferptr = 0;
|
||||
|
||||
load_param(&cdc, sizeof(cdc));
|
||||
load_param(&cdc.ifstat, sizeof(cdc.ifstat));
|
||||
load_param(&cdc.ifctrl, sizeof(cdc.ifctrl));
|
||||
load_param(&cdc.dbc, sizeof(cdc.dbc));
|
||||
load_param(&cdc.dac, sizeof(cdc.dac));
|
||||
load_param(&cdc.pt, sizeof(cdc.pt));
|
||||
load_param(&cdc.wa, sizeof(cdc.wa));
|
||||
load_param(&cdc.ctrl, sizeof(cdc.ctrl));
|
||||
load_param(&cdc.head, sizeof(cdc.head));
|
||||
load_param(&cdc.stat, sizeof(cdc.stat));
|
||||
load_param(&cdc.cycles, sizeof(cdc.cycles));
|
||||
load_param(&cdc.dma_w, sizeof(cdc.dma_w));
|
||||
load_param(&cdc.ram, sizeof(cdc.ram));
|
||||
|
||||
load_param(&tmp8, 1);
|
||||
|
||||
switch (tmp8)
|
||||
@ -333,9 +369,9 @@ void cdc_decoder_update(uint32 header)
|
||||
void cdc_reg_w(unsigned char data)
|
||||
{
|
||||
#ifdef LOG_CDC
|
||||
error("CDC register %X write 0x%04x (%X)\n", scd.regs[0x04>>1].byte.l & 0x0F, data, s68k.pc);
|
||||
error("CDC register %d write 0x%04x (%X)\n", scd.regs[0x04>>1].byte.l, data, s68k.pc);
|
||||
#endif
|
||||
switch (scd.regs[0x04>>1].byte.l & 0x0F)
|
||||
switch (scd.regs[0x04>>1].byte.l)
|
||||
{
|
||||
case 0x01: /* IFCTRL */
|
||||
{
|
||||
@ -370,28 +406,23 @@ void cdc_reg_w(unsigned char data)
|
||||
}
|
||||
|
||||
cdc.ifctrl = data;
|
||||
scd.regs[0x04>>1].byte.l = 0x02;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x02: /* DBCL */
|
||||
cdc.dbc.byte.l = data;
|
||||
scd.regs[0x04>>1].byte.l = 0x03;
|
||||
break;
|
||||
|
||||
case 0x03: /* DBCH */
|
||||
cdc.dbc.byte.h = data;
|
||||
scd.regs[0x04>>1].byte.l = 0x04;
|
||||
cdc.dbc.byte.h = data & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x04: /* DACL */
|
||||
cdc.dac.byte.l = data;
|
||||
scd.regs[0x04>>1].byte.l = 0x05;
|
||||
break;
|
||||
|
||||
case 0x05: /* DACH */
|
||||
cdc.dac.byte.h = data;
|
||||
scd.regs[0x04>>1].byte.l = 0x06;
|
||||
break;
|
||||
|
||||
case 0x06: /* DTRG */
|
||||
@ -402,9 +433,6 @@ void cdc_reg_w(unsigned char data)
|
||||
/* set !DTBSY and !DTEN */
|
||||
cdc.ifstat &= ~(BIT_DTBSY | BIT_DTEN);
|
||||
|
||||
/* clear DBCH bits 4-7 */
|
||||
cdc.dbc.byte.h &= 0x0f;
|
||||
|
||||
/* clear EDT & DSR bits (SCD register $04) */
|
||||
scd.regs[0x04>>1].byte.h &= 0x07;
|
||||
|
||||
@ -470,7 +498,6 @@ void cdc_reg_w(unsigned char data)
|
||||
}
|
||||
}
|
||||
|
||||
scd.regs[0x04>>1].byte.l = 0x07;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -479,9 +506,6 @@ void cdc_reg_w(unsigned char data)
|
||||
/* clear pending data transfer end interrupt */
|
||||
cdc.ifstat |= BIT_DTEI;
|
||||
|
||||
/* clear DBCH bits 4-7 */
|
||||
cdc.dbc.byte.h &= 0x0f;
|
||||
|
||||
#if 0
|
||||
/* no pending decoder interrupt ? */
|
||||
if ((cdc.ifstat | BIT_DECI) || !(cdc.ifctrl & BIT_DECIEN))
|
||||
@ -493,18 +517,15 @@ void cdc_reg_w(unsigned char data)
|
||||
s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1);
|
||||
}
|
||||
#endif
|
||||
scd.regs[0x04>>1].byte.l = 0x08;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x08: /* WAL */
|
||||
cdc.wa.byte.l = data;
|
||||
scd.regs[0x04>>1].byte.l = 0x09;
|
||||
break;
|
||||
|
||||
case 0x09: /* WAH */
|
||||
cdc.wa.byte.h = data;
|
||||
scd.regs[0x04>>1].byte.l = 0x0a;
|
||||
break;
|
||||
|
||||
case 0x0a: /* CTRL0 */
|
||||
@ -525,7 +546,6 @@ void cdc_reg_w(unsigned char data)
|
||||
}
|
||||
|
||||
cdc.ctrl[0] = data;
|
||||
scd.regs[0x04>>1].byte.l = 0x0b;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -544,96 +564,125 @@ void cdc_reg_w(unsigned char data)
|
||||
}
|
||||
|
||||
cdc.ctrl[1] = data;
|
||||
scd.regs[0x04>>1].byte.l = 0x0c;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x0c: /* PTL */
|
||||
cdc.pt.byte.l = data;
|
||||
scd.regs[0x04>>1].byte.l = 0x0d;
|
||||
break;
|
||||
|
||||
case 0x0d: /* PTH */
|
||||
cdc.pt.byte.h = data;
|
||||
scd.regs[0x04>>1].byte.l = 0x0e;
|
||||
break;
|
||||
|
||||
case 0x0e: /* CTRL2 (unused) */
|
||||
scd.regs[0x04>>1].byte.l = 0x0f;
|
||||
break;
|
||||
|
||||
case 0x0f: /* RESET */
|
||||
cdc_reset();
|
||||
break;
|
||||
|
||||
default: /* by default, SBOUT is not used */
|
||||
default: /* unemulated registers*/
|
||||
break;
|
||||
}
|
||||
|
||||
/* increment address register (except when register #0 is selected) */
|
||||
if (scd.regs[0x04>>1].byte.l)
|
||||
{
|
||||
scd.regs[0x04>>1].byte.l = (scd.regs[0x04>>1].byte.l + 1) & cdc.ar_mask;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char cdc_reg_r(void)
|
||||
{
|
||||
switch (scd.regs[0x04>>1].byte.l & 0x0F)
|
||||
uint8 data;
|
||||
|
||||
switch (scd.regs[0x04>>1].byte.l)
|
||||
{
|
||||
case 0x01: /* IFSTAT */
|
||||
scd.regs[0x04>>1].byte.l = 0x02;
|
||||
return cdc.ifstat;
|
||||
{
|
||||
data = cdc.ifstat;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x02: /* DBCL */
|
||||
scd.regs[0x04>>1].byte.l = 0x03;
|
||||
return cdc.dbc.byte.l;
|
||||
{
|
||||
data = cdc.dbc.byte.l;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x03: /* DBCH */
|
||||
scd.regs[0x04>>1].byte.l = 0x04;
|
||||
return cdc.dbc.byte.h;
|
||||
{
|
||||
data = cdc.dbc.byte.h;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x04: /* HEAD0 */
|
||||
scd.regs[0x04>>1].byte.l = 0x05;
|
||||
return cdc.head[cdc.ctrl[1] & BIT_SHDREN][0];
|
||||
{
|
||||
data = cdc.head[cdc.ctrl[1] & BIT_SHDREN][0];
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x05: /* HEAD1 */
|
||||
scd.regs[0x04>>1].byte.l = 0x06;
|
||||
return cdc.head[cdc.ctrl[1] & BIT_SHDREN][1];
|
||||
{
|
||||
data = cdc.head[cdc.ctrl[1] & BIT_SHDREN][1];
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x06: /* HEAD2 */
|
||||
scd.regs[0x04>>1].byte.l = 0x07;
|
||||
return cdc.head[cdc.ctrl[1] & BIT_SHDREN][2];
|
||||
{
|
||||
data = cdc.head[cdc.ctrl[1] & BIT_SHDREN][2];
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x07: /* HEAD3 */
|
||||
scd.regs[0x04>>1].byte.l = 0x08;
|
||||
return cdc.head[cdc.ctrl[1] & BIT_SHDREN][3];
|
||||
{
|
||||
data = cdc.head[cdc.ctrl[1] & BIT_SHDREN][3];
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x08: /* PTL */
|
||||
scd.regs[0x04>>1].byte.l = 0x09;
|
||||
return cdc.pt.byte.l;
|
||||
{
|
||||
data = cdc.pt.byte.l;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x09: /* PTH */
|
||||
scd.regs[0x04>>1].byte.l = 0x0a;
|
||||
return cdc.pt.byte.h;
|
||||
{
|
||||
data = cdc.pt.byte.h;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x0a: /* WAL */
|
||||
scd.regs[0x04>>1].byte.l = 0x0b;
|
||||
return cdc.wa.byte.l;
|
||||
{
|
||||
data = cdc.wa.byte.l;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x0b: /* WAH */
|
||||
scd.regs[0x04>>1].byte.l = 0x0c;
|
||||
return cdc.wa.byte.h;
|
||||
{
|
||||
data = cdc.wa.byte.h;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x0c: /* STAT0 */
|
||||
scd.regs[0x04>>1].byte.l = 0x0d;
|
||||
return cdc.stat[0];
|
||||
{
|
||||
data = cdc.stat[0];
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x0d: /* STAT1 (always return 0) */
|
||||
scd.regs[0x04>>1].byte.l = 0x0e;
|
||||
return 0x00;
|
||||
{
|
||||
data = 0x00;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x0e: /* STAT2 */
|
||||
scd.regs[0x04>>1].byte.l = 0x0f;
|
||||
return cdc.stat[2];
|
||||
{
|
||||
data = cdc.stat[2];
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x0f: /* STAT3 */
|
||||
{
|
||||
uint8 data = cdc.stat[3];
|
||||
data = cdc.stat[3];
|
||||
|
||||
/* clear !VALST (note: this is not 100% correct but BIOS do not seem to care) */
|
||||
cdc.stat[3] = BIT_VALST;
|
||||
@ -653,13 +702,27 @@ unsigned char cdc_reg_r(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
scd.regs[0x04>>1].byte.l = 0x00;
|
||||
return data;
|
||||
break;
|
||||
}
|
||||
|
||||
default: /* by default, COMIN is always empty */
|
||||
return 0xff;
|
||||
default: /* unemulated registers */
|
||||
{
|
||||
data = 0xff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef LOG_CDC
|
||||
error("CDC register %d read 0x%02X (%X)\n", scd.regs[0x04>>1].byte.l, data, s68k.pc);
|
||||
#endif
|
||||
|
||||
/* increment address register (except when register #0 is selected) */
|
||||
if (scd.regs[0x04>>1].byte.l)
|
||||
{
|
||||
scd.regs[0x04>>1].byte.l = (scd.regs[0x04>>1].byte.l + 1) & cdc.ar_mask;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
unsigned short cdc_host_r(void)
|
||||
|
@ -55,6 +55,7 @@ typedef struct
|
||||
int cycles;
|
||||
void (*dma_w)(unsigned int length); /* DMA transfer callback */
|
||||
uint8 ram[0x4000 + 2352]; /* 16K external RAM (with one block overhead to handle buffer overrun) */
|
||||
uint8 ar_mask;
|
||||
} cdc_t;
|
||||
|
||||
/* Function prototypes */
|
||||
|
@ -70,11 +70,6 @@
|
||||
#define CD_TRAY 0x0E /* unused */
|
||||
#define CD_TEST 0x0F /* unusec */
|
||||
|
||||
/* CD-DA digital filter types */
|
||||
#define CD_TYPE_DEFAULT 0x00
|
||||
#define CD_TYPE_WONDERMEGA 0x01
|
||||
#define CD_TYPE_WONDERMEGA_M2 0x02
|
||||
|
||||
/* CD track */
|
||||
typedef struct
|
||||
{
|
||||
@ -116,7 +111,6 @@ typedef struct
|
||||
{
|
||||
uint32 cycles;
|
||||
uint32 latency;
|
||||
int type;
|
||||
int loaded;
|
||||
int index;
|
||||
int lba;
|
||||
|
@ -584,14 +584,10 @@ static unsigned int scd_read_byte(unsigned int address)
|
||||
return scd.regs[0x58>>1].byte.h;
|
||||
}
|
||||
|
||||
/* CDC register data (controlled by BIOS, byte access only ?) */
|
||||
/* CDC register data */
|
||||
if (address == 0x07)
|
||||
{
|
||||
unsigned int data = cdc_reg_r();
|
||||
#ifdef LOG_CDC
|
||||
error("CDC register %X read 0x%02X (%X)\n", scd.regs[0x04>>1].byte.l & 0x0F, data, s68k.pc);
|
||||
#endif
|
||||
return data;
|
||||
return cdc_reg_r();
|
||||
}
|
||||
|
||||
/* LED status */
|
||||
@ -725,6 +721,12 @@ static unsigned int scd_read_word(unsigned int address)
|
||||
return data;
|
||||
}
|
||||
|
||||
/* CDC register data */
|
||||
if (address == 0x06)
|
||||
{
|
||||
return cdc_reg_r();
|
||||
}
|
||||
|
||||
/* MAIN-CPU communication words */
|
||||
if ((address & 0x1f0) == 0x10)
|
||||
{
|
||||
@ -1036,6 +1038,12 @@ static void scd_write_byte(unsigned int address, unsigned int data)
|
||||
return;
|
||||
}
|
||||
|
||||
case 0x05: /* CDC register address */
|
||||
{
|
||||
scd.regs[0x04 >> 1].byte.l = data & cdc.ar_mask;
|
||||
return;
|
||||
}
|
||||
|
||||
case 0x07: /* CDC register write */
|
||||
{
|
||||
cdc_reg_w(data);
|
||||
@ -1339,6 +1347,12 @@ static void scd_write_word(unsigned int address, unsigned int data)
|
||||
return;
|
||||
}
|
||||
|
||||
case 0x04: /* CDC mode & register address */
|
||||
{
|
||||
scd.regs[0x04 >> 1].w = data & (0x0700 | cdc.ar_mask);
|
||||
return;
|
||||
}
|
||||
|
||||
case 0x06: /* CDC register write */
|
||||
{
|
||||
cdc_reg_w(data);
|
||||
@ -1406,7 +1420,7 @@ static void scd_write_word(unsigned int address, unsigned int data)
|
||||
case 0x34: /* CD Fader */
|
||||
{
|
||||
/* Wondermega hardware (CXD2554M digital filter) */
|
||||
if (cdd.type == CD_TYPE_WONDERMEGA)
|
||||
if (scd.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) */
|
||||
@ -1417,7 +1431,7 @@ static void scd_write_word(unsigned int address, unsigned int data)
|
||||
}
|
||||
|
||||
/* Wondermega M2 / X'Eye hardware (SM5841A digital filter) */
|
||||
else if (cdd.type == CD_TYPE_WONDERMEGA_M2)
|
||||
else if (scd.type == CD_TYPE_WONDERMEGA_M2)
|
||||
{
|
||||
/* only MSB is latched by SM5841A chip, LSB is ignored (8-bit digital filter) */
|
||||
data = data >> 8;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/***************************************************************************************
|
||||
* Genesis Plus
|
||||
* Mega CD / Sega CD hardware
|
||||
* Mega-CD / Sega CD hardware
|
||||
*
|
||||
* Copyright (C) 2012-2023 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
@ -50,6 +50,12 @@
|
||||
#define scd ext.cd_hw
|
||||
#endif
|
||||
|
||||
/* CD hardware models */
|
||||
#define CD_TYPE_DEFAULT 0x00
|
||||
#define CD_TYPE_WONDERMEGA 0x01
|
||||
#define CD_TYPE_WONDERMEGA_M2 0x02
|
||||
#define CD_TYPE_CDX 0x03
|
||||
|
||||
/* CD hardware Master Clock (50 MHz) */
|
||||
#define SCD_CLOCK 50000000
|
||||
|
||||
@ -76,6 +82,7 @@ typedef struct
|
||||
int32 timer; /* Timer counter */
|
||||
uint8 pending; /* Pending interrupts */
|
||||
uint8 dmna; /* Pending DMNA write status */
|
||||
uint8 type; /* CD hardware model */
|
||||
gfx_t gfx_hw; /* Graphics processor */
|
||||
cdc_t cdc_hw; /* CD data controller */
|
||||
cdd_t cdd_hw; /* CD drive processor */
|
||||
|
@ -3,7 +3,7 @@
|
||||
* ROM Loading Support
|
||||
*
|
||||
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
|
||||
* Copyright (C) 2007-2022 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2007-2023 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@ -422,17 +422,22 @@ int load_bios(int system)
|
||||
if (!memcmp (&scd.bootrom[0x120], "WONDER-MEGA BOOT", 16))
|
||||
{
|
||||
/* Wondermega CD hardware */
|
||||
cdd.type = CD_TYPE_WONDERMEGA;
|
||||
scd.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;
|
||||
scd.type = CD_TYPE_WONDERMEGA_M2;
|
||||
}
|
||||
else if (!memcmp (&scd.bootrom[0x120], "CDX BOOT ROM ", 16))
|
||||
{
|
||||
/* CDX / Multi-Mega CD hardware */
|
||||
scd.type = CD_TYPE_CDX;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* default CD hardware */
|
||||
cdd.type = CD_TYPE_DEFAULT;
|
||||
scd.type = CD_TYPE_DEFAULT;
|
||||
}
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
|
@ -3,7 +3,7 @@
|
||||
* ROM Loading Support
|
||||
*
|
||||
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
|
||||
* Copyright (C) 2007-2022 Eke-Eke (Genesis Plus GX)
|
||||
* Copyright (C) 2007-2023 Eke-Eke (Genesis Plus GX)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
|
@ -376,6 +376,12 @@ unsigned int ctrl_io_read_byte(unsigned int address)
|
||||
return scd.regs[0x04>>1].byte.h & 0xc7;
|
||||
}
|
||||
|
||||
/* CDC register address (not accessible from MAIN-CPU) */
|
||||
if (index == 0x05)
|
||||
{
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
/* SUB-CPU communication flags */
|
||||
if (index == 0x0f)
|
||||
{
|
||||
@ -546,6 +552,12 @@ unsigned int ctrl_io_read_word(unsigned int address)
|
||||
return (scd.regs[0x0c>>1].w + ((cycles - scd.stopwatch) / TIMERS_SCYCLES_RATIO)) & 0xfff;
|
||||
}
|
||||
|
||||
/* CDC Mode (CDC register address not accessible from MAIN-CPU) */
|
||||
if (index == 0x04)
|
||||
{
|
||||
return (scd.regs[index >> 1].byte.h << 8);
|
||||
}
|
||||
|
||||
/* default registers */
|
||||
if (index < 0x30)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user