mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-26 11:11:48 +01:00
[Core/CD] improved accuracy of CDC transfer to Main-CPU & Sub-CPU (verified on real hardware, cf. Krikzz's mcd-verificator)
This commit is contained in:
parent
fcb6620202
commit
52b4f78b82
@ -24,6 +24,7 @@ Genesis Plus GX 1.7.5 (xx/xx/xxxx) (Eke-Eke)
|
|||||||
* 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 accuracy of Main-CPU & Sub-CPU access to CDC registers (verified on real hardware, cf. Krikzz's mcd-verificator)
|
||||||
|
* improved accuracy of CDC transfer to Main-CPU & Sub-CPU (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 |
147
core/cd_hw/cdc.c
147
core/cd_hw/cdc.c
@ -433,7 +433,7 @@ 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 EDT & DSR bits (SCD register $04) */
|
/* clear EDT & DSR bits (gate-array register $04) */
|
||||||
scd.regs[0x04>>1].byte.h &= 0x07;
|
scd.regs[0x04>>1].byte.h &= 0x07;
|
||||||
|
|
||||||
/* setup data transfer destination */
|
/* setup data transfer destination */
|
||||||
@ -442,8 +442,52 @@ void cdc_reg_w(unsigned char data)
|
|||||||
case 2: /* MAIN-CPU host read */
|
case 2: /* MAIN-CPU host read */
|
||||||
case 3: /* SUB-CPU host read */
|
case 3: /* SUB-CPU host read */
|
||||||
{
|
{
|
||||||
/* set DSR bit (SCD register $04) */
|
/* read 16-bit word from CDC RAM buffer (big-endian format) into gate-array register $08 */
|
||||||
|
/* Note: on real-hardware, 16-bit word is not immediately available, cf. https://github.com/MiSTer-devel/MegaCD_MiSTer/blob/master/docs/mcd%20logs/dma_sub_read.jpg for transfer timings */
|
||||||
|
scd.regs[0x08>>1].w = READ_WORD(cdc.ram, cdc.dac.w & 0x3ffe);
|
||||||
|
#ifdef LOG_CDC
|
||||||
|
error("CDC host read 0x%04x -> 0x%04x (dbc=0x%x) (%X)\n", cdc.dac.w, scd.regs[0x08>>1].w, cdc.dbc.w, s68k.pc);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* set DSR bit (gate-array register $04) */
|
||||||
scd.regs[0x04>>1].byte.h |= 0x40;
|
scd.regs[0x04>>1].byte.h |= 0x40;
|
||||||
|
|
||||||
|
/* increment data address counter */
|
||||||
|
cdc.dac.w += 2;
|
||||||
|
|
||||||
|
/* decrement data byte counter */
|
||||||
|
cdc.dbc.w -= 2;
|
||||||
|
|
||||||
|
/* end of transfer ? */
|
||||||
|
if ((int16)cdc.dbc.w < 0)
|
||||||
|
{
|
||||||
|
/* reset data byte counter (DBCH bits 4-7 should also be set to 1) */
|
||||||
|
cdc.dbc.w = 0xffff;
|
||||||
|
|
||||||
|
/* clear !DTEN and !DTBSY */
|
||||||
|
cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
|
||||||
|
|
||||||
|
/* pending Data Transfer End interrupt */
|
||||||
|
cdc.ifstat &= ~BIT_DTEI;
|
||||||
|
|
||||||
|
/* Data Transfer End interrupt enabled ? */
|
||||||
|
if (cdc.ifctrl & BIT_DTEIEN)
|
||||||
|
{
|
||||||
|
/* pending level 5 interrupt */
|
||||||
|
scd.pending |= (1 << 5);
|
||||||
|
|
||||||
|
/* level 5 interrupt enabled ? */
|
||||||
|
if (scd.regs[0x32>>1].byte.l & 0x20)
|
||||||
|
{
|
||||||
|
/* update IRQ level */
|
||||||
|
s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set EDT bit (gate-array register $04) */
|
||||||
|
scd.regs[0x04>>1].byte.h |= 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -727,57 +771,64 @@ unsigned char cdc_reg_r(void)
|
|||||||
|
|
||||||
unsigned short cdc_host_r(void)
|
unsigned short cdc_host_r(void)
|
||||||
{
|
{
|
||||||
/* check if data is available */
|
/* read CDC buffered data (gate-array register $08) */
|
||||||
|
uint16 data = scd.regs[0x08>>1].w;
|
||||||
|
|
||||||
|
/* check if host data transfer is enabled */
|
||||||
if (scd.regs[0x04>>1].byte.h & 0x40)
|
if (scd.regs[0x04>>1].byte.h & 0x40)
|
||||||
{
|
{
|
||||||
/* read 16-bit word from CDC RAM buffer (big-endian format) */
|
/* check if EDT bit (gate-array register $04) is set (host data transfer is finished) */
|
||||||
uint16 data = READ_WORD(cdc.ram, cdc.dac.w & 0x3ffe);
|
if (scd.regs[0x04>>1].byte.h & 0x80)
|
||||||
|
|
||||||
#ifdef LOG_CDC
|
|
||||||
error("CDC host read 0x%04x -> 0x%04x (dbc=0x%x) (%X)\n", cdc.dac.w, data, cdc.dbc.w, s68k.pc);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* increment data address counter */
|
|
||||||
cdc.dac.w += 2;
|
|
||||||
|
|
||||||
/* decrement data byte counter */
|
|
||||||
cdc.dbc.w -= 2;
|
|
||||||
|
|
||||||
/* end of transfer ? */
|
|
||||||
if ((int16)cdc.dbc.w <= 0)
|
|
||||||
{
|
{
|
||||||
/* reset data byte counter (DBCH bits 4-7 should be set to 1) */
|
/* clear DSR bit (gate-array register $04) */
|
||||||
cdc.dbc.w = 0xf000;
|
scd.regs[0x04>>1].byte.h &= ~0x40;
|
||||||
|
|
||||||
/* clear !DTEN and !DTBSY */
|
|
||||||
cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
|
|
||||||
|
|
||||||
/* pending Data Transfer End interrupt */
|
|
||||||
cdc.ifstat &= ~BIT_DTEI;
|
|
||||||
|
|
||||||
/* Data Transfer End interrupt enabled ? */
|
|
||||||
if (cdc.ifctrl & BIT_DTEIEN)
|
|
||||||
{
|
|
||||||
/* pending level 5 interrupt */
|
|
||||||
scd.pending |= (1 << 5);
|
|
||||||
|
|
||||||
/* level 5 interrupt enabled ? */
|
|
||||||
if (scd.regs[0x32>>1].byte.l & 0x20)
|
|
||||||
{
|
|
||||||
/* update IRQ level */
|
|
||||||
s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clear DSR bit & set EDT bit (SCD register $04) */
|
|
||||||
scd.regs[0x04>>1].byte.h = (scd.regs[0x04>>1].byte.h & 0x07) | 0x80;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* read next 16-bit word from CDC RAM buffer (big-endian format) into gate-array register $08 */
|
||||||
|
/* Note: on real-hardware, 16-bit word is not immediately available, cf. https://github.com/MiSTer-devel/MegaCD_MiSTer/blob/master/docs/mcd%20logs/dma_sub_read.jpg for transfer timings */
|
||||||
|
scd.regs[0x08>>1].w = READ_WORD(cdc.ram, cdc.dac.w & 0x3ffe);
|
||||||
|
#ifdef LOG_CDC
|
||||||
|
error("CDC host read 0x%04x -> 0x%04x (dbc=0x%x) (%X)\n", cdc.dac.w, scd.regs[0x08>>1].w, cdc.dbc.w, s68k.pc);
|
||||||
|
#endif
|
||||||
|
|
||||||
return data;
|
/* increment data address counter */
|
||||||
|
cdc.dac.w += 2;
|
||||||
|
|
||||||
|
/* decrement data byte counter */
|
||||||
|
cdc.dbc.w -= 2;
|
||||||
|
|
||||||
|
/* end of transfer ? */
|
||||||
|
if ((int16)cdc.dbc.w < 0)
|
||||||
|
{
|
||||||
|
/* reset data byte counter (DBCH bits 4-7 should also be set to 1) */
|
||||||
|
cdc.dbc.w = 0xffff;
|
||||||
|
|
||||||
|
/* clear !DTEN and !DTBSY */
|
||||||
|
cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
|
||||||
|
|
||||||
|
/* pending Data Transfer End interrupt */
|
||||||
|
cdc.ifstat &= ~BIT_DTEI;
|
||||||
|
|
||||||
|
/* Data Transfer End interrupt enabled ? */
|
||||||
|
if (cdc.ifctrl & BIT_DTEIEN)
|
||||||
|
{
|
||||||
|
/* pending level 5 interrupt */
|
||||||
|
scd.pending |= (1 << 5);
|
||||||
|
|
||||||
|
/* level 5 interrupt enabled ? */
|
||||||
|
if (scd.regs[0x32>>1].byte.l & 0x20)
|
||||||
|
{
|
||||||
|
/* update IRQ level */
|
||||||
|
s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set EDT bit (gate-array register $04) */
|
||||||
|
scd.regs[0x04>>1].byte.h |= 0x80;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LOG_CDC
|
return data;
|
||||||
error("error reading CDC host (data transfer disabled)\n");
|
|
||||||
#endif
|
|
||||||
return 0xffff;
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user