famec: make reentrant
[picodrive.git] / cpu / fame / famec.c
index aa0a9d8..6891526 100644 (file)
 #include <stdlib.h>\r
 #include <string.h>\r
 \r
+#ifdef __GNUC__\r
+#pragma GCC diagnostic ignored "-Wunused-variable"\r
+#endif\r
+\r
 #include "fame.h"\r
 \r
 \r
@@ -20,7 +24,7 @@
 #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
 #undef s32\r
 #endif\r
 \r
+#ifdef uptr\r
+#undef uptr\r
+#endif\r
+\r
 #define u8     unsigned char\r
 #define s8     signed char\r
 #define u16    unsigned short\r
 #define s16    signed short\r
 #define u32    unsigned int\r
 #define s32    signed int\r
+#define uptr   unsigned long\r
 \r
 /*\r
 typedef unsigned char  u8;\r
@@ -262,6 +271,10 @@ typedef signed int s32;
     goto famec_Exec;\r
 #endif\r
 \r
+#define RET0() \\r
+    m68kcontext.io_cycle_counter = -6; \\r
+    goto famec_End;\r
+\r
 #else\r
 \r
 #define NEXT \\r
@@ -274,12 +287,16 @@ typedef signed int        s32;
     m68kcontext.io_cycle_counter -= (A);  \\r
     return;\r
 \r
+#define RET0() \\r
+    m68kcontext.io_cycle_counter = -6; \\r
+    return;\r
+\r
 #endif\r
 \r
 #define M68K_PPL (m68kcontext.sr >> 8) & 7\r
 \r
 #define GET_PC                  \\r
-       ((u32)PC - BasePC)\r
+       (u32)((uptr)PC - BasePC)\r
 \r
 \r
 #ifdef FAMEC_CHECK_BRANCHES\r
@@ -511,22 +528,20 @@ M68K_CONTEXT *g_m68kcontext;
 #define m68kcontext (*g_m68kcontext)\r
 \r
 #ifdef FAMEC_NO_GOTOS\r
-static u32 Opcode;\r
-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
-static u32 flag_X;\r
+#define Opcode m68kcontext.Opcode\r
+#define cycles_needed m68kcontext.cycles_needed\r
+#define PC m68kcontext.PC\r
+#define BasePC m68kcontext.BasePC\r
+#define flag_C m68kcontext.flag_C\r
+#define flag_V m68kcontext.flag_V\r
+#define flag_NotZ m68kcontext.flag_NotZ\r
+#define flag_N m68kcontext.flag_N\r
+#define flag_X m68kcontext.flag_X\r
 #endif\r
 \r
-#ifdef FAMEC_EMULATE_TRACE\r
-static u32 flag_T;\r
-#endif\r
-static u32 flag_S;\r
-static u32 flag_I;\r
+#define flag_T m68kcontext.flag_T\r
+#define flag_S m68kcontext.flag_S\r
+#define flag_I m68kcontext.flag_I\r
 \r
 static u32 initialised = 0;\r
 \r
@@ -689,7 +704,7 @@ int fm68k_reset(void)
 u32 fm68k_get_pc(M68K_CONTEXT *context)\r
 {\r
 #ifdef FAMEC_NO_GOTOS\r
-       return (context->execinfo & M68K_RUNNING)?(u32)PC-BasePC:context->pc;\r
+       return (context->execinfo & M68K_RUNNING)?(uptr)PC-BasePC:context->pc;\r
 #else\r
        return context->pc; // approximate PC in this mode\r
 #endif\r
@@ -768,8 +783,6 @@ static FAMEC_EXTRA_INLINE u32 execute_exception_group_0(s32 vect, s32 addr, u16
 }\r
 \r
 \r
-static void setup_jumptable(void);\r
-\r
 #ifdef FAMEC_NO_GOTOS\r
 \r
 #define OPCODE(N_OP) static void OP_##N_OP(void)\r
@@ -787,7 +800,7 @@ int fm68k_emulate(s32 cycles, int dualcore, int idle_mode)
        u32 Opcode;\r
        s32 cycles_needed;\r
        u16 *PC;\r
-       u32 BasePC;\r
+       uptr BasePC;\r
        u32 flag_C;\r
        u32 flag_V;\r
        u32 flag_NotZ;\r
@@ -914,6 +927,7 @@ famec_Exec:
                        u32 line;\r
                        m68kcontext.io_cycle_counter = cycles_needed;\r
                        cycles_needed = 0;\r
+                       if (m68kcontext.io_cycle_counter <= 0) goto famec_End;\r
                        line=interrupt_chk__();\r
                        if (line>0)\r
                        {\r
@@ -5041,8 +5055,8 @@ idle_install:
        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
+       INSTALL_IDLE(0x7dfe, 0x60fe, idle_detector_bcc8, 0x6001_idle, 0x6001);\r
+       INSTALL_IDLE(0x7dfc, 0x60fc, idle_detector_bcc8, 0x6001_idle, 0x6001);\r
        return 0;\r
 \r
 idle_remove:\r