filename | src/sh4/sh4.c |
changeset | 740:dd11269ee48b |
prev | 736:a02d1475ccfd |
next | 790:a0c7d28bbb0c |
author | nkeynes |
date | Wed Jul 16 10:40:10 2008 +0000 (14 years ago) |
permissions | -rw-r--r-- |
last change | Rationalize the two SH4 run slice impls into sh4.c, and tidy up the vm exits. Fixes broken soft-reset with emulator core Fixes broken build without translator |
file | annotate | diff | log | raw |
1.1 --- a/src/sh4/sh4.c Mon Jul 14 07:44:42 2008 +00001.2 +++ b/src/sh4/sh4.c Wed Jul 16 10:40:10 2008 +00001.3 @@ -19,6 +19,7 @@1.5 #define MODULE sh4_module1.6 #include <math.h>1.7 +#include <setjmp.h>1.8 #include <assert.h>1.9 #include "lxdream.h"1.10 #include "dreamcast.h"1.11 @@ -54,24 +55,23 @@1.12 sh4ptr_t sh4_main_ram;1.13 gboolean sh4_starting = FALSE;1.14 static gboolean sh4_use_translator = FALSE;1.15 +static jmp_buf sh4_exit_jmp_buf;1.16 +static gboolean sh4_running = FALSE;1.17 struct sh4_icache_struct sh4_icache = { NULL, -1, -1, 0 };1.19 -void sh4_set_use_xlat( gboolean use )1.20 +void sh4_translate_set_enabled( gboolean use )1.21 {1.22 // No-op if the translator was not built1.23 #ifdef SH4_TRANSLATOR1.24 + xlat_cache_init();1.25 if( use ) {1.26 - xlat_cache_init();1.27 sh4_translate_init();1.28 - sh4_module.run_time_slice = sh4_xlat_run_slice;1.29 - } else {1.30 - sh4_module.run_time_slice = sh4_run_slice;1.31 }1.32 sh4_use_translator = use;1.33 #endif1.34 }1.36 -gboolean sh4_is_using_xlat()1.37 +gboolean sh4_translate_is_enabled()1.38 {1.39 return sh4_use_translator;1.40 }1.41 @@ -136,6 +136,91 @@1.43 }1.45 +/**1.46 + * Execute a timeslice using translated code only (ie translate/execute loop)1.47 + */1.48 +uint32_t sh4_run_slice( uint32_t nanosecs )1.49 +{1.50 + sh4r.slice_cycle = 0;1.51 +1.52 + if( sh4r.sh4_state != SH4_STATE_RUNNING ) {1.53 + sh4_sleep_run_slice(nanosecs);1.54 + }1.55 +1.56 + /* Setup for sudden vm exits */1.57 + switch( setjmp(sh4_exit_jmp_buf) ) {1.58 + case CORE_EXIT_BREAKPOINT:1.59 + sh4_clear_breakpoint( sh4r.pc, BREAK_ONESHOT );1.60 + /* fallthrough */1.61 + case CORE_EXIT_HALT:1.62 + if( sh4r.sh4_state != SH4_STATE_STANDBY ) {1.63 + TMU_run_slice( sh4r.slice_cycle );1.64 + SCIF_run_slice( sh4r.slice_cycle );1.65 + dreamcast_stop();1.66 + return sh4r.slice_cycle;1.67 + }1.68 + case CORE_EXIT_SYSRESET:1.69 + dreamcast_reset();1.70 + break;1.71 + case CORE_EXIT_SLEEP:1.72 + sh4_sleep_run_slice(nanosecs);1.73 + break;1.74 + case CORE_EXIT_FLUSH_ICACHE:1.75 +#ifdef SH4_TRANSLATOR1.76 + xlat_flush_cache();1.77 +#endif1.78 + break;1.79 + }1.80 +1.81 + sh4_running = TRUE;1.82 +1.83 + /* Execute the core's real slice */1.84 +#ifdef SH4_TRANSLATOR1.85 + if( sh4_use_translator ) {1.86 + sh4_translate_run_slice(nanosecs);1.87 + } else {1.88 + sh4_emulate_run_slice(nanosecs);1.89 + }1.90 +#else1.91 + sh4_emulate_run_slice(nanosecs);1.92 +#endif1.93 +1.94 + /* And finish off the peripherals afterwards */1.95 +1.96 + sh4_running = FALSE;1.97 + sh4_starting = FALSE;1.98 + sh4r.slice_cycle = nanosecs;1.99 + if( sh4r.sh4_state != SH4_STATE_STANDBY ) {1.100 + TMU_run_slice( nanosecs );1.101 + SCIF_run_slice( nanosecs );1.102 + }1.103 + return nanosecs;1.104 +}1.105 +1.106 +void sh4_core_exit( int exit_code )1.107 +{1.108 + if( sh4_running ) {1.109 +#ifdef SH4_TRANSLATOR1.110 + if( sh4_use_translator ) {1.111 + sh4_translate_exit_recover();1.112 + }1.113 +#endif1.114 + // longjmp back into sh4_run_slice1.115 + sh4_running = FALSE;1.116 + longjmp(sh4_exit_jmp_buf, exit_code);1.117 + }1.118 +}1.119 +1.120 +void sh4_flush_icache()1.121 +{1.122 +#ifdef SH4_TRANSLATOR1.123 + // FIXME: Special case needs to be generalized1.124 + if( sh4_translate_flush_cache() ) {1.125 + longjmp(sh4_exit_jmp_buf, CORE_EXIT_CONTINUE);1.126 + }1.127 +#endif1.128 +}1.129 +1.130 void sh4_save_state( FILE *f )1.131 {1.132 if( sh4_use_translator ) {1.133 @@ -271,7 +356,7 @@1.134 #define RAISE( x, v ) do{ \1.135 if( sh4r.vbr == 0 ) { \1.136 ERROR( "%08X: VBR not initialized while raising exception %03X, halting", sh4r.pc, x ); \1.137 - dreamcast_stop(); return FALSE; \1.138 + sh4_core_exit(CORE_EXIT_HALT); return FALSE; \1.139 } else { \1.140 sh4r.spc = sh4r.pc; \1.141 sh4r.ssr = sh4_read_sr(); \1.142 @@ -380,9 +465,7 @@1.143 sh4r.sh4_state = SH4_STATE_SLEEP;1.144 }1.145 }1.146 - if( sh4_xlat_is_running() ) {1.147 - sh4_translate_exit( XLAT_EXIT_SLEEP );1.148 - }1.149 + sh4_core_exit( CORE_EXIT_SLEEP );1.150 }1.152 /**
.