FAMEC idle loops, PSP port sync, minor adjustments
[picodrive.git] / cpu / fame / famec.c
index 19657fc..ba1c893 100644 (file)
@@ -503,8 +503,6 @@ typedef signed int  s32;
 #endif\r
 \r
 \r
-static int init_jump_table(void);\r
-\r
 // global variable\r
 ///////////////////\r
 \r
@@ -634,7 +632,7 @@ void fm68k_init(void)
 #endif\r
 \r
     if (!initialised)\r
-           fm68k_emulate(0, 0);\r
+           fm68k_emulate(0, 0, 0);\r
 \r
 #ifdef FAMEC_DEBUG\r
        puts("FAME initialized.");\r
@@ -653,7 +651,7 @@ void fm68k_init(void)
 int fm68k_reset(void)\r
 {\r
        if (!initialised)\r
-               fm68k_emulate(0, 0);\r
+               fm68k_emulate(0, 0, 0);\r
 \r
        // Si la CPU esta en ejecucion, salir con M68K_RUNNING\r
        if (m68kcontext.execinfo & M68K_RUNNING)\r
@@ -783,7 +781,7 @@ static void setup_jumptable(void);
 // main exec function\r
 //////////////////////\r
 \r
-int fm68k_emulate(s32 cycles, int dualcore)\r
+int fm68k_emulate(s32 cycles, int dualcore, int idle_mode)\r
 {\r
 #ifndef FAMEC_NO_GOTOS\r
        u32 Opcode;\r
@@ -799,16 +797,13 @@ int fm68k_emulate(s32 cycles, int dualcore)
 \r
        if (!initialised)\r
        {\r
-#ifdef FAMEC_NO_GOTOS\r
-               init_jump_table();\r
-               return 0;\r
-#else\r
                goto init_jump_table;\r
-#endif\r
        }\r
 \r
 #ifdef PICODRIVE_HACK\r
        if (dualcore) goto dualcore_mode;\r
+       if      (idle_mode == 1) goto idle_install;\r
+       else if (idle_mode == 2) goto idle_remove;\r
 famec_restart:\r
 #endif\r
 \r
@@ -1006,17 +1001,8 @@ dualcore_mode:
        }\r
 #endif\r
 \r
-\r
-\r
-#ifdef FAMEC_NO_GOTOS\r
-}\r
-\r
-static int init_jump_table(void)\r
-{{\r
-#else\r
 init_jump_table:\r
 {\r
-#endif\r
        u32 i, j;\r
 \r
        for(i = 0x0000; i <= 0xFFFF; i += 0x0001)\r
@@ -5032,6 +5018,49 @@ init_jump_table:
 \r
        initialised = 1;\r
        return 0;\r
-}}\r
+}\r
+\r
+#ifdef PICODRIVE_HACK\r
+\r
+#define INSTALL_IDLE(fake_op_base,real_op,detector,idle_handler,normal_handler) \\r
+       JumpTable[fake_op_base] = CAST_OP(idle_handler); \\r
+       JumpTable[fake_op_base|0x0200] = CAST_OP(normal_handler); \\r
+       JumpTable[real_op] = CAST_OP(detector)\r
+\r
+#define UNDO_IDLE(fake_op_base,real_op,normal_handler) \\r
+       JumpTable[fake_op_base] = JumpTable[fake_op_base|0x0200] = CAST_OP(0x4AFC); \\r
+       JumpTable[real_op] = CAST_OP(normal_handler)\r
+\r
+idle_install:\r
+       printf("install..\n");\r
+       INSTALL_IDLE(0x71fa, 0x66fa, idle_detector_bcc8, 0x6601_idle, 0x6601);\r
+       INSTALL_IDLE(0x71f8, 0x66f8, idle_detector_bcc8, 0x6601_idle, 0x6601);\r
+       INSTALL_IDLE(0x71f6, 0x66f6, idle_detector_bcc8, 0x6601_idle, 0x6601);\r
+       INSTALL_IDLE(0x71f2, 0x66f2, idle_detector_bcc8, 0x6601_idle, 0x6601);\r
+       INSTALL_IDLE(0x75fa, 0x67fa, idle_detector_bcc8, 0x6701_idle, 0x6701);\r
+       INSTALL_IDLE(0x75f8, 0x67f8, idle_detector_bcc8, 0x6701_idle, 0x6701);\r
+       INSTALL_IDLE(0x75f6, 0x67f6, idle_detector_bcc8, 0x6701_idle, 0x6701);\r
+       INSTALL_IDLE(0x75f2, 0x67f2, idle_detector_bcc8, 0x6701_idle, 0x6701);\r
+       INSTALL_IDLE(0x7dfe, 0x60fe, idle_detector_dead, 0x6001_idle, 0x6001);\r
+       INSTALL_IDLE(0x7dfc, 0x60fc, idle_detector_dead, 0x6001_idle, 0x6001);\r
+       return 0;\r
+\r
+idle_remove:\r
+       printf("remove..\n");\r
+       UNDO_IDLE(0x71fa, 0x66fa, 0x6601);\r
+       UNDO_IDLE(0x71f8, 0x66f8, 0x6601);\r
+       UNDO_IDLE(0x71f6, 0x66f6, 0x6601);\r
+       UNDO_IDLE(0x71f2, 0x66f2, 0x6601);\r
+       UNDO_IDLE(0x75fa, 0x67fa, 0x6701);\r
+       UNDO_IDLE(0x75f8, 0x67f8, 0x6701);\r
+       UNDO_IDLE(0x75f6, 0x67f6, 0x6701);\r
+       UNDO_IDLE(0x75f2, 0x67f2, 0x6701);\r
+       UNDO_IDLE(0x7dfe, 0x60fe, 0x6001);\r
+       UNDO_IDLE(0x7dfc, 0x60fc, 0x6001);\r
+       return 0;\r
+\r
+#endif\r
+}\r
 \r
+void *get_jumptab(void) { return JumpTable; }\r
 \r