/* Autor: Oscar Orallo Pelaez */\r
/* Fecha de comienzo: 03-10-2006 */\r
/* Ultima actualizacion: 08-10-2006 */\r
-/* Based on the excellent FAMEC emulator by Stèphane Dallongueville */\r
+/* Based on the excellent C68K emulator by Stèphane Dallongueville */\r
/****************************************************************************/\r
\r
#include <stdio.h>\r
((u32)PC - BasePC)\r
\r
\r
+#ifdef FAMEC_CHECK_BRANCHES\r
+#define FORCE_ALIGNMENT(pc)\r
+#else\r
+#define FORCE_ALIGNMENT(pc) pc&=~1;\r
+#endif\r
+\r
#ifndef FAMEC_32BIT_PC\r
\r
#define SET_PC(A) \\r
{ \\r
u32 pc = A; \\r
+ FORCE_ALIGNMENT(pc); \\r
BasePC = m68kcontext.Fetch[(pc >> M68K_FETCHSFT) & M68K_FETCHMASK]; \\r
PC = (u16*)((pc & M68K_ADR_MASK) + BasePC); \\r
}\r
#define SET_PC(A) \\r
{ \\r
u32 pc = A; \\r
+ FORCE_ALIGNMENT(pc); \\r
BasePC = m68kcontext.Fetch[(pc >> M68K_FETCHSFT) & M68K_FETCHMASK]; \\r
BasePC -= pc & 0xFF000000; \\r
PC = (u16*)(pc + BasePC); \\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
#ifndef FAMEC_32BIT_PC\r
newPC&=M68K_ADR_MASK\r
#endif\r
+#ifdef FAMEC_CHECK_BRANCHES\r
newPC&=~1; // don't crash on games with bad vector tables\r
+#endif\r
\r
// SET_PC(newPC)\r
\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
+ while (1)\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
+ }\r
+#endif\r
+\r
+\r
\r
#ifdef FAMEC_NO_GOTOS\r
}\r