From: notaz Date: Fri, 26 Oct 2007 20:08:13 +0000 (+0000) Subject: basic psp snd + cz80 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0953046be2782a1a8c2853f4f46838ebd34c90d4;p=libpicofe.git basic psp snd + cz80 git-svn-id: file:///home/notaz/opt/svn/PicoDrive/platform@280 be3aeb3a-fb24-0410-a615-afba39da0efa --- diff --git a/psp/Makefile b/psp/Makefile index db032d8..6aaf51b 100644 --- a/psp/Makefile +++ b/psp/Makefile @@ -4,7 +4,7 @@ PSPSDK = $(shell psp-config --pspsdk-path) # settings #use_musashi = 1 -use_mz80 = 1 +#use_mz80 = 1 amalgamate = 0 #profile = 1 #up = 1 @@ -69,13 +69,14 @@ ifeq "$(use_mz80)" "1" CFLAGS += -D_USE_MZ80 OBJS += ../../cpu/mz80/mz80.o else -$(error nothing here!) +CFLAGS += -D_USE_CZ80 +OBJS += ../../cpu/cz80/cz80.o endif # bg images OBJS += data/bg32.o data/bg40.o -LIBS += -lpng -lm -lpspgu -lpsppower -Wl,-Map=PicoDrive.map # -lpspaudio -lpsphprm +LIBS += -lpng -lm -lpspgu -lpsppower -Wl,-Map=PicoDrive.map -lpspaudio # target TARGET = PicoDrive diff --git a/psp/emu.c b/psp/emu.c index 8542a8f..df4a08e 100644 --- a/psp/emu.c +++ b/psp/emu.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "psp.h" #include "menu.h" @@ -20,6 +21,13 @@ #define OSD_FPS_X 420 #endif +// additional pspaudio imports, credits to crazyc +int sceAudio_38553111(unsigned short samples, unsigned short freq, char unknown); // play with conversion? +int sceAudio_5C37C0AE(void); // end play? +int sceAudio_E0727056(int volume, void *buffer); // blocking output +int sceAudioOutput2GetRestSample(); + + char romFileName[PATH_MAX]; unsigned char *PicoDraw2FB = (unsigned char *)VRAM_CACHED_STUFF + 8; // +8 to be able to skip border with 1 quadword.. int engineState; @@ -29,6 +37,8 @@ static unsigned int noticeMsgTime = 0; int reset_timing = 0; // do we need this? +static void sound_init(void); +static void sound_deinit(void); static void blit2(const char *fps, const char *notice); static void clearArea(int full); @@ -82,6 +92,8 @@ void emu_Init(void) mkdir("brm", 0777); mkdir("cfg", 0777); + sound_init(); + PicoInit(); PicoMessage = emu_msg_cb; PicoMCDopenTray = emu_msg_tray_open; @@ -111,6 +123,7 @@ void emu_Deinit(void) } PicoExit(); + sound_deinit(); } void emu_setDefaultConfig(void) @@ -462,14 +475,147 @@ static void vidResetMode(void) sceGuSync(0,0); } -/* -static void updateSound(int len) + +/* sound stuff */ +#define SOUND_DEF_BLOCK_SIZE 1024 // 1152 // 1024 +#define SOUND_BLOCK_COUNT 4 + +static short __attribute__((aligned(4))) sndBuffer[SOUND_DEF_BLOCK_SIZE*SOUND_BLOCK_COUNT*2 + 44100/50*2]; +static short *snd_playptr = NULL; +static int samples_made = 0, samples_done = 0, samples_block = SOUND_DEF_BLOCK_SIZE; +static int sound_thread_exit = 0; +static SceUID sound_sem = -1; + +static void writeSound(int len); + +static int sound_thread(SceSize args, void *argp) { + short *endptr = &sndBuffer[SOUND_DEF_BLOCK_SIZE*SOUND_BLOCK_COUNT*2]; + int ret; + + lprintf("sound_thread: started, priority %i\n", sceKernelGetThreadCurrentPriority()); + + while (!sound_thread_exit) + { + if (samples_made - samples_done < samples_block) { + // wait for data... + //lprintf("sthr: wait... (%i/%i)\n", samples_done, samples_made); + ret = sceKernelWaitSema(sound_sem, 1, 0); + //lprintf("sthr: sceKernelWaitSema: %i\n", ret); + continue; + } + + //lprintf("sthr: got data: %i\n", samples_made - samples_done); + + ret = sceAudio_E0727056(PSP_AUDIO_VOLUME_MAX, snd_playptr); + + samples_done += samples_block; + snd_playptr += samples_block; + if (snd_playptr >= endptr) + snd_playptr = sndBuffer; + if (ret) + lprintf("sthr: outf: %i; pos %i/%i\n", ret, samples_done, samples_made); + } + + lprintf("sthr: exit\n"); + sceKernelExitDeleteThread(0); + return 0; +} + +static void sound_init(void) +{ + SceUID thid; + + sound_sem = sceKernelCreateSema("sndsem", 0, 0, 1, NULL); + if (sound_sem < 0) lprintf("sceKernelCreateSema() failed: %i\n", sound_sem); + + sound_thread_exit = 0; + thid = sceKernelCreateThread("sndthread", sound_thread, 0x12, 0x10000, 0, NULL); + if (thid >= 0) + { + sceKernelStartThread(thid, 0, 0); + } + else + lprintf("sceKernelCreateThread failed: %i\n", thid); +} + +static void sound_prepare(void) +{ + static int PsndRate_old = 0, PicoOpt_old = 0, pal_old = 0; + int ret, stereo; + + samples_made = samples_done = 0; + + if (PsndRate != PsndRate_old || (PicoOpt&0x0b) != (PicoOpt_old&0x0b) || Pico.m.pal != pal_old) { + sound_rerate(Pico.m.frame_count ? 1 : 0); + } + stereo=(PicoOpt&8)>>3; + samples_block = SOUND_DEF_BLOCK_SIZE; + if (PsndRate < 44100) samples_block = SOUND_DEF_BLOCK_SIZE / 2; + if (PsndRate < 22050) samples_block = SOUND_DEF_BLOCK_SIZE / 4; + + lprintf("starting audio: %i, len: %i, stereo: %i, pal: %i, block samples: %i\n", + PsndRate, PsndLen, stereo, Pico.m.pal, samples_block); + + while (sceAudioOutput2GetRestSample() > 0) psp_msleep(100); + sceAudio_5C37C0AE(); + ret = sceAudio_38553111(samples_block/2, PsndRate, 2/*stereo ? 2 : 1*/); + lprintf("sceAudio_38553111() ret: %i\n", ret); + if (ret < 0) { + lprintf("sceAudio_38553111() failed: %i\n", ret); + sprintf(noticeMsg, "sound init failed (%i), snd disabled", ret); + noticeMsgTime = sceKernelGetSystemTimeLow(); + currentConfig.EmuOpt &= ~4; + } else { +// int ret = sceAudioSetChannelDataLen(ret, PsndLen); // a try.. +// lprintf("sceAudioSetChannelDataLen: %i\n", ret); + PicoWriteSound = writeSound; + memset32((int *)(void *)sndBuffer, 0, sizeof(sndBuffer)/4); + snd_playptr = sndBuffer; + PsndOut = sndBuffer; + PsndRate_old = PsndRate; + PicoOpt_old = PicoOpt; + pal_old = Pico.m.pal; + } +} + +static void sound_end(void) +{ + int ret; + while (sceAudioOutput2GetRestSample() > 0) psp_msleep(100); + ret = sceAudio_5C37C0AE(); + lprintf("sound_end: sceAudio_5C37C0AE ret %i\n", ret); +} + +static void sound_deinit(void) +{ + sound_thread_exit = 1; + sceKernelSignalSema(sound_sem, 1); +} + +static void writeSound(int len) +{ + int ret; + short *endptr = &sndBuffer[SOUND_DEF_BLOCK_SIZE*SOUND_BLOCK_COUNT*2]; if (PicoOpt&8) len<<=1; - // TODO.. + PsndOut += len; + if (PsndOut > endptr) { + memcpy32((int *)(void *)sndBuffer, (int *)endptr, (PsndOut - endptr + 1) / 2); + PsndOut = &sndBuffer[PsndOut - endptr]; + } + else if (PsndOut == endptr) + PsndOut = sndBuffer; // happy case + + // signal the snd thread + samples_made += len; + if (samples_made - samples_done >= samples_block) { + if (!Pico.m.scanline) lprintf("signal, %i/%i\n", samples_done, samples_made); + ret = sceKernelSignalSema(sound_sem, 1); + if (!Pico.m.scanline) lprintf("signal ret %i\n", ret); + } } -*/ + static void SkipFrame(void) { @@ -490,6 +636,7 @@ void emu_forcedFrame(void) vidResetMode(); memset32(VRAM_CACHED_STUFF, 0xe0e0e0e0, 512*8/4); // borders memset32((int *)VRAM_CACHED_STUFF + 512*232/4, 0xe0e0e0e0, 512*8/4); + memset32((int *)psp_screen + 512*264*2/4, 0, 512*8*2/4); PicoDrawSetColorFormat(-1); PicoScan = EmuScanSlow; @@ -676,7 +823,6 @@ static void simpleWait(unsigned int until) void emu_Loop(void) { - //static int PsndRate_old = 0, PicoOpt_old = 0, pal_old = 0; char fpsbuff[24]; // fps count c string unsigned int tval, tval_prev = 0, tval_thissec = 0; // timing int frames_done = 0, frames_shown = 0, oldmodes = 0; @@ -711,36 +857,10 @@ void emu_Loop(void) // prepare sound stuff PsndOut = NULL; -#if 0 // TODO if (currentConfig.EmuOpt & 4) { - int ret, snd_excess_add, stereo; - if (PsndRate != PsndRate_old || (PicoOpt&0x0b) != (PicoOpt_old&0x0b) || Pico.m.pal != pal_old) { - sound_rerate(Pico.m.frame_count ? 1 : 0); - } - stereo=(PicoOpt&8)>>3; - snd_excess_add = ((PsndRate - PsndLen*target_fps)<<16) / target_fps; - snd_cbuf_samples = (PsndRate< 0; i--, dst += 480, src += 512) menu_darken_bg(dst, src, 480, 1); @@ -1695,7 +1693,7 @@ static void menu_prepare_bg(int use_game_bg, int use_back_buff) static void menu_gfx_prepare(void) { - menu_prepare_bg(rom_data != NULL, 0); + menu_prepare_bg(rom_data != NULL); menu_draw_begin(); menu_draw_end(); diff --git a/psp/psp.c b/psp/psp.c index 84ab5c8..b2d0d72 100644 --- a/psp/psp.c +++ b/psp/psp.c @@ -32,7 +32,8 @@ static int callback_thread(SceSize args, void *argp) { int cbid; - lprintf("callback_thread started with id %i\n", sceKernelGetThreadId()); + lprintf("callback_thread started with id %i, priority %i\n", + sceKernelGetThreadId(), sceKernelGetThreadCurrentPriority()); cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); sceKernelRegisterExitCallback(cbid); @@ -44,9 +45,10 @@ static int callback_thread(SceSize args, void *argp) void psp_init(void) { - int thid; + SceUID thid; - lprintf("entered psp_init, threadId %i\n", sceKernelGetThreadId()); + lprintf("entered psp_init, threadId %i, priority %i\n", sceKernelGetThreadId(), + sceKernelGetThreadCurrentPriority()); thid = sceKernelCreateThread("update_thread", callback_thread, 0x11, 0xFA0, 0, 0); if (thid >= 0)