Search
lxdream.org :: lxdream/src/sh4/sh4core.h
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4core.h
changeset 260:c82e26ec0cac
prev246:98054d036a24
next265:5daf59b7f31b
author nkeynes
date Wed Jan 03 09:00:17 2007 +0000 (13 years ago)
permissions -rw-r--r--
last change Adjust timers when they're read rather than waiting until the next time
slice. Also temporarily cut the CPU time by 4.
Initialize the FRQCR register to 0x0E0A for convenience
file annotate diff log raw
nkeynes@10
     1
/**
nkeynes@260
     2
 * $Id: sh4core.h,v 1.15 2007-01-03 09:00:17 nkeynes Exp $
nkeynes@10
     3
 * 
nkeynes@54
     4
 * This file defines the internal functions exported/used by the SH4 core, 
nkeynes@54
     5
 * except for disassembly functions defined in sh4dasm.h
nkeynes@10
     6
 *
nkeynes@10
     7
 * Copyright (c) 2005 Nathan Keynes.
nkeynes@10
     8
 *
nkeynes@10
     9
 * This program is free software; you can redistribute it and/or modify
nkeynes@10
    10
 * it under the terms of the GNU General Public License as published by
nkeynes@10
    11
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@10
    12
 * (at your option) any later version.
nkeynes@10
    13
 *
nkeynes@10
    14
 * This program is distributed in the hope that it will be useful,
nkeynes@10
    15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@10
    16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@10
    17
 * GNU General Public License for more details.
nkeynes@1
    18
 */
nkeynes@30
    19
nkeynes@1
    20
#ifndef sh4core_H
nkeynes@1
    21
#define sh4core_H 1
nkeynes@1
    22
nkeynes@27
    23
#include <glib/gtypes.h>
nkeynes@1
    24
#include <stdint.h>
nkeynes@23
    25
#include <stdio.h>
nkeynes@1
    26
nkeynes@1
    27
#ifdef __cplusplus
nkeynes@1
    28
extern "C" {
nkeynes@1
    29
#if 0
nkeynes@1
    30
}
nkeynes@1
    31
#endif
nkeynes@1
    32
#endif
nkeynes@1
    33
nkeynes@27
    34
nkeynes@27
    35
/**
nkeynes@27
    36
 * SH4 is running normally 
nkeynes@27
    37
 */
nkeynes@27
    38
#define SH4_STATE_RUNNING 1
nkeynes@27
    39
/**
nkeynes@27
    40
 * SH4 is not executing instructions but all peripheral modules are still
nkeynes@27
    41
 * running
nkeynes@27
    42
 */
nkeynes@27
    43
#define SH4_STATE_SLEEP 2
nkeynes@27
    44
/**
nkeynes@27
    45
 * SH4 is not executing instructions, DMAC is halted, but all other peripheral
nkeynes@27
    46
 * modules are still running
nkeynes@27
    47
 */
nkeynes@27
    48
#define SH4_STATE_DEEP_SLEEP 3
nkeynes@27
    49
/**
nkeynes@27
    50
 * SH4 is not executing instructions and all peripheral modules are also
nkeynes@27
    51
 * stopped. As close as you can get to powered-off without actually being
nkeynes@27
    52
 * off.
nkeynes@27
    53
 */
nkeynes@27
    54
#define SH4_STATE_STANDBY 4
nkeynes@27
    55
nkeynes@1
    56
struct sh4_registers {
nkeynes@1
    57
    uint32_t r[16];
nkeynes@1
    58
    uint32_t r_bank[8]; /* hidden banked registers */
nkeynes@1
    59
    uint32_t sr, gbr, ssr, spc, sgr, dbr, vbr;
nkeynes@84
    60
    uint32_t pr, pc, fpscr;
nkeynes@84
    61
    int32_t fpul;
nkeynes@1
    62
    uint64_t mac;
nkeynes@1
    63
    uint32_t m, q, s, t; /* really boolean - 0 or 1 */
nkeynes@1
    64
    float fr[2][16];
nkeynes@1
    65
nkeynes@2
    66
    int32_t store_queue[16]; /* technically 2 banks of 32 bytes */
nkeynes@2
    67
    
nkeynes@1
    68
    uint32_t new_pc; /* Not a real register, but used to handle delay slots */
nkeynes@1
    69
    uint32_t icount; /* Also not a real register, instruction counter */
nkeynes@1
    70
    uint32_t int_pending; /* flag set by the INTC = pending priority level */
nkeynes@2
    71
    int in_delay_slot; /* flag to indicate the current instruction is in
nkeynes@2
    72
                             * a delay slot (certain rules apply) */
nkeynes@53
    73
    uint32_t slice_cycle; /* Current cycle within the timeslice */
nkeynes@27
    74
    int sh4_state; /* Current power-on state (one of the SH4_STATE_* values ) */
nkeynes@1
    75
};
nkeynes@1
    76
nkeynes@1
    77
extern struct sh4_registers sh4r;
nkeynes@1
    78
nkeynes@1
    79
/* Public functions */
nkeynes@1
    80
nkeynes@1
    81
void sh4_init( void );
nkeynes@1
    82
void sh4_reset( void );
nkeynes@1
    83
void sh4_run( void );
nkeynes@1
    84
void sh4_runto( uint32_t pc, uint32_t count );
nkeynes@1
    85
void sh4_runfor( uint32_t count );
nkeynes@1
    86
int sh4_isrunning( void );
nkeynes@1
    87
void sh4_stop( void );
nkeynes@1
    88
void sh4_set_pc( int );
nkeynes@27
    89
gboolean sh4_execute_instruction( void );
nkeynes@246
    90
gboolean sh4_raise_exception( int );
nkeynes@246
    91
gboolean sh4_raise_slot_exception( int, int );
nkeynes@246
    92
gboolean sh4_raise_tlb_exception( int );
nkeynes@23
    93
void sh4_set_breakpoint( uint32_t pc, int type );
nkeynes@43
    94
gboolean sh4_clear_breakpoint( uint32_t pc, int type );
nkeynes@43
    95
int sh4_get_breakpoint( uint32_t pc );
nkeynes@23
    96
nkeynes@23
    97
#define BREAK_ONESHOT 1
nkeynes@23
    98
#define BREAK_PERM 2
nkeynes@1
    99
nkeynes@10
   100
/* SH4 Memory */
nkeynes@10
   101
int32_t sh4_read_long( uint32_t addr );
nkeynes@10
   102
int32_t sh4_read_word( uint32_t addr );
nkeynes@10
   103
int32_t sh4_read_byte( uint32_t addr );
nkeynes@10
   104
void sh4_write_long( uint32_t addr, uint32_t val );
nkeynes@10
   105
void sh4_write_word( uint32_t addr, uint32_t val );
nkeynes@10
   106
void sh4_write_byte( uint32_t addr, uint32_t val );
nkeynes@10
   107
int32_t sh4_read_phys_word( uint32_t addr );
nkeynes@10
   108
nkeynes@23
   109
/* Peripheral functions */
nkeynes@260
   110
void CPG_reset( void );
nkeynes@30
   111
void TMU_run_slice( uint32_t );
nkeynes@53
   112
void TMU_update_clocks( void );
nkeynes@53
   113
void TMU_reset( void );
nkeynes@53
   114
void TMU_save_state( FILE * );
nkeynes@53
   115
int TMU_load_state( FILE * );
nkeynes@54
   116
void DMAC_reset( void );
nkeynes@54
   117
void DMAC_run_slice( uint32_t );
nkeynes@54
   118
void DMAC_save_state( FILE * );
nkeynes@54
   119
int DMAC_load_state( FILE * );
nkeynes@32
   120
void SCIF_reset( void );
nkeynes@30
   121
void SCIF_run_slice( uint32_t );
nkeynes@23
   122
void SCIF_save_state( FILE *f );
nkeynes@23
   123
int SCIF_load_state( FILE *f );
nkeynes@157
   124
void INTC_reset( void );
nkeynes@157
   125
void INTC_save_state( FILE *f );
nkeynes@157
   126
int INTC_load_state( FILE *f );
nkeynes@1
   127
nkeynes@1
   128
#define SIGNEXT4(n) ((((int32_t)(n))<<28)>>28)
nkeynes@1
   129
#define SIGNEXT8(n) ((int32_t)((int8_t)(n)))
nkeynes@1
   130
#define SIGNEXT12(n) ((((int32_t)(n))<<20)>>20)
nkeynes@1
   131
#define SIGNEXT16(n) ((int32_t)((int16_t)(n)))
nkeynes@1
   132
#define SIGNEXT32(n) ((int64_t)((int32_t)(n)))
nkeynes@1
   133
#define SIGNEXT48(n) ((((int64_t)(n))<<16)>>16)
nkeynes@1
   134
nkeynes@1
   135
/* Status Register (SR) bits */
nkeynes@1
   136
#define SR_MD    0x40000000 /* Processor mode ( User=0, Privileged=1 ) */ 
nkeynes@1
   137
#define SR_RB    0x20000000 /* Register bank (priviledged mode only) */
nkeynes@1
   138
#define SR_BL    0x10000000 /* Exception/interupt block (1 = masked) */
nkeynes@1
   139
#define SR_FD    0x00008000 /* FPU disable */
nkeynes@1
   140
#define SR_M     0x00000200
nkeynes@1
   141
#define SR_Q     0x00000100
nkeynes@1
   142
#define SR_IMASK 0x000000F0 /* Interrupt mask level */
nkeynes@1
   143
#define SR_S     0x00000002 /* Saturation operation for MAC instructions */
nkeynes@1
   144
#define SR_T     0x00000001 /* True/false or carry/borrow */
nkeynes@1
   145
#define SR_MASK  0x700083F3
nkeynes@1
   146
#define SR_MQSTMASK 0xFFFFFCFC /* Mask to clear the flags we're keeping separately */
nkeynes@1
   147
nkeynes@1
   148
#define IS_SH4_PRIVMODE() (sh4r.sr&SR_MD)
nkeynes@1
   149
#define SH4_INTMASK() ((sh4r.sr&SR_IMASK)>>4)
nkeynes@2
   150
#define SH4_INT_PENDING() (sh4r.int_pending && !sh4r.in_delay_slot)
nkeynes@1
   151
nkeynes@1
   152
#define FPSCR_FR     0x00200000 /* FPU register bank */
nkeynes@1
   153
#define FPSCR_SZ     0x00100000 /* FPU transfer size (0=32 bits, 1=64 bits) */
nkeynes@1
   154
#define FPSCR_PR     0x00080000 /* Precision (0=32 bites, 1=64 bits) */
nkeynes@1
   155
#define FPSCR_DN     0x00040000 /* Denormalization mode (1 = treat as 0) */
nkeynes@1
   156
#define FPSCR_CAUSE  0x0003F000
nkeynes@1
   157
#define FPSCR_ENABLE 0x00000F80
nkeynes@1
   158
#define FPSCR_FLAG   0x0000007C
nkeynes@1
   159
#define FPSCR_RM     0x00000003 /* Rounding mode (0=nearest, 1=to zero) */
nkeynes@1
   160
nkeynes@1
   161
#define IS_FPU_DOUBLEPREC() (sh4r.fpscr&FPSCR_PR)
nkeynes@1
   162
#define IS_FPU_DOUBLESIZE() (sh4r.fpscr&FPSCR_SZ)
nkeynes@1
   163
#define IS_FPU_ENABLED() ((sh4r.sr&SR_FD)==0)
nkeynes@1
   164
nkeynes@84
   165
#define FR(x) sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21][(x)^1]
nkeynes@84
   166
#define DR(x) ((double *)(sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21]))[x]
nkeynes@84
   167
#define XF(x) sh4r.fr[((~sh4r.fpscr)&FPSCR_FR)>>21][(x)^1]
nkeynes@95
   168
#define XDR(x) ((double *)(sh4r.fr[((~sh4r.fpscr)&FPSCR_FR)>>21]))[x]
nkeynes@95
   169
#define DRb(x,b) ((double *)(sh4r.fr[((b ? (~sh4r.fpscr) : sh4r.fpscr)&FPSCR_FR)>>21]))[x]
nkeynes@1
   170
/* Exceptions (for use with sh4_raise_exception) */
nkeynes@1
   171
nkeynes@1
   172
#define EX_ILLEGAL_INSTRUCTION 0x180, 0x100
nkeynes@1
   173
#define EX_SLOT_ILLEGAL        0x1A0, 0x100
nkeynes@1
   174
#define EX_TLB_MISS_READ       0x040, 0x400
nkeynes@1
   175
#define EX_TLB_MISS_WRITE      0x060, 0x400
nkeynes@1
   176
#define EX_INIT_PAGE_WRITE     0x080, 0x100
nkeynes@1
   177
#define EX_TLB_PROT_READ       0x0A0, 0x100
nkeynes@1
   178
#define EX_TLB_PROT_WRITE      0x0C0, 0x100
nkeynes@1
   179
#define EX_DATA_ADDR_READ      0x0E0, 0x100
nkeynes@1
   180
#define EX_DATA_ADDR_WRITE     0x100, 0x100
nkeynes@1
   181
#define EX_FPU_EXCEPTION       0x120, 0x100
nkeynes@1
   182
#define EX_TRAPA               0x160, 0x100
nkeynes@1
   183
#define EX_BREAKPOINT          0x1E0, 0x100
nkeynes@1
   184
#define EX_FPU_DISABLED        0x800, 0x100
nkeynes@1
   185
#define EX_SLOT_FPU_DISABLED   0x820, 0x100
nkeynes@1
   186
nkeynes@2
   187
#define SH4_WRITE_STORE_QUEUE(addr,val) sh4r.store_queue[(addr>>2)&0xF] = val;
nkeynes@1
   188
nkeynes@1
   189
#ifdef __cplusplus
nkeynes@1
   190
}
nkeynes@1
   191
#endif
nkeynes@1
   192
#endif
.