mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-26 03:01:50 +01:00
new sync using audio DMA
This commit is contained in:
parent
fefc260ec4
commit
840a370418
@ -113,7 +113,6 @@ void reloadrom ()
|
|||||||
audio_init(48000); /* Audio System initialization */
|
audio_init(48000); /* Audio System initialization */
|
||||||
ClearGGCodes (); /* Clear Game Genie patches */
|
ClearGGCodes (); /* Clear Game Genie patches */
|
||||||
system_reset (); /* System Power ON */
|
system_reset (); /* System Power ON */
|
||||||
ogc_audio__reset(); /* reset audio buffers */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
@ -132,8 +131,6 @@ int main (int argc, char *argv[])
|
|||||||
DI_Init();
|
DI_Init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
u16 usBetweenFrames;
|
|
||||||
long long now, prev;
|
|
||||||
int RenderedFrameCount = 0;
|
int RenderedFrameCount = 0;
|
||||||
int FrameCount = 0;
|
int FrameCount = 0;
|
||||||
|
|
||||||
@ -189,41 +186,12 @@ int main (int argc, char *argv[])
|
|||||||
MainMenu();
|
MainMenu();
|
||||||
ConfigRequested = 0;
|
ConfigRequested = 0;
|
||||||
|
|
||||||
/* Initialize Frame timings */
|
|
||||||
frameticker = 0;
|
|
||||||
prev = gettime();
|
|
||||||
|
|
||||||
/* Emulation Loop */
|
/* Emulation Loop */
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
/* audio DMA starting point */
|
||||||
ogc_audio__start();
|
ogc_audio__start();
|
||||||
|
|
||||||
/* Frame synchronization */
|
|
||||||
if (gc_pal != vdp_pal)
|
|
||||||
{
|
|
||||||
/* use timers */
|
|
||||||
usBetweenFrames = vdp_pal ? 20000 : 16666;
|
|
||||||
now = gettime();
|
|
||||||
if (diff_usec(prev, now) > usBetweenFrames)
|
|
||||||
{
|
|
||||||
/* Frame skipping */
|
|
||||||
prev = now;
|
|
||||||
system_frame(1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Delay */
|
|
||||||
while (diff_usec(prev, now) < usBetweenFrames) now = gettime();
|
|
||||||
|
|
||||||
/* Render Frame */
|
|
||||||
prev = now;
|
|
||||||
system_frame(0);
|
|
||||||
RenderedFrameCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* use VSync */
|
|
||||||
if (frameticker > 1)
|
if (frameticker > 1)
|
||||||
{
|
{
|
||||||
/* Frame skipping */
|
/* Frame skipping */
|
||||||
@ -241,7 +209,6 @@ int main (int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
frameticker--;
|
frameticker--;
|
||||||
}
|
|
||||||
|
|
||||||
/* update video & audio */
|
/* update video & audio */
|
||||||
ogc_audio__update();
|
ogc_audio__update();
|
||||||
@ -268,7 +235,6 @@ int main (int argc, char *argv[])
|
|||||||
|
|
||||||
/* reset frame timings */
|
/* reset frame timings */
|
||||||
frameticker = 0;
|
frameticker = 0;
|
||||||
prev = gettime();
|
|
||||||
FrameCount = 0;
|
FrameCount = 0;
|
||||||
RenderedFrameCount = 0;
|
RenderedFrameCount = 0;
|
||||||
}
|
}
|
||||||
|
@ -24,59 +24,55 @@
|
|||||||
#include "shared.h"
|
#include "shared.h"
|
||||||
|
|
||||||
/* global datas */
|
/* global datas */
|
||||||
unsigned char soundbuffer[16][3840] ATTRIBUTE_ALIGN(32);
|
unsigned char soundbuffer[2][3840] ATTRIBUTE_ALIGN(32);
|
||||||
int mixbuffer = 0;
|
u8 mixbuffer = 0;
|
||||||
|
|
||||||
static int playbuffer = 0;
|
|
||||||
static int IsPlaying = 0;
|
static int IsPlaying = 0;
|
||||||
static u32 dma_len = 3200;
|
static int dma_len = 3200;
|
||||||
|
|
||||||
/*** AudioSwitchBuffers
|
/*** AudioDmaCallback
|
||||||
Genesis Plus only provides sound data on completion of each frame.
|
Genesis Plus only provides sound data on completion of each frame.
|
||||||
To try to make the audio less choppy, this function is called from both the
|
To try to make the audio less choppy, we synchronize emulation with audio DMA
|
||||||
DMA completion and update_audio.
|
This ensure we only update audio framebuffer when DMA is finished
|
||||||
Testing for data in the buffer ensures that there are no clashes.
|
|
||||||
***/
|
***/
|
||||||
static void AudioSwitchBuffers()
|
static void AudioDmaCallback()
|
||||||
{
|
{
|
||||||
/* increment soundbuffers index */
|
frameticker++;
|
||||||
playbuffer++;
|
|
||||||
playbuffer &= 0xf;
|
|
||||||
|
|
||||||
/* reset audio DMA parameters */
|
|
||||||
AUDIO_InitDMA((u32) soundbuffer[playbuffer], dma_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ogc_audio__init(void)
|
void ogc_audio__init(void)
|
||||||
{
|
{
|
||||||
AUDIO_Init (NULL);
|
AUDIO_Init (NULL);
|
||||||
AUDIO_SetDSPSampleRate (AI_SAMPLERATE_48KHZ);
|
AUDIO_SetDSPSampleRate (AI_SAMPLERATE_48KHZ);
|
||||||
// AUDIO_RegisterDMACallback (AudioSwitchBuffers);
|
AUDIO_RegisterDMACallback (AudioDmaCallback);
|
||||||
}
|
|
||||||
|
|
||||||
void ogc_audio__reset(void)
|
|
||||||
{
|
|
||||||
IsPlaying = 0;
|
|
||||||
mixbuffer = 0;
|
mixbuffer = 0;
|
||||||
playbuffer = 0;
|
memset(soundbuffer, 0, 2 * 3840);
|
||||||
memset(soundbuffer, 0, 16 * 3840);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ogc_audio__update(void)
|
void ogc_audio__update(void)
|
||||||
{
|
{
|
||||||
|
/* buffer size */
|
||||||
|
uint32 dma_len = vdp_pal ? 3840 : 3200;
|
||||||
|
|
||||||
|
/* update DMA settings (this will only be taken in account when current DMA finishes) */
|
||||||
|
AUDIO_InitDMA((u32) soundbuffer[mixbuffer], dma_len);
|
||||||
|
|
||||||
/* flush data from CPU cache */
|
/* flush data from CPU cache */
|
||||||
DCFlushRange(soundbuffer[mixbuffer], dma_len);
|
DCFlushRange(soundbuffer[mixbuffer], dma_len);
|
||||||
AUDIO_InitDMA((u32) soundbuffer[mixbuffer], dma_len);
|
|
||||||
|
/* switch buffer */
|
||||||
|
mixbuffer ^= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ogc_audio__stop(void)
|
void ogc_audio__stop(void)
|
||||||
{
|
{
|
||||||
/* stop audio DMA */
|
/* stop audio DMA */
|
||||||
AUDIO_StopDMA ();
|
AUDIO_StopDMA ();
|
||||||
AUDIO_InitDMA((u32) soundbuffer[0], dma_len);
|
|
||||||
IsPlaying = 0;
|
IsPlaying = 0;
|
||||||
|
|
||||||
|
/* reset audio buffers */
|
||||||
mixbuffer = 0;
|
mixbuffer = 0;
|
||||||
playbuffer = 0;
|
memset(soundbuffer, 0, 2 * 3840);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ogc_audio__start(void)
|
void ogc_audio__start(void)
|
||||||
@ -86,8 +82,8 @@ void ogc_audio__start(void)
|
|||||||
/* buffer size */
|
/* buffer size */
|
||||||
dma_len = vdp_pal ? 3840 : 3200;
|
dma_len = vdp_pal ? 3840 : 3200;
|
||||||
|
|
||||||
/* set default DMA parameters */
|
/* set first DMA parameters */
|
||||||
AUDIO_InitDMA((u32) soundbuffer[0], dma_len);
|
AUDIO_InitDMA((u32) soundbuffer[1], dma_len);
|
||||||
|
|
||||||
/* start audio DMA */
|
/* start audio DMA */
|
||||||
AUDIO_StartDMA();
|
AUDIO_StartDMA();
|
||||||
|
@ -24,11 +24,10 @@
|
|||||||
#ifndef _GC_AUDIO_H_
|
#ifndef _GC_AUDIO_H_
|
||||||
#define _GC_AUDIO_H_
|
#define _GC_AUDIO_H_
|
||||||
|
|
||||||
extern u8 soundbuffer[16][3840];
|
extern u8 soundbuffer[2][3840];
|
||||||
extern int mixbuffer;
|
extern u8 mixbuffer;
|
||||||
|
|
||||||
extern void ogc_audio__init(void);
|
extern void ogc_audio__init(void);
|
||||||
extern void ogc_audio__reset(void);
|
|
||||||
extern void ogc_audio__stop(void);
|
extern void ogc_audio__stop(void);
|
||||||
extern void ogc_audio__start(void);
|
extern void ogc_audio__start(void);
|
||||||
extern void ogc_audio__update(void);
|
extern void ogc_audio__update(void);
|
||||||
|
@ -346,13 +346,6 @@ static inline void draw_square (void)
|
|||||||
GX_End ();
|
GX_End ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* retrace handler */
|
|
||||||
static void framestart(u32 retraceCnt)
|
|
||||||
{
|
|
||||||
/* simply increment the tick counter */
|
|
||||||
frameticker++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize GX */
|
/* Initialize GX */
|
||||||
static void gxStart(void)
|
static void gxStart(void)
|
||||||
{
|
{
|
||||||
@ -725,9 +718,6 @@ void ogc_video__init(void)
|
|||||||
/* Set the framebuffer to be displayed at next VBlank */
|
/* Set the framebuffer to be displayed at next VBlank */
|
||||||
VIDEO_SetNextFramebuffer (xfb[0]);
|
VIDEO_SetNextFramebuffer (xfb[0]);
|
||||||
|
|
||||||
/* Register Video Retrace handlers */
|
|
||||||
VIDEO_SetPreRetraceCallback(framestart);
|
|
||||||
|
|
||||||
/* Enable Video Interface */
|
/* Enable Video Interface */
|
||||||
VIDEO_SetBlack (FALSE);
|
VIDEO_SetBlack (FALSE);
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ static inline uint32 psg_sample_cnt(uint8 is_z80)
|
|||||||
/* update FM samples */
|
/* update FM samples */
|
||||||
static inline void fm_update()
|
static inline void fm_update()
|
||||||
{
|
{
|
||||||
if(snd.fm.curStage - snd.fm.lastStage > 0)
|
if(snd.fm.curStage - snd.fm.lastStage > 1)
|
||||||
{
|
{
|
||||||
int *tempBuffer[2];
|
int *tempBuffer[2];
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ static inline void fm_update()
|
|||||||
/* update PSG samples */
|
/* update PSG samples */
|
||||||
static inline void psg_update()
|
static inline void psg_update()
|
||||||
{
|
{
|
||||||
if(snd.psg.curStage - snd.psg.lastStage > 0)
|
if(snd.psg.curStage - snd.psg.lastStage > 1)
|
||||||
{
|
{
|
||||||
int16 *tempBuffer = snd.psg.buffer + snd.psg.lastStage;
|
int16 *tempBuffer = snd.psg.buffer + snd.psg.lastStage;
|
||||||
SN76489_Update (0, tempBuffer, snd.psg.curStage - snd.psg.lastStage);
|
SN76489_Update (0, tempBuffer, snd.psg.curStage - snd.psg.lastStage);
|
||||||
@ -221,11 +221,8 @@ void fm_restore(void)
|
|||||||
/* write FM chip */
|
/* write FM chip */
|
||||||
void fm_write(unsigned int cpu, unsigned int address, unsigned int data)
|
void fm_write(unsigned int cpu, unsigned int address, unsigned int data)
|
||||||
{
|
{
|
||||||
if (address & 1)
|
|
||||||
{
|
|
||||||
snd.fm.curStage = fm_sample_cnt(cpu);
|
snd.fm.curStage = fm_sample_cnt(cpu);
|
||||||
fm_update();
|
fm_update();
|
||||||
}
|
|
||||||
_YM2612_Write(address & 3, data);
|
_YM2612_Write(address & 3, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user