Search
lxdream.org :: lxdream/src/sh4/sh4core.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4core.c
changeset 235:880bff11df92
prev232:9c8ef78376ed
next246:98054d036a24
author nkeynes
date Tue Dec 12 09:20:25 2006 +0000 (13 years ago)
permissions -rw-r--r--
last change Add a couple of performance hacks:
1. Simplify sh4_run_slice for the usual case (no breakpoints)
2. Cache the last-read instruction page, massively speeding up instruction fetch
file annotate diff log raw
1.1 --- a/src/sh4/sh4core.c Tue Sep 26 11:09:13 2006 +0000
1.2 +++ b/src/sh4/sh4core.c Tue Dec 12 09:20:25 2006 +0000
1.3 @@ -1,5 +1,5 @@
1.4 /**
1.5 - * $Id: sh4core.c,v 1.33 2006-09-26 11:09:13 nkeynes Exp $
1.6 + * $Id: sh4core.c,v 1.34 2006-12-12 09:20:25 nkeynes Exp $
1.7 *
1.8 * SH4 emulation core, and parent module for all the SH4 peripheral
1.9 * modules.
1.10 @@ -95,6 +95,8 @@
1.11
1.12 static struct breakpoint_struct sh4_breakpoints[MAX_BREAKPOINTS];
1.13 static int sh4_breakpoint_count = 0;
1.14 +static uint16_t *sh4_icache = NULL;
1.15 +static uint32_t sh4_icache_addr = 0;
1.16
1.17 void sh4_set_breakpoint( uint32_t pc, int type )
1.18 {
1.19 @@ -142,22 +144,31 @@
1.20 sh4r.sh4_state = SH4_STATE_RUNNING;;
1.21 }
1.22
1.23 - for( sh4r.slice_cycle = 0; sh4r.slice_cycle < nanosecs; sh4r.slice_cycle += sh4_cpu_period ) {
1.24 - if( !sh4_execute_instruction() )
1.25 - break;
1.26 -#ifdef ENABLE_DEBUG_MODE
1.27 - for( i=0; i<sh4_breakpoint_count; i++ ) {
1.28 - if( sh4_breakpoints[i].address == sh4r.pc ) {
1.29 + if( sh4_breakpoint_count == 0 ) {
1.30 + for( sh4r.slice_cycle = 0; sh4r.slice_cycle < nanosecs; sh4r.slice_cycle += sh4_cpu_period ) {
1.31 + if( !sh4_execute_instruction() ) {
1.32 break;
1.33 }
1.34 }
1.35 - if( i != sh4_breakpoint_count ) {
1.36 - dreamcast_stop();
1.37 - if( sh4_breakpoints[i].type == BREAK_ONESHOT )
1.38 - sh4_clear_breakpoint( sh4r.pc, BREAK_ONESHOT );
1.39 - break;
1.40 + } else {
1.41 +
1.42 + for( sh4r.slice_cycle = 0; sh4r.slice_cycle < nanosecs; sh4r.slice_cycle += sh4_cpu_period ) {
1.43 + if( !sh4_execute_instruction() )
1.44 + break;
1.45 +#ifdef ENABLE_DEBUG_MODE
1.46 + for( i=0; i<sh4_breakpoint_count; i++ ) {
1.47 + if( sh4_breakpoints[i].address == sh4r.pc ) {
1.48 + break;
1.49 + }
1.50 + }
1.51 + if( i != sh4_breakpoint_count ) {
1.52 + dreamcast_stop();
1.53 + if( sh4_breakpoints[i].type == BREAK_ONESHOT )
1.54 + sh4_clear_breakpoint( sh4r.pc, BREAK_ONESHOT );
1.55 + break;
1.56 + }
1.57 +#endif
1.58 }
1.59 -#endif
1.60 }
1.61
1.62 /* If we aborted early, but the cpu is still technically running,
1.63 @@ -426,7 +437,24 @@
1.64 sh4r.new_pc = sh4r.pc + 2;
1.65 }
1.66 CHECKRALIGN16(pc);
1.67 - ir = MEM_READ_WORD(pc);
1.68 +
1.69 + /* Read instruction */
1.70 + uint32_t pageaddr = pc >> 12;
1.71 + if( sh4_icache != NULL && pageaddr == sh4_icache_addr ) {
1.72 + ir = sh4_icache[(pc&0xFFF)>>1];
1.73 + } else {
1.74 + sh4_icache = (uint16_t *)mem_get_page(pc);
1.75 + if( ((uint32_t)sh4_icache) < MAX_IO_REGIONS ) {
1.76 + /* If someone's actually been so daft as to try to execute out of an IO
1.77 + * region, fallback on the full-blown memory read
1.78 + */
1.79 + sh4_icache = NULL;
1.80 + ir = MEM_READ_WORD(pc);
1.81 + } else {
1.82 + sh4_icache_addr = pageaddr;
1.83 + ir = sh4_icache[(pc&0xFFF)>>1];
1.84 + }
1.85 + }
1.86 sh4r.icount++;
1.87
1.88 switch( (ir&0xF000)>>12 ) {
.