[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 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 CDC DMA to PCM RAM when transfer length is not word-aligned
* optimized Sub-CPU / Main-CPU synchronization
[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
* 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
* provided that the following conditions are met:
@ -181,17 +181,14 @@ int cdc_context_load(uint8 *state)
void cdc_dma_update(void)
{
/* maximal transfer length */
int length = DMA_BYTES_PER_LINE;
/* end of DMA transfer ? */
if (cdc.dbc.w < DMA_BYTES_PER_LINE)
{
/* transfer remaining words using 16-bit DMA */
cdc.dma_w((cdc.dbc.w + 1) >> 1);
/* transfer remaining bytes using DMA */
cdc.dma_w(cdc.dbc.w + 1);
/* reset data byte counter (DBCH bits 4-7 should be set to 1) */
cdc.dbc.w = 0xf000;
/* 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);
@ -234,11 +231,11 @@ void cdc_dma_update(void)
}
else
{
/* transfer all words using 16-bit DMA */
cdc.dma_w(DMA_BYTES_PER_LINE >> 1);
/* transfer limited amount of bytes using DMA */
cdc.dma_w(DMA_BYTES_PER_LINE);
/* decrement data byte counter */
cdc.dbc.w -= length;
cdc.dbc.w -= DMA_BYTES_PER_LINE;
}
}

View File

@ -2,7 +2,7 @@
* Genesis Plus
* 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
* provided that the following conditions are met:
@ -53,7 +53,7 @@ typedef struct
uint8 head[2][4];
uint8 stat[4];
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) */
} cdc_t;

View File

@ -2,7 +2,7 @@
* Genesis Plus
* 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
* provided that the following conditions are met:
@ -41,10 +41,13 @@
/* 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;
/* 16-bit DMA only */
unsigned int words = length >> 1;
/* CDC buffer source address */
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;
/* 16-bit DMA only */
unsigned int words = length >> 1;
/* CDC buffer source address */
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;
/* 16-bit DMA only */
unsigned int words = length >> 1;
/* CDC buffer source address */
uint16 src_index = cdc.dac.w & 0x3ffe;

View File

@ -2,7 +2,7 @@
* Genesis Plus
* 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
* provided that the following conditions are met:
@ -61,9 +61,9 @@ typedef struct
/***************************************************************/
/* WORD-RAM DMA interfaces (1M & 2M modes) */
/***************************************************************/
extern void word_ram_0_dma_w(unsigned int words);
extern void word_ram_1_dma_w(unsigned int words);
extern void word_ram_2M_dma_w(unsigned int words);
extern void word_ram_0_dma_w(unsigned int length);
extern void word_ram_1_dma_w(unsigned int length);
extern void word_ram_2M_dma_w(unsigned int length);
/***************************************************************/
/* WORD-RAM 0 & 1 CPU interfaces (1M mode) */

View File

@ -2,7 +2,7 @@
* Genesis Plus
* 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
* provided that the following conditions are met:
@ -395,36 +395,31 @@ unsigned char pcm_read(unsigned int address, unsigned int cycles)
return 0xff;
}
void pcm_ram_dma_w(unsigned int words)
void pcm_ram_dma_w(unsigned int length)
{
uint16 data;
/* CDC buffer source address */
uint16 src_index = cdc.dac.w & 0x3ffe;
uint16 src_index = cdc.dac.w & 0x3fff;
/* 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 */
scd.regs[0x0a>>1].w += (words >> 1);
scd.regs[0x0a>>1].w += (length >> 2);
/* update DMA source address */
cdc.dac.w += (words << 1);
cdc.dac.w += length;
/* DMA transfer */
while (words--)
while (length--)
{
/* read 16-bit word from CDC buffer */
data = *(uint16 *)(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 ;
/* copy byte from CDC buffer to PCM RAM bank */
pcm.bank[dst_index] = cdc.ram[src_index];
/* increment CDC buffer source address */
src_index = (src_index + 2) & 0x3ffe;
src_index = (src_index + 1) & 0x3fff;
/* 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
* 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
* 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_write(unsigned int address, unsigned char data, 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

View File

@ -2,7 +2,7 @@
* Genesis Plus
* 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
* 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 */
/*--------------------------------------------------------------------------*/
void prg_ram_dma_w(unsigned int words)
void prg_ram_dma_w(unsigned int length)
{
uint16 data;
/* 16-bit DMA only */
unsigned int words = length >> 1;
/* CDC buffer source address */
uint16 src_index = cdc.dac.w & 0x3ffe;

View File

@ -2,7 +2,7 @@
* Genesis Plus
* 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
* 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_save(uint8 *state);
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