Search
lxdream.org :: lxdream/src/sh4/sh4.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4.c
changeset 740:dd11269ee48b
prev736:a02d1475ccfd
next790: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 +0000
1.2 +++ b/src/sh4/sh4.c Wed Jul 16 10:40:10 2008 +0000
1.3 @@ -19,6 +19,7 @@
1.4
1.5 #define MODULE sh4_module
1.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.18
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 built
1.23 #ifdef SH4_TRANSLATOR
1.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 #endif
1.34 }
1.35
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.42
1.43 }
1.44
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_TRANSLATOR
1.76 + xlat_flush_cache();
1.77 +#endif
1.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_TRANSLATOR
1.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 +#else
1.91 + sh4_emulate_run_slice(nanosecs);
1.92 +#endif
1.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_TRANSLATOR
1.110 + if( sh4_use_translator ) {
1.111 + sh4_translate_exit_recover();
1.112 + }
1.113 +#endif
1.114 + // longjmp back into sh4_run_slice
1.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_TRANSLATOR
1.123 + // FIXME: Special case needs to be generalized
1.124 + if( sh4_translate_flush_cache() ) {
1.125 + longjmp(sh4_exit_jmp_buf, CORE_EXIT_CONTINUE);
1.126 + }
1.127 +#endif
1.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.151
1.152 /**
.