mame/src/emu/cpu/sh4/sh4comn.h
2008-11-26 20:07:20 +00:00

173 lines
4.4 KiB
C

/*****************************************************************************
*
* sh4comn.h
*
* SH-4 non-specific components
*
*****************************************************************************/
#pragma once
#ifndef __SH4COMN_H__
#define __SH4COMN_H__
//#define USE_SH4DRC
/* speed up delay loops, bail out of tight loops */
#define BUSY_LOOP_HACKS 0
#define VERBOSE 0
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
#define EXPPRI(pl,po,p,n) (((4-(pl)) << 24) | ((15-(po)) << 16) | ((p) << 8) | (255-(n)))
#define NMIPRI() EXPPRI(3,0,16,SH4_INTC_NMI)
#define INTPRI(p,n) EXPPRI(4,2,p,n)
#define FP_RS(r) sh4.fr[(r)] // binary representation of single precision floating point register r
#define FP_RFS(r) *( (float *)(sh4.fr+(r)) ) // single precision floating point register r
#define FP_RFD(r) *( (double *)(sh4.fr+(r)) ) // double precision floating point register r
#define FP_XS(r) sh4.xf[(r)] // binary representation of extended single precision floating point register r
#define FP_XFS(r) *( (float *)(sh4.xf+(r)) ) // single precision extended floating point register r
#define FP_XFD(r) *( (double *)(sh4.xf+(r)) ) // double precision extended floating point register r
#ifdef LSB_FIRST
#define FP_RS2(r) sh4.fr[(r) ^ sh4.fpu_pr]
#define FP_RFS2(r) *( (float *)(sh4.fr+((r) ^ sh4.fpu_pr)) )
#define FP_XS2(r) sh4.xf[(r) ^ sh4.fpu_pr]
#define FP_XFS2(r) *( (float *)(sh4.xf+((r) ^ sh4.fpu_pr)) )
#endif
typedef struct
{
UINT32 ppc;
UINT32 pc, spc;
UINT32 pr;
UINT32 sr, ssr;
UINT32 gbr, vbr;
UINT32 mach, macl;
UINT32 r[16], rbnk[2][8], sgr;
UINT32 fr[16], xf[16];
UINT32 ea;
UINT32 delay;
UINT32 cpu_off;
UINT32 pending_irq;
UINT32 test_irq;
UINT32 fpscr;
UINT32 fpul;
UINT32 dbr;
UINT32 exception_priority[128];
int exception_requesting[128];
INT8 irq_line_state[17];
cpu_irq_callback irq_callback;
const device_config *device;
const address_space *internal;
const address_space *program;
const address_space *io;
UINT32 *m;
INT8 nmi_line_state;
int frt_input;
int irln;
int internal_irq_level;
int internal_irq_vector;
emu_timer *dma_timer[4];
emu_timer *refresh_timer;
emu_timer *rtc_timer;
emu_timer *timer[3];
UINT32 refresh_timer_base;
int dma_timer_active[4];
int sh4_icount;
int is_slave, cpu_number;
int cpu_clock, bus_clock, pm_clock;
int fpu_sz, fpu_pr;
int ioport16_pullup, ioport16_direction;
int ioport4_pullup, ioport4_direction;
void (*ftcsr_read_callback)(UINT32 data);
} SH4;
extern SH4 sh4;
enum
{
ICF = 0x00800000,
OCFA = 0x00080000,
OCFB = 0x00040000,
OVF = 0x00020000
};
/* Bits in SR */
#define T 0x00000001
#define S 0x00000002
#define I 0x000000f0
#define Q 0x00000100
#define M 0x00000200
#define FD 0x00008000
#define BL 0x10000000
#define sRB 0x20000000
#define MD 0x40000000
/* 29 bits */
#define AM 0x1fffffff
#define FLAGS (MD|sRB|BL|FD|M|Q|I|S|T)
/* Bits in FPSCR */
#define RM 0x00000003
#define DN 0x00040000
#define PR 0x00080000
#define SZ 0x00100000
#define FR 0x00200000
#define Rn ((opcode>>8)&15)
#define Rm ((opcode>>4)&15)
void sh4_exception_recompute(void); // checks if there is any interrupt with high enough priority
void sh4_exception_request(int exception); // start requesting an exception
void sh4_exception_unrequest(int exception); // stop requesting an exception
void sh4_exception_checkunrequest(int exception);
void sh4_exception(const char *message, int exception); // handle exception
void sh4_change_register_bank(int to);
void sh4_syncronize_register_bank(int to);
void sh4_swap_fp_registers(void);
void sh4_default_exception_priorities(void); // setup default priorities for exceptions
void sh4_parse_configuration(const struct sh4_config *conf);
void sh4_dma_ddt(struct sh4_ddt_dma *s);
void sh4_set_irq_line(int irqline, int state); // set state of external interrupt line
void sh4_set_frt_input(const device_config *device, int state);
void sh4_set_irln_input(const device_config *device, int value);
#ifdef LSB_FIRST
void sh4_swap_fp_couples(void);
#endif
void sh4_common_init(const device_config *device);
INLINE void sh4_check_pending_irq(const char *message) // look for highest priority active exception and handle it
{
int a,irq,z;
irq = 0;
z = -1;
for (a=0;a <= SH4_INTC_ROVI;a++)
{
if (sh4.exception_requesting[a])
{
if ((int)sh4.exception_priority[a] > z)
{
z = sh4.exception_priority[a];
irq = a;
}
}
}
if (z >= 0)
{
sh4_exception(message, irq);
}
}
#endif /* __SH4COMN_H__ */