CycloneRun(&PicoCpuCM68k);\r
return 1-PicoCpuCM68k.cycles;\r
#elif defined(EMU_F68K)\r
- return fm68k_emulate(1);\r
+ return fm68k_emulate(1, 0);\r
#endif\r
}\r
\r
#elif defined(EMU_M68K)\r
SekCycleCnt+=m68k_execute(cyc_do);\r
#elif defined(EMU_F68K)\r
- SekCycleCnt+=fm68k_emulate(cyc_do+1);\r
+ SekCycleCnt+=fm68k_emulate(cyc_do+1, 0);\r
#endif\r
}\r
\r
#elif defined(EMU_M68K)\r
SekCycleCnt+=m68k_execute(1);\r
#elif defined(EMU_F68K)\r
- SekCycleCnt+=fm68k_emulate(1);\r
+ SekCycleCnt+=fm68k_emulate(1, 0);\r
#endif\r
SekCycleAim=realaim;\r
}\r
goto end;\r
}\r
\r
+ if (a==0x400000) {\r
+ if (SRam.data != NULL) d=3; // 64k cart\r
+ goto end;\r
+ }\r
+\r
+ if ((a&0xfe0000)==0x600000) {\r
+ if (SRam.data != NULL) {\r
+ d=SRam.data[((a>>1)&0xffff)+0x2000];\r
+ if (realsize == 8) d|=d<<8;\r
+ }\r
+ goto end;\r
+ }\r
+\r
+ if (a==0x7ffffe) {\r
+ d=Pico_mcd->m.bcram_reg;\r
+ goto end;\r
+ }\r
+\r
dprintf("m68k FIXME: unusual r%i: %06x @%06x", realsize&~1, (a&0xfffffe)+(realsize&1), SekPc);\r
\r
end:\r
{\r
if ((a&0xffffc0)==0xa12000) { m68k_reg_write8(a, d); return; }\r
\r
+ if ((a&0xfe0000)==0x600000) {\r
+ if (SRam.data != NULL && (Pico_mcd->m.bcram_reg&1)) {\r
+ SRam.data[((a>>1)&0xffff)+0x2000]=d;\r
+ SRam.changed = 1;\r
+ }\r
+ return;\r
+ }\r
+\r
+ if (a==0x7fffff) {\r
+ Pico_mcd->m.bcram_reg=d;\r
+ return;\r
+ }\r
+\r
dprintf("m68k FIXME: strange w%i: [%06x], %08x @%06x", realsize, a&0xffffff, d, SekPc);\r
}\r
\r
add r2, r2, #0x110000
add r2, r2, #0x002200
.if \is_read
- ldrb r0, [r2, #0x18]
+ ldrb r0, [r2, #0x18] @ Pico_mcd->m.bcram_reg
.else
strb r1, [r2, #0x18]
.endif
SekCycleCnt+=m68k_execute(cyc_do);
#elif defined(EMU_F68K)
g_m68kcontext=&PicoCpuFM68k;
- SekCycleCnt+=fm68k_emulate(cyc_do);
+ SekCycleCnt+=fm68k_emulate(cyc_do, 0);
#endif
}
SekCycleCntS68k+=m68k_execute(cyc_do);
#elif defined(EMU_F68K)
g_m68kcontext=&PicoCpuFS68k;
- SekCycleCntS68k+=fm68k_emulate(cyc_do);
+ SekCycleCntS68k+=fm68k_emulate(cyc_do, 0);
#endif
}
#define PS_STEP_M68K ((488<<16)/20) // ~24
//#define PS_STEP_S68K 13
-#ifdef _ASM_CD_PICO_C
-void SekRunPS(int cyc_m68k, int cyc_s68k);
+#if defined(_ASM_CD_PICO_C)
+extern void SekRunPS(int cyc_m68k, int cyc_s68k);
+#elif defined(EMU_F68K)
+static __inline void SekRunPS(int cyc_m68k, int cyc_s68k)
+{
+ SekCycleAim+=cyc_m68k;
+ SekCycleAimS68k+=cyc_s68k;
+ fm68k_emulate(0, 1);
+}
#else
static __inline void SekRunPS(int cyc_m68k, int cyc_s68k)
{
SekCycleCnt += m68k_execute(cyc_do);
#elif defined(EMU_F68K)
g_m68kcontext = &PicoCpuFM68k;
- SekCycleCnt += fm68k_emulate(cyc_do);
+ SekCycleCnt += fm68k_emulate(cyc_do, 0);
#endif
}
if ((cyc_do = SekCycleAimS68k-SekCycleCntS68k-cycn_s68k) > 0) {
SekCycleCntS68k += m68k_execute(cyc_do);
#elif defined(EMU_F68K)
g_m68kcontext = &PicoCpuFS68k;
- SekCycleCntS68k += fm68k_emulate(cyc_do);
+ SekCycleCntS68k += fm68k_emulate(cyc_do, 0);
#endif
}
}
#include "../PicoInt.h"
-//#include <stdlib.h>
-
int PicoCDBuffers = 0;
static unsigned char *cd_buffer = NULL;
static int prev_lba = 0x80000000;
/* try alloc'ing until we succeed */
while (PicoCDBuffers > 0)
{
- tmp = realloc(cd_buffer, PicoCDBuffers * 2048);
+ tmp = realloc(cd_buffer, PicoCDBuffers * 2048 + 304);
if (tmp != NULL) break;
PicoCDBuffers >>= 1;
}
if (is_bin)
{
- int i;
- for (i = 0; i < read_len; i++)
+ int i = 0;
+#if REDUCE_IO_CALLS
+ int bufs = (read_len*2048+304) / (2048+304);
+ pm_read(cd_buffer, bufs*(2048+304), Pico_mcd->TOC.Tracks[0].F);
+ for (i = 1; i < bufs; i++)
+ // should really use memmove here, but my memcpy32 implementation is also suitable here
+ memcpy32((int *)(cd_buffer + i*2048), (int *)(cd_buffer + i*(2048+304)), 2048/4);
+#endif
+ for (; i < read_len; i++)
{
- pm_read(cd_buffer + i*2048, 2048, Pico_mcd->TOC.Tracks[0].F);
- pm_seek(Pico_mcd->TOC.Tracks[0].F, 304, SEEK_CUR);
+ pm_read(cd_buffer + i*2048, 2048 + 304, Pico_mcd->TOC.Tracks[0].F);
+ // pm_seek(Pico_mcd->TOC.Tracks[0].F, 304, SEEK_CUR); // seeking is slower, in PSP case even more
}
}
else
/* General purpose functions */\r
void fm68k_init(void);\r
int fm68k_reset(void);\r
-int fm68k_emulate(int n);\r
+int fm68k_emulate(int n, int dualcore);\r
int fm68k_would_interrupt(void); // to be called from fm68k_emulate()\r
\r
unsigned fm68k_get_pc(M68K_CONTEXT *context);\r
#define FAMEC_CHECK_BRANCHES\r
#define FAMEC_EXTRA_INLINE\r
// #define FAMEC_DEBUG\r
-#define FAMEC_NO_GOTOS\r
+//#define FAMEC_NO_GOTOS\r
#define FAMEC_ADR_BITS 24\r
// #define FAMEC_FETCHBITS 8\r
#define FAMEC_DATABITS 8\r
static u32 initialised = 0;\r
\r
#ifdef PICODRIVE_HACK\r
-extern M68K_CONTEXT PicoCpuFS68k;\r
+extern M68K_CONTEXT PicoCpuFM68k, PicoCpuFS68k;\r
#endif\r
\r
/* Custom function handler */\r
#endif\r
\r
if (!initialised)\r
- fm68k_emulate(0);\r
+ fm68k_emulate(0, 0);\r
\r
#ifdef FAMEC_DEBUG\r
puts("FAME initialized.");\r
int fm68k_reset(void)\r
{\r
if (!initialised)\r
- fm68k_emulate(0);\r
+ fm68k_emulate(0, 0);\r
\r
// Si la CPU esta en ejecucion, salir con M68K_RUNNING\r
if (m68kcontext.execinfo & M68K_RUNNING)\r
// main exec function\r
//////////////////////\r
\r
-int fm68k_emulate(s32 cycles)\r
+int fm68k_emulate(s32 cycles, int dualcore)\r
{\r
#ifndef FAMEC_NO_GOTOS\r
u32 Opcode;\r
#endif\r
}\r
\r
+#ifdef PICODRIVE_HACK\r
+ if (dualcore) goto dualcore_mode;\r
+famec_restart:\r
+#endif\r
+\r
// won't emulate double fault\r
// if (m68kcontext.execinfo & M68K_FAULTED) return -1;\r
\r
printf("pc: 0x%08x\n",m68kcontext.pc);\r
#endif\r
\r
- return cycles - m68kcontext.io_cycle_counter;\r
+#ifdef PICODRIVE_HACK\r
+ if (!dualcore)\r
+#endif\r
+ return cycles - m68kcontext.io_cycle_counter;\r
+\r
+#ifdef PICODRIVE_HACK\r
+dualcore_mode:\r
+\r
+ {\r
+ extern int SekCycleAim, SekCycleCnt, SekCycleAimS68k, SekCycleCntS68k;\r
+ #define PS_STEP_M68K ((488<<16)/20) // ~24\r
+ if (dualcore == 1)\r
+ {\r
+ dualcore = (488<<16); // ~ cycn in Pico.c\r
+ // adjust for first iteration\r
+ g_m68kcontext = &PicoCpuFS68k;\r
+ cycles = m68kcontext.io_cycle_counter = 0;\r
+ }\r
+ if (g_m68kcontext == &PicoCpuFS68k)\r
+ {\r
+ SekCycleCntS68k += cycles - m68kcontext.io_cycle_counter;\r
+ // end?\r
+ dualcore -= PS_STEP_M68K;\r
+ if (dualcore < 0) return 0;\r
+ // become main 68k\r
+ g_m68kcontext = &PicoCpuFM68k;\r
+ if ((cycles = SekCycleAim-SekCycleCnt-(dualcore>>16)) > 0)\r
+ {\r
+ if ((m68kcontext.execinfo & FM68K_HALTED) && m68kcontext.interrupts[0] <= (M68K_PPL))\r
+ SekCycleCnt += cycles; // halted\r
+ else goto famec_restart;\r
+ //else { printf("go main %i\n", cycles); goto famec_restart; }\r
+ }\r
+ cycles = m68kcontext.io_cycle_counter = 0;\r
+ }\r
+ if (g_m68kcontext == &PicoCpuFM68k)\r
+ {\r
+ int cycn_s68k = (dualcore + dualcore/2 + dualcore/8) >> 16;\r
+ SekCycleCnt += cycles - m68kcontext.io_cycle_counter;\r
+ // become sub 68k\r
+ g_m68kcontext = &PicoCpuFS68k;\r
+ if ((cycles = SekCycleAimS68k-SekCycleCntS68k-cycn_s68k) > 0)\r
+ {\r
+ if ((m68kcontext.execinfo & FM68K_HALTED) && m68kcontext.interrupts[0] <= (M68K_PPL))\r
+ SekCycleCntS68k += cycles; // halted\r
+ else goto famec_restart;\r
+ }\r
+ cycles = m68kcontext.io_cycle_counter = 0;\r
+ }\r
+ goto dualcore_mode;\r
+ }\r
+#endif\r
+\r
+\r
\r
#ifdef FAMEC_NO_GOTOS\r
}\r
\r
#define CASE_SENSITIVE_FS 0\r
#define DONT_OPEN_MANY_FILES 0\r
+#define REDUCE_IO_CALLS 0\r
\r
// draw.c\r
#define OVERRIDE_HIGHCOL 1\r
\r
# cleanup\r
clean: tidy\r
- @$(RM) PicoDrive.gpe\r
+ $(RM) PicoDrive.gpe\r
tidy:\r
- @$(RM) $(OBJS)\r
+ $(RM) $(OBJS)\r
# @make -C ../../cpu/Cyclone/proj -f Makefile.linux clean\r
\r
\r
\r
#define CASE_SENSITIVE_FS 1 // CS filesystem\r
#define DONT_OPEN_MANY_FILES 0\r
+#define REDUCE_IO_CALLS 0\r
\r
// draw.c\r
#define OVERRIDE_HIGHCOL 0\r
if (len > 0) *dst = 0;
}
-static void osd_text(int x, const char *text, int is_active)
+static void osd_text(int x, const char *text, int is_active, int clear_all)
{
unsigned short *screen = is_active ? psp_video_get_active_fb() : psp_screen;
- int len = strlen(text) * 8 / 2;
+ int len = clear_all ? (480 / 2) : (strlen(text) * 8 / 2);
int *p, h;
void *tmp;
for (h = 0; h < 8; h++) {
void emu_msg_cb(const char *msg)
{
- osd_text(4, msg, 1);
+ osd_text(4, msg, 1, 1);
noticeMsgTime = sceKernelGetSystemTimeLow() - 2000000;
/* assumption: emu_msg_cb gets called only when something slow is about to happen */
currentConfig.KeyBinds[30] = 1<<1;
currentConfig.KeyBinds[31] = 1<<2;
currentConfig.KeyBinds[29] = 1<<3;
- currentConfig.PicoCDBuffers = 0;
+ currentConfig.PicoCDBuffers = 64;
currentConfig.scaling = 1; // bilinear filtering for psp
currentConfig.scale = 1.20; // fullscreen
currentConfig.hscale40 = 1.25;
int vsync = 0, emu_opt = currentConfig.EmuOpt;
if (notice || (emu_opt & 2)) {
- if (notice) osd_text(4, notice, 0);
- if (emu_opt & 2) osd_text(OSD_FPS_X, fps, 0);
+ if (notice) osd_text(4, notice, 0, 0);
+ if (emu_opt & 2) osd_text(OSD_FPS_X, fps, 0, 0);
}
dbg_text();
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();
+ // while (sceAudioOutput2GetRestSample() > 0) psp_msleep(100);
+ // sceAudio_5C37C0AE();
ret = sceAudio_38553111(samples_block/2, PsndRate, 2); // seems to not need that stupid 64byte alignment
if (ret < 0) {
lprintf("sceAudio_38553111() failed: %i\n", ret);
static void sound_end(void)
{
+ int i;
+ if (samples_done == 0)
+ {
+ // if no data is written between sceAudio_38553111 and sceAudio_5C37C0AE calls,
+ // we get a deadlock on next sceAudio_38553111 call
+ // so this is yet another workaround:
+ memset32((int *)(void *)sndBuffer, 0, samples_block*4/4);
+ samples_made = samples_block * 3;
+ sceKernelSignalSema(sound_sem, 1);
+ }
+ sceKernelDelayThread(100*1000);
samples_made = samples_done = 0;
- while (sceAudioOutput2GetRestSample() > 0)
+ for (i = 0; sceAudioOutput2GetRestSample() > 0 && i < 16; i++)
psp_msleep(100);
sceAudio_5C37C0AE();
}
if (do_it)
{
- osd_text(4, (which & 0x1000) ? "LOADING GAME" : "SAVING GAME", 1);
+ osd_text(4, (which & 0x1000) ? "LOADING GAME" : "SAVING GAME", 1, 0);
PicoStateProgressCB = emu_msg_cb;
emu_SaveLoadGame((which & 0x1000) >> 12, 0);
PicoStateProgressCB = NULL;
char *bios, *p;
if (emu_findBios(4, &bios)) { // US
- for (p = bios+strlen(bios)-1; p > bios && *p != '/'; p--); p++;
+ for (p = bios+strlen(bios)-1; p > bios && *p != '/'; p--);
+ if (*p == '/') p++;
strncpy(bios_names.us, p, sizeof(bios_names.us)); bios_names.us[sizeof(bios_names.us)-1] = 0;
} else strcpy(bios_names.us, "NOT FOUND");
if (emu_findBios(8, &bios)) { // EU
- for (p = bios+strlen(bios)-1; p > bios && *p != '/'; p--); p++;
+ for (p = bios+strlen(bios)-1; p > bios && *p != '/'; p--);
+ if (*p == '/') p++;
strncpy(bios_names.eu, p, sizeof(bios_names.eu)); bios_names.eu[sizeof(bios_names.eu)-1] = 0;
} else strcpy(bios_names.eu, "NOT FOUND");
if (emu_findBios(1, &bios)) { // JP
- for (p = bios+strlen(bios)-1; p > bios && *p != '/'; p--); p++;
+ for (p = bios+strlen(bios)-1; p > bios && *p != '/'; p--);
+ if (*p == '/') p++;
strncpy(bios_names.jp, p, sizeof(bios_names.jp)); bios_names.jp[sizeof(bios_names.jp)-1] = 0;
} else strcpy(bios_names.jp, "NOT FOUND");
}
if (frame_offset) {
- lprintf("unaligned, foffs=%i, offs=%i\n", mp3_src_pos - bytes_read, frame_offset);
+ //lprintf("unaligned, foffs=%i, offs=%i\n", mp3_src_pos - bytes_read, frame_offset);
memmove(mp3_src_buffer[which_buffer], mp3_src_buffer[which_buffer] + frame_offset, frame_size);
}
lprintf("mp3_start_play(%s) @ %i\n", fname, pos);
psp_sem_lock(thread_busy_sem);
- if (mp3_fname != fname)
+ if (mp3_fname != fname || mp3_handle < 0)
{
if (mp3_handle >= 0) sceIoClose(mp3_handle);
mp3_handle = sceIoOpen(fname, PSP_O_RDONLY, 0777);
#define PORT_CONFIG_H\r
\r
#define CASE_SENSITIVE_FS 0\r
-#define DONT_OPEN_MANY_FILES 1 // work around the stupid PSP 10 open file limit\r
+#define DONT_OPEN_MANY_FILES 1 // work around the stupid PSP ~10 open file limit\r
+#define REDUCE_IO_CALLS 1 // another workaround\r
\r
// draw.c\r
#define USE_BGR555 1\r