mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2025-01-13 11:49:06 +01:00
[Core/CD] improved accuracy of CDC decoder processing (verified on real hardware, cf. Krikzz's mcd-verificator)
This commit is contained in:
parent
904613f51c
commit
e8a6086c89
@ -26,6 +26,7 @@ Genesis Plus GX 1.7.5 (xx/xx/xxxx) (Eke-Eke)
|
||||
* improved accuracy of Main-CPU & Sub-CPU access to CDC registers (verified on real hardware, cf. Krikzz's mcd-verificator)
|
||||
* improved accuracy of CDC data transfer to Main-CPU & Sub-CPU (verified on real hardware, cf. Krikzz's mcd-verificator)
|
||||
* improved accuracy of CDC DMA processing (verified on real hardware, cf. Krikzz's mcd-verificator)
|
||||
* improved accuracy of CDC decoder processing (verified on real hardware, cf. Krikzz's mcd-verificator)
|
||||
* improved accuracy of CDC interrupt processing (verified on real hardware, cf. Krikzz's mcd-verificator)
|
||||
* improved emulation of mirrored memory areas
|
||||
* improved savestate format
|
||||
|
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 |
@ -108,8 +108,8 @@ void cdc_reset(void)
|
||||
cdc.head[1][2] = 0x00;
|
||||
cdc.head[1][3] = 0x00;
|
||||
|
||||
/* reset CDC DMA cycle counter */
|
||||
cdc.cycles = 0;
|
||||
/* reset CDC DMA & decoder cycle counters */
|
||||
cdc.cycles[0] = cdc.cycles[1] = 0;
|
||||
|
||||
/* disable CDC DMA */
|
||||
cdc.dma_w = cdc.halted_dma_w = 0;
|
||||
@ -176,7 +176,6 @@ int cdc_context_save(uint8 *state)
|
||||
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);
|
||||
|
||||
@ -198,7 +197,6 @@ int cdc_context_load(uint8 *state)
|
||||
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);
|
||||
@ -290,6 +288,16 @@ void cdc_dma_init(void)
|
||||
/* Data Transfer End interrupt enabled ? */
|
||||
if (cdc.ifctrl & BIT_DTEIEN)
|
||||
{
|
||||
/* check end of CDC decoder active period */
|
||||
if ((cdc.irq & BIT_DECI) && (cdc.cycles[0] > cdc.cycles[1]))
|
||||
{
|
||||
/* clear pending decoder interrupt */
|
||||
cdc.ifstat |= BIT_DECI;
|
||||
|
||||
/* update CDC IRQ state */
|
||||
cdc.irq &= ~BIT_DECI;
|
||||
}
|
||||
|
||||
/* level 5 interrupt triggered only on CDC /INT falling edge with interrupt enabled on gate-array side */
|
||||
if (!cdc.irq && (scd.regs[0x32>>1].byte.l & 0x20))
|
||||
{
|
||||
@ -380,7 +388,7 @@ void cdc_dma_init(void)
|
||||
void cdc_dma_update(unsigned int cycles)
|
||||
{
|
||||
/* max number of bytes that can be transfered */
|
||||
int dma_bytes = (cycles - cdc.cycles + DMA_CYCLES_PER_BYTE - 1) / DMA_CYCLES_PER_BYTE;
|
||||
int dma_bytes = (cycles - cdc.cycles[0] + DMA_CYCLES_PER_BYTE - 1) / DMA_CYCLES_PER_BYTE;
|
||||
|
||||
/* always process blocks of 8 bytes */
|
||||
dma_bytes = (dma_bytes / 8) * 8;
|
||||
@ -391,6 +399,9 @@ void cdc_dma_update(unsigned int cycles)
|
||||
/* transfer remaining bytes using DMA */
|
||||
cdc.dma_w(cdc.dbc.w + 1);
|
||||
|
||||
/* update DMA cycle counter */
|
||||
cdc.cycles[0] += (cdc.dbc.w + 1) * DMA_CYCLES_PER_BYTE;
|
||||
|
||||
/* reset data byte counter (DBCH bits 4-7 should also be set to 1) */
|
||||
cdc.dbc.w = 0xffff;
|
||||
|
||||
@ -403,6 +414,16 @@ void cdc_dma_update(unsigned int cycles)
|
||||
/* Data Transfer End interrupt enabled ? */
|
||||
if (cdc.ifctrl & BIT_DTEIEN)
|
||||
{
|
||||
/* check end of CDC decoder active period */
|
||||
if ((cdc.irq & BIT_DECI) && (cdc.cycles[0] > cdc.cycles[1]))
|
||||
{
|
||||
/* clear pending decoder interrupt */
|
||||
cdc.ifstat |= BIT_DECI;
|
||||
|
||||
/* update CDC IRQ state */
|
||||
cdc.irq &= ~BIT_DECI;
|
||||
}
|
||||
|
||||
/* level 5 interrupt triggered only on CDC /INT falling edge with interrupt enabled on gate-array side*/
|
||||
if (!cdc.irq && (scd.regs[0x32>>1].byte.l & 0x20))
|
||||
{
|
||||
@ -424,7 +445,7 @@ void cdc_dma_update(unsigned int cycles)
|
||||
if (s68k.stopped & (1<<0x04))
|
||||
{
|
||||
/* sync SUB-CPU with CDC DMA */
|
||||
s68k.cycles = cdc.cycles;
|
||||
s68k.cycles = cdc.cycles[0];
|
||||
|
||||
/* restart SUB-CPU */
|
||||
s68k.stopped = 0;
|
||||
@ -445,7 +466,7 @@ void cdc_dma_update(unsigned int cycles)
|
||||
cdc.dbc.w -= dma_bytes;
|
||||
|
||||
/* update DMA cycle counter */
|
||||
cdc.cycles += dma_bytes * DMA_CYCLES_PER_BYTE;
|
||||
cdc.cycles[0] += dma_bytes * DMA_CYCLES_PER_BYTE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -463,6 +484,9 @@ void cdc_decoder_update(uint32 header)
|
||||
/* pending decoder interrupt */
|
||||
cdc.ifstat &= ~BIT_DECI;
|
||||
|
||||
/* update CDC decoder end cycle (value adjusted for MCD-verificator CDC FLAGS Tests #40 & #41) */
|
||||
cdc.cycles[1] = s68k.cycles + 269000;
|
||||
|
||||
/* decoder interrupt enabled ? */
|
||||
if (cdc.ifctrl & BIT_DECIEN)
|
||||
{
|
||||
@ -555,6 +579,16 @@ void cdc_reg_w(unsigned char data)
|
||||
{
|
||||
/* previous CDC IRQ state */
|
||||
uint8 prev_irq = cdc.irq;
|
||||
|
||||
/* check end of CDC decoder active period */
|
||||
if (s68k.cycles > cdc.cycles[1])
|
||||
{
|
||||
/* clear pending decoder interrupt */
|
||||
cdc.ifstat |= BIT_DECI;
|
||||
|
||||
/* update previous CDC IRQ state */
|
||||
prev_irq &= ~BIT_DECI;
|
||||
}
|
||||
|
||||
/* update CDC IRQ state according to DTEIEN and DECIEN bits */
|
||||
cdc.irq = ~cdc.ifstat & data & (BIT_DTEIEN | BIT_DECIEN);
|
||||
@ -614,7 +648,7 @@ void cdc_reg_w(unsigned char data)
|
||||
cdc_dma_init();
|
||||
|
||||
/* initialize DMA cycle counter */
|
||||
cdc.cycles = s68k.cycles;
|
||||
cdc.cycles[0] = s68k.cycles;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -708,6 +742,16 @@ unsigned char cdc_reg_r(void)
|
||||
{
|
||||
case 0x01: /* IFSTAT */
|
||||
{
|
||||
/* check end of CDC decoder active period */
|
||||
if (s68k.cycles > cdc.cycles[1])
|
||||
{
|
||||
/* clear pending decoder interrupt */
|
||||
cdc.ifstat |= BIT_DECI;
|
||||
|
||||
/* update CDC IRQ state */
|
||||
cdc.irq &= ~BIT_DECI;
|
||||
}
|
||||
|
||||
data = cdc.ifstat;
|
||||
break;
|
||||
}
|
||||
@ -869,6 +913,16 @@ unsigned short cdc_host_r(uint8 cpu_access)
|
||||
/* Data Transfer End interrupt enabled ? */
|
||||
if (cdc.ifctrl & BIT_DTEIEN)
|
||||
{
|
||||
/* check end of CDC decoder active period */
|
||||
if ((cdc.irq & BIT_DECI) && (cdc.cycles[0] > cdc.cycles[1]))
|
||||
{
|
||||
/* clear pending decoder interrupt */
|
||||
cdc.ifstat |= BIT_DECI;
|
||||
|
||||
/* update CDC IRQ state */
|
||||
cdc.irq &= ~BIT_DECI;
|
||||
}
|
||||
|
||||
/* level 5 interrupt triggered only on CDC /INT falling edge with interrupt enabled on gate-array side */
|
||||
if (!cdc.irq && (scd.regs[0x32>>1].byte.l & 0x20))
|
||||
{
|
||||
|
@ -55,7 +55,7 @@ typedef struct
|
||||
uint8 ctrl[2];
|
||||
uint8 head[2][4];
|
||||
uint8 stat[4];
|
||||
unsigned int cycles;
|
||||
int cycles[2];
|
||||
void (*dma_w)(unsigned int length); /* active DMA callback */
|
||||
void (*halted_dma_w)(unsigned int length); /* halted DMA callback */
|
||||
uint8 ram[0x4000 + 2352]; /* 16K external RAM (with one block overhead to handle buffer overrun) */
|
||||
|
@ -1983,9 +1983,11 @@ void scd_end_frame(unsigned int cycles)
|
||||
/* adjust Stopwatch counter for next frame (can be negative) */
|
||||
scd.stopwatch += (ticks * TIMERS_SCYCLES_RATIO) - cycles;
|
||||
|
||||
/* adjust SUB-CPU & GPU cycle counters for next frame */
|
||||
s68k.cycles -= cycles;
|
||||
gfx.cycles -= cycles;
|
||||
/* adjust SUB-CPU, GPU and CDC cycle counters for next frame */
|
||||
s68k.cycles -= cycles;
|
||||
gfx.cycles -= cycles;
|
||||
cdc.cycles[0] -= cycles;
|
||||
cdc.cycles[1] -= cycles;
|
||||
|
||||
/* reset CPU registers polling */
|
||||
m68k.poll.cycle = 0;
|
||||
|
@ -788,9 +788,9 @@ void ctrl_io_write_byte(unsigned int address, unsigned int data)
|
||||
cdc.halted_dma_w = 0;
|
||||
|
||||
/* synchronize CDC DMA with MAIN-CPU (only if not already ahead) */
|
||||
if (cdc.cycles < cycles)
|
||||
if (cdc.cycles[0] < cycles)
|
||||
{
|
||||
cdc.cycles = cycles;
|
||||
cdc.cycles[0] = cycles;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -902,9 +902,9 @@ void ctrl_io_write_byte(unsigned int address, unsigned int data)
|
||||
cdc.halted_dma_w = 0;
|
||||
|
||||
/* synchronize CDC DMA with MAIN-CPU (only if not already ahead) */
|
||||
if (cdc.cycles < cycles)
|
||||
if (cdc.cycles[0] < cycles)
|
||||
{
|
||||
cdc.cycles = cycles;
|
||||
cdc.cycles[0] = cycles;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1117,9 +1117,9 @@ void ctrl_io_write_word(unsigned int address, unsigned int data)
|
||||
cdc.halted_dma_w = 0;
|
||||
|
||||
/* synchronize CDC DMA with MAIN-CPU (only if not already ahead) */
|
||||
if (cdc.cycles < cycles)
|
||||
if (cdc.cycles[0] < cycles)
|
||||
{
|
||||
cdc.cycles = cycles;
|
||||
cdc.cycles[0] = cycles;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1241,9 +1241,9 @@ void ctrl_io_write_word(unsigned int address, unsigned int data)
|
||||
cdc.halted_dma_w = 0;
|
||||
|
||||
/* synchronize CDC DMA with MAIN-CPU (only if not already ahead) */
|
||||
if (cdc.cycles < cycles)
|
||||
if (cdc.cycles[0] < cycles)
|
||||
{
|
||||
cdc.cycles = cycles;
|
||||
cdc.cycles[0] = cycles;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
Loading…
x
Reference in New Issue
Block a user