[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:
ekeeke 2023-11-25 19:09:03 +01:00
parent b330eb85cf
commit fcb6620202
12 changed files with 181 additions and 83 deletions

View File

@ -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 configurable CD-DA and PCM outputs mixing volume
* added setting to enable/disable CD access time simulation * 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 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 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 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 emulation of mirrored memory areas
* improved savestate format * improved savestate format
* improved Sub-CPU synchronization with Main-CPU (fixes "Soul Star") * 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

View File

@ -68,6 +68,18 @@
void cdc_init(void) void cdc_init(void)
{ {
memset(&cdc, 0, sizeof(cdc_t)); 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) void cdc_reset(void)
@ -140,7 +152,19 @@ int cdc_context_save(uint8 *state)
tmp8 = 0; 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); save_param(&tmp8, 1);
return bufferptr; return bufferptr;
@ -151,7 +175,19 @@ int cdc_context_load(uint8 *state)
uint8 tmp8; uint8 tmp8;
int bufferptr = 0; 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); load_param(&tmp8, 1);
switch (tmp8) switch (tmp8)
@ -333,9 +369,9 @@ void cdc_decoder_update(uint32 header)
void cdc_reg_w(unsigned char data) void cdc_reg_w(unsigned char data)
{ {
#ifdef LOG_CDC #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 #endif
switch (scd.regs[0x04>>1].byte.l & 0x0F) switch (scd.regs[0x04>>1].byte.l)
{ {
case 0x01: /* IFCTRL */ case 0x01: /* IFCTRL */
{ {
@ -370,28 +406,23 @@ void cdc_reg_w(unsigned char data)
} }
cdc.ifctrl = data; cdc.ifctrl = data;
scd.regs[0x04>>1].byte.l = 0x02;
break; break;
} }
case 0x02: /* DBCL */ case 0x02: /* DBCL */
cdc.dbc.byte.l = data; cdc.dbc.byte.l = data;
scd.regs[0x04>>1].byte.l = 0x03;
break; break;
case 0x03: /* DBCH */ case 0x03: /* DBCH */
cdc.dbc.byte.h = data; cdc.dbc.byte.h = data & 0x0f;
scd.regs[0x04>>1].byte.l = 0x04;
break; break;
case 0x04: /* DACL */ case 0x04: /* DACL */
cdc.dac.byte.l = data; cdc.dac.byte.l = data;
scd.regs[0x04>>1].byte.l = 0x05;
break; break;
case 0x05: /* DACH */ case 0x05: /* DACH */
cdc.dac.byte.h = data; cdc.dac.byte.h = data;
scd.regs[0x04>>1].byte.l = 0x06;
break; break;
case 0x06: /* DTRG */ case 0x06: /* DTRG */
@ -402,9 +433,6 @@ void cdc_reg_w(unsigned char data)
/* set !DTBSY and !DTEN */ /* set !DTBSY and !DTEN */
cdc.ifstat &= ~(BIT_DTBSY | BIT_DTEN); cdc.ifstat &= ~(BIT_DTBSY | BIT_DTEN);
/* clear DBCH bits 4-7 */
cdc.dbc.byte.h &= 0x0f;
/* clear EDT & DSR bits (SCD register $04) */ /* clear EDT & DSR bits (SCD register $04) */
scd.regs[0x04>>1].byte.h &= 0x07; 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; break;
} }
@ -479,9 +506,6 @@ void cdc_reg_w(unsigned char data)
/* clear pending data transfer end interrupt */ /* clear pending data transfer end interrupt */
cdc.ifstat |= BIT_DTEI; cdc.ifstat |= BIT_DTEI;
/* clear DBCH bits 4-7 */
cdc.dbc.byte.h &= 0x0f;
#if 0 #if 0
/* no pending decoder interrupt ? */ /* no pending decoder interrupt ? */
if ((cdc.ifstat | BIT_DECI) || !(cdc.ifctrl & BIT_DECIEN)) 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); s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1);
} }
#endif #endif
scd.regs[0x04>>1].byte.l = 0x08;
break; break;
} }
case 0x08: /* WAL */ case 0x08: /* WAL */
cdc.wa.byte.l = data; cdc.wa.byte.l = data;
scd.regs[0x04>>1].byte.l = 0x09;
break; break;
case 0x09: /* WAH */ case 0x09: /* WAH */
cdc.wa.byte.h = data; cdc.wa.byte.h = data;
scd.regs[0x04>>1].byte.l = 0x0a;
break; break;
case 0x0a: /* CTRL0 */ case 0x0a: /* CTRL0 */
@ -525,7 +546,6 @@ void cdc_reg_w(unsigned char data)
} }
cdc.ctrl[0] = data; cdc.ctrl[0] = data;
scd.regs[0x04>>1].byte.l = 0x0b;
break; break;
} }
@ -544,96 +564,125 @@ void cdc_reg_w(unsigned char data)
} }
cdc.ctrl[1] = data; cdc.ctrl[1] = data;
scd.regs[0x04>>1].byte.l = 0x0c;
break; break;
} }
case 0x0c: /* PTL */ case 0x0c: /* PTL */
cdc.pt.byte.l = data; cdc.pt.byte.l = data;
scd.regs[0x04>>1].byte.l = 0x0d;
break; break;
case 0x0d: /* PTH */ case 0x0d: /* PTH */
cdc.pt.byte.h = data; 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; break;
case 0x0f: /* RESET */ case 0x0f: /* RESET */
cdc_reset(); cdc_reset();
break; break;
default: /* by default, SBOUT is not used */ default: /* unemulated registers*/
break; 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) 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 */ case 0x01: /* IFSTAT */
scd.regs[0x04>>1].byte.l = 0x02; {
return cdc.ifstat; data = cdc.ifstat;
break;
}
case 0x02: /* DBCL */ case 0x02: /* DBCL */
scd.regs[0x04>>1].byte.l = 0x03; {
return cdc.dbc.byte.l; data = cdc.dbc.byte.l;
break;
}
case 0x03: /* DBCH */ case 0x03: /* DBCH */
scd.regs[0x04>>1].byte.l = 0x04; {
return cdc.dbc.byte.h; data = cdc.dbc.byte.h;
break;
}
case 0x04: /* HEAD0 */ 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 */ 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 */ 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 */ 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 */ case 0x08: /* PTL */
scd.regs[0x04>>1].byte.l = 0x09; {
return cdc.pt.byte.l; data = cdc.pt.byte.l;
break;
}
case 0x09: /* PTH */ case 0x09: /* PTH */
scd.regs[0x04>>1].byte.l = 0x0a; {
return cdc.pt.byte.h; data = cdc.pt.byte.h;
break;
}
case 0x0a: /* WAL */ case 0x0a: /* WAL */
scd.regs[0x04>>1].byte.l = 0x0b; {
return cdc.wa.byte.l; data = cdc.wa.byte.l;
break;
}
case 0x0b: /* WAH */ case 0x0b: /* WAH */
scd.regs[0x04>>1].byte.l = 0x0c; {
return cdc.wa.byte.h; data = cdc.wa.byte.h;
break;
}
case 0x0c: /* STAT0 */ 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) */ case 0x0d: /* STAT1 (always return 0) */
scd.regs[0x04>>1].byte.l = 0x0e; {
return 0x00; data = 0x00;
break;
}
case 0x0e: /* STAT2 */ case 0x0e: /* STAT2 */
scd.regs[0x04>>1].byte.l = 0x0f; {
return cdc.stat[2]; data = cdc.stat[2];
break;
}
case 0x0f: /* STAT3 */ 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) */ /* clear !VALST (note: this is not 100% correct but BIOS do not seem to care) */
cdc.stat[3] = BIT_VALST; cdc.stat[3] = BIT_VALST;
@ -653,13 +702,27 @@ unsigned char cdc_reg_r(void)
} }
#endif #endif
scd.regs[0x04>>1].byte.l = 0x00; break;
return data;
} }
default: /* by default, COMIN is always empty */ default: /* unemulated registers */
return 0xff; {
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) unsigned short cdc_host_r(void)

View File

@ -55,6 +55,7 @@ typedef struct
int cycles; int cycles;
void (*dma_w)(unsigned int length); /* DMA transfer callback */ 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 ram[0x4000 + 2352]; /* 16K external RAM (with one block overhead to handle buffer overrun) */
uint8 ar_mask;
} cdc_t; } cdc_t;
/* Function prototypes */ /* Function prototypes */

View File

@ -70,11 +70,6 @@
#define CD_TRAY 0x0E /* unused */ #define CD_TRAY 0x0E /* unused */
#define CD_TEST 0x0F /* unusec */ #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 */ /* CD track */
typedef struct typedef struct
{ {
@ -116,7 +111,6 @@ typedef struct
{ {
uint32 cycles; uint32 cycles;
uint32 latency; uint32 latency;
int type;
int loaded; int loaded;
int index; int index;
int lba; int lba;

View File

@ -584,14 +584,10 @@ static unsigned int scd_read_byte(unsigned int address)
return scd.regs[0x58>>1].byte.h; return scd.regs[0x58>>1].byte.h;
} }
/* CDC register data (controlled by BIOS, byte access only ?) */ /* CDC register data */
if (address == 0x07) if (address == 0x07)
{ {
unsigned int data = cdc_reg_r(); return 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;
} }
/* LED status */ /* LED status */
@ -725,6 +721,12 @@ static unsigned int scd_read_word(unsigned int address)
return data; return data;
} }
/* CDC register data */
if (address == 0x06)
{
return cdc_reg_r();
}
/* MAIN-CPU communication words */ /* MAIN-CPU communication words */
if ((address & 0x1f0) == 0x10) if ((address & 0x1f0) == 0x10)
{ {
@ -1036,6 +1038,12 @@ static void scd_write_byte(unsigned int address, unsigned int data)
return; return;
} }
case 0x05: /* CDC register address */
{
scd.regs[0x04 >> 1].byte.l = data & cdc.ar_mask;
return;
}
case 0x07: /* CDC register write */ case 0x07: /* CDC register write */
{ {
cdc_reg_w(data); cdc_reg_w(data);
@ -1339,6 +1347,12 @@ static void scd_write_word(unsigned int address, unsigned int data)
return; return;
} }
case 0x04: /* CDC mode & register address */
{
scd.regs[0x04 >> 1].w = data & (0x0700 | cdc.ar_mask);
return;
}
case 0x06: /* CDC register write */ case 0x06: /* CDC register write */
{ {
cdc_reg_w(data); cdc_reg_w(data);
@ -1406,7 +1420,7 @@ static void scd_write_word(unsigned int address, unsigned int data)
case 0x34: /* CD Fader */ case 0x34: /* CD Fader */
{ {
/* Wondermega hardware (CXD2554M digital filter) */ /* 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) */ /* only MSB is latched by CXD2554M chip, LSB is ignored (8-bit digital filter) */
/* attenuator data is 7-bit only (bits 0-7) */ /* 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) */ /* 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) */ /* only MSB is latched by SM5841A chip, LSB is ignored (8-bit digital filter) */
data = data >> 8; data = data >> 8;

View File

@ -1,6 +1,6 @@
/*************************************************************************************** /***************************************************************************************
* Genesis Plus * Genesis Plus
* Mega CD / Sega CD hardware * Mega-CD / Sega CD hardware
* *
* Copyright (C) 2012-2023 Eke-Eke (Genesis Plus GX) * Copyright (C) 2012-2023 Eke-Eke (Genesis Plus GX)
* *
@ -50,6 +50,12 @@
#define scd ext.cd_hw #define scd ext.cd_hw
#endif #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) */ /* CD hardware Master Clock (50 MHz) */
#define SCD_CLOCK 50000000 #define SCD_CLOCK 50000000
@ -76,6 +82,7 @@ typedef struct
int32 timer; /* Timer counter */ int32 timer; /* Timer counter */
uint8 pending; /* Pending interrupts */ uint8 pending; /* Pending interrupts */
uint8 dmna; /* Pending DMNA write status */ uint8 dmna; /* Pending DMNA write status */
uint8 type; /* CD hardware model */
gfx_t gfx_hw; /* Graphics processor */ gfx_t gfx_hw; /* Graphics processor */
cdc_t cdc_hw; /* CD data controller */ cdc_t cdc_hw; /* CD data controller */
cdd_t cdd_hw; /* CD drive processor */ cdd_t cdd_hw; /* CD drive processor */

View File

@ -3,7 +3,7 @@
* ROM Loading Support * ROM Loading Support
* *
* Copyright (C) 1998-2003 Charles Mac Donald (original code) * 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 * 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:
@ -422,17 +422,22 @@ int load_bios(int system)
if (!memcmp (&scd.bootrom[0x120], "WONDER-MEGA BOOT", 16)) if (!memcmp (&scd.bootrom[0x120], "WONDER-MEGA BOOT", 16))
{ {
/* Wondermega CD hardware */ /* Wondermega CD hardware */
cdd.type = CD_TYPE_WONDERMEGA; scd.type = CD_TYPE_WONDERMEGA;
} }
else if (!memcmp (&scd.bootrom[0x120], "WONDERMEGA2 BOOT", 16)) else if (!memcmp (&scd.bootrom[0x120], "WONDERMEGA2 BOOT", 16))
{ {
/* Wondermega M2 / X'Eye CD hardware */ /* 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 else
{ {
/* default CD hardware */ /* default CD hardware */
cdd.type = CD_TYPE_DEFAULT; scd.type = CD_TYPE_DEFAULT;
} }
#ifdef LSB_FIRST #ifdef LSB_FIRST

View File

@ -3,7 +3,7 @@
* ROM Loading Support * ROM Loading Support
* *
* Copyright (C) 1998-2003 Charles Mac Donald (original code) * 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 * 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

@ -376,6 +376,12 @@ unsigned int ctrl_io_read_byte(unsigned int address)
return scd.regs[0x04>>1].byte.h & 0xc7; 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 */ /* SUB-CPU communication flags */
if (index == 0x0f) 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; 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 */ /* default registers */
if (index < 0x30) if (index < 0x30)
{ {