mirror of
https://github.com/gligli/nulldc-360.git
synced 2025-04-02 11:11:56 -04:00
332 lines
No EOL
5.9 KiB
C
332 lines
No EOL
5.9 KiB
C
#pragma once
|
|
#include "types.h"
|
|
#include "intc_types.h"
|
|
|
|
#define xstr(s) str(s)
|
|
#define str(s) #s
|
|
#include "../../emitter/emitter.h"
|
|
|
|
//sh4 exeption saved stack pointer :)
|
|
extern u32* sh4_exept_ssp;
|
|
//sh4 next opcode execute
|
|
extern u32* sh4_exept_next;
|
|
//sh4 exeption raised bool , set to true when an exeption was raised , and its not handled
|
|
extern bool sh4_exept_raised;
|
|
|
|
enum Sh4RegType
|
|
{
|
|
//GPR , bank 0
|
|
r0=0,
|
|
r1=1,
|
|
r2=2,
|
|
r3=3,
|
|
r4=4,
|
|
r5=5,
|
|
r6=6,
|
|
r7=7,
|
|
r8=8,
|
|
r9=9,
|
|
r10=10,
|
|
r11=11,
|
|
r12=12,
|
|
r13=13,
|
|
r14=14,
|
|
r15=15,
|
|
|
|
//GPR , bank 1
|
|
r0_Bank=16,
|
|
r1_Bank=17,
|
|
r2_Bank=18,
|
|
r3_Bank=19,
|
|
r4_Bank=20,
|
|
r5_Bank=21,
|
|
r6_Bank=22,
|
|
r7_Bank=23,
|
|
|
|
//Misc regs
|
|
reg_gbr=24,
|
|
reg_ssr=25,
|
|
reg_spc=26,
|
|
reg_sgr=27,
|
|
reg_dbr=28,
|
|
reg_vbr=29,
|
|
reg_mach=30,
|
|
reg_macl=31,
|
|
reg_pr=32,
|
|
reg_fpul=33,
|
|
reg_pc=34,
|
|
reg_sr=35,
|
|
reg_fpscr=36,
|
|
|
|
//FPU gpr , bank 0
|
|
fr_0=37,
|
|
fr_1=fr_0+1,
|
|
fr_2=fr_0+2,
|
|
fr_3=fr_0+3,
|
|
fr_4=fr_0+4,
|
|
fr_5=fr_0+5,
|
|
fr_6=fr_0+6,
|
|
fr_7=fr_0+7,
|
|
fr_8=fr_0+8,
|
|
fr_9=fr_0+9,
|
|
fr_10=fr_0+10,
|
|
fr_11=fr_0+11,
|
|
fr_12=fr_0+12,
|
|
fr_13=fr_0+13,
|
|
fr_14=fr_0+14,
|
|
fr_15=fr_0+15,
|
|
|
|
//FPU gpr , bank 1
|
|
xf_0=fr_15+1,
|
|
xf_1=xf_0+1,
|
|
xf_2=xf_0+2,
|
|
xf_3=xf_0+3,
|
|
xf_4=xf_0+4,
|
|
xf_5=xf_0+5,
|
|
xf_6=xf_0+6,
|
|
xf_7=xf_0+7,
|
|
xf_8=xf_0+8,
|
|
xf_9=xf_0+9,
|
|
xf_10=xf_0+10,
|
|
xf_11=xf_0+11,
|
|
xf_12=xf_0+12,
|
|
xf_13=xf_0+13,
|
|
xf_14=xf_0+14,
|
|
xf_15=xf_0+15,
|
|
|
|
//special regs , used _only_ on rec
|
|
reg_ftrv=xf_15+1,
|
|
reg_xmtrx=reg_ftrv+1,
|
|
//sr_T=xmtrx+1,
|
|
//sr_Q=sr_T+1,
|
|
//sr_S=sr_Q+1,
|
|
//sr_M=sr_S+1,
|
|
|
|
dr_0=reg_xmtrx+1,
|
|
dr_7=dr_0+7,
|
|
|
|
xd_0=dr_7+1,
|
|
xd_7=xd_0+7,
|
|
reg_pc_temp=xd_7+1,
|
|
reg_sr_T=reg_pc_temp+1,
|
|
|
|
sh4_reg_count,
|
|
|
|
NoReg=-1
|
|
};
|
|
extern u8 GetSingleFromDouble(u8 dbl);
|
|
|
|
#define STATUS_MASK 0x700083F2
|
|
|
|
struct __attribute__((packed)) StatusReg
|
|
{//
|
|
union
|
|
{
|
|
#ifndef XENON
|
|
struct
|
|
{
|
|
u32 T_h :1;//<<0
|
|
u32 S :1;//<<1
|
|
u32 rsvd0 :2;//<<2
|
|
u32 IMASK :4;//<<4
|
|
u32 Q :1;//<<8
|
|
u32 M :1;//<<9
|
|
u32 rsvd1 :5;//<<10
|
|
u32 FD :1;//<<15
|
|
u32 rsvd2 :12;//<<16
|
|
u32 BL :1;//<<28
|
|
u32 RB :1;//<<29
|
|
u32 MD :1;//<<20
|
|
u32 rsvd3 :1;//<<31
|
|
};
|
|
#else
|
|
struct
|
|
{
|
|
u32 rsvd3 :1;//<<31
|
|
u32 MD :1;//<<20
|
|
u32 RB :1;//<<29
|
|
u32 BL :1;//<<28
|
|
u32 rsvd2 :12;//<<16
|
|
u32 FD :1;//<<15
|
|
u32 rsvd1 :5;//<<10
|
|
u32 M :1;//<<9
|
|
u32 Q :1;//<<8
|
|
u32 IMASK :4;//<<4
|
|
u32 rsvd0 :2;//<<2
|
|
u32 S :1;//<<1
|
|
u32 T_h :1;//<<0
|
|
};
|
|
#endif
|
|
u32 m_full;
|
|
};
|
|
u32 T_;
|
|
|
|
INLINE u32 GetT()
|
|
{
|
|
GetFull(true);
|
|
return T_;
|
|
}
|
|
|
|
INLINE void SetT(u32 t)
|
|
{
|
|
SetFull((GetFull(true)&~1) | (t&1),true);
|
|
}
|
|
|
|
INLINE u32 GetFull(bool autoDR)
|
|
{
|
|
if (autoDR && settings.dynarec.Enable)
|
|
{
|
|
//gli interpeter T needs to be up to date
|
|
u32 Tloc=0;
|
|
asm volatile (
|
|
"li %[Tloc],0 \n"
|
|
"bc 4," xstr(CR_T_FLAG) ",1f \n"
|
|
"li %[Tloc],1 \n"
|
|
"1: \n"
|
|
:[Tloc] "+r" (Tloc)
|
|
);
|
|
T_=Tloc;
|
|
}
|
|
|
|
return (m_full&STATUS_MASK) | (T_&1);
|
|
}
|
|
|
|
INLINE void SetFull(u32 value,bool autoDR)
|
|
{
|
|
m_full=value & STATUS_MASK;
|
|
T_=value&1;
|
|
|
|
if (autoDR && settings.dynarec.Enable)
|
|
{
|
|
//gli dynarec T needs to be up to date
|
|
u32 Tloc=T_;
|
|
asm volatile (
|
|
"cmplwi %[Tloc],0 \n"
|
|
"crnor " xstr(CR_T_FLAG) ",2,2 \n"
|
|
::[Tloc] "r" (Tloc)
|
|
);
|
|
}
|
|
}
|
|
|
|
};
|
|
struct __attribute__((packed)) fpscr_type
|
|
{
|
|
union
|
|
{
|
|
u32 full;
|
|
#ifndef XENON
|
|
struct
|
|
{
|
|
u32 RM:2;
|
|
u32 finexact:1;
|
|
u32 funderflow:1;
|
|
u32 foverflow:1;
|
|
u32 fdivbyzero:1;
|
|
u32 finvalidop:1;
|
|
u32 einexact:1;
|
|
u32 eunderflow:1;
|
|
u32 eoverflow:1;
|
|
u32 edivbyzero:1;
|
|
u32 einvalidop:1;
|
|
u32 cinexact:1;
|
|
u32 cunderflow:1;
|
|
u32 coverflow:1;
|
|
u32 cdivbyzero:1;
|
|
u32 cinvalid:1;
|
|
u32 cfpuerr:1;
|
|
u32 DN:1;
|
|
u32 PR:1;
|
|
u32 SZ:1;
|
|
u32 FR:1;
|
|
u32 rsvd:10;
|
|
};
|
|
struct
|
|
{
|
|
u32 nil:2+1+1+1+1+4+8+1;
|
|
u32 PR_SZ:2;
|
|
u32 nil2:11;
|
|
};
|
|
#else
|
|
struct
|
|
{
|
|
u32 rsvd:10;
|
|
u32 FR:1;
|
|
u32 SZ:1;
|
|
u32 PR:1;
|
|
u32 DN:1;
|
|
u32 cfpuerr:1;
|
|
u32 cinvalid:1;
|
|
u32 cdivbyzero:1;
|
|
u32 coverflow:1;
|
|
u32 cunderflow:1;
|
|
u32 cinexact:1;
|
|
u32 einvalidop:1;
|
|
u32 edivbyzero:1;
|
|
u32 eoverflow:1;
|
|
u32 eunderflow:1;
|
|
u32 einexact:1;
|
|
u32 finvalidop:1;
|
|
u32 fdivbyzero:1;
|
|
u32 foverflow:1;
|
|
u32 funderflow:1;
|
|
u32 finexact:1;
|
|
u32 RM:2;
|
|
};
|
|
struct
|
|
{
|
|
u32 nil2:11;
|
|
u32 PR_SZ:2;
|
|
u32 nil:2+1+1+1+1+4+8+1;
|
|
};
|
|
#endif
|
|
};
|
|
};
|
|
|
|
|
|
typedef void RunFP();
|
|
typedef void StopFP();
|
|
typedef void StepFP();
|
|
typedef void SkipFP();
|
|
typedef void ResetFP(bool Manual);
|
|
typedef void InitFP();
|
|
typedef void TermFP();
|
|
typedef bool IsCpuRunningFP();
|
|
typedef u32 GetRegisterFP(Sh4RegType reg);
|
|
typedef void SetRegisterFP(Sh4RegType reg,u32 value);
|
|
typedef cResetEvent* GetArmResetEventFP();
|
|
typedef void __fastcall sh4_int_RaiseExeptionFP(u32 ExeptionCode,u32 VectorAddress);
|
|
|
|
|
|
|
|
//sh4 interface
|
|
struct sh4_if
|
|
{
|
|
RunFP* Run;
|
|
StopFP* Stop;
|
|
StepFP* Step;
|
|
SkipFP* Skip;
|
|
ResetFP* Reset;
|
|
InitFP* Init;
|
|
TermFP* Term;
|
|
|
|
TermFP* ResetCache;
|
|
|
|
IsCpuRunningFP* IsCpuRunning;
|
|
GetRegisterFP* GetRegister;
|
|
SetRegisterFP* SetRegister;
|
|
//Sh4RaiseInterruptFP* RaiseInterrupt;
|
|
sh4_int_RaiseExeptionFP* RaiseExeption;
|
|
};
|
|
|
|
//Get an interface to sh4 interpreter
|
|
sh4_if* Get_Sh4Interpreter();
|
|
//Get an interface to sh4 dynarec
|
|
sh4_if* Get_Sh4Recompiler();
|
|
//free it
|
|
void Release_Sh4If(sh4_if* cpu);
|
|
|
|
void DissasembleOpcode(u16 opcode,u32 pc,char* Dissasm);
|
|
|
|
#define BPT_OPCODE 0x8A00
|
|
|
|
bool IsReg64(Sh4RegType reg); |