Skip to content

Commit e8a6086

Browse files
committed
[Core/CD] improved accuracy of CDC decoder processing (verified on real hardware, cf. Krikzz's mcd-verificator)
1 parent 904613f commit e8a6086

File tree

8 files changed

+77
-20
lines changed

8 files changed

+77
-20
lines changed

HISTORY.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Genesis Plus GX 1.7.5 (xx/xx/xxxx) (Eke-Eke)
2626
* improved accuracy of Main-CPU & Sub-CPU access to CDC registers (verified on real hardware, cf. Krikzz's mcd-verificator)
2727
* improved accuracy of CDC data transfer to Main-CPU & Sub-CPU (verified on real hardware, cf. Krikzz's mcd-verificator)
2828
* improved accuracy of CDC DMA processing (verified on real hardware, cf. Krikzz's mcd-verificator)
29+
* improved accuracy of CDC decoder processing (verified on real hardware, cf. Krikzz's mcd-verificator)
2930
* improved accuracy of CDC interrupt processing (verified on real hardware, cf. Krikzz's mcd-verificator)
3031
* improved emulation of mirrored memory areas
3132
* improved savestate format

builds/genesis_plus_gx_libretro.dll

0 Bytes
Binary file not shown.

builds/genplus_cube.dol

320 Bytes
Binary file not shown.

builds/genplus_wii.dol

320 Bytes
Binary file not shown.

core/cd_hw/cdc.c

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ void cdc_reset(void)
108108
cdc.head[1][2] = 0x00;
109109
cdc.head[1][3] = 0x00;
110110

111-
/* reset CDC DMA cycle counter */
112-
cdc.cycles = 0;
111+
/* reset CDC DMA & decoder cycle counters */
112+
cdc.cycles[0] = cdc.cycles[1] = 0;
113113

114114
/* disable CDC DMA */
115115
cdc.dma_w = cdc.halted_dma_w = 0;
@@ -176,7 +176,6 @@ int cdc_context_save(uint8 *state)
176176
save_param(&cdc.head, sizeof(cdc.head));
177177
save_param(&cdc.stat, sizeof(cdc.stat));
178178
save_param(&cdc.cycles, sizeof(cdc.cycles));
179-
save_param(&cdc.dma_w, sizeof(cdc.dma_w));
180179
save_param(&cdc.ram, sizeof(cdc.ram));
181180
save_param(&tmp8, 1);
182181

@@ -198,7 +197,6 @@ int cdc_context_load(uint8 *state)
198197
load_param(&cdc.head, sizeof(cdc.head));
199198
load_param(&cdc.stat, sizeof(cdc.stat));
200199
load_param(&cdc.cycles, sizeof(cdc.cycles));
201-
load_param(&cdc.dma_w, sizeof(cdc.dma_w));
202200
load_param(&cdc.ram, sizeof(cdc.ram));
203201

204202
load_param(&tmp8, 1);
@@ -290,6 +288,16 @@ void cdc_dma_init(void)
290288
/* Data Transfer End interrupt enabled ? */
291289
if (cdc.ifctrl & BIT_DTEIEN)
292290
{
291+
/* check end of CDC decoder active period */
292+
if ((cdc.irq & BIT_DECI) && (cdc.cycles[0] > cdc.cycles[1]))
293+
{
294+
/* clear pending decoder interrupt */
295+
cdc.ifstat |= BIT_DECI;
296+
297+
/* update CDC IRQ state */
298+
cdc.irq &= ~BIT_DECI;
299+
}
300+
293301
/* level 5 interrupt triggered only on CDC /INT falling edge with interrupt enabled on gate-array side */
294302
if (!cdc.irq && (scd.regs[0x32>>1].byte.l & 0x20))
295303
{
@@ -380,7 +388,7 @@ void cdc_dma_init(void)
380388
void cdc_dma_update(unsigned int cycles)
381389
{
382390
/* max number of bytes that can be transfered */
383-
int dma_bytes = (cycles - cdc.cycles + DMA_CYCLES_PER_BYTE - 1) / DMA_CYCLES_PER_BYTE;
391+
int dma_bytes = (cycles - cdc.cycles[0] + DMA_CYCLES_PER_BYTE - 1) / DMA_CYCLES_PER_BYTE;
384392

385393
/* always process blocks of 8 bytes */
386394
dma_bytes = (dma_bytes / 8) * 8;
@@ -391,6 +399,9 @@ void cdc_dma_update(unsigned int cycles)
391399
/* transfer remaining bytes using DMA */
392400
cdc.dma_w(cdc.dbc.w + 1);
393401

402+
/* update DMA cycle counter */
403+
cdc.cycles[0] += (cdc.dbc.w + 1) * DMA_CYCLES_PER_BYTE;
404+
394405
/* reset data byte counter (DBCH bits 4-7 should also be set to 1) */
395406
cdc.dbc.w = 0xffff;
396407

@@ -403,6 +414,16 @@ void cdc_dma_update(unsigned int cycles)
403414
/* Data Transfer End interrupt enabled ? */
404415
if (cdc.ifctrl & BIT_DTEIEN)
405416
{
417+
/* check end of CDC decoder active period */
418+
if ((cdc.irq & BIT_DECI) && (cdc.cycles[0] > cdc.cycles[1]))
419+
{
420+
/* clear pending decoder interrupt */
421+
cdc.ifstat |= BIT_DECI;
422+
423+
/* update CDC IRQ state */
424+
cdc.irq &= ~BIT_DECI;
425+
}
426+
406427
/* level 5 interrupt triggered only on CDC /INT falling edge with interrupt enabled on gate-array side*/
407428
if (!cdc.irq && (scd.regs[0x32>>1].byte.l & 0x20))
408429
{
@@ -424,7 +445,7 @@ void cdc_dma_update(unsigned int cycles)
424445
if (s68k.stopped & (1<<0x04))
425446
{
426447
/* sync SUB-CPU with CDC DMA */
427-
s68k.cycles = cdc.cycles;
448+
s68k.cycles = cdc.cycles[0];
428449

429450
/* restart SUB-CPU */
430451
s68k.stopped = 0;
@@ -445,7 +466,7 @@ void cdc_dma_update(unsigned int cycles)
445466
cdc.dbc.w -= dma_bytes;
446467

447468
/* update DMA cycle counter */
448-
cdc.cycles += dma_bytes * DMA_CYCLES_PER_BYTE;
469+
cdc.cycles[0] += dma_bytes * DMA_CYCLES_PER_BYTE;
449470
}
450471
}
451472

@@ -463,6 +484,9 @@ void cdc_decoder_update(uint32 header)
463484
/* pending decoder interrupt */
464485
cdc.ifstat &= ~BIT_DECI;
465486

487+
/* update CDC decoder end cycle (value adjusted for MCD-verificator CDC FLAGS Tests #40 & #41) */
488+
cdc.cycles[1] = s68k.cycles + 269000;
489+
466490
/* decoder interrupt enabled ? */
467491
if (cdc.ifctrl & BIT_DECIEN)
468492
{
@@ -555,6 +579,16 @@ void cdc_reg_w(unsigned char data)
555579
{
556580
/* previous CDC IRQ state */
557581
uint8 prev_irq = cdc.irq;
582+
583+
/* check end of CDC decoder active period */
584+
if (s68k.cycles > cdc.cycles[1])
585+
{
586+
/* clear pending decoder interrupt */
587+
cdc.ifstat |= BIT_DECI;
588+
589+
/* update previous CDC IRQ state */
590+
prev_irq &= ~BIT_DECI;
591+
}
558592

559593
/* update CDC IRQ state according to DTEIEN and DECIEN bits */
560594
cdc.irq = ~cdc.ifstat & data & (BIT_DTEIEN | BIT_DECIEN);
@@ -614,7 +648,7 @@ void cdc_reg_w(unsigned char data)
614648
cdc_dma_init();
615649

616650
/* initialize DMA cycle counter */
617-
cdc.cycles = s68k.cycles;
651+
cdc.cycles[0] = s68k.cycles;
618652
}
619653

620654
break;
@@ -708,6 +742,16 @@ unsigned char cdc_reg_r(void)
708742
{
709743
case 0x01: /* IFSTAT */
710744
{
745+
/* check end of CDC decoder active period */
746+
if (s68k.cycles > cdc.cycles[1])
747+
{
748+
/* clear pending decoder interrupt */
749+
cdc.ifstat |= BIT_DECI;
750+
751+
/* update CDC IRQ state */
752+
cdc.irq &= ~BIT_DECI;
753+
}
754+
711755
data = cdc.ifstat;
712756
break;
713757
}
@@ -869,6 +913,16 @@ unsigned short cdc_host_r(uint8 cpu_access)
869913
/* Data Transfer End interrupt enabled ? */
870914
if (cdc.ifctrl & BIT_DTEIEN)
871915
{
916+
/* check end of CDC decoder active period */
917+
if ((cdc.irq & BIT_DECI) && (cdc.cycles[0] > cdc.cycles[1]))
918+
{
919+
/* clear pending decoder interrupt */
920+
cdc.ifstat |= BIT_DECI;
921+
922+
/* update CDC IRQ state */
923+
cdc.irq &= ~BIT_DECI;
924+
}
925+
872926
/* level 5 interrupt triggered only on CDC /INT falling edge with interrupt enabled on gate-array side */
873927
if (!cdc.irq && (scd.regs[0x32>>1].byte.l & 0x20))
874928
{

core/cd_hw/cdc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ typedef struct
5555
uint8 ctrl[2];
5656
uint8 head[2][4];
5757
uint8 stat[4];
58-
unsigned int cycles;
58+
int cycles[2];
5959
void (*dma_w)(unsigned int length); /* active DMA callback */
6060
void (*halted_dma_w)(unsigned int length); /* halted DMA callback */
6161
uint8 ram[0x4000 + 2352]; /* 16K external RAM (with one block overhead to handle buffer overrun) */

core/cd_hw/scd.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1983,9 +1983,11 @@ void scd_end_frame(unsigned int cycles)
19831983
/* adjust Stopwatch counter for next frame (can be negative) */
19841984
scd.stopwatch += (ticks * TIMERS_SCYCLES_RATIO) - cycles;
19851985

1986-
/* adjust SUB-CPU & GPU cycle counters for next frame */
1987-
s68k.cycles -= cycles;
1988-
gfx.cycles -= cycles;
1986+
/* adjust SUB-CPU, GPU and CDC cycle counters for next frame */
1987+
s68k.cycles -= cycles;
1988+
gfx.cycles -= cycles;
1989+
cdc.cycles[0] -= cycles;
1990+
cdc.cycles[1] -= cycles;
19891991

19901992
/* reset CPU registers polling */
19911993
m68k.poll.cycle = 0;

core/mem68k.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -788,9 +788,9 @@ void ctrl_io_write_byte(unsigned int address, unsigned int data)
788788
cdc.halted_dma_w = 0;
789789

790790
/* synchronize CDC DMA with MAIN-CPU (only if not already ahead) */
791-
if (cdc.cycles < cycles)
791+
if (cdc.cycles[0] < cycles)
792792
{
793-
cdc.cycles = cycles;
793+
cdc.cycles[0] = cycles;
794794
}
795795
}
796796
}
@@ -902,9 +902,9 @@ void ctrl_io_write_byte(unsigned int address, unsigned int data)
902902
cdc.halted_dma_w = 0;
903903

904904
/* synchronize CDC DMA with MAIN-CPU (only if not already ahead) */
905-
if (cdc.cycles < cycles)
905+
if (cdc.cycles[0] < cycles)
906906
{
907-
cdc.cycles = cycles;
907+
cdc.cycles[0] = cycles;
908908
}
909909
}
910910

@@ -1117,9 +1117,9 @@ void ctrl_io_write_word(unsigned int address, unsigned int data)
11171117
cdc.halted_dma_w = 0;
11181118

11191119
/* synchronize CDC DMA with MAIN-CPU (only if not already ahead) */
1120-
if (cdc.cycles < cycles)
1120+
if (cdc.cycles[0] < cycles)
11211121
{
1122-
cdc.cycles = cycles;
1122+
cdc.cycles[0] = cycles;
11231123
}
11241124
}
11251125
}
@@ -1241,9 +1241,9 @@ void ctrl_io_write_word(unsigned int address, unsigned int data)
12411241
cdc.halted_dma_w = 0;
12421242

12431243
/* synchronize CDC DMA with MAIN-CPU (only if not already ahead) */
1244-
if (cdc.cycles < cycles)
1244+
if (cdc.cycles[0] < cycles)
12451245
{
1246-
cdc.cycles = cycles;
1246+
cdc.cycles[0] = cycles;
12471247
}
12481248
}
12491249
return;

0 commit comments

Comments
 (0)