X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=cpu%2Ffame%2Ffamec.c;h=508a12f7bfcf653ce0205b44801e0b989ced1a8e;hb=12f23dac6f91eb707f985ef00a5d48e9e5ef8838;hp=ba1c893c3c879b098dde9f9cb35ac435af8786f5;hpb=c060a9ab9c428e1ed9c4159b56529a2a36031e44;p=picodrive.git diff --git a/cpu/fame/famec.c b/cpu/fame/famec.c index ba1c893..508a12f 100644 --- a/cpu/fame/famec.c +++ b/cpu/fame/famec.c @@ -11,6 +11,10 @@ #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 @@ -31,7 +35,17 @@ #define PICODRIVE_HACK // Options // - +#ifndef FAMEC_NO_GOTOS +// computed gotos is a GNU extension +#ifndef __GNUC__ +#define FAMEC_NO_GOTOS +#endif +// as of 3.3, clang takes over 3h to compile this in computed goto mode.. +#ifdef __clang__ +#define FAMEC_NO_GOTOS +#endif +#endif + #undef INLINE #ifdef _MSC_VER #define INLINE @@ -70,12 +84,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; @@ -262,6 +281,10 @@ typedef signed int s32; goto famec_Exec; #endif +#define RET0() \ + m68kcontext.io_cycle_counter = -6; \ + goto famec_End; + #else #define NEXT \ @@ -274,12 +297,16 @@ 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 @@ -511,27 +538,25 @@ M68K_CONTEXT *g_m68kcontext; #define m68kcontext (*g_m68kcontext) #ifdef FAMEC_NO_GOTOS -static u32 Opcode; -static s32 cycles_needed; -static u16 *PC; -static u32 BasePC; -static u32 flag_C; -static u32 flag_V; -static u32 flag_NotZ; -static u32 flag_N; -static u32 flag_X; +#define Opcode m68kcontext.Opcode +#define cycles_needed m68kcontext.cycles_needed +#define PC m68kcontext.PC +#define BasePC m68kcontext.BasePC +#define flag_C m68kcontext.flag_C +#define flag_V m68kcontext.flag_V +#define flag_NotZ m68kcontext.flag_NotZ +#define flag_N m68kcontext.flag_N +#define flag_X m68kcontext.flag_X #endif -#ifdef FAMEC_EMULATE_TRACE -static u32 flag_T; -#endif -static u32 flag_S; -static u32 flag_I; +#define flag_T m68kcontext.flag_T +#define flag_S m68kcontext.flag_S +#define flag_I m68kcontext.flag_I static u32 initialised = 0; #ifdef PICODRIVE_HACK -extern M68K_CONTEXT PicoCpuFM68k, PicoCpuFS68k; +extern M68K_CONTEXT PicoCpuFS68k; #endif /* Custom function handler */ @@ -615,6 +640,7 @@ static const s32 exception_cycle_table[256] = 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 }; +static int init_jump_table(void); /***********************/ /* core main functions */ @@ -631,8 +657,8 @@ void fm68k_init(void) puts("Initializing FAME..."); #endif - if (!initialised) - fm68k_emulate(0, 0, 0); + if (!initialised) + init_jump_table(); #ifdef FAMEC_DEBUG puts("FAME initialized."); @@ -648,10 +674,12 @@ void fm68k_init(void) /* M68K_NO_SUP_ADDR_SPACE (2): No se puede resetear porque no hay mapa */ /* de memoria supervisor de extraccion de opcodes */ /******************************************************************************/ -int fm68k_reset(void) +int fm68k_reset(M68K_CONTEXT *ctx) { if (!initialised) - fm68k_emulate(0, 0, 0); + init_jump_table(); + + g_m68kcontext = ctx; // Si la CPU esta en ejecucion, salir con M68K_RUNNING if (m68kcontext.execinfo & M68K_RUNNING) @@ -689,7 +717,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 @@ -706,7 +734,7 @@ static FAMEC_EXTRA_INLINE s32 interrupt_chk__(void) return 0; } -int fm68k_would_interrupt(void) +int fm68k_would_interrupt(M68K_CONTEXT *ctx) { return interrupt_chk__(); } @@ -717,6 +745,9 @@ static FAMEC_EXTRA_INLINE u32 execute_exception(s32 vect, u32 oldPC, u32 oldSR) //u32 oldSR = GET_SR; m68kcontext.io_cycle_counter -= exception_cycle_table[vect]; +#ifdef FAMEC_EMULATE_TRACE + m68kcontext.execinfo &= ~FM68K_EMULATE_TRACE; +#endif PRE_IO @@ -738,6 +769,7 @@ static FAMEC_EXTRA_INLINE u32 execute_exception(s32 vect, u32 oldPC, u32 oldSR) /* adjust SR */ flag_S = M68K_SR_S; + flag_T = 0; #ifndef FAMEC_32BIT_PC newPC&=M68K_ADR_MASK @@ -768,8 +800,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) @@ -781,31 +811,35 @@ static void setup_jumptable(void); // main exec function ////////////////////// -int fm68k_emulate(s32 cycles, int dualcore, int idle_mode) +int fm68k_emulate(M68K_CONTEXT *ctx, s32 cycles, fm68k_call_reason reason) { #ifndef FAMEC_NO_GOTOS u32 Opcode; s32 cycles_needed; u16 *PC; - u32 BasePC; + uptr BasePC; u32 flag_C; u32 flag_V; u32 flag_NotZ; u32 flag_N; u32 flag_X; -#endif - if (!initialised) + switch (reason) { + case fm68k_reason_init: goto init_jump_table; - } - #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: + case fm68k_reason_idle_install: + goto idle_install; + case fm68k_reason_idle_remove: + goto idle_remove; #endif + case fm68k_reason_emulate: + break; + } +#endif // FAMEC_NO_GOTOS + + g_m68kcontext = ctx; // won't emulate double fault // if (m68kcontext.execinfo & M68K_FAULTED) return -1; @@ -895,12 +929,11 @@ famec_Exec: #ifdef FAMEC_EMULATE_TRACE if (m68kcontext.execinfo & FM68K_EMULATE_TRACE) { - m68kcontext.io_cycle_counter = cycles_needed; + m68kcontext.io_cycle_counter += cycles_needed; cycles_needed = 0; m68kcontext.execinfo &= ~FM68K_EMULATE_TRACE; m68kcontext.execinfo |= FM68K_DO_TRACE; SET_PC(execute_exception(M68K_TRACE_EX, GET_PC, GET_SR)); - flag_T=0; if (m68kcontext.io_cycle_counter > 0) { //NEXT @@ -912,8 +945,9 @@ famec_Exec: if (cycles_needed != 0) { u32 line; - m68kcontext.io_cycle_counter = cycles_needed; + m68kcontext.io_cycle_counter += cycles_needed; cycles_needed = 0; + //if (m68kcontext.io_cycle_counter <= 0) goto famec_End; line=interrupt_chk__(); if (line>0) { @@ -948,60 +982,15 @@ famec_End: printf("pc: 0x%08x\n",m68kcontext.pc); #endif -#ifdef PICODRIVE_HACK - if (!dualcore) -#endif - return cycles - m68kcontext.io_cycle_counter; + return cycles - m68kcontext.io_cycle_counter; -#ifdef PICODRIVE_HACK -dualcore_mode: +#ifndef FAMEC_NO_GOTOS +init_jump_table: +#else +} - while (1) - { - extern int SekCycleAim, SekCycleCnt, SekCycleAimS68k, SekCycleCntS68k; - #define PS_STEP_M68K ((488<<16)/20) // ~24 - if (dualcore == 1) - { - dualcore = (488<<16); // ~ cycn in Pico.c - // adjust for first iteration - g_m68kcontext = &PicoCpuFS68k; - cycles = m68kcontext.io_cycle_counter = 0; - } - if (g_m68kcontext == &PicoCpuFS68k) - { - SekCycleCntS68k += cycles - m68kcontext.io_cycle_counter; - // end? - dualcore -= PS_STEP_M68K; - if (dualcore < 0) return 0; - // become main 68k - g_m68kcontext = &PicoCpuFM68k; - if ((cycles = SekCycleAim-SekCycleCnt-(dualcore>>16)) > 0) - { - if ((m68kcontext.execinfo & FM68K_HALTED) && m68kcontext.interrupts[0] <= (M68K_PPL)) - SekCycleCnt += cycles; // halted - else goto famec_restart; - //else { printf("go main %i\n", cycles); goto famec_restart; } - } - cycles = m68kcontext.io_cycle_counter = 0; - } - if (g_m68kcontext == &PicoCpuFM68k) - { - int cycn_s68k = (dualcore + dualcore/2 + dualcore/8) >> 16; - SekCycleCnt += cycles - m68kcontext.io_cycle_counter; - // become sub 68k - g_m68kcontext = &PicoCpuFS68k; - if ((cycles = SekCycleAimS68k-SekCycleCntS68k-cycn_s68k) > 0) - { - if ((m68kcontext.execinfo & FM68K_HALTED) && m68kcontext.interrupts[0] <= (M68K_PPL)) - SekCycleCntS68k += cycles; // halted - else goto famec_restart; - } - cycles = m68kcontext.io_cycle_counter = 0; - } - } +static int init_jump_table(void) #endif - -init_jump_table: { u32 i, j; @@ -5031,8 +5020,13 @@ init_jump_table: JumpTable[fake_op_base] = JumpTable[fake_op_base|0x0200] = CAST_OP(0x4AFC); \ JumpTable[real_op] = CAST_OP(normal_handler) +#ifndef FAMEC_NO_GOTOS idle_install: - printf("install..\n"); +#else +int fm68k_idle_install(void) +#endif +{ + // 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); @@ -5041,12 +5035,18 @@ idle_install: 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_dead, 0x6001_idle, 0x6001); - INSTALL_IDLE(0x7dfc, 0x60fc, idle_detector_dead, 0x6001_idle, 0x6001); + INSTALL_IDLE(0x7dfe, 0x60fe, idle_detector_bcc8, 0x6001_idle, 0x6001); + INSTALL_IDLE(0x7dfc, 0x60fc, idle_detector_bcc8, 0x6001_idle, 0x6001); return 0; +} +#ifndef FAMEC_NO_GOTOS idle_remove: - printf("remove..\n"); +#else +int fm68k_idle_remove(void) +#endif +{ + // printf("remove..\n"); UNDO_IDLE(0x71fa, 0x66fa, 0x6601); UNDO_IDLE(0x71f8, 0x66f8, 0x6601); UNDO_IDLE(0x71f6, 0x66f6, 0x6601); @@ -5058,9 +5058,26 @@ idle_remove: UNDO_IDLE(0x7dfe, 0x60fe, 0x6001); UNDO_IDLE(0x7dfc, 0x60fc, 0x6001); return 0; +} +#endif // PICODRIVE_HACK -#endif +#ifndef FAMEC_NO_GOTOS } -void *get_jumptab(void) { return JumpTable; } +static int init_jump_table(void) +{ + return fm68k_emulate(NULL, 0, fm68k_reason_init); +} + +#ifdef PICODRIVE_HACK +int fm68k_idle_install(void) +{ + return fm68k_emulate(NULL, 0, fm68k_reason_idle_install); +} +int fm68k_idle_remove(void) +{ + return fm68k_emulate(NULL, 0, fm68k_reason_idle_remove); +} +#endif +#endif // FAMEC_NO_GOTOS