Search
lxdream.org :: lxdream/src/sh4/sh4.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4.c
changeset 378:f10fbdd4e24b
next401:f79327f39818
author nkeynes
date Wed Sep 12 09:20:38 2007 +0000 (16 years ago)
permissions -rw-r--r--
last change Start splitting the common SH4 parts into sh4.c, with sh4core.c to become
just the emulation core.
file annotate diff log raw
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/sh4/sh4.c Wed Sep 12 09:20:38 2007 +0000
1.3 @@ -0,0 +1,150 @@
1.4 +/**
1.5 + * $Id: sh4.c,v 1.1 2007-09-12 09:20:38 nkeynes Exp $
1.6 + *
1.7 + * SH4 parent module for all CPU modes and SH4 peripheral
1.8 + * modules.
1.9 + *
1.10 + * Copyright (c) 2005 Nathan Keynes.
1.11 + *
1.12 + * This program is free software; you can redistribute it and/or modify
1.13 + * it under the terms of the GNU General Public License as published by
1.14 + * the Free Software Foundation; either version 2 of the License, or
1.15 + * (at your option) any later version.
1.16 + *
1.17 + * This program is distributed in the hope that it will be useful,
1.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.20 + * GNU General Public License for more details.
1.21 + */
1.22 +
1.23 +#define MODULE sh4_module
1.24 +#include <math.h>
1.25 +#include "dream.h"
1.26 +#include "sh4/sh4core.h"
1.27 +#include "sh4/sh4mmio.h"
1.28 +#include "sh4/intc.h"
1.29 +#include "mem.h"
1.30 +#include "clock.h"
1.31 +#include "syscall.h"
1.32 +
1.33 +void sh4_init( void );
1.34 +void sh4_reset( void );
1.35 +void sh4_start( void );
1.36 +void sh4_stop( void );
1.37 +void sh4_save_state( FILE *f );
1.38 +int sh4_load_state( FILE *f );
1.39 +
1.40 +uint32_t sh4_run_slice( uint32_t );
1.41 +uint32_t sh4_xlat_run_slice( uint32_t );
1.42 +
1.43 +struct dreamcast_module sh4_module = { "SH4", sh4_init, sh4_reset,
1.44 + NULL, sh4_run_slice, sh4_stop,
1.45 + sh4_save_state, sh4_load_state };
1.46 +
1.47 +struct sh4_registers sh4r;
1.48 +struct breakpoint_struct sh4_breakpoints[MAX_BREAKPOINTS];
1.49 +int sh4_breakpoint_count = 0;
1.50 +
1.51 +void sh4_set_use_xlat( gboolean use )
1.52 +{
1.53 + if( use ) {
1.54 + xlat_cache_init();
1.55 + sh4_x86_init();
1.56 + sh4_module.run_time_slice = sh4_xlat_run_slice;
1.57 + } else {
1.58 + sh4_module.run_time_slice = sh4_run_slice;
1.59 + }
1.60 +}
1.61 +
1.62 +void sh4_init(void)
1.63 +{
1.64 + register_io_regions( mmio_list_sh4mmio );
1.65 + MMU_init();
1.66 + sh4_reset();
1.67 +}
1.68 +
1.69 +void sh4_reset(void)
1.70 +{
1.71 + /* zero everything out, for the sake of having a consistent state. */
1.72 + memset( &sh4r, 0, sizeof(sh4r) );
1.73 +
1.74 + /* Resume running if we were halted */
1.75 + sh4r.sh4_state = SH4_STATE_RUNNING;
1.76 +
1.77 + sh4r.pc = 0xA0000000;
1.78 + sh4r.new_pc= 0xA0000002;
1.79 + sh4r.vbr = 0x00000000;
1.80 + sh4r.fpscr = 0x00040001;
1.81 + sh4r.sr = 0x700000F0;
1.82 + sh4r.fr_bank = &sh4r.fr[0][0];
1.83 +
1.84 + /* Mem reset will do this, but if we want to reset _just_ the SH4... */
1.85 + MMIO_WRITE( MMU, EXPEVT, EXC_POWER_RESET );
1.86 +
1.87 + /* Peripheral modules */
1.88 + CPG_reset();
1.89 + INTC_reset();
1.90 + MMU_reset();
1.91 + TMU_reset();
1.92 + SCIF_reset();
1.93 +}
1.94 +
1.95 +void sh4_stop(void)
1.96 +{
1.97 +
1.98 +}
1.99 +
1.100 +void sh4_save_state( FILE *f )
1.101 +{
1.102 + fwrite( &sh4r, sizeof(sh4r), 1, f );
1.103 + MMU_save_state( f );
1.104 + INTC_save_state( f );
1.105 + TMU_save_state( f );
1.106 + SCIF_save_state( f );
1.107 +}
1.108 +
1.109 +int sh4_load_state( FILE * f )
1.110 +{
1.111 + fread( &sh4r, sizeof(sh4r), 1, f );
1.112 + MMU_load_state( f );
1.113 + INTC_load_state( f );
1.114 + TMU_load_state( f );
1.115 + return SCIF_load_state( f );
1.116 +}
1.117 +
1.118 +
1.119 +void sh4_set_breakpoint( uint32_t pc, int type )
1.120 +{
1.121 + sh4_breakpoints[sh4_breakpoint_count].address = pc;
1.122 + sh4_breakpoints[sh4_breakpoint_count].type = type;
1.123 + sh4_breakpoint_count++;
1.124 +}
1.125 +
1.126 +gboolean sh4_clear_breakpoint( uint32_t pc, int type )
1.127 +{
1.128 + int i;
1.129 +
1.130 + for( i=0; i<sh4_breakpoint_count; i++ ) {
1.131 + if( sh4_breakpoints[i].address == pc &&
1.132 + sh4_breakpoints[i].type == type ) {
1.133 + while( ++i < sh4_breakpoint_count ) {
1.134 + sh4_breakpoints[i-1].address = sh4_breakpoints[i].address;
1.135 + sh4_breakpoints[i-1].type = sh4_breakpoints[i].type;
1.136 + }
1.137 + sh4_breakpoint_count--;
1.138 + return TRUE;
1.139 + }
1.140 + }
1.141 + return FALSE;
1.142 +}
1.143 +
1.144 +int sh4_get_breakpoint( uint32_t pc )
1.145 +{
1.146 + int i;
1.147 + for( i=0; i<sh4_breakpoint_count; i++ ) {
1.148 + if( sh4_breakpoints[i].address == pc )
1.149 + return sh4_breakpoints[i].type;
1.150 + }
1.151 + return 0;
1.152 +}
1.153 +
.