optimizations, fixes, hacks, psp, ...
[picodrive.git] / cpu / fame / famec.c
index 11d2cb2..e8753e4 100644 (file)
@@ -16,8 +16,8 @@
 \r
 // Options //\r
 #define FAMEC_ROLL_INLINE\r
-#define FAMEC_EMULATE_TRACE\r
-#define FAMEC_CHECK_BRANCHES\r
+//#define FAMEC_EMULATE_TRACE\r
+//#define FAMEC_CHECK_BRANCHES\r
 #define FAMEC_EXTRA_INLINE\r
 // #define FAMEC_DEBUG\r
 //#define FAMEC_NO_GOTOS\r
@@ -28,6 +28,7 @@
 \r
 #define USE_CYCLONE_TIMING\r
 #define USE_CYCLONE_TIMING_DIV\r
+#define PICODRIVE_HACK\r
 // Options //\r
 \r
 \r
@@ -279,11 +280,18 @@ typedef signed int        s32;
        ((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
@@ -293,6 +301,7 @@ typedef signed int  s32;
 #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
@@ -506,6 +515,7 @@ static u32 Opcode;
 static s32 cycles_needed;\r
 static u16 *PC;\r
 static u32 BasePC;\r
+static u32 flag_C;\r
 static u32 flag_V;\r
 static u32 flag_NotZ;\r
 static u32 flag_N;\r
@@ -520,6 +530,10 @@ static u32 flag_I;
 \r
 static u32 initialised = 0;\r
 \r
+#ifdef PICODRIVE_HACK\r
+extern M68K_CONTEXT PicoCpuFM68k, PicoCpuFS68k;\r
+#endif\r
+\r
 /* Custom function handler */\r
 typedef void (*opcode_func)(void);\r
 \r
@@ -618,7 +632,7 @@ void fm68k_init(void)
 #endif\r
 \r
     if (!initialised)\r
-           fm68k_emulate(0);\r
+           fm68k_emulate(0, 0);\r
 \r
 #ifdef FAMEC_DEBUG\r
        puts("FAME initialized.");\r
@@ -637,7 +651,7 @@ void fm68k_init(void)
 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
@@ -728,7 +742,9 @@ static FAMEC_EXTRA_INLINE u32 execute_exception(s32 vect, u32 oldPC, u32 oldSR)
 #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
@@ -765,7 +781,7 @@ static void setup_jumptable(void);
 // 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
@@ -789,9 +805,17 @@ int fm68k_emulate(s32 cycles)
 #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
+       // Cache PPL\r
+       flag_I = M68K_PPL;\r
+\r
        if (m68kcontext.execinfo & FM68K_HALTED)\r
        {\r
                if (interrupt_chk__() <= 0)\r
@@ -811,9 +835,6 @@ int fm68k_emulate(s32 cycles)
        // Cache SR\r
        SET_SR(m68kcontext.sr)\r
 \r
-       // Cache PPL\r
-       flag_I = M68K_PPL;\r
-\r
        // Fijar PC\r
        SET_PC(m68kcontext.pc)\r
 \r
@@ -929,7 +950,60 @@ famec_End:
        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
@@ -942,8 +1016,6 @@ init_jump_table:
 #endif\r
        u32 i, j;\r
 \r
-       m68kcontext.sr = 0x2704; // Z flag\r
-\r
        for(i = 0x0000; i <= 0xFFFF; i += 0x0001)\r
                JumpTable[0x0000 + i] = CAST_OP(0x4AFC);\r
        for(i = 0x0000; i <= 0x0007; i += 0x0001)\r