Search
lxdream.org :: lxdream/src/sh4/sh4.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4.c
changeset 378:f10fbdd4e24b
next401:f79327f39818
author nkeynes
date Tue Sep 18 09:12:30 2007 +0000 (16 years ago)
permissions -rw-r--r--
last change Ensure correct end-of-block PC
Handle syscalls
file annotate diff log raw
nkeynes@378
     1
/**
nkeynes@378
     2
 * $Id: sh4.c,v 1.1 2007-09-12 09:20:38 nkeynes Exp $
nkeynes@378
     3
 * 
nkeynes@378
     4
 * SH4 parent module for all CPU modes and SH4 peripheral
nkeynes@378
     5
 * modules.
nkeynes@378
     6
 *
nkeynes@378
     7
 * Copyright (c) 2005 Nathan Keynes.
nkeynes@378
     8
 *
nkeynes@378
     9
 * This program is free software; you can redistribute it and/or modify
nkeynes@378
    10
 * it under the terms of the GNU General Public License as published by
nkeynes@378
    11
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@378
    12
 * (at your option) any later version.
nkeynes@378
    13
 *
nkeynes@378
    14
 * This program is distributed in the hope that it will be useful,
nkeynes@378
    15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@378
    16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@378
    17
 * GNU General Public License for more details.
nkeynes@378
    18
 */
nkeynes@378
    19
nkeynes@378
    20
#define MODULE sh4_module
nkeynes@378
    21
#include <math.h>
nkeynes@378
    22
#include "dream.h"
nkeynes@378
    23
#include "sh4/sh4core.h"
nkeynes@378
    24
#include "sh4/sh4mmio.h"
nkeynes@378
    25
#include "sh4/intc.h"
nkeynes@378
    26
#include "mem.h"
nkeynes@378
    27
#include "clock.h"
nkeynes@378
    28
#include "syscall.h"
nkeynes@378
    29
nkeynes@378
    30
void sh4_init( void );
nkeynes@378
    31
void sh4_reset( void );
nkeynes@378
    32
void sh4_start( void );
nkeynes@378
    33
void sh4_stop( void );
nkeynes@378
    34
void sh4_save_state( FILE *f );
nkeynes@378
    35
int sh4_load_state( FILE *f );
nkeynes@378
    36
nkeynes@378
    37
uint32_t sh4_run_slice( uint32_t );
nkeynes@378
    38
uint32_t sh4_xlat_run_slice( uint32_t );
nkeynes@378
    39
nkeynes@378
    40
struct dreamcast_module sh4_module = { "SH4", sh4_init, sh4_reset, 
nkeynes@378
    41
				       NULL, sh4_run_slice, sh4_stop,
nkeynes@378
    42
				       sh4_save_state, sh4_load_state };
nkeynes@378
    43
nkeynes@378
    44
struct sh4_registers sh4r;
nkeynes@378
    45
struct breakpoint_struct sh4_breakpoints[MAX_BREAKPOINTS];
nkeynes@378
    46
int sh4_breakpoint_count = 0;
nkeynes@378
    47
nkeynes@378
    48
void sh4_set_use_xlat( gboolean use )
nkeynes@378
    49
{
nkeynes@378
    50
    if( use ) {
nkeynes@378
    51
	xlat_cache_init();
nkeynes@378
    52
	sh4_x86_init();
nkeynes@378
    53
	sh4_module.run_time_slice = sh4_xlat_run_slice;
nkeynes@378
    54
    } else {
nkeynes@378
    55
	sh4_module.run_time_slice = sh4_run_slice;
nkeynes@378
    56
    }
nkeynes@378
    57
}
nkeynes@378
    58
nkeynes@378
    59
void sh4_init(void)
nkeynes@378
    60
{
nkeynes@378
    61
    register_io_regions( mmio_list_sh4mmio );
nkeynes@378
    62
    MMU_init();
nkeynes@378
    63
    sh4_reset();
nkeynes@378
    64
}
nkeynes@378
    65
nkeynes@378
    66
void sh4_reset(void)
nkeynes@378
    67
{
nkeynes@378
    68
    /* zero everything out, for the sake of having a consistent state. */
nkeynes@378
    69
    memset( &sh4r, 0, sizeof(sh4r) );
nkeynes@378
    70
nkeynes@378
    71
    /* Resume running if we were halted */
nkeynes@378
    72
    sh4r.sh4_state = SH4_STATE_RUNNING;
nkeynes@378
    73
nkeynes@378
    74
    sh4r.pc    = 0xA0000000;
nkeynes@378
    75
    sh4r.new_pc= 0xA0000002;
nkeynes@378
    76
    sh4r.vbr   = 0x00000000;
nkeynes@378
    77
    sh4r.fpscr = 0x00040001;
nkeynes@378
    78
    sh4r.sr    = 0x700000F0;
nkeynes@378
    79
    sh4r.fr_bank = &sh4r.fr[0][0];
nkeynes@378
    80
nkeynes@378
    81
    /* Mem reset will do this, but if we want to reset _just_ the SH4... */
nkeynes@378
    82
    MMIO_WRITE( MMU, EXPEVT, EXC_POWER_RESET );
nkeynes@378
    83
nkeynes@378
    84
    /* Peripheral modules */
nkeynes@378
    85
    CPG_reset();
nkeynes@378
    86
    INTC_reset();
nkeynes@378
    87
    MMU_reset();
nkeynes@378
    88
    TMU_reset();
nkeynes@378
    89
    SCIF_reset();
nkeynes@378
    90
}
nkeynes@378
    91
nkeynes@378
    92
void sh4_stop(void)
nkeynes@378
    93
{
nkeynes@378
    94
nkeynes@378
    95
}
nkeynes@378
    96
nkeynes@378
    97
void sh4_save_state( FILE *f )
nkeynes@378
    98
{
nkeynes@378
    99
    fwrite( &sh4r, sizeof(sh4r), 1, f );
nkeynes@378
   100
    MMU_save_state( f );
nkeynes@378
   101
    INTC_save_state( f );
nkeynes@378
   102
    TMU_save_state( f );
nkeynes@378
   103
    SCIF_save_state( f );
nkeynes@378
   104
}
nkeynes@378
   105
nkeynes@378
   106
int sh4_load_state( FILE * f )
nkeynes@378
   107
{
nkeynes@378
   108
    fread( &sh4r, sizeof(sh4r), 1, f );
nkeynes@378
   109
    MMU_load_state( f );
nkeynes@378
   110
    INTC_load_state( f );
nkeynes@378
   111
    TMU_load_state( f );
nkeynes@378
   112
    return SCIF_load_state( f );
nkeynes@378
   113
}
nkeynes@378
   114
nkeynes@378
   115
nkeynes@378
   116
void sh4_set_breakpoint( uint32_t pc, int type )
nkeynes@378
   117
{
nkeynes@378
   118
    sh4_breakpoints[sh4_breakpoint_count].address = pc;
nkeynes@378
   119
    sh4_breakpoints[sh4_breakpoint_count].type = type;
nkeynes@378
   120
    sh4_breakpoint_count++;
nkeynes@378
   121
}
nkeynes@378
   122
nkeynes@378
   123
gboolean sh4_clear_breakpoint( uint32_t pc, int type )
nkeynes@378
   124
{
nkeynes@378
   125
    int i;
nkeynes@378
   126
nkeynes@378
   127
    for( i=0; i<sh4_breakpoint_count; i++ ) {
nkeynes@378
   128
	if( sh4_breakpoints[i].address == pc && 
nkeynes@378
   129
	    sh4_breakpoints[i].type == type ) {
nkeynes@378
   130
	    while( ++i < sh4_breakpoint_count ) {
nkeynes@378
   131
		sh4_breakpoints[i-1].address = sh4_breakpoints[i].address;
nkeynes@378
   132
		sh4_breakpoints[i-1].type = sh4_breakpoints[i].type;
nkeynes@378
   133
	    }
nkeynes@378
   134
	    sh4_breakpoint_count--;
nkeynes@378
   135
	    return TRUE;
nkeynes@378
   136
	}
nkeynes@378
   137
    }
nkeynes@378
   138
    return FALSE;
nkeynes@378
   139
}
nkeynes@378
   140
nkeynes@378
   141
int sh4_get_breakpoint( uint32_t pc )
nkeynes@378
   142
{
nkeynes@378
   143
    int i;
nkeynes@378
   144
    for( i=0; i<sh4_breakpoint_count; i++ ) {
nkeynes@378
   145
	if( sh4_breakpoints[i].address == pc )
nkeynes@378
   146
	    return sh4_breakpoints[i].type;
nkeynes@378
   147
    }
nkeynes@378
   148
    return 0;
nkeynes@378
   149
}
nkeynes@378
   150
.