}
-static __inline void getSamples(int y)
-{
- int len = PsndRender(0, PsndLen);
- if (PicoWriteSound) PicoWriteSound(len);
- // clear sound buffer
- PsndClear();
-}
-
-
#define PICO_CD
#include "../pico_cmn.c"
// (c) Copyright 2008 notaz, All rights reserved.
#include "pico_int.h"
+#include "sound/ym2612.h"
#include "debug.h"
#define bit(r, x) ((r>>x)&1)
}
}
+void PDebugZ80Frame(void)
+{
+ int lines, line_sample;
+
+ if (Pico.m.pal) {
+ lines = 312;
+ line_sample = 68;
+ } else {
+ lines = 262;
+ line_sample = 93;
+ }
+
+ z80_resetCycles();
+ emustatus &= ~1;
+
+ if (Pico.m.z80Run && !Pico.m.z80_reset && (PicoOpt&POPT_EN_Z80))
+ PicoSyncZ80(line_sample*488);
+ if (ym2612.dacen && PsndDacLine <= line_sample)
+ PsndDoDAC(line_sample);
+ if (PsndOut)
+ PsndGetSamples(line_sample);
+
+ if (Pico.m.z80Run && !Pico.m.z80_reset && (PicoOpt&POPT_EN_Z80)) {
+ PicoSyncZ80(224*488);
+ z80_int();
+ }
+ if (ym2612.dacen && PsndDacLine <= 224)
+ PsndDoDAC(224);
+ if (PsndOut)
+ PsndGetSamples(224);
+
+ // sync z80
+ if (Pico.m.z80Run && !Pico.m.z80_reset && (PicoOpt&POPT_EN_Z80))
+ PicoSyncZ80(Pico.m.pal ? 151809 : 127671); // cycles adjusted for converter
+ if (PsndOut && ym2612.dacen && PsndDacLine <= lines-1)
+ PsndDoDAC(lines-1);
+
+ timers_cycle();
+}
+
void PDebugShowPalette(unsigned short *screen, int stride);
void PDebugShowSprite(unsigned short *screen, int stride, int which);
void PDebugDumpMem(void);
+void PDebugZ80Frame(void);
#endif\r
}\r
\r
-\r
-// to be called on 224 or line_sample scanlines only\r
-static __inline void getSamples(int y)\r
-{\r
-#if SIMPLE_WRITE_SOUND\r
- if (y != 224) return;\r
- PsndRender(0, PsndLen);\r
- if (PicoWriteSound) PicoWriteSound(PsndLen);\r
- PsndClear();\r
-#else\r
- static int curr_pos = 0;\r
-\r
- if(y == 224) {\r
- if(emustatus & 2)\r
- curr_pos += PsndRender(curr_pos, PsndLen-PsndLen/2);\r
- else curr_pos = PsndRender(0, PsndLen);\r
- if (emustatus&1) emustatus|=2; else emustatus&=~2;\r
- if (PicoWriteSound) PicoWriteSound(curr_pos);\r
- // clear sound buffer\r
- PsndClear();\r
- }\r
- else if(emustatus & 3) {\r
- emustatus|= 2;\r
- emustatus&=~1;\r
- curr_pos = PsndRender(0, PsndLen/2);\r
- }\r
-#endif\r
-}\r
-\r
#include "pico_cmn.c"\r
\r
int z80stopCycle;\r
SekCyclesResetS68k();
#endif
PsndDacLine = 0;
+ emustatus &= ~1;
pv->status&=~0x88; // clear V-Int, come out of vblank
}
}
-#ifndef PICO_CD
// get samples from sound chips
- if (y == 32 && PsndOut)
- emustatus &= ~1;
- else if ((y == 224 || y == line_sample) && PsndOut)
+ if ((y == 224 || y == line_sample) && PsndOut)
{
if (Pico.m.z80Run && !Pico.m.z80_reset && (PicoOpt&POPT_EN_Z80))
PicoSyncZ80(SekCycleCnt);
if (ym2612.dacen && PsndDacLine <= y)
PsndDoDAC(y);
- getSamples(y);
+ PsndGetSamples(y);
}
-#endif
// Run scanline:
if (Pico.m.dma_xfers) SekCyclesBurn(CheckDMA());
}
// get samples from sound chips
-#ifndef PICO_CD
- if (y == 224)
-#endif
- if (PsndOut)
- {
- if (ym2612.dacen && PsndDacLine <= y)
- PsndDoDAC(y);
- getSamples(y);
- }
+ if (y == 224 && PsndOut)
+ {
+ if (ym2612.dacen && PsndDacLine <= y)
+ PsndDoDAC(y);
+ PsndGetSamples(y);
+ }
// Run scanline:
if (Pico.m.dma_xfers) SekCyclesBurn(CheckDMA());
// sound/sound.c\r
PICO_INTERNAL void PsndReset(void);\r
PICO_INTERNAL void PsndDoDAC(int line_to);\r
-PICO_INTERNAL int PsndRender(int offset, int length);\r
PICO_INTERNAL void PsndClear(void);\r
+PICO_INTERNAL void PsndGetSamples(int y);\r
// z80 functionality wrappers\r
PICO_INTERNAL void z80_init(void);\r
PICO_INTERNAL void z80_pack(unsigned char *data);\r
}\r
\r
\r
-PICO_INTERNAL int PsndRender(int offset, int length)\r
+static int PsndRender(int offset, int length)\r
{\r
int buf32_updated = 0;\r
int *buf32 = PsndBuffer+offset;\r
return length;\r
}\r
\r
+// to be called on 224 or line_sample scanlines only\r
+PICO_INTERNAL void PsndGetSamples(int y)\r
+{\r
+#if SIMPLE_WRITE_SOUND\r
+ if (y != 224) return;\r
+ PsndRender(0, PsndLen);\r
+ if (PicoWriteSound) PicoWriteSound(PsndLen);\r
+ PsndClear();\r
+#else\r
+ static int curr_pos = 0;\r
+\r
+ if (y == 224)\r
+ {\r
+ if (emustatus & 2)\r
+ curr_pos += PsndRender(curr_pos, PsndLen-PsndLen/2);\r
+ else curr_pos = PsndRender(0, PsndLen);\r
+ if (emustatus&1) emustatus|=2; else emustatus&=~2;\r
+ if (PicoWriteSound) PicoWriteSound(curr_pos);\r
+ // clear sound buffer\r
+ PsndClear();\r
+ }\r
+ else if (emustatus & 3) {\r
+ emustatus|= 2;\r
+ emustatus&=~1;\r
+ curr_pos = PsndRender(0, PsndLen/2);\r
+ }\r
+#endif\r
+}\r
+\r
\r
// -----------------------------------------------------------------\r
// z80 stuff\r
char *emu_makeRomId(void);
void emu_getGameName(char *str150);
void emu_findKeyBindCombos(void);
-void emu_forcedFrame(int opts);
void emu_changeFastForward(int set_on);
void emu_RunEventsPico(unsigned int events);
void emu_DoTurbo(int *pad, int acts);
void emu_unpackConfig(void);
void emu_shutdownMCD(void);
+/* not in common */
extern const char * const keyNames[];
void emu_prepareDefaultConfig(void);
void emu_platformDebugCat(char *str);
+void emu_forcedFrame(int opts);
+void emu_startSound(void);
+void emu_endSound(void);
+void emu_waitSound(void);
#ifdef __cplusplus
} // extern "C"
\r
void SekStepM68k(void);\r
\r
+static void mplayer_loop(void)\r
+{\r
+ emu_startSound();\r
+\r
+ while (1)\r
+ {\r
+ PDebugZ80Frame();\r
+ if (read_buttons_async(BTN_NORTH)) break;\r
+ emu_waitSound();\r
+ }\r
+\r
+ emu_endSound();\r
+}\r
+\r
static void draw_text_debug(const char *str, int skip, int from)\r
{\r
const char *p;\r
}\r
menu_draw_end();\r
\r
- inp = read_buttons(BTN_EAST|BTN_SOUTH|BTN_WEST|BTN_L|BTN_R|BTN_UP|BTN_DOWN|BTN_LEFT|BTN_RIGHT);\r
+ inp = read_buttons(BTN_EAST|BTN_SOUTH|BTN_WEST|BTN_NORTH|BTN_L|BTN_R|BTN_UP|BTN_DOWN|BTN_LEFT|BTN_RIGHT);\r
if (inp & BTN_SOUTH) return;\r
if (inp & BTN_L) { mode--; if (mode < 0) mode = 3; }\r
if (inp & BTN_R) { mode++; if (mode > 3) mode = 0; }\r
{\r
case 0:\r
if (inp & BTN_EAST) SekStepM68k();\r
+ if (inp & BTN_NORTH) {\r
+ while (inp & BTN_NORTH) inp = read_buttons_async(BTN_NORTH);\r
+ mplayer_loop();\r
+ }\r
if ((inp & (BTN_WEST|BTN_LEFT)) == (BTN_WEST|BTN_LEFT)) {\r
mkdir("dumps", 0777);\r
PDebugDumpMem();\r
gp2x_sound_write(PsndOut, len<<1);\r
}\r
\r
+void emu_startSound(void)\r
+{\r
+ static int PsndRate_old = 0, PicoOpt_old = 0, pal_old = 0;\r
+ int target_fps = Pico.m.pal ? 50 : 60;\r
+\r
+ PsndOut = NULL;\r
+\r
+ // prepare sound stuff\r
+ if (currentConfig.EmuOpt & 4)\r
+ {\r
+ int snd_excess_add;\r
+ if (PsndRate != PsndRate_old || (PicoOpt&0x20b) != (PicoOpt_old&0x20b) || Pico.m.pal != pal_old ||\r
+ ((PicoOpt&0x200) && crashed_940)) {\r
+ PsndRerate(Pico.m.frame_count ? 1 : 0);\r
+ }\r
+ snd_excess_add = ((PsndRate - PsndLen*target_fps)<<16) / target_fps;\r
+ printf("starting audio: %i len: %i (ex: %04x) stereo: %i, pal: %i\n",\r
+ PsndRate, PsndLen, snd_excess_add, (PicoOpt&8)>>3, Pico.m.pal);\r
+ gp2x_start_sound(PsndRate, 16, (PicoOpt&8)>>3);\r
+ gp2x_sound_volume(currentConfig.volume, currentConfig.volume);\r
+ PicoWriteSound = updateSound;\r
+ update_volume(0, 0);\r
+ memset(sndBuffer, 0, sizeof(sndBuffer));\r
+ PsndOut = sndBuffer;\r
+ PsndRate_old = PsndRate;\r
+ PicoOpt_old = PicoOpt;\r
+ pal_old = Pico.m.pal;\r
+ }\r
+}\r
+\r
+void emu_endSound(void)\r
+{\r
+}\r
+\r
+/* wait until we can write more sound */\r
+void emu_waitSound(void)\r
+{\r
+ // don't need to do anything, writes will block by themselves\r
+}\r
+\r
\r
static void SkipFrame(int do_audio)\r
{\r
\r
void emu_Loop(void)\r
{\r
- static int gp2x_old_clock = 200;\r
- static int PsndRate_old = 0, PicoOpt_old = 0, EmuOpt_old = 0, pal_old = 0;\r
+ static int gp2x_old_clock = 200, EmuOpt_old = 0;\r
char fpsbuff[24]; // fps count c string\r
struct timeval tval; // timing\r
int pframes_done, pframes_shown, pthissec; // "period" frames, used for sync\r
target_frametime = 1000000/target_fps;\r
reset_timing = 1;\r
\r
- // prepare sound stuff\r
- if (currentConfig.EmuOpt & 4)\r
- {\r
- int snd_excess_add;\r
- if (PsndRate != PsndRate_old || (PicoOpt&0x20b) != (PicoOpt_old&0x20b) || Pico.m.pal != pal_old ||\r
- ((PicoOpt&0x200) && crashed_940)) {\r
- PsndRerate(Pico.m.frame_count ? 1 : 0);\r
- }\r
- snd_excess_add = ((PsndRate - PsndLen*target_fps)<<16) / target_fps;\r
- printf("starting audio: %i len: %i (ex: %04x) stereo: %i, pal: %i\n",\r
- PsndRate, PsndLen, snd_excess_add, (PicoOpt&8)>>3, Pico.m.pal);\r
- gp2x_start_sound(PsndRate, 16, (PicoOpt&8)>>3);\r
- gp2x_sound_volume(currentConfig.volume, currentConfig.volume);\r
- PicoWriteSound = updateSound;\r
- update_volume(0, 0);\r
- memset(sndBuffer, 0, sizeof(sndBuffer));\r
- PsndOut = sndBuffer;\r
- PsndRate_old = PsndRate;\r
- PicoOpt_old = PicoOpt;\r
- pal_old = Pico.m.pal;\r
- } else {\r
- PsndOut = NULL;\r
- }\r
+ emu_startSound();\r
\r
// prepare CD buffer\r
if (PicoAHW & PAHW_MCD) PicoCDBufferInit();\r
void gp2x_start_sound(int rate, int bits, int stereo);\r
void gp2x_sound_write(void *buff, int len);\r
void gp2x_sound_volume(int l, int r);\r
+void gp2x_sound_sync(void);\r
\r
/* input */\r
unsigned long gp2x_joystick_read(int allow_usb_joy);\r
lprintf("sceKernelCreateThread failed: %i\n", thid);
}
-static void sound_prepare(void)
+void emu_startSound(void)
{
static int PsndRate_old = 0, PicoOpt_old = 0, pal_old = 0;
int ret, stereo;
}
}
-static void sound_end(void)
+void emu_endSound(void)
{
int i;
if (samples_done == 0)
sceAudio_5C37C0AE();
}
+/* wait until we can write more sound */
+void emu_waitSound(void)
+{
+ // TODO: test this
+ while (!sound_thread_exit && samples_made - samples_done > samples_block * 4)
+ psp_msleep(10);
+}
+
static void sound_deinit(void)
{
sound_thread_exit = 1;
PsndOut = NULL;
if (currentConfig.EmuOpt & 4)
{
- sound_prepare();
+ emu_startSound();
}
sceDisplayWaitVblankStart();
if (PicoAHW & PAHW_MCD) PicoCDBufferFree();
if (PsndOut != NULL) {
+ emu_endSound();
PsndOut = NULL;
- sound_end();
}
// save SRAM