[Core/CD] fixed CDC DMA to PCM RAM when transfer length is not word-aligned

This commit is contained in:
ekeeke 2023-11-10 14:25:32 +01:00
parent a2931d161f
commit 8e02a430aa
12 changed files with 48 additions and 43 deletions

View File

@ -55,6 +55,7 @@ Genesis Plus GX 1.7.5 (xx/xx/xxxx) (Eke-Eke)
* fixed word access to CDD control register (fixes spurious audio track playback on startup with Mode 1 patched games using MSU-MD driver) * fixed word access to CDD control register (fixes spurious audio track playback on startup with Mode 1 patched games using MSU-MD driver)
* fixed CD communication registers state on peripheral reset (fixes SUB-CPU side initialization in MSU-MD sample demo and some Mode 1 patched games using MSU-MD driver) * fixed CD communication registers state on peripheral reset (fixes SUB-CPU side initialization in MSU-MD sample demo and some Mode 1 patched games using MSU-MD driver)
* fixed 32x32 pixels stamp index masking during GFX operation (fixes graphics rotation/scaling effects in "Chuck Rock II - Son of Chuck") * fixed 32x32 pixels stamp index masking during GFX operation (fixes graphics rotation/scaling effects in "Chuck Rock II - Son of Chuck")
* fixed CDC DMA to PCM RAM when transfer length is not word-aligned
* optimized Sub-CPU / Main-CPU synchronization * optimized Sub-CPU / Main-CPU synchronization
[Core/MD] [Core/MD]

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

@ -2,7 +2,7 @@
* Genesis Plus * Genesis Plus
* CD data controller (LC8951x compatible) * CD data controller (LC8951x compatible)
* *
* Copyright (C) 2012-2019 Eke-Eke (Genesis Plus GX) * Copyright (C) 2012-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:
@ -181,17 +181,14 @@ int cdc_context_load(uint8 *state)
void cdc_dma_update(void) void cdc_dma_update(void)
{ {
/* maximal transfer length */
int length = DMA_BYTES_PER_LINE;
/* end of DMA transfer ? */ /* end of DMA transfer ? */
if (cdc.dbc.w < DMA_BYTES_PER_LINE) if (cdc.dbc.w < DMA_BYTES_PER_LINE)
{ {
/* transfer remaining words using 16-bit DMA */ /* transfer remaining bytes using DMA */
cdc.dma_w((cdc.dbc.w + 1) >> 1); cdc.dma_w(cdc.dbc.w + 1);
/* reset data byte counter (DBCH bits 4-7 should be set to 1) */ /* reset data byte counter (DBCH bits 4-7 should also be set to 1) */
cdc.dbc.w = 0xf000; cdc.dbc.w = 0xffff;
/* clear !DTEN and !DTBSY */ /* clear !DTEN and !DTBSY */
cdc.ifstat |= (BIT_DTBSY | BIT_DTEN); cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
@ -234,11 +231,11 @@ void cdc_dma_update(void)
} }
else else
{ {
/* transfer all words using 16-bit DMA */ /* transfer limited amount of bytes using DMA */
cdc.dma_w(DMA_BYTES_PER_LINE >> 1); cdc.dma_w(DMA_BYTES_PER_LINE);
/* decrement data byte counter */ /* decrement data byte counter */
cdc.dbc.w -= length; cdc.dbc.w -= DMA_BYTES_PER_LINE;
} }
} }

View File

@ -2,7 +2,7 @@
* Genesis Plus * Genesis Plus
* CD data controller (LC8951x compatible) * CD data controller (LC8951x compatible)
* *
* Copyright (C) 2012-2019 Eke-Eke (Genesis Plus GX) * Copyright (C) 2012-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:
@ -53,7 +53,7 @@ typedef struct
uint8 head[2][4]; uint8 head[2][4];
uint8 stat[4]; uint8 stat[4];
int cycles; int cycles;
void (*dma_w)(unsigned int words); /* 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) */
} cdc_t; } cdc_t;

View File

@ -2,7 +2,7 @@
* Genesis Plus * Genesis Plus
* CD graphics processor * CD graphics processor
* *
* Copyright (C) 2012-2022 Eke-Eke (Genesis Plus GX) * Copyright (C) 2012-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:
@ -41,10 +41,13 @@
/* WORD-RAM DMA interfaces (1M & 2M modes) */ /* WORD-RAM DMA interfaces (1M & 2M modes) */
/***************************************************************/ /***************************************************************/
void word_ram_0_dma_w(unsigned int words) void word_ram_0_dma_w(unsigned int length)
{ {
uint16 data; uint16 data;
/* 16-bit DMA only */
unsigned int words = length >> 1;
/* CDC buffer source address */ /* CDC buffer source address */
uint16 src_index = cdc.dac.w & 0x3ffe; uint16 src_index = cdc.dac.w & 0x3ffe;
@ -74,10 +77,13 @@ void word_ram_0_dma_w(unsigned int words)
} }
} }
void word_ram_1_dma_w(unsigned int words) void word_ram_1_dma_w(unsigned int length)
{ {
uint16 data; uint16 data;
/* 16-bit DMA only */
unsigned int words = length >> 1;
/* CDC buffer source address */ /* CDC buffer source address */
uint16 src_index = cdc.dac.w & 0x3ffe; uint16 src_index = cdc.dac.w & 0x3ffe;
@ -107,10 +113,13 @@ void word_ram_1_dma_w(unsigned int words)
} }
} }
void word_ram_2M_dma_w(unsigned int words) void word_ram_2M_dma_w(unsigned int length)
{ {
uint16 data; uint16 data;
/* 16-bit DMA only */
unsigned int words = length >> 1;
/* CDC buffer source address */ /* CDC buffer source address */
uint16 src_index = cdc.dac.w & 0x3ffe; uint16 src_index = cdc.dac.w & 0x3ffe;

View File

@ -2,7 +2,7 @@
* Genesis Plus * Genesis Plus
* CD graphics processor * CD graphics processor
* *
* Copyright (C) 2012-2022 Eke-Eke (Genesis Plus GX) * Copyright (C) 2012-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:
@ -61,9 +61,9 @@ typedef struct
/***************************************************************/ /***************************************************************/
/* WORD-RAM DMA interfaces (1M & 2M modes) */ /* WORD-RAM DMA interfaces (1M & 2M modes) */
/***************************************************************/ /***************************************************************/
extern void word_ram_0_dma_w(unsigned int words); extern void word_ram_0_dma_w(unsigned int length);
extern void word_ram_1_dma_w(unsigned int words); extern void word_ram_1_dma_w(unsigned int length);
extern void word_ram_2M_dma_w(unsigned int words); extern void word_ram_2M_dma_w(unsigned int length);
/***************************************************************/ /***************************************************************/
/* WORD-RAM 0 & 1 CPU interfaces (1M mode) */ /* WORD-RAM 0 & 1 CPU interfaces (1M mode) */

View File

@ -2,7 +2,7 @@
* Genesis Plus * Genesis Plus
* PCM sound chip (315-5476A) (RF5C164 compatible) * PCM sound chip (315-5476A) (RF5C164 compatible)
* *
* Copyright (C) 2012-2021 Eke-Eke (Genesis Plus GX) * Copyright (C) 2012-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:
@ -395,36 +395,31 @@ unsigned char pcm_read(unsigned int address, unsigned int cycles)
return 0xff; return 0xff;
} }
void pcm_ram_dma_w(unsigned int words) void pcm_ram_dma_w(unsigned int length)
{ {
uint16 data;
/* CDC buffer source address */ /* CDC buffer source address */
uint16 src_index = cdc.dac.w & 0x3ffe; uint16 src_index = cdc.dac.w & 0x3fff;
/* PCM-RAM destination address*/ /* PCM-RAM destination address*/
uint16 dst_index = (scd.regs[0x0a>>1].w << 2) & 0xffe; uint16 dst_index = (scd.regs[0x0a>>1].w << 2) & 0xfff;
/* update DMA destination address */ /* update DMA destination address */
scd.regs[0x0a>>1].w += (words >> 1); scd.regs[0x0a>>1].w += (length >> 2);
/* update DMA source address */ /* update DMA source address */
cdc.dac.w += (words << 1); cdc.dac.w += length;
/* DMA transfer */ /* DMA transfer */
while (words--) while (length--)
{ {
/* read 16-bit word from CDC buffer */ /* copy byte from CDC buffer to PCM RAM bank */
data = *(uint16 *)(cdc.ram + src_index); pcm.bank[dst_index] = cdc.ram[src_index];
/* write 16-bit word to PCM RAM (endianness does not matter since PCM RAM is always accessed as byte)*/
*(uint16 *)(pcm.bank + dst_index) = data ;
/* increment CDC buffer source address */ /* increment CDC buffer source address */
src_index = (src_index + 2) & 0x3ffe; src_index = (src_index + 1) & 0x3fff;
/* increment PCM-RAM destination address */ /* increment PCM-RAM destination address */
dst_index = (dst_index + 2) & 0xffe; dst_index = (dst_index + 1) & 0xfff;
} }
} }

View File

@ -2,7 +2,7 @@
* Genesis Plus * Genesis Plus
* PCM sound chip (315-5476A) (RF5C164 compatible) * PCM sound chip (315-5476A) (RF5C164 compatible)
* *
* Copyright (C) 2012-2021 Eke-Eke (Genesis Plus GX) * Copyright (C) 2012-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:
@ -72,6 +72,6 @@ extern int pcm_context_load(uint8 *state);
extern void pcm_update(unsigned int samples); extern void pcm_update(unsigned int samples);
extern void pcm_write(unsigned int address, unsigned char data, unsigned int cycles); extern void pcm_write(unsigned int address, unsigned char data, unsigned int cycles);
extern unsigned char pcm_read(unsigned int address, unsigned int cycles); extern unsigned char pcm_read(unsigned int address, unsigned int cycles);
extern void pcm_ram_dma_w(unsigned int words); extern void pcm_ram_dma_w(unsigned int length);
#endif #endif

View File

@ -2,7 +2,7 @@
* Genesis Plus * Genesis Plus
* Mega CD / Sega CD hardware * Mega CD / Sega CD hardware
* *
* Copyright (C) 2012-2022 Eke-Eke (Genesis Plus GX) * Copyright (C) 2012-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:
@ -76,10 +76,13 @@ static void s68k_unused_16_w(unsigned int address, unsigned int data)
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
/* PRG-RAM DMA access */ /* PRG-RAM DMA access */
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
void prg_ram_dma_w(unsigned int words) void prg_ram_dma_w(unsigned int length)
{ {
uint16 data; uint16 data;
/* 16-bit DMA only */
unsigned int words = length >> 1;
/* CDC buffer source address */ /* CDC buffer source address */
uint16 src_index = cdc.dac.w & 0x3ffe; uint16 src_index = cdc.dac.w & 0x3ffe;

View File

@ -2,7 +2,7 @@
* Genesis Plus * Genesis Plus
* Mega CD / Sega CD hardware * Mega CD / Sega CD hardware
* *
* Copyright (C) 2012-2022 Eke-Eke (Genesis Plus GX) * Copyright (C) 2012-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:
@ -90,6 +90,6 @@ extern void scd_end_frame(unsigned int cycles);
extern int scd_context_load(uint8 *state, char *version); extern int scd_context_load(uint8 *state, char *version);
extern int scd_context_save(uint8 *state); extern int scd_context_save(uint8 *state);
extern int scd_68k_irq_ack(int level); extern int scd_68k_irq_ack(int level);
extern void prg_ram_dma_w(unsigned int words); extern void prg_ram_dma_w(unsigned int length);
#endif #endif