X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=cpu%2Ffame%2Ffamec.c;h=1aba794f3f889e1458cb2d085b5661b28ec3c2ca;hb=3e5b912cf8820efc2c74e8f639a1c29cd4f68b75;hp=6b147b28b0b9fa7f125c9a51bfefd57a31611e4e;hpb=8022f53da61b8e70420a3bac97250119bbe26457;p=picodrive.git diff --git a/cpu/fame/famec.c b/cpu/fame/famec.c index 6b147b2..1aba794 100644 --- a/cpu/fame/famec.c +++ b/cpu/fame/famec.c @@ -4,13 +4,17 @@ /* Autor: Oscar Orallo Pelaez */ /* Fecha de comienzo: 03-10-2006 */ /* Ultima actualizacion: 08-10-2006 */ -/* Based on the excellent FAMEC emulator by Stèphane Dallongueville */ +/* Based on the excellent C68K emulator by Stèphane Dallongueville */ /****************************************************************************/ #include #include #include +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wunused-variable" +#endif + #include "fame.h" @@ -20,7 +24,7 @@ #define FAMEC_CHECK_BRANCHES #define FAMEC_EXTRA_INLINE // #define FAMEC_DEBUG -//#define FAMEC_NO_GOTOS +#define FAMEC_NO_GOTOS #define FAMEC_ADR_BITS 24 // #define FAMEC_FETCHBITS 8 #define FAMEC_DATABITS 8 @@ -33,7 +37,9 @@ #undef INLINE -#ifndef INLINE +#ifdef _MSC_VER +#define INLINE +#else #define INLINE __inline__ #endif @@ -68,12 +74,17 @@ #undef s32 #endif +#ifdef uptr +#undef uptr +#endif + #define u8 unsigned char #define s8 signed char #define u16 unsigned short #define s16 signed short #define u32 unsigned int #define s32 signed int +#define uptr unsigned long /* typedef unsigned char u8; @@ -260,6 +271,10 @@ typedef signed int s32; goto famec_Exec; #endif +#define RET0() \ + m68kcontext.io_cycle_counter = -6; \ + goto famec_End; + #else #define NEXT \ @@ -272,19 +287,30 @@ typedef signed int s32; m68kcontext.io_cycle_counter -= (A); \ return; +#define RET0() \ + m68kcontext.io_cycle_counter = -6; \ + return; + #endif #define M68K_PPL (m68kcontext.sr >> 8) & 7 #define GET_PC \ - ((u32)PC - BasePC) + (u32)((uptr)PC - BasePC) +#ifdef FAMEC_CHECK_BRANCHES +#define FORCE_ALIGNMENT(pc) +#else +#define FORCE_ALIGNMENT(pc) pc&=~1; +#endif + #ifndef FAMEC_32BIT_PC #define SET_PC(A) \ { \ u32 pc = A; \ + FORCE_ALIGNMENT(pc); \ BasePC = m68kcontext.Fetch[(pc >> M68K_FETCHSFT) & M68K_FETCHMASK]; \ PC = (u16*)((pc & M68K_ADR_MASK) + BasePC); \ } @@ -294,6 +320,7 @@ typedef signed int s32; #define SET_PC(A) \ { \ u32 pc = A; \ + FORCE_ALIGNMENT(pc); \ BasePC = m68kcontext.Fetch[(pc >> M68K_FETCHSFT) & M68K_FETCHMASK]; \ BasePC -= pc & 0xFF000000; \ PC = (u16*)(pc + BasePC); \ @@ -493,8 +520,6 @@ typedef signed int s32; #endif -static int init_jump_table(void); - // global variable /////////////////// @@ -506,7 +531,7 @@ M68K_CONTEXT *g_m68kcontext; static u32 Opcode; static s32 cycles_needed; static u16 *PC; -static u32 BasePC; +static uptr BasePC; static u32 flag_C; static u32 flag_V; static u32 flag_NotZ; @@ -624,7 +649,7 @@ void fm68k_init(void) #endif if (!initialised) - fm68k_emulate(0, 0); + fm68k_emulate(0, 0, 0); #ifdef FAMEC_DEBUG puts("FAME initialized."); @@ -643,7 +668,7 @@ void fm68k_init(void) int fm68k_reset(void) { if (!initialised) - fm68k_emulate(0, 0); + fm68k_emulate(0, 0, 0); // Si la CPU esta en ejecucion, salir con M68K_RUNNING if (m68kcontext.execinfo & M68K_RUNNING) @@ -681,7 +706,7 @@ int fm68k_reset(void) u32 fm68k_get_pc(M68K_CONTEXT *context) { #ifdef FAMEC_NO_GOTOS - return (context->execinfo & M68K_RUNNING)?(u32)PC-BasePC:context->pc; + return (context->execinfo & M68K_RUNNING)?(uptr)PC-BasePC:context->pc; #else return context->pc; // approximate PC in this mode #endif @@ -734,7 +759,9 @@ static FAMEC_EXTRA_INLINE u32 execute_exception(s32 vect, u32 oldPC, u32 oldSR) #ifndef FAMEC_32BIT_PC newPC&=M68K_ADR_MASK #endif +#ifdef FAMEC_CHECK_BRANCHES newPC&=~1; // don't crash on games with bad vector tables +#endif // SET_PC(newPC) @@ -758,8 +785,6 @@ static FAMEC_EXTRA_INLINE u32 execute_exception_group_0(s32 vect, s32 addr, u16 } -static void setup_jumptable(void); - #ifdef FAMEC_NO_GOTOS #define OPCODE(N_OP) static void OP_##N_OP(void) @@ -771,13 +796,13 @@ static void setup_jumptable(void); // main exec function ////////////////////// -int fm68k_emulate(s32 cycles, int dualcore) +int fm68k_emulate(s32 cycles, int dualcore, int idle_mode) { #ifndef FAMEC_NO_GOTOS u32 Opcode; s32 cycles_needed; u16 *PC; - u32 BasePC; + uptr BasePC; u32 flag_C; u32 flag_V; u32 flag_NotZ; @@ -787,16 +812,13 @@ int fm68k_emulate(s32 cycles, int dualcore) if (!initialised) { -#ifdef FAMEC_NO_GOTOS - init_jump_table(); - return 0; -#else goto init_jump_table; -#endif } #ifdef PICODRIVE_HACK if (dualcore) goto dualcore_mode; + if (idle_mode == 1) goto idle_install; + else if (idle_mode == 2) goto idle_remove; famec_restart: #endif @@ -904,9 +926,11 @@ famec_Exec: #endif if (cycles_needed != 0) { + u32 line; m68kcontext.io_cycle_counter = cycles_needed; cycles_needed = 0; - s32 line=interrupt_chk__(); + if (m68kcontext.io_cycle_counter <= 0) goto famec_End; + line=interrupt_chk__(); if (line>0) { if (m68kcontext.iack_handler != NULL) @@ -948,6 +972,7 @@ famec_End: #ifdef PICODRIVE_HACK dualcore_mode: + while (1) { extern int SekCycleAim, SekCycleCnt, SekCycleAimS68k, SekCycleCntS68k; #define PS_STEP_M68K ((488<<16)/20) // ~24 @@ -989,21 +1014,11 @@ dualcore_mode: } cycles = m68kcontext.io_cycle_counter = 0; } - goto dualcore_mode; } #endif - - -#ifdef FAMEC_NO_GOTOS -} - -static int init_jump_table(void) -{{ -#else init_jump_table: { -#endif u32 i, j; for(i = 0x0000; i <= 0xFFFF; i += 0x0001) @@ -5019,6 +5034,49 @@ init_jump_table: initialised = 1; return 0; -}} +} + +#ifdef PICODRIVE_HACK + +#define INSTALL_IDLE(fake_op_base,real_op,detector,idle_handler,normal_handler) \ + JumpTable[fake_op_base] = CAST_OP(idle_handler); \ + JumpTable[fake_op_base|0x0200] = CAST_OP(normal_handler); \ + JumpTable[real_op] = CAST_OP(detector) + +#define UNDO_IDLE(fake_op_base,real_op,normal_handler) \ + JumpTable[fake_op_base] = JumpTable[fake_op_base|0x0200] = CAST_OP(0x4AFC); \ + JumpTable[real_op] = CAST_OP(normal_handler) + +idle_install: + // printf("install..\n"); + INSTALL_IDLE(0x71fa, 0x66fa, idle_detector_bcc8, 0x6601_idle, 0x6601); + INSTALL_IDLE(0x71f8, 0x66f8, idle_detector_bcc8, 0x6601_idle, 0x6601); + INSTALL_IDLE(0x71f6, 0x66f6, idle_detector_bcc8, 0x6601_idle, 0x6601); + INSTALL_IDLE(0x71f2, 0x66f2, idle_detector_bcc8, 0x6601_idle, 0x6601); + INSTALL_IDLE(0x75fa, 0x67fa, idle_detector_bcc8, 0x6701_idle, 0x6701); + INSTALL_IDLE(0x75f8, 0x67f8, idle_detector_bcc8, 0x6701_idle, 0x6701); + INSTALL_IDLE(0x75f6, 0x67f6, idle_detector_bcc8, 0x6701_idle, 0x6701); + INSTALL_IDLE(0x75f2, 0x67f2, idle_detector_bcc8, 0x6701_idle, 0x6701); + INSTALL_IDLE(0x7dfe, 0x60fe, idle_detector_bcc8, 0x6001_idle, 0x6001); + INSTALL_IDLE(0x7dfc, 0x60fc, idle_detector_bcc8, 0x6001_idle, 0x6001); + return 0; + +idle_remove: + // printf("remove..\n"); + UNDO_IDLE(0x71fa, 0x66fa, 0x6601); + UNDO_IDLE(0x71f8, 0x66f8, 0x6601); + UNDO_IDLE(0x71f6, 0x66f6, 0x6601); + UNDO_IDLE(0x71f2, 0x66f2, 0x6601); + UNDO_IDLE(0x75fa, 0x67fa, 0x6701); + UNDO_IDLE(0x75f8, 0x67f8, 0x6701); + UNDO_IDLE(0x75f6, 0x67f6, 0x6701); + UNDO_IDLE(0x75f2, 0x67f2, 0x6701); + UNDO_IDLE(0x7dfe, 0x60fe, 0x6001); + UNDO_IDLE(0x7dfc, 0x60fc, 0x6001); + return 0; + +#endif +} +void *get_jumptab(void) { return JumpTable; }