Search
lxdream.org :: lxdream/src/sh4/sh4core.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4core.c
changeset 157:fbe03268ad8a
prev124:ceb38f08619a
next164:84f6b203cfe1
author nkeynes
date Thu Jun 15 10:27:10 2006 +0000 (14 years ago)
permissions -rw-r--r--
last change Add preliminary call-stack tracing ability
Fix INTC state save/load/reset
file annotate diff log raw
1.1 --- a/src/sh4/sh4core.c Wed Mar 22 14:27:40 2006 +0000
1.2 +++ b/src/sh4/sh4core.c Thu Jun 15 10:27:10 2006 +0000
1.3 @@ -1,5 +1,5 @@
1.4 /**
1.5 - * $Id: sh4core.c,v 1.26 2006-03-22 14:27:40 nkeynes Exp $
1.6 + * $Id: sh4core.c,v 1.27 2006-06-15 10:27:10 nkeynes Exp $
1.7 *
1.8 * SH4 emulation core, and parent module for all the SH4 peripheral
1.9 * modules.
1.10 @@ -27,6 +27,8 @@
1.11 #include "clock.h"
1.12 #include "syscall.h"
1.13
1.14 +#define SH4_CALLTRACE 1
1.15 +
1.16 #define MAX_INT 0x7FFFFFFF
1.17 #define MIN_INT 0x80000000
1.18 #define MAX_INTF 2147483647.0
1.19 @@ -84,7 +86,8 @@
1.20 MMIO_WRITE( MMU, EXPEVT, EXC_POWER_RESET );
1.21
1.22 /* Peripheral modules */
1.23 - intc_reset();
1.24 + INTC_reset();
1.25 + TMU_reset();
1.26 SCIF_reset();
1.27 }
1.28
1.29 @@ -178,6 +181,7 @@
1.30 void sh4_save_state( FILE *f )
1.31 {
1.32 fwrite( &sh4r, sizeof(sh4r), 1, f );
1.33 + INTC_save_state( f );
1.34 TMU_save_state( f );
1.35 SCIF_save_state( f );
1.36 }
1.37 @@ -185,6 +189,7 @@
1.38 int sh4_load_state( FILE * f )
1.39 {
1.40 fread( &sh4r, sizeof(sh4r), 1, f );
1.41 + INTC_load_state( f );
1.42 TMU_load_state( f );
1.43 return SCIF_load_state( f );
1.44 }
1.45 @@ -200,6 +205,53 @@
1.46 #define UNDEF(ir) do{ ERROR( "Raising exception on undefined instruction at %08x, opcode = %04x", sh4r.pc, ir ); dreamcast_stop(); return FALSE; }while(0)
1.47 #define UNIMP(ir) do{ ERROR( "Halted on unimplemented instruction at %08x, opcode = %04x", sh4r.pc, ir ); dreamcast_stop(); return FALSE; }while(0)
1.48
1.49 +#if(SH4_CALLTRACE == 1)
1.50 +#define MAX_CALLSTACK 32
1.51 +static struct call_stack {
1.52 + sh4addr_t call_addr;
1.53 + sh4addr_t target_addr;
1.54 + sh4addr_t stack_pointer;
1.55 +} call_stack[MAX_CALLSTACK];
1.56 +
1.57 +static int call_stack_depth = 0;
1.58 +int sh4_call_trace_on = 0;
1.59 +
1.60 +static inline trace_call( sh4addr_t source, sh4addr_t dest )
1.61 +{
1.62 + if( call_stack_depth < MAX_CALLSTACK ) {
1.63 + call_stack[call_stack_depth].call_addr = source;
1.64 + call_stack[call_stack_depth].target_addr = dest;
1.65 + call_stack[call_stack_depth].stack_pointer = sh4r.r[15];
1.66 + }
1.67 + call_stack_depth++;
1.68 +}
1.69 +
1.70 +static inline trace_return( sh4addr_t source, sh4addr_t dest )
1.71 +{
1.72 + if( call_stack_depth > 0 ) {
1.73 + call_stack_depth--;
1.74 + }
1.75 +}
1.76 +
1.77 +void fprint_stack_trace( FILE *f )
1.78 +{
1.79 + int i = call_stack_depth -1;
1.80 + if( i >= MAX_CALLSTACK )
1.81 + i = MAX_CALLSTACK - 1;
1.82 + for( ; i >= 0; i-- ) {
1.83 + fprintf( f, "%d. Call from %08X => %08X, SP=%08X\n",
1.84 + (call_stack_depth - i), call_stack[i].call_addr,
1.85 + call_stack[i].target_addr, call_stack[i].stack_pointer );
1.86 + }
1.87 +}
1.88 +
1.89 +#define TRACE_CALL( source, dest ) trace_call(source, dest)
1.90 +#define TRACE_RETURN( source, dest ) trace_return(source, dest)
1.91 +#else
1.92 +#define TRACE_CALL( dest, rts )
1.93 +#define TRACE_RETURN( source, dest )
1.94 +#endif
1.95 +
1.96 #define RAISE( x, v ) do{ \
1.97 if( sh4r.vbr == 0 ) { \
1.98 ERROR( "%08X: VBR not initialized while raising exception %03X, halting", sh4r.pc, x ); \
1.99 @@ -407,6 +459,7 @@
1.100 sh4r.pr = sh4r.pc + 4;
1.101 sh4r.pc = sh4r.new_pc;
1.102 sh4r.new_pc = pc + 4 + RN(ir);
1.103 + TRACE_CALL( pc, sh4r.new_pc );
1.104 return TRUE;
1.105 case 2: /* BRAF Rn */
1.106 CHECKDEST( pc + 4 + RN(ir) );
1.107 @@ -519,6 +572,7 @@
1.108 sh4r.in_delay_slot = 1;
1.109 sh4r.pc = sh4r.new_pc;
1.110 sh4r.new_pc = sh4r.pr;
1.111 + TRACE_RETURN( pc, sh4r.new_pc );
1.112 return TRUE;
1.113 case 1: /* SLEEP */
1.114 if( MMIO_READ( CPG, STBCR ) & 0x80 ) {
1.115 @@ -761,6 +815,7 @@
1.116 sh4r.pc = sh4r.new_pc;
1.117 sh4r.new_pc = RN(ir);
1.118 sh4r.pr = pc + 4;
1.119 + TRACE_CALL( pc, sh4r.new_pc );
1.120 return TRUE;
1.121 case 0x0E: /* LDC Rn, SR */
1.122 CHECKPRIV();
1.123 @@ -1128,6 +1183,7 @@
1.124 sh4r.pr = pc + 4;
1.125 sh4r.pc = sh4r.new_pc;
1.126 sh4r.new_pc = pc + 4 + (DISP12(ir)<<1);
1.127 + TRACE_CALL( pc, sh4r.new_pc );
1.128 return TRUE;
1.129 case 12:/* 1100xxxxdddddddd */
1.130 switch( (ir&0x0F00)>>8 ) {
.